diff --git a/CHANGES.md b/CHANGES.md
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,6 +1,587 @@
 * Hackage: <http://hackage.haskell.org/package/sbv>
 * GitHub:  <http://github.com/LeventErkok/sbv>
 
+### Version 14.8, 2026-09-25
+
+  * The main change in this release is a new C backend, with much broader
+    support for SBV programs, including arbitrary-width bit-vectors, recursive
+    functions, ADTs, and higher-order specializations. This was largely developed
+    with LLM assistance. The original backend remains available through
+    `Data.SBV.Tools.CodeGen.Legacy`, but we recommend the new backend and welcome
+    reports of any issues. See below for specific changes.
+
+  * [BACKWARDS COMPATIBILITY] `Data.SBV.Tools.CodeGen` now selects a new C compiler.
+    Import `Data.SBV.Tools.CodeGen.Legacy` to keep using the original one, including
+    its low-level compilation functions.
+
+    The new compiler supports standalone programs and static libraries using
+    arbitrary-width bit-vectors, native and arbitrary-format floating point, exact
+    integers and rational-valued reals, strings, lists, sets, tuples, ADTs, arrays,
+    recursive function definitions, closed array lambdas, and SBV's firstified
+    higher-order functions. Unsupported constructs, including solver-only features
+    and captured array lambdas, produce explicit errors.
+
+    Unmapped `SInteger` and rational-valued `SReal` now use GMP instead of being
+    rejected. Keep `cgIntegerSize` or `cgSRealType` if native, precision-losing
+    representations are intentional. Arbitrary-format floats and rounding-sensitive
+    floating operations require LibBF; native bit-vector programs need neither.
+
+    Regenerate C sources and headers together; generated type and helper names
+    have changed.
+    Detected runtime failures terminate the process; there is no error-return API.
+    See `Data.SBV.Tools.CodeGen` for supported features, dependencies, and the
+    ownership rules for composite values.
+
+  * Generated floating-point code supports all five SBV rounding modes, including
+    conversions and fused operations. Ordinary `SFloat` and `SDouble` arithmetic
+    retains native C types. Callers and callbacks must preserve `FE_TONEAREST`;
+    builds must disable implicit contraction and fast-math. Generated Makefiles
+    supply the contraction flag. These restrictions do not apply to integer-only
+    programs. `CgLongDouble` conversions support binary64, x87 extended, and
+    binary128 target formats.
+
+  * The new C compiler supports regex matching without an additional dependency.
+    `cgSetRegexLimits` (named settings) and `cgRegexLimits` control generation
+    budgets without limiting runtime string length. Direct array equality is
+    supported for finite key domains, with a configurable `cgArrayEqualityLimit`.
+    Exceeding these limits produces a generation error, not an approximation.
+
+  * Generated C libraries rebuild correctly after component or header changes.
+    Required libraries and `cgAddLDFlags` settings are kept in `SBV_LIBS`, so
+    caller-supplied `LDFLAGS` no longer discard them. Use `SBV_LIBS` to override
+    dependency discovery when integrating a custom installation.
+
+  * Fix incorrect C results for pseudo-Boolean comparisons with large totals and
+    native-mapped real-to-integer flooring. Generated diagnostic labels and
+    assertion messages safely handle special characters.
+
+  * ADTs containing other ADTs inside tuples, lists, sets, or arrays no longer
+    need unrelated uses or explicit type registration to work reliably.
+    This also applies to literal-only computations and to named and unnamed
+    query-mode fresh variables.
+
+  * Functions defined with `smtFunction` and its variants can now be first used
+    in query mode without calling `registerFunction` beforehand.
+    Thanks to David Van Balen for reporting [issue #815](https://github.com/LeventErkok/sbv/issues/815).
+
+  * Fix constant folding of integral literals converted with `toSFloatingPoint`
+    under non-default rounding modes, including overflow. Integral conversions
+    with `toSFloat` and `toSDouble` now also fold in all five rounding modes.
+
+  * Fix literal regex matching involving universal, complement, difference, and
+    intersection expressions inside concatenations and repetitions. Empty
+    concatenations (`Conc []`) now serialize correctly; invalid `Loop` and
+    `Power` bounds are rejected consistently.
+
+  * Fix first use of rational types in query mode, including rational fields
+    nested in other types. `registerType` now works inside queries and can
+    be safely repeated.
+
+  * `registerFunction` no longer rules out NaN results for floating-point
+    functions.
+
+  * `getFunction` now preserves the current model and handles
+    uninterpreted argument sorts and quoted function names correctly.
+
+  * [BACKWARDS COMPATIBILITY] `getFunction` now rejects unregistered functions.
+    Use the function in a constraint or call `registerFunction` before checking
+    satisfiability. Custom `SMTFunction` instances overriding `sexprToFun` must
+    accept an additional function-name argument.
+
+  * New example: `Documentation.SBV.Examples.ADT.Shapes` demonstrates symbolic
+    pattern matching and enumerating datatype values with `allSat` and query mode.
+
+### Version 14.7, 2026-08-31
+
+  * Fix https://github.com/LeventErkok/sbv/issues/813. Thanks to David van Balen for reporting.
+
+  * Add support for sets and arrays as ADT fields: A type declared via `mkSymbolic` can now
+    have `RCSet` and `ArrayModel` valued constructor arguments.
+
+### Version 14.6, 2026-08-18
+
+  * New TP example: Binary trees (`Documentation.SBV.Examples.TP.Tree`). Proves that mirroring
+    a tree is an involution, that it preserves the tree's size, and that the in-order traversal
+    of a mirrored tree is the reverse of the original's.
+
+  * `Data.SBV.TP` now exports `atProxy`, which annotates a proof name with the type it is being
+    run at: `atProxy (Proxy @a) "myLemma"` gives `myLemma @Integer` when `a` is `Integer`. Handy
+    for polymorphic lemmas that get used at several types within a single proof, so each instance
+    shows up under its own name in the transcript.
+
+  * Add `(.**)`, integer exponentiation following SMT-LIB's `**` operator over the `Int` theory.
+    Unlike `(.^)` (which mirrors Haskell's `^` and requires a non-negative, non-symbolic exponent),
+    `(.**)` is total and places no restriction on the exponent: it may be negative or symbolic. When
+    both arguments are concrete and the exponent is non-negative, the result is computed directly;
+    otherwise the application is emitted as SMT-LIB's `**` for the solver to interpret. Note that no
+    current solver supports `**`, so symbolic (or negative) exponentiation will typically come back
+    as `unknown` (or be rejected) until backend support arrives. Thanks to Ryan Scott for the pointer.
+
+  * [DEVELOPERS ONLY] SBV used to rely on latest z3 compiled from github master. While this was
+    important as tools matured, it also created extra-work to keep track of daily z3 changes. Starting
+    with this release, we'll track only officially released latest version of z3, which should bring
+    more stability to both the build process and end users who most likely download binaries of z3.
+    This is also true for other solvers we support, i.e., we'll track only the officially released
+    versions, instead of their latest source code.
+
+### Version 14.5, 2026-07-26
+
+  * Add `sRationalToSReal` and `sRealToSRational`, converting between symbolic rationals and
+    reals. The rational-to-real direction is always exact. The real-to-rational direction is
+    exact for reals that are rational (introducing a defining constraint for symbolic inputs);
+    note that applying it to an irrational value renders the problem unsatisfiable.
+
+  * Add the `smtLib2Compliant` field to `SMTConfig` (default: `True`), controlling whether SBV
+    asks the solver to be strictly SMTLib2 compliant. Turning it off can help with solvers (e.g.,
+    z3) that otherwise mishandle overloaded operators when integers and reals are mixed in the
+    same problem.
+
+  * Add `sRealToSIntegerRM` and `sRationalToSIntegerRM`, which convert a real/rational to an
+    integer using a symbolic rounding-mode argument, along with the helper `sCaseRoundingMode`
+    for dispatching on a symbolic `SRoundingMode`. Thanks to Ryan Scott for the implementation.
+
+  * [BACKWARDS COMPATIBILITY] The real-to-integer flooring function `sRealToSInteger` has been
+    renamed to `sRealToSIntegerFloor`, for consistency with the new `sRealToSIntegerCeiling`,
+    `sRealToSIntegerTruncate`, etc. (and with the rational counterparts below). If you use
+    `sRealToSInteger`, simply replace it with `sRealToSIntegerFloor`; the behavior is unchanged.
+
+  * Export the individual real-to-integer and rational-to-integer rounding functions, in addition
+    to the rounding-mode-dispatched versions above: `sRealToSIntegerFloor`, `sRealToSIntegerCeiling`,
+    `sRealToSIntegerTruncate`, `sRealToSIntegerRoundAway`, `sRealToSIntegerRoundToEven`, and the
+    rational counterparts `sRationalToSIntegerFloor`, `sRationalToSIntegerCeiling`,
+    `sRationalToSIntegerTruncate`, `sRationalToSIntegerRoundAway`, and `sRationalToSIntegerRoundToEven`.
+
+  * Fix `svDivide` (i.e., `/` on unbounded integers in `Data.SBV.Dynamic`), which used flooring
+    (`div`) on concrete integers instead of the Euclidean division that its symbolic counterpart
+    (and `svQuot`) implements. The two now agree, always yielding a non-negative remainder.
+    Thanks to Ryan Scott for the report.
+
+  * Improve the Haddocks for `sQuot`, `sDiv`, `sRem`, `sMod`, and related functions, clarifying
+    the truncating- vs. flooring-division distinction and documenting that the `Data.SBV.Dynamic`
+    operations `svQuot`, `svRem`, and `svQuotRem` behave differently from their `s`-prefixed
+    counterparts on unbounded integers. Thanks to Ryan Scott for the implementation.
+
+### Version 14.4, 2026-07-03
+
+  * Add `curry` and `uncurry` (for symbolic 2-tuples) and `curry3` and `uncurry3` (for
+    symbolic 3-tuples) to `Data.SBV.Tuple`, mirroring `Prelude.curry`/`Prelude.uncurry`.
+
+  * New example `Documentation.SBV.Examples.BitPrecise.Adders`, building ripple-carry and
+    carry-lookahead adders out of logic gates and proving them correct (equal to bit-vector
+    addition, equal to each other, and the carry-out equal to the overflow flag) fully
+    automatically by bit-blasting.
+
+  * New example `Documentation.SBV.Examples.TP.Adder`, the inductive companion to the above:
+    it models the operands as arbitrary-length symbolic bit lists and proves, for all widths
+    at once, that a ripple-carry adder computes the integer value of the bits, and that a
+    parallel-prefix (carry-lookahead) tree computes the same carry as the ripple---resting on
+    the associativity of the generate/propagate carry operator.
+
+  * Use str.to_re (instead of str.to.re) in regular-expression construction, which is the standard
+    naming in SMTLib2. Thanks to May Torrence for reporting the discrepancy.
+
+### Version 14.3, 2026-06-19
+
+  * Improve fpRoundToIntegralH to remove redundant internal check. Thanks to Ryan Scott for the report.
+
+  * Add support for arctan/arcsin/arccos in CVC5. Thanks to Ryan Scott for pointing out support for it.
+
+  * Improved backend-solver communication so that if a solver returns an error message SBV now makes
+    sure it gets captured and displayed properly before the solver-process itself terminates.
+
+  * Drop support for pi as an SReal: The whole premise of SReal is it represents algebraic-reals
+    (i.e., those that are roots of polynomials) exactly. But pi is not representable as such, since
+    it's transcendental. Older versions of SBV used an approximation, but that's confusing to say
+    the least, and downright wrong. Note that you can still use pi at floating-point types, where
+    precision loss is built into the semantics.
+
+  * Fix the enumeration quasi-quoter for a zero step: `[sEnum| 1, 1 .. 5 |]` is now the
+    (semantically infinite) list of 1's, instead of the empty list.
+
+  * Soundness fix for termination measures: a real-valued measure is now rejected at compile
+    time. The reals are not well-ordered (an infinite descending chain like 1, 1/2, 1/4, ...
+    never reaches a minimum), so a non-negative, strictly-decreasing real measure does not
+    imply termination. Use an integer-valued measure instead.
+
+  * Termination measures may now be given over the bounded bit-vector types (`Word8`..`Word64`,
+    `Int8`..`Int64`, `WordN n`, `IntN n`), in addition to the integer/float types supported before.
+
+### Version 14.2, 2026-06-05
+
+  * Fix float to integer conversions, which were ignoring the rounding mode previously. Thanks to
+    Ryan Scott for the report.
+
+  * Fix the implementation of properFraction for arbitrary-sized floats. Thanks to Ryan Scott
+    for the report and the fix.
+
+  * Fix a bug in pCase, where SBV was over-approximating the bound variables, causing the
+    unused-variable warning checker to flag branches unnecessarily in generated code.
+
+  * New TP example: Run-length encoding roundtrip (`Documentation.SBV.Examples.TP.RunLength`).
+    Proves that `decode (encode xs) == xs` for a run-length encode/decode pair.
+
+  * New TP example: Two-stack queue (`Documentation.SBV.Examples.TP.Queue`).
+    Proves that a queue implemented with two lists (front/back) correctly implements
+    FIFO semantics via an abstraction function.
+
+  * New cabal flag `compile_examples` (default: True) controls whether the
+    `Documentation.SBV.Examples.*` modules are built as part of the library.
+    Disable with `-f-compile_examples` when using SBV as a dependency to skip
+    compiling the example modules. Thanks to Robin Webbers for the contribution.
+
+  * Add more floating-point operations to `Data.SBV.Dynamic`. Thanks to Ryan Scott for the patch.
+
+### Version 14.1, 2026-05-04
+
+  * [BACKWARDS COMPATIBILITY] Removed `tpRibbon`. The ribbon length for TP proof
+    output is now auto-computed from the proof structure via a lightweight dry-run
+    pass. Users no longer need to manually set it.
+
+  * New TP combinators `whenDryRun` and `unlessDryRun` allow user code to guard
+    actions (e.g., proof tree printing) that should only run during the real pass of a TP
+    based proof.
+
+  * TP `pCase` now supports nested `case` expressions as proof case-splits,
+    mirroring how `sCase` treats nested `case` as symbolic cases.
+
+  * Consolidated internal solver IPC timeouts into named constants.
+    Set the environment variable `SBV_COMM_TIMEOUT_FACTOR` to scale them (e.g., `2` to double).
+
+  * Better handling of logic-strings, accommodating solver differences. Thanks to Ryan Scott for the report.
+
+  * Fixed a bug in fpRemH, which calculates the floating point reminder for concrete values. The result
+    was rounded twice, which is against the specification. Thanks to Ryan Scott for the report and the fix.
+
+  * Simplify how floating-point literals are printed. The older method worked for Z3/CVC5, but not for Bitwuzla.
+    Thanks to Ryan Scott for the report and the fix.
+
+  * Fix the definition of sRealToSIntegerTruncate to do proper truncation. Thanks to Ryan Scott for the
+    report and the fix.
+
+### Version 14.0, 2026-04-01
+
+  * [BACKWARDS COMPATIBILITY] The most important change in this release is how SBV treats
+    function definitions via `smtFunction` and its variants. In prior versions, these definitions were
+    directly translated to SMT-lib, without checking that they actually terminate. Starting with
+    this release, SBV now requires all functions to terminate (with an escape hatch where the user
+    explicitly opts out), and it proves it for all functions involved in a proof. SBV guesses
+    and verifies a termination measure, and in case it can't do so will tell the user to supply
+    their own version. This major departure from the old style of ignoring termination is a step
+    towards incorporating a better architecture for much improved (semi-)automated theorem proving
+    in SBV. See below for more details.
+
+  * [BACKWARDS COMPATIBILITY] Major improvements to the `sCase` and `pCase` quasi-quoters:
+    - Type prefix is no longer required; the type is inferred automatically
+      from the patterns. Old syntax: `[sCase|Expr e of ...]`. New syntax: `[sCase| e of ...]`.
+
+    - Wildcard-only patterns are now supported. An unguarded wildcard generates the rhs directly,
+      while guarded wildcards produce an `ite`-chain (for `sCase`) or proof obligations (for `pCase`).
+
+    - Built-in types are now supported: `Maybe`, `Either`, `List`, and `Tuple2` through `Tuple8`.
+      Nested patterns across built-in types are also supported (e.g., `Just (x:_)`, `Left (a, b)`).
+      For single-constructor types, the generated code omits the redundant constructor tester guard.
+
+    - Primitive types are now supported: `Bool`, `Integer`, `Char`, and `String`. Patterns can use
+      `True`/`False`, integer literals, character literals, string literals, variable bindings,
+      and wildcards.
+
+       ```haskell
+       [sCase| m of         [sCase| x of      [sCase| xs of                [sCase| c of
+          Nothing -> 0         0 -> sTrue        []      -> 0                 'a' -> 1
+          Just x  -> x + 1     _ -> sFalse       x : xs' -> x + f xs'         'b' -> 2
+       |]                   |]                |]                               _   -> 0
+                                                                           |]
+
+       [sCase| x of                            [sCase| x of
+          _ | x .> 0 -> x                         0         -> y
+            | sTrue  -> -x                        _ | x .> y -> x
+       |]                                           | sTrue  -> y
+                                               |]
+       ```
+
+    - As-patterns (`x@pat`) are now supported in both top-level and nested positions.
+      The as-name is bound to the scrutinee (top-level) or accessor (nested) via a
+      let-binding, which is elided when the name is unused. This works with all pattern
+      types: constructors, tuples, lists, wildcards, and in combination with nested `case`
+      expressions.
+
+       ```haskell
+       [sCase| xs of
+          a : tl@(_ : _) -> a + case tl of
+                                   b : _ -> b
+                                   []    -> 0
+          _ : _           -> 0
+          []              -> 0
+       |]
+       ```
+
+    - Plain `case` expressions inside `[sCase|...|]` and `[pCase|...|]` are now automatically
+      treated as symbolic case-splits. This works around GHC's quasi-quoter nesting limitation
+      (`[sCase|` cannot contain `|]`), and makes nested symbolic case expressions natural:
+
+       ```haskell
+       [sCase| e of
+          Zero      -> case m of
+                         Nothing -> 0
+                         Just v  -> v
+          Num k     -> k
+          Add a b   -> t a m + t b m
+       |]
+       ```
+
+      All `case` expressions inside `sCase` and `pCase` become symbolic; use a `let` or helper
+      function for regular Haskell case expressions.
+
+  * Improved documentation for `lambdaArray`, explaining the model-theoretic distinction
+    between the pure array theory (`select`/`store`/`const`) and the richer setting where
+    arrays are identified with function spaces.
+
+  * [BACKWARDS COMPATIBILITY] `recall` and `recallWith` no longer take a `String` argument.
+    A recalled proof is now automatically cached and reused if the same proposition is
+    encountered again. `tpNoCache` has been removed.
+
+  * SBV now detects conflicting `smtFunction` definitions: if two calls use the same SMT
+    name but have different bodies, an error is raised. Identical re-registrations (which
+    happen naturally with recursive functions) remain allowed.
+
+  * SBV now automatically checks termination of recursive functions defined via `smtFunction`.
+    A measure (a non-negative expression that strictly decreases at each recursive call) is
+    guessed automatically from argument types when possible. For functions that need an explicit
+    measure, use `smtFunctionWithMeasure`:
+
+    ```haskell
+    ld = smtFunctionWithMeasure "ld" (\k n -> (n - k) `smax` 0, [])
+       $ \k n -> ite (n `sMod` k .== 0) k (ld (k+1) n)
+    ```
+
+    When the measure requires inductive properties to verify, supply TP proof actions as helpers
+    via `measureLemma`/`measureLemmaWith`:
+
+    ```haskell
+    normalize = smtFunctionWithMeasure "normalize"
+                  ( \f -> tuple (ifComplexity f, ifDepth f)
+                  , [measureLemma ifDepthNonNeg, measureLemma ifComplexityPos]
+                  )
+              $ \f -> ...
+    ```
+
+  * For nested recursive functions (like McCarthy's 91 function) where the termination argument
+    depends on the function's return value at smaller inputs, use `smtFunctionWithContract`. This
+    takes a measure and a contract (post-condition) that are verified simultaneously via well-founded
+    induction:
+
+    ```haskell
+    mcCarthy91 = smtFunctionWithContract "mcCarthy91"
+                   ( \n -> 0 `smax` (101 - n)
+                   , \n r -> n .<= 100 .=> r .== 91
+                   , []
+                   )
+               $ \n -> ite (n .> 100) (n - 10) (mcCarthy91 (mcCarthy91 (n + 11)))
+    ```
+
+  * Productive (corecursive) functions can now be defined via `smtProductiveFunction`. Unlike
+    terminating functions, productive functions need not have a base case — they may produce
+    infinite output, so long as every recursive call is guarded by a data constructor.
+
+  * New function `smtFunctionNoTermination` for defining recursive SMT functions without any
+    termination check. The function is emitted as `define-fun-rec` and the user takes
+    responsibility for well-definedness. Use this for functions where termination is believed
+    but cannot be proven. Any TP proof that depends on such a function will be marked as
+    `[Modulo: <name> termination]` instead of `[Proven]` in its root of trust.
+
+  * New example `Documentation.SBV.Examples.TP.Countdown`, proving properties of a
+    list-building countdown function using induction.
+
+  * New example `Documentation.SBV.Examples.TP.NatStream`, demonstrating `smtProductiveFunction`
+    with the infinite stream `nats n = [n, n+1, n+2, ...]` and proofs about its head, length, and
+    element access.
+
+  * New example `Documentation.SBV.Examples.TP.MutualCorecursion`, demonstrating mutually
+    corecursive productive functions. Two functions `ping` and `pong` take turns producing
+    elements of a stream, and we prove elementwise equality and that the k-th element of
+    `ping n` is `n + k`.
+
+  * New example `Documentation.SBV.Examples.TP.Collatz`, using `smtFunctionNoTermination` to
+    define the Collatz function (whose termination is a famous open problem) and proving that
+    all powers of two reach 1.
+
+### Version 13.6, 2026-03-02
+
+  * The `sCase` quasi-quoter now supports nested constructor patterns. Sub-patterns
+    in a constructor match can themselves be constructors, including nullary ones. For example:
+
+    ```haskell
+    normalize f = smtFunction "normalize" $ \f ->
+      [sCase|Formula f of
+        If (If p q r) left right -> normalize (sIf p (sIf q left right) (sIf r left right))
+        If c          left right -> sIf c (normalize left) (normalize right)
+        _                        -> f
+      |]
+    ```
+
+    Nested patterns generate appropriate `isCstr`/`getCstr_i` guards and let-bindings
+    automatically. Pattern guards (`, e1, e2`) may also be used alongside nested patterns.
+    Additionally, `| True` is now accepted as a synonym for `| sTrue` in guards.
+
+  * The `sCase` quasi-quoter now supports integer and string literal patterns in nested
+    positions (and at the top level inside a constructor). For example:
+
+    ```haskell
+    p e = [sCase|Formula e of
+             Val 0         -> 100          -- fires when the Val field equals 0
+             Val 1         -> 200          -- fires when the Val field equals 1
+             Add (Val 0) r -> eval r       -- nested literal: fires when left child is Val 0
+             _             -> eval e
+          |]
+    ```
+
+    A literal sub-pattern desugars to a symbolic equality guard (`getC_i e .== lit`),
+    so the exhaustiveness checker correctly requires a fallback for any constructor
+    that only appears with literal sub-patterns.
+
+  * Add the `pCase` quasi-quoter for proof case-splits. Same syntax as `sCase`, but
+    generates `cases [cond ==> proof, ...]` instead of `ite` chains. Wildcards are
+    allowed as the last arm (with or without guards), generating a negated disjunction
+    of all prior guards to do fall-thru proofs.
+
+  * Add minimum and maximum to Data.SBV.List. If they receive empty list as argument,
+    then the result is underspecified, i.e., can be any value of the element type.
+
+  * Add mapConcat to Documentation.SBV.Examples.TP.Lists, which proves the theorem
+    `map f . concat = concat . map (map f)`.
+
+  * Add Documentation.SBV.Examples.TP.Kadane, proving the correctness of Kadane's algorithm
+    for computing the maximum segment sum. The proof uses a generalized invariant lemma to relate
+    the accumulator-based implementation to the specification. (This proof was completed with
+    assistance from Claude, in particular the part where we had to come up with the invariant
+    about the helper function.)
+
+  * Add Documentation.SBV.Examples.TP.Coins, proving the classic coin change theorem: for any
+    amount n >= 8, you can make exact change using only 3-cent and 5-cent coins. Inspired by
+    an Imandra example at <https://github.com/imandra-ai/imandrax-examples/blob/main/src/coins.iml>.
+
+  * Add Documentation.SBV.Examples.TP.Ackermann, proving the relationship between Ackermann's
+    original function and R. Peter's version (1935). Inspired by an Imandra example at
+    <https://github.com/imandra-ai/imandrax-examples/blob/main/src/ackermann.iml>. This proof
+    was developed by Claude with minimal user prompting and guidance.
+
+  * Add Documentation.SBV.Examples.TP.PigeonHole, proving the pigeonhole principle: If a list
+    of numbers sum up to more than the length of the list, then some cell must have a value
+    greater than one.
+
+  * Add Documentation.SBV.Examples.TP.TautologyChecker, a verified tautology checker for
+    propositional formulas using an unordered BDD-style SAT solver approach. The proof establishes
+    both soundness (if the checker says a formula is a tautology, it evaluates to true under all
+    bindings) and completeness (if the checker says a formula is not a tautology, falsify returns
+    a counterexample binding). Inspired by an Imandra example at
+    <https://github.com/imandra-ai/imandrax-examples/blob/main/src/tautology.iml>, originally
+    based on Boyer-Moore '79. This proof was developed with Claude's assistance.
+
+  * Add Documentation.SBV.Examples.TP.ConstFold, proving the correctness of a constant-folding
+    optimizer for a simple expression language with variables, constants, arithmetic, and let-bindings.
+    The optimizer performs bottom-up simplification including arithmetic identities (e.g., addition/
+    multiplication by 0 or 1, constant propagation) and let-folding (inlining `Let x (Con v) b` via
+    capture-avoiding substitution).
+
+### Version 13.5, 2026-01-26
+
+  * Replace internal SMT-lib program representation from plain String to Text. This
+    should improve performance and memory behavior in certain cases. Since solver time
+    dominates for most cases, this is not going to be noticeable by end-users, except
+    for very large programs. In any case, it should at least improve memory usage.
+    NB. Historical note: Most of these transformations were done by Claude code; the
+    era of AI coding had its first contributions to SBV. I' duly impressed by Claude's
+    ability to understand and manipulate Haskell. (I also tried Gemini, which was less
+    successful, compared to Claude.) I, for one, welcome our new computer overlords.
+
+  * Added Documentation.SBV.Examples.TP.UpDown.hs, demonstrating proof of a a couple of
+    list-processing functions together with naturals using TP. The problem itself is inspired
+    by a midterm exam question for an ACL2-class taught by J Moore at UT Austin back in 2011;
+    a minor tribute to J's amazing legacy.
+
+### Version 13.4, 2026-01-09
+
+  * Remove Eq constraint on readArray, generalizing it to arbitrary types for array-reads.
+
+  * Added 'freeArray', which creates an array with no constraints at all. (Compare to 'constArray'.)
+    Note that this is useful for expression contexts. If you're in a symbolic context (i.e., in
+    the Symbolic monad), you can just use 'free' or 'sArray' as usual.)
+
+  * Add missing instance of SatModel for Arrays. Thanks to Robin Webbers for the patch.
+
+  * Export ArrayModel, so it can be programmatically processed after a call.
+
+  * Moved Data/SBV/TP/List.hs to Documentation/SBV/Examples/TP/Lists.hs, which aligns better with the
+    haddock documentation.
+
+  * Fixed closure-version implementations of list functions filter, partition, takeWhile, and dropWhile.
+    Thanks to amigalemming on github for the bug report.
+
+  * Query mode now works with optimization directives. In this case, we perform lexicographic
+    optimization. (Let me know if you need other methods.) The advantage of this is that calls
+    to getValue works in this mode, so it is easier to access optimized model values. In case
+    the optimal value is in an extension field (i.e., involves epsilon or infinity values),
+    then calls to  getValue  will throw an error and alert the user. In this latter case, you
+    should resort back to using the regular optimize calls.
+
+  * Added new puzzle example: Documentation.SBV.Examples.Puzzles.SquareBirthday
+
+  * Add recallWith to Data.SBV.TP, which allows you to change the solver in a recalled proof.
+
+### Version 13.3, 2025-12-05
+
+  * Added 'constArray', which allows creation of constant valued symbolic arrays. The definition
+    is semantically equivalent to 'lambdaArray . const', but we generate simpler SMTLib code
+    for it. For the general case of initializing an array with arbitrary functions, continue
+    using 'lambdaArray'. Thanks to Robin Webbers for the patch.
+
+  * Improved the infinite-number-of-primes theorem statement slightly.
+
+### Version 13.2, 2025-12-02
+
+  * Improve support for SMTDefinable class, allowing support for on-the-fly generated functions.
+    Thanks to Eddy Westbrook for the patch. This should have no impact on existing code or usage,
+    just allowing new use cases. Let us know if it breaks anything.
+
+  * SBV now supports uninterpreted functions of arbitrary arities. (Previously, we had support for upto
+    12 args; Eddy's work above generalized this to arbitrary arity.)
+
+  * Added Documentation.SBV.Examples.TP.Primes, which formalizes prime numbers and proves that there are
+    an infinite number of primes.
+
+### Version 13.1, 2025-10-31
+
+  * Tweaks to make sure SBV compiles with GHC 9.8.4. No other changes on top of 13.0 below.
+
+### Version 13.0, 2025-10-31
+
+  * SBV now supports algebraic data-types. A new function 'mkSymbolic' is introduced, which take a list of types
+    and turns them into types that you can symbolically process. Clearly, Haskell ADTs are extremely rich:
+    Parameterized, self-referential, and mutually-recursive datatypes are supported. GADTs and more complicated
+    forms of data-types (with higher-order fields, for instance) are not supported. What SBV covers should handle
+    most use cases, please get in touch if you have a use case that is currently not supported.
+
+  * Introduced a new quasiquoter, named sCase, which allows writing case-expressions over symbolic ADTs. It supports
+    wildcards and guards. It does not support pattern guards, nor complex patterns. (Each pattern is either a
+    variable or an underscore.) Symbolic-boolean guards allow for concise expressions. This construct makes
+    symbolic programming with ADTs easier.
+
+  * Added examples under Documentation.SBV.Examples.ADT, demonstrating the use of basic ADTs and a case study
+    of modeling type-checking constraints.
+
+  * Added Documentation.SBV.Examples.TP.Peano, modeling peano numbers using an ADT and demonstrating many proofs.
+
+  * Added Documentation.SBV.Examples.TP.VM demonstrating the correctness of a simple interpreter over an expression
+    language with respect to a version that compiles the expression and runs the instructions over a virtual machine.
+
+  * [BACKWARDS COMPATIBILITY] The old functions 'mkSymbolicEnumeration' and 'mkUninterpretedSort' are now removed,
+    since their functionality is subsumed by 'mkSymbolic'.
+
+  * [BACKWARDS COMPATIBILITY] Strong-induction now takes extra proof objects that can be used to establish that
+    the measure provided is non-negative. This is usually not needed, so simply pass []. However, in case of strong
+    induction over ADTs in particular, it can come in handy to aid the solver in establishing the given measure
+    is valid.
+
 ### Version 12.2, 2025-08-15
 
   * Fix floating-point constant-folding code, which inadvertently constant-folded for symbolic rounding modes.
@@ -43,7 +624,7 @@
     implications and ask them to use custom-functions instead.
 
 ### Version 12.0, 2025-07-04
-  
+
   * [BACKWARDS COMPATIBILITY] Renamed KnuckleDragger to TP, for theorem-proving. The original name was confusing, and
     the design has diverged from Phil's tool in significant ways and goals.
 
@@ -72,7 +653,7 @@
       - Documentation.SBV.Examples.TP.Majority:   Proof of Boyer-Moore's majority selection algorithm correct.
       - Documentation.SBV.Examples.TP.McCarthy91: Proof of correctness for McCarthy's 91 function.
       - Documentation.SBV.Examples.TP.PowerMod:   Proving arithmetic properties relating power operation and modular arithmetic.
-      - Documentation.SBV.Examples.TP.ReverseAcc: Proving the accummulating reverse definition is correct.
+      - Documentation.SBV.Examples.TP.ReverseAcc: Proving the accumulating reverse definition is correct.
       - Documentation.SBV.Examples.TP.Reverse:    Proving a definition of reverse that uses no auxiliary definitions is correct.
       - Documentation.SBV.Examples.TP.SumReverse: Proving summing a list and its reverse are equivalent.
 
@@ -114,7 +695,7 @@
     methods/tactics on top of knuckle-dragger provided facilities.
 
 ### Version 11.6, 2025-05-10
- 
+
   * Make SBV compile cleanly with GHC 9.8.4. This is really as far back a GHC you should be using,
     unless you can't use anything newer.
 
@@ -133,7 +714,7 @@
 
 ### Version 11.4, 2025-03-12
 
-  * Generalize the strong-induction principle to use lexicographic order for simultanous
+  * Generalize the strong-induction principle to use lexicographic order for simultaneous
     induction over two lists.
 
   * Added a proof of correctness for the merge-sort algorithm using KnuckleDragger
@@ -167,11 +748,11 @@
     the SMT solver to find tricky proofs. See Documentation/SBV/Examples/KnuckleDragger directory for many
     examples demonstrating the new features.
 
-  * Generalize support for polyorphic and higher-order functions. These are still experimental, as SMTLib's
+  * Generalize support for polymorphic and higher-order functions. These are still experimental, as SMTLib's
     higher-order function support is nascent. (Version 3 of SMTLib will have proper support for such functions, which
     is not released yet.) Currently, SBV can handle polymorphic and higher-order usage of: 'reverse', 'any', 'all',
     'filter', 'map', 'foldl', 'foldr', 'zip', and 'zipWith'; all exported from the 'Data.SBV.List' module.
-    These functions are supported polymporphically, and (except reverse and zip) all take a function as
+    These functions are supported polymorphically, and (except reverse and zip) all take a function as
     an argument. SBV firstifies these functions, and the resulting code is compatible with Z3 and CVC5.
     (Firstification might change in the future, as SMTLib gains support for more higher-order
     features itself.) Proof-support in backend solvers for higher-order functions is still quite weak,
@@ -255,14 +836,14 @@
 
   * Fix a few custom-floating-point format conversion bugs. Thanks to Sirui Lu for the patch.
 
-  * Add a few OVERLAPPABLE pragms to generic Queriable instances to make them easily overridable by
+  * Add a few OVERLAPPABLE pragmas to generic Queriable instances to make them easily overridable by
     user programs. Thanks to Marco Zocca for reporting.
 
   * Add signedMulOverflow, which checks whether multiplication of two signed-bitvectors can overflow.
     SBV already had a method (bvMulO) that served this purpose, translating to the corresponding predicate
     in SMTLib. Unfortunately not all solvers support this predicate efficiently. In particular, as of Aug 2024,
     bitwuzla has a performant checker for this overflow, but z3 does not. In case you cannot use bitwuzla for
-    some reason, you might want to use the new signedMulOverflow funtion for better performance.
+    some reason, you might want to use the new signedMulOverflow function for better performance.
 
 ### Version 10.11, 2024-07-26
 
@@ -417,7 +998,7 @@
     ForallN and ExistsN for creating multiple variables at the same time.
 
     The new function skolemize can be used to skolemize quantified formulas: The skolemized version of a
-    formula has no existential (replaced by uninterpeted functions), and is equisatisfiable to the original.
+    formula has no existential (replaced by uninterpreted functions), and is equisatisfiable to the original.
 
     See the following files demonstrating reasoning with quantifiers:
 
@@ -438,7 +1019,7 @@
   * Added new SList functions: map, mapi, foldl, foldr, foldli, foldri, zip, zipWith, filter, all, any.
     Note that these work on arbitrary--but finite--length lists, with all terminating elements, per
     usual SBV interpretation. These functions map to the underlying solver's fold and map functions,
-    via lambda-abtractions. Note that the SMT engines remain incomplete with respect to sequence
+    via lambda-abstractions. Note that the SMT engines remain incomplete with respect to sequence
     theories. (That is, any property that requires induction for its proof will cause unknown
     answers, or will not terminate.) However, basic properties, especially when the solver can determine the
     shape of the sequence arguments (i.e., number of elements), should go through.
@@ -620,7 +1201,7 @@
     significand. This format is affectionately called "brain-float"
     because it's often used in modeling neural networks machine-learning
     applications, offering a wider-range than IEEE's half-float, at the
-    exponse of reduced precision. It has 8-exponent bits and 8-significand
+    expense of reduced precision. It has 8-exponent bits and 8-significand
     bits, including the hidden bit.
 
   * Add support for SRational type, rational values built out of the ratio
@@ -634,7 +1215,7 @@
     use cases. (Essentially, when there are no uninterpreted values or sorts present.)
     The new algorithm has been measured to be at least an order of magnitude
     faster or more in common cases as it splits the search space into disjoint
-    models, reducing the burden of accummulated lemmas over multiple calls. (See
+    models, reducing the burden of accumulated lemmas over multiple calls. (See
     http://theory.stanford.edu/%7Enikolaj/programmingz3.html#sec-blocking-evaluations
     for details.)
 
@@ -697,7 +1278,7 @@
   * Use SMTLib's int2bv if supported by the backend solver. If not, we still
     do a manual translation. (CVC4 and z3 support it natively, Yices and
     MathSAT does not, for which we do the manual translation. ABC and dReal
-    doesn't support the coversion at all, since former doesn't support integers
+    doesn't support the conversion at all, since former doesn't support integers
     and the latter doesn't support bit-vectors.) Thanks to Martin Lundfall
     for the initial pull request.
 
@@ -1502,7 +2083,7 @@
     Note that currently only Z3 and CVC4 has support for this logic,
     and they do differ in some details. Various character/string
     operations are supported, including length, concatenation,
-    regular-expression matching, substrig operations, recognizers, etc.
+    regular-expression matching, substring operations, recognizers, etc.
     If you use this logic, you are likely to find bugs in solvers themselves
     as support is rather new: Please report.
 
@@ -2521,10 +3102,6 @@
 
 ### Version 3.1, 2014-07-12
 
- NB: GHC 7.8.1 and 7.8.2 has a serious bug <https://gitlab.haskell.org/ghc/ghc/-/issues/9078>
-     that causes SBV to crash under heavy/repeated calls. The bug is addressed
-     in GHC 7.8.3; so upgrading to GHC 7.8.3 is essential for using SBV!
-
  New features/bug-fixes in v3.1:
 
  * Using multiple-SMT solvers in parallel:
@@ -2731,18 +3308,13 @@
     hackage can no longer compile it due to some dependency mismatch.
   * Add forgotten Real class instance for the type 'AlgReal'
   * Stop putting bounds on hackage dependencies, as they cause
-    more trouble then they actually help. (See the discussion
-    here: <http://www.haskell.org/pipermail/haskell-cafe/2012-July/102352.html>.)
+    more trouble then they actually help.
 
 ### Version 2.3, 2012-07-20
 
   * Maintenance release, no new features.
   * Tweak cabal dependencies to avoid using packages that are newer
-    than those that come with ghc-7.4.2. Apparently this is a no-no
-    that breaks many things, see the discussion in this thread:
-      http://www.haskell.org/pipermail/haskell-cafe/2012-July/102352.html
-    In particular, the use of containers >= 0.5 is *not* OK until we have
-    a version of GHC that comes with that version.
+    than those that come with ghc-7.4.2.
 
 ### Version 2.2, 2012-07-17
 
diff --git a/COPYRIGHT b/COPYRIGHT
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -1,4 +1,4 @@
-Copyright (c) 2010-2025, Levent Erkok (erkokl@gmail.com)
+Copyright (c) 2010-2026, Levent Erkok (erkokl@gmail.com)
 All rights reserved.
 
 The sbv library is distributed with the BSD3 license. See the LICENSE file
diff --git a/Data/SBV.hs b/Data/SBV.hs
--- a/Data/SBV.hs
+++ b/Data/SBV.hs
@@ -81,6 +81,8 @@
 --
 --   * Uninterpreted sorts, and proofs over such sorts, potentially with axioms.
 --
+--   *  Algebraic data types, including recursive fields..
+--
 --   * Ability to define SMTLib functions, generated directly from Haskell versions,
 --     including support for recursive and mutually recursive functions.
 --
@@ -123,7 +125,7 @@
 -- The SBV library is designed to work with any SMT-Lib compliant SMT-solver.
 -- Currently, we support the following SMT-Solvers out-of-the box:
 --
---   * ABC from University of Berkeley: <http://www.eecs.berkeley.edu/~alanmi/abc/>
+--   * ABC from University of Berkeley: <https://github.com/berkeley-abc/abc>
 --
 --   * CVC4, and CVC5 from Stanford University and the University of Iowa. <https://cvc4.github.io/> and <https://cvc5.github.io>
 --
@@ -156,7 +158,7 @@
 -- solvers are not good at proofs that require induction, or those that require complex chains of reasoning. Induction is necessary to reason about
 -- any recursive algorithm, and most such proofs require carefully constructed equational steps.
 --
--- SBV allows for a style of semi-automated theorem proving, called TP. which can be used to construct such proofs.
+-- SBV allows for a style of semi-automated theorem proving, called TP, which can be used to construct such proofs.
 -- The documentation includes example proofs for many list functions, and even inductive proofs for
 -- the familiar insertion, merge, quick-sort algorithms, along with a proof that the square-root of 2 is irrational.
 -- While a proper theorem prover (such as Lean, Isabelle etc.) is a more appropriate choice for such proofs, with some
@@ -211,7 +213,7 @@
   , SWord8, SWord16, SWord32, SWord64, SWord, WordN
   -- *** Signed bit-vectors
   , SInt8, SInt16, SInt32, SInt64, SInt, IntN
-  -- *** Converting between fixed-size and arbitrary bitvectors
+  -- *** Converting between fixed-size and arbitrary bit-vectors
   , BVIsNonZero, FromSized, ToSized, fromSized, toSized
   -- ** Unbounded integers
   -- $unboundedLimitations
@@ -228,26 +230,32 @@
   , fpFromInteger
   -- ** Rationals
   , SRational, (.%)
+  , sRationalToSIntegerFloor, sRationalToSIntegerCeiling, sRationalToSIntegerTruncate
+  , sRationalToSIntegerRoundAway, sRationalToSIntegerRoundToEven, sRationalToSIntegerRM
+  , sRationalToSReal, sRealToSRational
   -- ** Algebraic reals
   -- $algReals
-  , SReal, AlgReal(..), sRealToSInteger, algRealToRational, RealPoint(..), realPoint, RationalCV(..)
+  , SReal, AlgReal(..)
+  , sRealToSIntegerFloor, sRealToSIntegerCeiling, sRealToSIntegerTruncate
+  , sRealToSIntegerRoundAway, sRealToSIntegerRoundToEven, sRealToSIntegerRM
+  , algRealToRational, RealPoint(..), realPoint, RationalCV(..)
   -- ** Characters, Strings and Regular Expressions
   -- $strings
   , SChar, SString
   -- ** Symbolic lists
   -- $lists
-  , SList
+  , SList, (.:)
   -- ** Symbolic enumerators
   , EnumSymbolic(..), sEnum
+  -- ** Symbolic case-expressions
+  , sCase, pCase
   -- ** Tuples
   -- $tuples
   , SymTuple, STuple, STuple2, STuple3, STuple4, STuple5, STuple6, STuple7, STuple8
-  -- ** Sum types
-  , SMaybe, SEither
   -- ** Sets
   , RCSet(..), SSet
   -- * Arrays of symbolic values
-  , SArray, sArray, sArray_, sArrays, readArray, writeArray, lambdaArray, listArray, ArrayModel
+  , SArray, sArray, sArray_, sArrays, readArray, writeArray, lambdaArray, constArray, freeArray, listArray, ArrayModel(..)
 
   -- * Creating symbolic values
   -- ** Single value
@@ -270,10 +278,14 @@
   , sString, sString_
   , sList, sList_
   , sTuple, sTuple_
-  , sEither, sEither_
-  , sMaybe, sMaybe_
   , sSet, sSet_
 
+  -- * Symbolic 'Maybe'
+  , SMaybe, sMaybe, sMaybe_, sMaybes
+
+  -- * Symbolic 'Either'
+  , SEither, sEither, sEither_, sEithers
+
   -- ** List of values
   -- $createSyms
   , sBools
@@ -294,13 +306,11 @@
   , sStrings
   , sLists
   , sTuples
-  , sEithers
-  , sMaybes
   , sSets
 
   -- * Symbolic Equality and Comparisons
   -- $distinctNote
-  , EqSymbolic(..), OrdSymbolic(..), Equality(..)
+  , EqSymbolic(..), OrdSymbolic(..), Zero(..), MeasureOf, Equality(..)
   -- * Conditionals: Mergeable values
   , Mergeable(..), ite, iteLazy
 
@@ -321,11 +331,11 @@
   -- ** Splitting, joining, and extending bit-vectors
   , bvExtract, (#), zeroExtend, signExtend, bvDrop, bvTake, ByteConverter(..)
   -- ** Exponentiation
-  , (.^)
+  , (.^), (.**)
   -- * IEEE-floating point numbers
   , IEEEFloating(..), RoundingMode(..), SRoundingMode, nan, infinity, sNaN, sInfinity
   -- ** Rounding modes
-  , sRoundNearestTiesToEven, sRoundNearestTiesToAway, sRoundTowardPositive, sRoundTowardNegative, sRoundTowardZero, sRNE, sRNA, sRTP, sRTN, sRTZ
+  , sRoundNearestTiesToEven, sRoundNearestTiesToAway, sRoundTowardPositive, sRoundTowardNegative, sRoundTowardZero, sRNE, sRNA, sRTP, sRTN, sRTZ, sCaseRoundingMode
   -- ** Conversion to/from floats
   -- $conversionNote
   , IEEEFloatConvertible(..)
@@ -343,16 +353,19 @@
   -- ** Showing values in detail
   , crack
 
-  -- * Enumerations
-  -- $enumerations
-  , mkSymbolicEnumeration
-
-  -- * Uninterpreted sorts, constants, and functions
-  -- $uninterpreted
-  , mkUninterpretedSort
+  -- * Symbolic data types
+  -- $symbolicADT
+  , mkSymbolic
 
   -- * Stopping unrolling: Defined functions
-  , SMTDefinable(..), smtHOFunction, Closure(..), registerType
+  , SMTDefinable(..)
+  , smtFunction
+  , smtFunctionWithMeasure
+  , smtFunctionWithContract
+  , smtProductiveFunction
+  , smtFunctionNoTermination
+  , ContractOf, MeasureHelper(..)
+  , smtHOFunction, smtHOFunctionWithMeasure, Closure(..), registerType
 
   -- * Special relations
   -- $specialRels
@@ -442,7 +455,7 @@
   -- ** Programmable model extraction
   -- $programmableExtraction
   , Modelable(..), displayModels, extractModels
-  , getModelDictionaries, getModelValues, getModelUninterpretedValues
+  , getModelDictionaries, getModelValues
 
   -- * SMT Interface
   , SMTConfig(..), TPOptions(..), Timing(..), SMTLibVersion(..), Solver(..), SMTSolver(..)
@@ -479,6 +492,8 @@
 import Control.Monad       (unless)
 import Control.Monad.Trans (MonadIO)
 
+import qualified Data.Text as T
+
 import Data.SBV.Core.AlgReals
 import Data.SBV.Core.Data       hiding (free, free_, mkFreeVars,
                                         output, symbolic, symbolics, mkSymVal,
@@ -497,7 +512,7 @@
                                         sRational, sRational_, sRationals,
                                         sWord8, sWord8_, sWord8s, sWord16, sWord16_, sWord16s,
                                         sWord32, sWord32_, sWord32s, sWord64, sWord64_, sWord64s,
-                                        sMaybe, sMaybe_, sMaybes, sEither, sEither_, sEithers, sSet, sSet_, sSets,
+                                        sSet, sSet_, sSets,
                                         sArray, sArray_, sArrays,
                                         sBarrelRotateLeft, sBarrelRotateRight, zeroExtend, signExtend, sObserve)
 
@@ -508,6 +523,9 @@
 
 import Data.SBV.Core.SizedFloats
 
+import Data.SBV.Maybe hiding (map)
+import Data.SBV.Either
+
 import Data.SBV.Core.Floating
 import Data.SBV.Core.Symbolic   ( MonadSymbolic(..), SymbolicT, registerKind
                                 , ProgInfo(..), rProgInfo, SpecialRelOp(..), UICodeKind(UINone)
@@ -548,6 +566,7 @@
 import Data.Char (isSpace, isPunctuation)
 import Data.SBV.List (EnumSymbolic(..))
 import Data.SBV.SEnum (sEnum)
+import Data.SBV.SCase (sCase, pCase)
 
 import Data.SBV.Rational
 
@@ -677,7 +696,7 @@
   Goals can be lexicographically (default), independently, or pareto-front optimized. The relevant functions are:
 
       * 'minimize': Minimize a given arithmetic goal
-      * 'maximize': Minimize a given arithmetic goal
+      * 'maximize': Maximize a given arithmetic goal
 
   Goals can be optimized at a regular or an extended value: An extended value is either positive or negative infinity
   (for unbounded integers and reals) or positive or negative epsilon differential from a real value (for reals).
@@ -823,7 +842,7 @@
 overflow/underflow as it is the case with the bounded types, such as 'SWord8', 'SInt16', etc. However,
 some bit-vector based operations are /not/ supported for the 'SInteger' type while in the verification mode. That
 is, you can use these operations on 'SInteger' values during normal programming/simulation.
-but the SMT translation will not support these operations since there corresponding operations are not supported in SMT-Lib.
+but the SMT translation will not support these operations since their corresponding operations are not supported in SMT-Lib.
 Note that this should rarely be a problem in practice, as these operations are mostly meaningful on fixed-size
 bit-vectors. The operations that are restricted to bounded word/int sizes are:
 
@@ -880,10 +899,10 @@
 -}
 
 {- $partitionIntro
-The function 'allSatPartition' one to restrict the results returned by calls to 'Data.SBV.allSat'.
+The function 'allSatPartition' allows one to restrict the results returned by calls to 'Data.SBV.allSat'.
 In certain cases, we might consider certain models to be "equivalent," i.e., we might want to
 create equivalence classes over the search space when it comes to what we consider all satisfying
-solutions. In these cases, we can use 'allSatPartition' tell SBV what classes of solutions to consider
+solutions. In these cases, we can use 'allSatPartition' to tell SBV what classes of solutions to consider
 as unique. Consider:
 
 >>> :{
@@ -894,30 +913,30 @@
    allSatPartition "p2" $ y .>= 0
 :}
 Solution #1:
-  x  =     0 :: Integer
-  y  =    -1 :: Integer
-  p1 =  True :: Bool
-  p2 = False :: Bool
-Solution #2:
   x  =    -1 :: Integer
   y  =     0 :: Integer
   p1 = False :: Bool
   p2 =  True :: Bool
+Solution #2:
+  x  =    0 :: Integer
+  y  =    0 :: Integer
+  p1 = True :: Bool
+  p2 = True :: Bool
 Solution #3:
+  x  =     0 :: Integer
+  y  =    -1 :: Integer
+  p1 =  True :: Bool
+  p2 = False :: Bool
+Solution #4:
   x  =    -1 :: Integer
   y  =    -1 :: Integer
   p1 = False :: Bool
   p2 = False :: Bool
-Solution #4:
-  x  =    0 :: Integer
-  y  =    0 :: Integer
-  p1 = True :: Bool
-  p2 = True :: Bool
 Found 4 different solutions.
 
 Without the call to 'allSatPartition' the above example, 'allSat' would return all possible combinations of @x@ and @y@ subject to the constraints. (Since we have none here,
-the call would try to enumerate the infinite set of all integer tuples!) But 'allSatPartition' us to restrict our attention to the examples that satisfy the partitioning
-constraints. The first argument to 'allSatPartition' simply a name, for diagnostic purposes. Note that the conditions given by 'allSatPartition' /not/ imposed on the search
+the call would try to enumerate the infinite set of all integer tuples!) But 'allSatPartition' allows us to restrict our attention to the examples that satisfy the partitioning
+constraints. The first argument to 'allSatPartition' is simply a name, for diagnostic purposes. Note that the conditions given by 'allSatPartition' are /not/ imposed on the search
 space at all: They're only used when we construct the search space. In the above example, we pick one example from each quadrant. Furthermore, while it is typical to pass
 a boolean as a partitioning argument, it is not required: Any expression is OK, whose value creates the equivalence class:
 
@@ -953,7 +972,7 @@
       ...
 @
 
-The first constraint requires @x@ to be larger than @y@. The scond one says that
+The first constraint requires @x@ to be larger than @y@. The second one says that
 sum of @x@ and @y@ must be at least @12@, and the final one says that @y@ to be at least @3@.
 Constraints provide an easy way to assert additional properties on the input domain, right at the point of
 the introduction of variables.
@@ -1114,78 +1133,79 @@
 See 'Data.SBV.Control.getUnsatCore' for details and "Documentation.SBV.Examples.Queries.UnsatCore" for an example use case.
 -}
 
-{- $uninterpreted
+{- $symbolicADT
 Users can introduce new uninterpreted sorts simply by defining an empty data-type in Haskell and registering it as such. The
 following example demonstrates:
 
   @
      data B
-     mkUninterpretedSort ''B
+     mkSymbolic [''B]
   @
 
-(Note that you'll also need to use pragmas @TemplateHaskell@, @StandAloneDeriving@, @DeriveDataTypeable@, and @DeriveAnyClass@ for this to work, follow GHC's error messages!)
-
 This is all it takes to introduce @B@ as an uninterpreted sort in SBV, which makes the type @SBV B@ automagically become available as the type
 of symbolic values that ranges over @B@ values. Note that this will also introduce the type @SB@ into your environment, which is a synonym
 for @SBV B@.
 
-
-Uninterpreted functions over both uninterpreted and regular sorts can be declared using the facilities introduced by
-the 'Data.SBV.Core.Model.SMTDefinable' class.
--}
-
-{- $enumerations
 If the uninterpreted sort definition takes the form of an enumeration (i.e., a simple data type with all nullary constructors), then
-you can use the 'mkSymbolicEnumeration' function to turn it into an enumeration in SMTLib.
-A simple example is:
+it will turn into an enumeration in SMTLib.  A simple example is:
 
 @
-    data X = A | B | C deriving (Enum, Bounded)
-    mkSymbolicEnumeration ''X
+    data X = A | B | C
+    mkSymbolic [''X]
 @
 
-Note the magic incantation @mkSymbolicEnumeration ''X@. For this to work, you need to have the following
-options turned on:
-
->   LANGUAGE TemplateHaskell
->   LANGUAGE StandaloneDeriving
->   LANGUAGE DeriveDataTypeable
->   LANGUAGE DeriveAnyClass
->   LANGUAGE FlexibleInstances
+Note the magic incantation @mkSymbolic [''X]@, requires the following extensions:
+@TemplateHaskell@, @TypeApplications@, and @FlexibleInstances@.
+Parametric data-types also require @ScopedTypeVariables@.
 
-and your own declaration must have instances of 'Enum' and 'Bounded'. (The instances can be derived, as above.)
-This will automatically introduce the type:
+SBV also supports good old ADT's as well, with fields. The support for this is similar, where SBV will create the
+corresponding datatype in a symbolic manner:
 
 @
-    type SX = SBV X
-@
+-- | A basic arithmetic expression type.
+data Expr = Num Integer
+          | Var String
+          | Add Expr Expr
+          | Mul Expr Expr
+          | Let String Expr Expr
 
-along with symbolic values of each of the enumerated values @sA@, @sB@, and @sC@. This way,
-you can refer to the symbolic version as @SX@, treating it as a regular symbolic type ranging over the values @A@, @B@, and @C@. Such values can be compared for equality, and with the usual
-other comparison operators, such as @.==@, @./=@, @.>@, @.>=@, @<@, and @<=@. For each enumerated value @X@, the symbolic versions @sX@ is defined to be equal to @literal X@. Furthermore, the symbolic type will be an instance of 'EnumSymbolic', allowing you to use
-arithmetic progressions on symbolic values.
+-- | Create a symbolic version of expressions.
+mkSymbolic [''Expr]
+@
 
-A simple query would look like:
+These types can also be parameterized, per usual Haskell usage.
 
-@
-     allSat $ \x -> x .== (x :: SX)
-@
+For a complete example of constraining and enumerating datatype values, see
+"Documentation.SBV.Examples.ADT.Shapes".
 
-which would list all three elements of this domain as satisfying solutions.
+We also support a symbolic case-expression quasi-quoter, allowing us to write:
 
 @
-     Solution #1:
-       s0 = A :: X
-     Solution #2:
-       s0 = B :: X
-     Solution #3:
-       s0 = C :: X
-     Found 3 different solutions.
+eval :: SExpr -> SInteger
+eval = go []
+ where go :: SList (String, Integer) -> SExpr -> SInteger
+       go = smtFunction "eval"
+          $ \env expr -> [sCase| expr of
+                            Num i     -> i
+                            Var s     -> get env s
+                            Add l r   -> go env l + go env r
+                            Mul l r   -> go env l * go env r
+                            Let s e r -> go (tuple (s, go env e) SL..: env) r
+                         |]
+
+       get :: SList (String, Integer) -> SString -> SInteger
+       get = smtFunction "get"
+           $ \env s -> ite (SL.null env) 0
+                     $ let (k, v) = untuple (SL.head env)
+                       in ite (s .== k) v (get (SL.tail env) s)
 @
 
-Note that the result is properly typed as @X@ elements; these are not mere strings.
+which defines an interpreter for this data-type. Such definitions also come with an induction principle
+to perform TP based proofs on. These can be accessed using the 'Data.SBV.TP.inductiveLemma' function.
 
-See "Documentation.SBV.Examples.Misc.Enumerate" for an extended example on how to use symbolic enumerations.
+The argument to @mkSymbolic@ is typically a list of types. The requirement is that if the types you pass on
+are mutually recursively defined, you should give them as a list. Otherwise, you can give them all together,
+or one at a time.
 -}
 
 {- $cardIntro
@@ -1301,7 +1321,7 @@
 Conversions to float: 'toSFloat' and 'toSDouble' simply return the
 nearest representable float from the given type based on the rounding
 mode provided. Similarly, 'toSFloatingPoint' converts to a generalized
-floating-point number with specified exponent and significand bith widths.
+floating-point number with specified exponent and significand bit widths.
 
 Conversions from float: 'fromSFloat', 'fromSDouble', 'fromSFloatingPoint' functions do
 the reverse conversion. However some care is needed when given values
@@ -1330,7 +1350,7 @@
 same thing! Same goes for Haskell, which seems to convert via Int64, but we do
 not model that behavior in SBV as it doesn't seem to be intentional nor well documented.
 
-You can check for @NaN@, @oo@ and @-oo@, using the predicates 'fpIsNaN', 'fpIsInfinite',
+You can check for @NaN@, @oo@ and @-oo@, using the predicates 'Data.SBV.Core.Floating.fpIsNaN', 'Data.SBV.Core.Floating.fpIsInfinite',
 and 'fpIsPositive', 'fpIsNegative' predicates, respectively; and do the proper conversion
 based on your needs. (0 is a good choice, as are min/max bounds of the target type.)
 
@@ -1357,15 +1377,15 @@
 Q.E.D.
 >>> prove $ roundTrip @Int32
 Falsifiable. Counter-example:
-  s0 = RoundTowardPositive :: RoundingMode
-  s1 =          1104019333 :: Int32
+  s0 = RoundNearestTiesToEven :: RoundingMode
+  s1 =             -892327435 :: Int32
 
 Note how we get a failure on `Int32`. The counter-example value is not representable exactly as a single precision float:
 
->>> toRational (1104019333 :: Float)
-1104019328 % 1
+>>> toRational (-892327435 :: Float)
+(-892327424) % 1
 
-Note how the numerator is different, it is off by 5. This is hardly surprising, since floats become sparser as
+Note how the numerator is different, it is off by 11. This is hardly surprising, since floats become sparser as
 the magnitude increases to be able to cover all the integer values representable.
 
 >>> :{
@@ -1387,20 +1407,20 @@
 Q.E.D.
 >>> prove $ roundTrip @Int64
 Falsifiable. Counter-example:
-  s0 = RoundNearestTiesToEven :: RoundingMode
-  s1 =   -2305843042984656748 :: Int64
+  s0 =  RoundTowardPositive :: RoundingMode
+  s1 = -2370765003978487132 :: Int64
 
 Just like in the `SFloat` case, once we reach 64-bits, we no longer can exactly represent the
 integer value for all possible values:
 
->>> toRational (fromIntegral (-2305843042984656748 :: Int64) :: Double)
-(-2305843042984656896) % 1
+>>> toRational (fromIntegral (-2370765003978487132 :: Int64) :: Double)
+(-2370765003978487296) % 1
 
-In this case the numerator is off by 148.
+In this case the numerator is off by 164.
 -}
 
 -- | An implementation of rotate-left, using a barrel shifter like design. Only works when both
--- arguments are finite bitvectors, and furthermore when the second argument is unsigned.
+-- arguments are finite bit-vectors, and furthermore when the second argument is unsigned.
 -- The first condition is enforced by the type, but the second is dynamically checked.
 -- We provide this implementation as an alternative to `sRotateLeft` since SMTLib logic
 -- does not support variable argument rotates (as opposed to shifts), and thus this
@@ -1435,7 +1455,7 @@
                                       -> SBV (bv (i - j + 1))   -- ^ Output is of size @i - j + 1@
 bvExtract = CD.bvExtract
 
--- | Join two bitvectors.
+-- | Join two bit-vectors.
 --
 -- >>> prove $ \x y -> x .== bvExtract (Proxy @79) (Proxy @71) ((x :: SWord 9) # (y :: SWord 71))
 -- Q.E.D.
@@ -1733,7 +1753,7 @@
                                sa <- sbvToSV st a
                                sb <- sbvToSV st b
 
-                               newExpr st KBool $ SBVApp (Uninterpreted nm) [sa, sb]
+                               newExpr st KBool $ SBVApp (Uninterpreted (T.pack nm)) [sa, sb]
 
 -- | Check if the given relation satisfies the required axioms
 checkSpecialRelation :: forall a. SymVal a => SpecialRelOp -> Relation a -> SBool
@@ -1756,8 +1776,12 @@
                        unless (op `elem` curSpecialRels) $ do
 
                           registerKind st ka
-                          nm' <- newUninterpreted st (UIGiven nm) Nothing (SBVType [ka, ka, KBool]) (UINone True)
+                          uop <- newUninterpreted st (UIGiven nm) Nothing (SBVType [ka, ka, KBool]) (UINone True)
 
+                          let nm' = case uop of
+                                      Uninterpreted s -> T.unpack s
+                                      _               -> error $ "Data.SBV: Impossible happened: checkSpecialRelation received: " ++ show op
+
                           -- Add to the end so if we get incremental ones the order doesn't change for old ones!
                           modifyIORef' (rProgInfo st) (\u -> u{progSpecialRels = curSpecialRels ++ [iop]})
 
@@ -1838,6 +1862,6 @@
 
   create  = freshVar_
   project = getValue
-  embed   = return . literal
+  embed   = pure . literal
 
 {- HLint ignore module "Use import/export shortcut" -}
diff --git a/Data/SBV/Char.hs b/Data/SBV/Char.hs
--- a/Data/SBV/Char.hs
+++ b/Data/SBV/Char.hs
@@ -21,12 +21,10 @@
 -- we will provide full unicode versions as well.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE CPP                 #-}
-{-# LANGUAGE OverloadedLists     #-}
-{-# LANGUAGE OverloadedStrings   #-}
-{-# LANGUAGE Rank2Types          #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeApplications    #-}
+{-# LANGUAGE CPP               #-}
+{-# LANGUAGE OverloadedLists   #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TypeApplications  #-}
 
 {-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
diff --git a/Data/SBV/Client.hs b/Data/SBV/Client.hs
--- a/Data/SBV/Client.hs
+++ b/Data/SBV/Client.hs
@@ -10,54 +10,71 @@
 -----------------------------------------------------------------------------
 
 {-# LANGUAGE CPP                 #-}
+{-# LANGUAGE DeriveLift          #-}
+{-# LANGUAGE LambdaCase          #-}
 {-# LANGUAGE PackageImports      #-}
-{-# LANGUAGE QuasiQuotes         #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE StandaloneDeriving  #-}
 {-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE TupleSections       #-}
 
 #if MIN_VERSION_template_haskell(2,22,1)
-{-# OPTIONS_GHC -Wall -Werror #-}
+-- No need for newer versions of TH
 #else
-{-# LANGUAGE DeriveLift #-}
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# LANGUAGE FlexibleInstances   #-}
 #endif
 
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
+
 module Data.SBV.Client
   ( sbvCheckSolverInstallation
   , defaultSolverConfig
   , getAvailableSolvers
-  , mkSymbolicEnumeration
-  , mkUninterpretedSort
+  , mkSymbolic
+  , getConstructors
   ) where
 
-import Control.Monad (filterM)
-import Data.Generics
+import Data.SBV.Core.TH (getConstructors, bad, report)
 
-import Test.QuickCheck (Arbitrary(..), arbitraryBoundedEnum)
+import Data.Generics
 
-import qualified Data.SBV.List as SL
+import Control.Monad (filterM, mapAndUnzipM, zipWithM)
+import Data.Function (fix)
+import Test.QuickCheck (Arbitrary(..), elements)
 
 import qualified Control.Exception as C
 
+import Data.Char
+import Data.Word
+import Data.Int
+import Data.Ratio
+
 import qualified "template-haskell" Language.Haskell.TH        as TH
-#if MIN_VERSION_template_haskell(2,18,0)
 import qualified "template-haskell" Language.Haskell.TH.Syntax as TH
-#endif
 
+import Language.Haskell.TH.ExpandSyns as TH
+
+import Data.SBV.Core.Concrete (cvRank)
 import Data.SBV.Core.Data
+import Data.SBV.Core.Kind (withADTDependencies)
 import Data.SBV.Core.Model
-import Data.SBV.Core.Operations
+import Data.SBV.Core.SizedFloats
+
 import Data.SBV.Provers.Prover
+import qualified Data.SBV.List as SL
 
+import Data.List (genericLength)
+
+import Data.SBV.TP.Kernel
+
 -- | Check whether the given solver is installed and is ready to go. This call does a
 -- simple call to the solver to ensure all is well.
 sbvCheckSolverInstallation :: SMTConfig -> IO Bool
-sbvCheckSolverInstallation cfg = check `C.catch` (\(_ :: C.SomeException) -> return False)
+sbvCheckSolverInstallation cfg = check `C.catch` (\(_ :: C.SomeException) -> pure False)
   where check = do ThmResult r <- proveWith cfg $ \x -> sNot (sNot x) .== (x :: SBool)
                    case r of
-                     Unsatisfiable{} -> return True
-                     _               -> return False
+                     Unsatisfiable{} -> pure True
+                     _               -> pure False
 
 -- | The default configs corresponding to supported SMT solvers
 defaultSolverConfig :: Solver -> SMTConfig
@@ -85,159 +102,712 @@
 deriving instance TH.Lift TH.ModName
 deriving instance TH.Lift TH.NameFlavour
 deriving instance TH.Lift TH.Name
+deriving instance TH.Lift TH.Type
+deriving instance TH.Lift TH.Specificity
+deriving instance TH.Lift (TH.TyVarBndr TH.Specificity)
+deriving instance TH.Lift (TH.TyVarBndr ())
+deriving instance TH.Lift TH.TyLit
 #endif
 
--- | Turn a name into a symbolic type. If first argument is true, then we're doing an enumeration, otherwise it's an uninterpreted type
-declareSymbolic :: Bool -> TH.Name -> TH.Q [TH.Dec]
-declareSymbolic isEnum typeName = do
-    let typeCon  = TH.conT typeName
-        sTypeCon = TH.conT ''SBV `TH.appT` typeCon
+data ADTKind = ADTUninterpreted -- Completely uninterpreted
+             | ADTEnum          -- Enumeration
+             | ADTFull          -- A full datatype
 
-    cstrs <- if isEnum then ensureEnumeration typeName
-                       else ensureEmptyData   typeName
+-- | Create a mutually recursive group of ADTs.
+mkSymbolic :: [TH.Name] -> TH.Q [TH.Dec]
+mkSymbolic ts = concat <$> mapM mkSymbolicADT ts
 
-    derives <- [d| deriving instance Show     $typeCon
-                   deriving instance Read     $typeCon
-                   deriving instance Data     $typeCon
-                   deriving instance HasKind  $typeCon
-                   deriving instance SatModel $typeCon
-               |]
+-- | Create a symbolic ADT.
+mkSymbolicADT :: TH.Name -> TH.Q [TH.Dec]
+mkSymbolicADT typeName = do
 
-    symVals <- if isEnum
-                  then [d| instance SymVal $typeCon where
-                             minMaxBound = Just (minBound, maxBound)
+     (tKind, params, cstrs) <- dissect typeName
+     ds <- mkADT tKind typeName params cstrs
 
-                           instance Arbitrary $typeCon where
-                             arbitrary = arbitraryBoundedEnum
-                       |]
-                  else [d| instance SymVal $typeCon where
-                             minMaxBound = Nothing
+     -- declare an "undefiner" so we don't have stray names
+     nm <- TH.newName $ "_undefiner_" ++ TH.nameBase typeName
+     addDoc "Autogenerated definition to avoid unused-variable warnings from GHC." nm
 
-                           -- It's unfortunate we have to give this instance to make things
-                           -- simple; but uninterpreted types don't really fit with the testing strategy.
-                           instance {-# OVERLAPPABLE #-} Arbitrary $typeCon where
-                             arbitrary = error $ unlines [ ""
-                                                         , "*** Data.SBV: Cannot quickcheck the given property."
-                                                         , "***"
-                                                         , "*** Default arbitrary instance for " ++ TH.nameBase typeName ++ " is too limited."
-                                                         , "***"
-                                                         , "*** You can overcome this by giving your own Arbitrary instance."
-                                                         , "*** Please get in touch if this workaround is not suitable for your case."
-                                                         ]
-                       |]
+     -- undefiner must be careful in putting ascriptions
+     aVar <- TH.newName "a"
+     let undefine n
+           | base == "sCase" ++ tbase = wrap 1   -- Needs an extra param
+           | True                     = wrap 0
+           where tbase  = TH.nameBase typeName
+                 base   = TH.nameBase n
+                 wrap c = foldl TH.AppTypeE (TH.VarE n) (replicate (c + length params) (TH.ConT ''Integer))
 
-    symEnum <- if isEnum
-                  then [d| instance SL.EnumSymbolic $typeCon where
-                              succ     x = let elts = [minBound .. maxBound] in x `SL.lookup` literal (zip elts (drop 1 elts))
-                              pred     x = let elts = [minBound .. maxBound] in x `SL.lookup` literal (zip (drop 1 elts) elts)
+         names     = [undefine n | TH.FunD n _ <- ds]
+         body      = foldl TH.AppE (TH.VarE 'undefined)
+                                   (names ++ [TH.SigE (TH.VarE 'undefined)
+                                                      (foldl TH.AppT (TH.ConT (TH.mkName ('S' : TH.nameBase typeName)))
+                                                                     (map (const (TH.ConT ''Integer)) params))])
 
-                              toEnum   x = let elts = [minBound .. maxBound] in x `SL.lookup` literal (zip [0..] elts)
-                              fromEnum x = let elts = [minBound .. maxBound] in x `SL.lookup` literal (zip elts [0..])
+         undefSig  = TH.SigD nm (TH.ForallT [] [] (TH.VarT aVar))
+         undefBody = TH.FunD nm [TH.Clause [] (TH.NormalB body) []]
 
-                              enumFrom n = SL.map SL.toEnum (SL.enumFromTo (SL.fromEnum n) (SL.fromEnum (literal (maxBound :: $typeCon))))
+     pure $ ds ++ [undefSig, undefBody]
 
-                              enumFromThen = smtFunction ("EnumSymbolic." ++ TH.nameBase typeName ++ ".enumFromThen") $ \n1 n2 ->
-                                                         let i_n1, i_n2 :: SInteger
-                                                             i_n1 = SL.fromEnum n1
-                                                             i_n2 = SL.fromEnum n2
-                                                         in SL.map SL.toEnum (ite (i_n2 .>= i_n1)
-                                                                                  (SL.enumFromThenTo i_n1 i_n2 (SL.fromEnum (literal (maxBound :: $typeCon))))
-                                                                                  (SL.enumFromThenTo i_n1 i_n2 (SL.fromEnum (literal (minBound :: $typeCon)))))
+-- | Add document to a generated declaration for the declaration
+addDeclDocs :: (TH.Name, String) -> [(TH.Name, String)] -> TH.Q ()
+addDeclDocs (tnm, ts) cnms = do add True (tnm, ts)
+                                mapM_  (add False) cnms
+   where add True  (cnm, cs) = TH.addModFinalizer $ TH.putDoc (TH.DeclDoc cnm) $ "Symbolic version of the type t'"        ++ cs ++ "'."
+         add False (cnm, cs) = TH.addModFinalizer $ TH.putDoc (TH.DeclDoc cnm) $ "Symbolic version of the constructor v'" ++ cs ++ "'."
 
-                              enumFromTo     n m   = SL.map SL.toEnum (SL.enumFromTo     (SL.fromEnum n) (SL.fromEnum m))
+-- | Add document to a generated function
+addDoc :: String -> TH.Name -> TH.Q ()
+addDoc what tnm = TH.addModFinalizer $ TH.putDoc (TH.DeclDoc tnm) what
 
-                              enumFromThenTo n m t = SL.map SL.toEnum (SL.enumFromThenTo (SL.fromEnum n) (SL.fromEnum m) (SL.fromEnum t))
+-- | Symbolic version of a type
+mkSBV :: TH.Type -> TH.Type
+mkSBV a = TH.ConT ''SBV `TH.AppT` a
 
-                           instance OrdSymbolic $sTypeCon where
-                             SBV a .<  SBV b = SBV (a `svLessThan`    b)
-                             SBV a .<= SBV b = SBV (a `svLessEq`      b)
-                             SBV a .>  SBV b = SBV (a `svGreaterThan` b)
-                             SBV a .>= SBV b = SBV (a `svGreaterEq`   b)
-                       |]
-                  else pure []
+-- | Saturate the type with its parameters
+saturate :: TH.Type -> [TH.Name] -> TH.Type
+saturate t ps = foldr (\p b -> TH.AppT b (TH.VarT p)) t (reverse ps)
 
-    sType <- sTypeCon
+-- | Create a symbolic ADT
+mkADT ::  ADTKind                                       -- What kind of ADT are we generating?
+       -> TH.Name                                       -- type name
+       -> [TH.Name]                                     -- parameters
+       -> [(TH.Name, [(Maybe TH.Name, TH.Type, Kind)])] -- constructors
+       -> TH.Q [TH.Dec]                                 -- declarations
+mkADT adtKind typeName params cstrs = do
 
-    let declConstructor c = ((nm, bnm), [sig, def])
-          where bnm  = TH.nameBase c
-                nm   = TH.mkName $ 's' : bnm
-                def  = TH.FunD nm [TH.Clause [] (TH.NormalB body) []]
-                body = TH.AppE (TH.VarE 'literal) (TH.ConE c)
-                sig  = TH.SigD nm sType
+    let typeCon = saturate (TH.ConT typeName) params
+        sType   = mkSBV typeCon
 
-        (constrNames, cdecls) = unzip (map declConstructor cstrs)
+        inSymValContext = TH.ForallT [] [TH.AppT (TH.ConT ''SymVal) (TH.VarT n) | n <- params]
 
+        isEnum = case adtKind of
+                  ADTUninterpreted -> False
+                  ADTEnum          -> True
+                  ADTFull          -> False
+
+        -- Given Cstr f1 f2 f3, generate the clause:
+        --     inp@(Cstr [f1, f2, f3]) = case sequenceA [unlitCV (literal f1), unlitCV (literal f2), unlitCV (literal f3)] of
+        --                                 Just c  -> let k = kindOf inp
+        --                                            in SBV $ SVal k (Left (CV k (CADT (Cstr, c))))
+        --                                 Nothing -> sCstr (literal f1)
+        --
+        mkLitClause (n, fs) = do
+           as  <- mapM (const (TH.newName "a")) fs
+           inp <- TH.newName "inp"
+           c   <- TH.newName "c"
+
+           let app a b = [| $a (literal $b) |]
+
+           TH.clause [TH.asP inp (TH.conP n (map TH.varP as))]
+                     (TH.normalB
+                           (TH.caseE [| sequenceA $(TH.listE [ [| unlitCV (literal $(TH.varE a)) |] | a <- as ]) |]
+                                     [ TH.match [p|Just $(TH.varP c)|]
+                                                (TH.normalB [| let k = kindOf $(TH.varE inp)
+                                                               in SBV $ SVal k (Left (CV k (CADT (TH.nameBase n, $(TH.varE c)))))
+                                                            |])
+                                                []
+                                     , TH.match [p|Nothing|]
+                                                (TH.normalB (foldl app (TH.varE (TH.mkName ('s' : TH.nameBase n))) (map TH.varE as)))
+                                                []
+                                     ]))
+                     []
+
+    litFun <- case adtKind of
+                ADTUninterpreted -> do noLit <- [| error $ unlines [ "Data.SBV: unexpected call to derived literal implementation"
+                                                                   , "***"
+                                                                   , "*** Type: " ++ show typeName
+                                                                   , ""
+                                                                   , "***Please report this as a bug!"
+                                                                   ]
+                                                |]
+                                       pure $ TH.FunD 'literal [TH.Clause [TH.WildP] (TH.NormalB noLit) []]
+
+                ADTEnum          -> TH.FunD 'literal <$> mapM mkLitClause cstrs
+                ADTFull          -> TH.FunD 'literal <$> mapM mkLitClause cstrs
+
+    fromCVFunName <- TH.newName ("cv2" ++ TH.nameBase typeName)
+    addDoc ("Conversion from SMT values to " ++ TH.nameBase typeName ++ " values.") fromCVFunName
+
+    let fromCVSig = TH.SigD fromCVFunName
+                            (inSymValContext (foldr (TH.AppT . TH.AppT TH.ArrowT) typeCon
+                                                    [TH.ConT ''String, TH.AppT TH.ListT (TH.ConT ''CV)]))
+
+        fromCVCls :: (TH.Name, [(Maybe TH.Name, TH.Type, Kind)]) -> TH.Q TH.Clause
+        fromCVCls (nm, args) = do
+            ns <- mapM (\(i, _) -> TH.newName ("a" ++ show i)) (zip [(1::Int)..] args)
+            let pat = foldr ((\p acc -> TH.ConP '(:) [] [p, acc]) . TH.VarP) (TH.ConP '[] [] []) ns
+            pure $ TH.Clause [TH.LitP (TH.StringL (TH.nameBase nm)), pat]
+                             (TH.NormalB (foldl TH.AppE (TH.ConE nm)
+                                                        [TH.AppE (TH.VarE 'fromCV) (TH.VarE n) | n <- ns]))
+                             []
+
+    catchAll <- do s <- TH.newName "s"
+                   l <- TH.newName "l"
+                   let errStr   = TH.LitE (TH.StringL ("fromCV " ++ TH.nameBase typeName ++ ": Unexpected constructor/arity: "))
+                       tup      = TH.TupE [Just (TH.VarE s), Just (TH.AppE (TH.VarE 'length) (TH.VarE l))]
+                       showCall = TH.AppE (TH.VarE 'show) tup
+                       errMsg   = TH.InfixE (Just errStr) (TH.VarE '(++)) (Just showCall)
+                   pure $ TH.Clause [TH.VarP s, TH.VarP l] (TH.NormalB (TH.AppE (TH.VarE 'error) errMsg)) []
+
+    fromCVFun <- do clss <- mapM fromCVCls cstrs
+                    pure $ TH.FunD fromCVFunName (clss ++ [catchAll])
+
+    getFromCV <- [| let unexpected w = error $ "fromCV: " ++ show typeName ++ ": " ++ w
+                        kindName (KADT n _ _) = n
+                        kindName (KApp n _)   = n
+                        kindName k            = unexpected $ "An ADT kind was expected, but got: " ++ show k
+                    in \case CV k (CADT (c, kvs)) | kindName k == unmod typeName
+                                                 -> $(TH.varE fromCVFunName) c (map (uncurry CV) kvs)
+                             CV k e -> unexpected $ "Was expecting a CADT value, but got kind: " ++ show k ++ " (rank: " ++ show (cvRank e) ++ ")"
+                 |]
+
+    symCtx  <- TH.cxt [TH.appT (TH.conT ''SymVal) (TH.varT n) | n <- params]
+
+    mmBound <- if isEnum
+                  then let universe     = [TH.conE con | (con, _) <- cstrs]
+                           (minb, maxb) = case (universe, reverse universe) of
+                                             (x:_, y:_) -> (x, y)
+                                             _          -> error $ "Impossible: Ran out of elements in determining bounds: " ++ show cstrs
+                       in [| Just ($minb, $maxb) |]
+                  else [| Nothing |]
+
+    -- Retain declarations on the kind so literals and symbolic variables take
+    -- the same registration path, including beneath containers.
+    dependencies <- adtRegistrationTypes typeName
+
+    let symVal = TH.InstanceD
+                      Nothing
+                      symCtx
+                      (TH.AppT (TH.ConT ''SymVal) typeCon)
+                      [ litFun
+                      , TH.FunD 'minMaxBound [TH.Clause [] (TH.NormalB mmBound)   []]
+                      , TH.FunD 'fromCV      [TH.Clause [] (TH.NormalB getFromCV) []]
+                       ]
+
+    defCstrs <- [| [(unmod n, map (\(_, _, t) -> t) ntks) | (n, ntks) <- cstrs] |]
+
+    kindCtx <- TH.cxt [TH.appT (TH.conT ''HasKind) (TH.varT p) | p <- params]
+
+    let mkPair a b = TH.TupE [Just a, Just b]
+        kindDef = foldl1 TH.AppE [ TH.ConE 'KADT
+                                 , TH.LitE (TH.StringL (unmod typeName))
+                                 , TH.ListE [ mkPair (TH.LitE (TH.StringL (TH.nameBase p)))
+                                                     (TH.AppE (TH.VarE 'kindOf) (TH.AppTypeE (TH.ConE 'Proxy) (TH.VarT p)))
+                                            | p <- params
+                                            ]
+                                 , defCstrs
+                                 ]
+
+        kindDecl = TH.InstanceD
+                        Nothing
+                        kindCtx
+                        (TH.AppT (TH.ConT ''HasKind) typeCon)
+                        [TH.FunD 'kindOf [TH.Clause [TH.WildP] (TH.NormalB completeKindDef) []]]
+
+        completeKindDef = TH.AppE (TH.AppE (TH.VarE 'withADTDependencies)
+                                          (TH.ListE [TH.AppE (TH.VarE 'kindOf) (TH.AppTypeE (TH.ConE 'Proxy) t) | t <- dependencies]))
+                                 kindDef
+
+    hasArbitrary <- TH.isInstance ''Arbitrary [typeCon]
+    arbDecl <- case () of
+                () | hasArbitrary -> pure []
+                   | isEnum       -> let universe  = TH.listE [TH.conE con | (con, _) <- cstrs]
+                                     in [d|instance Arbitrary $(pure typeCon) where
+                                             arbitrary = elements $universe
+                                        |]
+                   | True         -> [d|instance {-# OVERLAPPABLE #-} Arbitrary $(pure typeCon) where
+                                          arbitrary = error $ unlines [ ""
+                                                                      , "*** Data.SBV: Cannot quickcheck the given property."
+                                                                      , "***"
+                                                                      , "*** Default arbitrary instance for " ++ TH.nameBase typeName ++ " is too limited."
+                                                                      , "***"
+                                                                      , "*** You can overcome this by giving your own Arbitrary instance."
+                                                                      , "*** Please get in touch if this workaround is not suitable for your case."
+                                                                      ]
+                                    |]
+
+    -- Declare constructors
+    let declConstructor :: (TH.Name, [(Maybe TH.Name, TH.Type, Kind)]) -> TH.Q ((TH.Name, String), [TH.Dec])
+        declConstructor (n, ntks) = do
+            let ats = map (mkSBV . (\(_, t, _) -> t)) ntks
+                ty  = inSymValContext $ foldr (TH.AppT . TH.AppT TH.ArrowT) sType ats
+                bnm = TH.nameBase n
+                nm  = TH.mkName $ 's' : bnm
+
+            as    <- mapM (const (TH.newName "a")) ntks
+            c     <- TH.newName "c"
+
+            cls <- TH.clause (map TH.varP as)
+                             (TH.normalB
+                                   (TH.caseE [| sequenceA $(TH.listE [ [| unlitCV $(TH.varE a) |] | a <- as ]) |]
+                                             [ TH.match [p|Just $(TH.varP c)|]
+                                                        -- We need the kind of the result type to build the value, but the
+                                                        -- result type can only be recovered from the (signature-pinned) result
+                                                        -- itself: a parametric type may carry the parameter in a phantom
+                                                        -- position (e.g. the @a@ in @Right :: b -> Either a b@) that no argument
+                                                        -- mentions. We tie the kind to the result via 'fix'. Crucially, 'fix'
+                                                        -- binds @res@ as a /lambda-bound/ variable, which is always monomorphic;
+                                                        -- a plain @let@ group would be generalized when the monomorphism
+                                                        -- restriction is off (as it is at the GHCi prompt), yielding a spurious
+                                                        -- ambiguous @HasKind@. ('kindOf' ignores its argument, so 'fix' is safe.)
+                                                        (TH.normalB [| fix (\res -> let k = kindOf res
+                                                                                    in SBV $ SVal k (Left (CV k (CADT (bnm, $(TH.varE c)))))) |])
+                                                        []
+                                             , TH.match [p|Nothing|]
+                                                        (TH.normalB (foldl (\a b -> [| $a $b |]) [| mkADTConstructor bnm |] (map TH.varE as)))
+                                                        []
+                                             ]))
+                             []
+
+            pure ((nm, bnm), [TH.SigD nm ty, TH.FunD nm [cls]])
+
+    (constrNames, cdecls) <- mapAndUnzipM declConstructor cstrs
+
     let btname = TH.nameBase typeName
         tname  = TH.mkName ('S' : btname)
-        tdecl  = TH.TySynD tname [] sType
+        tdecl  = TH.TySynD tname [TH.PlainTV p TH.BndrReq | p <- params] sType
 
-    addDocs (tname, btname) constrNames
+    addDeclDocs (tname, btname) constrNames
 
-    pure $ derives ++ symVals ++ symEnum ++ [tdecl] ++ concat cdecls
+    -- Declare accessors
+    let -- NB. field count starts at 1!
+        declAccessor :: TH.Name -> (Maybe TH.Name, TH.Type, Kind) -> Int -> TH.Q [((TH.Name, String), [TH.Dec])]
+        declAccessor c (mbUN, ft, _) i = do
+                let bnm  = TH.nameBase c
+                    anm  = "get" ++ bnm ++ "_" ++ show i
+                    nm   = TH.mkName anm
+                    ty    = inSymValContext $ TH.AppT (TH.AppT TH.ArrowT sType) (mkSBV ft)
 
- where addDocs :: (TH.Name, String) -> [(TH.Name, String)] -> TH.Q ()
-#if MIN_VERSION_template_haskell(2,18,0)
-       addDocs (tnm, ts) cnms = do addDoc True (tnm, ts)
-                                   mapM_  (addDoc False) cnms
-          where addDoc True  (cnm, cs) = TH.addModFinalizer $ TH.putDoc (TH.DeclDoc cnm) $ "Symbolic version of the type '"        ++ cs ++ "'."
-                addDoc False (cnm, cs) = TH.addModFinalizer $ TH.putDoc (TH.DeclDoc cnm) $ "Symbolic version of the constructor '" ++ cs ++ "'."
-#else
-       addDocs _ _ = pure ()
-#endif
+                cls <- do inp <- TH.newName "inp"
+                          TH.clause [TH.varP inp]
+                                    (TH.normalB
+                                          (TH.caseE [| unlitCV $(TH.varE inp) |]
+                                                    [ TH.match [p|Just (_, CADT (got, kv))|]
+                                                               (TH.guardedB [do g <- TH.normalG [| got == bnm |]
+                                                                                e <- [| let (k, v) = (kv !! (i-1))
+                                                                                        in SBV $ SVal k (Left (CV k v))
+                                                                                     |]
+                                                                                pure (g, e)
+                                                                            ])
+                                                               []
+                                                    , TH.match [p|_|]
+                                                               (TH.normalB [| mkADTAccessor anm $(TH.varE inp) |])
+                                                               []
+                                                    ]))
+                                    []
 
--- | Make an enumeration a symbolic type.
-mkSymbolicEnumeration :: TH.Name -> TH.Q [TH.Dec]
-mkSymbolicEnumeration = declareSymbolic True
+                -- If there's a custom accessor given, declare that here too
+                extras <- case mbUN of
+                            Nothing -> pure []
+                            Just un -> do let sun = TH.mkName $ 's' : TH.nameBase un
+                                          pure [((sun, bnm), [TH.SigD sun ty, TH.FunD sun [cls]])]
 
--- | Make an uninterpred sort.
-mkUninterpretedSort :: TH.Name -> TH.Q [TH.Dec]
-mkUninterpretedSort = declareSymbolic False
+                pure $ ((nm, bnm), [TH.SigD nm ty, TH.FunD nm [cls]]) : extras
 
--- | Make sure the given type is an enumeration
-ensureEnumeration :: TH.Name -> TH.Q [TH.Name]
-ensureEnumeration nm = do
-        c <- TH.reify nm
-        case c of
-          TH.TyConI d -> case d of
-                           TH.DataD _ _ _ _ cons _ -> case cons of
-                                                        [] -> bad "The datatype given has no constructors."
-                                                        xs -> concat <$> mapM check xs
-                           _                       -> bad "The name given is not a datatype."
+    allDefs <- sequence [zipWithM (declAccessor c) fs [(1::Int) ..] | (c, fs) <- cstrs]
+    let (accessorNames, accessorDecls) = unzip $ concat (concat allDefs)
 
-          _        -> bad "The name given is not a datatype."
- where n = TH.nameBase nm
+    mapM_ (addDoc "Field accessor function." . fst) accessorNames
 
-       check (TH.NormalC c xs) = case xs of
-                                   [] -> pure [c]
-                                   _  -> bad $ "Constructor " ++ show c ++ " has arguments."
+    testerDecls <- mkTesters sType inSymValContext cstrs
 
-       check c                 = bad $ "Constructor " ++ show c ++ " is not an enumeration value."
+    -- Get the case analyzer
+    caseSigFuns <- mkCaseAnalyzer adtKind typeName params cstrs
 
-       bad m = do TH.reportError $ unlines [ "Data.SBV.mkSymbolicEnumeration: Invalid argument " ++ show n
-                                           , ""
-                                           , "    Expected an enumeration. " ++ m
-                                           , ""
-                                           , "    To create an enumerated sort, use a simple Haskell enumerated type."
-                                           ]
-                  pure []
+    -- Get the induction schema, upto 5 extra args. Only for enums and adts
+    indDecs <- do let schemas = mapM (mkInductionSchema typeName params cstrs) [0 .. 5]
+                  case adtKind of
+                    ADTUninterpreted -> pure []
+                    ADTEnum          -> schemas
+                    ADTFull          -> schemas
 
--- | Make sure the given type is an empty data
-ensureEmptyData :: TH.Name -> TH.Q [TH.Name]
-ensureEmptyData nm = do
-        c <- TH.reify nm
-        case c of
-          TH.TyConI d -> case d of
-                           TH.DataD _ _ _ _ cons _ -> case cons of
-                                                        [] -> pure []
-                                                        _  -> bad "The datatype given has constructors."
-                           _                       -> bad "The name given is not a datatype."
+    -- If this is an enumeration get EnumSymbolic and OrSymbolic instances
+    symEnum <- case adtKind of
+                ADTUninterpreted -> pure []
+                ADTFull          -> pure []
+                ADTEnum          ->
+                  let universe  = TH.listE [TH.conE                          con   | (con, _) <- cstrs]
+                      universeS = TH.listE [TH.litE (TH.stringL (TH.nameBase con)) | (con, _) <- cstrs]
+                  in [d| instance SatModel $(TH.conT typeName) where
+                           parseCVs (CV _ (CADT (s, [])) : r)
+                             | Just v <- s `lookup` zip $universeS $universe
+                             = Just (v, r)
+                           parseCVs _ = Nothing
 
-          _        -> bad "The name given is not a datatype."
- where n = TH.nameBase nm
-       bad m = do TH.reportError $ unlines [ "Data.SBV.mkUninterpretedSort: Invalid argument " ++ show n
-                                           , ""
-                                           , "    Expected an empty datatype. " ++ m
-                                           , ""
-                                           , "    To create an uninterpreted sort, use an empty datatype declaration."
-                                           ]
-                  pure []
+                         instance SL.EnumSymbolic $(TH.conT typeName) where
+                           succ x = go (zip $universe (drop 1 $universe))
+                             where go []              = some ("succ_" ++ show typeName ++ "_maximal") (const sTrue)
+                                   go ((c, s) : rest) = ite (x .== literal c) (literal s) (go rest)
+
+                           pred x = go (zip (drop 1 $universe) $universe)
+                             where go []              = some ("pred_" ++ show typeName ++ "_minimal") (const sTrue)
+                                   go ((c, s) : rest) = ite (x .== literal c) (literal s) (go rest)
+
+                           toEnum x = go (zip $universe [0..])
+                             where go []              = some ("toEnum_" ++ show typeName ++ "_out_of_range") (const sTrue)
+                                   go ((c, i) : rest) = ite (x .== literal i) (literal c) (go rest)
+
+                           fromEnum x = go 0 $universe
+                             where go _ []     = error "fromEnum: Impossible happened, ran out of elements."
+                                   go i [_]    = i
+                                   go i (c:cs) = ite (x .== literal c) i (go (i+1) cs)
+
+                           enumFrom n = SL.map SL.toEnum (SL.enumFromTo (SL.fromEnum n) (genericLength $universe - 1))
+
+                           enumFromThen = smtFunction ("EnumSymbolic." ++ TH.nameBase typeName ++ ".enumFromThen") $ \n1 n2 ->
+                                                      let i_n1, i_n2 :: SInteger
+                                                          i_n1 = SL.fromEnum n1
+                                                          i_n2 = SL.fromEnum n2
+                                                      in SL.map SL.toEnum (ite (i_n2 .>= i_n1)
+                                                                               (SL.enumFromThenTo i_n1 i_n2 (genericLength $universe - 1))
+                                                                               (SL.enumFromThenTo i_n1 i_n2 0))
+
+                           enumFromTo     n m   = SL.map SL.toEnum (SL.enumFromTo     (SL.fromEnum n) (SL.fromEnum m))
+
+                           enumFromThenTo n m t = SL.map SL.toEnum (SL.enumFromThenTo (SL.fromEnum n) (SL.fromEnum m) (SL.fromEnum t))
+
+                         instance OrdSymbolic (SBV $(TH.conT typeName)) where
+                           a .<  b = SL.fromEnum a .<  SL.fromEnum b
+                           a .<= b = SL.fromEnum a .<= SL.fromEnum b
+                           a .>  b = SL.fromEnum a .>  SL.fromEnum b
+                           a .>= b = SL.fromEnum a .>= SL.fromEnum b
+                     |]
+
+    pure $  [tdecl, symVal, kindDecl]
+         ++ arbDecl
+         ++ concat cdecls
+         ++ testerDecls
+         ++ concat accessorDecls
+         ++ symEnum
+         ++ [fromCVSig, fromCVFun]
+         ++ caseSigFuns
+         ++ concat indDecs
+
+-- | Make a case analyzer for the type. Works for ADTs and enums. Returns sig and defn
+mkCaseAnalyzer :: ADTKind -> TH.Name -> [TH.Name] -> [(TH.Name, [(Maybe TH.Name, TH.Type, Kind)])] -> TH.Q [TH.Dec]
+mkCaseAnalyzer kind typeName params cstrs = case kind of
+                                              ADTUninterpreted -> pure [] -- no case analyzer for fully uninterpreted types
+                                              ADTEnum          -> mk
+                                              ADTFull          -> mk
+  where mk = do let typeCon = saturate (TH.ConT typeName) params
+                    sType   = mkSBV typeCon
+
+                    bnm = TH.nameBase typeName
+                    cnm = TH.mkName $ "sCase" ++ bnm
+
+                se   <- TH.newName ('s' : bnm)
+                fs   <- mapM (\(nm, _) -> TH.newName ('f' : TH.nameBase nm)) cstrs
+                res  <- TH.newName "result"
+
+                let def = TH.FunD cnm [TH.Clause (map TH.VarP (fs ++ [se])) (TH.NormalB (iteChain (zipWith (mkCase se) fs cstrs))) []]
+
+                    iteChain :: [(TH.Exp, TH.Exp)] -> TH.Exp
+                    iteChain []       = error $ unlines [ "Data.SBV.mkADT: Impossible happened!"
+                                                        , ""
+                                                        , "   Received an empty list for: " ++ show typeName
+                                                        , ""
+                                                        , "While building the case-analyzer."
+                                                        , "Please report this as a bug."
+                                                        ]
+                    iteChain [(_, l)]        = l
+                    iteChain ((t, e) : rest) = foldl TH.AppE (TH.VarE 'ite) [TH.AppE t (TH.VarE se), e, iteChain rest]
+
+                    mkCase :: TH.Name -> TH.Name -> (TH.Name, [(Maybe TH.Name, TH.Type, Kind)]) -> (TH.Exp, TH.Exp)
+                    mkCase cexpr func (c, fields) = (TH.VarE (TH.mkName ("is" ++ TH.nameBase c)), foldl TH.AppE (TH.VarE func) args)
+                       where getters = [TH.mkName ("get" ++ TH.nameBase c ++ "_" ++ show i) | (i, _) <- zip [(1 :: Int) ..] fields]
+                             args    = map (\g -> TH.AppE (TH.VarE g) (TH.VarE cexpr)) getters
+
+                    rvar   = TH.VarT res
+                    mkFun  = foldr (TH.AppT . TH.AppT TH.ArrowT) rvar
+                    fTypes = [mkFun (map (mkSBV . (\(_, t, _) -> t)) ftks) | (_, ftks) <- cstrs]
+                    sig    = TH.SigD cnm (TH.ForallT []
+                                                     (TH.AppT (TH.ConT ''Mergeable) (TH.VarT res)
+                                                     : [TH.AppT (TH.ConT ''SymVal) (TH.VarT p) | p <- params]
+                                                     )
+                                                     (mkFun (fTypes ++ [sType])))
+
+                addDoc ("Case analyzer for the type " ++ bnm ++ ".") cnm
+                pure [sig, def]
+
+-- | Declare testers
+mkTesters :: TH.Type -> (TH.Type -> TH.Type) -> [(TH.Name, [(Maybe TH.Name, TH.Type, Kind)])] -> TH.Q [TH.Dec]
+mkTesters sType inSymValContext cstrs = do
+    let declTester :: (TH.Name, [(Maybe TH.Name, TH.Type, Kind)]) -> TH.Q ((TH.Name, String), [TH.Dec])
+        declTester (c, _) = do
+             let ty  = inSymValContext $ TH.AppT (TH.AppT TH.ArrowT sType) (TH.ConT ''SBool)
+                 bnm = TH.nameBase c
+                 nm  = TH.mkName $ "is" ++ bnm
+
+             inp <- TH.newName "inp"
+             cls <- TH.clause [TH.varP inp]
+                              (TH.normalB
+                                    (TH.caseE [| unlitCV $(TH.varE inp) |]
+                                              [ TH.match [p|Just (_, CADT (got, _))|]
+                                                         (TH.normalB [| literal (got == bnm) |])
+                                                         []
+                                              , TH.match [p|Nothing|]
+                                                         (TH.normalB [| mkADTTester ("is-" ++ bnm) $(TH.varE inp) |])
+                                                         []
+                                              ]))
+                              []
+             pure ((nm, bnm), [TH.SigD nm ty, TH.FunD nm [cls]])
+
+    (testerNames, testerDecls) <- mapAndUnzipM declTester cstrs
+
+    mapM_ (addDoc "Field recognizer predicate." . fst) testerNames
+
+    pure $ concat testerDecls
+
+-- We'll just drop the modules to keep this simple
+-- If you use multiple expressions named the same (coming from different modules), oh well.
+unmod :: TH.Name -> String
+unmod = reverse . takeWhile (/= '.') . reverse . show
+
+-- | Given a type name, determine what kind of a data-type it is.
+dissect :: TH.Name -> TH.Q (ADTKind, [TH.Name], [(TH.Name, [(Maybe TH.Name, TH.Type, Kind)])])
+dissect typeName = do
+        (args, tcs) <- getConstructors typeName
+
+        let mk n (mbfn, t) = do k <- expandSyns t >>= toSBV typeName n
+                                pure (mbfn, t, k)
+
+        cs <- mapM (\(n, ts) -> (n,) <$> mapM (mk n) ts) tcs
+
+        let k | null cs             = ADTUninterpreted
+              | all (null . snd) cs = ADTEnum
+              | True                = ADTFull
+
+        pure (k, args, cs)
+
+-- | Find all ADT definitions needed by a generated kind, including
+-- references nested in containers and dependencies of those references. Visit each
+-- type constructor once so recursive and mutually recursive declarations terminate.
+-- Registration needs only the datatype schema: replace free type variables with
+-- Integer, retaining concrete arguments and the declaration's own type variables.
+adtRegistrationTypes :: TH.Name -> TH.Q [TH.Type]
+adtRegistrationTypes root = dependencies root >>= collect [root]
+ where collect _    [] = pure []
+       collect seen ((nm, ty) : pending)
+         | nm `elem` seen = collect seen pending
+         | True = do nested <- dependencies nm
+                     rest   <- collect (nm : seen) (pending ++ nested)
+                     pure (concretize ty : rest)
+
+       -- Integer is only a registration placeholder used to obtain a schema,
+       -- not the program's instantiation; actual type arguments are substituted
+       -- separately when the schema is used.
+       concretize TH.VarT{}       = TH.ConT ''Integer
+       concretize (TH.AppT l arg) = TH.AppT (concretize l) (concretize arg)
+       concretize ty              = ty
+
+       dependencies nm = do (_, _, constructors) <- dissect nm
+                            concat <$> sequence [field nm constructor ty | (constructor, fields) <- constructors, (_, ty, _) <- fields]
+
+       field owner constructor original = do
+         ty   <- expandSyns original
+         kind <- toSBV owner constructor ty
+         let (headType, arguments) = applications ty []
+             nested = concat <$> mapM (field owner constructor) arguments
+         case kind of
+           KApp{} | TH.ConT nm <- headType -> ((nm, ty) :) <$> nested
+           KTuple{} -> nested
+           KList{}  -> nested
+           KSet{}   -> nested
+           KArray{} -> nested
+           _        -> pure []
+
+       applications (TH.AppT fun arg) arguments = applications fun (arg : arguments)
+       applications fun               arguments = (fun, arguments)
+
+-- | Find the SBV kind for this type
+toSBV :: TH.Name -> TH.Name -> TH.Type -> TH.Q Kind
+toSBV typeName constructorName = go
+  where hasArrows (TH.AppT TH.ArrowT _)   = True
+        hasArrows (TH.AppT lhs       rhs) = hasArrows lhs || hasArrows rhs
+        hasArrows _                       = False
+
+        -- Handle type variables (parameters)
+        go (TH.VarT v) = pure $ KVar (TH.nameBase v)
+
+        -- tuples
+        go t | Just ps <- getTuple t = KTuple <$> mapM go ps
+
+        -- recognize strings, since we don't (yet) support chars
+        go (TH.AppT TH.ListT (TH.ConT t)) | t == ''Char = pure KString
+
+        -- lists
+        go (TH.AppT TH.ListT t) = KList <$> go t
+
+        -- arbitrary words/ints
+        go (TH.AppT (TH.ConT nm) (TH.LitT (TH.NumTyLit n)))
+            | nm == ''WordN = pure $ KBounded False (fromIntegral n)
+            | nm == ''IntN  = pure $ KBounded True  (fromIntegral n)
+
+        -- arbitrary floats
+        go (TH.AppT (TH.AppT (TH.ConT nm) (TH.LitT (TH.NumTyLit eb))) (TH.LitT (TH.NumTyLit sb)))
+            | nm == ''FloatingPoint = pure $ KFP (fromIntegral eb) (fromIntegral sb)
+
+        -- Rational
+        go (TH.AppT (TH.ConT nm) (TH.ConT i))
+            | nm == ''Ratio && i == ''Integer
+            = pure KRational
+
+        -- sets
+        go (TH.AppT (TH.ConT nm) t)
+            | nm == ''RCSet = KSet <$> go t
+
+        -- arrays
+        go (TH.AppT (TH.AppT (TH.ConT nm) t1) t2)
+            | nm == ''ArrayModel = KArray <$> go t1 <*> go t2
+
+        -- deal with base types
+        go t@(TH.ConT constr)
+            | Just base <- getBase constr
+            = case base of
+                Left (w, r) -> bad w $ [ "Datatype   : " ++ show typeName
+                                       , "Constructor: " ++ show constructorName
+                                       , "Kind       : " ++ TH.pprint t
+                                       , ""
+                                       ] ++ r
+                Right k     -> pure k
+
+        -- deal with constructors
+        go t
+           | Just (c, ps) <- getConApp t
+           = KApp (TH.nameBase c) <$> mapM go ps
+
+        -- giving up
+        go t = bad "Unsupported constructor kind" [ "Datatype   : " ++ TH.nameBase typeName
+                                                  , "Constructor: " ++ TH.nameBase constructorName
+                                                  , "Kind       : " ++ TH.pprint t
+                                                  , ""
+                                                  , if hasArrows t
+                                                    then "Higher order fields (i.e., function values) are not supported."
+                                                    else report
+                                                  ]
+
+        -- Extract application of a constructor to some type-variables
+        getConApp t = locate t []
+          where locate (TH.ConT c)     sofar = Just (c, sofar)
+                locate (TH.AppT l arg) sofar = locate l (arg : sofar)
+                locate _               _     = Nothing
+
+        -- Extract an N-tuple
+        getTuple = tup []
+          where tup sofar (TH.TupleT _) = Just sofar
+                tup sofar (TH.AppT t p) = tup (p : sofar) t
+                tup _     _             = Nothing
+
+        -- Given the name of a base type, what's the equivalent in the SBV domain (if we have it)
+        getBase :: TH.Name -> Maybe (Either (String, [String]) Kind)
+        getBase t
+          | t == ''Bool     = Just $ Right KBool
+          | t == ''Integer  = Just $ Right KUnbounded
+          | t == ''Float    = Just $ Right KFloat
+          | t == ''Double   = Just $ Right KDouble
+          | t == ''Char     = Just $ Right KChar
+          | t == ''String   = Just $ Right KString
+          | t == ''AlgReal  = Just $ Right KReal
+          | t == ''Rational = Just $ Right KRational
+          | t == ''Word8    = Just $ Right $ KBounded False  8
+          | t == ''Word16   = Just $ Right $ KBounded False 16
+          | t == ''Word32   = Just $ Right $ KBounded False 32
+          | t == ''Word64   = Just $ Right $ KBounded False 64
+          | t == ''Int8     = Just $ Right $ KBounded True   8
+          | t == ''Int16    = Just $ Right $ KBounded True  16
+          | t == ''Int32    = Just $ Right $ KBounded True  32
+          | t == ''Int64    = Just $ Right $ KBounded True  64
+
+          -- Platform specific, flag:
+          |    t == ''Int
+            || t == ''Word  = Just $ Left ( "Platform specific type: " ++ show t
+                                          , [ "Please pick a more specific type, such as"
+                                            , "Integer, Word8, WordN 32, IntN 16 etc."
+                                            ])
+
+          -- Otherwise, can't translate
+          | True            = Nothing
+
+-- | Make an induction schema for the type, with n extra arguments.
+mkInductionSchema :: TH.Name -> [TH.Name] -> [(TH.Name, [(Maybe TH.Name, TH.Type, Kind)])] -> Int -> TH.Q [TH.Dec]
+mkInductionSchema typeName params cstrs extraArgCnt = do
+   let btype = TH.nameBase typeName
+       nm    = "induct" ++ btype ++ if extraArgCnt == 0 then "" else show extraArgCnt
+
+   pf <- TH.newName "pf"
+
+   extraNames <- mapM (const (TH.newName "extraN")) [0 .. extraArgCnt-1]
+   extraSyms  <- mapM (const (TH.newName "extraS")) [0 .. extraArgCnt-1]
+   extraTypes <- mapM (const (TH.newName "extraT")) [0 .. extraArgCnt-1]
+
+   let mkLam = TH.lamE . map (\a -> TH.conP 'Forall [TH.varP a])
+
+   let mkIndCase :: (TH.Name, [(Maybe TH.Name, TH.Type, Kind)]) -> TH.Q TH.Exp
+       mkIndCase (cstr, flds)
+         | null flds && null extraNames
+         = [| $(TH.varE pf) $(scstr) |]
+         | True
+         = do as <- mapM (const (TH.newName "a")) flds
+              let -- When can we have the inductive hypothesis?
+                  --  (1) same type
+                  --  (2) applied at exactly the same types
+                  isRecursive (_, _, k) = case k of
+                                            KApp t ps -> t == btype && ps == map (KVar . TH.nameBase) params
+                                            _         -> False
+                  recFields = [a | (a, f) <- zip as flds, isRecursive f]
+
+              TH.appE (TH.varE 'quantifiedBool)
+                      (mkLam (as ++ extraNames)
+                             (mkImp recFields (foldl TH.appE
+                                                     (TH.appE (TH.varE pf) (foldl TH.appE scstr (map TH.varE as)))
+                                                     (map TH.varE extraNames))))
+         where cnm   = TH.nameBase cstr
+               lcnm  = map toLower cnm
+               scstr = TH.varE (TH.mkName ('s' : cnm))
+
+               mkImp []  e = e
+               mkImp [i] e = foldl1 TH.appE [TH.varE '(.=>), assume i, e]
+               mkImp is  e = foldl1 TH.appE [TH.varE '(.=>), foldl1 TH.appE [TH.varE 'sAnd, TH.listE (map assume is)], e]
+
+               assume :: TH.Name -> TH.Q TH.Exp
+               assume n = do en <- mapM (const (TH.newName (lcnm ++ "_extraN"))) [0 .. extraArgCnt-1]
+                             TH.appE (TH.varE 'quantifiedBool)
+                                     (mkLam en (foldl TH.appE (TH.varE pf) (map TH.varE (n : en))))
+
+   cases <- mapM mkIndCase cstrs
+   post  <- do a <- TH.newName "recVal"
+               TH.appE (TH.varE 'quantifiedBool)
+                       (mkLam (a : extraNames) $ foldl TH.appE (TH.varE pf) (map TH.varE (a : extraNames)))
+
+   propName <- TH.newName "prop"
+   argName  <- TH.newName "a"
+   taName   <- TH.newName "ta"
+
+   let pre    = foldl1 TH.AppE [TH.VarE 'sAnd,  TH.ListE cases]
+       schema = foldl1 TH.AppE [TH.VarE '(.=>), pre, post]
+       ihB    = TH.AppE (TH.VarE 'proofOf) (foldl1 TH.AppE [TH.VarE 'internalAxiom, TH.LitE (TH.StringL nm), schema])
+
+       instHead = TH.AppT (TH.ConT ''HasInductionSchema)
+                          (foldr (TH.AppT . TH.AppT TH.ArrowT)
+                                 (TH.ConT ''SBool)
+                                 [  TH.AppT (TH.ConT ''Forall) (TH.VarT es) `TH.AppT` et
+                                  | (es, et) <- zip (taName : extraSyms)
+                                                    (saturate (TH.ConT typeName) params : map TH.VarT extraTypes)
+                                 ])
+
+       pfFun = TH.FunD pf [TH.Clause (map TH.VarP (argName : extraNames))
+                                     (TH.NormalB (foldl TH.AppE
+                                                        (TH.VarE propName)
+                                                        [TH.AppE (TH.ConE 'Forall) (TH.VarE a) | a <- argName : extraNames]))
+                                     []
+                          ]
+
+       method = TH.FunD 'inductionSchema
+                        [TH.Clause [TH.VarP propName]
+                                   (TH.NormalB (TH.LetE [pfFun] ihB))
+                                   []
+                        ]
+
+   context <- TH.cxt [TH.appT (TH.conT ''SymVal) (TH.varT n) | n <- params ++ extraTypes]
+
+   pure [TH.InstanceD Nothing context instHead [method]]
diff --git a/Data/SBV/Client/BaseIO.hs b/Data/SBV/Client/BaseIO.hs
--- a/Data/SBV/Client/BaseIO.hs
+++ b/Data/SBV/Client/BaseIO.hs
@@ -23,7 +23,7 @@
                                 SFPHalf, SFPBFloat, SFPSingle, SFPDouble, SFPQuad, SFloatingPoint,
                                 SInt8, SInt16, SInt32, SInt64, SInteger, SList,
                                 SReal, SString, SV, SWord8, SWord16, SWord32,
-                                SWord64, SEither, SRational, SMaybe, SSet, SArray, constrain, (.==))
+                                SWord64, SRational, SSet, SArray, constrain, (.==))
 import Data.SBV.Core.Kind      (BVIsNonZero, ValidFloat)
 import Data.SBV.Core.Model     (Metric(..), SymTuple)
 import Data.SBV.Core.Symbolic  (Objective, OptimizeStyle, Result, VarContext, Symbolic, SBVRunMode, SMTConfig,
@@ -34,7 +34,7 @@
 
 import GHC.TypeLits (KnownNat)
 
-import Data.IORef(readIORef, writeIORef)
+import Data.IORef(readIORef, modifyIORef')
 
 import qualified Data.SBV.Core.Data      as Trans
 import qualified Data.SBV.Core.Model     as Trans
@@ -224,7 +224,7 @@
                         let new = case filter (`notElem` olds) (nm : [nm ++ "_" ++ show i | i <- [(1 :: Int) ..]]) of
                                     h:_ -> h
                                     []  -> error $ "Impossible: Can't get a fresh variable from infinite list in partition." ++ show (nm, term)
-                        writeIORef rPartitionVars (olds ++ [new])
+                        modifyIORef' rPartitionVars (++ [new])
                         pure new
 
    -- declare and constrain
@@ -725,24 +725,6 @@
 sTuples :: (SymTuple tup, SymVal tup) => [String] -> Symbolic [SBV tup]
 sTuples = Trans.sTuples
 
--- | Declare a named 'Data.SBV.SEither'.
---
--- NB. For a version which generalizes over the underlying monad, see 'Data.SBV.Trans.sEither'
-sEither :: (SymVal a, SymVal b) => String -> Symbolic (SEither a b)
-sEither = Trans.sEither
-
--- | Declare an unnamed 'Data.SBV.SEither'.
---
--- NB. For a version which generalizes over the underlying monad, see 'Data.SBV.Trans.sEither_'
-sEither_ :: (SymVal a, SymVal b) => Symbolic (SEither a b)
-sEither_ = Trans.sEither_
-
--- | Declare a list of 'Data.SBV.SEither' values.
---
--- NB. For a version which generalizes over the underlying monad, see 'Data.SBV.Trans.sEithers'
-sEithers :: (SymVal a, SymVal b) => [String] -> Symbolic [SEither a b]
-sEithers = Trans.sEithers
-
 -- | Declare a named 'Data.SBV.SRational'.
 --
 -- NB. For a version which generalizes over the underlying monad, see 'Data.SBV.Trans.sRational'
@@ -760,24 +742,6 @@
 -- NB. For a version which generalizes over the underlying monad, see 'Data.SBV.Trans.sRationals'
 sRationals :: [String] -> Symbolic [SRational]
 sRationals = Trans.sRationals
-
--- | Declare a named 'Data.SBV.SMaybe'.
---
--- NB. For a version which generalizes over the underlying monad, see 'Data.SBV.Trans.sMaybe'
-sMaybe :: SymVal a => String -> Symbolic (SMaybe a)
-sMaybe = Trans.sMaybe
-
--- | Declare an unnamed 'Data.SBV.SMaybe'.
---
--- NB. For a version which generalizes over the underlying monad, see 'Data.SBV.Trans.sMaybe_'
-sMaybe_ :: SymVal a => Symbolic (SMaybe a)
-sMaybe_ = Trans.sMaybe_
-
--- | Declare a list of 'Data.SBV.SMaybe' values.
---
--- NB. For a version which generalizes over the underlying monad, see 'Data.SBV.Trans.sMaybes'
-sMaybes :: SymVal a => [String] -> Symbolic [SMaybe a]
-sMaybes = Trans.sMaybes
 
 -- | Declare a named 'Data.SBV.SSet'.
 --
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
@@ -6,1083 +6,64 @@
 -- Maintainer: erkokl@gmail.com
 -- Stability : experimental
 --
--- Compilation of symbolic programs to C
------------------------------------------------------------------------------
-
-{-# LANGUAGE CPP           #-}
-{-# LANGUAGE PatternGuards #-}
-{-# LANGUAGE TupleSections #-}
-
-{-# OPTIONS_GHC -Wall -Werror -Wno-incomplete-uni-patterns #-}
-
-module Data.SBV.Compilers.C(compileToC, compileToCLib, compileToC', compileToCLib') where
-
-import Control.DeepSeq                (rnf)
-import Data.Char                      (isSpace)
-import Data.List                      (nub, intercalate, intersperse)
-import Data.Maybe                     (isJust, isNothing, fromJust)
-import qualified Data.Foldable as F   (toList)
-import qualified Data.Set      as Set (member, union, unions, empty, toList, singleton, fromList)
-import System.FilePath                (takeBaseName, replaceExtension)
-import System.Random
-
-import Data.SBV.Core.Symbolic (ResultInp(..), ProgInfo(..))
-
--- Work around the fact that GHC 8.4.1 started exporting <>.. Hmm..
-import Text.PrettyPrint.HughesPJ
-import qualified Text.PrettyPrint.HughesPJ as P ((<>))
-
-import Data.SBV.Core.Data
-import Data.SBV.Compilers.CodeGen
-
-import Data.SBV.Utils.PrettyNum   (chex, showCFloat, showCDouble)
-
-import GHC.Stack
-
----------------------------------------------------------------------------
--- * API
----------------------------------------------------------------------------
-
--- | Given a symbolic computation, render it as an equivalent collection of files
--- that make up a C program:
---
---   * The first argument is the directory name under which the files will be saved. To save
---     files in the current directory pass @'Just' \".\"@. Use 'Nothing' for printing to stdout.
---
---   * The second argument is the name of the C function to generate.
---
---   * The final argument is the function to be compiled.
---
--- Compilation will also generate a @Makefile@,  a header file, and a driver (test) program, etc. As a
--- result, we return whatever the code-gen function returns. Most uses should simply have @()@ as
--- the return type here, but the value can be useful if you want to chain the result of
--- one compilation act to the next.
-compileToC :: Maybe FilePath -> String -> SBVCodeGen a -> IO a
-compileToC mbDirName nm f = do (retVal, cfg, bundle) <- compileToC' nm f
-                               renderCgPgmBundle mbDirName (cfg, bundle)
-                               return retVal
-
--- | Lower level version of 'compileToC', producing a t'CgPgmBundle'
-compileToC' :: String -> SBVCodeGen a -> IO (a, CgConfig, CgPgmBundle)
-compileToC' nm f = do rands <- randoms `fmap` newStdGen
-                      codeGen SBVToC (defaultCgConfig { cgDriverVals = rands }) nm f
-
--- | Create code to generate a library archive (.a) from given symbolic functions. Useful when generating code
--- from multiple functions that work together as a library.
---
---   * The first argument is the directory name under which the files will be saved. To save
---     files in the current directory pass @'Just' \".\"@. Use 'Nothing' for printing to stdout.
---
---   * The second argument is the name of the archive to generate.
---
---   * The third argument is the list of functions to include, in the form of function-name/code pairs, similar
---     to the second and third arguments of 'compileToC', except in a list.
-compileToCLib :: Maybe FilePath -> String -> [(String, SBVCodeGen a)] -> IO [a]
-compileToCLib mbDirName libName comps = do (retVal, cfg, pgm) <- compileToCLib' libName comps
-                                           renderCgPgmBundle mbDirName (cfg, pgm)
-                                           return retVal
-
--- | Lower level version of 'compileToCLib', producing a t'CgPgmBundle'
-compileToCLib' :: String -> [(String, SBVCodeGen a)] -> IO ([a], CgConfig, CgPgmBundle)
-compileToCLib' libName comps = do resCfgBundles <- mapM (uncurry compileToC') comps
-                                  let (finalCfg, finalPgm) = mergeToLib libName [(c, b) | (_, c, b) <- resCfgBundles]
-                                  return ([r | (r, _, _) <- resCfgBundles], finalCfg, finalPgm)
-
----------------------------------------------------------------------------
--- * Implementation
----------------------------------------------------------------------------
-
--- token for the target language
-data SBVToC = SBVToC
-
-instance CgTarget SBVToC where
-  targetName _ = "C"
-  translate  _ = cgen
-
--- Unexpected input, or things we will probably never support
-die :: String -> a
-die msg = error $ "SBV->C: Unexpected: " ++ msg
-
--- Unsupported features, or features TBD
-tbd :: String -> a
-tbd msg = error $ "SBV->C: Not yet supported: " ++ msg
-
-cgen :: CgConfig -> String -> CgState -> Result -> CgPgmBundle
-cgen cfg nm st sbvProg
-   -- we rnf the main pg and the sig to make sure any exceptions in type conversion pop-out early enough
-   -- this is purely cosmetic, of course..
-   = rnf (render sig) `seq` rnf (render (vcat body)) `seq` result
-  where result = CgPgmBundle bundleKind
-                        $ filt [ ("Makefile",  (CgMakefile flags, [genMake (cgGenDriver cfg) nm nmd flags]))
-                               , (nm  ++ ".h", (CgHeader [sig],   [genHeader bundleKind nm [sig] extProtos]))
-                               , (nmd ++ ".c", (CgDriver,         genDriver cfg randVals nm ins outs mbRet))
-                               , (nm  ++ ".c", (CgSource,         body))
-                               ]
-
-        (body, flagsNeeded) = genCProg cfg nm sig sbvProg ins outs mbRet extDecls
-
-        bundleKind = (cgInteger cfg, cgReal cfg)
-
-        randVals = cgDriverVals cfg
-
-        filt xs  = [c | c@(_, (k, _)) <- xs, need k]
-          where need k | isCgDriver   k = cgGenDriver cfg
-                       | isCgMakefile k = cgGenMakefile cfg
-                       | True           = True
-
-        nmd      = nm ++ "_driver"
-        sig      = pprCFunHeader nm ins outs mbRet
-        ins      = cgInputs st
-        outs     = cgOutputs st
-        mbRet    = case cgReturns st of
-                     []           -> Nothing
-                     [CgAtomic o] -> Just o
-                     [CgArray _]  -> tbd "Non-atomic return values"
-                     _            -> tbd "Multiple return values"
-        extProtos = case cgPrototypes st of
-                     [] -> empty
-                     xs -> vcat $ text "/* User given prototypes: */" : map text xs
-        extDecls  = case cgDecls st of
-                     [] -> empty
-                     xs -> vcat $ text "/* User given declarations: */" : map text xs
-        flags    = flagsNeeded ++ cgLDFlags st
-
--- | Pretty print a functions type. If there is only one output, we compile it
--- as a function that returns that value. Otherwise, we compile it as a void function
--- that takes return values as pointers to be updated.
-pprCFunHeader :: String -> [(String, CgVal)] -> [(String, CgVal)] -> Maybe SV -> Doc
-pprCFunHeader fn ins outs mbRet = retType <+> text fn P.<> parens (fsep (punctuate comma (map mkParam ins ++ map mkPParam outs)))
-  where retType = case mbRet of
-                   Nothing -> text "void"
-                   Just sv -> pprCWord False sv
-
-mkParam, mkPParam :: (String, CgVal) -> Doc
-mkParam  (n, CgAtomic sv)     = pprCWord True  sv <+> text n
-mkParam  (_, CgArray  [])     = die "mkParam: CgArray with no elements!"
-mkParam  (n, CgArray  (sv:_)) = pprCWord True  sv <+> text "*" P.<> text n
-mkPParam (n, CgAtomic sv)     = pprCWord False sv <+> text "*" P.<> text n
-mkPParam (_, CgArray  [])     = die "mPkParam: CgArray with no elements!"
-mkPParam (n, CgArray  (sv:_)) = pprCWord False sv <+> text "*" P.<> text n
-
--- | Renders as "const SWord8 s0", etc. the first parameter is the width of the typefield
-declSV :: Int -> SV -> Doc
-declSV w sv = text "const" <+> pad (showCType sv) <+> text (show sv)
-  where pad s = text $ s ++ replicate (w - length s) ' '
-
--- | Return the proper declaration and the result as a pair. No consts
-declSVNoConst :: Int -> SV -> (Doc, Doc)
-declSVNoConst w sv = (text "     " <+> pad (showCType sv), text (show sv))
-  where pad s = text $ s ++ replicate (w - length s) ' '
-
--- | Renders as "s0", etc, or the corresponding constant
-showSV :: CgConfig -> [(SV, CV)] -> SV -> Doc
-showSV cfg consts sv
-  | sv == falseSV                 = text "false"
-  | sv == trueSV                  = text "true"
-  | Just cv <- sv `lookup` consts = mkConst cfg cv
-  | True                          = text $ show sv
-
--- | Words as it would map to a C word
-pprCWord :: HasKind a => Bool -> a -> Doc
-pprCWord cnst v = (if cnst then text "const" else empty) <+> text (showCType v)
-
--- | Almost a "show", but map "SWord1" to "SBool"
--- which is used for extracting one-bit words. This is OK since C's bool type
--- handles arithmetic fine, and maps nicely to our `SWord 1`. (Same isn't true for `SInt 1`, which
--- doesn't have an easy counter-part on the C side.
-showCType :: HasKind a => a -> String
-showCType i = case kindOf i of
-                KBounded False 1 -> "SBool"
-                k                -> show k
-
--- | The printf specifier for the type
-specifier :: CgConfig -> SV -> Doc
-specifier cfg sv = case kindOf sv of
-                     KBool         -> spec (False, 1)
-                     KBounded b i  -> spec (b, i)
-                     KUnbounded    -> spec (True, fromJust (cgInteger cfg))
-                     KReal         -> specF (fromJust (cgReal cfg))
-                     KFloat        -> specF CgFloat
-                     KDouble       -> specF CgDouble
-                     KString       -> text "%s"
-                     KChar         -> text "%c"
-                     KRational     -> die   "rational sort"
-                     KFP{}         -> die   "arbitrary float sort"
-                     KList k       -> die $ "list sort: "   ++ show k
-                     KSet  k       -> die $ "set sort: "    ++ show k
-                     KUserSort s _ -> die $ "user sort: "   ++ s
-                     KTuple k      -> die $ "tuple sort: "  ++ show k
-                     KMaybe  k     -> die $ "maybe sort: "  ++ show k
-                     KEither k1 k2 -> die $ "either sort: " ++ show (k1, k2)
-                     KArray  k1 k2 -> die $ "array sort: "  ++ show (k1, k2)
-  where u8InHex = cgShowU8InHex cfg
-
-        spec :: (Bool, Int) -> Doc
-        spec (False,  1) = text "%d"
-        spec (False,  8)
-          | u8InHex      = text "0x%02\"PRIx8\""
-          | True         = text "%\"PRIu8\""
-        spec (True,   8) = text "%\"PRId8\""
-        spec (False, 16) = text "0x%04\"PRIx16\"U"
-        spec (True,  16) = text "%\"PRId16\""
-        spec (False, 32) = text "0x%08\"PRIx32\"UL"
-        spec (True,  32) = text "%\"PRId32\"L"
-        spec (False, 64) = text "0x%016\"PRIx64\"ULL"
-        spec (True,  64) = text "%\"PRId64\"LL"
-        spec (s, sz)     = die $ "Format specifier at type " ++ (if s then "SInt" else "SWord") ++ show sz
-
-        specF :: CgSRealType -> Doc
-        specF CgFloat      = text "%a"
-        specF CgDouble     = text "%a"
-        specF CgLongDouble = text "%Lf"
-
--- | Make a constant value of the given type. We don't check for out of bounds here, as it should not be needed.
---   There are many options here, using binary, decimal, etc. We simply use decimal for values 8-bits or less,
---   and hex otherwise.
-mkConst :: CgConfig -> CV -> Doc
-mkConst cfg  (CV KReal (CAlgReal (AlgRational _ r))) = double (fromRational r :: Double) P.<> sRealSuffix (fromJust (cgReal cfg))
-  where sRealSuffix CgFloat      = text "F"
-        sRealSuffix CgDouble     = empty
-        sRealSuffix CgLongDouble = text "L"
-mkConst cfg (CV KUnbounded       (CInteger i)) = showSizedConst (cgShowU8InHex cfg) i (True, fromJust (cgInteger cfg))
-mkConst cfg (CV (KBounded sg sz) (CInteger i)) = showSizedConst (cgShowU8InHex cfg) i (sg,   sz)
-mkConst cfg (CV KBool            (CInteger i)) = showSizedConst (cgShowU8InHex cfg) i (False, 1)
-mkConst _   (CV KFloat           (CFloat f))   = text $ showCFloat f
-mkConst _   (CV KDouble          (CDouble d))  = text $ showCDouble d
-mkConst _   (CV KString          (CString s))  = text $ show s
-mkConst _   (CV KChar            (CChar c))    = text $ show c
-mkConst _   cv                                 = die $ "mkConst: " ++ show cv
-
-showSizedConst :: Bool -> Integer -> (Bool, Int) -> Doc
-showSizedConst _   i   (False,  1) = text (if i == 0 then "false" else "true")
-showSizedConst u8h i t@(False,  8)
-  | u8h                            = text (chex False True t i)
-  | True                           = integer i
-showSizedConst _   i   (True,   8) = integer i
-showSizedConst _   i t@(False, 16) = text $ chex False True t i
-showSizedConst _   i t@(True,  16) = text $ chex False True t i
-showSizedConst _   i t@(False, 32) = text $ chex False True t i
-showSizedConst _   i t@(True,  32) = text $ chex False True t i
-showSizedConst _   i t@(False, 64) = text $ chex False True t i
-showSizedConst _   i t@(True,  64) = text $ chex False True t i
-showSizedConst _   i   (s, sz)     = die $ "Constant " ++ show i ++ " at type " ++ (if s then "SInt" else "SWord") ++ show sz
-
--- | Generate a makefile. The first argument is True if we have a driver.
-genMake :: Bool -> String -> String -> [String] -> Doc
-genMake ifdr fn dn ldFlags = foldr1 ($$) [l | (True, l) <- lns]
- where ifld = not (null ldFlags)
-       ld | ifld = text "${LDFLAGS}"
-          | True = empty
-       lns = [ (True, text "# Makefile for" <+> nm P.<> text ". Automatically generated by SBV. Do not edit!")
-             , (True, text "")
-             , (True, text "# include any user-defined .mk file in the current directory.")
-             , (True, text "-include *.mk")
-             , (True, text "")
-             , (True, text "CC?=gcc")
-             , (True, text "CCFLAGS?=-Wall -O3 -DNDEBUG -fomit-frame-pointer")
-             , (ifld, text "LDFLAGS?=" P.<> text (unwords ldFlags))
-             , (True, text "")
-             , (ifdr, text "all:" <+> nmd)
-             , (ifdr, text "")
-             , (True, nmo P.<> text (": " ++ ppSameLine (hsep [nmc, nmh])))
-             , (True, text "\t${CC} ${CCFLAGS}" <+> text "-c $< -o $@")
-             , (True, text "")
-             , (ifdr, nmdo P.<> text ":" <+> nmdc)
-             , (ifdr, text "\t${CC} ${CCFLAGS}" <+> text "-c $< -o $@")
-             , (ifdr, text "")
-             , (ifdr, nmd P.<> text (": " ++ ppSameLine (hsep [nmo, nmdo])))
-             , (ifdr, text "\t${CC} ${CCFLAGS}" <+> text "$^ -o $@" <+> ld)
-             , (ifdr, text "")
-             , (True, text "clean:")
-             , (True, text "\trm -f *.o")
-             , (True, text "")
-             , (ifdr, text "veryclean: clean")
-             , (ifdr, text "\trm -f" <+> nmd)
-             , (ifdr, text "")
-             ]
-       nm   = text fn
-       nmd  = text dn
-       nmh  = nm P.<> text ".h"
-       nmc  = nm P.<> text ".c"
-       nmo  = nm P.<> text ".o"
-       nmdc = nmd P.<> text ".c"
-       nmdo = nmd P.<> text ".o"
-
--- | Generate the header
-genHeader :: (Maybe Int, Maybe CgSRealType) -> String -> [Doc] -> Doc -> Doc
-genHeader (ik, rk) fn sigs protos =
-     text "/* Header file for" <+> nm P.<> text ". Automatically generated by SBV. Do not edit! */"
-  $$ text ""
-  $$ text "#ifndef" <+> tag
-  $$ text "#define" <+> tag
-  $$ text ""
-  $$ text "#include <stdio.h>"
-  $$ text "#include <stdlib.h>"
-  $$ text "#include <inttypes.h>"
-  $$ text "#include <stdint.h>"
-  $$ text "#include <stdbool.h>"
-  $$ text "#include <string.h>"
-  $$ text "#include <math.h>"
-  $$ text ""
-  $$ text "/* The boolean type */"
-  $$ text "typedef bool SBool;"
-  $$ text ""
-  $$ text "/* The float type */"
-  $$ text "typedef float SFloat;"
-  $$ text ""
-  $$ text "/* The double type */"
-  $$ text "typedef double SDouble;"
-  $$ text ""
-  $$ text "/* Unsigned bit-vectors */"
-  $$ text "typedef uint8_t  SWord8;"
-  $$ text "typedef uint16_t SWord16;"
-  $$ text "typedef uint32_t SWord32;"
-  $$ text "typedef uint64_t SWord64;"
-  $$ text ""
-  $$ text "/* Signed bit-vectors */"
-  $$ text "typedef int8_t  SInt8;"
-  $$ text "typedef int16_t SInt16;"
-  $$ text "typedef int32_t SInt32;"
-  $$ text "typedef int64_t SInt64;"
-  $$ text ""
-  $$ imapping
-  $$ rmapping
-  $$ text ("/* Entry point prototype" ++ plu ++ ": */")
-  $$ vcat (map (P.<> semi) sigs)
-  $$ text ""
-  $$ protos
-  $$ text "#endif /*" <+> tag <+> text "*/"
-  $$ text ""
- where nm  = text fn
-       tag = text "__" P.<> nm P.<> text "__HEADER_INCLUDED__"
-       plu = if length sigs /= 1 then "s" else ""
-       imapping = case ik of
-                    Nothing -> empty
-                    Just i  ->    text "/* User requested mapping for SInteger.                                 */"
-                               $$ text "/* NB. Loss of precision: Target type is subject to modular arithmetic. */"
-                               $$ text ("typedef SInt" ++ show i ++ " SInteger;")
-                               $$ text ""
-       rmapping = case rk of
-                    Nothing -> empty
-                    Just t  ->    text "/* User requested mapping for SReal.                          */"
-                               $$ text "/* NB. Loss of precision: Target type is subject to rounding. */"
-                               $$ text ("typedef " ++ show t ++ " SReal;")
-                               $$ text ""
-
-sepIf :: Bool -> Doc
-sepIf b = if b then text "" else empty
-
--- | Generate an example driver program
-genDriver :: CgConfig -> [Integer] -> String -> [(String, CgVal)] -> [(String, CgVal)] -> Maybe SV -> [Doc]
-genDriver cfg randVals fn inps outs mbRet = [pre, header, body, post]
- where pre    =  text "/* Example driver program for" <+> nm P.<> text ". */"
-              $$ text "/* Automatically generated by SBV. Edit as you see fit! */"
-              $$ text ""
-              $$ text "#include <stdio.h>"
-       header =  text "#include" <+> doubleQuotes (nm P.<> text ".h")
-              $$ text ""
-              $$ text "int main(void)"
-              $$ text "{"
-       body   =  text ""
-              $$ nest 2 (   vcat (map mkInp pairedInputs)
-                      $$ vcat (map mkOut outs)
-                      $$ sepIf (not (null [() | (_, _, CgArray{}) <- pairedInputs]) || not (null outs))
-                      $$ call
-                      $$ text ""
-                      $$ (case mbRet of
-                              Just sv -> text "printf" P.<> parens (printQuotes (fcall <+> text "=" <+> specifier cfg sv P.<> text "\\n")
-                                                                              P.<> comma <+> resultVar) P.<> semi
-                              Nothing -> text "printf" P.<> parens (printQuotes (fcall <+> text "->\\n")) P.<> semi)
-                      $$ vcat (map display outs)
-                      )
-       post   =   text ""
-              $+$ nest 2 (text "return 0" P.<> semi)
-              $$  text "}"
-              $$  text ""
-       nm = text fn
-       pairedInputs = matchRands randVals inps
-       matchRands _      []                                 = []
-       matchRands []     _                                  = die "Run out of driver values!"
-       matchRands (r:rs) ((n, CgAtomic sv)            : cs) = ([mkRVal sv r], n, CgAtomic sv) : matchRands rs cs
-       matchRands _      ((n, CgArray [])             : _ ) = die $ "Unsupported empty array input " ++ show n
-       matchRands rs     ((n, a@(CgArray sws@(sv:_))) : cs)
-          | length frs /= l                                 = die "Run out of driver values!"
-          | True                                            = (map (mkRVal sv) frs, n, a) : matchRands srs cs
-          where l          = length sws
-                (frs, srs) = splitAt l rs
-       mkRVal sv r = mkConst cfg $ mkConstCV (kindOf sv) r
-       mkInp (_,  _, CgAtomic{})         = empty  -- constant, no need to declare
-       mkInp (_,  n, CgArray [])         = die $ "Unsupported empty array value for " ++ show n
-       mkInp (vs, n, CgArray sws@(sv:_)) =  pprCWord True sv <+> text n P.<> brackets (int (length sws)) <+> text "= {"
-                                                      $$ nest 4 (fsep (punctuate comma (align vs)))
-                                                      $$ text "};"
-                                         $$ text ""
-                                         $$ text "printf" P.<> parens (printQuotes (text "Contents of input array" <+> text n P.<> text ":\\n")) P.<> semi
-                                         $$ display (n, CgArray sws)
-                                         $$ text ""
-       mkOut (v, CgAtomic sv)            = pprCWord False sv <+> text v P.<> semi
-       mkOut (v, CgArray [])             = die $ "Unsupported empty array value for " ++ show v
-       mkOut (v, CgArray sws@(sv:_))     = pprCWord False sv <+> text v P.<> brackets (int (length sws)) P.<> semi
-       resultVar = text "__result"
-       call = case mbRet of
-                Nothing -> fcall P.<> semi
-                Just sv -> pprCWord True sv <+> resultVar <+> text "=" <+> fcall P.<> semi
-       fcall = nm P.<> parens (fsep (punctuate comma (map mkCVal pairedInputs ++ map mkOVal outs)))
-       mkCVal ([v], _, CgAtomic{}) = v
-       mkCVal (vs,  n, CgAtomic{}) = die $ "Unexpected driver value computed for " ++ show n ++ render (hcat vs)
-       mkCVal (_,   n, CgArray{})  = text n
-       mkOVal (n, CgAtomic{})      = text "&" P.<> text n
-       mkOVal (n, CgArray{})       = text n
-       display (n, CgAtomic sv)         = text "printf" P.<> parens (printQuotes (text " " <+> text n <+> text "=" <+> specifier cfg sv
-                                                                                P.<> text "\\n") P.<> comma <+> text n) P.<> semi
-       display (n, CgArray [])         =  die $ "Unsupported empty array value for " ++ show n
-       display (n, CgArray sws@(sv:_)) =   text "int" <+> nctr P.<> semi
-                                        $$ text "for(" P.<> nctr <+> text "= 0;" <+> nctr <+> text "<" <+> int len <+> text "; ++" P.<> nctr P.<> text ")"
-                                        $$ nest 2 (text "printf" P.<> parens (printQuotes (text " " <+> entrySpec <+> text "=" <+> spec P.<> text "\\n")
-                                                                 P.<> comma <+> nctr <+> comma P.<> entry) P.<> semi)
-                  where nctr      = text n P.<> text "_ctr"
-                        entry     = text n P.<> text "[" P.<> nctr P.<> text "]"
-                        entrySpec = text n P.<> text "[%" P.<> int tab P.<> text "d]"
-                        spec      = specifier cfg sv
-                        len       = length sws
-                        tab       = length $ show (len - 1)
-
--- | Generate the C program
-genCProg :: CgConfig -> String -> Doc -> Result -> [(String, CgVal)] -> [(String, CgVal)] -> Maybe SV -> Doc -> ([Doc], [String])
-genCProg cfg fn proto (Result pinfo kindInfo _tvals _ovals cgs topInps (_, preConsts) tbls _uis axioms (SBVPgm asgns) cstrs origAsserts _) inVars outVars mbRet extDecls
-  | isNothing (cgInteger cfg) && KUnbounded `Set.member` kindInfo
-  = error $ "SBV->C: Unbounded integers are not supported by the C compiler."
-          ++ "\nUse 'cgIntegerSize' to specify a fixed size for SInteger representation."
-  | KString `Set.member` kindInfo
-  = notyet "Strings"
-  | KChar `Set.member` kindInfo
-  = notyet "Characters"
-  | any isSet kindInfo
-  = notyet "Sets (SSet)"
-  | any isList kindInfo
-  = notyet "Lists (SList)"
-  | any isTuple kindInfo
-  = notyet "Tuples (STupleN)"
-  | any isMaybe kindInfo
-  = notyet "Optional (SMaybe) values"
-  | any isEither kindInfo
-  = notyet "Either (SEither) values"
-  | isNothing (cgReal cfg) && KReal `Set.member` kindInfo
-  = error $ "SBV->C: SReal values are not supported by the C compiler."
-          ++ "\nUse 'cgSRealType' to specify a custom type for SReal representation."
-  | not (null unsupportedBVs)
-  = error $ "SBV->C: Unsupported bit-vector type(s): " ++ intercalate ", " (map show unsupportedBVs)
-  | not (null usorts)
-  = error $ "SBV->C: Cannot compile functions with uninterpreted sorts: " ++ intercalate ", " usorts
-  | hasQuants pinfo
-  = error "SBV->C: Cannot compile in the presence of quantified variables."
-  | not $ null (progSpecialRels pinfo)
-  = error "SBV->C: Cannot compile in the presence of special relations."
-  | not (null axioms)
-  = error "SBV->C: Cannot compile in the presence of 'smtFunction' definitions, use 'compileToCLib' instead."
-  | not (null cstrs)
-  = tbd "Explicit constraints"
-  | True
-  = ([pre, header, post], flagsNeeded)
- where notyet m = error $ "SBV->C: " ++ m ++ " are currently not supported by the C compiler. Please get in touch if you'd like support for this feature!"
-
-       asserts | cgIgnoreAsserts cfg = []
-               | True                = origAsserts
-
-       usorts = [s | KUserSort s _ <- Set.toList kindInfo, s /= "RoundingMode"] -- No support for any sorts other than RoundingMode!
-
-       pre    =  text "/* File:" <+> doubleQuotes (nm P.<> text ".c") P.<> text ". Automatically generated by SBV. Do not edit! */"
-              $$ text ""
-
-       header = text "#include" <+> doubleQuotes (nm P.<> text ".h")
-
-       unsupportedBVs = [k | k@(KBounded sg sz) <- Set.toList kindInfo, (not . supported) (sg, sz)]
-         where supported (False, sz) = sz `elem` [1, 8, 16, 32, 64]
-               supported (True,  sz) = sz `elem` [   8, 16, 32, 64]
-
-       post   = text ""
-             $$ vcat (map codeSeg cgs)
-             $$ extDecls
-             $$ proto
-             $$ text "{"
-             $$ text ""
-             $$ nest 2 (   vcat (concatMap (genIO True . (\v -> (isAlive v, v))) inVars)
-                        $$ vcat (merge (map genTbl tbls) (map genAsgn assignments) (map genAssert asserts))
-                        $$ sepIf (not (null assignments) || not (null tbls))
-                        $$ vcat (concatMap (genIO False . (True,)) outVars)
-                        $$ maybe empty mkRet mbRet
-                       )
-             $$ text "}"
-             $$ text ""
-
-       nm = text fn
-
-       assignments = F.toList asgns
-
-       -- Do we need any linker flags for C?
-       flagsNeeded = nub $ concatMap (getLDFlag . opRes) assignments
-          where opRes (sv, SBVApp o _) = (o, kindOf sv)
-
-       codeSeg (fnm, ls) =  text "/* User specified custom code for" <+> doubleQuotes (text fnm) <+> text "*/"
-                         $$ vcat (map text ls)
-                         $$ text ""
-
-       ins = case topInps of
-               ResultTopInps (is, []) -> is
-               ResultTopInps is       -> die $ "Unexpected trackers: " ++ show is
-               ResultLamInps is       -> die $ "Unexpected inputs  : " ++ show is
-
-       typeWidth = getMax 0 $ [len (kindOf s) | (s, _) <- assignments] ++ [len (kindOf s) | NamedSymVar s _ <- ins]
-                where len KReal{}            = 5
-                      len KFloat{}           = 6 -- SFloat
-                      len KDouble{}          = 7 -- SDouble
-                      len KString{}          = 7 -- SString
-                      len KChar{}            = 5 -- SChar
-                      len KUnbounded{}       = 8
-                      len KBool              = 5 -- SBool
-                      len (KBounded False n) = 5 + length (show n) -- SWordN
-                      len (KBounded True  n) = 4 + length (show n) -- SIntN
-                      len KRational{}        = die   "Rational."
-                      len KFP{}              = die   "Arbitrary float."
-                      len (KList s)          = die $ "List sort: "   ++ show s
-                      len (KSet  s)          = die $ "Set sort: "    ++ show s
-                      len (KTuple s)         = die $ "Tuple sort: "  ++ show s
-                      len (KMaybe k)         = die $ "Maybe sort: "  ++ show k
-                      len (KEither k1 k2)    = die $ "Either sort: " ++ show (k1, k2)
-                      len (KArray  k1 k2)    = die $ "Array sort:  " ++ show (k1, k2)
-                      len (KUserSort s _)    = die $ "Uninterpreted sort: " ++ s
-
-                      getMax 8 _      = 8  -- 8 is the max we can get with SInteger, so don't bother looking any further
-                      getMax m []     = m
-                      getMax m (x:xs) = getMax (m `max` x) xs
-
-       consts = (falseSV, falseCV) : (trueSV, trueCV) : preConsts
-
-       isConst s = isJust (lookup s consts)
-
-       -- TODO: The following is brittle. We should really have a function elsewhere
-       -- that walks the SBVExprs and collects the SWs together.
-       usedVariables = Set.unions (retSWs : map usedCgVal outVars ++ map usedAsgn assignments)
-         where retSWs = maybe Set.empty Set.singleton mbRet
-
-               usedCgVal (_, CgAtomic s)  = Set.singleton s
-               usedCgVal (_, CgArray ss)  = Set.fromList ss
-               usedAsgn  (_, SBVApp o ss) = Set.union (opSWs o) (Set.fromList ss)
-
-               opSWs (LkUp _ a b)             = Set.fromList [a, b]
-               opSWs (IEEEFP (FP_Cast _ _ s)) = Set.singleton s
-               opSWs _                        = Set.empty
-
-       isAlive :: (String, CgVal) -> Bool
-       isAlive (_, CgAtomic sv) = sv `Set.member` usedVariables
-       isAlive (_, _)           = True
-
-       genIO :: Bool -> (Bool, (String, CgVal)) -> [Doc]
-       genIO True  (alive, (cNm, CgAtomic sv)) = [declSV typeWidth sv  <+> text "=" <+> text cNm P.<> semi               | alive]
-       genIO False (alive, (cNm, CgAtomic sv)) = [text "*" P.<> text cNm <+> text "=" <+> showSV cfg consts sv P.<> semi | alive]
-       genIO isInp (_,     (cNm, CgArray sws)) = zipWith genElt sws [(0::Int)..]
-         where genElt sv i
-                 | isInp = declSV typeWidth sv <+> text "=" <+> text entry       P.<> semi
-                 | True  = text entry          <+> text "=" <+> showSV cfg consts sv P.<> semi
-                 where entry = cNm ++ "[" ++ show i ++ "]"
-
-       mkRet sv = text "return" <+> showSV cfg consts sv P.<> semi
-
-       genTbl :: ((Int, Kind, Kind), [SV]) -> (Int, Doc)
-       genTbl ((i, _, k), elts) =  (location, static <+> text "const" <+> text (show k) <+> text ("table" ++ show i) P.<> text "[] = {"
-                                              $$ nest 4 (fsep (punctuate comma (align (map (showSV cfg consts) elts))))
-                                              $$ text "};")
-         where static   = if location == -1 then text "static" else empty
-               location = maximum (-1 : map getNodeId elts)
-
-       getNodeId s@(SV _ (NodeId (_, _, n))) | isConst s = -1
-                                             | True      = n
-
-       genAsgn :: (SV, SBVExpr) -> (Int, Doc)
-       genAsgn (sv, n) = (getNodeId sv, ppExpr cfg consts n (declSV typeWidth sv) (declSVNoConst typeWidth sv) P.<> semi)
-
-       -- merge tables intermixed with assignments and assertions, paying attention to putting tables as
-       -- early as possible and tables right after.. Note that the assignment list (second argument) is sorted on its order
-       merge :: [(Int, Doc)] -> [(Int, Doc)] -> [(Int, Doc)] -> [Doc]
-       merge tables asgnments asrts = map snd $ merge2 asrts (merge2 tables asgnments)
-         where merge2 []               as                  = as
-               merge2 ts               []                  = ts
-               merge2 ts@((i, t):trest) as@((i', a):arest)
-                 | i < i'                                 = (i,  t)  : merge2 trest as
-                 | True                                   = (i', a) : merge2 ts arest
-
-       genAssert (msg, cs, sv) = (getNodeId sv, doc)
-         where doc =     text "/* ASSERTION:" <+> text msg
-                     $$  maybe empty (vcat . map text) (locInfo (getCallStack `fmap` cs))
-                     $$  text " */"
-                     $$  text "if" P.<> parens (showSV cfg consts sv)
-                     $$  text "{"
-                     $+$ nest 2 (vcat [errOut, text "exit(-1);"])
-                     $$  text "}"
-                     $$  text ""
-               errOut = text $ "fprintf(stderr, \"%s:%d:ASSERTION FAILED: " ++ msg ++ "\\n\", __FILE__, __LINE__);"
-               locInfo (Just ps) = let loc (f, sl) = concat [srcLocFile sl, ":", show (srcLocStartLine sl), ":", show (srcLocStartCol sl), ":", f ]
-                                   in case map loc ps of
-                                         []     -> Nothing
-                                         (f:rs) -> Just $ (" * SOURCE   : " ++ f) : map (" *            " ++)  rs
-               locInfo _         = Nothing
-
-handlePB :: PBOp -> [Doc] -> Doc
-handlePB o args = case o of
-                    PB_AtMost  k -> addIf (repeat 1) <+> text "<=" <+> int k
-                    PB_AtLeast k -> addIf (repeat 1) <+> text ">=" <+> int k
-                    PB_Exactly k -> addIf (repeat 1) <+> text "==" <+> int k
-                    PB_Le cs   k -> addIf cs         <+> text "<=" <+> int k
-                    PB_Ge cs   k -> addIf cs         <+> text ">=" <+> int k
-                    PB_Eq cs   k -> addIf cs         <+> text "==" <+> int k
-
-  where addIf :: [Int] -> Doc
-        addIf cs = parens $ fsep $ intersperse (text "+") [parens (a <+> text "?" <+> int c <+> text ":" <+> int 0) | (a, c) <- zip args cs]
-
-handleIEEE :: FPOp -> [(SV, CV)] -> [(SV, Doc)] -> Doc -> Doc
-handleIEEE w consts as var = cvt w
-  where same f                   = (f, f)
-        named fnm dnm f          = (f fnm, f dnm)
-
-        cvt (FP_Cast from to m)     = case checkRM (m `lookup` consts) of
-                                        Nothing          -> cast $ \[a] -> parens (text (show to)) <+> rnd a
-                                        Just (Left  msg) -> die msg
-                                        Just (Right msg) -> tbd msg
-                                      where -- if we're converting from float to some integral like; first use rint/rintf to do the internal conversion and then cast.
-                                            rnd a
-                                             | (isFloat from || isDouble from) && (isBounded to || isUnbounded to)
-                                             = let f = if isFloat from then "rintf" else "rint"
-                                               in text f P.<> parens a
-                                             | True
-                                             = a
-
-        cvt (FP_Reinterpret f t) = case (f, t) of
-                                     (KBounded False 32, KFloat)  -> cast $ cpy "sizeof(SFloat)"
-                                     (KBounded False 64, KDouble) -> cast $ cpy "sizeof(SDouble)"
-                                     (KFloat,  KBounded False 32) -> cast $ cpy "sizeof(SWord32)"
-                                     (KDouble, KBounded False 64) -> cast $ cpy "sizeof(SWord64)"
-                                     _                            -> die $ "Reinterpretation from : " ++ show f ++ " to " ++ show t
-                                    where cpy sz = \[a] -> let alhs = text "&" P.<> var
-                                                               arhs = text "&" P.<> a
-                                                           in text "memcpy" P.<> parens (fsep (punctuate comma [alhs, arhs, text sz]))
-        cvt FP_Abs               = dispatch $ named "fabsf" "fabs" $ \nm _ [a] -> text nm P.<> parens a
-        cvt FP_Neg               = dispatch $ same $ \_ [a] -> text "-" P.<> a
-        cvt FP_Add               = dispatch $ same $ \_ [a, b] -> a <+> text "+" <+> b
-        cvt FP_Sub               = dispatch $ same $ \_ [a, b] -> a <+> text "-" <+> b
-        cvt FP_Mul               = dispatch $ same $ \_ [a, b] -> a <+> text "*" <+> b
-        cvt FP_Div               = dispatch $ same $ \_ [a, b] -> a <+> text "/" <+> b
-        cvt FP_FMA               = dispatch $ named "fmaf"  "fma"  $ \nm _ [a, b, c] -> text nm P.<> parens (fsep (punctuate comma [a, b, c]))
-        cvt FP_Sqrt              = dispatch $ named "sqrtf" "sqrt" $ \nm _ [a]       -> text nm P.<> parens a
-        cvt FP_Rem               = dispatch $ named "fmodf" "fmod" $ \nm _ [a, b]    -> text nm P.<> parens (fsep (punctuate comma [a, b]))
-        cvt FP_RoundToIntegral   = dispatch $ named "rintf" "rint" $ \nm _ [a]       -> text nm P.<> parens a
-        cvt FP_Min               = dispatch $ named "fminf" "fmin" $ \nm k [a, b]    -> wrapMinMax k a b (text nm P.<> parens (fsep (punctuate comma [a, b])))
-        cvt FP_Max               = dispatch $ named "fmaxf" "fmax" $ \nm k [a, b]    -> wrapMinMax k a b (text nm P.<> parens (fsep (punctuate comma [a, b])))
-        cvt FP_ObjEqual          = let mkIte   x y z = x <+> text "?" <+> y <+> text ":" <+> z
-                                       chkNaN  x     = text "isnan"   P.<> parens x
-                                       signbit x     = text "signbit" P.<> parens x
-                                       eq      x y   = parens (x <+> text "==" <+> y)
-                                       eqZero  x     = eq x (text "0")
-                                       negZero x     = parens (signbit x <+> text "&&" <+> eqZero x)
-                                   in dispatch $ same $ \_ [a, b] -> mkIte (chkNaN a) (chkNaN b) (mkIte (negZero a) (negZero b) (mkIte (negZero b) (negZero a) (eq a b)))
-        cvt FP_IsNormal          = dispatch $ same $ \_ [a] -> text "isnormal" P.<> parens a
-        cvt FP_IsSubnormal       = dispatch $ same $ \_ [a] -> text "FP_SUBNORMAL == fpclassify" P.<> parens a
-        cvt FP_IsZero            = dispatch $ same $ \_ [a] -> text "FP_ZERO == fpclassify" P.<> parens a
-        cvt FP_IsInfinite        = dispatch $ same $ \_ [a] -> text "isinf" P.<> parens a
-        cvt FP_IsNaN             = dispatch $ same $ \_ [a] -> text "isnan" P.<> parens a
-        cvt FP_IsNegative        = dispatch $ same $ \_ [a] -> text "!isnan" P.<> parens a <+> text "&&" <+> text "signbit"  P.<> parens a
-        cvt FP_IsPositive        = dispatch $ same $ \_ [a] -> text "!isnan" P.<> parens a <+> text "&&" <+> text "!signbit" P.<> parens a
-
-        -- grab the rounding-mode, if present, and make sure it's RoundNearestTiesToEven. Otherwise skip.
-        fpArgs = case as of
-                   []            -> []
-                   ((m, _):args) -> case kindOf m of
-                                      KUserSort "RoundingMode" _ -> case checkRM (m `lookup` consts) of
-                                                                      Nothing          -> args
-                                                                      Just (Left  msg) -> die msg
-                                                                      Just (Right msg) -> tbd msg
-                                      _                          -> as
-
-        -- Check that the RM is RoundNearestTiesToEven.
-        -- If we start supporting other rounding-modes, this would be the point where we'd insert the rounding-mode set/reset code
-        -- instead of merely returning OK or not
-        checkRM (Just cv@(CV (KUserSort "RoundingMode" _) v)) =
-              case v of
-                CUserSort (_, "RoundNearestTiesToEven") -> Nothing
-                CUserSort (_, s)                        -> Just (Right $ "handleIEEE: Unsupported rounding-mode: " ++ show s ++ " for: " ++ show w)
-                _                                       -> Just (Left  $ "handleIEEE: Unexpected value for rounding-mode: " ++ show cv ++ " for: " ++ show w)
-        checkRM (Just cv) = Just (Left  $ "handleIEEE: Expected rounding-mode, but got: " ++ show cv ++ " for: " ++ show w)
-        checkRM Nothing   = Just (Right $ "handleIEEE: Non-constant rounding-mode for: " ++ show w)
-
-        pickOp _          []             = die $ "Cannot determine float/double kind for op: " ++ show w
-        pickOp (fOp, dOp) args@((a,_):_) = case kindOf a of
-                                             KFloat  -> fOp KFloat  (map snd args)
-                                             KDouble -> dOp KDouble (map snd args)
-                                             k       -> die $ "handleIEEE: Expected double/float args, but got: " ++ show k ++ " for: " ++ show w
-
-        dispatch (fOp, dOp) = pickOp (fOp, dOp) fpArgs
-        cast f              = f (map snd fpArgs)
-
-        -- In SMT-Lib, fpMin/fpMax is underspecified when given +0/-0 as the two arguments. (In any order.)
-        -- In C, the second argument is returned. (I think, might depend on the architecture, optimizations etc.).
-        -- We'll translate it so that we deterministically return +0.
-        -- There's really no good choice here.
-        wrapMinMax k a b s = parens cond <+> text "?" <+> fzero <+> text ":" <+> s
-          where fzero = text $ if k == KFloat then showCFloat 0 else showCDouble 0
-                cond  =                   parens (text "FP_ZERO == fpclassify" P.<> parens a)                                  -- a is zero
-                        <+> text "&&" <+> parens (text "FP_ZERO == fpclassify" P.<> parens b)                                  -- b is zero
-                        <+> text "&&" <+> parens (text "signbit" P.<> parens a <+> text "!=" <+> text "signbit" P.<> parens b) -- a and b differ in sign
-
-ppExpr :: CgConfig -> [(SV, CV)] -> SBVExpr -> Doc -> (Doc, Doc) -> Doc
-ppExpr cfg consts (SBVApp op opArgs) lhs (typ, var)
-  | doNotAssign op
-  = typ <+> var P.<> semi <+> rhs
-  | True
-  = lhs <+> text "=" <+> rhs
-  where doNotAssign (IEEEFP FP_Reinterpret{}) = True   -- generates a memcpy instead; no simple assignment
-        doNotAssign _                         = False  -- generates simple assignment
-
-        rhs = p op (map (showSV cfg consts) opArgs)
-
-        rtc = cgRTC cfg
-
-        cBinOps = [ (Plus, "+"),  (Times, "*"), (Minus, "-")
-                  , (Equal False, "==")  -- no strong equality!
-                  , (NotEqual, "!="), (LessThan, "<"), (GreaterThan, ">"), (LessEq, "<="), (GreaterEq, ">=")
-                  , (And, "&"), (Or, "|"), (XOr, "^")
-                  ]
-
-        -- see if we can find a constant shift; makes the output way more readable
-        getShiftAmnt def [_, sv] = case sv `lookup` consts of
-                                    Just (CV _  (CInteger i)) -> integer i
-                                    _                         -> def
-        getShiftAmnt def _       = def
-
-        hd _ (h:_) = h
-        hd w []    = error $ "Data.SBV.C.ppExpr: Impossible happened: " ++ w ++ ", received empty list!"
-
-        p :: Op -> [Doc] -> Doc
-        p ReadArray{}       _  = tbd "User specified arrays (ReadArray)"
-        p WriteArray{}      _  = tbd "User specified arrays (WriteArray)"
-        p (Label s)        [a] = a <+> text "/*" <+> text s <+> text "*/"
-        p (IEEEFP w)         as = handleIEEE w  consts (zip opArgs as) var
-        p (PseudoBoolean pb) as = handlePB pb as
-        p (OverflowOp o) _      = tbd $ "Overflow operations" ++ show o
-        p (KindCast _ to)   [a] = parens (text (show to)) <+> a
-        p (Uninterpreted s) [] = text "/* Uninterpreted constant */" <+> text s
-        p (Uninterpreted s) as = text "/* Uninterpreted function */" <+> text s P.<> parens (fsep (punctuate comma as))
-        p (Extract i j) [a]    = extract i j (hd "Extract" opArgs) a
-        p Join [a, b]          = join (let (s1 : s2 : _) = opArgs in (s1, s2, a, b))
-        p (Rol i) [a]          = rotate True  i a (hd "Rol" opArgs)
-        p (Ror i) [a]          = rotate False i a (hd "Ror" opArgs)
-        p Shl     [a, i]       = shift  True  (getShiftAmnt i opArgs) a -- The order of i/a being reversed here is
-        p Shr     [a, i]       = shift  False (getShiftAmnt i opArgs) a -- intentional and historical (from the days when Shl/Shr had a constant parameter.)
-        p Not [a]              = case kindOf (hd "Not" opArgs) of
-                                   -- be careful about booleans, bitwise complement is not correct for them!
-                                   KBool -> text "!" P.<> a
-                                   _     -> text "~" P.<> a
-        p Ite [a, b, c] = a <+> text "?" <+> b <+> text ":" <+> c
-        p (LkUp (t, k, _, len) ind def) []
-          | not rtc                    = lkUp -- ignore run-time-checks per user request
-          | needsCheckL && needsCheckR = cndLkUp checkBoth
-          | needsCheckL                = cndLkUp checkLeft
-          | needsCheckR                = cndLkUp checkRight
-          | True                       = lkUp
-          where [index, defVal] = map (showSV cfg consts) [ind, def]
-
-                lkUp = text "table" P.<> int t P.<> brackets (showSV cfg consts ind)
-                cndLkUp cnd = cnd <+> text "?" <+> defVal <+> text ":" <+> lkUp
-
-                checkLeft  = index <+> text "< 0"
-                checkRight = index <+> text ">=" <+> int len
-                checkBoth  = parens (checkLeft <+> text "||" <+> checkRight)
-
-                canOverflow True  sz = (2::Integer)^(sz-1)-1 >= fromIntegral len
-                canOverflow False sz = (2::Integer)^sz    -1 >= fromIntegral len
-
-                (needsCheckL, needsCheckR) = case k of
-                                               KBool           -> (False, canOverflow False (1::Int))
-                                               KBounded sg sz  -> (sg, canOverflow sg sz)
-                                               KReal           -> die "array index with real value"
-                                               KFloat          -> die "array index with float value"
-                                               KDouble         -> die "array index with double value"
-                                               KFP{}           -> die "array index with arbitrary float value"
-                                               KRational       -> die "array index with rational value"
-                                               KString         -> die "array index with string value"
-                                               KChar           -> die "array index with character value"
-                                               KUnbounded      -> case cgInteger cfg of
-                                                                    Nothing -> (True, True) -- won't matter, it'll be rejected later
-                                                                    Just i  -> (True, canOverflow True i)
-                                               KList     s     -> die $ "List sort "   ++ show s
-                                               KSet      s     -> die $ "Set sort "    ++ show s
-                                               KTuple    s     -> die $ "Tuple sort "  ++ show s
-                                               KMaybe    ek    -> die $ "Maybe sort "  ++ show ek
-                                               KEither   k1 k2 -> die $ "Either sort " ++ show (k1, k2)
-                                               KArray    k1 k2 -> die $ "Array  sort " ++ show (k1, k2)
-                                               KUserSort s _   -> die $ "Uninterpreted sort: " ++ s
-
-        -- Div/Rem should be careful on 0, in the SBV world x `div` 0 is 0, x `rem` 0 is x
-        -- NB: Quot is supposed to truncate toward 0; Not clear to me if C guarantees this behavior.
-        -- Brief googling suggests C99 does indeed truncate toward 0, but other C compilers might differ.
-        p Quot [a, b] = let k = kindOf (hd "Quot" opArgs)
-                            z = mkConst cfg $ mkConstCV k (0::Integer)
-                        in protectDiv0 k "/" z a b
-        p Rem  [a, b] = protectDiv0 (kindOf (hd "Rem" opArgs)) "%" a a b
-        p UNeg [a]    = parens (text "-" <+> a)
-        p Abs  [a]    = let f KFloat             = text "fabsf" P.<> parens a
-                            f KDouble            = text "fabs"  P.<> parens a
-                            f (KBounded False _) = text "/* unsigned, skipping call to abs */" <+> a
-                            f (KBounded True 32) = text "labs"  P.<> parens a
-                            f (KBounded True 64) = text "llabs" P.<> parens a
-                            f KUnbounded         = case cgInteger cfg of
-                                                     Nothing -> f $ KBounded True 32 -- won't matter, it'll be rejected later
-                                                     Just i  -> f $ KBounded True i
-                            f KReal              = case cgReal cfg of
-                                                     Nothing           -> f KDouble -- won't matter, it'll be rejected later
-                                                     Just CgFloat      -> f KFloat
-                                                     Just CgDouble     -> f KDouble
-                                                     Just CgLongDouble -> text "fabsl" P.<> parens a
-                            f _                  = text "abs" P.<> parens a
-                        in f (kindOf (hd "Abs" opArgs))
-        -- for And/Or, translate to boolean versions if on boolean kind
-        p And [a, b] | kindOf (hd "And" opArgs) == KBool = a <+> text "&&" <+> b
-        p Or  [a, b] | kindOf (hd "Or"  opArgs) == KBool = a <+> text "||" <+> b
-        p o [a, b]
-          | Just co <- lookup o cBinOps
-          = a <+> text co <+> b
-
-        p Implies [a, b] | kindOf (hd "Implies" opArgs) == KBool = parens (text "!" P.<> a <+> text "||" <+> b)
-
-        p NotEqual xs = mkDistinct xs
-        p o args = die $ "Received operator " ++ show o ++ " applied to " ++ show args
-
-        -- generate a pairwise inequality check
-        mkDistinct args = fsep $ andAll $ walk args
-          where walk []     = []
-                walk (e:es) = map (pair e) es ++ walk es
-
-                pair e1 e2  = parens (e1 <+> text "!=" <+> e2)
-
-                -- like punctuate, but more spacing
-                andAll []     = []
-                andAll (d:ds) = go d ds
-                     where go d' [] = [d']
-                           go d' (e:es) = (d' <+> text "&&") : go e es
-
-        -- Div0 needs to protect, but only when the arguments are not float/double. (Div by 0 for those are well defined to be Inf/NaN etc.)
-        protectDiv0 k divOp def a b = case k of
-                                        KFloat  -> res
-                                        KDouble -> res
-                                        _       -> wrap
-           where res  = a <+> text divOp <+> b
-                 wrap = parens (b <+> text "== 0") <+> text "?" <+> def <+> text ":" <+> parens res
-
-        shift toLeft i a = a <+> text cop <+> i
-          where cop | toLeft = "<<"
-                    | True   = ">>"
-
-        rotate toLeft i a s
-          | i < 0   = rotate (not toLeft) (-i) a s
-          | i == 0  = a
-          | True    = case kindOf s of
-                        KBounded True _             -> tbd $ "Rotation of signed quantities: " ++ show (toLeft, i, s)
-                        KBounded False sz | i >= sz -> rotate toLeft (i `mod` sz) a s
-                        KBounded False sz           ->     parens (a <+> text cop  <+> int i)
-                                                      <+> text "|"
-                                                      <+> parens (a <+> text cop' <+> int (sz - i))
-                        KUnbounded                  -> shift toLeft (int i) a -- For SInteger, rotate is the same as shift in Haskell
-                        _                           -> tbd $ "Rotation for unbounded quantity: " ++ show (toLeft, i, s)
-          where (cop, cop') | toLeft = ("<<", ">>")
-                            | True   = (">>", "<<")
-
-        -- TBD: below we only support the values for extract that are "easy" to implement. These should cover
-        -- almost all instances actually generated by SBV, however.
-        extract hi lo i a  -- Isolate the bit-extraction case
-          | hi == lo, KBounded _ sz <- kindOf i, hi < sz, hi >= 0
-          = if hi == 0
-            then text "(SBool)" <+> parens (a <+> text "& 1")
-            else text "(SBool)" <+> parens (parens (a <+> text ">>" <+> int hi) <+> text "& 1")
-        extract hi lo i a
-          | srcSize `notElem` [64, 32, 16]
-          = bad "Unsupported source size"
-          | (hi + 1) `mod` 8 /= 0 || lo `mod` 8 /= 0
-          = bad "Unsupported non-byte-aligned extraction"
-          | tgtSize < 8 || tgtSize `mod` 8 /= 0
-          = bad "Unsupported target size"
-          | True
-          = text cast <+> shifted
-          where bad why    = tbd $ "extract with " ++ show (hi, lo, k, i) ++ " (Reason: " ++ why ++ ".)"
-
-                k          = kindOf i
-                srcSize    = intSizeOf k
-                tgtSize    = hi - lo + 1
-                signChange = srcSize == tgtSize
-
-                cast
-                  | signChange && hasSign k = "(SWord" ++ show srcSize ++ ")"
-                  | signChange              = "(SInt"  ++ show srcSize ++ ")"
-                  | True                    = "(SWord" ++ show tgtSize ++ ")"
-
-                shifted
-                  | lo == 0 = a
-                  | True    = parens (a <+> text ">>" <+> int lo)
-
-        -- TBD: ditto here for join, just like extract above
-        join (i, j, a, b) = case (kindOf i, kindOf j) of
-                              (KBounded False  8, KBounded False  8) -> parens (parens (text "(SWord16)" <+> a) <+> text "<< 8")  <+> text "|" <+> parens (text "(SWord16)" <+> b)
-                              (KBounded False 16, KBounded False 16) -> parens (parens (text "(SWord32)" <+> a) <+> text "<< 16") <+> text "|" <+> parens (text "(SWord32)" <+> b)
-                              (KBounded False 32, KBounded False 32) -> parens (parens (text "(SWord64)" <+> a) <+> text "<< 32") <+> text "|" <+> parens (text "(SWord64)" <+> b)
-                              (k1,                k2)                -> tbd $ "join with " ++ show ((k1, i), (k2, j))
-
--- same as doubleQuotes, except we have to make sure there are no line breaks..
--- Otherwise breaks the generated code.. sigh
-printQuotes :: Doc -> Doc
-printQuotes d = text $ '"' : ppSameLine d ++ "\""
-
--- Remove newlines.. Useful when generating Makefile and such
-ppSameLine :: Doc -> String
-ppSameLine = trim . render
- where trim ""        = ""
-       trim ('\n':cs) = ' ' : trim (dropWhile isSpace cs)
-       trim (c:cs)    = c   : trim cs
-
--- Align a bunch of docs to occupy the exact same length by padding in the left by space
--- this is ugly and inefficient, but easy to code..
-align :: [Doc] -> [Doc]
-align ds = map (text . pad) ss
-  where ss    = map render ds
-        l     = maximum (0 : map length ss)
-        pad s = replicate (l - length s) ' ' ++ s
-
--- | Merge a bunch of bundles to generate code for a library. For the final
--- config, we simply return the first config we receive, or the default if none.
-mergeToLib :: String -> [(CgConfig, CgPgmBundle)] -> (CgConfig, CgPgmBundle)
-mergeToLib libName cfgBundles
-  | length nubKinds /= 1
-  = error $  "Cannot merge programs with differing SInteger/SReal mappings. Received the following kinds:\n"
-          ++ unlines (map show nubKinds)
-  | True
-  = (finalCfg, CgPgmBundle bundleKind $ sources ++ libHeader : [libDriver | anyDriver] ++ [libMake | anyMake])
-  where bundles     = map snd cfgBundles
-        kinds       = [k | CgPgmBundle k _ <- bundles]
-        nubKinds    = nub kinds
-        bundleKind  = case nubKinds of
-                        bk:_ -> bk
-                        []   -> error "Data.SBV.C: Impossible happened: mergeLibs: kinds ended up being empty!"
-        files       = concat [fs | CgPgmBundle _ fs <- bundles]
-        sigs        = concat [ss | (_, (CgHeader ss, _)) <- files]
-        anyMake     = not (null [() | (_, (CgMakefile{}, _)) <- files])
-        drivers     = [ds | (_, (CgDriver, ds)) <- files]
-        anyDriver   = not (null drivers)
-        mkFlags     = nub (concat [xs | (_, (CgMakefile xs, _)) <- files])
-        sources     = [(f, (CgSource, [pre, libHInclude, post])) | (f, (CgSource, [pre, _, post])) <- files]
-        sourceNms   = map fst sources
-        libHeader   = (libName ++ ".h", (CgHeader sigs, [genHeader bundleKind libName sigs empty]))
-        libHInclude = text "#include" <+> text (show (libName ++ ".h"))
-        libMake     = ("Makefile", (CgMakefile mkFlags, [genLibMake anyDriver libName sourceNms mkFlags]))
-        libDriver   = (libName ++ "_driver.c", (CgDriver, mergeDrivers libName libHInclude (zip (map takeBaseName sourceNms) drivers)))
-        finalCfg    = case cfgBundles of
-                        []         -> defaultCgConfig
-                        ((c, _):_) -> c
-
--- | Create a Makefile for the library
-genLibMake :: Bool -> String -> [String] -> [String] -> Doc
-genLibMake ifdr libName fs ldFlags = foldr1 ($$) [l | (True, l) <- lns]
- where ifld = not (null ldFlags)
-       ld | ifld = text "${LDFLAGS}"
-          | True = empty
-       lns = [ (True, text "# Makefile for" <+> nm P.<> text ". Automatically generated by SBV. Do not edit!")
-             , (True,  text "")
-             , (True,  text "# include any user-defined .mk file in the current directory.")
-             , (True,  text "-include *.mk")
-             , (True,  text "")
-             , (True,  text "CC?=gcc")
-             , (True,  text "CCFLAGS?=-Wall -O3 -DNDEBUG -fomit-frame-pointer")
-             , (ifld,  text "LDFLAGS?=" P.<> text (unwords ldFlags))
-             , (True,  text "AR?=ar")
-             , (True,  text "ARFLAGS?=cr")
-             , (True,  text "")
-             , (not ifdr,  text ("all: " ++ liba))
-             , (ifdr,      text ("all: " ++ unwords [liba, libd]))
-             , (True,  text "")
-             , (True,  text liba P.<> text (": " ++ unwords os))
-             , (True,  text "\t${AR} ${ARFLAGS} $@ $^")
-             , (True,  text "")
-             , (ifdr,  text libd P.<> text (": " ++ unwords [libd ++ ".c", libh]))
-             , (ifdr,  text ("\t${CC} ${CCFLAGS} $< -o $@ " ++ liba) <+> ld)
-             , (ifdr,  text "")
-             , (True,  vcat (zipWith mkObj os fs))
-             , (True,  text "clean:")
-             , (True,  text "\trm -f *.o")
-             , (True,  text "")
-             , (True,  text "veryclean: clean")
-             , (not ifdr,  text "\trm -f" <+> text liba)
-             , (ifdr,      text "\trm -f" <+> text (unwords [liba, libd]))
-             , (True,  text "")
-             ]
-       nm = text libName
-       liba = libName ++ ".a"
-       libh = libName ++ ".h"
-       libd = libName ++ "_driver"
-       os   = map (`replaceExtension` ".o") fs
-       mkObj o f =  text o P.<> text (": " ++ unwords [f, libh])
-                 $$ text "\t${CC} ${CCFLAGS} -c $< -o $@"
-                 $$ text ""
-
--- | Create a driver for a library
-mergeDrivers :: String -> Doc -> [(FilePath, [Doc])] -> [Doc]
-mergeDrivers libName inc ds = pre : concatMap mkDFun ds ++ [callDrivers (map fst ds)]
-  where pre =  text "/* Example driver program for" <+> text libName P.<> text ". */"
-            $$ text "/* Automatically generated by SBV. Edit as you see fit! */"
-            $$ text ""
-            $$ text "#include <stdio.h>"
-            $$ inc
-        mkDFun (f, [_pre, _header, body, _post]) = [header, body, post]
-           where header =  text ""
-                        $$ text ("void " ++ f ++ "_driver(void)")
-                        $$ text "{"
-                 post   =  text "}"
-        mkDFun (f, _) = die $ "mergeDrivers: non-conforming driver program for " ++ show f
-        callDrivers fs =   text ""
-                       $$  text "int main(void)"
-                       $$  text "{"
-                       $+$ nest 2 (vcat (map call fs))
-                       $$  nest 2 (text "return 0;")
-                       $$  text "}"
-        call f =  text psep
-               $$ text ptag
-               $$ text psep
-               $$ text (f ++ "_driver();")
-               $$ text ""
-           where tag  = "** Driver run for " ++ f ++ ":"
-                 ptag = "printf(\"" ++ tag ++ "\\n\");"
-                 lsep = replicate (length tag) '='
-                 psep = "printf(\"" ++ lsep ++ "\\n\");"
-
--- Does this operation with this result kind require an LD flag?
-getLDFlag :: (Op, Kind) -> [String]
-getLDFlag (o, k) = flag o
-  where math = ["-lm"]
-
-        flag (IEEEFP FP_Cast{})                                     = math
-        flag (IEEEFP fop)       | fop `elem` requiresMath           = math
-        flag Abs                | k `elem` [KFloat, KDouble, KReal] = math
-        flag _                                                      = []
-
-        requiresMath = [ FP_Abs
-                       , FP_FMA
-                       , FP_Sqrt
-                       , FP_Rem
-                       , FP_Min
-                       , FP_Max
-                       , FP_RoundToIntegral
-                       , FP_ObjEqual
-                       , FP_IsSubnormal
-                       , FP_IsInfinite
-                       , FP_IsNaN
-                       , FP_IsNegative
-                       , FP_IsPositive
-                       , FP_IsNormal
-                       , FP_IsZero
-                       ]
-
-{- HLint ignore module "Redundant lambda" -}
+-- Default SBV-to-C compiler. This module deliberately remains a thin facade
+-- so the implementation can coexist with the compatibility backend in
+-- "Data.SBV.Compilers.C.Legacy".
+--
+-- == Execution model and supported values
+--
+-- The compiler evaluates a finite symbolic expression graph; it does not
+-- invoke an SMT solver at run time. Generated standalone programs and static
+-- libraries support:
+--
+-- * Booleans and signed or unsigned bit-vectors of any positive width.
+-- * Exact GMP-backed integers, rational-valued reals, and rationals. The
+--   historical bounded integer and native floating-point real mappings remain
+--   available through @cgIntegerSize@ and @cgSRealType@.
+-- * Native and arbitrary-format IEEE floating point. Arbitrary formats and
+--   directed native rounding use LibBF.
+-- * Characters, strings, lists, finite or cofinite sets, tuples, and concrete
+--   algebraic datatypes, including recursive datatypes.
+-- * Finite lookup tables and persistent arrays created from constants,
+--   writes, retained lambdas, or caller-provided lookup callbacks. Direct
+--   array equality enumerates supported finite key domains, subject to
+--   @cgArrayEqualityLimit@ (256 keys by default).
+-- * First-order @smtFunction@ definitions and SBV's firstified
+--   @smtHOFunction@ specializations, including recursive and mutually
+--   recursive groups, closed nested array lambdas, explicit closure
+--   environments, hard constraints as executable preconditions, scalar and
+--   grouped results, and multi-function static libraries.
+-- * Regular-expression membership and language equality, compiled using bounded
+--   automata without additional dependencies. Generation budgets are configurable;
+--   successfully generated matchers accept strings of arbitrary length.
+--
+-- Numeric lowering includes exact-width arithmetic, comparisons, shifts,
+-- rotations, joins and extractions, overflow predicates, conversions,
+-- divisibility, and integer exponentiation. Mapped reals additionally support
+-- the C @libm@ transcendental operations. Exact rational reals reject those
+-- operations because their results cannot in general be represented by GMP
+-- rationals; select @cgSRealType@ when an approximation is acceptable.
+--
+-- == Deliberate boundaries
+--
+-- Quantifiers, special solver relations, uninterpreted sorts, and soft
+-- constraints are rejected. General extensional array equality and arrays nested
+-- in compared values remain unsupported. Array lambdas must be closed; capturing
+-- outer symbolic values is rejected during generation. The C backend compiles
+-- higher-order uses after SBV has firstified them; it does not expose symbolic
+-- functions as runtime C values.
+--
+-- Import "Data.SBV.Compilers.C.Legacy" to retain the previous compiler while
+-- migrating code that encounters one of these boundaries.
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Data.SBV.Compilers.C
+  ( compileToC
+  , compileToCLib
+  , compileToC'
+  , compileToCLib'
+  ) where
+
+import Data.SBV.Compilers.C.Backend (compileToC, compileToC', compileToCLib, compileToCLib')
diff --git a/Data/SBV/Compilers/C/ADT.hs b/Data/SBV/Compilers/C/ADT.hs
new file mode 100644
--- /dev/null
+++ b/Data/SBV/Compilers/C/ADT.hs
@@ -0,0 +1,1083 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Data.SBV.Compilers.C.ADT
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Algebraic-data-type lowering for the SBV-to-C compiler.
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Data.SBV.Compilers.C.ADT
+  ( adtKinds
+  , resolveADTReferences
+  , adtCType
+  , adtForwardTypeDecls
+  , adtTypeDecls
+  , adtTypeDeclsFor
+  , adtDeclarationDependencies
+  , adtEqualityRuntimeDecls
+  , adtEqualityRuntime
+  , adtOwnershipTypePrototypes
+  , adtOwnershipTypeDecls
+  , adtOwnedCloneName
+  , adtOwnedReleaseName
+  , adtDriverInit
+  , adtValue
+  , adtConst
+  , adtExpr
+  , adtUsesExact
+  , adtNeedsOwnership
+  , adtIsRecursive
+  , adtDriverValue
+  , adtPrint
+  , adtPrintHelpers
+  , adtConstructors
+  ) where
+
+import qualified Data.Graph as DG
+import Data.List                       (find, nub)
+import qualified Data.Set as Set
+import qualified Data.Text as T
+
+import Text.PrettyPrint.HughesPJ
+import qualified Text.PrettyPrint.HughesPJ as P ((<>))
+
+import Data.SBV.Compilers.C.Array      (arrayStoredLoad, arrayStoredValue)
+import Data.SBV.Compilers.C.BV         (isWideBV, wideBVEqual)
+import Data.SBV.Compilers.C.FP         (arbitraryFPEqual, arbitraryFPObjectEqual, nativeFPObjectEqual)
+import Data.SBV.Compilers.C.GMP        (gmpDriverAssign, gmpFunctionName, gmpOutputType, isExactGMPKind)
+import Data.SBV.Compilers.C.List       ( listClone
+                                       , listDriverClear
+                                       , listDriverInit
+                                       , listEqual
+                                       , listNeedsDriverInit
+                                       , listRelease
+                                       )
+import Data.SBV.Compilers.C.Lowering   (CLowering(..), expressionLowering)
+import Data.SBV.Compilers.C.Syntax     (cUnusedAttribute, cCommentText)
+import Data.SBV.Compilers.C.Set        ( setClone
+                                       , setDriverClear
+                                       , setDriverInit
+                                       , setEqual
+                                       , setNeedsDriverInit
+                                       , setRelease
+                                       )
+import Data.SBV.Compilers.C.Tuple      ( tupleOwnedInitName
+                                       , tupleOwnedReleaseName
+                                       , tupleOwnedSetName
+                                       , tupleNeedsOwnership
+                                       )
+import Data.SBV.Compilers.C.Types      (isConcreteADT, adtCType, elementCType, tupleFieldName, adtOwnedInitName, adtOwnedSetName, adtOwnedCloneName, adtOwnedReleaseName, adtEqualName)
+import Data.SBV.Compilers.C.Value      (byValueEqual, managedValueClone, managedValueRelease, valueNeedsOwnership)
+import Data.SBV.Compilers.CodeGen      (CgConfig)
+import Data.SBV.Core.Data
+import Data.SBV.Core.Kind              (expandKinds, substituteADTVars)
+import Data.SBV.Core.Symbolic          (ADTOp(..))
+
+-- | A concrete ADT field and whether its declaration is a recursive pointer
+-- edge within the same strongly connected component.
+data ADTField = ADTField Kind Bool
+
+-- | Return the used concrete, non-built-in ADT kinds in dependency order.
+-- The first set supplies every registered ADT template and the second supplies
+-- the kinds actually reached by the program. References through 'KApp' are
+-- accepted for both acyclic and recursive declarations. Recursive components
+-- are kept adjacent so their C layouts can use forward-declared pointer edges.
+adtKinds :: Set.Set Kind -> Set.Set Kind -> [Kind]
+adtKinds registeredKinds usedKinds = concatMap orderedComponent (DG.stronglyConnComp dependencyNodes)
+ where registeredADTs = nub (filter isConcreteADT (Set.toAscList registeredKinds))
+       usedADTs       = nub (filter isConcreteADT (Set.toAscList usedKinds))
+       adts           = closeRegistry usedADTs
+
+       dependencyNodes = [(kind, adtKey kind, dependencies kind) | kind <- adts]
+
+       closeRegistry current
+         | length expanded == length current = current
+         | True                              = closeRegistry expanded
+        where referenced = [ application
+                           | kind <- current
+                           , application@KApp{} <- referenceApplications kind
+                           ]
+              expanded = nub (current ++ map (resolveADTReferences registeredADTs) referenced)
+
+       referenceApplications (KADT typeName parameters constructors) =
+         [ application
+         | (_, fields) <- constructors
+         , field <- fields
+         , application@KApp{} <- expandKinds (substituteADTVars typeName parameters field)
+         ]
+       referenceApplications kind = error $ "SBV->C: Expected an ADT kind, received " ++ show kind
+
+       dependencies kind =
+         [ (referencedName, referencedArguments)
+         | KApp referencedName referencedArguments <- referenceApplications kind
+         ]
+
+       orderedComponent (DG.AcyclicSCC kind)           = [kind]
+       orderedComponent (DG.CyclicSCC recursiveKinds) = recursiveKinds
+
+       adtKey (KADT typeName parameters _) = (typeName, map snd parameters)
+       adtKey kind = error $ "SBV->C: Expected an ADT kind, received " ++ show kind
+
+-- | Emit forward declarations that permit collection descriptors to refer to
+-- ADT element types before their tagged-union layouts are complete.
+adtForwardTypeDecls :: [Kind] -> Doc
+adtForwardTypeDecls []   = empty
+adtForwardTypeDecls adts = text . unlines $ concatMap forwardDeclaration adts
+ where forwardDeclaration kind =
+         [ "#ifndef " ++ adtForwardGuard kind
+         , "#define " ++ adtForwardGuard kind
+         , "typedef struct " ++ adtCType kind ++ " " ++ adtCType kind ++ ";"
+         , "#endif"
+         , ""
+         ]
+
+-- | Emit public tagged-union declarations for all ADT kinds used by a program.
+adtTypeDecls :: CgConfig -> [Kind] -> Doc
+adtTypeDecls cfg adts = adtTypeDeclsFor cfg adts adts
+
+-- | Emit selected public tagged-union declarations using the complete ADT
+-- registry to resolve constructor fields. This supports dependency-ordered
+-- interleaving with tuple declarations.
+adtTypeDeclsFor :: CgConfig -> [Kind] -> [Kind] -> Doc
+adtTypeDeclsFor _ _        []           = empty
+adtTypeDeclsFor _ registry declarations = text . unlines $
+     [ "/* Algebraic data types. Recursive fields form finite, acyclic pointer graphs. */"
+     , "/* Inputs borrow these graphs; owned outputs and returns must be released. */"
+     , cUnusedAttribute
+     , ""
+     ]
+  ++ concatMap forwardDeclaration declarations
+  ++ concatMap declaration declarations
+  ++ dereferenceDeclarations
+ where forwardDeclaration kind =
+          [ "#ifndef " ++ adtForwardGuard kind
+          , "#define " ++ adtForwardGuard kind
+          , "typedef struct " ++ adtCType kind ++ " " ++ adtCType kind ++ ";"
+          , "#endif"
+          , ""
+          ]
+
+       declaration kind =
+            [ "#ifndef " ++ adtGuard kind
+            , "#define " ++ adtGuard kind
+            , "typedef enum {"
+            ]
+         ++ zipWith (enumEntry kind) [1 :: Int ..] constructors
+         ++ [ "} " ++ adtTagCType kind ++ ";"
+            , "struct " ++ adtCType kind ++ " {"
+            , "  " ++ adtTagCType kind ++ " tag;"
+            ]
+         ++ payloadDeclaration kind
+         ++ [ "};"
+            , "#endif"
+            , ""
+            ]
+        where constructors = adtConstructorFields registry kind
+
+       enumEntry kind index _ = "  " ++ adtTagName kind index ++ " = " ++ show (index - 1)
+                             ++ if index == length (adtConstructorFields registry kind) then "" else ","
+
+       payloadDeclaration kind
+         | null populated = []
+         | True           = ["  union {"] ++ concatMap constructorPayload populated ++ ["  } payload;"]
+        where populated = [ (index, fields)
+                          | (index, (_, fields)) <- zip [1 :: Int ..] (adtConstructorFields registry kind)
+                          , not (null fields)
+                          ]
+              constructorPayload (constructorIndex, fields) =
+                   ["    struct {"]
+                ++ zipWith fieldDeclaration [1 :: Int ..] fields
+                ++ ["    } " ++ adtConstructorMember constructorIndex ++ ";"]
+              fieldDeclaration fieldIndex field = "      " ++ adtFieldCType field ++ " " ++ adtFieldName fieldIndex ++ ";"
+
+       recursiveKinds = filter (adtIsRecursive registry) declarations
+
+       dereferenceDeclarations = concatMap dereferenceDeclaration recursiveKinds
+
+       dereferenceDeclaration kind =
+         [ "#ifndef " ++ dereferenceGuard kind
+         , "#define " ++ dereferenceGuard kind
+         , "static inline SBV_CGEN_UNUSED " ++ adtCType kind ++ " " ++ adtDereferenceName kind
+        ++ "(const " ++ adtCType kind ++ " *value)"
+         , "{"
+         , "  if (value == NULL) abort();"
+         , "  return *value;"
+         , "}"
+         , "#endif"
+         , ""
+         ]
+
+-- | Return complete by-value tuple and ADT dependencies of one ADT layout.
+-- Recursive pointer fields need only a forward declaration and are excluded.
+adtDeclarationDependencies :: [Kind] -> Kind -> [Kind]
+adtDeclarationDependencies adts kind = nub
+  [ fieldKind
+  | (_, fields) <- adtConstructorFields adts kind
+  , ADTField fieldKind recursive <- fields
+  , not recursive
+  , isTuple fieldKind || isConcreteADT fieldKind
+  ]
+
+-- | Emit forward declarations for the ADT equality helpers used by collection
+-- element comparisons.
+adtEqualityRuntimeDecls :: [Kind] -> Doc
+adtEqualityRuntimeDecls []   = empty
+adtEqualityRuntimeDecls adts = text . unlines $ concatMap prototypes [False, True]
+ where prototypes strong =
+         [ "static SBV_CGEN_UNUSED bool " ++ adtEqualName strong kind
+        ++ "(" ++ adtCType kind ++ " left, " ++ adtCType kind ++ " right);"
+         | kind <- adts
+         ] ++ [""]
+
+-- | Emit private structural-equality helpers for concrete ADTs. These
+-- definitions follow the collection runtimes so managed fields can reuse the
+-- same list and set equality semantics as top-level expressions.
+adtEqualityRuntime :: CgConfig -> [Kind] -> Doc
+adtEqualityRuntime cfg adts
+  | null adts = empty
+  | True      = text . unlines $ concatMap definitions [False, True]
+ where definitions strong = concatMap (definition strong) adts
+
+       definition strong kind =
+          [ "static SBV_CGEN_UNUSED bool " ++ adtEqualName strong kind
+         ++ "(" ++ adtCType kind ++ " left, " ++ adtCType kind ++ " right)"
+          , "{"
+          , "  if (left.tag != right.tag) return false;"
+          , "  switch (left.tag) {"
+          ]
+        ++ concatMap (equalityCase strong kind) (zip [1 :: Int ..] (adtConstructorFields adts kind))
+        ++ [ "    default: abort();"
+           , "  }"
+           , "}"
+           , ""
+           ]
+
+       equalityCase strong kind (constructorIndex, (_, fields)) =
+          ["    case " ++ adtTagName kind constructorIndex ++ ":"]
+        ++ concatMap (nullChecks constructorIndex) (zip [1 :: Int ..] fields)
+        ++ ["      return " ++ render (andExpressions comparisons) ++ ";"]
+        where comparisons = zipWith (compareField strong constructorIndex) [1 :: Int ..] fields
+
+       nullChecks constructorIndex (fieldIndex, ADTField _ True) =
+         [ "      if (" ++ render (adtField (text "left") constructorIndex fieldIndex) ++ " == NULL"
+        ++ " || " ++ render (adtField (text "right") constructorIndex fieldIndex) ++ " == NULL) abort();"
+         ]
+       nullChecks _ _ = []
+
+       compareField strong constructorIndex fieldIndex (ADTField fieldKind recursive)
+         | recursive = text (adtEqualName strong fieldKind)
+                    P.<> parens (fsep (punctuate comma [deref "left", deref "right"]))
+         | True      = adtFieldEqual cfg adts strong fieldKind
+                         (adtField (text "left")  constructorIndex fieldIndex)
+                         (adtField (text "right") constructorIndex fieldIndex)
+        where deref side = text "*" P.<> parens (adtField (text side) constructorIndex fieldIndex)
+
+-- | Emit forward declarations for the uniform ADT ownership helpers. These
+-- precede tuple helper definitions so tuples and ADTs can contain one another
+-- without imposing an ownership-definition order.
+adtOwnershipTypePrototypes :: [Kind] -> Doc
+adtOwnershipTypePrototypes []   = empty
+adtOwnershipTypePrototypes adts = text . unlines $ concatMap prototypes adts
+ where prototypes kind =
+         [ "static inline SBV_CGEN_UNUSED void " ++ adtOwnedInitName kind
+        ++ "(" ++ adtCType kind ++ " *value, " ++ adtTagCType kind ++ " tag);"
+         , "static inline SBV_CGEN_UNUSED void " ++ adtOwnedReleaseName kind
+        ++ "(" ++ adtCType kind ++ " *value);"
+         , "static inline SBV_CGEN_UNUSED void " ++ adtOwnedSetName kind
+        ++ "(" ++ adtCType kind ++ " *target, " ++ adtCType kind ++ " source);"
+         , "static inline SBV_CGEN_UNUSED " ++ adtCType kind ++ " " ++ adtOwnedCloneName kind
+        ++ "(" ++ adtCType kind ++ " source);"
+         , ""
+         ]
+
+-- | Emit public ownership-helper definitions for concrete ADTs. Inputs borrow
+-- their field storage. Cloned values own all managed fields of the active
+-- constructor and must be released with 'adtOwnedReleaseName'; by-value ADTs
+-- use the same uniform protocol so collections need no representation-specific
+-- branch.
+adtOwnershipTypeDecls :: CgConfig -> [Kind] -> Doc
+adtOwnershipTypeDecls cfg adts
+  | null adts = empty
+  | True      = text . unlines $ concatMap declaration adts
+ where declaration kind =
+          [ "#ifndef " ++ ownershipGuard
+          , "#define " ++ ownershipGuard
+          , "/* Deep-ownership helpers for " ++ adtCType kind ++ ". */"
+          , "/* Owned values have unique ownership; clone before copying and release every owner. */"
+          , initSignature
+          , "{"
+          , "  if (value == NULL) abort();"
+          , "  memset(value, 0, sizeof *value);"
+          , "  value->tag = tag;"
+          , "  switch (tag) {"
+          ]
+          ++ concatMap (constructorCase initializeField kind) indexedConstructors
+          ++ [ "    default: abort();"
+          , "  }"
+          , "}"
+          , ""
+          , releaseSignature
+          , "{"
+          , "  if (value == NULL) return;"
+          , "  switch (value->tag) {"
+          ]
+          ++ concatMap (constructorCase releaseField kind) indexedConstructors
+          ++ [ "    default: abort();"
+          , "  }"
+          , "  memset(value, 0, sizeof *value);"
+          , "}"
+          , ""
+          , setSignature
+          , "{"
+          , "  if (target == NULL) abort();"
+          , "  if (target->tag != source.tag) {"
+          , "    " ++ adtOwnedReleaseName kind ++ "(target);"
+          , "    " ++ adtOwnedInitName kind ++ "(target, source.tag);"
+          , "  }"
+          , "  switch (source.tag) {"
+          ]
+          ++ concatMap (constructorCase setField kind) indexedConstructors
+          ++ [ "    default: abort();"
+          , "  }"
+          , "}"
+          , ""
+          , cloneSignature
+          , "{"
+          , "  " ++ adtCType kind ++ " result;"
+          , "  " ++ adtOwnedInitName kind ++ "(&result, source.tag);"
+          , "  " ++ adtOwnedSetName kind ++ "(&result, source);"
+          , "  return result;"
+          , "}"
+          , "#endif"
+          , ""
+         ]
+         where ownershipGuard = adtCType kind ++ "_OWNERSHIP_DEFINED"
+
+               initSignature = "static inline SBV_CGEN_UNUSED void "
+                            ++ adtOwnedInitName kind
+                            ++ "(" ++ adtCType kind ++ " *value, " ++ adtTagCType kind ++ " tag)"
+
+               releaseSignature = "static inline SBV_CGEN_UNUSED void "
+                               ++ adtOwnedReleaseName kind
+                               ++ "(" ++ adtCType kind ++ " *value)"
+
+               setSignature = "static inline SBV_CGEN_UNUSED void "
+                           ++ adtOwnedSetName kind
+                           ++ "(" ++ adtCType kind ++ " *target, " ++ adtCType kind ++ " source)"
+
+               cloneSignature = "static inline SBV_CGEN_UNUSED "
+                             ++ adtCType kind ++ " " ++ adtOwnedCloneName kind
+                             ++ "(" ++ adtCType kind ++ " source)"
+
+               indexedConstructors = zip [1 :: Int ..] (adtConstructorFields adts kind)
+
+       constructorCase renderField kind (constructorIndex, (_, fields)) =
+          [ "    case " ++ adtTagName kind constructorIndex ++ ": {" ]
+          ++ concat (zipWith (renderField constructorIndex) [1 :: Int ..] fields)
+          ++ [ "      break;"
+          , "    }"
+          ]
+
+       initializeField constructorIndex fieldIndex (ADTField fieldKind recursive)
+         | recursive
+         = []
+         | isExactGMPKind cfg fieldKind
+         = let access  = ownedField "value->" constructorIndex fieldIndex
+               mutable = gmpOutputType fieldKind
+               local   = "field" ++ show constructorIndex ++ "_" ++ show fieldIndex
+           in [ "      " ++ mutable ++ " " ++ local ++ " = (" ++ mutable ++ ") malloc(sizeof(*" ++ local ++ "));"
+              , "      if (" ++ local ++ " == NULL) abort();"
+              , "      " ++ gmpFunctionName fieldKind "init" ++ "(" ++ local ++ ");"
+              , "      " ++ access ++ " = " ++ local ++ ";"
+              ]
+         | fieldKind == KString
+         = [ "      " ++ ownedField "value->" constructorIndex fieldIndex
+          ++ " = (SString) {NULL, 0, 0};"
+           ]
+         | isList fieldKind
+         = [ "      " ++ ownedField "value->" constructorIndex fieldIndex
+          ++ " = (" ++ elementCType fieldKind ++ ") {NULL, 0};"
+           ]
+         | isSet fieldKind
+         = [ "      " ++ ownedField "value->" constructorIndex fieldIndex
+          ++ " = (" ++ elementCType fieldKind ++ ") {NULL, 0, false};"
+           ]
+         | isArray fieldKind
+         = ["      " ++ ownedField "value->" constructorIndex fieldIndex ++ " = NULL;"]
+         | tupleNeedsOwnership cfg fieldKind
+         = [ "      " ++ tupleOwnedInitName fieldKind
+          ++ "(&" ++ ownedField "value->" constructorIndex fieldIndex ++ ");"
+           ]
+         | isConcreteADT fieldKind
+         , adtNeedsOwnership cfg adts fieldKind
+         = [ "      " ++ adtOwnedInitName fieldKind
+          ++ "(&" ++ ownedField "value->" constructorIndex fieldIndex
+          ++ ", " ++ adtTagName fieldKind 1 ++ ");"
+           ]
+         | True
+         = []
+
+       setField constructorIndex fieldIndex (ADTField fieldKind recursive)
+         | recursive
+         = [ "      " ++ adtCType fieldKind ++ " *" ++ copy
+          ++ " = (" ++ adtCType fieldKind ++ " *) malloc(sizeof *" ++ copy ++ ");"
+           , "      if (" ++ copy ++ " == NULL || " ++ source ++ " == NULL) abort();"
+           , "      *" ++ copy ++ " = " ++ adtOwnedCloneName fieldKind ++ "(*" ++ source ++ ");"
+           , "      if (" ++ target ++ " != NULL) {"
+           , "        " ++ adtOwnedReleaseName fieldKind ++ "(" ++ target ++ ");"
+           , "        free(" ++ target ++ ");"
+           , "      }"
+           , "      " ++ target ++ " = " ++ copy ++ ";"
+           ]
+         | isExactGMPKind cfg fieldKind
+         = [ "      " ++ gmpFunctionName fieldKind "set"
+          ++ "((" ++ gmpOutputType fieldKind ++ ") " ++ target ++ ", " ++ source ++ ");"
+           ]
+         | fieldKind == KString
+         = [ "      const SString " ++ copy
+          ++ " = " ++ render (managedValueClone fieldKind (text source)) ++ ";"
+           , "      " ++ render (managedValueRelease fieldKind (text ("&" ++ target)))
+           , "      " ++ target ++ " = " ++ copy ++ ";"
+           ]
+         | isList fieldKind
+         = [ "      const " ++ elementCType fieldKind ++ " " ++ copy
+          ++ " = " ++ render (listClone fieldKind (text source)) ++ ";"
+           , "      " ++ render (listRelease fieldKind (text target))
+           , "      " ++ target ++ " = " ++ copy ++ ";"
+           ]
+         | isSet fieldKind
+         = [ "      const " ++ elementCType fieldKind ++ " " ++ copy
+          ++ " = " ++ render (setClone fieldKind (text source)) ++ ";"
+           , "      " ++ render (setRelease fieldKind (text target))
+           , "      " ++ target ++ " = " ++ copy ++ ";"
+           ]
+         | isArray fieldKind
+         = [ "      " ++ elementCType fieldKind ++ " " ++ copy
+          ++ " = " ++ render (managedValueClone fieldKind (text source)) ++ ";"
+           , "      " ++ render (managedValueRelease fieldKind (text ("&" ++ target)))
+           , "      " ++ target ++ " = " ++ copy ++ ";"
+           ]
+         | tupleNeedsOwnership cfg fieldKind
+         = ["      " ++ tupleOwnedSetName fieldKind ++ "(&" ++ target ++ ", " ++ source ++ ");"]
+         | isConcreteADT fieldKind
+         , adtNeedsOwnership cfg adts fieldKind
+         = ["      " ++ adtOwnedSetName fieldKind ++ "(&" ++ target ++ ", " ++ source ++ ");"]
+         | True
+         = ["      " ++ target ++ " = " ++ source ++ ";"]
+        where target = ownedField "target->" constructorIndex fieldIndex
+              source = ownedField "source."  constructorIndex fieldIndex
+              copy   = "copy" ++ show constructorIndex ++ "_" ++ show fieldIndex
+
+       releaseField constructorIndex fieldIndex (ADTField fieldKind recursive)
+         | recursive
+         = [ "      if (" ++ access ++ " != NULL) {"
+           , "        " ++ adtOwnedReleaseName fieldKind ++ "(" ++ access ++ ");"
+           , "        free(" ++ access ++ ");"
+           , "      }"
+           ]
+         | isExactGMPKind cfg fieldKind
+         = [ "      if (" ++ access ++ " != NULL) {"
+           , "        " ++ gmpFunctionName fieldKind "clear" ++ "((" ++ gmpOutputType fieldKind ++ ") " ++ access ++ ");"
+           , "        free((void *) " ++ access ++ ");"
+           , "      }"
+           ]
+         | fieldKind == KString
+         = ["      " ++ render (managedValueRelease fieldKind (text ("&" ++ access)))]
+         | isList fieldKind
+         = ["      " ++ render (listRelease fieldKind (text access))]
+         | isSet fieldKind
+         = ["      " ++ render (setRelease fieldKind (text access))]
+         | isArray fieldKind
+         = ["      " ++ render (managedValueRelease fieldKind (text ("&" ++ access)))]
+         | tupleNeedsOwnership cfg fieldKind
+         = ["      " ++ tupleOwnedReleaseName fieldKind ++ "(&" ++ access ++ ");"]
+         | isConcreteADT fieldKind && adtNeedsOwnership cfg adts fieldKind
+         = ["      " ++ adtOwnedReleaseName fieldKind ++ "(&" ++ access ++ ");"]
+         | True
+         = []
+        where access = ownedField "value->" constructorIndex fieldIndex
+
+       ownedField root constructorIndex fieldIndex = root
+                                                    ++ "payload."
+                                                    ++ adtConstructorMember constructorIndex
+                                                    ++ "."
+                                                    ++ adtFieldName fieldIndex
+
+-- | Initialize a generated-driver ADT and populate its active constructor
+-- from a seed. Managed fields use the public owned-ADT storage protocol; other
+-- fields use the supplied scalar renderer. The statement renderer initializes
+-- retained values that occur through nested aggregate fields.
+adtDriverInit :: CgConfig -> [Kind] -> (Kind -> Integer -> Doc) -> (Kind -> String -> Integer -> Doc) -> Kind -> String -> Integer -> Doc
+adtDriverInit cfg adts renderValue initializeValue kind externalName seed
+  | isConcreteADT kind
+  , adtNeedsOwnership cfg adts kind
+  =  text (adtCType kind) <+> text externalName P.<> semi
+  $$ initialize kind (text externalName) constructorIndex
+  $$ vcat (assignConstructor maximumDepth kind (text externalName) externalName constructorIndex fields seed)
+  | True
+  = error $ "SBV->C: Expected an owned ADT, received " ++ show kind
+ where maximumDepth = max 3 (length adts + 1)
+       (constructorIndex, fields) = chooseConstructor maximumDepth kind seed
+
+       initialize fieldKind access index = text (adtOwnedInitName fieldKind)
+         P.<> parens (fsep (punctuate comma [text "&" P.<> parens access, text (adtTagName fieldKind index)]))
+         P.<> semi
+
+       release fieldKind access = text (adtOwnedReleaseName fieldKind)
+         P.<> parens (text "&" P.<> parens access)
+         P.<> semi
+
+       assignConstructor depth _ access accessName index fieldKinds fieldSeed = concat
+         (zipWith (assignField depth access accessName index) [1 :: Int ..] (zip fieldKinds [fieldSeed ..]))
+
+       assignField depth access accessName constructor fieldIndex (field, nestedSeed) =
+         assignAt depth field fieldAccess fieldName nestedSeed
+        where fieldAccess = adtField access constructor fieldIndex
+              fieldName   = accessName ++ "_constructor_" ++ show constructor ++ "_field_" ++ show fieldIndex
+
+       assignAt depth (ADTField fieldKind recursive) access accessName fieldSeed
+         | recursive
+         = let nestedDepth                   = depth - 1
+               (nestedIndex, nestedFields)  = chooseConstructor nestedDepth fieldKind fieldSeed
+               dereferenced                 = text "*" P.<> parens access
+           in [ access <+> text "=" <+> parens (text (adtCType fieldKind) <+> text "*")
+                  <+> text "malloc" P.<> parens (text "sizeof" <+> text "*" P.<> parens access) P.<> semi
+              , text "if" <+> parens (access <+> text "== NULL") <+> text "abort" P.<> parens empty P.<> semi
+              , initialize fieldKind dereferenced nestedIndex
+              ]
+           ++ assignConstructor nestedDepth fieldKind dereferenced (accessName ++ "_recursive") nestedIndex nestedFields fieldSeed
+         | isExactGMPKind cfg fieldKind
+         = exactAssignments fieldKind access fieldSeed
+         | fieldKind == KString
+         = [access <+> text "=" <+> managedValueClone fieldKind (renderValue fieldKind fieldSeed) P.<> semi]
+         | isArray fieldKind
+         = [ initializeValue fieldKind accessName fieldSeed
+           , access <+> text "=" <+> text accessName P.<> semi
+           ]
+         | isList fieldKind
+         = collectionAssignment listNeedsDriverInit listDriverInit listDriverClear listClone
+         | isSet fieldKind
+         = collectionAssignment setNeedsDriverInit setDriverInit setDriverClear setClone
+         | KTuple fieldKinds <- fieldKind
+         , tupleNeedsOwnership cfg fieldKind
+         = concat (zipWith assignTupleField [1 :: Int ..] (zip fieldKinds [fieldSeed ..]))
+         | isConcreteADT fieldKind
+         , adtNeedsOwnership cfg adts fieldKind
+         = let (nestedIndex, nestedFields) = chooseConstructor depth fieldKind fieldSeed
+           in release fieldKind access
+            : initialize fieldKind access nestedIndex
+            : assignConstructor depth fieldKind access accessName nestedIndex nestedFields fieldSeed
+         | True
+         = [access <+> text "=" <+> renderValue fieldKind fieldSeed P.<> semi]
+        where assignTupleField fieldIndex (nestedKind, nestedSeed) = assignAt depth (ADTField nestedKind False) nestedAccess nestedName nestedSeed
+                where nestedAccess = access P.<> text "." P.<> text (tupleFieldName fieldIndex)
+                      nestedName   = accessName ++ "_field_" ++ show fieldIndex
+
+              collectionAssignment needsDriverInit driverInit driverClear clone
+                | needsDriverInit cfg fieldKind
+                = [ driverInit cfg renderValue initializeValue fieldKind accessName fieldSeed
+                  , access <+> text "=" <+> clone fieldKind (text accessName) P.<> semi
+                  , driverClear cfg fieldKind accessName
+                  ]
+                | True
+                = [access <+> text "=" <+> clone fieldKind (renderValue fieldKind fieldSeed) P.<> semi]
+
+       chooseConstructor depth fieldKind fieldSeed
+         | null eligible = error $ "SBV->C: Recursive ADT " ++ show fieldKind
+                                ++ " has no finite constructor for a generated driver value"
+         | True          = let (index, (_, selectedFields)) = eligible !! fromInteger (mod fieldSeed (fromIntegral (length eligible)))
+                           in (index, selectedFields)
+        where eligible = [(index, constructor)
+                         | (index, constructor@(_, candidateFields)) <- zip [1 :: Int ..] (adtConstructorFields adts fieldKind)
+                         , all (fits depth) candidateFields
+                         ]
+
+       fits _     (ADTField _         False) = True
+       fits depth (ADTField fieldKind True)  = depth > 0 && constructible (depth - 1) fieldKind
+
+       constructible depth fieldKind = any (all (fits depth) . snd) (adtConstructorFields adts fieldKind)
+
+       exactAssignments fieldKind access value = gmpDriverAssign fieldKind access (integer value)
+
+-- | Render a concrete ADT value as a C99 compound literal using the enclosing
+-- program's complete registry, shared with nested constant rendering.
+adtConst :: [Kind] -> (CV -> Doc) -> CV -> Maybe Doc
+adtConst adts renderValue cv@(CV kind (CADT (constructorName, fieldValues)))
+  | isConcreteADT kind
+  , Just (constructorIndex, fieldKinds) <- findConstructor adts kind constructorName
+  , map fst fieldValues == fieldKinds
+  = Just $ adtValue adts kind constructorIndex
+        [arrayStoredValue fieldKind (renderValue (CV fieldKind fieldValue)) | (fieldKind, fieldValue) <- fieldValues]
+  | isConcreteADT kind
+  = error $ "SBV->C: Malformed ADT constant " ++ show cv
+adtConst _ _ _ = Nothing
+
+-- | Lower ADT construction, tests, accessors, equality, conditionals, and labels.
+adtExpr :: CgConfig -> [Kind] -> Op -> [SV] -> SV -> [Doc] -> Maybe CLowering
+adtExpr cfg adts op svs resultSV args
+  | not (isConcreteADT resultKind || any (isConcreteADT . kindOf) svs)
+  = Nothing
+  | LkUp{} <- op
+  = Nothing
+  | TupleConstructor{} <- op
+  = Nothing
+  | TupleAccess{} <- op
+  = Nothing
+  | Uninterpreted{} <- op
+  = Nothing
+  | True
+  = case (op, svs, args) of
+      (ADTOp (ADTConstructor constructorName kind), fields, renderedFields)
+        | kind == resultKind
+        , Just (constructorIndex, fieldKinds) <- findConstructor adts kind (T.unpack constructorName)
+        , map kindOf fields == fieldKinds
+        -> lowerConstructor kind constructorIndex (zipWith arrayStoredValue fieldKinds renderedFields)
+      (ADTOp (ADTTester testerName operationResultKind), [value], [renderedValue])
+        | operationResultKind == resultKind
+        , Just constructorIndex <- findTester adts (kindOf value) (T.unpack testerName)
+        -> lower $ adtTag renderedValue <+> text "==" <+> text (adtTagName (kindOf value) constructorIndex)
+      -- The operation records SBV's scalar result kind, which strips any
+      -- surrounding arrays. The accessor field and result SV retain the full kind.
+      (ADTOp (ADTAccessor accessorName _operationResultKind), [value], [renderedValue])
+        | Just (constructorIndex, fieldIndex, fieldKind, recursive) <- findAccessor adts (kindOf value) (T.unpack accessorName)
+        , fieldKind == resultKind
+        -> let field = if recursive
+                       then text (adtDereferenceName fieldKind)
+                         P.<> parens (adtField renderedValue constructorIndex fieldIndex)
+                       else adtField renderedValue constructorIndex fieldIndex
+           in if isArray resultKind then Just (arrayStoredLoad resultSV field) else lower field
+      (Equal strong, [left, right], [renderedLeft, renderedRight])
+        | kindOf left == kindOf right
+        -> lower $ adtEqual cfg adts strong (kindOf left) renderedLeft renderedRight
+      (NotEqual, [left, right], [renderedLeft, renderedRight])
+        | kindOf left == kindOf right
+        -> lower $ text "!" P.<> parens (adtEqual cfg adts False (kindOf left) renderedLeft renderedRight)
+      (comparison, [left, right], [renderedLeft, renderedRight])
+        | adtIsEnumeration adts (kindOf left)
+        , kindOf left == kindOf right
+        , Just comparisonSymbol <- adtComparisonSymbol comparison
+        -> lower $ adtTag renderedLeft <+> text comparisonSymbol <+> adtTag renderedRight
+      (Label label, [_], [renderedValue])
+        -> lower $ renderedValue <+> text "/*" <+> cCommentText label <+> text "*/"
+      _ -> error $ "SBV->C: ADT lowering does not support " ++ adtOperationName op
+                ++ " with argument kinds " ++ show (map kindOf svs)
+                ++ " and result kind " ++ show resultKind
+                ++ "; constructors "
+                ++ show [constructorName | (constructorName, _) <- adtConstructors adts (sourceADTKind resultKind svs)]
+ where resultKind = kindOf resultSV
+
+       lower = Just . expressionLowering []
+
+       lowerConstructor kind constructorIndex renderedFields
+         | null recursiveFields
+         = lower (adtValue adts kind constructorIndex renderedFields)
+         | True
+         = Just CLowering
+             { loweringExpression   = adtValueWithStorage adts kind constructorIndex storeField renderedFields
+             , loweringDeclarations = [text (adtCType fieldKind) <+> text (backingName fieldIndex) P.<> semi
+                                      | (fieldIndex, fieldKind, _) <- recursiveFields
+                                      ]
+             , loweringSetup        = [text (backingName fieldIndex) <+> text "=" <+> field P.<> semi
+                                      | (fieldIndex, _, field) <- recursiveFields
+                                      ]
+             , loweringRequirements = Set.empty
+             }
+        where fieldInfo = snd (adtConstructorFields adts kind !! (constructorIndex - 1))
+              recursiveFields = [ (fieldIndex, fieldKind, field)
+                                | (fieldIndex, (ADTField fieldKind True, field)) <- zip [1 :: Int ..] (zip fieldInfo renderedFields)
+                                ]
+
+              backingName fieldIndex = "sbv_local_adt_recursive_" ++ show resultSV ++ "_" ++ show fieldIndex
+
+              storeField fieldIndex _ True  _     = text "&" P.<> text (backingName fieldIndex)
+              storeField _          _ False field = field
+
+-- | Test whether an ADT contains an exact GMP-backed integer, real, or
+-- rational field.
+adtUsesExact :: CgConfig -> [Kind] -> Kind -> Bool
+adtUsesExact cfg adts = any constructorUsesExact . adtConstructors adts
+ where constructorUsesExact (_, fields) = any fieldUsesExact fields
+       fieldUsesExact = any (isExactGMPKind cfg) . expandKinds
+
+-- | Test whether an ADT needs deep ownership because it contains collection
+-- storage, exact storage, recursive pointers, or another managed aggregate.
+adtNeedsOwnership :: CgConfig -> [Kind] -> Kind -> Bool
+adtNeedsOwnership cfg adts = needsOwnership Set.empty
+ where needsOwnership visited kind
+         | kind `Set.member` visited = adtIsRecursive adts kind
+         | adtUsesExact cfg adts kind = True
+         | True                       = any (any fieldNeedsOwnership . snd) (adtConstructorFields adts kind)
+        where next = Set.insert kind visited
+              fieldNeedsOwnership (ADTField _         True)  = True
+              fieldNeedsOwnership (ADTField fieldKind False)
+                | isConcreteADT fieldKind = needsOwnership next fieldKind
+                | True                    = valueNeedsOwnership cfg fieldKind
+
+-- | Construct a deterministic driver value, choosing a constructor from the
+-- supplied integer and delegating field values to the caller.
+adtDriverValue :: [Kind] -> (Kind -> Integer -> Doc) -> Kind -> Integer -> Doc
+adtDriverValue adts renderField = construct (max 3 (length adts + 1))
+ where construct :: Int -> Kind -> Integer -> Doc
+       construct depth kind seed
+         | null constructors = error $ "SBV->C: Cannot construct an uninterpreted sort in the C driver: " ++ show kind
+         | True              = adtValue adts kind constructorIndex (zipWith renderADTField fields [seed ..])
+        where constructors     = adtConstructorFields adts kind
+              eligible = [ (index, constructor)
+                         | (index, constructor@(_, candidateFields)) <- zip [1 :: Int ..] constructors
+                         , all (fits depth) candidateFields
+                         ]
+              (constructorIndex, (_, fields))
+                | null eligible = error $ "SBV->C: Recursive ADT " ++ show kind
+                                       ++ " has no finite constructor for a generated driver value"
+                | True          = eligible !! fromInteger (mod seed (fromIntegral (length eligible)))
+
+              renderADTField (ADTField fieldKind recursive) fieldSeed
+                | isConcreteADT fieldKind = construct (if recursive then depth - 1 else depth) fieldKind fieldSeed
+                | True                    = renderField fieldKind fieldSeed
+
+       fits _     (ADTField _         False) = True
+       fits depth (ADTField fieldKind True)  = depth > 0 && constructible (depth - 1) fieldKind
+
+       constructible depth kind = any (all (fits depth) . snd) (adtConstructorFields adts kind)
+
+-- | Render C statements that print an ADT value by constructor name and fields.
+adtPrint :: [Kind] -> (Kind -> Doc -> Doc) -> Kind -> Doc -> Doc
+adtPrint adts printField kind value
+  | adtIsRecursive adts kind = text (adtPrintName kind) P.<> parens value P.<> semi
+  | True                     = adtPrintSwitch adts printField kind value
+
+-- | Emit mutually recursive driver-side printers for recursive ADTs.
+adtPrintHelpers :: [Kind] -> (Kind -> Doc -> Doc) -> Doc
+adtPrintHelpers adts printField
+  | null recursiveKinds = empty
+  | True                = vcat (map prototype recursiveKinds)
+                       $$ text ""
+                       $$ vcat (map definition recursiveKinds)
+ where recursiveKinds = filter (adtIsRecursive adts) adts
+       prototype kind = text "static SBV_CGEN_UNUSED void" <+> text (adtPrintName kind)
+                     P.<> parens (text (adtCType kind) <+> text "value")
+                     P.<> semi
+       definition kind = text "#ifndef" <+> text (adtPrintGuard kind)
+                      $$ text "#define" <+> text (adtPrintGuard kind)
+                      $$ text "static SBV_CGEN_UNUSED void" <+> text (adtPrintName kind)
+                      P.<> parens (text (adtCType kind) <+> text "value")
+                      $$ text "{"
+                      $$ nest 2 (adtPrintSwitch adts printField kind (text "value"))
+                      $$ text "}"
+                      $$ text "#endif"
+                      $$ text ""
+
+-- | Render the tag switch shared by inline and recursive ADT printers.
+adtPrintSwitch :: [Kind] -> (Kind -> Doc -> Doc) -> Kind -> Doc -> Doc
+adtPrintSwitch adts printField kind value
+  = text "switch" <+> parens (adtTag value) <+> text "{"
+ $$ nest 2 (vcat (zipWith printConstructor [1 :: Int ..] (adtConstructorFields adts kind))
+         $$ text "default: printf(\"<invalid ADT tag>\"); break;")
+ $$ text "}"
+ where printConstructor constructorIndex (constructorName, fields)
+         =  text "case" <+> text (adtTagName kind constructorIndex) P.<> colon
+         $$ nest 2 (text "printf" P.<> parens (fsep (punctuate comma [text "\"%s\"", text (show constructorName)])) P.<> semi
+                 $$ printFields constructorIndex fields
+                 $$ text "break" P.<> semi)
+
+       printFields _                []     = empty
+       printFields constructorIndex fields =
+            text "printf(\"(\");"
+         $$ vcat (zipWith (printOne constructorIndex) [1 :: Int ..] fields)
+         $$ text "printf(\")\");"
+
+       printOne constructorIndex fieldIndex (ADTField fieldKind recursive)
+         =  (if fieldIndex == 1 then empty else text "printf(\", \");")
+         $$ if recursive
+            then text "if" <+> parens (fieldValue <+> text "== NULL")
+              <+> text "printf(\"<null recursive ADT>\");"
+              <+> text "else"
+              <+> printField fieldKind (text "*" P.<> parens fieldValue)
+            else printField fieldKind fieldValue
+        where fieldValue = adtField value constructorIndex fieldIndex
+
+-- | Return the driver-side printer name for a recursive ADT.
+adtPrintName :: Kind -> String
+adtPrintName kind = "sbv_adt_print_" ++ adtCType kind
+
+-- | Return the preprocessor guard for one driver-side recursive ADT printer.
+adtPrintGuard :: Kind -> String
+adtPrintGuard kind = adtPrintName kind ++ "_DEFINED"
+
+-- | Return constructors with parameter variables and 'KApp' references
+-- replaced by their concrete kinds.
+adtConstructors :: [Kind] -> Kind -> [(String, [Kind])]
+adtConstructors adts kind = [(constructorName, [fieldKind | ADTField fieldKind _ <- fields])
+                            | (constructorName, fields) <- adtConstructorFields adts kind
+                            ]
+
+-- | Return concrete constructor fields while retaining which direct 'KApp'
+-- references must use pointers to break recursive C layouts.
+adtConstructorFields :: [Kind] -> Kind -> [(String, [ADTField])]
+adtConstructorFields adts kind@(KADT typeName parameters constructors)
+  | isConcreteADT kind = map substituteConstructor constructors
+  | True               = error $ "SBV->C: Expected a concrete ADT kind, received " ++ show kind
+ where substituteConstructor (constructorName, fields) = (constructorName, map substituteField fields)
+
+       substituteField field = ADTField concrete recursive
+        where substituted = substituteADTVars typeName parameters field
+              concrete    = resolveADTReferences adts substituted
+              recursive   = case substituted of
+                              KApp{} -> adtReachable adts concrete kind
+                              _ | any (\application -> adtReachable adts (resolveADTReferences adts application) kind)
+                                      [application | application@KApp{} <- expandKinds substituted]
+                                -> error $ "SBV->C: Recursive ADT references nested inside composite fields are not supported: " ++ show kind
+                                         ++ ". Put the recursive reference in a direct constructor field instead."
+                                | True -> False
+adtConstructorFields _ kind = error $ "SBV->C: Expected an ADT kind, received " ++ show kind
+
+-- | Return whether the second ADT is reachable from the first through ADT
+-- declaration references. The visited set makes recursive registries finite.
+adtReachable :: [Kind] -> Kind -> Kind -> Bool
+adtReachable adts source target = walk Set.empty source
+ where walk visited current
+         | current == target            = True
+         | current `Set.member` visited = False
+         | True                         = any (walk (Set.insert current visited)) (adtDependencies adts current)
+
+-- | Return the concrete ADTs referenced directly or through composite fields
+-- by one concrete ADT declaration.
+adtDependencies :: [Kind] -> Kind -> [Kind]
+adtDependencies adts (KADT typeName parameters constructors) = nub
+  [ resolveADTReferences adts application
+  | (_, fields) <- constructors
+  , field <- fields
+  , application@KApp{} <- expandKinds (substituteADTVars typeName parameters field)
+  ]
+adtDependencies _ kind = error $ "SBV->C: Expected an ADT kind, received " ++ show kind
+
+-- | Resolve concrete ADT applications occurring inside a supported composite
+-- field without recursively expanding the referenced declaration.
+resolveADTReferences :: [Kind] -> Kind -> Kind
+resolveADTReferences adts kind@(KApp typeName arguments) =
+  case [ (parameters, constructors)
+       | KADT candidateName parameters constructors <- adts
+       , candidateName == typeName
+       , length parameters == length arguments
+       ] of
+    ((parameters, constructors) : _) -> KADT typeName (zip (map fst parameters) arguments) constructors
+    [] -> error $ "SBV->C: Cannot resolve ADT reference " ++ show kind
+             ++ "; available concrete ADTs: " ++ show adts
+resolveADTReferences adts (KList elementKind) = KList (resolveADTReferences adts elementKind)
+resolveADTReferences adts (KSet elementKind) = KSet (resolveADTReferences adts elementKind)
+resolveADTReferences adts (KTuple fieldKinds) = KTuple (map (resolveADTReferences adts) fieldKinds)
+resolveADTReferences adts (KArray keyKind valueKind) =
+  KArray (resolveADTReferences adts keyKind) (resolveADTReferences adts valueKind)
+resolveADTReferences _ kind = kind
+
+-- | Render the field-level equality semantics used inside an ADT comparison.
+adtFieldEqual :: CgConfig -> [Kind] -> Bool -> Kind -> Doc -> Doc -> Doc
+adtFieldEqual cfg adts strong kind left right
+  | isWideBV kind                              = wideBVEqual kind left right
+  | isFP kind && strong                        = arbitraryFPObjectEqual kind left right
+  | isFP kind                                  = arbitraryFPEqual kind left right
+  | strong && (isFloat kind || isDouble kind) = nativeFPObjectEqual left right
+  | isExactGMPKind cfg kind                    = adtExactEqual kind left right
+  | kind == KString                            = byValueEqual cfg strong kind left right
+  | isList kind                                = listEqual kind left right
+  | isSet kind                                 = setEqual kind left right
+  | isArray kind                               = byValueEqual cfg strong kind left right
+  | KTuple fields <- kind                      = tupleEqual cfg adts strong fields left right
+  | isConcreteADT kind                         = adtEqual cfg adts strong kind left right
+  | True                                       = left <+> text "==" <+> right
+
+-- | Render exact equality directly with GMP's public comparison API.
+adtExactEqual :: Kind -> Doc -> Doc -> Doc
+adtExactEqual KUnbounded left right = text "mpz_cmp"
+                                   P.<> parens (fsep (punctuate comma [left, right]))
+                                   <+> text "== 0"
+adtExactEqual exactKind left right
+  | exactKind `elem` [KReal, KRational]
+  = text "mpq_cmp"
+      P.<> parens (fsep (punctuate comma [left, right]))
+      <+> text "== 0"
+adtExactEqual kind _ _ = error $ "SBV->C: Expected an exact ADT field, received " ++ show kind
+
+-- | Render structural equality for a tuple nested in an ADT field.
+tupleEqual :: CgConfig -> [Kind] -> Bool -> [Kind] -> Doc -> Doc -> Doc
+tupleEqual cfg adts strong fields left right = andExpressions comparisons
+ where comparisons = zipWith compareField [1 :: Int ..] fields
+       compareField index fieldKind = adtFieldEqual cfg adts strong fieldKind
+         (parens left  P.<> text ".field" P.<> int index)
+         (parens right P.<> text ".field" P.<> int index)
+
+-- | Render tag-sensitive structural equality for two ADT values.
+adtEqual :: CgConfig -> [Kind] -> Bool -> Kind -> Doc -> Doc -> Doc
+adtEqual cfg adts strong kind left right
+  | adtIsRecursive adts kind = text (adtEqualName strong kind)
+                            P.<> parens (fsep (punctuate comma [left, right]))
+  | True                     = parens $ tagEquality <+> text "&&" <+> constructorEquality
+ where tagEquality = parens (adtTag left <+> text "==" <+> adtTag right)
+       constructorEquality = parens . orExpressions $ zipWith constructorCase [1 :: Int ..] (adtConstructors adts kind)
+       constructorCase constructorIndex (_, fields) = andExpressions
+         (parens (adtTag left <+> text "==" <+> text (adtTagName kind constructorIndex))
+        : zipWith (fieldEquality constructorIndex) [1 :: Int ..] fields)
+       fieldEquality constructorIndex fieldIndex fieldKind = adtFieldEqual cfg adts strong fieldKind
+         (adtField left  constructorIndex fieldIndex)
+         (adtField right constructorIndex fieldIndex)
+
+-- | Return whether an ADT has at least one pointer-backed recursive field.
+adtIsRecursive :: [Kind] -> Kind -> Bool
+adtIsRecursive adts = any (any recursive . snd) . adtConstructorFields adts
+ where recursive (ADTField _ isRecursive) = isRecursive
+
+-- | Return the generated checked-dereference helper for a recursive ADT edge.
+adtDereferenceName :: Kind -> String
+adtDereferenceName kind = "sbv_adt_dereference_" ++ adtCType kind
+
+-- | Return the guard protecting one recursive ADT dereference helper.
+dereferenceGuard :: Kind -> String
+dereferenceGuard kind = adtDereferenceName kind ++ "_DEFINED"
+
+-- | Join Boolean C expressions with short-circuiting conjunction.
+andExpressions :: [Doc] -> Doc
+andExpressions []          = text "true"
+andExpressions expressions = parens (fsep (punctuate (text " &&") expressions))
+
+-- | Join Boolean C expressions with short-circuiting disjunction.
+orExpressions :: [Doc] -> Doc
+orExpressions []          = text "false"
+orExpressions expressions = parens (fsep (punctuate (text " ||") expressions))
+
+-- | Locate a constructor and return its one-based tag and concrete fields.
+findConstructor :: [Kind] -> Kind -> String -> Maybe (Int, [Kind])
+findConstructor adts kind constructorName = do
+  (index, (_, fields)) <- find ((== constructorName) . fst . snd)
+                               (zip [1 :: Int ..] (adtConstructors adts kind))
+  pure (index, fields)
+
+-- | Locate the constructor named by a canonical @is-Constructor@ tester.
+findTester :: [Kind] -> Kind -> String -> Maybe Int
+findTester adts kind testerName = fst <$> find matches (zip [1 :: Int ..] (adtConstructors adts kind))
+ where matches (_, (constructorName, _)) = testerName == "is-" ++ constructorName
+
+-- | Locate the constructor field named by a canonical
+-- @getConstructor_fieldIndex@ accessor.
+findAccessor :: [Kind] -> Kind -> String -> Maybe (Int, Int, Kind, Bool)
+findAccessor adts kind accessorName = findMatch candidates
+ where candidates = [(constructorIndex, fieldIndex, fieldKind, recursive)
+                    | (constructorIndex, (constructorName, fields)) <- zip [1 :: Int ..] (adtConstructorFields adts kind)
+                    , (fieldIndex, ADTField fieldKind recursive) <- zip [1 :: Int ..] fields
+                    , accessorName == "get" ++ constructorName ++ "_" ++ show fieldIndex
+                    ]
+       findMatch []    = Nothing
+       findMatch (x:_) = Just x
+
+-- | Return the C type used for a supported ADT field, introducing a pointer
+-- precisely for a recursive dependency edge.
+adtFieldCType :: ADTField -> String
+adtFieldCType (ADTField kind True) = adtCType kind ++ " *"
+adtFieldCType (ADTField kind False)
+  | isConcreteADT kind = adtCType kind
+adtFieldCType (ADTField kind False) = elementCType kind
+
+
+-- | Render the tag-selection expression for an ADT value.
+adtTag :: Doc -> Doc
+adtTag value = parens value P.<> text ".tag"
+
+-- | Render the payload-selection expression for an ADT field.
+adtField :: Doc -> Int -> Int -> Doc
+adtField value constructorIndex fieldIndex = parens value
+  P.<> text ".payload."
+  P.<> text (adtConstructorMember constructorIndex)
+  P.<> text "."
+  P.<> text (adtFieldName fieldIndex)
+
+-- | Return the generated payload member for a one-based constructor index.
+adtConstructorMember :: Int -> String
+adtConstructorMember index = "constructor" ++ show index
+
+-- | Return the generated field member for a one-based field index.
+adtFieldName :: Int -> String
+adtFieldName index = "field" ++ show index
+
+-- | Return the generated enumeration type used for an ADT tag.
+adtTagCType :: Kind -> String
+adtTagCType kind = adtCType kind ++ "_Tag"
+
+-- | Return the generated enumeration constant for one ADT constructor.
+adtTagName :: Kind -> Int -> String
+adtTagName kind constructorIndex = adtCType kind ++ "_TAG_" ++ show constructorIndex
+
+-- | Return the preprocessor guard protecting one ADT declaration.
+adtGuard :: Kind -> String
+adtGuard kind = adtCType kind ++ "_DEFINED"
+
+-- | Return the preprocessor guard protecting one ADT forward declaration.
+adtForwardGuard :: Kind -> String
+adtForwardGuard kind = adtCType kind ++ "_DECLARED"
+
+-- | Render a C99 tagged-union compound literal.
+adtValue :: [Kind] -> Kind -> Int -> [Doc] -> Doc
+adtValue adts kind constructorIndex = adtValueWithStorage adts kind constructorIndex storeField
+ where storeField _ fieldKind True field
+         = text "&"
+        P.<> parens (   parens (text (adtCType fieldKind) P.<> brackets (text "1"))
+                    P.<> braces field
+                   )
+        P.<> brackets (text "0")
+       storeField _ _ False field = field
+
+-- | Render a C99 tagged-union compound literal while allowing the caller to
+-- choose how each recursive pointer field receives its backing storage.
+adtValueWithStorage :: [Kind] -> Kind -> Int -> (Int -> Kind -> Bool -> Doc -> Doc) -> [Doc] -> Doc
+adtValueWithStorage adts kind constructorIndex storeField fields
+  | constructorIndex < 1 || constructorIndex > length constructors
+  = error $ "SBV->C: Invalid ADT constructor index " ++ show constructorIndex ++ " for " ++ show kind
+  | length fields /= length expectedFields
+  = error $ "SBV->C: ADT literal field mismatch for " ++ show kind
+  | True
+  = parens (text (adtCType kind)) P.<> braces (fsep (punctuate comma initializers))
+ where constructors = adtConstructors adts kind
+       expectedFields = snd (constructors !! (constructorIndex - 1))
+       initializers = text ".tag" <+> text "=" <+> text (adtTagName kind constructorIndex)
+                    : zipWith initializer [1 :: Int ..] (zip fields fieldInfo)
+       fieldInfo = snd (adtConstructorFields adts kind !! (constructorIndex - 1))
+       initializer fieldIndex (field, ADTField fieldKind recursive) = text ".payload."
+                                                                    P.<> text (adtConstructorMember constructorIndex)
+                                                                    P.<> text "."
+                                                                    P.<> text (adtFieldName fieldIndex)
+                                                                    <+> text "=" <+> storeField fieldIndex fieldKind recursive field
+
+-- | Return a total diagnostic name for an operation involving an ADT.
+adtOperationName :: Op -> String
+adtOperationName (ADTOp (ADTConstructor opName _)) = "constructor " ++ show opName
+adtOperationName (ADTOp (ADTTester      opName _)) = "tester "      ++ show opName
+adtOperationName (ADTOp (ADTAccessor    opName _)) = "accessor "    ++ show opName
+adtOperationName LkUp{}                            = "table lookup"
+adtOperationName (Equal strong)                    = if strong then "strong equality" else "equality"
+adtOperationName NotEqual                          = "inequality"
+adtOperationName Ite                               = "conditional"
+adtOperationName (Label label)                     = "label " ++ show label
+adtOperationName _                                 = "an unsupported operation"
+
+-- | Recover the ADT kind participating in a failed lowering for diagnostics.
+sourceADTKind :: Kind -> [SV] -> Kind
+sourceADTKind resultKind _
+  | isConcreteADT resultKind = resultKind
+sourceADTKind _ svs = case filter (isConcreteADT . kindOf) svs of
+  value : _ -> kindOf value
+  []        -> error "SBV->C: Missing ADT kind in ADT lowering diagnostic"
+
+-- | Return whether every constructor of an ADT is nullary.
+adtIsEnumeration :: [Kind] -> Kind -> Bool
+adtIsEnumeration adts = all (null . snd) . adtConstructors adts
+
+-- | Return the C comparison token supported for enumeration ADTs.
+adtComparisonSymbol :: Op -> Maybe String
+adtComparisonSymbol LessThan    = Just "<"
+adtComparisonSymbol GreaterThan = Just ">"
+adtComparisonSymbol LessEq      = Just "<="
+adtComparisonSymbol GreaterEq   = Just ">="
+adtComparisonSymbol _           = Nothing
diff --git a/Data/SBV/Compilers/C/Arena.hs b/Data/SBV/Compilers/C/Arena.hs
new file mode 100644
--- /dev/null
+++ b/Data/SBV/Compilers/C/Arena.hs
@@ -0,0 +1,76 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Data.SBV.Compilers.C.Arena
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Shared emission of per-call storage arenas for text and collections.
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Data.SBV.Compilers.C.Arena (CArena(..), arenaRuntime) where
+
+-- | Separate ownership domains sharing the same allocation protocol. Keep
+-- their C types and lifetimes independent even though their emitter is shared.
+data CArena = TextArena  -- ^ Byte-addressed UTF-8 string storage.
+            | ListArena -- ^ Aligned storage for symbolic-list elements.
+            | SetArena  -- ^ Aligned storage for symbolic-set elements.
+
+-- | Emit overflow-checked allocation and whole-arena cleanup. Empty allocations
+-- return null without allocating. Collection storage retains its long-double
+-- alignment and checks both multiplication and header-addition overflow; text
+-- storage accepts a byte count directly. Nodes own only their payload buffer,
+-- not the managed values referenced by collection elements.
+arenaRuntime :: CArena -> [String]
+arenaRuntime arena
+  = [ "/* Per-call ownership arena for " ++ description ++ " temporaries. */"
+    , "typedef struct " ++ nodeType ++ " { struct " ++ nodeType ++ " *next; " ++ payloadType ++ " data[]; } " ++ nodeType ++ ";"
+    , "typedef struct { " ++ nodeType ++ " *head; } " ++ contextType ++ ";"
+    ]
+ ++ separator
+ ++ [ "static " ++ resultType ++ " *" ++ prefix ++ "_alloc(" ++ contextType ++ " *ctx, size_t count" ++ elementParameter ++ ")"
+    , "{"
+    , "  if (count == 0) return NULL;"
+    ]
+ ++ [ line
+    | not byteStorage
+    , line <- [ "  if (element_size == 0 || count > SIZE_MAX / element_size) abort();"
+              , "  const size_t bytes = count * element_size;"
+              ]
+    ]
+ ++ [ "  if (" ++ byteCount ++ " > SIZE_MAX - sizeof(" ++ nodeType ++ ")) abort();"
+    , "  " ++ nodeType ++ " *node = (" ++ nodeType ++ " *) malloc(sizeof(*node) + " ++ byteCount ++ ");"
+    , "  if (node == NULL) abort();"
+    , "  node->next = ctx->head; ctx->head = node; return node->data;"
+    , "}"
+    ]
+ ++ separator
+ ++ [ "static void " ++ prefix ++ "_ctx_end(" ++ contextType ++ " *ctx)"
+    , "{"
+    , "  while (ctx->head != NULL) {"
+    , "    " ++ nodeType ++ " *next = ctx->head->next; free(ctx->head); ctx->head = next;"
+    , "  }"
+    , "}"
+    ]
+ where stem = case arena of
+                TextArena -> "text"
+                ListArena -> "list"
+                SetArena  -> "set"
+       description = case arena of
+                       TextArena -> "string"
+                       ListArena -> "symbolic-list"
+                       SetArena  -> "symbolic-set"
+       byteStorage = case arena of
+                       TextArena -> True
+                       _         -> False
+       prefix           = "sbv_" ++ stem
+       nodeType         = prefix ++ "_node"
+       contextType      = prefix ++ "_ctx"
+       payloadType      = if byteStorage then "uint8_t" else "long double"
+       resultType       = if byteStorage then "uint8_t" else "void"
+       byteCount        = if byteStorage then "count"   else "bytes"
+       elementParameter = if byteStorage then ""        else ", size_t element_size"
+       separator        = ["" | byteStorage]
diff --git a/Data/SBV/Compilers/C/Array.hs b/Data/SBV/Compilers/C/Array.hs
new file mode 100644
--- /dev/null
+++ b/Data/SBV/Compilers/C/Array.hs
@@ -0,0 +1,855 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Data.SBV.Compilers.C.Array
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Persistent functional-array lowering for the SBV-to-C compiler.
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Data.SBV.Compilers.C.Array
+  ( arrayKinds
+  , arrayCType
+  , arrayInputCType
+  , arrayOutputCType
+  , arrayForwardTypeDecls
+  , arrayOutputReadName
+  , arrayOutputReleaseName
+  , arrayExportName
+  , arrayStoredValue
+  , arrayStoredLoad
+  , arrayTypeDecls
+  , arrayRuntime
+  , arrayContextStart
+  , arrayContextEnd
+  , arrayInputSetup
+  , arrayDriverCallback
+  , arrayDriverInput
+  , arrayDriverStoredInput
+  , arrayLambdaName
+  , arrayConst
+  , arrayExpr
+  , arrayReadName
+  , arrayEqualName
+  ) where
+
+import Data.List (nubBy, tails)
+
+import qualified Data.Set as Set
+import qualified Data.Text as T
+
+import Text.PrettyPrint.HughesPJ
+import qualified Text.PrettyPrint.HughesPJ as P ((<>), render)
+
+import Data.SBV.Compilers.C.BV         (isWideBV)
+import Data.SBV.Compilers.C.GMP        (gmpFunctionName, gmpNewName, gmpOutputType, isExactGMPKind)
+import Data.SBV.Compilers.C.Lowering   (CLowering(..), CRequirement(..), expressionLowering)
+import Data.SBV.Compilers.C.Syntax     (cUnusedAttribute, cCommentText)
+import Data.SBV.Compilers.C.Types      ( isConcreteADT
+                                       , constElementCType
+                                       , arrayKindTag
+                                       , arrayOutputCTypeName
+                                       , arrayStoredCloneName
+                                       , arrayStoredReleaseName
+                                       , elementCType
+                                       )
+import Data.SBV.Compilers.C.Value      (byValueEqual, managedValueClone, managedValueRelease, valueNeedsOwnership)
+import Data.SBV.Compilers.CodeGen      (CgConfig)
+import Data.SBV.Core.Data
+import Data.SBV.Core.Symbolic          (smtLambdaInfo)
+
+-- | Return and validate the distinct array kinds used by a program. Arrays may
+-- occur as values, but not as keys: array-key matching would require general
+-- extensional equality, which the C backend cannot implement for arbitrary
+-- domains. Deduplicate by C type: Boolean and unsigned one-bit keys or values
+-- have the same representation and share their runtime helpers.
+arrayKinds :: Set.Set Kind -> [Kind]
+arrayKinds = nubBy (\left right -> arrayCType left == arrayCType right) . map validate . filter isArray . Set.toAscList
+ where validate k@(KArray keyKind valueKind)
+         | isArray keyKind
+         = error $ "SBV->C: Array-valued array keys require unsupported extensional equality: " ++ show k
+         | supported keyKind && supported valueKind
+         = k
+         | True
+         = error $ "SBV->C: Array kind is not yet supported: " ++ show k
+       validate kind = error $ "SBV->C: Expected an array kind, received " ++ show kind
+
+       supported kind = case kind of
+         KBool                    -> True
+         KBounded{}               -> True
+         KUnbounded               -> True
+         KReal                    -> True
+         KRational                -> True
+         KFloat                   -> True
+         KDouble                  -> True
+         KFP{}                    -> True
+         KChar                    -> True
+         KString                  -> True
+         KList elementKind        -> supported elementKind
+         KSet elementKind         -> supported elementKind
+         KTuple fields            -> all supported fields
+         KArray keyKind valueKind -> not (isArray keyKind) && supported keyKind && supported valueKind
+         KADT{}                   -> isRoundingMode kind || isConcreteADT kind
+         _                        -> False
+
+-- | Return the public opaque-pointer type used for an SBV array kind.
+arrayCType :: Kind -> String
+arrayCType kind@KArray{} = "SBVArray_" ++ arrayKindTag kind
+arrayCType kind          = error $ "SBV->C: Expected an array kind, received " ++ show kind
+
+-- | Return the public callback-descriptor type accepted for an array-valued
+-- C input. The descriptor and its context are borrowed for the duration of
+-- the generated call.
+arrayInputCType :: Kind -> String
+arrayInputCType kind = "SBVArrayInput_" ++ arraySuffix kind
+
+-- | Return the public owned-descriptor type produced for an array-valued C
+-- output or return value.
+arrayOutputCType :: Kind -> String
+arrayOutputCType = arrayOutputCTypeName
+
+-- | Return the public helper name used to read an owned array output.
+arrayOutputReadName :: Kind -> String
+arrayOutputReadName kind = "sbv_array_output_read_" ++ arraySuffix kind
+
+-- | Return the public helper name used to release an owned array output.
+arrayOutputReleaseName :: Kind -> String
+arrayOutputReleaseName kind = "sbv_array_output_release_" ++ arraySuffix kind
+
+-- | Return the public helper name used to retain an owned array output.
+arrayOutputRetainName :: Kind -> String
+arrayOutputRetainName kind = "sbv_array_output_retain_" ++ arraySuffix kind
+
+-- | Return the public helper name used to borrow an owned output as an input
+-- descriptor for another generated call.
+arrayOutputAsInputName :: Kind -> String
+arrayOutputAsInputName kind = "sbv_array_output_as_input_" ++ arraySuffix kind
+
+-- | Return the internal helper name used to export a function-scoped array.
+arrayExportName :: Kind -> String
+arrayExportName kind = "sbv_array_export_" ++ arraySuffix kind
+
+-- | Return the internal helper name that exports an array into the generated
+-- function's temporary ownership arena.
+arrayStoredExportName :: Kind -> String
+arrayStoredExportName kind = "sbv_array_stored_export_" ++ arraySuffix kind
+
+-- | Convert an internal array expression to the retained descriptor pointer
+-- representation used when an array is stored inside another value. Other
+-- kinds are returned unchanged.
+arrayStoredValue :: Kind -> Doc -> Doc
+arrayStoredValue kind value
+  | isArray kind
+  = text (arrayStoredExportName kind)
+      P.<> parens (fsep (punctuate comma [text "&sbv_local_array_ctx", value]))
+  | True
+  = value
+
+-- | Borrow a retained descriptor pointer as an internal array root for the
+-- remainder of a generated call.
+arrayStoredLoad :: SV -> Doc -> CLowering
+arrayStoredLoad resultSV descriptor = CLowering
+  { loweringExpression   = text "&" P.<> text nodeName
+  , loweringDeclarations = [ text "const" <+> text (arrayOutputCType kind) <+> text "*" P.<> text descriptorName P.<> semi
+                           , text (arrayNodeType kind) <+> text nodeName P.<> semi
+                           ]
+  , loweringSetup        = [ text descriptorName <+> text "=" <+> descriptor P.<> semi
+                           , text "if" P.<> parens (text descriptorName <+> text "== NULL" <+> text "||" <+> text descriptorName P.<> text "->lookup == NULL")
+                             <+> text "abort" P.<> parens empty P.<> semi
+                           , text nodeName <+> text "=" <+> parens (text (arrayNodeType kind))
+                             <+> braces (fsep (punctuate comma descriptorFields)) P.<> semi
+                           ]
+  , loweringRequirements = Set.singleton CRequiresArrays
+  }
+ where kind             = kindOf resultSV
+       descriptorName   = "sbv_local_array_descriptor_" ++ show resultSV
+       nodeName         = "sbv_local_array_" ++ show resultSV
+       descriptorFields = [ text ".kind = SBV_ARRAY_CALLBACK"
+                          , text ".lookup ="  <+> text descriptorName P.<> text "->lookup"
+                          , text ".context =" <+> text descriptorName P.<> text "->context"
+                          , text ".retain ="  <+> text descriptorName P.<> text "->retain"
+                          , text ".release =" <+> text descriptorName P.<> text "->release"
+                          ]
+
+-- | Emit descriptor forward declarations needed by aggregate layouts that
+-- store arrays by pointer. The complete descriptor remains delayed until its
+-- key and value layouts are available.
+arrayForwardTypeDecls :: [Kind] -> Doc
+arrayForwardTypeDecls []    = empty
+arrayForwardTypeDecls kinds = text . unlines $
+     commonDeclarations
+  ++ concatMap declaration kinds
+ where commonDeclarations =
+         [ "/* Forward declarations for retained array descriptors. */"
+         , cUnusedAttribute
+         , "#ifndef SBV_ARRAY_CONTEXT_LIFETIME_DEFINED"
+         , "#define SBV_ARRAY_CONTEXT_LIFETIME_DEFINED"
+         , "typedef const void *(*SBVArrayContextRetain)(const void *context);"
+         , "typedef void (*SBVArrayContextRelease)(const void *context);"
+         , "#endif"
+         , ""
+         ]
+
+       declaration kind@KArray{} =
+         [ "#ifndef " ++ arrayForwardGuard kind
+         , "#define " ++ arrayForwardGuard kind
+         , "typedef struct " ++ arrayOutputCType kind ++ " " ++ arrayOutputCType kind ++ ";"
+         , "static inline SBV_CGEN_UNUSED " ++ arrayOutputCType kind ++ " *" ++ arrayStoredCloneName kind
+        ++   "(const " ++ arrayOutputCType kind ++ " *value);"
+         , "static inline SBV_CGEN_UNUSED void " ++ arrayStoredReleaseName kind
+        ++   "(" ++ arrayOutputCType kind ++ " **value);"
+         , "#endif"
+         , ""
+         ]
+       declaration kind = error $ "SBV->C: Expected an array kind, received " ++ show kind
+
+-- | Emit opaque public array types for every kind used by a generated
+-- program. Input descriptors are borrowed during a call. Output descriptors
+-- own retained contexts and must be released with their generated helper.
+arrayTypeDecls :: [Kind] -> Doc
+arrayTypeDecls [] = empty
+arrayTypeDecls kinds = text . unlines $
+     [ "/* Persistent functional arrays. Internal references are valid for one call. */"
+     , "/* Input contexts are borrowed unless an escaping result invokes their retain */"
+     , "/* callback. Owned outputs must be released with the generated release helper. */"
+     , "/* Callback results borrow their context; aggregate reads borrow the array owner. */"
+     , "/* Clone a managed read result to outlive its owner. The as_input helper only borrows. */"
+     , "/* Lookups must be stable; escaping non-null contexts require both retain and release. */"
+     ]
+  ++ concatMap declaration kinds
+ where declaration kind@(KArray keyKind valueKind)
+         = let inputType       = arrayInputCType kind
+               outputType      = arrayOutputCType kind
+               lookupType      = arrayLookupType kind
+               readOutput      = arrayOutputReadName kind
+               retainOutput    = arrayOutputRetainName kind
+               releaseOutput   = arrayOutputReleaseName kind
+               asInput         = arrayOutputAsInputName kind
+               cloneStored     = arrayStoredCloneName kind
+               releaseStored   = arrayStoredReleaseName kind
+               keyType         = elementCType keyKind
+               valueType       = elementCType valueKind
+           in [ "#ifndef " ++ arrayGuard kind
+           , "#define " ++ arrayGuard kind
+           , "/* Owned descriptors carry one reference. Retain copied descriptors and release each owner. */"
+           , "/* The input adapter is borrowed; a generated callee retains it if the array escapes. */"
+           , "#ifndef " ++ arrayForwardGuard kind
+           , "#define " ++ arrayForwardGuard kind
+           , "typedef struct " ++ outputType ++ " " ++ outputType ++ ";"
+           , "static inline SBV_CGEN_UNUSED " ++ outputType ++ " *" ++ cloneStored ++ "(const " ++ outputType ++ " *value);"
+           , "static inline SBV_CGEN_UNUSED void " ++ releaseStored ++ "(" ++ outputType ++ " **value);"
+           , "#endif"
+           , "typedef struct " ++ arrayNodeType kind ++ " " ++ arrayNodeType kind ++ ";"
+           , "typedef const " ++ arrayNodeType kind ++ " *" ++ arrayCType kind ++ ";"
+           , "typedef " ++ valueType ++ " (*" ++ lookupType ++ ")(const void *context, " ++ keyType ++ " key);"
+           , "typedef struct { " ++ lookupType ++ " lookup; const void *context; SBVArrayContextRetain retain; SBVArrayContextRelease release; } " ++ inputType ++ ";"
+           , "struct " ++ outputType ++ " { " ++ lookupType ++ " lookup; const void *context; SBVArrayContextRetain retain; SBVArrayContextRelease release; };"
+           , "static inline " ++ valueType ++ " " ++ readOutput ++ "(" ++ outputType ++ " array, " ++ keyType ++ " key)"
+           , "{ if (array.lookup == NULL) abort(); return array.lookup(array.context, key); }"
+           , "static inline " ++ outputType ++ " " ++ retainOutput ++ "(" ++ outputType ++ " array)"
+           , "{"
+           , "  if (array.context != NULL) {"
+           , "    if (array.retain == NULL) abort();"
+           , "    array.context = array.retain(array.context);"
+           , "    if (array.context == NULL) abort();"
+           , "  }"
+           , "  return array;"
+           , "}"
+           , "static inline void " ++ releaseOutput ++ "(" ++ outputType ++ " *array)"
+           , "{ if (array == NULL) return; if (array->context != NULL) { if (array->release == NULL) abort(); array->release(array->context); } array->lookup = NULL; array->context = NULL; array->retain = NULL; array->release = NULL; }"
+           , "static inline " ++ inputType ++ " " ++ asInput ++ "(" ++ outputType ++ " array)"
+           , "{ " ++ inputType ++ " input = {array.lookup, array.context, array.retain, array.release}; return input; }"
+           , "static inline SBV_CGEN_UNUSED " ++ outputType ++ " *" ++ cloneStored ++ "(const " ++ outputType ++ " *value)"
+           , "{"
+           , "  if (value == NULL) abort();"
+           , "  " ++ outputType ++ " *copy = (" ++ outputType ++ " *) malloc(sizeof *copy);"
+           , "  if (copy == NULL) abort();"
+           , "  *copy = " ++ retainOutput ++ "(*value);"
+           , "  return copy;"
+           , "}"
+           , "static inline SBV_CGEN_UNUSED void " ++ releaseStored ++ "(" ++ outputType ++ " **value)"
+           , "{"
+           , "  if (value == NULL || *value == NULL) return;"
+           , "  " ++ releaseOutput ++ "(*value);"
+           , "  free(*value);"
+           , "  *value = NULL;"
+           , "}"
+           , "#endif"
+           , ""
+           ]
+       declaration kind = error $ "SBV->C: Expected an array kind, received " ++ show kind
+
+-- | Emit the node layouts and newest-write-first lookup helpers for every
+-- array kind used by a generated program.
+arrayRuntime :: CgConfig -> [Kind] -> Doc
+arrayRuntime _   []    = empty
+arrayRuntime cfg kinds = text . unlines $
+     [ "/* Persistent functional-array runtime. */"
+     , "typedef enum { SBV_ARRAY_CONSTANT, SBV_ARRAY_STORE, SBV_ARRAY_CALLBACK } SBVArrayNodeKind;"
+     , "typedef struct sbv_array_temp sbv_array_temp;"
+     , "struct sbv_array_temp { sbv_array_temp *next; void *value; void (*release)(void *value); };"
+     , "typedef struct { sbv_array_temp *temporaries; } sbv_array_ctx;"
+     , ""
+     , "static SBV_CGEN_UNUSED void sbv_array_ctx_remember(sbv_array_ctx *ctx, void *value, void (*release)(void *value))"
+     , "{"
+     , "  if (ctx == NULL || value == NULL || release == NULL) abort();"
+     , "  sbv_array_temp *temporary = (sbv_array_temp *) malloc(sizeof *temporary);"
+     , "  if (temporary == NULL) abort();"
+     , "  temporary->next = ctx->temporaries;"
+     , "  temporary->value = value;"
+     , "  temporary->release = release;"
+     , "  ctx->temporaries = temporary;"
+     , "}"
+     , ""
+     , "static SBV_CGEN_UNUSED void sbv_array_ctx_end(sbv_array_ctx *ctx)"
+     , "{"
+     , "  while (ctx != NULL && ctx->temporaries != NULL) {"
+     , "    sbv_array_temp *temporary = ctx->temporaries;"
+     , "    ctx->temporaries = temporary->next;"
+     , "    temporary->release(temporary->value);"
+     , "    free(temporary);"
+     , "  }"
+     , "}"
+     , ""
+     ]
+  ++ concatMap runtime kinds
+ where runtime kind@(KArray keyKind valueKind) =
+         let nodeType    = arrayNodeType kind
+             arrayType   = arrayCType kind
+             keyType     = elementCType keyKind
+             valueType   = elementCType valueKind
+             readName    = arrayReadName kind
+             keyEquality = P.render $ keyEqual cfg keyKind (text "array->key") (text "key")
+         in [ "struct " ++ nodeType ++ " {"
+            , "  SBVArrayNodeKind kind;"
+            , "  " ++ arrayType ++ " parent;"
+            , "  " ++ keyType ++ " key;"
+            , "  " ++ valueType ++ " value;"
+            , "  " ++ arrayLookupType kind ++ " lookup;"
+            , "  const void *context;"
+            , "  SBVArrayContextRetain retain;"
+            , "  SBVArrayContextRelease release;"
+            , "};"
+            , ""
+            , "static SBV_CGEN_UNUSED " ++ valueType ++ " " ++ readName ++ "(" ++ arrayType ++ " array, " ++ keyType ++ " key)"
+            , "{"
+            , "  while (array->kind == SBV_ARRAY_STORE) {"
+            , "    if (" ++ keyEquality ++ ") return array->value;"
+            , "    array = array->parent;"
+            , "  }"
+            , "  if (array->kind == SBV_ARRAY_CALLBACK) return array->lookup(array->context, key);"
+            , "  return array->value;"
+            , "}"
+            , ""
+            ]
+         ++ ownershipRuntime cfg kind
+         ++ storedArrayRuntime kind
+       runtime kind = error $ "SBV->C: Expected an array kind, received " ++ show kind
+
+-- | Emit the per-kind bridge that turns a call-scoped array node into an
+-- owned descriptor pointer tracked by the function's temporary arena.
+storedArrayRuntime :: Kind -> [String]
+storedArrayRuntime kind@KArray{} =
+  [ "static SBV_CGEN_UNUSED void " ++ releaseVoid ++ "(void *value)"
+  , "{"
+  , "  " ++ outputType ++ " *array = (" ++ outputType ++ " *) value;"
+  , "  " ++ arrayOutputReleaseName kind ++ "(array);"
+  , "  free(array);"
+  , "}"
+  , ""
+  , "static SBV_CGEN_UNUSED " ++ outputType ++ " *" ++ exportStored
+ ++   "(sbv_array_ctx *ctx, " ++ arrayCType kind ++ " array)"
+  , "{"
+  , "  " ++ outputType ++ " *result = (" ++ outputType ++ " *) malloc(sizeof *result);"
+  , "  if (result == NULL) abort();"
+  , "  *result = " ++ arrayExportName kind ++ "(array);"
+  , "  sbv_array_ctx_remember(ctx, result, " ++ releaseVoid ++ ");"
+  , "  return result;"
+  , "}"
+  , ""
+  ]
+ where outputType   = arrayOutputCType kind
+       exportStored = arrayStoredExportName kind
+       releaseVoid  = "sbv_array_stored_release_void_" ++ arraySuffix kind
+storedArrayRuntime kind = error $ "SBV->C: Expected an array kind, received " ++ show kind
+
+-- | Emit the heap owner used when an array escapes its generated call. Store
+-- chains are copied, exact keys and values are duplicated into a private GMP
+-- arena, managed aggregates are deep-copied, and callback contexts are
+-- retained through their lifetime protocol.
+ownershipRuntime :: CgConfig -> Kind -> [String]
+ownershipRuntime cfg kind@(KArray keyKind valueKind) =
+  [ "typedef struct {"
+  , "  size_t references;"
+  , "  size_t node_count;"
+  , "  " ++ nodeType ++ " *nodes;"
+  ]
+  ++ ["  sbv_gmp_ctx exact_values;" | hasExact]
+  ++ [ "  const void *base_context;"
+     , "  SBVArrayContextRelease base_release;"
+     , "} " ++ ownerType ++ ";"
+     , ""
+     , "static SBV_CGEN_UNUSED " ++ valueType ++ " " ++ ownedLookup ++ "(const void *context, " ++ keyType ++ " key)"
+     , "{"
+     , "  const " ++ ownerType ++ " *owner = (const " ++ ownerType ++ " *) context;"
+     , "  return " ++ arrayReadName kind ++ "(&owner->nodes[0], key);"
+     , "}"
+     , ""
+     , "static SBV_CGEN_UNUSED const void *" ++ ownedRetain ++ "(const void *context)"
+     , "{"
+     , "  " ++ ownerType ++ " *owner = (" ++ ownerType ++ " *) context;"
+     , "  ++owner->references;"
+     , "  return context;"
+     , "}"
+     , ""
+     , "static SBV_CGEN_UNUSED void " ++ ownedRelease ++ "(const void *context)"
+     , "{"
+     , "  " ++ ownerType ++ " *owner = (" ++ ownerType ++ " *) context;"
+     , "  if (--owner->references != 0) return;"
+     , "  if (owner->base_release != NULL) owner->base_release(owner->base_context);"
+     ]
+  ++ releaseManagedFields
+  ++ ["  sbv_gmp_ctx_end(&owner->exact_values);" | hasExact]
+  ++ [ "  free(owner->nodes);"
+     , "  free(owner);"
+     , "}"
+     , ""
+     , "static SBV_CGEN_UNUSED " ++ outputType ++ " " ++ arrayExportName kind ++ "(" ++ arrayType ++ " array)"
+     , "{"
+     , "  size_t count = 1;"
+     , "  " ++ arrayType ++ " cursor = array;"
+     , "  if (cursor == NULL) abort();"
+     , "  while (cursor->kind == SBV_ARRAY_STORE) { if (cursor->parent == NULL) abort(); ++count; cursor = cursor->parent; }"
+     , "  " ++ ownerType ++ " *owner = (" ++ ownerType ++ " *) calloc(1, sizeof(*owner));"
+     , "  if (owner == NULL) abort();"
+     , "  owner->nodes = (" ++ nodeType ++ " *) calloc(count, sizeof(*owner->nodes));"
+     , "  if (owner->nodes == NULL) { free(owner); abort(); }"
+     , "  owner->references = 1;"
+     , "  owner->node_count = count;"
+     , "  " ++ arrayType ++ " source = array;"
+     , "  for (size_t i = 0; i < count; ++i) {"
+     , "    owner->nodes[i] = *source;"
+     , "    if (source->kind == SBV_ARRAY_STORE) {"
+     , "      owner->nodes[i].parent = &owner->nodes[i + 1];"
+     ]
+  ++ cloneExact "key" keyKind
+  ++ cloneManaged "key" keyKind
+  ++ [ "    }"
+     , "    if (source->kind != SBV_ARRAY_CALLBACK) {"
+     ]
+  ++ cloneExact "value" valueKind
+  ++ cloneManaged "value" valueKind
+  ++ [ "    }"
+     , "    if (source->kind == SBV_ARRAY_CALLBACK && source->context != NULL) {"
+     , "      if (source->retain == NULL || source->release == NULL) abort();"
+     , "      owner->base_context = source->retain(source->context);"
+     , "      if (owner->base_context == NULL) abort();"
+     , "      owner->base_release = source->release;"
+     , "      owner->nodes[i].context = owner->base_context;"
+     , "    }"
+     , "    if (source->kind == SBV_ARRAY_STORE) source = source->parent;"
+     , "  }"
+     , "  " ++ outputType ++ " output = {" ++ ownedLookup ++ ", owner, " ++ ownedRetain ++ ", " ++ ownedRelease ++ "};"
+     , "  return output;"
+     , "}"
+     , ""
+     ]
+ where nodeType      = arrayNodeType kind
+       arrayType     = arrayCType kind
+       inputSuffix   = arraySuffix kind
+       ownerType     = "sbv_array_owner_" ++ inputSuffix
+       outputType    = arrayOutputCType kind
+       ownedLookup   = "sbv_array_owned_lookup_" ++ inputSuffix
+       ownedRetain   = "sbv_array_owned_retain_" ++ inputSuffix
+       ownedRelease  = "sbv_array_owned_release_" ++ inputSuffix
+       keyType       = elementCType keyKind
+       valueType     = elementCType valueKind
+       hasExact      = isExactGMPKind cfg keyKind || isExactGMPKind cfg valueKind
+
+       releaseManagedFields
+         | keyManaged || valueManaged
+         = ["  for (size_t i = 0; owner->nodes != NULL && i < owner->node_count; ++i) {"]
+        ++ [ "    if (owner->nodes[i].kind == SBV_ARRAY_STORE) " ++ release "key" keyKind
+           | keyManaged
+           ]
+        ++ [ "    if (owner->nodes[i].kind != SBV_ARRAY_CALLBACK) " ++ release "value" valueKind
+           | valueManaged
+           ]
+        ++ ["  }"]
+         | True
+         = []
+
+       keyManaged   = arrayFieldNeedsOwnership cfg keyKind
+       valueManaged = arrayFieldNeedsOwnership cfg valueKind
+
+       release field fieldKind = P.render $ managedValueRelease fieldKind (text ("&owner->nodes[i]." ++ field))
+
+       cloneExact field fieldKind
+         | isExactGMPKind cfg fieldKind
+         = [ "      " ++ gmpOutputType fieldKind ++ " copy = " ++ gmpNewName fieldKind ++ "(&owner->exact_values);"
+           , "      " ++ gmpFunctionName fieldKind "set" ++ "(copy, source->" ++ field ++ ");"
+           , "      owner->nodes[i]." ++ field ++ " = copy;"
+           ]
+         | True
+         = []
+
+       cloneManaged field fieldKind
+         | arrayFieldNeedsOwnership cfg fieldKind
+         = [ "      owner->nodes[i]." ++ field ++ " = "
+          ++ P.render (managedValueClone fieldKind (text ("source->" ++ field))) ++ ";"
+           ]
+         | True
+         = []
+
+ownershipRuntime _ kind = error $ "SBV->C: Expected an array kind, received " ++ show kind
+
+-- | Materialize a borrowed public callback descriptor as an internal array
+-- root. A null lookup callback is rejected before the symbolic program runs.
+arrayInputSetup :: Int -> SV -> String -> [Doc]
+arrayInputSetup typeWidth sv externalName
+  | kind@KArray{} <- kindOf sv
+  = [ text "if" P.<> parens (external P.<> text ".lookup == NULL") <+> text "abort" P.<> parens empty P.<> semi
+    , text "if" P.<> parens (parens (external P.<> text ".retain == NULL") <+> text "!=" <+> parens (external P.<> text ".release == NULL")) <+> text "abort" P.<> parens empty P.<> semi
+    , text "const" <+> text (arrayNodeType kind) <+> text nodeName <+> text "=" <+> braces (fsep (punctuate comma fields)) P.<> semi
+    , text "const" <+> paddedType <+> text (show sv) <+> text "=" <+> text "&" P.<> text nodeName P.<> semi
+    ]
+ where external   = text externalName
+       nodeName   = "sbv_local_array_input_" ++ show sv
+       paddedType = text $ arrayCType (kindOf sv) ++ replicate (typeWidth - length (arrayCType (kindOf sv))) ' '
+       fields     = [ text ".kind = SBV_ARRAY_CALLBACK"
+                    , text ".lookup ="  <+> external P.<> text ".lookup"
+                    , text ".context =" <+> external P.<> text ".context"
+                    , text ".retain ="  <+> external P.<> text ".retain"
+                    , text ".release =" <+> external P.<> text ".release"
+                    ]
+arrayInputSetup _ sv _ = error $ "SBV->C: Expected an array input, received " ++ show (kindOf sv)
+
+-- | Emit the per-kind default-only callback used by example-driver array
+-- values. Sharing one callback per array kind lets arrays appear at arbitrary
+-- depth inside driver aggregates without requiring path-specific functions.
+arrayDriverCallback :: CgConfig -> Kind -> Doc
+arrayDriverCallback cfg kind@(KArray keyKind valueKind)
+  = text "#ifndef" <+> text (arrayDriverGuard kind)
+  $$ text "#define" <+> text (arrayDriverGuard kind)
+  $$ text "static SBV_CGEN_UNUSED" <+> text (elementCType valueKind) <+> text callbackName
+      P.<> parens (fsep (punctuate comma [text "const void *context", text (elementCType keyKind) <+> text "key"]))
+  $$ text "{"
+  $$ nest 2 (   parens (text "void") <+> text "key" P.<> semi
+             $$ text "return" <+> result P.<> semi
+            )
+  $$ text "}"
+  $$ text ""
+  $$ retainContext
+  $$ text ""
+  $$ releaseContext
+  $$ text "#endif"
+ where callbackName = arrayDriverCallbackName kind
+       retainName   = arrayDriverRetainName kind
+       releaseName  = arrayDriverReleaseName kind
+       result
+         | isExactGMPKind cfg valueKind = parens (text (elementCType valueKind)) <+> text "context"
+         | True                          = text "*" P.<> parens (parens (text (constElementCType valueKind) <+> text "*") <+> text "context")
+
+       retainContext
+         | isExactGMPKind cfg valueKind
+         = text "static SBV_CGEN_UNUSED const void *" P.<> text retainName P.<> parens (text "const void *context")
+           $$ text "{"
+           $$ nest 2 (   text mutableType <+> text "copy =" <+> parens (text mutableType) <+> text "malloc(sizeof(*copy));"
+                      $$ text "if (copy == NULL) abort();"
+                      $$ vcat (map text exactCopy)
+                      $$ text "return copy;"
+                     )
+           $$ text "}"
+         | arrayFieldNeedsOwnership cfg valueKind
+         = text "static SBV_CGEN_UNUSED const void *" P.<> text retainName P.<> parens (text "const void *context")
+           $$ text "{"
+           $$ nest 2 (   text (elementCType valueKind) <+> text "*copy =" <+> parens (text (elementCType valueKind) <+> text "*") <+> text "malloc(sizeof(*copy));"
+                      $$ text "if (copy == NULL) abort();"
+                      $$ text "*copy =" <+> managedValueClone valueKind managedContextValue P.<> semi
+                      $$ text "return copy;"
+                     )
+           $$ text "}"
+         | True
+         = text "static SBV_CGEN_UNUSED const void *" P.<> text retainName P.<> parens (text "const void *context")
+           $$ text "{"
+           $$ nest 2 (   text (elementCType valueKind) <+> text "*copy =" <+> parens (text (elementCType valueKind) <+> text "*") <+> text "malloc(sizeof(*copy));"
+                      $$ text "if (copy == NULL) abort();"
+                      $$ text "*copy =" <+> managedContextValue P.<> semi
+                      $$ text "return copy;"
+                     )
+           $$ text "}"
+
+       releaseContext
+         = text "static SBV_CGEN_UNUSED void" <+> text releaseName P.<> parens (text "const void *context")
+           $$ text "{"
+           $$ nest 2 (   managedClear
+                      $$ exactClear
+                      $$ text "free" P.<> parens (text "(void *) context") P.<> semi
+                     )
+           $$ text "}"
+
+       managedContextValue = text "*" P.<> parens (parens (text (constElementCType valueKind) <+> text "*") <+> text "context")
+
+       managedClear
+         | arrayFieldNeedsOwnership cfg valueKind
+         =  text (elementCType valueKind) <+> text "*value =" <+> parens (text (elementCType valueKind) <+> text "*") <+> text "context" P.<> semi
+         $$ managedValueRelease valueKind (text "value")
+         | True
+         = empty
+
+       mutableType
+         | KUnbounded <- valueKind            = "mpz_ptr"
+         | isExactGMPKind cfg valueKind        = "mpq_ptr"
+         | True                                = error $ "SBV->C: Expected an exact callback value, received " ++ show valueKind
+
+       exactCopy
+         | KUnbounded <- valueKind = ["mpz_init_set(copy, (SInteger) context);"]
+         | isExactGMPKind cfg valueKind
+         = ["mpq_init(copy);", "mpq_set(copy, (" ++ elementCType valueKind ++ ") context);"]
+         | True = error $ "SBV->C: Expected an exact callback value, received " ++ show valueKind
+
+       exactClear
+         | KUnbounded <- valueKind            = text "mpz_clear((mpz_ptr) context);"
+         | isExactGMPKind cfg valueKind        = text "mpq_clear((mpq_ptr) context);"
+         | True                                = empty
+arrayDriverCallback _ kind = error $ "SBV->C: Expected an array input kind, received " ++ show kind
+
+-- | Construct an example-driver descriptor around a named default value and
+-- its generated callback. Exact GMP defaults already decay to pointers;
+-- ordinary values are passed to the callback by address.
+arrayDriverInput :: CgConfig -> Kind -> String -> String -> Doc
+arrayDriverInput cfg kind inputName defaultName
+  | KArray _ valueKind <- kind
+  = let context
+          | isExactGMPKind cfg valueKind = text defaultName
+          | True                          = text "&" P.<> text defaultName
+    in text "const" <+> text (arrayInputCType kind) <+> text inputName <+> text "="
+         <+> braces (fsep (punctuate comma [ text ".lookup ="  <+> text (arrayDriverCallbackName kind)
+                                          , text ".context =" <+> context
+                                          , text ".retain ="  <+> text (arrayDriverRetainName kind)
+                                          , text ".release =" <+> text (arrayDriverReleaseName kind)
+                                          ])) P.<> semi
+  | True
+  = error $ "SBV->C: Expected an array input kind, received " ++ show kind
+
+-- | Retain a generated input descriptor into the pointer representation used
+-- by array-valued aggregate fields. The returned pointer owns both its heap
+-- descriptor and one retained callback-context reference.
+arrayDriverStoredInput :: Kind -> String -> String -> Doc
+arrayDriverStoredInput kind@KArray{} externalName inputName
+  =  text (arrayOutputCType kind) <+> text "*" P.<> text externalName <+> text "="
+       <+> parens (text (arrayOutputCType kind) <+> text "*") <+> text "malloc(sizeof(*" P.<> text externalName P.<> text "));"
+  $$ text "if" <+> parens (text externalName <+> text "== NULL") <+> text "abort();"
+  $$ text "*" P.<> text externalName <+> text "="
+       <+> text (arrayOutputRetainName kind)
+       P.<> parens (parens (text (arrayOutputCType kind))
+             <+> braces (fsep (punctuate comma [ text ".lookup ="  <+> text inputName P.<> text ".lookup"
+                                               , text ".context =" <+> text inputName P.<> text ".context"
+                                               , text ".retain ="  <+> text inputName P.<> text ".retain"
+                                               , text ".release =" <+> text inputName P.<> text ".release"
+                                               ]))) P.<> semi
+arrayDriverStoredInput kind _ _ = error $ "SBV->C: Expected an array input kind, received " ++ show kind
+
+-- | Render a concrete array model as a nested chain of C99 compound literals.
+-- Association-list entries retain SBV's newest-write-first ordering.
+arrayConst :: (CV -> Doc) -> CV -> Maybe Doc
+arrayConst renderValue (CV kind@(KArray keyKind valueKind) (CArray (ArrayModel associations defaultValue)))
+  = Just $ foldr store base associations
+ where base = nodeLiteral [text ".kind = SBV_ARRAY_CONSTANT", text ".value =" <+> renderField valueKind defaultValue]
+
+       store (key, value) parent = nodeLiteral
+         [ text ".kind = SBV_ARRAY_STORE"
+         , text ".parent =" <+> parent
+         , text ".key ="    <+> renderValue (CV keyKind key)
+         , text ".value ="  <+> renderField valueKind value
+         ]
+
+       renderField fieldKind fieldValue
+         = arrayStoredValue fieldKind (renderValue (CV fieldKind fieldValue))
+
+       nodeLiteral fields = parens $ text "&" P.<> parens (text (arrayNodeType kind)) P.<> braces (fsep (punctuate comma fields))
+arrayConst _ _ = Nothing
+
+-- | Lower array initialization, reads, writes, and array-valued conditionals.
+-- Structured lambda-backed arrays, including free arrays, become callback
+-- roots. Array-valued elements cross node boundaries through retained
+-- descriptor pointers. The supplied name resolvers identify private defined
+-- functions and lambda-lifted array callbacks. Equality calls a helper whose
+-- finite key domain and enumeration limit are checked by the C renderer.
+arrayExpr :: CgConfig
+          -> (T.Text -> Maybe String)
+          -> (SV -> Maybe String)
+          -> Op
+          -> [SV]
+          -> SV
+          -> [Doc]
+          -> Maybe CLowering
+arrayExpr cfg definedFunctionName structuredLambdaName op svs resultSV args
+  | not (isArray resultKind || any isArray svs)
+  = Nothing
+  | True
+  = case (op, svs, args) of
+      (TupleConstructor{}, _, _) -> Nothing
+      (TupleAccess{},      _, _) -> Nothing
+      (ADTOp{},            _, _) -> Nothing
+      (SeqOp{},            _, _) -> Nothing
+      (SetOp{},            _, _) -> Nothing
+      (LkUp{},             _, _) -> Nothing
+      (Uninterpreted symbol, _, renderedArguments)
+        | isArray resultKind
+        , Just functionName <- definedFunctionName symbol
+        -> Just $ arrayStoredLoad resultSV
+             (namedCall functionName (text "&sbv_local_function_ctx" : renderedArguments))
+        | True
+        -> Nothing
+      (ArrayInit (Left pair), [_], [defaultValue])
+        | resultKind == uncurry KArray pair
+        -> nodeLowering resultKind
+             [text ".kind = SBV_ARRAY_CONSTANT", text ".value =" <+> storedValue (snd pair) defaultValue]
+      (ArrayInit (Right lambdaDef), [], [])
+        | Just _            <- smtLambdaInfo lambdaDef
+        , Just callbackName <- structuredLambdaName resultSV
+        -> nodeLowering resultKind
+             [ text ".kind = SBV_ARRAY_CALLBACK"
+             , text ".lookup ="  <+> text callbackName
+             , text ".context =" <+> text "&sbv_local_function_ctx"
+             , text ".retain ="  <+> text "sbv_function_ctx_retain_empty"
+             , text ".release =" <+> text "sbv_function_ctx_release_owned"
+             ]
+        | True
+        -> unsupported "lambda arrays without registered retained structured expressions"
+      (ReadArray, [array, key], [renderedArray, renderedKey])
+        | kindOf array == KArray (kindOf key) resultKind
+        -> let readResult = namedCall (arrayReadName (kindOf array)) [renderedArray, renderedKey]
+           in if isArray resultKind then Just (arrayStoredLoad resultSV readResult) else expression readResult
+      (WriteArray, [array, key, value], [renderedArray, renderedKey, renderedValue])
+        | resultKind == kindOf array
+        , resultKind == KArray (kindOf key) (kindOf value)
+        -> nodeLowering resultKind
+             [ text ".kind = SBV_ARRAY_STORE"
+             , text ".parent =" <+> renderedArray
+             , text ".key ="    <+> renderedKey
+             , text ".value ="  <+> storedValue (kindOf value) renderedValue
+             ]
+      (Label label, [_], [array])
+        -> expression $ array <+> text "/*" <+> cCommentText label <+> text "*/"
+      (Equal{}, initial:rest, a:as)
+        | all ((== kindOf initial) . kindOf) rest
+        -> expression $ conjunction [namedCall (arrayEqualName (kindOf initial)) [a, b] | b <- as]
+      (NotEqual, initial:rest, _)
+        | all ((== kindOf initial) . kindOf) rest
+        -> expression $ conjunction [text "!" P.<> parens (namedCall (arrayEqualName (kindOf initial)) [a, b])
+                                    | a:as <- tails args, b <- as]
+      _                  -> error $ "SBV->C: Unsupported array operation " ++ show op
+                           ++ " with argument kinds " ++ show (map kindOf svs)
+                           ++ " and result kind " ++ show resultKind
+ where resultKind = kindOf resultSV
+
+       expression = Just . expressionLowering requirements
+
+       conjunction [] = text "true"
+       conjunction ds = hsep (punctuate (text " &&") (map parens ds))
+
+       nodeLowering kind fields = Just CLowering
+         { loweringExpression   = text "&" P.<> text nodeName
+         , loweringDeclarations = [text (arrayNodeType kind) <+> text nodeName P.<> semi]
+         , loweringSetup        = [text nodeName <+> text "=" <+> parens (text (arrayNodeType kind))
+                                                    <+> braces (fsep (punctuate comma fields)) P.<> semi]
+         , loweringRequirements = Set.fromList requirements
+         }
+
+       nodeName = "sbv_local_array_" ++ show resultSV
+
+       storedValue = arrayStoredValue
+
+       requirements = CRequiresArrays : concatMap kindRequirements (resultKind : map kindOf svs)
+
+       kindRequirements kind
+         | isWideBV kind                 = [CRequiresWideBV]
+         | isFP kind                     = [CRequiresLibBF, CRequiresLibM]
+         | isExactGMPKind cfg kind        = [CRequiresGMP]
+         | kind `elem` [KFloat, KDouble] = [CRequiresLibM]
+         | KArray keyKind valueKind <- kind
+         = kindRequirements keyKind ++ kindRequirements valueKind
+         | True = []
+
+       unsupported feature = error $ "SBV->C: Arrays do not yet support " ++ feature ++ "."
+
+       namedCall functionName callArgs = text functionName P.<> parens (fsep (punctuate comma callArgs))
+
+-- | Name the private exact finite-domain array equality helper.
+arrayEqualName :: Kind -> String
+arrayEqualName kind = "sbv_array_equal_" ++ arraySuffix kind
+
+-- | Initialize the arena that owns array descriptors embedded in temporary
+-- generated values.
+arrayContextStart :: Doc
+arrayContextStart = text "sbv_array_ctx sbv_local_array_ctx = {NULL};"
+
+-- | Release the array descriptors embedded in temporary generated values.
+arrayContextEnd :: Doc
+arrayContextEnd = text "sbv_array_ctx_end" P.<> parens (text "&sbv_local_array_ctx") P.<> semi
+
+-- | Return the concrete node-structure name for an array kind.
+arrayNodeType :: Kind -> String
+arrayNodeType kind = "sbv_array_node_" ++ arraySuffix kind
+
+-- | Return the lookup-helper name for an array kind.
+arrayReadName :: Kind -> String
+arrayReadName kind = "sbv_array_read_" ++ arraySuffix kind
+
+-- | Return the callback-function-pointer type for an array kind.
+arrayLookupType :: Kind -> String
+arrayLookupType kind = "SBVArrayLookup_" ++ arraySuffix kind
+
+-- | Return the generated example-driver callback name for an array kind.
+arrayDriverCallbackName :: Kind -> String
+arrayDriverCallbackName kind = "sbv_local_array_driver_lookup_" ++ arraySuffix kind
+
+-- | Return the generated example-driver context-retain callback name.
+arrayDriverRetainName :: Kind -> String
+arrayDriverRetainName kind = "sbv_local_array_retain_driver_" ++ arraySuffix kind
+
+-- | Return the generated example-driver context-release callback name.
+arrayDriverReleaseName :: Kind -> String
+arrayDriverReleaseName kind = "sbv_local_array_release_driver_" ++ arraySuffix kind
+
+-- | Return the preprocessor guard that deduplicates a per-kind driver callback
+-- when independently generated library components share an array type.
+arrayDriverGuard :: Kind -> String
+arrayDriverGuard kind = "SBV_ARRAY_DRIVER_CALLBACK_" ++ arraySuffix kind ++ "_DEFINED"
+
+-- | Return the generated C lookup-helper name for a structured lambda array.
+arrayLambdaName :: SV -> String
+arrayLambdaName array = "sbv_array_lambda_" ++ show array
+
+-- | Return the key/value suffix shared by the generated names for an array
+-- kind.
+arraySuffix :: Kind -> String
+arraySuffix = arrayKindTag
+
+-- | Return the preprocessor guard protecting an array type declaration.
+arrayGuard :: Kind -> String
+arrayGuard kind = arrayCType kind ++ "_DEFINED"
+
+-- | Return the preprocessor guard protecting an array descriptor's forward
+-- declaration and stored-value helper prototypes.
+arrayForwardGuard :: Kind -> String
+arrayForwardGuard kind = arrayOutputCType kind ++ "_FORWARD_DEFINED"
+
+-- | Render the strong equality used to match array keys. Unlike IEEE numeric
+-- equality, this recursively preserves object equality for aggregate fields.
+keyEqual :: CgConfig -> Kind -> Doc -> Doc -> Doc
+keyEqual cfg = byValueEqual cfg True
+
+-- | Test whether an array field needs an independent deep copy when its node
+-- escapes the generated call. Direct exact values use the owner's GMP arena.
+arrayFieldNeedsOwnership :: CgConfig -> Kind -> Bool
+arrayFieldNeedsOwnership cfg kind
+  | isExactGMPKind cfg kind = False
+  | isConcreteADT kind      = True
+  | True                    = valueNeedsOwnership cfg kind
diff --git a/Data/SBV/Compilers/C/BV.hs b/Data/SBV/Compilers/C/BV.hs
new file mode 100644
--- /dev/null
+++ b/Data/SBV/Compilers/C/BV.hs
@@ -0,0 +1,1031 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Data.SBV.Compilers.C.BV
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Exact, portable lowering of non-native sized bit-vectors to C.
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Data.SBV.Compilers.C.BV
+  ( isWideBV
+  , wideBVKinds
+  , wideBVTypeDecls
+  , bitVectorRuntime
+  , wideBVConst
+  , wideBVExpr
+  , bitVectorCastExpr
+  , nativeBVExpr
+  , mappedIntegerKind
+  , nativeBVOverflowExpr
+  , wideBVLookupInRange
+  , wideBVLookupIndex
+  , wideBVEqual
+  , wideBVNormalize
+  , wideBVPrint
+  ) where
+
+import Data.SBV.Compilers.C.Syntax (cUnusedAttribute)
+import Data.Bits                  (shiftL, shiftR, (.&.))
+import Data.Char                  (toUpper)
+import Data.List                  (intercalate, nub, stripPrefix, tails)
+import qualified Data.Set as Set
+import Numeric                    (showHex)
+
+import Text.PrettyPrint.HughesPJ
+import qualified Text.PrettyPrint.HughesPJ as P ((<>))
+
+import Data.SBV.Compilers.C.Lowering  (CLowering, CRequirement(..), expressionLowering)
+import Data.SBV.Core.Data
+
+-- | True when a bit-vector cannot use the historical scalar C ABI. These
+-- values are represented as little-endian arrays of 64-bit limbs.
+isWideBV :: Kind -> Bool
+isWideBV k = isBounded k
+          && k /= KBounded False 1
+          && intSizeOf k `notElem` [8, 16, 32, 64]
+
+-- | The distinct non-native bit-vector kinds used by a program.
+wideBVKinds :: Set.Set Kind -> [Kind]
+wideBVKinds = filter isWideBV . Set.toAscList
+
+-- | Type declarations and printing routines belonging in the public header.
+wideBVTypeDecls :: [Kind] -> Doc
+wideBVTypeDecls [] = empty
+wideBVTypeDecls ks = text . unlines $
+     ["/* Exact-width bit-vectors (least-significant limb first). */"
+     , cUnusedAttribute]
+  ++ concatMap decl ks
+ where decl k = ["#ifndef " ++ guard k
+                , "#define " ++ guard k
+                , "typedef struct { uint64_t limb[" ++ show (limbs k) ++ "]; } " ++ cType k ++ ";"
+                , "static inline SBV_CGEN_UNUSED void " ++ prefix k ++ "_fprint(FILE *stream, " ++ cType k ++ " value)"
+                , "{"
+                , "  size_t i = " ++ show (limbs k) ++ ";"
+                , "  fputs(\"0x\", stream);"
+                , "  while (i-- > 0) { fprintf(stream, \"%016\" PRIx64, value.limb[i]); }"
+                , "}"
+                , "#endif"
+                , ""]
+
+       guard k = "SBV_BV_" ++ map toUpper (tag k) ++ "_DEFINED"
+
+-- | Runtime routines for each used exact-width type, together with the exact
+-- native arithmetic, bit-manipulation, and cross-width helpers demanded by
+-- the complete symbolic DAG. Native-only programs can require these helpers
+-- even when no limb-backed type occurs. The optional integer width selects
+-- modular arithmetic helpers for explicitly mapped 'SInteger' values too.
+bitVectorRuntime :: Maybe Int -> [Kind] -> [(SV, SBVExpr)] -> Doc
+bitVectorRuntime integerWidth ks asgns
+  | null routines = empty
+  | True          = text . unlines . map markUnused $
+       [ "/* Exact bit-vector runtime. All arithmetic is modulo the declared width. */"
+       , cUnusedAttribute
+       , ""
+       ]
+    ++ routines
+ where specials (sv, SBVApp op args) = case op of
+         Extract hi lo                  -> [SpecialExtract (kindOf (headArg "Extract" args)) hi lo (kindOf sv)]
+         Join                           -> case args of
+                                             [a, b] -> [SpecialJoin (kindOf a) (kindOf b) (kindOf sv)]
+                                             _      -> badArity "Join" args
+         Rol{}
+           | source : _ <- args
+           , isNativeBV source          -> [SpecialRotate (kindOf source)]
+         Ror{}
+           | source : _ <- args
+           , isNativeBV source          -> [SpecialRotate (kindOf source)]
+         Shl
+           | source : _ <- args
+           , isNativeBV source          -> [SpecialShift (kindOf source)]
+         Shr
+           | source : _ <- args
+           , isNativeBV source          -> [SpecialShift (kindOf source)]
+         Plus                           -> nativeArithmetic args SpecialAdd
+         Minus                          -> nativeArithmetic args SpecialSub
+         Times                          -> nativeArithmetic args SpecialMul
+         UNeg                           -> nativeArithmetic args SpecialNeg
+         Abs                            -> nativeArithmetic args SpecialAbs
+         Quot                           -> nativeArithmetic args SpecialQuot
+         Rem                            -> nativeArithmetic args SpecialRem
+         ZeroExtend _                   -> [SpecialConvert False (kindOf (headArg "ZeroExtend" args)) (kindOf sv)]
+         SignExtend _                   -> [SpecialConvert True  (kindOf (headArg "SignExtend" args)) (kindOf sv)]
+         KindCast fr to
+           | let source = mappedIntegerKind integerWidth fr
+           , let target = mappedIntegerKind integerWidth to
+           , isBounded source && isBounded target -> [SpecialConvert (hasSign source) source target]
+         IEEEFP (FP_Reinterpret fr to)
+           | isBounded fr && isBounded to -> [SpecialConvert False fr to]
+         _                              -> []
+
+       specialRuntime s = case s of
+         SpecialExtract fr hi lo to      -> conversionRuntime (extractName fr hi lo to) False lo fr to
+         SpecialJoin a b to              -> joinRuntime a b to
+         SpecialConvert sign fr to       -> conversionRuntime (convertName sign fr to) sign 0 fr to
+         SpecialRotate kind              -> rotationRuntime kind
+         SpecialShift kind               -> shiftRuntime kind
+         SpecialArithmetic arith kind    -> nativeArithmeticRuntime arith kind
+
+       routines = concatMap coreRuntime ks
+               ++ concatMap specialRuntime (nub (concatMap specials asgns))
+
+       nativeArithmetic args arith = case args of
+         source : _
+           | let kind = mappedIntegerKind integerWidth (kindOf source)
+           , isNativeBVKind kind -> [SpecialArithmetic (integerArithmetic (kindOf source) arith) kind]
+         _                        -> []
+
+       markUnused line
+         | Just rest <- stripPrefix "static inline " line = "static inline SBV_CGEN_UNUSED " ++ rest
+         | otherwise                                      = line
+
+-- | Render a constant as a C99 compound literal.
+wideBVConst :: Kind -> Integer -> Maybe Doc
+wideBVConst k i
+  | isWideBV k = Just . text $ "(" ++ cType k ++ "){{" ++ intercalate ", " (map word [0 .. limbs k - 1]) ++ "}}"
+  | True       = Nothing
+ where normalized = i `mod` (2 ^ intSizeOf k)
+       word n     = u64 $ (normalized `shiftR` (64 * n)) .&. ((1 `shiftL` 64) - 1)
+
+-- | Lower an operation involving a non-native bit-vector. A 'Nothing' result
+-- means that the legacy scalar lowering should handle the operation.
+wideBVExpr :: Op -> [SV] -> Kind -> [Doc] -> Maybe CLowering
+wideBVExpr op svs resultKind args
+  | not (isWideBV resultKind || any (isWideBV . kindOf) svs)
+  = Nothing
+  | LkUp{} <- op
+  = Nothing
+  | Uninterpreted{} <- op
+  = Nothing
+  | True
+  = Just . expressionLowering [CRequiresWideBV] $ case (op, args, svs) of
+      (Label _                       , [a]      , _)      -> a
+      (Plus                          , [a, b]   , _)      -> call "add" [a, b]
+      (Minus                         , [a, b]   , _)      -> call "sub" [a, b]
+      (Times                         , [a, b]   , _)      -> call "mul" [a, b]
+      (UNeg                          , [a]      , _)      -> call "neg" [a]
+      (Abs                           , [a]      , _)      -> call "abs" [a]
+      (And                           , [a, b]   , _)      -> call "and" [a, b]
+      (Or                            , [a, b]   , _)      -> call "or" [a, b]
+      (XOr                           , [a, b]   , _)      -> call "xor" [a, b]
+      (Not                           , [a]      , _)      -> call "not" [a]
+      (Equal _                       , [a, b]   , x:_)    -> argCall x "eq" [a, b]
+      (NotEqual                      , as       , x:_)    -> fsep $ punctuate (text " &&")
+                                                                 [text "!" P.<> parens (argCall x "eq" [a, b])
+                                                                 | (a:rest) <- tails as, b <- rest]
+      (LessThan                      , [a, b]   , x:_)    -> argCall x "lt" [a, b]
+      (GreaterThan                   , [a, b]   , x:_)    -> argCall x "lt" [b, a]
+      (LessEq                        , [a, b]   , x:_)    -> text "!" P.<> parens (argCall x "lt" [b, a])
+      (GreaterEq                     , [a, b]   , x:_)    -> text "!" P.<> parens (argCall x "lt" [a, b])
+      (Ite                           , [c, a, b], _)      -> c <+> text "?" <+> a <+> text ":" <+> b
+      (Quot                          , [a, b]   , _)      -> call "quot" [a, b]
+      (Rem                           , [a, b]   , _)      -> call "rem" [a, b]
+      (Shl                           , [a, n]   , x:_)    -> argCall x "shl" [a, argCall x "shift_amount" [n]]
+      (Shr                           , [a, n]   , x:_)    -> argCall x (if hasSign x then "ashr" else "lshr") [a, argCall x "shift_amount" [n]]
+      (Rol n                         , [a]      , _)      -> call "rotl" [a, integer (fromIntegral n)]
+      (Ror n                         , [a]      , _)      -> call "rotr" [a, integer (fromIntegral n)]
+      (Extract hi lo                 , [a]      , x:_)    -> namedCall (extractName (kindOf x) hi lo resultKind) [a]
+      (Join                          , [a, b]   , [x, y]) -> namedCall (joinName (kindOf x) (kindOf y) resultKind) [a, b]
+      (ZeroExtend _                  , [a]      , x:_)    -> namedCall (convertName False (kindOf x) resultKind) [a]
+      (SignExtend _                  , [a]      , x:_)    -> namedCall (convertName True  (kindOf x) resultKind) [a]
+      (OverflowOp ov                 , as       , x:_)    -> argCall x (overflowName ov) as
+      (IEEEFP (FP_Reinterpret fr to) , [a]      , _)
+          | isBounded fr && isBounded to                  -> namedCall (convertName False fr to) [a]
+      _                                                   -> error $ "SBV->C: exact bit-vector lowering does not yet support " ++ show op
+                                                                  ++ " with argument kinds " ++ show (map kindOf svs)
+                                                                  ++ " and result kind " ++ show resultKind
+ where call suffix       = namedCall (prefix resultKind ++ "_" ++ suffix)
+       argCall sv suffix = namedCall (prefix (kindOf sv) ++ "_" ++ suffix)
+
+-- | Lower casts between native or limb-backed bit-vectors, including explicit
+-- native integer mappings. Resolve only the representations: the source's
+-- signedness controls extension, and narrowing preserves the target's low bits.
+bitVectorCastExpr :: Maybe Int -> Op -> [SV] -> Kind -> [Doc] -> Maybe CLowering
+bitVectorCastExpr integerWidth (KindCast fr to) [source] resultKind [value]
+  | fr == kindOf source
+  , to == resultKind
+  , isBounded from
+  , isBounded target
+  = Just $ expressionLowering [CRequiresWideBV | isWideBV from || isWideBV target]
+         $ namedCall (convertName (hasSign from) from target) [value]
+ where from   = mappedIntegerKind integerWidth fr
+       target = mappedIntegerKind integerWidth to
+bitVectorCastExpr _ _ _ _ _ = Nothing
+
+-- | Lower native-width arithmetic, conversion, and bit manipulation through
+-- exact bit-vector helpers. This avoids C's signed-overflow, promotion,
+-- signed-shift, and oversized-shift behavior while retaining the scalar
+-- public ABI. Explicitly mapped integers share the modular arithmetic helpers,
+-- with separate Euclidean division helpers matching their symbolic operations.
+nativeBVExpr :: Maybe Int -> Op -> [SV] -> Kind -> [Doc] -> Maybe CLowering
+nativeBVExpr integerWidth op svs resultKind args = case (op, svs, args) of
+  (Extract hi lo , [source]   , [renderedSource])
+    | isNativeBV source
+    , isNativeBVKind resultKind
+    -> lower $ namedCall (extractName (kindOf source) hi lo resultKind) [renderedSource]
+  (Join          , [high, low], [renderedHigh, renderedLow])
+    | isNativeBV high
+    , isNativeBV low
+    , isNativeBVKind resultKind
+    -> lower $ namedCall (joinName (kindOf high) (kindOf low) resultKind) [renderedHigh, renderedLow]
+  (ZeroExtend _  , [source]   , [renderedSource])
+    | isNativeBV source
+    , isNativeBVKind resultKind
+    -> lower $ namedCall (convertName False (kindOf source) resultKind) [renderedSource]
+  (SignExtend _  , [source]   , [renderedSource])
+    | isNativeBV source
+    , isNativeBVKind resultKind
+    -> lower $ namedCall (convertName True (kindOf source) resultKind) [renderedSource]
+  (Plus            , [left, right]   , [renderedLeft, renderedRight])
+    | nativeBinary left right
+    -> arithmetic SpecialAdd [renderedLeft, renderedRight]
+  (Minus           , [left, right]   , [renderedLeft, renderedRight])
+    | nativeBinary left right
+    -> arithmetic SpecialSub [renderedLeft, renderedRight]
+  (Times           , [left, right]   , [renderedLeft, renderedRight])
+    | nativeBinary left right
+    -> arithmetic SpecialMul [renderedLeft, renderedRight]
+  (UNeg            , [source]        , [renderedSource])
+    | nativeUnary source
+    -> arithmetic SpecialNeg [renderedSource]
+  (Abs             , [source]        , [renderedSource])
+    | nativeUnary source
+    -> arithmetic SpecialAbs [renderedSource]
+  (Quot            , [left, right]   , [renderedLeft, renderedRight])
+    | nativeBinary left right
+    -> arithmetic SpecialQuot [renderedLeft, renderedRight]
+  (Rem             , [left, right]   , [renderedLeft, renderedRight])
+    | nativeBinary left right
+    -> arithmetic SpecialRem [renderedLeft, renderedRight]
+  (Shl             , [source, amount], [renderedSource, renderedAmount])
+    | isNativeBV source
+    , isNativeBV amount
+    , kindOf source == resultKind
+    -> lower $ namedCall (prefix resultKind ++ "_shl") [renderedSource, renderedAmount]
+  (Shr             , [source, amount], [renderedSource, renderedAmount])
+    | isNativeBV source
+    , isNativeBV amount
+    , kindOf source == resultKind
+    -> lower $ namedCall (prefix resultKind ++ if hasSign source then "_ashr" else "_lshr") [renderedSource, renderedAmount]
+  (Rol amount      , [source]        , [renderedSource])
+    | isNativeBV source
+    , kindOf source == resultKind
+    -> lower $ namedCall (prefix resultKind ++ "_rotl") [renderedSource, integer (fromIntegral amount)]
+  (Ror amount      , [source]        , [renderedSource])
+    | isNativeBV source
+    , kindOf source == resultKind
+    -> lower $ namedCall (prefix resultKind ++ "_rotr") [renderedSource, integer (fromIntegral amount)]
+  _ -> Nothing
+ where lower = Just . expressionLowering []
+
+       arithmeticKind = mappedIntegerKind integerWidth resultKind
+
+       nativeUnary source = isNativeBVKind arithmeticKind && kindOf source == resultKind
+
+       nativeBinary left right = nativeUnary left && kindOf right == resultKind
+
+       arithmetic arith = lower . namedCall (prefix arithmeticKind ++ "_" ++ arithmeticSuffix (integerArithmetic resultKind arith))
+
+-- | Select the integer representation used by arithmetic and conversion
+-- helpers without changing the symbolic graph or its operation semantics.
+mappedIntegerKind :: Maybe Int -> Kind -> Kind
+mappedIntegerKind (Just bits) KUnbounded = KBounded True bits
+mappedIntegerKind _           kind       = kind
+
+-- | Integer division in the symbolic graph is Euclidean, even when a native
+-- representation is selected. Bit-vector division remains truncating.
+integerArithmetic :: Kind -> NativeArithmetic -> NativeArithmetic
+integerArithmetic KUnbounded SpecialQuot = SpecialEuclideanQuot
+integerArithmetic KUnbounded SpecialRem  = SpecialEuclideanRem
+integerArithmetic _          arith       = arith
+
+-- | Lower overflow predicates for scalar C bit-vector representations. The
+-- one-bit unsigned case follows its Boolean truth table; wider native cases
+-- avoid evaluating the overflowing operation itself, including signed
+-- division of the minimum value by -1.
+nativeBVOverflowExpr :: Op -> [SV] -> [Doc] -> Maybe CLowering
+nativeBVOverflowExpr (OverflowOp ov) svs args
+  | x:_ <- svs
+  , let k = kindOf x
+  , k == KBounded False 1
+  = Just . expressionLowering [] $ case (ov, args) of
+      (PlusOv False, [a, b]) -> a .&&. b
+      (SubOv  False, [a, b]) -> parens (text "!" P.<> a) .&&. b
+      (MulOv  False, [_, _]) -> text "false"
+      (DivOv       , [_, _]) -> text "false"
+      (NegOv       , [_])    -> text "false"
+      _                      -> error $ "SBV->C: One-bit overflow operation is invalid or has an unexpected arity: " ++ show ov
+  | x:_ <- svs
+  , let k = kindOf x
+  , isBounded k
+  , not (isWideBV k)
+  , intSizeOf k `elem` [8, 16, 32, 64]
+  = Just . expressionLowering [] $ case (ov, args) of
+      (PlusOv False, [a, b]) -> a .>. (maximumValue k .-. b)
+      (PlusOv True , [a, b]) -> signedAdd k a b
+      (SubOv  False, [a, b]) -> a .<. b
+      (SubOv  True , [a, b]) -> signedSub k a b
+      (MulOv  False, [a, b]) -> (b ./=. zero) .&&. (a .>. (maximumValue k ./. b))
+      (MulOv  True , [a, b]) -> signedMul k a b
+      (DivOv       , [a, b]) -> (a .==. minimumValue k) .&&. (b .==. negativeOne)
+      (NegOv       , [a])    -> a .==. minimumValue k
+      _                      -> error $ "SBV->C: Overflow operation has an unexpected arity: " ++ show ov
+  | True = Nothing
+ where x .<.  y = parens (x <+> text "<"  <+> y)
+       x .>.  y = parens (x <+> text ">"  <+> y)
+       x .==. y = parens (x <+> text "==" <+> y)
+       x ./=. y = parens (x <+> text "!=" <+> y)
+       x .&&. y = parens (x <+> text "&&" <+> y)
+       x .||. y = parens (x <+> text "||" <+> y)
+       x .+.  y = parens (x <+> text "+"  <+> y)
+       x .-.  y = parens (x <+> text "-"  <+> y)
+       x ./.  y = parens (x <+> text "/"  <+> y)
+
+       zero        = text "0"
+       negativeOne = text "-1"
+
+       signedAdd k a b = ((b .>. zero) .&&. (a .>. (maximumValue k .-. b)))
+                      .||. ((b .<. zero) .&&. (a .<. (minimumValue k .-. b)))
+
+       signedSub k a b = ((b .<. zero) .&&. (a .>. (maximumValue k .+. b)))
+                      .||. ((b .>. zero) .&&. (a .<. (minimumValue k .+. b)))
+
+       signedMul k a b = ((a .>. zero) .&&. (((b .>. zero) .&&. (a .>. (maximumValue k ./. b)))
+                                         .||. ((b .<. zero) .&&. (b .<. (minimumValue k ./. a)))))
+                      .||. ((a .<. zero) .&&. (((b .>. zero) .&&. (a .<. (minimumValue k ./. b)))
+                                          .||. ((b .<. zero) .&&. (b .<. (maximumValue k ./. a)))))
+
+       minimumValue k = text $ "INT" ++ show (intSizeOf k) ++ "_MIN"
+       maximumValue k = text $ (if hasSign k then "INT" else "UINT") ++ show (intSizeOf k) ++ "_MAX"
+nativeBVOverflowExpr _ _ _ = Nothing
+
+-- | Print a wide value without requiring a printf conversion specifier.
+wideBVPrint :: Kind -> Doc -> Doc
+wideBVPrint k value = namedCall (prefix k ++ "_fprint") [text "stdout", value]
+
+-- | Test whether a wide bit-vector is a valid zero-based index below the
+-- supplied table length.
+wideBVLookupInRange :: Kind -> Int -> Doc -> Doc
+wideBVLookupInRange k len value = namedCall (prefix k ++ "_index_in_range") [value, integer (fromIntegral len)]
+
+-- | Convert a wide bit-vector known to be in range to a native C table index.
+wideBVLookupIndex :: Kind -> Doc -> Doc
+wideBVLookupIndex k value = namedCall (prefix k ++ "_index") [value]
+
+-- | Compare two wide bit-vectors for exact bit-pattern equality.
+wideBVEqual :: Kind -> Doc -> Doc -> Doc
+wideBVEqual k left right = namedCall (prefix k ++ "_eq") [left, right]
+
+-- | Canonicalize an externally supplied wide value by clearing unused bits in
+-- its most-significant limb.
+wideBVNormalize :: Kind -> Doc -> Doc
+wideBVNormalize k value = namedCall (prefix k ++ "_norm") [value]
+
+-- | Cross-width helpers discovered while walking the symbolic DAG.
+data Special = SpecialExtract    Kind Int Int Kind
+             | SpecialJoin       Kind Kind Kind
+             | SpecialConvert    Bool Kind Kind
+             | SpecialRotate     Kind
+             | SpecialShift      Kind
+             | SpecialArithmetic NativeArithmetic Kind
+             deriving (Eq)
+
+-- | Native scalar arithmetic operations that require exact modular C
+-- helpers.
+data NativeArithmetic = SpecialAdd
+                      | SpecialSub
+                      | SpecialMul
+                      | SpecialNeg
+                      | SpecialAbs
+                      | SpecialQuot
+                      | SpecialRem
+                      | SpecialEuclideanQuot
+                      | SpecialEuclideanRem
+                      deriving (Eq)
+
+-- | Emit one exact native-width arithmetic helper. Modular operations are
+-- evaluated through unsigned bits; signed division is guarded against both
+-- zero divisors and the otherwise undefined minimum-value quotient.
+nativeArithmeticRuntime :: NativeArithmetic -> Kind -> [String]
+nativeArithmeticRuntime arith kind =
+     ["static inline " ++ ty ++ " " ++ functionName ++ "(" ++ parameters ++ ")"
+     , "{"
+     ]
+  ++ body
+  ++ ["}", ""]
+ where ty           = cType kind
+       rawTy        = cType (KBounded False width)
+       width        = bitWidth kind
+       mask         = u64 (topMask kind)
+       signMask     = u64 (1 `shiftL` (width - 1))
+       functionName = prefix kind ++ "_" ++ arithmeticSuffix arith
+       parameters
+         | arith `elem` [SpecialNeg, SpecialAbs] = ty ++ " a"
+         | True                                   = ty ++ " a, " ++ ty ++ " b"
+
+       raw value = "((uint64_t) (" ++ rawTy ++ ") " ++ value ++ ")"
+
+       modular expression =
+         ("  const " ++ rawTy ++ " bits = (" ++ rawTy ++ ") ((" ++ expression ++ ") & " ++ mask ++ ");")
+         : returnBits "bits"
+
+       returnBits bits
+         | hasSign kind = ["  " ++ ty ++ " result; memcpy(&result, &" ++ bits ++ ", sizeof result); return result;"]
+         | True         = ["  return (" ++ ty ++ ") " ++ bits ++ ";"]
+
+       body = case arith of
+         SpecialAdd           -> modular (raw "a" ++ " + " ++ raw "b")
+         SpecialSub           -> modular (raw "a" ++ " - " ++ raw "b")
+         SpecialMul           -> modular (raw "a" ++ " * " ++ raw "b")
+         SpecialNeg           -> modular ("UINT64_C(0) - " ++ raw "a")
+         SpecialAbs
+           | hasSign kind -> modular ("(" ++ raw "a" ++ " & " ++ signMask ++ ") != 0 ? UINT64_C(0) - " ++ raw "a" ++ " : " ++ raw "a")
+           | True         -> modular (raw "a")
+         SpecialQuot          -> divisionBody "/" ("(" ++ ty ++ ") 0") "a"
+         SpecialRem           -> divisionBody "%" "a" ("(" ++ ty ++ ") 0")
+         SpecialEuclideanQuot -> euclideanBody True
+         SpecialEuclideanRem  -> euclideanBody False
+
+       -- Once zero and minimum/-1 are excluded, both division and its
+       -- Euclidean correction fit the signed type. Subtract the negative
+       -- divisor directly so its minimum value is never negated.
+       euclideanBody quotient =
+         [ "  if (b == (" ++ ty ++ ") 0) return a;"
+         , "  if (a == " ++ minimumValue ++ " && b == (" ++ ty ++ ") -1) return " ++ (if quotient then "a" else "0") ++ ";"
+         , "  const " ++ ty ++ " remainder = (" ++ ty ++ ") (a % b);"
+         ]
+         ++ if quotient
+            then [ "  const " ++ ty ++ " quotient = (" ++ ty ++ ") (a / b);"
+                 , "  return remainder < 0 ? (b > 0 ? quotient - 1 : quotient + 1) : quotient;"
+                 ]
+            else [ "  return remainder < 0 ? (b > 0 ? remainder + b : remainder - b) : remainder;"
+                 ]
+
+       divisionBody operator zeroResult overflowResult =
+            ["  if (b == (" ++ ty ++ ") 0) return " ++ zeroResult ++ ";"]
+         ++ signedOverflow
+         ++ ["  return (" ++ ty ++ ") (a " ++ operator ++ " b);"]
+        where signedOverflow
+                | hasSign kind = ["  if (a == " ++ minimumValue ++ " && b == (" ++ ty ++ ") -1) return " ++ overflowResult ++ ";"]
+                | True         = []
+
+       minimumValue = "INT" ++ show width ++ "_MIN"
+
+-- | Return the generated helper suffix for exact native arithmetic.
+arithmeticSuffix :: NativeArithmetic -> String
+arithmeticSuffix SpecialAdd           = "add"
+arithmeticSuffix SpecialSub           = "sub"
+arithmeticSuffix SpecialMul           = "mul"
+arithmeticSuffix SpecialNeg           = "neg"
+arithmeticSuffix SpecialAbs           = "abs"
+arithmeticSuffix SpecialQuot          = "quot"
+arithmeticSuffix SpecialRem           = "rem"
+arithmeticSuffix SpecialEuclideanQuot = "equot"
+arithmeticSuffix SpecialEuclideanRem  = "erem"
+
+-- | Emit exact native-width rotations through an unsigned representation so
+-- the result is independent of integer promotions and signed-shift rules.
+rotationRuntime :: Kind -> [String]
+rotationRuntime kind =
+     signedConversion
+  ++ ["static inline " ++ ty ++ " " ++ p ++ "_rotl(" ++ ty ++ " a, uint64_t amount)"
+  , "{"
+  , "  amount %= " ++ show width ++ ";"
+  , "  if (amount == 0) return a;"
+  , "  return " ++ finish ("(" ++ rawTy ++ ") ((((uint64_t) (" ++ rawTy ++ ") a) << amount) | (((uint64_t) (" ++ rawTy ++ ") a) >> (" ++ show width ++ " - amount)))") ++ ";"
+  , "}"
+  , ""
+  , "static inline " ++ ty ++ " " ++ p ++ "_rotr(" ++ ty ++ " a, uint64_t amount)"
+  , "{"
+  , "  amount %= " ++ show width ++ ";"
+  , "  if (amount == 0) return a;"
+  , "  return " ++ finish ("(" ++ rawTy ++ ") ((((uint64_t) (" ++ rawTy ++ ") a) >> amount) | (((uint64_t) (" ++ rawTy ++ ") a) << (" ++ show width ++ " - amount)))") ++ ";"
+  , "}"
+  , ""
+  ]
+ where ty               = cType kind
+       p                = prefix kind
+       width            = bitWidth kind
+       rawTy            = cType (KBounded False width)
+       conversionName   = p ++ "_rotate_from_bits"
+       signedConversion
+         | hasSign kind = ["static inline " ++ ty ++ " " ++ conversionName ++ "(" ++ rawTy ++ " bits)"
+                          , "{ " ++ ty ++ " result; memcpy(&result, &bits, sizeof result); return result; }"
+                          , ""]
+         | True         = []
+       finish value
+         | hasSign kind = conversionName ++ "(" ++ value ++ ")"
+         | True         = value
+
+-- | Emit exact native-width logical and arithmetic shifts. The shift amount
+-- is interpreted as an unsigned bit-vector, and amounts at least as large as
+-- the operand width produce SMT-Lib's defined zero or sign-filled result.
+shiftRuntime :: Kind -> [String]
+shiftRuntime kind =
+     signedConversion
+  ++ leftShift
+  ++ rightShift
+ where ty               = cType kind
+       p                = prefix kind
+       width            = bitWidth kind
+       rawTy            = cType (KBounded False width)
+       amountValue      = "(uint64_t) (" ++ rawTy ++ ") amount"
+       mask             = u64 (topMask kind)
+       signMask         = u64 (1 `shiftL` (width - 1))
+       conversionName   = p ++ "_shift_from_bits"
+       signedConversion
+         | hasSign kind = ["static inline " ++ ty ++ " " ++ conversionName ++ "(" ++ rawTy ++ " bits)"
+                          , "{ " ++ ty ++ " result; memcpy(&result, &bits, sizeof result); return result; }"
+                          , ""]
+         | True         = []
+       finish value
+         | hasSign kind = conversionName ++ "(" ++ value ++ ")"
+         | True         = value
+       leftShift = ["static inline " ++ ty ++ " " ++ p ++ "_shl(" ++ ty ++ " a, " ++ ty ++ " amount)"
+                   , "{"
+                   , "  const uint64_t n = " ++ amountValue ++ ";"
+                   , "  const " ++ rawTy ++ " result = n >= " ++ show width ++ " ? (" ++ rawTy ++ ") 0 : (" ++ rawTy ++ ") ((uint64_t) (" ++ rawTy ++ ") a << n);"
+                   , "  return " ++ finish "result" ++ ";"
+                   , "}"
+                   , ""]
+       rightShift
+         | hasSign kind = ["static inline " ++ ty ++ " " ++ p ++ "_ashr(" ++ ty ++ " a, " ++ ty ++ " amount)"
+                          , "{"
+                          , "  const uint64_t n = " ++ amountValue ++ ";"
+                          , "  const uint64_t raw = (uint64_t) (" ++ rawTy ++ ") a;"
+                          , "  const bool sign = (raw & " ++ signMask ++ ") != 0;"
+                          , "  " ++ rawTy ++ " result;"
+                          , "  if (n >= " ++ show width ++ ") result = sign ? (" ++ rawTy ++ ") " ++ mask ++ " : (" ++ rawTy ++ ") 0;"
+                          , "  else { result = (" ++ rawTy ++ ") (raw >> n); if (sign && n != 0) result = (" ++ rawTy ++ ") ((uint64_t) result | (" ++ mask ++ " << (" ++ show width ++ " - n))); }"
+                          , "  return " ++ finish "result" ++ ";"
+                          , "}"
+                          , ""]
+         | True = ["static inline " ++ ty ++ " " ++ p ++ "_lshr(" ++ ty ++ " a, " ++ ty ++ " amount)"
+                  , "{"
+                  , "  const uint64_t n = " ++ amountValue ++ ";"
+                  , "  return n >= " ++ show width ++ " ? (" ++ ty ++ ") 0 : (" ++ ty ++ ") ((uint64_t) (" ++ rawTy ++ ") a >> n);"
+                  , "}"
+                  , ""]
+
+-- | Emit the complete modular-arithmetic runtime for one bit-vector kind.
+coreRuntime :: Kind -> [String]
+coreRuntime k =
+  ["static inline " ++ ty ++ " " ++ p ++ "_zero(void)"
+  , "{"
+  , "  " ++ ty ++ " r = {{0}};"
+  , "  return r;"
+  , "}"
+  , ""
+  , "static inline " ++ ty ++ " " ++ p ++ "_norm(" ++ ty ++ " a)"
+  , "{"
+  , "  a.limb[" ++ show (n - 1) ++ "] &= " ++ u64 mask ++ ";"
+  , "  return a;"
+  , "}"
+  , ""
+  , "static inline bool " ++ p ++ "_get(" ++ ty ++ " a, uint64_t bit)"
+  , "{"
+  , "  return bit < " ++ show w ++ " && ((a.limb[bit / 64] >> (bit % 64)) & UINT64_C(1)) != 0;"
+  , "}"
+  , ""
+  , "static inline void " ++ p ++ "_set(" ++ ty ++ " *a, uint64_t bit, bool value)"
+  , "{"
+  , "  const uint64_t m = UINT64_C(1) << (bit % 64);"
+  , "  if (value) { a->limb[bit / 64] |= m; } else { a->limb[bit / 64] &= ~m; }"
+  , "}"
+  , ""
+  , "static inline bool " ++ p ++ "_is_zero(" ++ ty ++ " a)"
+  , "{"
+  , "  uint64_t v = 0;"
+  , "  size_t i;"
+  , "  for (i = 0; i < " ++ show n ++ "; ++i) { v |= a.limb[i]; }"
+  , "  return v == 0;"
+  , "}"
+  , ""
+  , "static inline bool " ++ p ++ "_eq(" ++ ty ++ " a, " ++ ty ++ " b)"
+  , "{"
+  , "  uint64_t v = 0;"
+  , "  size_t i;"
+  , "  for (i = 0; i < " ++ show n ++ "; ++i) { v |= a.limb[i] ^ b.limb[i]; }"
+  , "  return v == 0;"
+  , "}"
+  , ""
+  , "static inline int " ++ p ++ "_cmpu(" ++ ty ++ " a, " ++ ty ++ " b)"
+  , "{"
+  , "  size_t i = " ++ show n ++ ";"
+  , "  while (i-- > 0) { if (a.limb[i] < b.limb[i]) return -1; if (a.limb[i] > b.limb[i]) return 1; }"
+  , "  return 0;"
+  , "}"
+  , ""
+  , "static inline bool " ++ p ++ "_lt(" ++ ty ++ " a, " ++ ty ++ " b)"
+  , "{"
+  ]
+  ++ signedCompare
+  ++ ["}"
+     , ""
+     , "static inline " ++ ty ++ " " ++ p ++ "_add(" ++ ty ++ " a, " ++ ty ++ " b)"
+     , "{"
+     , "  " ++ ty ++ " r;"
+     , "  uint64_t carry = 0;"
+     , "  size_t i;"
+     , "  for (i = 0; i < " ++ show n ++ "; ++i) {"
+     , "    uint64_t s = a.limb[i] + b.limb[i];"
+     , "    uint64_t c1 = s < a.limb[i];"
+     , "    uint64_t t = s + carry;"
+     , "    uint64_t c2 = t < s;"
+     , "    r.limb[i] = t; carry = c1 | c2;"
+     , "  }"
+     , "  return " ++ p ++ "_norm(r);"
+     , "}"
+     , ""
+     , "static inline uint64_t " ++ p ++ "_index(" ++ ty ++ " a)"
+     , "{"
+     , "  return a.limb[0];"
+     , "}"
+     , ""
+     , "static inline bool " ++ p ++ "_index_in_range(" ++ ty ++ " a, uint64_t limit)"
+     , "{"
+     , "  size_t i;"
+     , "  for (i = 1; i < " ++ show n ++ "; ++i) if (a.limb[i] != UINT64_C(0)) return false;"
+     , "  return a.limb[0] < limit;"
+     , "}"
+     , ""
+     , "static inline " ++ ty ++ " " ++ p ++ "_sub(" ++ ty ++ " a, " ++ ty ++ " b)"
+     , "{"
+     , "  " ++ ty ++ " r;"
+     , "  uint64_t borrow = 0;"
+     , "  size_t i;"
+     , "  for (i = 0; i < " ++ show n ++ "; ++i) {"
+     , "    uint64_t d = a.limb[i] - b.limb[i];"
+     , "    uint64_t b1 = a.limb[i] < b.limb[i];"
+     , "    uint64_t t = d - borrow;"
+     , "    uint64_t b2 = d < borrow;"
+     , "    r.limb[i] = t; borrow = b1 | b2;"
+     , "  }"
+     , "  return " ++ p ++ "_norm(r);"
+     , "}"
+     , ""
+     , "static inline " ++ ty ++ " " ++ p ++ "_not(" ++ ty ++ " a)"
+     , "{"
+     , "  size_t i;"
+     , "  for (i = 0; i < " ++ show n ++ "; ++i) { a.limb[i] = ~a.limb[i]; }"
+     , "  return " ++ p ++ "_norm(a);"
+     , "}"
+     , ""
+     , "static inline " ++ ty ++ " " ++ p ++ "_neg(" ++ ty ++ " a)"
+     , "{"
+     , "  " ++ ty ++ " one = " ++ p ++ "_zero(); one.limb[0] = 1;"
+     , "  return " ++ p ++ "_add(" ++ p ++ "_not(a), one);"
+     , "}"
+     , ""
+     ]
+  ++ concatMap bitwise [("and", "&"), ("or", "|"), ("xor", "^")]
+  ++ ["static inline " ++ ty ++ " " ++ p ++ "_shl(" ++ ty ++ " a, uint64_t amount)"
+     , "{"
+     , "  " ++ ty ++ " r = " ++ p ++ "_zero();"
+     , "  uint64_t ws, bs; size_t i;"
+     , "  if (amount >= " ++ show w ++ ") return r;"
+     , "  ws = amount / 64; bs = amount % 64;"
+     , "  for (i = " ++ show n ++ "; i-- > ws;) {"
+     , "    r.limb[i] = a.limb[i - ws] << bs;"
+     , "    if (bs != 0 && i > ws) r.limb[i] |= a.limb[i - ws - 1] >> (64 - bs);"
+     , "  }"
+     , "  return " ++ p ++ "_norm(r);"
+     , "}"
+     , ""
+     , "static inline " ++ ty ++ " " ++ p ++ "_lshr(" ++ ty ++ " a, uint64_t amount)"
+     , "{"
+     , "  " ++ ty ++ " r = " ++ p ++ "_zero();"
+     , "  uint64_t ws, bs; size_t i;"
+     , "  if (amount >= " ++ show w ++ ") return r;"
+     , "  ws = amount / 64; bs = amount % 64;"
+     , "  for (i = 0; i + ws < " ++ show n ++ "; ++i) {"
+     , "    r.limb[i] = a.limb[i + ws] >> bs;"
+     , "    if (bs != 0 && i + ws + 1 < " ++ show n ++ ") r.limb[i] |= a.limb[i + ws + 1] << (64 - bs);"
+     , "  }"
+     , "  return " ++ p ++ "_norm(r);"
+     , "}"
+     , ""
+     , "static inline " ++ ty ++ " " ++ p ++ "_ashr(" ++ ty ++ " a, uint64_t amount)"
+     , "{"
+     , "  " ++ ty ++ " r = " ++ p ++ "_zero(); uint64_t i;"
+     , "  const bool sign = " ++ p ++ "_get(a, " ++ show (w - 1) ++ ");"
+     , "  for (i = 0; i < " ++ show w ++ "; ++i) { " ++ p ++ "_set(&r, i, i + amount < " ++ show w ++ " ? " ++ p ++ "_get(a, i + amount) : sign); }"
+     , "  return r;"
+     , "}"
+     , ""
+     , "static inline uint64_t " ++ p ++ "_shift_amount(" ++ ty ++ " a)"
+     , "{"
+     , "  size_t i;"
+     , "  for (i = 1; i < " ++ show n ++ "; ++i) if (a.limb[i] != 0) return " ++ show w ++ ";"
+     , "  return a.limb[0] < " ++ show w ++ " ? a.limb[0] : " ++ show w ++ ";"
+     , "}"
+     , ""
+     , "static inline " ++ ty ++ " " ++ p ++ "_rotl(" ++ ty ++ " a, uint64_t amount)"
+     , "{"
+     , "  amount %= " ++ show w ++ ";"
+     , "  return amount == 0 ? a : " ++ p ++ "_or(" ++ p ++ "_shl(a, amount), " ++ p ++ "_lshr(a, " ++ show w ++ " - amount));"
+     , "}"
+     , ""
+     , "static inline " ++ ty ++ " " ++ p ++ "_rotr(" ++ ty ++ " a, uint64_t amount)"
+     , "{"
+     , "  amount %= " ++ show w ++ ";"
+     , "  return amount == 0 ? a : " ++ p ++ "_or(" ++ p ++ "_lshr(a, amount), " ++ p ++ "_shl(a, " ++ show w ++ " - amount));"
+     , "}"
+     , ""
+     , "static inline " ++ ty ++ " " ++ p ++ "_mul(" ++ ty ++ " a, " ++ ty ++ " b)"
+     , "{"
+     , "  " ++ ty ++ " r = " ++ p ++ "_zero(); uint64_t bit;"
+     , "  for (bit = 0; bit < " ++ show w ++ "; ++bit) {"
+     , "    " ++ ty ++ " selected; uint64_t mask = UINT64_C(0) - (uint64_t) " ++ p ++ "_get(b, bit); size_t i;"
+     , "    for (i = 0; i < " ++ show n ++ "; ++i) selected.limb[i] = a.limb[i] & mask;"
+     , "    r = " ++ p ++ "_add(r, selected); a = " ++ p ++ "_shl(a, 1);"
+     , "  }"
+     , "  return r;"
+     , "}"
+     , ""
+     , "static inline void " ++ p ++ "_udivrem(" ++ ty ++ " a, " ++ ty ++ " b, " ++ ty ++ " *q, " ++ ty ++ " *r)"
+     , "{"
+     , "  uint64_t bit; *q = " ++ p ++ "_zero(); *r = " ++ p ++ "_zero();"
+     , "  if (" ++ p ++ "_is_zero(b)) { *r = a; return; }"
+     , "  for (bit = " ++ show w ++ "; bit-- > 0;) {"
+     , "    *r = " ++ p ++ "_shl(*r, 1); " ++ p ++ "_set(r, 0, " ++ p ++ "_get(a, bit));"
+     , "    if (" ++ p ++ "_cmpu(*r, b) >= 0) { *r = " ++ p ++ "_sub(*r, b); " ++ p ++ "_set(q, bit, true); }"
+     , "  }"
+     , "}"
+     , ""
+     ]
+  ++ division
+  ++ ["static inline " ++ ty ++ " " ++ p ++ "_abs(" ++ ty ++ " a)"
+     , "{"
+     , if hasSign k then "  return " ++ p ++ "_get(a, " ++ show (w - 1) ++ ") ? " ++ p ++ "_neg(a) : a;" else "  return a;"
+     , "}"
+     , ""
+     ]
+  ++ overflowRuntime
+ where ty   = cType k
+       p    = prefix k
+       w    = intSizeOf k
+       n    = limbs k
+       mask = topMask k
+
+       signedCompare
+         | hasSign k = ["  const bool sa = " ++ p ++ "_get(a, " ++ show (w - 1) ++ ");"
+                        , "  const bool sb = " ++ p ++ "_get(b, " ++ show (w - 1) ++ ");"
+                        , "  return sa != sb ? sa : " ++ p ++ "_cmpu(a, b) < 0;"]
+         | True       = ["  return " ++ p ++ "_cmpu(a, b) < 0;"]
+
+       bitwise (nm, op) =
+         ["static inline " ++ ty ++ " " ++ p ++ "_" ++ nm ++ "(" ++ ty ++ " a, " ++ ty ++ " b)"
+         , "{"
+         , "  size_t i;"
+         , "  for (i = 0; i < " ++ show n ++ "; ++i) { a.limb[i] " ++ op ++ "= b.limb[i]; }"
+         , "  return " ++ p ++ "_norm(a);"
+         , "}"
+         , ""]
+
+       division
+         | hasSign k =
+            ["static inline " ++ ty ++ " " ++ p ++ "_quot(" ++ ty ++ " a, " ++ ty ++ " b)"
+            , "{"
+            , "  " ++ ty ++ " q, r; const bool sa = " ++ p ++ "_get(a, " ++ show (w - 1) ++ "); const bool sb = " ++ p ++ "_get(b, " ++ show (w - 1) ++ ");"
+            , "  " ++ p ++ "_udivrem(sa ? " ++ p ++ "_neg(a) : a, sb ? " ++ p ++ "_neg(b) : b, &q, &r);"
+            , "  return sa != sb ? " ++ p ++ "_neg(q) : q;"
+            , "}"
+            , ""
+            , "static inline " ++ ty ++ " " ++ p ++ "_rem(" ++ ty ++ " a, " ++ ty ++ " b)"
+            , "{"
+            , "  " ++ ty ++ " q, r; const bool sa = " ++ p ++ "_get(a, " ++ show (w - 1) ++ "); const bool sb = " ++ p ++ "_get(b, " ++ show (w - 1) ++ ");"
+            , "  " ++ p ++ "_udivrem(sa ? " ++ p ++ "_neg(a) : a, sb ? " ++ p ++ "_neg(b) : b, &q, &r);"
+            , "  return sa ? " ++ p ++ "_neg(r) : r;"
+            , "}"
+            , ""]
+         | True =
+            ["static inline " ++ ty ++ " " ++ p ++ "_quot(" ++ ty ++ " a, " ++ ty ++ " b)"
+            , "{ " ++ ty ++ " q, r; " ++ p ++ "_udivrem(a, b, &q, &r); return q; }"
+            , ""
+            , "static inline " ++ ty ++ " " ++ p ++ "_rem(" ++ ty ++ " a, " ++ ty ++ " b)"
+            , "{ " ++ ty ++ " q, r; " ++ p ++ "_udivrem(a, b, &q, &r); return r; }"
+            , ""]
+
+       overflowRuntime =
+         ["static inline bool " ++ p ++ "_is_min(" ++ ty ++ " a)"
+         , "{"
+         , "  " ++ ty ++ " m = " ++ p ++ "_zero();"
+         , "  " ++ p ++ "_set(&m, " ++ show (w - 1) ++ ", true);"
+         , "  return " ++ p ++ "_eq(a, m);"
+         , "}"
+         , ""
+         , "static inline bool " ++ p ++ "_uaddo(" ++ ty ++ " a, " ++ ty ++ " b)"
+         , "{"
+         , "  return " ++ p ++ "_cmpu(" ++ p ++ "_add(a, b), a) < 0;"
+         , "}"
+         , ""
+         , "static inline bool " ++ p ++ "_saddo(" ++ ty ++ " a, " ++ ty ++ " b)"
+         , "{"
+         , "  const " ++ ty ++ " r = " ++ p ++ "_add(a, b);"
+         , "  const bool sa = " ++ p ++ "_get(a, " ++ show (w - 1) ++ ");"
+         , "  const bool sb = " ++ p ++ "_get(b, " ++ show (w - 1) ++ ");"
+         , "  const bool sr = " ++ p ++ "_get(r, " ++ show (w - 1) ++ ");"
+         , "  return sa == sb && sa != sr;"
+         , "}"
+         , ""
+         , "static inline bool " ++ p ++ "_usubo(" ++ ty ++ " a, " ++ ty ++ " b)"
+         , "{"
+         , "  return " ++ p ++ "_cmpu(a, b) < 0;"
+         , "}"
+         , ""
+         , "static inline bool " ++ p ++ "_ssubo(" ++ ty ++ " a, " ++ ty ++ " b)"
+         , "{"
+         , "  const " ++ ty ++ " r = " ++ p ++ "_sub(a, b);"
+         , "  const bool sa = " ++ p ++ "_get(a, " ++ show (w - 1) ++ ");"
+         , "  const bool sb = " ++ p ++ "_get(b, " ++ show (w - 1) ++ ");"
+         , "  const bool sr = " ++ p ++ "_get(r, " ++ show (w - 1) ++ ");"
+         , "  return sa != sb && sa != sr;"
+         , "}"
+         , ""
+         , "static inline bool " ++ p ++ "_umulo(" ++ ty ++ " a, " ++ ty ++ " b)"
+         , "{"
+         , "  " ++ ty ++ " q, r;"
+         , "  if (" ++ p ++ "_is_zero(b)) return false;"
+         , "  " ++ p ++ "_udivrem(" ++ p ++ "_mul(a, b), b, &q, &r);"
+         , "  return !" ++ p ++ "_eq(q, a);"
+         , "}"
+         , ""
+         , "static inline bool " ++ p ++ "_smulo(" ++ ty ++ " a, " ++ ty ++ " b)"
+         , "{"
+         , "  " ++ ty ++ " q, r, limit = " ++ p ++ "_zero();"
+         , "  const bool sa = " ++ p ++ "_get(a, " ++ show (w - 1) ++ ");"
+         , "  const bool sb = " ++ p ++ "_get(b, " ++ show (w - 1) ++ ");"
+         , "  const bool negative = sa != sb;"
+         , "  uint64_t bit;"
+         , "  if (sa) a = " ++ p ++ "_neg(a);"
+         , "  if (sb) b = " ++ p ++ "_neg(b);"
+         , "  if (" ++ p ++ "_is_zero(a) || " ++ p ++ "_is_zero(b)) return false;"
+         , "  if (negative) " ++ p ++ "_set(&limit, " ++ show (w - 1) ++ ", true);"
+         , "  else for (bit = 0; bit < " ++ show (w - 1) ++ "; ++bit) " ++ p ++ "_set(&limit, bit, true);"
+         , "  " ++ p ++ "_udivrem(limit, b, &q, &r);"
+         , "  return " ++ p ++ "_cmpu(a, q) > 0;"
+         , "}"
+         , ""
+         , "static inline bool " ++ p ++ "_sdivo(" ++ ty ++ " a, " ++ ty ++ " b)"
+         , "{"
+         , "  return " ++ p ++ "_is_min(a) && " ++ p ++ "_eq(b, " ++ p ++ "_not(" ++ p ++ "_zero()));"
+         , "}"
+         , ""
+         , "static inline bool " ++ p ++ "_snego(" ++ ty ++ " a)"
+         , "{"
+         , "  return " ++ p ++ "_is_min(a);"
+         , "}"
+         , ""]
+
+-- | Emit a bit-preserving extraction, extension, or integral conversion.
+conversionRuntime :: String -> Bool -> Int -> Kind -> Kind -> [String]
+conversionRuntime nm signExtend sourceOffset fr to =
+  ["static inline " ++ cType to ++ " " ++ nm ++ "(" ++ cType fr ++ " a)"
+  , "{"
+  , "  " ++ cType to ++ " r = " ++ zeroValue to ++ ";"
+  , "  uint64_t i;"
+  , "  for (i = 0; i < " ++ show copied ++ "; ++i) { " ++ setBit to "r" "i" (getBit fr "a" (offset "i")) ++ " }"
+  ]
+  ++ extension
+  ++ ["  return " ++ normalize to "r" ++ ";"
+     , "}"
+     , ""]
+ where available = max 0 (bitWidth fr - sourceOffset)
+       copied    = min available (bitWidth to)
+       offset i  = if sourceOffset == 0 then i else i ++ " + " ++ show sourceOffset
+       extension
+         | signExtend && bitWidth to > copied =
+             ["  if (" ++ getBit fr "a" (show (bitWidth fr - 1)) ++ ") for (i = " ++ show copied ++ "; i < " ++ show (bitWidth to) ++ "; ++i) { " ++ setBit to "r" "i" "true" ++ " }"]
+         | True                                      = []
+
+-- | Emit concatenation code for a particular pair of operand kinds.
+joinRuntime :: Kind -> Kind -> Kind -> [String]
+joinRuntime a b to =
+  ["static inline " ++ cType to ++ " " ++ joinName a b to ++ "(" ++ cType a ++ " high, " ++ cType b ++ " low)"
+  , "{"
+  , "  " ++ cType to ++ " r = " ++ zeroValue to ++ "; uint64_t i;"
+  , "  for (i = 0; i < " ++ show (bitWidth b) ++ "; ++i) { " ++ setBit to "r" "i" (getBit b "low" "i") ++ " }"
+  , "  for (i = 0; i < " ++ show (bitWidth a) ++ "; ++i) { " ++ setBit to "r" ("i + " ++ show (bitWidth b)) (getBit a "high" "i") ++ " }"
+  , "  return " ++ normalize to "r" ++ ";"
+  , "}"
+  , ""]
+
+-- | Render a target-independent bit read from a scalar or limb value.
+getBit :: Kind -> String -> String -> String
+getBit k value bit
+  | isWideBV k                  = prefix k ++ "_get(" ++ value ++ ", " ++ bit ++ ")"
+  | isBoolean k || isBounded k = "((((uint64_t) " ++ value ++ ") >> (" ++ bit ++ ")) & UINT64_C(1)) != 0"
+  | otherwise                  = error $ "SBV->C: Cannot extract bits from " ++ show k
+
+-- | Render a target-independent bit update to a scalar or limb value.
+setBit :: Kind -> String -> String -> String -> String
+setBit k value bit bitValue
+  | isWideBV k                  = prefix k ++ "_set(&" ++ value ++ ", " ++ bit ++ ", " ++ bitValue ++ ");"
+  | isBoolean k || isBounded k = value ++ " = (" ++ cType k ++ ") ((uint64_t) " ++ value ++ " | ((uint64_t) (" ++ bitValue ++ ") << (" ++ bit ++ ")));"
+  | otherwise                  = error $ "SBV->C: Cannot set bits in " ++ show k
+
+-- | Render the zero value for a scalar or limb representation.
+zeroValue :: Kind -> String
+zeroValue k
+  | isWideBV k                  = prefix k ++ "_zero()"
+  | isBoolean k || isBounded k = "(" ++ cType k ++ ") 0"
+  | otherwise                  = error $ "SBV->C: Cannot construct a zero of " ++ show k
+
+-- | Render canonicalization for a scalar or limb representation.
+normalize :: Kind -> String -> String
+normalize k value
+  | isWideBV k                  = prefix k ++ "_norm(" ++ value ++ ")"
+  | isBoolean k || isBounded k = value
+  | otherwise                  = error $ "SBV->C: Cannot normalize " ++ show k
+
+-- | Construct the collision-free name of an extraction helper.
+extractName :: Kind -> Int -> Int -> Kind -> String
+extractName fr hi lo to = "sbv_bv_extract_" ++ tag fr ++ "_" ++ show hi ++ "_" ++ show lo ++ "_" ++ tag to
+
+-- | Construct the collision-free name of a concatenation helper.
+joinName :: Kind -> Kind -> Kind -> String
+joinName a b to = "sbv_bv_join_" ++ tag a ++ "_" ++ tag b ++ "_" ++ tag to
+
+-- | Construct the collision-free name of an extension/conversion helper.
+convertName :: Bool -> Kind -> Kind -> String
+convertName sign fr to = "sbv_bv_" ++ (if sign then "sext_" else "zext_") ++ tag fr ++ "_" ++ tag to
+
+-- | Render a C function call.
+namedCall :: String -> [Doc] -> Doc
+namedCall nm args = text nm P.<> parens (fsep (punctuate comma args))
+
+-- | Select the first operation argument, reporting an internal arity error.
+headArg :: String -> [a] -> a
+headArg _ (a:_) = a
+headArg nm []    = error $ "SBV->C: " ++ nm ++ " unexpectedly has no arguments"
+
+-- | Report an internal arity error for an operation.
+badArity :: String -> [a] -> b
+badArity nm _ = error $ "SBV->C: " ++ nm ++ " has an unexpected arity"
+
+-- | Return the generated helper suffix for an overflow predicate.
+overflowName :: OvOp -> String
+overflowName (PlusOv False) = "uaddo"
+overflowName (PlusOv True)  = "saddo"
+overflowName (SubOv  False) = "usubo"
+overflowName (SubOv  True)  = "ssubo"
+overflowName (MulOv  False) = "umulo"
+overflowName (MulOv  True)  = "smulo"
+overflowName DivOv          = "sdivo"
+overflowName NegOv          = "snego"
+
+-- | Return the logical bit width used by the C representation. Unlike
+-- 'intSizeOf', this is defined for 'KBool', which occupies one logical bit.
+bitWidth :: Kind -> Int
+bitWidth k
+  | isBoolean k = 1
+  | otherwise   = intSizeOf k
+
+-- | Test whether a symbolic value uses one of the scalar C bit-vector
+-- representations, including the one-bit unsigned representation.
+isNativeBV :: HasKind a => a -> Bool
+isNativeBV value = isNativeBVKind (kindOf value)
+
+-- | Test whether a kind uses one of the scalar C bit-vector representations.
+isNativeBVKind :: Kind -> Bool
+isNativeBVKind kind = isBounded kind && not (isWideBV kind)
+
+-- | Return the number of 64-bit limbs needed by a kind.
+limbs :: Kind -> Int
+limbs k = (intSizeOf k + 63) `div` 64
+
+-- | Return the mask for the final limb of a canonical value.
+topMask :: Kind -> Integer
+topMask k
+  | r == 0    = (1 `shiftL` 64) - 1
+  | otherwise = (1 `shiftL` r) - 1
+ where r = intSizeOf k `mod` 64
+
+-- | Return the C type name used for a bit-vector kind.
+cType :: Kind -> String
+cType KBool               = "SBool"
+cType (KBounded False 1)  = "SBool"
+cType (KBounded False w)  = "SWord" ++ show w
+cType (KBounded True  w)  = "SInt"  ++ show w
+cType k                   = error $ "SBV->C: Expected a C bit-vector type, received " ++ show k
+
+-- | Return the compact signedness-and-width tag used in generated names.
+tag :: Kind -> String
+tag KBool               = "u1"
+tag (KBounded False w)  = "u" ++ show w
+tag (KBounded True  w)  = "s" ++ show w
+tag k                   = error $ "SBV->C: Expected a bit-vector tag, received " ++ show k
+
+-- | Return the namespace prefix for helpers belonging to a kind.
+prefix :: Kind -> String
+prefix k = "sbv_bv_" ++ tag k
+
+-- | Render an integer as a padded, portable C @uint64_t@ literal.
+u64 :: Integer -> String
+u64 i = "UINT64_C(0x" ++ pad 16 (showHex i "") ++ ")"
+ where pad n s = replicate (n - length s) '0' ++ s
diff --git a/Data/SBV/Compilers/C/Backend.hs b/Data/SBV/Compilers/C/Backend.hs
new file mode 100644
--- /dev/null
+++ b/Data/SBV/Compilers/C/Backend.hs
@@ -0,0 +1,3143 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Data.SBV.Compilers.C.Backend
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Compilation of symbolic programs to C
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE TupleSections #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Data.SBV.Compilers.C.Backend(compileToC, compileToCLib, compileToC', compileToCLib') where
+
+import Data.SBV.Compilers.C.Types (isConcreteADTReference)
+import Control.DeepSeq                 (rnf)
+import Data.Char                       (isAsciiLower, isAsciiUpper, isDigit, isSpace, toLower)
+import qualified Data.Foldable         as F (toList)
+import qualified Data.Graph            as DG
+import Data.List                       (intercalate, intersperse, isPrefixOf, nub, sortOn)
+import qualified Data.Map.Strict       as Map
+import Data.Maybe                      (fromJust, fromMaybe, isJust, isNothing, maybeToList)
+import qualified Data.Set              as Set (Set, difference, empty, fromList, insert, intersection, map, member, notMember, null, toList, union, unions)
+import qualified Data.Text             as T
+import System.FilePath                 (replaceExtension, takeBaseName)
+import System.Random
+
+import Data.SBV.Core.Symbolic (LambdaInfo(..), ResultInp(..), ProgInfo(..), SMTDef(SMTDef), smtDefInfo, smtLambdaInfo)
+
+-- Work around the fact that GHC 8.4.1 started exporting <>.. Hmm..
+import Text.PrettyPrint.HughesPJ
+import qualified Text.PrettyPrint.HughesPJ as P ((<>))
+
+import Data.SBV.Core.Data
+import Data.SBV.Core.Kind (expandKinds, kRoundingMode)
+import Data.SBV.Compilers.C.ADT
+import Data.SBV.Compilers.C.Array
+import Data.SBV.Compilers.C.BV
+import Data.SBV.Compilers.C.FP
+import Data.SBV.Compilers.C.Finite (finiteDomainSize)
+import Data.SBV.Compilers.C.GMP
+import Data.SBV.Compilers.C.List
+import Data.SBV.Compilers.C.Lowering
+import Data.SBV.Compilers.C.NonLinear
+import Data.SBV.Compilers.C.PseudoBoolean (assignPseudoBoolean)
+import Data.SBV.Compilers.C.Real (mappedRealFloorWidth, mappedRealFloorCall, mappedRealFloorRuntime)
+import Data.SBV.Compilers.C.RegExp (regexExpr)
+import Data.SBV.Compilers.C.Set
+import Data.SBV.Compilers.C.Syntax (cUnusedAttribute, cCommentText, cStringLiteral)
+import Data.SBV.Compilers.C.Table
+import Data.SBV.Compilers.C.Text
+import qualified Data.SBV.Compilers.C.Types as CTypes (constElementCType, definedFunctionCName, elementCType, kindTag)
+import Data.SBV.Compilers.C.Tuple
+import Data.SBV.Compilers.C.Value ( byValueEqual, managedValueClone, managedValueRelease, valueNeedsOwnership
+                                , valueDriverNeedsInitialization, valueDriverInit, valueDriverClear
+                                )
+import Data.SBV.Compilers.CodeGen
+
+import Data.SBV.Utils.PrettyNum   (chex, showCFloat, showCDouble)
+
+import GHC.Stack
+
+---------------------------------------------------------------------------
+-- * API
+---------------------------------------------------------------------------
+
+-- | Given a symbolic computation, render it as an equivalent collection of files
+-- that make up a C program:
+--
+--   * The first argument is the directory name under which the files will be saved. To save
+--     files in the current directory pass @'Just' \".\"@. Use 'Nothing' for printing to stdout.
+--
+--   * The second argument is the name of the C function to generate.
+--
+--   * The final argument is the function to be compiled.
+--
+-- Compilation will also generate a @Makefile@,  a header file, and a driver (test) program, etc. As a
+-- result, we return whatever the code-gen function returns. Most uses should simply have @()@ as
+-- the return type here, but the value can be useful if you want to chain the result of
+-- one compilation act to the next.
+-- Names must obey the public naming contract in "Data.SBV.Tools.CodeGen";
+-- invalid or reserved names are rejected before any files are written.
+--
+-- Detected runtime failures in the generated code terminate the calling process;
+-- there is no recoverable error-return interface. See the runtime contract in
+-- "Data.SBV.Tools.CodeGen".
+-- Callers must enter generated code in @FE_TONEAREST@ hardware rounding mode;
+-- generated code does not check or change that mode.
+compileToC :: Maybe FilePath -> String -> SBVCodeGen a -> IO a
+compileToC mbDirName nm f = do (retVal, cfg, bundle) <- compileToC' nm f
+                               renderCgPgmBundle mbDirName (cfg, bundle)
+                               pure retVal
+
+-- | Lower level version of 'compileToC', producing a t'CgPgmBundle'
+compileToC' :: String -> SBVCodeGen a -> IO (a, CgConfig, CgPgmBundle)
+compileToC' nm f = do validateCName "function" nm `seq` pure ()
+                      rands <- randoms <$> newStdGen
+                      result@(_, _, bundle) <- codeGen SBVToC (defaultCgConfig { cgDriverVals = rands }) nm f
+                      bundle `seq` pure result
+
+-- | Create code to generate a library archive (.a) from given symbolic functions. Useful when generating code
+-- from multiple functions that work together as a library.
+--
+--   * The first argument is the directory name under which the files will be saved. To save
+--     files in the current directory pass @'Just' \".\"@. Use 'Nothing' for printing to stdout.
+--
+--   * The second argument is the name of the archive to generate.
+--
+--   * The third argument is the list of functions to include, in the form of function-name/code pairs, similar
+--     to the second and third arguments of 'compileToC', except in a list.
+--
+-- The component list must be nonempty and component names must be distinct.
+-- Generated file names and driver entry points must not collide either.
+-- As with 'compileToC', detected runtime failures terminate the calling process,
+-- including when the generated functions are used as a library.
+compileToCLib :: Maybe FilePath -> String -> [(String, SBVCodeGen a)] -> IO [a]
+compileToCLib mbDirName libName comps = do (retVal, cfg, pgm) <- compileToCLib' libName comps
+                                           renderCgPgmBundle mbDirName (cfg, pgm)
+                                           pure retVal
+
+-- | Lower level version of 'compileToCLib', producing a t'CgPgmBundle'
+compileToCLib' :: String -> [(String, SBVCodeGen a)] -> IO ([a], CgConfig, CgPgmBundle)
+compileToCLib' libName comps
+  | null comps
+  = error "SBV.compileToCLib: A library must contain at least one component."
+  | not (null duplicates)
+  = error $ "SBV.compileToCLib: Duplicate component names: " ++ unwords duplicates
+  | True
+  = do validateCName "library" libName `seq` pure ()
+       mapM_ (\(fn, _) -> validateCName "component" fn `seq` pure ()) comps
+       resCfgBundles <- mapM component comps
+       let (finalCfg, finalPgm) = mergeToLib libName [(c, b) | (_, c, b) <- resCfgBundles]
+       finalPgm `seq` pure ([r | (r, _, _) <- resCfgBundles], finalCfg, finalPgm)
+ where duplicates = duplicateNames (map fst comps)
+
+       component (componentName, program) = do
+         rands <- randoms <$> newStdGen
+         codeGen SBVToCLibraryComponent (defaultCgConfig { cgDriverVals = rands }) componentName program
+
+-- | Report each repeated name once, preserving its first occurrence order.
+duplicateNames :: [String] -> [String]
+duplicateNames names = [nm | nm <- nub names, length (filter (== nm) names) > 1]
+
+-- | Retain the first value for each key without repeated linear scans or
+-- repeated rendering of documents. Original order is significant in C output.
+uniqueOn :: Ord key => (value -> key) -> [value] -> [value]
+uniqueOn key = go Set.empty
+ where go _ [] = []
+       go seen (value:rest)
+         | valueKey `Set.member` seen = go seen rest
+         | True                       = value : go (Set.insert valueKey seen) rest
+         where valueKey = key value
+
+-- | Validate public C names before rendering. Use a portable ASCII spelling,
+-- excluding language keywords and namespaces owned by the generated runtime
+-- and its headers. User-supplied C declarations remain the caller's responsibility.
+validateCName :: String -> String -> ()
+validateCName role nm
+  | not validIdentifier = reject "expected an ASCII C identifier"
+  | nm `elem` keywords  = reject "C keyword"
+  | reserved            = reject "reserved C/backend name"
+  | True                = ()
+ where reject reason = error $ "SBV->C: Invalid " ++ role ++ " name " ++ show nm ++ ": " ++ reason ++ "."
+       letter c = isAsciiLower c || isAsciiUpper c
+       validIdentifier = case nm of
+                           initial : rest -> (letter initial || initial == '_') && all (\c -> letter c || isDigit c || c == '_') rest
+                           []           -> False
+       keywords = words ("auto break case char const continue default do double else enum extern float for goto if inline int long register"
+                  ++ " restrict return short signed sizeof static struct switch typedef union unsigned void volatile while alignas alignof"
+                  ++ " bool constexpr false nullptr static_assert thread_local true typeof typeof_unqual")
+       reserved = any (`isPrefixOf` nm)
+                    ["_", "sbv_", "SBV", "SWord", "SInt", "SFP", "mp_", "mpz_", "mpq_", "mpf_", "gmp_", "bf_", "BF_", "GMP_"
+                    , "FLT_", "DBL_", "LDBL_", "FP_", "FE_", "va_"]
+               || nm `elem` integerMacros
+               || nm `elem` words ("SBool SFloat SDouble SReal SRational SChar SString RoundingMode div_t ldiv_t lldiv_t size_t ptrdiff_t intmax_t"
+                  ++ " uintmax_t intptr_t uintptr_t FILE fpos_t NULL EOF stdin stdout stderr BUFSIZ FILENAME_MAX FOPEN_MAX L_tmpnam"
+                  ++ " SEEK_CUR SEEK_END SEEK_SET TMP_MAX EXIT_SUCCESS EXIT_FAILURE RAND_MAX MB_CUR_MAX HUGE_VAL HUGE_VALF HUGE_VALL"
+                  ++ " INFINITY NAN MATH_ERRNO MATH_ERREXCEPT math_errhandling errno limb_t slimb_t fenv_t fexcept_t"
+                  ++ " SIZE_MAX PTRDIFF_MAX PTRDIFF_MIN SIG_ATOMIC_MIN SIG_ATOMIC_MAX WCHAR_MIN WCHAR_MAX WINT_MIN WINT_MAX")
+               || nm `elem` [sign ++ "int" ++ flavor ++ show bits ++ "_t" | sign <- ["", "u"], flavor <- ["", "_least", "_fast"], bits <- [8, 16, 32, 64 :: Int]]
+               || (role /= "parameter" && (nm `elem` libraryFunctions || nm `elem` mathFunctions))
+
+       -- External library identifiers may be shadowed in a prototype's
+       -- parameter scope, but cannot be redefined as generated entry points.
+       libraryFunctions = words ("main abort exit quick_exit _Exit atexit at_quick_exit malloc calloc realloc free aligned_alloc abs labs llabs div ldiv"
+                  ++ " lldiv atoi atol atoll atof strtol strtoll strtoul strtoull strtof strtod strtold rand srand"
+                  ++ " getenv system bsearch qsort mblen mbtowc wctomb mbstowcs wcstombs remove rename tmpfile tmpnam fclose fflush fopen"
+                  ++ " freopen setbuf setvbuf fprintf fscanf printf scanf snprintf sprintf sscanf vfprintf vfscanf vprintf vscanf vsnprintf"
+                  ++ " vsprintf vsscanf fgetc fgets fputc fputs getc getchar putc putchar puts ungetc fread fwrite fgetpos fseek fsetpos"
+                  ++ " ftell rewind clearerr feof ferror perror memcpy memmove memcmp memchr memset strcat strncat strchr strrchr strcmp"
+                  ++ " strncmp strcoll strcpy strncpy strcspn strerror strlen strpbrk strspn strstr strtok strxfrm fpclassify isfinite"
+                  ++ " isinf isnan isnormal signbit isgreater isgreaterequal isless islessequal islessgreater isunordered")
+       mathFunctions = [base ++ suffix | base <- words ("acos asin atan atan2 cos sin tan acosh asinh atanh cosh sinh tanh exp exp2 expm1 frexp ldexp log log10 log1p log2"
+                  ++ " logb modf scalbn scalbln cbrt fabs hypot pow sqrt erf erfc lgamma tgamma ceil floor nearbyint rint lrint llrint"
+                  ++ " round lround llround trunc fmod remainder remquo copysign nan nextafter nexttoward fdim fmax fmin fma"), suffix <- ["", "f", "l"]]
+
+       integerMacros = [sign ++ flavor ++ width ++ suffix
+                       | sign <- ["INT", "UINT"], flavor <- ["", "_LEAST", "_FAST"]
+                       , width <- ["8", "16", "32", "64", "MAX", "PTR"], suffix <- ["_MIN", "_MAX", "_C"]]
+                    ++ [prefix ++ conversion ++ flavor ++ width
+                       | prefix <- ["PRI", "SCN"], conversion <- ["d", "i", "o", "u", "x", "X"]
+                       , flavor <- ["", "LEAST", "FAST"], width <- ["8", "16", "32", "64", "MAX", "PTR"]]
+
+-- | Bind each public parameter to a disjoint implementation-only name. C
+-- parameter names do not affect linkage or the positional calling convention.
+privateParameters :: String -> [(String, CgVal)] -> [(String, CgVal)]
+privateParameters prefix = zipWith (\index (_, value) -> (prefix ++ show index, value)) [0 :: Int ..]
+
+---------------------------------------------------------------------------
+-- * Implementation
+---------------------------------------------------------------------------
+
+-- | C targets differ only in whether optional build metadata must survive
+-- until library merging. The user's requested output configuration is retained.
+data SBVToC = SBVToC | SBVToCLibraryComponent
+
+-- | Select the current lowering pipeline, retaining component build metadata
+-- until a library's dependencies have been combined.
+instance CgTarget SBVToC where
+  targetName _                       = "C"
+  translate SBVToC                   = cgen False
+  translate SBVToCLibraryComponent   = cgen True
+
+-- | Report an unexpected compiler input or violated internal invariant.
+die :: String -> a
+die msg = error $ "SBV->C: Unexpected: " ++ msg
+
+-- | Report an operation without an executable lowering.
+tbd :: String -> a
+tbd msg = error $ "SBV->C: Not yet supported: " ++ msg
+
+-- | Assemble the generated translation unit, public header, and optional
+-- driver and build instructions from the symbolic result.
+cgen :: Bool -> CgConfig -> String -> CgState -> Result -> CgPgmBundle
+cgen retainBuildMetadata cfg nm st sbvProg
+   -- Force type declarations, the signature, and the main program so any
+   -- type-conversion exceptions appear while constructing the bundle.
+   = foldr (seq . validateCName "parameter") () interfaceNames `seq`
+     rnf (render extraTypes) `seq` rnf (render sig) `seq` rnf (render (vcat body)) `seq` result
+  where result = CgPgmBundle bundleKind
+                        $ filt [ ("Makefile"   , (CgMakefile flags          , [genMake usesFloating (cgGenDriver cfg) nm nmd flags]))
+                               , (nm  ++ ".h"  , (CgCHeader (CgCHeaderInfo usesFloating extraTypes [sig] extProtos), [genHeader usesFloating bundleKind nm [sig] extProtos extraTypes]))
+                               , (nmd ++ ".c"  , (CgDriver                  , driver))
+                               , (nm  ++ ".c"  , (CgSource                  , body))
+                               ]
+
+        (body, requirements) = genCProg cfg adts lists sets nm implementationSig sbvProg privateIns privateOuts mbRet extDecls
+        privateIns          = privateParameters "sbv_input_" ins
+        privateOuts         = privateParameters "sbv_output_" allOuts
+        implementationSig   = pprCFunHeader cfg nm privateIns privateOuts mbRet
+
+        bundleKind = (cgInteger cfg, cgReal cfg)
+
+        extraTypes =  roundingModeTypeDecls usesRoundingModeType
+                   $$ (if hasRequirement CRequiresWideBV then wideBVTypeDecls (wideBVKinds kinds) else empty)
+                   $$ (if hasRequirement CRequiresLibBF  then arbitraryFPTypeDecls (arbitraryFPKinds kinds) else empty)
+                   $$ (if hasRequirement CRequiresGMP    then gmpTypeDecls cfg kinds else empty)
+                   $$ (if hasRequirement CRequiresText   then textTypeDecls kinds else empty)
+                   $$ (if hasRequirement CRequiresArrays then arrayForwardTypeDecls arrays else empty)
+                   $$ tupleForwardTypeDecls tuples
+                   $$ adtForwardTypeDecls adts
+                   $$ listForwardTypeDecls lists
+                   $$ setForwardTypeDecls sets
+                   $$ (if hasRequirement CRequiresLists  then listTypeDecls cfg lists else empty)
+                   $$ (if hasRequirement CRequiresSets   then setTypeDecls cfg sets else empty)
+                   $$ structuralTypeDecls cfg adts tuples
+                   $$ adtOwnershipTypePrototypes adts
+                   $$ tupleOwnershipTypeDecls cfg tuples
+                   $$ adtOwnershipTypeDecls cfg adts
+                   $$ (if hasRequirement CRequiresLists then listOwnershipTypeDecls cfg lists else empty)
+                   $$ (if hasRequirement CRequiresSets  then setOwnershipTypeDecls cfg sets else empty)
+                   $$ (if hasRequirement CRequiresArrays then arrayTypeDecls arrays else empty)
+        kinds           = Set.unions [reskinds sbvProg, usedKinds]
+        usesFloating    = any (cFloatingKind cfg) kinds
+        usedKinds       = Set.union interfaceKinds (cProgramUsedKinds sbvProg)
+        interfaceKinds  = Set.fromList . concatMap expandKinds
+                        $ concatMap cgValKinds (map snd ins ++ map snd outs ++ cgReturns st)
+          where cgValKinds (CgAtomic sv) = [kindOf sv]
+                cgValKinds (CgArray svs) = map kindOf svs
+        arrays          = arrayKinds kinds
+        lists           = listKinds kinds
+        sets            = setKinds kinds
+        adts            = adtKinds kinds usedKinds
+        tuples          = tupleKinds (Set.map (resolveADTReferences adts) kinds)
+
+        hasRequirement requirement = requirement `Set.member` requirements
+
+        usesRoundingModeType = any (any isRoundingMode . expandKinds) kinds
+
+        randVals = cgDriverVals cfg
+        driver   = genDriver cfg adts randVals nm ins allOuts mbRet
+
+        filt xs  = [c | c@(_, (k, _)) <- xs, need k]
+          where need k | isCgDriver   k = cgGenDriver cfg
+                       | isCgMakefile k = retainBuildMetadata || cgGenMakefile cfg
+                       | True           = True
+
+        nmd      = nm ++ "_driver"
+        sig      = pprCFunHeader cfg nm ins allOuts mbRet
+        ins      = cgInputs st
+        outs     = cgOutputs st
+        allOuts  = outs ++ returnOuts
+        mbRet    = case cgReturns st of
+                     [CgAtomic resultSV] -> Just resultSV
+                     _                   -> Nothing
+
+        returnOuts = case cgReturns st of
+                       []           -> []
+                       [CgAtomic{}] -> []
+                       results      -> zipWith (\index returnValue -> (returnName index, returnValue)) [0 :: Int ..] results
+
+        returnName index = availableName 0
+          where availableName prefixLength
+                  | candidate `elem` interfaceNames = availableName (prefixLength + 1)
+                  | True                            = candidate
+                  where candidate = concat (replicate prefixLength "sbv_") ++ "result_" ++ show index
+
+        interfaceNames = map fst (ins ++ outs)
+
+        extProtos = case cgPrototypes st of
+                     [] -> empty
+                     xs -> vcat $ text "/* User given prototypes: */" : map text xs
+        extDecls  = case cgDecls st of
+                     [] -> empty
+                     xs -> vcat $ text "/* User given declarations: */" : map text xs
+        flags    = requirementLDFlags requirements ++ cgLDFlags st
+
+-- | Collect types used by the entry point and all retained function/lambda
+-- bodies. A private computation can construct and consume an ADT without that
+-- type appearing in any public signature or top-level assignment. Constants,
+-- parameters, and table entries count even when their body has no assignments.
+cProgramUsedKinds :: Result -> Set.Set Kind
+cProgramUsedKinds result = Set.fromList . concatMap expandKinds $
+     assignmentKinds assignments
+  ++ map (kindOf . fst) (snd (resConsts result))
+  ++ tableKinds (resTables result)
+  ++ concat [lambdaKinds body | (_, (definition, _)) <- resDefinitions result, Just body <- [smtDefInfo definition]]
+ where SBVPgm program = resAsgns result
+       assignments = F.toList program
+
+       assignmentKinds expressions = concat
+         [ map kindOf (value : arguments)
+        ++ case operation of
+             ArrayInit (Right lambdaDef) | Just body <- smtLambdaInfo lambdaDef -> lambdaKinds body
+             _                                                                 -> []
+         | (value, SBVApp operation arguments) <- expressions]
+
+       lambdaKinds body = map kindOf (liOutput body : map snd (liParams body) ++ map fst (liConsts body))
+                       ++ assignmentKinds (F.toList (liAssignments body))
+                       ++ tableKinds (liTables body)
+
+       tableKinds tables = concat [keyKind : valueKind : map kindOf entries | ((_, keyKind, valueKind), entries) <- tables]
+
+-- | Emit tuple and ADT layouts in their joint by-value dependency order.
+-- Forward-declared recursive ADT pointers impose no ordering constraint.
+structuralTypeDecls :: CgConfig -> [Kind] -> [Kind] -> Doc
+structuralTypeDecls cfg adts tuples = vcat (map declaration orderedKinds)
+ where allKinds        = tuples ++ adts
+       availableKinds  = Set.fromList allKinds
+       dependencyNodes = [(kind, kind, filter (`Set.member` availableKinds) (dependencies kind)) | kind <- allKinds]
+       orderedKinds     = concatMap orderedComponent (DG.stronglyConnComp dependencyNodes)
+
+       dependencies (KTuple fieldKinds) = [ resolved
+                                           | fieldKind <- fieldKinds
+                                           , let resolved = resolveADTReferences adts fieldKind
+                                           , isTuple resolved || isConcreteADTReference resolved
+                                           ]
+       dependencies kind
+         | isConcreteADTReference kind = adtDeclarationDependencies adts kind
+         | True                   = []
+
+       orderedComponent (DG.AcyclicSCC kind) = [kind]
+       orderedComponent (DG.CyclicSCC kinds) = error $ "SBV->C: Recursive by-value tuple/ADT layout: " ++ show kinds
+
+       declaration kind
+         | isTuple kind           = tupleTypeDecls [kind]
+         | isConcreteADTReference kind = adtTypeDeclsFor cfg adts [kind]
+         | True                   = error $ "SBV->C: Expected a tuple or ADT layout, received " ++ show kind
+
+-- | Pretty print a function type. A single return value uses C's return
+-- position when its representation permits; aggregate return groups and
+-- multiple returns are passed as output parameters by the caller.
+pprCFunHeader :: CgConfig -> String -> [(String, CgVal)] -> [(String, CgVal)] -> Maybe SV -> Doc
+pprCFunHeader cfg fn ins outs mbRet = retType <+> text fn P.<> parens (fsep (punctuate comma params))
+  where params  = map (mkParam cfg) ins ++ map (mkPParam cfg) outs ++ exactResult
+        retType = case mbRet of
+                    Just sv | isArray sv                           -> text (arrayOutputCType (kindOf sv))
+                    Just sv | not (isExactGMPKind cfg (kindOf sv)) -> pprCWord False sv
+                    _                                              -> text "void"
+
+        exactResult = case mbRet of
+                        Just sv | isExactGMPKind cfg (kindOf sv) -> [text (gmpOutputType (kindOf sv)) <+> text "sbv_result"]
+                        _                                        -> []
+
+-- | Render a generated C input parameter.
+mkParam :: CgConfig -> (String, CgVal) -> Doc
+mkParam _   (n, CgAtomic sv)
+  | isArray sv = text "const" <+> text (arrayInputCType (kindOf sv)) <+> text n
+mkParam _   (n, CgAtomic sv)     = pprCWord True sv <+> text n
+mkParam _   (_, CgArray [])        = die "mkParam: CgArray with no elements!"
+mkParam cfg (n, CgArray (sv:_))
+  | isExactGMPKind cfg kind = text "const" <+> text (gmpArrayType kind) <+> text "*" P.<> text n
+  | isArray kind            = text "const" <+> text (arrayInputCType kind) <+> text "*" P.<> text n
+  | True                    = pprCWord True sv <+> text "*" P.<> text n
+  where kind = kindOf sv
+
+-- | Render a generated C output parameter.
+mkPParam :: CgConfig -> (String, CgVal) -> Doc
+mkPParam _   (n, CgAtomic sv)
+  | isArray sv = text (arrayOutputCType (kindOf sv)) <+> text "*" P.<> text n
+mkPParam cfg (n, CgAtomic sv)
+  | isExactGMPKind cfg (kindOf sv) = text (gmpOutputType (kindOf sv)) <+> text n
+  | True                           = pprCWord False sv <+> text "*" P.<> text n
+mkPParam _   (_, CgArray [])        = die "mkPParam: CgArray with no elements!"
+mkPParam cfg (n, CgArray (sv:_))
+  | isExactGMPKind cfg kind = text (gmpArrayType kind) <+> text "*" P.<> text n
+  | isArray kind            = text (arrayOutputCType kind) <+> text "*" P.<> text n
+  | True                    = pprCWord False sv <+> text "*" P.<> text n
+  where kind = kindOf sv
+
+-- | Renders as "const SWord8 s0", etc. the first parameter is the width of the typefield
+declSV :: Int -> SV -> Doc
+declSV w sv = text "const" <+> pad (showCType sv) <+> text (show sv)
+  where pad s = text $ s ++ replicate (w - length s) ' '
+
+-- | Return the proper declaration and the result as a pair. No consts
+declSVNoConst :: Int -> SV -> (Doc, Doc)
+declSVNoConst w sv = (text "     " <+> pad (showCType sv), text (show sv))
+  where pad s = text $ s ++ replicate (w - length s) ' '
+
+-- | Shared rendering information for one generated function. Constants are
+-- scoped to that function, while the ADT registry describes the whole bundle.
+data CRenderEnv = CRenderEnv
+  { renderConfig    :: CgConfig   -- ^ Representation and runtime-check choices.
+  , renderADTs      :: [Kind]     -- ^ Complete concrete ADT registry.
+  , renderConstants :: [(SV, CV)] -- ^ Constants still eligible for inline rendering.
+  }
+
+-- | Renders as "s0", etc, or the corresponding constant.
+showSV :: CRenderEnv -> SV -> Doc
+showSV env sv
+  | sv == falseSV                              = text "false"
+  | sv == trueSV                               = text "true"
+  | Just cv <- sv `lookup` renderConstants env = mkConst env cv
+  | True                                       = text $ show sv
+
+-- | Words as it would map to a C word
+pprCWord :: HasKind a => Bool -> a -> Doc
+pprCWord cnst v = (if cnst then text "const" else empty) <+> text (showCType v)
+
+-- | Almost a "show", but map "SWord1" to "SBool"
+-- which is used for extracting one-bit words. This is OK since C's bool type
+-- handles arithmetic fine, and maps nicely to our `SWord 1`. (Same isn't true for `SInt 1`, which
+-- doesn't have an easy counter-part on the C side.
+showCType :: HasKind a => a -> String
+showCType i = case kindOf i of
+                KBounded False 1 -> "SBool"
+                KBounded False w -> "SWord" ++ show w
+                KBounded True  w -> "SInt"  ++ show w
+                k@KArray{}        -> arrayCType k
+                k@KTuple{}        -> tupleCType k
+                k@KADT{}
+                  | not (isRoundingMode k) && not (isUninterpreted k) -> adtCType k
+                k@KFP{}           -> arbitraryFPCType k
+                KString           -> "SString"
+                KChar             -> "SChar"
+                k@KList{}         -> listCType k
+                k@KSet{}          -> setCType k
+                k                -> show k
+
+-- | The printf specifier for the type
+specifier :: CgConfig -> SV -> Doc
+specifier cfg = specifierKind cfg . kindOf
+
+-- | Return the @printf@ conversion for a supported scalar kind.
+specifierKind :: CgConfig -> Kind -> Doc
+specifierKind cfg kind = case kind of
+  KVar{}        -> die $ "variable sort: " ++ show kind
+  KBool         -> spec (False, 1)
+  KBounded b i  -> spec (b, i)
+  KUnbounded    -> spec (True, fromJust (cgInteger cfg))
+  KReal         -> specF (fromJust (cgReal cfg))
+  KFloat        -> specF CgFloat
+  KDouble       -> specF CgDouble
+  KString       -> text "%s"
+  KChar         -> text "%c"
+  KRational     -> die   "rational sort"
+  KFP{}         -> die   "arbitrary float sort"
+  KList k       -> die $ "list sort: "   ++ show k
+  KSet  k       -> die $ "set sort: "    ++ show k
+  KApp s _      -> die $ "ADT app: "     ++ s
+  k@(KADT s _ _)
+    | isRoundingMode k -> text "%d"
+    | True             -> die $ "ADT: " ++ s
+  KTuple k      -> die $ "tuple sort: "  ++ show k
+  KArray  k1 k2 -> die $ "array sort: "  ++ show (k1, k2)
+  where u8InHex = cgShowU8InHex cfg
+
+        spec :: (Bool, Int) -> Doc
+        spec (False,  1) = text "%d"
+        spec (False,  8)
+          | u8InHex      = text "0x%02\"PRIx8\""
+          | True         = text "%\"PRIu8\""
+        spec (True,   8) = text "%\"PRId8\""
+        spec (False, 16) = text "0x%04\"PRIx16\"U"
+        spec (True,  16) = text "%\"PRId16\""
+        spec (False, 32) = text "0x%08\"PRIx32\"UL"
+        spec (True,  32) = text "%\"PRId32\"L"
+        spec (False, 64) = text "0x%016\"PRIx64\"ULL"
+        spec (True,  64) = text "%\"PRId64\"LL"
+        spec (s, sz)     = die $ "Format specifier at type " ++ (if s then "SInt" else "SWord") ++ show sz
+
+        specF :: CgSRealType -> Doc
+        specF CgFloat      = text "%a"
+        specF CgDouble     = text "%a"
+        specF CgLongDouble = text "%Lf"
+
+-- | Make a constant value of the given type. Explicitly mapped integers are
+-- reduced to their requested width; bounded constants are already normalized.
+-- The enclosing program's ADT registry is reused throughout nested literals.
+--   There are many options here, using binary, decimal, etc. We simply use decimal for values 8-bits or less,
+--   and hex otherwise.
+mkConst :: CRenderEnv -> CV -> Doc
+mkConst env = renderConstant
+ where
+  cfg  = renderConfig env
+  adts = renderADTs env
+
+  renderConstant (CV KReal (CAlgReal (AlgRational False _)))
+    = error "SBV->C: Inexact SReal literals do not specify an exact value and cannot be compiled."
+  renderConstant (CV KReal (CAlgReal AlgInterval{}))
+    = error "SBV->C: Interval SReal literals do not specify an exact value and cannot be compiled."
+  renderConstant (CV KReal (CAlgReal AlgPolyRoot{}))
+    = error "SBV->C: Algebraic SReal literals are not supported; use an explicitly chosen rational approximation."
+  renderConstant cv
+    | Just d <- roundingModeConst cv = d
+  renderConstant cv
+    | Just d <- arrayConst renderConstant cv = d
+  renderConstant cv
+    | Just d <- tupleConst renderConstant cv = d
+  renderConstant cv
+    | Just d <- adtConst adts renderConstant cv = d
+  renderConstant cv
+    | Just d <- listConst renderConstant cv = d
+  renderConstant cv
+    | Just d <- setConst renderConstant cv = d
+  renderConstant cv
+    | Just d <- gmpConst cfg cv = d
+  renderConstant (CV k (CInteger i))
+    | Just d <- wideBVConst k i = d
+  renderConstant (CV KReal (CAlgReal (AlgRational _ r))) = double (fromRational r :: Double) P.<> sRealSuffix (fromJust (cgReal cfg))
+    where sRealSuffix CgFloat      = text "F"
+          sRealSuffix CgDouble     = empty
+          sRealSuffix CgLongDouble = text "L"
+  renderConstant (CV KUnbounded       (CInteger i)) = renderConstant (normCV (CV (KBounded True (fromJust (cgInteger cfg))) (CInteger i)))
+  renderConstant (CV (KBounded sg sz) (CInteger i)) = showSizedConst (cgShowU8InHex cfg) i (sg, sz)
+  renderConstant (CV KBool            (CInteger i)) = showSizedConst (cgShowU8InHex cfg) i (False, 1)
+  renderConstant (CV KFloat           (CFloat f))   = text $ showCFloat f
+  renderConstant (CV KDouble          (CDouble d))  = text $ showCDouble d
+  renderConstant (CV k@KFP{}          (CFP fp))     = fromJust (arbitraryFPConst k fp)
+  renderConstant cv@(CV KString       CString{})     = fromJust (textConst cv)
+  renderConstant cv@(CV KChar         CChar{})       = fromJust (textConst cv)
+  renderConstant cv                                 = die $ "mkConst: " ++ show cv
+
+-- | Render a bounded literal using its signedness, width, and display mode.
+showSizedConst :: Bool -> Integer -> (Bool, Int) -> Doc
+showSizedConst _   i   (False,  1) = text (if i == 0 then "false" else "true")
+showSizedConst u8h i t@(False,  8)
+  | u8h                            = text $ T.unpack (chex False True t i)
+  | True                           = integer i
+showSizedConst _   i   (True,   8) = integer i
+showSizedConst _   i t@(False, 16) = text $ T.unpack $ chex False True t i
+showSizedConst _   i t@(True,  16) = text $ T.unpack $ chex False True t i
+showSizedConst _   i t@(False, 32) = text $ T.unpack $ chex False True t i
+showSizedConst _   i t@(True,  32) = text $ T.unpack $ chex False True t i
+showSizedConst _   i t@(False, 64) = text $ T.unpack $ chex False True t i
+showSizedConst _   i t@(True,  64) = text $ T.unpack $ chex False True t i
+showSizedConst _   i   (s, sz)     = die $ "Constant " ++ show i ++ " at type " ++ (if s then "SInt" else "SWord") ++ show sz
+
+-- | Invoke the C compiler with contraction disabled after user flags, including
+-- during LTO linking. Explicit calls to @fma@ are not implicit contraction.
+cCompilerCommand :: Bool -> Bool -> String
+cCompilerCommand floating gmp = "${CC} ${CCFLAGS}" ++ (if gmp then " ${GMP_CFLAGS}" else "")
+                                                 ++ (if floating then " -ffp-contract=off" else "")
+
+-- | Does a representation require the floating-point compilation contract?
+cFloatingKind :: CgConfig -> Kind -> Bool
+cFloatingKind cfg kind = isFloat kind || isDouble kind || isFP kind || (isReal kind && isJust (cgReal cfg))
+
+-- | Generate a makefile. The first argument is True if we have a driver.
+genMake :: Bool -> Bool -> String -> String -> [String] -> Doc
+genMake floating ifdr fn dn ldFlags = foldr1 ($$) [l | (True, l) <- lns]
+ where ifld = not (null ldFlags)
+       gmp  = "-lgmp" `elem` ldFlags
+       ld = text "${LDFLAGS}" <+> if ifld then text "${SBV_LIBS}" else empty
+       renderedLDFlags = unwords $ filter (/= "-lgmp") ldFlags ++ ["${GMP_LIBS}" | gmp]
+       lns = [ (True, text "# Makefile for" <+> nm P.<> text ". Automatically generated by SBV. Do not edit!")
+             , (True, text "")
+             , (True, text "# include any user-defined .mk file in the current directory.")
+             , (True, text "-include *.mk")
+             , (True, text "")
+             , (True, text "CC?=gcc")
+             , (True, text "CCFLAGS?=-Wall -O3 -DNDEBUG -fomit-frame-pointer")
+             , (gmp,  text "GMP_CFLAGS?=$(shell pkg-config --cflags gmp)")
+             , (gmp,  text "GMP_LIBS?=$(shell pkg-config --libs gmp)")
+             , (ifld, text "SBV_LIBS?=" P.<> text renderedLDFlags)
+             , (True, text "")
+             , (ifdr, text "all:" <+> nmd)
+             , (ifdr, text "")
+             , (True, nmo P.<> text (": " ++ ppSameLine (hsep [nmc, nmh])))
+             , (True, text ("\t" ++ cCompilerCommand floating gmp) <+> text "-c $< -o $@")
+             , (True, text "")
+             , (ifdr, nmdo P.<> text (": " ++ ppSameLine (hsep [nmdc, nmh])))
+             , (ifdr, text ("\t" ++ cCompilerCommand floating gmp) <+> text "-c $< -o $@")
+             , (ifdr, text "")
+             , (ifdr, nmd P.<> text (": " ++ ppSameLine (hsep [nmo, nmdo])))
+             , (ifdr, text ("\t" ++ cCompilerCommand floating False) <+> text "$^ -o $@" <+> ld)
+             , (ifdr, text "")
+             , (True, text "clean:")
+             , (True, text "\trm -f *.o")
+             , (True, text "")
+             , (ifdr, text "veryclean: clean")
+             , (ifdr, text "\trm -f" <+> nmd)
+             , (ifdr, text "")
+             ]
+       nm   = text fn
+       nmd  = text dn
+       nmh  = nm P.<> text ".h"
+       nmc  = nm P.<> text ".c"
+       nmo  = nm P.<> text ".o"
+       nmdc = nmd P.<> text ".c"
+       nmdo = nmd P.<> text ".o"
+
+-- | Generate the header
+genHeader :: Bool -> (Maybe Int, Maybe CgSRealType) -> String -> [Doc] -> Doc -> Doc -> Doc
+genHeader floating (ik, rk) fn sigs protos extraTypes =
+     text "/* Header file for" <+> nm P.<> text ". Automatically generated by SBV. Do not edit! */"
+  $$ text ""
+  $$ text "#ifndef" <+> tag
+  $$ text "#define" <+> tag
+  $$ text ""
+  $$ (if floating then vcat [text "#if defined(__FAST_MATH__) || (defined(__FINITE_MATH_ONLY__) && __FINITE_MATH_ONLY__ > 0)"
+                           , text "#error \"SBV-generated C requires IEEE floating-point semantics; disable fast-math and finite-math-only.\""
+                           , text "#endif"] else empty)
+  $$ text ""
+  $$ text "#include <stdio.h>"
+  $$ text "#include <stdlib.h>"
+  $$ text "#include <inttypes.h>"
+  $$ text "#include <stdint.h>"
+  $$ text "#include <stdbool.h>"
+  $$ text "#include <string.h>"
+  $$ text "#include <math.h>"
+  $$ (if floating then vcat [text "#include <float.h>"
+                           , text "#if FLT_EVAL_METHOD != 0"
+                           , text "#error \"SBV-generated C requires FLT_EVAL_METHOD == 0; indeterminate or excess-precision floating evaluation is unsupported.\""
+                           , text "#endif"] else empty)
+  $$ text ""
+  $$ text "/* Floating-point calling convention:"
+  $$ text " * Enter generated code in FE_TONEAREST (round-to-nearest, ties-to-even)."
+  $$ text " * Callbacks must preserve this mode before returning or re-entering."
+  $$ text " * Generated code does not check or change the hardware rounding mode."
+  $$ text " * Custom builds must disable implicit FP contraction, including at LTO link time."
+  $$ text " */"
+  $$ text ""
+  $$ text "/* The boolean type */"
+  $$ text "typedef bool SBool;"
+  $$ text ""
+  $$ text "/* The float type */"
+  $$ text "typedef float SFloat;"
+  $$ text ""
+  $$ text "/* The double type */"
+  $$ text "typedef double SDouble;"
+  $$ text ""
+  $$ text "/* Unsigned bit-vectors */"
+  $$ text "typedef uint8_t  SWord8;"
+  $$ text "typedef uint16_t SWord16;"
+  $$ text "typedef uint32_t SWord32;"
+  $$ text "typedef uint64_t SWord64;"
+  $$ text ""
+  $$ text "/* Signed bit-vectors */"
+  $$ text "typedef int8_t  SInt8;"
+  $$ text "typedef int16_t SInt16;"
+  $$ text "typedef int32_t SInt32;"
+  $$ text "typedef int64_t SInt64;"
+  $$ text ""
+  $$ imapping
+  $$ rmapping
+  $$ extraTypes
+  $$ text ("/* Entry point prototype" ++ plu ++ ": */")
+  $$ vcat (map (P.<> semi) sigs)
+  $$ text ""
+  $$ protos
+  $$ text "#endif /*" <+> tag <+> text "*/"
+  $$ text ""
+ where nm  = text fn
+       tag = text "SBV_GENERATED_" P.<> nm P.<> text "_HEADER_INCLUDED"
+       plu = if length sigs /= 1 then "s" else ""
+       imapping = case ik of
+                    Nothing -> empty
+                    Just i  ->    text "/* User requested mapping for SInteger.                                 */"
+                               $$ text "/* NB. Loss of precision: Target type is subject to modular arithmetic. */"
+                               $$ text ("typedef SInt" ++ show i ++ " SInteger;")
+                               $$ text ""
+       rmapping = case rk of
+                    Nothing -> empty
+                    Just t  ->    text "/* User requested mapping for SReal.                          */"
+                               $$ text "/* NB. Loss of precision: Target type is subject to rounding. */"
+                               $$ text ("typedef " ++ show t ++ " SReal;")
+                               $$ text ""
+
+-- | Insert an empty separating line when the condition holds.
+sepIf :: Bool -> Doc
+sepIf b = if b then text "" else empty
+
+-- | Test whether an ADT value needs the caller-owned deep-storage ABI.
+isOwnedADT :: CgConfig -> [Kind] -> SV -> Bool
+isOwnedADT cfg adts sv = isADT sv
+                     && not (isRoundingMode sv)
+                     && adtNeedsOwnership cfg adts (kindOf sv)
+
+-- | Generate an example driver program
+genDriver :: CgConfig -> [Kind] -> [Integer] -> String -> [(String, CgVal)] -> [(String, CgVal)] -> Maybe SV -> [Doc]
+genDriver cfg adts randVals fn publicInputs publicOutputs mbRet
+  = [pre, include, callbacks, printHelpers, header, body, post]
+ where env  = CRenderEnv cfg adts []
+       inps = privateParameters "sbv_driver_input_" publicInputs
+       outs = privateParameters "sbv_driver_output_" publicOutputs
+       publicName local = fromMaybe local (lookup local publicNames)
+       publicNames = zip (map fst (inps ++ outs)) (map fst (publicInputs ++ publicOutputs))
+
+       pre         =  text "/* Example driver program for" <+> nm P.<> text ". */"
+                   $$ text "/* Automatically generated by SBV. Edit as you see fit! */"
+                   $$ text ""
+                   $$ text "#include <stdio.h>"
+       include     = text "#include" <+> doubleQuotes (nm P.<> text ".h")
+       callbacks   = vcat (map (arrayDriverCallback cfg) inputArrayKinds)
+       header      =  text ""
+                   $$ text "int main(void)"
+                   $$ text "{"
+       body        =  text ""
+                   $$ nest 2 (   vcat (map mkInp pairedInputs)
+                           $$ vcat (map mkOut outs)
+                           $$ sepIf (not (null [() | (_, _, CgArray{}) <- pairedInputs]) || not (null outs))
+                           $$ call
+                           $$ text ""
+                           $$ (case mbRet of
+                              Just sv | isArray sv
+                                      -> displayArray "sbv_result" displayCall resultVar (kindOf sv)
+                              Just sv | isTuple sv
+                                      -> displayTuple displayCall resultVar (kindOf sv)
+                              Just sv | isADT sv && not (isRoundingMode sv)
+                                      -> displayADT displayCall resultVar (kindOf sv)
+                              Just sv | isList sv
+                                      -> displayList displayCall resultVar (kindOf sv)
+                              Just sv | isSet sv
+                                      -> displaySet displayCall resultVar (kindOf sv)
+                              Just sv | isWideBV (kindOf sv)
+                                      -> text "printf" P.<> parens (printQuotes (displayCall <+> text "=")) P.<> semi
+                                      $$ wideBVPrint (kindOf sv) resultVar P.<> semi
+                                      $$ text "printf(\"\\n\");"
+                              Just sv | isFP (kindOf sv)
+                                      -> text "printf" P.<> parens (printQuotes (displayCall <+> text "=")) P.<> semi
+                                      $$ arbitraryFPPrint (kindOf sv) resultVar P.<> semi
+                                      $$ text "printf(\"\\n\");"
+                              Just sv | isExactGMPKind cfg (kindOf sv)
+                                      -> text "printf" P.<> parens (printQuotes (displayCall <+> text "=")) P.<> semi
+                                      $$ gmpPrint (kindOf sv) resultVar P.<> semi
+                                      $$ text "printf(\"\\n\");"
+                              Just sv | kindOf sv `elem` [KChar, KString]
+                                      -> text "printf" P.<> parens (printQuotes (displayCall <+> text "=")) P.<> semi
+                                      $$ textPrint (kindOf sv) resultVar P.<> semi
+                                      $$ text "printf(\"\\n\");"
+                              Just sv -> text "printf" P.<> parens (printQuotes (displayCall <+> text "=" <+> specifier cfg sv P.<> text "\\n")
+                                                                              P.<> comma <+> resultVar) P.<> semi
+                              Nothing -> text "printf" P.<> parens (printQuotes (displayCall <+> text "->\\n")) P.<> semi)
+                           $$ vcat (map display outs)
+                           $$ driverCleanup
+                           )
+       post        =   text ""
+                   $+$ nest 2 (text "return 0" P.<> semi)
+                   $$  text "}"
+                   $$  text ""
+       nm                 = text fn
+       inputArrayKinds    = nub . concatMap collectInputArrays $ concatMap inputKinds inps
+       inputKinds (_, CgAtomic sv) = [kindOf sv]
+       inputKinds (_, CgArray svs) = map kindOf svs
+
+       collectInputArrays = collect Set.empty
+        where collect visited kind
+                | kind `Set.member` visited = []
+                | KApp{} <- kind
+                = collect nextVisited (resolveADTReferences adts kind)
+                | KArray keyKind valueKind <- kind
+                = kind : collect nextVisited keyKind ++ collect nextVisited valueKind
+                | KTuple fieldKinds <- kind
+                = concatMap (collect nextVisited) fieldKinds
+                | KList elementKind <- kind
+                = collect nextVisited elementKind
+                | KSet elementKind <- kind
+                = collect nextVisited elementKind
+                | isConcreteADTReference kind
+                = concatMap (concatMap (collect nextVisited) . snd) (adtConstructors adts kind)
+                | True
+                = []
+               where nextVisited = Set.insert kind visited
+       pairedInputs = matchRands randVals inps
+       inputSeeds   = matchInputSeeds randVals inps
+       matchRands _      []                                 = []
+       matchRands []     _                                  = die "Run out of driver values!"
+       matchRands (r:rs) ((n, CgAtomic sv)            : cs)
+         | KArray _ valueKind <- kindOf sv                   = ([mkRValKind valueKind r], n, CgAtomic sv) : matchRands rs cs
+       matchRands (r:rs) ((n, CgAtomic sv)            : cs) = ([mkRVal sv r], n, CgAtomic sv) : matchRands rs cs
+       matchRands _      ((n, CgArray [])             : _ ) = die $ "Unsupported empty array input " ++ show n
+       matchRands rs     ((n, a@(CgArray sws@(sv:_))) : cs)
+          | length frs /= l                                 = die "Run out of driver values!"
+          | True                                            = (map (mkRVal sv) frs, n, a) : matchRands srs cs
+          where l          = length sws
+                (frs, srs) = splitAt l rs
+       matchInputSeeds _      []                            = []
+       matchInputSeeds []     _                             = die "Run out of driver values!"
+       matchInputSeeds (r:rs) ((n, CgAtomic{})        : cs) = (n, [r]) : matchInputSeeds rs cs
+       matchInputSeeds _      ((n, CgArray [])        : _ ) = die $ "Unsupported empty array input " ++ show n
+       matchInputSeeds rs     ((n, CgArray values@(_:_)) : cs)
+         | length seeds == length values                       = (n, seeds) : matchInputSeeds rest cs
+         | True                                                = die "Run out of driver values!"
+        where (seeds, rest) = splitAt (length values) rs
+       inputSeed n = case inputGroupSeeds n of
+                       seed:_ -> seed
+                       []     -> die $ "Missing driver seed for composite input " ++ show n
+       inputGroupSeeds n = case lookup n inputSeeds of
+                            Just seeds -> seeds
+                            Nothing    -> die $ "Missing driver seed for composite input " ++ show n
+       inputElementName n index = n ++ "_element_" ++ show (index :: Int)
+       inputNeedsInitialization kind
+         | isConcreteADTReference kind = adtNeedsOwnership cfg adts kind
+         | True                        = valueDriverNeedsInitialization cfg kind
+       mkRVal sv = mkRValKind (kindOf sv)
+       mkRValKind kind r
+         | isRoundingMode kind            = roundingModeDriverValue r
+         | isExactGMPKind cfg kind         = integer r
+         | kind `elem` [KChar, KString]    = textDriverValue kind r
+         | isList kind                     = listDriverValue mkRValKind kind r
+         | isSet kind                      = setDriverValue mkRValKind kind r
+         | KTuple fieldKinds <- kind       = tupleValue kind (zipWith mkField fieldKinds [0 :: Integer ..])
+         | isADT kind                      = adtDriverValue adts mkRValKind kind r
+         | True                            = mkConst env $ mkConstCV kind r
+         where mkField fieldKind offset = mkRValKind fieldKind (r + offset)
+       driverValueInit = valueDriverInit cfg mkRValKind initializeComposite
+
+       -- Only these constructors need the complete ADT registry or the public
+       -- versus stored array ABI. All other dispatch belongs to Value.
+       -- Resolving KApp re-enters the generic dispatcher with the concrete kind.
+       initializeComposite kind externalName seed
+         | KApp{} <- kind                   = driverValueInit (resolveADTReferences adts kind) externalName seed
+         | isArray kind                    = initializeArray kind externalName seed
+         | isConcreteADTReference kind
+         , adtNeedsOwnership cfg adts kind  = adtDriverInit cfg adts mkRValKind driverValueInit kind externalName seed
+         | isConcreteADTReference kind      = text (adtCType kind) <+> text externalName <+> text "="
+                                           <+> adtDriverValue adts mkRValKind kind seed P.<> semi
+         | True                            = die $ "Expected an array or ADT driver kind, received " ++ show kind
+       initializeArray kind@(KArray _ valueKind) externalName seed
+         = let defaultName = externalName ++ "_default"
+               inputName   = externalName ++ "_input"
+           in driverValueInit valueKind defaultName seed
+              $$ arrayDriverInput cfg kind inputName defaultName
+              $$ arrayDriverStoredInput kind externalName inputName
+              $$ driverValueClear valueKind defaultName
+       initializeArray kind _ _ = die $ "Expected an array driver kind, received " ++ show kind
+       driverValueClear kind externalName
+         | isConcreteADTReference kind
+         , not (adtNeedsOwnership cfg adts kind) = empty
+         | True                                 = valueDriverClear cfg kind externalName
+       mkInp (_, n, CgAtomic sv)
+         | KArray _ valueKind <- kindOf sv
+         = let defaultName = n ++ "_default"
+           in driverValueInit valueKind defaultName (inputSeed n)
+              $$ arrayDriverInput cfg (kindOf sv) n defaultName
+       mkInp ([_], n, CgAtomic sv)
+         | inputNeedsInitialization (kindOf sv) = driverValueInit (kindOf sv) n (inputSeed n)
+       mkInp (_,   _, CgAtomic{})         = empty  -- constant, no need to declare
+       mkInp (_,   n, CgArray [])         = die $ "Unsupported empty array value for " ++ show n
+       mkInp (vs, n, CgArray sws@(sv:_))
+         | isExactGMPKind cfg kind = text (gmpArrayType kind) <+> text n P.<> brackets (int lengthOfArray) P.<> semi
+                                  $$ vcat (zipWith initialize [0 :: Int ..] vs)
+                                  $$ displayInputArray
+         | inputNeedsInitialization kind
+         = vcat [initializeElement elementName seed | (elementName, seed) <- zip elementNames (inputGroupSeeds n)]
+        $$ text "const" <+> text inputType <+> text n P.<> brackets (int lengthOfArray)
+           <+> text "=" <+> braces (fsep (punctuate comma (map text elementNames))) P.<> semi
+        $$ displayInputArray
+         | True                    = pprCWord True sv <+> text n P.<> brackets (int lengthOfArray) <+> text "= {"
+                                  $$ nest 4 (fsep (punctuate comma (align vs)))
+                                  $$ text "};"
+                                  $$ displayInputArray
+         where kind          = kindOf sv
+               lengthOfArray = length sws
+
+               initialize index = gmpDriverInitialize kind (text n P.<> brackets (int index))
+
+               elementNames = [inputElementName n index | index <- [0 .. lengthOfArray - 1]]
+               inputType
+                 | isArray kind = arrayInputCType kind
+                 | True         = showCType kind
+               initializeElement elementName seed
+                 | KArray _ valueKind <- kind
+                 = driverValueInit valueKind (elementName ++ "_default") seed
+                $$ arrayDriverInput cfg kind elementName (elementName ++ "_default")
+                 | True
+                 = driverValueInit kind elementName seed
+
+               displayInputArray = text ""
+                                $$ text "printf" P.<> parens (printQuotes (text "Contents of input array" <+> text (publicName n) P.<> text ":\\n")) P.<> semi
+                                $$ display (n, CgArray sws)
+                                $$ text ""
+       mkOut (v, CgAtomic sv)
+         | isArray sv                          = text (arrayOutputCType (kindOf sv)) <+> text v <+> text "=" <+> braces (text "0") P.<> semi
+         | isExactGMPKind cfg (kindOf sv)      = gmpDriverInit (kindOf sv) (text v) (text "0")
+         | kindOf sv == KString                = text "SString" <+> text v <+> text "=" <+> braces (text "0") P.<> semi
+         | isList sv                           = text (listCType (kindOf sv)) <+> text v <+> text "=" <+> braces (text "0") P.<> semi
+         | isSet sv                            = text (setCType (kindOf sv)) <+> text v <+> text "=" <+> braces (text "0") P.<> semi
+         | tupleNeedsOwnership cfg (kindOf sv) = text (tupleCType (kindOf sv)) <+> text v
+                                             <+> text "=" <+> braces (text "0") P.<> semi
+         | isOwnedADT cfg adts sv              = text (adtCType (kindOf sv)) <+> text v
+                                             <+> text "=" <+> braces (text "0") P.<> semi
+         | True                                = pprCWord False sv <+> text v P.<> semi
+       mkOut (v, CgArray [])         = die $ "Unsupported empty array value for " ++ show v
+       mkOut (v, CgArray sws@(sv:_))
+         | isExactGMPKind cfg kind = text (gmpArrayType kind) <+> text v P.<> brackets (int lengthOfArray) P.<> semi
+                                  $$ vcat [gmpDriverInitialize kind (text v P.<> brackets (int index)) (text "0") | index <- [0 .. lengthOfArray - 1]]
+         | isArray kind            = text (arrayOutputCType kind) <+> text v P.<> brackets (int lengthOfArray)
+                                  <+> text "=" <+> braces (text "0") P.<> semi
+         | True                    = pprCWord False sv <+> text v P.<> brackets (int lengthOfArray) P.<> semi
+         where kind          = kindOf sv
+               lengthOfArray = length sws
+       resultVar = text "sbv_result"
+       call = case mbRet of
+                Nothing -> fcall P.<> semi
+                Just sv
+                  | isExactGMPKind cfg (kindOf sv)      -> gmpDriverInit (kindOf sv) resultVar (text "0")
+                                                        $$ fcall P.<> semi
+                  | isArray sv                          -> text (arrayOutputCType (kindOf sv)) <+> resultVar
+                                                       <+> text "=" <+> fcall P.<> semi
+                  | tupleNeedsOwnership cfg (kindOf sv) -> text (tupleCType (kindOf sv)) <+> resultVar
+                                                       <+> text "=" <+> fcall P.<> semi
+                  | isOwnedADT cfg adts sv              -> text (adtCType (kindOf sv)) <+> resultVar
+                                                       <+> text "=" <+> fcall P.<> semi
+                  | kindOf sv == KString                -> text "SString" <+> resultVar <+> text "=" <+> fcall P.<> semi
+                  | isList sv                           -> text (listCType (kindOf sv)) <+> resultVar
+                                                       <+> text "=" <+> fcall P.<> semi
+                  | isSet sv                            -> text (setCType (kindOf sv)) <+> resultVar
+                                                       <+> text "=" <+> fcall P.<> semi
+                  | True                                -> pprCWord True sv <+> resultVar <+> text "=" <+> fcall P.<> semi
+       fcall       = functionCall id
+       displayCall = nm P.<> parens (fsep (punctuate comma (map displayInput pairedInputs ++ map (mkOVal publicName) outs ++ exactResultArg)))
+       displayInput input@(_, inputName, CgAtomic sv)
+         | kindOf sv == KString || isTuple sv || isADT sv || isWideBV (kindOf sv) || isFP sv
+         = text (publicName inputName)
+         | True = mkCVal publicName input
+       displayInput input = mkCVal publicName input
+       functionCall rename = nm P.<> parens (fsep (punctuate comma (map (mkCVal rename) pairedInputs ++ map (mkOVal rename) outs ++ exactResultArg)))
+       exactResultArg = case mbRet of
+                          Just sv | isExactGMPKind cfg (kindOf sv) -> [resultVar]
+                          _                                        -> []
+       mkCVal rename ([v], n, CgAtomic sv)
+         | inputNeedsInitialization (kindOf sv) = text (rename n)
+         | True                                = v
+       mkCVal _      (vs, n, CgAtomic{}) = die $ "Unexpected driver value computed for " ++ show n ++ render (hcat vs)
+       mkCVal rename (_,  n, CgArray{})  = text (rename n)
+       mkOVal rename (n, CgAtomic sv)
+         | isExactGMPKind cfg (kindOf sv) = text (rename n)
+         | True                           = text "&" P.<> text (rename n)
+       mkOVal rename (n, CgArray{}) = text (rename n)
+       display (n, CgAtomic sv)
+         | isArray sv                           = displayArray n label (text n) (kindOf sv)
+         | isTuple sv                           = displayTuple label (text n) (kindOf sv)
+         | isADT sv && not (isRoundingMode sv) = displayADT label (text n) (kindOf sv)
+         | isList sv                            = displayList label (text n) (kindOf sv)
+         | isSet sv                             = displaySet label (text n) (kindOf sv)
+         | isWideBV (kindOf sv)                 = text "printf" P.<> parens (printQuotes (text " " <+> label <+> text "=")) P.<> semi
+                                                $$ wideBVPrint (kindOf sv) (text n) P.<> semi
+                                                $$ text "printf(\"\\n\");"
+         | isFP (kindOf sv)                     = text "printf" P.<> parens (printQuotes (text " " <+> label <+> text "=")) P.<> semi
+                                                $$ arbitraryFPPrint (kindOf sv) (text n) P.<> semi
+                                                $$ text "printf(\"\\n\");"
+         | isExactGMPKind cfg (kindOf sv)       = text "printf" P.<> parens (printQuotes (text " " <+> label <+> text "=")) P.<> semi
+                                                $$ gmpPrint (kindOf sv) (text n) P.<> semi
+                                                $$ text "printf(\"\\n\");"
+         | kindOf sv `elem` [KChar, KString]     = text "printf" P.<> parens (printQuotes (text " " <+> label <+> text "=")) P.<> semi
+                                                $$ textPrint (kindOf sv) (text n) P.<> semi
+                                                $$ text "printf(\"\\n\");"
+         | True                                 = text "printf" P.<> parens (printQuotes (text " " <+> label <+> text "=" <+> specifier cfg sv
+                                                                                         P.<> text "\\n") P.<> comma <+> text n) P.<> semi
+         where label = text (publicName n)
+       display (n, CgArray [])         = die $ "Unsupported empty array value for " ++ show n
+       display (n, CgArray sws@(sv:_)) = text "int" <+> nctr P.<> semi
+                                      $$ text "for(" P.<> nctr <+> text "= 0;" <+> nctr <+> text "<" <+> int len <+> text "; ++" P.<> nctr P.<> text ")"
+                                      $$ text "{"
+                                      $$ nest 2 displayEntry
+                                      $$ text "}"
+         where nctr      = text n P.<> text "_ctr"
+               entry     = text n P.<> text "[" P.<> nctr P.<> text "]"
+               entrySpec = text (publicName n) P.<> text "[%" P.<> int tab P.<> text "d]"
+               kind      = kindOf sv
+               len       = length sws
+               tab       = length $ show (len - 1)
+
+               displayEntry
+                 | isArray kind = displayArrayEntry kind
+                 | True         = text "printf" P.<> parens (printQuotes (text " " <+> entrySpec <+> text "= ") P.<> comma <+> nctr) P.<> semi
+                               $$ printValue kind entry
+                               $$ text "printf(\"\\n\");"
+
+               displayArrayEntry arrayKind@(KArray keyKind valueKind)
+                 =  keySetup
+                 $$ text "printf" P.<> parens (printQuotes (text " " <+> (entrySpec P.<> text "[0] =")) P.<> comma <+> nctr) P.<> semi
+                 $$ printValue valueKind arrayValue
+                 $$ text "printf(\"\\n\");"
+                 $$ keyCleanup
+                where keyName    = "sbv_local_array_key_" ++ n
+                      key        = text keyName
+                      keySetup   = driverValueInit keyKind keyName 0
+                      keyCleanup = driverValueClear keyKind keyName
+                      arrayValue
+                        | n `elem` map fst inps
+                        = entry P.<> text ".lookup" P.<> parens (fsep (punctuate comma [entry P.<> text ".context", key]))
+                        | True
+                        = text (arrayOutputReadName arrayKind) P.<> parens (fsep (punctuate comma [entry, key]))
+               displayArrayEntry arrayKind = die $ "Expected an array return-group element, received " ++ show arrayKind
+
+       displayArray stem label descriptor kind@(KArray keyKind valueKind)
+         =  keySetup
+         $$ text "printf" P.<> parens (printQuotes (text " " <+> label P.<> text "[0] =")) P.<> semi
+         $$ printArrayValue
+         $$ text "printf(\"\\n\");"
+         $$ keyCleanup
+        where keyName = "sbv_local_array_key_" ++ stem
+              key     = text keyName
+
+              keySetup   = driverValueInit  keyKind keyName 0
+              keyCleanup = driverValueClear keyKind keyName
+
+              value = text (arrayOutputReadName kind) P.<> parens (fsep (punctuate comma [descriptor, key]))
+              printArrayValue = printValue valueKind value
+       displayArray _ _ _ kind = die $ "Expected an array output, received " ++ show kind
+
+       displayTuple label value kind@KTuple{}
+         =  text "printf" P.<> parens (printQuotes (text " " <+> label <+> text "=")) P.<> semi
+         $$ printTupleValue value kind
+         $$ text "printf(\"\\n\");"
+       displayTuple _ _ kind = die $ "Expected a tuple output, received " ++ show kind
+
+       displayADT label value kind
+         =  text "printf" P.<> parens (printQuotes (text " " <+> label <+> text "=")) P.<> semi
+         $$ adtPrint adts printValue kind value
+         $$ text "printf(\"\\n\");"
+
+       displayList label value kind@KList{}
+         =  text "printf" P.<> parens (printQuotes (text " " <+> label <+> text "=")) P.<> semi
+         $$ listPrint printValue kind value
+         $$ text "printf(\"\\n\");"
+       displayList _ _ kind = die $ "Expected a list output, received " ++ show kind
+
+       displaySet label value kind@KSet{}
+         =  text "printf" P.<> parens (printQuotes (text " " <+> label <+> text "=")) P.<> semi
+         $$ setPrint printValue kind value
+         $$ text "printf(\"\\n\");"
+       displaySet _ _ kind = die $ "Expected a set output, received " ++ show kind
+
+       printHelpers = adtPrintHelpers adts printValue
+
+       printTupleValue _     (KTuple []) = text "printf(\"()\");"
+       printTupleValue value (KTuple fieldKinds)
+         =  text "printf(\"(\");"
+         $$ vcat (intersperse (text "printf(\", \");") (zipWith printField [1 :: Int ..] fieldKinds))
+         $$ text "printf(\")\");"
+        where printField index fieldKind = printValue fieldKind (parens value P.<> text "." P.<> text (tupleFieldName index))
+       printTupleValue _ kind = die $ "Expected a tuple value, received " ++ show kind
+
+       printValue kind value
+         | KTuple{} <- kind                        = printTupleValue value kind
+         | KList{} <- kind                         = listPrint printValue kind value
+         | KSet{} <- kind                          = setPrint printValue kind value
+         | KArray{} <- kind                        = printStoredArray value kind
+         | isADT kind && not (isRoundingMode kind) = adtPrint adts printValue kind value
+         | isWideBV kind                           = wideBVPrint kind value P.<> semi
+         | isFP kind                               = arbitraryFPPrint kind value P.<> semi
+         | isExactGMPKind cfg kind                 = gmpPrint kind value P.<> semi
+         | kind `elem` [KChar, KString]             = textPrint kind value P.<> semi
+         | True                                    = text "printf" P.<> parens (printQuotes (specifierKind cfg kind) P.<> comma <+> value) P.<> semi
+
+       printStoredArray descriptor kind@(KArray keyKind valueKind)
+         =  text "{"
+         $$ nest 2 (   text "if" P.<> parens (descriptor <+> text "== NULL") <+> text "abort" P.<> parens empty P.<> semi
+                    $$ keySetup
+                    $$ text "printf(\"[0] =\");"
+                    $$ printValue valueKind storedValue
+                    $$ keyCleanup
+                   )
+         $$ text "}"
+        where keyName     = "sbv_local_array_stored_key_" ++ kindTag kind
+              key         = text keyName
+              keySetup    = driverValueInit keyKind keyName 0
+              keyCleanup  = driverValueClear keyKind keyName
+              storedValue = text (arrayOutputReadName kind)
+                         P.<> parens (fsep (punctuate comma [text "*" P.<> parens descriptor, key]))
+       printStoredArray _ kind = die $ "Expected a stored array, received " ++ show kind
+
+       driverCleanup = vcat $ inputCleanup ++ outputCleanup ++ returnCleanup
+         where inputCleanup = [ clearInputElement (kindOf sv) n
+                              | (_, n, CgAtomic sv) <- pairedInputs
+                              , inputNeedsInitialization (kindOf sv)
+                              ]
+                           ++ [ clearInputElement (kindOf sv) elementName
+                              | (_, n, CgArray svs) <- pairedInputs
+                              , (index, sv) <- zip [0 :: Int ..] svs
+                              , inputNeedsInitialization (kindOf sv)
+                              , let elementName
+                                      | isExactGMPKind cfg (kindOf sv) = n ++ "[" ++ show index ++ "]"
+                                      | True                          = inputElementName n index
+                              ]
+               clearInputElement (KArray _ valueKind) elementName = driverValueClear valueKind (elementName ++ "_default")
+               clearInputElement kind                elementName = driverValueClear kind elementName
+
+               outputCleanup = concatMap clearOutput outs
+               clearOutput (n, CgAtomic sv) = [outputValueClear (kindOf sv) n]
+               clearOutput (n, CgArray svs) = [outputValueClear (kindOf sv) (n ++ "[" ++ show index ++ "]")
+                                             | (index, sv) <- zip [0 :: Int ..] svs
+                                             ]
+               returnCleanup = [outputValueClear (kindOf sv) "sbv_result" | sv <- maybeToList mbRet]
+
+               -- Public array outputs own an exported descriptor. Collection
+               -- outputs own their elements; driver inputs merely borrow them.
+               outputValueClear kind externalName
+                 | isArray kind                                = text (arrayOutputReleaseName kind) P.<> parens address P.<> semi
+                 | kind == KString || isList kind || isSet kind = managedValueRelease kind address
+                 | True                                        = driverValueClear kind externalName
+                where address = text "&" P.<> text externalName
+
+-- | Generate the C program
+genCProg :: CgConfig
+         -> [Kind]
+         -> [Kind]
+         -> [Kind]
+         -> String
+         -> Doc
+         -> Result
+         -> [(String, CgVal)]
+         -> [(String, CgVal)]
+         -> Maybe SV
+         -> Doc
+         -> ([Doc], Set.Set CRequirement)
+genCProg cfg adts lists sets fn proto
+         (Result pinfo kindInfo _tvals _ovals cgs topInps (_, preConsts) tbls _uis definitions
+                 (SBVPgm asgns) cstrs origAsserts _)
+         inVars outVars mbRet extDecls
+  | not (null usorts)
+  = error $ "SBV->C: Cannot compile functions with uninterpreted sorts: " ++ intercalate ", " usorts
+  | not (null unsupportedSets)
+  = notyet $ "Sets with element kinds " ++ intercalate ", " (map (show . setElementKind) unsupportedSets)
+  | any (requiresExtensionalEquality adts (Equal True) . pure . setElementKind) sets
+  = error "SBV->C: Set elements require general extensional array equality."
+  | or [requiresExtensionalEquality adts (Equal True) [keyKind] | KArray keyKind _ <- arrays]
+  = error "SBV->C: Array keys require general extensional array equality."
+  | any containsNestedSet kindInfo
+  = notyet "Sets nested in arrays or unsupported aggregate types"
+  | not (null unsupportedLists)
+  = notyet $ "Lists with element kinds " ++ intercalate ", " (map (show . listElementKind) unsupportedLists)
+  | any containsNestedList kindInfo
+  = notyet "Lists nested in arrays or unsupported aggregate types"
+  | not $ null (progSpecialRels pinfo)
+  = error "SBV->C: Cannot compile in the presence of special relations."
+  | hasQuants pinfo
+  = error "SBV->C: Cannot compile in the presence of quantified variables."
+  | not (null unstructuredDefinitions)
+  = error $ "SBV->C: Cannot compile SMT-text-only function definitions: " ++ intercalate ", " unstructuredDefinitions
+  | (callbackName, captures) : _ <- capturingArrayLambdas
+  = error $ unlines
+      [ "SBV->C: Array lambdas that capture outer symbolic values are not supported."
+      , "  Callback: " ++ callbackName
+      , "  Captured values: " ++ intercalate ", " [show sv ++ " :: " ++ show (kindOf sv) | sv <- captures]
+      , "Only closed lambdaArray bodies can be compiled: use the index, literal constants, and local computations."
+      , "Support for captured array-lambda environments is deferred; captured values are never approximated or ignored."
+      ]
+  | (functionName, captures) : _ <- capturingFunctions
+  = error $ unlines
+      [ "SBV->C: Defined functions with implicit captures of outer symbolic values are not supported."
+      , "  Function: " ++ functionName
+      , "  Captured values: " ++ intercalate ", " [show sv ++ " :: " ++ show (kindOf sv) | sv <- captures]
+      , "Pass captured values as explicit function arguments, or use Closure with an explicit closureEnv for higher-order operations."
+      ]
+  | not (null softConstraints)
+  = tbd "Soft constraints"
+  | not (null unsupportedConstraintAttributes)
+  = tbd $ "Constraint attributes: " ++ intercalate ", " unsupportedConstraintAttributes
+  | True
+  = ([pre, header, post], requirements)
+ where notyet m = error $ "SBV->C: " ++ m ++ " are currently not supported by the C compiler. Please get in touch if you'd like support for this feature!"
+
+       asserts | cgIgnoreAsserts cfg = []
+               | True                = origAsserts
+
+       usorts = [s | k@(KADT s _ _) <- Set.toList kindInfo, isUninterpreted k]
+
+       pre    =  text "/* File:" <+> doubleQuotes (nm P.<> text ".c") P.<> text ". Automatically generated by SBV. Do not edit! */"
+              $$ text ""
+
+       header = text "#include" <+> doubleQuotes (nm P.<> text ".h")
+             $$ (if requires CRequiresLibBF then text "#include <libbf.h>" else empty)
+
+       wideKinds        = wideBVKinds kindInfo
+       fpKinds          = arbitraryFPKinds kindInfo
+       arrays           = arrayKinds kindInfo
+       unsupportedLists = filter (not . listSupported cfg) lists
+       unsupportedSets  = filter (not . setSupported cfg) sets
+       post   = text ""
+             $$ (if any (cFloatingKind cfg) kindInfo then nativeFPCompilePragmas else empty)
+             $$ vcat (map codeSeg cgs)
+             $$ extDecls
+             $$ mappedRealFloorRuntime cfg allAssignments
+             $$ bitVectorRuntime (cgInteger cfg) wideKinds allAssignments
+             $$ (if requires CRequiresGMP    then gmpRuntime cfg kindInfo allAssignments else empty)
+             $$ (if requires CRequiresLibBF  then arbitraryFPRuntime cfg fpKinds allAssignments else empty)
+             $$ (if requires CRequiresNativeFPRounding then nativeFPRuntime else empty)
+             $$ (if requires CRequiresIntegerPower     then mappedIntegerPowerRuntime cfg else empty)
+             $$ (if requires CRequiresText             then textRuntime cfg usesExactInteger else empty)
+             $$ adtEqualityRuntimeDecls adts
+             $$ (if requires CRequiresLists            then listRuntimeDecls cfg lists else empty)
+             $$ (if requires CRequiresSets             then setRuntimeDecls cfg sets else empty)
+             $$ (if requires CRequiresLists            then listRuntime cfg usesExactInteger lists else empty)
+             $$ (if requires CRequiresSets             then setRuntime cfg (map snd . adtConstructors adts . resolveADTReferences adts) sets else empty)
+             $$ (if requires CRequiresArrays           then arrayRuntime cfg arrays else empty)
+             $$ adtEqualityRuntime cfg adts
+             $$ vcat [ppArrayEquality cfg adts kind | kind <- equalityArrayKinds]
+             $$ definedFunctionResultRuntime functionResultKinds
+             $$ (if hasStructuredCallbacks then definedFunctionContextType requirements else empty)
+             $$ vcat functionPrototypes
+             $$ vcat arrayLambdaPrototypes
+             $$ vcat functionDocs
+             $$ vcat arrayLambdaDocs
+             $$ proto
+             $$ text "{"
+             $$ text ""
+             $$ nest 2 (   gmpStart
+                        $$ textStart
+                        $$ listStart
+                        $$ setStart
+                        $$ arrayStart
+                        $$ functionResultStart
+                        $$ functionContextStart
+                        $$ vcat (concatMap (genIO True . (\v -> (isAlive v, v))) inVars)
+                        $$ constantDeclarations
+                        $$ scheduledAssignments
+                        $$ sepIf (not (null assignments) || not (null tbls))
+                        $$ vcat (concatMap (genIO False . (True,)) outVars)
+                        $$ exactReturn
+                        $$ arrayReturn
+                        $$ ownedTupleReturn
+                        $$ exactADTReturn
+                        $$ textReturn
+                        $$ listReturn
+                        $$ setReturn
+                        $$ functionResultEnd
+                        $$ arrayEnd
+                        $$ setEnd
+                        $$ listEnd
+                        $$ textEnd
+                        $$ gmpEnd
+                        $$ normalReturn
+                       )
+             $$ text "}"
+             $$ text ""
+
+       nm = text fn
+
+       assignments = F.toList asgns
+
+       constraints = F.toList cstrs
+
+       softConstraints = [() | (True, _, _) <- constraints]
+
+       unsupportedConstraintAttributes = nub [attribute
+                                              | (_, attributes, _) <- constraints
+                                              , (attribute, _) <- attributes
+                                              , attribute /= ":named"
+                                              ]
+
+       runtimeChecks = sortOn (cLocation allConsts . fst)
+                    $ [(sv, snd (genAssert assertion)) | assertion@(_, _, sv) <- asserts]
+                   ++ [(sv, snd (genConstraint constraint)) | constraint@(_, _, sv) <- constraints]
+
+       functionNames = [(T.pack functionName, CTypes.definedFunctionCName functionName) | (functionName, _) <- definitions]
+
+       structuredDefinitions = [ (functionName, resultKind, dependencies, functionType, lambdaInfo)
+                               | (functionName, (definition@(SMTDef resultKind dependencies _ _), functionType)) <- definitions
+                               , Just lambdaInfo <- [smtDefInfo definition]
+                               ]
+
+       unstructuredDefinitions = [ functionName
+                                 | (functionName, (definition, _)) <- definitions
+                                 , Nothing <- [smtDefInfo definition]
+                                 ]
+
+       topLevelArrayLambdaDefinitions = [ (arrayLambdaName sv, sv, lambdaInfo)
+                                        | (sv, SBVApp (ArrayInit (Right lambdaDef)) []) <- assignments
+                                        , Just lambdaInfo <- [smtLambdaInfo lambdaDef]
+                                        ]
+
+       topLevelArrayLambdaNames = [(sv, callbackName) | (callbackName, sv, _) <- topLevelArrayLambdaDefinitions]
+
+       arrayLambdaDefinitions =
+            topLevelArrayLambdaDefinitions
+         ++ concat [nestedArrayLambdaDefinitions callbackName lambdaInfo
+                   | (callbackName, _, lambdaInfo) <- topLevelArrayLambdaDefinitions
+                   ]
+         ++ concat [nestedArrayLambdaDefinitions (CTypes.definedFunctionCName functionName) lambdaInfo
+                   | (functionName, _, _, _, lambdaInfo) <- structuredDefinitions
+                   ]
+
+       nestedArrayLambdaDefinitions scope LambdaInfo{liAssignments = nestedAssignments}
+         = concat [ (callbackName, sv, lambdaInfo) : nestedArrayLambdaDefinitions callbackName lambdaInfo
+                  | (sv, SBVApp (ArrayInit (Right lambdaDef)) []) <- F.toList nestedAssignments
+                  , let callbackName = scopedArrayLambdaName scope sv
+                  , Just lambdaInfo <- [smtLambdaInfo lambdaDef]
+                  ]
+
+       functionAssignments    = concatMap (\(_, _, _, _, lambdaInfo) -> F.toList (liAssignments lambdaInfo)) structuredDefinitions
+       arrayLambdaAssignments = concatMap (\(_, _, lambdaInfo) -> F.toList (liAssignments lambdaInfo)) arrayLambdaDefinitions
+       lambdaAssignments      = functionAssignments ++ arrayLambdaAssignments
+       allAssignments         = assignments ++ lambdaAssignments
+       capturingArrayLambdas  = [ (callbackName, captures)
+                               | (callbackName, _, lambdaInfo) <- arrayLambdaDefinitions
+                               , let captures = cLambdaFreeValues lambdaInfo
+                               , not (null captures)
+                               ]
+       capturingFunctions     = [ (functionName, captures)
+                               | (functionName, _, _, _, lambdaInfo) <- structuredDefinitions
+                               , let captures = cLambdaFreeValues lambdaInfo
+                               , not (null captures)
+                               ]
+       equalityArrayKinds     = uniqueOn arrayEqualName
+                                    [kindOf value | (_, SBVApp op (value:_)) <- allAssignments
+                                                , op `elem` [Equal False, Equal True, NotEqual]
+                                                , isArray value]
+
+       functionPrototypes  = [ definedFunctionSignature functionName resultKind (liParams lambdaInfo) P.<> semi
+                             | (functionName, resultKind, _, _, lambdaInfo) <- structuredDefinitions
+                             ]
+
+       generatedFunctions =
+         [ ppDefinedFunction cfg adts functionNames functionName resultKind functionType lambdaInfo
+         | (functionName, resultKind, _, functionType, lambdaInfo) <- structuredDefinitions
+         ]
+       functionDocs        = map fst generatedFunctions
+
+       functionResultKinds = nub $
+            [ resultKind
+            | (_, resultKind, _, _, _) <- structuredDefinitions
+            , definedFunctionResultNeedsClone cfg adts resultKind
+            ]
+         ++ [ kindOf (liOutput lambdaInfo)
+            | (_, _, lambdaInfo) <- arrayLambdaDefinitions
+            , definedFunctionResultNeedsClone cfg adts (kindOf (liOutput lambdaInfo))
+            ]
+
+       generatedArrayLambdas = [ppArrayLambda cfg adts functionNames callbackName sv lambdaInfo
+                               | (callbackName, sv, lambdaInfo) <- arrayLambdaDefinitions
+                               ]
+       arrayLambdaPrototypes  = [arrayLambdaSignature callbackName sv lambdaInfo P.<> semi
+                                | (callbackName, sv, lambdaInfo) <- arrayLambdaDefinitions
+                                ]
+       arrayLambdaDocs        = map fst generatedArrayLambdas
+
+       (scheduledAssignments, scheduledRequirements) =
+         scheduleC env functionNames topLevelArrayLambdaNames
+                   (map fst allConsts ++ concatMap (cgValues . snd) inVars) assignments tbls True typeWidth
+                   evaluationRoots
+
+       evaluationRoots = runtimeChecks ++ [(sv, empty) | sv <- concatMap (cgValues . snd) outVars ++ maybe [] pure mbRet]
+
+       cgValues (CgAtomic sv) = [sv]
+       cgValues (CgArray svs) = svs
+
+       requirements = Set.unions
+         [ kindRequirements
+         , scheduledRequirements
+         , Set.unions (map snd generatedFunctions)
+         , Set.unions (map snd generatedArrayLambdas)
+         , Set.unions [operationRequirements cfg (op, kindOf sv) | (sv, SBVApp op _) <- assignments]
+         ]
+
+       kindRequirements = Set.fromList $
+            [CRequiresWideBV | not (null wideKinds)]
+         ++ [CRequiresLibBF  | not (null fpKinds)]
+         ++ [CRequiresLibM   | not (null fpKinds)]
+         ++ [CRequiresGMP    | usesGMP]
+         ++ [CRequiresText   | KString `Set.member` kindInfo || KChar `Set.member` kindInfo]
+         ++ [CRequiresLists  | not (null lists)]
+         ++ [CRequiresSets   | not (null sets)]
+         ++ [CRequiresArrays | not (null arrays)]
+
+       requires requirement = requirement `Set.member` requirements
+
+       usesGMP          = any (isExactGMPKind cfg) kindInfo
+       usesExactInteger = isExactGMPKind cfg KUnbounded && KUnbounded `Set.member` kindInfo
+
+       containsNestedList = containsUnsupportedCollection isList
+
+       containsNestedSet = containsUnsupportedCollection isSet
+
+       containsUnsupportedCollection isCollection = walk Set.empty
+        where walk _ kind
+                | isCollection kind
+                = False
+              walk visited (KTuple fields)
+                = any (walk visited) fields
+              walk visited (KList elementKind)
+                = walk visited elementKind
+              walk visited (KSet elementKind)
+                = walk visited elementKind
+              walk visited (KArray keyKind valueKind)
+                = walk visited keyKind || walk visited valueKind
+              walk visited kind
+                | isADT kind
+                , not (isRoundingMode kind)
+                , not (isUninterpreted kind)
+                =    not (kind `Set.member` visited)
+                  && any (any (walk (Set.insert kind visited)) . snd) (adtConstructors adts kind)
+              walk _ kind
+                = any isCollection (expandKinds kind)
+
+       listElementKind (KList elementKind) = elementKind
+       listElementKind kind                = die $ "Expected a list kind, received " ++ show kind
+
+       setElementKind (KSet elementKind) = elementKind
+       setElementKind kind               = die $ "Expected a set kind, received " ++ show kind
+
+       gmpStart
+         | requires CRequiresGMP = gmpContextStart
+         | True                     = empty
+       gmpEnd
+         | requires CRequiresGMP = gmpContextEnd
+         | True                     = empty
+
+       textStart
+         | requires CRequiresText = textContextStart
+         | True                    = empty
+       textEnd
+         | requires CRequiresText = textContextEnd
+         | True                    = empty
+
+       listStart
+         | requires CRequiresLists = listContextStart
+         | True                    = empty
+       listEnd
+         | requires CRequiresLists = listContextEnd
+         | True                    = empty
+
+       setStart
+         | requires CRequiresSets = setContextStart
+         | True                   = empty
+       setEnd
+         | requires CRequiresSets = setContextEnd
+         | True                   = empty
+
+       arrayStart
+         | requires CRequiresArrays = arrayContextStart
+         | True                     = empty
+
+       arrayEnd
+         | requires CRequiresArrays = arrayContextEnd
+         | True                     = empty
+
+       functionContextStart
+         | hasStructuredCallbacks = definedFunctionContextInitialization requirements
+         | True                   = empty
+
+       hasStructuredCallbacks = not (null structuredDefinitions && null arrayLambdaDefinitions)
+
+       functionResultStart
+         | requires CRequiresFunctionResults = text "sbv_function_result_ctx sbv_local_function_result_ctx = {NULL};"
+         | True                               = empty
+
+       functionResultEnd
+         | requires CRequiresFunctionResults = text "sbv_function_result_ctx_end(&sbv_local_function_result_ctx);"
+         | True                               = empty
+
+       exactReturn = case mbRet of
+                       Just sv | isExactGMPKind cfg (kindOf sv)
+                               -> gmpSet (kindOf sv) (text "sbv_result") (showSV env sv) P.<> semi
+                       _       -> empty
+
+       arrayReturn = case mbRet of
+                       Just sv | isArray sv
+                               -> text "const" <+> text (arrayOutputCType (kindOf sv)) <+> text "sbv_result" <+> text "="
+                                  <+> text (arrayExportName (kindOf sv)) P.<> parens (showSV env sv) P.<> semi
+                       _       -> empty
+
+       ownedTupleReturn = case mbRet of
+                            Just sv
+                              | tupleNeedsOwnership cfg (kindOf sv)
+                              -> text "const" <+> text (tupleCType (kindOf sv)) <+> text "sbv_result" <+> text "="
+                                 <+> text (tupleOwnedCloneName (kindOf sv)) P.<> parens (showSV env sv) P.<> semi
+                            _ -> empty
+
+       exactADTReturn = case mbRet of
+                          Just sv
+                            | isOwnedADT cfg adts sv
+                            -> text "const" <+> text (adtCType (kindOf sv)) <+> text "sbv_result" <+> text "="
+                           <+> text (adtOwnedCloneName (kindOf sv))
+                                 P.<> parens (showSV env sv)
+                                 P.<> semi
+                          _ -> empty
+
+       textReturn = case mbRet of
+                      Just sv | kindOf sv == KString
+                              -> text "const SString sbv_result =" <+> textClone (showSV env sv) P.<> semi
+                      _       -> empty
+
+       listReturn = case mbRet of
+                      Just sv | isList sv
+                              -> text "const" <+> text (listCType (kindOf sv)) <+> text "sbv_result ="
+                              <+> listClone (kindOf sv) (showSV env sv) P.<> semi
+                      _       -> empty
+
+       setReturn = case mbRet of
+                     Just sv | isSet sv
+                             -> text "const" <+> text (setCType (kindOf sv)) <+> text "sbv_result ="
+                             <+> setClone (kindOf sv) (showSV env sv) P.<> semi
+                     _       -> empty
+
+       normalReturn = case mbRet of
+                        Just sv | isArray sv                           -> text "return sbv_result;"
+                        Just sv | tupleNeedsOwnership cfg (kindOf sv) -> text "return sbv_result;"
+                        Just sv | isOwnedADT cfg adts sv               -> text "return sbv_result;"
+                        Just sv | kindOf sv == KString                 -> text "return sbv_result;"
+                        Just sv | isList sv                            -> text "return sbv_result;"
+                        Just sv | isSet sv                             -> text "return sbv_result;"
+                        Just sv | not (isExactGMPKind cfg (kindOf sv)) -> mkRet sv
+                        _                                             -> empty
+
+       codeSeg (fnm, ls) =  text "/* User specified custom code for" <+> doubleQuotes (text fnm) <+> text "*/"
+                         $$ vcat (map text ls)
+                         $$ text ""
+
+       ins = case topInps of
+               ResultTopInps (is, []) -> is
+               ResultTopInps is       -> die $ "Unexpected trackers: " ++ show is
+               ResultLamInps is       -> die $ "Unexpected inputs  : " ++ show is
+
+       typeWidth = getMax 0 $ [len (kindOf s) | (s, _) <- assignments] ++ [len (kindOf s) | NamedSymVar s _ <- ins]
+                where len (KVar s)           = die $ "Variable: " ++ s
+                      len KReal{}            = 5
+                      len KFloat{}           = 6 -- SFloat
+                      len KDouble{}          = 7 -- SDouble
+                      len KString{}          = 7 -- SString
+                      len KChar{}            = 5 -- SChar
+                      len k@KList{}          = length (listCType k)
+                      len k@KSet{}           = length (setCType k)
+                      len KUnbounded{}       = 8
+                      len KBool              = 5 -- SBool
+                      len (KBounded False n) = 5 + length (show n) -- SWordN
+                      len (KBounded True  n) = 4 + length (show n) -- SIntN
+                      len KRational{}        = length "SRational"
+                      len (KFP eb sb)         = 6 + length (show eb) + length (show sb)
+                      len k@KArray{}         = length (arrayCType k)
+                      len k@KTuple{}         = length (tupleCType k)
+                      len (KApp s _)         = die $ "Uninterpreted ADT app: " ++ s
+                      len k@(KADT s _ _)
+                        | isRoundingMode k = length (show k)
+                        | isUninterpreted k = die $ "Uninterpreted ADT: " ++ s
+                        | True             = length (adtCType k)
+
+                      getMax m []     = m
+                      getMax m (x:xs) = getMax (m `max` x) xs
+
+       allConsts = (falseSV, falseCV) : (trueSV, trueCV) : preConsts
+       (constantDeclarations, consts) = stabilizeCConstants cfg adts typeWidth (filter ((`Set.member` usedVariables) . fst) allConsts)
+       env = CRenderEnv cfg adts consts
+
+       usedVariables = cReachableValues cfg (Map.fromList assignments) tbls (map fst evaluationRoots)
+
+       isAlive :: (String, CgVal) -> Bool
+       isAlive (_, CgAtomic sv) = sv `Set.member` usedVariables
+       isAlive (_, _)           = True
+
+       genIO :: Bool -> (Bool, (String, CgVal)) -> [Doc]
+       genIO True  (alive, (cNm, CgAtomic sv))
+         | isArray sv = [statement | alive, statement <- arrayInputSetup typeWidth sv cNm]
+         | isSet sv   = [declSV typeWidth sv <+> text "=" <+> setNormalize (kindOf sv) (text cNm) P.<> semi | alive]
+         | True       = [declSV typeWidth sv <+> text "=" <+> inputValue cNm sv P.<> semi | alive]
+       genIO False (alive, (cNm, CgAtomic sv))
+         | isArray sv                          = [text "*" P.<> text cNm <+> text "=" <+> text (arrayExportName (kindOf sv)) P.<> parens (showSV env sv) P.<> semi | alive]
+         | isExactGMPKind cfg (kindOf sv)      = [gmpSet (kindOf sv) (text cNm) (showSV env sv) P.<> semi | alive]
+         | kindOf sv == KString                = [text "*" P.<> text cNm <+> text "=" <+> textClone (showSV env sv) P.<> semi | alive]
+         | isList sv                           = [text "*" P.<> text cNm <+> text "=" <+> listClone (kindOf sv) (showSV env sv) P.<> semi | alive]
+         | isSet sv                            = [text "*" P.<> text cNm <+> text "=" <+> setClone (kindOf sv) (showSV env sv) P.<> semi | alive]
+         | tupleNeedsOwnership cfg (kindOf sv) = [text "*" P.<> text cNm <+> text "=" <+> text (tupleOwnedCloneName (kindOf sv)) P.<> parens (showSV env sv) P.<> semi | alive]
+         | isOwnedADT cfg adts sv              = [ text "*" P.<> text cNm <+> text "="
+                                               <+> text (adtOwnedCloneName (kindOf sv))
+                                                     P.<> parens (showSV env sv)
+                                                     P.<> semi
+                                                 | alive
+                                                 ]
+         | True                                = [text "*" P.<> text cNm <+> text "=" <+> showSV env sv P.<> semi | alive]
+       genIO isInp (_,     (cNm, CgArray sws)) = zipWith genElt sws [(0::Int)..]
+         where genElt sv i
+                 | isInp                         = vcat (genIO True (sv `Set.member` usedVariables, (entry, CgAtomic sv)))
+                 | isExactGMPKind cfg kind      = gmpSet kind (text entry) value P.<> semi
+                 | isArray kind                 = text entry <+> text "=" <+> text (arrayExportName kind) P.<> parens value P.<> semi
+                 | kind == KString              = text entry <+> text "=" <+> textClone value P.<> semi
+                 | isList kind                  = text entry <+> text "=" <+> listClone kind value P.<> semi
+                 | isSet kind                   = text entry <+> text "=" <+> setClone kind value P.<> semi
+                 | tupleNeedsOwnership cfg kind = text entry <+> text "=" <+> text (tupleOwnedCloneName kind) P.<> parens value P.<> semi
+                 | isOwnedADT cfg adts sv        = text entry <+> text "=" <+> text (adtOwnedCloneName kind) P.<> parens value P.<> semi
+                 | True                         = text entry <+> text "=" <+> value P.<> semi
+                 where entry = cNm ++ "[" ++ show i ++ "]"
+                       kind  = kindOf sv
+                       value = showSV env sv
+
+       inputValue cNm sv
+         | isWideBV k = wideBVNormalize k (text cNm)
+         | isFP k      = arbitraryFPNormalize k (text cNm)
+         | True        = text cNm
+         where k = kindOf sv
+
+       mkRet sv = text "return" <+> showSV env sv P.<> semi
+
+       genAssert (msg, cs, sv) = (cLocation consts sv, doc)
+         where doc =     text "/* ASSERTION:" <+> cCommentText msg
+                     $$  maybe empty (vcat . map cCommentText) (locInfo (getCallStack <$> cs))
+                     $$  text " */"
+                     $$  text "if" P.<> parens (showSV env sv)
+                     $$  text "{"
+                     $+$ nest 2 (vcat [errOut, text "exit(-1);"])
+                     $$  text "}"
+                     $$  text ""
+               errOut = text "fprintf" P.<> parens (fsep (punctuate comma [ text "stderr"
+                                                                          , cStringLiteral "%s:%d:ASSERTION FAILED: %s\n"
+                                                                          , text "__FILE__"
+                                                                          , text "__LINE__"
+                                                                          , cStringLiteral msg
+                                                                          ])) P.<> semi
+               locInfo (Just ps) = let loc (f, sl) = concat [srcLocFile sl, ":", show (srcLocStartLine sl), ":", show (srcLocStartCol sl), ":", f ]
+                                   in case map loc ps of
+                                         []     -> Nothing
+                                         (f:rs) -> Just $ (" * SOURCE   : " ++ f) : map (" *            " ++)  rs
+               locInfo _         = Nothing
+
+       genConstraint (_, attributes, sv) = (cLocation consts sv, doc)
+         where doc =  text "/* CONSTRAINT */"
+                   $$ text "if" P.<> parens (text "!" P.<> parens (showSV env sv))
+                   $$ text "{"
+                   $+$ nest 2 (vcat [errOut, text "exit(-1);"])
+                   $$ text "}"
+                   $$ text ""
+
+               description = fromMaybe "unnamed" (lookup ":named" attributes)
+
+               errOut = text "fprintf" P.<> parens (fsep (punctuate comma [ text "stderr"
+                                                                          , cStringLiteral "%s:%d:CONSTRAINT FAILED: %s\n"
+                                                                          , text "__FILE__"
+                                                                          , text "__LINE__"
+                                                                          , cStringLiteral description
+                                                                          ])) P.<> semi
+
+-- | Return the source-order location used to interleave a value's dependent
+-- declarations. Constants are available before every generated assignment.
+cLocation :: [(SV, CV)] -> SV -> Int
+cLocation constants sv@(SV _ (NodeId (_, _, nodeIndex)))
+  | isJust (lookup sv constants) = -1
+  | True                         = nodeIndex
+
+-- | Render one finite lookup table at the point where all its elements are
+-- available. Constant top-level tables may use static storage; lambda-local
+-- tables always use automatic storage so their entries may depend on parameters.
+ppTable :: CRenderEnv -> Bool -> ((Int, Kind, Kind), [SV]) -> (Int, Doc)
+ppTable env allowStatic ((tableIndex, _, resultKind), elements)
+  = (location, storage <+> text tableElementType <+> tableName P.<> text "[] = {"
+              $$ nest 4 (fsep (punctuate comma (align (map renderElement elements))))
+              $$ text "};")
+ where cfg = renderConfig env
+       location = maximum (-1 : map (cLocation (renderConstants env)) elements)
+       renderElement element = arrayStoredValue resultKind (showSV env element)
+       tableElementType
+         | isArray resultKind = CTypes.constElementCType resultKind
+         | True               = "const " ++ showCType resultKind
+       storage
+         | allowStatic && location == -1 && not (tableMustBeLocal cfg resultKind) = text "static"
+         | True                                                                  = empty
+       tableName = text ("table" ++ show tableIndex)
+
+-- | Declare the private ownership-arena bundle threaded through generated SBV
+-- functions and retained array callbacks. The retain bridge creates empty
+-- arenas so an escaping lambda can produce fresh managed values without
+-- retaining storage owned by the call that created it.
+-- Define its unused-function annotation even when no other runtime is needed.
+definedFunctionContextType :: Set.Set CRequirement -> Doc
+definedFunctionContextType requirements = text . unlines $
+     [ cUnusedAttribute
+     , ""
+     , "typedef struct {"
+     ]
+  ++ ["  void *" ++ fieldName ++ ";" | (_, _, fieldName) <- functionContextFields]
+  ++ [ "} sbv_function_ctx;"
+     , ""
+     , "static SBV_CGEN_UNUSED const void *sbv_function_ctx_retain_empty(const void *context)"
+     , "{"
+     , "  if (context == NULL) abort();"
+     , "  const sbv_function_ctx *source = (const sbv_function_ctx *) context;"
+     , "  (void) source;"
+     , "  sbv_function_ctx *owned = (sbv_function_ctx *) calloc(1, sizeof *owned);"
+     , "  if (owned == NULL) abort();"
+     ]
+  ++ concatMap retainArena activeArenas
+  ++ [ "  return owned;"
+     , "}"
+     , ""
+     , "static SBV_CGEN_UNUSED void sbv_function_ctx_release_owned(const void *context)"
+     , "{"
+     , "  sbv_function_ctx *owned = (sbv_function_ctx *) context;"
+     , "  if (owned == NULL) return;"
+     ]
+  ++ concatMap releaseArena activeArenas
+  ++ [ "  free(owned);"
+     , "}"
+     , ""
+     ]
+ where activeArenas = [ arena
+                      | arena@(requirement, _, _, _) <- contextArenas
+                      , requirement `Set.member` requirements
+                      ]
+
+       contextArenas = [ (requirement, fieldName, contextType, contextType ++ "_end")
+                       | (requirement, contextType, fieldName) <- functionContextFields
+                       ]
+
+       retainArena (_, fieldName, contextType, _) =
+         [ "  if (source->" ++ fieldName ++ " != NULL) {"
+         , "    " ++ contextType ++ " *arena = (" ++ contextType ++ " *) calloc(1, sizeof *arena);"
+         , "    if (arena == NULL) abort();"
+         , "    owned->" ++ fieldName ++ " = arena;"
+         , "  }"
+         ]
+
+       releaseArena (_, fieldName, contextType, contextEnd) =
+         [ "  if (owned->" ++ fieldName ++ " != NULL) {"
+         , "    " ++ contextEnd ++ "((" ++ contextType ++ " *) owned->" ++ fieldName ++ ");"
+         , "    free(owned->" ++ fieldName ++ ");"
+         , "  }"
+         ]
+
+-- | Initialize a private function-context bundle from the ownership arenas
+-- available in the surrounding generated function.
+definedFunctionContextInitialization :: Set.Set CRequirement -> Doc
+definedFunctionContextInitialization requirements
+  = text "sbv_function_ctx sbv_local_function_ctx =" <+> braces (fsep (punctuate comma fields)) P.<> semi
+ where fields = [ field requirement fieldName ("sbv_local_" ++ fieldName ++ "_ctx")
+                | (requirement, _, fieldName) <- functionContextFields
+                ]
+
+       field requirement fieldName contextName
+         = text ("." ++ fieldName ++ " =") <+> if requirement `Set.member` requirements
+                                                   then text ("&" ++ contextName)
+                                                   else text "NULL"
+
+-- | Test whether a private function result needs a stable deep copy because
+-- its by-value representation contains independently owned aggregate storage.
+definedFunctionResultNeedsClone :: CgConfig -> [Kind] -> Kind -> Bool
+definedFunctionResultNeedsClone cfg adts kind
+  | kind == KString        = True
+  | isList kind            = True
+  | isSet kind             = True
+  | KTuple{} <- kind       = tupleNeedsOwnership cfg kind
+  | isConcreteADTReference kind = adtNeedsOwnership cfg adts kind
+  | True                   = False
+
+-- | Shared ownership-context fields: requirement, C arena type, and field
+-- name. Private functions and array callbacks must bind the same arenas.
+functionContextFields :: [(CRequirement, String, String)]
+functionContextFields =
+  [ (CRequiresGMP, "sbv_gmp_ctx", "gmp")
+  , (CRequiresText, "sbv_text_ctx", "text")
+  , (CRequiresLists, "sbv_list_ctx", "list")
+  , (CRequiresSets, "sbv_set_ctx", "set")
+  , (CRequiresArrays, "sbv_array_ctx", "array")
+  , (CRequiresFunctionResults, "sbv_function_result_ctx", "function_result")
+  ]
+
+-- | Borrow required parent arenas and bind a local function context to them.
+functionContextSetup :: Set.Set CRequirement -> Doc
+functionContextSetup requirements
+  = vcat [ text contextType <+> text ("*sbv_local_parent_" ++ fieldName ++ "_ctx = (" ++ contextType ++ " *) sbv_local_parent_function_ctx->" ++ fieldName ++ ";")
+        $$ text contextType <+> text ("sbv_local_" ++ fieldName ++ "_ctx = *sbv_local_parent_" ++ fieldName ++ "_ctx;")
+         | (requirement, contextType, fieldName) <- functionContextFields, requirement `Set.member` requirements
+         ]
+ $$ text "sbv_function_ctx sbv_local_function_ctx = *sbv_local_parent_function_ctx; (void) sbv_local_function_ctx;"
+ $$ vcat [text ("sbv_local_function_ctx." ++ fieldName ++ " = &sbv_local_" ++ fieldName ++ "_ctx;")
+         | (requirement, _, fieldName) <- functionContextFields, requirement `Set.member` requirements
+         ]
+
+-- | Publish arena allocations back to the parent before returning a result.
+functionContextCommit :: Set.Set CRequirement -> Doc
+functionContextCommit requirements
+  = vcat [text ("*sbv_local_parent_" ++ fieldName ++ "_ctx = sbv_local_" ++ fieldName ++ "_ctx;")
+         | (requirement, _, fieldName) <- functionContextFields, requirement `Set.member` requirements
+         ]
+
+-- | Return the generated helper name that clones one private managed result
+-- into the shared function-result arena.
+definedFunctionResultCloneName :: Kind -> String
+definedFunctionResultCloneName kind = "sbv_function_result_clone_" ++ CTypes.kindTag kind
+
+-- | Render a deep clone into the shared private function-result arena.
+definedFunctionResultClone :: Kind -> Doc -> Doc
+definedFunctionResultClone kind value
+  = text (definedFunctionResultCloneName kind)
+      P.<> parens (fsep (punctuate comma [text "&sbv_local_function_result_ctx", value]))
+
+-- | Emit temporary ownership storage for managed values returned by private
+-- generated functions or retained array callbacks. Public boundaries clone
+-- these values once more before this arena is released.
+definedFunctionResultRuntime :: [Kind] -> Doc
+definedFunctionResultRuntime []    = empty
+definedFunctionResultRuntime kinds = text . unlines $
+     [ "/* Stable storage for managed private-function and array-lambda results. */"
+     , "typedef void (*sbv_function_result_release)(void *);"
+     , "typedef struct sbv_function_result_node {"
+     , "  struct sbv_function_result_node *next;"
+     , "  void *value;"
+     , "  sbv_function_result_release release;"
+     , "} sbv_function_result_node;"
+     , "typedef struct { sbv_function_result_node *head; } sbv_function_result_ctx;"
+     , ""
+     , "static SBV_CGEN_UNUSED void sbv_function_result_ctx_remember(sbv_function_result_ctx *ctx, void *value, sbv_function_result_release release)"
+     , "{"
+     , "  sbv_function_result_node *node = (sbv_function_result_node *) malloc(sizeof(*node));"
+     , "  if (ctx == NULL || value == NULL || release == NULL || node == NULL) abort();"
+     , "  node->next = ctx->head;"
+     , "  node->value = value;"
+     , "  node->release = release;"
+     , "  ctx->head = node;"
+     , "}"
+     , ""
+     , "static SBV_CGEN_UNUSED void sbv_function_result_ctx_end(sbv_function_result_ctx *ctx)"
+     , "{"
+     , "  while (ctx->head != NULL) {"
+     , "    sbv_function_result_node *node = ctx->head;"
+     , "    ctx->head = node->next;"
+     , "    node->release(node->value);"
+     , "    free(node);"
+     , "  }"
+     , "}"
+     , ""
+     ]
+  ++ concatMap helpers kinds
+ where helpers kind =
+         [ "static SBV_CGEN_UNUSED void " ++ releaseName ++ "(void *opaque)"
+         , "{"
+         , "  " ++ cType ++ " *value = (" ++ cType ++ " *) opaque;"
+         , "  " ++ render (managedValueRelease kind (text "value"))
+         , "  free(value);"
+         , "}"
+         , ""
+         , "static SBV_CGEN_UNUSED " ++ cType ++ " " ++ cloneName ++ "(sbv_function_result_ctx *ctx, " ++ cType ++ " value)"
+         , "{"
+         , "  " ++ cType ++ " *result = (" ++ cType ++ " *) malloc(sizeof(*result));"
+         , "  if (result == NULL) abort();"
+         , "  *result = " ++ render (managedValueClone kind (text "value")) ++ ";"
+         , "  sbv_function_result_ctx_remember(ctx, result, " ++ releaseName ++ ");"
+         , "  return *result;"
+         , "}"
+         , ""
+         ]
+        where cType       = showCType kind
+              cloneName   = definedFunctionResultCloneName kind
+              releaseName = "sbv_function_result_release_" ++ CTypes.kindTag kind
+
+-- | Render the private C signature shared by a defined function's prototype
+-- and implementation.
+definedFunctionSignature :: String -> Kind -> [(Quantifier, SV)] -> Doc
+definedFunctionSignature originalName resultKind parameters
+  = text "static" <+> text resultType <+> text (CTypes.definedFunctionCName originalName)
+      P.<> parens renderedParameters
+ where resultType
+         | isArray resultKind = CTypes.elementCType resultKind
+         | True               = showCType resultKind
+
+       renderedParameters = fsep . punctuate comma $
+           text "sbv_function_ctx *const sbv_local_parent_function_ctx"
+         : [text "const" <+> text (showCType parameter) <+> text (show parameter) | (_, parameter) <- parameters]
+
+-- | Lower one first-order SBV function definition from its retained expression
+-- DAG. All definitions use demand-driven control flow so operations protected
+-- by conditionals and short-circuiting Boolean operations remain protected in
+-- C, including partial ADT selectors in acyclic functions. Closed nested array
+-- lambdas are lambda-lifted into private callbacks;
+-- SBV's firstified higher-order specializations arrive through the same
+-- first-order representation.
+ppDefinedFunction :: CgConfig
+                  -> [Kind]
+                  -> [(T.Text, String)]
+                  -> String
+                  -> Kind
+                  -> SBVType
+                  -> LambdaInfo
+                  -> (Doc, Set.Set CRequirement)
+ppDefinedFunction cfg adts functionNames originalName declaredResultKind (SBVType signatureKinds)
+                  LambdaInfo{ liAssignments = functionProgram
+                            , liParams      = parameters
+                            , liOutput      = functionOutput
+                            , liConsts      = constants
+                            , liTables      = tables
+                            }
+  | null signatureKinds
+  = die $ "Empty type for defined function " ++ show originalName
+  | declaredResultKind /= resultKind
+  = die $ "Result-kind mismatch in defined function " ++ show originalName
+  | map (kindOf . snd) parameters /= parameterKinds
+  = die $ "Parameter-kind mismatch in defined function " ++ show originalName
+  | any ((/= ALL) . fst) parameters
+  = die $ "Non-universal parameter in defined function " ++ show originalName
+  | kindOf functionOutput /= resultKind
+  = die $ "Output-kind mismatch in defined function " ++ show originalName
+  | not (null unsupportedManagedKinds)
+  = tbd $ "Managed values in defined function " ++ show originalName ++ ": " ++ intercalate ", " (map show unsupportedManagedKinds)
+  | True
+  = (functionDoc, functionRequirements)
+ where (parameterKinds, resultKind) = (init signatureKinds, last signatureKinds)
+       assignments                  = F.toList functionProgram
+       functionConsts               = (falseSV, falseCV) : (trueSV, trueCV) : constants
+       reachableValues              = cReachableValues cfg (Map.fromList assignments) tables [functionOutput]
+       (constantDeclarations, renderingConsts) = stabilizeCConstants cfg adts typeWidth (filter ((`Set.member` reachableValues) . fst) functionConsts)
+       env = CRenderEnv cfg adts renderingConsts
+       functionValues               = functionOutput : map snd parameters ++ map fst assignments ++ map fst constants
+       typeWidth                    = maximum (0 : map (length . showCType) functionValues)
+       nestedLambdaNames            = [ (sv, scopedArrayLambdaName (CTypes.definedFunctionCName originalName) sv)
+                                      | (sv, SBVApp (ArrayInit (Right _)) _) <- assignments
+                                      ]
+       unsupportedManagedKinds      = nub [ kind
+                                          | value <- functionValues
+                                          , let kind = kindOf value
+                                          , functionValueHasUnsupportedManagedStorage kind
+                                          ]
+
+       functionValueHasUnsupportedManagedStorage kind
+         | isExactGMPKind cfg kind = False
+         | kind == KString         = False
+         | isList kind             = False
+         | isSet kind              = False
+         | isArray kind            = False
+         | KTuple fields <- kind   = any functionValueHasUnsupportedManagedStorage fields
+         | isConcreteADTReference kind  = False
+         | True                    = valueNeedsOwnership cfg kind
+
+       (scheduledAssignments, scheduledRequirements) =
+         scheduleC env functionNames nestedLambdaNames
+                   (map fst functionConsts ++ map snd parameters) assignments tables False typeWidth [(functionOutput, empty)]
+
+       functionRequirements = Set.unions
+         [ Set.fromList $ [CRequiresGMP             | any (isExactGMPKind cfg) expandedFunctionKinds]
+                       ++ [CRequiresText            | KString `elem` expandedFunctionKinds]
+                       ++ [CRequiresLists           | any isList expandedFunctionKinds]
+                       ++ [CRequiresSets            | any isSet expandedFunctionKinds]
+                       ++ [CRequiresArrays          | any isArray expandedFunctionKinds]
+                       ++ [CRequiresFunctionResults | definedFunctionResultNeedsClone cfg adts resultKind]
+         , scheduledRequirements
+         , Set.unions [operationRequirements cfg (op, kindOf sv) | (sv, SBVApp op _) <- assignments]
+         ]
+
+       expandedFunctionKinds = concatMap (expandKinds . kindOf) functionValues
+
+       contextSetup  = functionContextSetup functionRequirements
+       contextCommit = functionContextCommit functionRequirements
+
+       functionDoc
+         = definedFunctionSignature originalName resultKind parameters
+          $$ text "{"
+          $$ nest 2 (   contextSetup
+                     $$ constantDeclarations
+                     $$ functionAssignments
+                     $$ functionResultDeclaration <+> text "sbv_local_function_result =" <+> functionResult P.<> semi
+                     $$ contextCommit
+                     $$ text "return sbv_local_function_result;"
+                    )
+          $$ text "}"
+          $$ text ""
+
+       functionAssignments = scheduledAssignments
+
+       functionResult
+         | isArray resultKind
+         = arrayStoredValue resultKind (showSV env functionOutput)
+         | definedFunctionResultNeedsClone cfg adts resultKind
+         = definedFunctionResultClone resultKind (showSV env functionOutput)
+         | True
+         = showSV env functionOutput
+
+       functionResultType
+         | isArray resultKind = CTypes.elementCType resultKind
+         | True               = showCType resultKind
+
+       functionResultDeclaration
+         | isArray resultKind = text functionResultType
+         | True               = text "const" <+> text functionResultType
+
+-- | Collect every operand, including values retained inside an operator
+-- instead of its ordinary argument list and the entries of referenced tables.
+-- Defaults omitted by unchecked or provably in-range lookups are not live.
+cExpressionDependencies :: CgConfig -> [((Int, Kind, Kind), [SV])] -> SBVExpr -> [SV]
+cExpressionDependencies cfg tables (SBVApp op arguments) = arguments ++ case op of
+  LkUp (tableIndex, indexKind, _, tableLength) index defaultValue
+    -> index : [defaultValue | tableNeedsBounds cfg indexKind, isJust (snd (tableIndexAndBounds cfg indexKind tableLength empty))]
+            ++ [value | ((candidateIndex, _, _), values) <- tables, candidateIndex == tableIndex, value <- values]
+  IEEEFP (FP_Cast _ _ rmSV) -> [rmSV]
+  _                       -> []
+
+-- | Find the complete demand closure of a collection of roots. Inputs and
+-- constants are included, so declaration liveness and evaluation scheduling
+-- use the same dependency graph.
+cReachableValues :: CgConfig -> Map.Map SV SBVExpr -> [((Int, Kind, Kind), [SV])] -> [SV] -> Set.Set SV
+cReachableValues cfg assignments tables = foldl reach Set.empty
+ where reach visited sv
+         | sv `Set.member` visited = visited
+         | True = foldl reach (Set.insert sv visited)
+                        (maybe [] (cExpressionDependencies cfg tables) (Map.lookup sv assignments))
+
+-- | Give managed constants function-wide backing storage. Rendering compound
+-- literals inside a conditional would otherwise leave dangling pointers when
+-- a descriptor is used after that branch exits. A lowering may elide a live
+-- operand, such as an unreachable table default, so acknowledge each binding
+-- even if its rendered use disappears.
+stabilizeCConstants :: CgConfig -> [Kind] -> Int -> [(SV, CV)] -> (Doc, [(SV, CV)])
+stabilizeCConstants cfg adts typeWidth constants
+  = ( vcat [ declSV typeWidth sv <+> text "=" <+> mkConst env cv P.<> semi
+          $$ text "(void)" <+> text (show sv) P.<> semi
+           | (sv, cv) <- stabilized
+           ]
+    , filter ((`Set.notMember` stabilizedValues) . fst) constants
+    )
+ where env = CRenderEnv cfg adts constants
+       stabilized = [(sv, cv) | (sv, cv) <- constants, isArray sv || definedFunctionResultNeedsClone cfg adts (kindOf sv)]
+       stabilizedValues = Set.fromList (map fst stabilized)
+
+-- | Recognize total bit-vector operations that may be computed before a
+-- guard when all their dependencies are already safe. Restrict speculation
+-- to the exact bit-vector runtime: calls, selectors, allocation, and native
+-- floating-point operations retain their demand ordering.
+cSpeculatable :: SV -> SBVExpr -> Bool
+cSpeculatable result (SBVApp op arguments) = all bitVector (result : arguments) && totalOperation op
+ where bitVector sv = kindOf sv == KBool || isBounded sv
+
+       totalOperation operation = case operation of
+         Plus        -> True
+         Times       -> True
+         Minus       -> True
+         UNeg        -> True
+         Abs         -> True
+         Quot        -> True
+         Rem         -> True
+         Equal{}     -> True
+         NotEqual    -> True
+         LessThan    -> True
+         GreaterThan -> True
+         LessEq      -> True
+         GreaterEq   -> True
+         Ite         -> True
+         Implies     -> True
+         And         -> True
+         Or          -> True
+         XOr         -> True
+         Not         -> True
+         Shl         -> True
+         Shr         -> True
+         Rol{}       -> True
+         Ror{}       -> True
+         Extract{}   -> True
+         Join        -> True
+         _           -> False
+
+-- | Path-sensitive scheduling facts. Tables, unlike hoisted values, are local
+-- to the C block that declares them. Memoized values accumulate across paths.
+data CAvailability = CAvailability
+  { definitelyAvailable :: Set.Set SV  -- ^ Values computed on every incoming path.
+  , possiblyAvailable   :: Set.Set SV  -- ^ Values computed on some incoming path.
+  , availableCTables    :: Set.Set Int -- ^ Tables declared in the current scope.
+  , memoizedValues      :: Set.Set SV  -- ^ Values requiring a runtime readiness check.
+  }
+
+-- | Schedule a collection of demanded values and their following statements.
+-- Branch-local work stays under its guard, while declarations are hoisted so
+-- values computed on both paths can safely be reused after the join. Root
+-- statements let entry points retain runtime checks even without live outputs.
+scheduleC :: CRenderEnv
+          -> [(T.Text, String)]
+          -> [(SV, String)]
+          -> [SV]
+          -> [(SV, SBVExpr)]
+          -> [((Int, Kind, Kind), [SV])]
+          -> Bool
+          -> Int
+          -> [(SV, Doc)]
+          -> (Doc, Set.Set CRequirement)
+scheduleC env functionNames lambdaNames initialValues assignments tables allowStatic typeWidth roots
+  = (vcat eagerDocs $$ declarations $$ statements, Set.union requirements eagerRequirements)
+ where cfg = renderConfig env
+       initialAvailability = CAvailability eagerValues eagerValues Set.empty Set.empty
+       (analyzed, _, _, _) = schedulePass Set.empty
+       guardedValues = memoizedValues analyzed
+       (_, statements, requirements, extraDeclarations) = guardedValues `seq` schedulePass guardedValues
+       declarations = vcat [typ <+> var <+> (if sv `Set.member` guardedValues then text "= {0}" else empty) P.<> semi
+                           | (sv, _) <- assignments
+                           , sv `Set.member` reachableValues
+                           , sv `Set.notMember` eagerValues
+                           , let (typ, var) = declSVNoConst typeWidth sv
+                           ]
+                   $$ vcat [text "bool" <+> readyName sv <+> text "= false;" | sv <- Set.toList guardedValues]
+                   $$ vcat (uniqueOn render extraDeclarations)
+
+       assignmentMap   = Map.fromList assignments
+       reachableValues = cReachableValues cfg assignmentMap tables (map fst roots)
+
+       -- The first pass discovers which values need readiness flags. The
+       -- second pass receives that completed set explicitly. Even forcing
+       -- first-pass documents cannot create a dependency on the second pass.
+       readyName sv = text ("sbv_ready_" ++ show sv)
+
+       (eagerValues, eagerReversed) = foldl speculate (Set.fromList initialValues, []) assignments
+       eagerLowerings = [ppExpr env functionNames lambdaNames expression sv
+                               (declSV typeWidth sv) (declSVNoConst typeWidth sv) True
+                        | (sv, expression) <- reverse eagerReversed]
+       eagerDocs = [doc | (doc, _, _) <- eagerLowerings]
+       eagerRequirements = Set.unions [needed | (_, needed, _) <- eagerLowerings]
+
+       speculate available@(values, emitted) assignment@(sv, expression)
+         | sv `Set.member` reachableValues
+         , cSpeculatable sv expression
+         , all (`Set.member` values) (cExpressionDependencies cfg tables expression)
+         = (Set.insert sv values, assignment : emitted)
+         | True
+         = available
+
+       schedulePass markedValues = emitRoots initialAvailability roots
+        where
+         emitRoots available [] = (available, empty, Set.empty, [])
+         emitRoots available ((sv, action):rest) =
+           let (withValue, valueDocs, valueRequirements, valueDeclarations) = emit available sv
+               (withRest, restDocs, restRequirements, restDeclarations) = emitRoots withValue rest
+           in ( withRest
+              , valueDocs $$ action $$ restDocs
+              , Set.union valueRequirements restRequirements
+              , valueDeclarations ++ restDeclarations
+              )
+
+         emit available sv
+           | sv `Set.member` definitelyAvailable available
+           = (available, empty, Set.empty, [])
+           | True
+           = let (after, docs, needed, decls) = emitAssignment available sv
+                 marked = docs $$ if sv `Set.member` markedValues then readyName sv <+> text "= true;" else empty
+                 guarded = text "if" P.<> parens (text "!" P.<> readyName sv)
+                        $$ text "{"
+                        $$ nest 2 marked
+                        $$ text "}"
+             in if sv `Set.member` possiblyAvailable available
+                  then (after { availableCTables = availableCTables available
+                              , memoizedValues = Set.insert sv (memoizedValues after)
+                              }, guarded, needed, decls)
+                  else (after, marked, needed, decls)
+
+         emitAssignment available sv
+           | Just expression@(SBVApp op arguments) <- Map.lookup sv assignmentMap
+           = case (op, arguments) of
+               (LkUp tableInfo index defaultValue, [])
+                 -> tableLookup available sv expression tableInfo index defaultValue
+               (Ite, [condition, trueValue, falseValue])
+                 -> conditional available sv condition trueValue falseValue
+               (And, [left, right])
+                 | kindOf sv == KBool
+                 -> conditional available sv left right falseSV
+               (Or, [left, right])
+                 | kindOf sv == KBool
+                 -> conditional available sv left trueSV right
+               (Implies, [left, right])
+                 | kindOf sv == KBool
+                 -> conditional available sv left right trueSV
+               _ -> let (withArguments, argumentDocs, argumentRequirements, argumentDeclarations) = emitMany available
+                                                                                                             (cExpressionDependencies cfg tables expression)
+                        (withTable, tableDocs) = emitTable withArguments op
+                        (assignmentDoc, assignmentRequirements, assignmentDeclarations) =
+                          ppExpr env functionNames lambdaNames expression sv (text (show sv))
+                                 (declSVNoConst typeWidth sv) False
+                    in ( insertAvailableValue sv withTable
+                       , argumentDocs $$ tableDocs $$ assignmentDoc
+                       , Set.union argumentRequirements assignmentRequirements
+                       , argumentDeclarations ++ assignmentDeclarations
+                       )
+           | True
+           = die $ "Missing assignment while scheduling C evaluation: " ++ show sv
+
+         emitMany available [] = (available, empty, Set.empty, [])
+         emitMany available (sv:svs) =
+           let (withValue, valueDocs, valueRequirements, valueDeclarations) = emit available sv
+               (withRest, restDocs, restRequirements, restDeclarations) = emitMany withValue svs
+           in ( withRest
+              , valueDocs $$ restDocs
+              , Set.union valueRequirements restRequirements
+              , valueDeclarations ++ restDeclarations
+              )
+
+         emitTable available op
+           | LkUp (tableIndex, _, _, _) _ _ <- op
+           , tableIndex `Set.notMember` availableCTables available
+           = case [table | table@((candidateIndex, _, _), _) <- tables, candidateIndex == tableIndex] of
+               [table] -> (insertAvailableTable tableIndex available, snd (ppTable env allowStatic table))
+               _       -> die "Missing table while scheduling C evaluation"
+           | True
+           = (available, empty)
+
+         tableLookup available result expression (tableIndex, indexKind, _, tableLength) index defaultValue =
+           let (withIndex, indexDocs, indexRequirements, indexDeclarations) = emit available index
+               (afterLookup, lookupDocs, lookupRequirements, lookupDeclarations) = selectValue withIndex
+           in ( afterLookup
+              , indexDocs $$ lookupDocs
+              , Set.union indexRequirements lookupRequirements
+              , indexDeclarations ++ lookupDeclarations
+              )
+           where elements = case [values | ((candidateIndex, _, _), values) <- tables, candidateIndex == tableIndex] of
+                              [values] | length values == tableLength -> values
+                              _ -> die "Missing or inconsistent table while scheduling C evaluation"
+                 (nativeIndex, outOfRange) = tableIndexAndBounds cfg indexKind tableLength (showSV env index)
+                 checkedBounds = if tableNeedsBounds cfg indexKind then outOfRange else Nothing
+                 entriesReady current = all (`Set.member` definitelyAvailable current) elements
+
+                 selectValue current
+                   | entriesReady current
+                   , isNothing checkedBounds || defaultValue `Set.member` definitelyAvailable current
+                   = renderLookup cfg current
+                   | Just check <- checkedBounds
+                   = let (withDefault, defaultDocs, defaultRequirements, defaultDeclarations) = emitChoice current defaultValue
+                         (withEntry, entryDocs, entryRequirements, entryDeclarations) = selectEntry current
+                     in ( insertAvailableValue result (joinAvailability current [withDefault, withEntry])
+                        , text "if" P.<> parens check
+                       $$ text "{" $$ nest 2 defaultDocs $$ text "}"
+                       $$ text "else"
+                       $$ text "{" $$ nest 2 entryDocs $$ text "}"
+                        , Set.union defaultRequirements entryRequirements
+                        , defaultDeclarations ++ entryDeclarations
+                        )
+                   | True
+                   = selectEntry current
+
+                 selectEntry current
+                   | entriesReady current
+                   , isNothing checkedBounds || defaultValue `Set.member` definitelyAvailable current
+                   = renderLookup (cfg {cgRTC = False}) current
+                   | True
+                   = let cases = [(position, emitChoice current value) | (position, value) <- zip [0 :: Int ..] elements]
+                         renderCase (position, (_, docs, _, _)) = text "case" <+> int position P.<> colon
+                                                             $$ text "{"
+                                                             $$ nest 2 (docs $$ text "break;")
+                                                             $$ text "}"
+                         availableAfter = joinAvailability current [values | (_, (values, _, _, _)) <- cases]
+                     in ( insertAvailableValue result availableAfter
+                        , text "switch" P.<> parens (text "(uint64_t)" <+> parens nativeIndex)
+                       $$ text "{"
+                       $$ nest 2 (vcat (map renderCase cases)
+                               $$ text "default:"
+                               $$ nest 2 (text "/* Unreachable for checked indices; invalid unchecked index. */" $$ text "abort();"))
+                       $$ text "}"
+                        , Set.unions [needed | (_, (_, _, needed, _)) <- cases]
+                        , concat [decls | (_, (_, _, _, decls)) <- cases]
+                        )
+
+                 emitChoice current value =
+                   let (withValue, docs, needed, decls) = emit current value
+                   in ( insertAvailableValue result withValue
+                      , docs $$ text (show result) <+> text "=" <+> showSV env value P.<> semi
+                      , needed
+                      , decls
+                      )
+
+                 renderLookup loweringConfig current =
+                   let SBVApp op _ = expression
+                       (withTable, tableDocs) = emitTable current op
+                       (docs, needed, decls) = ppExpr env{renderConfig = loweringConfig} functionNames lambdaNames expression result
+                                                     (text (show result)) (declSVNoConst typeWidth result) False
+                   in (insertAvailableValue result withTable, tableDocs $$ docs, needed, decls)
+
+         conditional available result condition trueValue falseValue =
+           let (withCondition, conditionDocs, conditionRequirements, conditionDeclarations) = emit available condition
+               shared = Set.intersection (mandatoryValues withCondition trueValue) (mandatoryValues withCondition falseValue)
+               (withCommon, commonDocs, commonRequirements, commonDeclarations) = emitMany withCondition (Set.toList shared)
+               (withTrue, trueDocs, trueRequirements, trueDeclarations) = emit withCommon trueValue
+               (withFalse, falseDocs, falseRequirements, falseDeclarations) = emit withCommon falseValue
+               branch label branchDocs branchValue = text label
+                                                  $$ text "{"
+                                                  $$ nest 2 (branchDocs $$ assign branchValue)
+                                                  $$ text "}"
+               assign value = text (show result) <+> text "=" <+> showSV env value P.<> semi
+               docs = conditionDocs
+                   $$ commonDocs
+                   $$ text "if" P.<> parens (showSV env condition)
+                   $$ branch "" trueDocs trueValue
+                   $$ branch "else" falseDocs falseValue
+               needed = Set.unions [conditionRequirements, commonRequirements, trueRequirements, falseRequirements]
+               -- Values are declared outside the branches, but branch-local C
+               -- table declarations do not remain in scope after the join.
+               availableAfter = joinAvailability withCommon [withTrue, withFalse]
+               branchDeclarations = conditionDeclarations ++ commonDeclarations ++ trueDeclarations ++ falseDeclarations
+           in (insertAvailableValue result availableAfter, docs, needed, branchDeclarations)
+
+         -- Sharing a mandatory dependency is safe even for partial operations:
+         -- either branch will demand it. Stop at nested guards rather than
+         -- treating their inactive alternatives as mandatory dependencies.
+         mandatoryValues available = walk Set.empty
+           where walk visited sv
+                   | sv `Set.member` definitelyAvailable available || sv `Set.member` visited = visited
+                   | True = foldl walk (Set.insert sv visited) dependencies
+                   where dependencies = case Map.lookup sv assignmentMap of
+                           Just (SBVApp Ite (condition:_)) -> [condition]
+                           Just (SBVApp (LkUp _ index _) _) -> [index]
+                           Just (SBVApp op (left:_))
+                             | kindOf sv == KBool, op `elem` [And, Or, Implies] -> [left]
+                           Just expression -> cExpressionDependencies cfg tables expression
+                           Nothing         -> []
+
+         joinAvailability current [] = current
+         joinAvailability current branches@(initial:rest) = current
+           { definitelyAvailable = foldl Set.intersection (definitelyAvailable initial) (map definitelyAvailable rest)
+           , possiblyAvailable = Set.unions (map possiblyAvailable branches)
+           , memoizedValues = Set.unions (map memoizedValues branches)
+           }
+
+         insertAvailableValue value available = available
+           { definitelyAvailable = Set.insert value (definitelyAvailable available)
+           , possiblyAvailable = Set.insert value (possiblyAvailable available)
+           }
+
+         insertAvailableTable tableIndex available = available {availableCTables = Set.insert tableIndex (availableCTables available)}
+
+-- | Give a lambda-lifted array callback a name unique to its lexical owner.
+scopedArrayLambdaName :: String -> SV -> String
+scopedArrayLambdaName scope arraySV = scope ++ "_nested_" ++ show arraySV
+
+-- | Render the private C signature for a structured array callback.
+-- Captures are rejected separately before any callback is lowered.
+arrayLambdaSignature :: String -> SV -> LambdaInfo -> Doc
+arrayLambdaSignature callbackName arraySV LambdaInfo{liParams = parameters}
+  = case (kindOf arraySV, parameters) of
+      (KArray _ valueKind, [(ALL, parameter)])
+        -> text "static" <+> text (arrayLambdaResultType valueKind) <+> text callbackName
+             P.<> parens (fsep (punctuate comma [text "const void *context", text (showCType (kindOf parameter)) <+> text (show parameter)]))
+      (KArray{}, _) -> die $ "Expected exactly one universal array-lambda parameter, received " ++ show parameters
+      (kind, _)     -> die $ "Expected an array-valued lambda node, received " ++ show kind
+
+-- | Return the C callback result type for an array element kind.
+arrayLambdaResultType :: Kind -> String
+arrayLambdaResultType kind
+  | isArray kind = CTypes.elementCType kind
+  | True         = showCType kind
+
+-- | Conservatively check the complete retained body for free symbolic values,
+-- independently of scheduling or dead-code elimination. Include values hidden
+-- in operators, every table entry/default, the result itself, and free values
+-- of nested array lambdas. Each nested callback is also checked separately,
+-- so capturing its enclosing lambda's parameter is rejected too.
+cLambdaFreeValues :: LambdaInfo -> [SV]
+cLambdaFreeValues lambdaInfo = Set.toList $ Set.fromList uses `Set.difference` bound
+ where assignments = F.toList (liAssignments lambdaInfo)
+       bound       = Set.fromList (falseSV : trueSV : map fst assignments ++ map snd (liParams lambdaInfo) ++ map fst (liConsts lambdaInfo))
+       uses        = liOutput lambdaInfo : concatMap (dependencies . snd) assignments ++ concatMap snd (liTables lambdaInfo)
+
+       dependencies (SBVApp op arguments) = arguments ++ case op of
+         LkUp _ index defaultValue -> [index, defaultValue]
+         IEEEFP (FP_Cast _ _ rm)   -> [rm]
+         ArrayInit (Right lambdaDef)
+           | Just nested <- smtLambdaInfo lambdaDef -> cLambdaFreeValues nested
+         _                        -> []
+
+-- | Lower a retained one-argument array lambda into a C lookup callback. Its
+-- local DAG uses the ordinary lowering pipeline, so scalar and managed values
+-- share the same semantics and ownership arenas as the enclosing generated
+-- function.
+ppArrayLambda :: CgConfig
+              -> [Kind]
+              -> [(T.Text, String)]
+              -> String
+              -> SV
+              -> LambdaInfo
+              -> (Doc, Set.Set CRequirement)
+ppArrayLambda cfg adts functionNames callbackName arraySV lambdaInfo@LambdaInfo{ liAssignments = lambdaPgm
+                                                                              , liParams      = parameters
+                                                                              , liOutput      = lambdaOutput
+                                                                              , liConsts      = constants
+                                                                              , liTables      = tables
+                                                                              }
+  = case (kindOf arraySV, parameters) of
+      (KArray keyKind valueKind, [(ALL, parameter)])
+        | kindOf parameter /= keyKind
+        -> die $ "Array-lambda parameter kind " ++ show (kindOf parameter) ++ " does not match " ++ show keyKind
+        | kindOf lambdaOutput /= valueKind
+        -> die $ "Array-lambda result kind " ++ show (kindOf lambdaOutput) ++ " does not match " ++ show valueKind
+        | True
+        -> (helper keyKind valueKind parameter, requirements)
+      (KArray{}, _) -> die $ "Expected exactly one universal array-lambda parameter, received " ++ show parameters
+      (kind, _)     -> die $ "Expected an array-valued lambda node, received " ++ show kind
+ where assignments = F.toList lambdaPgm
+       lambdaConsts = (falseSV, falseCV) : (trueSV, trueCV) : constants
+       reachableValues = cReachableValues cfg (Map.fromList assignments) tables [lambdaOutput]
+       (constantDeclarations, renderingConsts) = stabilizeCConstants cfg adts typeWidth (filter ((`Set.member` reachableValues) . fst) lambdaConsts)
+       env = CRenderEnv cfg adts renderingConsts
+       lambdaValues = lambdaOutput : map snd parameters ++ map fst assignments ++ map fst constants ++ concatMap snd tables
+       typeWidth    = maximum (0 : map (length . showCType) lambdaValues)
+
+       nestedLambdaNames = [ (sv, scopedArrayLambdaName callbackName sv)
+                           | (sv, SBVApp (ArrayInit (Right _)) _) <- assignments
+                           ]
+       definedFunctionCalls = [ symbol
+                              | (_, SBVApp (Uninterpreted symbol) _) <- assignments
+                              , isJust (lookup symbol functionNames)
+                              ]
+
+       (scheduledAssignments, scheduledRequirements) =
+         scheduleC env functionNames nestedLambdaNames
+                   (map fst lambdaConsts ++ map snd parameters) assignments tables False typeWidth [(lambdaOutput, empty)]
+
+       requirements = Set.unions
+         [ contextRequirements
+         , scheduledRequirements
+         , Set.unions [operationRequirements cfg (op, kindOf sv) | (sv, SBVApp op _) <- assignments]
+         ]
+
+       expandedLambdaKinds = concatMap (expandKinds . kindOf) lambdaValues
+
+       contextRequirements = Set.fromList $
+            [CRequiresGMP    | any (isExactGMPKind cfg) expandedLambdaKinds]
+         ++ [CRequiresText   | any (`elem` [KChar, KString]) expandedLambdaKinds]
+         ++ [CRequiresLists  | any isList expandedLambdaKinds]
+         ++ [CRequiresSets   | any isSet expandedLambdaKinds]
+         ++ [CRequiresArrays | any isArray expandedLambdaKinds]
+         ++ [CRequiresFunctionResults | definedFunctionResultNeedsClone cfg adts (kindOf lambdaOutput)]
+
+       helper _ valueKind _
+         = arrayLambdaSignature callbackName arraySV lambdaInfo
+          $$ text "{"
+          $$ nest 2 (   contextSetup
+                     $$ constantDeclarations
+                     $$ scheduledAssignments
+                     $$ lambdaResultDeclaration valueKind <+> text "sbv_local_lambda_result" <+> text "=" <+> lambdaResult P.<> semi
+                     $$ contextCommit
+                     $$ text "return sbv_local_lambda_result;"
+                    )
+          $$ text "}"
+          $$ text ""
+
+       lambdaResult
+         | isArray lambdaOutput
+         = arrayStoredValue (kindOf lambdaOutput) (showSV env lambdaOutput)
+         | definedFunctionResultNeedsClone cfg adts (kindOf lambdaOutput)
+         = definedFunctionResultClone (kindOf lambdaOutput) (showSV env lambdaOutput)
+         | True
+         = showSV env lambdaOutput
+
+       lambdaResultDeclaration valueKind
+         | isArray lambdaOutput = text (arrayLambdaResultType valueKind)
+         | True                 = text "const" <+> text (arrayLambdaResultType valueKind)
+
+       contextSetup
+         | not needsFunctionContext = parens (text "void") <+> text "context" P.<> semi
+         | True
+         =  text "sbv_function_ctx *const sbv_local_parent_function_ctx = (sbv_function_ctx *) context;"
+         $$ functionContextSetup contextRequirements
+
+       contextCommit = functionContextCommit contextRequirements
+
+       needsFunctionContext = not (Set.null contextRequirements && null definedFunctionCalls)
+
+
+-- | Lower native IEEE operations not handled by the explicit LibBF adapters.
+handleIEEE :: FPOp -> [(SV, CV)] -> [(SV, Doc)] -> Doc -> Doc
+handleIEEE w consts as var = cvt w
+  where same f                   = (f, f)
+        named fnm dnm f          = (f fnm, f dnm)
+
+        unary f [a]         = f a
+        unary _ args        = wrongArity 1 args
+        binary f [a, b]     = f a b
+        binary _ args       = wrongArity 2 args
+        ternary f [a, b, c] = f a b c
+        ternary _ args      = wrongArity 3 args
+        wrongArity expected args = die $ "Native floating-point operation " ++ show w ++ " expects "
+                                      ++ show (expected :: Int) ++ " arguments, received " ++ show (length args)
+
+        cvt FP_Cast{} = die "Floating-point cast escaped the exact cast lowering pipeline"
+
+        cvt (FP_Reinterpret f t) = case (f, t) of
+                                     (KBounded False 32, KFloat)  -> cast $ cpy "sizeof(SFloat)"
+                                     (KBounded False 64, KDouble) -> cast $ cpy "sizeof(SDouble)"
+                                     (KFloat,  KBounded False 32) -> cast $ cpy "sizeof(SWord32)"
+                                     (KDouble, KBounded False 64) -> cast $ cpy "sizeof(SWord64)"
+                                     _                            -> die $ "Reinterpretation from : " ++ show f ++ " to " ++ show t
+                                    where cpy sz = unary $ \a -> text "memcpy" P.<> parens (fsep (punctuate comma
+                                                                 [text "&" P.<> var, text "&" P.<> a, text sz]))
+        cvt FP_Abs               = dispatch $ named "fabsf" "fabs" $ \nm _ -> unary $ \a -> text nm P.<> parens a
+        cvt FP_Neg               = dispatch $ same $ \_ -> unary $ \a -> text "-" P.<> a
+        cvt FP_Add               = dispatch $ same $ \_ -> binary $ \a b -> a <+> text "+" <+> b
+        cvt FP_Sub               = dispatch $ same $ \_ -> binary $ \a b -> a <+> text "-" <+> b
+        cvt FP_Mul               = dispatch $ same $ \_ -> binary $ \a b -> a <+> text "*" <+> b
+        cvt FP_Div               = dispatch $ same $ \_ -> binary $ \a b -> a <+> text "/" <+> b
+        cvt FP_FMA               = dispatch $ named "fmaf"  "fma"  $ \nm _ -> ternary $ \a b c -> text nm P.<> parens (fsep (punctuate comma [a, b, c]))
+        cvt FP_Sqrt              = dispatch $ named "sqrtf" "sqrt" $ \nm _ -> unary $ \a       -> text nm P.<> parens a
+        cvt FP_Rem               = dispatch $ named "remainderf" "remainder" $ \nm _ -> binary $ \a b -> text nm P.<> parens (fsep (punctuate comma [a, b]))
+        cvt FP_RoundToIntegral   = dispatch $ named "rintf" "rint" $ \nm _ -> unary $ \a       -> text nm P.<> parens a
+        cvt FP_Min               = dispatch $ named "fminf" "fmin" $ \nm k -> binary $ \a b    -> wrapMinMax k a b (text nm P.<> parens (fsep (punctuate comma [a, b])))
+        cvt FP_Max               = dispatch $ named "fmaxf" "fmax" $ \nm k -> binary $ \a b    -> wrapMinMax k a b (text nm P.<> parens (fsep (punctuate comma [a, b])))
+        cvt FP_ObjEqual          = dispatch $ same $ \_ -> binary $ \a b -> nativeFPObjectEqual a b
+        cvt FP_IsNormal          = dispatch $ same $ \_ -> unary $ \a -> text "isnormal" P.<> parens a
+        cvt FP_IsSubnormal       = dispatch $ same $ \_ -> unary $ \a -> text "FP_SUBNORMAL == fpclassify" P.<> parens a
+        cvt FP_IsZero            = dispatch $ same $ \_ -> unary $ \a -> text "FP_ZERO == fpclassify" P.<> parens a
+        cvt FP_IsInfinite        = dispatch $ same $ \_ -> unary $ \a -> text "isinf" P.<> parens a
+        cvt FP_IsNaN             = dispatch $ same $ \_ -> unary $ \a -> text "isnan" P.<> parens a
+        cvt FP_IsNegative        = dispatch $ same $ \_ -> unary $ \a -> text "!isnan" P.<> parens a <+> text "&&" <+> text "signbit"  P.<> parens a
+        cvt FP_IsPositive        = dispatch $ same $ \_ -> unary $ \a -> text "!isnan" P.<> parens a <+> text "&&" <+> text "!signbit" P.<> parens a
+
+        -- grab the rounding-mode, if present, and make sure it's RoundNearestTiesToEven. Otherwise skip.
+        fpArgs = case as of
+                   []            -> []
+                   ((m, _):args)
+                     | isRoundingMode m -> case checkRM (m `lookup` consts) of
+                                             Nothing          -> args
+                                             Just (Left  msg) -> die msg
+                                             Just (Right msg) -> tbd msg
+                     | True              -> as
+
+        -- Explicit non-default and symbolic rounding modes are handled by the
+        -- LibBF adapters before this native fallback is selected.
+        checkRM (Just cv@(CV k v))
+          | k == kRoundingMode = case v of
+                                   CADT ("RoundNearestTiesToEven", []) -> Nothing
+                                   CADT (s,                        []) -> Just (Right $ "handleIEEE: Unsupported rounding-mode: " ++ show s ++ " for: " ++ show w)
+                                   _                                   -> Just (Left  $ "handleIEEE: Unexpected value for rounding-mode: " ++ show cv ++ " for: " ++ show w)
+        checkRM (Just cv) = Just (Left  $ "handleIEEE: Expected rounding-mode, but got: " ++ show cv ++ " for: " ++ show w)
+        checkRM Nothing   = Just (Right $ "handleIEEE: Non-constant rounding-mode for: " ++ show w)
+
+        pickOp _          []             = die $ "Cannot determine float/double kind for op: " ++ show w
+        pickOp (fOp, dOp) args@((a,_):_) = case kindOf a of
+                                             KFloat  -> fOp KFloat  (map snd args)
+                                             KDouble -> dOp KDouble (map snd args)
+                                             k       -> die $ "handleIEEE: Expected double/float args, but got: " ++ show k ++ " for: " ++ show w
+
+        dispatch (fOp, dOp) = pickOp (fOp, dOp) fpArgs
+        cast f              = f (map snd fpArgs)
+
+        -- In SMT-Lib, fpMin/fpMax is underspecified when given +0/-0 as the two arguments. (In any order.)
+        -- In C, the second argument is returned. (I think, might depend on the architecture, optimizations etc.).
+        -- We'll translate it so that we deterministically return +0.
+        -- There's really no good choice here.
+        wrapMinMax k a b s = parens cond <+> text "?" <+> fzero <+> text ":" <+> s
+          where fzero = text $ if k == KFloat then showCFloat 0 else showCDouble 0
+                cond  =                   parens (text "FP_ZERO == fpclassify" P.<> parens a)                                  -- a is zero
+                        <+> text "&&" <+> parens (text "FP_ZERO == fpclassify" P.<> parens b)                                  -- b is zero
+                        <+> text "&&" <+> parens (text "signbit" P.<> parens a <+> text "!=" <+> text "signbit" P.<> parens b) -- a and b differ in sign
+
+-- | Lower and render one symbolic assignment together with the facilities it
+-- requires from the generated C translation unit.
+ppExpr :: CRenderEnv
+       -> [(T.Text, String)]
+       -> [(SV, String)]
+       -> SBVExpr
+       -> SV
+       -> Doc
+       -> (Doc, Doc)
+       -> Bool
+       -> (Doc, Set.Set CRequirement, [Doc])
+ppExpr env functionNames structuredLambdaNames (SBVApp op opArgs) resultSV lhs (typ, var) declareResult
+  | requiresExtensionalEquality adts op (map kindOf opArgs)
+  , not (op `elem` [Equal False, Equal True, NotEqual] && all isArray opArgs)
+  = error $ "SBV->C: " ++ show op ++ " requires general extensional array equality, including array-valued elements or fields."
+  | True
+  = ( vcat $ declarations
+          ++ loweringSetup selected
+          ++ [assignment]
+    , loweringRequirements selected
+    , loweringDeclarations selected
+    )
+  where cfg    = renderConfig env
+        adts   = renderADTs env
+        consts = renderConstants env
+
+        declarations
+          | declareResult = loweringDeclarations selected
+          | True          = []
+
+        doNotAssign (IEEEFP FP_Reinterpret{})
+          | not (isFP (kindOf resultSV) || any (isFP . kindOf) opArgs)
+          , not (isWideBV (kindOf resultSV) || any (isWideBV . kindOf) opArgs)
+          = True   -- generates a memcpy instead; no simple assignment
+        doNotAssign PseudoBoolean{} = True   -- assigns through an overflow-safe reduction
+        doNotAssign _              = False
+
+        renderedArgs = map (showSV env) opArgs
+
+        -- Precedence is intentional, not a uniqueness invariant: aggregate
+        -- storage operations precede scalar operations touching their fields;
+        -- exact/mapped casts precede native fallbacks. In particular FP owns
+        -- BV/FP reinterpretation, including interchange vectors wider than 64.
+        -- Ite and short-circuit booleans are scheduled separately; only total
+        -- bit-vector Ite can reach this dispatch through eager speculation.
+        selected = fromMaybe legacy $ chooseLowering
+          [ arrayExpr cfg (`lookup` functionNames) (`lookup` structuredLambdaNames) op opArgs resultSV renderedArgs
+          , tableExpr cfg (showSV env) op resultSV
+          , setExpr cfg op opArgs (kindOf resultSV) renderedArgs
+          , nonLinearExpr cfg op opArgs (kindOf resultSV) renderedArgs
+          , regexExpr cfg op resultSV renderedArgs
+          , textExpr cfg op opArgs (kindOf resultSV) renderedArgs
+          , listExpr cfg op opArgs resultSV renderedArgs
+          , adtExpr cfg adts op opArgs resultSV renderedArgs
+          , tupleExpr op opArgs resultSV renderedArgs
+          , gmpExpr cfg op opArgs (kindOf resultSV) renderedArgs
+          , bitVectorCastExpr (cgInteger cfg) op opArgs (kindOf resultSV) renderedArgs
+          , arbitraryFPExpr cfg consts op opArgs (kindOf resultSV) renderedArgs
+          , nativeFPExpr consts op opArgs (kindOf resultSV) renderedArgs
+          , nativeBVExpr (cgInteger cfg) op opArgs (kindOf resultSV) renderedArgs
+          , nativeBVOverflowExpr op opArgs renderedArgs
+          , wideBVExpr op opArgs (kindOf resultSV) renderedArgs
+          ]
+
+        legacy = expressionLowering [] (p op renderedArgs)
+
+        rhs = loweringExpression selected
+
+        assignment
+          | doNotAssign op
+          = (if declareResult then typ <+> var P.<> semi else empty) <+> rhs P.<> semi
+          | True
+          = lhs <+> text "=" <+> rhs P.<> semi
+
+        rtc = cgRTC cfg
+
+        functionName symbol = fromMaybe (T.unpack symbol) (lookup symbol functionNames)
+
+        functionArguments symbol arguments
+          | isJust (lookup symbol functionNames) = text "&sbv_local_function_ctx" : arguments
+          | True                                 = arguments
+
+        cBinOps = [ (Plus, "+"), (Times, "*"), (Minus, "-")
+                  , (Equal False, "==")  -- no strong equality!
+                  , (NotEqual, "!="), (LessThan, "<"), (GreaterThan, ">"), (LessEq, "<="), (GreaterEq, ">=")
+                  , (And, "&"), (Or, "|"), (XOr, "^")
+                  ]
+
+        hd _ (h:_) = h
+        hd w []    = error $ "Data.SBV.C.ppExpr: Impossible happened: " ++ w ++ ", received empty list!"
+
+        p :: Op -> [Doc] -> Doc
+        p ReadArray{}          _   = die "Array read escaped the persistent-array lowering pipeline"
+        p WriteArray{}         _   = die "Array write escaped the persistent-array lowering pipeline"
+        p ArrayInit{}          _   = die "Array initialization escaped the persistent-array lowering pipeline"
+        p QuantifiedBool{}     _   = solverOnly "quantified Boolean expressions"
+        p SpecialRelOp{}       _   = solverOnly "special relations"
+        p RegExOp{}            _   = die "Regex comparison escaped the bounded-automaton lowering pipeline"
+        p (StrOp StrInRe{})    _   = die "Regex membership escaped the bounded-automaton lowering pipeline"
+        p (Label s)           [a]  = a <+> text "/*" <+> cCommentText s <+> text "*/"
+        p (IEEEFP w)            as = handleIEEE w consts (zip opArgs as) var
+        p (PseudoBoolean pb)    as = assignPseudoBoolean pb as var
+        p OverflowOp{}         _   = die "Overflow operation escaped the exact bit-vector lowering pipeline"
+        p NonLinear{}          _   = die "Non-linear operation escaped the dedicated lowering pipeline"
+        p castOp@KindCast{}    [a]
+          | Just width <- mappedRealFloorWidth cfg castOp
+          = mappedRealFloorCall width a
+        p (KindCast _ to)      [a]  = parens (text (showCType to)) <+> a
+        p (Uninterpreted s) []
+          | isJust (lookup s functionNames)
+          = text "/* Defined function */" <+> text (functionName s) P.<> parens (text "&sbv_local_function_ctx")
+          | True
+          = text "/* Uninterpreted constant */" <+> text (functionName s)
+        p (Uninterpreted s) as = text "/* Uninterpreted function */" <+> text (functionName s)
+                                  P.<> parens (fsep (punctuate comma (functionArguments s as)))
+        p Extract{}       _      = die "Bit-vector extraction escaped the exact bit-vector lowering pipeline"
+        p Join            _      = die "Bit-vector concatenation escaped the exact bit-vector lowering pipeline"
+        p ZeroExtend{}    _      = die "Zero extension escaped the exact bit-vector lowering pipeline"
+        p SignExtend{}    _      = die "Sign extension escaped the exact bit-vector lowering pipeline"
+        p Rol{}           _      = die "Left rotation escaped the exact bit-vector lowering pipeline"
+        p Ror{}           _      = die "Right rotation escaped the exact bit-vector lowering pipeline"
+        p Shl{}           _      = die "Left shift escaped the exact bit-vector lowering pipeline"
+        p Shr{}           _      = die "Right shift escaped the exact bit-vector lowering pipeline"
+        p Not          [a]       = case kindOf (hd "Not" opArgs) of
+                                   -- be careful about booleans, bitwise complement is not correct for them!
+                                   KBool -> text "!" P.<> a
+                                   _     -> text "~" P.<> a
+        p Ite [a, b, c] = a <+> text "?" <+> b <+> text ":" <+> c
+        p (LkUp (t, k, _, len) ind def) []
+          | not rtc                    = lkUp -- ignore run-time-checks per user request
+          | needsCheckL && needsCheckR = cndLkUp checkBoth
+          | needsCheckL                = cndLkUp checkLeft
+          | needsCheckR                = cndLkUp checkRight
+          | True                       = lkUp
+          where index  = showSV env ind
+                defVal = showSV env def
+
+                lkUp = text "table" P.<> int t P.<> brackets renderedIndex
+                cndLkUp cnd = cnd <+> text "?" <+> defVal <+> text ":" <+> lkUp
+
+                checkLeft
+                  | isWideBV k = text "!" P.<> parens (wideBVLookupInRange k len index)
+                  | True       = index <+> text "< 0"
+
+                checkRight
+                  | isWideBV k = text "!" P.<> parens (wideBVLookupInRange k len index)
+                  | True       = index <+> text ">=" <+> int len
+
+                checkBoth  = parens (checkLeft <+> text "||" <+> checkRight)
+
+                renderedIndex
+                  | isWideBV k = wideBVLookupIndex k index
+                  | True       = index
+
+                canOverflow True  sz = (2::Integer)^(sz-1)-1 >= fromIntegral len
+                canOverflow False sz = (2::Integer)^sz    -1 >= fromIntegral len
+
+                (needsCheckL, needsCheckR) = case k of
+                                               KVar{}          -> die $ "array index with variable: " ++ show k
+                                               KBool           -> (False, canOverflow False (1::Int))
+                                               KBounded sg sz
+                                                 | isWideBV k -> (sg, not sg)
+                                                 | True       -> (sg, canOverflow sg sz)
+                                               KReal           -> die "array index with real value"
+                                               KFloat          -> die "array index with float value"
+                                               KDouble         -> die "array index with double value"
+                                               KFP{}           -> die "array index with arbitrary float value"
+                                               KRational       -> die "array index with rational value"
+                                               KString         -> die "array index with string value"
+                                               KChar           -> die "array index with character value"
+                                               KUnbounded      -> case cgInteger cfg of
+                                                                    Nothing -> (True, True) -- won't matter, it'll be rejected later
+                                                                    Just i  -> (True, canOverflow True i)
+                                               KList     s     -> die $ "List sort "   ++ show s
+                                               KSet      s     -> die $ "Set sort "    ++ show s
+                                               KTuple    s     -> die $ "Tuple sort "  ++ show s
+                                               KArray    k1 k2 -> die $ "Array  sort " ++ show (k1, k2)
+                                               KApp      s _   -> die $ "ADT app: " ++ s
+                                               KADT      s _ _ -> die $ "ADT: "     ++ s
+
+        -- Integral quotient/remainder use the dedicated GMP or bit-vector
+        -- helpers above. Keep zero-divisor protection in the scalar fallback;
+        -- native IEEE division itself must retain its infinities and NaNs.
+        p (Divides n) [a]    = mappedIntegerDivides n a
+        p Quot        [a, b] = let k = kindOf (hd "Quot" opArgs)
+                                   z = mkConst env $ mkConstCV k (0::Integer)
+                               in protectDiv0 k "/" z a b
+        p Rem         [a, b] = protectDiv0 (kindOf (hd "Rem" opArgs)) "%" a a b
+        p UNeg        [a]    = parens (text "-" <+> a)
+        p Abs         [a]    = let f KFloat             = text "fabsf" P.<> parens a
+                                   f KDouble            = text "fabs"  P.<> parens a
+                                   f (KBounded False _) = text "/* unsigned, skipping call to abs */" <+> a
+                                   f (KBounded True 32) = text "labs"  P.<> parens a
+                                   f (KBounded True 64) = text "llabs" P.<> parens a
+                                   f KUnbounded         = case cgInteger cfg of
+                                                            Nothing -> f $ KBounded True 32 -- won't matter, it'll be rejected later
+                                                            Just i  -> f $ KBounded True i
+                                   f KReal              = case cgReal cfg of
+                                                            Nothing           -> f KDouble -- won't matter, it'll be rejected later
+                                                            Just CgFloat      -> f KFloat
+                                                            Just CgDouble     -> f KDouble
+                                                            Just CgLongDouble -> text "fabsl" P.<> parens a
+                                   f _                  = text "abs" P.<> parens a
+                               in f (kindOf (hd "Abs" opArgs))
+        -- for And/Or, translate to boolean versions if on boolean kind
+        p And [a, b] | kindOf (hd "And" opArgs) == KBool = a <+> text "&&" <+> b
+        p Or  [a, b] | kindOf (hd "Or"  opArgs) == KBool = a <+> text "||" <+> b
+        p o [a, b]
+          | Just co <- lookup o cBinOps
+          = a <+> text co <+> b
+
+        p Implies [a, b] | kindOf (hd "Implies" opArgs) == KBool = parens (text "!" P.<> a <+> text "||" <+> b)
+
+        p NotEqual xs = mkDistinct xs
+        p o args      = die $ "Received operator " ++ show o ++ " applied to " ++ show args
+
+        solverOnly feature = error $ "SBV->C: " ++ feature ++ " has solver-only semantics and cannot be compiled to executable C"
+
+        mappedIntegerDivides divisor value
+          | divisor > maximumMagnitude = parens (value <+> text "==" <+> text "0")
+          | True = parens $ magnitude <+> text "%" <+> uint64 divisor <+> text "==" <+> uint64 0
+          where width = case cgInteger cfg of
+                          Just w  -> w
+                          Nothing -> die "Exact integer divisibility escaped the GMP lowering pipeline"
+
+                maximumMagnitude = 2 ^ (width - 1)
+                magnitude        = parens $ value <+> text "< 0"
+                                         <+> text "?" <+> uint64 0 <+> text "-" <+> asUnsigned value
+                                         <+> text ":" <+> asUnsigned value
+                asUnsigned a     = parens (text "uint64_t") <+> a
+                uint64 n         = text "UINT64_C" P.<> parens (integer n)
+
+        -- generate a pairwise inequality check
+        mkDistinct args = fsep $ andAll $ walk args
+          where walk []     = []
+                walk (e:es) = map (pair e) es ++ walk es
+
+                pair e1 e2  = parens (e1 <+> text "!=" <+> e2)
+
+                -- like punctuate, but more spacing
+                andAll []     = []
+                andAll (d:ds) = go d ds
+                     where go d' [] = [d']
+                           go d' (e:es) = (d' <+> text "&&") : go e es
+
+        -- Div0 needs to protect, but only when the arguments are not float/double. (Div by 0 for those are well defined to be Inf/NaN etc.)
+        protectDiv0 k divOp def a b = case k of
+                                        KFloat  -> res
+                                        KDouble -> res
+                                        _       -> wrap
+           where res  = a <+> text divOp <+> b
+                 wrap = parens (b <+> text "== 0") <+> text "?" <+> def <+> text ":" <+> parens res
+
+-- | Render exact equality over a finite array domain. Each iteration performs
+-- two ordered lookups and an SMT object comparison; no backing arrays are
+-- materialized. Reject excessive domains before any C files are emitted.
+ppArrayEquality :: CgConfig -> [Kind] -> Kind -> Doc
+ppArrayEquality cfg adts kind@(KArray keyKind valueKind)
+  | requiresExtensionalEquality adts (Equal True) [valueKind]
+  = error $ "SBV->C: Nested extensional array equality is not supported: array values of kind " ++ show valueKind
+         ++ " contain arrays. This comparison is not approximated."
+  | cgArrayEqualityMaxKeys cfg == 0
+  = error "SBV->C: Extensional array equality is disabled by cgArrayEqualityLimit 0. Select a positive limit to permit finite-domain comparisons."
+  | Nothing <- cardinality
+  = error $ "SBV->C: Extensional array equality cannot enumerate key domain " ++ show keyKind
+         ++ ". Only supported finite domains can be compared; raising cgArrayEqualityLimit does not enable infinite or unsupported domains."
+  | Just count <- cardinality, count > cgArrayEqualityMaxKeys cfg
+  = error $ "SBV->C: Extensional array equality for " ++ show keyKind ++ " requires " ++ show count
+       ++ " keys, exceeding cgArrayEqualityLimit " ++ show (cgArrayEqualityMaxKeys cfg)
+       ++ ". Raise cgArrayEqualityLimit explicitly to permit this work."
+  | True
+  = text "static SBV_CGEN_UNUSED bool" <+> text (arrayEqualName kind)
+      P.<> parens (text (arrayCType kind ++ " left, " ++ arrayCType kind ++ " right"))
+ $$ text "{"
+ $$ nest 2 (enumerate "sbv_local_key" keyKind compareAt $$ text "return true;")
+ $$ text "}"
+ $$ text ""
+ where cardinality = finiteDomainSize (map snd . adtConstructors adts) keyKind
+
+       compareAt key = text ("const " ++ showCType keyKind ++ " key =") <+> key P.<> semi
+                    $$ text ("const " ++ CTypes.elementCType valueKind ++ " left_value = " ++ arrayReadName kind ++ "(left, key);")
+                    $$ text ("const " ++ CTypes.elementCType valueKind ++ " right_value = " ++ arrayReadName kind ++ "(right, key);")
+                    $$ text "if" P.<> parens (text "!" P.<> parens (byValueEqual cfg True valueKind (text "left_value") (text "right_value")))
+                    $$ nest 2 (text "return false;")
+
+       enumerate scope key yield
+         | key == KBool || key == KBounded False 1
+         = counted scope 2 (\counter -> yield (parens (text "SBool") <+> counter))
+         | key == KFloat   = floating scope key 32 yield
+         | key == KDouble  = floating scope key 64 yield
+         | KFP eb sb <- key = floating scope key (eb + sb) yield
+         | isWideBV key
+         = limbEnumeration scope key (intSizeOf key) yield
+         | isBounded key
+         = let raw       = scope ++ "_raw"
+               keyDoc    = if hasSign key then text scope else text raw
+               signedKey = if hasSign key
+                              then text (showCType key ++ " " ++ scope ++ "; memcpy(&" ++ scope ++ ", &" ++ raw ++ ", sizeof " ++ scope ++ ");")
+                              else empty
+           in text ("uint" ++ show (intSizeOf key) ++ "_t " ++ raw ++ " = 0;")
+           $$ text "do {"
+           $$ nest 2 (signedKey $$ yield keyDoc $$ text ("++" ++ raw ++ ";"))
+           $$ text ("} while (" ++ raw ++ " != 0);")
+         | key == KChar
+         = counted scope 0x30000 yield
+         | isRoundingMode key
+         = counted scope 5 (\counter -> yield (parens (text (showCType key)) <+> counter))
+         | KTuple fields <- key
+         = enumerateFields scope fields (yield . tupleValue key)
+         | isConcreteADTReference key
+         = vcat [ text "{" $$ nest 2 (enumerateFields (scope ++ "_c" ++ show index) fields (yield . adtValue adts key index)) $$ text "}"
+                | (index, (_, fields)) <- zip [1 :: Int ..] (adtConstructors adts key)]
+         | True
+         = die $ "Cannot enumerate array key kind " ++ show key
+
+       limbEnumeration :: String -> Kind -> Int -> (Doc -> Doc) -> Doc
+       limbEnumeration scope key width yield =
+         let limbCount  = (width + 63) `div` 64
+             limb index = scope ++ ".limb[" ++ show index ++ "]"
+             topMask    = 2 ^ (1 + (width - 1) `mod` 64) - 1 :: Integer
+         in text (showCType key ++ " " ++ scope ++ " = {{0}};")
+         $$ text "do {"
+         $$ nest 2 (yield (text scope)
+                 $$ text ("for (size_t i = 0; i < " ++ show limbCount ++ "; ++i) { if (++" ++ scope ++ ".limb[i] != 0) break; }")
+                 $$ text (limb (limbCount - 1) ++ " &= UINT64_C(" ++ show topMask ++ ");"))
+         $$ text ("} while (" ++ intercalate " || " [limb i ++ " != 0" | i <- [0 .. limbCount - 1]] ++ ");")
+
+       floating :: String -> Kind -> Int -> (Doc -> Doc) -> Doc
+       floating scope key width yield =
+         let seen        = scope ++ "_nan_seen"
+             visit value = text "const bool is_nan =" <+> (if isFP key then arbitraryFPIsNaN key value else text "isnan" P.<> parens value) P.<> semi
+                        $$ text ("if (!is_nan || !" ++ seen ++ ") {")
+                        $$ nest 2 (text (seen ++ " |= is_nan;") $$ yield value)
+                        $$ text "}"
+             raw         = scope ++ "_raw"
+             nativeLoop = text ("uint" ++ show width ++ "_t " ++ raw ++ " = 0;")
+                       $$ text "do {"
+                       $$ nest 2 (text (showCType key ++ " " ++ scope ++ "; memcpy(&" ++ scope ++ ", &" ++ raw ++ ", sizeof " ++ scope ++ ");")
+                               $$ visit (text scope) $$ text ("++" ++ raw ++ ";"))
+                       $$ text ("} while (" ++ raw ++ " != 0);")
+         in text ("bool " ++ seen ++ " = false;")
+         $$ if isFP key then limbEnumeration scope key width visit else nativeLoop
+
+       enumerateFields scope fields yield = fieldsFrom (1 :: Int) fields []
+         where fieldsFrom _ [] values = yield (reverse values)
+               fieldsFrom index (field:rest) values = enumerate (scope ++ "_f" ++ show index) field
+                                                         (\value -> fieldsFrom (index + 1) rest (value : values))
+
+       counted scope count yield = text ("for (uint32_t " ++ scope ++ " = 0; " ++ scope ++ " < " ++ show (count :: Integer) ++ "; ++" ++ scope ++ ") {")
+                                $$ nest 2 (yield (text scope))
+                                $$ text "}"
+ppArrayEquality _ _ kind = die $ "Expected an array equality kind, received " ++ show kind
+
+-- | Detect comparisons that transitively require array equality, resolving
+-- recursive ADT references without revisiting already inspected definitions.
+-- Array-valued data can still be constructed, selected, and transported.
+requiresExtensionalEquality :: [Kind] -> Op -> [Kind] -> Bool
+requiresExtensionalEquality adts op kinds = comparesElements op && any (containsArray Set.empty) kinds
+ where comparesElements Equal{}               = True
+       comparesElements NotEqual              = True
+       comparesElements (SeqOp SeqIndexOf{})   = True
+       comparesElements (SeqOp SeqContains{})  = True
+       comparesElements (SeqOp SeqPrefixOf{})  = True
+       comparesElements (SeqOp SeqSuffixOf{})  = True
+       comparesElements (SeqOp SeqReplace{})   = True
+       comparesElements _                     = False
+
+       containsArray _       KArray{}            = True
+       containsArray visited (KList elementKind)  = containsArray visited elementKind
+       containsArray visited (KSet elementKind)   = containsArray visited elementKind
+       containsArray visited (KTuple fields)      = any (containsArray visited) fields
+       containsArray visited kind
+         | isConcreteADTReference kind
+         , kind `Set.notMember` visited
+         = any (any (containsArray (Set.insert kind visited)) . snd) (adtConstructors adts kind)
+         | True
+         = False
+
+-- | Quote a document after removing line breaks, for generated format strings.
+printQuotes :: Doc -> Doc
+printQuotes d = text $ '"' : ppSameLine d ++ "\""
+
+-- | Flatten a document onto one line for generated build commands and labels.
+ppSameLine :: Doc -> String
+ppSameLine = trim . render
+ where trim ""        = ""
+       trim ('\n':cs) = ' ' : trim (dropWhile isSpace cs)
+       trim (c:cs)    = c   : trim cs
+
+-- | Left-pad documents so their rendered representations have equal width.
+align :: [Doc] -> [Doc]
+align ds = map (text . pad) ss
+  where ss    = map render ds
+        l     = maximum (0 : map length ss)
+        pad s = replicate (l - length s) ' ' ++ s
+
+-- | Merge component bundles. Code-generation options have already been
+-- applied per component; the returned config describes the merged artifacts
+-- and permits overwriting only when every component explicitly permits it.
+-- Other returned settings are representative of the first component.
+mergeToLib :: String -> [(CgConfig, CgPgmBundle)] -> (CgConfig, CgPgmBundle)
+mergeToLib libName cfgBundles
+  | length nubKinds /= 1
+  = error $  "Cannot merge programs with differing SInteger/SReal mappings. Received the following kinds:\n"
+          ++ unlines (map show nubKinds)
+  | not (null duplicateFiles)
+  = error $ "SBV.compileToCLib: Conflicting generated file names: " ++ unwords duplicateFiles
+  | not (null duplicateSymbols)
+  = error $ "SBV.compileToCLib: Conflicting generated entry points: " ++ unwords duplicateSymbols
+  | True
+  = (finalCfg, CgPgmBundle bundleKind resultFiles)
+  where bundles     = map snd cfgBundles
+        kinds       = [k | CgPgmBundle k _ <- bundles]
+        nubKinds    = nub kinds
+        bundleKind  = case nubKinds of
+                        bk:_ -> bk
+                        []   -> error "Data.SBV.C: Impossible happened: mergeLibs: kinds ended up being empty!"
+        files       = concat [fs | CgPgmBundle _ fs <- bundles]
+        headerMeta  = [metadata | (_, (CgCHeader metadata, _)) <- files]
+        typeDecls   = uniqueOn render (map cgHeaderTypes headerMeta)
+        sigs        = concatMap cgHeaderSignatures headerMeta
+        extProtos   = vcat $ uniqueOn render (map cgHeaderPrototypes headerMeta)
+        floating    = any cgHeaderFloating headerMeta
+        anyMake     = any (cgGenMakefile . fst) cfgBundles
+        drivers     = [(takeBaseName sourceName, ds)
+                      | (_, CgPgmBundle _ componentFiles) <- cfgBundles
+                      , (sourceName, (CgSource, _)) <- componentFiles
+                      , (_, (CgDriver, ds)) <- componentFiles
+                      ]
+        anyDriver   = not (null drivers)
+        mkFlags     = nub (concat [xs | (_, (CgMakefile xs, _)) <- files])
+        sources     = [(f, (CgSource, replaceHeader f parts)) | (f, (CgSource, parts)) <- files]
+        replaceHeader _ [pre, _, post] = [pre, libHInclude, post]
+        replaceHeader f _ = die $ "Invalid C source bundle layout for " ++ f
+        sourceNms   = map fst sources
+        libHeader   = (libName ++ ".h", (CgCHeader (CgCHeaderInfo floating (vcat typeDecls) sigs extProtos), [genHeader floating bundleKind libName sigs extProtos (vcat typeDecls)]))
+        libHInclude =  text "#include" <+> text (show (libName ++ ".h"))
+                    $$ if "-lbf" `elem` mkFlags then text "#include <libbf.h>" else empty
+        libMake     = ("Makefile", (CgMakefile mkFlags, [genLibMake floating anyDriver libName sourceNms mkFlags]))
+        libDriver   = (libName ++ "_driver.c", (CgDriver, mergeDrivers libName libHInclude drivers))
+        resultFiles = sources ++ libHeader : [libDriver | anyDriver] ++ [libMake | anyMake]
+        duplicateFiles = duplicateNames (map (map toLower . fst) resultFiles)
+        duplicateSymbols = duplicateNames $ map takeBaseName sourceNms ++ [fn ++ "_driver" | (fn, _) <- drivers] ++ ["main" | anyDriver]
+        finalCfg    = case cfgBundles of
+                        []         -> defaultCgConfig
+                        ((c, _):_) -> c { cgGenDriver = anyDriver
+                                        , cgGenMakefile = anyMake
+                                        , cgOverwriteGenerated = all (cgOverwriteGenerated . fst) cfgBundles
+                                        }
+
+-- | Create a Makefile for the library
+genLibMake :: Bool -> Bool -> String -> [String] -> [String] -> Doc
+genLibMake floating ifdr libName fs ldFlags = foldr1 ($$) [l | (True, l) <- lns]
+ where ifld = not (null ldFlags)
+       gmp  = "-lgmp" `elem` ldFlags
+       ld = text "${LDFLAGS}" <+> if ifld then text "${SBV_LIBS}" else empty
+       renderedLDFlags = unwords $ filter (/= "-lgmp") ldFlags ++ ["${GMP_LIBS}" | gmp]
+       lns = [ (True, text "# Makefile for" <+> nm P.<> text ". Automatically generated by SBV. Do not edit!")
+             , (True,  text "")
+             , (True,  text "# include any user-defined .mk file in the current directory.")
+             , (True,  text "-include *.mk")
+             , (True,  text "")
+             , (True,  text "CC?=gcc")
+             , (True,  text "CCFLAGS?=-Wall -O3 -DNDEBUG -fomit-frame-pointer")
+             , (gmp,   text "GMP_CFLAGS?=$(shell pkg-config --cflags gmp)")
+             , (gmp,   text "GMP_LIBS?=$(shell pkg-config --libs gmp)")
+             , (ifld,  text "SBV_LIBS?=" P.<> text renderedLDFlags)
+             , (True,  text "AR?=ar")
+             , (True,  text "ARFLAGS?=cr")
+             , (True,  text "")
+             , (not ifdr,  text ("all: " ++ liba))
+             , (ifdr,      text ("all: " ++ unwords [liba, libd]))
+             , (True,  text "")
+             , (True,  text liba P.<> text (": " ++ unwords os))
+             , (True,  text "\trm -f $@.tmp")
+             , (True,  text "\t${AR} ${ARFLAGS} $@.tmp $^")
+             , (True,  text "\tmv -f $@.tmp $@")
+             , (True,  text "")
+             , (ifdr,  text libd P.<> text (": " ++ unwords [libd ++ ".c", libh, liba]))
+             , (ifdr,  text ("\t" ++ cCompilerCommand floating gmp ++ " $< -o $@ " ++ liba) <+> ld)
+             , (ifdr,  text "")
+             , (True,  vcat (zipWith mkObj os fs))
+             , (True,  text "clean:")
+             , (True,  text "\trm -f *.o")
+             , (True,  text "")
+             , (True,  text "veryclean: clean")
+             , (not ifdr,  text "\trm -f" <+> text (unwords [liba, liba ++ ".tmp"]))
+             , (ifdr,      text "\trm -f" <+> text (unwords [liba, libd, liba ++ ".tmp"]))
+             , (True,  text "")
+             ]
+       nm = text libName
+       liba = libName ++ ".a"
+       libh = libName ++ ".h"
+       libd = libName ++ "_driver"
+       os   = map (`replaceExtension` ".o") fs
+       mkObj o f =  text o P.<> text (": " ++ unwords [f, libh])
+                 $$ text ("\t" ++ cCompilerCommand floating gmp ++ " -c $< -o $@")
+                 $$ text ""
+
+-- | Create a driver for a library
+mergeDrivers :: String -> Doc -> [(FilePath, [Doc])] -> [Doc]
+mergeDrivers libName inc ds = pre : concatMap mkDFun ds ++ [callDrivers (map fst ds)]
+  where pre =  text "/* Example driver program for" <+> text libName P.<> text ". */"
+            $$ text "/* Automatically generated by SBV. Edit as you see fit! */"
+            $$ text ""
+            $$ text "#include <stdio.h>"
+            $$ inc
+        mkDFun (f, [_pre, _include, callbacks, helpers, _header, body, _post]) = [callbacks, helpers, header, body, post]
+           where header =  text ""
+                        $$ text ("void " ++ f ++ "_driver(void)")
+                        $$ text "{"
+                 post   =  text "}"
+        mkDFun (f, _) = die $ "mergeDrivers: non-conforming driver program for " ++ show f
+        callDrivers fs =   text ""
+                       $$  text "int main(void)"
+                       $$  text "{"
+                       $+$ nest 2 (vcat (map call fs))
+                       $$  nest 2 (text "return 0;")
+                       $$  text "}"
+        call f =  text psep
+               $$ text ptag
+               $$ text psep
+               $$ text (f ++ "_driver();")
+               $$ text ""
+           where tag  = "** Driver run for " ++ f ++ ":"
+                 ptag = "printf(\"" ++ tag ++ "\\n\");"
+                 lsep = replicate (length tag) '='
+                 psep = "printf(\"" ++ lsep ++ "\\n\");"
+
+-- | Return the runtime requirements introduced by a legacy scalar operation.
+operationRequirements :: CgConfig -> (Op, Kind) -> Set.Set CRequirement
+operationRequirements cfg (o, k) = Set.fromList (required o)
+  where required (IEEEFP FP_Cast{}) = math
+        required castOp@KindCast{}
+          | Just _ <- mappedRealFloorWidth cfg castOp = math
+        required (IEEEFP fop)
+          | fop `elem` requiresMath = math
+        required Abs
+          | usesNativeFloatingPoint k = math
+        required _ = []
+
+        math = [CRequiresLibM]
+
+        usesNativeFloatingPoint KFloat = True
+        usesNativeFloatingPoint KDouble = True
+        usesNativeFloatingPoint KReal   = not (isExactGMPKind cfg KReal)
+        usesNativeFloatingPoint _       = False
+
+        requiresMath = [ FP_Abs
+                       , FP_FMA
+                       , FP_Sqrt
+                       , FP_Rem
+                       , FP_Min
+                       , FP_Max
+                       , FP_RoundToIntegral
+                       , FP_ObjEqual
+                       , FP_IsSubnormal
+                       , FP_IsInfinite
+                       , FP_IsNaN
+                       , FP_IsNegative
+                       , FP_IsPositive
+                       , FP_IsNormal
+                       , FP_IsZero
+                       ]
+
+-- | Translate collected runtime requirements to external C linker options.
+requirementLDFlags :: Set.Set CRequirement -> [String]
+requirementLDFlags requirements =
+  [ flag
+  | (requirement, flag) <- [ (CRequiresGMP, "-lgmp")
+                           , (CRequiresLibBF, "-lbf")
+                           , (CRequiresLibM, "-lm")
+                           ]
+  , requirement `Set.member` requirements
+  ]
+
+{- HLint ignore module "Redundant lambda" -}
diff --git a/Data/SBV/Compilers/C/FP.hs b/Data/SBV/Compilers/C/FP.hs
new file mode 100644
--- /dev/null
+++ b/Data/SBV/Compilers/C/FP.hs
@@ -0,0 +1,1261 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Data.SBV.Compilers.C.FP
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- LibBF-backed lowering of arbitrary IEEE-754 floating-point values to C.
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Data.SBV.Compilers.C.FP
+  ( arbitraryFPKinds
+  , roundingModeTypeDecls
+  , roundingModeConst
+  , roundingModeDriverValue
+  , arbitraryFPTypeDecls
+  , arbitraryFPRuntime
+  , arbitraryFPConst
+  , arbitraryFPExpr
+  , nativeFPRuntime
+  , nativeFPExpr
+  , nativeFPCompilePragmas
+  , arbitraryFPNormalize
+  , arbitraryFPPrint
+  , arbitraryFPCType
+  , arbitraryFPEqual
+  , arbitraryFPObjectEqual
+  , arbitraryFPIsNaN
+  , nativeFPObjectEqual
+  ) where
+
+import Data.SBV.Compilers.C.Syntax (cUnusedAttribute)
+import Data.Bits                       (shiftL, shiftR, (.&.))
+import Data.List                       (intercalate, nub, tails)
+import qualified Data.Set as Set
+import Numeric                         (showHex)
+
+import qualified LibBF as BF
+
+import Text.PrettyPrint.HughesPJ
+import qualified Text.PrettyPrint.HughesPJ as P ((<>))
+
+import Data.SBV.Compilers.C.BV        (isWideBV, mappedIntegerKind)
+import Data.SBV.Compilers.C.GMP       (isExactGMPKind)
+import Data.SBV.Compilers.C.Lowering  (CLowering, CRequirement(..), expressionLowering)
+import Data.SBV.Compilers.C.Real      (mappedRealFloorWidth)
+import Data.SBV.Compilers.CodeGen      (CgConfig(..), CgSRealType(..))
+import Data.SBV.Core.Data
+import Data.SBV.Core.SizedFloats       (FP(..), mkBFOpts)
+
+-- | Disable implicit contraction in generated translation units without
+-- changing the caller's compilation state through a public header. The
+-- Makefiles also pass @-ffp-contract=off@: Clang can ignore these pragmas when
+-- contraction is explicitly enabled on the command line. Explicit FMA calls
+-- retain their single-rounding semantics.
+nativeFPCompilePragmas :: Doc
+nativeFPCompilePragmas = text . unlines $
+  ["/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */"
+  , "#if defined(__clang__)"
+  , "#pragma STDC FP_CONTRACT OFF"
+  , "#endif"
+  , ""]
+
+-- | The distinct arbitrary floating-point kinds used by a program.
+arbitraryFPKinds :: Set.Set Kind -> [Kind]
+arbitraryFPKinds = map validate . filter isFP . Set.toAscList
+ where validate k@(KFP eb _)
+         | eb <= 61 = k
+         | True     = error $ "SBV->C: LibBF supports arbitrary floating-point exponent widths only up to 61 bits, received " ++ show k
+       validate k = error $ "SBV->C: Expected an arbitrary floating-point kind, received " ++ show k
+
+-- | Declare the public C enumeration used for symbolic rounding modes.
+roundingModeTypeDecls :: Bool -> Doc
+roundingModeTypeDecls required
+  | required = text . unlines $
+      ["/* IEEE-754 rounding modes. */"
+      , "#ifndef SBV_ROUNDING_MODE_DEFINED"
+      , "#define SBV_ROUNDING_MODE_DEFINED"
+      , "typedef enum { SBV_RM_RNE = 0, SBV_RM_RNA = 1, SBV_RM_RTP = 2, SBV_RM_RTN = 3, SBV_RM_RTZ = 4 } RoundingMode;"
+      , "#endif"
+      , ""]
+  | True     = empty
+
+-- | Render an SBV rounding-mode constant as a public C enumerator.
+roundingModeConst :: CV -> Maybe Doc
+roundingModeConst (CV k (CADT (constructorName, [])))
+  | isRoundingMode k = text . fst <$> lookup constructorName roundingModeNames
+roundingModeConst _ = Nothing
+
+-- | Select a deterministic rounding-mode enumerator for a generated driver.
+roundingModeDriverValue :: Integer -> Doc
+roundingModeDriverValue sample = text cName
+ where (cName, _) = map snd roundingModeNames !! fromInteger (sample `mod` toInteger (length roundingModeNames))
+
+-- | Declare the raw IEEE interchange representation used at the public C ABI.
+arbitraryFPTypeDecls :: [Kind] -> Doc
+arbitraryFPTypeDecls [] = empty
+arbitraryFPTypeDecls ks = text . unlines $
+     ["/* Arbitrary IEEE-754 values, encoded as raw interchange bits. */"
+     , cUnusedAttribute]
+  ++ concatMap decl ks
+ where decl k = ["#ifndef " ++ typeGuard k
+                , "#define " ++ typeGuard k
+                , "typedef struct { uint64_t limb[" ++ show (limbs k) ++ "]; } " ++ arbitraryFPCType k ++ ";"
+                , "static inline SBV_CGEN_UNUSED void " ++ prefix k ++ "_fprint(FILE *stream, " ++ arbitraryFPCType k ++ " value)"
+                , "{"
+                , "  size_t i = " ++ show (limbs k) ++ ";"
+                , "  fputs(\"0x\", stream);"
+                , "  while (i-- > 0) fprintf(stream, \"%016\" PRIx64, value.limb[i]);"
+                , "}"
+                , "#endif"
+                , ""]
+
+       typeGuard (KFP eb sb) = "SBV_FP_E" ++ show eb ++ "_S" ++ show sb ++ "_DEFINED"
+       typeGuard k           = error $ "SBV->C: Expected an arbitrary floating-point kind, received " ++ show k
+
+-- | Emit the LibBF adapter and helpers for arbitrary formats and conversions
+-- that require exact rounding.
+arbitraryFPRuntime :: CgConfig -> [Kind] -> [(SV, SBVExpr)] -> Doc
+arbitraryFPRuntime cfg ks asgns
+  | null ks && null floatCasts = empty
+  | True                       = text . unlines . map markUnused $
+     ["/* LibBF-backed arbitrary floating-point runtime. */"
+     , cUnusedAttribute
+     , ""
+     , "static inline bf_rnd_t sbv_bf_rounding_mode(int mode)"
+     , "{"
+     , "  switch (mode) {"
+     , "    case 0: return BF_RNDN;"
+     , "    case 1: return BF_RNDNA;"
+     , "    case 2: return BF_RNDU;"
+     , "    case 3: return BF_RNDD;"
+     , "    case 4: return BF_RNDZ;"
+     , "    default: abort();"
+     , "  }"
+     , "}"
+     , ""
+     , "static void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)"
+     , "{"
+     , "  (void) opaque;"
+     , "  return realloc(ptr, size);"
+     , "}"
+     , ""]
+  ++ concatMap formatRuntime ks
+  ++ concat [exactBridgeRuntime | any castUsesExact floatCasts]
+  ++ concat [longDoubleBridgeRuntime | cgReal cfg == Just CgLongDouble, any castUsesReal floatCasts]
+  ++ concatMap reinterpretRuntime (nub (concatMap reinterprets asgns))
+  ++ concatMap (castRuntime cfg) floatCasts
+ where markUnused line = case splitAt 7 line of
+                           ("static ", rest) -> "static SBV_CGEN_UNUSED " ++ rest
+                           _                 -> line
+
+       reinterprets (_, SBVApp (IEEEFP (FP_Reinterpret fr to)) _)
+         | isFP fr || isFP to = [Reinterpret fr to]
+       reinterprets _ = []
+
+       casts (_, SBVApp (IEEEFP (FP_Cast fr to _)) _)
+         | supportedFPCast cfg fr to
+         , not (exactNativeFPCast (floatCastKind cfg fr) (floatCastKind cfg to)) = [FloatCast fr to]
+       casts (_, SBVApp castOp@(KindCast fr to) _)
+         | Nothing <- mappedRealFloorWidth cfg castOp
+         , mappedFloatCast cfg fr to = [FloatCast fr to]
+       casts _ = []
+
+       floatCasts = nub (concatMap casts asgns)
+
+       castUsesExact (FloatCast fr to) = isExactGMPKind cfg fr || isExactGMPKind cfg to
+       castUsesReal  (FloatCast fr to) = KReal `elem` [fr, to]
+
+-- | Shared ownership predicate for cast lowering and helper emission. Keeping
+-- this decision in one place prevents generation of calls without definitions.
+supportedFPCast :: CgConfig -> Kind -> Kind -> Bool
+supportedFPCast cfg fr to = isFP fr || isFP to || mappedFloatCast cfg fr to
+                        || (native fr && (native to || isBounded to || isExactGMPKind cfg to))
+                        || (native to && (isBounded fr || isExactGMPKind cfg fr))
+ where native kind = isFloat kind || isDouble kind
+
+-- | Render an arbitrary floating-point constant in raw interchange form.
+arbitraryFPConst :: Kind -> FP -> Maybe Doc
+arbitraryFPConst k@(KFP eb sb) (FP _ _ value) = Just . text $ rawLiteral k bits
+ where bits = BF.bfToBits (mkBFOpts eb sb BF.NearEven) value
+arbitraryFPConst _ _ = Nothing
+
+-- | Lower an operation requiring LibBF-backed floating-point semantics. A
+-- 'Nothing' result delegates native RNE operations, table lookup, and
+-- user-defined functions to the general C renderer.
+-- Numeric floating casts use the bridge unless their native conversion is
+-- provably exact: C casts and @rint@ would otherwise depend on the caller's
+-- hardware rounding mode, even for RNE.
+arbitraryFPExpr :: CgConfig -> [(SV, CV)] -> Op -> [SV] -> Kind -> [Doc] -> Maybe CLowering
+arbitraryFPExpr cfg consts op svs resultKind args
+  | Just _ <- mappedRealFloorWidth cfg op
+  = Nothing
+  | IEEEFP (FP_Cast fr to rm) <- op
+  , let target = floatCastKind cfg to
+  , exactNativeFPCast (floatCastKind cfg fr) target
+  , value:_ <- reverse args
+  , let ignored = maybe [text (show rm)] (const []) (lookup rm consts)
+  , let cast = parens (text (if isFloat target then "SFloat" else "SDouble")) <+> value
+  = Just . expressionLowering [] $ case ignored of
+      [] -> cast
+      _  -> parens $ fsep (punctuate comma (map (text "(void)" <+>) ignored ++ [cast]))
+  | not (isFP resultKind
+      || any (isFP . kindOf) svs
+      || isSupportedCast)
+  = Nothing
+  | LkUp{} <- op
+  = Nothing
+  | Uninterpreted{} <- op
+  = Nothing
+  | True
+  = Just . expressionLowering requirements $ case (op, args, svs) of
+      (Label _         , [a]         , _)            -> a
+      (UNeg            , [a]         , x:_)          -> argCall x "neg" [a]
+      (Abs             , [a]         , x:_)          -> argCall x "abs" [a]
+      (Plus            , [a, b]      , x:_)          -> argCall x "add" [a, b, text "BF_RNDN"]
+      (Minus           , [a, b]      , x:_)          -> argCall x "sub" [a, b, text "BF_RNDN"]
+      (Times           , [a, b]      , x:_)          -> argCall x "mul" [a, b, text "BF_RNDN"]
+      (Quot            , [a, b]      , x:_)          -> argCall x "div" [a, b, text "BF_RNDN"]
+      (Equal False     , [a, b]      , x:_)          -> argCall x "eq" [a, b]
+      (Equal True      , [a, b]      , x:_)          -> argCall x "obj_eq" [a, b]
+      (NotEqual        , as          , x:_)          -> distinctExpr x as
+      (LessThan        , [a, b]      , x:_)          -> argCall x "lt" [a, b]
+      (GreaterThan     , [a, b]      , x:_)          -> argCall x "lt" [b, a]
+      (LessEq          , [a, b]      , x:_)          -> argCall x "le" [a, b]
+      (GreaterEq       , [a, b]      , x:_)          -> argCall x "le" [b, a]
+      (IEEEFP fpOp     , as          , fpArgs)       -> fpExpr fpOp as fpArgs
+      (KindCast fr to  , [a]         , _)            -> namedCall (castName fr to)
+                                                         ([text "&sbv_local_gmp_ctx" | isExactGMPKind cfg to]
+                                                       ++ [a, text (if fr == KReal && to == KUnbounded then "BF_RNDD" else "BF_RNDN")])
+      _                                              -> unsupported
+ where argCall sv suffix = namedCall (prefix (kindOf sv) ++ "_" ++ suffix)
+
+       distinctExpr sv as = fsep $ punctuate (text " &&")
+                                  [text "!" P.<> parens (argCall sv "eq" [a, b])
+                                  | (a:rest) <- tails as, b <- rest]
+
+       fpExpr fpOp as fpArgs = case (fpOp, as, fpArgs) of
+         (FP_Abs              , [a]           , x:_)    -> argCall x "abs" [a]
+         (FP_Neg              , [a]           , x:_)    -> argCall x "neg" [a]
+         (FP_Add              , [_rm, a, b]   , r:x:_)  -> argCall x "add" [a, b, bfRoundingMode consts r]
+         (FP_Sub              , [_rm, a, b]   , r:x:_)  -> argCall x "sub" [a, b, bfRoundingMode consts r]
+         (FP_Mul              , [_rm, a, b]   , r:x:_)  -> argCall x "mul" [a, b, bfRoundingMode consts r]
+         (FP_Div              , [_rm, a, b]   , r:x:_)  -> argCall x "div" [a, b, bfRoundingMode consts r]
+         (FP_FMA              , [_rm, a, b, c], r:x:_)  -> argCall x "fma" [a, b, c, bfRoundingMode consts r]
+         (FP_Sqrt             , [_rm, a]      , r:x:_)  -> argCall x "sqrt" [a, bfRoundingMode consts r]
+         (FP_Rem              , [a, b]        , x:_)    -> argCall x "rem" [a, b]
+         (FP_RoundToIntegral  , [_rm, a]      , r:x:_)  -> argCall x "round" [a, bfRoundingMode consts r]
+         (FP_Min              , [a, b]        , x:_)    -> argCall x "min" [a, b]
+         (FP_Max              , [a, b]        , x:_)    -> argCall x "max" [a, b]
+         (FP_ObjEqual         , [a, b]        , x:_)    -> argCall x "obj_eq" [a, b]
+         (FP_IsNormal         , [a]           , x:_)    -> argCall x "is_normal" [a]
+         (FP_IsSubnormal      , [a]           , x:_)    -> argCall x "is_subnormal" [a]
+         (FP_IsZero           , [a]           , x:_)    -> argCall x "is_zero" [a]
+         (FP_IsInfinite       , [a]           , x:_)    -> argCall x "is_infinite" [a]
+         (FP_IsNaN            , [a]           , x:_)    -> argCall x "is_nan" [a]
+         (FP_IsNegative       , [a]           , x:_)    -> argCall x "is_negative" [a]
+         (FP_IsPositive       , [a]           , x:_)    -> argCall x "is_positive" [a]
+         (FP_Reinterpret fr to, [a]           , _)      -> namedCall (reinterpretName fr to) [a]
+         (FP_Cast fr to rm    , [a]           , _)      -> namedCall (castName fr to) (castArgs to a rm)
+         (FP_Cast fr to rm    , [_rm, a]      , _)      -> namedCall (castName fr to) (castArgs to a rm)
+         _                                              -> unsupported
+
+       castArgs to a rm
+         | isExactGMPKind cfg to = [text "&sbv_local_gmp_ctx", a, bfRoundingMode consts rm]
+         | True                  = [a, bfRoundingMode consts rm]
+
+       requirements = [CRequiresLibBF, CRequiresLibM] ++ [CRequiresGMP | usesExact]
+
+       usesExact = isExactGMPKind cfg resultKind || any (isExactGMPKind cfg . kindOf) svs
+
+       isSupportedCast = case op of
+         IEEEFP (FP_Cast fr to _) -> supportedFPCast cfg fr to
+         KindCast fr to          -> mappedFloatCast cfg fr to
+         _                        -> False
+
+       unsupported = error $ "SBV->C: arbitrary floating-point lowering does not yet support " ++ show op
+                          ++ " with argument kinds " ++ show (map kindOf svs)
+                          ++ " and result kind " ++ show resultKind
+
+-- | Identify scalar casts whose entire source range is exactly representable
+-- in the destination. No rounding, software adapter, or hardware rounding-mode
+-- change is needed for any valid SBV rounding mode.
+exactNativeFPCast :: Kind -> Kind -> Bool
+exactNativeFPCast from to
+  | to `notElem` [KFloat, KDouble] = False
+  | from == to                   = True
+  | from == KFloat, to == KDouble = True
+  | isBounded from
+  , not (isWideBV from)           = intSizeOf from - (if hasSign from then 1 else 0) <= significandBits to
+  | True                         = False
+
+-- | Emit LibBF adapters for native 'SFloat' and 'SDouble' operations whose
+-- rounding mode cannot safely be expressed as an ordinary C expression.
+nativeFPRuntime :: Doc
+nativeFPRuntime = text . unlines . map markUnused $
+     ["/* Exact rounding adapters for native floating-point operations. */"
+     , cUnusedAttribute
+     , ""
+     , "static inline bf_rnd_t sbv_native_bf_rounding_mode(int mode)"
+     , "{"
+     , "  switch (mode) {"
+     , "    case 0: return BF_RNDN;"
+     , "    case 1: return BF_RNDNA;"
+     , "    case 2: return BF_RNDU;"
+     , "    case 3: return BF_RNDD;"
+     , "    case 4: return BF_RNDZ;"
+     , "    default: abort();"
+     , "  }"
+     , "}"
+     , ""
+     , "static void *sbv_native_bf_realloc(void *opaque, void *ptr, size_t size)"
+     , "{"
+     , "  (void) opaque;"
+     , "  return realloc(ptr, size);"
+     , "}"
+     , ""
+     ]
+  ++ concatMap format [("SFloat", "float", 24, 8), ("SDouble", "double", 53, 11)]
+ where markUnused line = case splitAt 14 line of
+                           ("static inline ", rest) -> "static inline SBV_CGEN_UNUSED " ++ rest
+                           _                        -> line
+
+       format :: (String, String, Int, Int) -> [String]
+       format (cType, tag, precision, exponentBits) =
+            ["static inline bf_flags_t sbv_native_" ++ tag ++ "_flags(bf_rnd_t rnd)"
+            , "{ return (bf_flags_t) rnd | BF_FLAG_SUBNORMAL | bf_set_exp_bits(" ++ show exponentBits ++ "); }"
+            , ""
+            , "static inline " ++ cType ++ " sbv_native_" ++ tag ++ "_finish(bf_t *value, bf_rnd_t rnd)"
+            , "{"
+            , "  double result;"
+            , "  bf_get_float64(value, &result, rnd);"
+            , "  return (" ++ cType ++ ") result;"
+            , "}"
+            , ""
+            , "static inline " ++ cType ++ " sbv_native_" ++ tag ++ "_binary(" ++ cType ++ " a, " ++ cType ++ " b, bf_rnd_t rnd, int op)"
+            , "{"
+            , "  bf_context_t ctx; bf_t x, y, r; " ++ cType ++ " result;"
+            , "  bf_context_init(&ctx, sbv_native_bf_realloc, NULL); bf_init(&ctx, &x); bf_init(&ctx, &y); bf_init(&ctx, &r);"
+            , "  bf_set_float64(&x, (double) a); bf_set_float64(&y, (double) b);"
+            , "  if (op == 0) bf_add(&r, &x, &y, " ++ show precision ++ ", sbv_native_" ++ tag ++ "_flags(rnd));"
+            , "  else if (op == 1) bf_sub(&r, &x, &y, " ++ show precision ++ ", sbv_native_" ++ tag ++ "_flags(rnd));"
+            , "  else if (op == 2) bf_mul(&r, &x, &y, " ++ show precision ++ ", sbv_native_" ++ tag ++ "_flags(rnd));"
+            , "  else bf_div(&r, &x, &y, " ++ show precision ++ ", sbv_native_" ++ tag ++ "_flags(rnd));"
+            , "  result = sbv_native_" ++ tag ++ "_finish(&r, rnd);"
+            , "  bf_delete(&r); bf_delete(&y); bf_delete(&x); bf_context_end(&ctx); return result;"
+            , "}"
+            , ""
+            ]
+         ++ concatMap (binaryWrapper cType tag) [("add", 0), ("sub", 1), ("mul", 2), ("div", 3)]
+         ++ ["static inline " ++ cType ++ " sbv_native_" ++ tag ++ "_sqrt(" ++ cType ++ " a, bf_rnd_t rnd)"
+            , "{"
+            , "  bf_context_t ctx; bf_t x, r; " ++ cType ++ " result;"
+            , "  bf_context_init(&ctx, sbv_native_bf_realloc, NULL); bf_init(&ctx, &x); bf_init(&ctx, &r); bf_set_float64(&x, (double) a);"
+            , "  bf_sqrt(&r, &x, " ++ show precision ++ ", sbv_native_" ++ tag ++ "_flags(rnd)); result = sbv_native_" ++ tag ++ "_finish(&r, rnd);"
+            , "  bf_delete(&r); bf_delete(&x); bf_context_end(&ctx); return result;"
+            , "}"
+            , ""
+            , "static inline " ++ cType ++ " sbv_native_" ++ tag ++ "_round(" ++ cType ++ " a, bf_rnd_t rnd)"
+            , "{"
+            , "  bf_context_t ctx; bf_t x; " ++ cType ++ " result;"
+            , "  bf_context_init(&ctx, sbv_native_bf_realloc, NULL); bf_init(&ctx, &x); bf_set_float64(&x, (double) a);"
+            , "  bf_rint(&x, rnd); result = sbv_native_" ++ tag ++ "_finish(&x, rnd);"
+            , "  bf_delete(&x); bf_context_end(&ctx); return result;"
+            , "}"
+            , ""
+            , "static inline " ++ cType ++ " sbv_native_" ++ tag ++ "_fma(" ++ cType ++ " a, " ++ cType ++ " b, " ++ cType ++ " c, bf_rnd_t rnd)"
+            , "{"
+            , "  bf_context_t ctx; bf_t x, y, z, r; " ++ cType ++ " result;"
+            , "  bf_context_init(&ctx, sbv_native_bf_realloc, NULL); bf_init(&ctx, &x); bf_init(&ctx, &y); bf_init(&ctx, &z); bf_init(&ctx, &r);"
+            , "  bf_set_float64(&x, (double) a); bf_set_float64(&y, (double) b); bf_set_float64(&z, (double) c);"
+            , "  bf_mul(&r, &x, &y, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDN);"
+            , "  bf_add(&r, &r, &z, " ++ show precision ++ ", sbv_native_" ++ tag ++ "_flags(rnd)); result = sbv_native_" ++ tag ++ "_finish(&r, rnd);"
+            , "  bf_delete(&r); bf_delete(&z); bf_delete(&y); bf_delete(&x); bf_context_end(&ctx); return result;"
+            , "}"
+            , ""
+            ]
+
+       binaryWrapper :: String -> String -> (String, Int) -> [String]
+       binaryWrapper cType tag (suffix, operation) =
+         ["static inline " ++ cType ++ " sbv_native_" ++ tag ++ "_" ++ suffix ++ "(" ++ cType ++ " a, " ++ cType ++ " b, bf_rnd_t rnd)"
+         , "{ return sbv_native_" ++ tag ++ "_binary(a, b, rnd, " ++ show operation ++ "); }"
+         , ""]
+
+-- | Lower explicitly rounded native floating-point arithmetic. RNE remains a
+-- direct native C operation under the public FE_TONEAREST calling convention;
+-- other constants and symbolic modes use LibBF without changing hardware
+-- rounding. The caller precondition is not checked at runtime.
+nativeFPExpr :: [(SV, CV)] -> Op -> [SV] -> Kind -> [Doc] -> Maybe CLowering
+nativeFPExpr consts (IEEEFP fpOp) svs resultKind args
+  | resultKind `elem` [KFloat, KDouble]
+  = case (fpOp, args, svs) of
+      (FP_Add             , [_rm, a, b]   , r:_) | needsAdapter r -> lower "add"   [a, b] r
+      (FP_Sub             , [_rm, a, b]   , r:_) | needsAdapter r -> lower "sub"   [a, b] r
+      (FP_Mul             , [_rm, a, b]   , r:_) | needsAdapter r -> lower "mul"   [a, b] r
+      (FP_Div             , [_rm, a, b]   , r:_) | needsAdapter r -> lower "div"   [a, b] r
+      (FP_FMA             , [_rm, a, b, c], r:_) | needsAdapter r -> lower "fma"   [a, b, c] r
+      (FP_Sqrt            , [_rm, a]      , r:_) | needsAdapter r -> lower "sqrt"  [a] r
+      (FP_RoundToIntegral , [_rm, a]      , r:_) | needsAdapter r -> lower "round" [a] r
+      _                                                           -> Nothing
+  | True = Nothing
+ where lower suffix values rm = Just . expressionLowering
+                                   [CRequiresLibBF, CRequiresLibM, CRequiresNativeFPRounding]
+                                 $ namedCall (nativePrefix resultKind ++ suffix)
+                                             (values ++ [nativeBFRoundingMode consts rm])
+
+       needsAdapter rm = case rm `lookup` consts of
+         Just (CV k (CADT ("RoundNearestTiesToEven", []))) | isRoundingMode k -> False
+         Just (CV k (CADT (_, [])))                        | isRoundingMode k -> True
+         Nothing                                           | isRoundingMode rm -> True
+         _ -> error $ "SBV->C: Expected a rounding mode, received " ++ show rm
+
+       nativePrefix KFloat  = "sbv_native_float_"
+       nativePrefix KDouble = "sbv_native_double_"
+       nativePrefix k       = error $ "SBV->C: Expected a native floating-point kind, received " ++ show k
+nativeFPExpr _ _ _ _ _ = Nothing
+
+-- | Render a LibBF rounding mode for a native floating-point adapter.
+nativeBFRoundingMode :: [(SV, CV)] -> SV -> Doc
+nativeBFRoundingMode consts sv = case sv `lookup` consts of
+  Just (CV k (CADT (rmName, [])))
+    | isRoundingMode k -> maybe bad (text . snd) (lookup rmName roundingModeNames)
+  Nothing
+    | isRoundingMode sv -> namedCall "sbv_native_bf_rounding_mode" [text (show sv)]
+  _                     -> bad
+ where bad = error $ "SBV->C: Expected a rounding mode, received " ++ show sv
+
+-- | Canonicalize externally supplied raw bits by clearing unused high bits.
+arbitraryFPNormalize :: Kind -> Doc -> Doc
+arbitraryFPNormalize k value = namedCall (prefix k ++ "_norm") [value]
+
+-- | Print arbitrary floating-point interchange bits as fixed-width hexadecimal.
+arbitraryFPPrint :: Kind -> Doc -> Doc
+arbitraryFPPrint k value = namedCall (prefix k ++ "_fprint") [text "stdout", value]
+
+-- | Compare two arbitrary floating-point interchange values using SMT object
+-- equality: all NaNs compare equal and the two signed zeroes remain distinct.
+arbitraryFPObjectEqual :: Kind -> Doc -> Doc -> Doc
+arbitraryFPObjectEqual k left right = namedCall (prefix k ++ "_obj_eq") [left, right]
+
+-- | Classify a raw arbitrary-format value without performing arithmetic.
+arbitraryFPIsNaN :: Kind -> Doc -> Doc
+arbitraryFPIsNaN kind value = namedCall (prefix kind ++ "_is_nan") [value]
+
+-- | Compare two arbitrary floating-point values using IEEE equality.
+arbitraryFPEqual :: Kind -> Doc -> Doc -> Doc
+arbitraryFPEqual k left right = namedCall (prefix k ++ "_eq") [left, right]
+
+-- | Compare two native floating-point values using SMT object equality: all
+-- NaNs compare equal and the two signed zeroes remain distinct.
+nativeFPObjectEqual :: Doc -> Doc -> Doc
+nativeFPObjectEqual left right = choose (renderedIsNaN left) (renderedIsNaN right)
+                              $ choose (renderedIsNegativeZero left) (renderedIsNegativeZero right)
+                              $ choose (renderedIsNegativeZero right) (renderedIsNegativeZero left) (equal left right)
+ where choose condition ifTrue ifFalse = condition <+> text "?" <+> ifTrue <+> text ":" <+> ifFalse
+       renderedIsNaN value          = text "isnan" P.<> parens value
+       equal x y                    = parens (x <+> text "==" <+> y)
+       renderedIsNegativeZero value = parens (text "signbit" P.<> parens value <+> text "&&" <+> equal value (text "0"))
+
+-- | Return the public C type name for an arbitrary floating-point kind.
+arbitraryFPCType :: Kind -> String
+arbitraryFPCType (KFP eb sb) = "SFP" ++ show eb ++ "_" ++ show sb
+arbitraryFPCType k           = error $ "SBV->C: Expected an arbitrary floating-point kind, received " ++ show k
+
+-- | A bit-preserving conversion between a floating-point interchange value
+-- and a bit-vector of the same width.
+data Reinterpret = Reinterpret Kind Kind deriving Eq
+
+-- | A value conversion implemented by the LibBF runtime.
+data FloatCast = FloatCast Kind Kind deriving Eq
+
+-- | Emit a bit-preserving conversion between raw C representations.
+reinterpretRuntime :: Reinterpret -> [String]
+reinterpretRuntime (Reinterpret fr to)
+  | reprWidth fr /= reprWidth to = error $ "SBV->C: Cannot reinterpret representations of different widths: " ++ show (fr, to)
+  | True =
+      ["static inline " ++ reprCType to ++ " " ++ reinterpretName fr to ++ "(" ++ reprCType fr ++ " a)"
+      , "{"
+      , "  " ++ reprCType to ++ " r = " ++ reprZero to ++ "; uint64_t i;"
+      , "  for (i = 0; i < " ++ show (reprWidth to) ++ "; ++i) { " ++ reprSetBit to "r" "i" (reprGetBit fr "a" "i") ++ " }"
+      , "  return " ++ reprNormalize to "r" ++ ";"
+      , "}"
+      , ""]
+
+-- | Construct the collision-free name of a reinterpretation helper.
+reinterpretName :: Kind -> Kind -> String
+reinterpretName fr to = "sbv_fp_reinterpret_" ++ reprTag fr ++ "_" ++ reprTag to
+
+-- | Resolve explicit native mappings for numeric conversion helpers. A native
+-- real mapping to long double has no fixed SBV IEEE kind; retain 'KReal' so the
+-- bridge can use the target C compiler's format instead of assuming binary64.
+floatCastKind :: CgConfig -> Kind -> Kind
+floatCastKind cfg KReal = case cgReal cfg of
+                           Just CgFloat  -> KFloat
+                           Just CgDouble -> KDouble
+                           _             -> KReal
+floatCastKind cfg kind = mappedIntegerKind (cgInteger cfg) kind
+
+-- | Test whether a cast crosses an explicitly mapped floating representation,
+-- including integer mappings used as a floating-point source or destination.
+mappedFloatCast :: CgConfig -> Kind -> Kind -> Bool
+mappedFloatCast cfg fr to = (from /= fr || target /= to || mappedReal)
+                        && (floating from || floating target || mappedReal)
+ where from   = floatCastKind cfg fr
+       target = floatCastKind cfg to
+       floating kind = isFP kind || isFloat kind || isDouble kind
+       mappedReal = KReal `elem` [fr, to] && case cgReal cfg of
+                                             Just{}  -> True
+                                             Nothing -> False
+
+-- | Emit a LibBF-backed value conversion between supported numeric formats.
+castRuntime :: CgConfig -> FloatCast -> [String]
+castRuntime cfg (FloatCast source target) = case (fr, to) of
+  (KFP{}, KFP{}) ->
+    ["static inline " ++ reprCType to ++ " " ++ helperName ++ "(" ++ reprCType fr ++ " a, bf_rnd_t rnd)"
+    , "{"
+    , "  bf_context_t ctx; bf_t x; " ++ reprCType to ++ " raw;"
+    , "  bf_context_init(&ctx, sbv_bf_realloc, NULL); " ++ prefix fr ++ "_decode(&ctx, &x, a);"
+    , "  bf_round(&x, " ++ show (significandBits to) ++ ", " ++ prefix to ++ "_flags(rnd)); raw = " ++ prefix to ++ "_encode(&x);"
+    , "  bf_delete(&x); bf_context_end(&ctx); return raw;"
+    , "}"
+    , ""]
+  (KFloat, KFP{})               -> fromNative "SFloat"
+  (KDouble, KFP{})              -> fromNative "SDouble"
+  (KReal, KFP{}) | longDouble fr -> fromNative "SReal"
+  (KFP{}, KFloat)               -> toNative "SFloat" True
+  (KFP{}, KDouble)              -> toNative "SDouble" False
+  (KFP{}, KReal) | longDouble to -> toNative "SReal" False
+  _ | isNativeFloat fr && isNativeFloat to      -> nativeToNative
+  _ | isExactGMPKind cfg fr && isNativeFloat to -> exactToNative
+  _ | isNativeFloat fr && isExactGMPKind cfg to -> nativeToExact
+  _ | isExactGMPKind cfg fr && isFP to -> exactToFP
+  _ | isFP fr && isExactGMPKind cfg to -> fpToExact
+  _ | isBounded fr && isSomeFloat to -> integerToFP
+  _ | isSomeFloat fr && isBounded to -> fpToInteger
+  _                   -> error $ "SBV->C: Unsupported arbitrary floating-point cast: " ++ show (fr, to)
+ where fr = floatCastKind cfg source
+       to = floatCastKind cfg target
+       helperName = castName source target
+
+       fromNative sourceType =
+         ["static inline " ++ reprCType to ++ " " ++ helperName ++ "(" ++ sourceType ++ " a, bf_rnd_t rnd)"
+         , "{"
+         , "  bf_context_t ctx; bf_t x; " ++ reprCType to ++ " raw;"
+         , "  bf_context_init(&ctx, sbv_bf_realloc, NULL); " ++ decodeFloating fr
+         , "  bf_round(&x, " ++ show (significandBits to) ++ ", " ++ prefix to ++ "_flags(rnd)); raw = " ++ prefix to ++ "_encode(&x);"
+         , "  bf_delete(&x); bf_context_end(&ctx); return raw;"
+         , "}"
+         , ""]
+
+       toNative targetType singlePrecision =
+            ["static inline " ++ targetType ++ " " ++ helperName ++ "(" ++ reprCType fr ++ " a, bf_rnd_t rnd)"
+            , "{"
+            , "  bf_context_t ctx; bf_t x; " ++ nativeResultType to ++ " result;"
+            , "  bf_context_init(&ctx, sbv_bf_realloc, NULL); " ++ prefix fr ++ "_decode(&ctx, &x, a);"
+            ]
+         ++ ["  bf_round(&x, 24, BF_FLAG_SUBNORMAL | bf_set_exp_bits(8) | (bf_flags_t) rnd);" | singlePrecision]
+         ++ ["  " ++ getNative to ++ " bf_delete(&x); bf_context_end(&ctx); return (" ++ targetType ++ ") result;"
+            , "}"
+            , ""]
+
+       nativeToNative =
+         ["static inline " ++ nativeCType to ++ " " ++ helperName ++ "(" ++ nativeCType fr ++ " a, bf_rnd_t rnd)"
+         , "{"
+         , "  bf_context_t ctx; bf_t x; " ++ nativeResultType to ++ " result;"
+         , "  bf_context_init(&ctx, sbv_bf_realloc, NULL); " ++ decodeFloating fr
+         , "  bf_round(&x, " ++ precision to ++ ", " ++ nativeFlags to ++ "); " ++ getNative to
+         , "  bf_delete(&x); bf_context_end(&ctx); return (" ++ nativeCType to ++ ") result;"
+         , "}"
+         , ""]
+
+       integerToFP =
+         ["static inline " ++ floatingCType to ++ " " ++ helperName ++ "(" ++ reprCType fr ++ " a, bf_rnd_t rnd)"
+         , "{"
+         , "  uint64_t words[" ++ show sourceWords ++ "]; uint64_t carry = 1; size_t i; limb_t j;"
+         , "  const bool negative = " ++ (if hasSign fr then reprGetBit fr "a" (show (reprWidth fr - 1)) else "false") ++ ";"
+         , "  bf_context_t ctx; bf_t x, chunk;" ++ integerResultDeclaration
+         , "  for (i = 0; i < " ++ show sourceWords ++ "; ++i) {"
+         , "    words[i] = 0;"
+         , "    for (j = 0; j < 64 && i * 64 + j < " ++ show (reprWidth fr) ++ "; ++j)"
+         , "      if (" ++ reprGetBit fr "a" "(i * 64 + j)" ++ ") words[i] |= UINT64_C(1) << j;"
+         , "  }"
+         , "  if (negative) for (i = 0; i < " ++ show sourceWords ++ "; ++i) {"
+         , "    const uint64_t next = ~words[i] + carry; carry = carry && next == 0; words[i] = next;"
+         , "  }"
+         , "  words[" ++ show (sourceWords - 1) ++ "] &= " ++ u64 (reprTopMask fr) ++ ";"
+         , "  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_init(&ctx, &chunk); bf_set_ui(&x, 0);"
+         , "  for (i = " ++ show sourceWords ++ "; i-- > 0;) {"
+         , "    bf_mul_2exp(&x, i == " ++ show (sourceWords - 1) ++ " ? " ++ show sourceTopBits ++ " : 64, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);"
+         , "    bf_set_ui(&chunk, words[i]); bf_add(&x, &x, &chunk, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);"
+         , "  }"
+         , "  if (negative) bf_neg(&x);"
+         , "  bf_round(&x, " ++ precision to ++ ", " ++ floatingFlags to ++ ");" ++ integerFinish
+         , "  bf_delete(&chunk); bf_delete(&x); bf_context_end(&ctx); return " ++ integerResult ++ ";"
+         , "}"
+         , ""]
+
+       fpToInteger =
+         ["static inline " ++ reprCType to ++ " " ++ helperName ++ "(" ++ floatingCType fr ++ " a, bf_rnd_t rnd)"
+         , "{"
+         , "  bf_context_t ctx; bf_t x; " ++ reprCType integerBits ++ " raw = " ++ reprZero integerBits ++ "; limb_t i;"
+         , "  bf_context_init(&ctx, sbv_bf_realloc, NULL); " ++ decodeFloating fr ++ " bf_rint(&x, rnd);"
+         , "  if (bf_is_finite(&x) && !bf_is_zero(&x)) {"
+         , "    const slimb_t base = (slimb_t) x.len * LIMB_BITS;"
+         , "    for (i = 0; i < " ++ show (reprWidth to) ++ "; ++i) {"
+         , "      const slimb_t bit = (slimb_t) i - x.expn + base;"
+         , "      if (bit >= 0 && bit < base) { " ++ reprSetBit integerBits "raw" "i" "((x.tab[bit / LIMB_BITS] >> (bit % LIMB_BITS)) & 1) != 0" ++ " }"
+         , "    }"
+         , "    if (x.sign) raw = " ++ negateRepr integerBits "raw" ++ ";"
+         , "  }"
+         , "  bf_delete(&x); bf_context_end(&ctx);"
+         , if integerBits /= to
+              then "  " ++ reprCType to ++ " result; memcpy(&result, &raw, sizeof result); return result;"
+              else "  return " ++ reprNormalize to "raw" ++ ";"
+         , "}"
+         , ""]
+
+       -- Reconstruct native signed results through their unsigned object
+       -- representation, avoiding implementation-defined unsigned-to-signed casts.
+       integerBits
+         | KBounded True width <- to
+         , not (isWideBV to) = KBounded False width
+         | True             = to
+
+       exactToFP
+         | fr == KUnbounded =
+            ["static inline " ++ reprCType to ++ " " ++ helperName ++ "(SInteger a, bf_rnd_t rnd)"
+            , "{"
+            , "  bf_context_t ctx; bf_t x, chunk; " ++ reprCType to ++ " raw;"
+            , "  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_init(&ctx, &chunk);"
+            , "  sbv_bf_set_mpz(&x, &chunk, a); bf_round(&x, " ++ show (significandBits to) ++ ", " ++ prefix to ++ "_flags(rnd));"
+            , "  raw = " ++ prefix to ++ "_encode(&x); bf_delete(&chunk); bf_delete(&x); bf_context_end(&ctx); return raw;"
+            , "}"
+            , ""]
+         | fr == KReal =
+            ["static inline " ++ reprCType to ++ " " ++ helperName ++ "(SReal a, bf_rnd_t rnd)"
+            , "{"
+            , "  bf_context_t ctx; bf_t x, numerator, denominator, chunk; " ++ reprCType to ++ " raw;"
+            , "  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_init(&ctx, &numerator); bf_init(&ctx, &denominator); bf_init(&ctx, &chunk);"
+            , "  sbv_bf_set_mpz(&numerator, &chunk, mpq_numref(a)); sbv_bf_set_mpz(&denominator, &chunk, mpq_denref(a));"
+            , "  bf_div(&x, &numerator, &denominator, " ++ show (significandBits to) ++ ", " ++ prefix to ++ "_flags(rnd)); raw = " ++ prefix to ++ "_encode(&x);"
+            , "  bf_delete(&chunk); bf_delete(&denominator); bf_delete(&numerator); bf_delete(&x); bf_context_end(&ctx); return raw;"
+            , "}"
+            , ""]
+         | otherwise = error $ "SBV->C: Expected an exact GMP source kind, received " ++ show fr
+
+       fpToExact
+         | to == KUnbounded =
+            ["static inline SInteger " ++ helperName ++ "(sbv_gmp_ctx *gmp_ctx, " ++ reprCType fr ++ " a, bf_rnd_t rnd)"
+            , "{"
+            , "  bf_context_t ctx; bf_t x; mpz_ptr result = sbv_gmp_new_integer(gmp_ctx);"
+            , "  bf_context_init(&ctx, sbv_bf_realloc, NULL); " ++ prefix fr ++ "_decode(&ctx, &x, a); bf_rint(&x, rnd);"
+            , "  sbv_bf_get_mpz(result, &x); bf_delete(&x); bf_context_end(&ctx); return result;"
+            , "}"
+            , ""]
+         | to == KReal =
+            ["static inline SReal " ++ helperName ++ "(sbv_gmp_ctx *gmp_ctx, " ++ reprCType fr ++ " a, bf_rnd_t rnd)"
+            , "{"
+            , "  bf_context_t ctx; bf_t x; mpq_ptr result = sbv_gmp_new_real(gmp_ctx);"
+            , "  (void) rnd; bf_context_init(&ctx, sbv_bf_realloc, NULL); " ++ prefix fr ++ "_decode(&ctx, &x, a);"
+            , "  sbv_bf_get_mpq(result, &x); bf_delete(&x); bf_context_end(&ctx); return result;"
+            , "}"
+            , ""]
+         | otherwise = error $ "SBV->C: Expected an exact GMP target kind, received " ++ show to
+
+       exactToNative
+         | fr == KUnbounded =
+            ["static inline " ++ nativeCType to ++ " " ++ helperName ++ "(SInteger a, bf_rnd_t rnd)"
+            , "{"
+            , "  bf_context_t ctx; bf_t x, chunk; " ++ nativeResultType to ++ " result;"
+            , "  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_init(&ctx, &chunk); sbv_bf_set_mpz(&x, &chunk, a);"
+            , "  bf_round(&x, " ++ precision to ++ ", " ++ nativeFlags to ++ "); " ++ getNative to
+            , "  bf_delete(&chunk); bf_delete(&x); bf_context_end(&ctx); return (" ++ nativeCType to ++ ") result;"
+            , "}"
+            , ""]
+         | fr == KReal =
+            ["static inline " ++ nativeCType to ++ " " ++ helperName ++ "(SReal a, bf_rnd_t rnd)"
+            , "{"
+            , "  bf_context_t ctx; bf_t x, numerator, denominator, chunk; " ++ nativeResultType to ++ " result;"
+            , "  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_init(&ctx, &numerator); bf_init(&ctx, &denominator); bf_init(&ctx, &chunk);"
+            , "  sbv_bf_set_mpz(&numerator, &chunk, mpq_numref(a)); sbv_bf_set_mpz(&denominator, &chunk, mpq_denref(a));"
+            , "  bf_div(&x, &numerator, &denominator, " ++ precision to ++ ", " ++ nativeFlags to ++ "); " ++ getNative to
+            , "  bf_delete(&chunk); bf_delete(&denominator); bf_delete(&numerator); bf_delete(&x); bf_context_end(&ctx); return (" ++ nativeCType to ++ ") result;"
+            , "}"
+            , ""]
+         | otherwise = error $ "SBV->C: Expected an exact GMP source kind, received " ++ show fr
+
+       nativeToExact
+         | to == KUnbounded =
+            ["static inline SInteger " ++ helperName ++ "(sbv_gmp_ctx *gmp_ctx, " ++ nativeCType fr ++ " a, bf_rnd_t rnd)"
+            , "{"
+            ]
+         ++ ["  if (!isfinite(a)) { fputs(\"SBV->C: Cannot convert a non-finite mapped SReal to exact SInteger.\\n\", stderr); abort(); }" | source == KReal]
+         ++ [ "  bf_context_t ctx; bf_t x; mpz_ptr result = sbv_gmp_new_integer(gmp_ctx);"
+            , "  bf_context_init(&ctx, sbv_bf_realloc, NULL); " ++ decodeFloating fr ++ " bf_rint(&x, rnd);"
+            , "  sbv_bf_get_mpz(result, &x); bf_delete(&x); bf_context_end(&ctx); return result;"
+            , "}"
+            , ""]
+         | to == KReal =
+            ["static inline SReal " ++ helperName ++ "(sbv_gmp_ctx *gmp_ctx, " ++ nativeCType fr ++ " a, bf_rnd_t rnd)"
+            , "{"
+            , "  bf_context_t ctx; bf_t x; mpq_ptr result = sbv_gmp_new_real(gmp_ctx);"
+            , "  (void) rnd; bf_context_init(&ctx, sbv_bf_realloc, NULL); " ++ decodeFloating fr
+            , "  sbv_bf_get_mpq(result, &x); bf_delete(&x); bf_context_end(&ctx); return result;"
+            , "}"
+            , ""]
+         | otherwise = error $ "SBV->C: Expected an exact GMP target kind, received " ++ show to
+
+       nativeFlags KFloat                   = "BF_FLAG_SUBNORMAL | bf_set_exp_bits(8) | (bf_flags_t) rnd"
+       nativeFlags KDouble                  = "BF_FLAG_SUBNORMAL | bf_set_exp_bits(11) | (bf_flags_t) rnd"
+       nativeFlags KReal | longDouble KReal = "sbv_bf_long_double_flags(rnd)"
+       nativeFlags k                        = error $ "SBV->C: Expected a native floating-point kind, received " ++ show k
+
+       nativeCType KFloat                   = "SFloat"
+       nativeCType KDouble                  = "SDouble"
+       nativeCType KReal | longDouble KReal = "SReal"
+       nativeCType k                        = error $ "SBV->C: Expected a native floating-point kind, received " ++ show k
+
+       longDouble k = k == KReal && cgReal cfg == Just CgLongDouble
+
+       precision k | longDouble k = "LDBL_MANT_DIG"
+                   | True         = show (significandBits k)
+
+       nativeResultType k | longDouble k = "long double"
+                          | True         = "double"
+
+       getNative k | longDouble k = "result = sbv_bf_get_long_double(&x, rnd);"
+                   | True         = "bf_get_float64(&x, &result, rnd);"
+
+       isNativeFloat k = k == KFloat || k == KDouble || longDouble k
+
+       isSomeFloat k = isFP k || isNativeFloat k
+
+       floatingCType k
+         | isFP k          = reprCType k
+         | isNativeFloat k = nativeCType k
+         | otherwise       = error $ "SBV->C: Expected a floating-point kind, received " ++ show k
+
+       floatingFlags k
+         | isFP k          = prefix k ++ "_flags(rnd)"
+         | isNativeFloat k = nativeFlags k
+         | otherwise       = error $ "SBV->C: Expected a floating-point kind, received " ++ show k
+
+       decodeFloating k
+         | isFP k          = prefix k ++ "_decode(&ctx, &x, a);"
+         | longDouble k    = "bf_init(&ctx, &x); sbv_bf_set_long_double(&x, a);"
+         | isNativeFloat k = "bf_init(&ctx, &x); bf_set_float64(&x, (double) a);"
+         | otherwise       = error $ "SBV->C: Expected a floating-point kind, received " ++ show k
+
+       integerResultDeclaration
+         | isFP to          = " " ++ reprCType to ++ " raw;"
+         | isNativeFloat to = " " ++ nativeResultType to ++ " result;"
+         | otherwise        = error $ "SBV->C: Expected a floating-point target kind, received " ++ show to
+
+       integerFinish
+         | isFP to          = " raw = " ++ prefix to ++ "_encode(&x);"
+         | isNativeFloat to = " " ++ getNative to
+         | otherwise        = error $ "SBV->C: Expected a floating-point target kind, received " ++ show to
+
+       integerResult
+         | isFP to          = "raw"
+         | isNativeFloat to = "(" ++ nativeCType to ++ ") result"
+         | otherwise        = error $ "SBV->C: Expected a floating-point target kind, received " ++ show to
+
+       sourceWords   = (reprWidth fr + 63) `div` 64
+       sourceTopBits = let r = reprWidth fr `mod` 64 in if r == 0 then 64 else r
+
+-- | Import and export native long doubles without binary64 intermediates.
+-- Work on numeric significands, not ABI-dependent object layouts (in particular
+-- x87 padding and its explicit integer bit). Unsupported non-IEEE-like formats
+-- are rejected by the target compiler. All reconstruction operations are exact
+-- after LibBF has rounded once to the target precision and exponent range.
+longDoubleBridgeRuntime :: [String]
+longDoubleBridgeRuntime =
+  [ "#include <float.h>"
+  , "#if FLT_RADIX == 2 && LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 && LDBL_MIN_EXP == -1021"
+  , "#define SBV_LDBL_EXP_BITS 11"
+  , "#elif FLT_RADIX == 2 && (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 && LDBL_MIN_EXP == -16381"
+  , "#define SBV_LDBL_EXP_BITS 15"
+  , "#else"
+  , "#error SBV C long-double conversions require binary64, x87 extended, or binary128 long double"
+  , "#endif"
+  , "#if BF_EXP_BITS_MAX < SBV_LDBL_EXP_BITS"
+  , "#error SBV C long-double conversions exceed the LibBF exponent range"
+  , "#endif"
+  , ""
+  , "static bf_flags_t sbv_bf_long_double_flags(bf_rnd_t rnd)"
+  , "{"
+  , "  return BF_FLAG_SUBNORMAL | bf_set_exp_bits(SBV_LDBL_EXP_BITS) | (bf_flags_t) rnd;"
+  , "}"
+  , ""
+  , "static void sbv_bf_set_long_double(bf_t *result, long double value)"
+  , "{"
+  , "  int exponent, shift = 0, status = 0; bf_t chunk;"
+  , "  if (isnan(value)) { bf_set_nan(result); return; }"
+  , "  if (isinf(value)) { bf_set_inf(result, signbit(value) != 0); return; }"
+  , "  if (value == 0) { bf_set_zero(result, signbit(value) != 0); return; }"
+  , "  long double fraction = frexpl(fabsl(value), &exponent);"
+  , "  bf_init(result->ctx, &chunk); bf_set_zero(result, 0);"
+  , "  while (fraction != 0) {"
+  , "    fraction = ldexpl(fraction, 32);"
+  , "    const uint32_t bits = (uint32_t) fraction; fraction -= (long double) bits;"
+  , "    status |= bf_mul_2exp(result, 32, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);"
+  , "    status |= bf_set_ui(&chunk, bits);"
+  , "    status |= bf_add(result, result, &chunk, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ); shift += 32;"
+  , "  }"
+  , "  status |= bf_mul_2exp(result, exponent - shift, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);"
+  , "  bf_delete(&chunk); if (status & BF_ST_MEM_ERROR) abort();"
+  , "  if (signbit(value)) bf_neg(result);"
+  , "}"
+  , ""
+  , "static long double sbv_bf_get_long_double(bf_t *value, bf_rnd_t rnd)"
+  , "{"
+  , "  if (bf_round(value, LDBL_MANT_DIG, sbv_bf_long_double_flags(rnd)) & BF_ST_MEM_ERROR) abort();"
+  , "  if (bf_is_nan(value)) return nanl(\"\");"
+  , "  if (!bf_is_finite(value)) return value->sign ? -HUGE_VALL : HUGE_VALL;"
+  , "  if (bf_is_zero(value)) return value->sign ? -0.0L : 0.0L;"
+  , "  long double significand = 0;"
+  , "  const slimb_t base = (slimb_t) value->len * LIMB_BITS;"
+  , "  for (int i = 0; i < LDBL_MANT_DIG; ++i) {"
+  , "    const slimb_t bit = base - 1 - i;"
+  , "    const unsigned digit = bit < 0 ? 0 : (unsigned) ((value->tab[bit / LIMB_BITS] >> (bit % LIMB_BITS)) & 1);"
+  , "    significand = significand * 2 + digit;"
+  , "  }"
+  , "  const long double result = ldexpl(significand, (int) value->expn - LDBL_MANT_DIG);"
+  , "  return value->sign ? -result : result;"
+  , "}"
+  , ""
+  ]
+
+-- | Emit conversion primitives shared by LibBF/GMP value casts.
+exactBridgeRuntime :: [String]
+exactBridgeRuntime =
+  ["static void sbv_bf_set_mpz(bf_t *result, bf_t *chunk, mpz_srcptr value)"
+  , "{"
+  , "  const size_t count = (mpz_sizeinbase(value, 2) + 63) / 64; size_t written = 0, i;"
+  , "  uint64_t *words; bf_set_ui(result, 0);"
+  , "  if (mpz_sgn(value) == 0) return;"
+  , "  words = (uint64_t *) calloc(count, sizeof(*words)); if (words == NULL) abort();"
+  , "  mpz_export(words, &written, -1, sizeof(*words), 0, 0, value);"
+  , "  for (i = written; i-- > 0;) {"
+  , "    bf_mul_2exp(result, 64, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);"
+  , "    bf_set_ui(chunk, words[i]); bf_add(result, result, chunk, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);"
+  , "  }"
+  , "  free(words); if (mpz_sgn(value) < 0) bf_neg(result);"
+  , "}"
+  , ""
+  , "static void sbv_bf_get_mpz(mpz_ptr result, const bf_t *value)"
+  , "{"
+  , "  slimb_t shift; mpz_set_ui(result, 0);"
+  , "  if (!bf_is_finite(value) || bf_is_zero(value)) return;"
+  , "  mpz_import(result, value->len, -1, sizeof(*value->tab), 0, 0, value->tab);"
+  , "  shift = value->expn - (slimb_t) value->len * LIMB_BITS;"
+  , "  if (shift >= 0) mpz_mul_2exp(result, result, (mp_bitcnt_t) shift);"
+  , "  else mpz_tdiv_q_2exp(result, result, (mp_bitcnt_t) -shift);"
+  , "  if (value->sign) mpz_neg(result, result);"
+  , "}"
+  , ""
+  , "static void sbv_bf_get_mpq(mpq_ptr result, const bf_t *value)"
+  , "{"
+  , "  slimb_t shift; mpq_set_ui(result, 0, 1);"
+  , "  if (!bf_is_finite(value) || bf_is_zero(value)) return;"
+  , "  mpz_import(mpq_numref(result), value->len, -1, sizeof(*value->tab), 0, 0, value->tab);"
+  , "  shift = value->expn - (slimb_t) value->len * LIMB_BITS;"
+  , "  if (shift >= 0) mpz_mul_2exp(mpq_numref(result), mpq_numref(result), (mp_bitcnt_t) shift);"
+  , "  else mpz_mul_2exp(mpq_denref(result), mpq_denref(result), (mp_bitcnt_t) -shift);"
+  , "  if (value->sign) mpz_neg(mpq_numref(result), mpq_numref(result)); mpq_canonicalize(result);"
+  , "}"
+  , ""]
+
+-- | Construct the collision-free name of a floating-point value conversion.
+castName :: Kind -> Kind -> String
+castName fr to = "sbv_fp_cast_" ++ castTag fr ++ "_" ++ castTag to
+
+-- | Return the generated tag used in a floating-point value conversion.
+castTag :: Kind -> String
+castTag k@KFP{}    = reprTag k
+castTag KFloat     = "float"
+castTag KDouble    = "double"
+castTag KUnbounded = "integer"
+castTag KReal      = "real"
+castTag k          = reprTag k
+
+-- | Return the significand width of an arbitrary floating-point kind.
+significandBits :: Kind -> Int
+significandBits (KFP _ sb) = sb
+significandBits KFloat     = 24
+significandBits KDouble    = 53
+significandBits k          = error $ "SBV->C: Expected a floating-point kind, received " ++ show k
+
+-- | Render modular negation of a raw bit-vector representation.
+negateRepr :: Kind -> String -> String
+negateRepr k value
+  | isWideBV k  = bvPrefix k ++ "_neg(" ++ value ++ ")"
+  | isBounded k = "(" ++ reprCType k ++ ") (~(uint64_t) " ++ value ++ " + UINT64_C(1))"
+  | otherwise   = error $ "SBV->C: Cannot negate " ++ show k
+
+-- | Return the mask for the high limb of a raw bit-vector representation.
+reprTopMask :: Kind -> Integer
+reprTopMask k
+  | r == 0    = (1 `shiftL` 64) - 1
+  | otherwise = (1 `shiftL` r) - 1
+ where r = reprWidth k `mod` 64
+
+-- | Return the bit width of a raw floating-point or bit-vector representation.
+reprWidth :: Kind -> Int
+reprWidth k
+  | isFP k || isBounded k = intSizeOf k
+  | otherwise             = error $ "SBV->C: Expected a raw floating-point or bit-vector representation, received " ++ show k
+
+-- | Return the C type used by a raw floating-point or bit-vector representation.
+reprCType :: Kind -> String
+reprCType k@KFP{}            = arbitraryFPCType k
+reprCType (KBounded False 1) = "SBool"
+reprCType (KBounded False w) = "SWord" ++ show w
+reprCType (KBounded True  w) = "SInt" ++ show w
+reprCType k                  = error $ "SBV->C: Expected a raw floating-point or bit-vector representation, received " ++ show k
+
+-- | Return the generated tag for a raw representation.
+reprTag :: Kind -> String
+reprTag (KFP eb sb)          = "f" ++ show eb ++ "_" ++ show sb
+reprTag (KBounded False w)   = "u" ++ show w
+reprTag (KBounded True  w)   = "s" ++ show w
+reprTag k                    = error $ "SBV->C: Expected a raw floating-point or bit-vector representation, received " ++ show k
+
+-- | Render a bit read from a raw representation.
+reprGetBit :: Kind -> String -> String -> String
+reprGetBit k@KFP{} value bit = prefix k ++ "_get(" ++ value ++ ", " ++ bit ++ ")"
+reprGetBit k value bit
+  | isWideBV k  = bvPrefix k ++ "_get(" ++ value ++ ", " ++ bit ++ ")"
+  | isBounded k = "((((uint64_t) " ++ value ++ ") >> (" ++ bit ++ ")) & UINT64_C(1)) != 0"
+  | otherwise   = error $ "SBV->C: Cannot read bits from " ++ show k
+
+-- | Render a bit update to a raw representation.
+reprSetBit :: Kind -> String -> String -> String -> String
+reprSetBit k@KFP{} value bit bitValue = prefix k ++ "_set(&" ++ value ++ ", " ++ bit ++ ", " ++ bitValue ++ ");"
+reprSetBit k value bit bitValue
+  | isWideBV k  = bvPrefix k ++ "_set(&" ++ value ++ ", " ++ bit ++ ", " ++ bitValue ++ ");"
+  | isBounded k = value ++ " = (" ++ reprCType k ++ ") ((uint64_t) " ++ value ++ " | ((uint64_t) (" ++ bitValue ++ ") << (" ++ bit ++ ")));"
+  | otherwise   = error $ "SBV->C: Cannot update bits in " ++ show k
+
+-- | Render the zero value for a raw representation.
+reprZero :: Kind -> String
+reprZero k@KFP{} = prefix k ++ "_zero()"
+reprZero k
+  | isWideBV k  = bvPrefix k ++ "_zero()"
+  | isBounded k = "(" ++ reprCType k ++ ") 0"
+  | otherwise   = error $ "SBV->C: Cannot construct a zero of " ++ show k
+
+-- | Render canonicalization for a raw representation.
+reprNormalize :: Kind -> String -> String
+reprNormalize k@KFP{} value = prefix k ++ "_norm(" ++ value ++ ")"
+reprNormalize k value
+  | isWideBV k  = bvPrefix k ++ "_norm(" ++ value ++ ")"
+  | isBounded k = value
+  | otherwise   = error $ "SBV->C: Cannot normalize " ++ show k
+
+-- | Return the generated namespace prefix for an exact-width bit-vector.
+bvPrefix :: Kind -> String
+bvPrefix (KBounded False w) = "sbv_bv_u" ++ show w
+bvPrefix (KBounded True  w) = "sbv_bv_s" ++ show w
+bvPrefix k                  = error $ "SBV->C: Expected a bit-vector kind, received " ++ show k
+
+-- | Emit all helpers associated with a single floating-point format.
+formatRuntime :: Kind -> [String]
+formatRuntime k@(KFP eb sb) =
+  ["#if BF_EXP_BITS_MAX < " ++ show eb
+  , "#error \"The selected LibBF build cannot represent " ++ arbitraryFPCType k ++ "\""
+  , "#endif"
+  , ""
+  , "static inline " ++ ty ++ " " ++ p ++ "_zero(void)"
+  , "{"
+  , "  " ++ ty ++ " r = {{0}};"
+  , "  return r;"
+  , "}"
+  , ""
+  , "static inline " ++ ty ++ " " ++ p ++ "_norm(" ++ ty ++ " a)"
+  , "{"
+  , "  a.limb[" ++ show (n - 1) ++ "] &= " ++ u64 mask ++ ";"
+  , "  return a;"
+  , "}"
+  , ""
+  , "static inline bool " ++ p ++ "_get(" ++ ty ++ " a, limb_t bit)"
+  , "{"
+  , "  return bit < " ++ show width ++ " && ((a.limb[bit / 64] >> (bit % 64)) & UINT64_C(1)) != 0;"
+  , "}"
+  , ""
+  , "static inline void " ++ p ++ "_set(" ++ ty ++ " *a, limb_t bit, bool value)"
+  , "{"
+  , "  const uint64_t m = UINT64_C(1) << (bit % 64);"
+  , "  if (value) { a->limb[bit / 64] |= m; } else { a->limb[bit / 64] &= ~m; }"
+  , "}"
+  , ""
+  , "static inline uint64_t " ++ p ++ "_slice(" ++ ty ++ " a, limb_t offset, limb_t count)"
+  , "{"
+  , "  uint64_t r = 0; limb_t i;"
+  , "  for (i = 0; i < count; ++i) if (" ++ p ++ "_get(a, offset + i)) r |= UINT64_C(1) << i;"
+  , "  return r;"
+  , "}"
+  , ""
+  , "static inline bool " ++ p ++ "_raw_eq(" ++ ty ++ " a, " ++ ty ++ " b)"
+  , "{"
+  , "  uint64_t r = 0; size_t i;"
+  , "  for (i = 0; i < " ++ show n ++ "; ++i) r |= a.limb[i] ^ b.limb[i];"
+  , "  return r == 0;"
+  , "}"
+  , ""
+  , "static inline uint64_t " ++ p ++ "_exponent(" ++ ty ++ " a)"
+  , "{"
+  , "  return " ++ p ++ "_slice(a, " ++ show fracBits ++ ", " ++ show eb ++ ");"
+  , "}"
+  , ""
+  , "static inline bool " ++ p ++ "_fraction_is_zero(" ++ ty ++ " a)"
+  , "{"
+  , "  limb_t i;"
+  , "  for (i = 0; i < " ++ show fracBits ++ "; ++i) if (" ++ p ++ "_get(a, i)) return false;"
+  , "  return true;"
+  , "}"
+  , ""
+  , "static inline bool " ++ p ++ "_is_nan(" ++ ty ++ " a)"
+  , "{ return " ++ p ++ "_exponent(a) == " ++ show expMask ++ " && !" ++ p ++ "_fraction_is_zero(a); }"
+  , ""
+  , "static inline bool " ++ p ++ "_is_infinite(" ++ ty ++ " a)"
+  , "{ return " ++ p ++ "_exponent(a) == " ++ show expMask ++ " && " ++ p ++ "_fraction_is_zero(a); }"
+  , ""
+  , "static inline bool " ++ p ++ "_is_zero(" ++ ty ++ " a)"
+  , "{ return " ++ p ++ "_exponent(a) == 0 && " ++ p ++ "_fraction_is_zero(a); }"
+  , ""
+  , "static inline bool " ++ p ++ "_is_subnormal(" ++ ty ++ " a)"
+  , "{ return " ++ p ++ "_exponent(a) == 0 && !" ++ p ++ "_fraction_is_zero(a); }"
+  , ""
+  , "static inline bool " ++ p ++ "_is_normal(" ++ ty ++ " a)"
+  , "{ const uint64_t e = " ++ p ++ "_exponent(a); return e != 0 && e != " ++ show expMask ++ "; }"
+  , ""
+  , "static inline bool " ++ p ++ "_is_negative(" ++ ty ++ " a)"
+  , "{ return !" ++ p ++ "_is_nan(a) && " ++ p ++ "_get(a, " ++ show (width - 1) ++ "); }"
+  , ""
+  , "static inline bool " ++ p ++ "_is_positive(" ++ ty ++ " a)"
+  , "{ return !" ++ p ++ "_is_nan(a) && !" ++ p ++ "_get(a, " ++ show (width - 1) ++ "); }"
+  , ""
+  , "static inline " ++ ty ++ " " ++ p ++ "_neg(" ++ ty ++ " a)"
+  , "{ a.limb[" ++ show ((width - 1) `div` 64) ++ "] ^= UINT64_C(1) << " ++ show ((width - 1) `mod` 64) ++ "; return a; }"
+  , ""
+  , "static inline " ++ ty ++ " " ++ p ++ "_abs(" ++ ty ++ " a)"
+  , "{ a.limb[" ++ show ((width - 1) `div` 64) ++ "] &= ~(UINT64_C(1) << " ++ show ((width - 1) `mod` 64) ++ "); return a; }"
+  , ""
+  , "static inline bool " ++ p ++ "_obj_eq(" ++ ty ++ " a, " ++ ty ++ " b)"
+  , "{ return (" ++ p ++ "_is_nan(a) && " ++ p ++ "_is_nan(b)) || " ++ p ++ "_raw_eq(a, b); }"
+  , ""
+  , "static inline void " ++ p ++ "_decode(bf_context_t *ctx, bf_t *r, " ++ ty ++ " raw)"
+  , "{"
+  , "  const uint64_t e = " ++ p ++ "_exponent(raw);"
+  , "  const bool sign = " ++ p ++ "_get(raw, " ++ show (width - 1) ++ ");"
+  , "  bf_t chunk;"
+  , "  bf_init(ctx, r); bf_init(ctx, &chunk);"
+  , "  if (e == " ++ show expMask ++ ") {"
+  , "    if (" ++ p ++ "_fraction_is_zero(raw)) bf_set_inf(r, sign); else bf_set_nan(r);"
+  , "  } else if (e == 0 && " ++ p ++ "_fraction_is_zero(raw)) {"
+  , "    bf_set_zero(r, sign);"
+  , "  } else {"
+  , "    bf_set_ui(r, e == 0 ? 0 : 1);"
+  ]
+  ++ concatMap decodeChunk chunks
+  ++ ["    bf_mul_2exp(r, (slimb_t) e - " ++ show bias ++ " - " ++ show fracBits ++ " + (e == 0 ? 1 : 0), BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);"
+     , "    if (sign) bf_neg(r);"
+     , "  }"
+     , "  bf_delete(&chunk);"
+     , "}"
+     , ""
+     , "static inline " ++ ty ++ " " ++ p ++ "_encode(const bf_t *a)"
+     , "{"
+     , "  " ++ ty ++ " raw = " ++ p ++ "_zero(); limb_t i;"
+     , "  if (bf_is_nan(a)) {"
+     , "    for (i = 0; i < " ++ show eb ++ "; ++i) " ++ p ++ "_set(&raw, " ++ show fracBits ++ " + i, true);"
+     , "    " ++ p ++ "_set(&raw, " ++ show (fracBits - 1) ++ ", true);"
+     , "    return raw;"
+     , "  }"
+     , "  if (a->sign) " ++ p ++ "_set(&raw, " ++ show (width - 1) ++ ", true);"
+     , "  if (a->expn == BF_EXP_INF) {"
+     , "    for (i = 0; i < " ++ show eb ++ "; ++i) " ++ p ++ "_set(&raw, " ++ show fracBits ++ " + i, true);"
+     , "    return raw;"
+     , "  }"
+     , "  if (a->expn != BF_EXP_ZERO) {"
+     , "    const slimb_t biased = a->expn + " ++ show bias ++ " - 1;"
+     , "    const bool normal = biased > 0;"
+     , "    const uint64_t e = normal ? (uint64_t) biased : UINT64_C(0);"
+     , "    const slimb_t base = (slimb_t) a->len * LIMB_BITS;"
+     , "    for (i = 0; i < " ++ show eb ++ "; ++i) " ++ p ++ "_set(&raw, " ++ show fracBits ++ " + i, ((e >> i) & UINT64_C(1)) != 0);"
+     , "    for (i = 0; i < " ++ show fracBits ++ "; ++i) {"
+     , "      const slimb_t bit = normal ? base + (slimb_t) i - " ++ show sb
+                                  ++ " : base + (slimb_t) i + 2 - " ++ show bias ++ " - " ++ show sb ++ " - a->expn;"
+     , "      if (bit >= 0 && bit < base) " ++ p ++ "_set(&raw, i, ((a->tab[bit / LIMB_BITS] >> (bit % LIMB_BITS)) & 1) != 0);"
+     , "    }"
+     , "  }"
+     , "  return raw;"
+     , "}"
+     , ""
+     ]
+  ++ arithmeticRuntime k
+ where ty       = arbitraryFPCType k
+       p        = prefix k
+       width    = eb + sb
+       fracBits = sb - 1
+       n        = limbs k
+       mask     = topMask k
+       expMask  = (1 `shiftL` eb) - 1 :: Integer
+       bias     = expMask `shiftR` 1
+       chunks   = reverse [(offset, min 64 (fracBits - offset)) | offset <- [0, 64 .. fracBits - 1]]
+
+       decodeChunk (offset, count) =
+         ["    bf_mul_2exp(r, " ++ show count ++ ", BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);"
+         , "    bf_set_ui(&chunk, " ++ p ++ "_slice(raw, " ++ show offset ++ ", " ++ show count ++ "));"
+         , "    bf_add(r, r, &chunk, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);"
+         ]
+formatRuntime k = error $ "SBV->C: Expected an arbitrary floating-point kind, received " ++ show k
+
+-- | Emit arithmetic and comparison adapters for one floating-point format.
+arithmeticRuntime :: Kind -> [String]
+arithmeticRuntime k@(KFP eb sb) =
+  ["static inline bf_flags_t " ++ p ++ "_flags(bf_rnd_t rnd)"
+  , "{ return (bf_flags_t) rnd | BF_FLAG_SUBNORMAL | bf_set_exp_bits(" ++ show eb ++ "); }"
+  , ""
+  , "static inline " ++ ty ++ " " ++ p ++ "_binary(" ++ ty ++ " a, " ++ ty ++ " b, bf_rnd_t rnd, int op)"
+  , "{"
+  , "  bf_context_t ctx; bf_t x, y, r; " ++ ty ++ " raw;"
+  , "  bf_context_init(&ctx, sbv_bf_realloc, NULL);"
+  , "  " ++ p ++ "_decode(&ctx, &x, a); " ++ p ++ "_decode(&ctx, &y, b); bf_init(&ctx, &r);"
+  , "  if (op == 0) bf_add(&r, &x, &y, " ++ show sb ++ ", " ++ p ++ "_flags(rnd));"
+  , "  else if (op == 1) bf_sub(&r, &x, &y, " ++ show sb ++ ", " ++ p ++ "_flags(rnd));"
+  , "  else if (op == 2) bf_mul(&r, &x, &y, " ++ show sb ++ ", " ++ p ++ "_flags(rnd));"
+  , "  else if (op == 3) bf_div(&r, &x, &y, " ++ show sb ++ ", " ++ p ++ "_flags(rnd));"
+  , "  else bf_rem(&r, &x, &y, " ++ show sb ++ ", " ++ p ++ "_flags(BF_RNDN), BF_RNDN);"
+  , "  raw = " ++ p ++ "_encode(&r);"
+  , "  bf_delete(&r); bf_delete(&y); bf_delete(&x); bf_context_end(&ctx);"
+  , "  return raw;"
+  , "}"
+  , ""
+  ]
+  ++ concatMap binaryWrapper [("add", 0), ("sub", 1), ("mul", 2), ("div", 3)]
+  ++ ["static inline " ++ ty ++ " " ++ p ++ "_rem(" ++ ty ++ " a, " ++ ty ++ " b)"
+     , "{ return " ++ p ++ "_binary(a, b, BF_RNDN, 4); }"
+     , ""
+     , "static inline " ++ ty ++ " " ++ p ++ "_sqrt(" ++ ty ++ " a, bf_rnd_t rnd)"
+     , "{"
+     , "  bf_context_t ctx; bf_t x, r; " ++ ty ++ " raw;"
+     , "  bf_context_init(&ctx, sbv_bf_realloc, NULL); " ++ p ++ "_decode(&ctx, &x, a); bf_init(&ctx, &r);"
+     , "  bf_sqrt(&r, &x, " ++ show sb ++ ", " ++ p ++ "_flags(rnd)); raw = " ++ p ++ "_encode(&r);"
+     , "  bf_delete(&r); bf_delete(&x); bf_context_end(&ctx); return raw;"
+     , "}"
+     , ""
+     , "static inline " ++ ty ++ " " ++ p ++ "_round(" ++ ty ++ " a, bf_rnd_t rnd)"
+     , "{"
+     , "  bf_context_t ctx; bf_t x; " ++ ty ++ " raw;"
+     , "  bf_context_init(&ctx, sbv_bf_realloc, NULL); " ++ p ++ "_decode(&ctx, &x, a);"
+     , "  bf_rint(&x, rnd); raw = " ++ p ++ "_encode(&x);"
+     , "  bf_delete(&x); bf_context_end(&ctx); return raw;"
+     , "}"
+     , ""
+     , "static inline " ++ ty ++ " " ++ p ++ "_fma(" ++ ty ++ " a, " ++ ty ++ " b, " ++ ty ++ " c, bf_rnd_t rnd)"
+     , "{"
+     , "  bf_context_t ctx; bf_t x, y, z, r; " ++ ty ++ " raw;"
+     , "  bf_context_init(&ctx, sbv_bf_realloc, NULL);"
+     , "  " ++ p ++ "_decode(&ctx, &x, a); " ++ p ++ "_decode(&ctx, &y, b); " ++ p ++ "_decode(&ctx, &z, c); bf_init(&ctx, &r);"
+     , "  bf_mul(&r, &x, &y, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDN); bf_add(&r, &r, &z, " ++ show sb ++ ", " ++ p ++ "_flags(rnd));"
+     , "  raw = " ++ p ++ "_encode(&r);"
+     , "  bf_delete(&r); bf_delete(&z); bf_delete(&y); bf_delete(&x); bf_context_end(&ctx); return raw;"
+     , "}"
+     , ""
+     , "static inline int " ++ p ++ "_compare(" ++ ty ++ " a, " ++ ty ++ " b)"
+     , "{"
+     , "  bf_context_t ctx; bf_t x, y; int result;"
+     , "  bf_context_init(&ctx, sbv_bf_realloc, NULL); " ++ p ++ "_decode(&ctx, &x, a); " ++ p ++ "_decode(&ctx, &y, b);"
+     , "  result = bf_cmp(&x, &y); bf_delete(&y); bf_delete(&x); bf_context_end(&ctx); return result;"
+     , "}"
+     , ""
+     , "static inline bool " ++ p ++ "_eq(" ++ ty ++ " a, " ++ ty ++ " b)"
+     , "{ return " ++ p ++ "_compare(a, b) == 0; }"
+     , ""
+     , "static inline bool " ++ p ++ "_lt(" ++ ty ++ " a, " ++ ty ++ " b)"
+     , "{ return " ++ p ++ "_compare(a, b) < 0; }"
+     , ""
+     , "static inline bool " ++ p ++ "_le(" ++ ty ++ " a, " ++ ty ++ " b)"
+     , "{ return " ++ p ++ "_compare(a, b) <= 0; }"
+     , ""
+     , "static inline " ++ ty ++ " " ++ p ++ "_min(" ++ ty ++ " a, " ++ ty ++ " b)"
+     , "{"
+     , "  if (" ++ p ++ "_is_nan(a)) return b; if (" ++ p ++ "_is_nan(b)) return a;"
+     , "  if (" ++ p ++ "_is_zero(a) && " ++ p ++ "_is_zero(b)) return " ++ p ++ "_is_negative(a) ? a : b;"
+     , "  return " ++ p ++ "_lt(a, b) ? a : b;"
+     , "}"
+     , ""
+     , "static inline " ++ ty ++ " " ++ p ++ "_max(" ++ ty ++ " a, " ++ ty ++ " b)"
+     , "{"
+     , "  if (" ++ p ++ "_is_nan(a)) return b; if (" ++ p ++ "_is_nan(b)) return a;"
+     , "  if (" ++ p ++ "_is_zero(a) && " ++ p ++ "_is_zero(b)) return " ++ p ++ "_is_negative(a) ? b : a;"
+     , "  return " ++ p ++ "_lt(b, a) ? a : b;"
+     , "}"
+     , ""
+     ]
+ where ty = arbitraryFPCType k
+       p  = prefix k
+
+       binaryWrapper :: (String, Int) -> [String]
+       binaryWrapper (nm, op) =
+         ["static inline " ++ ty ++ " " ++ p ++ "_" ++ nm ++ "(" ++ ty ++ " a, " ++ ty ++ " b, bf_rnd_t rnd)"
+         , "{ return " ++ p ++ "_binary(a, b, rnd, " ++ show op ++ "); }"
+         , ""]
+arithmeticRuntime k = error $ "SBV->C: Expected an arbitrary floating-point kind, received " ++ show k
+
+-- | Render the LibBF rounding mode corresponding to an SBV value.
+bfRoundingMode :: [(SV, CV)] -> SV -> Doc
+bfRoundingMode consts sv = case sv `lookup` consts of
+  Just (CV k (CADT (rmName, [])))
+    | isRoundingMode k -> maybe bad (text . snd) (lookup rmName roundingModeNames)
+  Nothing
+    | isRoundingMode sv -> namedCall "sbv_bf_rounding_mode" [text (show sv)]
+  _                     -> bad
+ where bad = error $ "SBV->C: Expected a rounding mode, received " ++ show sv
+
+-- | Mapping from SBV constructor names to public C and LibBF constants.
+roundingModeNames :: [(String, (String, String))]
+roundingModeNames =
+  [ ("RoundNearestTiesToEven", ("SBV_RM_RNE", "BF_RNDN"))
+  , ("RoundNearestTiesToAway", ("SBV_RM_RNA", "BF_RNDNA"))
+  , ("RoundTowardPositive",    ("SBV_RM_RTP", "BF_RNDU"))
+  , ("RoundTowardNegative",    ("SBV_RM_RTN", "BF_RNDD"))
+  , ("RoundTowardZero",        ("SBV_RM_RTZ", "BF_RNDZ"))
+  ]
+
+-- | Render a C function call.
+namedCall :: String -> [Doc] -> Doc
+namedCall nm args = text nm P.<> parens (fsep (punctuate comma args))
+
+-- | Return the number of raw 64-bit limbs occupied by an arbitrary float.
+limbs :: Kind -> Int
+limbs k = (intSizeOf k + 63) `div` 64
+
+-- | Return the mask for the high raw limb of an arbitrary float.
+topMask :: Kind -> Integer
+topMask k
+  | r == 0    = (1 `shiftL` 64) - 1
+  | otherwise = (1 `shiftL` r) - 1
+ where r = intSizeOf k `mod` 64
+
+-- | Return the generated namespace prefix for a floating-point format.
+prefix :: Kind -> String
+prefix (KFP eb sb) = "sbv_fp_e" ++ show eb ++ "_s" ++ show sb
+prefix k           = error $ "SBV->C: Expected an arbitrary floating-point kind, received " ++ show k
+
+-- | Render raw interchange bits as a C compound literal.
+rawLiteral :: Kind -> Integer -> String
+rawLiteral k bits = "(" ++ arbitraryFPCType k ++ "){{" ++ intercalate ", " words64 ++ "}}"
+ where words64 = [u64 ((bits `shiftR` (64 * i)) .&. ((1 `shiftL` 64) - 1)) | i <- [0 .. limbs k - 1]]
+
+-- | Render an integer as a padded, portable C @uint64_t@ literal.
+u64 :: Integer -> String
+u64 i = "UINT64_C(0x" ++ pad 16 (showHex i "") ++ ")"
+ where pad n s = replicate (n - length s) '0' ++ s
diff --git a/Data/SBV/Compilers/C/Finite.hs b/Data/SBV/Compilers/C/Finite.hs
new file mode 100644
--- /dev/null
+++ b/Data/SBV/Compilers/C/Finite.hs
@@ -0,0 +1,40 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Data.SBV.Compilers.C.Finite
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Finite SMT-object domains shared by C collection lowering.
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Data.SBV.Compilers.C.Finite (finiteDomainSize) where
+
+import qualified Data.Set as Set
+
+import Data.SBV.Core.Data
+
+-- | Count distinct SMT objects without imposing a machine-integer limit.
+-- All NaN encodings denote one object; signed zeros remain distinct. The
+-- constructor callback resolves ADT references without a module dependency
+-- cycle. Recursive and unbounded domains return 'Nothing'.
+finiteDomainSize :: (Kind -> [[Kind]]) -> Kind -> Maybe Integer
+finiteDomainSize constructorsOf = count Set.empty
+ where count _ KBool                 = Just 2
+       count _ (KBounded _ width)     = Just (2 ^ width)
+       count _ KFloat                = Just (2 ^ (32 :: Int) - 2 ^ (24 :: Int) + 3)
+       count _ KDouble               = Just (2 ^ (64 :: Int) - 2 ^ (53 :: Int) + 3)
+       count _ KChar                 = Just 0x30000
+       count _ (KFP eb sb)            = Just (2 ^ (eb + sb) - 2 ^ sb + 3)
+       count seen (KTuple fields)     = product <$> mapM (count seen) fields
+       count seen kind
+         | isRoundingMode kind = Just 5
+         | concrete kind, kind `Set.notMember` seen
+         = sum <$> mapM (fmap product . mapM (count (Set.insert kind seen))) (constructorsOf kind)
+         | True = Nothing
+
+       concrete KApp{} = True
+       concrete kind   = isADT kind && not (isUninterpreted kind)
diff --git a/Data/SBV/Compilers/C/GMP.hs b/Data/SBV/Compilers/C/GMP.hs
new file mode 100644
--- /dev/null
+++ b/Data/SBV/Compilers/C/GMP.hs
@@ -0,0 +1,801 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Data.SBV.Compilers.C.GMP
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Exact GMP-backed lowering of unbounded integers, reals, and rationals to C.
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Data.SBV.Compilers.C.GMP
+  ( isExactGMPKind
+  , gmpEqual
+  , gmpTypeDecls
+  , gmpRuntime
+  , gmpConst
+  , gmpExpr
+  , gmpPrint
+  , gmpSet
+  , gmpFunctionName
+  , gmpNewName
+  , gmpInitializeCopy
+  , gmpDriverAssign
+  , gmpOutputType
+  , gmpArrayType
+  , gmpDriverInitialize
+  , gmpDriverInit
+  , gmpDriverClear
+  , gmpContextStart
+  , gmpContextEnd
+  ) where
+
+import Data.SBV.Compilers.C.Syntax (cUnusedAttribute)
+import Data.Bits                       (shiftL)
+import Data.List                       (nub, stripPrefix, tails)
+import Data.Ratio                      (denominator, numerator)
+import qualified Data.Set as Set
+import qualified Data.Text as T
+import Numeric                         (showHex)
+
+import Text.PrettyPrint.HughesPJ
+import qualified Text.PrettyPrint.HughesPJ as P ((<>))
+
+import Data.SBV.Compilers.C.BV         (isWideBV, mappedIntegerKind)
+import Data.SBV.Compilers.C.Lowering   (CLowering, CRequirement(..), expressionLowering)
+import Data.SBV.Compilers.CodeGen      (CgConfig(..))
+import Data.SBV.Core.Data
+import Data.SBV.Core.Symbolic          (NROp(..))
+
+-- | Test whether a kind uses the exact GMP representation under this
+-- configuration. Supplying 'Data.SBV.Tools.CodeGen.cgIntegerSize' or
+-- 'Data.SBV.Tools.CodeGen.cgSRealType' selects the
+-- historical lossy representation for 'KUnbounded' or 'KReal'; 'KRational'
+-- is always exact.
+isExactGMPKind :: CgConfig -> Kind -> Bool
+isExactGMPKind cfg KUnbounded = case cgInteger cfg of
+                                  Nothing -> True
+                                  Just{}  -> False
+isExactGMPKind cfg KReal      = case cgReal cfg of
+                                  Nothing -> True
+                                  Just{}  -> False
+isExactGMPKind _   KRational  = True
+isExactGMPKind _   _          = False
+
+-- | Compare two exact GMP-backed values for equality.
+gmpEqual :: Kind -> Doc -> Doc -> Doc
+gmpEqual kind left right = parens $ namedCall (kindPrefix kind ++ "cmp") [left, right] <+> text "==" <+> text "0"
+
+-- | Declare the GMP-backed public C types required by the supplied kinds.
+-- Inputs are borrowed read-only pointers. Outputs and exact return parameters
+-- are caller-initialized mutable GMP pointers.
+gmpTypeDecls :: CgConfig -> Set.Set Kind -> Doc
+gmpTypeDecls cfg kinds
+  | not needsExactInteger && not needsExactQuotient = empty
+  | True                                            = text . unlines $
+      ["/* Exact integers, reals, and rationals. Inputs are borrowed; scalar outputs are caller-initialized. */"
+      , "/* Initialize each scalar/group output with mpz_init or mpq_init; clear it after its last use. */"
+      , "/* Aggregate outputs instead receive fresh owned values, including any embedded GMP fields. */"
+      , "#include <gmp.h>"
+      , cUnusedAttribute]
+   ++ integerDecls
+   ++ realDecls
+   ++ rationalDecls
+   ++ [""]
+ where needsExactInteger  = isExactGMPKind cfg KUnbounded && KUnbounded `Set.member` kinds
+       needsExactReal     = isExactGMPKind cfg KReal      && KReal      `Set.member` kinds
+       needsRational      = KRational `Set.member` kinds
+       needsExactQuotient = needsExactReal || needsRational
+
+       integerDecls
+         | needsExactInteger = [ "#ifndef SBV_GMP_INTEGER_DEFINED"
+                               , "#define SBV_GMP_INTEGER_DEFINED"
+                               , "typedef mpz_srcptr SInteger;"
+                               , "#endif"
+                               ]
+         | True              = []
+
+       realDecls
+         | needsExactReal = [ "#ifndef SBV_GMP_REAL_DEFINED"
+                            , "#define SBV_GMP_REAL_DEFINED"
+                            , "typedef mpq_srcptr SReal;"
+                            , "#endif"
+                            ]
+         | True           = []
+
+       rationalDecls
+         | needsRational = [ "#ifndef SBV_GMP_RATIONAL_DEFINED"
+                           , "#define SBV_GMP_RATIONAL_DEFINED"
+                           , "typedef mpq_srcptr SRational;"
+                           , "#endif"
+                           ]
+         | True          = []
+
+-- | Emit the per-call arena and the exact numeric helpers required by a
+-- program. Every temporary GMP value is released together at function exit.
+gmpRuntime :: CgConfig -> Set.Set Kind -> [(SV, SBVExpr)] -> Doc
+gmpRuntime cfg kinds assignments
+  | not needsExactInteger && not needsExactQuotient = empty
+  | True                                            = text . unlines . map markUnused $
+      commonRuntime
+   ++ [""]
+   ++ concat [integerRuntime needsIntegerShifts | needsExactInteger]
+   ++ concat [realRuntime     | needsExactQuotient]
+   ++ concat [rationalRuntime cfg | needsRational]
+   ++ concat [crossRuntime    | needsExactInteger && needsExactQuotient]
+   ++ concatMap nativeGMPResultRuntime (nativeGMPResultKinds cfg assignments)
+   ++ concat [concatMap wideIntegerRuntime conversions | needsExactInteger]
+   ++ concat [concatMap wideQuotientRuntime quotientConversions | needsExactQuotient]
+ where needsExactInteger   = isExactGMPKind cfg KUnbounded && KUnbounded `Set.member` kinds
+       needsExactReal      = isExactGMPKind cfg KReal      && KReal      `Set.member` kinds
+       needsRational       = KRational `Set.member` kinds
+       needsExactQuotient  = needsExactReal || needsRational
+       conversions         = nub (concatMap wideIntegerConversions assignments)
+       quotientConversions = nub (concatMap wideQuotientConversions assignments)
+       needsIntegerShifts = any integerShift assignments
+       integerShift (result, SBVApp operation _)
+         | kindOf result == KUnbounded = case operation of
+             Shl   -> True
+             Shr   -> True
+             Rol{} -> True
+             Ror{} -> True
+             _     -> False
+         | True = False
+
+       markUnused line = case stripPrefix "static " line of
+                           Just rest -> "static SBV_CGEN_UNUSED " ++ rest
+                           Nothing   -> line
+
+-- | Render an exact integer, real, or rational constant as an arena allocation.
+gmpConst :: CgConfig -> CV -> Maybe Doc
+gmpConst cfg (CV KUnbounded (CInteger i))
+  | isExactGMPKind cfg KUnbounded
+  = Just $ namedCall "sbv_gmp_integer_const" [text "&sbv_local_gmp_ctx", doubleQuotes (integer i)]
+gmpConst cfg (CV KReal (CAlgReal (AlgRational _ r)))
+  | isExactGMPKind cfg KReal
+  = Just $ namedCall "sbv_gmp_real_const" [text "&sbv_local_gmp_ctx", doubleQuotes (text value)]
+  where value = show (numerator r) ++ "/" ++ show (denominator r)
+gmpConst cfg (CV KReal (CAlgReal r))
+  | isExactGMPKind cfg KReal
+  = error $ "SBV->C: GMP-backed SReal constants must be rational, received " ++ show r
+gmpConst _ (CV KRational (CRational r))
+  = Just $ namedCall "sbv_gmp_real_const" [text "&sbv_local_gmp_ctx", doubleQuotes (text value)]
+  where value = show (numerator r) ++ "/" ++ show (denominator r)
+gmpConst _ _ = Nothing
+
+-- | Lower an operation involving an exact GMP value. A 'Nothing' result
+-- delegates the operation to another C lowering module.
+gmpExpr :: CgConfig -> Op -> [SV] -> Kind -> [Doc] -> Maybe CLowering
+gmpExpr cfg op svs resultKind args
+  | not (isExactGMPKind cfg resultKind || any (isExactGMPKind cfg . kindOf) svs)
+  = Nothing
+  | IEEEFP{} <- op
+  = Nothing
+  | KindCast fr to <- op
+  , Just{} <- cgReal cfg
+  , KReal `elem` [fr, to]
+  = Nothing
+  | LkUp{} <- op
+  = Nothing
+  | Uninterpreted functionName <- op
+  , T.unpack functionName /= "sbv.rat.numerator"
+  , T.unpack functionName /= "sbv.rat.denominator"
+  = Nothing
+  | True
+  = case (op, args, svs) of
+      (Label _              , [a]      , _)   -> lower a
+      (Plus                 , [a, b]   , x:_) -> lower $ valueCall x "add" [a, b]
+      (Minus                , [a, b]   , x:_) -> lower $ valueCall x "sub" [a, b]
+      (Times                , [a, b]   , x:_) -> lower $ valueCall x "mul" [a, b]
+      (NonLinear NR_IntPow  , [a, b]   , x:_) -> lower $ valueCall x "pow" [a, b]
+      (UNeg                 , [a]      , x:_) -> lower $ valueCall x "neg" [a]
+      (Abs                  , [a]      , x:_) -> lower $ valueCall x "abs" [a]
+      (Quot                 , [a, b]   , x:_) -> lower $ valueCall x "quot" [a, b]
+      (RationalConstructor  , [n, d]   , _)   -> lower $ namedCall "sbv_gmp_rational_construct" [text "&sbv_local_gmp_ctx", n, d]
+      (Uninterpreted funName, [a]      , _)
+        | T.unpack funName == "sbv.rat.numerator"   -> lower $ namedCall "sbv_gmp_rational_numerator" [a]
+        | T.unpack funName == "sbv.rat.denominator" -> lower $ namedCall "sbv_gmp_rational_denominator" [a]
+      (Rem                  , [a, b]   , x:_)
+        | kindOf x == KUnbounded                   -> lower $ valueCall x "rem" [a, b]
+      (And                  , [a, b]   , x:_)
+        | kindOf x == KUnbounded                   -> lower $ valueCall x "and" [a, b]
+      (Or                   , [a, b]   , x:_)
+        | kindOf x == KUnbounded                   -> lower $ valueCall x "or" [a, b]
+      (XOr                  , [a, b]   , x:_)
+        | kindOf x == KUnbounded                   -> lower $ valueCall x "xor" [a, b]
+      (Not                  , [a]      , x:_)
+        | kindOf x == KUnbounded                   -> lower $ valueCall x "com" [a]
+      (Shl                  , [a, n]   , x:_)
+        | kindOf x == KUnbounded                   -> lower $ valueCall x "shl" [a, n]
+      (Shr                  , [a, n]   , x:_)
+        | kindOf x == KUnbounded                   -> lower $ valueCall x "shr" [a, n]
+      (Rol n                , [a]      , x:_)
+        | kindOf x == KUnbounded                   -> lower $ valueCall x "shl" [a, integerValue n]
+      (Ror n                , [a]      , x:_)
+        | kindOf x == KUnbounded                   -> lower $ valueCall x "shr" [a, integerValue n]
+      (Equal _              , [a, b]   , x:_) -> lower $ comparison x "==" a b
+      (NotEqual             , as       , x:_) -> lower $ distinctExpr x as
+      (LessThan             , [a, b]   , x:_) -> lower $ comparison x "<"  a b
+      (GreaterThan          , [a, b]   , x:_) -> lower $ comparison x ">"  a b
+      (LessEq               , [a, b]   , x:_) -> lower $ comparison x "<=" a b
+      (GreaterEq            , [a, b]   , x:_) -> lower $ comparison x ">=" a b
+      (Divides n            , [a]      , x:_)
+        | kindOf x == KUnbounded                   -> lower $ namedCall "sbv_gmp_integer_divides"
+                                                               [namedCall "sbv_gmp_integer_const" [text "&sbv_local_gmp_ctx", doubleQuotes (integer n)], a]
+      (KindCast fr to       , [a]      , _)   -> gmpCast fr to a
+      _ -> unsupported
+ where lower = lowerWith [CRequiresGMP]
+
+       lowerWith requirements = Just . expressionLowering requirements
+
+       valueCall sv suffix = namedCall (kindPrefix (kindOf sv) ++ suffix) . (text "&sbv_local_gmp_ctx" :)
+
+       comparison sv relation a b = parens $ namedCall (kindPrefix (kindOf sv) ++ "cmp") [a, b] <+> text relation <+> text "0"
+
+       integerValue value = namedCall "sbv_gmp_integer_const" [text "&sbv_local_gmp_ctx", doubleQuotes (integer (fromIntegral value))]
+
+       distinctExpr sv as = fsep $ punctuate (text " &&")
+                                  [parens (namedCall (kindPrefix (kindOf sv) ++ "cmp") [a, b] <+> text "!= 0")
+                                  | (a:rest) <- tails as, b <- rest]
+
+       gmpCast fr to a
+         | fr == to = lower a
+         | fr == KUnbounded && to `elem` [KReal, KRational]
+         = if isExactGMPKind cfg KUnbounded
+           then lower $ namedCall "sbv_gmp_real_from_integer" [text "&sbv_local_gmp_ctx", a]
+           else lower $ namedCall "sbv_gmp_real_from_s64"
+                                  [text "&sbv_local_gmp_ctx", parens (text "int64_t") <+> a]
+         | fr == KReal && to == KUnbounded
+         = if isExactGMPKind cfg to
+           then lower $ namedCall "sbv_gmp_integer_from_real" [text "&sbv_local_gmp_ctx", a]
+           else lower $ nativeResult to (namedCall "sbv_gmp_real_low_u64" [a])
+         | isWideBV fr && to `elem` [KReal, KRational]
+         = lowerWith [CRequiresGMP, CRequiresWideBV] $ namedCall (quotientFromWideName fr) [text "&sbv_local_gmp_ctx", a]
+         | isWideBV fr && to == KUnbounded
+         = lowerWith [CRequiresGMP, CRequiresWideBV] $ namedCall (integerFromWideName fr) [text "&sbv_local_gmp_ctx", a]
+         | fr == KUnbounded && isWideBV to
+         = lowerWith [CRequiresGMP, CRequiresWideBV] $ namedCall (integerToWideName to) [a]
+         | isBounded fr && intSizeOf fr <= 64 && to == KUnbounded
+         = lower $ namedCall (if hasSign fr then "sbv_gmp_integer_from_s64" else "sbv_gmp_integer_from_u64")
+                             [text "&sbv_local_gmp_ctx", parens (text (if hasSign fr then "int64_t" else "uint64_t")) <+> a]
+         | fr == KUnbounded && isBounded to && not (isWideBV to)
+         = lower $ nativeResult to (namedCall "sbv_gmp_integer_low_u64" [a])
+         | isBounded fr && intSizeOf fr <= 64 && to `elem` [KReal, KRational]
+         = lower $ namedCall (if hasSign fr then "sbv_gmp_real_from_s64" else "sbv_gmp_real_from_u64")
+                             [text "&sbv_local_gmp_ctx", parens (text (if hasSign fr then "int64_t" else "uint64_t")) <+> a]
+         | fr == KReal && isBounded to && not (isWideBV to)
+         = lower $ nativeResult to (namedCall "sbv_gmp_real_low_u64" [a])
+         | otherwise
+         = unsupportedCast fr to
+
+       nativeResult to value = namedCall (nativeGMPResultName (mappedIntegerKind (cgInteger cfg) to)) [value]
+
+       unsupported = error $ "SBV->C: exact GMP lowering does not yet support " ++ show op
+                          ++ " with argument kinds " ++ show (map kindOf svs)
+                          ++ " and result kind " ++ show resultKind
+
+       unsupportedCast fr to = error $ "SBV->C: exact GMP lowering does not yet support a cast from " ++ show fr ++ " to " ++ show to
+
+-- | Discover native result representations for exact GMP casts. Explicitly
+-- mapped integers use the same low-bit conversion as signed bit-vectors.
+nativeGMPResultKinds :: CgConfig -> [(SV, SBVExpr)] -> [Kind]
+nativeGMPResultKinds cfg = nub . concatMap resultKind
+ where resultKind (_, SBVApp (KindCast fr to) _)
+         | isExactGMPKind cfg fr
+         , let target = mappedIntegerKind (cgInteger cfg) to
+         , isBounded target
+         , not (isWideBV target) = [target]
+       resultKind _ = []
+
+-- | Name a helper that interprets low integer bits in a native representation.
+nativeGMPResultName :: Kind -> String
+nativeGMPResultName kind = "sbv_gmp_low_bits_" ++ boundedTag kind
+
+-- | Convert reduced unsigned bits without implementation-defined signed
+-- narrowing or C's nonzero-to-Boolean conversion. A one-bit vector uses bit 0.
+nativeGMPResultRuntime :: Kind -> [String]
+nativeGMPResultRuntime kind =
+  [ "static " ++ boundedCType kind ++ " " ++ nativeGMPResultName kind ++ "(uint64_t value)"
+  , "{"
+  ]
+  ++ result
+  ++ ["}", ""]
+ where result
+         | kind == KBounded False 1
+         = ["  return (value & UINT64_C(1)) != 0;"]
+         | hasSign kind
+         = [ "  const SWord" ++ show (intSizeOf kind) ++ " bits = (SWord" ++ show (intSizeOf kind) ++ ") value;"
+           , "  " ++ boundedCType kind ++ " result; memcpy(&result, &bits, sizeof result); return result;"
+           ]
+         | True
+         = ["  return (" ++ boundedCType kind ++ ") value;"]
+
+-- | A generated conversion between a limb-backed bit-vector and an exact GMP
+-- integer.
+data WideIntegerConversion = IntegerFromWide Kind
+                           | IntegerToWide Kind
+                           deriving Eq
+
+-- | Discover wide bit-vector and exact-integer casts in one symbolic
+-- assignment.
+wideIntegerConversions :: (SV, SBVExpr) -> [WideIntegerConversion]
+wideIntegerConversions (_, SBVApp (KindCast fr to) _)
+  | isWideBV fr && to == KUnbounded = [IntegerFromWide fr]
+  | fr == KUnbounded && isWideBV to = [IntegerToWide to]
+wideIntegerConversions _ = []
+
+-- | A generated conversion from a limb-backed bit-vector to an exact GMP
+-- real or rational.
+newtype WideQuotientConversion = QuotientFromWide Kind
+                              deriving Eq
+
+-- | Discover limb-backed bit-vector to exact real or rational casts in one
+-- symbolic assignment.
+wideQuotientConversions :: (SV, SBVExpr) -> [WideQuotientConversion]
+wideQuotientConversions (_, SBVApp (KindCast fr to) _)
+  | isWideBV fr
+  , to `elem` [KReal, KRational] = [QuotientFromWide fr]
+wideQuotientConversions _ = []
+
+-- | Emit an exact conversion helper for one wide bit-vector kind.
+wideIntegerRuntime :: WideIntegerConversion -> [String]
+wideIntegerRuntime (IntegerFromWide k) =
+  [ "static SInteger " ++ integerFromWideName k ++ "(sbv_gmp_ctx *ctx, " ++ boundedCType k ++ " a)"
+  , "{"
+  , "  mpz_ptr r = sbv_gmp_new_integer(ctx);"
+  , "  mpz_import(r, " ++ show limbCount ++ ", -1, sizeof(a.limb[0]), 0, 0, a.limb);"
+  ]
+  ++ signedAdjustment
+  ++ [ "  return r;"
+     , "}"
+     , ""
+     ]
+ where limbCount = (intSizeOf k + 63) `div` 64
+       signedAdjustment
+         | hasSign k =
+             [ "  if ((a.limb[" ++ show topLimb ++ "] & " ++ u64 signMask ++ ") != 0) {"
+             , "    mpz_t modulus; mpz_init_set_ui(modulus, 1); mpz_mul_2exp(modulus, modulus, " ++ show width ++ ");"
+             , "    mpz_sub(r, r, modulus); mpz_clear(modulus);"
+             , "  }"
+             ]
+         | True = []
+       width    = intSizeOf k
+       topLimb  = (width - 1) `div` 64
+       signMask = 1 `shiftL` ((width - 1) `mod` 64)
+wideIntegerRuntime (IntegerToWide k) =
+  [ "static " ++ boundedCType k ++ " " ++ integerToWideName k ++ "(SInteger a)"
+  , "{"
+  , "  " ++ boundedCType k ++ " r = {{0}}; size_t count = 0; mpz_t reduced;"
+  , "  mpz_init(reduced); mpz_fdiv_r_2exp(reduced, a, " ++ show (intSizeOf k) ++ ");"
+  , "  mpz_export(r.limb, &count, -1, sizeof(r.limb[0]), 0, 0, reduced); mpz_clear(reduced);"
+  , "  r.limb[" ++ show (limbCount - 1) ++ "] &= " ++ u64 topMask ++ ";"
+  , "  return r;"
+  , "}"
+  , ""
+  ]
+ where limbCount = (intSizeOf k + 63) `div` 64
+       remainder = intSizeOf k `mod` 64
+       topMask
+         | remainder == 0 = (1 `shiftL` 64) - 1
+         | True           = (1 `shiftL` remainder) - 1
+
+-- | Emit an exact real-or-rational conversion helper for one wide bit-vector
+-- kind.
+wideQuotientRuntime :: WideQuotientConversion -> [String]
+wideQuotientRuntime (QuotientFromWide k) =
+  [ "static mpq_srcptr " ++ quotientFromWideName k ++ "(sbv_gmp_ctx *ctx, " ++ boundedCType k ++ " a)"
+  , "{"
+  , "  mpq_ptr r = sbv_gmp_new_real(ctx);"
+  , "  mpz_import(mpq_numref(r), " ++ show limbCount ++ ", -1, sizeof(a.limb[0]), 0, 0, a.limb);"
+  ]
+  ++ signedAdjustment
+  ++ [ "  return r;"
+     , "}"
+     , ""
+     ]
+ where limbCount = (intSizeOf k + 63) `div` 64
+       signedAdjustment
+         | hasSign k =
+             [ "  if ((a.limb[" ++ show topLimb ++ "] & " ++ u64 signMask ++ ") != 0) {"
+             , "    mpz_t modulus; mpz_init_set_ui(modulus, 1); mpz_mul_2exp(modulus, modulus, " ++ show width ++ ");"
+             , "    mpz_sub(mpq_numref(r), mpq_numref(r), modulus); mpz_clear(modulus);"
+             , "  }"
+             ]
+         | True = []
+       width    = intSizeOf k
+       topLimb  = (width - 1) `div` 64
+       signMask = 1 `shiftL` ((width - 1) `mod` 64)
+
+-- | Construct the helper name for a wide bit-vector to exact-integer cast.
+integerFromWideName :: Kind -> String
+integerFromWideName k = "sbv_gmp_integer_from_" ++ boundedTag k
+
+-- | Construct the helper name for an exact-integer to wide bit-vector cast.
+integerToWideName :: Kind -> String
+integerToWideName k = "sbv_gmp_integer_to_" ++ boundedTag k
+
+-- | Construct the helper name for a wide bit-vector to an exact GMP quotient.
+quotientFromWideName :: Kind -> String
+quotientFromWideName k = "sbv_gmp_real_from_" ++ boundedTag k
+
+-- | Return the C type used for a bounded SBV kind.
+boundedCType :: Kind -> String
+boundedCType (KBounded False 1) = "SBool"
+boundedCType (KBounded False w) = "SWord" ++ show w
+boundedCType (KBounded True  w) = "SInt"  ++ show w
+boundedCType k                  = error $ "SBV->C: Expected a bounded kind, received " ++ show k
+
+-- | Return the signedness-and-width suffix used in a conversion helper name.
+boundedTag :: Kind -> String
+boundedTag k
+  | isBounded k = (if hasSign k then "s" else "u") ++ show (intSizeOf k)
+  | True        = error $ "SBV->C: Expected a bounded kind, received " ++ show k
+
+-- | Render a padded, portable C @uint64_t@ literal.
+u64 :: Integer -> String
+u64 value = "UINT64_C(0x" ++ replicate (16 - length rendered) '0' ++ rendered ++ ")"
+ where rendered = showHex value ""
+
+-- | Print an exact GMP value in canonical decimal notation.
+gmpPrint :: Kind -> Doc -> Doc
+gmpPrint KUnbounded value = namedCall "gmp_printf" [doubleQuotes (text "%Zd"), value]
+gmpPrint KReal      value = namedCall "gmp_printf" [doubleQuotes (text "%Qd"), value]
+gmpPrint KRational  value = namedCall "gmp_printf" [doubleQuotes (text "%Qd"), value]
+gmpPrint k          _     = error $ "SBV->C: Expected an exact GMP kind, received " ++ show k
+
+-- | Copy an internal immutable exact value into caller-owned GMP storage.
+gmpSet :: Kind -> Doc -> Doc -> Doc
+gmpSet kind target value = namedCall (gmpFunctionName kind "set") [target, value]
+
+-- | Select a public GMP operation for storage already known to use the exact
+-- representation. Callers must check 'isExactGMPKind' before using this for a
+-- configurable integer or real kind.
+gmpFunctionName :: Kind -> String -> String
+gmpFunctionName kind suffix = gmpPrefix kind ++ suffix
+
+-- | Public GMP namespace for a kind whose storage has already been selected
+-- as exact. Representation selection belongs to 'isExactGMPKind'; this helper
+-- supplies the common prefix of both function and type names.
+gmpPrefix :: Kind -> String
+gmpPrefix KUnbounded = "mpz_"
+gmpPrefix KReal      = "mpq_"
+gmpPrefix KRational  = "mpq_"
+gmpPrefix kind       = error $ "SBV->C: Expected an exact GMP kind, received " ++ show kind
+
+-- | Name the arena allocator for an exact value. It returns initialized,
+-- mutable GMP storage owned by the supplied arena.
+gmpNewName :: Kind -> String
+gmpNewName KUnbounded = "sbv_gmp_new_integer"
+gmpNewName KReal      = "sbv_gmp_new_real"
+gmpNewName KRational  = "sbv_gmp_new_real"
+gmpNewName kind       = error $ "SBV->C: Expected an exact GMP kind, received " ++ show kind
+
+-- | Initialize uninitialized exact storage with a copy. GMP provides a
+-- combined operation for integers, but rationals require two calls.
+gmpInitializeCopy :: Kind -> Doc -> Doc -> Doc
+gmpInitializeCopy KUnbounded target value = namedCall "mpz_init_set" [target, value] P.<> semi
+gmpInitializeCopy kind       target value = namedCall (gmpFunctionName kind "init") [target] P.<> semi
+                                        $$ gmpSet kind target value P.<> semi
+
+-- | Assign an integer-valued decimal driver sample to an initialized field.
+-- The field may have the immutable public pointer type, so cast back to its
+-- owned mutable storage. Rational values are canonicalized after parsing.
+gmpDriverAssign :: Kind -> Doc -> Doc -> [Doc]
+gmpDriverAssign kind access value
+  = ( text "if" <+> parens (namedCall (gmpFunctionName kind "set_str") [target, doubleQuotes value, text "10"] <+> text "!= 0")
+                <+> namedCall "abort" [] P.<> semi
+    )
+  : [namedCall (gmpFunctionName kind "canonicalize") [target] P.<> semi | kind /= KUnbounded]
+ where target = parens (text (gmpOutputType kind)) <+> access
+
+-- | Return the mutable GMP pointer type used for an output parameter.
+gmpOutputType :: Kind -> String
+gmpOutputType kind = gmpPrefix kind ++ "ptr"
+
+-- | Return the mutable GMP storage type used for one element of a generated
+-- fixed-size array.
+gmpArrayType :: Kind -> String
+gmpArrayType kind = gmpPrefix kind ++ "t"
+
+-- | Initialize already-declared caller-owned GMP storage from an
+-- integer-valued driver sample.
+gmpDriverInitialize :: Kind -> Doc -> Doc -> Doc
+gmpDriverInitialize KUnbounded storage value = namedCall "mpz_init_set_str" [storage, doubleQuotes value, text "10"] P.<> semi
+gmpDriverInitialize KReal      storage value = namedCall "mpq_init" [storage] P.<> semi
+                                             $$ namedCall "mpq_set_str" [storage, doubleQuotes value, text "10"] P.<> semi
+                                             $$ namedCall "mpq_canonicalize" [storage] P.<> semi
+gmpDriverInitialize KRational  storage value = namedCall "mpq_init" [storage] P.<> semi
+                                             $$ namedCall "mpq_set_str" [storage, doubleQuotes value, text "10"] P.<> semi
+                                             $$ namedCall "mpq_canonicalize" [storage] P.<> semi
+gmpDriverInitialize kind       _       _     = error $ "SBV->C: Expected an exact GMP kind, received " ++ show kind
+
+-- | Declare and initialize a caller-owned GMP value from an integer-valued
+-- driver sample.
+gmpDriverInit :: Kind -> Doc -> Doc -> Doc
+gmpDriverInit kind storage value = text (gmpArrayType kind) <+> storage P.<> semi
+                                $$ gmpDriverInitialize kind storage value
+
+-- | Clear caller-owned GMP storage in a generated driver.
+gmpDriverClear :: Kind -> Doc -> Doc
+gmpDriverClear kind storage = namedCall (gmpFunctionName kind "clear") [storage] P.<> semi
+
+-- | Initialize the arena used by exact temporaries in a generated function.
+gmpContextStart :: Doc
+gmpContextStart = text "sbv_gmp_ctx sbv_local_gmp_ctx = {NULL};"
+
+-- | Release all exact temporaries allocated by a generated function.
+gmpContextEnd :: Doc
+gmpContextEnd = namedCall "sbv_gmp_ctx_end" [text "&sbv_local_gmp_ctx"] P.<> semi
+
+-- | Return the generated helper namespace for an exact numeric kind.
+kindPrefix :: Kind -> String
+kindPrefix KUnbounded = "sbv_gmp_integer_"
+kindPrefix KReal      = "sbv_gmp_real_"
+kindPrefix KRational  = "sbv_gmp_real_"
+kindPrefix k          = error $ "SBV->C: Expected an exact GMP kind, received " ++ show k
+
+-- | Render a C function call.
+namedCall :: String -> [Doc] -> Doc
+namedCall nm args = text nm P.<> parens (fsep (punctuate comma args))
+
+-- | Runtime shared by exact integers, reals, and rationals.
+commonRuntime :: [String]
+commonRuntime =
+  ["/* Per-call ownership arena for exact GMP temporaries. */"
+  , "typedef struct sbv_gmp_node {"
+  , "  struct sbv_gmp_node *next;"
+  , "  bool is_real;"
+  , "  union { mpz_t integer; mpq_t real; } value;"
+  , "} sbv_gmp_node;"
+  , ""
+  , "typedef struct { sbv_gmp_node *head; } sbv_gmp_ctx;"
+  , ""
+  , "static mpz_ptr sbv_gmp_new_integer(sbv_gmp_ctx *ctx)"
+  , "{"
+  , "  sbv_gmp_node *node = (sbv_gmp_node *) malloc(sizeof(*node));"
+  , "  if (node == NULL) abort();"
+  , "  node->next = ctx->head; node->is_real = false; ctx->head = node;"
+  , "  mpz_init(node->value.integer);"
+  , "  return node->value.integer;"
+  , "}"
+  , ""
+  , "static mpq_ptr sbv_gmp_new_real(sbv_gmp_ctx *ctx)"
+  , "{"
+  , "  sbv_gmp_node *node = (sbv_gmp_node *) malloc(sizeof(*node));"
+  , "  if (node == NULL) abort();"
+  , "  node->next = ctx->head; node->is_real = true; ctx->head = node;"
+  , "  mpq_init(node->value.real);"
+  , "  return node->value.real;"
+  , "}"
+  , ""
+  , "static void sbv_gmp_ctx_end(sbv_gmp_ctx *ctx)"
+  , "{"
+  , "  while (ctx->head != NULL) {"
+  , "    sbv_gmp_node *node = ctx->head; ctx->head = node->next;"
+  , "    if (node->is_real) mpq_clear(node->value.real); else mpz_clear(node->value.integer);"
+  , "    free(node);"
+  , "  }"
+  , "}"
+  , ""
+  , "static void sbv_gmp_ctx_release_owned(const void *context)"
+  , "{"
+  , "  sbv_gmp_ctx *owned = (sbv_gmp_ctx *) context;"
+  , "  sbv_gmp_ctx_end(owned);"
+  , "  free(owned);"
+  , "}"
+  ]
+
+-- | Runtime helpers for exact unbounded integers. Raw low-level shift nodes
+-- need additional helpers; ordinary SBV integer programs do not emit them.
+integerRuntime :: Bool -> [String]
+integerRuntime includeShifts =
+  ["static SInteger sbv_gmp_integer_const(sbv_gmp_ctx *ctx, const char *value)"
+  , "{ mpz_ptr r = sbv_gmp_new_integer(ctx); if (mpz_set_str(r, value, 10) != 0) abort(); return r; }"
+  , ""
+  , "static SInteger sbv_gmp_integer_from_u64(sbv_gmp_ctx *ctx, uint64_t value)"
+  , "{ mpz_ptr r = sbv_gmp_new_integer(ctx); mpz_import(r, 1, -1, sizeof(value), 0, 0, &value); return r; }"
+  , ""
+  , "static SInteger sbv_gmp_integer_from_s64(sbv_gmp_ctx *ctx, int64_t value)"
+  , "{"
+  , "  const uint64_t magnitude = value < 0 ? UINT64_C(0) - (uint64_t) value : (uint64_t) value;"
+  , "  mpz_ptr r = sbv_gmp_new_integer(ctx); mpz_import(r, 1, -1, sizeof(magnitude), 0, 0, &magnitude);"
+  , "  if (value < 0) mpz_neg(r, r); return r;"
+  , "}"
+  , ""
+  , "static uint64_t sbv_gmp_integer_low_u64(SInteger value)"
+  , "{"
+  , "  uint64_t result = 0; size_t count; mpz_t reduced;"
+  , "  mpz_init(reduced); mpz_fdiv_r_2exp(reduced, value, 64);"
+  , "  mpz_export(&result, &count, -1, sizeof(result), 0, 0, reduced); mpz_clear(reduced); return result;"
+  , "}"
+  , ""
+  ]
+  ++ concatMap integerUnary [("neg", "mpz_neg"), ("abs", "mpz_abs"), ("com", "mpz_com")]
+  ++ concatMap integerBinary [("add", "mpz_add"), ("sub", "mpz_sub"), ("mul", "mpz_mul"), ("and", "mpz_and"), ("or", "mpz_ior"), ("xor", "mpz_xor")]
+  ++ ["static SInteger sbv_gmp_integer_quot(sbv_gmp_ctx *ctx, SInteger a, SInteger b)"
+     , "{"
+     , "  mpz_ptr r = sbv_gmp_new_integer(ctx); mpz_t divisor;"
+     , "  if (mpz_sgn(b) == 0) { mpz_set(r, a); return r; }"
+     , "  mpz_init(divisor); mpz_abs(divisor, b); mpz_fdiv_q(r, a, divisor);"
+     , "  if (mpz_sgn(b) < 0) mpz_neg(r, r); mpz_clear(divisor); return r;"
+     , "}"
+     , ""
+     , "static SInteger sbv_gmp_integer_rem(sbv_gmp_ctx *ctx, SInteger a, SInteger b)"
+     , "{"
+     , "  mpz_ptr r = sbv_gmp_new_integer(ctx); mpz_t divisor;"
+     , "  if (mpz_sgn(b) == 0) { mpz_set(r, a); return r; }"
+     , "  mpz_init(divisor); mpz_abs(divisor, b); mpz_fdiv_r(r, a, divisor); mpz_clear(divisor); return r;"
+     , "}"
+     , ""
+     , "static int sbv_gmp_integer_cmp(SInteger a, SInteger b) { return mpz_cmp(a, b); }"
+     , ""
+     , "static bool sbv_gmp_integer_divides(SInteger divisor, SInteger value)"
+     , "{ return mpz_sgn(divisor) != 0 && mpz_divisible_p(value, divisor) != 0; }"
+     , ""
+     , "static SInteger sbv_gmp_integer_pow(sbv_gmp_ctx *ctx, SInteger base, SInteger exponent)"
+     , "{"
+     , "  mpz_ptr result = sbv_gmp_new_integer(ctx); mpz_t factor, power;"
+     , "  if (mpz_sgn(exponent) < 0) {"
+     , "    if (mpz_cmp_si(base, 1) == 0) mpz_set_ui(result, 1);"
+     , "    else if (mpz_cmp_si(base, -1) == 0) mpz_set_si(result, mpz_odd_p(exponent) ? -1 : 1);"
+     , "    else mpz_set_ui(result, 0);"
+     , "    return result;"
+     , "  }"
+     , "  mpz_set_ui(result, 1); mpz_init_set(factor, base); mpz_init_set(power, exponent);"
+     , "  while (mpz_sgn(power) != 0) {"
+     , "    if (mpz_odd_p(power)) mpz_mul(result, result, factor);"
+     , "    mpz_fdiv_q_2exp(power, power, 1);"
+     , "    if (mpz_sgn(power) != 0) mpz_mul(factor, factor, factor);"
+     , "  }"
+     , "  mpz_clear(power); mpz_clear(factor); return result;"
+     , "}"
+     , ""
+     ]
+  ++ [line | includeShifts, line <-
+     [ "static SInteger sbv_gmp_integer_shift(sbv_gmp_ctx *ctx, SInteger a, SInteger amount, bool left)"
+     , "{"
+     , "  mpz_ptr r = sbv_gmp_new_integer(ctx); mpz_t magnitude; bool effective_left = left;"
+     , "  mpz_init(magnitude); mpz_abs(magnitude, amount);"
+     , "  if (mpz_sgn(amount) < 0) effective_left = !effective_left;"
+     , "  if (!mpz_fits_ulong_p(magnitude)) {"
+     , "    if (effective_left) abort();"
+     , "    mpz_set_si(r, mpz_sgn(a) < 0 ? -1 : 0);"
+     , "  } else if (effective_left) {"
+     , "    mpz_mul_2exp(r, a, mpz_get_ui(magnitude));"
+     , "  } else {"
+     , "    mpz_fdiv_q_2exp(r, a, mpz_get_ui(magnitude));"
+     , "  }"
+     , "  mpz_clear(magnitude); return r;"
+     , "}"
+     , ""
+     , "static SInteger sbv_gmp_integer_shl(sbv_gmp_ctx *ctx, SInteger a, SInteger amount)"
+     , "{ return sbv_gmp_integer_shift(ctx, a, amount, true); }"
+     , ""
+     , "static SInteger sbv_gmp_integer_shr(sbv_gmp_ctx *ctx, SInteger a, SInteger amount)"
+     , "{ return sbv_gmp_integer_shift(ctx, a, amount, false); }"
+     , ""
+     ]
+     ]
+ where integerUnary (suffix, operation) =
+         ["static SInteger sbv_gmp_integer_" ++ suffix ++ "(sbv_gmp_ctx *ctx, SInteger a)"
+         , "{ mpz_ptr r = sbv_gmp_new_integer(ctx); " ++ operation ++ "(r, a); return r; }"
+         , ""]
+
+       integerBinary (suffix, operation) =
+         ["static SInteger sbv_gmp_integer_" ++ suffix ++ "(sbv_gmp_ctx *ctx, SInteger a, SInteger b)"
+         , "{ mpz_ptr r = sbv_gmp_new_integer(ctx); " ++ operation ++ "(r, a, b); return r; }"
+         , ""]
+
+-- | Runtime helpers shared by exact reals and symbolic rationals.
+realRuntime :: [String]
+realRuntime =
+  ["static mpq_srcptr sbv_gmp_real_const(sbv_gmp_ctx *ctx, const char *value)"
+  , "{ mpq_ptr r = sbv_gmp_new_real(ctx); if (mpq_set_str(r, value, 10) != 0) abort(); mpq_canonicalize(r); return r; }"
+  , ""
+  , "static mpq_srcptr sbv_gmp_real_from_u64(sbv_gmp_ctx *ctx, uint64_t value)"
+  , "{ mpq_ptr r = sbv_gmp_new_real(ctx); mpz_import(mpq_numref(r), 1, -1, sizeof(value), 0, 0, &value); return r; }"
+  , ""
+  , "static mpq_srcptr sbv_gmp_real_from_s64(sbv_gmp_ctx *ctx, int64_t value)"
+  , "{"
+  , "  const uint64_t magnitude = value < 0 ? UINT64_C(0) - (uint64_t) value : (uint64_t) value;"
+  , "  mpq_ptr r = sbv_gmp_new_real(ctx); mpz_import(mpq_numref(r), 1, -1, sizeof(magnitude), 0, 0, &magnitude);"
+  , "  if (value < 0) mpz_neg(mpq_numref(r), mpq_numref(r)); return r;"
+  , "}"
+  , ""
+  , "static uint64_t sbv_gmp_real_low_u64(mpq_srcptr value)"
+  , "{"
+  , "  uint64_t result = 0; size_t count; mpz_t rounded, reduced;"
+  , "  mpz_init(rounded); mpz_init(reduced); mpz_fdiv_q(rounded, mpq_numref(value), mpq_denref(value));"
+  , "  mpz_fdiv_r_2exp(reduced, rounded, 64); mpz_export(&result, &count, -1, sizeof(result), 0, 0, reduced);"
+  , "  mpz_clear(reduced); mpz_clear(rounded); return result;"
+  , "}"
+  , ""
+  ]
+  ++ concatMap realUnary [("neg", "mpq_neg"), ("abs", "mpq_abs")]
+  ++ concatMap realBinary [("add", "mpq_add"), ("sub", "mpq_sub"), ("mul", "mpq_mul")]
+  ++ ["static mpq_srcptr sbv_gmp_real_quot(sbv_gmp_ctx *ctx, mpq_srcptr a, mpq_srcptr b)"
+     , "{ mpq_ptr r = sbv_gmp_new_real(ctx); if (mpq_sgn(b) == 0) mpq_set_ui(r, 0, 1); else mpq_div(r, a, b); return r; }"
+     , ""
+     , "static int sbv_gmp_real_cmp(mpq_srcptr a, mpq_srcptr b) { return mpq_cmp(a, b); }"
+     , ""
+     ]
+ where realUnary (suffix, operation) =
+         ["static mpq_srcptr sbv_gmp_real_" ++ suffix ++ "(sbv_gmp_ctx *ctx, mpq_srcptr a)"
+         , "{ mpq_ptr r = sbv_gmp_new_real(ctx); " ++ operation ++ "(r, a); return r; }"
+         , ""]
+
+       realBinary (suffix, operation) =
+         ["static mpq_srcptr sbv_gmp_real_" ++ suffix ++ "(sbv_gmp_ctx *ctx, mpq_srcptr a, mpq_srcptr b)"
+         , "{ mpq_ptr r = sbv_gmp_new_real(ctx); " ++ operation ++ "(r, a, b); return r; }"
+         , ""]
+
+-- | Runtime helpers for the symbolic-rational constructor and internal
+-- numerator/denominator accessors.
+rationalRuntime :: CgConfig -> [String]
+rationalRuntime cfg
+  | isExactGMPKind cfg KUnbounded = exactRuntime
+  | Just width <- cgInteger cfg   = mappedRuntime width
+  | True                          = error "SBV->C: Cannot determine the SInteger representation used by SRational."
+ where exactRuntime =
+        ["static SRational sbv_gmp_rational_construct(sbv_gmp_ctx *ctx, mpz_srcptr numerator, mpz_srcptr denominator)"
+        , "{"
+        , "  mpq_ptr r = sbv_gmp_new_real(ctx);"
+        , "  if (mpz_sgn(denominator) == 0) { mpq_set_ui(r, 0, 1); return r; }"
+        , "  mpz_set(mpq_numref(r), numerator); mpz_set(mpq_denref(r), denominator);"
+        , "  if (mpz_sgn(mpq_denref(r)) < 0) { mpz_neg(mpq_numref(r), mpq_numref(r)); mpz_neg(mpq_denref(r), mpq_denref(r)); }"
+        , "  mpq_canonicalize(r); return r;"
+        , "}"
+        , ""
+        , "static mpz_srcptr sbv_gmp_rational_numerator(SRational value) { return mpq_numref(value); }"
+        , ""
+        , "static mpz_srcptr sbv_gmp_rational_denominator(SRational value) { return mpq_denref(value); }"
+        , ""
+        ]
+
+       mappedRuntime width =
+        ["static void sbv_gmp_rational_set_s64(mpz_ptr target, int64_t value)"
+        , "{"
+        , "  const uint64_t magnitude = value < 0 ? UINT64_C(0) - (uint64_t) value : (uint64_t) value;"
+        , "  mpz_import(target, 1, -1, sizeof(magnitude), 0, 0, &magnitude);"
+        , "  if (value < 0) mpz_neg(target, target);"
+        , "}"
+        , ""
+        , "static SInteger sbv_gmp_rational_part(mpz_srcptr value)"
+        , "{"
+        , "  " ++ unsignedType width ++ " bits = 0; size_t count; mpz_t reduced; SInteger result;"
+        , "  mpz_init(reduced); mpz_fdiv_r_2exp(reduced, value, " ++ show width ++ ");"
+        , "  mpz_export(&bits, &count, -1, sizeof(bits), 0, 0, reduced); mpz_clear(reduced);"
+        , "  memcpy(&result, &bits, sizeof result); return result;"
+        , "}"
+        , ""
+        , "static SRational sbv_gmp_rational_construct(sbv_gmp_ctx *ctx, SInteger numerator, SInteger denominator)"
+        , "{"
+        , "  mpq_ptr r = sbv_gmp_new_real(ctx);"
+        , "  if (denominator == 0) { mpq_set_ui(r, 0, 1); return r; }"
+        , "  sbv_gmp_rational_set_s64(mpq_numref(r), (int64_t) numerator);"
+        , "  sbv_gmp_rational_set_s64(mpq_denref(r), (int64_t) denominator);"
+        , "  if (mpz_sgn(mpq_denref(r)) < 0) { mpz_neg(mpq_numref(r), mpq_numref(r)); mpz_neg(mpq_denref(r), mpq_denref(r)); }"
+        , "  mpq_canonicalize(r); return r;"
+        , "}"
+        , ""
+        , "static SInteger sbv_gmp_rational_numerator(SRational value) { return sbv_gmp_rational_part(mpq_numref(value)); }"
+        , ""
+        , "static SInteger sbv_gmp_rational_denominator(SRational value) { return sbv_gmp_rational_part(mpq_denref(value)); }"
+        , ""
+        ]
+
+       unsignedType width = "SWord" ++ show width
+
+-- | Runtime helpers that convert between exact integers and GMP quotients.
+crossRuntime :: [String]
+crossRuntime =
+  ["static SInteger sbv_gmp_integer_from_real(sbv_gmp_ctx *ctx, mpq_srcptr a)"
+  , "{ mpz_ptr r = sbv_gmp_new_integer(ctx); mpz_fdiv_q(r, mpq_numref(a), mpq_denref(a)); return r; }"
+  , ""
+  , "static mpq_srcptr sbv_gmp_real_from_integer(sbv_gmp_ctx *ctx, SInteger a)"
+  , "{ mpq_ptr r = sbv_gmp_new_real(ctx); mpq_set_z(r, a); return r; }"
+  , ""
+  ]
diff --git a/Data/SBV/Compilers/C/Legacy.hs b/Data/SBV/Compilers/C/Legacy.hs
new file mode 100644
--- /dev/null
+++ b/Data/SBV/Compilers/C/Legacy.hs
@@ -0,0 +1,21 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Data.SBV.Compilers.C.Legacy
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Compatibility facade for the original SBV-to-C compiler.
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Data.SBV.Compilers.C.Legacy
+  ( compileToC
+  , compileToCLib
+  , compileToC'
+  , compileToCLib'
+  ) where
+
+import Data.SBV.Compilers.C.Legacy.Internal (compileToC, compileToC', compileToCLib, compileToCLib')
diff --git a/Data/SBV/Compilers/C/Legacy/Internal.hs b/Data/SBV/Compilers/C/Legacy/Internal.hs
new file mode 100644
--- /dev/null
+++ b/Data/SBV/Compilers/C/Legacy/Internal.hs
@@ -0,0 +1,1095 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Data.SBV.Compilers.C.Legacy.Internal
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Frozen compatibility implementation of the original SBV-to-C compiler.
+-- Based on the implementation before comprehensive backend work began,
+-- at SBV commit @8c161542945382014976a3cb1f9c17dc6e51b270@. The initial copy
+-- added Haddocks and formatting; subsequent changes are compatibility fixes,
+-- not a verbatim snapshot of today's master.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE TupleSections #-}
+
+{-# OPTIONS_GHC -Wall -Werror -Wno-incomplete-uni-patterns #-}
+
+module Data.SBV.Compilers.C.Legacy.Internal(compileToC, compileToCLib, compileToC', compileToCLib') where
+
+import Control.DeepSeq                (rnf)
+import Data.Char                      (isSpace)
+import Data.List                      (nub, intercalate)
+import Data.Maybe                     (isJust, isNothing, fromJust)
+import qualified Data.Foldable as F   (toList)
+import qualified Data.Set      as Set (member, union, unions, empty, toList, singleton, fromList)
+import qualified Data.Text     as T
+import System.FilePath                (takeBaseName, replaceExtension)
+import System.Random
+
+import Data.SBV.Core.Symbolic (ResultInp(..), ProgInfo(..))
+
+-- Work around the fact that GHC 8.4.1 started exporting <>.. Hmm..
+import Text.PrettyPrint.HughesPJ
+import qualified Text.PrettyPrint.HughesPJ as P ((<>))
+
+import Data.SBV.Core.Data
+import Data.SBV.Core.Kind (kRoundingMode)
+import Data.SBV.Compilers.C.PseudoBoolean (assignPseudoBoolean)
+import Data.SBV.Compilers.C.Real (mappedRealFloorWidth, mappedRealFloorCall, mappedRealFloorRuntime)
+import Data.SBV.Compilers.C.Syntax (cCommentText, cStringLiteral)
+import Data.SBV.Compilers.CodeGen
+
+import Data.SBV.Utils.PrettyNum   (chex, showCFloat, showCDouble)
+
+import GHC.Stack
+
+---------------------------------------------------------------------------
+-- * API
+---------------------------------------------------------------------------
+
+-- | Given a symbolic computation, render it as an equivalent collection of files
+-- that make up a C program:
+--
+--   * The first argument is the directory name under which the files will be saved. To save
+--     files in the current directory pass @'Just' \".\"@. Use 'Nothing' for printing to stdout.
+--
+--   * The second argument is the name of the C function to generate.
+--
+--   * The final argument is the function to be compiled.
+--
+-- Compilation will also generate a @Makefile@,  a header file, and a driver (test) program, etc. As a
+-- result, we return whatever the code-gen function returns. Most uses should simply have @()@ as
+-- the return type here, but the value can be useful if you want to chain the result of
+-- one compilation act to the next.
+compileToC :: Maybe FilePath -> String -> SBVCodeGen a -> IO a
+compileToC mbDirName nm f = do (retVal, cfg, bundle) <- compileToC' nm f
+                               renderCgPgmBundle mbDirName (cfg, bundle)
+                               pure retVal
+
+-- | Lower level version of 'compileToC', producing a t'CgPgmBundle'
+compileToC' :: String -> SBVCodeGen a -> IO (a, CgConfig, CgPgmBundle)
+compileToC' nm f = do rands <- randoms <$> newStdGen
+                      codeGen SBVToC (defaultCgConfig { cgDriverVals = rands }) nm f
+
+-- | Create code to generate a library archive (.a) from given symbolic functions. Useful when generating code
+-- from multiple functions that work together as a library.
+--
+--   * The first argument is the directory name under which the files will be saved. To save
+--     files in the current directory pass @'Just' \".\"@. Use 'Nothing' for printing to stdout.
+--
+--   * The second argument is the name of the archive to generate.
+--
+--   * The third argument is the list of functions to include, in the form of function-name/code pairs, similar
+--     to the second and third arguments of 'compileToC', except in a list.
+compileToCLib :: Maybe FilePath -> String -> [(String, SBVCodeGen a)] -> IO [a]
+compileToCLib mbDirName libName comps = do (retVal, cfg, pgm) <- compileToCLib' libName comps
+                                           renderCgPgmBundle mbDirName (cfg, pgm)
+                                           pure retVal
+
+-- | Lower level version of 'compileToCLib', producing a t'CgPgmBundle'
+compileToCLib' :: String -> [(String, SBVCodeGen a)] -> IO ([a], CgConfig, CgPgmBundle)
+compileToCLib' libName comps = do resCfgBundles <- mapM (uncurry compileToC') comps
+                                  let (finalCfg, finalPgm) = mergeToLib libName [(c, b) | (_, c, b) <- resCfgBundles]
+                                  pure ([r | (r, _, _) <- resCfgBundles], finalCfg, finalPgm)
+
+---------------------------------------------------------------------------
+-- * Implementation
+---------------------------------------------------------------------------
+
+-- | Target-language marker for the legacy C compiler.
+data SBVToC = SBVToC
+
+-- | Connect the legacy C compiler to the shared code-generation framework.
+instance CgTarget SBVToC where
+  targetName _ = "C"
+  translate  _ = cgen
+
+-- | Report an unexpected input to the legacy compiler.
+die :: String -> a
+die msg = error $ "SBV->C: Unexpected: " ++ msg
+
+-- | Report a feature unsupported by the legacy compiler.
+tbd :: String -> a
+tbd msg = error $ "SBV->C: Not yet supported: " ++ msg
+
+-- | Translate a symbolic result with the legacy C implementation.
+cgen :: CgConfig -> String -> CgState -> Result -> CgPgmBundle
+cgen cfg nm st sbvProg
+   -- we rnf the main pg and the sig to make sure any exceptions in type conversion pop-out early enough
+   -- this is purely cosmetic, of course..
+   = rnf (render sig) `seq` rnf (render (vcat body)) `seq` result
+  where result = CgPgmBundle bundleKind
+                        $ filt [ ("Makefile",  (CgMakefile flags, [genMake (cgGenDriver cfg) nm nmd flags]))
+                               , (nm  ++ ".h", (CgHeader [sig],   [genHeader bundleKind nm [sig] extProtos]))
+                               , (nmd ++ ".c", (CgDriver,         genDriver cfg randVals nm ins outs mbRet))
+                               , (nm  ++ ".c", (CgSource,         body))
+                               ]
+
+        (body, flagsNeeded) = genCProg cfg nm sig sbvProg ins outs mbRet extDecls
+
+        bundleKind = (cgInteger cfg, cgReal cfg)
+
+        randVals = cgDriverVals cfg
+
+        filt xs  = [c | c@(_, (k, _)) <- xs, need k]
+          where need k | isCgDriver   k = cgGenDriver cfg
+                       | isCgMakefile k = cgGenMakefile cfg
+                       | True           = True
+
+        nmd      = nm ++ "_driver"
+        sig      = pprCFunHeader nm ins outs mbRet
+        ins      = cgInputs st
+        outs     = cgOutputs st
+        mbRet    = case cgReturns st of
+                     []           -> Nothing
+                     [CgAtomic o] -> Just o
+                     [CgArray _]  -> tbd "Non-atomic return values"
+                     _            -> tbd "Multiple return values"
+        extProtos = case cgPrototypes st of
+                     [] -> empty
+                     xs -> vcat $ text "/* User given prototypes: */" : map text xs
+        extDecls  = case cgDecls st of
+                     [] -> empty
+                     xs -> vcat $ text "/* User given declarations: */" : map text xs
+        flags    = flagsNeeded ++ cgLDFlags st
+
+-- | Pretty print a functions type. If there is only one output, we compile it
+-- as a function that returns that value. Otherwise, we compile it as a void function
+-- that takes return values as pointers to be updated.
+pprCFunHeader :: String -> [(String, CgVal)] -> [(String, CgVal)] -> Maybe SV -> Doc
+pprCFunHeader fn ins outs mbRet = retType <+> text fn P.<> parens (fsep (punctuate comma (map mkParam ins ++ map mkPParam outs)))
+  where retType = case mbRet of
+                   Nothing -> text "void"
+                   Just sv -> pprCWord False sv
+
+-- | Render legacy C input and output parameters, respectively.
+mkParam, mkPParam :: (String, CgVal) -> Doc
+mkParam  (n, CgAtomic sv)     = pprCWord True  sv <+> text n
+mkParam  (_, CgArray  [])     = die "mkParam: CgArray with no elements!"
+mkParam  (n, CgArray  (sv:_)) = pprCWord True  sv <+> text "*" P.<> text n
+mkPParam (n, CgAtomic sv)     = pprCWord False sv <+> text "*" P.<> text n
+mkPParam (_, CgArray  [])     = die "mPkParam: CgArray with no elements!"
+mkPParam (n, CgArray  (sv:_)) = pprCWord False sv <+> text "*" P.<> text n
+
+-- | Renders as "const SWord8 s0", etc. the first parameter is the width of the typefield
+declSV :: Int -> SV -> Doc
+declSV w sv = text "const" <+> pad (showCType sv) <+> text (show sv)
+  where pad s = text $ s ++ replicate (w - length s) ' '
+
+-- | Return the proper declaration and the result as a pair. No consts
+declSVNoConst :: Int -> SV -> (Doc, Doc)
+declSVNoConst w sv = (text "     " <+> pad (showCType sv), text (show sv))
+  where pad s = text $ s ++ replicate (w - length s) ' '
+
+-- | Renders as "s0", etc, or the corresponding constant
+showSV :: CgConfig -> [(SV, CV)] -> SV -> Doc
+showSV cfg consts sv
+  | sv == falseSV                 = text "false"
+  | sv == trueSV                  = text "true"
+  | Just cv <- sv `lookup` consts = mkConst cfg cv
+  | True                          = text $ show sv
+
+-- | Words as it would map to a C word
+pprCWord :: HasKind a => Bool -> a -> Doc
+pprCWord cnst v = (if cnst then text "const" else empty) <+> text (showCType v)
+
+-- | Almost a "show", but map "SWord1" to "SBool"
+-- which is used for extracting one-bit words. This is OK since C's bool type
+-- handles arithmetic fine, and maps nicely to our `SWord 1`. (Same isn't true for `SInt 1`, which
+-- doesn't have an easy counter-part on the C side.
+showCType :: HasKind a => a -> String
+showCType i = case kindOf i of
+                KBounded False 1 -> "SBool"
+                k                -> show k
+
+-- | The printf specifier for the type
+specifier :: CgConfig -> SV -> Doc
+specifier cfg sv = case kindOf sv of
+                     KVar{}        -> die $ "variable sort: " ++ show (kindOf sv)
+                     KBool         -> spec (False, 1)
+                     KBounded b i  -> spec (b, i)
+                     KUnbounded    -> spec (True, fromJust (cgInteger cfg))
+                     KReal         -> specF (fromJust (cgReal cfg))
+                     KFloat        -> specF CgFloat
+                     KDouble       -> specF CgDouble
+                     KString       -> text "%s"
+                     KChar         -> text "%c"
+                     KRational     -> die   "rational sort"
+                     KFP{}         -> die   "arbitrary float sort"
+                     KList k       -> die $ "list sort: "   ++ show k
+                     KSet  k       -> die $ "set sort: "    ++ show k
+                     KApp s _      -> die $ "ADT app: "     ++ s
+                     KADT s _ _    -> die $ "ADT: "         ++ s
+                     KTuple k      -> die $ "tuple sort: "  ++ show k
+                     KArray  k1 k2 -> die $ "array sort: "  ++ show (k1, k2)
+  where u8InHex = cgShowU8InHex cfg
+
+        spec :: (Bool, Int) -> Doc
+        spec (False,  1) = text "%d"
+        spec (False,  8)
+          | u8InHex      = text "0x%02\"PRIx8\""
+          | True         = text "%\"PRIu8\""
+        spec (True,   8) = text "%\"PRId8\""
+        spec (False, 16) = text "0x%04\"PRIx16\"U"
+        spec (True,  16) = text "%\"PRId16\""
+        spec (False, 32) = text "0x%08\"PRIx32\"UL"
+        spec (True,  32) = text "%\"PRId32\"L"
+        spec (False, 64) = text "0x%016\"PRIx64\"ULL"
+        spec (True,  64) = text "%\"PRId64\"LL"
+        spec (s, sz)     = die $ "Format specifier at type " ++ (if s then "SInt" else "SWord") ++ show sz
+
+        specF :: CgSRealType -> Doc
+        specF CgFloat      = text "%a"
+        specF CgDouble     = text "%a"
+        specF CgLongDouble = text "%Lf"
+
+-- | Make a constant value of the given type. We don't check for out of bounds here, as it should not be needed.
+--   There are many options here, using binary, decimal, etc. We simply use decimal for values 8-bits or less,
+--   and hex otherwise.
+mkConst :: CgConfig -> CV -> Doc
+mkConst cfg  (CV KReal (CAlgReal (AlgRational _ r))) = double (fromRational r :: Double) P.<> sRealSuffix (fromJust (cgReal cfg))
+  where sRealSuffix CgFloat      = text "F"
+        sRealSuffix CgDouble     = empty
+        sRealSuffix CgLongDouble = text "L"
+mkConst cfg (CV KUnbounded       (CInteger i)) = showSizedConst (cgShowU8InHex cfg) i (True, fromJust (cgInteger cfg))
+mkConst cfg (CV (KBounded sg sz) (CInteger i)) = showSizedConst (cgShowU8InHex cfg) i (sg,   sz)
+mkConst cfg (CV KBool            (CInteger i)) = showSizedConst (cgShowU8InHex cfg) i (False, 1)
+mkConst _   (CV KFloat           (CFloat f))   = text $ showCFloat f
+mkConst _   (CV KDouble          (CDouble d))  = text $ showCDouble d
+mkConst _   (CV KString          (CString s))  = text $ show s
+mkConst _   (CV KChar            (CChar c))    = text $ show c
+mkConst _   cv                                 = die $ "mkConst: " ++ show cv
+
+-- | Render an integral constant using one of the legacy native C widths.
+showSizedConst :: Bool -> Integer -> (Bool, Int) -> Doc
+showSizedConst _   i   (False,  1) = text (if i == 0 then "false" else "true")
+showSizedConst u8h i t@(False,  8)
+  | u8h                            = text $ T.unpack (chex False True t i)
+  | True                           = integer i
+showSizedConst _   i   (True,   8) = integer i
+showSizedConst _   i t@(False, 16) = text $ T.unpack $ chex False True t i
+showSizedConst _   i t@(True,  16) = text $ T.unpack $ chex False True t i
+showSizedConst _   i t@(False, 32) = text $ T.unpack $ chex False True t i
+showSizedConst _   i t@(True,  32) = text $ T.unpack $ chex False True t i
+showSizedConst _   i t@(False, 64) = text $ T.unpack $ chex False True t i
+showSizedConst _   i t@(True,  64) = text $ T.unpack $ chex False True t i
+showSizedConst _   i   (s, sz)     = die $ "Constant " ++ show i ++ " at type " ++ (if s then "SInt" else "SWord") ++ show sz
+
+-- | Generate a makefile. The first argument is True if we have a driver.
+genMake :: Bool -> String -> String -> [String] -> Doc
+genMake ifdr fn dn ldFlags = foldr1 ($$) [l | (True, l) <- lns]
+ where ifld = not (null ldFlags)
+       ld | ifld = text "${LDFLAGS}"
+          | True = empty
+       lns = [ (True, text "# Makefile for" <+> nm P.<> text ". Automatically generated by SBV. Do not edit!")
+             , (True, text "")
+             , (True, text "# include any user-defined .mk file in the current directory.")
+             , (True, text "-include *.mk")
+             , (True, text "")
+             , (True, text "CC?=gcc")
+             , (True, text "CCFLAGS?=-Wall -O3 -DNDEBUG -fomit-frame-pointer")
+             , (ifld, text "LDFLAGS?=" P.<> text (unwords ldFlags))
+             , (True, text "")
+             , (ifdr, text "all:" <+> nmd)
+             , (ifdr, text "")
+             , (True, nmo P.<> text (": " ++ ppSameLine (hsep [nmc, nmh])))
+             , (True, text "\t${CC} ${CCFLAGS}" <+> text "-c $< -o $@")
+             , (True, text "")
+             , (ifdr, nmdo P.<> text (": " ++ ppSameLine (hsep [nmdc, nmh])))
+             , (ifdr, text "\t${CC} ${CCFLAGS}" <+> text "-c $< -o $@")
+             , (ifdr, text "")
+             , (ifdr, nmd P.<> text (": " ++ ppSameLine (hsep [nmo, nmdo])))
+             , (ifdr, text "\t${CC} ${CCFLAGS}" <+> text "$^ -o $@" <+> ld)
+             , (ifdr, text "")
+             , (True, text "clean:")
+             , (True, text "\trm -f *.o")
+             , (True, text "")
+             , (ifdr, text "veryclean: clean")
+             , (ifdr, text "\trm -f" <+> nmd)
+             , (ifdr, text "")
+             ]
+       nm   = text fn
+       nmd  = text dn
+       nmh  = nm P.<> text ".h"
+       nmc  = nm P.<> text ".c"
+       nmo  = nm P.<> text ".o"
+       nmdc = nmd P.<> text ".c"
+       nmdo = nmd P.<> text ".o"
+
+-- | Generate the header
+genHeader :: (Maybe Int, Maybe CgSRealType) -> String -> [Doc] -> Doc -> Doc
+genHeader (ik, rk) fn sigs protos =
+     text "/* Header file for" <+> nm P.<> text ". Automatically generated by SBV. Do not edit! */"
+  $$ text ""
+  $$ text "#ifndef" <+> tag
+  $$ text "#define" <+> tag
+  $$ text ""
+  $$ text "#include <stdio.h>"
+  $$ text "#include <stdlib.h>"
+  $$ text "#include <inttypes.h>"
+  $$ text "#include <stdint.h>"
+  $$ text "#include <stdbool.h>"
+  $$ text "#include <string.h>"
+  $$ text "#include <math.h>"
+  $$ text ""
+  $$ text "/* The boolean type */"
+  $$ text "typedef bool SBool;"
+  $$ text ""
+  $$ text "/* The float type */"
+  $$ text "typedef float SFloat;"
+  $$ text ""
+  $$ text "/* The double type */"
+  $$ text "typedef double SDouble;"
+  $$ text ""
+  $$ text "/* Unsigned bit-vectors */"
+  $$ text "typedef uint8_t  SWord8;"
+  $$ text "typedef uint16_t SWord16;"
+  $$ text "typedef uint32_t SWord32;"
+  $$ text "typedef uint64_t SWord64;"
+  $$ text ""
+  $$ text "/* Signed bit-vectors */"
+  $$ text "typedef int8_t  SInt8;"
+  $$ text "typedef int16_t SInt16;"
+  $$ text "typedef int32_t SInt32;"
+  $$ text "typedef int64_t SInt64;"
+  $$ text ""
+  $$ imapping
+  $$ rmapping
+  $$ text ("/* Entry point prototype" ++ plu ++ ": */")
+  $$ vcat (map (P.<> semi) sigs)
+  $$ text ""
+  $$ protos
+  $$ text "#endif /*" <+> tag <+> text "*/"
+  $$ text ""
+ where nm  = text fn
+       tag = text "__" P.<> nm P.<> text "__HEADER_INCLUDED__"
+       plu = if length sigs /= 1 then "s" else ""
+       imapping = case ik of
+                    Nothing -> empty
+                    Just i  ->    text "/* User requested mapping for SInteger.                                 */"
+                               $$ text "/* NB. Loss of precision: Target type is subject to modular arithmetic. */"
+                               $$ text ("typedef SInt" ++ show i ++ " SInteger;")
+                               $$ text ""
+       rmapping = case rk of
+                    Nothing -> empty
+                    Just t  ->    text "/* User requested mapping for SReal.                          */"
+                               $$ text "/* NB. Loss of precision: Target type is subject to rounding. */"
+                               $$ text ("typedef " ++ show t ++ " SReal;")
+                               $$ text ""
+
+-- | Emit a blank separator line when requested.
+sepIf :: Bool -> Doc
+sepIf b = if b then text "" else empty
+
+-- | Generate an example driver program
+genDriver :: CgConfig -> [Integer] -> String -> [(String, CgVal)] -> [(String, CgVal)] -> Maybe SV -> [Doc]
+genDriver cfg randVals fn inps outs mbRet = [pre, header, body, post]
+ where pre    =  text "/* Example driver program for" <+> nm P.<> text ". */"
+              $$ text "/* Automatically generated by SBV. Edit as you see fit! */"
+              $$ text ""
+              $$ text "#include <stdio.h>"
+       header =  text "#include" <+> doubleQuotes (nm P.<> text ".h")
+              $$ text ""
+              $$ text "int main(void)"
+              $$ text "{"
+       body   =  text ""
+              $$ nest 2 (   vcat (map mkInp pairedInputs)
+                      $$ vcat (map mkOut outs)
+                      $$ sepIf (not (null [() | (_, _, CgArray{}) <- pairedInputs]) || not (null outs))
+                      $$ call
+                      $$ text ""
+                      $$ (case mbRet of
+                              Just sv -> text "printf" P.<> parens (printQuotes (fcall <+> text "=" <+> specifier cfg sv P.<> text "\\n")
+                                                                              P.<> comma <+> resultVar) P.<> semi
+                              Nothing -> text "printf" P.<> parens (printQuotes (fcall <+> text "->\\n")) P.<> semi)
+                      $$ vcat (map display outs)
+                      )
+       post   =   text ""
+              $+$ nest 2 (text "return 0" P.<> semi)
+              $$  text "}"
+              $$  text ""
+       nm = text fn
+       pairedInputs = matchRands randVals inps
+       matchRands _      []                                 = []
+       matchRands []     _                                  = die "Run out of driver values!"
+       matchRands (r:rs) ((n, CgAtomic sv)            : cs) = ([mkRVal sv r], n, CgAtomic sv) : matchRands rs cs
+       matchRands _      ((n, CgArray [])             : _ ) = die $ "Unsupported empty array input " ++ show n
+       matchRands rs     ((n, a@(CgArray sws@(sv:_))) : cs)
+          | length frs /= l                                 = die "Run out of driver values!"
+          | True                                            = (map (mkRVal sv) frs, n, a) : matchRands srs cs
+          where l          = length sws
+                (frs, srs) = splitAt l rs
+       mkRVal sv r = mkConst cfg $ mkConstCV (kindOf sv) r
+       mkInp (_,  _, CgAtomic{})         = empty  -- constant, no need to declare
+       mkInp (_,  n, CgArray [])         = die $ "Unsupported empty array value for " ++ show n
+       mkInp (vs, n, CgArray sws@(sv:_)) =  pprCWord True sv <+> text n P.<> brackets (int (length sws)) <+> text "= {"
+                                                      $$ nest 4 (fsep (punctuate comma (align vs)))
+                                                      $$ text "};"
+                                         $$ text ""
+                                         $$ text "printf" P.<> parens (printQuotes (text "Contents of input array" <+> text n P.<> text ":\\n")) P.<> semi
+                                         $$ display (n, CgArray sws)
+                                         $$ text ""
+       mkOut (v, CgAtomic sv)            = pprCWord False sv <+> text v P.<> semi
+       mkOut (v, CgArray [])             = die $ "Unsupported empty array value for " ++ show v
+       mkOut (v, CgArray sws@(sv:_))     = pprCWord False sv <+> text v P.<> brackets (int (length sws)) P.<> semi
+       resultVar = text "__result"
+       call = case mbRet of
+                Nothing -> fcall P.<> semi
+                Just sv -> pprCWord True sv <+> resultVar <+> text "=" <+> fcall P.<> semi
+       fcall = nm P.<> parens (fsep (punctuate comma (map mkCVal pairedInputs ++ map mkOVal outs)))
+       mkCVal ([v], _, CgAtomic{}) = v
+       mkCVal (vs,  n, CgAtomic{}) = die $ "Unexpected driver value computed for " ++ show n ++ render (hcat vs)
+       mkCVal (_,   n, CgArray{})  = text n
+       mkOVal (n, CgAtomic{})      = text "&" P.<> text n
+       mkOVal (n, CgArray{})       = text n
+       display (n, CgAtomic sv)         = text "printf" P.<> parens (printQuotes (text " " <+> text n <+> text "=" <+> specifier cfg sv
+                                                                                P.<> text "\\n") P.<> comma <+> text n) P.<> semi
+       display (n, CgArray [])         =  die $ "Unsupported empty array value for " ++ show n
+       display (n, CgArray sws@(sv:_)) =   text "int" <+> nctr P.<> semi
+                                        $$ text "for(" P.<> nctr <+> text "= 0;" <+> nctr <+> text "<" <+> int len <+> text "; ++" P.<> nctr P.<> text ")"
+                                        $$ nest 2 (text "printf" P.<> parens (printQuotes (text " " <+> entrySpec <+> text "=" <+> spec P.<> text "\\n")
+                                                                 P.<> comma <+> nctr <+> comma P.<> entry) P.<> semi)
+                  where nctr      = text n P.<> text "_ctr"
+                        entry     = text n P.<> text "[" P.<> nctr P.<> text "]"
+                        entrySpec = text n P.<> text "[%" P.<> int tab P.<> text "d]"
+                        spec      = specifier cfg sv
+                        len       = length sws
+                        tab       = length $ show (len - 1)
+
+-- | Generate the C program
+genCProg :: CgConfig -> String -> Doc -> Result -> [(String, CgVal)] -> [(String, CgVal)] -> Maybe SV -> Doc -> ([Doc], [String])
+genCProg cfg fn proto (Result pinfo kindInfo _tvals _ovals cgs topInps (_, preConsts) tbls _uis axioms (SBVPgm asgns) cstrs origAsserts _) inVars outVars mbRet extDecls
+  | isNothing (cgInteger cfg) && KUnbounded `Set.member` kindInfo
+  = error $ "SBV->C: Unbounded integers are not supported by the C compiler."
+          ++ "\nUse 'cgIntegerSize' to specify a fixed size for SInteger representation."
+  | KString `Set.member` kindInfo
+  = notyet "Strings"
+  | KChar `Set.member` kindInfo
+  = notyet "Characters"
+  | any isSet kindInfo
+  = notyet "Sets (SSet)"
+  | any isList kindInfo
+  = notyet "Lists (SList)"
+  | any isTuple kindInfo
+  = notyet "Tuples (STupleN)"
+  | isNothing (cgReal cfg) && KReal `Set.member` kindInfo
+  = error $ "SBV->C: SReal values are not supported by the C compiler."
+          ++ "\nUse 'cgSRealType' to specify a custom type for SReal representation."
+  | not (null unsupportedBVs)
+  = error $ "SBV->C: Unsupported bit-vector type(s): " ++ intercalate ", " (map show unsupportedBVs)
+  | not (null usorts)
+  = error $ "SBV->C: Cannot compile functions with uninterpreted sorts: " ++ intercalate ", " usorts
+  | hasQuants pinfo
+  = error "SBV->C: Cannot compile in the presence of quantified variables."
+  | not $ null (progSpecialRels pinfo)
+  = error "SBV->C: Cannot compile in the presence of special relations."
+  | not (null axioms)
+  = error "SBV->C: Cannot compile in the presence of 'smtFunction' definitions, use 'compileToCLib' instead."
+  | not (null cstrs)
+  = tbd "Explicit constraints"
+  | True
+  = ([pre, header, post], flagsNeeded)
+ where notyet m = error $ "SBV->C: " ++ m ++ " are currently not supported by the C compiler. Please get in touch if you'd like support for this feature!"
+
+       asserts | cgIgnoreAsserts cfg = []
+               | True                = origAsserts
+
+       usorts = [s | k@(KADT s _ _) <- Set.toList kindInfo, isADT k && not (isRoundingMode k)] -- No support for any sorts other than RoundingMode!
+
+       pre    =  text "/* File:" <+> doubleQuotes (nm P.<> text ".c") P.<> text ". Automatically generated by SBV. Do not edit! */"
+              $$ text ""
+
+       header = text "#include" <+> doubleQuotes (nm P.<> text ".h")
+
+       unsupportedBVs = [k | k@(KBounded sg sz) <- Set.toList kindInfo, (not . supported) (sg, sz)]
+         where supported (False, sz) = sz `elem` [1, 8, 16, 32, 64]
+               supported (True,  sz) = sz `elem` [   8, 16, 32, 64]
+
+       post   = text ""
+             $$ vcat (map codeSeg cgs)
+             $$ extDecls
+             $$ mappedRealFloorRuntime cfg assignments
+             $$ proto
+             $$ text "{"
+             $$ text ""
+             $$ nest 2 (   vcat (concatMap (genIO True . (\v -> (isAlive v, v))) inVars)
+                        $$ vcat (merge (map genTbl tbls) (map genAsgn assignments) (map genAssert asserts))
+                        $$ sepIf (not (null assignments) || not (null tbls))
+                        $$ vcat (concatMap (genIO False . (True,)) outVars)
+                        $$ maybe empty mkRet mbRet
+                       )
+             $$ text "}"
+             $$ text ""
+
+       nm = text fn
+
+       assignments = F.toList asgns
+
+       -- Do we need any linker flags for C?
+       flagsNeeded = nub $ concatMap (getLDFlag . opRes) assignments
+          where opRes (sv, SBVApp o _) = (o, kindOf sv)
+
+       codeSeg (fnm, ls) =  text "/* User specified custom code for" <+> doubleQuotes (text fnm) <+> text "*/"
+                         $$ vcat (map text ls)
+                         $$ text ""
+
+       ins = case topInps of
+               ResultTopInps (is, []) -> is
+               ResultTopInps is       -> die $ "Unexpected trackers: " ++ show is
+               ResultLamInps is       -> die $ "Unexpected inputs  : " ++ show is
+
+       typeWidth = getMax 0 $ [len (kindOf s) | (s, _) <- assignments] ++ [len (kindOf s) | NamedSymVar s _ <- ins]
+                where len (KVar s)           = die $ "Variable: " ++ s
+                      len KReal{}            = 5
+                      len KFloat{}           = 6 -- SFloat
+                      len KDouble{}          = 7 -- SDouble
+                      len KString{}          = 7 -- SString
+                      len KChar{}            = 5 -- SChar
+                      len KUnbounded{}       = 8
+                      len KBool              = 5 -- SBool
+                      len (KBounded False n) = 5 + length (show n) -- SWordN
+                      len (KBounded True  n) = 4 + length (show n) -- SIntN
+                      len KRational{}        = die   "Rational."
+                      len KFP{}              = die   "Arbitrary float."
+                      len (KList s)          = die $ "List sort: "   ++ show s
+                      len (KSet  s)          = die $ "Set sort: "    ++ show s
+                      len (KTuple s)         = die $ "Tuple sort: "  ++ show s
+                      len (KArray  k1 k2)    = die $ "Array sort:  " ++ show (k1, k2)
+                      len (KApp s _)         = die $ "Uninterpreted ADT app: " ++ s
+                      len (KADT s _ _)       = die $ "Uninterpreted ADT: "     ++ s
+
+                      getMax 8 _      = 8  -- 8 is the max we can get with SInteger, so don't bother looking any further
+                      getMax m []     = m
+                      getMax m (x:xs) = getMax (m `max` x) xs
+
+       consts = (falseSV, falseCV) : (trueSV, trueCV) : preConsts
+
+       isConst s = isJust (lookup s consts)
+
+       -- TODO: The following is brittle. We should really have a function elsewhere
+       -- that walks the SBVExprs and collects the SWs together.
+       usedVariables = Set.unions (retSWs : map usedCgVal outVars ++ map usedAsgn assignments)
+         where retSWs = maybe Set.empty Set.singleton mbRet
+
+               usedCgVal (_, CgAtomic s)  = Set.singleton s
+               usedCgVal (_, CgArray ss)  = Set.fromList ss
+               usedAsgn  (_, SBVApp o ss) = Set.union (opSWs o) (Set.fromList ss)
+
+               opSWs (LkUp _ a b)             = Set.fromList [a, b]
+               opSWs (IEEEFP (FP_Cast _ _ s)) = Set.singleton s
+               opSWs _                        = Set.empty
+
+       isAlive :: (String, CgVal) -> Bool
+       isAlive (_, CgAtomic sv) = sv `Set.member` usedVariables
+       isAlive (_, _)           = True
+
+       genIO :: Bool -> (Bool, (String, CgVal)) -> [Doc]
+       genIO True  (alive, (cNm, CgAtomic sv)) = [declSV typeWidth sv  <+> text "=" <+> text cNm P.<> semi               | alive]
+       genIO False (alive, (cNm, CgAtomic sv)) = [text "*" P.<> text cNm <+> text "=" <+> showSV cfg consts sv P.<> semi | alive]
+       genIO isInp (_,     (cNm, CgArray sws)) = zipWith genElt sws [(0::Int)..]
+         where genElt sv i
+                 | isInp = declSV typeWidth sv <+> text "=" <+> text entry       P.<> semi
+                 | True  = text entry          <+> text "=" <+> showSV cfg consts sv P.<> semi
+                 where entry = cNm ++ "[" ++ show i ++ "]"
+
+       mkRet sv = text "return" <+> showSV cfg consts sv P.<> semi
+
+       genTbl :: ((Int, Kind, Kind), [SV]) -> (Int, Doc)
+       genTbl ((i, _, k), elts) =  (location, static <+> text "const" <+> text (show k) <+> text ("table" ++ show i) P.<> text "[] = {"
+                                              $$ nest 4 (fsep (punctuate comma (align (map (showSV cfg consts) elts))))
+                                              $$ text "};")
+         where static   = if location == -1 then text "static" else empty
+               location = maximum (-1 : map getNodeId elts)
+
+       getNodeId s@(SV _ (NodeId (_, _, n))) | isConst s = -1
+                                             | True      = n
+
+       genAsgn :: (SV, SBVExpr) -> (Int, Doc)
+       genAsgn (sv, n) = (getNodeId sv, ppExpr cfg consts n (declSV typeWidth sv) (declSVNoConst typeWidth sv) P.<> semi)
+
+       -- merge tables intermixed with assignments and assertions, paying attention to putting tables as
+       -- early as possible and tables right after.. Note that the assignment list (second argument) is sorted on its order
+       merge :: [(Int, Doc)] -> [(Int, Doc)] -> [(Int, Doc)] -> [Doc]
+       merge tables asgnments asrts = map snd $ merge2 asrts (merge2 tables asgnments)
+         where merge2 []               as                  = as
+               merge2 ts               []                  = ts
+               merge2 ts@((i, t):trest) as@((i', a):arest)
+                 | i < i'                                 = (i,  t)  : merge2 trest as
+                 | True                                   = (i', a) : merge2 ts arest
+
+       genAssert (msg, cs, sv) = (getNodeId sv, doc)
+         where doc =     text "/* ASSERTION:" <+> cCommentText msg
+                     $$  maybe empty (vcat . map cCommentText) (locInfo (getCallStack <$> cs))
+                     $$  text " */"
+                     $$  text "if" P.<> parens (showSV cfg consts sv)
+                     $$  text "{"
+                     $+$ nest 2 (vcat [errOut, text "exit(-1);"])
+                     $$  text "}"
+                     $$  text ""
+               errOut = text "fprintf(stderr, \"%s:%d:ASSERTION FAILED: %s\\n\", __FILE__, __LINE__,"
+                    <+> cStringLiteral msg P.<> text ");"
+               locInfo (Just ps) = let loc (f, sl) = concat [srcLocFile sl, ":", show (srcLocStartLine sl), ":", show (srcLocStartCol sl), ":", f ]
+                                   in case map loc ps of
+                                         []     -> Nothing
+                                         (f:rs) -> Just $ (" * SOURCE   : " ++ f) : map (" *            " ++)  rs
+               locInfo _         = Nothing
+
+-- | Render a native floating-point operation with the legacy lowering.
+handleIEEE :: FPOp -> [(SV, CV)] -> [(SV, Doc)] -> Doc -> Doc
+handleIEEE w consts as var = cvt w
+  where same f                   = (f, f)
+        named fnm dnm f          = (f fnm, f dnm)
+
+        cvt (FP_Cast from to m)     = case checkRM (m `lookup` consts) of
+                                        Nothing          -> cast $ \[a] -> parens (text (show to)) <+> rnd a
+                                        Just (Left  msg) -> die msg
+                                        Just (Right msg) -> tbd msg
+                                      where -- if we're converting from float to some integral like; first use rint/rintf to do the internal conversion and then cast.
+                                            rnd a
+                                             | (isFloat from || isDouble from) && (isBounded to || isUnbounded to)
+                                             = let f = if isFloat from then "rintf" else "rint"
+                                               in text f P.<> parens a
+                                             | True
+                                             = a
+
+        cvt (FP_Reinterpret f t) = case (f, t) of
+                                     (KBounded False 32, KFloat)  -> cast $ cpy "sizeof(SFloat)"
+                                     (KBounded False 64, KDouble) -> cast $ cpy "sizeof(SDouble)"
+                                     (KFloat,  KBounded False 32) -> cast $ cpy "sizeof(SWord32)"
+                                     (KDouble, KBounded False 64) -> cast $ cpy "sizeof(SWord64)"
+                                     _                            -> die $ "Reinterpretation from : " ++ show f ++ " to " ++ show t
+                                    where cpy sz = \[a] -> let alhs = text "&" P.<> var
+                                                               arhs = text "&" P.<> a
+                                                           in text "memcpy" P.<> parens (fsep (punctuate comma [alhs, arhs, text sz]))
+        cvt FP_Abs               = dispatch $ named "fabsf" "fabs" $ \nm _ [a] -> text nm P.<> parens a
+        cvt FP_Neg               = dispatch $ same $ \_ [a] -> text "-" P.<> a
+        cvt FP_Add               = dispatch $ same $ \_ [a, b] -> a <+> text "+" <+> b
+        cvt FP_Sub               = dispatch $ same $ \_ [a, b] -> a <+> text "-" <+> b
+        cvt FP_Mul               = dispatch $ same $ \_ [a, b] -> a <+> text "*" <+> b
+        cvt FP_Div               = dispatch $ same $ \_ [a, b] -> a <+> text "/" <+> b
+        cvt FP_FMA               = dispatch $ named "fmaf"  "fma"  $ \nm _ [a, b, c] -> text nm P.<> parens (fsep (punctuate comma [a, b, c]))
+        cvt FP_Sqrt              = dispatch $ named "sqrtf" "sqrt" $ \nm _ [a]       -> text nm P.<> parens a
+        cvt FP_Rem               = dispatch $ named "fmodf" "fmod" $ \nm _ [a, b]    -> text nm P.<> parens (fsep (punctuate comma [a, b]))
+        cvt FP_RoundToIntegral   = dispatch $ named "rintf" "rint" $ \nm _ [a]       -> text nm P.<> parens a
+        cvt FP_Min               = dispatch $ named "fminf" "fmin" $ \nm k [a, b]    -> wrapMinMax k a b (text nm P.<> parens (fsep (punctuate comma [a, b])))
+        cvt FP_Max               = dispatch $ named "fmaxf" "fmax" $ \nm k [a, b]    -> wrapMinMax k a b (text nm P.<> parens (fsep (punctuate comma [a, b])))
+        cvt FP_ObjEqual          = let mkIte   x y z = x <+> text "?" <+> y <+> text ":" <+> z
+                                       chkNaN  x     = text "isnan"   P.<> parens x
+                                       signbit x     = text "signbit" P.<> parens x
+                                       eq      x y   = parens (x <+> text "==" <+> y)
+                                       eqZero  x     = eq x (text "0")
+                                       negZero x     = parens (signbit x <+> text "&&" <+> eqZero x)
+                                   in dispatch $ same $ \_ [a, b] -> mkIte (chkNaN a) (chkNaN b) (mkIte (negZero a) (negZero b) (mkIte (negZero b) (negZero a) (eq a b)))
+        cvt FP_IsNormal          = dispatch $ same $ \_ [a] -> text "isnormal" P.<> parens a
+        cvt FP_IsSubnormal       = dispatch $ same $ \_ [a] -> text "FP_SUBNORMAL == fpclassify" P.<> parens a
+        cvt FP_IsZero            = dispatch $ same $ \_ [a] -> text "FP_ZERO == fpclassify" P.<> parens a
+        cvt FP_IsInfinite        = dispatch $ same $ \_ [a] -> text "isinf" P.<> parens a
+        cvt FP_IsNaN             = dispatch $ same $ \_ [a] -> text "isnan" P.<> parens a
+        cvt FP_IsNegative        = dispatch $ same $ \_ [a] -> text "!isnan" P.<> parens a <+> text "&&" <+> text "signbit"  P.<> parens a
+        cvt FP_IsPositive        = dispatch $ same $ \_ [a] -> text "!isnan" P.<> parens a <+> text "&&" <+> text "!signbit" P.<> parens a
+
+        -- grab the rounding-mode, if present, and make sure it's RoundNearestTiesToEven. Otherwise skip.
+        fpArgs = case as of
+                   []            -> []
+                   ((m, _):args)
+                     | isRoundingMode m -> case checkRM (m `lookup` consts) of
+                                             Nothing          -> args
+                                             Just (Left  msg) -> die msg
+                                             Just (Right msg) -> tbd msg
+                     | True              -> as
+
+        -- Check that the RM is RoundNearestTiesToEven.
+        -- If we start supporting other rounding-modes, this would be the point where we'd insert the rounding-mode set/reset code
+        -- instead of merely returning OK or not
+        checkRM (Just cv@(CV k v))
+          | k == kRoundingMode = case v of
+                                   CADT ("RoundNearestTiesToEven", []) -> Nothing
+                                   CADT (s,                        []) -> Just (Right $ "handleIEEE: Unsupported rounding-mode: " ++ show s ++ " for: " ++ show w)
+                                   _                                   -> Just (Left  $ "handleIEEE: Unexpected value for rounding-mode: " ++ show cv ++ " for: " ++ show w)
+        checkRM (Just cv) = Just (Left  $ "handleIEEE: Expected rounding-mode, but got: " ++ show cv ++ " for: " ++ show w)
+        checkRM Nothing   = Just (Right $ "handleIEEE: Non-constant rounding-mode for: " ++ show w)
+
+        pickOp _          []             = die $ "Cannot determine float/double kind for op: " ++ show w
+        pickOp (fOp, dOp) args@((a,_):_) = case kindOf a of
+                                             KFloat  -> fOp KFloat  (map snd args)
+                                             KDouble -> dOp KDouble (map snd args)
+                                             k       -> die $ "handleIEEE: Expected double/float args, but got: " ++ show k ++ " for: " ++ show w
+
+        dispatch (fOp, dOp) = pickOp (fOp, dOp) fpArgs
+        cast f              = f (map snd fpArgs)
+
+        -- In SMT-Lib, fpMin/fpMax is underspecified when given +0/-0 as the two arguments. (In any order.)
+        -- In C, the second argument is returned. (I think, might depend on the architecture, optimizations etc.).
+        -- We'll translate it so that we deterministically return +0.
+        -- There's really no good choice here.
+        wrapMinMax k a b s = parens cond <+> text "?" <+> fzero <+> text ":" <+> s
+          where fzero = text $ if k == KFloat then showCFloat 0 else showCDouble 0
+                cond  =                   parens (text "FP_ZERO == fpclassify" P.<> parens a)                                  -- a is zero
+                        <+> text "&&" <+> parens (text "FP_ZERO == fpclassify" P.<> parens b)                                  -- b is zero
+                        <+> text "&&" <+> parens (text "signbit" P.<> parens a <+> text "!=" <+> text "signbit" P.<> parens b) -- a and b differ in sign
+
+-- | Render one symbolic assignment with the legacy operation dispatcher.
+ppExpr :: CgConfig -> [(SV, CV)] -> SBVExpr -> Doc -> (Doc, Doc) -> Doc
+ppExpr cfg consts (SBVApp op opArgs) lhs (typ, var)
+  | doNotAssign op
+  = typ <+> var P.<> semi <+> rhs
+  | True
+  = lhs <+> text "=" <+> rhs
+  where doNotAssign (IEEEFP FP_Reinterpret{}) = True   -- generates a memcpy instead; no simple assignment
+        doNotAssign PseudoBoolean{}            = True   -- assigns through an overflow-safe reduction
+        doNotAssign _                          = False  -- generates simple assignment
+
+        rhs = p op (map (showSV cfg consts) opArgs)
+
+        rtc = cgRTC cfg
+
+        cBinOps = [ (Plus, "+"), (Times, "*"), (Minus, "-")
+                  , (Equal False, "==")  -- no strong equality!
+                  , (NotEqual, "!="), (LessThan, "<"), (GreaterThan, ">"), (LessEq, "<="), (GreaterEq, ">=")
+                  , (And, "&"), (Or, "|"), (XOr, "^")
+                  ]
+
+        -- see if we can find a constant shift; makes the output way more readable
+        getShiftAmnt def [_, sv] = case sv `lookup` consts of
+                                    Just (CV _  (CInteger i)) -> integer i
+                                    _                         -> def
+        getShiftAmnt def _       = def
+
+        hd _ (h:_) = h
+        hd w []    = error $ "Data.SBV.C.ppExpr: Impossible happened: " ++ w ++ ", received empty list!"
+
+        p :: Op -> [Doc] -> Doc
+        p ReadArray{}       _  = tbd "User specified arrays (ReadArray)"
+        p WriteArray{}      _  = tbd "User specified arrays (WriteArray)"
+        p (Label s)        [a] = a <+> text "/*" <+> cCommentText s <+> text "*/"
+        p (IEEEFP w)         as = handleIEEE w  consts (zip opArgs as) var
+        p (PseudoBoolean pb) as = assignPseudoBoolean pb as var
+        p (OverflowOp o) _      = tbd $ "Overflow operations" ++ show o
+        p castOp@KindCast{} [a]
+          | Just width <- mappedRealFloorWidth cfg castOp
+          = mappedRealFloorCall width a
+        p (KindCast _ to)   [a] = parens (text (show to)) <+> a
+        p (Uninterpreted s) [] = text "/* Uninterpreted constant */" <+> text (T.unpack s)
+        p (Uninterpreted s) as = text "/* Uninterpreted function */" <+> text (T.unpack s) P.<> parens (fsep (punctuate comma as))
+        p (Extract i j) [a]    = extract i j (hd "Extract" opArgs) a
+        p Join [a, b]          = join (let (s1 : s2 : _) = opArgs in (s1, s2, a, b))
+        p (Rol i) [a]          = rotate True  i a (hd "Rol" opArgs)
+        p (Ror i) [a]          = rotate False i a (hd "Ror" opArgs)
+        p Shl     [a, i]       = shift  True  (getShiftAmnt i opArgs) a -- The order of i/a being reversed here is
+        p Shr     [a, i]       = shift  False (getShiftAmnt i opArgs) a -- intentional and historical (from the days when Shl/Shr had a constant parameter.)
+        p Not [a]              = case kindOf (hd "Not" opArgs) of
+                                   -- be careful about booleans, bitwise complement is not correct for them!
+                                   KBool -> text "!" P.<> a
+                                   _     -> text "~" P.<> a
+        p Ite [a, b, c] = a <+> text "?" <+> b <+> text ":" <+> c
+        p (LkUp (t, k, _, len) ind def) []
+          | not rtc                    = lkUp -- ignore run-time-checks per user request
+          | needsCheckL && needsCheckR = cndLkUp checkBoth
+          | needsCheckL                = cndLkUp checkLeft
+          | needsCheckR                = cndLkUp checkRight
+          | True                       = lkUp
+          where [index, defVal] = map (showSV cfg consts) [ind, def]
+
+                lkUp = text "table" P.<> int t P.<> brackets (showSV cfg consts ind)
+                cndLkUp cnd = cnd <+> text "?" <+> defVal <+> text ":" <+> lkUp
+
+                checkLeft  = index <+> text "< 0"
+                checkRight = index <+> text ">=" <+> int len
+                checkBoth  = parens (checkLeft <+> text "||" <+> checkRight)
+
+                canOverflow True  sz = (2::Integer)^(sz-1)-1 >= fromIntegral len
+                canOverflow False sz = (2::Integer)^sz    -1 >= fromIntegral len
+
+                (needsCheckL, needsCheckR) = case k of
+                                               KVar{}          -> die $ "array index with variable: " ++ show k
+                                               KBool           -> (False, canOverflow False (1::Int))
+                                               KBounded sg sz  -> (sg, canOverflow sg sz)
+                                               KReal           -> die "array index with real value"
+                                               KFloat          -> die "array index with float value"
+                                               KDouble         -> die "array index with double value"
+                                               KFP{}           -> die "array index with arbitrary float value"
+                                               KRational       -> die "array index with rational value"
+                                               KString         -> die "array index with string value"
+                                               KChar           -> die "array index with character value"
+                                               KUnbounded      -> case cgInteger cfg of
+                                                                    Nothing -> (True, True) -- won't matter, it'll be rejected later
+                                                                    Just i  -> (True, canOverflow True i)
+                                               KList     s     -> die $ "List sort "   ++ show s
+                                               KSet      s     -> die $ "Set sort "    ++ show s
+                                               KTuple    s     -> die $ "Tuple sort "  ++ show s
+                                               KArray    k1 k2 -> die $ "Array  sort " ++ show (k1, k2)
+                                               KApp      s _   -> die $ "ADT app: " ++ s
+                                               KADT      s _ _ -> die $ "ADT: "     ++ s
+
+        -- Div/Rem should be careful on 0, in the SBV world x `div` 0 is 0, x `rem` 0 is x
+        -- NB: Quot is supposed to truncate toward 0; Not clear to me if C guarantees this behavior.
+        -- Brief googling suggests C99 does indeed truncate toward 0, but other C compilers might differ.
+        p Quot [a, b] = let k = kindOf (hd "Quot" opArgs)
+                            z = mkConst cfg $ mkConstCV k (0::Integer)
+                        in protectDiv0 k "/" z a b
+        p Rem  [a, b] = protectDiv0 (kindOf (hd "Rem" opArgs)) "%" a a b
+        p UNeg [a]    = parens (text "-" <+> a)
+        p Abs  [a]    = let f KFloat             = text "fabsf" P.<> parens a
+                            f KDouble            = text "fabs"  P.<> parens a
+                            f (KBounded False _) = text "/* unsigned, skipping call to abs */" <+> a
+                            f (KBounded True 32) = text "labs"  P.<> parens a
+                            f (KBounded True 64) = text "llabs" P.<> parens a
+                            f KUnbounded         = case cgInteger cfg of
+                                                     Nothing -> f $ KBounded True 32 -- won't matter, it'll be rejected later
+                                                     Just i  -> f $ KBounded True i
+                            f KReal              = case cgReal cfg of
+                                                     Nothing           -> f KDouble -- won't matter, it'll be rejected later
+                                                     Just CgFloat      -> f KFloat
+                                                     Just CgDouble     -> f KDouble
+                                                     Just CgLongDouble -> text "fabsl" P.<> parens a
+                            f _                  = text "abs" P.<> parens a
+                        in f (kindOf (hd "Abs" opArgs))
+        -- for And/Or, translate to boolean versions if on boolean kind
+        p And [a, b] | kindOf (hd "And" opArgs) == KBool = a <+> text "&&" <+> b
+        p Or  [a, b] | kindOf (hd "Or"  opArgs) == KBool = a <+> text "||" <+> b
+        p o [a, b]
+          | Just co <- lookup o cBinOps
+          = a <+> text co <+> b
+
+        p Implies [a, b] | kindOf (hd "Implies" opArgs) == KBool = parens (text "!" P.<> a <+> text "||" <+> b)
+
+        p NotEqual xs = mkDistinct xs
+        p o args = die $ "Received operator " ++ show o ++ " applied to " ++ show args
+
+        -- generate a pairwise inequality check
+        mkDistinct args = fsep $ andAll $ walk args
+          where walk []     = []
+                walk (e:es) = map (pair e) es ++ walk es
+
+                pair e1 e2  = parens (e1 <+> text "!=" <+> e2)
+
+                -- like punctuate, but more spacing
+                andAll []     = []
+                andAll (d:ds) = go d ds
+                     where go d' [] = [d']
+                           go d' (e:es) = (d' <+> text "&&") : go e es
+
+        -- Div0 needs to protect, but only when the arguments are not float/double. (Div by 0 for those are well defined to be Inf/NaN etc.)
+        protectDiv0 k divOp def a b = case k of
+                                        KFloat  -> res
+                                        KDouble -> res
+                                        _       -> wrap
+           where res  = a <+> text divOp <+> b
+                 wrap = parens (b <+> text "== 0") <+> text "?" <+> def <+> text ":" <+> parens res
+
+        shift toLeft i a = a <+> text cop <+> i
+          where cop | toLeft = "<<"
+                    | True   = ">>"
+
+        rotate toLeft i a s
+          | i < 0   = rotate (not toLeft) (-i) a s
+          | i == 0  = a
+          | True    = case kindOf s of
+                        KBounded True _             -> tbd $ "Rotation of signed quantities: " ++ show (toLeft, i, s)
+                        KBounded False sz | i >= sz -> rotate toLeft (i `mod` sz) a s
+                        KBounded False sz           ->     parens (a <+> text cop  <+> int i)
+                                                      <+> text "|"
+                                                      <+> parens (a <+> text cop' <+> int (sz - i))
+                        KUnbounded                  -> shift toLeft (int i) a -- For SInteger, rotate is the same as shift in Haskell
+                        _                           -> tbd $ "Rotation for unbounded quantity: " ++ show (toLeft, i, s)
+          where (cop, cop') | toLeft = ("<<", ">>")
+                            | True   = (">>", "<<")
+
+        -- TBD: below we only support the values for extract that are "easy" to implement. These should cover
+        -- almost all instances actually generated by SBV, however.
+        extract hi lo i a  -- Isolate the bit-extraction case
+          | hi == lo, KBounded _ sz <- kindOf i, hi < sz, hi >= 0
+          = if hi == 0
+            then text "(SBool)" <+> parens (a <+> text "& 1")
+            else text "(SBool)" <+> parens (parens (a <+> text ">>" <+> int hi) <+> text "& 1")
+        extract hi lo i a
+          | srcSize `notElem` [64, 32, 16]
+          = bad "Unsupported source size"
+          | (hi + 1) `mod` 8 /= 0 || lo `mod` 8 /= 0
+          = bad "Unsupported non-byte-aligned extraction"
+          | tgtSize < 8 || tgtSize `mod` 8 /= 0
+          = bad "Unsupported target size"
+          | True
+          = text cast <+> shifted
+          where bad why    = tbd $ "extract with " ++ show (hi, lo, k, i) ++ " (Reason: " ++ why ++ ".)"
+
+                k          = kindOf i
+                srcSize    = intSizeOf k
+                tgtSize    = hi - lo + 1
+                signChange = srcSize == tgtSize
+
+                cast
+                  | signChange && hasSign k = "(SWord" ++ show srcSize ++ ")"
+                  | signChange              = "(SInt"  ++ show srcSize ++ ")"
+                  | True                    = "(SWord" ++ show tgtSize ++ ")"
+
+                shifted
+                  | lo == 0 = a
+                  | True    = parens (a <+> text ">>" <+> int lo)
+
+        -- TBD: ditto here for join, just like extract above
+        join (i, j, a, b) = case (kindOf i, kindOf j) of
+                              (KBounded False  8, KBounded False  8) -> parens (parens (text "(SWord16)" <+> a) <+> text "<< 8")  <+> text "|" <+> parens (text "(SWord16)" <+> b)
+                              (KBounded False 16, KBounded False 16) -> parens (parens (text "(SWord32)" <+> a) <+> text "<< 16") <+> text "|" <+> parens (text "(SWord32)" <+> b)
+                              (KBounded False 32, KBounded False 32) -> parens (parens (text "(SWord64)" <+> a) <+> text "<< 32") <+> text "|" <+> parens (text "(SWord64)" <+> b)
+                              (k1,                k2)                -> tbd $ "join with " ++ show ((k1, i), (k2, j))
+
+-- | Quote a document after replacing its line breaks with spaces.
+-- Otherwise breaks the generated code.. sigh
+printQuotes :: Doc -> Doc
+printQuotes d = text $ '"' : ppSameLine d ++ "\""
+
+-- | Replace document line breaks with spaces for single-line output.
+ppSameLine :: Doc -> String
+ppSameLine = trim . render
+ where trim ""        = ""
+       trim ('\n':cs) = ' ' : trim (dropWhile isSpace cs)
+       trim (c:cs)    = c   : trim cs
+
+-- | Align documents by padding their left sides to the same width.
+-- this is ugly and inefficient, but easy to code..
+align :: [Doc] -> [Doc]
+align ds = map (text . pad) ss
+  where ss    = map render ds
+        l     = maximum (0 : map length ss)
+        pad s = replicate (l - length s) ' ' ++ s
+
+-- | Merge a bunch of bundles to generate code for a library. For the final
+-- config, we simply return the first config we receive, or the default if none.
+mergeToLib :: String -> [(CgConfig, CgPgmBundle)] -> (CgConfig, CgPgmBundle)
+mergeToLib libName cfgBundles
+  | length nubKinds /= 1
+  = error $  "Cannot merge programs with differing SInteger/SReal mappings. Received the following kinds:\n"
+          ++ unlines (map show nubKinds)
+  | True
+  = (finalCfg, CgPgmBundle bundleKind $ sources ++ libHeader : [libDriver | anyDriver] ++ [libMake | anyMake])
+  where bundles     = map snd cfgBundles
+        kinds       = [k | CgPgmBundle k _ <- bundles]
+        nubKinds    = nub kinds
+        bundleKind  = case nubKinds of
+                        bk:_ -> bk
+                        []   -> error "Data.SBV.C: Impossible happened: mergeLibs: kinds ended up being empty!"
+        files       = concat [fs | CgPgmBundle _ fs <- bundles]
+        sigs        = concat [ss | (_, (CgHeader ss, _)) <- files]
+        anyMake     = not (null [() | (_, (CgMakefile{}, _)) <- files])
+        drivers     = [ds | (_, (CgDriver, ds)) <- files]
+        anyDriver   = not (null drivers)
+        mkFlags     = nub (concat [xs | (_, (CgMakefile xs, _)) <- files])
+        sources     = [(f, (CgSource, [pre, libHInclude, post])) | (f, (CgSource, [pre, _, post])) <- files]
+        sourceNms   = map fst sources
+        libHeader   = (libName ++ ".h", (CgHeader sigs, [genHeader bundleKind libName sigs empty]))
+        libHInclude = text "#include" <+> text (show (libName ++ ".h"))
+        libMake     = ("Makefile", (CgMakefile mkFlags, [genLibMake anyDriver libName sourceNms mkFlags]))
+        libDriver   = (libName ++ "_driver.c", (CgDriver, mergeDrivers libName libHInclude (zip (map takeBaseName sourceNms) drivers)))
+        finalCfg    = case cfgBundles of
+                        []         -> defaultCgConfig
+                        ((c, _):_) -> c
+
+-- | Create a Makefile for the library
+genLibMake :: Bool -> String -> [String] -> [String] -> Doc
+genLibMake ifdr libName fs ldFlags = foldr1 ($$) [l | (True, l) <- lns]
+ where ifld = not (null ldFlags)
+       ld | ifld = text "${LDFLAGS}"
+          | True = empty
+       lns = [ (True, text "# Makefile for" <+> nm P.<> text ". Automatically generated by SBV. Do not edit!")
+             , (True,  text "")
+             , (True,  text "# include any user-defined .mk file in the current directory.")
+             , (True,  text "-include *.mk")
+             , (True,  text "")
+             , (True,  text "CC?=gcc")
+             , (True,  text "CCFLAGS?=-Wall -O3 -DNDEBUG -fomit-frame-pointer")
+             , (ifld,  text "LDFLAGS?=" P.<> text (unwords ldFlags))
+             , (True,  text "AR?=ar")
+             , (True,  text "ARFLAGS?=cr")
+             , (True,  text "")
+             , (not ifdr,  text ("all: " ++ liba))
+             , (ifdr,      text ("all: " ++ unwords [liba, libd]))
+             , (True,  text "")
+             , (True,  text liba P.<> text (": " ++ unwords os))
+             , (True,  text "\trm -f $@.tmp")
+             , (True,  text "\t${AR} ${ARFLAGS} $@.tmp $^")
+             , (True,  text "\tmv -f $@.tmp $@")
+             , (True,  text "")
+             , (ifdr,  text libd P.<> text (": " ++ unwords [libd ++ ".c", libh, liba]))
+             , (ifdr,  text ("\t${CC} ${CCFLAGS} $< -o $@ " ++ liba) <+> ld)
+             , (ifdr,  text "")
+             , (True,  vcat (zipWith mkObj os fs))
+             , (True,  text "clean:")
+             , (True,  text "\trm -f *.o")
+             , (True,  text "")
+             , (True,  text "veryclean: clean")
+             , (not ifdr,  text "\trm -f" <+> text (unwords [liba, liba ++ ".tmp"]))
+             , (ifdr,      text "\trm -f" <+> text (unwords [liba, libd, liba ++ ".tmp"]))
+             , (True,  text "")
+             ]
+       nm = text libName
+       liba = libName ++ ".a"
+       libh = libName ++ ".h"
+       libd = libName ++ "_driver"
+       os   = map (`replaceExtension` ".o") fs
+       mkObj o f =  text o P.<> text (": " ++ unwords [f, libh])
+                 $$ text "\t${CC} ${CCFLAGS} -c $< -o $@"
+                 $$ text ""
+
+-- | Create a driver for a library
+mergeDrivers :: String -> Doc -> [(FilePath, [Doc])] -> [Doc]
+mergeDrivers libName inc ds = pre : concatMap mkDFun ds ++ [callDrivers (map fst ds)]
+  where pre =  text "/* Example driver program for" <+> text libName P.<> text ". */"
+            $$ text "/* Automatically generated by SBV. Edit as you see fit! */"
+            $$ text ""
+            $$ text "#include <stdio.h>"
+            $$ inc
+        mkDFun (f, [_pre, _header, body, _post]) = [header, body, post]
+           where header =  text ""
+                        $$ text ("void " ++ f ++ "_driver(void)")
+                        $$ text "{"
+                 post   =  text "}"
+        mkDFun (f, _) = die $ "mergeDrivers: non-conforming driver program for " ++ show f
+        callDrivers fs =   text ""
+                       $$  text "int main(void)"
+                       $$  text "{"
+                       $+$ nest 2 (vcat (map call fs))
+                       $$  nest 2 (text "return 0;")
+                       $$  text "}"
+        call f =  text psep
+               $$ text ptag
+               $$ text psep
+               $$ text (f ++ "_driver();")
+               $$ text ""
+           where tag  = "** Driver run for " ++ f ++ ":"
+                 ptag = "printf(\"" ++ tag ++ "\\n\");"
+                 lsep = replicate (length tag) '='
+                 psep = "printf(\"" ++ lsep ++ "\\n\");"
+
+-- | Return the linker flags required by a legacy scalar operation.
+getLDFlag :: (Op, Kind) -> [String]
+getLDFlag (o, k) = flag o
+  where math = ["-lm"]
+
+        flag (IEEEFP FP_Cast{})                                     = math
+        flag (KindCast KReal KUnbounded)                            = math
+        flag (IEEEFP fop)       | fop `elem` requiresMath           = math
+        flag Abs                | k `elem` [KFloat, KDouble, KReal] = math
+        flag _                                                      = []
+
+        requiresMath = [ FP_Abs
+                       , FP_FMA
+                       , FP_Sqrt
+                       , FP_Rem
+                       , FP_Min
+                       , FP_Max
+                       , FP_RoundToIntegral
+                       , FP_ObjEqual
+                       , FP_IsSubnormal
+                       , FP_IsInfinite
+                       , FP_IsNaN
+                       , FP_IsNegative
+                       , FP_IsPositive
+                       , FP_IsNormal
+                       , FP_IsZero
+                       ]
+
+{- HLint ignore module "Redundant lambda" -}
diff --git a/Data/SBV/Compilers/C/List.hs b/Data/SBV/Compilers/C/List.hs
new file mode 100644
--- /dev/null
+++ b/Data/SBV/Compilers/C/List.hs
@@ -0,0 +1,605 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Data.SBV.Compilers.C.List
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Typed symbolic-list lowering for generated C.
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Data.SBV.Compilers.C.List
+  ( listKinds
+  , listSupported
+  , listUsesExact
+  , listNeedsDriverInit
+  , listCType
+  , listForwardTypeDecls
+  , listTypeDecls
+  , listOwnershipTypeDecls
+  , listRuntimeDecls
+  , listRuntime
+  , listConst
+  , listExpr
+  , listEqual
+  , listClone
+  , listRelease
+  , listDriverValue
+  , listDriverInit
+  , listDriverClear
+  , listPrint
+  , listContextStart
+  , listContextEnd
+  ) where
+
+import Data.SBV.Compilers.C.Syntax (cUnusedAttribute)
+import Data.List                       (nub, sortOn, stripPrefix, tails)
+import qualified Data.Set as Set
+
+import Text.PrettyPrint.HughesPJ
+import qualified Text.PrettyPrint.HughesPJ as P ((<>))
+
+import Data.SBV.Compilers.C.Arena      (CArena(..), arenaRuntime)
+import Data.SBV.Compilers.C.Array      (arrayStoredLoad, arrayStoredValue)
+import Data.SBV.Compilers.C.GMP        (gmpFunctionName, gmpInitializeCopy, gmpOutputType, isExactGMPKind)
+import Data.SBV.Compilers.C.Lowering   (CLowering, CRequirement(..), expressionLowering)
+import Data.SBV.Compilers.C.Types      (isConcreteADT, constElementCType, elementCType, kindTag, listCloneName, listReleaseName, listHelperName)
+import Data.SBV.Compilers.C.Value      ( byValueEqual
+                                       , managedValueClone
+                                       , managedValueRelease
+                                       , valueDriverClear
+                                       , valueDriverInit
+                                       , valueDriverNeedsInitialization
+                                       , valueNeedsOwnership
+                                       )
+import Data.SBV.Compilers.CodeGen      (CgConfig)
+import Data.SBV.Core.Data
+import Data.SBV.Core.Kind              (expandKinds)
+
+-- | Return all distinct symbolic-list kinds in dependency order.
+listKinds :: Set.Set Kind -> [Kind]
+listKinds = sortOn listDepth . nub . concatMap (filter isList . expandKinds) . Set.toAscList
+ where listDepth :: Kind -> Int
+       listDepth (KList elementKind) = 1 + listDepth elementKind
+       listDepth _                   = 0
+
+-- | Test whether a list element kind has a supported C representation. Array
+-- elements support structural movement and indexing, but operations requiring
+-- extensional element equality are rejected by 'listExpr'.
+listSupported :: CgConfig -> Kind -> Bool
+listSupported _ (KList elementKind) = supportedElement elementKind
+ where supportedElement KBool                          = True
+       supportedElement KBounded{}                     = True
+       supportedElement KFloat                         = True
+       supportedElement KDouble                        = True
+       supportedElement KChar                          = True
+       supportedElement KString                        = True
+       supportedElement KFP{}                          = True
+       supportedElement KUnbounded                     = True
+       supportedElement KReal                          = True
+       supportedElement KRational                      = True
+       supportedElement (KList kind)                   = supportedElement kind
+       supportedElement (KSet kind)                    = supportedElement kind
+       supportedElement (KArray keyKind valueKind)     = supportedElement keyKind && supportedElement valueKind
+       supportedElement (KTuple kinds)                 = all supportedElement kinds
+       supportedElement kind
+         | isConcreteADT kind = True
+         | True               = isRoundingMode kind
+listSupported _ _ = False
+
+-- | Test whether a list stores exact GMP-backed elements.
+listUsesExact :: CgConfig -> Kind -> Bool
+listUsesExact cfg (KList elementKind) = isExactGMPKind cfg elementKind
+listUsesExact _   _                   = False
+
+-- | Test whether an example-driver list requires statement-based element
+-- initialization instead of a single compound literal.
+listNeedsDriverInit :: CgConfig -> Kind -> Bool
+listNeedsDriverInit cfg (KList elementKind) = valueDriverNeedsInitialization cfg elementKind
+listNeedsDriverInit _   _                   = False
+
+-- | Return the public C descriptor type for a symbolic-list kind.
+listCType :: Kind -> String
+listCType kind@KList{} = elementCType kind
+listCType kind         = error $ "SBV->C: Expected a list kind, received " ++ show kind
+
+-- | Emit guarded forward declarations for symbolic-list descriptor types.
+-- These declarations allow list and set descriptors to contain pointers to
+-- each other before either family has emitted its complete layouts.
+listForwardTypeDecls :: [Kind] -> Doc
+listForwardTypeDecls []    = empty
+listForwardTypeDecls kinds = text . unlines $ concatMap declaration kinds
+ where declaration kind@KList{} =
+         [ "#ifndef " ++ listForwardGuard kind
+         , "#define " ++ listForwardGuard kind
+         , "typedef struct " ++ listCType kind ++ " " ++ listCType kind ++ ";"
+         , "#endif"
+         , ""
+         ]
+       declaration kind = error $ "SBV->C: Expected a list kind, received " ++ show kind
+
+-- | Emit typed borrowed-list descriptors and ownership-helper prototypes.
+-- The element type may remain incomplete here because descriptors only carry
+-- pointers; definitions that inspect elements are emitted later by
+-- 'listOwnershipTypeDecls'.
+listTypeDecls :: CgConfig -> [Kind] -> Doc
+listTypeDecls cfg kinds
+  | null kinds = empty
+  | True       = listForwardTypeDecls kinds $$ text (unlines $
+      ["/* Typed symbolic lists. Inputs borrow their elements; outputs and returns own them. */"
+      , cUnusedAttribute
+      ]
+      ++ concatMap declaration kinds
+      )
+ where declaration kind@(KList elementKind)
+         | listSupported cfg kind
+         = let cType       = listCType kind
+               cloneName    = listCloneName kind
+               releaseName  = listReleaseName kind
+           in [ "#ifndef " ++ listGuard kind
+              , "#define " ++ listGuard kind
+              , "struct " ++ cType ++ " { " ++ constElementCType elementKind ++ " *data; size_t length; };"
+              , "static inline SBV_CGEN_UNUSED " ++ cType ++ " " ++ cloneName ++ "(" ++ cType ++ " value);"
+              , "static inline SBV_CGEN_UNUSED void " ++ releaseName ++ "(" ++ cType ++ " *value);"
+              , "#endif"
+              , ""
+              ]
+         | True
+         = error $ "SBV->C: Unsupported list element kind: " ++ show elementKind
+       declaration kind = error $ "SBV->C: Expected a list kind, received " ++ show kind
+
+-- | Emit list clone and release definitions after aggregate element layouts
+-- are complete. Inputs borrow their element arrays; output and return values
+-- own a cloned array and must be released with the matching helper.
+listOwnershipTypeDecls :: CgConfig -> [Kind] -> Doc
+listOwnershipTypeDecls cfg kinds
+  | null kinds = empty
+  | True       = text . unlines $ concatMap declaration kinds
+ where declaration kind@(KList elementKind)
+         | listSupported cfg kind
+         = let cType       = listCType kind
+               elementType = listElementCType elementKind
+               cloneName    = listCloneName kind
+               releaseName  = listReleaseName kind
+           in [ "#ifndef " ++ listOwnershipGuard kind
+              , "#define " ++ listOwnershipGuard kind
+              , "static inline SBV_CGEN_UNUSED " ++ cType ++ " " ++ cloneName ++ "(" ++ cType ++ " value)"
+              , "{"
+              , "  " ++ elementType ++ " *copy = NULL;"
+              , "  if (value.length != 0) {"
+              , "    if (value.length > SIZE_MAX / sizeof(*copy)) abort();"
+              , "    copy = (" ++ elementType ++ " *) malloc(value.length * sizeof(*copy));"
+              , "    if (copy == NULL) abort();"
+              ]
+              ++ cloneElements elementKind
+              ++ [ "  }"
+              , "  return (" ++ cType ++ ") {copy, value.length};"
+              , "}"
+              , "static inline SBV_CGEN_UNUSED void " ++ releaseName ++ "(" ++ cType ++ " *value)"
+              , "{"
+              , "  if (value == NULL) return;"
+              ]
+              ++ releaseElements elementKind
+              ++ [ "  *value = (" ++ cType ++ ") {NULL, 0};"
+              , "}"
+              , "#endif"
+              , ""
+              ]
+         | True
+         = error $ "SBV->C: Unsupported list element kind: " ++ show elementKind
+       declaration kind = error $ "SBV->C: Expected a list kind, received " ++ show kind
+
+       cloneElements elementKind
+         | isExactGMPKind cfg elementKind
+         =  [ "    for (size_t i = 0; i < value.length; ++i) {"
+            , "      " ++ gmpOutputType elementKind ++ " element = (" ++ gmpOutputType elementKind ++ ") malloc(sizeof(*element));"
+            , "      if (element == NULL) abort();"
+            ]
+         ++ map ("      " ++) (lines (render (gmpInitializeCopy elementKind (text "element") (text "value.data[i]"))))
+         ++ [ "      copy[i] = element;"
+            , "    }"
+            ]
+         | isConcreteADT elementKind || valueNeedsOwnership cfg elementKind
+         = [ "    for (size_t i = 0; i < value.length; ++i)"
+           , "      copy[i] = " ++ render (managedValueClone elementKind (text "value.data[i]")) ++ ";"
+           ]
+         | True
+         = ["    memcpy(copy, value.data, value.length * sizeof(*copy));"]
+
+       releaseElements elementKind
+         | isExactGMPKind cfg elementKind
+         = [ "  " ++ listElementCType elementKind ++ " *data = (" ++ listElementCType elementKind ++ " *) value->data;"
+           , "  for (size_t i = 0; i < value->length; ++i) {"
+           , "    " ++ gmpOutputType elementKind ++ " element = (" ++ gmpOutputType elementKind ++ ") data[i];"
+           , "    if (element != NULL) { " ++ gmpFunctionName elementKind "clear" ++ "(element); free(element); }"
+           , "  }"
+           , "  free(data);"
+           ]
+         | isConcreteADT elementKind || valueNeedsOwnership cfg elementKind
+         = [ "  " ++ listElementCType elementKind ++ " *data = (" ++ listElementCType elementKind ++ " *) value->data;"
+           , "  for (size_t i = 0; i < value->length; ++i)"
+           , "    " ++ render (managedValueRelease elementKind (text "&data[i]"))
+           , "  free(data);"
+           ]
+         | True
+         = ["  free((void *) value->data);"]
+
+-- | Emit forward declarations for list equality helpers referenced by nested
+-- aggregate element comparisons.
+listRuntimeDecls :: CgConfig -> [Kind] -> Doc
+listRuntimeDecls cfg kinds = text . unlines $
+  [ "static SBV_CGEN_UNUSED bool " ++ helperName kind "equal" ++ "(" ++ listCType kind ++ " left, " ++ listCType kind ++ " right);"
+  | kind <- kinds
+  , listSupported cfg kind
+  ]
+
+-- | Emit the shared list arena and specialized sequence operations for every
+-- list kind used by the generated program.
+listRuntime :: CgConfig -> Bool -> [Kind] -> Doc
+listRuntime cfg usesExactInteger kinds = text . unlines . map markUnused $
+     commonRuntime
+  ++ (if usesExactInteger then exactIndexRuntime else [])
+  ++ concatMap specializedRuntime kinds
+ where markUnused line = case stripPrefix "static " line of
+                           Just rest -> "static SBV_CGEN_UNUSED " ++ rest
+                           Nothing   -> line
+
+       specializedRuntime kind
+         | listSupported cfg kind = listKindRuntime cfg usesExactInteger kind
+         | True                   = error $ "SBV->C: Unsupported list kind: " ++ show kind
+
+-- | Render a list constant with a caller-supplied renderer for its elements.
+listConst :: (CV -> Doc) -> CV -> Maybe Doc
+listConst renderElement (CV kind@(KList elementKind) (CList values))
+  = Just $ text "((" P.<> text (listCType kind) P.<> text ") {"
+       P.<> elements
+       P.<> text ", "
+       P.<> int (length values)
+       P.<> text "})"
+ where elements
+         | null values = text "NULL"
+         | True        = text "(" P.<> text (constElementCType elementKind) P.<> text "[]) {"
+                      P.<> fsep (punctuate comma (map (arrayStoredValue elementKind . renderElement . CV elementKind) values))
+                      P.<> text "}"
+listConst _ _ = Nothing
+
+-- | Lower the core symbolic sequence operations for non-character lists.
+listExpr :: CgConfig -> Op -> [SV] -> SV -> [Doc] -> Maybe CLowering
+listExpr cfg op svs resultSV args
+  | not touchesList = Nothing
+  | True            = case (op, args) of
+      (ADTOp{}                   , _        )                    -> Nothing
+      (TupleConstructor{}        , _        )                    -> Nothing
+      (TupleAccess{}             , _        )                    -> Nothing
+      (Uninterpreted{}           , _        )                    -> Nothing
+      (Label _                   , [a]      )                    -> lower a
+      (Equal _                   , [a, b]   )                    -> lower $ call (helper "equal") [a, b]
+      (NotEqual                  , as       )                    -> lower $ distinctLists as
+      (SeqOp (SeqLen kind)       , [a]      ) | kind /= KChar   -> lowerInteger False $ call (helperFor kind "length") [a]
+      (SeqOp (SeqConcat _)       , as       )
+        | KList elementKind <- resultKind                       -> lower $ foldLists elementKind as
+      (SeqOp (SeqNth kind)       , [a, i]   ) | kind /= KChar   -> loadArray $ indexed kind "nth" [a] i
+      (SeqOp (SeqUnit kind)      , [a]      ) | kind /= KChar   -> lower $ call (helperFor kind "unit") [text "&sbv_local_list_ctx", arrayStoredValue kind a]
+      (SeqOp (SeqSubseq kind)    , [a, i, n]) | kind /= KChar   -> lower $ indexed2 kind "substring" a i n
+      (SeqOp (SeqIndexOf kind)   , [a, b, i]) | kind /= KChar   -> lowerInteger True $ indexed kind "index_of" [a, b] i
+      (SeqOp (SeqContains kind)  , [a, b]   ) | kind /= KChar   -> lower $ call (helperFor kind "contains") [a, b]
+      (SeqOp (SeqPrefixOf kind)  , [a, b]   ) | kind /= KChar   -> lower $ call (helperFor kind "prefix_of") [a, b]
+      (SeqOp (SeqSuffixOf kind)  , [a, b]   ) | kind /= KChar   -> lower $ call (helperFor kind "suffix_of") [a, b]
+      (SeqOp (SeqReplace kind)   , [a, b, c]) | kind /= KChar   -> lower $ call (helperFor kind "replace") [text "&sbv_local_list_ctx", a, b, c]
+      _ -> unsupported
+ where resultKind = kindOf resultSV
+
+       touchesList = isList resultKind || any (isList . kindOf) svs || isListOp op
+
+       listKind = case [kind | value <- resultKind : map kindOf svs, kind@(KList _) <- [value]] of
+                    kind:_ -> kind
+                    []     -> error $ "SBV->C: Cannot determine list kind for " ++ show op
+
+       lower expression = Just $ expressionLowering requirements expression
+
+       loadArray expression
+         | isArray resultKind = Just (arrayStoredLoad resultSV expression)
+         | True               = lower expression
+
+       lowerInteger signed expression
+         | isExactGMPKind cfg resultKind
+         = Just $ expressionLowering [CRequiresLists, CRequiresGMP]
+                $ call (if signed then "sbv_gmp_integer_from_s64" else "sbv_gmp_integer_from_u64")
+                       [text "&sbv_local_gmp_ctx", expression]
+         | True
+         = lower $ parens (text "SInteger") <+> expression
+
+       requirements = CRequiresLists : [CRequiresGMP | any (isExactGMPKind cfg) touchedKinds]
+
+       touchedKinds = concatMap expandKinds (resultKind : map kindOf svs)
+
+       helper = helperName listKind
+
+       helperFor elementKind = helperName (KList elementKind)
+
+       distinctLists rendered = fsep $ punctuate (text " &&")
+                                      [parens (text "!" P.<> call (helper "equal") [left, right])
+                                      | (left:rest) <- tails rendered, right <- rest]
+
+       foldLists _           []           = text "((" P.<> text (listCType listKind) P.<> text ") {NULL, 0})"
+       foldLists _           [value]      = value
+       foldLists elementKind (value:rest) = foldl combine value rest
+         where combine left right = call (helperFor elementKind "concat") [text "&sbv_local_list_ctx", left, right]
+
+       indexed elementKind suffix prefix index
+        | exactIndex = call (helperFor elementKind (suffix ++ "_mpz")) (context ++ prefix ++ [index])
+        | True       = call (helperFor elementKind suffix) (context ++ prefix ++ [parens (text "int64_t") <+> index])
+        where context
+                | suffix == "nth" && isExactGMPKind cfg elementKind = [text "&sbv_local_gmp_ctx"]
+                | True                                               = []
+
+       indexed2 elementKind suffix value offset count
+         | exactIndex = call (helperFor elementKind (suffix ++ "_mpz")) [text "&sbv_local_list_ctx", value, offset, count]
+         | True       = call (helperFor elementKind suffix)
+                             [text "&sbv_local_list_ctx", value, parens (text "int64_t") <+> offset, parens (text "int64_t") <+> count]
+
+       exactIndex = any (isExactGMPKind cfg . kindOf) svs
+
+       requiresElementEquality Equal{}                 = True
+       requiresElementEquality NotEqual                = True
+       requiresElementEquality (SeqOp SeqIndexOf{})    = True
+       requiresElementEquality (SeqOp SeqContains{})   = True
+       requiresElementEquality (SeqOp SeqPrefixOf{})   = True
+       requiresElementEquality (SeqOp SeqSuffixOf{})   = True
+       requiresElementEquality (SeqOp SeqReplace{})    = True
+       requiresElementEquality _                       = False
+
+       unsupported
+         | requiresElementEquality op
+         , any isArray (expandKinds (listElementKind listKind))
+         = error $ "SBV->C: List operation " ++ show op
+                ++ " requires unsupported extensional equality for array-valued elements."
+         | True
+         = error $ "SBV->C: List lowering does not support " ++ show op
+                ++ " with argument kinds " ++ show (map kindOf svs)
+                ++ " and result kind " ++ show resultKind
+
+-- | Compare two list descriptors using symbolic sequence equality.
+listEqual :: Kind -> Doc -> Doc -> Doc
+listEqual kind left right = call (helperName kind "equal") [left, right]
+
+-- | Deep-copy a list across the generated function's ownership boundary.
+listClone :: Kind -> Doc -> Doc
+listClone kind value = call (listCloneName kind) [value]
+
+-- | Release an owned list in a generated driver.
+listRelease :: Kind -> Doc -> Doc
+listRelease kind value = call (listReleaseName kind) [text "&" P.<> value] P.<> semi
+
+-- | Produce a deterministic three-element list value for an example driver.
+listDriverValue :: (Kind -> Integer -> Doc) -> Kind -> Integer -> Doc
+listDriverValue renderValue kind@(KList elementKind) seed
+  = text "((" P.<> text (listCType kind) P.<> text ") {"
+       P.<> text "(" P.<> text (constElementCType elementKind) P.<> text "[]) {"
+       P.<> fsep (punctuate comma [renderValue elementKind seed, renderValue elementKind (seed + 1), renderValue elementKind (seed + 2)])
+       P.<> text "}, 3})"
+listDriverValue _ kind _ = error $ "SBV->C: Expected a list kind, received " ++ show kind
+
+-- | Initialize a generated-driver list whose elements require statement-based
+-- setup. The descriptor borrows three independently initialized elements;
+-- release their storage with 'listDriverClear' after the call completes. The
+-- supplied statement renderer handles retained array and ADT elements.
+listDriverInit :: CgConfig -> (Kind -> Integer -> Doc) -> (Kind -> String -> Integer -> Doc) -> Kind -> String -> Integer -> Doc
+listDriverInit cfg renderValue initializeValue kind@KList{} externalName seed = valueDriverInit cfg renderValue initializeValue kind externalName seed
+listDriverInit _   _           _               kind         _            _    = error $ "SBV->C: Expected a list kind, received " ++ show kind
+
+-- | Clear managed element storage initialized by 'listDriverInit'.
+listDriverClear :: CgConfig -> Kind -> String -> Doc
+listDriverClear cfg kind@KList{} externalName = valueDriverClear cfg kind externalName
+listDriverClear _   kind         _            = error $ "SBV->C: Expected a list kind, received " ++ show kind
+
+-- | Print a list value using the supplied element printer.
+listPrint :: (Kind -> Doc -> Doc) -> Kind -> Doc -> Doc
+listPrint printElement (KList elementKind) value
+  = text "printf(\"[\");"
+ $$ text "for (size_t" <+> index <+> text "= 0;" <+> index <+> text "<" <+> value P.<> text ".length; ++" P.<> index P.<> text ")"
+ $$ text "{"
+ $$ nest 2 (   text "if" <+> parens (index <+> text "!= 0") <+> text "printf(\", \");"
+            $$ printElement elementKind (value P.<> text ".data[" P.<> index P.<> text "]")
+           )
+ $$ text "}"
+ $$ text "printf(\"]\");"
+ where index = text ("sbv_local_list_print_index_" ++ kindTag elementKind)
+listPrint _ kind _ = error $ "SBV->C: Expected a list kind, received " ++ show kind
+
+-- | Initialize the arena used by list temporaries in a generated function.
+listContextStart :: Doc
+listContextStart = text "sbv_list_ctx sbv_local_list_ctx = {NULL};"
+
+-- | Release all list temporaries allocated by a generated function.
+listContextEnd :: Doc
+listContextEnd = call "sbv_list_ctx_end" [text "&sbv_local_list_ctx"] P.<> semi
+
+-- | Test whether an operation belongs to the non-character sequence family.
+isListOp :: Op -> Bool
+isListOp (SeqOp (SeqLen kind))      = kind /= KChar
+isListOp (SeqOp (SeqConcat kind))   = kind /= KChar
+isListOp (SeqOp (SeqNth kind))      = kind /= KChar
+isListOp (SeqOp (SeqUnit kind))     = kind /= KChar
+isListOp (SeqOp (SeqSubseq kind))   = kind /= KChar
+isListOp (SeqOp (SeqIndexOf kind))  = kind /= KChar
+isListOp (SeqOp (SeqContains kind)) = kind /= KChar
+isListOp (SeqOp (SeqPrefixOf kind)) = kind /= KChar
+isListOp (SeqOp (SeqSuffixOf kind)) = kind /= KChar
+isListOp (SeqOp (SeqReplace kind))  = kind /= KChar
+isListOp _                          = False
+
+-- | Return the C type used to store one supported list element.
+listElementCType :: Kind -> String
+listElementCType KChar = "SChar"
+listElementCType kind  = elementCType kind
+
+-- | Return the preprocessor guard for one list forward declaration.
+listForwardGuard :: Kind -> String
+listForwardGuard kind = "SBV_LIST_" ++ kindTag (listElementKind kind) ++ "_FORWARD_DEFINED"
+
+-- | Return the preprocessor guard for one list descriptor.
+listGuard :: Kind -> String
+listGuard kind = "SBV_LIST_" ++ kindTag (listElementKind kind) ++ "_DEFINED"
+
+-- | Return the preprocessor guard for one list ownership-helper definition.
+listOwnershipGuard :: Kind -> String
+listOwnershipGuard kind = "SBV_LIST_" ++ kindTag (listElementKind kind) ++ "_OWNERSHIP_DEFINED"
+
+-- | Return the element kind of a symbolic-list kind.
+listElementKind :: Kind -> Kind
+listElementKind (KList elementKind) = elementKind
+listElementKind kind                = error $ "SBV->C: Expected a list kind, received " ++ show kind
+
+-- | Return one specialized list-operation helper name.
+helperName :: Kind -> String -> String
+helperName = listHelperName
+
+-- | Render a C helper call.
+call :: String -> [Doc] -> Doc
+call functionName args = text functionName P.<> parens (fsep (punctuate comma args))
+
+-- | Shared per-call allocation arena used by every list specialization.
+commonRuntime :: [String]
+commonRuntime = arenaRuntime ListArena
+
+-- | Exact-GMP index conversion shared by specialized list operations.
+exactIndexRuntime :: [String]
+exactIndexRuntime =
+  ["static bool sbv_list_mpz_to_size(SInteger value, size_t *result)"
+  , "{"
+  , "  if (mpz_sgn(value) < 0 || mpz_sizeinbase(value, 2) > sizeof(size_t) * CHAR_BIT) return false;"
+  , "  size_t written = 0; *result = 0;"
+  , "  (void) mpz_export(result, &written, -1, sizeof(*result), 0, 0, value);"
+  , "  return true;"
+  , "}"
+  ]
+
+-- | Emit all sequence helpers for one supported list element kind.
+listKindRuntime :: CgConfig -> Bool -> Kind -> [String]
+listKindRuntime cfg usesExactInteger kind@(KList elementKind) =
+  [ ""
+  , "static bool " ++ equalElement ++ "(" ++ elementType ++ " left, " ++ elementType ++ " right)"
+  , "{ return " ++ elementEqual ++ "; }"
+  , "static bool " ++ equalList ++ "(" ++ listType ++ " left, " ++ listType ++ " right)"
+  , "{"
+  , "  if (left.length != right.length) return false;"
+  , "  for (size_t i = 0; i < left.length; ++i) if (!" ++ equalElement ++ "(left.data[i], right.data[i])) return false;"
+  , "  return true;"
+  , "}"
+  , "static uint64_t " ++ helper "length" ++ "(" ++ listType ++ " value) { return (uint64_t) value.length; }"
+  , "static " ++ listType ++ " " ++ helper "concat" ++ "(sbv_list_ctx *ctx, " ++ listType ++ " left, " ++ listType ++ " right)"
+  , "{"
+  , "  if (right.length > SIZE_MAX - left.length) abort();"
+  , "  if (left.length == 0) return right;"
+  , "  if (right.length == 0) return left;"
+  , "  const size_t length = left.length + right.length;"
+  , "  " ++ elementType ++ " *data = (" ++ elementType ++ " *) sbv_list_alloc(ctx, length, sizeof(*data));"
+  , "  memcpy(data, left.data, left.length * sizeof(*data));"
+  , "  memcpy(data + left.length, right.data, right.length * sizeof(*data));"
+  , "  return (" ++ listType ++ ") {data, length};"
+  , "}"
+  , "static " ++ listType ++ " " ++ helper "unit" ++ "(sbv_list_ctx *ctx, " ++ elementType ++ " value)"
+  , "{"
+  , "  " ++ elementType ++ " *data = (" ++ elementType ++ " *) sbv_list_alloc(ctx, 1, sizeof(*data));"
+  , "  data[0] = value; return (" ++ listType ++ ") {data, 1};"
+  , "}"
+  , "static " ++ elementType ++ " " ++ helper "nth_size" ++ "(" ++ exactContextParam ++ listType ++ " value, size_t index)"
+  , "{ return index < value.length ? value.data[index] : " ++ defaultElement ++ "; }"
+  , "static " ++ elementType ++ " " ++ helper "nth" ++ "(" ++ exactContextParam ++ listType ++ " value, int64_t index)"
+  , "{ return index < 0 ? " ++ defaultElement ++ " : " ++ helper "nth_size" ++ "(" ++ exactContextArg ++ "value, (size_t) index); }"
+  , "static " ++ listType ++ " " ++ helper "substring_size" ++ "(sbv_list_ctx *ctx, " ++ listType ++ " value, size_t offset, size_t count)"
+  , "{"
+  , "  if (offset >= value.length || count == 0) return (" ++ listType ++ ") {NULL, 0};"
+  , "  if (count > value.length - offset) count = value.length - offset;"
+  , "  " ++ elementType ++ " *data = (" ++ elementType ++ " *) sbv_list_alloc(ctx, count, sizeof(*data));"
+  , "  memcpy(data, value.data + offset, count * sizeof(*data)); return (" ++ listType ++ ") {data, count};"
+  , "}"
+  , "static " ++ listType ++ " " ++ helper "substring" ++ "(sbv_list_ctx *ctx, " ++ listType ++ " value, int64_t offset, int64_t count)"
+  , "{"
+  , "  if (offset < 0 || count <= 0) return (" ++ listType ++ ") {NULL, 0};"
+  , "  return " ++ helper "substring_size" ++ "(ctx, value, (size_t) offset, (size_t) count);"
+  , "}"
+  ]
+  ++ matchRuntime
+  ++ [ "static bool " ++ helper "prefix_of" ++ "(" ++ listType ++ " prefix, " ++ listType ++ " value)"
+     , "{ return prefix.length <= value.length && " ++ helper "match_at" ++ "(value, prefix, 0); }"
+     , "static bool " ++ helper "suffix_of" ++ "(" ++ listType ++ " suffix, " ++ listType ++ " value)"
+     , "{ return suffix.length <= value.length && " ++ helper "match_at" ++ "(value, suffix, value.length - suffix.length); }"
+     , "static bool " ++ helper "contains" ++ "(" ++ listType ++ " value, " ++ listType ++ " part)"
+     , "{ return " ++ helper "index_of_size" ++ "(value, part, 0) >= 0; }"
+     , "static int64_t " ++ helper "index_of" ++ "(" ++ listType ++ " value, " ++ listType ++ " part, int64_t start)"
+     , "{ return start < 0 ? -1 : " ++ helper "index_of_size" ++ "(value, part, (size_t) start); }"
+     , "static " ++ listType ++ " " ++ helper "replace" ++ "(sbv_list_ctx *ctx, " ++ listType ++ " value, " ++ listType ++ " source, " ++ listType ++ " replacement)"
+     , "{"
+     , "  const int64_t index = " ++ helper "index_of_size" ++ "(value, source, 0);"
+     , "  if (index < 0) return value;"
+     , "  const size_t retained = value.length - source.length;"
+     , "  if (replacement.length > SIZE_MAX - retained) abort();"
+     , "  const size_t length = retained + replacement.length;"
+     , "  " ++ elementType ++ " *data = (" ++ elementType ++ " *) sbv_list_alloc(ctx, length, sizeof(*data));"
+     , "  const size_t first = (size_t) index; const size_t after = first + source.length;"
+     , "  if (first != 0) memcpy(data, value.data, first * sizeof(*data));"
+     , "  if (replacement.length != 0) memcpy(data + first, replacement.data, replacement.length * sizeof(*data));"
+     , "  if (after != value.length) memcpy(data + first + replacement.length, value.data + after, (value.length - after) * sizeof(*data));"
+     , "  return (" ++ listType ++ ") {data, length};"
+     , "}"
+     ]
+  ++ exactRuntime
+ where listType     = listCType kind
+       elementType  = listElementCType elementKind
+       helper       = helperName kind
+       equalElement = helper "element_equal"
+       equalList    = helper "equal"
+       elementEqual = render $ byValueEqual cfg True elementKind (text "left") (text "right")
+
+       exactContextParam
+         | isExactGMPKind cfg elementKind = "sbv_gmp_ctx *exact_ctx, "
+         | True                           = ""
+
+       exactContextArg
+         | isExactGMPKind cfg elementKind = "exact_ctx, "
+         | True                           = ""
+
+       defaultElement
+         | isExactGMPKind cfg elementKind
+         , elementKind == KUnbounded      = "sbv_gmp_integer_const(exact_ctx, \"0\")"
+         | isExactGMPKind cfg elementKind = "sbv_gmp_real_const(exact_ctx, \"0\")"
+         | True                           = "(" ++ elementType ++ ") {0}"
+
+       matchRuntime =
+         [ "static bool " ++ helper "match_at" ++ "(" ++ listType ++ " value, " ++ listType ++ " part, size_t offset)"
+         , "{"
+         , "  if (offset > value.length || part.length > value.length - offset) return false;"
+         , "  for (size_t i = 0; i < part.length; ++i) if (!" ++ equalElement ++ "(value.data[offset + i], part.data[i])) return false;"
+         , "  return true;"
+         , "}"
+         , "static int64_t " ++ helper "index_of_size" ++ "(" ++ listType ++ " value, " ++ listType ++ " part, size_t start)"
+         , "{"
+         , "  if (start > value.length) return -1;"
+         , "  for (size_t i = start; i <= value.length; ++i) {"
+         , "    if (" ++ helper "match_at" ++ "(value, part, i)) return i <= INT64_MAX ? (int64_t) i : -1;"
+         , "    if (i == value.length) break;"
+         , "  }"
+         , "  return -1;"
+         , "}"
+         ]
+
+       exactRuntime
+         | usesExactInteger =
+             [ "static " ++ elementType ++ " " ++ helper "nth_mpz" ++ "(" ++ exactContextParam ++ listType ++ " value, SInteger index)"
+             , "{ size_t converted; return sbv_list_mpz_to_size(index, &converted) ? " ++ helper "nth_size" ++ "(" ++ exactContextArg ++ "value, converted) : " ++ defaultElement ++ "; }"
+             , "static " ++ listType ++ " " ++ helper "substring_mpz" ++ "(sbv_list_ctx *ctx, " ++ listType ++ " value, SInteger offset, SInteger count)"
+             , "{"
+             , "  size_t converted_offset, converted_count;"
+             , "  if (!sbv_list_mpz_to_size(offset, &converted_offset) || !sbv_list_mpz_to_size(count, &converted_count)) return (" ++ listType ++ ") {NULL, 0};"
+             , "  return " ++ helper "substring_size" ++ "(ctx, value, converted_offset, converted_count);"
+             , "}"
+             , "static int64_t " ++ helper "index_of_mpz" ++ "(" ++ listType ++ " value, " ++ listType ++ " part, SInteger start)"
+             , "{ size_t converted; return sbv_list_mpz_to_size(start, &converted) ? " ++ helper "index_of_size" ++ "(value, part, converted) : -1; }"
+             ]
+         | True = []
+listKindRuntime _ _ kind = error $ "SBV->C: Expected a list kind, received " ++ show kind
diff --git a/Data/SBV/Compilers/C/Lowering.hs b/Data/SBV/Compilers/C/Lowering.hs
new file mode 100644
--- /dev/null
+++ b/Data/SBV/Compilers/C/Lowering.hs
@@ -0,0 +1,63 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Data.SBV.Compilers.C.Lowering
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Structured results shared by the individual C lowering backends.
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Data.SBV.Compilers.C.Lowering
+  ( CLowering(..)
+  , CRequirement(..)
+  , expressionLowering
+  , chooseLowering
+  ) where
+
+import Data.Maybe                     (catMaybes, listToMaybe)
+import qualified Data.Set as Set
+
+import Text.PrettyPrint.HughesPJ      (Doc)
+
+-- | Facilities required by a lowered C fragment. The program-level
+-- collector will ultimately turn these capabilities into includes, runtime
+-- helpers, compiler options, and linker options.
+data CRequirement = CRequiresGMP              -- ^ GMP-backed exact-number support.
+                  | CRequiresLibBF            -- ^ LibBF-backed arbitrary floating-point support.
+                  | CRequiresLibM             -- ^ The platform C mathematics library.
+                  | CRequiresNativeFPRounding -- ^ LibBF adapters for explicitly rounded native floating-point operations.
+                  | CRequiresWideBV           -- ^ Exact-width limb-backed bit-vector support.
+                  | CRequiresArrays           -- ^ Persistent functional-array support.
+                  | CRequiresText             -- ^ Length-aware character and string support.
+                  | CRequiresLists            -- ^ Typed symbolic-list support.
+                  | CRequiresSets             -- ^ Finite/cofinite symbolic-set support.
+                  | CRequiresFunctionResults  -- ^ Stable private storage for owned aggregate function results.
+                  | CRequiresIntegerPower     -- ^ Modular exponentiation for mapped unbounded integers.
+                  deriving (Eq, Ord, Show)
+
+-- | A C expression together with statements and capabilities needed around
+-- its evaluation. Declarations may be hoisted for function-wide backing
+-- storage, but setup statements execute in order only when the value is demanded.
+data CLowering = CLowering
+  { loweringExpression   :: Doc                     -- ^ Expression producing the lowered result.
+  , loweringDeclarations :: [Doc]                   -- ^ Declarations that may be hoisted above guarded control flow.
+  , loweringSetup        :: [Doc]                   -- ^ Statements required before evaluation.
+  , loweringRequirements :: Set.Set CRequirement    -- ^ Runtime and external capabilities used.
+  }
+
+-- | Construct a statement-free expression lowering.
+expressionLowering :: [CRequirement] -> Doc -> CLowering
+expressionLowering requirements expression = CLowering
+  { loweringExpression   = expression
+  , loweringDeclarations = []
+  , loweringSetup        = []
+  , loweringRequirements = Set.fromList requirements
+  }
+
+-- | Select the first backend that accepts an operation.
+chooseLowering :: [Maybe CLowering] -> Maybe CLowering
+chooseLowering = listToMaybe . catMaybes
diff --git a/Data/SBV/Compilers/C/NonLinear.hs b/Data/SBV/Compilers/C/NonLinear.hs
new file mode 100644
--- /dev/null
+++ b/Data/SBV/Compilers/C/NonLinear.hs
@@ -0,0 +1,119 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Data.SBV.Compilers.C.NonLinear
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Lowering of transcendental real operations and mapped integer powers.
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Data.SBV.Compilers.C.NonLinear
+  ( nonLinearExpr
+  , mappedIntegerPowerRuntime
+  ) where
+
+import Text.PrettyPrint.HughesPJ
+import qualified Text.PrettyPrint.HughesPJ as P ((<>))
+
+import Data.SBV.Compilers.C.Lowering (CLowering, CRequirement(..), expressionLowering)
+import Data.SBV.Compilers.CodeGen    (CgConfig(..), CgSRealType(..))
+import Data.SBV.Core.Data
+import Data.SBV.Core.Symbolic        (NROp(..))
+
+-- | Lower mapped-real transcendental operations and mapped integer
+-- exponentiation. Exact integer exponentiation delegates to the GMP lowering
+-- stage, while transcendental operations over exact rational reals receive an
+-- actionable diagnostic.
+nonLinearExpr :: CgConfig -> Op -> [SV] -> Kind -> [Doc] -> Maybe CLowering
+nonLinearExpr cfg (NonLinear nonLinearOp) svs resultKind args
+  | nonLinearOp == NR_IntPow
+  = integerPower
+  | resultKind == KReal && all ((== KReal) . kindOf) svs
+  = realOperation
+  | True
+  = unsupported
+ where integerPower
+         | resultKind == KUnbounded
+         , map kindOf svs == [KUnbounded, KUnbounded]
+         , [base, powerValue] <- args
+         = case cgInteger cfg of
+             Nothing    -> Nothing
+             Just width -> Just $ expressionLowering [CRequiresIntegerPower]
+                                $ namedCall ("sbv_integer_pow_s" ++ show width) [base, powerValue]
+         | True
+         = unsupported
+
+       realOperation = case cgReal cfg of
+         Nothing       -> error $ "SBV->C: The exact GMP-rational SReal representation cannot represent "
+                                ++ nonLinearName nonLinearOp
+                                ++ ". Select a native approximation with cgSRealType to compile this operation."
+         Just realType -> Just $ expressionLowering [CRequiresLibM] (renderReal realType)
+
+       renderReal realType = case (nonLinearOp, args) of
+         (NR_Pow   , [left, right]) -> namedCall (realFunction realType "pow") [left, right]
+         (NR_IntPow, _            ) -> unsupportedDoc
+         (_        , [value]       ) -> namedCall (realFunction realType (nonLinearName nonLinearOp)) [value]
+         _                         -> unsupportedDoc
+
+       unsupportedDoc = error unsupportedMessage
+       unsupported    = error unsupportedMessage
+
+       unsupportedMessage = "SBV->C: Cannot lower " ++ nonLinearName nonLinearOp
+                         ++ " with argument kinds " ++ show (map kindOf svs)
+                         ++ " and result kind " ++ show resultKind
+
+       namedCall functionName callArgs = text functionName P.<> parens (fsep (punctuate comma callArgs))
+
+       realFunction CgFloat      baseName = baseName ++ "f"
+       realFunction CgDouble     baseName = baseName
+       realFunction CgLongDouble baseName = baseName ++ "l"
+
+       nonLinearName NR_Sin    = "sin"
+       nonLinearName NR_Cos    = "cos"
+       nonLinearName NR_Tan    = "tan"
+       nonLinearName NR_ASin   = "asin"
+       nonLinearName NR_ACos   = "acos"
+       nonLinearName NR_ATan   = "atan"
+       nonLinearName NR_Sqrt   = "sqrt"
+       nonLinearName NR_Sinh   = "sinh"
+       nonLinearName NR_Cosh   = "cosh"
+       nonLinearName NR_Tanh   = "tanh"
+       nonLinearName NR_Exp    = "exp"
+       nonLinearName NR_Log    = "log"
+       nonLinearName NR_Pow    = "pow"
+       nonLinearName NR_IntPow = "integer exponentiation"
+nonLinearExpr _ _ _ _ _ = Nothing
+
+-- | Emit modular exponentiation for an explicitly bounded C representation
+-- of 'SInteger'. Negative exponents follow SMT-LIB integer-power semantics;
+-- nonnegative results wrap through the selected two's-complement width.
+mappedIntegerPowerRuntime :: CgConfig -> Doc
+mappedIntegerPowerRuntime cfg = case cgInteger cfg of
+  Nothing    -> error "SBV->C: Mapped integer-power runtime requested for exact SInteger"
+  Just width -> text . unlines $
+    [ "static " ++ signedType ++ " " ++ helperName ++ "(" ++ signedType ++ " base, " ++ signedType ++ " exponent)"
+    , "{"
+    , "  " ++ unsignedType ++ " result_bits = (" ++ unsignedType ++ ") 1, factor_bits, power;"
+    , "  " ++ signedType ++ " result;"
+    , "  if (exponent < 0) {"
+    , "    if (base == 1) return (" ++ signedType ++ ") 1;"
+    , "    if (base == -1) return ((" ++ unsignedType ++ ") exponent & (" ++ unsignedType ++ ") 1) != 0 ? (" ++ signedType ++ ") -1 : (" ++ signedType ++ ") 1;"
+    , "    return (" ++ signedType ++ ") 0;"
+    , "  }"
+    , "  memcpy(&factor_bits, &base, sizeof factor_bits); power = (" ++ unsignedType ++ ") exponent;"
+    , "  while (power != 0) {"
+    , "    if ((power & (" ++ unsignedType ++ ") 1) != 0) result_bits = (" ++ unsignedType ++ ") ((uint64_t) result_bits * (uint64_t) factor_bits);"
+    , "    power = (" ++ unsignedType ++ ") (power >> 1);"
+    , "    if (power != 0) factor_bits = (" ++ unsignedType ++ ") ((uint64_t) factor_bits * (uint64_t) factor_bits);"
+    , "  }"
+    , "  memcpy(&result, &result_bits, sizeof result); return result;"
+    , "}"
+    , ""
+    ]
+    where signedType   = "SInt"  ++ show width
+          unsignedType = "SWord" ++ show width
+          helperName   = "sbv_integer_pow_s" ++ show width
diff --git a/Data/SBV/Compilers/C/PseudoBoolean.hs b/Data/SBV/Compilers/C/PseudoBoolean.hs
new file mode 100644
--- /dev/null
+++ b/Data/SBV/Compilers/C/PseudoBoolean.hs
@@ -0,0 +1,58 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Data.SBV.Compilers.C.PseudoBoolean
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Overflow-safe pseudo-Boolean comparisons shared by the C backends.
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Data.SBV.Compilers.C.PseudoBoolean (assignPseudoBoolean) where
+
+import Text.PrettyPrint.HughesPJ
+import qualified Text.PrettyPrint.HughesPJ as P ((<>))
+
+import Data.SBV.Core.Data (PBOp(..))
+
+-- | Assign a pseudo-Boolean comparison to an already declared Boolean result.
+-- Use an exact unsigned sum when the maximum possible total fits in 64 bits.
+-- Otherwise stop adding after exceeding the bound: non-negative coefficients
+-- cannot bring the sum back down. Both the bound and each coefficient fit in
+-- a signed 64-bit integer, so every addition to a sum at most the bound fits
+-- in uint64_t, even when the mathematical total would require more bits.
+-- Retain zero-weight operands so their generated bindings remain referenced.
+assignPseudoBoolean :: PBOp -> [Doc] -> Doc -> Doc
+assignPseudoBoolean operation arguments result
+  | length coefficients /= length arguments
+  = error "SBV->C: Pseudo-Boolean coefficient/argument count mismatch."
+  | any (\n -> n < 0 || n > 2 ^ (63 :: Int) - 1) (bound : coefficients)
+  = error "SBV->C: Pseudo-Boolean coefficients and bounds must be non-negative signed 64-bit values."
+  | sum coefficients <= 2 ^ (64 :: Int) - 1
+  = assign (case terms of [] -> unsigned 0; _ -> parens (hsep (punctuate (text " +") terms)))
+  | True
+  = text "{"
+ $$ nest 2 (text "uint64_t sbv_pb_sum = UINT64_C(0);"
+         $$ vcat [ text "if" P.<> parens (accumulator <+> text "<=" <+> unsigned bound <+> text "&&" <+> parens argument)
+                $$ nest 2 (accumulator <+> text "+=" <+> unsigned coefficient P.<> semi)
+                 | (coefficient, argument) <- weighted
+                 ]
+         $$ assign accumulator)
+ $$ text "}"
+ where (coefficients, comparison, bound) = case operation of
+         PB_AtMost  k -> (replicate (length arguments) 1, "<=", toInteger k)
+         PB_AtLeast k -> (replicate (length arguments) 1, ">=", toInteger k)
+         PB_Exactly k -> (replicate (length arguments) 1, "==", toInteger k)
+         PB_Le cs   k -> (map toInteger cs,               "<=", toInteger k)
+         PB_Ge cs   k -> (map toInteger cs,               ">=", toInteger k)
+         PB_Eq cs   k -> (map toInteger cs,               "==", toInteger k)
+
+       weighted      = zip coefficients arguments
+       accumulator   = text "sbv_pb_sum"
+       unsigned n    = text "UINT64_C" P.<> parens (integer n)
+       assign sumDoc = result <+> text "=" <+> sumDoc <+> text comparison <+> unsigned bound P.<> semi
+       terms = [parens (argument <+> text "?" <+> unsigned coefficient <+> text ":" <+> unsigned 0)
+               | (coefficient, argument) <- weighted]
diff --git a/Data/SBV/Compilers/C/Real.hs b/Data/SBV/Compilers/C/Real.hs
new file mode 100644
--- /dev/null
+++ b/Data/SBV/Compilers/C/Real.hs
@@ -0,0 +1,67 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Data.SBV.Compilers.C.Real
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Safe flooring of native real representations to mapped integers.
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Data.SBV.Compilers.C.Real (mappedRealFloorWidth, mappedRealFloorCall, mappedRealFloorRuntime) where
+
+import Data.Maybe (mapMaybe)
+import Text.PrettyPrint.HughesPJ
+import qualified Text.PrettyPrint.HughesPJ as P ((<>))
+
+import Data.SBV.Compilers.CodeGen (CgConfig(..))
+import Data.SBV.Core.Data
+
+-- | Identify flooring from an explicitly native real to a mapped integer.
+-- Exact GMP representations are handled by their own conversion paths.
+mappedRealFloorWidth :: CgConfig -> Op -> Maybe Int
+mappedRealFloorWidth cfg (KindCast KReal KUnbounded)
+  | Just _ <- cgReal cfg = cgInteger cfg
+mappedRealFloorWidth _ _ = Nothing
+
+-- | Call the width-specific helper. Promotion to long double is exact for
+-- the native float and double mappings and preserves long-double precision.
+mappedRealFloorCall :: Int -> Doc -> Doc
+mappedRealFloorCall width value = text (mappedRealFloorName width) P.<> parens value
+
+-- | Emit the helper only when a program actually floors a mapped real.
+-- Reduce the magnitude modulo a power of two before any integer cast. Split
+-- 64-bit residues into 32-bit halves so even a binary64 long double never
+-- needs to represent UINT64_MAX or a rounded signed upper bound.
+-- Non-finite real representations have no mathematical floor and fail fast.
+mappedRealFloorRuntime :: CgConfig -> [(SV, SBVExpr)] -> Doc
+mappedRealFloorRuntime cfg assignments = case mapMaybe (\(_, SBVApp operation _) -> mappedRealFloorWidth cfg operation) assignments of
+  []      -> empty
+  width:_ -> text . unlines $
+    [ "/* Floor native reals, then retain the mapped integer's low bits. */"
+    , "static " ++ signedType ++ " " ++ mappedRealFloorName width ++ "(long double value)"
+    , "{"
+    , "  if (!isfinite(value)) {"
+    , "    fputs(\"SBV->C: Cannot floor a non-finite mapped SReal to SInteger.\\n\", stderr);"
+    , "    abort();"
+    , "  }"
+    , "  const long double integral = floorl(value);"
+    , "  const long double residue = fmodl(fabsl(integral), 0x1p" ++ show width ++ "L);"
+    , "  const uint64_t high = (uint64_t) (residue / 0x1p32L);"
+    , "  const uint64_t low = (uint64_t) (residue - (long double) high * 0x1p32L);"
+    , "  uint64_t bits = (high << 32) | low;"
+    , "  if (signbit(integral)) bits = UINT64_C(0) - bits;"
+    , "  const " ++ unsignedType ++ " raw = (" ++ unsignedType ++ ") bits;"
+    , "  " ++ signedType ++ " result; memcpy(&result, &raw, sizeof result); return result;"
+    , "}"
+    , ""
+    ]
+    where signedType   = "SInt" ++ show width
+          unsignedType = "SWord" ++ show width
+
+-- | Name the private helper by its mapped integer width.
+mappedRealFloorName :: Int -> String
+mappedRealFloorName width = "sbv_real_floor_to_s" ++ show width
diff --git a/Data/SBV/Compilers/C/RegExp.hs b/Data/SBV/Compilers/C/RegExp.hs
new file mode 100644
--- /dev/null
+++ b/Data/SBV/Compilers/C/RegExp.hs
@@ -0,0 +1,371 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Data.SBV.Compilers.C.RegExp
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Bounded derivative automata for dependency-free, exact C regex operations.
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Data.SBV.Compilers.C.RegExp (regexExpr) where
+
+import Control.Monad (foldM, when)
+import Control.Monad.State.Strict (StateT, evalStateT, get, put, lift)
+import Data.Char (ord)
+import Data.List (intercalate)
+import Data.Maybe (fromMaybe)
+import qualified Data.Map.Strict as Map
+import qualified Data.Sequence as Seq
+import qualified Data.Set as Set
+import Text.PrettyPrint.HughesPJ (Doc, render, text)
+
+import Data.SBV.Compilers.CodeGen (CgConfig(..))
+import Data.SBV.Compilers.C.Lowering (CLowering(..), CRequirement(..), expressionLowering)
+import qualified Data.SBV.Core.Data as S
+import Data.SBV.Core.Symbolic (validateRegExp)
+
+-- | A normalized residual language, caching nullability and tree size so
+-- nullable concatenation and budget checks need no uncharged recursive walks.
+data Regex = Regex { nullable  :: !Bool      -- ^ Whether this residual accepts the empty string.
+                   , nodeCount :: !Integer   -- ^ Nodes in its normalized expression tree.
+                   , form      :: !RegexForm -- ^ Canonical constructor and children.
+                   }
+           deriving (Eq, Ord)
+
+-- | Union and intersection operands are sorted and duplicate-free;
+-- concatenations are flattened. Complement is relative to the SBV alphabet.
+data RegexForm = Empty
+               | Epsilon
+               | Character Int Int
+               | Concatenate [Regex]
+               | Unite [Regex]
+               | Intersect [Regex]
+               | Complement Regex
+               | Star Regex
+               deriving (Eq, Ord)
+
+-- | Per-operation budgets. Work counts visited/constructed nodes and a
+-- conservative allowance for normalization and automaton-state comparisons.
+data Budget = Budget { configuration :: CgConfig  -- ^ User-selected limits for this operation.
+                     , remainingWork :: !Integer -- ^ Work still available before generation fails.
+                     }
+
+-- | Pure compilation with explicit, recoverable internal budget failures.
+type Build = StateT Budget (Either String)
+
+-- | The empty language.
+emptyRegex :: Regex
+emptyRegex = Regex False 1 Empty
+
+-- | The language containing only the empty string.
+epsilonRegex :: Regex
+epsilonRegex = Regex True 1 Epsilon
+
+-- | All strings over SBV's character domain.
+allRegex :: Regex
+allRegex = Regex True 2 (Complement emptyRegex)
+
+-- | One past the largest SBV character, including numeric surrogate values.
+alphabetEnd :: Int
+alphabetEnd = 0x30000
+
+-- | Turn a compiler-budget failure into the usual generation diagnostic.
+runCompiler :: CgConfig -> Build a -> a
+runCompiler cfg action
+  | any (<= 0) [cgRegexMaxStates cfg, cgRegexMaxNodes cfg, cgRegexMaxWork cfg]
+  = error "SBV->C: Regex compilation is disabled by cgRegexLimits; all three limits must be positive."
+  | True
+  = either (error . ("SBV->C: " ++)) id $ evalStateT action (Budget cfg (cgRegexMaxWork cfg))
+
+-- | Fail without printing a potentially huge input or derivative expression.
+exceeded :: String -> Integer -> Build a
+exceeded dimension limit = lift $ Left $ "Regex generation exceeds the " ++ dimension ++ " limit (" ++ show limit
+                                      ++ "). Raise cgRegexLimits explicitly to permit more generation work."
+
+-- | Charge work before performing the associated allocation or traversal.
+charge :: Integer -> Build ()
+charge amount = do
+  budget <- get
+  when (amount > remainingWork budget) $ exceeded "work" (cgRegexMaxWork (configuration budget))
+  put budget { remainingWork = remainingWork budget - amount }
+
+-- | Check a normalized expression or bounded expansion before allocating it.
+checkNodes :: Integer -> Build ()
+checkNodes count = do
+  budget <- get
+  let limit = cgRegexMaxNodes (configuration budget)
+  when (count > limit) $ exceeded "expression-node" limit
+
+-- | Construct a bounded node. Children are shared, not copied; charge the
+-- immediate traversal while retaining the full expression-size bound.
+node :: Bool -> RegexForm -> [Regex] -> Build Regex
+node accepts shape children = do
+  let count = 1 + sum (map nodeCount children)
+  checkNodes count
+  charge (1 + toInteger (length children))
+  pure (Regex accepts count shape)
+
+-- | Traverse a source list without first allocating an unbounded converted
+-- list. This also bounds literals and concatenations before normalization.
+boundedTraverse :: (a -> Build b) -> [a] -> Build [b]
+boundedTraverse convert values = reverse . snd <$> foldM step (0, []) values
+ where step (count, results) value = do
+         checkNodes (count + 1)
+         charge 1
+         result <- convert value
+         pure (count + 1, result : results)
+
+-- | Flatten an associative operation after charging its input traversal.
+flatten :: (RegexForm -> Maybe [Regex]) -> [Regex] -> Build [Regex]
+flatten children rs = do
+  let result = concatMap (\r -> fromMaybe [r] (children (form r))) rs
+  charge (1 + toInteger (length rs + length result))
+  pure result
+
+-- | Canonicalize a Boolean operation without distributing it over other
+-- operators. The comparison allowance is deliberately conservative.
+boolean :: Bool -> [Regex] -> Build Regex
+boolean intersection rs = do
+  flat <- flatten children rs
+  charge (comparisonDepth (length flat) * (1 + sum (map nodeCount flat)))
+  let absorbing = if intersection then emptyRegex else allRegex
+      identity  = if intersection then allRegex else emptyRegex
+      members   = Set.fromList (filter (/= identity) flat)
+      opposite r = case form r of
+                     Complement value -> value `Set.member` members
+                     _                -> False
+  if absorbing `Set.member` members || any opposite members
+    then pure absorbing
+    else case Set.toAscList members of
+           []  -> pure identity
+           [r] -> pure r
+           xs  -> node (if intersection then all nullable xs else any nullable xs)
+                       (if intersection then Intersect xs else Unite xs) xs
+ where children (Intersect xs) | intersection     = Just xs
+       children (Unite xs)     | not intersection = Just xs
+       children _                                = Nothing
+
+-- | Flatten concatenation, eliminate epsilon, and propagate the empty language.
+concatenate :: [Regex] -> Build Regex
+concatenate rs = do
+  flat <- flatten children rs
+  if any ((== Empty) . form) flat
+    then pure emptyRegex
+    else case filter ((/= Epsilon) . form) flat of
+           []  -> pure epsilonRegex
+           [r] -> pure r
+           xs  -> node (all nullable xs) (Concatenate xs) xs
+ where children (Concatenate xs) = Just xs
+       children _                = Nothing
+
+-- | Cancel double complements; no language approximation is performed.
+complement :: Regex -> Build Regex
+complement r = case form r of
+                 Complement value -> charge 1 >> pure value
+                 _                -> node (not (nullable r)) (Complement r) [r]
+
+-- | Normalize trivial and nested stars without unrolling any repetition.
+star :: Regex -> Build Regex
+star r = case form r of
+           Empty   -> pure epsilonRegex
+           Epsilon -> pure epsilonRegex
+           Star _  -> pure r
+           _       -> node True (Star r) [r]
+
+-- | Translate every SBV regex constructor. Bounded repetitions are expanded
+-- only after checking their size; invalid bounds retain the frontend diagnostic.
+convertRegex :: S.RegExp -> Build Regex
+convertRegex regex = do
+  charge 1
+  result <- case regex of
+    S.Literal value -> boundedTraverse character value >>= concatenate
+    S.All           -> pure allRegex
+    S.AllChar       -> node False (Character 0 (alphabetEnd - 1)) []
+    S.None          -> pure emptyRegex
+    S.Range lo hi   -> do
+      a <- code lo
+      b <- code hi
+      if a > b then pure emptyRegex else node False (Character a b) []
+    S.Conc rs       -> boundedTraverse convertRegex rs >>= concatenate
+    S.Union rs      -> boundedTraverse convertRegex rs >>= boolean False
+    S.Inter a b     -> pair a b >>= boolean True
+    S.Diff a b      -> do
+      left  <- convertRegex a
+      right <- convertRegex b >>= complement
+      boolean True [left, right]
+    S.Comp r        -> convertRegex r >>= complement
+    S.KStar r       -> convertRegex r >>= star
+    S.KPlus r       -> do
+      body <- convertRegex r
+      rest <- star body
+      concatenate [body, rest]
+    S.Opt r         -> convertRegex r >>= \body -> boolean False [epsilonRegex, body]
+    S.Loop lo hi r  -> validateRegExp (S.Loop lo hi (S.Literal "")) `seq` repeatRegex lo hi r
+    S.Power n r     -> validateRegExp (S.Power n (S.Literal "")) `seq` repeatRegex n n r
+  checkNodes (nodeCount result)
+  pure result
+ where code c
+         | ord c < alphabetEnd = pure (ord c)
+         | True                = lift $ Left "Regex character is outside SBV's domain 0..0x2ffff."
+
+       character c = do
+         value <- code c
+         node False (Character value value) []
+
+       pair a b = sequence [convertRegex a, convertRegex b]
+
+       repeatRegex lo hi r = do
+         checkNodes (1 + toInteger hi)
+         charge (toInteger hi)
+         body <- convertRegex r
+         optional <- boolean False [epsilonRegex, body]
+         checkNodes (1 + toInteger lo * nodeCount body + toInteger (hi - lo) * nodeCount optional)
+         concatenate (replicate lo body ++ replicate (hi - lo) optional)
+
+-- | Compute the left derivative by a single representative character.
+-- Nullability of the result states whether the consumed input is accepted.
+derivative :: Int -> Regex -> Build Regex
+derivative c regex = do
+  charge 1
+  case form regex of
+    Empty             -> pure emptyRegex
+    Epsilon           -> pure emptyRegex
+    Character lo hi   -> pure $ if lo <= c && c <= hi then epsilonRegex else emptyRegex
+    Unite rs          -> mapM (derivative c) rs >>= boolean False
+    Intersect rs      -> mapM (derivative c) rs >>= boolean True
+    Complement r      -> derivative c r >>= complement
+    Star r            -> derivative c r >>= \first -> concatenate [first, regex]
+    Concatenate []    -> pure emptyRegex
+    Concatenate (r:rs) -> do
+      first <- derivative c r >>= \value -> concatenate (value : rs)
+      if nullable r
+        then do rest <- concatenate rs >>= derivative c
+                boolean False [first, rest]
+        else pure first
+
+-- | Partition the complete character domain at every literal/range boundary.
+-- Derivatives cannot introduce new boundaries, so representatives are exact.
+alphabet :: [Regex] -> Build [(Int, Int)]
+alphabet regexes = do
+  cuts <- foldM visit (Set.fromList [0, alphabetEnd]) regexes
+  let points = Set.toAscList cuts
+  pure [(lo, end - 1) | (lo, end) <- zip points (drop 1 points)]
+ where visit cuts r = do
+         charge 1
+         case form r of
+           Character lo hi -> pure $ Set.insert lo (Set.insert (hi + 1) cuts)
+           Concatenate rs  -> foldM visit cuts rs
+           Unite rs        -> foldM visit cuts rs
+           Intersect rs    -> foldM visit cuts rs
+           Complement x    -> visit cuts x
+           Star x          -> visit cuts x
+           _               -> pure cuts
+
+-- | A complete automaton or an early language-inequality witness. An accepting
+-- state in a membership automaton is not itself an inequality witness.
+data Exploration = CompleteAutomaton [(Bool, [Int])] -- ^ All reachable states and transitions.
+                 | InequalityWitness                -- ^ A reachable pair differs in acceptance.
+
+-- | Explore states breadth-first, assigning deterministic integer indices.
+-- Language comparison stops at the first accepting product state (a witness
+-- of inequality); membership builds all reachable rows. State limits apply
+-- before insertion, including to pairs explored for language comparison.
+explore :: Ord a => Bool -> (a -> Bool) -> (a -> Integer) -> (Int -> a -> Build a)
+        -> [(Int, Int)] -> a -> Build Exploration
+explore stop accepts size step classes initial = go (Map.singleton initial 0) (Seq.singleton initial) []
+ where go known pending rows = case Seq.viewl pending of
+         Seq.EmptyL -> pure (CompleteAutomaton (reverse rows))
+         r Seq.:< rest -> do
+           charge 1
+           if stop && accepts r
+             then pure InequalityWitness
+             else do
+               (known', pending', reversed) <- foldM (transition r) (known, rest, []) classes
+               go known' pending' ((accepts r, reverse reversed) : rows)
+
+       transition r (known, pending, indices) (c, _) = do
+         next <- step c r
+         charge (comparisonDepth (Map.size known) * size next)
+         case Map.lookup next known of
+           Just index -> pure (known, pending, index : indices)
+           Nothing -> do
+             budget <- get
+             let index = Map.size known
+                 limit = cgRegexMaxStates (configuration budget)
+             when (toInteger index >= limit) $ exceeded "state" limit
+             pure (Map.insert next index known, pending Seq.|> next, index : indices)
+
+-- | Conservative logarithmic comparison allowance for balanced maps and sets.
+comparisonDepth :: Int -> Integer
+comparisonDepth count
+  | count <= 1 = 1
+  | True       = 1 + comparisonDepth (count `quot` 2)
+
+-- | Compile exact membership into function-local static tables and a guarded
+-- loop. Locally scoped names work unchanged in definitions, callbacks, and
+-- library components; dead operations are never compiled by the scheduler.
+regexExpr :: CgConfig -> S.Op -> S.SV -> [Doc] -> Maybe CLowering
+regexExpr cfg (S.StrOp (S.StrInRe regex)) result [value] = Just $ runCompiler cfg $ do
+  initial <- convertRegex regex
+  classes <- alphabet [initial]
+  automaton <- explore False nullable nodeCount derivative classes initial
+  case automaton of
+    CompleteAutomaton rows -> pure $ membership result value classes rows
+    InequalityWitness      -> lift $ Left "Unexpected inequality witness during regex membership compilation."
+regexExpr cfg (S.RegExOp operation) _ [] = Just $ runCompiler cfg $ do
+  let (left, right, negateResult) = case operation of
+        S.RegExEq  a b -> (a, b, False)
+        S.RegExNEq a b -> (a, b, True)
+  a <- convertRegex left
+  b <- convertRegex right
+  classes <- alphabet [a, b]
+  comparison <- explore True (\(x, y) -> nullable x /= nullable y) (\(x, y) -> nodeCount x + nodeCount y)
+                       (\c (x, y) -> (,) <$> derivative c x <*> derivative c y) classes (a, b)
+  let equal = case comparison of
+                CompleteAutomaton{} -> True
+                InequalityWitness   -> False
+  pure $ expressionLowering [] (text (if equal /= negateResult then "true" else "false"))
+regexExpr _ _ _ _ = Nothing
+
+-- | Render an allocation-free matcher over canonical SBV text, preserving
+-- embedded NULs and surrogate character codes. Use compact transition entries
+-- when all actual state indices fit, falling back to size_t for larger custom
+-- budgets. Input size is independent of the generation budgets.
+membership :: S.SV -> Doc -> [(Int, Int)] -> [(Bool, [Int])] -> CLowering
+membership result value classes rows = (expressionLowering [CRequiresText] (text answer))
+  { loweringDeclarations = map text
+      [ "static const uint32_t " ++ bounds ++ "[] = {" ++ intercalate ", " (map (show . snd) classes) ++ "};"
+      , "static const uint8_t " ++ accepting ++ "[] = {" ++ intercalate ", " [if yes then "1" else "0" | (yes, _) <- rows] ++ "};"
+      , "static const " ++ transitionType ++ " " ++ transitions ++ "[][" ++ show (length classes) ++ "] = {\n"
+          ++ intercalate ",\n" ["  {" ++ intercalate ", " (map show indices) ++ "}" | (_, indices) <- rows] ++ "\n};"
+      , "SBool " ++ answer ++ ";"
+      ]
+  , loweringSetup = [text $ unlines
+      [ "{"
+      , "  const SString input = " ++ render value ++ ";"
+      , "  size_t state = 0;"
+      , "  for (size_t offset = 0; offset < input.byte_length;) {"
+      , "    const SChar character = sbv_text_decode(input.data + offset);"
+      , "    if (character > UINT32_C(0x2ffff)) abort();"
+      , "    offset += sbv_text_width(input.data[offset]);"
+      , "    size_t column = 0;"
+      , "    while (column + 1 < " ++ show (length classes) ++ " && character > " ++ bounds ++ "[column]) ++column;"
+      , "    state = " ++ transitions ++ "[state][column];"
+      , "  }"
+      , "  " ++ answer ++ " = " ++ accepting ++ "[state];"
+      , "}"
+      ]]
+  }
+ where prefix      = "sbv_regex_" ++ show result
+       transitionType | stateCount <= 65536      = "uint16_t"
+                      | stateCount <= 4294967296 = "uint32_t"
+                      | True                     = "size_t"
+       stateCount  = toInteger (length rows)
+       answer      = prefix ++ "_result"
+       bounds      = prefix ++ "_bounds"
+       accepting   = prefix ++ "_accept"
+       transitions = prefix ++ "_step"
diff --git a/Data/SBV/Compilers/C/Set.hs b/Data/SBV/Compilers/C/Set.hs
new file mode 100644
--- /dev/null
+++ b/Data/SBV/Compilers/C/Set.hs
@@ -0,0 +1,584 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Data.SBV.Compilers.C.Set
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Finite and cofinite symbolic-set lowering for generated C.
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Data.SBV.Compilers.C.Set
+  ( setKinds
+  , setSupported
+  , setUsesExact
+  , setNeedsDriverInit
+  , setCType
+  , setForwardTypeDecls
+  , setTypeDecls
+  , setOwnershipTypeDecls
+  , setRuntimeDecls
+  , setRuntime
+  , setConst
+  , setExpr
+  , setEqual
+  , setNormalize
+  , setClone
+  , setRelease
+  , setDriverValue
+  , setDriverInit
+  , setDriverClear
+  , setPrint
+  , setContextStart
+  , setContextEnd
+  ) where
+
+import Data.SBV.Compilers.C.Syntax (cUnusedAttribute)
+import Data.List                       (nub, stripPrefix, tails)
+import qualified Data.Set as Set
+
+import Text.PrettyPrint.HughesPJ
+import qualified Text.PrettyPrint.HughesPJ as P ((<>))
+
+import Data.SBV.Compilers.C.Arena      (CArena(..), arenaRuntime)
+import Data.SBV.Compilers.C.Finite     (finiteDomainSize)
+import Data.SBV.Compilers.C.GMP        (gmpFunctionName, gmpInitializeCopy, gmpOutputType, isExactGMPKind)
+import Data.SBV.Compilers.C.Lowering   (CLowering, CRequirement(..), expressionLowering)
+import Data.SBV.Compilers.C.Types      (isConcreteADT, elementCType, kindTag, setCloneName, setReleaseName, setHelperName)
+import Data.SBV.Compilers.C.Value      ( byValueEqual
+                                       , managedValueClone
+                                       , managedValueRelease
+                                       , valueDriverClear
+                                       , valueDriverInit
+                                       , valueDriverNeedsInitialization
+                                       , valueNeedsOwnership
+                                       )
+import Data.SBV.Compilers.CodeGen      (CgConfig)
+import Data.SBV.Core.Data
+import Data.SBV.Core.Kind              (expandKinds)
+import Data.SBV.Core.Symbolic          (SetOp(..))
+
+-- | Return all distinct symbolic-set kinds used by a program.
+setKinds :: Set.Set Kind -> [Kind]
+setKinds = nub . concatMap (filter isSet . expandKinds) . Set.toAscList
+
+-- | Test whether a set element kind has a supported C representation.
+setSupported :: CgConfig -> Kind -> Bool
+setSupported _ (KSet elementKind) = supportedElement elementKind
+ where supportedElement KBool          = True
+       supportedElement KBounded{}     = True
+       supportedElement KFloat         = True
+       supportedElement KDouble        = True
+       supportedElement KChar          = True
+       supportedElement KString        = True
+       supportedElement KFP{}          = True
+       supportedElement KUnbounded     = True
+       supportedElement KReal          = True
+       supportedElement KRational      = True
+       supportedElement (KList kind)   = supportedElement kind
+       supportedElement (KTuple kinds) = all supportedElement kinds
+       supportedElement kind
+         | isConcreteADT kind = True
+         | True               = isRoundingMode kind
+setSupported _ _ = False
+
+-- | Test whether a set stores exact GMP-backed elements.
+setUsesExact :: CgConfig -> Kind -> Bool
+setUsesExact cfg (KSet elementKind) = isExactGMPKind cfg elementKind
+setUsesExact _   _                  = False
+
+-- | Test whether an example-driver set requires statement-based element
+-- initialization instead of a single compound literal.
+setNeedsDriverInit :: CgConfig -> Kind -> Bool
+setNeedsDriverInit cfg (KSet elementKind) = valueDriverNeedsInitialization cfg elementKind
+setNeedsDriverInit _   _                  = False
+
+-- | Return the public C descriptor type for a symbolic-set kind.
+setCType :: Kind -> String
+setCType kind@KSet{} = elementCType kind
+setCType kind        = error $ "SBV->C: Expected a set kind, received " ++ show kind
+
+-- | Emit guarded forward declarations for symbolic-set descriptor types.
+-- These declarations allow set and list descriptors to contain pointers to
+-- each other before either family has emitted its complete layouts.
+setForwardTypeDecls :: [Kind] -> Doc
+setForwardTypeDecls []    = empty
+setForwardTypeDecls kinds = text . unlines $ concatMap declaration kinds
+ where declaration kind@KSet{} =
+         [ "#ifndef " ++ setForwardGuard kind
+         , "#define " ++ setForwardGuard kind
+         , "typedef struct " ++ setCType kind ++ " " ++ setCType kind ++ ";"
+         , "#endif"
+         , ""
+         ]
+       declaration kind = error $ "SBV->C: Expected a set kind, received " ++ show kind
+
+-- | Emit finite/cofinite set descriptors and ownership-helper prototypes.
+-- Aggregate element layouts may remain incomplete here; helper definitions
+-- are emitted later by 'setOwnershipTypeDecls'.
+setTypeDecls :: CgConfig -> [Kind] -> Doc
+setTypeDecls cfg kinds
+  | null kinds = empty
+  | True       = setForwardTypeDecls kinds $$ text (unlines $
+      ["/* Finite/cofinite symbolic sets. Inputs borrow elements; outputs and returns own them. */"
+      , cUnusedAttribute
+      ]
+      ++ concatMap declaration kinds
+      )
+ where declaration kind@(KSet elementKind)
+         | setSupported cfg kind
+         = let cType       = setCType kind
+               elementType = setElementCType elementKind
+               cloneName    = setCloneName kind
+               releaseName  = setReleaseName kind
+           in [ "#ifndef " ++ setGuard kind
+              , "#define " ++ setGuard kind
+              , "struct " ++ cType ++ " { const " ++ elementType ++ " *data; size_t length; bool is_complement; };"
+              , "static inline SBV_CGEN_UNUSED " ++ cType ++ " " ++ cloneName ++ "(" ++ cType ++ " value);"
+              , "static inline SBV_CGEN_UNUSED void " ++ releaseName ++ "(" ++ cType ++ " *value);"
+              , "#endif"
+              , ""
+              ]
+         | True
+         = error $ "SBV->C: Unsupported set element kind: " ++ show elementKind
+       declaration kind = error $ "SBV->C: Expected a set kind, received " ++ show kind
+
+-- | Emit set clone and release definitions after aggregate element layouts
+-- are complete. Inputs borrow arrays that may contain duplicates; outputs and
+-- returns own their cloned arrays.
+setOwnershipTypeDecls :: CgConfig -> [Kind] -> Doc
+setOwnershipTypeDecls cfg kinds
+  | null kinds = empty
+  | True       = text . unlines $ concatMap declaration kinds
+ where declaration kind@(KSet elementKind)
+         | setSupported cfg kind
+         = let cType       = setCType kind
+               elementType = setElementCType elementKind
+               cloneName    = setCloneName kind
+               releaseName  = setReleaseName kind
+           in [ "#ifndef " ++ setOwnershipGuard kind
+              , "#define " ++ setOwnershipGuard kind
+              , "static inline SBV_CGEN_UNUSED " ++ cType ++ " " ++ cloneName ++ "(" ++ cType ++ " value)"
+              , "{"
+              , "  " ++ elementType ++ " *copy = NULL;"
+              , "  if (value.length != 0) {"
+              , "    if (value.length > SIZE_MAX / sizeof(*copy)) abort();"
+              , "    copy = (" ++ elementType ++ " *) malloc(value.length * sizeof(*copy));"
+              , "    if (copy == NULL) abort();"
+              ]
+              ++ cloneElements elementKind
+              ++ [ "  }"
+              , "  return (" ++ cType ++ ") {copy, value.length, value.is_complement};"
+              , "}"
+              , "static inline SBV_CGEN_UNUSED void " ++ releaseName ++ "(" ++ cType ++ " *value)"
+              , "{"
+              , "  if (value == NULL) return;"
+              ]
+              ++ releaseElements elementKind
+              ++ [ "  *value = (" ++ cType ++ ") {NULL, 0, false};"
+              , "}"
+              , "#endif"
+              , ""
+              ]
+         | True
+         = error $ "SBV->C: Unsupported set element kind: " ++ show elementKind
+       declaration kind = error $ "SBV->C: Expected a set kind, received " ++ show kind
+
+       cloneElements elementKind
+         | isExactGMPKind cfg elementKind
+         =  [ "    for (size_t i = 0; i < value.length; ++i) {"
+            , "      " ++ gmpOutputType elementKind ++ " element = (" ++ gmpOutputType elementKind ++ ") malloc(sizeof(*element));"
+            , "      if (element == NULL) abort();"
+            ]
+         ++ map ("      " ++) (lines (render (gmpInitializeCopy elementKind (text "element") (text "value.data[i]"))))
+         ++ [ "      copy[i] = element;"
+            , "    }"
+            ]
+         | isConcreteADT elementKind || valueNeedsOwnership cfg elementKind
+         = [ "    for (size_t i = 0; i < value.length; ++i)"
+           , "      copy[i] = " ++ render (managedValueClone elementKind (text "value.data[i]")) ++ ";"
+           ]
+         | True
+         = ["    memcpy(copy, value.data, value.length * sizeof(*copy));"]
+
+       releaseElements elementKind
+         | isExactGMPKind cfg elementKind
+         = [ "  " ++ setElementCType elementKind ++ " *data = (" ++ setElementCType elementKind ++ " *) value->data;"
+           , "  for (size_t i = 0; i < value->length; ++i) {"
+           , "    " ++ gmpOutputType elementKind ++ " element = (" ++ gmpOutputType elementKind ++ ") data[i];"
+           , "    if (element != NULL) { " ++ gmpFunctionName elementKind "clear" ++ "(element); free(element); }"
+           , "  }"
+           , "  free(data);"
+           ]
+         | isConcreteADT elementKind || valueNeedsOwnership cfg elementKind
+         = [ "  " ++ setElementCType elementKind ++ " *data = (" ++ setElementCType elementKind ++ " *) value->data;"
+           , "  for (size_t i = 0; i < value->length; ++i)"
+           , "    " ++ render (managedValueRelease elementKind (text "&data[i]"))
+           , "  free(data);"
+           ]
+         | True
+         = ["  free((void *) value->data);"]
+
+-- | Emit forward declarations for set equality helpers referenced by nested
+-- aggregate element comparisons.
+setRuntimeDecls :: CgConfig -> [Kind] -> Doc
+setRuntimeDecls cfg kinds = text . unlines $
+  [ "static SBV_CGEN_UNUSED bool " ++ helperName kind "equal" ++ "(" ++ setCType kind ++ " left, " ++ setCType kind ++ " right);"
+  | kind <- kinds
+  , setSupported cfg kind
+  ]
+
+-- | Emit the shared set arena and one operation family per element kind.
+setRuntime :: CgConfig -> (Kind -> [[Kind]]) -> [Kind] -> Doc
+setRuntime cfg constructorsOf kinds = text . unlines . map markUnused $ commonRuntime ++ concatMap specializedRuntime kinds
+ where markUnused line = case stripPrefix "static " line of
+                           Just rest -> "static SBV_CGEN_UNUSED " ++ rest
+                           Nothing   -> line
+
+       specializedRuntime kind
+         | setSupported cfg kind = setKindRuntime cfg constructorsOf kind
+         | True                  = error $ "SBV->C: Unsupported set kind: " ++ show kind
+
+-- | Render a regular or complemented set constant.
+setConst :: (CV -> Doc) -> CV -> Maybe Doc
+setConst renderElement (CV kind@(KSet elementKind) (CSet value))
+  = Just $ text "((" P.<> text (setCType kind) P.<> text ") {"
+       P.<> elements
+       P.<> text ", "
+       P.<> int (length values)
+       P.<> text ", "
+       P.<> text (if isComplement then "true" else "false")
+       P.<> text "})"
+ where (isComplement, stored) = case value of
+                                  RegularSet entries    -> (False, entries)
+                                  ComplementSet entries -> (True,  entries)
+       values = Set.toAscList stored
+       elements
+         | null values = text "NULL"
+         | True        = text "(const" <+> text (setElementCType elementKind) P.<> text "[]) {"
+                      P.<> fsep (punctuate comma (map (renderElement . CV elementKind) values))
+                      P.<> text "}"
+setConst _ _ = Nothing
+
+-- | Lower symbolic set construction, membership, comparison, and algebra.
+setExpr :: CgConfig -> Op -> [SV] -> Kind -> [Doc] -> Maybe CLowering
+setExpr cfg op svs resultKind args
+  | not touchesSet = Nothing
+  | True           = case (op, args) of
+      (ADTOp{}                       , _        ) -> Nothing
+      (TupleConstructor{}            , _        ) -> Nothing
+      (TupleAccess{}                 , _        ) -> Nothing
+      (Uninterpreted{}               , _        ) -> Nothing
+      (Label _                       , [a]      ) -> lower a
+      (Equal _                       , [a, b]   ) -> lower $ call (helper "equal") [a, b]
+      (NotEqual                      , as       ) -> lower $ distinctSets as
+      (SetOp SetEqual                , [a, b]   ) -> lower $ call (helper "equal") [a, b]
+      (SetOp SetMember               , [e, s]   ) -> lower $ call (helper "member") [e, s]
+      (SetOp SetInsert               , [e, s]   ) -> lower $ arenaCall "insert" [e, s]
+      (SetOp SetDelete               , [e, s]   ) -> lower $ arenaCall "delete" [e, s]
+      (SetOp SetIntersect            , [a, b]   ) -> lower $ arenaCall "intersection" [a, b]
+      (SetOp SetUnion                , [a, b]   ) -> lower $ arenaCall "union" [a, b]
+      (SetOp SetSubset               , [a, b]   ) -> lower $ call (helper "subset") [a, b]
+      (SetOp SetDifference           , [a, b]   ) -> lower $ arenaCall "difference" [a, b]
+      (SetOp SetComplement           , [a]      ) -> lower $ call (helper "complement") [a]
+      _ -> unsupported
+ where touchesSet = isSet resultKind || any (isSet . kindOf) svs || isSetOp op
+
+       setKind = case [kind | value <- resultKind : map kindOf svs, kind@(KSet _) <- [value]] of
+                   kind : _ -> kind
+                   []       -> error $ "SBV->C: Cannot determine set kind for " ++ show op
+
+       lower expression = Just $ expressionLowering requirements expression
+
+       requirements = CRequiresSets : [CRequiresGMP | any (isExactGMPKind cfg) touchedKinds]
+
+       touchedKinds = concatMap expandKinds (resultKind : map kindOf svs)
+
+       helper = helperName setKind
+
+       arenaCall suffix rendered = call (helper suffix) (text "&sbv_local_set_ctx" : rendered)
+
+       distinctSets rendered = fsep $ punctuate (text " &&")
+                                     [parens (text "!" P.<> call (helper "equal") [left, right])
+                                     | left : rest <- tails rendered, right <- rest]
+
+       unsupported = error $ "SBV->C: Set lowering does not support " ++ show op
+                          ++ " with argument kinds " ++ show (map kindOf svs)
+                          ++ " and result kind " ++ show resultKind
+
+-- | Compare two set descriptors using finite/cofinite symbolic-set equality.
+setEqual :: Kind -> Doc -> Doc -> Doc
+setEqual kind left right = call (helperName kind "equal") [left, right]
+
+-- | Normalize a borrowed set descriptor into the generated function's arena.
+setNormalize :: Kind -> Doc -> Doc
+setNormalize kind value = call (helperName kind "normalize") [text "&sbv_local_set_ctx", value]
+
+-- | Deep-copy a set across the generated function's ownership boundary.
+setClone :: Kind -> Doc -> Doc
+setClone kind value = call (setCloneName kind) [value]
+
+-- | Release an owned set in a generated driver.
+setRelease :: Kind -> Doc -> Doc
+setRelease kind value = call (setReleaseName kind) [text "&" P.<> value] P.<> semi
+
+-- | Produce a deterministic three-element finite or cofinite driver value.
+setDriverValue :: (Kind -> Integer -> Doc) -> Kind -> Integer -> Doc
+setDriverValue renderValue kind@(KSet elementKind) seed
+  = text "((" P.<> text (setCType kind) P.<> text ") {"
+       P.<> text "(const" <+> text (setElementCType elementKind) P.<> text "[]) {"
+       P.<> fsep (punctuate comma [renderValue elementKind seed, renderValue elementKind (seed + 1), renderValue elementKind (seed + 2)])
+       P.<> text "}, 3, "
+       P.<> text (if odd seed then "true" else "false")
+       P.<> text "})"
+setDriverValue _ kind _ = error $ "SBV->C: Expected a set kind, received " ++ show kind
+
+-- | Initialize a generated-driver set whose elements require statement-based
+-- setup. The descriptor borrows three independently initialized elements and
+-- uses the sample seed's parity to choose a finite or cofinite representation.
+-- The supplied statement renderer handles retained aggregate elements.
+setDriverInit :: CgConfig -> (Kind -> Integer -> Doc) -> (Kind -> String -> Integer -> Doc) -> Kind -> String -> Integer -> Doc
+setDriverInit cfg renderValue initializeValue kind@KSet{} externalName seed = valueDriverInit cfg renderValue initializeValue kind externalName seed
+setDriverInit _   _           _               kind        _            _    = error $ "SBV->C: Expected a set kind, received " ++ show kind
+
+-- | Clear managed element storage initialized by 'setDriverInit'.
+setDriverClear :: CgConfig -> Kind -> String -> Doc
+setDriverClear cfg kind@KSet{} externalName = valueDriverClear cfg kind externalName
+setDriverClear _   kind        _            = error $ "SBV->C: Expected a set kind, received " ++ show kind
+
+-- | Print a finite set as @{...}@ and a cofinite set as @U - {...}@.
+setPrint :: (Kind -> Doc -> Doc) -> Kind -> Doc -> Doc
+setPrint printElement (KSet elementKind) value
+  = text "if" P.<> parens (value P.<> text ".is_complement") <+> text "printf(\"U\");"
+ $$ text "if" P.<> parens (text "!" P.<> value P.<> text ".is_complement ||" <+> value P.<> text ".length != 0")
+ $$ text "{"
+ $$ nest 2 (   text "if" P.<> parens (value P.<> text ".is_complement") <+> text "printf(\" - \");"
+            $$ text "printf(\"{\");"
+            $$ text "for (size_t" <+> index <+> text "= 0;" <+> index <+> text "<" <+> value P.<> text ".length; ++" P.<> index P.<> text ")"
+            $$ text "{"
+            $$ nest 2 (   text "if" <+> parens (index <+> text "!= 0") <+> text "printf(\", \");"
+                       $$ printElement elementKind (value P.<> text ".data[" P.<> index P.<> text "]")
+                      )
+            $$ text "}"
+            $$ text "printf(\"}\");"
+           )
+ $$ text "}"
+ where index = text ("sbv_local_set_print_index_" ++ kindTag elementKind)
+setPrint _ kind _ = error $ "SBV->C: Expected a set kind, received " ++ show kind
+
+-- | Initialize the arena used by set temporaries in a generated function.
+setContextStart :: Doc
+setContextStart = text "sbv_set_ctx sbv_local_set_ctx = {NULL};"
+
+-- | Release all set temporaries allocated by a generated function.
+setContextEnd :: Doc
+setContextEnd = call "sbv_set_ctx_end" [text "&sbv_local_set_ctx"] P.<> semi
+
+-- | Test whether an operation belongs to the symbolic-set family.
+isSetOp :: Op -> Bool
+isSetOp SetOp{} = True
+isSetOp _       = False
+
+-- | Return the element kind of a symbolic-set kind.
+setElementKind :: Kind -> Kind
+setElementKind (KSet elementKind) = elementKind
+setElementKind kind               = error $ "SBV->C: Expected a set kind, received " ++ show kind
+
+-- | Return the public C type used for one supported set element.
+setElementCType :: Kind -> String
+setElementCType KChar = "SChar"
+setElementCType kind  = elementCType kind
+
+-- | Return the preprocessor guard for one set forward declaration.
+setForwardGuard :: Kind -> String
+setForwardGuard kind = "SBV_SET_" ++ kindTag (setElementKind kind) ++ "_FORWARD_DEFINED"
+
+-- | Return the preprocessor guard for one set descriptor.
+setGuard :: Kind -> String
+setGuard kind = "SBV_SET_" ++ kindTag (setElementKind kind) ++ "_DEFINED"
+
+-- | Return the preprocessor guard for one set ownership-helper definition.
+setOwnershipGuard :: Kind -> String
+setOwnershipGuard kind = "SBV_SET_" ++ kindTag (setElementKind kind) ++ "_OWNERSHIP_DEFINED"
+
+-- | Return one specialized set-operation helper name.
+helperName :: Kind -> String -> String
+helperName = setHelperName
+
+-- | Render a C helper call.
+call :: String -> [Doc] -> Doc
+call functionName args = text functionName P.<> parens (fsep (punctuate comma args))
+
+-- | Shared per-call allocation arena used by every set specialization.
+commonRuntime :: [String]
+commonRuntime = arenaRuntime SetArena
+
+-- | Emit all set helpers for one supported element kind.
+setKindRuntime :: CgConfig -> (Kind -> [[Kind]]) -> Kind -> [String]
+setKindRuntime cfg constructorsOf kind@(KSet elementKind) =
+  [ ""
+  , "static bool " ++ equalElement ++ "(" ++ elementType ++ " left, " ++ elementType ++ " right)"
+  , "{ return " ++ elementEqual ++ "; }"
+  , "static bool " ++ helper "stored_contains" ++ "(" ++ setType ++ " value, " ++ elementType ++ " element)"
+  , "{"
+  , "  for (size_t i = 0; i < value.length; ++i) if (" ++ equalElement ++ "(value.data[i], element)) return true;"
+  , "  return false;"
+  , "}"
+  , "static " ++ setType ++ " " ++ helper "normalize" ++ "(sbv_set_ctx *ctx, " ++ setType ++ " value)"
+  , "{"
+  , "  " ++ elementType ++ " *data = (" ++ elementType ++ " *) sbv_set_alloc(ctx, value.length, sizeof(*data));"
+  , "  " ++ setType ++ " result = (" ++ setType ++ ") {data, 0, value.is_complement};"
+  , "  for (size_t i = 0; i < value.length; ++i) if (!" ++ helper "stored_contains" ++ "(result, value.data[i])) data[result.length++] = value.data[i];"
+  , "  return result;"
+  , "}"
+  , "static bool " ++ helper "stored_subset" ++ "(" ++ setType ++ " left, " ++ setType ++ " right)"
+  , "{"
+  , "  for (size_t i = 0; i < left.length; ++i) if (!" ++ helper "stored_contains" ++ "(right, left.data[i])) return false;"
+  , "  return true;"
+  , "}"
+  , "static bool " ++ helper "stored_disjoint" ++ "(" ++ setType ++ " left, " ++ setType ++ " right)"
+  , "{"
+  , "  for (size_t i = 0; i < left.length; ++i) if (" ++ helper "stored_contains" ++ "(right, left.data[i])) return false;"
+  , "  return true;"
+  , "}"
+  ]
+  ++ storedRuntime
+  ++ domainRuntime
+  ++ [ "static bool " ++ helper "equal" ++ "(" ++ setType ++ " left, " ++ setType ++ " right)"
+     , "{"
+     , "  if (left.is_complement == right.is_complement) return " ++ helper "stored_subset" ++ "(left, right) && " ++ helper "stored_subset" ++ "(right, left);"
+     , "  return " ++ helper "stored_disjoint" ++ "(left, right) && " ++ helper "domain_covered" ++ "(left, right);"
+     , "}"
+     , "static bool " ++ helper "member" ++ "(" ++ elementType ++ " element, " ++ setType ++ " value)"
+     , "{ return value.is_complement != " ++ helper "stored_contains" ++ "(value, element); }"
+     , "static " ++ setType ++ " " ++ helper "insert" ++ "(sbv_set_ctx *ctx, " ++ elementType ++ " element, " ++ setType ++ " value)"
+     , "{"
+     , "  const bool stored = " ++ helper "stored_contains" ++ "(value, element);"
+     , "  if ((!value.is_complement && stored) || (value.is_complement && !stored)) return value;"
+     , "  if (value.is_complement) return " ++ helper "stored_remove" ++ "(ctx, value, element, true);"
+     , "  return " ++ helper "stored_add" ++ "(ctx, value, element, false);"
+     , "}"
+     , "static " ++ setType ++ " " ++ helper "delete" ++ "(sbv_set_ctx *ctx, " ++ elementType ++ " element, " ++ setType ++ " value)"
+     , "{"
+     , "  const bool stored = " ++ helper "stored_contains" ++ "(value, element);"
+     , "  if ((!value.is_complement && !stored) || (value.is_complement && stored)) return value;"
+     , "  if (value.is_complement) return " ++ helper "stored_add" ++ "(ctx, value, element, true);"
+     , "  return " ++ helper "stored_remove" ++ "(ctx, value, element, false);"
+     , "}"
+     , "static " ++ setType ++ " " ++ helper "union" ++ "(sbv_set_ctx *ctx, " ++ setType ++ " left, " ++ setType ++ " right)"
+     , "{"
+     , "  if (!left.is_complement && !right.is_complement) return " ++ helper "stored_union" ++ "(ctx, left, right, false);"
+     , "  if (!left.is_complement &&  right.is_complement) return " ++ helper "stored_difference" ++ "(ctx, right, left, true);"
+     , "  if ( left.is_complement && !right.is_complement) return " ++ helper "stored_difference" ++ "(ctx, left, right, true);"
+     , "  return " ++ helper "stored_intersection" ++ "(ctx, left, right, true);"
+     , "}"
+     , "static " ++ setType ++ " " ++ helper "intersection" ++ "(sbv_set_ctx *ctx, " ++ setType ++ " left, " ++ setType ++ " right)"
+     , "{"
+     , "  if (!left.is_complement && !right.is_complement) return " ++ helper "stored_intersection" ++ "(ctx, left, right, false);"
+     , "  if (!left.is_complement &&  right.is_complement) return " ++ helper "stored_difference" ++ "(ctx, left, right, false);"
+     , "  if ( left.is_complement && !right.is_complement) return " ++ helper "stored_difference" ++ "(ctx, right, left, false);"
+     , "  return " ++ helper "stored_union" ++ "(ctx, left, right, true);"
+     , "}"
+     , "static " ++ setType ++ " " ++ helper "difference" ++ "(sbv_set_ctx *ctx, " ++ setType ++ " left, " ++ setType ++ " right)"
+     , "{"
+     , "  if (!left.is_complement && !right.is_complement) return " ++ helper "stored_difference" ++ "(ctx, left, right, false);"
+     , "  if (!left.is_complement &&  right.is_complement) return " ++ helper "stored_intersection" ++ "(ctx, left, right, false);"
+     , "  if ( left.is_complement && !right.is_complement) return " ++ helper "stored_union" ++ "(ctx, left, right, true);"
+     , "  return " ++ helper "stored_difference" ++ "(ctx, right, left, false);"
+     , "}"
+     , "static " ++ setType ++ " " ++ helper "complement" ++ "(" ++ setType ++ " value)"
+     , "{ value.is_complement = !value.is_complement; return value; }"
+     , "static bool " ++ helper "subset" ++ "(" ++ setType ++ " left, " ++ setType ++ " right)"
+     , "{"
+     , "  if (!left.is_complement && !right.is_complement) return " ++ helper "stored_subset" ++ "(left, right);"
+     , "  if (!left.is_complement &&  right.is_complement) return " ++ helper "stored_disjoint" ++ "(left, right);"
+     , "  if ( left.is_complement && !right.is_complement) return " ++ helper "domain_covered" ++ "(left, right);"
+     , "  return " ++ helper "stored_subset" ++ "(right, left);"
+     , "}"
+     ]
+ where setType      = setCType kind
+       elementType  = setElementCType elementKind
+       helper       = helperName kind
+       equalElement = helper "element_equal"
+
+       elementEqual = render $ byValueEqual cfg True elementKind (text "left") (text "right")
+
+       domainRuntime =
+         [ "static bool " ++ helper "domain_covered" ++ "(" ++ setType ++ " left, " ++ setType ++ " right)"
+         , "{"
+         ]
+         ++ case elementDomainSize constructorsOf elementKind of
+              Nothing -> [ "  (void) left; (void) right; return false;" ]
+              Just domainSize ->
+                [ "  const uint64_t domain_size = UINT64_C(" ++ show domainSize ++ ");"
+                , "  if (domain_size > (uint64_t) SIZE_MAX) return false;"
+                , "  size_t covered = 0;"
+                , "  for (size_t i = 0; i < left.length; ++i) {"
+                , "    bool duplicate = false;"
+                , "    for (size_t j = 0; j < i; ++j) if (" ++ equalElement ++ "(left.data[i], left.data[j])) { duplicate = true; break; }"
+                , "    if (!duplicate) ++covered;"
+                , "  }"
+                , "  for (size_t i = 0; i < right.length; ++i) {"
+                , "    bool duplicate = " ++ helper "stored_contains" ++ "(left, right.data[i]);"
+                , "    for (size_t j = 0; !duplicate && j < i; ++j) duplicate = " ++ equalElement ++ "(right.data[i], right.data[j]);"
+                , "    if (!duplicate) ++covered;"
+                , "  }"
+                , "  return (uint64_t) covered == domain_size;"
+                ]
+         ++ [ "}" ]
+
+       storedRuntime =
+         [ "static " ++ setType ++ " " ++ helper "stored_add" ++ "(sbv_set_ctx *ctx, " ++ setType ++ " value, " ++ elementType ++ " element, bool is_complement)"
+         , "{"
+         , "  if (value.length == SIZE_MAX) abort();"
+         , "  " ++ elementType ++ " *data = (" ++ elementType ++ " *) sbv_set_alloc(ctx, value.length + 1, sizeof(*data));"
+         , "  if (value.length != 0) memcpy(data, value.data, value.length * sizeof(*data));"
+         , "  data[value.length] = element; return (" ++ setType ++ ") {data, value.length + 1, is_complement};"
+         , "}"
+         , "static " ++ setType ++ " " ++ helper "stored_remove" ++ "(sbv_set_ctx *ctx, " ++ setType ++ " value, " ++ elementType ++ " element, bool is_complement)"
+         , "{"
+         , "  size_t length = 0;"
+         , "  for (size_t i = 0; i < value.length; ++i) if (!" ++ equalElement ++ "(value.data[i], element)) ++length;"
+         , "  " ++ elementType ++ " *data = (" ++ elementType ++ " *) sbv_set_alloc(ctx, length, sizeof(*data));"
+         , "  size_t output = 0;"
+         , "  for (size_t i = 0; i < value.length; ++i) if (!" ++ equalElement ++ "(value.data[i], element)) data[output++] = value.data[i];"
+         , "  return (" ++ setType ++ ") {data, length, is_complement};"
+         , "}"
+         , "static " ++ setType ++ " " ++ helper "stored_union" ++ "(sbv_set_ctx *ctx, " ++ setType ++ " left, " ++ setType ++ " right, bool is_complement)"
+         , "{"
+         , "  if (right.length > SIZE_MAX - left.length) abort();"
+         , "  " ++ elementType ++ " *data = (" ++ elementType ++ " *) sbv_set_alloc(ctx, left.length + right.length, sizeof(*data));"
+         , "  " ++ setType ++ " result = (" ++ setType ++ ") {data, 0, is_complement};"
+         , "  for (size_t i = 0; i < left.length; ++i) data[result.length++] = left.data[i];"
+         , "  for (size_t i = 0; i < right.length; ++i) if (!" ++ helper "stored_contains" ++ "(result, right.data[i])) data[result.length++] = right.data[i];"
+         , "  return result;"
+         , "}"
+         , "static " ++ setType ++ " " ++ helper "stored_intersection" ++ "(sbv_set_ctx *ctx, " ++ setType ++ " left, " ++ setType ++ " right, bool is_complement)"
+         , "{"
+         , "  " ++ elementType ++ " *data = (" ++ elementType ++ " *) sbv_set_alloc(ctx, left.length, sizeof(*data));"
+         , "  " ++ setType ++ " result = (" ++ setType ++ ") {data, 0, is_complement};"
+         , "  for (size_t i = 0; i < left.length; ++i) if (" ++ helper "stored_contains" ++ "(right, left.data[i])) data[result.length++] = left.data[i];"
+         , "  return result;"
+         , "}"
+         , "static " ++ setType ++ " " ++ helper "stored_difference" ++ "(sbv_set_ctx *ctx, " ++ setType ++ " left, " ++ setType ++ " right, bool is_complement)"
+         , "{"
+         , "  " ++ elementType ++ " *data = (" ++ elementType ++ " *) sbv_set_alloc(ctx, left.length, sizeof(*data));"
+         , "  " ++ setType ++ " result = (" ++ setType ++ ") {data, 0, is_complement};"
+         , "  for (size_t i = 0; i < left.length; ++i) if (!" ++ helper "stored_contains" ++ "(right, left.data[i])) data[result.length++] = left.data[i];"
+         , "  return result;"
+         , "}"
+         ]
+setKindRuntime _ _ kind = error $ "SBV->C: Expected a set kind, received " ++ show kind
+
+
+-- | Return the number of distinct SMT objects when the domain cardinality fits
+-- in a C @uint64_t@. The callback supplies resolved ADT constructor fields,
+-- allowing finite sums of products without importing the ADT lowering module.
+-- Recursive domains and domains too large for a descriptor return 'Nothing'.
+elementDomainSize :: (Kind -> [[Kind]]) -> Kind -> Maybe Integer
+elementDomainSize constructorsOf kind = do
+  total <- finiteDomainSize constructorsOf kind
+  if total <= 2 ^ (64 :: Int) - 1 then Just total else Nothing
diff --git a/Data/SBV/Compilers/C/Syntax.hs b/Data/SBV/Compilers/C/Syntax.hs
new file mode 100644
--- /dev/null
+++ b/Data/SBV/Compilers/C/Syntax.hs
@@ -0,0 +1,63 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Data.SBV.Compilers.C.Syntax
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Safe rendering of diagnostic text in generated C source.
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Data.SBV.Compilers.C.Syntax (cCommentText, cStringLiteral, cUnusedAttribute) where
+
+import qualified Data.ByteString as BS
+import Data.Char (chr, isControl, ord)
+import Data.List (intercalate)
+import qualified Data.Text as T
+import qualified Data.Text.Encoding as TE
+import Numeric (showOct)
+import Text.PrettyPrint.HughesPJ (Doc, doubleQuotes, text)
+
+-- | Shared portability preamble for helpers unused by a particular program.
+cUnusedAttribute :: String
+cUnusedAttribute = intercalate "\n"
+  [ "#ifndef SBV_CGEN_UNUSED"
+  , "#if defined(__GNUC__) || defined(__clang__)"
+  , "#define SBV_CGEN_UNUSED __attribute__((unused))"
+  , "#else"
+  , "#define SBV_CGEN_UNUSED"
+  , "#endif"
+  , "#endif"
+  ]
+
+-- | Render comment contents without allowing comment delimiters, line splices,
+-- trigraphs, or embedded control characters to affect the surrounding C source.
+-- Octal spellings here are readable text, not escapes interpreted by C comments.
+cCommentText :: String -> Doc
+cCommentText = text . protect
+ where protect []             = []
+       protect ('*':'/':rest) = "\\052/" ++ protect rest
+       protect ('/':'*':rest) = "/\\052" ++ protect rest
+       protect ('?':'?':rest) = "\\077" ++ protect ('?' : rest)
+       protect (c:rest)       = escape c ++ protect rest
+       escape '\\' = "\\134"
+       escape '\n' = "\n"
+       escape '\t' = "\t"
+       escape c
+         | isControl c = '\\' : showOct (ord c) ""
+         | True        = [c]
+
+-- | Render arbitrary text as a UTF-8 C string literal, using fixed-width
+-- octal escapes where a byte cannot safely appear verbatim.
+cStringLiteral :: String -> Doc
+cStringLiteral = doubleQuotes . text . concatMap escapeByte . BS.unpack . TE.encodeUtf8 . T.pack
+ where escapeByte byte
+         | byte == 34              = "\\\""
+         | byte == 63              = "\\?"
+         | byte == 92              = "\\\\"
+         | 32 <= byte, byte <= 126 = [chr (fromIntegral byte)]
+         | True                    = '\\' : replicate (3 - length octal) '0' ++ octal
+         where octal = showOct byte ""
diff --git a/Data/SBV/Compilers/C/Table.hs b/Data/SBV/Compilers/C/Table.hs
new file mode 100644
--- /dev/null
+++ b/Data/SBV/Compilers/C/Table.hs
@@ -0,0 +1,135 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Data.SBV.Compilers.C.Table
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Lowering of finite SBV lookup tables to C arrays.
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Data.SBV.Compilers.C.Table
+  ( tableExpr
+  , tableIndexAndBounds
+  , tableMustBeLocal
+  , tableNeedsBounds
+  ) where
+
+import Data.SBV.Compilers.C.Types (isConcreteADT)
+import qualified Data.Set as Set
+
+import Text.PrettyPrint.HughesPJ
+import qualified Text.PrettyPrint.HughesPJ as P ((<>))
+
+import Data.SBV.Compilers.C.Array    (arrayStoredLoad, arrayStoredValue)
+import Data.SBV.Compilers.C.BV       (isWideBV, wideBVLookupIndex, wideBVLookupInRange)
+import Data.SBV.Compilers.C.GMP      (isExactGMPKind)
+import Data.SBV.Compilers.C.Lowering (CLowering(..), CRequirement(..), expressionLowering)
+import Data.SBV.Compilers.C.Value    (valueNeedsOwnership)
+import Data.SBV.Compilers.CodeGen    (CgConfig(..))
+import Data.SBV.Core.Data
+import Data.SBV.Core.Kind             (expandKinds)
+
+-- | Lower a finite SBV table lookup. Bounds are checked when requested by the
+-- code-generation configuration (always before wide/exact index narrowing),
+-- and the default value is returned for every checked out-of-range index.
+-- Only the integral index kinds accepted by SBV's
+-- 'Data.SBV.select' operation can reach this function.
+tableExpr :: CgConfig -> (SV -> Doc) -> Op -> SV -> Maybe CLowering
+tableExpr cfg renderSV (LkUp (tableId, indexKind, _, tableLength) index defaultValue) resultSV
+  | isArray resultKind
+  = let lowering = arrayStoredLoad resultSV selectedValue
+    in Just lowering {loweringRequirements = Set.fromList requirements}
+  | True
+  = Just $ expressionLowering requirements selectedValue
+ where renderedIndex   = renderSV index
+       renderedDefault = arrayStoredValue resultKind (renderSV defaultValue)
+       lookupValue     = text "table" P.<> int tableId P.<> brackets nativeIndex
+       selectedValue   = case outOfRange of
+                           Just check | tableNeedsBounds cfg indexKind -> check <+> text "?" <+> renderedDefault <+> text ":" <+> lookupValue
+                           _                      -> lookupValue
+
+       resultKind = kindOf resultSV
+
+       requirements =  [CRequiresGMP    | any (isExactGMPKind cfg) touchedKinds]
+                    ++ [CRequiresWideBV | any isWideBV touchedKinds]
+                    ++ [CRequiresLibBF  | any isFP touchedKinds]
+                    ++ [CRequiresLibM   | any isFP touchedKinds]
+                    ++ [CRequiresText   | any (`elem` [KChar, KString]) touchedKinds]
+                    ++ [CRequiresLists  | any isList touchedKinds]
+                    ++ [CRequiresSets   | any isSet touchedKinds]
+                    ++ [CRequiresArrays | any isArray touchedKinds]
+
+       touchedKinds = concatMap expandKinds [indexKind, resultKind]
+
+       (nativeIndex, outOfRange) = tableIndexAndBounds cfg indexKind tableLength renderedIndex
+tableExpr _ _ _ _ = Nothing
+
+-- | Representation-changing index conversions must preserve out-of-range
+-- values even when optional native-index checks are disabled.
+tableNeedsBounds :: CgConfig -> Kind -> Bool
+tableNeedsBounds cfg kind = cgRTC cfg || isWideBV kind || isExactGMPKind cfg kind
+
+-- | Render a machine index together with its exact out-of-range predicate.
+-- Check the original value before narrowing a wide bit-vector or GMP integer;
+-- otherwise a large index could alias an in-range table entry.
+tableIndexAndBounds :: CgConfig -> Kind -> Int -> Doc -> (Doc, Maybe Doc)
+tableIndexAndBounds cfg indexKind tableLength renderedIndex = (nativeIndex, outOfRange)
+ where nativeIndex
+         | isWideBV indexKind              = wideBVLookupIndex indexKind renderedIndex
+         | isExactGMPKind cfg indexKind     = namedCall "mpz_get_ui" [renderedIndex]
+         | True                             = renderedIndex
+
+       outOfRange
+         | isWideBV indexKind
+         = Just $ text "!" P.<> parens (wideBVLookupInRange indexKind tableLength renderedIndex)
+         | isExactGMPKind cfg indexKind
+         = Just $ text "!" P.<> parens (   namedCall "mpz_sgn" [renderedIndex] <+> text ">= 0"
+                                        <+> text "&&"
+                                        <+> namedCall "mpz_cmp_ui" [renderedIndex, int tableLength] <+> text "< 0"
+                                      )
+         | KBool <- indexKind
+         = if maximumIndex indexKind >= fromIntegral tableLength
+           then Just $ renderedIndex <+> text ">=" <+> int tableLength
+           else Nothing
+         | isBounded indexKind
+         = case (hasSign indexKind, maximumIndex indexKind >= fromIntegral tableLength) of
+             (True,  True)  -> Just . parens $ renderedIndex <+> text "< 0"
+                                             <+> text "||"
+                                             <+> renderedIndex <+> text ">=" <+> int tableLength
+             (True,  False) -> Just $ renderedIndex <+> text "< 0"
+             (False, True)  -> Just $ renderedIndex <+> text ">=" <+> int tableLength
+             (False, False) -> Nothing
+         | KUnbounded <- indexKind
+         = case cgInteger cfg of
+             Nothing    -> error "SBV->C: Internal error: exact SInteger table index escaped GMP lowering."
+             Just width -> case maximumSignedIndex width >= fromIntegral tableLength of
+                             True  -> Just . parens $ renderedIndex <+> text "< 0"
+                                                     <+> text "||"
+                                                     <+> renderedIndex <+> text ">=" <+> int tableLength
+                             False -> Just $ renderedIndex <+> text "< 0"
+         | True
+         = error $ "SBV->C: Unsupported table index kind: " ++ show indexKind
+
+       maximumIndex :: Kind -> Integer
+       maximumIndex KBool = 1
+       maximumIndex kind
+         | hasSign kind = maximumSignedIndex (intSizeOf kind)
+         | True         = 2 ^ intSizeOf kind - 1
+
+       maximumSignedIndex :: Int -> Integer
+       maximumSignedIndex width = 2 ^ (width - 1) - 1
+
+       namedCall functionName args = text functionName P.<> parens (fsep (punctuate comma args))
+
+-- | Test whether a table declaration must be emitted inside the generated
+-- function. Exact GMP values use the function's ownership arena, while
+-- managed descriptors point at compound-literal backing storage that is not
+-- a portable static C initializer. ADTs are conservatively local because
+-- their concrete ownership graph is resolved by the ADT lowering phase.
+tableMustBeLocal :: CgConfig -> Kind -> Bool
+tableMustBeLocal cfg = any mustBeLocal . expandKinds
+ where mustBeLocal kind = isExactGMPKind cfg kind || valueNeedsOwnership cfg kind || isConcreteADT kind
diff --git a/Data/SBV/Compilers/C/Text.hs b/Data/SBV/Compilers/C/Text.hs
new file mode 100644
--- /dev/null
+++ b/Data/SBV/Compilers/C/Text.hs
@@ -0,0 +1,580 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Data.SBV.Compilers.C.Text
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Length-aware character and string lowering for generated C.
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Data.SBV.Compilers.C.Text
+  ( textTypeDecls
+  , textRuntime
+  , textConst
+  , textExpr
+  , textPrint
+  , textClone
+  , textRelease
+  , textDriverValue
+  , textContextStart
+  , textContextEnd
+  ) where
+
+import Data.SBV.Compilers.C.Syntax (cUnusedAttribute)
+import Data.Bits                       ((.&.), (.|.), shiftR)
+import Data.Char                       (chr, ord)
+import Data.List                       (intercalate, stripPrefix, tails)
+import qualified Data.Set as Set
+import Numeric                         (showHex)
+
+import Text.PrettyPrint.HughesPJ
+import qualified Text.PrettyPrint.HughesPJ as P ((<>))
+
+import Data.SBV.Compilers.C.Arena      (CArena(..), arenaRuntime)
+import Data.SBV.Compilers.C.GMP        (isExactGMPKind)
+import Data.SBV.Compilers.C.Lowering   (CLowering, CRequirement(..), expressionLowering)
+import Data.SBV.Compilers.C.Types      (textCloneName, textReleaseName, textCompareName)
+import Data.SBV.Compilers.CodeGen      (CgConfig)
+import Data.SBV.Core.Data
+
+-- | Declare the public character and string C types. String inputs borrow
+-- their bytes for the duration of a generated call; returned and output
+-- strings own their bytes and must be released with @sbv_string_release@.
+textTypeDecls :: Set.Set Kind -> Doc
+textTypeDecls kinds
+  | not usesText = empty
+  | True         = text . unlines $
+      ["/* Characters and length-aware UTF-8-compatible strings. */"
+      , "/* SString inputs borrow their bytes for the duration of a generated call. */"
+      , "/* SString outputs and returns own their bytes; release them with sbv_string_release. */"
+      , "/* sbv_string_borrow preserves embedded NULs; sbv_string_borrow_utf8 is for NUL-terminated input. */"
+      , "/* Borrowed text must use the canonical encoding below and character codes must be at most 0x2ffff. */"
+      , "#ifndef SBV_TEXT_TYPES_DEFINED"
+      , "#define SBV_TEXT_TYPES_DEFINED"
+      , "#include <limits.h>"
+      , cUnusedAttribute
+      , "typedef uint32_t SChar;"
+      , "typedef struct {"
+      , "  const uint8_t *data;"
+      , "  size_t byte_length;"
+      , "  size_t length;"
+      , "} SString;"
+      , ""
+      , "static inline SString sbv_string_borrow(const uint8_t *data, size_t byte_length, size_t length)"
+      , "{"
+      , "  const SString result = {data, byte_length, length};"
+      , "  return result;"
+      , "}"
+      , ""
+      , "static inline SString sbv_string_borrow_utf8(const char *value)"
+      , "{"
+      , "  const size_t byte_length = value == NULL ? 0 : strlen(value);"
+      , "  size_t length = 0;"
+      , "  for (size_t i = 0; i < byte_length; ++i)"
+      , "    if ((((const uint8_t *) value)[i] & UINT8_C(0xc0)) != UINT8_C(0x80)) ++length;"
+      , "  return sbv_string_borrow((const uint8_t *) value, byte_length, length);"
+      , "}"
+      , ""
+      , "static inline SString " ++ textCloneName ++ "(SString value)"
+      , "{"
+      , "  uint8_t *copy = NULL;"
+      , "  if (value.byte_length != 0) {"
+      , "    copy = (uint8_t *) malloc(value.byte_length);"
+      , "    if (copy == NULL) abort();"
+      , "    memcpy(copy, value.data, value.byte_length);"
+      , "  }"
+      , "  return sbv_string_borrow(copy, value.byte_length, value.length);"
+      , "}"
+      , ""
+      , "static inline void " ++ textReleaseName ++ "(SString *value)"
+      , "{"
+      , "  if (value == NULL) return;"
+      , "  free((void *) value->data);"
+      , "  *value = sbv_string_borrow(NULL, 0, 0);"
+      , "}"
+      , ""
+      , "static inline void sbv_string_fprint(FILE *stream, SString value)"
+      , "{"
+      , "  if (value.byte_length != 0) (void) fwrite(value.data, 1, value.byte_length, stream);"
+      , "}"
+      , ""
+      , "static inline size_t sbv_char_encode(SChar value, uint8_t bytes[4])"
+      , "{"
+      , "  if (value > UINT32_C(0x2ffff)) abort();"
+      , "  if (value <= UINT32_C(0x7f)) { bytes[0] = (uint8_t) value; return 1; }"
+      , "  if (value <= UINT32_C(0x7ff)) {"
+      , "    bytes[0] = (uint8_t) (UINT32_C(0xc0) | (value >> 6));"
+      , "    bytes[1] = (uint8_t) (UINT32_C(0x80) | (value & UINT32_C(0x3f)));"
+      , "    return 2;"
+      , "  }"
+      , "  if (value <= UINT32_C(0xffff)) {"
+      , "    bytes[0] = (uint8_t) (UINT32_C(0xe0) | (value >> 12));"
+      , "    bytes[1] = (uint8_t) (UINT32_C(0x80) | ((value >> 6) & UINT32_C(0x3f)));"
+      , "    bytes[2] = (uint8_t) (UINT32_C(0x80) | (value & UINT32_C(0x3f)));"
+      , "    return 3;"
+      , "  }"
+      , "  bytes[0] = (uint8_t) (UINT32_C(0xf0) | (value >> 18));"
+      , "  bytes[1] = (uint8_t) (UINT32_C(0x80) | ((value >> 12) & UINT32_C(0x3f)));"
+      , "  bytes[2] = (uint8_t) (UINT32_C(0x80) | ((value >> 6) & UINT32_C(0x3f)));"
+      , "  bytes[3] = (uint8_t) (UINT32_C(0x80) | (value & UINT32_C(0x3f)));"
+      , "  return 4;"
+      , "}"
+      , ""
+      , "static inline void sbv_char_fprint(FILE *stream, SChar value)"
+      , "{"
+      , "  uint8_t bytes[4];"
+      , "  const size_t count = sbv_char_encode(value, bytes);"
+      , "  (void) fwrite(bytes, 1, count, stream);"
+      , "}"
+      , "#endif"
+      , ""
+      ]
+ where usesText = KString `Set.member` kinds || KChar `Set.member` kinds
+
+-- | Emit the per-call text arena and the helpers used by string operations.
+textRuntime :: CgConfig -> Bool -> Doc
+textRuntime cfg usesExactInteger = text . unlines . map markUnused $
+     commonRuntime
+  ++ nativeIntegerRuntime
+  ++ if usesExactInteger then exactIntegerRuntime else []
+ where markUnused line = case stripPrefix "static " line of
+                           Just rest -> "static SBV_CGEN_UNUSED " ++ rest
+                           Nothing   -> line
+
+       nativeIntegerRuntime
+         | isExactGMPKind cfg KUnbounded = []
+         | True                          = nativeIntegerHelpers
+
+-- | Render a character or string constant without relying on C string
+-- escaping, so embedded NULs and arbitrary character codes are preserved.
+textConst :: CV -> Maybe Doc
+textConst (CV KChar (CChar value))
+  | ord value > 0x2ffff = error $ "SBV->C: Character literal exceeds the SMT-LIB maximum: " ++ show value
+  | True                = Just $ text (charLiteral value)
+textConst (CV KString (CString value))
+  | any ((> 0x2ffff) . ord) value = error "SBV->C: String literal contains a character exceeding the SMT-LIB maximum"
+  | True                          = Just $ text "((SString) {"
+       P.<> dataBytes
+       P.<> text ", "
+       P.<> integer (fromIntegral (length bytes))
+       P.<> text ", "
+       P.<> integer (fromIntegral (length value))
+       P.<> text "})"
+ where bytes = concatMap encodeChar value
+       dataBytes
+         | null bytes = text "NULL"
+         | True       = text "(const uint8_t[]) {" P.<> text (intercalate ", " (map byteLiteral bytes)) P.<> text "}"
+textConst _ = Nothing
+
+-- | Lower character and string operations. Sequence operations are accepted
+-- here only when their element kind is 'KChar'; general sequences are handled
+-- by the list runtime.
+textExpr :: CgConfig -> Op -> [SV] -> Kind -> [Doc] -> Maybe CLowering
+textExpr cfg op svs resultKind args
+  | not touchesText = Nothing
+  | True            = case (op, args) of
+      (ADTOp{}                   , _        ) -> Nothing
+      (Uninterpreted{}           , _        ) -> Nothing
+      (Label _                   , [a]      ) -> lower a
+      (Equal _                   , [a, b]   ) -> lower $ equal a b
+      (NotEqual                  , as       ) -> lower $ distinctText as
+      (LessThan                  , [a, b]   ) -> lower $ ordered "<"  a b
+      (GreaterThan               , [a, b]   ) -> lower $ ordered ">"  a b
+      (LessEq                    , [a, b]   ) -> lower $ ordered "<=" a b
+      (GreaterEq                 , [a, b]   ) -> lower $ ordered ">=" a b
+      (SeqOp (SeqLen KChar)      , [a]      ) -> lowerInteger False $ text "sbv_text_length" P.<> parens a
+      (SeqOp (SeqConcat KChar)   , as       ) -> lower $ foldText "sbv_text_concat" as
+      (SeqOp (SeqNth KChar)      , [a, i]   ) -> lower $ indexed "sbv_text_nth" [a] i
+      (SeqOp (SeqUnit KChar)     , [a]      ) -> lower $ call "sbv_text_unit" [text "&sbv_local_text_ctx", a]
+      (SeqOp (SeqSubseq KChar)   , [a, i, n]) -> lower $ indexed2 "sbv_text_substring" a i n
+      (SeqOp (SeqIndexOf KChar)  , [a, b, i]) -> lowerInteger True $ indexed "sbv_text_index_of" [a, b] i
+      (SeqOp (SeqContains KChar) , [a, b]   ) -> lower $ call "sbv_text_contains" [a, b]
+      (SeqOp (SeqPrefixOf KChar) , [a, b]   ) -> lower $ call "sbv_text_prefix_of" [a, b]
+      (SeqOp (SeqSuffixOf KChar) , [a, b]   ) -> lower $ call "sbv_text_suffix_of" [a, b]
+      (SeqOp (SeqReplace KChar)  , [a, b, c]) -> lower $ call "sbv_text_replace" [text "&sbv_local_text_ctx", a, b, c]
+      (StrOp StrToCode           , [a]      ) -> lowerInteger False a
+      (StrOp StrFromCode         , [a]      ) -> lower $ fromCode a
+      (StrOp StrStrToNat         , [a]      ) -> lowerNat a
+      (StrOp StrNatToStr         , [a]      ) -> lower $ fromNat a
+      (StrOp StrInRe{}           , _        ) -> Nothing
+      (TupleConstructor{}        , _        ) -> Nothing
+      (TupleAccess{}             , _        ) -> Nothing
+      _                                         -> unsupported (show op)
+ where touchesText = resultKind `elem` [KChar, KString]
+                  || any ((`elem` [KChar, KString]) . kindOf) svs
+                  || isTextOp op
+
+       lower expression = Just $ expressionLowering [CRequiresText] expression
+
+       lowerNat value
+         | isExactGMPKind cfg resultKind
+         = Just $ expressionLowering [CRequiresText, CRequiresGMP] (toNat value)
+         | True
+         = lower $ parens (text "SInteger") <+> toNat value
+
+       lowerInteger signed expression
+         | isExactGMPKind cfg resultKind
+         = Just $ expressionLowering [CRequiresText, CRequiresGMP]
+                $ call (if signed then "sbv_gmp_integer_from_s64" else "sbv_gmp_integer_from_u64")
+                       [text "&sbv_local_gmp_ctx", expression]
+         | True
+         = lower $ parens (text "SInteger") <+> expression
+
+       usesString = any ((== KString) . kindOf) svs
+
+       equal a b
+         | usesString = parens $ call textCompareName [a, b] <+> text "== 0"
+         | True       = a <+> text "==" <+> b
+
+       ordered relation a b
+         | usesString = parens $ call textCompareName [a, b] <+> text relation <+> text "0"
+         | True       = a <+> text relation <+> b
+
+       distinctText as = fsep $ punctuate (text " &&")
+                              [parens (if usesString
+                                       then call textCompareName [a, b] <+> text "!= 0"
+                                       else a <+> text "!=" <+> b)
+                              | (a:rest) <- tails as, b <- rest]
+
+       foldText _      []     = text "((SString) {NULL, 0, 0})"
+       foldText _      [a]    = a
+       foldText helper (a:as) = foldl (\left right -> call helper [text "&sbv_local_text_ctx", left, right]) a as
+
+       indexed helper prefix index
+         | exactIndex = call (helper ++ "_mpz") (prefix ++ [index])
+         | True       = call helper (prefix ++ [parens (text "int64_t") <+> index])
+
+       indexed2 helper value offset count
+         | exactIndex = call (helper ++ "_mpz") [text "&sbv_local_text_ctx", value, offset, count]
+         | True       = call helper [text "&sbv_local_text_ctx", value, parens (text "int64_t") <+> offset, parens (text "int64_t") <+> count]
+
+       exactIndex = any (isExactGMPKind cfg . kindOf) svs
+
+       fromCode value
+         | exactIndex = call "sbv_text_from_code_mpz" [value]
+         | True       = call "sbv_text_from_code" [parens (text "int64_t") <+> value]
+
+       toNat value
+         | isExactGMPKind cfg resultKind
+         = call "sbv_text_to_nat_mpz" [text "&sbv_local_gmp_ctx", text "&sbv_local_text_ctx", value]
+         | True
+         = call "sbv_text_to_nat" [value]
+
+       fromNat value
+         | exactIndex = call "sbv_text_from_nat_mpz" [text "&sbv_local_text_ctx", value]
+         | True       = call "sbv_text_from_nat" [text "&sbv_local_text_ctx", parens (text "int64_t") <+> value]
+
+       unsupported what = error $ "SBV->C: text lowering does not yet support " ++ what
+                               ++ " with argument kinds " ++ show (map kindOf svs)
+                               ++ " and result kind " ++ show resultKind
+
+-- | Print a generated character or string value to standard output.
+textPrint :: Kind -> Doc -> Doc
+textPrint KChar   value = call "sbv_char_fprint"   [text "stdout", value]
+textPrint KString value = call "sbv_string_fprint" [text "stdout", value]
+textPrint kind    _     = error $ "SBV->C: Expected a text kind, received " ++ show kind
+
+-- | Deep-copy a string across the generated function's ownership boundary.
+textClone :: Doc -> Doc
+textClone value = call textCloneName [value]
+
+-- | Release an owned string in a generated driver.
+textRelease :: Doc -> Doc
+textRelease value = call textReleaseName [text "&" P.<> value] P.<> semi
+
+-- | Produce a deterministic printable driver value for a character or string.
+textDriverValue :: Kind -> Integer -> Doc
+textDriverValue KChar   seed = text $ charLiteral $ chr $ 32 + fromInteger (abs seed `mod` 95)
+textDriverValue KString seed = case textConst (CV KString (CString ("sbv" ++ show (abs seed `mod` 1000)))) of
+                                Just value -> value
+                                Nothing    -> error "SBV->C: Impossible string driver value"
+textDriverValue kind    _    = error $ "SBV->C: Expected a text kind, received " ++ show kind
+
+-- | Initialize the arena used by string temporaries in a generated function.
+textContextStart :: Doc
+textContextStart = text "sbv_text_ctx sbv_local_text_ctx = {NULL};"
+
+-- | Release all string temporaries allocated by a generated function.
+textContextEnd :: Doc
+textContextEnd = call "sbv_text_ctx_end" [text "&sbv_local_text_ctx"] P.<> semi
+
+-- | Test whether an operation belongs to the string/character family even
+-- when neither its result nor all of its operands have a text kind.
+isTextOp :: Op -> Bool
+isTextOp StrOp{}                        = True
+isTextOp (SeqOp (SeqLen KChar))         = True
+isTextOp (SeqOp (SeqConcat KChar))      = True
+isTextOp (SeqOp (SeqNth KChar))         = True
+isTextOp (SeqOp (SeqUnit KChar))        = True
+isTextOp (SeqOp (SeqSubseq KChar))      = True
+isTextOp (SeqOp (SeqIndexOf KChar))     = True
+isTextOp (SeqOp (SeqContains KChar))    = True
+isTextOp (SeqOp (SeqPrefixOf KChar))    = True
+isTextOp (SeqOp (SeqSuffixOf KChar))    = True
+isTextOp (SeqOp (SeqReplace KChar))     = True
+isTextOp _                              = False
+
+-- | Render a portable numeric C character literal.
+charLiteral :: Char -> String
+charLiteral value = "UINT32_C(0x" ++ replicate (8 - length rendered) '0' ++ rendered ++ ")"
+ where rendered = showHex (ord value) ""
+
+-- | Encode one Haskell character with the canonical one-to-four-byte scheme
+-- used by the generated runtime. Numeric surrogate values are preserved.
+encodeChar :: Char -> [Int]
+encodeChar value
+  | code <= 0x7f   = [code]
+  | code <= 0x7ff  = [0xc0 .|. (code `shiftR` 6), 0x80 .|. (code .&. 0x3f)]
+  | code <= 0xffff = [ 0xe0 .|. (code `shiftR` 12)
+                      , 0x80 .|. ((code `shiftR` 6) .&. 0x3f)
+                      , 0x80 .|. (code .&. 0x3f)
+                      ]
+  | True           = [ 0xf0 .|. (code `shiftR` 18)
+                      , 0x80 .|. ((code `shiftR` 12) .&. 0x3f)
+                      , 0x80 .|. ((code `shiftR` 6) .&. 0x3f)
+                      , 0x80 .|. (code .&. 0x3f)
+                      ]
+ where code = ord value
+
+-- | Render one encoded byte as a fixed-width portable C literal.
+byteLiteral :: Int -> String
+byteLiteral value = "UINT8_C(0x" ++ replicate (2 - length rendered) '0' ++ rendered ++ ")"
+ where rendered = showHex value ""
+
+-- | Render a C helper call.
+call :: String -> [Doc] -> Doc
+call functionName args = text functionName P.<> parens (fsep (punctuate comma args))
+
+-- | Runtime helpers shared by mapped and exact integer configurations.
+commonRuntime :: [String]
+commonRuntime = arenaRuntime TextArena ++
+  [ ""
+  , "static size_t sbv_text_width(uint8_t first)"
+  , "{"
+  , "  if (first < UINT8_C(0x80)) return 1;"
+  , "  if (first < UINT8_C(0xe0)) return 2;"
+  , "  if (first < UINT8_C(0xf0)) return 3;"
+  , "  return 4;"
+  , "}"
+  , ""
+  , "static size_t sbv_text_byte_offset(SString value, size_t index)"
+  , "{"
+  , "  size_t byte = 0;"
+  , "  for (size_t character = 0; character < index && byte < value.byte_length; ++character)"
+  , "    byte += sbv_text_width(value.data[byte]);"
+  , "  return byte;"
+  , "}"
+  , ""
+  , "static SChar sbv_text_decode(const uint8_t *bytes)"
+  , "{"
+  , "  const size_t width = sbv_text_width(bytes[0]);"
+  , "  if (width == 1) return bytes[0];"
+  , "  SChar result = bytes[0] & (width == 2 ? UINT8_C(0x1f) : width == 3 ? UINT8_C(0x0f) : UINT8_C(0x07));"
+  , "  for (size_t i = 1; i < width; ++i) result = (result << 6) | (bytes[i] & UINT8_C(0x3f));"
+  , "  return result;"
+  , "}"
+  , ""
+  , "static uint64_t sbv_text_length(SString value) { return (uint64_t) value.length; }"
+  , ""
+  , "static int " ++ textCompareName ++ "(SString left, SString right)"
+  , "{"
+  , "  const size_t common = left.byte_length < right.byte_length ? left.byte_length : right.byte_length;"
+  , "  const int prefix = common == 0 ? 0 : memcmp(left.data, right.data, common);"
+  , "  if (prefix != 0) return prefix;"
+  , "  return left.byte_length < right.byte_length ? -1 : left.byte_length > right.byte_length ? 1 : 0;"
+  , "}"
+  , ""
+  , "static SString sbv_text_concat(sbv_text_ctx *ctx, SString left, SString right)"
+  , "{"
+  , "  if (SIZE_MAX - left.byte_length < right.byte_length || SIZE_MAX - left.length < right.length) abort();"
+  , "  if (left.byte_length == 0) return right;"
+  , "  if (right.byte_length == 0) return left;"
+  , "  const size_t byte_length = left.byte_length + right.byte_length;"
+  , "  uint8_t *data = sbv_text_alloc(ctx, byte_length);"
+  , "  memcpy(data, left.data, left.byte_length);"
+  , "  memcpy(data + left.byte_length, right.data, right.byte_length);"
+  , "  return sbv_string_borrow(data, byte_length, left.length + right.length);"
+  , "}"
+  , ""
+  , "static SString sbv_text_unit(sbv_text_ctx *ctx, SChar value)"
+  , "{"
+  , "  uint8_t encoded[4];"
+  , "  const size_t count = sbv_char_encode(value, encoded);"
+  , "  uint8_t *data = sbv_text_alloc(ctx, count); memcpy(data, encoded, count);"
+  , "  return sbv_string_borrow(data, count, 1);"
+  , "}"
+  , ""
+  , "static SChar sbv_text_nth(SString value, int64_t index)"
+  , "{"
+  , "  if (index < 0 || (uint64_t) index >= value.length) return UINT32_C(0);"
+  , "  return sbv_text_decode(value.data + sbv_text_byte_offset(value, (size_t) index));"
+  , "}"
+  , ""
+  , "static SString sbv_text_substring_size(sbv_text_ctx *ctx, SString value, size_t offset, size_t count)"
+  , "{"
+  , "  if (offset >= value.length || count == 0) return sbv_string_borrow(NULL, 0, 0);"
+  , "  if (count > value.length - offset) count = value.length - offset;"
+  , "  const size_t first = sbv_text_byte_offset(value, offset);"
+  , "  const size_t last = sbv_text_byte_offset(value, offset + count);"
+  , "  uint8_t *data = sbv_text_alloc(ctx, last - first); memcpy(data, value.data + first, last - first);"
+  , "  return sbv_string_borrow(data, last - first, count);"
+  , "}"
+  , ""
+  , "static SString sbv_text_substring(sbv_text_ctx *ctx, SString value, int64_t offset, int64_t count)"
+  , "{"
+  , "  if (offset < 0 || count <= 0) return sbv_string_borrow(NULL, 0, 0);"
+  , "  return sbv_text_substring_size(ctx, value, (size_t) offset, (size_t) count);"
+  , "}"
+  , ""
+  , "static bool sbv_text_prefix_of(SString prefix, SString value)"
+  , "{"
+  , "  return prefix.byte_length <= value.byte_length"
+  , "      && (prefix.byte_length == 0 || memcmp(prefix.data, value.data, prefix.byte_length) == 0);"
+  , "}"
+  , ""
+  , "static bool sbv_text_suffix_of(SString suffix, SString value)"
+  , "{"
+  , "  return suffix.byte_length <= value.byte_length"
+  , "      && (suffix.byte_length == 0 || memcmp(suffix.data, value.data + value.byte_length - suffix.byte_length, suffix.byte_length) == 0);"
+  , "}"
+  , ""
+  , "static bool sbv_text_contains(SString value, SString part)"
+  , "{"
+  , "  if (part.byte_length == 0) return true;"
+  , "  if (part.byte_length > value.byte_length) return false;"
+  , "  for (size_t offset = 0; offset + part.byte_length <= value.byte_length; offset += sbv_text_width(value.data[offset]))"
+  , "    if (memcmp(value.data + offset, part.data, part.byte_length) == 0) return true;"
+  , "  return false;"
+  , "}"
+  , ""
+  , "static int64_t sbv_text_index_of_size(SString value, SString part, size_t start)"
+  , "{"
+  , "  if (start > value.length) return -1;"
+  , "  if (part.byte_length == 0) return start <= INT64_MAX ? (int64_t) start : -1;"
+  , "  if (part.byte_length > value.byte_length) return -1;"
+  , "  size_t character = start;"
+  , "  for (size_t byte = sbv_text_byte_offset(value, start); byte + part.byte_length <= value.byte_length; ++character) {"
+  , "    if (memcmp(value.data + byte, part.data, part.byte_length) == 0) return character <= INT64_MAX ? (int64_t) character : -1;"
+  , "    byte += sbv_text_width(value.data[byte]);"
+  , "  }"
+  , "  return -1;"
+  , "}"
+  , ""
+  , "static int64_t sbv_text_index_of(SString value, SString part, int64_t start)"
+  , "{"
+  , "  return start < 0 ? -1 : sbv_text_index_of_size(value, part, (size_t) start);"
+  , "}"
+  , ""
+  , "static SString sbv_text_replace(sbv_text_ctx *ctx, SString value, SString source, SString replacement)"
+  , "{"
+  , "  const int64_t index = sbv_text_index_of_size(value, source, 0);"
+  , "  if (index < 0) return value;"
+  , "  const size_t first = sbv_text_byte_offset(value, (size_t) index);"
+  , "  const size_t after = first + source.byte_length;"
+  , "  const size_t retained = value.byte_length - source.byte_length;"
+  , "  if (replacement.byte_length > SIZE_MAX - retained) abort();"
+  , "  const size_t byte_length = retained + replacement.byte_length;"
+  , "  uint8_t *data = sbv_text_alloc(ctx, byte_length);"
+  , "  if (first != 0) memcpy(data, value.data, first);"
+  , "  if (replacement.byte_length != 0) memcpy(data + first, replacement.data, replacement.byte_length);"
+  , "  if (after != value.byte_length) memcpy(data + first + replacement.byte_length, value.data + after, value.byte_length - after);"
+  , "  return sbv_string_borrow(data, byte_length, value.length - source.length + replacement.length);"
+  , "}"
+  , ""
+  , "static SChar sbv_text_from_code(int64_t value)"
+  , "{"
+  , "  if (value < 0 || value > INT64_C(0x2ffff)) abort();"
+  , "  return (SChar) value;"
+  , "}"
+  ]
+
+-- | Runtime helpers used when 'SInteger' has a native lossy mapping.
+nativeIntegerHelpers :: [String]
+nativeIntegerHelpers =
+  [""
+  , "static int64_t sbv_text_to_nat(SString value)"
+  , "{"
+  , "  if (value.byte_length == 0) return -1;"
+  , "  uint64_t result = 0;"
+  , "  for (size_t i = 0; i < value.byte_length; ++i) {"
+  , "    if (value.data[i] < UINT8_C(0x30) || value.data[i] > UINT8_C(0x39)) return -1;"
+  , "    result = result * UINT64_C(10) + (value.data[i] - UINT8_C(0x30));"
+  , "  }"
+  , "  return (int64_t) result;"
+  , "}"
+  , ""
+  , "static SString sbv_text_from_nat(sbv_text_ctx *ctx, int64_t value)"
+  , "{"
+  , "  if (value < 0) return sbv_string_borrow(NULL, 0, 0);"
+  , "  char buffer[32];"
+  , "  const int count = snprintf(buffer, sizeof buffer, \"%\" PRIu64, (uint64_t) value);"
+  , "  uint8_t *data = sbv_text_alloc(ctx, (size_t) count); memcpy(data, buffer, (size_t) count);"
+  , "  return sbv_string_borrow(data, (size_t) count, (size_t) count);"
+  , "}"
+  ]
+
+-- | Runtime adapters used when 'SInteger' retains its exact GMP mapping.
+exactIntegerRuntime :: [String]
+exactIntegerRuntime =
+  [""
+  , "static bool sbv_text_mpz_to_size(SInteger value, size_t *result)"
+  , "{"
+  , "  if (mpz_sgn(value) < 0 || mpz_sizeinbase(value, 2) > sizeof(size_t) * CHAR_BIT) return false;"
+  , "  size_t written = 0; *result = 0;"
+  , "  (void) mpz_export(result, &written, -1, sizeof(*result), 0, 0, value);"
+  , "  return true;"
+  , "}"
+  , ""
+  , "static SChar sbv_text_nth_mpz(SString value, SInteger index)"
+  , "{"
+  , "  size_t converted;"
+  , "  if (!sbv_text_mpz_to_size(index, &converted) || converted >= value.length) return UINT32_C(0);"
+  , "  return sbv_text_decode(value.data + sbv_text_byte_offset(value, converted));"
+  , "}"
+  , ""
+  , "static SString sbv_text_substring_mpz(sbv_text_ctx *ctx, SString value, SInteger offset, SInteger count)"
+  , "{"
+  , "  size_t converted_offset, converted_count;"
+  , "  if (!sbv_text_mpz_to_size(offset, &converted_offset) || !sbv_text_mpz_to_size(count, &converted_count))"
+  , "    return sbv_string_borrow(NULL, 0, 0);"
+  , "  return sbv_text_substring_size(ctx, value, converted_offset, converted_count);"
+  , "}"
+  , ""
+  , "static int64_t sbv_text_index_of_mpz(SString value, SString part, SInteger start)"
+  , "{"
+  , "  size_t converted;"
+  , "  return sbv_text_mpz_to_size(start, &converted) ? sbv_text_index_of_size(value, part, converted) : -1;"
+  , "}"
+  , ""
+  , "static SChar sbv_text_from_code_mpz(SInteger value)"
+  , "{"
+  , "  if (mpz_sgn(value) < 0 || mpz_cmp_ui(value, 0x2ffffUL) > 0) abort();"
+  , "  return (SChar) mpz_get_ui(value);"
+  , "}"
+  , ""
+  , "static SInteger sbv_text_to_nat_mpz(sbv_gmp_ctx *gmp_ctx, sbv_text_ctx *text_ctx, SString value)"
+  , "{"
+  , "  if (value.byte_length == 0) return sbv_gmp_integer_from_s64(gmp_ctx, -1);"
+  , "  if (value.byte_length == SIZE_MAX) abort();"
+  , "  for (size_t i = 0; i < value.byte_length; ++i)"
+  , "    if (value.data[i] < UINT8_C(0x30) || value.data[i] > UINT8_C(0x39)) return sbv_gmp_integer_from_s64(gmp_ctx, -1);"
+  , "  char *digits = (char *) sbv_text_alloc(text_ctx, value.byte_length + 1);"
+  , "  memcpy(digits, value.data, value.byte_length); digits[value.byte_length] = '\\0';"
+  , "  return sbv_gmp_integer_const(gmp_ctx, digits);"
+  , "}"
+  , ""
+  , "static SString sbv_text_from_nat_mpz(sbv_text_ctx *ctx, SInteger value)"
+  , "{"
+  , "  if (mpz_sgn(value) < 0) return sbv_string_borrow(NULL, 0, 0);"
+  , "  const size_t count = mpz_sizeinbase(value, 10);"
+  , "  if (count == SIZE_MAX) abort();"
+  , "  uint8_t *data = sbv_text_alloc(ctx, count + 1);"
+  , "  (void) mpz_get_str((char *) data, 10, value);"
+  , "  const size_t length = strlen((const char *) data);"
+  , "  return sbv_string_borrow(data, length, length);"
+  , "}"
+  ]
diff --git a/Data/SBV/Compilers/C/Tuple.hs b/Data/SBV/Compilers/C/Tuple.hs
new file mode 100644
--- /dev/null
+++ b/Data/SBV/Compilers/C/Tuple.hs
@@ -0,0 +1,311 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Data.SBV.Compilers.C.Tuple
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Structural tuple lowering for the SBV-to-C compiler.
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Data.SBV.Compilers.C.Tuple
+  ( tupleKinds
+  , tupleCType
+  , tupleFieldName
+  , tupleForwardTypeDecls
+  , tupleTypeDecls
+  , tupleOwnershipTypeDecls
+  , tupleOwnedInitName
+  , tupleOwnedSetName
+  , tupleOwnedCloneName
+  , tupleOwnedReleaseName
+  , tupleDriverInit
+  , tupleValue
+  , tupleConst
+  , tupleExpr
+  , tupleUsesExact
+  , tupleNeedsOwnership
+  , elementCType
+  , kindTag
+  ) where
+
+import Data.List                       (nub, sortOn)
+import qualified Data.Set as Set
+
+import Text.PrettyPrint.HughesPJ
+import qualified Text.PrettyPrint.HughesPJ as P ((<>))
+
+import Data.SBV.Compilers.C.Array      (arrayStoredLoad, arrayStoredValue)
+import Data.SBV.Compilers.C.GMP        (gmpFunctionName, gmpOutputType, isExactGMPKind)
+import Data.SBV.Compilers.C.List       (listClone, listRelease)
+import Data.SBV.Compilers.C.Lowering   (CLowering, expressionLowering)
+import Data.SBV.Compilers.C.Set        (setClone, setRelease)
+import Data.SBV.Compilers.C.Syntax     (cCommentText)
+import Data.SBV.Compilers.C.Types      ( elementCType, kindTag, tupleCType, tupleFieldName
+                                     , tupleOwnedInitName, tupleOwnedSetName, tupleOwnedCloneName, tupleOwnedReleaseName
+                                     , textCloneName, textReleaseName
+                                     )
+import Data.SBV.Compilers.C.Value      (managedValueClone, managedValueRelease, valueDriverInit, valueNeedsOwnership)
+import Data.SBV.Compilers.CodeGen      (CgConfig)
+import Data.SBV.Core.Data
+import Data.SBV.Core.Kind              (expandKinds)
+
+-- | Return the distinct tuple kinds used by a program, with nested tuple
+-- declarations ordered before the structures that contain them.
+tupleKinds :: Set.Set Kind -> [Kind]
+tupleKinds = sortOn tupleDepth . nub . concatMap (filter isTuple . expandKinds) . Set.toAscList
+ where tupleDepth :: Kind -> Int
+       tupleDepth (KTuple fields) = 1 + maximum (0 : map tupleDepth fields)
+       tupleDepth _               = 0
+
+-- | Emit forward declarations that permit collection descriptors to refer to
+-- tuple element types before their layouts are complete.
+tupleForwardTypeDecls :: [Kind] -> Doc
+tupleForwardTypeDecls []     = empty
+tupleForwardTypeDecls tuples = text . unlines $ "/* Forward declarations for structural tuples. */" : concatMap declaration tuples
+ where declaration kind@KTuple{} =
+         [ "#ifndef " ++ tupleForwardGuard kind
+         , "#define " ++ tupleForwardGuard kind
+         , "typedef struct " ++ tupleCType kind ++ " " ++ tupleCType kind ++ ";"
+         , "#endif"
+         , ""
+         ]
+       declaration kind = error $ "SBV->C: Expected a tuple kind, received " ++ show kind
+
+-- | Emit public structure definitions for all tuple kinds used by a program.
+-- The unit tuple carries a private byte because ISO C does not permit empty
+-- structures. Each definition also provides its own guarded forward
+-- declaration so this function remains independently usable.
+tupleTypeDecls :: [Kind] -> Doc
+tupleTypeDecls []     = empty
+tupleTypeDecls tuples = text . unlines $ "/* Structural tuple values. */" : concatMap declaration tuples
+ where declaration kind@(KTuple fields) =
+            [ "#ifndef " ++ tupleGuard kind
+            , "#define " ++ tupleGuard kind
+            , "#ifndef " ++ tupleForwardGuard kind
+            , "#define " ++ tupleForwardGuard kind
+            , "typedef struct " ++ tupleCType kind ++ " " ++ tupleCType kind ++ ";"
+            , "#endif"
+            , "struct " ++ tupleCType kind ++ " {"
+            ]
+         ++ (case fields of
+               [] -> ["  uint8_t unit;"]
+               _  -> zipWith fieldDeclaration [1 :: Int ..] fields)
+         ++ [ "};"
+            , "#endif"
+            , ""
+            ]
+       declaration kind = error $ "SBV->C: Expected a tuple kind, received " ++ show kind
+
+       fieldDeclaration index kind = "  " ++ elementCType kind ++ " " ++ tupleFieldName index ++ ";"
+
+-- | Emit public ownership helpers for tuples containing exact GMP-backed,
+-- string, collection, retained-array, or concrete ADT fields. Inputs may
+-- borrow an ordinary tuple value.
+-- Cloned values own their recursively managed fields and must be released
+-- with 'tupleOwnedReleaseName'.
+tupleOwnershipTypeDecls :: CgConfig -> [Kind] -> Doc
+tupleOwnershipTypeDecls cfg tuples
+  | null owned = empty
+  | True       = text . unlines $ concatMap declaration owned
+ where owned = filter (tupleNeedsOwnership cfg) tuples
+
+       declaration kind@(KTuple fields) =
+          [ "#ifndef " ++ ownershipGuard
+          , "#define " ++ ownershipGuard
+          , "/* Recursive ownership helpers for " ++ tupleCType kind ++ ". */"
+          , "/* Owned values have unique ownership; clone before copying and release every owner. */"
+          , "static inline SBV_CGEN_UNUSED void " ++ tupleOwnedInitName kind ++ "(" ++ tupleCType kind ++ " *value)"
+          , "{"
+          , "  if (value == NULL) abort();"
+          , "  memset(value, 0, sizeof *value);"
+          ]
+          ++ concat (zipWith initializeField [1 :: Int ..] fields)
+          ++ [ "}"
+          , ""
+          , "static inline SBV_CGEN_UNUSED void " ++ tupleOwnedSetName kind ++ "(" ++ tupleCType kind ++ " *target, " ++ tupleCType kind ++ " source)"
+          , "{"
+          ]
+          ++ concat (zipWith setField [1 :: Int ..] fields)
+          ++ [ "}"
+          , ""
+          , "static inline SBV_CGEN_UNUSED " ++ tupleCType kind ++ " " ++ tupleOwnedCloneName kind ++ "(" ++ tupleCType kind ++ " source)"
+          , "{"
+          , "  " ++ tupleCType kind ++ " result;"
+          , "  " ++ tupleOwnedInitName kind ++ "(&result);"
+          , "  " ++ tupleOwnedSetName kind ++ "(&result, source);"
+          , "  return result;"
+          , "}"
+          , ""
+          , "static inline SBV_CGEN_UNUSED void " ++ tupleOwnedReleaseName kind ++ "(" ++ tupleCType kind ++ " *value)"
+          , "{"
+          , "  if (value == NULL) return;"
+          ]
+          ++ concat (zipWith releaseField [1 :: Int ..] fields)
+          ++ [ "  memset(value, 0, sizeof *value);"
+          , "}"
+          , "#endif"
+          , ""
+         ]
+         where ownershipGuard = tupleCType kind ++ "_OWNERSHIP_DEFINED"
+
+               initializeField index fieldKind
+                  | isExactGMPKind cfg fieldKind
+                  = let access  = "value->" ++ tupleFieldName index
+                        mutable = gmpOutputType fieldKind
+                        local   = "field" ++ show index
+                    in [ "  " ++ mutable ++ " " ++ local ++ " = (" ++ mutable ++ ") malloc(sizeof(*" ++ local ++ "));"
+                       , "  if (" ++ local ++ " == NULL) abort();"
+                       , "  " ++ gmpFunctionName fieldKind "init" ++ "(" ++ local ++ ");"
+                       , "  " ++ access ++ " = " ++ local ++ ";"
+                       ]
+                  | fieldKind == KString
+                  = ["  value->" ++ tupleFieldName index ++ " = (SString) {NULL, 0, 0};"]
+                  | isList fieldKind
+                  = ["  value->" ++ tupleFieldName index ++ " = (" ++ elementCType fieldKind ++ ") {NULL, 0};"]
+                  | isSet fieldKind
+                  = ["  value->" ++ tupleFieldName index ++ " = (" ++ elementCType fieldKind ++ ") {NULL, 0, false};"]
+                  | isArray fieldKind
+                  = ["  value->" ++ tupleFieldName index ++ " = NULL;"]
+                  | isTuple fieldKind && tupleNeedsOwnership cfg fieldKind
+                  = ["  " ++ tupleOwnedInitName fieldKind ++ "(&value->" ++ tupleFieldName index ++ ");"]
+                  | True
+                  = []
+
+               setField index fieldKind
+                  | isExactGMPKind cfg fieldKind
+                  = ["  " ++ gmpFunctionName fieldKind "set" ++ "((" ++ gmpOutputType fieldKind ++ ") target->" ++ field ++ ", source." ++ field ++ ");"]
+                  | fieldKind == KString
+                  = [ "  const SString " ++ field ++ "_copy = " ++ textCloneName ++ "(source." ++ field ++ ");"
+                    , "  " ++ textReleaseName ++ "(&target->" ++ field ++ ");"
+                    , "  target->" ++ field ++ " = " ++ field ++ "_copy;"
+                    ]
+                  | isList fieldKind
+                  = [ "  const " ++ elementCType fieldKind ++ " " ++ field ++ "_copy = " ++ render (listClone fieldKind (text ("source." ++ field))) ++ ";"
+                    , "  " ++ render (listRelease fieldKind (text ("target->" ++ field)))
+                    , "  target->" ++ field ++ " = " ++ field ++ "_copy;"
+                    ]
+                  | isSet fieldKind
+                  = [ "  const " ++ elementCType fieldKind ++ " " ++ field ++ "_copy = " ++ render (setClone fieldKind (text ("source." ++ field))) ++ ";"
+                    , "  " ++ render (setRelease fieldKind (text ("target->" ++ field)))
+                    , "  target->" ++ field ++ " = " ++ field ++ "_copy;"
+                    ]
+                  | isArray fieldKind
+                  = [ "  " ++ elementCType fieldKind ++ " " ++ field ++ "_copy = " ++ render (managedValueClone fieldKind (text ("source." ++ field))) ++ ";"
+                    , "  " ++ render (managedValueRelease fieldKind (text ("&target->" ++ field)))
+                    , "  target->" ++ field ++ " = " ++ field ++ "_copy;"
+                    ]
+                  | isTuple fieldKind && tupleNeedsOwnership cfg fieldKind
+                  = ["  " ++ tupleOwnedSetName fieldKind ++ "(&target->" ++ field ++ ", source." ++ field ++ ");"]
+                  | valueNeedsOwnership cfg fieldKind
+                  = [ "  " ++ elementCType fieldKind ++ " " ++ field ++ "_copy = " ++ render (managedValueClone fieldKind (text ("source." ++ field))) ++ ";"
+                    , "  " ++ render (managedValueRelease fieldKind (text ("&target->" ++ field)))
+                    , "  target->" ++ field ++ " = " ++ field ++ "_copy;"
+                    ]
+                  | True
+                  = ["  target->" ++ field ++ " = source." ++ field ++ ";"]
+                  where field = tupleFieldName index
+
+               releaseField index fieldKind
+                  | isExactGMPKind cfg fieldKind
+                  = [ "  if (value->" ++ field ++ " != NULL) {"
+                    , "    " ++ gmpFunctionName fieldKind "clear" ++ "((" ++ gmpOutputType fieldKind ++ ") value->" ++ field ++ ");"
+                    , "    free((void *) value->" ++ field ++ ");"
+                    , "  }"
+                    ]
+                  | fieldKind == KString
+                  = ["  " ++ textReleaseName ++ "(&value->" ++ field ++ ");"]
+                  | isList fieldKind
+                  = ["  " ++ render (listRelease fieldKind (text ("value->" ++ field)))]
+                  | isSet fieldKind
+                  = ["  " ++ render (setRelease fieldKind (text ("value->" ++ field)))]
+                  | isArray fieldKind
+                  = ["  " ++ render (managedValueRelease fieldKind (text ("&value->" ++ field)))]
+                  | isTuple fieldKind && tupleNeedsOwnership cfg fieldKind
+                  = ["  " ++ tupleOwnedReleaseName fieldKind ++ "(&value->" ++ field ++ ");"]
+                  | valueNeedsOwnership cfg fieldKind
+                  = ["  " ++ render (managedValueRelease fieldKind (text ("&value->" ++ field)))]
+                  | True
+                  = []
+                  where field = tupleFieldName index
+       declaration kind = error $ "SBV->C: Expected a tuple kind, received " ++ show kind
+
+-- | Initialize a generated-driver tuple and populate its fields from a seed.
+-- Recursively owned fields use the public owned-tuple storage protocol; other
+-- fields use the supplied scalar renderer. Array and ADT fields delegate to
+-- the supplied statement initializer.
+tupleDriverInit :: CgConfig -> (Kind -> Integer -> Doc) -> (Kind -> String -> Integer -> Doc) -> Kind -> String -> Integer -> Doc
+tupleDriverInit cfg renderValue initializeValue kind@KTuple{} externalName seed = valueDriverInit cfg renderValue initializeValue kind externalName seed
+tupleDriverInit _   _           _               kind         _            _    = error $ "SBV->C: Expected a tuple kind, received " ++ show kind
+
+-- | Render a concrete tuple value as a C99 compound literal.
+tupleConst :: (CV -> Doc) -> CV -> Maybe Doc
+tupleConst renderValue (CV kind@(KTuple fieldKinds) (CTuple fieldValues))
+  | length fieldKinds == length fieldValues
+  = Just $ tupleValue kind (zipWith (\fieldKind fieldValue -> arrayStoredValue fieldKind (renderValue (CV fieldKind fieldValue))) fieldKinds fieldValues)
+  | True
+  = error $ "SBV->C: Malformed tuple constant " ++ show (CV kind (CTuple fieldValues))
+tupleConst _ _ = Nothing
+
+-- | Lower tuple construction, projection, conditionals, and labels. Other
+-- operators are left to the scalar pipeline; SBV normally expands structural
+-- comparisons into field operations before code generation.
+tupleExpr :: Op -> [SV] -> SV -> [Doc] -> Maybe CLowering
+tupleExpr op svs resultSV args
+  | not (isTuple resultKind || any isTuple svs)
+  = Nothing
+  | True
+  = case (op, svs, args) of
+      (TupleConstructor arity, fields, renderedFields)
+        | KTuple fieldKinds <- resultKind
+        , arity == length fieldKinds
+        , map kindOf fields == fieldKinds
+        -> lower $ tupleValue resultKind (zipWith arrayStoredValue fieldKinds renderedFields)
+      (TupleAccess fieldIndex arity, [tupleSV], [renderedTuple])
+        | KTuple fieldKinds <- kindOf tupleSV
+        , arity == length fieldKinds
+        , fieldIndex >= 1
+        , fieldIndex <= arity
+        , resultKind == fieldKinds !! (fieldIndex - 1)
+        -> let field = parens renderedTuple P.<> text "." P.<> text (tupleFieldName fieldIndex)
+           in if isArray resultKind then Just (arrayStoredLoad resultSV field) else lower field
+      (Label label, [_], [renderedTuple])
+        -> lower $ renderedTuple <+> text "/*" <+> cCommentText label <+> text "*/"
+      _ -> Nothing
+ where resultKind = kindOf resultSV
+
+       lower = Just . expressionLowering []
+
+-- | Test whether a tuple contains an exact GMP-backed integer, real, or
+-- rational at any nesting depth under the active code-generation configuration.
+tupleUsesExact :: CgConfig -> Kind -> Bool
+tupleUsesExact cfg kind@KTuple{} = any (isExactGMPKind cfg) (expandKinds kind)
+tupleUsesExact _   _             = False
+
+-- | Test whether a tuple contains a field that must be cloned when it crosses
+-- the generated function's ownership boundary.
+tupleNeedsOwnership :: CgConfig -> Kind -> Bool
+tupleNeedsOwnership cfg kind@KTuple{} = valueNeedsOwnership cfg kind
+tupleNeedsOwnership _   _             = False
+
+-- | Render a tuple expression from its field expressions.
+tupleValue :: Kind -> [Doc] -> Doc
+tupleValue kind@(KTuple []) [] = parens (text (tupleCType kind)) P.<> braces (text "0")
+tupleValue kind@(KTuple fieldKinds) fields
+  | length fieldKinds == length fields
+  = parens (text (tupleCType kind)) P.<> braces (fsep (punctuate comma designatedFields))
+  | True
+  = error $ "SBV->C: Tuple literal field mismatch for " ++ show kind
+ where designatedFields = zipWith (\index field -> text "." P.<> text (tupleFieldName index) <+> text "=" <+> field) [1 :: Int ..] fields
+tupleValue kind _ = error $ "SBV->C: Expected a tuple kind, received " ++ show kind
+
+-- | Return the preprocessor guard protecting one tuple definition.
+tupleGuard :: Kind -> String
+tupleGuard kind = tupleCType kind ++ "_DEFINED"
+
+-- | Return the preprocessor guard protecting one tuple forward declaration.
+tupleForwardGuard :: Kind -> String
+tupleForwardGuard kind = tupleCType kind ++ "_FORWARD_DEFINED"
diff --git a/Data/SBV/Compilers/C/Types.hs b/Data/SBV/Compilers/C/Types.hs
new file mode 100644
--- /dev/null
+++ b/Data/SBV/Compilers/C/Types.hs
@@ -0,0 +1,274 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Data.SBV.Compilers.C.Types
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Shared C type and helper names for structurally lowered SBV kinds.
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Data.SBV.Compilers.C.Types
+  ( tupleCType
+  , adtCType
+  , definedFunctionCName
+  , arrayKindTag
+  , arrayOutputCTypeName
+  , arrayStoredCloneName
+  , arrayStoredReleaseName
+  , tupleFieldName
+  , tupleOwnedInitName
+  , tupleOwnedSetName
+  , tupleOwnedCloneName
+  , tupleOwnedReleaseName
+  , adtOwnedInitName
+  , adtOwnedSetName
+  , adtOwnedCloneName
+  , adtOwnedReleaseName
+  , adtEqualName
+  , listCloneName
+  , listReleaseName
+  , listHelperName
+  , setCloneName
+  , setReleaseName
+  , setHelperName
+  , textCloneName
+  , textReleaseName
+  , textCompareName
+  , elementCType
+  , constElementCType
+  , kindTag
+  , isConcreteADT
+  , isConcreteADTReference
+  ) where
+
+import Data.Char                   (isAlphaNum, isAscii, ord)
+import Numeric                     (showHex)
+
+import Data.SBV.Compilers.C.FP         (arbitraryFPCType)
+import Data.SBV.Core.Data
+
+-- | Return the helper name that initializes caller-owned storage for a tuple
+-- with recursively managed fields.
+tupleOwnedInitName :: Kind -> String
+tupleOwnedInitName kind = "sbv_tuple_owned_init_" ++ kindTag kind
+
+-- | Return the helper name that assigns into initialized owned tuple storage.
+tupleOwnedSetName :: Kind -> String
+tupleOwnedSetName kind = "sbv_tuple_owned_set_" ++ kindTag kind
+
+-- | Return the public helper name that deep-copies a managed-field tuple.
+tupleOwnedCloneName :: Kind -> String
+tupleOwnedCloneName kind = "sbv_tuple_owned_clone_" ++ kindTag kind
+
+-- | Return the public helper name that releases an owned managed-field tuple.
+tupleOwnedReleaseName :: Kind -> String
+tupleOwnedReleaseName kind = "sbv_tuple_owned_release_" ++ kindTag kind
+
+-- | Return the helper name that initializes caller-owned storage for one ADT
+-- constructor.
+adtOwnedInitName :: Kind -> String
+adtOwnedInitName kind = "sbv_adt_owned_init_" ++ adtCType kind
+
+-- | Return the helper name that assigns into initialized owned ADT storage.
+adtOwnedSetName :: Kind -> String
+adtOwnedSetName kind = "sbv_adt_owned_set_" ++ adtCType kind
+
+-- | Return the public helper name that deep-copies an owned ADT.
+adtOwnedCloneName :: Kind -> String
+adtOwnedCloneName kind = "sbv_adt_owned_clone_" ++ adtCType kind
+
+-- | Return the public helper name that releases an owned ADT.
+adtOwnedReleaseName :: Kind -> String
+adtOwnedReleaseName kind = "sbv_adt_owned_release_" ++ adtCType kind
+
+-- | Return the generated structural-equality helper for a recursive ADT.
+adtEqualName :: Bool -> Kind -> String
+adtEqualName strong kind = "sbv_adt_" ++ (if strong then "object_" else "")
+                        ++ "equal_" ++ adtCType kind
+
+-- | Return the generated clone-helper name for a list kind.
+listCloneName :: Kind -> String
+listCloneName (KList elementKind) = "sbv_list_clone_" ++ kindTag elementKind
+listCloneName kind                = error $ "SBV->C: Expected a list kind, received " ++ show kind
+
+-- | Return the generated release-helper name for a list kind.
+listReleaseName :: Kind -> String
+listReleaseName (KList elementKind) = "sbv_list_release_" ++ kindTag elementKind
+listReleaseName kind                = error $ "SBV->C: Expected a list kind, received " ++ show kind
+
+-- | Return one specialized list-operation helper name.
+listHelperName :: Kind -> String -> String
+listHelperName (KList elementKind) suffix = "sbv_list_" ++ kindTag elementKind ++ "_" ++ suffix
+listHelperName kind                _      = error $ "SBV->C: Expected a list kind, received " ++ show kind
+
+-- | Return the generated clone-helper name for a set kind.
+setCloneName :: Kind -> String
+setCloneName (KSet elementKind) = "sbv_set_clone_" ++ kindTag elementKind
+setCloneName kind               = error $ "SBV->C: Expected a set kind, received " ++ show kind
+
+-- | Return the generated release-helper name for a set kind.
+setReleaseName :: Kind -> String
+setReleaseName (KSet elementKind) = "sbv_set_release_" ++ kindTag elementKind
+setReleaseName kind               = error $ "SBV->C: Expected a set kind, received " ++ show kind
+
+-- | Return one specialized set-operation helper name.
+setHelperName :: Kind -> String -> String
+setHelperName (KSet elementKind) suffix = "sbv_set_" ++ kindTag elementKind ++ "_" ++ suffix
+setHelperName kind               _      = error $ "SBV->C: Expected a set kind, received " ++ show kind
+
+-- | Name of the public helper that copies a string into owned storage.
+textCloneName :: String
+textCloneName = "sbv_string_clone"
+
+-- | Name of the public helper that releases owned string storage.
+textReleaseName :: String
+textReleaseName = "sbv_string_release"
+
+-- | Name of the lexicographic string-comparison runtime helper.
+textCompareName :: String
+textCompareName = "sbv_text_compare"
+
+-- | A resolved user ADT, excluding built-in rounding modes and opaque sorts.
+isConcreteADT :: Kind -> Bool
+isConcreteADT kind = isADT kind && not (isRoundingMode kind) && not (isUninterpreted kind)
+
+-- | A user ADT or a retained application awaiting ADT-reference resolution.
+-- Keep this distinct from 'isConcreteADT' for dependency and ownership walks.
+isConcreteADTReference :: Kind -> Bool
+isConcreteADTReference KApp{} = True
+isConcreteADTReference kind   = isConcreteADT kind
+
+-- | Return the public C structure type used for a tuple kind.
+tupleCType :: Kind -> String
+tupleCType kind@KTuple{} = "SBVTuple_" ++ kindTag kind
+tupleCType kind          = error $ "SBV->C: Expected a tuple kind, received " ++ show kind
+
+-- | Return the public C structure type used for a concrete ADT kind or an
+-- unresolved application of a registered ADT.
+adtCType :: Kind -> String
+adtCType kind@(KADT typeName parameters _)
+  | isADT kind && not (isRoundingMode kind) && not (isUninterpreted kind)
+  = appliedType typeName (map snd parameters)
+  | True
+  = error $ "SBV->C: Expected a concrete ADT kind, received " ++ show kind
+adtCType (KApp typeName arguments) = appliedType typeName arguments
+adtCType kind = error $ "SBV->C: Expected an ADT kind, received " ++ show kind
+
+-- | Return the private C identifier used for an SBV-defined function. Encoding
+-- the complete SMT identifier keeps quoted and firstified names collision-free.
+definedFunctionCName :: String -> String
+definedFunctionCName functionName = "sbv_function_" ++ encodeIdentifier functionName
+
+-- | Render the common C type spelling shared by a concrete ADT and an
+-- unresolved application of that same registered ADT.
+appliedType :: String -> [Kind] -> String
+appliedType typeName arguments = "SBVADT_" ++ encodeIdentifier typeName ++ concatMap parameterTag arguments
+ where parameterTag parameterKind = "_" ++ show (length tag) ++ "_" ++ tag
+        where tag = kindTag parameterKind
+
+-- | Return the public member name used for a one-based tuple field index.
+tupleFieldName :: Int -> String
+tupleFieldName index
+  | index >= 1 = "field" ++ show index
+  | True       = error $ "SBV->C: Tuple fields are one-based, received " ++ show index
+
+-- | Return the public C type used for a structurally lowered field or element.
+elementCType :: Kind -> String
+elementCType KBool               = "SBool"
+elementCType (KBounded False 1)  = "SBool"
+elementCType (KBounded False w)  = "SWord" ++ show w
+elementCType (KBounded True  w)  = "SInt" ++ show w
+elementCType KUnbounded          = "SInteger"
+elementCType KReal               = "SReal"
+elementCType KRational           = "SRational"
+elementCType KFloat              = "SFloat"
+elementCType KDouble             = "SDouble"
+elementCType KChar               = "SChar"
+elementCType KString             = "SString"
+elementCType kind@KFP{}          = arbitraryFPCType kind
+elementCType kind@KTuple{}       = tupleCType kind
+elementCType kind@KADT{}
+  | isRoundingMode kind          = "RoundingMode"
+  | True                         = adtCType kind
+elementCType kind@KApp{}         = adtCType kind
+elementCType (KList elementKind) = "SBVList_" ++ kindTag elementKind
+elementCType (KSet elementKind)  = "SBVSet_" ++ kindTag elementKind
+elementCType kind@KArray{}       = arrayOutputCTypeName kind ++ " *"
+elementCType kind                = error $ "SBV->C: Unsupported structural kind: " ++ show kind
+
+-- | Qualify a stored value itself. Array values are spelled as pointers, so
+-- their const qualifier belongs after the pointer, not on its pointee.
+constElementCType :: Kind -> String
+constElementCType kind
+  | isArray kind = elementCType kind ++ " const"
+  | True         = "const " ++ elementCType kind
+
+-- | Return the suffix used by a generated structural C type. Structural
+-- components are length-framed and identifiers are escaped injectively.
+-- Consumers must preserve case, including in preprocessor guards and tags.
+-- Booleans and unsigned one-bit vectors intentionally share a representation,
+-- as do a concrete ADT and its corresponding resolved application.
+kindTag :: Kind -> String
+kindTag KBool               = "u1"
+kindTag (KBounded False w)  = "u" ++ show w
+kindTag (KBounded True  w)  = "s" ++ show w
+kindTag KUnbounded          = "integer"
+kindTag KReal               = "real"
+kindTag KRational           = "rational"
+kindTag KFloat              = "float"
+kindTag KDouble             = "double"
+kindTag KChar               = "char"
+kindTag KString             = "string"
+kindTag (KFP eb sb)         = "fp_e" ++ show eb ++ "_s" ++ show sb
+kindTag (KTuple fields)     = "t" ++ show (length fields) ++ concatMap (('_' :) . taggedKind . kindTag) fields
+kindTag kind@KADT{}
+  | isRoundingMode kind     = "rounding_mode"
+  | True                    = "adt_" ++ encodeIdentifier (adtCType kind)
+kindTag kind@KApp{}         = "adt_" ++ encodeIdentifier (adtCType kind)
+kindTag (KList elementKind) = "list_" ++ taggedKind (kindTag elementKind)
+kindTag (KSet elementKind)  = "set_"  ++ taggedKind (kindTag elementKind)
+kindTag kind@KArray{}       = "array_" ++ taggedKind (arrayKindTag kind)
+kindTag kind                = error $ "SBV->C: Unsupported structural kind: " ++ show kind
+
+-- | Return the key/value suffix shared by generated names for an array kind.
+-- Frame both components by length, just as for tuple fields and ADT arguments,
+-- so nested tags need not be parsed to find the key/value boundary.
+--
+-- >>> arrayKindTag (KArray (KBounded False 8) (KBounded False 32))
+-- "2_u8_3_u32"
+arrayKindTag :: Kind -> String
+arrayKindTag (KArray keyKind valueKind) = taggedKind (kindTag keyKind) ++ "_" ++ taggedKind (kindTag valueKind)
+arrayKindTag kind                       = error $ "SBV->C: Expected an array kind, received " ++ show kind
+
+-- | Return the public owned-output descriptor name for an array kind.
+arrayOutputCTypeName :: Kind -> String
+arrayOutputCTypeName kind@KArray{} = "SBVArrayOutput_" ++ arrayKindTag kind
+arrayOutputCTypeName kind          = error $ "SBV->C: Expected an array kind, received " ++ show kind
+
+-- | Return the helper name that clones an array descriptor stored by pointer
+-- inside another generated value.
+arrayStoredCloneName :: Kind -> String
+arrayStoredCloneName kind@KArray{} = "sbv_array_stored_clone_" ++ arrayKindTag kind
+arrayStoredCloneName kind          = error $ "SBV->C: Expected an array kind, received " ++ show kind
+
+-- | Return the helper name that releases an array descriptor stored by pointer
+-- inside another generated value.
+arrayStoredReleaseName :: Kind -> String
+arrayStoredReleaseName kind@KArray{} = "sbv_array_stored_release_" ++ arrayKindTag kind
+arrayStoredReleaseName kind          = error $ "SBV->C: Expected an array kind, received " ++ show kind
+
+-- | Prefix a generated kind tag with its length so adjacent tags cannot
+-- collide.
+taggedKind :: String -> String
+taggedKind value = show (length value) ++ "_" ++ value
+
+-- | Encode an arbitrary Haskell type name as a valid C identifier component.
+encodeIdentifier :: String -> String
+encodeIdentifier = concatMap encode
+ where encode character
+         | isAscii character && isAlphaNum character = [character]
+         | True                                      = "_x" ++ showHex (ord character) "" ++ "_"
diff --git a/Data/SBV/Compilers/C/Value.hs b/Data/SBV/Compilers/C/Value.hs
new file mode 100644
--- /dev/null
+++ b/Data/SBV/Compilers/C/Value.hs
@@ -0,0 +1,233 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Data.SBV.Compilers.C.Value
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Shared properties and operations for structurally lowered C values.
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Data.SBV.Compilers.C.Value
+  ( valueNeedsOwnership
+  , valueDriverNeedsInitialization
+  , byValueEqual
+  , managedValueClone
+  , managedValueRelease
+  , valueDriverInit
+  , valueDriverClear
+  ) where
+
+import Text.PrettyPrint.HughesPJ
+import qualified Text.PrettyPrint.HughesPJ as P ((<>))
+
+import Data.SBV.Compilers.C.BV         (isWideBV, wideBVEqual)
+import Data.SBV.Compilers.C.FP         (arbitraryFPEqual, arbitraryFPObjectEqual, nativeFPObjectEqual)
+import Data.SBV.Compilers.C.GMP        (gmpDriverAssign, gmpDriverClear, gmpDriverInit, gmpEqual, isExactGMPKind)
+import Data.SBV.Compilers.C.Types      ( isConcreteADTReference, arrayStoredCloneName, arrayStoredReleaseName
+                                     , constElementCType, elementCType, tupleCType, tupleFieldName
+                                     , adtEqualName, adtOwnedCloneName, adtOwnedReleaseName
+                                     , tupleOwnedInitName, tupleOwnedCloneName, tupleOwnedReleaseName
+                                     , listCloneName, listReleaseName, listHelperName
+                                     , setCloneName, setReleaseName, setHelperName
+                                     , textCloneName, textReleaseName, textCompareName
+                                     )
+import Data.SBV.Compilers.CodeGen      (CgConfig)
+import Data.SBV.Core.Data
+
+-- | Test whether a value requires clone-and-release ownership when it crosses
+-- a generated C ABI boundary. Concrete ADTs use a uniform ownership protocol,
+-- including those whose resolved fields do not themselves need deep storage.
+valueNeedsOwnership :: CgConfig -> Kind -> Bool
+valueNeedsOwnership cfg kind
+  | isExactGMPKind cfg kind = True
+valueNeedsOwnership _   KString        = True
+valueNeedsOwnership _   KList{}        = True
+valueNeedsOwnership _   KSet{}         = True
+valueNeedsOwnership _   KArray{}       = True
+valueNeedsOwnership cfg (KTuple kinds) = any (valueNeedsOwnership cfg) kinds
+valueNeedsOwnership _   kind@KADT{}    = isConcreteADTReference kind
+valueNeedsOwnership _   KApp{}         = True
+valueNeedsOwnership _   _              = False
+
+-- | Test whether a deterministic example-driver value needs declarations or
+-- initialization statements instead of a single C compound literal.
+valueDriverNeedsInitialization :: CgConfig -> Kind -> Bool
+valueDriverNeedsInitialization cfg kind
+  | isExactGMPKind cfg kind = True
+valueDriverNeedsInitialization cfg (KTuple fields)      = any (valueNeedsOwnership cfg) fields
+valueDriverNeedsInitialization cfg (KList elementKind)  = valueDriverNeedsInitialization cfg elementKind
+valueDriverNeedsInitialization cfg (KSet elementKind)   = valueDriverNeedsInitialization cfg elementKind
+valueDriverNeedsInitialization _   KArray{}             = True
+valueDriverNeedsInitialization _   kind@KADT{}          = isConcreteADTReference kind
+valueDriverNeedsInitialization _   KApp{}               = True
+valueDriverNeedsInitialization _   _                    = False
+
+-- | Render equality for a scalar or recursively nested aggregate. The Boolean
+-- flag selects object equality for floating-point values. Array-valued fields
+-- carry an unreachable abort sentinel: operation validation rejects consumers
+-- requiring extensional equality, while unused aggregate helpers may be emitted.
+byValueEqual :: CgConfig -> Bool -> Kind -> Doc -> Doc -> Doc
+byValueEqual cfg strong kind left right
+  | isWideBV kind                             = wideBVEqual kind left right
+  | isFP kind && strong                       = arbitraryFPObjectEqual kind left right
+  | isFP kind                                 = arbitraryFPEqual kind left right
+  | strong && (isFloat kind || isDouble kind) = nativeFPObjectEqual left right
+  | isExactGMPKind cfg kind                   = gmpEqual kind left right
+  | kind == KString                           = parens $ call textCompareName [left, right] <+> text "== 0"
+  | isList kind                               = call (listHelperName kind "equal") [left, right]
+  | isSet kind                                = call (setHelperName kind "equal") [left, right]
+  | isArray kind                              = text "(abort(), false)"
+  | KTuple fields <- kind                     = tupleEquality fields
+  | isConcreteADTReference kind               = call (adtEqualName strong kind) [left, right]
+  | True                                      = left <+> text "==" <+> right
+ where tupleEquality []     = parens . fsep . punctuate comma $ [text "(void)" <+> parens left, text "(void)" <+> parens right, text "true"]
+       tupleEquality fields = parens . fsep . punctuate (text " &&") $
+         zipWith equalField [1 :: Int ..] fields
+
+       equalField index fieldKind = byValueEqual cfg strong fieldKind
+         (parens left  P.<> text "." P.<> text (tupleFieldName index))
+         (parens right P.<> text "." P.<> text (tupleFieldName index))
+
+-- | Deep-copy one non-GMP managed value. Exact GMP values require initialized
+-- destination storage and are therefore handled by their aggregate owner.
+managedValueClone :: Kind -> Doc -> Doc
+managedValueClone KString value       = call textCloneName [value]
+managedValueClone kind@KList{} value  = call (listCloneName kind) [value]
+managedValueClone kind@KSet{} value   = call (setCloneName kind) [value]
+managedValueClone kind@KArray{} value = call (arrayStoredCloneName kind) [value]
+managedValueClone kind@KTuple{} value = call (tupleOwnedCloneName kind) [value]
+managedValueClone kind value
+  | isConcreteADTReference kind       = call (adtOwnedCloneName kind) [value]
+managedValueClone kind _              = error $ "SBV->C: Expected a non-GMP managed kind, received " ++ show kind
+
+-- | Release one non-GMP managed value through a pointer to its owned storage.
+managedValueRelease :: Kind -> Doc -> Doc
+managedValueRelease KString address       = call textReleaseName [address] P.<> semi
+managedValueRelease kind@KList{} address  = call (listReleaseName kind) [address] P.<> semi
+managedValueRelease kind@KSet{} address   = call (setReleaseName kind) [address] P.<> semi
+managedValueRelease kind@KArray{} address = call (arrayStoredReleaseName kind) [address] P.<> semi
+managedValueRelease kind@KTuple{} address = call (tupleOwnedReleaseName kind) [address] P.<> semi
+managedValueRelease kind address
+  | isConcreteADTReference kind           = call (adtOwnedReleaseName kind) [address] P.<> semi
+managedValueRelease kind _                = error $ "SBV->C: Expected a non-GMP managed kind, received " ++ show kind
+
+-- | Declare and initialize one deterministic example-driver value. Managed
+-- aggregates receive unique ownership; collection descriptors themselves
+-- borrow the element variables declared alongside them. The supplied
+-- statement renderer constructs retained arrays and registered ADTs without
+-- creating dependency cycles between the structural lowering modules.
+-- Collections whose elements need no initialization use a compound literal;
+-- 'valueDriverClear' emits no element cleanup for those borrowed literals.
+valueDriverInit :: CgConfig -> (Kind -> Integer -> Doc) -> (Kind -> String -> Integer -> Doc) -> Kind -> String -> Integer -> Doc
+valueDriverInit cfg _           _               kind                       externalName seed
+  | isExactGMPKind cfg kind
+  = gmpDriverInit kind (text externalName) (integer seed)
+valueDriverInit cfg renderValue initializeValue kind@(KTuple fields)       externalName seed
+  | valueNeedsOwnership cfg kind
+  =  text (tupleCType kind) <+> text externalName P.<> semi
+  $$ call (tupleOwnedInitName kind) [text "&" P.<> text externalName] P.<> semi
+  $$ vcat (concat (zipWith initializeTupleField [1 :: Int ..] (zip fields [seed ..])))
+ where initializeTupleField index (fieldKind, fieldSeed) = initializeAt fieldKind access fieldName fieldSeed
+        where access    = text externalName P.<> text "." P.<> text (tupleFieldName index)
+              fieldName = externalName ++ "_field_" ++ show index
+
+       initializeAt fieldKind access fieldName fieldSeed
+         | isExactGMPKind cfg fieldKind = exactAssignment fieldKind access fieldSeed
+         | fieldKind == KString         = [access <+> text "=" <+> managedValueClone fieldKind (renderValue fieldKind fieldSeed) P.<> semi]
+         | isArray fieldKind            = [ initializeValue fieldKind fieldName fieldSeed
+                                          , access <+> text "=" <+> text fieldName P.<> semi
+                                          ]
+         | isConcreteADTReference fieldKind      = [ initializeValue fieldKind fieldName fieldSeed
+                                          , access <+> text "=" <+> text fieldName P.<> semi
+                                          ]
+         | KList{}         <- fieldKind = collectionAssignment fieldKind access fieldName fieldSeed
+         | KSet{}          <- fieldKind = collectionAssignment fieldKind access fieldName fieldSeed
+         | nested@KTuple{} <- fieldKind
+         , valueNeedsOwnership cfg nested
+         = concat (zipWith initializeNested [1 :: Int ..] (zip (tupleFields nested) [fieldSeed ..]))
+         | True                           = [access <+> text "=" <+> renderValue fieldKind fieldSeed P.<> semi]
+        where initializeNested nestedIndex (nestedKind, nestedSeed) = initializeAt nestedKind nestedAccess nestedName nestedSeed
+               where nestedAccess = access P.<> text "." P.<> text (tupleFieldName nestedIndex)
+                     nestedName   = fieldName ++ "_field_" ++ show nestedIndex
+
+       collectionAssignment fieldKind access fieldName fieldSeed =
+         [ valueDriverInit cfg renderValue initializeValue fieldKind fieldName fieldSeed
+         , access <+> text "=" <+> managedValueClone fieldKind (text fieldName) P.<> semi
+         , valueDriverClear cfg fieldKind fieldName
+         ]
+
+       exactAssignment fieldKind access value = gmpDriverAssign fieldKind access (integer value)
+valueDriverInit cfg renderValue initializeValue kind@(KList elementKind)   externalName seed
+  | valueDriverNeedsInitialization cfg kind
+  = collectionDriverInit cfg renderValue initializeValue kind elementKind externalName seed False
+valueDriverInit cfg renderValue initializeValue kind@(KSet elementKind)    externalName seed
+  | valueDriverNeedsInitialization cfg kind
+  = collectionDriverInit cfg renderValue initializeValue kind elementKind externalName seed (odd seed)
+valueDriverInit _   _           initializeValue kind@KArray{}              externalName seed
+  = initializeValue kind externalName seed
+valueDriverInit _   _           initializeValue kind                       externalName seed
+  | isConcreteADTReference kind
+  = initializeValue kind externalName seed
+valueDriverInit _   renderValue _               kind                       externalName seed
+  = text "const" <+> text (elementCType kind) <+> text externalName <+> text "=" <+> renderValue kind seed P.<> semi
+
+-- | Release storage created by 'valueDriverInit'. Borrowed scalar and string
+-- literals require no cleanup. Collections use the same initialization test
+-- as construction, so cleanup names only separately declared element variables.
+valueDriverClear :: CgConfig -> Kind -> String -> Doc
+valueDriverClear cfg kind externalName
+  | isExactGMPKind cfg kind
+  = gmpDriverClear kind (text externalName)
+valueDriverClear cfg kind@KTuple{} externalName
+  | valueNeedsOwnership cfg kind
+  = managedValueRelease kind (text "&" P.<> text externalName)
+valueDriverClear _   kind                externalName
+  | isConcreteADTReference kind
+  = managedValueRelease kind (text "&" P.<> text externalName)
+valueDriverClear _   kind@KArray{}       externalName
+  = managedValueRelease kind (text "&" P.<> text externalName)
+valueDriverClear cfg kind@(KList elementKind) externalName
+  | valueDriverNeedsInitialization cfg kind
+  = vcat [valueDriverClear cfg elementKind (collectionElementName externalName index) | index <- [0 :: Int .. collectionElementCount - 1]]
+valueDriverClear cfg kind@(KSet elementKind) externalName
+  | valueDriverNeedsInitialization cfg kind
+  = vcat [valueDriverClear cfg elementKind (collectionElementName externalName index) | index <- [0 :: Int .. collectionElementCount - 1]]
+valueDriverClear _   _                   _            = empty
+
+-- | Declare a deterministic borrowed list or set descriptor and its elements.
+collectionDriverInit :: CgConfig -> (Kind -> Integer -> Doc) -> (Kind -> String -> Integer -> Doc) -> Kind -> Kind -> String -> Integer -> Bool -> Doc
+collectionDriverInit cfg renderValue initializeValue kind elementKind externalName seed isComplemented
+  =  vcat (zipWith initializeElement elementNames [seed ..])
+  $$ text (constElementCType elementKind) <+> text dataName P.<> brackets (int collectionElementCount)
+       <+> text "=" <+> braces (fsep (punctuate comma (map text elementNames))) P.<> semi
+  $$ text "const" <+> text (elementCType kind) <+> text externalName <+> text "="
+       <+> braces (fsep (punctuate comma descriptorFields)) P.<> semi
+ where elementNames     = [collectionElementName externalName index | index <- [0 :: Int .. collectionElementCount - 1]]
+       dataName         = externalName ++ "_data"
+       descriptorFields = [text dataName, int collectionElementCount]
+                       ++ case kind of
+                            KSet{} -> [text (if isComplemented then "true" else "false")]
+                            _      -> []
+
+       initializeElement = valueDriverInit cfg renderValue initializeValue elementKind
+
+-- | Return the generated name of one deterministic collection element.
+collectionElementName :: String -> Int -> String
+collectionElementName externalName index = externalName ++ "_element_" ++ show index
+
+-- | Number of elements placed in each deterministic example collection.
+collectionElementCount :: Int
+collectionElementCount = 3
+
+-- | Extract the fields of a tuple kind.
+tupleFields :: Kind -> [Kind]
+tupleFields (KTuple fields) = fields
+tupleFields kind            = error $ "SBV->C: Expected a tuple kind, received " ++ show kind
+
+-- | Render a C helper call.
+call :: String -> [Doc] -> Doc
+call functionName arguments = text functionName P.<> parens (fsep (punctuate comma arguments))
diff --git a/Data/SBV/Compilers/CodeGen.hs b/Data/SBV/Compilers/CodeGen.hs
--- a/Data/SBV/Compilers/CodeGen.hs
+++ b/Data/SBV/Compilers/CodeGen.hs
@@ -9,9 +9,8 @@
 -- Code generation utilities
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE CPP                        #-}
-{-# LANGUAGE FlexibleInstances          #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE PatternSynonyms           #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -30,12 +29,14 @@
         , svCgReturn, svCgReturnArr
 
         -- * Settings
-        , cgPerformRTCs, cgSetDriverValues
+        , cgPerformRTCs, cgSetDriverValues, cgArrayEqualityLimit, cgRegexLimits
+        , CgRegexLimits(..), defaultCgRegexLimits, cgSetRegexLimits
         , cgAddPrototype, cgAddDecl, cgAddLDFlags, cgIgnoreSAssert, cgOverwriteFiles, cgShowU8UsingHex
         , cgIntegerSize, cgSRealType, CgSRealType(..)
 
         -- * Infrastructure
-        , CgTarget(..), CgConfig(..), CgState(..), CgPgmBundle(..), CgPgmKind(..), CgVal(..)
+        , CgTarget(..), CgConfig(..), CgState(..), CgPgmBundle(..)
+        , CgPgmKind(CgMakefile, CgHeader, CgCHeader, CgSource, CgDriver), CgCHeader(..), CgVal(..)
         , defaultCgConfig, initCgState, isCgDriver, isCgMakefile
 
         -- * Generating collateral
@@ -55,14 +56,10 @@
 import qualified Text.PrettyPrint.HughesPJ as P (render)
 
 import Data.SBV.Core.Data
-import Data.SBV.Core.Symbolic (MonadSymbolic(..), svToSymSV, svMkSymVar, outputSVal, VarContext(..))
+import Data.SBV.Core.Symbolic (MonadSymbolic(..), addNewSMTOption, imposeConstraint, newInternalVariable, outputSVal, svMkSymVar, svToSymSV, VarContext(..))
 
 import Data.SBV.Provers.Prover(defaultSMTCfg)
 
-#if MIN_VERSION_base(4,11,0)
-import Control.Monad.Fail as Fail
-#endif
-
 -- | Abstract over code generation for different languages
 class CgTarget a where
   targetName :: a -> String
@@ -70,29 +67,39 @@
 
 -- | Options for code-generation.
 data CgConfig = CgConfig {
-          cgRTC                :: Bool               -- ^ If 'True', perform run-time-checks for index-out-of-bounds or shifting-by-large values etc.
-        , cgInteger            :: Maybe Int          -- ^ Bit-size to use for representing SInteger (if any)
-        , cgReal               :: Maybe CgSRealType  -- ^ Type to use for representing SReal (if any)
-        , cgDriverVals         :: [Integer]          -- ^ Values to use for the driver program generated, useful for generating non-random drivers.
-        , cgGenDriver          :: Bool               -- ^ If 'True', will generate a driver program
-        , cgGenMakefile        :: Bool               -- ^ If 'True', will generate a makefile
-        , cgIgnoreAsserts      :: Bool               -- ^ If 'True', will ignore 'Data.SBV.sAssert' calls
-        , cgOverwriteGenerated :: Bool               -- ^ If 'True', will overwrite the generated files without prompting.
-        , cgShowU8InHex        :: Bool               -- ^ If 'True', then 8-bit unsigned values will be shown in hex as well, otherwise decimal. (Other types always shown in hex.)
+          cgRTC                  :: Bool              -- ^ If 'True', check finite table indices and select the supplied default when out of bounds.
+        , cgInteger              :: Maybe Int         -- ^ Optional lossy bit-size for representing SInteger; 'Nothing' selects exact GMP integers
+        , cgReal                 :: Maybe CgSRealType -- ^ Optional lossy representation for SReal; 'Nothing' selects exact GMP rationals
+        , cgDriverVals           :: [Integer]         -- ^ Values to use for the driver program generated, useful for generating non-random drivers.
+        , cgGenDriver            :: Bool              -- ^ If 'True', will generate a driver program
+        , cgGenMakefile          :: Bool              -- ^ If 'True', will generate a makefile
+        , cgIgnoreAsserts        :: Bool              -- ^ If 'True', will ignore 'Data.SBV.sAssert' calls
+        , cgOverwriteGenerated   :: Bool              -- ^ If 'True', will overwrite the generated files without prompting.
+        , cgShowU8InHex          :: Bool              -- ^ If 'True', then 8-bit unsigned values will be shown in hex as well, otherwise decimal. (Other types always shown in hex.)
+        , cgArrayEqualityMaxKeys :: Integer           -- ^ Maximum key-domain size for exhaustive array equality in the current C backend.
+        , cgRegexMaxStates       :: Integer           -- ^ Maximum states explored per regex membership or language comparison.
+        , cgRegexMaxNodes        :: Integer           -- ^ Maximum nodes in a regex expression, including intermediate derivatives.
+        , cgRegexMaxWork         :: Integer           -- ^ Maximum charged generation work per regex operation; not a runtime input bound.
         }
 
--- | Default options for code generation. The run-time checks are turned-off, and the driver values are completely random.
+-- | Default options for code generation. Run-time checks are disabled, driver
+-- values are random, and any 'SInteger' or rational 'SReal' values use exact
+-- GMP representations.
 defaultCgConfig :: CgConfig
-defaultCgConfig = CgConfig { cgRTC                = False
-                           , cgInteger            = Nothing
-                           , cgReal               = Nothing
-                           , cgDriverVals         = []
-                           , cgGenDriver          = True
-                           , cgGenMakefile        = True
-                           , cgIgnoreAsserts      = False
-                           , cgOverwriteGenerated = False
-                           , cgShowU8InHex        = False
-                           }
+defaultCgConfig = CgConfig { cgRTC                  = False
+                          , cgInteger              = Nothing
+                          , cgReal                 = Nothing
+                          , cgDriverVals           = []
+                          , cgGenDriver            = True
+                          , cgGenMakefile          = True
+                          , cgIgnoreAsserts        = False
+                          , cgOverwriteGenerated   = False
+                          , cgShowU8InHex          = False
+                          , cgArrayEqualityMaxKeys = 256
+                          , cgRegexMaxStates       = 1024
+                          , cgRegexMaxNodes        = 4096
+                          , cgRegexMaxWork         = 16000000
+                          }
 
 -- | Abstraction of target language values
 data CgVal = CgAtomic SV
@@ -127,23 +134,111 @@
 newtype SBVCodeGen a = SBVCodeGen (StateT CgState Symbolic a)
                    deriving ( Applicative, Functor, Monad, MonadIO, MonadState CgState
                             , MonadSymbolic
-#if MIN_VERSION_base(4,11,0)
-                            , Fail.MonadFail
-#endif
+                            , MonadFail
                             )
 
+-- | Code-generation computations support hard symbolic constraints. Target
+-- backends decide which constraint variants have executable semantics.
+instance SolverContext SBVCodeGen where
+  constrain                    = imposeConstraint False []             . unSBV . quantifiedBool
+  softConstrain                = imposeConstraint True  []             . unSBV . quantifiedBool
+  namedConstraint        nm   = imposeConstraint False [(":named", nm)] . unSBV . quantifiedBool
+  constrainWithAttribute attrs = imposeConstraint False attrs          . unSBV . quantifiedBool
+
+  contextState = symbolicEnv
+  setOption    = addNewSMTOption
+
+  internalVariable kind = do
+    state <- contextState
+    sv    <- liftIO $ newInternalVariable state kind
+    pure $ SBV $ SVal kind $ Right $ cache $ const $ pure sv
+
 -- | Reach into symbolic monad from code-generation
 cgSym :: Symbolic a -> SBVCodeGen a
 cgSym = SBVCodeGen . lift
 
--- | Sets RTC (run-time-checks) for index-out-of-bounds, shift-with-large value etc. on/off. Default: 'False'.
+-- | Enable bounds checks for finite table selection. Out-of-range indices
+-- select the supplied default. With checks disabled (the default), callers
+-- must guarantee in-range indices. This setting does not disable assertions,
+-- executable constraints, ownership checks, or exact bit-vector shift
+-- semantics in the current C backend. Wide bit-vector and GMP indices always
+-- retain their bounds check before conversion to a machine index.
 cgPerformRTCs :: Bool -> SBVCodeGen ()
 cgPerformRTCs b = modify' (\s -> s { cgFinalConfig = (cgFinalConfig s) { cgRTC = b } })
 
+-- | Set the maximum number of keys enumerated by an array equality comparison
+-- in the current C backend. The default is 256. Larger or infinite domains
+-- are rejected during generation; equality is never approximated. Zero
+-- disables exhaustive array equality. Negative limits are invalid.
+--
+-- For example, @cgArrayEqualityLimit 65536@ permits comparing arrays indexed
+-- by 'SWord16', at the cost of up to 65,536 lookups in each array per comparison.
+-- The setting also applies inside generated defined functions and array lambdas.
+--
+-- >>> import Data.SBV
+-- >>> import Data.SBV.Internals (compileToC')
+-- >>> :{
+-- let compareArrays = do
+--       cgArrayEqualityLimit 65536
+--       left  <- cgInput "left"  :: SBVCodeGen (SArray Word16 Word8)
+--       right <- cgInput "right" :: SBVCodeGen (SArray Word16 Word8)
+--       cgReturn (left .== right)
+-- :}
+--
+-- >>> (_, _, generated) <- compileToC' "compareArrays" compareArrays
+-- >>> length (show generated) `seq` pure ()
+cgArrayEqualityLimit :: Integer -> SBVCodeGen ()
+cgArrayEqualityLimit limit
+  | limit < 0 = error "SBV.cgArrayEqualityLimit: The limit must be nonnegative."
+  | True      = modify' (\s -> s { cgFinalConfig = (cgFinalConfig s) { cgArrayEqualityMaxKeys = limit } })
+
+-- | Bound dependency-free C regex compilation: maximum explored states,
+-- expression nodes, and generation work, respectively. Defaults are 1024,
+-- 4096, and 16000000. Exceeding a budget fails during generation, never by
+-- approximating the language or limiting runtime input length. Zero disables
+-- regex compilation; negative limits are invalid. Limits apply independently
+-- to each operation, also inside defined functions and library components.
+--
+-- For example, @cgRegexLimits 4096 8192 64000000@ permits larger automata and
+-- intermediate expressions, at the cost of more generation time and memory.
+-- See "Data.SBV.Tools.CodeGen" for an executable generation example.
+cgRegexLimits :: Integer -> Integer -> Integer -> SBVCodeGen ()
+cgRegexLimits states nodes work
+  | any (< 0) [states, nodes, work] = error "SBV.cgRegexLimits: Limits must be nonnegative."
+  | True = modify' (\s -> s { cgFinalConfig = (cgFinalConfig s) { cgRegexMaxStates = states
+                                                              , cgRegexMaxNodes  = nodes
+                                                              , cgRegexMaxWork   = work
+                                                              } })
+
+-- | Named limits for dependency-free regex compilation. Work is a conservative
+-- generation allowance, not a promise that every smaller automaton will fit.
+data CgRegexLimits = CgRegexLimits
+  { regexMaxStates :: Integer -- ^ Maximum explored automaton states.
+  , regexMaxNodes  :: Integer -- ^ Maximum nodes per intermediate expression.
+  , regexMaxWork   :: Integer -- ^ Maximum charged construction work.
+  } deriving (Eq, Show)
+
+-- | The default regex budgets, suitable for record updates.
+defaultCgRegexLimits :: CgRegexLimits
+defaultCgRegexLimits = CgRegexLimits (cgRegexMaxStates defaultCgConfig)
+                                    (cgRegexMaxNodes defaultCgConfig)
+                                    (cgRegexMaxWork defaultCgConfig)
+
+-- | Configure regex budgets using named fields. The positional 'cgRegexLimits'
+-- remains available for compatibility.
+--
+-- >>> let larger = defaultCgRegexLimits { regexMaxStates = 4096, regexMaxWork = 64000000 }
+-- >>> regexMaxNodes larger == regexMaxNodes defaultCgRegexLimits
+-- True
+cgSetRegexLimits :: CgRegexLimits -> SBVCodeGen ()
+cgSetRegexLimits limits = cgRegexLimits (regexMaxStates limits) (regexMaxNodes limits) (regexMaxWork limits)
+
 -- | Sets number of bits to be used for representing the 'SInteger' type in the generated C code.
 -- The argument must be one of @8@, @16@, @32@, or @64@. Note that this is essentially unsafe as
 -- the semantics of unbounded Haskell integers becomes reduced to the corresponding bit size, as
--- typical in most C implementations.
+-- typical in most C implementations. Without this setting, generated C uses
+-- exact GMP integers in the current backend. The Legacy backend instead rejects
+-- SInteger programs unless this mapping is specified.
 cgIntegerSize :: Int -> SBVCodeGen ()
 cgIntegerSize i
   | i `notElem` [8, 16, 32, 64]
@@ -170,7 +265,9 @@
 -- The setting can be one of C's @"float"@, @"double"@, or @"long double"@, types, depending
 -- on the precision needed. Note that this is essentially unsafe as the semantics of
 -- infinite precision SReal values becomes reduced to the corresponding floating point type in
--- C, and hence it is subject to rounding errors.
+-- C, and hence it is subject to rounding errors. Without this setting,
+-- generated C uses exact GMP rationals for rational-valued computations in the
+-- current backend. The Legacy backend requires an explicit mapping instead.
 cgSRealType :: CgSRealType -> SBVCodeGen ()
 cgSRealType rt = modify' (\s -> s {cgFinalConfig = (cgFinalConfig s) { cgReal = Just rt }})
 
@@ -209,6 +306,9 @@
 
 
 -- | Adds the given lines to the program file generated, useful for generating programs with uninterpreted functions.
+-- External implementations must represent pure mathematical functions: their
+-- results must depend only on their arguments, with no observable side effects.
+-- The compiler may eliminate unused calls or share equal applications.
 cgAddDecl :: [String] -> SBVCodeGen ()
 cgAddDecl ss = modify' (\s -> s { cgDecls = cgDecls s ++ ss })
 
@@ -221,7 +321,7 @@
 svCgInput k nm = do r  <- symbolicEnv >>= liftIO . svMkSymVar (NonQueryVar (Just ALL)) k Nothing
                     sv <- svToSymSV r
                     modify' (\s -> s { cgInputs = (nm, CgAtomic sv) : cgInputs s })
-                    return r
+                    pure r
 
 -- | Creates an array input in the generated code.
 svCgInputArr :: Kind -> Int -> String -> SBVCodeGen [SVal]
@@ -230,7 +330,7 @@
   | True   = do rs  <- symbolicEnv >>= liftIO . replicateM sz . svMkSymVar (NonQueryVar (Just ALL)) k Nothing
                 sws <- mapM svToSymSV rs
                 modify' (\s -> s { cgInputs = (nm, CgArray sws) : cgInputs s })
-                return rs
+                pure rs
 
 -- | Creates an atomic output in the generated code.
 svCgOutput :: String -> SVal -> SBVCodeGen ()
@@ -267,7 +367,7 @@
 cgInput nm = do r  <- free_
                 sv <- sbvToSymSV r
                 modify' (\s -> s { cgInputs = (nm, CgAtomic sv) : cgInputs s })
-                return r
+                pure r
 
 -- | Creates an array input in the generated code.
 cgInputArr :: SymVal a => Int -> String -> SBVCodeGen [SBV a]
@@ -276,7 +376,7 @@
   | True   = do rs <- mapM (const free_) [1..sz]
                 sws <- mapM sbvToSymSV rs
                 modify' (\s -> s { cgInputs = (nm, CgArray sws) : cgInputs s })
-                return rs
+                pure rs
 
 -- | Creates an atomic output in the generated code.
 cgOutput :: String -> SBV a -> SBVCodeGen ()
@@ -313,10 +413,34 @@
 
 -- | Different kinds of "files" we can produce. Currently this is quite "C" specific.
 data CgPgmKind = CgMakefile [String]  -- list of flags to pass to linker
-               | CgHeader [Doc]
+               | CgHeaderInternal [Doc] (Maybe CgCHeader)
                | CgSource
                | CgDriver
 
+-- | Header signatures, as exposed by the original bundle interface. Matches
+-- headers from both backends; construction produces a header without private
+-- merge metadata. Existing four-way matches on 'CgPgmKind' remain exhaustive.
+pattern CgHeader :: [Doc] -> CgPgmKind
+pattern CgHeader signatures <- CgHeaderInternal signatures _
+  where CgHeader signatures = CgHeaderInternal signatures Nothing
+
+-- | Structured metadata for current-backend header merging. This is a more
+-- specific view of 'CgHeader', not an additional kind of generated file.
+pattern CgCHeader :: CgCHeader -> CgPgmKind
+pattern CgCHeader metadata <- CgHeaderInternal _ (Just metadata)
+  where CgCHeader metadata = CgHeaderInternal (cgHeaderSignatures metadata) (Just metadata)
+
+{-# COMPLETE CgMakefile, CgHeader, CgSource, CgDriver #-}
+
+-- | Structured C header metadata used when combining current-backend bundles.
+-- 'CgHeader' provides the compatibility view for both backends.
+data CgCHeader = CgCHeaderInfo
+  { cgHeaderFloating   :: Bool  -- ^ Requires IEEE floating-point compilation.
+  , cgHeaderTypes      :: Doc   -- ^ Runtime type declarations.
+  , cgHeaderSignatures :: [Doc] -- ^ Public entry points.
+  , cgHeaderPrototypes :: Doc   -- ^ User-supplied prototypes.
+  }
+
 -- | Is this a driver program?
 isCgDriver :: CgPgmKind -> Bool
 isCgDriver CgDriver = True
@@ -342,13 +466,14 @@
    ((retVal, st'), res) <- runSymbolic defaultSMTCfg CodeGen $ runStateT comp initCgState { cgFinalConfig = cgConfig }
    let st = st' { cgInputs  = reverse (cgInputs st')
                 , cgOutputs = reverse (cgOutputs st')
+                , cgReturns = reverse (cgReturns st')
                 }
        allNamedVars = map fst (cgInputs st ++ cgOutputs st)
        dupNames = allNamedVars \\ nub allNamedVars
    unless (null dupNames) $
         error $ "SBV.codeGen: " ++ show nm ++ " has following argument names duplicated: " ++ unwords dupNames
 
-   return (retVal, cgFinalConfig st, translate l (cgFinalConfig st) nm st res)
+   pure (retVal, cgFinalConfig st, translate l (cgFinalConfig st) nm st res)
 
 -- | Render a code-gen bundle to a directory or to stdout
 renderCgPgmBundle :: Maybe FilePath -> (CgConfig, CgPgmBundle) -> IO ()
@@ -362,14 +487,14 @@
         dups <- filterM (\fn -> doesFileExist (dirName </> fn)) (map fst files)
 
         goOn <- case (overWrite, dups) of
-                  (True, _) -> return True
-                  (_,   []) -> return True
+                  (True, _) -> pure True
+                  (_,   []) -> pure True
                   _         -> do putStrLn $ "Code generation would overwrite the following " ++ (if length dups == 1 then "file:" else "files:")
                                   mapM_ (\fn -> putStrLn ('\t' : fn)) dups
                                   putStr "Continue? [yn] "
                                   hFlush stdout
                                   resp <- getLine
-                                  return $ map toLower resp `isPrefixOf` "yes"
+                                  pure $ map toLower resp `isPrefixOf` "yes"
 
         if goOn then do mapM_ renderFile files
                         unless overWrite $ putStrLn "Done."
diff --git a/Data/SBV/Control.hs b/Data/SBV/Control.hs
--- a/Data/SBV/Control.hs
+++ b/Data/SBV/Control.hs
@@ -22,7 +22,7 @@
 
      -- * Querying the solver
      -- ** Extracting values
-     , getFunction, getUninterpretedValue, getModel, getAssignment, getSMTResult, getUnknownReason, getObservables
+     , getFunction, getModel, getAssignment, getSMTResult, getUnknownReason, getObservables
 
      -- ** Extracting the unsat core
      , getUnsatCore
diff --git a/Data/SBV/Control/BaseIO.hs b/Data/SBV/Control/BaseIO.hs
--- a/Data/SBV/Control/BaseIO.hs
+++ b/Data/SBV/Control/BaseIO.hs
@@ -11,8 +11,6 @@
 -- @Data.SBV.Control@, where we restrict the underlying monad to be IO.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE FlexibleContexts #-}
-
 {-# OPTIONS_GHC -Wall -Werror #-}
 
 module Data.SBV.Control.BaseIO where
@@ -20,9 +18,11 @@
 import Data.SBV.Control.Query (Assignment)
 import Data.SBV.Control.Types (CheckSatResult, SMTInfoFlag, SMTInfoResponse, SMTOption, SMTReasonUnknown)
 import Data.SBV.Core.Concrete (CV)
-import Data.SBV.Core.Data     (HasKind, Symbolic, SymVal, SBool, SBV, SBVType)
+import Data.SBV.Core.Data     (Symbolic, SymVal, SBool, SBV, SBVType)
 import Data.SBV.Core.Symbolic (Query, QueryContext, QueryState, State, SMTModel, SMTResult, SV, Name)
 
+import Data.Text (Text)
+
 import qualified Data.SBV.Control.Query as Trans
 import qualified Data.SBV.Control.Utils as Trans
 
@@ -240,7 +240,7 @@
 -- for this call to not error out!
 --
 -- To get an interpolant for a pair of formulas @A@ and @B@, use a 'Data.SBV.constrainWithAttribute' call to attach
--- interplation groups to @A@ and @B@. Then call 'getInterpolantMathSAT' @[\"A\"]@, assuming those are the names
+-- interpolation groups to @A@ and @B@. Then call 'getInterpolantMathSAT' @[\"A\"]@, assuming those are the names
 -- you gave to the formulas in the @A@ group.
 --
 -- An interpolant for @A@ and @B@ is a formula @I@ such that:
@@ -403,20 +403,20 @@
 -- file redirection is given, the output will go to the file.
 --
 -- NB. For a version which generalizes over the underlying monad, see 'Data.SBV.Trans.Control.queryDebug'
-queryDebug :: [String] -> Query ()
+queryDebug :: [Text] -> Query ()
 queryDebug = Trans.queryDebug
 
 -- | Send a string to the solver, and return the response
 --
 -- NB. For a version which generalizes over the underlying monad, see 'Data.SBV.Trans.Control.ask'
-ask :: String -> Query String
+ask :: Text -> Query String
 ask = Trans.ask
 
 -- | Send a string to the solver. If the first argument is 'True', we will require
 -- a "success" response as well. Otherwise, we'll fire and forget.
 --
 -- NB. For a version which generalizes over the underlying monad, see 'Data.SBV.Trans.Control.send'
-send :: Bool -> String -> Query ()
+send :: Bool -> Text -> Query ()
 send = Trans.send
 
 -- | Retrieve a responses from the solver until it produces a synchronization tag. We make the tag
@@ -436,17 +436,17 @@
 getValue :: SymVal a => SBV a -> Query a
 getValue = Trans.getValue
 
--- | Get the value of an uninterpreted sort, as a String
---
--- NB. For a version which generalizes over the underlying monad, see 'Data.SBV.Trans.Control.getUninterpretedValue'
-getUninterpretedValue :: HasKind a => SBV a -> Query String
-getUninterpretedValue = Trans.getUninterpretedValue
-
 -- | Get the value of an uninterpreted function, as a list of domain, value pairs.
 -- The final value is the "else" clause, i.e., what the function maps values outside
 -- of the domain of the first list. If the result is not a value-association, then we get a string
 -- representation and the triple of whether it's curried, the argument list given by the user, and the s-expression as parsed
 -- by SBV from the SMT solver.
+--
+-- The function must already be declared when satisfiability is checked. If it
+-- does not occur in any constraints, call 'Data.SBV.registerFunction' before
+-- entering the query, then 'ensureSat' before retrieving its interpretation.
+-- An unregistered function is an error; this call never changes solver state
+-- or reruns the satisfiability check.
 getFunction :: (SymVal a, SymVal r, Trans.SMTFunction fun a r) => fun -> Query (Either (String, (Bool, Maybe [String], SExpr)) ([(a, r)], r))
 getFunction = Trans.getFunction
 
@@ -514,7 +514,7 @@
 -- | Bail out if we don't get what we expected
 --
 -- NB. For a version which generalizes over the underlying monad, see 'Data.SBV.Trans.Control.unexpected'
-unexpected :: String -> String -> String -> Maybe [String] -> String -> Maybe [String] -> Query a
+unexpected :: String -> Text -> String -> Maybe [String] -> String -> Maybe [String] -> Query a
 unexpected = Trans.unexpected
 
 -- | Execute a query.
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
@@ -9,22 +9,19 @@
 -- Querying a solver interactively.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE BangPatterns        #-}
 {-# LANGUAGE LambdaCase          #-}
 {-# LANGUAGE NamedFieldPuns      #-}
-{-# LANGUAGE Rank2Types          #-}
+{-# LANGUAGE OverloadedStrings   #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TupleSections       #-}
-{-# LANGUAGE ViewPatterns        #-}
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
 module Data.SBV.Control.Query (
        send, ask, retrieveResponse
      , CheckSatResult(..), checkSat, checkSatUsing, checkSatAssuming, checkSatAssumingWithUnsatisfiableSet
      , getUnsatCore, getProof, getInterpolantMathSAT, getInterpolantZ3, getAbduct, getAbductNext, getAssignment, getOption
      , push, pop, getAssertionStackDepth
-     , inNewAssertionStack, echo, caseSplit, resetAssertions, exit, getAssertions, getUninterpretedValue, getModel, getSMTResult
+     , inNewAssertionStack, echo, caseSplit, resetAssertions, exit, getAssertions, getModel, getSMTResult
      , getLexicographicOptResults, getIndependentOptResults, getParetoOptResults, getAllSatResult, getUnknownReason, getObservables, ensureSat
      , SMTOption(..), SMTInfoFlag(..), SMTErrorBehavior(..), SMTReasonUnknown(..), SMTInfoResponse(..), getInfo
      , Logic(..), Assignment(..)
@@ -40,44 +37,30 @@
 import Data.IORef (readIORef)
 
 import qualified Data.Map.Strict as M
-import qualified Data.Sequence   as S
 import qualified Data.Text       as T
 import qualified Data.Foldable   as F
 
 
 import Data.Char      (toLower)
-import Data.List      (intercalate, nubBy, sortOn)
-import Data.Maybe     (listToMaybe, catMaybes, fromMaybe)
+import Data.List      (intercalate, nubBy)
+import Data.Maybe     (fromMaybe)
 import Data.Function  (on)
-import Data.Bifunctor (first)
-import Data.Foldable  (toList)
 
 import Data.SBV.Core.Data
 
-import Data.SBV.Core.Symbolic (MonadQuery(..), State(..), incrementInternalCounter, validationRequested, getSV, lookupInput, mustIgnoreVar)
+import Data.SBV.Core.Symbolic (MonadQuery(..), State(..), incrementInternalCounter, getSV)
 
 import Data.SBV.Utils.SExpr
 
 import Data.SBV.Control.Types
 import Data.SBV.Control.Utils
 
-import Data.SBV.Utils.Lib       (unBar)
+import Data.SBV.Utils.Lib       (showText, unBar)
 import Data.SBV.Utils.PrettyNum (showNegativeNumber)
 
 -- | An Assignment of a model binding
 data Assignment = Assign SVal CV
 
--- | Remove the bars from model names; these are (mostly!) automatically inserted
-unBarModel :: SMTModel -> SMTModel
-unBarModel SMTModel {modelObjectives, modelBindings, modelAssocs, modelUIFuns}
-   = SMTModel { modelObjectives = ubf       <$> modelObjectives
-              , modelBindings   = (ubn <$>) <$> modelBindings
-              , modelAssocs     = ubf       <$> modelAssocs
-              , modelUIFuns     = ubf       <$> modelUIFuns
-              }
-   where ubf (n, a) = (unBar n, a)
-         ubn (NamedSymVar sv nm, a) = (NamedSymVar sv (T.pack (unBar (T.unpack nm))), a)
-
 -- Is this a string? If so, return it, otherwise fail in the Maybe monad.
 fromECon :: SExpr -> Maybe String
 fromECon (ECon s) = Just s
@@ -86,7 +69,7 @@
 -- Collect strings appearing, used in 'getOption' only
 stringsOf :: SExpr -> [String]
 stringsOf (ECon s)           = [s]
-stringsOf (ENum (i, _))      = [show i]
+stringsOf (ENum (i, _, _))   = [show i]
 stringsOf (EReal   r)        = [show r]
 stringsOf (EFloat  f)        = [show f]
 stringsOf (EFloatingPoint f) = [show f]
@@ -97,10 +80,10 @@
 serialize :: Bool -> SExpr -> String
 serialize removeQuotes = go
   where go (ECon s)           = if removeQuotes then unQuote s else s
-        go (ENum (i, _))      = showNegativeNumber i
-        go (EReal   r)        = showNegativeNumber r
-        go (EFloat  f)        = showNegativeNumber f
-        go (EDouble d)        = showNegativeNumber d
+        go (ENum (i, _, _))   = T.unpack (showNegativeNumber i)
+        go (EReal   r)        = T.unpack (showNegativeNumber r)
+        go (EFloat  f)        = T.unpack (showNegativeNumber f)
+        go (EDouble d)        = T.unpack (showNegativeNumber d)
         go (EFloatingPoint f) = show f
         go (EApp [x])         = go x
         go (EApp ss)          = "(" ++ unwords (map go ss) ++ ")"
@@ -108,7 +91,7 @@
 -- | Generalization of 'Data.SBV.Control.getInfo'
 getInfo :: (MonadIO m, MonadQuery m) => SMTInfoFlag -> m SMTInfoResponse
 getInfo flag = do
-    let cmd = "(get-info " ++ show flag ++ ")"
+    let cmd = "(get-info " <> showText flag <> ")"
         bad = unexpected "getInfo" cmd "a valid get-info response" Nothing
 
         isAllStatistics AllStatistics = True
@@ -130,17 +113,17 @@
 
     parse r bad $ \pe ->
        if isAllStat
-          then return $ Resp_AllStatistics $ grabAllStats pe
+          then pure $ Resp_AllStatistics $ grabAllStats pe
           else case pe of
-                 ECon "unsupported"                                        -> return Resp_Unsupported
-                 EApp [ECon ":assertion-stack-levels", ENum (i, _)]        -> return $ Resp_AssertionStackLevels i
-                 EApp (ECon ":authors" : ns)                               -> return $ Resp_Authors (map render ns)
-                 EApp [ECon ":error-behavior", ECon "immediate-exit"]      -> return $ Resp_Error ErrorImmediateExit
-                 EApp [ECon ":error-behavior", ECon "continued-execution"] -> return $ Resp_Error ErrorContinuedExecution
-                 EApp (ECon ":name" : o)                                   -> return $ Resp_Name (render (EApp o))
-                 EApp (ECon ":reason-unknown" : o)                         -> return $ Resp_ReasonUnknown (unk o)
-                 EApp (ECon ":version" : o)                                -> return $ Resp_Version (render (EApp o))
-                 EApp (ECon s : o)                                         -> return $ Resp_InfoKeyword s (map render o)
+                 ECon "unsupported"                                        -> pure Resp_Unsupported
+                 EApp [ECon ":assertion-stack-levels", ENum (i, _, _)]     -> pure $ Resp_AssertionStackLevels i
+                 EApp (ECon ":authors" : ns)                               -> pure $ Resp_Authors (map render ns)
+                 EApp [ECon ":error-behavior", ECon "immediate-exit"]      -> pure $ Resp_Error ErrorImmediateExit
+                 EApp [ECon ":error-behavior", ECon "continued-execution"] -> pure $ Resp_Error ErrorContinuedExecution
+                 EApp (ECon ":name" : o)                                   -> pure $ Resp_Name (render (EApp o))
+                 EApp (ECon ":reason-unknown" : o)                         -> pure $ Resp_ReasonUnknown (unk o)
+                 EApp (ECon ":version" : o)                                -> pure $ Resp_Version (render (EApp o))
+                 EApp (ECon s : o)                                         -> pure $ Resp_InfoKeyword s (map render o)
                  _                                                         -> bad r Nothing
 
   where render = serialize True
@@ -178,33 +161,33 @@
                  SetInfo{}                   -> error "Data.SBV.Query: SMTLib does not allow querying value of meta-info!"
 
   where askFor sbvName smtLibName continue = do
-                let cmd = "(get-option " ++ smtLibName ++ ")"
+                let cmd = "(get-option " <> T.pack smtLibName <> ")"
                     bad = unexpected ("getOption " ++ sbvName) cmd "a valid option value" Nothing
 
                 r <- ask cmd
 
-                parse r bad $ \case ECon "unsupported" -> return Nothing
+                parse r bad $ \case ECon "unsupported" -> pure Nothing
                                     e                  -> continue e (bad r)
 
-        string c (ECon s) _ = return $ Just $ c s
+        string c (ECon s) _ = pure $ Just $ c s
         string _ e        k = k $ Just ["Expected string, but got: " ++ show (serialize False e)]
 
-        bool c (ENum (0, _)) _ = return $ Just $ c False
-        bool c (ENum (1, _)) _ = return $ Just $ c True
-        bool _ e             k = k $ Just ["Expected boolean, but got: " ++ show (serialize False e)]
+        bool c (ENum (0, _, True)) _ = pure $ Just $ c False
+        bool c (ENum (1, _, True)) _ = pure $ Just $ c True
+        bool _ e                   k = k $ Just ["Expected boolean, but got: " ++ show (serialize False e)]
 
-        integer c (ENum (i, _)) _ = return $ Just $ c i
-        integer _ e             k = k $ Just ["Expected integer, but got: " ++ show (serialize False e)]
+        integer c (ENum (i, _, _)) _ = pure $ Just $ c i
+        integer _ e                k = k $ Just ["Expected integer, but got: " ++ show (serialize False e)]
 
         -- free format, really
-        stringList c e _ = return $ Just $ c $ stringsOf e
+        stringList c e _ = pure $ Just $ c $ stringsOf e
 
 -- | Generalization of 'Data.SBV.Control.getUnknownReason'
 getUnknownReason :: (MonadIO m, MonadQuery m) => m SMTReasonUnknown
 getUnknownReason = do ru <- getInfo ReasonUnknown
                       case ru of
-                        Resp_Unsupported     -> return $ UnknownOther "Solver responded: Unsupported."
-                        Resp_ReasonUnknown r -> return r
+                        Resp_Unsupported     -> pure $ UnknownOther "Solver responded: Unsupported."
+                        Resp_ReasonUnknown r -> pure r
                         -- Shouldn't happen, but just in case:
                         _                    -> error $ "Unexpected reason value received: " ++ show ru
 
@@ -213,8 +196,8 @@
 ensureSat = do cfg <- getConfig
                cs <- checkSatUsing $ satCmd cfg
                case cs of
-                 Sat    -> return ()
-                 DSat{} -> return ()
+                 Sat    -> pure ()
+                 DSat{} -> pure ()
                  Unk    -> do s <- getUnknownReason
                               error $ unlines [ ""
                                               , "*** Data.SBV.ensureSat: Solver reported Unknown!"
@@ -250,7 +233,7 @@
                                   Unk    -> Unknown       cfg <$> getUnknownReason
    where getModelWithObjectives = do objectiveValues <- getObjectiveValues
                                      m               <- getModel
-                                     return m {modelObjectives = objectiveValues}
+                                     pure m {modelObjectives = objectiveValues}
 
 -- | Generalization of 'Data.SBV.Control.getIndependentOptResults'
 getIndependentOptResults :: forall m. (MonadIO m, MonadQuery m) => [String] -> m [(String, SMTResult)]
@@ -258,163 +241,48 @@
                                        cs  <- checkSat
 
                                        case cs of
-                                         Unsat  -> getUnsatCoreIfRequested >>= \mbUC -> return [(nm, Unsatisfiable cfg mbUC) | nm <- objNames]
+                                         Unsat  -> getUnsatCoreIfRequested >>= \mbUC -> pure [(nm, Unsatisfiable cfg mbUC) | nm <- objNames]
                                          Sat    -> continue (classifyModel cfg)
                                          DSat{} -> continue (classifyModel cfg)
                                          Unk    -> do ur <- Unknown cfg <$> getUnknownReason
-                                                      return [(nm, ur) | nm <- objNames]
+                                                      pure [(nm, ur) | nm <- objNames]
 
   where continue classify = do objectiveValues <- getObjectiveValues
                                nms <- zipWithM getIndependentResult [0..] objNames
-                               return [(n, classify (m {modelObjectives = objectiveValues})) | (n, m) <- nms]
+                               pure [(n, classify (m {modelObjectives = objectiveValues})) | (n, m) <- nms]
 
         getIndependentResult :: Int -> String -> m (String, SMTModel)
         getIndependentResult i s = do m <- getModelAtIndex (Just i)
-                                      return (s, m)
+                                      pure (s, m)
 
 -- | Generalization of 'Data.SBV.Control.getParetoOptResults'
 getParetoOptResults :: (MonadIO m, MonadQuery m) => Maybe Int -> m (Bool, [SMTResult])
 getParetoOptResults (Just i)
-        | i <= 0             = return (True, [])
+        | i <= 0             = pure (True, [])
 getParetoOptResults mbN      = do cfg <- getConfig
                                   cs  <- checkSat
 
                                   case cs of
-                                    Unsat  -> return (False, [])
+                                    Unsat  -> pure (False, [])
                                     Sat    -> continue (classifyModel cfg)
                                     DSat{} -> continue (classifyModel cfg)
                                     Unk    -> do ur <- getUnknownReason
-                                                 return (False, [ProofError cfg [show ur] Nothing])
+                                                 pure (False, [ProofError cfg [show ur] Nothing])
 
   where continue classify = do m <- getModel
                                (limReached, fronts) <- getParetoFronts (subtract 1 <$> mbN) [m]
-                               return (limReached, reverse (map classify fronts))
+                               pure (limReached, reverse (map classify fronts))
 
         getParetoFronts :: (MonadIO m, MonadQuery m) => Maybe Int -> [SMTModel] -> m (Bool, [SMTModel])
-        getParetoFronts (Just i) sofar | i <= 0 = return (True, sofar)
+        getParetoFronts (Just i) sofar | i <= 0 = pure (True, sofar)
         getParetoFronts mbi      sofar          = do cs <- checkSat
                                                      let more = getModel >>= \m -> getParetoFronts (subtract 1 <$> mbi) (m : sofar)
                                                      case cs of
-                                                       Unsat  -> return (False, sofar)
+                                                       Unsat  -> pure (False, sofar)
                                                        Sat    -> more
                                                        DSat{} -> more
                                                        Unk    -> more
 
--- | Generalization of 'Data.SBV.Control.getModel'
-getModel :: (MonadIO m, MonadQuery m) => m SMTModel
-getModel = getModelAtIndex Nothing
-
--- | Get a model stored at an index. This is likely very Z3 specific!
-getModelAtIndex :: (MonadIO m, MonadQuery m) => Maybe Int -> m SMTModel
-getModelAtIndex mbi = do
-    State{runMode} <- queryState
-    rm <- io $ readIORef runMode
-    case rm of
-      m@CodeGen     -> error $ "SBV.getModel: Model is not available in mode: " ++ show m
-      m@LambdaGen{} -> error $ "SBV.getModel: Model is not available in mode: " ++ show m
-      m@Concrete{}  -> error $ "SBV.getModel: Model is not available in mode: " ++ show m
-      SMTMode{}     -> do
-          cfg <- getConfig
-          uis <- getUIs
-
-          allModelInputs <- getTopLevelInputs
-          obsvs          <- getObservables
-
-          inputAssocs <- let grab (NamedSymVar sv nm) = let wrap !c = (sv, (nm, c)) in wrap <$> getValueCV mbi sv
-                         in mapM grab allModelInputs
-
-          let name     = fst . snd
-              removeSV = snd
-              prepare  = S.unstableSort . S.filter (not . mustIgnoreVar cfg . T.unpack . name)
-              assocs   = fmap removeSV (prepare inputAssocs) <> S.fromList (sortOn fst obsvs)
-
-          -- collect UIs, and UI functions if requested
-          let uiFuns = [ui | ui@(nm, (_, _, SBVType as)) <- uis, length as >  1, allSatTrackUFs cfg, not (mustIgnoreVar cfg nm)] -- functions have at least two things in their type!
-              uiRegs = [ui | ui@(nm, (_, _, SBVType as)) <- uis, length as == 1,                     not (mustIgnoreVar cfg nm)]
-
-          -- If there are uninterpreted functions, arrange so that z3's pretty-printer flattens things out
-          -- as cex's tend to get larger
-          unless (null uiFuns) $
-             let solverCaps = capabilities (solver cfg)
-             in case supportsFlattenedModels solverCaps of
-                  Nothing   -> return ()
-                  Just cmds -> mapM_ (send True) cmds
-
-          bindings <- let get i@(getSV -> sv) = case lookupInput fst sv inputAssocs of
-                                                  Just (_, (_, cv)) -> return (i, cv)
-                                                  Nothing           -> do cv <- getValueCV mbi sv
-                                                                          return (i, cv)
-
-                      in if validationRequested cfg
-                         then Just <$> mapM get allModelInputs
-                         else return Nothing
-
-          uiFunVals <- mapM (\ui@(nm, (c, _, t)) -> (\a -> (nm, (c, t, a))) <$> getUIFunCVAssoc mbi ui) uiFuns
-
-          uiVals    <- mapM (\ui@(nm, (_, _, _)) -> (nm,) <$> getUICVal mbi ui) uiRegs
-
-          return $ unBarModel $ SMTModel { modelObjectives = []
-                                         , modelBindings   = toList <$> bindings
-                                         , modelAssocs     = uiVals ++ toList (first T.unpack <$> assocs)
-                                         , modelUIFuns     = uiFunVals
-                                         }
-
--- | Just after a check-sat is issued, collect objective values. Used
--- internally only, not exposed to the user.
-getObjectiveValues :: forall m. (MonadIO m, MonadQuery m) => m [(String, GeneralizedCV)]
-getObjectiveValues = do let cmd = "(get-objectives)"
-
-                            bad = unexpected "getObjectiveValues" cmd "a list of objective values" Nothing
-
-                        r <- ask cmd
-
-                        inputs <- F.toList <$> getTopLevelInputs
-
-                        parse r bad $ \case EApp (ECon "objectives" : es) -> catMaybes <$> mapM (getObjValue (bad r) inputs) es
-                                            _                             -> bad r Nothing
-
-  where -- | Parse an objective value out.
-        getObjValue :: (forall a. Maybe [String] -> m a) -> [NamedSymVar] -> SExpr -> m (Maybe (String, GeneralizedCV))
-        getObjValue bailOut inputs expr =
-                case expr of
-                  EApp [_]          -> return Nothing            -- Happens when a soft-assertion has no associated group.
-                  EApp [ECon nm, v] -> locate nm v               -- Regular case
-                  _                 -> dontUnderstand (show expr)
-
-          where locate nm v = case listToMaybe [p | p@(NamedSymVar sv _) <- inputs, show sv == nm] of
-                                Nothing                          -> return Nothing -- Happens when the soft assertion has a group-id that's not one of the input names
-                                Just (NamedSymVar sv actualName) -> grab sv v >>= \val -> return $ Just (T.unpack actualName, val)
-
-                dontUnderstand s = bailOut $ Just [ "Unable to understand solver output."
-                                                  , "While trying to process: " ++ s
-                                                  ]
-
-                grab :: SV -> SExpr -> m GeneralizedCV
-                grab s topExpr
-                  | Just v <- recoverKindedValue k topExpr = return $ RegularCV v
-                  | True                                   = ExtendedCV <$> cvt (simplify topExpr)
-                  where k = kindOf s
-
-                        -- Convert to an extended expression. Hopefully complete!
-                        cvt :: SExpr -> m ExtCV
-                        cvt (ECon "oo")                    = return $ Infinite  k
-                        cvt (ECon "epsilon")               = return $ Epsilon   k
-                        cvt (EApp [ECon "interval", x, y]) =          Interval  <$> cvt x <*> cvt y
-                        cvt (ENum    (i, _))               = return $ BoundedCV $ mkConstCV k i
-                        cvt (EReal   r)                    = return $ BoundedCV $ CV k $ CAlgReal r
-                        cvt (EFloat  f)                    = return $ BoundedCV $ CV k $ CFloat   f
-                        cvt (EDouble d)                    = return $ BoundedCV $ CV k $ CDouble  d
-                        cvt (EApp [ECon "+", x, y])        =          AddExtCV <$> cvt x <*> cvt y
-                        cvt (EApp [ECon "*", x, y])        =          MulExtCV <$> cvt x <*> cvt y
-                        -- Nothing else should show up, hopefully!
-                        cvt e = dontUnderstand (show e)
-
-                        -- drop the pesky to_real's that Z3 produces.. Cool but useless.
-                        simplify :: SExpr -> SExpr
-                        simplify (EApp [ECon "to_real", n]) = n
-                        simplify (EApp xs)                  = EApp (map simplify xs)
-                        simplify e                          = e
-
 -- | Generalization of 'Data.SBV.Control.checkSatAssuming'
 checkSatAssuming :: (MonadIO m, MonadQuery m) => [SBool] -> m CheckSatResult
 checkSatAssuming sBools = fst <$> checkSatAssumingHelper False sBools
@@ -428,14 +296,14 @@
 checkSatAssumingHelper getAssumptions sBools = do
         -- sigh.. SMT-Lib requires the values to be literals only. So, create proxies.
         let mkAssumption st = do swsOriginal <- mapM (\sb -> do sv <- sbvToSV st sb
-                                                                return (sv, sb)) sBools
+                                                                pure (sv, sb)) sBools
 
                                  -- drop duplicates and trues
                                  let swbs = [p | p@(sv, _) <- nubBy ((==) `on` fst) swsOriginal, sv /= trueSV]
 
                                  -- get a unique proxy name for each
                                  uniqueSWBs <- mapM (\(sv, sb) -> do unique <- incrementInternalCounter st
-                                                                     return (sv, (unique, sb))) swbs
+                                                                     pure (sv, (unique, sb))) swbs
 
                                  let translate (sv, (unique, sb)) = (nm, decls, (proxy, sb))
                                         where nm    = show sv
@@ -444,13 +312,13 @@
                                                       , "(assert (= " ++ proxy ++ " " ++ nm ++ "))"
                                                       ]
 
-                                 return $ map translate uniqueSWBs
+                                 pure $ map translate uniqueSWBs
 
         assumptions <- inNewContext mkAssumption
 
         let (origNames, declss, proxyMap) = unzip3 assumptions
 
-        let cmd = "(check-sat-assuming (" ++ unwords (map fst proxyMap) ++ "))"
+        let cmd = "(check-sat-assuming (" <> T.pack (unwords (map fst proxyMap)) <> "))"
             bad = unexpected "checkSatAssuming" cmd "one of sat/unsat/unknown"
                            $ Just [ "Make sure you use:"
                                   , ""
@@ -459,17 +327,17 @@
                                   , "to tell the solver to produce unsat assumptions."
                                   ]
 
-        mapM_ (send True) $ concat declss
+        mapM_ (send True . T.pack) $ concat declss
         r <- ask cmd
 
         let grabUnsat
              | getAssumptions = do as <- getUnsatAssumptions origNames proxyMap
-                                   return (Unsat, Just as)
-             | True           = return (Unsat, Nothing)
+                                   pure (Unsat, Just as)
+             | True           = pure (Unsat, Nothing)
 
-        parse r bad $ \case ECon "sat"     -> return (Sat, Nothing)
+        parse r bad $ \case ECon "sat"     -> pure (Sat, Nothing)
                             ECon "unsat"   -> grabUnsat
-                            ECon "unknown" -> return (Unk, Nothing)
+                            ECon "unknown" -> pure (Unk, Nothing)
                             _              -> bad r Nothing
 
 -- | Generalization of 'Data.SBV.Control.getAssertionStackDepth'
@@ -485,23 +353,23 @@
                             let inits = [ "table"  ++ show i ++ "_initializer" | i <- [0 .. tCount - 1]]
 
                             case inits of
-                              []  -> return ()   -- Nothing to do
-                              [x] -> send True $ "(assert " ++ x ++ ")"
-                              xs  -> send True $ "(assert (and " ++ unwords xs ++ "))"
+                              []  -> pure ()   -- Nothing to do
+                              [x] -> send True $ "(assert " <> T.pack x <> ")"
+                              xs  -> send True $ "(assert (and " <> T.pack (unwords xs) <> "))"
 
 -- | Generalization of 'Data.SBV.Control.inNewAssertionStack'
 inNewAssertionStack :: (MonadIO m, MonadQuery m) => m a -> m a
 inNewAssertionStack q = do push 1
                            r <- q
                            pop 1
-                           return r
+                           pure r
 
 -- | Generalization of 'Data.SBV.Control.push'
 push :: (MonadIO m, MonadQuery m) => Int -> m ()
 push i
  | i <= 0 = error $ "Data.SBV: push requires a strictly positive level argument, received: " ++ show i
  | True   = do depth <- getAssertionStackDepth
-               send True $ "(push " ++ show i ++ ")"
+               send True $ "(push " <> showText i <> ")"
                modifyQueryState $ \s -> s{queryAssertionStackDepth = depth + i}
 
 -- | Generalization of 'Data.SBV.Control.pop'
@@ -519,7 +387,7 @@
                                                   , "***"
                                                   , "*** Request this as a feature for the underlying solver!"
                                                   ]
-                             else do send True $ "(pop " ++ show i ++ ")"
+                             else do send True $ "(pop " <> showText i <> ")"
                                      restoreTablesAndArrays
                                      modifyQueryState $ \s -> s{queryAssertionStackDepth = depth - i}
    where shl 1 = "one level"
@@ -531,7 +399,7 @@
                                 go cfg (cases ++ [("Coverage", sNot (sOr (map snd cases)))])
   where msg = when printCases . io . putStrLn
 
-        go _ []            = return Nothing
+        go _ []            = pure Nothing
         go cfg ((n,c):ncs) = do let notify s = msg $ "Case " ++ n ++ ": " ++ s
 
                                 notify "Starting"
@@ -543,15 +411,15 @@
 
                                   Sat      -> do notify "Satisfiable"
                                                  res <- Satisfiable cfg <$> getModel
-                                                 return $ Just (n, res)
+                                                 pure $ Just (n, res)
 
                                   DSat mbP -> do notify $ "Delta satisfiable" ++ maybe "" (" (precision: " ++) mbP
                                                  res <- DeltaSat cfg mbP <$> getModel
-                                                 return $ Just (n, res)
+                                                 pure $ Just (n, res)
 
                                   Unk      -> do notify "Unknown"
                                                  res <- Unknown cfg <$> getUnknownReason
-                                                 return $ Just (n, res)
+                                                 pure $ Just (n, res)
 
 -- | Generalization of 'Data.SBV.Control.resetAssertions'
 resetAssertions :: (MonadIO m, MonadQuery m) => m ()
@@ -563,7 +431,7 @@
 
 -- | Generalization of 'Data.SBV.Control.echo'
 echo :: (MonadIO m, MonadQuery m) => String -> m ()
-echo s = do let cmd = "(echo \"" ++ concatMap sanitize s ++ "\")"
+echo s = do let cmd = "(echo \"" <> T.pack (concatMap sanitize s) <> "\")"
 
             -- we send the command, but otherwise ignore the response
             -- note that 'send True/False' would be incorrect here. 'send True' would
@@ -572,7 +440,7 @@
             -- and forgets about it immediately.
             _ <- ask cmd
 
-            return ()
+            pure ()
   where sanitize '"'  = "\"\""  -- quotes need to be duplicated
         sanitize c    = [c]
 
@@ -584,7 +452,7 @@
 -- | Generalization of 'Data.SBV.Control.getUnsatCore'
 getUnsatCore :: (MonadIO m, MonadQuery m) => m [String]
 getUnsatCore = do
-        let cmd = "(get-unsat-core)"
+        let cmd = "(get-unsat-core)" :: T.Text
             bad = unexpected "getUnsatCore" cmd "an unsat-core response"
                            $ Just [ "Make sure you use:"
                                   , ""
@@ -606,7 +474,7 @@
         r <- ask cmd
 
         parse r bad $ \case
-           EApp es | Just xs <- mapM fromECon es -> return $ map unBar xs
+           EApp es | Just xs <- mapM fromECon es -> pure $ map unBar xs
            _                                     -> bad r Nothing
 
 -- | Retrieve the unsat core if it was asked for in the configuration
@@ -615,12 +483,12 @@
         cfg <- getConfig
         if or [b | ProduceUnsatCores b <- solverSetOptions cfg]
            then Just <$> getUnsatCore
-           else return Nothing
+           else pure Nothing
 
 -- | Generalization of 'Data.SBV.Control.getProof'
 getProof :: (MonadIO m, MonadQuery m) => m String
 getProof = do
-        let cmd = "(get-proof)"
+        let cmd = "(get-proof)" :: T.Text
             bad = unexpected "getProof" cmd "a get-proof response"
                            $ Just [ "Make sure you use:"
                                   , ""
@@ -635,7 +503,7 @@
 
         -- we only care about the fact that we can parse the output, so the
         -- result of parsing is ignored.
-        parse r bad $ \_ -> return r
+        parse r bad $ \_ -> pure r
 
 -- | Generalization of 'Data.SBV.Control.getInterpolantMathSAT'. Use this version with MathSAT.
 getInterpolantMathSAT :: (MonadIO m, MonadQuery m) => [String] -> m String
@@ -644,7 +512,7 @@
   = error "SBV.getInterpolantMathSAT requires at least one marked constraint, received none!"
   | True
   = do let bar s = '|' : s ++ "|"
-           cmd = "(get-interpolant (" ++ unwords (map bar fs) ++ "))"
+           cmd = "(get-interpolant (" <> T.pack (unwords (map bar fs)) <> "))"
            bad = unexpected "getInterpolant" cmd "a get-interpolant response"
                           $ Just [ "Make sure you use:"
                                  , ""
@@ -657,29 +525,29 @@
 
        r <- ask cmd
 
-       parse r bad $ \e -> return $ serialize False e
+       parse r bad $ \e -> pure $ serialize False e
 
 
 -- | Generalization of 'Data.SBV.Control.getAbduct'.
 getAbduct :: (SolverContext m, MonadIO m, MonadQuery m) => Maybe String -> String -> SBool -> m String
 getAbduct mbGrammar defName b = do
    s <- inNewContext (`sbvToSV` b)
-   let cmd = "(get-abduct " ++ defName ++ " " ++ show s ++ fromMaybe "" mbGrammar ++ ")"
+   let cmd = "(get-abduct " <> T.pack defName <> " " <> showText s <> T.pack (fromMaybe "" mbGrammar) <> ")"
        bad = unexpected "getAbduct" cmd "a get-abduct response" Nothing
 
    r <- ask cmd
 
-   parse r bad $ \e -> return $ serialize False e
+   parse r bad $ \e -> pure $ serialize False e
 
 -- | Generalization of 'Data.SBV.Control.getAbductNext'.
 getAbductNext :: (MonadIO m, MonadQuery m) => m String
 getAbductNext = do
-   let cmd = "(get-abduct-next)"
+   let cmd = "(get-abduct-next)" :: T.Text
        bad = unexpected "getAbductNext" cmd "a get-abduct-next response" Nothing
 
    r <- ask cmd
 
-   parse r bad $ \e -> return $ serialize False e
+   parse r bad $ \e -> pure $ serialize False e
 
 -- | Generalization of 'Data.SBV.Control.getInterpolantZ3'. Use this version with Z3.
 getInterpolantZ3 :: (MonadIO m, MonadQuery m) => [SBool] -> m String
@@ -687,22 +555,22 @@
   | length fs < 2
   = error $ "SBV.getInterpolantZ3 requires at least two booleans, received: " ++ show fs
   | True
-  = do ss <- let fAll []     sofar = return $ reverse sofar
+  = do ss <- let fAll []     sofar = pure $ reverse sofar
                  fAll (b:bs) sofar = do sv <- inNewContext (`sbvToSV` b)
                                         fAll bs (sv : sofar)
              in fAll fs []
 
-       let cmd = "(get-interpolant " ++ unwords (map show ss) ++ ")"
+       let cmd = "(get-interpolant " <> T.pack (unwords (map show ss)) <> ")"
            bad = unexpected "getInterpolant" cmd "a get-interpolant response" Nothing
 
        r <- ask cmd
 
-       parse r bad $ \e -> return $ serialize False e
+       parse r bad $ \e -> pure $ serialize False e
 
 -- | Generalization of 'Data.SBV.Control.getAssertions'
 getAssertions :: (MonadIO m, MonadQuery m) => m [String]
 getAssertions = do
-        let cmd = "(get-assertions)"
+        let cmd = "(get-assertions)" :: T.Text
             bad = unexpected "getAssertions" cmd "a get-assertions response"
                            $ Just [ "Make sure you use:"
                                   , ""
@@ -716,13 +584,13 @@
         r <- ask cmd
 
         parse r bad $ \pe -> case pe of
-                                EApp xs -> return $ map render xs
-                                _       -> return [render pe]
+                                EApp xs -> pure $ map render xs
+                                _       -> pure [render pe]
 
 -- | Generalization of 'Data.SBV.Control.getAssignment'
 getAssignment :: (MonadIO m, MonadQuery m) => m [(String, Bool)]
 getAssignment = do
-        let cmd = "(get-assignment)"
+        let cmd = "(get-assignment)" :: T.Text
             bad = unexpected "getAssignment" cmd "a get-assignment response"
                            $ Just [ "Make sure you use:"
                                   , ""
@@ -733,13 +601,13 @@
                                   ]
 
             -- we're expecting boolean assignment to labels, essentially
-            grab (EApp [ECon s, ENum (0, _)]) = Just (unQuote s, False)
-            grab (EApp [ECon s, ENum (1, _)]) = Just (unQuote s, True)
-            grab _                            = Nothing
+            grab (EApp [ECon s, ENum (0, _, _)]) = Just (unQuote s, False)
+            grab (EApp [ECon s, ENum (1, _, _)]) = Just (unQuote s, True)
+            grab _                               = Nothing
 
         r <- ask cmd
 
-        parse r bad $ \case EApp ps | Just vs <- mapM grab ps -> return vs
+        parse r bad $ \case EApp ps | Just vs <- mapM grab ps -> pure vs
                             _                                 -> bad r Nothing
 
 -- | Make an assignment. The type 'Assignment' is abstract, the result is typically passed
@@ -769,7 +637,7 @@
              QueryState{queryConfig} <- getQueryState
              inps <- F.toList <$> getTopLevelInputs
 
-             let grabValues st = do let extract (Assign s n) = sbvToSV st (SBV s) >>= \sv -> return (sv, n)
+             let grabValues st = do let extract (Assign s n) = sbvToSV st (SBV s) >>= \sv -> pure (sv, n)
 
                                     modelAssignment <- mapM extract asgns
 
@@ -820,7 +688,7 @@
                                                                                 , "***   Candidates: " ++ unwords nms
                                                                                 ]
 
-                                    return [(findName s, n) | (s, n) <- modelAssignment]
+                                    pure [(findName s, n) | (s, n) <- modelAssignment]
 
              assocs <- inNewContext grabValues
 
@@ -830,6 +698,4 @@
                               , modelUIFuns     = []
                               }
 
-             return $ Satisfiable queryConfig m
-
-{- HLint ignore getModelAtIndex "Use forM_" -}
+             pure $ Satisfiable queryConfig m
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
@@ -164,14 +164,14 @@
 -- logics that might be supported on new solvers. See <https://smt-lib.org/logics.shtml> for the official list.
 data Logic
   = AUFLIA             -- ^ Formulas over the theory of linear integer arithmetic and arrays extended with free sort and function symbols but restricted to arrays with integer indices and values.
-  | AUFLIRA            -- ^ Linear formulas with free sort and function symbols over one- and two-dimentional arrays of integer index and real value.
+  | AUFLIRA            -- ^ Linear formulas with free sort and function symbols over one- and two-dimensional arrays of integer index and real value.
   | AUFNIRA            -- ^ Formulas with free function and predicate symbols over a theory of arrays of arrays of integer index and real value.
   | LRA                -- ^ Linear formulas in linear real arithmetic.
-  | QF_ABV             -- ^ Quantifier-free formulas over the theory of bitvectors and bitvector arrays.
-  | QF_AUFBV           -- ^ Quantifier-free formulas over the theory of bitvectors and bitvector arrays extended with free sort and function symbols.
+  | QF_ABV             -- ^ Quantifier-free formulas over the theory of bit-vectors and bit-vector arrays.
+  | QF_AUFBV           -- ^ Quantifier-free formulas over the theory of bit-vectors and bit-vector arrays extended with free sort and function symbols.
   | QF_AUFLIA          -- ^ Quantifier-free linear formulas over the theory of integer arrays extended with free sort and function symbols.
   | QF_AX              -- ^ Quantifier-free formulas over the theory of arrays with extensionality.
-  | QF_BV              -- ^ Quantifier-free formulas over the theory of fixed-size bitvectors.
+  | QF_BV              -- ^ Quantifier-free formulas over the theory of fixed-size bit-vectors.
   | QF_IDL             -- ^ Difference Logic over the integers. Boolean combinations of inequations of the form x - y < b where x and y are integer variables and b is an integer constant.
   | QF_LIA             -- ^ Unquantified linear integer arithmetic. In essence, Boolean combinations of inequations between linear polynomials over integer variables.
   | QF_LRA             -- ^ Unquantified linear real arithmetic. In essence, Boolean combinations of inequations between linear polynomials over real variables.
@@ -179,7 +179,7 @@
   | QF_NRA             -- ^ Quantifier-free real arithmetic.
   | QF_RDL             -- ^ Difference Logic over the reals. In essence, Boolean combinations of inequations of the form x - y < b where x and y are real variables and b is a rational constant.
   | QF_UF              -- ^ Unquantified formulas built over a signature of uninterpreted (i.e., free) sort and function symbols.
-  | QF_UFBV            -- ^ Unquantified formulas over bitvectors with uninterpreted sort function and symbols.
+  | QF_UFBV            -- ^ Unquantified formulas over bit-vectors with uninterpreted sort function and symbols.
   | QF_UFIDL           -- ^ Difference Logic over the integers (in essence) but with uninterpreted sort and function symbols.
   | QF_UFLIA           -- ^ Unquantified linear integer arithmetic with uninterpreted sort and function symbols.
   | QF_UFLRA           -- ^ Unquantified linear real arithmetic with uninterpreted sort and function symbols.
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
@@ -10,1958 +10,2199 @@
 -----------------------------------------------------------------------------
 
 {-# LANGUAGE BangPatterns           #-}
-{-# LANGUAGE InstanceSigs           #-}
-{-# LANGUAGE FlexibleContexts       #-}
-{-# LANGUAGE FlexibleInstances      #-}
-{-# LANGUAGE FunctionalDependencies #-}
-{-# LANGUAGE LambdaCase             #-}
-{-# LANGUAGE NamedFieldPuns         #-}
-{-# LANGUAGE OverloadedStrings      #-}
-{-# LANGUAGE ScopedTypeVariables    #-}
-{-# LANGUAGE TupleSections          #-}
-{-# LANGUAGE TypeApplications       #-}
-{-# LANGUAGE TypeFamilies           #-}
-{-# LANGUAGE ViewPatterns           #-}
-{-# LANGUAGE UndecidableInstances   #-}
-
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
-
-module Data.SBV.Control.Utils (
-       io
-     , ask, send, getValue, getFunction, getUninterpretedValue
-     , getValueCV, getUICVal, getUIFunCVAssoc, getUnsatAssumptions
-     , SMTFunction(..), getQueryState, modifyQueryState, getConfig, getObjectives, getUIs
-     , getSBVAssertions, getSBVPgm, getObservables
-     , checkSat, checkSatUsing, getAllSatResult
-     , inNewContext, freshVar, freshVar_
-     , getTopLevelInputs, parse, unexpected
-     , timeout, queryDebug, retrieveResponse, recoverKindedValue, runProofOn, executeQuery
-     ) where
-
-import Data.List  (sortBy, sortOn, elemIndex, partition, groupBy, tails, intercalate, nub, sort, isPrefixOf, isSuffixOf)
-
-import Data.Char      (isPunctuation, isSpace, isDigit)
-import Data.Function  (on)
-import Data.Bifunctor (first)
-
-import Data.Proxy
-
-import qualified Data.Foldable      as F (toList)
-import qualified Data.Map.Strict    as Map
-import qualified Data.Sequence      as S
-import qualified Data.Text          as T
-
-import Control.Monad            (join, unless, zipWithM, when, replicateM, forM_)
-import Control.Monad.IO.Class   (MonadIO, liftIO)
-import Control.Monad.Trans      (lift)
-import Control.Monad.Reader     (runReaderT)
-
-import Data.Maybe (isNothing, isJust)
-
-import Data.IORef (readIORef, writeIORef, IORef, newIORef, modifyIORef')
-
-import Data.Time (getZonedTime)
-import Data.Ratio
-
-import Data.SBV.Core.Data     ( SV(..), trueSV, falseSV, CV(..), trueCV, falseCV, SBV, sbvToSV, kindOf, Kind(..)
-                              , HasKind(..), mkConstCV, CVal(..), SMTResult(..)
-                              , NamedSymVar, SMTConfig(..), SMTModel(..)
-                              , QueryState(..), SVal(..), cache
-                              , newExpr, SBVExpr(..), Op(..), FPOp(..), SBV(..)
-                              , SolverContext(..), SBool, Objective(..), SolverCapabilities(..), capabilities
-                              , Result(..), SMTProblem(..), trueSV, SymVal(..), SBVPgm(..), SMTSolver(..), SBVRunMode(..)
-                              , SBVType(..), forceSVArg, RoundingMode(RoundNearestTiesToEven), (.=>)
-                              , RCSet(..), QuantifiedBool(..), ArrayModel(..)
-                              )
-
-import Data.SBV.Core.Symbolic ( IncState(..), withNewIncState, State(..), svToSV, symbolicEnv, SymbolicT
-                              , MonadQuery(..), QueryContext(..), VarContext(..)
-                              , registerLabel, svMkSymVar, validationRequested
-                              , isSafetyCheckingIStage, isSetupIStage, isRunIStage, IStage(..), QueryT(..)
-                              , extractSymbolicSimulationState, MonadSymbolic(..)
-                              , UserInputs, getSV, NamedSymVar(..), lookupInput, getUserName'
-                              , Name, CnstMap, Inputs(..), ProgInfo(..)
-                              , mustIgnoreVar, newInternalVariable
-                              )
-
-import Data.SBV.Core.AlgReals    (mergeAlgReals, AlgReal(..), RealPoint(..))
-import Data.SBV.Core.SizedFloats (fpZero, fpFromInteger, fpFromFloat, fpFromDouble)
-import Data.SBV.Core.Kind        (smtType, hasUninterpretedSorts)
-import Data.SBV.Core.Operations  (svNot, svNotEqual, svOr, svEqual)
-
-import Data.SBV.SMT.SMT     (showModel, parseCVs, SatModel, AllSatResult(..))
-import Data.SBV.SMT.SMTLib  (toIncSMTLib, toSMTLib)
-import Data.SBV.SMT.SMTLib2 (setSMTOption)
-import Data.SBV.SMT.Utils   ( showTimeoutValue, addAnnotations, alignPlain, debug
-                            , mergeSExpr, SBVException(..), recordTranscript, TranscriptMsg(..)
-                            , witnessName
-                            )
-
-import Data.SBV.Utils.ExtractIO
-import Data.SBV.Utils.Lib       (qfsToString)
-import Data.SBV.Utils.SExpr
-import Data.SBV.Utils.PrettyNum (cvToSMTLib)
-
-import Data.SBV.Control.Types
-
-import qualified Data.Set as Set (empty, fromList, toAscList)
-
-import qualified Control.Exception as C
-
-import GHC.Stack
-
--- | 'Data.SBV.Trans.Control.QueryT' as a 'SolverContext'.
-instance MonadIO m => SolverContext (QueryT m) where
-   constrain                   = addQueryConstraint False []                . quantifiedBool
-   softConstrain               = addQueryConstraint True  []                . quantifiedBool
-   namedConstraint nm          = addQueryConstraint False [(":named", nm)]  . quantifiedBool
-   constrainWithAttribute attr = addQueryConstraint False attr              . quantifiedBool
-
-   contextState = queryState
-
-   internalVariable :: forall a. Kind -> QueryT m (SBV a)
-   internalVariable k = contextState >>= \st -> liftIO $ do
-       sv  <- newInternalVariable st k
-       pure $ SBV $ SVal k (Right (cache (const (pure sv))))
-
-   setOption o
-     | isStartModeOption o = error $ unlines [ ""
-                                             , "*** Data.SBV: '" ++ show o ++ "' can only be set at start-up time."
-                                             , "*** Hint: Move the call to 'setOption' before the query."
-                                             ]
-     | True                = do State{stCfg} <- contextState
-                                send True $ setSMTOption stCfg o
-
--- | Adding a constraint, possibly with attributes and possibly soft. Only used internally.
--- Use 'constrain' and 'namedConstraint' from user programs.
-addQueryConstraint :: (MonadIO m, MonadQuery m) => Bool -> [(String, String)] -> SBool -> m ()
-addQueryConstraint isSoft atts b = do sv <- inNewContext (\st -> liftIO $ do mapM_ (registerLabel "Constraint" st) [nm | (":named", nm) <- atts]
-                                                                             sbvToSV st b)
-
-                                      unless (null atts && sv == trueSV) $
-                                             send True $ "(" ++ asrt ++ " " ++ addAnnotations atts (show sv)  ++ ")"
-   where asrt | isSoft = "assert-soft"
-              | True   = "assert"
-
--- | Get the current configuration
-getConfig :: (MonadIO m, MonadQuery m) => m SMTConfig
-getConfig = queryConfig <$> getQueryState
-
--- | Get the objectives
-getObjectives :: (MonadIO m, MonadQuery m) => m [Objective (SV, SV)]
-getObjectives = do State{rOptGoals} <- queryState
-                   io $ reverse <$> readIORef rOptGoals
-
--- | Get the program
-getSBVPgm :: (MonadIO m, MonadQuery m) => m SBVPgm
-getSBVPgm = do State{spgm} <- queryState
-               io $ readIORef spgm
-
--- | Get the assertions put in via 'Data.SBV.sAssert'
-getSBVAssertions :: (MonadIO m, MonadQuery m) => m [(String, Maybe CallStack, SV)]
-getSBVAssertions = do State{rAsserts} <- queryState
-                      io $ reverse <$> readIORef rAsserts
-
--- | Generalization of 'Data.SBV.Control.io'
-io :: MonadIO m => IO a -> m a
-io = liftIO
-
--- | Sync-up the external solver with new context we have generated
-syncUpSolver :: (MonadIO m, MonadQuery m) => ProgInfo -> IORef CnstMap -> IncState -> m ()
-syncUpSolver progInfo rGlobalConsts is = do
-        cfg <- getConfig
-
-        -- update global consts to have the new ones
-        (newConsts, allConsts) <- liftIO $ do nc <- readIORef (rNewConsts is)
-                                              oc <- readIORef rGlobalConsts
-                                              let allConsts = Map.union nc oc
-                                              writeIORef rGlobalConsts allConsts
-                                              pure (nc, allConsts)
-
-        ls  <- io $ do let swap  (a, b)        = (b, a)
-                           cmp   (a, _) (b, _) = a `compare` b
-                           arrange (i, (at, rt, es)) = ((i, at, rt), es)
-                       inps        <- reverse <$> readIORef (rNewInps is)
-                       ks          <- readIORef (rNewKinds is)
-                       tbls        <- map arrange . sortBy cmp . map swap . Map.toList <$> readIORef (rNewTbls is)
-                       uis         <- Map.toAscList <$> readIORef (rNewUIs is)
-                       as          <- readIORef (rNewAsgns is)
-                       constraints <- readIORef (rNewConstraints is)
-
-                       let cnsts = sortBy cmp . map swap . Map.toList $ newConsts
-
-                       return $ toIncSMTLib cfg progInfo inps ks (allConsts, cnsts) tbls uis as constraints cfg
-
-        mapM_ (send True) $ mergeSExpr ls
-
--- | Retrieve the query context
-getQueryState :: (MonadIO m, MonadQuery m) => m QueryState
-getQueryState = do state <- queryState
-                   mbQS  <- io $ readIORef (rQueryState state)
-                   case mbQS of
-                     Nothing -> error $ unlines [ ""
-                                                , "*** Data.SBV: Impossible happened: Query context required in a non-query mode."
-                                                , "Please report this as a bug!"
-                                                ]
-                     Just qs -> return qs
-
--- | Generalization of 'Data.SBV.Control.modifyQueryState'
-modifyQueryState :: (MonadIO m, MonadQuery m) => (QueryState -> QueryState) -> m ()
-modifyQueryState f = do state <- queryState
-                        mbQS  <- io $ readIORef (rQueryState state)
-                        case mbQS of
-                          Nothing -> error $ unlines [ ""
-                                                     , "*** Data.SBV: Impossible happened: Query context required in a non-query mode."
-                                                     , "Please report this as a bug!"
-                                                     ]
-                          Just qs -> let fqs = f qs
-                                     in fqs `seq` io $ writeIORef (rQueryState state) $ Just fqs
-
--- | Generalization of 'Data.SBV.Control.inNewContext'
-inNewContext :: (MonadIO m, MonadQuery m) => (State -> IO a) -> m a
-inNewContext act = do st@State{rconstMap, rProgInfo} <- queryState
-                      (is, r)  <- io $ withNewIncState st act
-                      progInfo <- io $ readIORef rProgInfo
-                      syncUpSolver progInfo rconstMap is
-                      return r
-
--- | Generalization of 'Data.SBV.Control.freshVar_'
-freshVar_ :: forall a m. (MonadIO m, MonadQuery m, SymVal a) => m (SBV a)
-freshVar_ = inNewContext $ fmap SBV . svMkSymVar QueryVar k Nothing
-  where k = kindOf (Proxy @a)
-
--- | Generalization of 'Data.SBV.Control.freshVar'
-freshVar :: forall a m. (MonadIO m, MonadQuery m, SymVal a) => String -> m (SBV a)
-freshVar nm = inNewContext $ fmap SBV . svMkSymVar QueryVar k (Just nm)
-  where k = kindOf (Proxy @a)
-
--- | Generalization of 'Data.SBV.Control.queryDebug'
-queryDebug :: (MonadIO m, MonadQuery m) => [String] -> m ()
-queryDebug msgs = do QueryState{queryConfig} <- getQueryState
-                     io $ do debug queryConfig msgs
-                             -- If we're doing a transcript, record it there too
-                             recordTranscript (transcript queryConfig) (DebugMsg (unlines msgs))
-
--- | We need to track sent asserts/check-sat calls so we can issue an extra check-sat call if needed
-trackAsserts :: (MonadIO m, MonadQuery m) => String -> m ()
-trackAsserts s
-   | isCheckSat || isAssert
-   = do State{rOutstandingAsserts} <- queryState
-        liftIO $ writeIORef rOutstandingAsserts isAssert
-   | True
-   = pure ()
-  where trimmedS   = dropWhile isSpace s
-        isCheckSat = "(check-sat" `isPrefixOf` trimmedS
-        isAssert   = "(assert"    `isPrefixOf` trimmedS
-
--- | Generalization of 'Data.SBV.Control.ask'
-ask :: (MonadIO m, MonadQuery m) => String -> m String
-ask s = askIgnoring s []
-
--- | Send a string to the solver, and return the response. Except, if the response
--- is one of the "ignore" ones, keep querying.
-askIgnoring :: (MonadIO m, MonadQuery m) => String -> [String] -> m String
-askIgnoring s ignoreList = do
-
-           trackAsserts s
-
-           QueryState{queryAsk, queryRetrieveResponse, queryTimeOutValue} <- getQueryState
-
-           case queryTimeOutValue of
-             Nothing -> queryDebug ["[SEND] " `alignPlain` s]
-             Just i  -> queryDebug ["[SEND, TimeOut: " ++ showTimeoutValue i ++ "] " `alignPlain` s]
-           r <- io $ queryAsk queryTimeOutValue s
-           queryDebug ["[RECV] " `alignPlain` r]
-
-           let loop currentResponse
-                 | currentResponse `notElem` ignoreList
-                 = return currentResponse
-                 | True
-                 = do queryDebug ["[WARN] Previous response is explicitly ignored, beware!"]
-                      newResponse <- io $ queryRetrieveResponse queryTimeOutValue
-                      queryDebug ["[RECV] " `alignPlain` newResponse]
-                      loop newResponse
-
-           loop r
-
--- | Generalization of 'Data.SBV.Control.send'
-send :: (MonadIO m, MonadQuery m) => Bool -> String -> m ()
-send requireSuccess s = do
-
-            trackAsserts s
-
-            QueryState{queryAsk, querySend, queryConfig, queryTimeOutValue} <- getQueryState
-
-            if requireSuccess && supportsCustomQueries (capabilities (solver queryConfig))
-               then do r <- io $ queryAsk queryTimeOutValue s
-
-                       case words r of
-                         ["success"] -> queryDebug ["[GOOD] " `alignPlain` s]
-                         _           -> do case queryTimeOutValue of
-                                             Nothing -> queryDebug ["[FAIL] " `alignPlain` s]
-                                             Just i  -> queryDebug [("[FAIL, TimeOut: " ++ showTimeoutValue i ++ "]  ") `alignPlain` s]
-
-
-                                           let cmd = case words (dropWhile (\c -> isSpace c || isPunctuation c) s) of
-                                                       (c:_) -> c
-                                                       _     -> "Command"
-
-                                           unexpected cmd s "success" Nothing r Nothing
-
-               else do -- fire and forget. if you use this, you're on your own!
-                       queryDebug ["[FIRE] " `alignPlain` s]
-                       io $ querySend queryTimeOutValue s
-
--- | Generalization of 'Data.SBV.Control.retrieveResponse'
-retrieveResponse :: (MonadIO m, MonadQuery m) => String -> Maybe Int -> m [String]
-retrieveResponse userTag mbTo = do
-             ts  <- io (show <$> getZonedTime)
-
-             let synchTag = show $ userTag ++ " (at: " ++ ts ++ ")"
-                 cmd = "(echo " ++ synchTag ++ ")"
-
-             queryDebug ["[SYNC] Attempting to synchronize with tag: " ++ synchTag]
-
-             send False cmd
-
-             QueryState{queryRetrieveResponse} <- getQueryState
-
-             let loop sofar = do
-                  s <- io $ queryRetrieveResponse mbTo
-
-                  -- strictly speaking SMTLib requires solvers to print quotes around
-                  -- echo'ed strings, but they don't always do. Accommodate for that
-                  -- here, though I wish we didn't have to.
-                  if s == synchTag || show s == synchTag
-                     then do queryDebug ["[SYNC] Synchronization achieved using tag: " ++ synchTag]
-                             return $ reverse sofar
-                     else do queryDebug ["[RECV] " `alignPlain` s]
-                             loop (s : sofar)
-
-             loop []
-
--- | Generalization of 'Data.SBV.Control.getValue'
-getValue :: (MonadIO m, MonadQuery m, SymVal a) => SBV a -> m a
-getValue s = do
-
-      sv <- inNewContext (`sbvToSV` s)
-
-      -- If we're issuing get-value, we gotta make sure there are no outstanding asserts
-      -- This can happen if we sent some ourselves. See https://github.com/LeventErkok/sbv/issues/682
-      outstandingAsserts <- do State{rOutstandingAsserts} <- queryState
-                               liftIO $ readIORef rOutstandingAsserts
-
-      when outstandingAsserts $ do
-        queryDebug ["[NOTE] getValue: There are outstanding asserts. Ensuring we're still sat."]
-        r <- checkSat
-        let bad = unexpected "checkSat" "check-sat" "one of sat/unsat/unknown" Nothing (show r) Nothing
-        case r of
-          Sat    -> pure ()
-          DSat{} -> pure ()
-          Unk    -> bad
-          Unsat  -> bad
-
-      cv <- getValueCV Nothing sv
-      return $ fromCV cv
-
--- | A class which allows for sexpr-conversion to functions
-class (HasKind r, SatModel r) => SMTFunction fun a r | fun -> a r where
-  sexprToArg     :: fun -> [SExpr] -> Maybe a
-  smtFunName     :: (MonadIO m, SolverContext m) => fun -> m ((String, Maybe [String]), Bool)
-  smtFunSaturate :: fun -> SBV r
-  smtFunType     :: fun -> SBVType
-  smtFunDefault  :: fun -> Maybe r
-  sexprToFun     :: (MonadIO m, SolverContext m, MonadQuery m, MonadSymbolic m, SymVal r) => fun -> (String, SExpr) -> m (Either String ([(a, r)], r))
-
-  {-# MINIMAL sexprToArg, smtFunSaturate, smtFunType  #-}
-
-  -- Given the function, figure out a default "return value"
-  smtFunDefault _
-    | let v = defaultKindedValue (kindOf (Proxy @r)), Just (res, []) <- parseCVs [v]
-    = Just res
-    | True
-    = Nothing
-
-  -- Given the function, determine what its name is and do some sanity checks
-  smtFunName f = do st@State{rUIMap} <- contextState
-                    uiMap <- liftIO $ readIORef rUIMap
-                    nm    <- findName st uiMap
-
-                    -- Read the uiMap again here. Why? Because the act of finding the name might've
-                    -- introduced it as an uninterperted name!
-                    newUIMap <- liftIO $ readIORef rUIMap
-                    case nm `Map.lookup` newUIMap of
-                      Nothing                     -> cantFind newUIMap
-                      Just (isCurried, mbArgs, _) -> pure ((nm, mbArgs), isCurried)
-    where cantFind uiMap = error $ unlines $    [ ""
-                                                , "*** Data.SBV.getFunction: Must be called on an uninterpreted function!"
-                                                , "***"
-                                                , "***    Expected to receive a function created by \"uninterpret\""
-                                                ]
-                                             ++ tag
-                                             ++ [ "***"
-                                                , "*** Make sure to call getFunction on uninterpreted functions only!"
-                                                , "*** If that is already the case, please report this as a bug."
-                                                ]
-             where tag = case map fst (Map.toList uiMap) of
-                               []    -> [ "***    But, there are no matching uninterpreted functions in the context." ]
-                               [x]   -> [ "***    The only possible candidate is: " ++ x ]
-                               cands -> [ "***    Candidates are:"
-                                        , "***        " ++ intercalate ", " cands
-                                        ]
-
-          findName st@State{spgm} uiMap = do
-             r <- liftIO $ sbvToSV st (smtFunSaturate f)
-             liftIO $ forceSVArg r
-             SBVPgm asgns <- liftIO $ readIORef spgm
-
-
-             case S.findIndexR ((== r) . fst) asgns of
-               Nothing -> cantFind uiMap
-               Just i  -> case asgns `S.index` i of
-                            (sv, SBVApp (Uninterpreted nm) _) | r == sv -> return nm
-                            _                                           -> cantFind uiMap
-
-  sexprToFun f (s, e) = do nm    <- fst . fst <$> smtFunName f
-                           mbRes <- case parseSExprFunction e of
-                                      Just (Left nm') -> case (nm == nm', smtFunDefault f) of
-                                                           (True, Just v)  -> return $ Just ([], v)
-                                                           _               -> bailOut nm
-                                      Just (Right v)  -> return $ convert v
-                                      Nothing         -> do mbPVS <- pointWiseExtract nm (smtFunType f)
-                                                            return $ mbPVS >>= convert
-                           pure $ maybe (Left s) Right mbRes
-    where convert    (vs, d) = (,) <$> mapM sexprPoint vs <*> sexprToVal d
-          sexprPoint (as, v) = (,) <$> sexprToArg f as    <*> sexprToVal v
-
-          bailOut nm = error $ unlines [ ""
-                                       , "*** Data.SBV.getFunction: Unable to extract an interpretation for function " ++ show nm
-                                       , "***"
-                                       , "*** Failed while trying to extract a pointwise interpretation."
-                                       , "***"
-                                       , "*** This could be a bug with SBV or the backend solver. Please report!"
-                                       ]
-
--- | Pointwise function value extraction. If we get unlucky and can't parse z3's output (happens
--- when we have all booleans and z3 decides to spit out an expression), just brute force our
--- way out of it. Note that we only do this if we have a pure boolean type, as otherwise we'd blow
--- up. And I think it'll only be necessary then, I haven't seen z3 try anything smarter in other scenarios.
-pointWiseExtract ::  forall m. (MonadIO m, MonadQuery m) => String -> SBVType -> m (Maybe ([([SExpr], SExpr)], SExpr))
-pointWiseExtract nm typ = tryPointWise
-  where trueSExpr  = ENum (1, Nothing)
-        falseSExpr = ENum (0, Nothing)
-
-        isTrueSExpr (ENum (1, Nothing)) = True
-        isTrueSExpr (ENum (0, Nothing)) = False
-        isTrueSExpr s                   = error $ "Data.SBV.pointWiseExtract: Impossible happened: Received: " ++ show s
-
-        (nArgs, isBoolFunc) = case typ of
-                                SBVType ts -> (length ts - 1, all (== KBool) ts)
-
-        getBVal :: [SExpr] -> m ([SExpr], SExpr)
-        getBVal args = do let shc c | isTrueSExpr c = "true"
-                                    | True          = "false"
-
-                              as = unwords $ map shc args
-
-                              cmd   = "(get-value ((" ++ nm ++ " " ++ as ++ ")))"
-
-                              bad   = unexpected "get-value" cmd ("pointwise value of boolean function " ++ nm ++ " on " ++ show as) Nothing
-
-                          r <- ask cmd
-
-                          parse r bad $ \case EApp [EApp [_, e]] -> return (args, e)
-                                              _                  -> bad r Nothing
-
-        getBVals :: m [([SExpr], SExpr)]
-        getBVals = mapM getBVal $ replicateM nArgs [falseSExpr, trueSExpr]
-
-        tryPointWise
-          | not isBoolFunc
-          = return Nothing
-          | nArgs < 1
-          = error $ "Data.SBV.pointWiseExtract: Impossible happened, nArgs < 1: " ++ show nArgs ++ " type: " ++ show typ
-          | True
-          = do vs <- getBVals
-               -- Pick the value that will give us the fewer entries
-               let (trues, falses) = partition (\(_, v) -> isTrueSExpr v) vs
-               return $ Just $ if length trues <= length falses
-                               then (trues,  falseSExpr)
-                               else (falses, trueSExpr)
-
--- | For saturation purposes, get a proper argument. The forall quantification
--- is safe here since we only use in smtFunSaturate calls, which looks at the
--- kind stored inside only.
-mkSaturatingArg :: forall a. Kind -> SBV a
-mkSaturatingArg k = SBV $ SVal k (Left (defaultKindedValue k))
-
--- | Functions of arity 1
-instance ( SymVal a, HasKind a
-         , SatModel r, HasKind r
-         ) => SMTFunction (SBV a -> SBV r) a r
-         where
-  sexprToArg _ [a0] = sexprToVal a0
-  sexprToArg _ _    = Nothing
-
-  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @r)]
-
-  smtFunSaturate f = f $ mkSaturatingArg (kindOf (Proxy @a))
-
--- | Functions of arity 2
-instance ( SymVal a,  HasKind a
-         , SymVal b,  HasKind b
-         , SatModel r, HasKind r
-         ) => SMTFunction (SBV a -> SBV b -> SBV r) (a, b) r
-         where
-  sexprToArg _ [a0, a1] = (,) <$> sexprToVal a0 <*> sexprToVal a1
-  sexprToArg _ _        = Nothing
-
-  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @r)]
-
-  smtFunSaturate f = f (mkSaturatingArg (kindOf (Proxy @a)))
-                       (mkSaturatingArg (kindOf (Proxy @b)))
-
--- | Functions of arity 3
-instance ( SymVal a,   HasKind a
-         , SymVal b,   HasKind b
-         , SymVal c,   HasKind c
-         , SatModel r, HasKind r
-         ) => SMTFunction (SBV a -> SBV b -> SBV c -> SBV r) (a, b, c) r
-         where
-  sexprToArg _ [a0, a1, a2] = (,,) <$> sexprToVal a0 <*> sexprToVal a1 <*> sexprToVal a2
-  sexprToArg _ _            = Nothing
-
-  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @c), kindOf (Proxy @r)]
-
-  smtFunSaturate f = f (mkSaturatingArg (kindOf (Proxy @a)))
-                       (mkSaturatingArg (kindOf (Proxy @b)))
-                       (mkSaturatingArg (kindOf (Proxy @c)))
-
--- | Functions of arity 4
-instance ( SymVal a,   HasKind a
-         , SymVal b,   HasKind b
-         , SymVal c,   HasKind c
-         , SymVal d,   HasKind d
-         , SatModel r, HasKind r
-         ) => SMTFunction (SBV a -> SBV b -> SBV c -> SBV d -> SBV r) (a, b, c, d) r
-         where
-  sexprToArg _ [a0, a1, a2, a3] = (,,,) <$> sexprToVal a0 <*> sexprToVal a1 <*> sexprToVal a2 <*> sexprToVal a3
-  sexprToArg _ _               = Nothing
-
-  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @c), kindOf (Proxy @d), kindOf (Proxy @r)]
-
-  smtFunSaturate f = f (mkSaturatingArg (kindOf (Proxy @a)))
-                       (mkSaturatingArg (kindOf (Proxy @b)))
-                       (mkSaturatingArg (kindOf (Proxy @c)))
-                       (mkSaturatingArg (kindOf (Proxy @d)))
-
--- | Functions of arity 5
-instance ( SymVal a,   HasKind a
-         , SymVal b,   HasKind b
-         , SymVal c,   HasKind c
-         , SymVal d,   HasKind d
-         , SymVal e,   HasKind e
-         , SatModel r, HasKind r
-         ) => SMTFunction (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV r) (a, b, c, d, e) r
-         where
-  sexprToArg _ [a0, a1, a2, a3, a4] = (,,,,) <$> sexprToVal a0 <*> sexprToVal a1 <*> sexprToVal a2 <*> sexprToVal a3 <*> sexprToVal a4
-  sexprToArg _ _                    = Nothing
-
-  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @c), kindOf (Proxy @d), kindOf (Proxy @e), kindOf (Proxy @r)]
-
-  smtFunSaturate f = f (mkSaturatingArg (kindOf (Proxy @a)))
-                       (mkSaturatingArg (kindOf (Proxy @b)))
-                       (mkSaturatingArg (kindOf (Proxy @c)))
-                       (mkSaturatingArg (kindOf (Proxy @d)))
-                       (mkSaturatingArg (kindOf (Proxy @e)))
-
--- | Functions of arity 6
-instance ( SymVal a,   HasKind a
-         , SymVal b,   HasKind b
-         , SymVal c,   HasKind c
-         , SymVal d,   HasKind d
-         , SymVal e,   HasKind e
-         , SymVal f,   HasKind f
-         , SatModel r, HasKind r
-         ) => SMTFunction (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV r) (a, b, c, d, e, f) r
-         where
-  sexprToArg _ [a0, a1, a2, a3, a4, a5] = (,,,,,) <$> sexprToVal a0 <*> sexprToVal a1 <*> sexprToVal a2 <*> sexprToVal a3 <*> sexprToVal a4 <*> sexprToVal a5
-  sexprToArg _ _                        = Nothing
-
-  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @c), kindOf (Proxy @d), kindOf (Proxy @e), kindOf (Proxy @f), kindOf (Proxy @r)]
-
-  smtFunSaturate f = f (mkSaturatingArg (kindOf (Proxy @a)))
-                       (mkSaturatingArg (kindOf (Proxy @b)))
-                       (mkSaturatingArg (kindOf (Proxy @c)))
-                       (mkSaturatingArg (kindOf (Proxy @d)))
-                       (mkSaturatingArg (kindOf (Proxy @e)))
-                       (mkSaturatingArg (kindOf (Proxy @f)))
-
--- | Functions of arity 7
-instance ( SymVal a,   HasKind a
-         , SymVal b,   HasKind b
-         , SymVal c,   HasKind c
-         , SymVal d,   HasKind d
-         , SymVal e,   HasKind e
-         , SymVal f,   HasKind f
-         , SymVal g,   HasKind g
-         , SatModel r, HasKind r
-         ) => SMTFunction (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV g -> SBV r) (a, b, c, d, e, f, g) r
-         where
-  sexprToArg _ [a0, a1, a2, a3, a4, a5, a6] = (,,,,,,) <$> sexprToVal a0 <*> sexprToVal a1 <*> sexprToVal a2 <*> sexprToVal a3 <*> sexprToVal a4 <*> sexprToVal a5 <*> sexprToVal a6
-  sexprToArg _ _                            = Nothing
-
-  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @c), kindOf (Proxy @d), kindOf (Proxy @e), kindOf (Proxy @f), kindOf (Proxy @g), kindOf (Proxy @r)]
-
-  smtFunSaturate f = f (mkSaturatingArg (kindOf (Proxy @a)))
-                       (mkSaturatingArg (kindOf (Proxy @b)))
-                       (mkSaturatingArg (kindOf (Proxy @c)))
-                       (mkSaturatingArg (kindOf (Proxy @d)))
-                       (mkSaturatingArg (kindOf (Proxy @e)))
-                       (mkSaturatingArg (kindOf (Proxy @f)))
-                       (mkSaturatingArg (kindOf (Proxy @g)))
-
--- | Functions of arity 8
-instance ( SymVal a,   HasKind a
-         , SymVal b,   HasKind b
-         , SymVal c,   HasKind c
-         , SymVal d,   HasKind d
-         , SymVal e,   HasKind e
-         , SymVal f,   HasKind f
-         , SymVal g,   HasKind g
-         , SymVal h,   HasKind h
-         , SatModel r, HasKind r
-         ) => SMTFunction (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV g -> SBV h -> SBV r) (a, b, c, d, e, f, g, h) r
-         where
-  sexprToArg _ [a0, a1, a2, a3, a4, a5, a6, a7] = (,,,,,,,) <$> sexprToVal a0 <*> sexprToVal a1 <*> sexprToVal a2 <*> sexprToVal a3 <*> sexprToVal a4 <*> sexprToVal a5 <*> sexprToVal a6 <*> sexprToVal a7
-  sexprToArg _ _                                = Nothing
-
-  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @c), kindOf (Proxy @d), kindOf (Proxy @e), kindOf (Proxy @f), kindOf (Proxy @g), kindOf (Proxy @h), kindOf (Proxy @r)]
-
-  smtFunSaturate f = f (mkSaturatingArg (kindOf (Proxy @a)))
-                       (mkSaturatingArg (kindOf (Proxy @b)))
-                       (mkSaturatingArg (kindOf (Proxy @c)))
-                       (mkSaturatingArg (kindOf (Proxy @d)))
-                       (mkSaturatingArg (kindOf (Proxy @e)))
-                       (mkSaturatingArg (kindOf (Proxy @f)))
-                       (mkSaturatingArg (kindOf (Proxy @g)))
-                       (mkSaturatingArg (kindOf (Proxy @h)))
-
--- | Curried functions of arity 2
-instance ( SymVal a,  HasKind a
-         , SymVal b,  HasKind b
-         , SatModel r, HasKind r
-         ) => SMTFunction ((SBV a, SBV b) -> SBV r) (a, b) r
-         where
-  sexprToArg _ [a0, a1] = (,) <$> sexprToVal a0 <*> sexprToVal a1
-  sexprToArg _ _        = Nothing
-
-  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @r)]
-
-  smtFunSaturate f = f ( mkSaturatingArg (kindOf (Proxy @a))
-                       , mkSaturatingArg (kindOf (Proxy @b))
-                       )
-
--- | Curried functions of arity 3
-instance ( SymVal a,  HasKind a
-         , SymVal b,  HasKind b
-         , SymVal c,  HasKind c
-         , SatModel r, HasKind r
-         ) => SMTFunction ((SBV a, SBV b, SBV c) -> SBV r) (a, b, c) r
-         where
-  sexprToArg _ [a0, a1, a2] = (,,) <$> sexprToVal a0 <*> sexprToVal a1 <*> sexprToVal a2
-  sexprToArg _ _            = Nothing
-
-  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @c), kindOf (Proxy @r)]
-
-  smtFunSaturate f = f ( mkSaturatingArg (kindOf (Proxy @a))
-                       , mkSaturatingArg (kindOf (Proxy @b))
-                       , mkSaturatingArg (kindOf (Proxy @c))
-                       )
-
--- | Curried functions of arity 4
-instance ( SymVal a,  HasKind a
-         , SymVal b,  HasKind b
-         , SymVal c,  HasKind c
-         , SymVal d,  HasKind d
-         , SatModel r, HasKind r
-         ) => SMTFunction ((SBV a, SBV b, SBV c, SBV d) -> SBV r) (a, b, c, d) r
-         where
-  sexprToArg _ [a0, a1, a2, a3] = (,,,) <$> sexprToVal a0 <*> sexprToVal a1 <*> sexprToVal a2 <*> sexprToVal a3
-  sexprToArg _ _                = Nothing
-
-  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @c), kindOf (Proxy @d), kindOf (Proxy @r)]
-
-  smtFunSaturate f = f ( mkSaturatingArg (kindOf (Proxy @a))
-                       , mkSaturatingArg (kindOf (Proxy @b))
-                       , mkSaturatingArg (kindOf (Proxy @c))
-                       , mkSaturatingArg (kindOf (Proxy @d))
-                       )
-
--- | Curried functions of arity 5
-instance ( SymVal a,  HasKind a
-         , SymVal b,  HasKind b
-         , SymVal c,  HasKind c
-         , SymVal d,  HasKind d
-         , SymVal e,  HasKind e
-         , SatModel r, HasKind r
-         ) => SMTFunction ((SBV a, SBV b, SBV c, SBV d, SBV e) -> SBV r) (a, b, c, d, e) r
-         where
-  sexprToArg _ [a0, a1, a2, a3, a4] = (,,,,) <$> sexprToVal a0 <*> sexprToVal a1 <*> sexprToVal a2 <*> sexprToVal a3 <*> sexprToVal a4
-  sexprToArg _ _                    = Nothing
-
-  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @c), kindOf (Proxy @d), kindOf (Proxy @e), kindOf (Proxy @r)]
-
-  smtFunSaturate f = f ( mkSaturatingArg (kindOf (Proxy @a))
-                       , mkSaturatingArg (kindOf (Proxy @b))
-                       , mkSaturatingArg (kindOf (Proxy @c))
-                       , mkSaturatingArg (kindOf (Proxy @d))
-                       , mkSaturatingArg (kindOf (Proxy @e))
-                       )
-
--- | Curried functions of arity 6
-instance ( SymVal a,  HasKind a
-         , SymVal b,  HasKind b
-         , SymVal c,  HasKind c
-         , SymVal d,  HasKind d
-         , SymVal e,  HasKind e
-         , SymVal f,  HasKind f
-         , SatModel r, HasKind r
-         ) => SMTFunction ((SBV a, SBV b, SBV c, SBV d, SBV e, SBV f) -> SBV r) (a, b, c, d, e, f) r
-         where
-  sexprToArg _ [a0, a1, a2, a3, a4, a5] = (,,,,,) <$> sexprToVal a0 <*> sexprToVal a1 <*> sexprToVal a2 <*> sexprToVal a3 <*> sexprToVal a4 <*> sexprToVal a5
-  sexprToArg _ _                        = Nothing
-
-  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @c), kindOf (Proxy @d), kindOf (Proxy @e), kindOf (Proxy @f), kindOf (Proxy @r)]
-
-  smtFunSaturate f = f ( mkSaturatingArg (kindOf (Proxy @a))
-                       , mkSaturatingArg (kindOf (Proxy @b))
-                       , mkSaturatingArg (kindOf (Proxy @c))
-                       , mkSaturatingArg (kindOf (Proxy @d))
-                       , mkSaturatingArg (kindOf (Proxy @e))
-                       , mkSaturatingArg (kindOf (Proxy @f))
-                       )
-
--- | Curried functions of arity 7
-instance ( SymVal a,  HasKind a
-         , SymVal b,  HasKind b
-         , SymVal c,  HasKind c
-         , SymVal d,  HasKind d
-         , SymVal e,  HasKind e
-         , SymVal f,  HasKind f
-         , SymVal g,  HasKind g
-         , SatModel r, HasKind r
-         ) => SMTFunction ((SBV a, SBV b, SBV c, SBV d, SBV e, SBV f, SBV g) -> SBV r) (a, b, c, d, e, f, g) r
-         where
-  sexprToArg _ [a0, a1, a2, a3, a4, a5, a6] = (,,,,,,) <$> sexprToVal a0 <*> sexprToVal a1 <*> sexprToVal a2 <*> sexprToVal a3 <*> sexprToVal a4 <*> sexprToVal a5 <*> sexprToVal a6
-  sexprToArg _ _                            = Nothing
-
-  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @c), kindOf (Proxy @d), kindOf (Proxy @e), kindOf (Proxy @f), kindOf (Proxy @g), kindOf (Proxy @r)]
-
-  smtFunSaturate f = f ( mkSaturatingArg (kindOf (Proxy @a))
-                       , mkSaturatingArg (kindOf (Proxy @b))
-                       , mkSaturatingArg (kindOf (Proxy @c))
-                       , mkSaturatingArg (kindOf (Proxy @d))
-                       , mkSaturatingArg (kindOf (Proxy @e))
-                       , mkSaturatingArg (kindOf (Proxy @f))
-                       , mkSaturatingArg (kindOf (Proxy @g))
-                       )
-
--- | Curried functions of arity 8
-instance ( SymVal a,  HasKind a
-         , SymVal b,  HasKind b
-         , SymVal c,  HasKind c
-         , SymVal d,  HasKind d
-         , SymVal e,  HasKind e
-         , SymVal f,  HasKind f
-         , SymVal g,  HasKind g
-         , SymVal h,  HasKind h
-         , SatModel r, HasKind r
-         ) => SMTFunction ((SBV a, SBV b, SBV c, SBV d, SBV e, SBV f, SBV g, SBV h) -> SBV r) (a, b, c, d, e, f, g, h) r
-         where
-  sexprToArg _ [a0, a1, a2, a3, a4, a5, a6, a7] = (,,,,,,,) <$> sexprToVal a0 <*> sexprToVal a1 <*> sexprToVal a2 <*> sexprToVal a3 <*> sexprToVal a4 <*> sexprToVal a5 <*> sexprToVal a6 <*> sexprToVal a7
-  sexprToArg _ _                                = Nothing
-
-  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @c), kindOf (Proxy @d), kindOf (Proxy @e), kindOf (Proxy @f), kindOf (Proxy @g), kindOf (Proxy @h), kindOf (Proxy @r)]
-
-  smtFunSaturate f = f ( mkSaturatingArg (kindOf (Proxy @a))
-                       , mkSaturatingArg (kindOf (Proxy @b))
-                       , mkSaturatingArg (kindOf (Proxy @c))
-                       , mkSaturatingArg (kindOf (Proxy @d))
-                       , mkSaturatingArg (kindOf (Proxy @e))
-                       , mkSaturatingArg (kindOf (Proxy @f))
-                       , mkSaturatingArg (kindOf (Proxy @g))
-                       , mkSaturatingArg (kindOf (Proxy @h))
-                       )
-
--- Turn "((F (lambda ((x!1 Int)) (+ 3 (* 2 x!1)))))"
--- into something more palatable.
--- If we can't do that, we simply return the input unchanged
-trimFunctionResponse :: String -> String -> Bool -> Maybe [String] -> String
-trimFunctionResponse resp nm isCurried mbArgs
-  | Just parsed <- makeHaskellFunction resp nm isCurried mbArgs
-  = parsed
-  | True
-  = def $ case trim resp of
-            '(':'(':rest | nm `isPrefixOf` rest -> butLast2 $ trim (drop (length nm) rest)
-            _                                   -> resp
-  where trim     = dropWhile isSpace
-        butLast2 = reverse . drop 2 . reverse
-        def x = nm ++ " = fromSMTLib " ++ x
-
--- | Generalization of 'Data.SBV.Control.getFunction'
-getFunction :: (MonadIO m, MonadQuery m, SolverContext m, MonadSymbolic m, SymVal a, SymVal r, SMTFunction fun a r)
-            => fun -> m (Either (String, (Bool, Maybe [String], SExpr))  ([(a, r)], r))
-getFunction f = do ((nm, args), isCurried) <- smtFunName f
-
-                   let cmd = "(get-value (" ++ nm ++ "))"
-                       bad = unexpected "getFunction" cmd "a function value" Nothing
-
-                   r <- ask cmd
-
-                   parse r bad $ \case EApp [EApp [ECon o, e]] | o == nm -> do mbAssocs <- sexprToFun f (trimFunctionResponse r nm isCurried args, e)
-                                                                               case mbAssocs of
-                                                                                 Right assocs -> return $ Right assocs
-                                                                                 Left  raw    -> do mbPVS <- pointWiseExtract nm (smtFunType f)
-                                                                                                    case mbPVS >>= convert of
-                                                                                                      Just x  -> return $ Right x
-                                                                                                      Nothing -> return $ Left (raw, (isCurried, args, e))
-                                       _                                 -> bad r Nothing
-    where convert    (vs, d) = (,) <$> mapM sexprPoint vs <*> sexprToVal d
-          sexprPoint (as, v) = (,) <$> sexprToArg f as    <*> sexprToVal v
-
--- | Generalization of 'Data.SBV.Control.getUninterpretedValue'
-getUninterpretedValue :: (MonadIO m, MonadQuery m, HasKind a) => SBV a -> m String
-getUninterpretedValue s =
-        case kindOf s of
-          KUserSort _ Nothing -> do sv <- inNewContext (`sbvToSV` s)
-
-                                    let nm  = show sv
-                                        cmd = "(get-value (" ++ nm ++ "))"
-                                        bad = unexpected "getValue" cmd "a model value" Nothing
-
-                                    r <- ask cmd
-
-                                    parse r bad $ \case EApp [EApp [ECon o,  ECon v]] | o == show sv -> return v
-                                                        _                                            -> bad r Nothing
-
-          k                   -> error $ unlines [""
-                                                 , "*** SBV.getUninterpretedValue: Called on an 'interpreted' kind"
-                                                 , "*** "
-                                                 , "***    Kind: " ++ show k
-                                                 , "***    Hint: Use 'getValue' to extract value for interpreted kinds."
-                                                 , "*** "
-                                                 , "*** Only truly uninterpreted sorts should be used with 'getUninterpretedValue.'"
-                                                 ]
-
--- | Get the value of a term, but in CV form. Used internally. The model-index, in particular is extremely Z3 specific!
-getValueCVHelper :: (MonadIO m, MonadQuery m) => Maybe Int -> SV -> m CV
-getValueCVHelper mbi s
-  | s == trueSV
-  = return trueCV
-  | s == falseSV
-  = return falseCV
-  | True
-  = extractValue mbi (show s) (kindOf s)
-
--- | "Make up" a CV for this type. Like zero, but smarter.
-defaultKindedValue :: Kind -> CV
-defaultKindedValue k = CV k $ cvt k
-  where cvt :: Kind -> CVal
-        cvt KBool            = CInteger 0
-        cvt KBounded{}       = CInteger 0
-        cvt KUnbounded       = CInteger 0
-        cvt KReal            = CAlgReal 0
-        cvt (KUserSort s ui) = uninterp s ui
-        cvt KFloat           = CFloat 0
-        cvt KDouble          = CDouble 0
-        cvt KRational        = CRational 0
-        cvt (KFP eb sb)      = CFP (fpZero False eb sb)
-        cvt KChar            = CChar '\NUL'                -- why not?
-        cvt KString          = CString ""
-        cvt (KList  _)       = CList []
-        cvt (KSet  _)        = CSet $ RegularSet Set.empty -- why not? Arguably, could be the universal set
-        cvt (KTuple ks)      = CTuple $ map cvt ks
-        cvt (KMaybe _)       = CMaybe Nothing
-        cvt (KEither k1 _)   = CEither . Left $ cvt k1     -- why not?
-        cvt (KArray  _  k2)  = CArray $ ArrayModel [] (cvt k2)
-
-        -- Tricky case of uninterpreted
-        uninterp _ (Just (c:_)) = CUserSort (Just 0, c)
-        uninterp _ (Just [])    = error "defaultKindedValue: enumerated kind with no constructors!"
-
-        -- A completely uninterpreted sort, i.e., no elements. Return the witness element for it.
-        uninterp s Nothing      = CUserSort (Nothing, witnessName s)
-
--- | Go from an SExpr directly to a value
-sexprToVal :: forall a. SymVal a => SExpr -> Maybe a
-sexprToVal e = fromCV <$> recoverKindedValue (kindOf (Proxy @a)) e
-
--- | Recover a given solver-printed value with a possible interpretation
-recoverKindedValue :: Kind -> SExpr -> Maybe CV
-recoverKindedValue k e = case k of
-                           KBool       | ENum (i, _) <- e      -> Just $ mkConstCV k i
-                                       | True                  -> Nothing
-
-                           KBounded{}  | ENum (i, _) <- e      -> Just $ mkConstCV k i
-                                       | True                  -> Nothing
-
-                           KUnbounded  | ENum (i, _) <- e      -> Just $ mkConstCV k i
-                                       | True                  -> Nothing
-
-                           KReal       | ENum (i, _) <- e      -> Just $ mkConstCV k i
-                                       | EReal i     <- e      -> Just $ CV KReal (CAlgReal i)
-                                       | True                  -> interpretInterval e
-
-                           KUserSort{} | ECon s <- e           -> Just $ CV k $ CUserSort (getUIIndex k s, simplifyECon s)
-                                       | True                  -> Nothing
-
-                           KFloat      | ENum (i, _) <- e      -> Just $ mkConstCV k i
-                                       | EFloat i    <- e      -> Just $ CV KFloat (CFloat i)
-                                       | True                  -> Nothing
-
-                           KDouble     | ENum (i, _) <- e      -> Just $ mkConstCV k i
-                                       | EDouble i   <- e      -> Just $ CV KDouble (CDouble i)
-                                       | True                  -> Nothing
-
-                           KFP eb sb   | ENum (i, _)      <- e -> Just $ CV k $ CFP $ fpFromInteger eb sb i
-                                       | EFloat f         <- e -> Just $ CV k $ CFP $ fpFromFloat   eb sb f
-                                       | EDouble d        <- e -> Just $ CV k $ CFP $ fpFromDouble  eb sb d
-                                       | EFloatingPoint c <- e -> Just $ CV k $ CFP c
-                                       | True                  -> Nothing
-
-                           KChar       | ECon s      <- e      -> Just $ CV KChar $ CChar $ interpretChar s
-                                       | True                  -> Nothing
-
-                           KString     | ECon s      <- e      -> Just $ CV KString $ CString $ interpretString s
-                                       | True                  -> Nothing
-
-                           KRational                           -> Just $ CV k $ CRational $ interpretRational       e
-                           KList ek                            -> Just $ CV k $ CList     $ interpretList ek        e
-                           KSet ek                             -> Just $ CV k $ CSet      $ interpretSet ek         e
-                           KTuple{}                            -> Just $ CV k $ CTuple    $ interpretTuple          e
-                           KMaybe{}                            -> Just $ CV k $ CMaybe    $ interpretMaybe    k     e
-                           KEither{}                           -> Just $ CV k $ CEither   $ interpretEither   k     e
-                           KArray k1 k2                        -> Just $ CV k $ CArray    $ interpretArray    k1 k2 e
-
-  where getUIIndex (KUserSort  _ (Just xs)) i = i `elemIndex` xs
-        getUIIndex _                        _ = Nothing
-
-        stringLike xs = length xs >= 2 && "\"" `isPrefixOf` xs && "\"" `isSuffixOf` xs
-
-        -- Make sure strings are really strings
-        interpretString xs
-          | not (stringLike xs)
-          = error $ "Expected a string constant with quotes, received: <" ++ xs ++ ">"
-          | True
-          = qfsToString $ drop 1 (init xs)
-
-        interpretChar xs = case interpretString xs of
-                             [c] -> c
-                             _   -> error $ "Expected a singleton char constant, received: <" ++ xs ++ ">"
-
-        interpretRational (EApp [ECon "SBV.Rational", v1, v2])
-           | Just (CV _ (CInteger n)) <- recoverKindedValue KUnbounded v1
-           , Just (CV _ (CInteger d)) <- recoverKindedValue KUnbounded v2
-           = n % d
-        interpretRational xs = error $ "Expected a rational constant, received: <" ++ show xs ++ ">"
-
-        interpretList ek topExpr = walk topExpr
-          where walk (EApp [ECon "as", v, _])      = walk v
-                walk (ECon "seq.empty")            = []
-                walk (EApp [ECon "seq.unit", v])   = case recoverKindedValue ek v of
-                                                       Just w -> [cvVal w]
-                                                       Nothing -> error $ "Cannot parse a sequence item of kind " ++ show ek ++ " from: " ++ show v ++ extra v
-                walk (EApp (ECon "seq.++" : rest)) = concatMap walk rest
-                walk cur                           = error $ "Expected a sequence constant, but received: " ++ show cur ++ extra cur
-
-                extra cur | show cur == t = ""
-                          | True          = "\nWhile parsing: " ++ t
-                          where t = show topExpr
-
-        -- Essentially treat sets as functions, since we do allow for store associations
-        interpretSet ke setExpr
-             | isUniversal setExpr             = ComplementSet Set.empty
-             | isEmpty     setExpr             = RegularSet    Set.empty
-             | Just (Right assocs) <- mbAssocs = decode assocs
-             | True                            = tbd "Expected a set value, but couldn't decipher the solver output."
-
-           where tbd :: String -> a
-                 tbd w = error $ unlines [ ""
-                                         , "*** Data.SBV.interpretSet: Unable to process solver output."
-                                         , "***"
-                                         , "*** Kind    : " ++ show (KSet ke)
-                                         , "*** Received: " ++ show setExpr
-                                         , "*** Reason  : " ++ w
-                                         , "***"
-                                         , "*** This is either a bug or something SBV currently does not support."
-                                         , "*** Please report this as a feature request!"
-                                         ]
-
-
-                 isTrue (ENum (1, Nothing)) = True
-                 isTrue (ENum (0, Nothing)) = False
-                 isTrue bad                 = tbd $ "Non-boolean membership value seen: " ++ show bad
-
-                 isUniversal (EApp [EApp [ECon "as", ECon "const", EApp [ECon "Array", _, ECon "Bool"]], r]) = isTrue r
-                 isUniversal _                                                                               = False
-
-                 isEmpty     (EApp [EApp [ECon "as", ECon "const", EApp [ECon "Array", _, ECon "Bool"]], r]) = not $ isTrue r
-                 isEmpty     _                                                                               = False
-
-                 mbAssocs = parseSExprFunction setExpr
-
-                 decode (args, r) | isTrue r = ComplementSet $ Set.fromList [x | (x, False) <- concatMap (contents True)  args]  -- deletions from universal
-                                  | True     = RegularSet    $ Set.fromList [x | (x, True)  <- concatMap (contents False) args]  -- additions to empty
-
-                 contents cvt ([v], r) = let t = isTrue r in map (, t) (element cvt v)
-                 contents _   bad      = tbd $ "Multi-valued set member seen: " ++ show bad
-
-                 element cvt x = case (cvt, ke) of
-                                   (True, KChar) -> case recoverKindedValue KString x of
-                                                      Just v  -> case cvVal v of
-                                                                  CString [c] -> [CChar c]
-                                                                  CString _   -> []
-                                                                  _           -> tbd $ "Unexpected value for kind: " ++ show (x, ke)
-                                                      Nothing -> tbd $ "Unexpected value for kind: " ++ show (x, ke)
-                                   _             -> case recoverKindedValue ke x of
-                                                      Just v  -> [cvVal v]
-                                                      Nothing -> tbd $ "Unexpected value for kind: " ++ show (x, ke)
-
-        interpretTuple te = walk (1 :: Int) (zipWith recoverKindedValue ks args) []
-                where (ks, n) = case k of
-                                  KTuple eks -> (eks, length eks)
-                                  _          -> error $ unlines [ "Impossible: Expected a tuple kind, but got: " ++ show k
-                                                                , "While trying to parse: " ++ show te
-                                                                ]
-
-                      -- | Convert a sexpr of n-tuple to constituent sexprs. Z3 and CVC4 differ here on how they
-                      -- present tuples, so we accommodate both:
-                      args = try te
-                        where -- Z3 way
-                              try (EApp (ECon f : as)) = case splitAt (T.length "mkSBVTuple") f of
-                                                             ("mkSBVTuple", c) | all isDigit c && read c == n && length as == n -> as
-                                                             _  -> bad
-                              -- CVC4 way
-                              try  (EApp (EApp [ECon "as", ECon f, _] : as)) = try (EApp (ECon f : as))
-                              try  _ = bad
-                              bad = error $ "Data.SBV.sexprToTuple: Impossible: Expected a constructor for " ++ show n ++ " tuple, but got: " ++ show te
-
-                      walk _ []           sofar = reverse sofar
-                      walk i (Just el:es) sofar = walk (i+1) es (cvVal el : sofar)
-                      walk i (Nothing:_)  _     = error $ unlines [ "Couldn't parse a tuple element at position " ++ show i
-                                                                  , "Kind: " ++ show k
-                                                                  , "Expr: " ++ show te
-                                                                  ]
-
-        -- SMaybe
-        interpretMaybe (KMaybe _)  (ECon "nothing_SBVMaybe")        = Nothing
-        interpretMaybe (KMaybe ek) (EApp [ECon "just_SBVMaybe", a]) = case recoverKindedValue ek a of
-                                                                        Just (CV _ v) -> Just v
-                                                                        Nothing       -> error $ unlines [ "Couldn't parse a maybe just value"
-                                                                                                         , "Kind: " ++ show ek
-                                                                                                         , "Expr: " ++ show a
-                                                                                                         ]
-        -- CVC4 puts in full ascriptions, handle those:
-        interpretMaybe _  (      EApp [ECon "as", ECon "nothing_SBVMaybe", _])     = Nothing
-        interpretMaybe mk (EApp [EApp [ECon "as", ECon "just_SBVMaybe",    _], a]) = interpretMaybe mk (EApp [ECon "just_SBVMaybe", a])
-
-        interpretMaybe _  other = error $ "Expected an SMaybe sexpr, but received: " ++ show (k, other)
-
-        -- SEither
-        interpretEither (KEither k1 _) (EApp [ECon "left_SBVEither",  a]) = case recoverKindedValue k1 a of
-                                                                              Just (CV _ v) -> Left v
-                                                                              Nothing       -> error $ unlines [ "Couldn't parse an either value on the left"
-                                                                                                               , "Kind: " ++ show k1
-                                                                                                               , "Expr: " ++ show a
-                                                                                                               ]
-        interpretEither (KEither _ k2) (EApp [ECon "right_SBVEither", b]) = case recoverKindedValue k2 b of
-                                                                              Just (CV _ v) -> Right v
-                                                                              Nothing       -> error $ unlines [ "Couldn't parse an either value on the right"
-                                                                                                               , "Kind: " ++ show k2
-                                                                                                               , "Expr: " ++ show b
-                                                                                                               ]
-
-        -- CVC4 puts full ascriptions:
-        interpretEither ek (EApp [EApp [ECon "as", ECon "left_SBVEither",  _], a]) = interpretEither ek (EApp [ECon "left_SBVEither", a])
-        interpretEither ek (EApp [EApp [ECon "as", ECon "right_SBVEither", _], b]) = interpretEither ek (EApp [ECon "right_SBVEither", b])
-
-        interpretEither _ other = error $ "Expected an SEither sexpr, but received: " ++ show (k, other)
-
-        -- Intervals, for dReal
-        interpretInterval expr = case expr of
-                                   EApp [ECon "interval", lo, hi] -> do vlo <- getBorder lo
-                                                                        vhi <- getBorder hi
-                                                                        pure $ CV KReal (CAlgReal (AlgInterval vlo vhi))
-                                   _                              -> Nothing
-          where getBorder (EApp [ECon "open",   v]) = recoverKindedValue KReal v >>= border OpenPoint
-                getBorder (EApp [ECon "closed", v]) = recoverKindedValue KReal v >>= border ClosedPoint
-                getBorder _                         = Nothing
-
-                border b (CV KReal (CAlgReal (AlgRational True v))) = pure $ b v
-                border _ other                                      = error $ "Data.SBV.interpretInterval.border: Expected a real-valued sexp, but received: " ++ show other
-
-        -- Essentially treat sets as functions, since we do allow for store associations
-        interpretArray k1 k2 expr = case parseSExprFunction expr of
-                                      Just (Right ascs) -> decode ascs
-                                      _                 -> tbd "Expected a set value, but couldn't decipher the solver output."
-
-           where tbd :: String -> a
-                 tbd w = error $ unlines [ ""
-                                         , "*** Data.SBV.interpretArray: Unable to process solver output."
-                                         , "***"
-                                         , "*** Kind    : " ++ show k
-                                         , "*** Received: " ++ show e
-                                         , "*** Reason  : " ++ w
-                                         , "***"
-                                         , "*** This is either a bug or something SBV currently does not support."
-                                         , "*** Please report this as a feature request!"
-                                         ]
-
-                 decode (args, d) = ArrayModel [(cvt k1 l, cvt k2 [r]) | (l, r) <- args] (cvt k2 [d])
-                   where cvt ek [v] = case recoverKindedValue ek v of
-                                         Just (CV _ x) -> x
-                                         _             -> tbd $ "Cannot convert value: " ++ show v
-                         cvt _ vs   = tbd $ "Unexpected function-like-value as array index" ++ show vs
-
--- | Generalization of 'Data.SBV.Control.getValueCV'
-getValueCV :: (MonadIO m, MonadQuery m) => Maybe Int -> SV -> m CV
-getValueCV mbi s
-  | kindOf s /= KReal
-  = getValueCVHelper mbi s
-  | True
-  = do cfg <- getConfig
-       if not (supportsApproxReals (capabilities (solver cfg)))
-          then getValueCVHelper mbi s
-          else do send True "(set-option :pp.decimal false)"
-                  rep1 <- getValueCVHelper mbi s
-                  send True   "(set-option :pp.decimal true)"
-                  send True $ "(set-option :pp.decimal_precision " ++ show (printRealPrec cfg) ++ ")"
-                  rep2 <- getValueCVHelper mbi s
-
-                  let bad = unexpected "getValueCV" "get-value" ("a real-valued binding for " ++ show s) Nothing (show (rep1, rep2)) Nothing
-
-                  case (rep1, rep2) of
-                    (CV KReal (CAlgReal a), CV KReal (CAlgReal b)) -> return $ CV KReal (CAlgReal (mergeAlgReals ("Cannot merge real-values for " ++ show s) a b))
-                    _                                              -> bad
-
--- | Retrieve value from the solver
-extractValue :: forall m. (MonadIO m, MonadQuery m) => Maybe Int -> String -> Kind -> m CV
-extractValue mbi nm k = do
-       let modelIndex = case mbi of
-                          Nothing -> ""
-                          Just i  -> " :model_index " ++ show i
-
-           cmd        = "(get-value (" ++ nm ++ ")" ++ modelIndex ++ ")"
-
-           bad = unexpected "get-value" cmd ("a value binding for kind: " ++ show k) Nothing
-
-       r <- ask cmd
-
-       let recover val = case recoverKindedValue k val of
-                           Just cv -> return cv
-                           Nothing -> bad r Nothing
-
-       parse r bad $ \case EApp [EApp [ECon v, val]] | v == nm -> recover val
-                           _                                   -> bad r Nothing
-
--- | Generalization of 'Data.SBV.Control.getUICVal'
-getUICVal :: forall m. (MonadIO m, MonadQuery m) => Maybe Int -> (String, (Bool, Maybe [String], SBVType)) -> m CV
-getUICVal mbi (nm, (_, _, t)) = case t of
-                                 SBVType [k] -> extractValue mbi nm k
-                                 _           -> error $ "SBV.getUICVal: Expected to be called on an uninterpeted value of a base type, received something else: " ++ show (nm, t)
-
--- | Generalization of 'Data.SBV.Control.getUIFunCVAssoc'
-getUIFunCVAssoc :: forall m. (MonadIO m, MonadQuery m) => Maybe Int -> (String, (Bool, Maybe [String], SBVType)) -> m (Either String ([([CV], CV)], CV))
-getUIFunCVAssoc mbi (nm, (isCurried, mbArgs, typ)) = do
-  let modelIndex = case mbi of
-                     Nothing -> ""
-                     Just i  -> " :model_index " ++ show i
-
-      cmd        = "(get-value (" ++ nm ++ ")" ++ modelIndex ++ ")"
-
-      bad        = unexpected "get-value" cmd "a function value" Nothing
-
-  r <- ask cmd
-
-  let (ats, rt) = case typ of
-                    SBVType as | length as > 1 -> (init as, last as)
-                    _                          -> error $ "Data.SBV.getUIFunCVAssoc: Expected a function type, got: " ++ show typ
-
-  let convert (vs, d) = (,) <$> mapM toPoint vs <*> toRes d
-      toPoint (as, v)
-         | length as == length ats = (,) <$> zipWithM recoverKindedValue ats as <*> toRes v
-         | True                    = error $ "Data.SBV.getUIFunCVAssoc: Mismatching type/value arity, got: " ++ show (as, ats)
-
-      toRes :: SExpr -> Maybe CV
-      toRes = recoverKindedValue rt
-
-      -- if we fail to parse, we'll return this answer as the string
-      fallBack = trimFunctionResponse r nm isCurried mbArgs
-
-      -- In case we end up in the pointwise scenario, boolify the result
-      -- as that's the only type we support here.
-      tryPointWise = do mbSExprs <- pointWiseExtract nm typ
-                        case mbSExprs of
-                          Nothing     -> pure $ Left fallBack
-                          Just sExprs -> pure $ maybe (Left fallBack) Right (convert sExprs)
-
-  parse r bad $ \case EApp [EApp [ECon o, e]] | o == nm -> case parseSExprFunction e of
-                                                             Just (Right assocs) | Just res <- convert assocs                 -> return (Right res)
-                                                                                 | True                                       -> tryPointWise
-
-                                                             Just (Left nm')     | nm == nm', let res = defaultKindedValue rt -> return (Right ([], res))
-                                                                                 | True                                       -> bad r Nothing
-
-                                                             Nothing                                                          -> tryPointWise
-
-                      _                                 -> bad r Nothing
-
--- | Generalization of 'Data.SBV.Control.checkSat'
-checkSat :: (MonadIO m, MonadQuery m) => m CheckSatResult
-checkSat = do cfg <- getConfig
-              checkSatUsing $ satCmd cfg
-
--- | Generalization of 'Data.SBV.Control.checkSatUsing'
-checkSatUsing :: (MonadIO m, MonadQuery m) => String -> m CheckSatResult
-checkSatUsing cmd = do let bad = unexpected "checkSat" cmd "one of sat/unsat/unknown" Nothing
-
-                           -- Sigh.. Ignore some of the pesky warnings. We only do it as an exception here.
-                           ignoreList = ["WARNING: optimization with quantified constraints is not supported"]
-
-                       r <- askIgnoring cmd ignoreList
-
-                       -- query for the precision if supported
-                       let getPrecision = do cfg <- getConfig
-                                             case supportsDeltaSat (capabilities (solver cfg)) of
-                                               Nothing -> pure Nothing
-                                               Just o  -> Just <$> ask o
-
-                       parse r bad $ \case ECon "sat"       -> return Sat
-                                           ECon "unsat"     -> return Unsat
-                                           ECon "unknown"   -> return Unk
-                                           ECon "delta-sat" -> DSat <$> getPrecision
-                                           _                -> bad r Nothing
-
--- | What are the top level inputs? Trackers are returned as top level existentials
-getTopLevelInputs :: (MonadIO m, MonadQuery m) => m UserInputs
-getTopLevelInputs = do State{rinps}                     <- queryState
-                       Inputs{userInputs, internInputs} <- liftIO $ readIORef rinps
-
-                       pure $ userInputs <> internInputs
-
--- | Get observables, i.e., those explicitly labeled by the user with a call to 'Data.SBV.observe'.
-getObservables :: (MonadIO m, MonadQuery m) => m [(Name, CV)]
-getObservables = do State{rObservables} <- queryState
-
-                    rObs <- liftIO $ readIORef rObservables
-
-                    -- This intentionally reverses the result; since 'rObs' stores in reversed order
-                    let walk []             !sofar = return sofar
-                        walk ((n, f, s):os) !sofar = do cv <- getValueCV Nothing s
-                                                        if f cv
-                                                          then walk os ((n, cv) : sofar)
-                                                          else walk os            sofar
-
-                    walk (F.toList rObs) []
-
--- | Get UIs, both constants and functions. This call returns both the before and after query ones.
--- Generalization of 'Data.SBV.Control.getUIs'.
-getUIs :: forall m. (MonadIO m, MonadQuery m) => m [(String, (Bool, Maybe [String], SBVType))]
-getUIs = do State{rUIMap, rDefns, rIncState} <- queryState
-            -- NB. no need to worry about new-defines, because we don't allow definitions once query mode starts
-            defines <- do allDefs <- io $ readIORef rDefns
-                          pure $ map fst allDefs
-
-            prior <- io $ readIORef rUIMap
-            new   <- io $ readIORef rIncState >>= readIORef . rNewUIs
-            return $ nub $ sort [p | p@(n, _) <- Map.toList prior ++ Map.toList new, n `notElem` defines]
-
--- | Return all satisfying models.
-getAllSatResult :: forall m. (MonadIO m, MonadQuery m, SolverContext m) => m AllSatResult
-getAllSatResult = do queryDebug ["*** Checking Satisfiability, all solutions.."]
-
-                     cfg <- getConfig
-                     unless (supportsCustomQueries (capabilities (solver cfg))) $
-                        error $ unlines [ ""
-                                        , "*** Data.SBV: Backend solver " ++ show (name (solver cfg)) ++ " does not support custom queries."
-                                        , "***"
-                                        , "*** Custom query support is needed for allSat functionality."
-                                        , "*** Please use a solver that supports this feature."
-                                        ]
-
-                     topState@State{rUsedKinds, rPartitionVars, rProgInfo} <- queryState
-
-                     progInfo <- liftIO $ readIORef rProgInfo
-                     ki       <- liftIO $ readIORef rUsedKinds
-
-                     allModelInputs    <- getTopLevelInputs
-                     allUninterpreteds <- getUIs
-                     partitionVars     <- liftIO $ readIORef rPartitionVars
-
-                      -- Functions have at least two kinds in their type and all components must be "interpreted"
-                     let allUiFuns = [u | allSatTrackUFs cfg                                              -- config says consider UIFs
-                                        , u@(nm, (_, _, SBVType as)) <- allUninterpreteds, length as > 1  -- get the function ones
-                                        , not (mustIgnoreVar cfg nm)                                      -- make sure they aren't explicitly ignored
-                                     ]
-
-                         allUiRegs = [u | u@(nm, (_, _, SBVType as)) <- allUninterpreteds, length as == 1 -- non-function ones
-                                        , not (mustIgnoreVar cfg nm)                                      -- make sure they aren't explicitly ignored
-                                     ]
-
-                         -- We can only "allSat" if all component types themselves are interpreted. (Otherwise
-                         -- there is no way to reflect back the values to the solver.)
-                         collectAcceptable []                                sofar = return sofar
-                         collectAcceptable ((nm, (_, _, t@(SBVType ats))):rest) sofar
-                           | not (any hasUninterpretedSorts ats)
-                           = collectAcceptable rest (nm : sofar)
-                           | True
-                           = do queryDebug [ "*** SBV.allSat: Uninterpreted function: " ++ nm ++ " :: " ++ show t
-                                           , "*** Will *not* be used in allSat considerations since its type"
-                                           , "*** has uninterpreted sorts present."
-                                           ]
-                                collectAcceptable rest sofar
-
-                     uiFuns <- reverse <$> collectAcceptable allUiFuns []
-                     _      <- collectAcceptable allUiRegs [] -- only done to get the queryDebug output. Actual result not needed/used
-
-                     -- If there are uninterpreted functions, arrange so that z3's pretty-printer flattens things out
-                     -- as cex's tend to get larger
-                     unless (null uiFuns) $
-                        let solverCaps = capabilities (solver cfg)
-                        in case supportsFlattenedModels solverCaps of
-                             Nothing   -> return ()
-                             Just cmds -> mapM_ (send True) cmds
-
-                     let usorts = [s | us@(KUserSort s _) <- Set.toAscList ki, isFree us]
-
-                     unless (null usorts) $ queryDebug [ "*** SBV.allSat: Uninterpreted sorts present: " ++ unwords usorts
-                                                       , "***             SBV will use equivalence classes to generate all-satisfying instances."
-                                                       ]
-
-                     -- Drop the things that are not model vars or internal
-                     let mkSVal nm@(getSV -> sv) = (SVal (kindOf sv) (Right (cache (const (return sv)))), nm)
-                     let extractVars :: S.Seq (SVal, NamedSymVar)
-                         extractVars = mkSVal <$> S.filter (not . mustIgnoreVar cfg . getUserName') allModelInputs
-
-                         vars :: S.Seq (SVal, NamedSymVar)
-                         vars = case partitionVars of
-                                  [] -> extractVars
-                                  pv -> mkSVal <$> S.filter (\k -> getUserName' k `elem` pv) allModelInputs
-
-                     -- We can go fast using the disjoint model trick if things are simple enough:
-                     --     - No uninterpreted functions (uninterpreted values are OK)
-                     --     - No uninterpreted sorts
-                     --     - No quantifiers
-                     --
-                     -- Why can't we support the above?
-                     --     - Uninterpreted functions: There is no (standard) way to define a function as a literal in SMTLib.
-                     --     Some solvers support lambda, but this isn't common/reliable yet.
-                     --     - Uninterpreted sort: There's no way to access the value the solver assigns to an uninterpreted sort.
-                     --     - Quantifiers: Too complicated!
-                     --
-                     -- So, if these two things are present, we go the "slow" route, by repeatedly rejecting the
-                     -- previous model and asking for a new one. If they don't exist (which is the common case anyhow)
-                     -- we use an idea due to z3 folks <http://theory.stanford.edu/%7Enikolaj/programmingz3.html#sec-blocking-evaluations>
-                     -- which splits the search space into disjoint models and can produce results much more quickly.
-                     let isSimple = null allUiFuns && null usorts && not (hasQuants progInfo)
-
-                         start = AllSatResult { allSatMaxModelCountReached  = False
-                                              , allSatSolverReturnedUnknown = False
-                                              , allSatSolverReturnedDSat    = False
-                                              , allSatResults               = []
-                                              }
-
-                     -- partition-variables are only supported if simple
-                     case partitionVars of
-                       [] -> pure ()
-                       xs -> unless isSimple $ error $ unlines [ ""
-                                                               , "Data.SBV: Unsupported complex allSat call in the presence of partition-variables"
-                                                               , ""
-                                                               , "Partition variables are only supported when there are no uninterpreted"
-                                                               , "functions or uninterpreted sorts."
-                                                               , ""
-                                                               , "Saw parition vars: " ++ unwords xs
-                                                               ]
-
-                     if isSimple
-                        then do let mkVar :: (String, (Bool, Maybe [String], SBVType)) -> IO (SVal, NamedSymVar)
-                                    mkVar (nm, (_, _, SBVType [k])) = do sv <- newExpr topState k (SBVApp (Uninterpreted nm) [])
-                                                                         let sval = SVal k $ Right $ cache $ \_ -> pure sv
-                                                                             nsv  = NamedSymVar sv (T.pack nm)
-                                                                         pure (sval, nsv)
-                                    mkVar nmt = error $ "Data.SBV: Impossible happened; allSat.mkVar. Unexpected: " ++ show nmt
-                                uiVars <- io $ S.fromList <$> mapM mkVar allUiRegs
-                                fastAllSat                                        allModelInputs (uiVars S.>< extractVars) (uiVars S.>< vars) cfg start
-                        else    loop       topState (allUiFuns, uiFuns) allUiRegs allModelInputs                                        vars  cfg start
-
-   where isFree (KUserSort _ Nothing) = True
-         isFree _                     = False
-
-         finalize cnt cfg sofar extra
-                = when (allSatPrintAlong cfg && not (null (allSatResults sofar))) $ do
-                           let msg 0 = "No solutions found."
-                               msg 1 = "This is the only solution."
-                               msg n = "Found " ++ show n ++ " different solutions."
-                           io . putStrLn $ msg (cnt - 1)
-                           case extra of
-                             Nothing -> pure ()
-                             Just m  -> io $ putStrLn m
-
-         fastAllSat :: S.Seq NamedSymVar -> S.Seq (SVal, NamedSymVar) -> S.Seq (SVal, NamedSymVar) -> SMTConfig -> AllSatResult -> m AllSatResult
-         fastAllSat allInputs extractVars vars cfg start = do
-                result <- io $ newIORef (0, start, False, Nothing)
-                go result vars
-                (found, sofar, _, extra) <- io $ readIORef result
-                finalize (found+1) cfg sofar extra
-                pure sofar
-
-           where haveEnough have = case allSatMaxModelCount cfg of
-                                     Just maxModels -> have >= maxModels
-                                     _              -> False
-
-                 go :: IORef (Int, AllSatResult, Bool, Maybe String) -> S.Seq (SVal, NamedSymVar) -> m ()
-                 go finalResult = walk True
-                   where shouldContinue = do (have, _, exitLoop, _) <- io $ readIORef finalResult
-                                             pure $ not (exitLoop || haveEnough have)
-
-                         walk :: Bool -> S.Seq (SVal, NamedSymVar) -> m ()
-                         walk firstRun terms
-                           | not firstRun && S.null terms
-                           = pure ()
-                           | True
-                           = do mbCont <- do (have, sofar, exitLoop, _) <- io $ readIORef finalResult
-                                             if exitLoop
-                                                then pure Nothing
-                                                else case allSatMaxModelCount cfg of
-                                                       Just maxModels
-                                                         | have >= maxModels -> do unless (allSatMaxModelCountReached sofar) $ do
-                                                                                      queryDebug ["*** Maximum model count request of " ++ show maxModels ++ " reached, stopping the search."]
-                                                                                      when (allSatPrintAlong cfg) $ io $ putStrLn "Search stopped since model count request was reached."
-                                                                                      io $ modifyIORef' finalResult $ \(h, s, _, m) -> (h, s{ allSatMaxModelCountReached = True }, True, m)
-                                                                                   pure Nothing
-                                                       _                     -> pure $ Just $ have+1
-
-                                case mbCont of
-                                  Nothing  -> pure ()
-                                  Just cnt -> do
-                                    queryDebug ["Fast allSat, Looking for solution " ++ show cnt]
-
-                                    cs <- checkSat
-
-                                    case cs of
-                                      Unsat  -> pure ()
-
-                                      Unk    -> do let m = "Solver returned unknown, terminating query."
-                                                   queryDebug ["*** " ++ m]
-                                                   io $ modifyIORef' finalResult $ \(h, s, _, _) -> (h, s{allSatSolverReturnedUnknown = True}, True, Just ("[" ++ m ++ "]"))
-
-                                      DSat _ -> do let m = "Solver returned delta-sat, terminating query."
-                                                   queryDebug ["*** " ++ m]
-                                                   io $ modifyIORef' finalResult $ \(h, s, _, _) -> (h, s{allSatSolverReturnedDSat = True}, True, Just ("[" ++ m ++ "]"))
-
-                                      Sat    -> do assocs <- mapM (\(sval, NamedSymVar sv n) -> do !cv <- getValueCV Nothing sv
-                                                                                                   return (sv, (n, (sval, cv)))) extractVars
-
-                                                   bindings <- let grab i@(getSV -> sv) = case lookupInput fst sv assocs of
-                                                                                            Just (_, (_, (_, cv))) -> return (i, cv)
-                                                                                            Nothing                -> do !cv <- getValueCV Nothing sv
-                                                                                                                         return (i, cv)
-                                                               in if validationRequested cfg
-                                                                  then Just <$> mapM grab allInputs
-                                                                  else return Nothing
-
-                                                   obsvs <- getObservables
-
-                                                   let lassocs = F.toList assocs
-                                                       model   = SMTModel { modelObjectives = []
-                                                                          , modelBindings   = F.toList <$> bindings
-                                                                          , modelAssocs     =    (first T.unpack <$> sortOn fst obsvs)
-                                                                                              <> [(T.unpack n, cv) | (_, (n, (_, cv))) <- lassocs]
-                                                                          , modelUIFuns     = []
-                                                                          }
-                                                       currentResult = Satisfiable cfg model
-
-                                                   io $ modifyIORef' finalResult $ \(h, s, e, m) -> let h' = h+1 in h' `seq` (h', s{allSatResults = currentResult : allSatResults s}, e, m)
-
-                                                   when (allSatPrintAlong cfg) $ do
-                                                        io $ putStrLn $ "Solution #" ++ show cnt ++ ":"
-                                                        io $ putStrLn $ showModel cfg model
-
-                                                   let findVal :: (SVal, NamedSymVar) -> (SVal, CV)
-                                                       findVal (_, NamedSymVar sv nm) = case F.toList (S.filter (\(sv', _) -> sv == sv') assocs) of
-                                                                                           [(_, (_, scv))] -> scv
-                                                                                           _               -> error $ "Data.SBV: Cannot uniquely determine " ++ show nm ++ " in " ++ show assocs
-
-                                                       cstr :: Bool -> (SVal, CV) -> m ()
-                                                       cstr shouldReject (sv, cv) = constrain (SBV $ mkEq (kindOf sv) sv (SVal (kindOf sv) (Left cv)) :: SBool)
-                                                         where mkEq :: Kind -> SVal -> SVal -> SVal
-                                                               mkEq k a b
-                                                                | isDouble k || isFloat k || isFP k
-                                                                = if shouldReject
-                                                                     then svNot  (a `fpEq` b)
-                                                                     else         a `fpEq` b
-                                                                | True
-                                                                = if shouldReject
-                                                                     then a `svNotEqual` b
-                                                                     else a `svEqual`    b
-
-                                                               fpEq a b = SVal KBool $ Right $ cache r
-                                                                   where r st = do sva <- svToSV st a
-                                                                                   svb <- svToSV st b
-                                                                                   newExpr st KBool (SBVApp (IEEEFP FP_ObjEqual) [sva, svb])
-
-                                                       reject, accept :: (SVal, NamedSymVar) -> m ()
-                                                       reject = cstr True  . findVal
-                                                       accept = cstr False . findVal
-
-                                                       scope :: (SVal, NamedSymVar) -> S.Seq (SVal, NamedSymVar) -> m () -> m ()
-                                                       scope cur pres c = do
-                                                                send True "(push 1)"
-                                                                reject cur
-                                                                mapM_ accept pres
-                                                                r <- c
-                                                                send True "(pop 1)"
-                                                                pure r
-
-                                                   forM_ [0 .. length terms - 1] $ \i -> do
-                                                        sc <- shouldContinue
-                                                        when sc $ do case S.splitAt i terms of
-                                                                       (pre, rest@(cur S.:<| _)) -> scope cur pre $ walk False rest
-                                                                       _                         -> error "Data.SBV.allSat: Impossible happened, ran out of terms!"
-
-         -- All sat loop. This is slower, as it implements the reject-the-previous model and loop around logic. But
-         -- it can handle uninterpreted sorts; so we keep it here as a fall-back.
-         loop topState (allUiFuns, uiFunsToReject) allUiRegs allInputs vars cfg = go (1::Int)
-           where go :: Int -> AllSatResult -> m AllSatResult
-                 go !cnt !sofar
-                   | Just maxModels <- allSatMaxModelCount cfg, cnt > maxModels
-                   = do queryDebug ["*** Maximum model count request of " ++ show maxModels ++ " reached, stopping the search."]
-                        when (allSatPrintAlong cfg) $ io $ putStrLn "Search stopped since model count request was reached."
-                        return $! sofar { allSatMaxModelCountReached = True }
-                   | True
-                   = do queryDebug ["Looking for solution " ++ show cnt]
-
-                        cs <- checkSat
-
-                        let endMsg = finalize cnt cfg sofar
-
-                        case cs of
-                          Unsat  -> do endMsg Nothing
-                                       return sofar
-
-                          Unk    -> do let m = "Solver returned unknown, terminating query."
-                                       queryDebug ["*** " ++ m]
-                                       endMsg $ Just $ "[" ++ m ++ "]"
-                                       return sofar{ allSatSolverReturnedUnknown = True }
-
-                          DSat _ -> do let m = "Solver returned delta-sat, terminating query."
-                                       queryDebug ["*** " ++ m]
-                                       endMsg $ Just $ "[" ++ m ++ "]"
-                                       return sofar{ allSatSolverReturnedDSat = True }
-
-                          Sat    -> do assocs <- mapM (\(sval, NamedSymVar sv n) -> do !cv <- getValueCV Nothing sv
-                                                                                       return (sv, (n, (sval, cv)))) vars
-
-                                       let getUIFun ui@(nm, (isCurried, _, t)) = do cvs <- getUIFunCVAssoc Nothing ui
-                                                                                    return (nm, (isCurried, t, cvs))
-                                       uiFunVals <- mapM getUIFun allUiFuns
-
-                                       uiRegVals <- mapM (\ui@(nm, _) -> (nm,) <$> getUICVal Nothing ui) allUiRegs
-
-                                       obsvs <- getObservables
-
-                                       bindings <- let grab i@(getSV -> sv) = case lookupInput fst sv assocs of
-                                                                                Just (_, (_, (_, cv))) -> return (i, cv)
-                                                                                Nothing                -> do !cv <- getValueCV Nothing sv
-                                                                                                             return (i, cv)
-                                                   in if validationRequested cfg
-                                                         then Just <$> mapM grab allInputs
-                                                         else return Nothing
-
-                                       let model = SMTModel { modelObjectives = []
-                                                            , modelBindings   = F.toList <$> bindings
-                                                            , modelAssocs     =    uiRegVals
-                                                                                <> (first T.unpack <$> sortOn fst obsvs)
-                                                                                <> [(T.unpack n, cv) | (_, (n, (_, cv))) <- F.toList assocs]
-                                                            , modelUIFuns     = uiFunVals
-                                                            }
-                                           m = Satisfiable cfg model
-
-                                           (interpreteds, uninterpreteds) = S.partition (not . isFree . kindOf . fst) (fmap (snd . snd) assocs)
-
-                                           interpretedRegUis = filter (not . isFree . kindOf . snd) uiRegVals
-
-                                           interpretedRegUiSVs = [(cvt n (kindOf cv), cv) | (n, cv) <- interpretedRegUis]
-                                             where cvt :: String -> Kind -> SVal
-                                                   cvt nm k = SVal k $ Right $ cache r
-                                                     where r st = newExpr st k (SBVApp (Uninterpreted nm) [])
-
-                                           -- For each interpreted variable, figure out the model equivalence
-                                           -- NB. When the kind is floating, we *have* to be careful, since +/- zero, and NaN's
-                                           -- and equality don't get along!
-                                           interpretedEqs :: [SVal]
-                                           interpretedEqs = [mkNotEq (kindOf sv) sv (SVal (kindOf sv) (Left cv)) | (sv, cv) <- interpretedRegUiSVs <> F.toList interpreteds]
-                                              where mkNotEq k a b
-                                                     | isDouble k || isFloat k || isFP k
-                                                     = svNot (a `fpEq` b)
-                                                     | True
-                                                     = a `svNotEqual` b
-
-                                                    fpEq a b = SVal KBool $ Right $ cache r
-                                                        where r st = do sva <- svToSV st a
-                                                                        svb <- svToSV st b
-                                                                        newExpr st KBool (SBVApp (IEEEFP FP_ObjEqual) [sva, svb])
-
-                                           -- For each uninterpreted constant, use equivalence class
-                                           uninterpretedEqs :: [SVal]
-                                           uninterpretedEqs = concatMap pwDistinct         -- Assert that they are pairwise distinct
-                                                            . filter (\l -> length l > 1)  -- Only need this class if it has at least two members
-                                                            . map (map fst)                -- throw away values, we only need svals
-                                                            . groupBy ((==) `on` snd)      -- make sure they belong to the same sort and have the same value
-                                                            . sortOn snd                   -- sort them according to their CV (i.e., sort/value)
-                                                            $ F.toList uninterpreteds
-                                             where pwDistinct :: [SVal] -> [SVal]
-                                                   pwDistinct ss = [x `svNotEqual` y | (x:ys) <- tails ss, y <- ys]
-
-                                           -- For each uninterpreted function, create a disqualifying equation
-                                           -- We do this rather brute-force, since we need to create a new function
-                                           -- and do an existential assertion.
-                                           uninterpretedReject :: Maybe [String]
-                                           uninterpretedFuns   :: [String]
-                                           (uninterpretedReject, uninterpretedFuns) = (uiReject, concat defs)
-                                               where uiReject = case rejects of
-                                                                  []  -> Nothing
-                                                                  xs  -> Just xs
-
-                                                     (rejects, defs) = unzip [mkNotEq ui | ui@(nm, _) <- uiFunVals, nm `elem` uiFunsToReject]
-
-                                                     -- Otherwise, we have things to refute, go for it if we have a good interpretation for it
-                                                     mkNotEq (nm, (_, typ, Left def)) =
-                                                        error $ unlines [
-                                                            ""
-                                                          , "*** allSat: Unsupported: Building a rejecting instance for:"
-                                                          , "***"
-                                                          , "***     " ++ nm ++ " :: " ++ show typ
-                                                          , "***     " ++ def
-                                                          , "***"
-                                                          , "*** At this time, SBV cannot compute allSat when the model has a non-table definition."
-                                                          , "***"
-                                                          , "*** You can ignore specific functions via the 'isNonModelVar' filter:"
-                                                          , "***"
-                                                          , "***    allSatWith z3{isNonModelVar = (`elem` [" ++ show nm ++ "])} ..."
-                                                          , "***"
-                                                          , "*** Or you can ignore all uninterpreted functions for all-sat purposes using the 'allSatTrackUFs' parameter:"
-                                                          , "***"
-                                                          , "***    allSatWith z3{allSatTrackUFs = False} ..."
-                                                          , "***"
-                                                          , "*** You can see the response from the solver by running with the '{verbose = True}' option."
-                                                          , "***"
-                                                          , "*** NB. If this is a use case you'd like SBV to support, please get in touch!"
-                                                          ]
-                                                     mkNotEq (nm, (_, SBVType ts, Right vs)) = (reject, def ++ dif)
-                                                       where nm' = nm ++ "_model" ++ show cnt
-
-                                                             reject = nm' ++ "_reject"
-
-                                                             -- rounding mode doesn't matter here, just pick one
-                                                             scv = cvToSMTLib RoundNearestTiesToEven
-
-                                                             (ats, rt) = (init ts, last ts)
-
-                                                             args = unwords ["(x!" ++ show i ++ " " ++ smtType t ++ ")" | (t, i) <- zip ats [(0::Int)..]]
-                                                             res  = smtType rt
-
-                                                             params = ["x!" ++ show i | (_, i) <- zip ats [(0::Int)..]]
-
-                                                             uparams = unwords params
-
-                                                             chain (vals, fallThru) = walk vals
-                                                               where walk []               = ["   " ++ scv fallThru ++ replicate (length vals) ')']
-                                                                     walk ((as, r) : rest) = ("   (ite " ++ cond as ++ " " ++ scv r) :  walk rest
-
-                                                                     cond as = "(and " ++ unwords (zipWith eq params as) ++ ")"
-                                                                     eq p a  = "(= " ++ p ++ " " ++ scv a ++ ")"
-
-                                                             def =    ("(define-fun " ++ nm' ++ " (" ++ args ++ ") " ++ res)
-                                                                   :  chain vs
-                                                                   ++ [")"]
-
-                                                             pad = replicate (1 + length nm' - length nm) ' '
-
-                                                             dif = [ "(define-fun " ++  reject ++ " () Bool"
-                                                                   , "   (exists (" ++ args ++ ")"
-                                                                   , "           (distinct (" ++ nm  ++ pad ++ uparams ++ ")"
-                                                                   , "                     (" ++ nm' ++ " " ++ uparams ++ "))))"
-                                                                   ]
-
-                                           eqs = interpretedEqs ++ uninterpretedEqs
-
-                                           disallow = case eqs of
-                                                        [] -> Nothing
-                                                        _  -> Just $ SBV $ foldr1 svOr eqs
-
-                                       when (allSatPrintAlong cfg) $ do
-                                         io $ putStrLn $ "Solution #" ++ show cnt ++ ":"
-                                         io $ putStrLn $ showModel cfg model
-
-                                       let resultsSoFar = sofar { allSatResults = m : allSatResults sofar }
-
-                                           -- This is clunky, but let's not generate a rejector unless we really need it
-                                           needMoreIterations
-                                                 | Just maxModels <- allSatMaxModelCount cfg, (cnt+1) > maxModels = False
-                                                 | True                                                           = True
-
-                                       -- Send function disequalities, if any:
-                                       if not needMoreIterations
-                                          then go (cnt+1) resultsSoFar
-                                          else do let uiFunRejector   = "uiFunRejector_model_" ++ show cnt
-                                                      header          = "define-fun " ++ uiFunRejector ++ " () Bool "
-
-                                                      defineRejector []     = return ()
-                                                      defineRejector [x]    = send True $ "(" ++ header ++ x ++ ")"
-                                                      defineRejector (x:xs) = mapM_ (send True) $ mergeSExpr $  ("(" ++ header)
-                                                                                                             :  ("        (or " ++ x)
-                                                                                                             :  ["            " ++ e | e <- xs]
-                                                                                                             ++ ["        ))"]
-                                                  rejectFuncs <- case uninterpretedReject of
-                                                                   Nothing -> return Nothing
-                                                                   Just fs -> do mapM_ (send True) $ mergeSExpr uninterpretedFuns
-                                                                                 defineRejector fs
-                                                                                 return $ Just uiFunRejector
-
-                                                  -- send the disallow clause and the uninterpreted rejector:
-                                                  case (disallow, rejectFuncs) of
-                                                     (Nothing, Nothing) -> pure resultsSoFar
-                                                     (Just d,  Nothing) -> do constrain d
-                                                                              go (cnt+1) resultsSoFar
-                                                     (Nothing, Just f)  -> do send True $ "(assert " ++ f ++ ")"
-                                                                              go (cnt+1) resultsSoFar
-                                                     (Just d,  Just f)  -> -- This is where it gets ugly. We have an SBV and a string and we need to "or" them.
-                                                                           -- But we need a way to force 'd' to be produced. So, go ahead and force it:
-                                                                           do constrain $ d .=> d  -- NB: Redundant, but it makes sure the corresponding constraint gets shown
-                                                                              svd <- io $ svToSV topState (unSBV d)
-                                                                              send True $ "(assert (or " ++ f ++ " " ++ show svd ++ "))"
-                                                                              go (cnt+1) resultsSoFar
-
--- | Generalization of 'Data.SBV.Control.getUnsatAssumptions'
-getUnsatAssumptions :: (MonadIO m, MonadQuery m) => [String] -> [(String, a)] -> m [a]
-getUnsatAssumptions originals proxyMap = do
-        let cmd = "(get-unsat-assumptions)"
-
-            bad = unexpected "getUnsatAssumptions" cmd "a list of unsatisfiable assumptions"
-                           $ Just [ "Make sure you use:"
-                                  , ""
-                                  , "       setOption $ ProduceUnsatAssumptions True"
-                                  , ""
-                                  , "to make sure the solver is ready for producing unsat assumptions,"
-                                  , "and that there is a model by first issuing a 'checkSat' call."
-                                  ]
-
-            fromECon (ECon s) = Just s
-            fromECon _        = Nothing
-
-        r <- ask cmd
-
-        -- If unsat-cores are enabled, z3 might end-up printing an assumption that wasn't
-        -- in the original list of assumptions for `check-sat-assuming`. So, we walk over
-        -- and ignore those that weren't in the original list, and put a warning for those
-        -- we couldn't find.
-        let walk []     sofar = return $ reverse sofar
-            walk (a:as) sofar = case a `lookup` proxyMap of
-                                  Just v  -> walk as (v:sofar)
-                                  Nothing -> do queryDebug [ "*** In call to 'getUnsatAssumptions'"
-                                                           , "***"
-                                                           , "***    Unexpected assumption named: " ++ show a
-                                                           , "***    Was expecting one of       : " ++ show originals
-                                                           , "***"
-                                                           , "*** This can happen if unsat-cores are also enabled. Ignoring."
-                                                           ]
-                                                walk as sofar
-
-        parse r bad $ \case
-           EApp es | Just xs <- mapM fromECon es -> walk xs []
-           _                                     -> bad r Nothing
-
--- | Timeout a query action, typically a command call to the underlying SMT solver.
--- The duration is in microseconds (@1\/10^6@ seconds). If the duration
--- is negative, then no timeout is imposed. When specifying long timeouts, be careful not to exceed
--- @maxBound :: Int@. (On a 64 bit machine, this bound is practically infinite. But on a 32 bit
--- machine, it corresponds to about 36 minutes!)
---
--- Semantics: The call @timeout n q@ causes the timeout value to be applied to all interactive calls that take place
--- as we execute the query @q@. That is, each call that happens during the execution of @q@ gets a separate
--- time-out value, as opposed to one timeout value that limits the whole query. This is typically the intended behavior.
--- It is advisable to apply this combinator to calls that involve a single call to the solver for
--- finer control, as opposed to an entire set of interactions. However, different use cases might call for different scenarios.
---
--- If the solver responds within the time-out specified, then we continue as usual. However, if the backend solver times-out
--- using this mechanism, there is no telling what the state of the solver will be. Thus, we raise an error in this case.
-timeout :: (MonadIO m, MonadQuery m) => Int -> m a -> m a
-timeout n q = do modifyQueryState (\qs -> qs {queryTimeOutValue = Just n})
-                 r <- q
-                 modifyQueryState (\qs -> qs {queryTimeOutValue = Nothing})
-                 return r
-
--- | Bail out if a parse goes bad
-parse :: String -> (String -> Maybe [String] -> a) -> (SExpr -> a) -> a
-parse r fCont sCont = case parseSExpr r of
-                        Left  e   -> fCont r (Just [e])
-                        Right res -> sCont res
-
--- | Generalization of 'Data.SBV.Control.unexpected'
-unexpected :: (MonadIO m, MonadQuery m) => String -> String -> String -> Maybe [String] -> String -> Maybe [String] -> m a
-unexpected ctx sent expected mbHint received mbReason = do
-        -- empty the response channel first
-        extras <- retrieveResponse "terminating upon unexpected response" (Just 5000000)
-
-        cfg <- getConfig
-
-        let exc = SBVException { sbvExceptionDescription = "Unexpected response from the solver, context: " ++ ctx
-                               , sbvExceptionSent        = Just sent
-                               , sbvExceptionExpected    = Just expected
-                               , sbvExceptionReceived    = Just received
-                               , sbvExceptionStdOut      = Just $ unlines extras
-                               , sbvExceptionStdErr      = Nothing
-                               , sbvExceptionExitCode    = Nothing
-                               , sbvExceptionConfig      = cfg
-                               , sbvExceptionReason      = mbReason
-                               , sbvExceptionHint        = mbHint
-                               }
-
-        io $ C.throwIO exc
-
--- | Convert a query result to an SMT Problem
-runProofOn :: SBVRunMode -> QueryContext -> [String] -> Result -> SMTProblem
-runProofOn rm context comments res@(Result progInfo ki _qcInfo _observables _codeSegs is consts tbls uis defns pgm cstrs _assertions outputs) =
-     let (config, isSat, isSafe, isSetup) = case rm of
-                                              SMTMode _ stage s c -> (c, s, isSafetyCheckingIStage stage, isSetupIStage stage)
-                                              _                   -> error $ "runProofOn: Unexpected run mode: " ++ show rm
-
-         o | isSafe = trueSV
-           | True   = case outputs of
-                        []  | isSetup -> trueSV
-                        [so]          -> case so of
-                                           SV KBool _ -> so
-                                           _          -> error $ unlines [ "Impossible happened, non-boolean output: " ++ show so
-                                                                         , "Detected while generating the trace:\n" ++ show res
-                                                                         ]
-                        os  -> error $ unlines [ "User error: Multiple output values detected: " ++ show os
-                                               , "Detected while generating the trace:\n" ++ show res
-                                               , "*** Check calls to \"output\", they are typically not needed!"
-                                               ]
-
-     in SMTProblem { smtLibPgm = toSMTLib config context progInfo ki isSat comments is consts tbls uis defns pgm cstrs o }
-
--- | Generalization of 'Data.SBV.Control.executeQuery'
-executeQuery :: forall m a. ExtractIO m => QueryContext -> QueryT m a -> SymbolicT m a
-executeQuery queryContext (QueryT userQuery) = do
-     st <- symbolicEnv
-     rm <- liftIO $ readIORef (runMode st)
-
-     -- Make sure the phases match:
-     () <- liftIO $ case (queryContext, rm) of
-                      (QueryInternal, _)                                -> return ()  -- no worries, internal
-                      (QueryExternal, SMTMode QueryExternal ISetup _ _) -> return () -- legitimate runSMT call
-                      _                                                 -> invalidQuery rm
-
-     case rm of
-        -- Transitioning from setup
-        SMTMode qc stage isSAT cfg | not (isRunIStage stage) -> do
-
-                  let slvr    = solver cfg
-                      backend = engine slvr
-
-                  -- make sure if we have dsat precision, then solver supports it
-                  let dsatOK =  isNothing (dsatPrecision cfg)
-                             || isJust    (supportsDeltaSat (capabilities slvr))
-
-                  unless dsatOK $ error $ unlines
-                                     [ ""
-                                     , "*** Data.SBV: Delta-sat precision is specified."
-                                     , "***           But the chosen solver (" ++ show (name slvr) ++ ") does not support"
-                                     , "***           delta-satisfiability."
-                                     ]
-
-                  res     <- liftIO $ extractSymbolicSimulationState st
-                  setOpts <- liftIO $ reverse <$> readIORef (rSMTOptions st)
-
-                  let SMTProblem{smtLibPgm} = runProofOn rm queryContext [] res
-                      cfg' = cfg { solverSetOptions = solverSetOptions cfg ++ setOpts }
-                      pgm  = smtLibPgm cfg'
-
-                  liftIO $ writeIORef (runMode st) $ SMTMode qc IRun isSAT cfg
-
-                  let terminateSolver maybeForwardedException = do
-                         qs <- readIORef $ rQueryState st
-                         case qs of
-                           Nothing                         -> return ()
-                           Just QueryState{queryTerminate} -> queryTerminate maybeForwardedException
-
-                  lift $ join $ liftIO $ C.mask $ \restore -> do
-                    r <- restore (extractIO $ join $ liftIO $ backend cfg' st (show pgm) $ extractIO . runReaderT userQuery)
-                          `C.catch` \e -> terminateSolver (Just e) >> C.throwIO (e :: C.SomeException)
-                    terminateSolver Nothing
-                    return r
-
-        -- Already in a query, in theory we can just continue, but that causes use-case issues
-        -- so we reject it. TODO: Review if we should actually support this. The issue arises with
-        -- expressions like this:
-        --
-        -- In the following t0's output doesn't get recorded, as the output call is too late when we get
-        -- here. (The output field isn't "incremental.") So, t0/t1 behave differently!
-        --
-        --   t0 = satWith z3{verbose=True, transcript=Just "t.smt2"} $ query (return (false::SBool))
-        --   t1 = satWith z3{verbose=True, transcript=Just "t.smt2"} $ ((return (false::SBool)) :: Predicate)
-        --
-        -- Also, not at all clear what it means to go in an out of query mode:
-        --
-        -- r = runSMTWith z3{verbose=True} $ do
-        --         a' <- sInteger "a"
-        --
-        --        (a, av) <- query $ do _ <- checkSat
-        --                              av <- getValue a'
-        --                              return (a', av)
-        --
-        --        liftIO $ putStrLn $ "Got: " ++ show av
-        --        -- constrain $ a .> literal av + 1      -- Can't do this since we're "out" of query. Sigh.
-        --
-        --        bv <- query $ do constrain $ a .> literal av + 1
-        --                         _ <- checkSat
-        --                         getValue a
-        --
-        --        return $ a' .== a' + 1
-        --
-        -- This would be one possible implementation, alas it has the problems above:
-        --
-        --    SMTMode IRun _ _ -> liftIO $ evalStateT userQuery st
-        --
-        -- So, we just reject it.
-
-        SMTMode _ IRun _ _ -> error $ unlines [ ""
-                                              , "*** Data.SBV: Unsupported nested query is detected."
-                                              , "***"
-                                              , "*** Please group your queries into one block. Note that this"
-                                              , "*** can also arise if you have a call to 'query' not within 'runSMT'"
-                                              , "*** For instance, within 'sat'/'prove' calls with custom user queries."
-                                              , "*** The solution is to do the sat/prove part in the query directly."
-                                              , "***"
-                                              , "*** While multiple/nested queries should not be necessary in general,"
-                                              , "*** please do get in touch if your use case does require such a feature,"
-                                              , "*** to see how we can accommodate such scenarios."
-                                              ]
-
-        -- Otherwise choke!
-        _ -> invalidQuery rm
-
-  where invalidQuery rm = error $ unlines [ ""
-                                          , "*** Data.SBV: Invalid query call."
-                                          , "***"
-                                          , "***   Current mode: " ++ show rm
-                                          , "***"
-                                          , "*** Query calls are only valid within runSMT/runSMTWith calls,"
-                                          , "*** and each call to runSMT should have only one query call inside."
-                                          ]
-
-{- HLint ignore module          "Reduce duplication" -}
-{- HLint ignore getAllSatResult "Use forM_"          -}
+{-# LANGUAGE FlexibleInstances      #-}
+{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE InstanceSigs           #-}
+{-# LANGUAGE LambdaCase             #-}
+{-# LANGUAGE NamedFieldPuns         #-}
+{-# LANGUAGE OverloadedStrings      #-}
+{-# LANGUAGE RankNTypes             #-}
+{-# LANGUAGE ScopedTypeVariables    #-}
+{-# LANGUAGE TupleSections          #-}
+{-# LANGUAGE TypeApplications       #-}
+{-# LANGUAGE ViewPatterns           #-}
+
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
+
+module Data.SBV.Control.Utils (
+       io
+     , ask, send, getValue, getFunction
+     , getValueCV, getUICVal, getUIFunCVAssoc, getUnsatAssumptions
+     , SMTFunction(..), getQueryState, modifyQueryState, getConfig, getObjectives, getUIs
+     , getSBVAssertions, getObservables
+     , checkSat, checkSatUsing, getAllSatResult
+     , inNewContext, freshVar, freshVar_
+     , getTopLevelInputs, parse, unexpected
+     , timeout, queryDebug, retrieveResponse, runProofOn, executeQuery
+     , startOptimizer, getObjectiveValues, getModel, getModelAtIndex
+     ) where
+
+import Data.List  (sortOn, partition, groupBy, tails, intercalate, isPrefixOf, isSuffixOf)
+
+import Data.Char      (isPunctuation, isSpace, isDigit)
+import Data.Function  (on)
+import Data.Bifunctor (first)
+
+import Data.Proxy
+
+import qualified Data.Foldable      as F (toList, for_)
+import qualified Data.Map.Strict    as Map
+import qualified Data.Set           as Set  (empty, fromList, toAscList)
+import qualified Data.Sequence      as S
+import qualified Data.Text          as T
+
+import Control.Monad            (join, unless, zipWithM, when, replicateM)
+import Control.Monad.IO.Class   (MonadIO, liftIO)
+import Control.Monad.Trans      (lift)
+import Control.Monad.Reader     (runReaderT)
+
+import Data.Maybe (isNothing, isJust, catMaybes, listToMaybe)
+
+import Data.IORef (readIORef, writeIORef, IORef, newIORef, modifyIORef')
+
+import Data.Time (getZonedTime)
+import Data.Ratio
+
+import Data.SBV.Core.Data     ( SV(..), trueSV, falseSV, CV(..), trueCV, falseCV, SBV, sbvToSV, kindOf, Kind(..)
+                              , HasKind(..), mkConstCV, CVal(..), SMTResult(..)
+                              , NamedSymVar, SMTConfig(..), SMTModel(..)
+                              , QueryState(..), SVal(..), cache
+                              , newExpr, SBVExpr(..), Op(..), FPOp(..), SBV(..)
+                              , SolverContext(..), SBool, Objective(..), SolverCapabilities(..), capabilities
+                              , Result(..), SMTProblem(..), trueSV, SymVal(..), SBVPgm(..), SMTSolver(..), SBVRunMode(..)
+                              , SBVType(..), forceSVArg, (.=>)
+                              , RCSet(..), QuantifiedBool(..), ArrayModel(..), SInfo(..), getSInfo
+                              , OptimizeStyle(..), GeneralizedCV(..), ExtCV(..)
+                              )
+
+import Data.SBV.Core.Symbolic ( IncState(..), withNewIncState, State(..), svToSV, symbolicEnv, SymbolicT
+                              , MonadQuery(..), QueryContext(..), VarContext(..)
+                              , registerLabel, svMkSymVar, validationRequested
+                              , isSafetyCheckingIStage, isSetupIStage, isRunIStage, IStage(..), QueryT(..)
+                              , extractSymbolicSimulationState, MonadSymbolic(..)
+                              , UserInputs, getSV, NamedSymVar(..), lookupInput, getUserName, getUserName'
+                              , Name, CnstMap, Inputs(..), ProgInfo(..)
+                              , mustIgnoreVar, newInternalVariable, Penalty(..), smtLibPgmText, registerKind, mkNewState
+                              )
+
+import Data.SBV.Core.AlgReals    (mergeAlgReals, AlgReal(..), RealPoint(..))
+import Data.SBV.Core.SizedFloats (fpZero, fpFromInteger, fpFromFloat, fpFromDouble)
+import Data.SBV.Core.Kind        (smtType, hasUninterpretedSorts, expandKinds, isSomeKindOfFloat, substituteADTVars)
+import Data.SBV.Core.Operations  (svNot, svNotEqual, svOr, svEqual)
+
+import Data.SBV.SMT.SMT     (showModel, parseCVs, SatModel, AllSatResult(..), OptimizeResult(..))
+import Data.SBV.SMT.SMTLib  (toIncSMTLib, toSMTLib)
+import Data.SBV.SMT.SMTLib2 (setSMTOption)
+import Data.SBV.SMT.Utils   ( showTimeoutValue, addAnnotations, alignPlain, debug
+                            , mergeSExpr, SBVException(..), recordTranscript, TranscriptMsg(..)
+                            )
+
+import Data.SBV.Utils.ExtractIO
+import Data.SBV.Utils.Lib       (qfsToString, unBar, mapToSortedList, showText)
+import Data.SBV.Utils.SExpr
+import Data.SBV.Utils.PrettyNum (cvToSMTLib)
+
+import Data.SBV.Control.Types
+
+import qualified Control.Exception as C
+
+import GHC.Stack
+
+-- | 'Data.SBV.Trans.Control.QueryT' as a 'SolverContext'.
+instance MonadIO m => SolverContext (QueryT m) where
+   constrain                   = addQueryConstraint False []                . quantifiedBool
+   softConstrain               = addQueryConstraint True  []                . quantifiedBool
+   namedConstraint nm          = addQueryConstraint False [(":named", nm)]  . quantifiedBool
+   constrainWithAttribute attr = addQueryConstraint False attr              . quantifiedBool
+
+   contextState = queryState
+
+   registerKindInContext k = inNewContext (`registerKind` k)
+
+   internalVariable :: forall a. Kind -> QueryT m (SBV a)
+   internalVariable k = contextState >>= \st -> liftIO $ do
+       sv  <- newInternalVariable st k
+       pure $ SBV $ SVal k (Right (cache (const (pure sv))))
+
+   setOption o
+     | isStartModeOption o = error $ unlines [ ""
+                                             , "*** Data.SBV: '" ++ show o ++ "' can only be set at start-up time."
+                                             , "*** Hint: Move the call to 'setOption' before the query."
+                                             ]
+     | True                = do State{stCfg} <- contextState
+                                send True $ setSMTOption stCfg o
+
+-- | Adding a constraint, possibly with attributes and possibly soft. Only used internally.
+-- Use 'constrain' and 'namedConstraint' from user programs.
+addQueryConstraint :: (MonadIO m, MonadQuery m) => Bool -> [(String, String)] -> SBool -> m ()
+addQueryConstraint isSoft atts b = do sv <- inNewContext (\st -> liftIO $ do mapM_ (registerLabel "Constraint" st) [nm | (":named", nm) <- atts]
+                                                                             sbvToSV st b)
+
+                                      unless (null atts && sv == trueSV) $
+                                             send True $ "(" <> T.pack asrt <> " " <> addAnnotations atts (showText sv) <> ")"
+   where asrt | isSoft = "assert-soft"
+              | True   = "assert"
+
+-- | Get the current configuration
+getConfig :: (MonadIO m, MonadQuery m) => m SMTConfig
+getConfig = queryConfig <$> getQueryState
+
+-- | Get the objectives
+getObjectives :: (MonadIO m, MonadQuery m) => m [Objective (SV, SV)]
+getObjectives = do State{rOptGoals} <- queryState
+                   io $ reverse <$> readIORef rOptGoals
+
+-- | Get the assertions put in via 'Data.SBV.sAssert'
+getSBVAssertions :: (MonadIO m, MonadQuery m) => m [(String, Maybe CallStack, SV)]
+getSBVAssertions = do State{rAsserts} <- queryState
+                      io $ reverse <$> readIORef rAsserts
+
+-- | Generalization of 'Data.SBV.Control.io'
+io :: MonadIO m => IO a -> m a
+io = liftIO
+
+-- | Sync-up the external solver with new context we have generated
+syncUpSolver :: (MonadIO m, MonadQuery m) => State -> ProgInfo -> IORef CnstMap -> IncState -> m ()
+syncUpSolver st progInfo rGlobalConsts is = do
+        cfg <- getConfig
+
+        checks <- io $ readIORef (rNewMeasureChecks is)
+        io $ verifyMeasureChecks cfg st checks
+
+        -- update global consts to have the new ones
+        (newConsts, allConsts) <- liftIO $ do nc <- readIORef (rNewConsts is)
+                                              oc <- readIORef rGlobalConsts
+                                              let !allConsts = Map.union nc oc
+                                              writeIORef rGlobalConsts allConsts
+                                              pure (nc, allConsts)
+
+        ls  <- io $ do let arrange (i, (at, rt, es)) = ((i, at, rt), es)
+                       inps        <- reverse <$> readIORef (rNewInps is)
+                       ks          <- readIORef (rNewKinds is)
+                       tbls        <- map arrange . mapToSortedList <$> readIORef (rNewTbls is)
+                       newUIs      <- readIORef (rNewUIs is)
+                       newDefns    <- readIORef (rNewDefns is)
+                       as          <- readIORef (rNewAsgns is)
+                       constraints <- readIORef (rNewConstraints is)
+
+                       let cnsts       = mapToSortedList newConsts
+                           defineSet   = Map.keysSet newDefns
+                           uis         = Map.toAscList (Map.withoutKeys newUIs defineSet)
+                           definitions = Map.toAscList newDefns
+
+                       pure $ toIncSMTLib cfg progInfo inps ks (allConsts, cnsts) tbls uis definitions as constraints cfg
+
+        mapM_ (send True) $ mergeSExpr ls
+
+-- | Run deferred termination and productivity checks before sending newly encountered definitions.
+verifyMeasureChecks :: SMTConfig -> State -> [(String, Bool, SMTConfig -> IO ())] -> IO ()
+verifyMeasureChecks cfg st checks = do
+        skip <- readIORef (rSkipMeasureChecks st)
+        unless (skip || null checks) $ do
+          let nms = map (\(n, _, _) -> n) checks
+          debug cfg ["[MEASURE] Verifying termination measures for: " <> T.pack (intercalate ", " nms)]
+          mapM_ (\(nm, isProductive, check) -> do
+                    debug cfg ["[MEASURE] Checking: " <> T.pack nm]
+                    check cfg
+                    let tag = if isProductive then "productive" else "terminating"
+                    debug cfg ["[MEASURE] Passed (" <> tag <> "): " <> T.pack nm]
+                ) checks
+
+-- | Retrieve the query context
+getQueryState :: (MonadIO m, MonadQuery m) => m QueryState
+getQueryState = do state <- queryState
+                   mbQS  <- io $ readIORef (rQueryState state)
+                   case mbQS of
+                     Nothing -> error $ unlines [ ""
+                                                , "*** Data.SBV: Impossible happened: Query context required in a non-query mode."
+                                                , "Please report this as a bug!"
+                                                ]
+                     Just qs -> pure qs
+
+-- | Generalization of 'Data.SBV.Control.modifyQueryState'
+modifyQueryState :: (MonadIO m, MonadQuery m) => (QueryState -> QueryState) -> m ()
+modifyQueryState f = do state <- queryState
+                        mbQS  <- io $ readIORef (rQueryState state)
+                        case mbQS of
+                          Nothing -> error $ unlines [ ""
+                                                     , "*** Data.SBV: Impossible happened: Query context required in a non-query mode."
+                                                     , "Please report this as a bug!"
+                                                     ]
+                          Just qs -> let fqs = f qs
+                                     in fqs `seq` io $ writeIORef (rQueryState state) $ Just fqs
+
+-- | Generalization of 'Data.SBV.Control.inNewContext'
+inNewContext :: (MonadIO m, MonadQuery m) => (State -> IO a) -> m a
+inNewContext act = do st@State{rconstMap, rProgInfo} <- queryState
+                      (is, r)  <- io $ withNewIncState st act
+                      progInfo <- io $ readIORef rProgInfo
+                      syncUpSolver st progInfo rconstMap is
+                      pure r
+
+-- | Generalization of 'Data.SBV.Control.freshVar_'
+freshVar_ :: forall a m. (MonadIO m, MonadQuery m, SymVal a) => m (SBV a)
+freshVar_ = inNewContext $ \st -> do
+              v <- SBV <$> svMkSymVar QueryVar k Nothing st
+              mkSymValInit st v
+              pure v
+  where k = kindOf (Proxy @a)
+
+-- | Generalization of 'Data.SBV.Control.freshVar'
+freshVar :: forall a m. (MonadIO m, MonadQuery m, SymVal a) => String -> m (SBV a)
+freshVar nm = inNewContext $ \st -> do
+                v <- SBV <$> svMkSymVar QueryVar k (Just nm) st
+                mkSymValInit st v
+                pure v
+  where k = kindOf (Proxy @a)
+
+-- | Generalization of 'Data.SBV.Control.queryDebug'
+queryDebug :: (MonadIO m, MonadQuery m) => [T.Text] -> m ()
+queryDebug msgs = do QueryState{queryConfig} <- getQueryState
+                     io $ do debug queryConfig msgs
+                             recordTranscript (transcript queryConfig) (DebugMsg (T.unlines msgs))
+
+-- | We need to track sent asserts/check-sat calls so we can issue an extra check-sat call if needed
+trackAsserts :: (MonadIO m, MonadQuery m) => T.Text -> m ()
+trackAsserts s
+   | isCheckSat || isAssert
+   = do State{rOutstandingAsserts} <- queryState
+        liftIO $ writeIORef rOutstandingAsserts isAssert
+   | True
+   = pure ()
+  where trimmedS   = T.dropWhile isSpace s
+        isCheckSat = "(check-sat" `T.isPrefixOf` trimmedS
+        isAssert   = "(assert"    `T.isPrefixOf` trimmedS
+
+-- | Generalization of 'Data.SBV.Control.ask'
+ask :: (MonadIO m, MonadQuery m) => T.Text -> m String
+ask s = askIgnoring s []
+
+-- | Send a string to the solver, and return the response. Except, if the response
+-- is one of the "ignore" ones, keep querying.
+askIgnoring :: (MonadIO m, MonadQuery m) => T.Text -> [String] -> m String
+askIgnoring s ignoreList = do
+
+           trackAsserts s
+
+           QueryState{queryAsk, queryRetrieveResponse, queryTimeOutValue} <- getQueryState
+
+           case queryTimeOutValue of
+             Nothing -> queryDebug ["[SEND] " `alignPlain` s]
+             Just i  -> queryDebug ["[SEND, TimeOut: " <> showTimeoutValue i <> "] " `alignPlain` s]
+           r <- io $ queryAsk queryTimeOutValue s
+           queryDebug ["[RECV] " `alignPlain` T.pack r]
+
+           let loop currentResponse
+                 | currentResponse `notElem` ignoreList
+                 = pure currentResponse
+                 | True
+                 = do queryDebug ["[WARN] Previous response is explicitly ignored, beware!"]
+                      newResponse <- io $ queryRetrieveResponse queryTimeOutValue
+                      queryDebug ["[RECV] " `alignPlain` T.pack newResponse]
+                      loop newResponse
+
+           loop r
+
+-- | Generalization of 'Data.SBV.Control.send'
+send :: (MonadIO m, MonadQuery m) => Bool -> T.Text -> m ()
+send requireSuccess s = do
+
+            trackAsserts s
+
+            QueryState{queryAsk, querySend, queryConfig, queryTimeOutValue} <- getQueryState
+
+            if requireSuccess && supportsCustomQueries (capabilities (solver queryConfig))
+               then do r <- io $ queryAsk queryTimeOutValue s
+
+                       case words r of
+                         ["success"] -> queryDebug ["[GOOD] " `alignPlain` s]
+                         _           -> do case queryTimeOutValue of
+                                             Nothing -> queryDebug ["[FAIL] " `alignPlain` s]
+                                             Just i  -> queryDebug ["[FAIL, TimeOut: " <> showTimeoutValue i <> "]  " `alignPlain` s]
+
+
+                                           let cmd = case T.words (T.dropWhile (\c -> isSpace c || isPunctuation c) s) of
+                                                       (c:_) -> T.unpack c
+                                                       _     -> "Command"
+
+                                           unexpected cmd s "success" Nothing r Nothing
+
+               else do -- fire and forget. if you use this, you're on your own!
+                       queryDebug ["[FIRE] " `alignPlain` s]
+                       io $ querySend queryTimeOutValue s
+
+-- | Generalization of 'Data.SBV.Control.retrieveResponse'
+retrieveResponse :: (MonadIO m, MonadQuery m) => String -> Maybe Int -> m [String]
+retrieveResponse userTag mbTo = do
+             ts  <- io (show <$> getZonedTime)
+
+             let synchTag = show $ userTag ++ " (at: " ++ ts ++ ")"
+                 cmd = "(echo " ++ synchTag ++ ")"
+
+             queryDebug ["[SYNC] Attempting to synchronize with tag: " <> T.pack synchTag]
+
+             send False (T.pack cmd)
+
+             QueryState{queryRetrieveResponse} <- getQueryState
+
+             let loop sofar = do
+                  s <- io $ queryRetrieveResponse mbTo
+
+                  -- strictly speaking SMTLib requires solvers to print quotes around
+                  -- echo'ed strings, but they don't always do. Accommodate for that
+                  -- here, though I wish we didn't have to.
+                  if s == synchTag || show s == synchTag
+                     then do queryDebug ["[SYNC] Synchronization achieved using tag: " <> T.pack synchTag]
+                             pure $ reverse sofar
+                     else do queryDebug ["[RECV] " `alignPlain` T.pack s]
+                             loop (s : sofar)
+
+             loop []
+
+-- | Generalization of 'Data.SBV.Control.getValue'
+getValue :: (MonadIO m, MonadQuery m, SymVal a) => SBV a -> m a
+getValue s = do
+
+      sv <- inNewContext (`sbvToSV` s)
+
+      -- If we're issuing get-value, we gotta make sure there are no outstanding asserts
+      -- This can happen if we sent some ourselves. See https://github.com/LeventErkok/sbv/issues/682
+      outstandingAsserts <- do State{rOutstandingAsserts} <- queryState
+                               liftIO $ readIORef rOutstandingAsserts
+
+      when outstandingAsserts $ do
+        queryDebug ["[NOTE] getValue: There are outstanding asserts. Ensuring we're still sat."]
+        r <- checkSat
+        let bad = unexpected "checkSat" "check-sat" "one of sat/unsat/unknown" Nothing (show r) Nothing
+        case r of
+          Sat    -> pure ()
+          DSat{} -> pure ()
+          Unk    -> bad
+          Unsat  -> bad
+
+      -- Are we in an optimization context? If so, we must ensure that the model is not in an extended field
+      objs <- getObjectives
+      unless (null objs) $ do
+         ovs <- getObjectiveValues
+         case [() | (_, ExtendedCV _) <- ovs] of
+           [] -> pure ()    -- We're good, all objectives are within the domain
+           _  -> do cfg <- getConfig
+                    m   <- getModel
+                    ov  <- getObjectiveValues
+
+                    let mdl = LexicographicResult (SatExtField cfg m{modelObjectives = ov})
+
+                        align "" = "***"
+                        align l  = "*** " ++ l
+
+                    error $ unlines $ "" : map align ([
+                                "Data.SBV.getValue: The current solver state is satisfiable in an extension field."
+                              , "That is, the optimized values assume epsilon/infinity values."
+                              , ""
+                              , "Calls to getValue is not supported in this context. Instead, use the 'optimize' method"
+                              , "directly and inspect the objective values explicitly."
+                              , ""
+                              , "The current model is:"
+                              , ""
+                              ] ++ map ("    " ++) (lines (show mdl)))
+
+      cv <- getValueCV Nothing sv
+      pure $ fromCV cv
+
+-- | A class which allows for sexpr-conversion to functions
+class (HasKind r, SatModel r) => SMTFunction fun a r | fun -> a r where
+  sexprToArg     :: (MonadIO m, SolverContext m) => fun -> [SExpr] -> m (Maybe a)
+  smtFunName     :: (MonadIO m, SolverContext m) => fun -> m ((String, Maybe [String]), Bool)
+  smtFunSaturate :: fun -> SBV r
+  smtFunType     :: fun -> SBVType
+  smtFunDefault  :: fun -> Maybe r
+  sexprToFun     :: (MonadIO m, SolverContext m, MonadQuery m, MonadSymbolic m, SymVal r) => fun -> String -> (String, SExpr) -> m (Either String ([(a, r)], r))
+
+  {-# MINIMAL sexprToArg, smtFunSaturate, smtFunType  #-}
+
+  -- Given the function, figure out a default "return value"
+  smtFunDefault _
+    | let v = defaultKindedValue (kindOf (Proxy @r)), Just (res, []) <- parseCVs [v]
+    = Just res
+    | True
+    = Nothing
+
+  -- Discover the name in an isolated state. Inspecting a model must not add
+  -- declarations to the live solver, which can invalidate its current model.
+  smtFunName f = do State{rUIMap, stCfg} <- contextState
+                    uiMap <- liftIO $ readIORef rUIMap
+                    probe <- mkNewState stCfg{verbose = False} (LambdaGen (Just 0))
+                    nm    <- findName probe uiMap
+                    case nm `Map.lookup` uiMap of
+                      Nothing -> error $ unlines
+                        [ ""
+                        , "*** Data.SBV.getFunction: Uninterpreted function " ++ show nm ++ " is not registered in this context."
+                        , "*** Use it in a constraint, or call registerFunction before entering the query."
+                        , "*** Then check satisfiability before calling getFunction."
+                        , "*** getFunction only inspects the current model; it does not register functions or rerun checkSat."
+                        ]
+                      -- SMT signatures do not distinguish curried and uncurried
+                      -- Haskell functions. Keep the registered display convention.
+                      Just (isCurried, mbArgs, ty)
+                        | ty == smtFunType f -> pure ((nm, mbArgs), isCurried)
+                        | True -> error $ unlines
+                            [ ""
+                            , "*** Data.SBV.getFunction: Uninterpreted function " ++ show nm ++ " used at incompatible SMT signatures."
+                            , "***    Requested argument/result sorts: " ++ show (smtFunType f)
+                            , "***    Declared argument/result sorts:  " ++ show ty
+                            ]
+    where cantFind uiMap = error $ unlines $    [ ""
+                                                , "*** Data.SBV.getFunction: Must be called on an uninterpreted function!"
+                                                , "***"
+                                                , "***    Expected to receive a function created by \"uninterpret\""
+                                                ]
+                                             ++ tag
+                                             ++ [ "***"
+                                                , "*** Make sure to call getFunction on uninterpreted functions only!"
+                                                , "*** If that is already the case, please report this as a bug."
+                                                ]
+             where tag = case map fst (Map.toList uiMap) of
+                               []    -> [ "***    But, there are no matching uninterpreted functions in the context." ]
+                               [x]   -> [ "***    The only possible candidate is: " ++ x ]
+                               cands -> [ "***    Candidates are:"
+                                        , "***        " ++ intercalate ", " cands
+                                        ]
+
+          findName st@State{spgm} uiMap = do
+             r <- liftIO $ sbvToSV st (smtFunSaturate f)
+             liftIO $ forceSVArg r
+             SBVPgm asgns <- liftIO $ readIORef spgm
+
+
+             case S.findIndexR ((== r) . fst) asgns of
+               Nothing -> cantFind uiMap
+               Just i  -> case asgns `S.index` i of
+                            (sv, SBVApp (Uninterpreted nm) _) | r == sv -> pure (T.unpack nm)
+                            _                                           -> cantFind uiMap
+
+  sexprToFun f nm (s, e) = do
+    si    <- contextState >>= getSInfo
+    mbRes <- case parseSExprFunction e of
+               Just (Left nm') -> case (unBar nm == unBar nm', smtFunDefault f) of
+                                    (True, Just v) -> pure $ Just ([], v)
+                                    _              -> bailOut
+               Just (Right v)  -> convert si v
+               Nothing         -> do mbPVS <- pointWiseExtract nm (smtFunType f)
+                                     case mbPVS of
+                                       Nothing  -> pure Nothing
+                                       Just pts -> convert si pts
+    pure $ maybe (Left s) Right mbRes
+    where convert st (vs, d) = do ps <- mapM (sexprPoint st) vs
+                                  pure $ (,) <$> sequenceA ps <*> sexprToVal st d
+
+          sexprPoint st (as, v) = do mbA <- sexprToArg f as
+                                     pure $ (,) <$> mbA <*> sexprToVal st v
+
+          bailOut = error $ unlines [ ""
+                                       , "*** Data.SBV.getFunction: Unable to extract an interpretation for function " ++ show nm
+                                       , "***"
+                                       , "*** Failed while trying to extract a pointwise interpretation."
+                                       , "***"
+                                       , "*** This could be a bug with SBV or the backend solver. Please report!"
+                                       ]
+
+-- | Pointwise function value extraction. If we get unlucky and can't parse z3's output (happens
+-- when we have all booleans and z3 decides to spit out an expression), just brute force our
+-- way out of it. Note that we only do this if we have a pure boolean type, as otherwise we'd blow
+-- up. And I think it'll only be necessary then, I haven't seen z3 try anything smarter in other scenarios.
+pointWiseExtract ::  forall m. (MonadIO m, MonadQuery m) => String -> SBVType -> m (Maybe ([([SExpr], SExpr)], SExpr))
+pointWiseExtract nm typ = tryPointWise
+  where trueSExpr  = ENum (1, Nothing, True)
+        falseSExpr = ENum (0, Nothing, True)
+
+        isTrueSExpr (ENum (1, Nothing, True)) = True
+        isTrueSExpr (ENum (0, Nothing, True)) = False
+        isTrueSExpr s                         = error $ "Data.SBV.pointWiseExtract: Impossible happened: Received: " ++ show s
+
+        (nArgs, isBoolFunc) = case typ of
+                                SBVType ts -> (length ts - 1, all (== KBool) ts)
+
+        getBVal :: [SExpr] -> m ([SExpr], SExpr)
+        getBVal args = do let shc c | isTrueSExpr c = "true"
+                                    | True          = "false"
+
+                              as = unwords $ map shc args
+
+                              cmd   = "(get-value ((" <> T.pack nm <> " " <> T.pack as <> ")))"
+
+                              bad   = unexpected "get-value" cmd ("pointwise value of boolean function " ++ nm ++ " on " ++ show as) Nothing
+
+                          r <- ask cmd
+
+                          parse r bad $ \case EApp [EApp [_, e]] -> pure (args, e)
+                                              _                  -> bad r Nothing
+
+        getBVals :: m [([SExpr], SExpr)]
+        getBVals = mapM getBVal $ replicateM nArgs [falseSExpr, trueSExpr]
+
+        tryPointWise
+          | not isBoolFunc
+          = pure Nothing
+          | nArgs < 1
+          = error $ "Data.SBV.pointWiseExtract: Impossible happened, nArgs < 1: " ++ show nArgs ++ " type: " ++ show typ
+          | True
+          = do vs <- getBVals
+               -- Pick the value that will give us the fewer entries
+               let (trues, falses) = partition (\(_, v) -> isTrueSExpr v) vs
+               pure $ Just $ if length trues <= length falses
+                               then (trues,  falseSExpr)
+                               else (falses, trueSExpr)
+
+-- | Use symbolic arguments for discovery: uninterpreted sorts need not have
+-- a concrete default value. These variables belong only to the probe state.
+-- The forall is safe since smtFunSaturate supplies the argument's actual kind.
+mkSaturatingArg :: forall a. Kind -> SBV a
+mkSaturatingArg k = SBV $ SVal k $ Right $ cache $ \st -> newInternalVariable st k
+
+-- | Functions of arity 1
+instance ( SymVal a, HasKind a
+         , SatModel r, HasKind r
+         ) => SMTFunction (SBV a -> SBV r) a r
+         where
+  sexprToArg _ [a0] = contextState >>= getSInfo >>= \si -> pure $ sexprToVal si a0
+  sexprToArg _ _    = pure Nothing
+
+  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @r)]
+
+  smtFunSaturate f = f $ mkSaturatingArg (kindOf (Proxy @a))
+
+-- | Functions of arity 2
+instance ( SymVal a,  HasKind a
+         , SymVal b,  HasKind b
+         , SatModel r, HasKind r
+         ) => SMTFunction (SBV a -> SBV b -> SBV r) (a, b) r
+         where
+  sexprToArg _ [a0, a1] = contextState >>= getSInfo >>= \si -> pure $ (,) <$> sexprToVal si a0 <*> sexprToVal si a1
+  sexprToArg _ _        = pure Nothing
+
+  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @r)]
+
+  smtFunSaturate f = f (mkSaturatingArg (kindOf (Proxy @a)))
+                       (mkSaturatingArg (kindOf (Proxy @b)))
+
+-- | Functions of arity 3
+instance ( SymVal a,   HasKind a
+         , SymVal b,   HasKind b
+         , SymVal c,   HasKind c
+         , SatModel r, HasKind r
+         ) => SMTFunction (SBV a -> SBV b -> SBV c -> SBV r) (a, b, c) r
+         where
+  sexprToArg _ [a0, a1, a2] = contextState >>= getSInfo >>= \si -> pure $ (,,) <$> sexprToVal si a0 <*> sexprToVal si a1 <*> sexprToVal si a2
+  sexprToArg _ _            = pure Nothing
+
+  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @c), kindOf (Proxy @r)]
+
+  smtFunSaturate f = f (mkSaturatingArg (kindOf (Proxy @a)))
+                       (mkSaturatingArg (kindOf (Proxy @b)))
+                       (mkSaturatingArg (kindOf (Proxy @c)))
+
+-- | Functions of arity 4
+instance ( SymVal a,   HasKind a
+         , SymVal b,   HasKind b
+         , SymVal c,   HasKind c
+         , SymVal d,   HasKind d
+         , SatModel r, HasKind r
+         ) => SMTFunction (SBV a -> SBV b -> SBV c -> SBV d -> SBV r) (a, b, c, d) r
+         where
+  sexprToArg _ [a0, a1, a2, a3] = contextState >>= getSInfo >>= \si -> pure $ (,,,) <$> sexprToVal si a0 <*> sexprToVal si a1 <*> sexprToVal si a2 <*> sexprToVal si a3
+  sexprToArg _ _                = pure Nothing
+
+  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @c), kindOf (Proxy @d), kindOf (Proxy @r)]
+
+  smtFunSaturate f = f (mkSaturatingArg (kindOf (Proxy @a)))
+                       (mkSaturatingArg (kindOf (Proxy @b)))
+                       (mkSaturatingArg (kindOf (Proxy @c)))
+                       (mkSaturatingArg (kindOf (Proxy @d)))
+
+-- | Functions of arity 5
+instance ( SymVal a,   HasKind a
+         , SymVal b,   HasKind b
+         , SymVal c,   HasKind c
+         , SymVal d,   HasKind d
+         , SymVal e,   HasKind e
+         , SatModel r, HasKind r
+         ) => SMTFunction (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV r) (a, b, c, d, e) r
+         where
+  sexprToArg _ [a0, a1, a2, a3, a4] = contextState >>= getSInfo >>= \si -> pure $ (,,,,) <$> sexprToVal si a0 <*> sexprToVal si a1 <*> sexprToVal si a2 <*> sexprToVal si a3 <*> sexprToVal si a4
+  sexprToArg _ _                    = pure Nothing
+
+  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @c), kindOf (Proxy @d), kindOf (Proxy @e), kindOf (Proxy @r)]
+
+  smtFunSaturate f = f (mkSaturatingArg (kindOf (Proxy @a)))
+                       (mkSaturatingArg (kindOf (Proxy @b)))
+                       (mkSaturatingArg (kindOf (Proxy @c)))
+                       (mkSaturatingArg (kindOf (Proxy @d)))
+                       (mkSaturatingArg (kindOf (Proxy @e)))
+
+-- | Functions of arity 6
+instance ( SymVal a,   HasKind a
+         , SymVal b,   HasKind b
+         , SymVal c,   HasKind c
+         , SymVal d,   HasKind d
+         , SymVal e,   HasKind e
+         , SymVal f,   HasKind f
+         , SatModel r, HasKind r
+         ) => SMTFunction (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV r) (a, b, c, d, e, f) r
+         where
+  sexprToArg _ [a0, a1, a2, a3, a4, a5] = contextState >>= getSInfo >>= \si -> pure $ (,,,,,) <$> sexprToVal si a0 <*> sexprToVal si a1 <*> sexprToVal si a2 <*> sexprToVal si a3 <*> sexprToVal si a4 <*> sexprToVal si a5
+  sexprToArg _ _                        = pure Nothing
+
+  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @c), kindOf (Proxy @d), kindOf (Proxy @e), kindOf (Proxy @f), kindOf (Proxy @r)]
+
+  smtFunSaturate f = f (mkSaturatingArg (kindOf (Proxy @a)))
+                       (mkSaturatingArg (kindOf (Proxy @b)))
+                       (mkSaturatingArg (kindOf (Proxy @c)))
+                       (mkSaturatingArg (kindOf (Proxy @d)))
+                       (mkSaturatingArg (kindOf (Proxy @e)))
+                       (mkSaturatingArg (kindOf (Proxy @f)))
+
+-- | Functions of arity 7
+instance ( SymVal a,   HasKind a
+         , SymVal b,   HasKind b
+         , SymVal c,   HasKind c
+         , SymVal d,   HasKind d
+         , SymVal e,   HasKind e
+         , SymVal f,   HasKind f
+         , SymVal g,   HasKind g
+         , SatModel r, HasKind r
+         ) => SMTFunction (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV g -> SBV r) (a, b, c, d, e, f, g) r
+         where
+  sexprToArg _ [a0, a1, a2, a3, a4, a5, a6] = contextState >>= getSInfo >>= \si -> pure $ (,,,,,,) <$> sexprToVal si a0 <*> sexprToVal si a1 <*> sexprToVal si a2 <*> sexprToVal si a3 <*> sexprToVal si a4 <*> sexprToVal si a5 <*> sexprToVal si a6
+  sexprToArg _ _                            = pure Nothing
+
+  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @c), kindOf (Proxy @d), kindOf (Proxy @e), kindOf (Proxy @f), kindOf (Proxy @g), kindOf (Proxy @r)]
+
+  smtFunSaturate f = f (mkSaturatingArg (kindOf (Proxy @a)))
+                       (mkSaturatingArg (kindOf (Proxy @b)))
+                       (mkSaturatingArg (kindOf (Proxy @c)))
+                       (mkSaturatingArg (kindOf (Proxy @d)))
+                       (mkSaturatingArg (kindOf (Proxy @e)))
+                       (mkSaturatingArg (kindOf (Proxy @f)))
+                       (mkSaturatingArg (kindOf (Proxy @g)))
+
+-- | Functions of arity 8
+instance ( SymVal a,   HasKind a
+         , SymVal b,   HasKind b
+         , SymVal c,   HasKind c
+         , SymVal d,   HasKind d
+         , SymVal e,   HasKind e
+         , SymVal f,   HasKind f
+         , SymVal g,   HasKind g
+         , SymVal h,   HasKind h
+         , SatModel r, HasKind r
+         ) => SMTFunction (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV g -> SBV h -> SBV r) (a, b, c, d, e, f, g, h) r
+         where
+  sexprToArg _ [a0, a1, a2, a3, a4, a5, a6, a7] = contextState >>= getSInfo >>= \si -> pure $ (,,,,,,,) <$> sexprToVal si a0 <*> sexprToVal si a1 <*> sexprToVal si a2 <*> sexprToVal si a3 <*> sexprToVal si a4 <*> sexprToVal si a5 <*> sexprToVal si a6 <*> sexprToVal si a7
+  sexprToArg _ _                                = pure Nothing
+
+  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @c), kindOf (Proxy @d), kindOf (Proxy @e), kindOf (Proxy @f), kindOf (Proxy @g), kindOf (Proxy @h), kindOf (Proxy @r)]
+
+  smtFunSaturate f = f (mkSaturatingArg (kindOf (Proxy @a)))
+                       (mkSaturatingArg (kindOf (Proxy @b)))
+                       (mkSaturatingArg (kindOf (Proxy @c)))
+                       (mkSaturatingArg (kindOf (Proxy @d)))
+                       (mkSaturatingArg (kindOf (Proxy @e)))
+                       (mkSaturatingArg (kindOf (Proxy @f)))
+                       (mkSaturatingArg (kindOf (Proxy @g)))
+                       (mkSaturatingArg (kindOf (Proxy @h)))
+
+-- | Curried functions of arity 2
+instance ( SymVal a,  HasKind a
+         , SymVal b,  HasKind b
+         , SatModel r, HasKind r
+         ) => SMTFunction ((SBV a, SBV b) -> SBV r) (a, b) r
+         where
+  sexprToArg _ [a0, a1] = contextState >>= getSInfo >>= \si -> pure $ (,) <$> sexprToVal si a0 <*> sexprToVal si a1
+  sexprToArg _ _        = pure Nothing
+
+  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @r)]
+
+  smtFunSaturate f = f ( mkSaturatingArg (kindOf (Proxy @a))
+                       , mkSaturatingArg (kindOf (Proxy @b))
+                       )
+
+-- | Curried functions of arity 3
+instance ( SymVal a,  HasKind a
+         , SymVal b,  HasKind b
+         , SymVal c,  HasKind c
+         , SatModel r, HasKind r
+         ) => SMTFunction ((SBV a, SBV b, SBV c) -> SBV r) (a, b, c) r
+         where
+  sexprToArg _ [a0, a1, a2] = contextState >>= getSInfo >>= \si -> pure $ (,,) <$> sexprToVal si a0 <*> sexprToVal si a1 <*> sexprToVal si a2
+  sexprToArg _ _            = pure Nothing
+
+  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @c), kindOf (Proxy @r)]
+
+  smtFunSaturate f = f ( mkSaturatingArg (kindOf (Proxy @a))
+                       , mkSaturatingArg (kindOf (Proxy @b))
+                       , mkSaturatingArg (kindOf (Proxy @c))
+                       )
+
+-- | Curried functions of arity 4
+instance ( SymVal a,  HasKind a
+         , SymVal b,  HasKind b
+         , SymVal c,  HasKind c
+         , SymVal d,  HasKind d
+         , SatModel r, HasKind r
+         ) => SMTFunction ((SBV a, SBV b, SBV c, SBV d) -> SBV r) (a, b, c, d) r
+         where
+  sexprToArg _ [a0, a1, a2, a3] = contextState >>= getSInfo >>= \si -> pure $ (,,,) <$> sexprToVal si a0 <*> sexprToVal si a1 <*> sexprToVal si a2 <*> sexprToVal si a3
+  sexprToArg _ _                = pure Nothing
+
+  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @c), kindOf (Proxy @d), kindOf (Proxy @r)]
+
+  smtFunSaturate f = f ( mkSaturatingArg (kindOf (Proxy @a))
+                       , mkSaturatingArg (kindOf (Proxy @b))
+                       , mkSaturatingArg (kindOf (Proxy @c))
+                       , mkSaturatingArg (kindOf (Proxy @d))
+                       )
+
+-- | Curried functions of arity 5
+instance ( SymVal a,  HasKind a
+         , SymVal b,  HasKind b
+         , SymVal c,  HasKind c
+         , SymVal d,  HasKind d
+         , SymVal e,  HasKind e
+         , SatModel r, HasKind r
+         ) => SMTFunction ((SBV a, SBV b, SBV c, SBV d, SBV e) -> SBV r) (a, b, c, d, e) r
+         where
+  sexprToArg _ [a0, a1, a2, a3, a4] = contextState >>= getSInfo >>= \si -> pure $ (,,,,) <$> sexprToVal si a0 <*> sexprToVal si a1 <*> sexprToVal si a2 <*> sexprToVal si a3 <*> sexprToVal si a4
+  sexprToArg _ _                    = pure Nothing
+
+  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @c), kindOf (Proxy @d), kindOf (Proxy @e), kindOf (Proxy @r)]
+
+  smtFunSaturate f = f ( mkSaturatingArg (kindOf (Proxy @a))
+                       , mkSaturatingArg (kindOf (Proxy @b))
+                       , mkSaturatingArg (kindOf (Proxy @c))
+                       , mkSaturatingArg (kindOf (Proxy @d))
+                       , mkSaturatingArg (kindOf (Proxy @e))
+                       )
+
+-- | Curried functions of arity 6
+instance ( SymVal a,  HasKind a
+         , SymVal b,  HasKind b
+         , SymVal c,  HasKind c
+         , SymVal d,  HasKind d
+         , SymVal e,  HasKind e
+         , SymVal f,  HasKind f
+         , SatModel r, HasKind r
+         ) => SMTFunction ((SBV a, SBV b, SBV c, SBV d, SBV e, SBV f) -> SBV r) (a, b, c, d, e, f) r
+         where
+  sexprToArg _ [a0, a1, a2, a3, a4, a5] = contextState >>= getSInfo >>= \si -> pure $ (,,,,,) <$> sexprToVal si a0 <*> sexprToVal si a1 <*> sexprToVal si a2 <*> sexprToVal si a3 <*> sexprToVal si a4 <*> sexprToVal si a5
+  sexprToArg _ _                        = pure Nothing
+
+  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @c), kindOf (Proxy @d), kindOf (Proxy @e), kindOf (Proxy @f), kindOf (Proxy @r)]
+
+  smtFunSaturate f = f ( mkSaturatingArg (kindOf (Proxy @a))
+                       , mkSaturatingArg (kindOf (Proxy @b))
+                       , mkSaturatingArg (kindOf (Proxy @c))
+                       , mkSaturatingArg (kindOf (Proxy @d))
+                       , mkSaturatingArg (kindOf (Proxy @e))
+                       , mkSaturatingArg (kindOf (Proxy @f))
+                       )
+
+-- | Curried functions of arity 7
+instance ( SymVal a,  HasKind a
+         , SymVal b,  HasKind b
+         , SymVal c,  HasKind c
+         , SymVal d,  HasKind d
+         , SymVal e,  HasKind e
+         , SymVal f,  HasKind f
+         , SymVal g,  HasKind g
+         , SatModel r, HasKind r
+         ) => SMTFunction ((SBV a, SBV b, SBV c, SBV d, SBV e, SBV f, SBV g) -> SBV r) (a, b, c, d, e, f, g) r
+         where
+  sexprToArg _ [a0, a1, a2, a3, a4, a5, a6] = contextState >>= getSInfo >>= \si -> pure $ (,,,,,,) <$> sexprToVal si a0 <*> sexprToVal si a1 <*> sexprToVal si a2 <*> sexprToVal si a3 <*> sexprToVal si a4 <*> sexprToVal si a5 <*> sexprToVal si a6
+  sexprToArg _ _                            = pure Nothing
+
+  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @c), kindOf (Proxy @d), kindOf (Proxy @e), kindOf (Proxy @f), kindOf (Proxy @g), kindOf (Proxy @r)]
+
+  smtFunSaturate f = f ( mkSaturatingArg (kindOf (Proxy @a))
+                       , mkSaturatingArg (kindOf (Proxy @b))
+                       , mkSaturatingArg (kindOf (Proxy @c))
+                       , mkSaturatingArg (kindOf (Proxy @d))
+                       , mkSaturatingArg (kindOf (Proxy @e))
+                       , mkSaturatingArg (kindOf (Proxy @f))
+                       , mkSaturatingArg (kindOf (Proxy @g))
+                       )
+
+-- | Curried functions of arity 8
+instance ( SymVal a,  HasKind a
+         , SymVal b,  HasKind b
+         , SymVal c,  HasKind c
+         , SymVal d,  HasKind d
+         , SymVal e,  HasKind e
+         , SymVal f,  HasKind f
+         , SymVal g,  HasKind g
+         , SymVal h,  HasKind h
+         , SatModel r, HasKind r
+         ) => SMTFunction ((SBV a, SBV b, SBV c, SBV d, SBV e, SBV f, SBV g, SBV h) -> SBV r) (a, b, c, d, e, f, g, h) r
+         where
+  sexprToArg _ [a0, a1, a2, a3, a4, a5, a6, a7] = contextState >>= getSInfo >>= \si -> pure $ (,,,,,,,) <$> sexprToVal si a0 <*> sexprToVal si a1 <*> sexprToVal si a2 <*> sexprToVal si a3 <*> sexprToVal si a4 <*> sexprToVal si a5 <*> sexprToVal si a6 <*> sexprToVal si a7
+  sexprToArg _ _                                = pure Nothing
+
+  smtFunType _ = SBVType [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @c), kindOf (Proxy @d), kindOf (Proxy @e), kindOf (Proxy @f), kindOf (Proxy @g), kindOf (Proxy @h), kindOf (Proxy @r)]
+
+  smtFunSaturate f = f ( mkSaturatingArg (kindOf (Proxy @a))
+                       , mkSaturatingArg (kindOf (Proxy @b))
+                       , mkSaturatingArg (kindOf (Proxy @c))
+                       , mkSaturatingArg (kindOf (Proxy @d))
+                       , mkSaturatingArg (kindOf (Proxy @e))
+                       , mkSaturatingArg (kindOf (Proxy @f))
+                       , mkSaturatingArg (kindOf (Proxy @g))
+                       , mkSaturatingArg (kindOf (Proxy @h))
+                       )
+
+-- | Generalization of 'Data.SBV.Control.getFunction'
+getFunction :: (MonadIO m, MonadQuery m, SolverContext m, MonadSymbolic m, SymVal a, SymVal r, SMTFunction fun a r)
+            => fun -> m (Either (String, (Bool, Maybe [String], SExpr))  ([(a, r)], r))
+getFunction f = do ((nm, args), isCurried) <- smtFunName f
+
+                   let cmd = "(get-value (" <> T.pack nm <> "))"
+                       bad = unexpected "getFunction" cmd "a function value" Nothing
+
+                   r <- ask cmd
+
+                   si <- contextState >>= getSInfo
+
+                   parse r bad $ \case EApp [EApp [ECon o, e]] | unBar o == unBar nm -> do
+                                          mbAssocs <- sexprToFun f nm (formatFunctionResponse e r nm isCurried args, e)
+                                          case mbAssocs of
+                                            Right assocs -> pure $ Right assocs
+                                            Left  raw    -> do
+                                               let rawRes = Left (raw, (isCurried, args, e))
+                                               mbPVS <- pointWiseExtract nm (smtFunType f)
+                                               case mbPVS of
+                                                 Just ps -> do rs <- convert si ps
+                                                               case rs of
+                                                                  Just x  -> pure $ Right x
+                                                                  Nothing -> pure rawRes
+                                                 Nothing -> pure rawRes
+                                       _ -> bad r Nothing
+    where convert si (vs, d) = do ps <- mapM (sexprPoint si) vs
+                                  pure $ (,) <$> sequenceA ps <*> sexprToVal si d
+
+          sexprPoint si (as, v) = do mbA <- sexprToArg f as
+                                     pure $ (,) <$> mbA <*> sexprToVal si v
+
+-- | Get the value of a term, but in CV form. Used internally. The model-index, in particular is extremely Z3 specific!
+getValueCVHelper :: (MonadIO m, MonadQuery m) => Maybe Int -> SV -> m CV
+getValueCVHelper mbi s
+  | s == trueSV
+  = pure trueCV
+  | s == falseSV
+  = pure falseCV
+  | True
+  = extractValue mbi (show s) (kindOf s)
+
+-- | "Make up" a CV for this type. Like zero, but smarter.
+defaultKindedValue :: Kind -> CV
+defaultKindedValue k = CV k $ cvt k
+  where cvt :: Kind -> CVal
+        cvt (KVar s)         = error ("defaultKindedValue: Unexpected kind: " ++ s)
+        cvt KBool            = CInteger 0
+        cvt KBounded{}       = CInteger 0
+        cvt KUnbounded       = CInteger 0
+        cvt KReal            = CAlgReal 0
+        cvt KFloat           = CFloat 0
+        cvt KDouble          = CDouble 0
+        cvt KRational        = CRational 0
+        cvt (KFP eb sb)      = CFP (fpZero False eb sb)
+        cvt KChar            = CChar '\NUL'                -- why not?
+        cvt KString          = CString ""
+        cvt (KList  _)       = CList []
+        cvt (KSet  _)        = CSet $ RegularSet Set.empty -- why not? Arguably, could be the universal set
+        cvt (KTuple ks)      = CTuple $ map cvt ks
+        cvt (KArray  _  k2)  = CArray $ ArrayModel [] (cvt k2)
+
+        cvt (KApp s _)       = error ("defaultKindedValue not supported for ADT app: " ++ s) -- tough luck
+
+        -- For ADTs, just return the first element if there's any
+        cvt (KADT s _ cstrs) = case cstrs of
+                                 []            -> error ("defaultKindedValue not supported for ADT: "     ++ s) -- tough luck
+                                 ((c, ks) : _) -> CADT (c, [(k, cvt fk) | fk <- ks])
+
+-- | Go from an SExpr directly to a value
+sexprToVal :: forall a. SymVal a => SInfo -> SExpr -> Maybe a
+sexprToVal si e = fromCV <$> recoverKindedValue si (kindOf (Proxy @a)) e
+
+-- | Recover a given solver-printed value with a possible interpretation
+recoverKindedValue :: SInfo -> Kind -> SExpr -> Maybe CV
+recoverKindedValue si k e =
+    case k of
+      KVar{}      -> error $ "Data.SBV.recoverKindedValue: Unexpected var kind: " ++ show k
+
+      KApp n ks   -> case [(s, ps, cstrs) | KADT s ps cstrs <- sInfoKinds si, s == n] of
+                       [(s, ps, cstr)]
+                         | length ks == length ps -> recoverKindedValue si (KADT s (zip (map fst ps) ks) cstr) e
+                       xs -> error $ unlines [ "Data.SBV.recoverKindedValue: Can't uniquely locate reference to ADT: "
+                                             , "***"
+                                             , "*** ADT    : " ++ show n
+                                             , "*** Params : " ++ show ks
+                                             , "*** Matched: " ++ show xs
+                                             , "*** Expr   : " ++ show e
+                                             , "***"
+                                             , "*** Please report this as a bug."
+                                             ]
+
+      KBool       | ENum (i, _, _) <- e   -> Just $ mkConstCV k i
+                  | True                  -> Nothing
+
+      KBounded{}  | ENum (i, _, _) <- e   -> Just $ mkConstCV k i
+                  | True                  -> Nothing
+
+      KUnbounded  | ENum (i, _, _) <- e   -> Just $ mkConstCV k i
+                  | True                  -> Nothing
+
+      KReal       | ENum (i, _, _) <- e   -> Just $ mkConstCV k i
+                  | EReal i        <- e   -> Just $ CV KReal (CAlgReal i)
+                  | True                  -> interpretInterval e
+
+      KADT nm dict def                    -> let k' = KADT nm dict [(c, map (substituteADTVars nm dict) ks) | (c, ks) <- def]
+                                             in Just $ CV k' $ CADT $ interpretADT k' e
+
+      KFloat      | ENum (i, _, _) <- e   -> Just $ mkConstCV k i
+                  | EFloat i       <- e   -> Just $ CV KFloat (CFloat i)
+                  | True                  -> Nothing
+
+      KDouble     | ENum (i, _, _) <- e   -> Just $ mkConstCV k i
+                  | EDouble i      <- e   -> Just $ CV KDouble (CDouble i)
+                  | True                  -> Nothing
+
+      KFP eb sb   | ENum (i, _, _)   <- e -> Just $ CV k $ CFP $ fpFromInteger eb sb i
+                  | EFloat f         <- e -> Just $ CV k $ CFP $ fpFromFloat   eb sb f
+                  | EDouble d        <- e -> Just $ CV k $ CFP $ fpFromDouble  eb sb d
+                  | EFloatingPoint c <- e -> Just $ CV k $ CFP c
+                  | True                  -> Nothing
+
+      KChar       | ECon s      <- e      -> Just $ CV KChar $ CChar $ interpretChar s
+                  | True                  -> Nothing
+
+      KString     | ECon s      <- e      -> Just $ CV KString $ CString $ interpretString s
+                  | True                  -> Nothing
+
+      KRational                           -> Just $ CV k $ CRational $ interpretRational       e
+      KList ek                            -> Just $ CV k $ CList     $ interpretList ek        e
+      KSet ek                             -> Just $ CV k $ CSet      $ interpretSet ek         e
+      KTuple{}                            -> Just $ CV k $ CTuple    $ interpretTuple          e
+      KArray k1 k2                        -> Just $ CV k $ CArray    $ interpretArray    k1 k2 e
+
+  where stringLike xs = length xs >= 2 && "\"" `isPrefixOf` xs && "\"" `isSuffixOf` xs
+
+        -- Make sure strings are really strings
+        interpretString xs
+          | not (stringLike xs)
+          = error $ "Expected a string constant with quotes, received: <" ++ xs ++ ">"
+          | True
+          = qfsToString $ drop 1 (init xs)
+
+        interpretChar xs = case interpretString xs of
+                             [c] -> c
+                             _   -> error $ "Expected a singleton char constant, received: <" ++ xs ++ ">"
+
+        interpretRational (EApp [ECon "SBV.Rational", v1, v2])
+           | Just (CV _ (CInteger n)) <- recoverKindedValue si KUnbounded v1
+           , Just (CV _ (CInteger d)) <- recoverKindedValue si KUnbounded v2
+           = n % d
+        interpretRational xs = error $ "Expected a rational constant, received: <" ++ show xs ++ ">"
+
+        interpretList ek topExpr = walk topExpr
+          where walk (EApp [ECon "as", v, _])      = walk v
+                walk (ECon "seq.empty")            = []
+                walk (EApp [ECon "seq.unit", v])   = case recoverKindedValue si ek v of
+                                                       Just w -> [cvVal w]
+                                                       Nothing -> error $ "Cannot parse a sequence item of kind " ++ show ek ++ " from: " ++ show v ++ extra v
+                walk (EApp (ECon "seq.++" : rest)) = concatMap walk rest
+                walk cur                           = error $ "Expected a sequence constant, but received: " ++ show cur ++ extra cur
+
+                extra cur | show cur == t = ""
+                          | True          = "\nWhile parsing: " ++ t
+                          where t = show topExpr
+
+        -- Essentially treat sets as functions, since we do allow for store associations
+        interpretSet ke setExpr
+             | isUniversal setExpr             = ComplementSet Set.empty
+             | isEmpty     setExpr             = RegularSet    Set.empty
+             | Just (Right assocs) <- mbAssocs = decode assocs
+             | True                            = tbd "Expected a set value, but couldn't decipher the solver output."
+
+           where tbd :: String -> a
+                 tbd w = error $ unlines [ ""
+                                         , "*** Data.SBV.interpretSet: Unable to process solver output."
+                                         , "***"
+                                         , "*** Kind    : " ++ show (KSet ke)
+                                         , "*** Received: " ++ show setExpr
+                                         , "*** Reason  : " ++ w
+                                         , "***"
+                                         , "*** This is either a bug or something SBV currently does not support."
+                                         , "*** Please report this as a feature request!"
+                                         ]
+
+
+                 isTrue (ENum (1, Nothing, True)) = True
+                 isTrue (ENum (0, Nothing, True)) = False
+                 isTrue bad                 = tbd $ "Non-boolean membership value seen: " ++ show bad
+
+                 isUniversal (EApp [EApp [ECon "as", ECon "const", EApp [ECon "Array", _, ECon "Bool"]], r]) = isTrue r
+                 isUniversal _                                                                               = False
+
+                 isEmpty     (EApp [EApp [ECon "as", ECon "const", EApp [ECon "Array", _, ECon "Bool"]], r]) = not $ isTrue r
+                 isEmpty     _                                                                               = False
+
+                 mbAssocs = parseSExprFunction setExpr
+
+                 decode (args, r) | isTrue r = ComplementSet $ Set.fromList [x | (x, False) <- concatMap (contents True)  args]  -- deletions from universal
+                                  | True     = RegularSet    $ Set.fromList [x | (x, True)  <- concatMap (contents False) args]  -- additions to empty
+
+                 contents cvt ([v], r) = let t = isTrue r in map (, t) (element cvt v)
+                 contents _   bad      = tbd $ "Multi-valued set member seen: " ++ show bad
+
+                 element cvt x = case (cvt, ke) of
+                                   (True, KChar) -> case recoverKindedValue si KString x of
+                                                      Just v  -> case cvVal v of
+                                                                  CString [c] -> [CChar c]
+                                                                  CString _   -> []
+                                                                  _           -> tbd $ "Unexpected value for kind: " ++ show (x, ke)
+                                                      Nothing -> tbd $ "Unexpected value for kind: " ++ show (x, ke)
+                                   _             -> case recoverKindedValue si ke x of
+                                                      Just v  -> [cvVal v]
+                                                      Nothing -> tbd $ "Unexpected value for kind: " ++ show (x, ke)
+
+        interpretTuple te = walk (1 :: Int) (zipWith (recoverKindedValue si) ks args) []
+                where (ks, n) = case k of
+                                  KTuple eks -> (eks, length eks)
+                                  _          -> error $ unlines [ "Impossible: Expected a tuple kind, but got: " ++ show k
+                                                                , "While trying to parse: " ++ show te
+                                                                ]
+
+                      -- | Convert a sexpr of n-tuple to constituent sexprs. Z3 and CVC4 differ here on how they
+                      -- present tuples, so we accommodate both:
+                      args = try te
+                        where -- Z3 way
+                              try (EApp (ECon f : as)) = case splitAt (T.length "mkSBVTuple") f of
+                                                             ("mkSBVTuple", c) | all isDigit c && read c == n && length as == n -> as
+                                                             _  -> bad
+                              -- CVC4 way
+                              try  (EApp (EApp [ECon "as", ECon f, _] : as)) = try (EApp (ECon f : as))
+                              try  _ = bad
+                              bad = error $ "Data.SBV.sexprToTuple: Impossible: Expected a constructor for " ++ show n ++ " tuple, but got: " ++ show te
+
+                      walk _ []           sofar = reverse sofar
+                      walk i (Just el:es) sofar = walk (i+1) es (cvVal el : sofar)
+                      walk i (Nothing:_)  _     = error $ unlines [ "Couldn't parse a tuple element at position " ++ show i
+                                                                  , "Kind: " ++ show k
+                                                                  , "Expr: " ++ show te
+                                                                  ]
+
+        -- Intervals, for dReal
+        interpretInterval expr = case expr of
+                                   EApp [ECon "interval", lo, hi] -> do vlo <- getBorder lo
+                                                                        vhi <- getBorder hi
+                                                                        pure $ CV KReal (CAlgReal (AlgInterval vlo vhi))
+                                   _                              -> Nothing
+          where getBorder (EApp [ECon "open",   v]) = recoverKindedValue si KReal v >>= border OpenPoint
+                getBorder (EApp [ECon "closed", v]) = recoverKindedValue si KReal v >>= border ClosedPoint
+                getBorder _                         = Nothing
+
+                border b (CV KReal (CAlgReal (AlgRational True v))) = pure $ b v
+                border _ other                                      = error $ "Data.SBV.interpretInterval.border: Expected a real-valued sexp, but received: " ++ show other
+
+        -- Essentially treat sets as functions, since we do allow for store associations
+        interpretArray k1 k2 expr = case parseSExprFunction expr of
+                                      Just (Right ascs) -> decode ascs
+                                      _                 -> tbd "Expected a set value, but couldn't decipher the solver output."
+
+           where tbd :: String -> a
+                 tbd w = error $ unlines [ ""
+                                         , "*** Data.SBV.interpretArray: Unable to process solver output."
+                                         , "***"
+                                         , "*** Kind    : " ++ show k
+                                         , "*** Received: " ++ show e
+                                         , "*** Reason  : " ++ w
+                                         , "***"
+                                         , "*** This is either a bug or something SBV currently does not support."
+                                         , "*** Please report this as a feature request!"
+                                         ]
+
+                 decode (args, d) = ArrayModel [(cvt k1 l, cvt k2 [r]) | (l, r) <- args] (cvt k2 [d])
+                   where cvt ek [v] = case recoverKindedValue si ek v of
+                                         Just (CV _ x) -> x
+                                         _             -> tbd $ "Cannot convert value: " ++ show v
+                         cvt _ vs   = tbd $ "Unexpected function-like-value as array index" ++ show vs
+
+        interpretADT :: Kind -> SExpr -> (String, [(Kind, CVal)])
+        interpretADT adtK@(KADT _ _ cks) expr
+           | isUninterpreted adtK
+           = case expr of
+               ECon s -> (simplifyECon s, [])
+               _      -> bad ["Unexpected expression value for uninterpreted kind."]
+           | Just ks <- cstr `lookup` cks
+           = if length fs == length ks
+             then (cstr, zipWith convert (zip [1..] ks) fs)
+             else bad ["Mismatching field count: " ++ show (fs, ks)]
+           | True
+           = bad ["Cannot find constructor in the kind: " ++ show (cstr, adtK)]
+          where (cstr, fs) = case removeAS expr of
+                               ECon c             -> (c, [])
+                               EApp (ECon c : cs) -> (c, cs)
+                               _                  -> bad ["Unexpected expression value; does not start with a constructor."]
+
+                -- Drop the "as" annotation off the constructor, if we have one. Note that we
+                -- only strip in the head position: The fields are recovered by a recursive
+                -- call to 'recoverKindedValue', which deals with their own annotations. (Do
+                -- not be tempted to recurse into the fields here: That would corrupt values
+                -- whose annotation is load bearing, e.g., sets and arrays, which are printed
+                -- using the ((as const (Array A B)) v) form.)
+                removeAS :: SExpr -> SExpr
+                removeAS (EApp [ECon "as", i, _]) = removeAS i
+                removeAS (EApp (f@EApp{} : as))   = EApp (removeAS f : as)
+                removeAS ae                       = ae
+
+                bad :: [String] -> a
+                bad extras = error $ unlines $ [ "Data.SBV.interpretADT: Cannot recover ADT value from solver output."
+                                               , "   Kind: " ++ show adtK
+                                               , "   Expr: " ++ show expr
+                                               ] ++ extras
+
+                convert :: (Int, Kind) -> SExpr -> (Kind, CVal)
+                convert (i, fk) f = case recoverKindedValue si fk f of
+                                      Just (CV kv v) -> (kv, v)
+                                      Nothing        -> bad ["Couldn't convert field " ++ show i ++ ": " ++ show (fk, f)]
+
+        interpretADT someK expr = error $ unlines [ "Data.SBV.interpretADT: Expected an ADT kind, but got something else."
+                                                  , "   Expr: " ++ show expr
+                                                  , "   Kind: " ++ show someK
+                                                  ]
+
+-- | Generalization of 'Data.SBV.Control.getValueCV'
+getValueCV :: (MonadIO m, MonadQuery m) => Maybe Int -> SV -> m CV
+getValueCV mbi s
+  | kindOf s /= KReal
+  = getValueCVHelper mbi s
+  | True
+  = do cfg <- getConfig
+       if not (supportsApproxReals (capabilities (solver cfg)))
+          then getValueCVHelper mbi s
+          else do send True "(set-option :pp.decimal false)"
+                  rep1 <- getValueCVHelper mbi s
+                  send True   "(set-option :pp.decimal true)"
+                  send True $ "(set-option :pp.decimal_precision " <> showText (printRealPrec cfg) <> ")"
+                  rep2 <- getValueCVHelper mbi s
+
+                  let bad = unexpected "getValueCV" "get-value" ("a real-valued binding for " ++ show s) Nothing (show (rep1, rep2)) Nothing
+
+                  case (rep1, rep2) of
+                    (CV KReal (CAlgReal a), CV KReal (CAlgReal b)) -> pure $ CV KReal (CAlgReal (mergeAlgReals ("Cannot merge real-values for " ++ show s) a b))
+                    _                                              -> bad
+
+-- | Retrieve value from the solver
+extractValue :: forall m. (MonadIO m, MonadQuery m) => Maybe Int -> String -> Kind -> m CV
+extractValue mbi nm k = do
+       let modelIndex = case mbi of
+                          Nothing -> ""
+                          Just i  -> " :model_index " ++ show i
+
+           cmd        = "(get-value (" <> T.pack nm <> ")" <> T.pack modelIndex <> ")"
+
+           bad = unexpected "get-value" cmd ("a value binding for kind: " ++ show k) Nothing
+
+       r <- ask cmd
+
+       si <- queryState >>= getSInfo
+
+       let recover val = case recoverKindedValue si k val of
+                           Just cv -> pure cv
+                           Nothing -> bad r Nothing
+
+       parse r bad $ \case EApp [EApp [ECon v, val]] | v == nm -> recover val
+                           _                                   -> bad r Nothing
+
+-- | Generalization of 'Data.SBV.Control.getUICVal'
+getUICVal :: forall m. (MonadIO m, MonadQuery m) => Maybe Int -> (String, (Bool, Maybe [String], SBVType)) -> m CV
+getUICVal mbi (nm, (_, _, t)) = case t of
+                                 SBVType [k] -> extractValue mbi nm k
+                                 _           -> error $ "SBV.getUICVal: Expected to be called on an uninterpreted value of a base type, received something else: " ++ show (nm, t)
+
+-- | Generalization of 'Data.SBV.Control.getUIFunCVAssoc'
+getUIFunCVAssoc :: forall m. (MonadIO m, MonadQuery m) => Maybe Int -> (String, (Bool, Maybe [String], SBVType)) -> m (Either String ([([CV], CV)], CV))
+getUIFunCVAssoc mbi (nm, (isCurried, mbArgs, typ)) = do
+  let modelIndex = case mbi of
+                     Nothing -> ""
+                     Just i  -> " :model_index " ++ show i
+
+      cmd        = "(get-value (" <> T.pack nm <> ")" <> T.pack modelIndex <> ")"
+
+      bad        = unexpected "get-value" cmd "a function value" Nothing
+
+  r <- ask cmd
+
+  si <- queryState >>= getSInfo
+
+  let (ats, rt) = case typ of
+                    SBVType as | length as > 1 -> (init as, last as)
+                    _                          -> error $ "Data.SBV.getUIFunCVAssoc: Expected a function type, got: " ++ show typ
+
+  let convert (vs, d) = (,) <$> mapM toPoint vs <*> toRes d
+      toPoint (as, v)
+         | length as == length ats = (,) <$> zipWithM (recoverKindedValue si) ats as <*> toRes v
+         | True                    = error $ "Data.SBV.getUIFunCVAssoc: Mismatching type/value arity, got: " ++ show (as, ats)
+
+      toRes :: SExpr -> Maybe CV
+      toRes = recoverKindedValue si rt
+
+      -- if we fail to parse, we'll return this answer as the string
+      fallBack e = formatFunctionResponse e r nm isCurried mbArgs
+
+      -- In case we end up in the pointwise scenario, boolify the result
+      -- as that's the only type we support here.
+      tryPointWise e = do mbSExprs <- pointWiseExtract nm typ
+                          case mbSExprs of
+                            Nothing     -> pure $ Left $ fallBack e
+                            Just sExprs -> pure $ maybe (Left $ fallBack e) Right (convert sExprs)
+
+  parse r bad $ \case
+    EApp [EApp [ECon o, e]] | unBar o == unBar nm -> case parseSExprFunction e of
+      Just (Right assocs)
+        | Just res <- convert assocs -> pure (Right res)
+        | True                       -> tryPointWise e
+      Just (Left nm')
+        | unBar nm == unBar nm'       -> pure (Right ([], defaultKindedValue rt))
+        | True                       -> bad r Nothing
+      Nothing                        -> tryPointWise e
+    _ -> bad r Nothing
+
+-- | Generalization of 'Data.SBV.Control.checkSat'
+checkSat :: (MonadIO m, MonadQuery m) => m CheckSatResult
+checkSat = do cfg <- getConfig
+              checkSatUsing $ satCmd cfg
+
+-- | Generalization of 'Data.SBV.Control.checkSatUsing'
+checkSatUsing :: (MonadIO m, MonadQuery m) => String -> m CheckSatResult
+checkSatUsing cmd = do let bad = unexpected "checkSat" (T.pack cmd) "one of sat/unsat/unknown" Nothing
+
+                           -- Sigh.. Ignore some of the pesky warnings. We only do it as an exception here.
+                           ignoreList = ["WARNING: optimization with quantified constraints is not supported"]
+
+                       r <- askIgnoring (T.pack cmd) ignoreList
+
+                       -- query for the precision if supported
+                       let getPrecision = do cfg <- getConfig
+                                             case supportsDeltaSat (capabilities (solver cfg)) of
+                                               Nothing -> pure Nothing
+                                               Just o  -> Just <$> ask (T.pack o)
+
+                       parse r bad $ \case ECon "sat"       -> pure Sat
+                                           ECon "unsat"     -> pure Unsat
+                                           ECon "unknown"   -> pure Unk
+                                           ECon "delta-sat" -> DSat <$> getPrecision
+                                           _                -> bad r Nothing
+
+-- | What are the top level inputs? Trackers are returned as top level existentials
+getTopLevelInputs :: (MonadIO m, MonadQuery m) => m UserInputs
+getTopLevelInputs = do State{rinps}                     <- queryState
+                       Inputs{userInputs, internInputs} <- liftIO $ readIORef rinps
+
+                       pure $ userInputs <> internInputs
+
+-- | Get observables, i.e., those explicitly labeled by the user with a call to 'Data.SBV.observe'.
+getObservables :: (MonadIO m, MonadQuery m) => m [(Name, CV)]
+getObservables = do State{rObservables} <- queryState
+
+                    rObs <- liftIO $ readIORef rObservables
+
+                    -- This intentionally reverses the result; since 'rObs' stores in reversed order
+                    let walk []             !sofar = pure sofar
+                        walk ((n, f, s):os) !sofar = do cv <- getValueCV Nothing s
+                                                        if f cv
+                                                          then walk os ((n, cv) : sofar)
+                                                          else walk os            sofar
+
+                    walk (F.toList rObs) []
+
+-- | Get UIs, both constants and functions. This call returns both the before and after query ones.
+-- Generalization of 'Data.SBV.Control.getUIs'.
+getUIs :: forall m. (MonadIO m, MonadQuery m) => m [(String, (Bool, Maybe [String], SBVType))]
+getUIs = do State{rUIMap, rDefns, rIncState} <- queryState
+            -- Definitions are tracked in the UI map as well, but they are not uninterpreted.
+            defineSet <- Map.keysSet <$> io (readIORef rDefns)
+
+            prior <- io $ readIORef rUIMap
+            new   <- io $ readIORef rIncState >>= readIORef . rNewUIs
+            pure $ Map.toList $ Map.withoutKeys (Map.union prior new) defineSet
+
+-- | Return all satisfying models.
+getAllSatResult :: forall m. (MonadIO m, MonadQuery m, SolverContext m) => m AllSatResult
+getAllSatResult = do queryDebug ["*** Checking Satisfiability, all solutions.."]
+
+                     cfg <- getConfig
+                     unless (supportsCustomQueries (capabilities (solver cfg))) $
+                        error $ unlines [ ""
+                                        , "*** Data.SBV: Backend solver " ++ show (name (solver cfg)) ++ " does not support custom queries."
+                                        , "***"
+                                        , "*** Custom query support is needed for allSat functionality."
+                                        , "*** Please use a solver that supports this feature."
+                                        ]
+
+                     topState@State{rUsedKinds, rPartitionVars, rProgInfo} <- queryState
+
+                     progInfo <- liftIO $ readIORef rProgInfo
+                     ki       <- liftIO $ readIORef rUsedKinds
+
+                     allModelInputs    <- getTopLevelInputs
+                     allUninterpreteds <- getUIs
+                     partitionVars     <- liftIO $ readIORef rPartitionVars
+
+                      -- Functions have at least two kinds in their type and all components must be "interpreted"
+                     let allUiFuns = [u | allSatTrackUFs cfg                                              -- config says consider UIFs
+                                        , u@(nm, (_, _, SBVType as)) <- allUninterpreteds, length as > 1  -- get the function ones
+                                        , not (mustIgnoreVar cfg (T.pack nm))                              -- make sure they aren't explicitly ignored
+                                     ]
+
+                         allUiRegs = [u | u@(nm, (_, _, SBVType as)) <- allUninterpreteds, length as == 1 -- non-function ones
+                                        , not (mustIgnoreVar cfg (T.pack nm))                              -- make sure they aren't explicitly ignored
+                                     ]
+
+                         -- We can only "allSat" if all component types themselves are interpreted. (Otherwise
+                         -- there is no way to reflect back the values to the solver.)
+                         collectAcceptable []                                sofar = pure sofar
+                         collectAcceptable ((nm, (_, _, t@(SBVType ats))):rest) sofar
+                           | not (any hasUninterpretedSorts ats)
+                           = collectAcceptable rest (nm : sofar)
+                           | True
+                           = do queryDebug [ "*** SBV.allSat: Uninterpreted function: " <> T.pack nm <> " :: " <> showText t
+                                           , "*** Will *not* be used in allSat considerations since its type"
+                                           , "*** has uninterpreted sorts present."
+                                           ]
+                                collectAcceptable rest sofar
+
+                     uiFuns <- reverse <$> collectAcceptable allUiFuns []
+                     _      <- collectAcceptable allUiRegs [] -- only done to get the queryDebug output. Actual result not needed/used
+
+                     -- If there are uninterpreted functions, arrange so that z3's pretty-printer flattens things out
+                     -- as cex's tend to get larger
+                     unless (null uiFuns) $
+                        let solverCaps = capabilities (solver cfg)
+                        in F.for_ (supportsFlattenedModels solverCaps) (mapM_ (send True . T.pack))
+
+                     let usorts = [s | us@(KADT s _ _) <- Set.toAscList ki, isUninterpreted us]
+
+                     unless (null usorts) $ queryDebug [ "*** SBV.allSat: Uninterpreted sorts present: " <> T.pack (unwords usorts)
+                                                       , "***             SBV will use equivalence classes to generate all-satisfying instances."
+                                                       ]
+
+                     -- Drop the things that are not model vars or internal
+                     let mkSVal nm@(getSV -> sv) = (SVal (kindOf sv) (Right (cache (const (pure sv)))), nm)
+                     let extractVars :: S.Seq (SVal, NamedSymVar)
+                         extractVars = mkSVal <$> S.filter (not . mustIgnoreVar cfg . getUserName) allModelInputs
+
+                         vars :: S.Seq (SVal, NamedSymVar)
+                         vars = case partitionVars of
+                                  [] -> extractVars
+                                  pv -> mkSVal <$> S.filter (\k -> getUserName' k `elem` pv) allModelInputs
+
+                     -- We can go fast using the disjoint model trick if things are simple enough:
+                     --     - No uninterpreted functions (uninterpreted values are OK)
+                     --     - No uninterpreted sorts
+                     --     - No quantifiers
+                     --
+                     -- Why can't we support the above?
+                     --     - Uninterpreted functions: There is no (standard) way to define a function as a literal in SMTLib.
+                     --     Some solvers support lambda, but this isn't common/reliable yet.
+                     --     - Uninterpreted sort: There's no way to access the value the solver assigns to an uninterpreted sort.
+                     --     - Quantifiers: Too complicated!
+                     --
+                     -- So, if these two things are present, we go the "slow" route, by repeatedly rejecting the
+                     -- previous model and asking for a new one. If they don't exist (which is the common case anyhow)
+                     -- we use an idea due to z3 folks <http://theory.stanford.edu/%7Enikolaj/programmingz3.html#sec-blocking-evaluations>
+                     -- which splits the search space into disjoint models and can produce results much more quickly.
+                     let isSimple = null allUiFuns && null usorts && not (hasQuants progInfo)
+
+                         start = AllSatResult { allSatMaxModelCountReached  = False
+                                              , allSatSolverReturnedUnknown = False
+                                              , allSatSolverReturnedDSat    = False
+                                              , allSatResults               = []
+                                              }
+
+                     -- partition-variables are only supported if simple
+                     case partitionVars of
+                       [] -> pure ()
+                       xs -> unless isSimple $ error $ unlines [ ""
+                                                               , "Data.SBV: Unsupported complex allSat call in the presence of partition-variables"
+                                                               , ""
+                                                               , "Partition variables are only supported when there are no uninterpreted"
+                                                               , "functions or uninterpreted sorts."
+                                                               , ""
+                                                               , "Saw parition vars: " ++ unwords xs
+                                                               ]
+
+                     if isSimple
+                        then do let mkVar :: (String, (Bool, Maybe [String], SBVType)) -> IO (SVal, NamedSymVar)
+                                    mkVar (nm, (_, _, SBVType [k])) = do sv <- newExpr topState k (SBVApp (Uninterpreted (T.pack nm)) [])
+                                                                         let sval = SVal k $ Right $ cache $ \_ -> pure sv
+                                                                             nsv  = NamedSymVar sv (T.pack nm)
+                                                                         pure (sval, nsv)
+                                    mkVar nmt = error $ "Data.SBV: Impossible happened; allSat.mkVar. Unexpected: " ++ show nmt
+                                uiVars <- io $ S.fromList <$> mapM mkVar allUiRegs
+                                fastAllSat                                        allModelInputs (uiVars S.>< extractVars) (uiVars S.>< vars) cfg start
+                        else    loop       topState (allUiFuns, uiFuns) allUiRegs allModelInputs                                        vars  cfg start
+
+   where finalize cnt cfg sofar extra
+                = when (allSatPrintAlong cfg && not (null (allSatResults sofar))) $ do
+                           let msg 0 = "No solutions found."
+                               msg 1 = "This is the only solution."
+                               msg n = "Found " ++ show n ++ " different solutions."
+                           io . putStrLn $ msg (cnt - 1)
+                           case extra of
+                             Nothing -> pure ()
+                             Just m  -> io $ putStrLn m
+
+         fastAllSat :: S.Seq NamedSymVar -> S.Seq (SVal, NamedSymVar) -> S.Seq (SVal, NamedSymVar) -> SMTConfig -> AllSatResult -> m AllSatResult
+         fastAllSat allInputs extractVars vars cfg start = do
+                result <- io $ newIORef (0, start, False, Nothing)
+                go result vars
+                (found, sofar, _, extra) <- io $ readIORef result
+                finalize (found+1) cfg sofar extra
+                pure sofar
+
+           where haveEnough have = case allSatMaxModelCount cfg of
+                                     Just maxModels -> have >= maxModels
+                                     _              -> False
+
+                 go :: IORef (Int, AllSatResult, Bool, Maybe String) -> S.Seq (SVal, NamedSymVar) -> m ()
+                 go finalResult = walk True
+                   where shouldContinue = do (have, _, exitLoop, _) <- io $ readIORef finalResult
+                                             pure $ not (exitLoop || haveEnough have)
+
+                         walk :: Bool -> S.Seq (SVal, NamedSymVar) -> m ()
+                         walk firstRun terms
+                           | not firstRun && S.null terms
+                           = pure ()
+                           | True
+                           = do mbCont <- do (have, sofar, exitLoop, _) <- io $ readIORef finalResult
+                                             if exitLoop
+                                                then pure Nothing
+                                                else case allSatMaxModelCount cfg of
+                                                       Just maxModels
+                                                         | have >= maxModels -> do unless (allSatMaxModelCountReached sofar) $ do
+                                                                                      queryDebug ["*** Maximum model count request of " <> showText maxModels <> " reached, stopping the search."]
+                                                                                      when (allSatPrintAlong cfg) $ io $ putStrLn "Search stopped since model count request was reached."
+                                                                                      io $ modifyIORef' finalResult $ \(h, s, _, m) -> (h, s{ allSatMaxModelCountReached = True }, True, m)
+                                                                                   pure Nothing
+                                                       _                     -> pure $ Just $ have+1
+
+                                case mbCont of
+                                  Nothing  -> pure ()
+                                  Just cnt -> do
+                                    queryDebug ["Fast allSat, Looking for solution " <> showText cnt]
+
+                                    cs <- checkSat
+
+                                    case cs of
+                                      Unsat  -> pure ()
+
+                                      Unk    -> do queryDebug ["*** Solver returned unknown, terminating query."]
+                                                   io $ modifyIORef' finalResult $ \(h, s, _, _) -> (h, s{allSatSolverReturnedUnknown = True}, True, Just "[Solver returned unknown, terminating query.]")
+
+                                      DSat _ -> do queryDebug ["*** Solver returned delta-sat, terminating query."]
+                                                   io $ modifyIORef' finalResult $ \(h, s, _, _) -> (h, s{allSatSolverReturnedDSat = True}, True, Just "[Solver returned delta-sat, terminating query.]")
+
+                                      Sat    -> do assocs <- mapM (\(sval, NamedSymVar sv n) -> do !cv <- getValueCV Nothing sv
+                                                                                                   pure (sv, (n, (sval, cv)))) extractVars
+
+                                                   bindings <- let grab i@(getSV -> sv) = case lookupInput fst sv assocs of
+                                                                                            Just (_, (_, (_, cv))) -> pure (i, cv)
+                                                                                            Nothing                -> do !cv <- getValueCV Nothing sv
+                                                                                                                         pure (i, cv)
+                                                               in if validationRequested cfg
+                                                                  then Just <$> mapM grab allInputs
+                                                                  else pure Nothing
+
+                                                   obsvs <- getObservables
+
+                                                   let lassocs = F.toList assocs
+                                                       model   = SMTModel { modelObjectives = []
+                                                                          , modelBindings   = F.toList <$> bindings
+                                                                          , modelAssocs     =    (first T.unpack <$> sortOn fst obsvs)
+                                                                                              <> [(T.unpack n, cv) | (_, (n, (_, cv))) <- lassocs]
+                                                                          , modelUIFuns     = []
+                                                                          }
+                                                       currentResult = Satisfiable cfg model
+
+                                                   io $ modifyIORef' finalResult $ \(h, s, e, m) -> let h' = h+1 in h' `seq` (h', s{allSatResults = currentResult : allSatResults s}, e, m)
+
+                                                   when (allSatPrintAlong cfg) $ do
+                                                        io $ putStrLn $ "Solution #" ++ show cnt ++ ":"
+                                                        io $ putStrLn $ showModel cfg model
+
+                                                   let findVal :: (SVal, NamedSymVar) -> (SVal, CV)
+                                                       findVal (_, NamedSymVar sv nm) = case F.toList (S.filter (\(sv', _) -> sv == sv') assocs) of
+                                                                                           [(_, (_, scv))] -> scv
+                                                                                           _               -> error $ "Data.SBV: Cannot uniquely determine " ++ show nm ++ " in " ++ show assocs
+
+                                                       cstr :: Bool -> (SVal, CV) -> m ()
+                                                       cstr shouldReject (sv, cv) = constrain (SBV $ mkEq (kindOf sv) sv (SVal (kindOf sv) (Left cv)) :: SBool)
+                                                         where mkEq :: Kind -> SVal -> SVal -> SVal
+                                                               mkEq k a b
+                                                                | any isSomeKindOfFloat (expandKinds k)
+                                                                = if shouldReject
+                                                                     then svNot  (a `fpEq` b)
+                                                                     else         a `fpEq` b
+                                                                | True
+                                                                = if shouldReject
+                                                                     then a `svNotEqual` b
+                                                                     else a `svEqual`    b
+
+                                                               fpEq a b = SVal KBool $ Right $ cache r
+                                                                   where r st = do sva <- svToSV st a
+                                                                                   svb <- svToSV st b
+                                                                                   newExpr st KBool (SBVApp (IEEEFP FP_ObjEqual) [sva, svb])
+
+                                                       reject, accept :: (SVal, NamedSymVar) -> m ()
+                                                       reject = cstr True  . findVal
+                                                       accept = cstr False . findVal
+
+                                                       scope :: (SVal, NamedSymVar) -> S.Seq (SVal, NamedSymVar) -> m () -> m ()
+                                                       scope cur pres c = do
+                                                                send True "(push 1)"
+                                                                reject cur
+                                                                mapM_ accept pres
+                                                                r <- c
+                                                                send True "(pop 1)"
+                                                                pure r
+
+                                                   F.for_ [0 .. length terms - 1] $ \i -> do
+                                                        sc <- shouldContinue
+                                                        when sc $ do case S.splitAt i terms of
+                                                                       (pre, rest@(cur S.:<| _)) -> scope cur pre $ walk False rest
+                                                                       _                         -> error "Data.SBV.allSat: Impossible happened, ran out of terms!"
+
+         -- All sat loop. This is slower, as it implements the reject-the-previous model and loop around logic. But
+         -- it can handle uninterpreted sorts; so we keep it here as a fall-back.
+         loop topState (allUiFuns, uiFunsToReject) allUiRegs allInputs vars cfg = go (1::Int)
+           where go :: Int -> AllSatResult -> m AllSatResult
+                 go !cnt !sofar
+                   | Just maxModels <- allSatMaxModelCount cfg, cnt > maxModels
+                   = do queryDebug ["*** Maximum model count request of " <> showText maxModels <> " reached, stopping the search."]
+                        when (allSatPrintAlong cfg) $ io $ putStrLn "Search stopped since model count request was reached."
+                        pure $! sofar { allSatMaxModelCountReached = True }
+                   | True
+                   = do queryDebug ["Looking for solution " <> showText cnt]
+
+                        cs <- checkSat
+
+                        let endMsg = finalize cnt cfg sofar
+
+                        case cs of
+                          Unsat  -> do endMsg Nothing
+                                       pure sofar
+
+                          Unk    -> do queryDebug ["*** Solver returned unknown, terminating query."]
+                                       endMsg $ Just "[Solver returned unknown, terminating query.]"
+                                       pure sofar{ allSatSolverReturnedUnknown = True }
+
+                          DSat _ -> do queryDebug ["*** Solver returned delta-sat, terminating query."]
+                                       endMsg $ Just "[Solver returned delta-sat, terminating query.]"
+                                       pure sofar{ allSatSolverReturnedDSat = True }
+
+                          Sat    -> do assocs <- mapM (\(sval, NamedSymVar sv n) -> do !cv <- getValueCV Nothing sv
+                                                                                       pure (sv, (n, (sval, cv)))) vars
+
+                                       let getUIFun ui@(nm, (isCurried, _, t)) = do cvs <- getUIFunCVAssoc Nothing ui
+                                                                                    pure (nm, (isCurried, t, cvs))
+                                       uiFunVals <- mapM getUIFun allUiFuns
+
+                                       uiRegVals <- mapM (\ui@(nm, _) -> (nm,) <$> getUICVal Nothing ui) allUiRegs
+
+                                       obsvs <- getObservables
+
+                                       bindings <- let grab i@(getSV -> sv) = case lookupInput fst sv assocs of
+                                                                                Just (_, (_, (_, cv))) -> pure (i, cv)
+                                                                                Nothing                -> do !cv <- getValueCV Nothing sv
+                                                                                                             pure (i, cv)
+                                                   in if validationRequested cfg
+                                                         then Just <$> mapM grab allInputs
+                                                         else pure Nothing
+
+                                       let model = SMTModel { modelObjectives = []
+                                                            , modelBindings   = F.toList <$> bindings
+                                                            , modelAssocs     =    uiRegVals
+                                                                                <> (first T.unpack <$> sortOn fst obsvs)
+                                                                                <> [(T.unpack n, cv) | (_, (n, (_, cv))) <- F.toList assocs]
+                                                            , modelUIFuns     = uiFunVals
+                                                            }
+                                           m = Satisfiable cfg model
+
+                                           (interpreteds, uninterpreteds) = S.partition (not . isUninterpreted . kindOf . fst) (snd . snd <$> assocs)
+
+                                           interpretedRegUis = filter (not . isUninterpreted . kindOf . snd) uiRegVals
+
+                                           interpretedRegUiSVs = [(cvt n (kindOf cv), cv) | (n, cv) <- interpretedRegUis]
+                                             where cvt :: String -> Kind -> SVal
+                                                   cvt nm k = SVal k $ Right $ cache r
+                                                     where r st = newExpr st k (SBVApp (Uninterpreted (T.pack nm)) [])
+
+                                           -- For each interpreted variable, figure out the model equivalence
+                                           -- NB. When the kind is floating, we *have* to be careful, since +/- zero, and NaN's
+                                           -- and equality don't get along!
+                                           interpretedEqs :: [SVal]
+                                           interpretedEqs = [mkNotEq (kindOf sv) sv (SVal (kindOf sv) (Left cv)) | (sv, cv) <- interpretedRegUiSVs <> F.toList interpreteds]
+                                              where mkNotEq k a b
+                                                     | isDouble k || isFloat k || isFP k
+                                                     = svNot (a `fpEq` b)
+                                                     | True
+                                                     = a `svNotEqual` b
+
+                                                    fpEq a b = SVal KBool $ Right $ cache r
+                                                        where r st = do sva <- svToSV st a
+                                                                        svb <- svToSV st b
+                                                                        newExpr st KBool (SBVApp (IEEEFP FP_ObjEqual) [sva, svb])
+
+                                           -- For each uninterpreted constant, use equivalence class
+                                           uninterpretedEqs :: [SVal]
+                                           uninterpretedEqs = concatMap pwDistinct         -- Assert that they are pairwise distinct
+                                                            . filter (\l -> length l > 1)  -- Only need this class if it has at least two members
+                                                            . map (map fst)                -- throw away values, we only need svals
+                                                            . groupBy ((==) `on` snd)      -- make sure they belong to the same sort and have the same value
+                                                            . sortOn snd                   -- sort them according to their CV (i.e., sort/value)
+                                                            $ F.toList uninterpreteds
+                                             where pwDistinct :: [SVal] -> [SVal]
+                                                   pwDistinct ss = [x `svNotEqual` y | (x:ys) <- tails ss, y <- ys]
+
+                                           -- For each uninterpreted function, create a disqualifying equation
+                                           -- We do this rather brute-force, since we need to create a new function
+                                           -- and do an existential assertion.
+                                           uninterpretedReject :: Maybe [T.Text]
+                                           uninterpretedFuns   :: [T.Text]
+                                           (uninterpretedReject, uninterpretedFuns) = (uiReject, concat defs)
+                                               where uiReject = case rejects of
+                                                                  []  -> Nothing
+                                                                  xs  -> Just xs
+
+                                                     (rejects, defs) = unzip [mkNotEq ui | ui@(nm, _) <- uiFunVals, nm `elem` uiFunsToReject]
+
+                                                     -- Otherwise, we have things to refute, go for it if we have a good interpretation for it
+                                                     mkNotEq (nm, (_, typ, Left def)) =
+                                                        error $ unlines [
+                                                            ""
+                                                          , "*** allSat: Unsupported: Building a rejecting instance for:"
+                                                          , "***"
+                                                          , "***     " ++ nm ++ " :: " ++ show typ
+                                                          , "***     " ++ def
+                                                          , "***"
+                                                          , "*** At this time, SBV cannot compute allSat when the model has a non-table definition."
+                                                          , "***"
+                                                          , "*** You can ignore specific functions via the 'isNonModelVar' filter:"
+                                                          , "***"
+                                                          , "***    allSatWith z3{isNonModelVar = (`elem` [" ++ show nm ++ "])} ..."
+                                                          , "***"
+                                                          , "*** Or you can ignore all uninterpreted functions for all-sat purposes using the 'allSatTrackUFs' parameter:"
+                                                          , "***"
+                                                          , "***    allSatWith z3{allSatTrackUFs = False} ..."
+                                                          , "***"
+                                                          , "*** You can see the response from the solver by running with the '{verbose = True}' option."
+                                                          , "***"
+                                                          , "*** NB. If this is a use case you'd like SBV to support, please get in touch!"
+                                                          ]
+                                                     mkNotEq (nm, (_, SBVType ts, Right vs)) = (reject, def ++ dif)
+                                                       where nm' = T.pack nm <> "_model" <> showText cnt
+
+                                                             reject = nm' <> "_reject"
+
+                                                             -- convert a constant
+                                                             scv = cvToSMTLib
+
+                                                             (ats, rt) = (init ts, last ts)
+
+                                                             args = T.unwords ["(x!" <> showText i <> " " <> smtType t <> ")" | (t, i) <- zip ats [(0::Int)..]]
+                                                             res  = smtType rt
+
+                                                             params = ["x!" <> showText i | (_, i) <- zip ats [(0::Int)..]]
+
+                                                             uparams = T.unwords params
+
+                                                             chain (vals, fallThru) = walk vals
+                                                               where walk []               = ["   " <> scv fallThru <> T.replicate (length vals) ")"]
+                                                                     walk ((as, r) : rest) = ("   (ite " <> cond as <> " " <> scv r) :  walk rest
+
+                                                                     cond as = "(and " <> T.unwords (zipWith eq params as) <> ")"
+                                                                     eq p a  = "(= " <> p <> " " <> scv a <> ")"
+
+                                                             def =    ("(define-fun " <> nm' <> " (" <> args <> ") " <> res)
+                                                                   :  chain vs
+                                                                   ++ [")"]
+
+                                                             pad = T.replicate (1 + T.length nm' - length nm) " "
+
+                                                             dif = [ "(define-fun " <>  reject <> " () Bool"
+                                                                   , "   (exists (" <> args <> ")"
+                                                                   , "           (distinct (" <> T.pack nm  <> pad <> uparams <> ")"
+                                                                   , "                     (" <> nm' <> " " <> uparams <> "))))"
+                                                                   ]
+
+                                           eqs = interpretedEqs ++ uninterpretedEqs
+
+                                           disallow = case eqs of
+                                                        [] -> Nothing
+                                                        _  -> Just $ SBV $ foldr1 svOr eqs
+
+                                       when (allSatPrintAlong cfg) $ do
+                                         io $ putStrLn $ "Solution #" ++ show cnt ++ ":"
+                                         io $ putStrLn $ showModel cfg model
+
+                                       let resultsSoFar = sofar { allSatResults = m : allSatResults sofar }
+
+                                           -- This is clunky, but let's not generate a rejector unless we really need it
+                                           needMoreIterations
+                                                 | Just maxModels <- allSatMaxModelCount cfg, (cnt+1) > maxModels = False
+                                                 | True                                                           = True
+
+                                       -- Send function disequalities, if any:
+                                       if not needMoreIterations
+                                          then go (cnt+1) resultsSoFar
+                                          else do let uiFunRejector   = "uiFunRejector_model_" ++ show cnt
+                                                      header          = "define-fun " ++ uiFunRejector ++ " () Bool "
+
+                                                      defineRejector []     = pure ()
+                                                      defineRejector [x]    = send True $ "(" <> T.pack header <> x <> ")"
+                                                      defineRejector (x:xs) = mapM_ (send True) $ mergeSExpr
+                                                                                                                  $  T.pack ("(" ++ header)
+                                                                                                                  :  ("        (or " <> x)
+                                                                                                                  :  ["            " <> e | e <- xs]
+                                                                                                                  ++ ["        ))"]
+                                                  rejectFuncs <- case uninterpretedReject of
+                                                                   Nothing -> pure Nothing
+                                                                   Just fs -> do mapM_ (send True) $ mergeSExpr uninterpretedFuns
+                                                                                 defineRejector fs
+                                                                                 pure $ Just uiFunRejector
+
+                                                  -- send the disallow clause and the uninterpreted rejector:
+                                                  case (disallow, rejectFuncs) of
+                                                     (Nothing, Nothing) -> pure resultsSoFar
+                                                     (Just d,  Nothing) -> do constrain d
+                                                                              go (cnt+1) resultsSoFar
+                                                     (Nothing, Just f)  -> do send True $ "(assert " <> T.pack f <> ")"
+                                                                              go (cnt+1) resultsSoFar
+                                                     (Just d,  Just f)  -> -- This is where it gets ugly. We have an SBV and a string and we need to "or" them.
+                                                                           -- But we need a way to force 'd' to be produced. So, go ahead and force it:
+                                                                           do constrain $ d .=> d  -- NB: Redundant, but it makes sure the corresponding constraint gets shown
+                                                                              svd <- io $ svToSV topState (unSBV d)
+                                                                              send True $ "(assert (or " <> T.pack f <> " " <> showText svd <> "))"
+                                                                              go (cnt+1) resultsSoFar
+
+-- | Generalization of 'Data.SBV.Control.getUnsatAssumptions'
+getUnsatAssumptions :: (MonadIO m, MonadQuery m) => [String] -> [(String, a)] -> m [a]
+getUnsatAssumptions originals proxyMap = do
+        let cmd = "(get-unsat-assumptions)" :: T.Text
+
+            bad = unexpected "getUnsatAssumptions" cmd "a list of unsatisfiable assumptions"
+                           $ Just [ "Make sure you use:"
+                                  , ""
+                                  , "       setOption $ ProduceUnsatAssumptions True"
+                                  , ""
+                                  , "to make sure the solver is ready for producing unsat assumptions,"
+                                  , "and that there is a model by first issuing a 'checkSat' call."
+                                  ]
+
+            fromECon (ECon s) = Just s
+            fromECon _        = Nothing
+
+        r <- ask cmd
+
+        -- If unsat-cores are enabled, z3 might end-up printing an assumption that wasn't
+        -- in the original list of assumptions for `check-sat-assuming`. So, we walk over
+        -- and ignore those that weren't in the original list, and put a warning for those
+        -- we couldn't find.
+        let walk []     sofar = pure $ reverse sofar
+            walk (a:as) sofar = case a `lookup` proxyMap of
+                                  Just v  -> walk as (v:sofar)
+                                  Nothing -> do queryDebug [ "*** In call to 'getUnsatAssumptions'"
+                                                           , "***"
+                                                           , "***    Unexpected assumption named: " <> showText a
+                                                           , "***    Was expecting one of       : " <> showText originals
+                                                           , "***"
+                                                           , "*** This can happen if unsat-cores are also enabled. Ignoring."
+                                                           ]
+                                                walk as sofar
+
+        parse r bad $ \case
+           EApp es | Just xs <- mapM fromECon es -> walk xs []
+           _                                     -> bad r Nothing
+
+-- | Timeout a query action, typically a command call to the underlying SMT solver.
+-- The duration is in microseconds (@1\/10^6@ seconds). If the duration
+-- is negative, then no timeout is imposed. When specifying long timeouts, be careful not to exceed
+-- @maxBound :: Int@. (On a 64 bit machine, this bound is practically infinite. But on a 32 bit
+-- machine, it corresponds to about 36 minutes!)
+--
+-- Semantics: The call @timeout n q@ causes the timeout value to be applied to all interactive calls that take place
+-- as we execute the query @q@. That is, each call that happens during the execution of @q@ gets a separate
+-- time-out value, as opposed to one timeout value that limits the whole query. This is typically the intended behavior.
+-- It is advisable to apply this combinator to calls that involve a single call to the solver for
+-- finer control, as opposed to an entire set of interactions. However, different use cases might call for different scenarios.
+--
+-- If the solver responds within the time-out specified, then we continue as usual. However, if the backend solver times-out
+-- using this mechanism, there is no telling what the state of the solver will be. Thus, we raise an error in this case.
+timeout :: (MonadIO m, MonadQuery m) => Int -> m a -> m a
+timeout n q = do modifyQueryState (\qs -> qs {queryTimeOutValue = Just n})
+                 r <- q
+                 modifyQueryState (\qs -> qs {queryTimeOutValue = Nothing})
+                 pure r
+
+-- | Bail out if a parse goes bad
+parse :: String -> (String -> Maybe [String] -> a) -> (SExpr -> a) -> a
+parse r fCont sCont = case parseSExpr r of
+                        Left  e   -> fCont r (Just [e])
+                        Right res -> sCont res
+
+-- | Generalization of 'Data.SBV.Control.unexpected'
+unexpected :: (MonadIO m, MonadQuery m) => String -> T.Text -> String -> Maybe [String] -> String -> Maybe [String] -> m a
+unexpected ctx sent expected mbHint received mbReason = do
+        -- empty the response channel first
+        extras <- retrieveResponse "terminating upon unexpected response" (Just 5000000)
+
+        cfg <- getConfig
+
+        let exc = SBVException { sbvExceptionDescription = "Unexpected response from the solver, context: " ++ ctx
+                               , sbvExceptionSent        = Just (T.unpack sent)
+                               , sbvExceptionExpected    = Just expected
+                               , sbvExceptionReceived    = Just received
+                               , sbvExceptionStdOut      = Just $ unlines extras
+                               , sbvExceptionStdErr      = Nothing
+                               , sbvExceptionExitCode    = Nothing
+                               , sbvExceptionConfig      = cfg
+                               , sbvExceptionReason      = mbReason
+                               , sbvExceptionHint        = mbHint
+                               }
+
+        io $ C.throwIO exc
+
+-- | Convert a query result to an SMT Problem
+runProofOn :: SBVRunMode -> QueryContext -> [String] -> Result -> SMTProblem
+runProofOn rm context comments res@(Result progInfo ki _qcInfo _observables _codeSegs is consts tbls uis defns pgm cstrs _assertions outputs) =
+     let (config, isSat, isSafe, isSetup) = case rm of
+                                              SMTMode _ stage s c -> (c, s, isSafetyCheckingIStage stage, isSetupIStage stage)
+                                              _                   -> error $ "runProofOn: Unexpected run mode: " ++ show rm
+
+         o | isSafe = trueSV
+           | True   = case outputs of
+                        []  | isSetup -> trueSV
+                        [so]          -> case so of
+                                           SV KBool _ -> so
+                                           _          -> error $ unlines [ "Impossible happened, non-boolean output: " ++ show so
+                                                                         , "Detected while generating the trace:\n" ++ show res
+                                                                         ]
+                        os  -> error $ unlines [ "User error: Multiple output values detected: " ++ show os
+                                               , "Detected while generating the trace:\n" ++ show res
+                                               , "*** Check calls to \"output\", they are typically not needed!"
+                                               ]
+
+     in SMTProblem { smtLibPgm = toSMTLib config context progInfo ki isSat comments is consts tbls uis defns pgm cstrs o }
+
+-- | Generalization of 'Data.SBV.Control.executeQuery'
+executeQuery :: forall m a. ExtractIO m => QueryContext -> QueryT m a -> SymbolicT m a
+executeQuery queryContext originalQuery = do
+     st <- symbolicEnv
+     rm <- liftIO $ readIORef (runMode st)
+
+     -- Make sure the phases match:
+     () <- liftIO $ case (queryContext, rm) of
+                      (QueryInternal, _)                                -> pure ()  -- no worries, internal
+                      (QueryExternal, SMTMode QueryExternal ISetup _ _) -> pure () -- legitimate runSMT call
+                      _                                                 -> invalidQuery rm
+
+     case rm of
+        -- Transitioning from setup
+        SMTMode qc stage isSAT cfg | not (isRunIStage stage) -> do
+
+                  let slvr    = solver cfg
+                      backend = engine slvr
+
+                  -- make sure if we have dsat precision, then solver supports it
+                  let dsatOK =  isNothing (dsatPrecision cfg)
+                             || isJust    (supportsDeltaSat (capabilities slvr))
+
+                  unless dsatOK $ error $ unlines
+                                     [ ""
+                                     , "*** Data.SBV: Delta-sat precision is specified."
+                                     , "***           But the chosen solver (" ++ show (name slvr) ++ ") does not support"
+                                     , "***           delta-satisfiability."
+                                     ]
+
+                  res     <- liftIO $ extractSymbolicSimulationState st
+                  setOpts <- liftIO $ reverse <$> readIORef (rSMTOptions st)
+
+                  -- Run any registered measure checks (termination/productivity verification)
+                  checks <- liftIO $ readIORef (rMeasureChecks st)
+                  liftIO $ verifyMeasureChecks cfg st checks
+
+                  let SMTProblem{smtLibPgm} = runProofOn rm queryContext [] res
+                      cfg' = cfg { solverSetOptions = solverSetOptions cfg ++ setOpts }
+                      pgm  = smtLibPgm cfg'
+
+                  liftIO $ writeIORef (runMode st) $ SMTMode qc IRun isSAT cfg
+
+                  let terminateSolver maybeForwardedException = do
+                         qs <- readIORef $ rQueryState st
+                         case qs of
+                           Nothing                         -> pure ()
+                           Just QueryState{queryTerminate} -> queryTerminate maybeForwardedException
+
+                  -- If this is an external query and there are objectives, let's add those to the list before we run
+                  -- Here we only allow Lexicographic; we might want to make that configurable later.
+                  let userQuery = case queryContext of
+                                    QueryInternal -> originalQuery
+                                    QueryExternal -> do mbDirs <- startOptimizer cfg Lexicographic
+                                                        case mbDirs of
+                                                          Nothing        -> pure ()
+                                                          Just (_, cmds) -> mapM_ (send True . T.pack) cmds
+                                                        originalQuery
+
+                  lift $ join $ liftIO $ C.mask $ \restore -> do
+                    r <- restore (extractIO $ join $ liftIO $ backend cfg' st (smtLibPgmText pgm) $ extractIO . runReaderT (runQueryT userQuery))
+                          `C.catch` \e -> terminateSolver (Just e) >> C.throwIO (e :: C.SomeException)
+                    terminateSolver Nothing
+                    pure r
+
+        -- Already in a query, in theory we can just continue, but that causes use-case issues
+        -- so we reject it. TODO: Review if we should actually support this. The issue arises with
+        -- expressions like this:
+        --
+        -- In the following t0's output doesn't get recorded, as the output call is too late when we get
+        -- here. (The output field isn't "incremental.") So, t0/t1 behave differently!
+        --
+        --   t0 = satWith z3{verbose=True, transcript=Just "t.smt2"} $ query (return (false::SBool))
+        --   t1 = satWith z3{verbose=True, transcript=Just "t.smt2"} $ ((return (false::SBool)) :: Predicate)
+        --
+        -- Also, not at all clear what it means to go in an out of query mode:
+        --
+        -- r = runSMTWith z3{verbose=True} $ do
+        --         a' <- sInteger "a"
+        --
+        --        (a, av) <- query $ do _ <- checkSat
+        --                              av <- getValue a'
+        --                              return (a', av)
+        --
+        --        liftIO $ putStrLn $ "Got: " ++ show av
+        --        -- constrain $ a .> literal av + 1      -- Can't do this since we're "out" of query. Sigh.
+        --
+        --        bv <- query $ do constrain $ a .> literal av + 1
+        --                         _ <- checkSat
+        --                         getValue a
+        --
+        --        return $ a' .== a' + 1
+        --
+        -- This would be one possible implementation, alas it has the problems above:
+        --
+        --    SMTMode IRun _ _ -> liftIO $ evalStateT userQuery st
+        --
+        -- So, we just reject it.
+
+        SMTMode _ IRun _ _ -> error $ unlines [ ""
+                                              , "*** Data.SBV: Unsupported nested query is detected."
+                                              , "***"
+                                              , "*** Please group your queries into one block. Note that this"
+                                              , "*** can also arise if you have a call to 'query' not within 'runSMT'"
+                                              , "*** For instance, within 'sat'/'prove' calls with custom user queries."
+                                              , "*** The solution is to do the sat/prove part in the query directly."
+                                              , "***"
+                                              , "*** While multiple/nested queries should not be necessary in general,"
+                                              , "*** please do get in touch if your use case does require such a feature,"
+                                              , "*** to see how we can accommodate such scenarios."
+                                              ]
+
+        -- Otherwise choke!
+        _ -> invalidQuery rm
+
+  where invalidQuery rm = error $ unlines [ ""
+                                          , "*** Data.SBV: Invalid query call."
+                                          , "***"
+                                          , "***   Current mode: " ++ show rm
+                                          , "***"
+                                          , "*** Query calls are only valid within runSMT/runSMTWith calls,"
+                                          , "*** and each call to runSMT should have only one query call inside."
+                                          ]
+
+-- | Preparing for optimization. If we have objectives, returns the directives for the solver. If not, it returns nothing.
+startOptimizer :: (MonadIO m, MonadQuery m) => SMTConfig -> OptimizeStyle -> m (Maybe ([Objective (SV, SV)], [String]))
+startOptimizer config style = do
+  objectives <- getObjectives
+
+  if null objectives
+     then pure Nothing
+     else do unless (supportsOptimization (capabilities (solver config))) $
+                    error $ unlines [ ""
+                                    , "*** Data.SBV: The backend solver " ++ show (name (solver config)) ++ "does not support optimization goals."
+                                    , "*** Please use a solver that has support, such as z3"
+                                    ]
+
+             when (validateModel config && not (optimizeValidateConstraints config)) $
+                    error $ unlines [ ""
+                                    , "*** Data.SBV: Model validation is not supported in optimization calls."
+                                    , "***"
+                                    , "*** Instead, use `cfg{optimizeValidateConstraints = True}`"
+                                    , "***"
+                                    , "*** which checks that the results satisfy the constraints but does"
+                                    , "*** NOT ensure that they are optimal."
+                                    ]
+
+
+             let optimizerDirectives = concatMap minmax objectives ++ priority style
+                   where mkEq (x, y) = "(assert (= " ++ show x ++ " " ++ show y ++ "))"
+
+                         minmax (Minimize          _  xy@(_, v))     = [mkEq xy, "(minimize "    ++ show v                 ++ ")"]
+                         minmax (Maximize          _  xy@(_, v))     = [mkEq xy, "(maximize "    ++ show v                 ++ ")"]
+                         minmax (AssertWithPenalty nm xy@(_, v) mbp) = [mkEq xy, "(assert-soft " ++ show v ++ penalize mbp ++ ")"]
+                           where penalize DefaultPenalty    = ""
+                                 penalize (Penalty w mbGrp)
+                                    | w <= 0 = error $ unlines [ "SBV.AssertWithPenalty: Goal " ++ show nm ++ " is assigned a non-positive penalty: " ++ shw
+                                                               , "All soft goals must have > 0 penalties associated."
+                                                               ]
+                                    | True   = " :weight " ++ shw ++ maybe "" group mbGrp
+                                    where shw = show (fromRational w :: Double)
+
+                                 group g = " :id " ++ g
+
+                         priority Lexicographic = [] -- default, no option needed
+                         priority Independent   = ["(set-option :opt.priority box)"]
+                         priority (Pareto _)    = ["(set-option :opt.priority pareto)"]
+
+             pure $ Just (objectives, optimizerDirectives)
+
+-- | Just after a check-sat is issued, collect objective values. Used
+-- internally only, not exposed to the user.
+getObjectiveValues :: forall m. (MonadIO m, MonadQuery m) => m [(String, GeneralizedCV)]
+getObjectiveValues = do let cmd = "(get-objectives)" :: T.Text
+
+                            bad = unexpected "getObjectiveValues" cmd "a list of objective values" Nothing
+
+                        r <- ask cmd
+
+                        si <- queryState >>= getSInfo
+
+                        inputs <- F.toList <$> getTopLevelInputs
+
+                        parse r bad $ \case EApp (ECon "objectives" : es) -> catMaybes <$> mapM (getObjValue si (bad r) inputs) es
+                                            _                             -> bad r Nothing
+
+  where -- | Parse an objective value out.
+        getObjValue :: SInfo -> (forall a. Maybe [String] -> m a) -> [NamedSymVar] -> SExpr -> m (Maybe (String, GeneralizedCV))
+        getObjValue si bailOut inputs expr =
+                case expr of
+                  EApp [_]          -> pure Nothing            -- Happens when a soft-assertion has no associated group.
+                  EApp [ECon nm, v] -> locate nm v               -- Regular case
+                  _                 -> dontUnderstand (show expr)
+
+          where locate nm v = case listToMaybe [p | p@(NamedSymVar sv _) <- inputs, show sv == nm] of
+                                Nothing                          -> pure Nothing -- Happens when the soft assertion has a group-id that's not one of the input names
+                                Just (NamedSymVar sv actualName) -> grab sv v >>= \val -> pure $ Just (T.unpack actualName, val)
+
+                dontUnderstand s = bailOut $ Just [ "Unable to understand solver output."
+                                                  , "While trying to process: " ++ s
+                                                  ]
+
+                grab :: SV -> SExpr -> m GeneralizedCV
+                grab s topExpr
+                  | Just v <- recoverKindedValue si k topExpr = pure $ RegularCV v
+                  | True                                      = ExtendedCV <$> cvt (simplify topExpr)
+                  where k = kindOf s
+
+                        -- Convert to an extended expression. Hopefully complete!
+                        cvt :: SExpr -> m ExtCV
+                        cvt (ECon "oo")                    = pure $ Infinite  k
+                        cvt (ECon "epsilon")               = pure $ Epsilon   k
+                        cvt (EApp [ECon "interval", x, y]) =          Interval  <$> cvt x <*> cvt y
+                        cvt (ENum    (i, _, _))            = pure $ BoundedCV $ mkConstCV k i
+                        cvt (EReal   r)                    = pure $ BoundedCV $ CV k $ CAlgReal r
+                        cvt (EFloat  f)                    = pure $ BoundedCV $ CV k $ CFloat   f
+                        cvt (EDouble d)                    = pure $ BoundedCV $ CV k $ CDouble  d
+                        cvt (EApp [ECon "+", x, y])        =          AddExtCV <$> cvt x <*> cvt y
+                        cvt (EApp [ECon "*", x, y])        =          MulExtCV <$> cvt x <*> cvt y
+                        -- Nothing else should show up, hopefully!
+                        cvt e = dontUnderstand (show e)
+
+                        -- drop the pesky to_real's that Z3 produces.. Cool but useless.
+                        simplify :: SExpr -> SExpr
+                        simplify (EApp [ECon "to_real", n]) = n
+                        simplify (EApp xs)                  = EApp (map simplify xs)
+                        simplify e                          = e
+
+-- | Generalization of 'Data.SBV.Control.getModel'
+getModel :: (MonadIO m, MonadQuery m) => m SMTModel
+getModel = getModelAtIndex Nothing
+
+-- | Get a model stored at an index. This is likely very Z3 specific!
+getModelAtIndex :: (MonadIO m, MonadQuery m) => Maybe Int -> m SMTModel
+getModelAtIndex mbi = do
+    State{runMode} <- queryState
+    rm <- io $ readIORef runMode
+    case rm of
+      m@CodeGen     -> error $ "SBV.getModel: Model is not available in mode: " ++ show m
+      m@LambdaGen{} -> error $ "SBV.getModel: Model is not available in mode: " ++ show m
+      m@Concrete{}  -> error $ "SBV.getModel: Model is not available in mode: " ++ show m
+      SMTMode{}     -> do
+          cfg <- getConfig
+          uis <- getUIs
+
+          allModelInputs <- getTopLevelInputs
+          obsvs          <- getObservables
+
+          inputAssocs <- let grab (NamedSymVar sv nm) = let wrap !c = (sv, (nm, c)) in wrap <$> getValueCV mbi sv
+                         in mapM grab allModelInputs
+
+          let name     = fst . snd
+              removeSV = snd
+              prepare  = S.unstableSort . S.filter (not . mustIgnoreVar cfg . name)
+              assocs   = (removeSV <$> prepare inputAssocs) <> S.fromList (sortOn fst obsvs)
+
+          -- collect UIs, and UI functions if requested
+          let uiFuns = [ui | ui@(nm, (_, _, SBVType as)) <- uis, length as >  1, allSatTrackUFs cfg, not (mustIgnoreVar cfg (T.pack nm))] -- functions have at least two things in their type!
+              uiRegs = [ui | ui@(nm, (_, _, SBVType as)) <- uis, length as == 1,                     not (mustIgnoreVar cfg (T.pack nm))]
+
+          -- If there are uninterpreted functions, arrange so that z3's pretty-printer flattens things out
+          -- as cex's tend to get larger
+          unless (null uiFuns) $
+             let solverCaps = capabilities (solver cfg)
+             in F.for_ (supportsFlattenedModels solverCaps) (mapM_ (send True . T.pack))
+
+          bindings <- let get i@(getSV -> sv) = case lookupInput fst sv inputAssocs of
+                                                  Just (_, (_, cv)) -> pure (i, cv)
+                                                  Nothing           -> do cv <- getValueCV mbi sv
+                                                                          pure (i, cv)
+
+                      in if validationRequested cfg
+                         then Just <$> mapM get allModelInputs
+                         else pure Nothing
+
+          uiFunVals <- mapM (\ui@(nm, (c, _, t)) -> (\a -> (nm, (c, t, a))) <$> getUIFunCVAssoc mbi ui) uiFuns
+
+          uiVals    <- mapM (\ui@(nm, (_, _, _)) -> (nm,) <$> getUICVal mbi ui) uiRegs
+
+          pure $ unBarModel $ SMTModel { modelObjectives = []
+                                       , modelBindings   = F.toList <$> bindings
+                                       , modelAssocs     = uiVals ++ F.toList (first T.unpack <$> assocs)
+                                       , modelUIFuns     = uiFunVals
+                                       }
+
+-- | Remove the bars from model names; these are (mostly!) automatically inserted
+unBarModel :: SMTModel -> SMTModel
+unBarModel SMTModel {modelObjectives, modelBindings, modelAssocs, modelUIFuns}
+   = SMTModel { modelObjectives = ubf       <$> modelObjectives
+              , modelBindings   = (ubn <$>) <$> modelBindings
+              , modelAssocs     = ubf       <$> modelAssocs
+              , modelUIFuns     = ubf       <$> modelUIFuns
+              }
+   where ubf (n, a) = (unBar n, a)
+         ubn (NamedSymVar sv nm, a) = (NamedSymVar sv (unBarT nm), a)
+
+         unBarT t = case T.uncons t of
+                      Just ('|', rest) | not (T.null rest) && T.last rest == '|' -> T.init rest
+                      _                                                          -> t
+
+{- HLint ignore module          "Reduce duplication" -}
+{- HLint ignore getAllSatResult "Use forM_"          -}
+{- HLint ignore getModelAtIndex "Use forM_"          -}
diff --git a/Data/SBV/Core/AlgReals.hs b/Data/SBV/Core/AlgReals.hs
--- a/Data/SBV/Core/AlgReals.hs
+++ b/Data/SBV/Core/AlgReals.hs
@@ -9,12 +9,13 @@
 -- Algebraic reals in Haskell.
 -----------------------------------------------------------------------------
 
+{-# LANGUAGE BangPatterns       #-}
 {-# LANGUAGE DeriveAnyClass     #-}
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE DeriveGeneric      #-}
 {-# LANGUAGE FlexibleInstances  #-}
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
 module Data.SBV.Core.AlgReals (
              AlgReal(..)
@@ -101,7 +102,7 @@
        merge []                     = []
        merge [x]                    = [x]
        merge ((a, b):r@((c, d):xs))
-         | b == d                   = merge ((a+c, b):xs)
+         | b == d                   = let !s = a+c in merge ((s, b):xs)
          | True                     = (a, b) : merge r
 
 instance Show AlgRealPoly where
@@ -129,8 +130,8 @@
 instance Show AlgReal where
   show (AlgRational exact a)         = showRat exact a
   show (AlgPolyRoot (i, p) mbApprox) = "root(" ++ show i ++ ", " ++ show p ++ ")" ++ maybe "" app mbApprox
-     where app v | last v == '?' = " = " ++ init v ++ "..."
-                 | True          = " = " ++ v
+     where app v | not (null v) && last v == '?' = " = " ++ init v ++ "..."
+                 | True                          = " = " ++ v
   show (AlgInterval a b)         = case (a, b) of
                                      (OpenPoint   l, OpenPoint   h) -> "(" ++ show l ++ ", " ++ show h ++ ")"
                                      (OpenPoint   l, ClosedPoint h) -> "(" ++ show l ++ ", " ++ show h ++ "]"
@@ -196,7 +197,7 @@
   toRational (AlgRational True v) = v
   toRational x                    = error $ "AlgReal.toRational: Argument cannot be represented as a rational value: " ++ algRealToHaskell x
 
--- | Random instance for rational needs to be careful to split the generator twice for numerator and denumerator
+-- | Random instance for rational needs to be careful to split the generator twice for numerator and denominator
 instance Random Rational where
   random g = (a % b', g'')
      where (a, g')  = random g
@@ -348,4 +349,4 @@
 
 -- Quickcheck instance
 instance Arbitrary AlgReal where
-  arbitrary = AlgRational True `fmap` arbitrary
+  arbitrary = AlgRational True <$> arbitrary
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
@@ -10,11 +10,10 @@
 -----------------------------------------------------------------------------
 
 {-# LANGUAGE DeriveAnyClass      #-}
-{-# LANGUAGE DeriveGeneric       #-}
 {-# LANGUAGE DeriveDataTypeable  #-}
+{-# LANGUAGE DeriveGeneric       #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeApplications    #-}
-{-# LANGUAGE Rank2Types          #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -29,6 +28,7 @@
 
 import Data.Char (chr, isSpace)
 import Data.List (intercalate)
+import qualified Data.Text as T
 
 import Data.SBV.Core.Kind
 import Data.SBV.Core.AlgReals
@@ -91,7 +91,7 @@
 -- That is, we store the history of the writes. The earlier a pair is in the list, the "later" it
 -- is done, i.e., it takes precedence over the latter entries.
 data ArrayModel a b = ArrayModel [(a, b)] b
-                     deriving (G.Data, Generic, NFData)
+                     deriving (G.Data, Generic, NFData, Show)
 
 -- | The kind of an ArrayModel
 instance (HasKind a, HasKind b) => HasKind (ArrayModel a b) where
@@ -100,21 +100,19 @@
 -- | A constant value.
 -- Note: If you add a new constructor here, make sure you add the
 -- corresponding equality in the instance "Eq CVal" and "Ord CVal"!
-data CVal = CAlgReal  !AlgReal                -- ^ Algebraic real
-          | CInteger  !Integer                -- ^ Bit-vector/unbounded integer
-          | CFloat    !Float                  -- ^ Float
-          | CDouble   !Double                 -- ^ Double
-          | CFP       !FP                     -- ^ Arbitrary float
-          | CRational Rational                -- ^ Rational
-          | CChar     !Char                   -- ^ Character
-          | CString   !String                 -- ^ String
-          | CList     ![CVal]                 -- ^ List
-          | CSet      !(RCSet CVal)           -- ^ Set. Can be regular or complemented.
-          | CUserSort !(Maybe Int, String)    -- ^ Value of an uninterpreted/user kind. The Maybe Int shows index position for enumerations
-          | CTuple    ![CVal]                 -- ^ Tuple
-          | CMaybe    !(Maybe CVal)           -- ^ Maybe
-          | CEither   !(Either CVal CVal)     -- ^ Disjoint union
-          | CArray    !(ArrayModel CVal CVal) -- ^ Arrays are backed by look-up tables concretely
+data CVal = CAlgReal  !AlgReal                  -- ^ Algebraic real
+          | CInteger  !Integer                  -- ^ Bit-vector/unbounded integer
+          | CFloat    !Float                    -- ^ Float
+          | CDouble   !Double                   -- ^ Double
+          | CFP       !FP                       -- ^ Arbitrary float
+          | CRational !Rational                 -- ^ Rational
+          | CChar     !Char                     -- ^ Character
+          | CString   !String                   -- ^ String
+          | CList     ![CVal]                   -- ^ List
+          | CSet      !(RCSet CVal)             -- ^ Set. Can be regular or complemented.
+          | CADT      !(String, [(Kind, CVal)]) -- ^ ADT: Constructor, and fields
+          | CTuple    ![CVal]                   -- ^ Tuple
+          | CArray    !(ArrayModel CVal CVal)   -- ^ Arrays are backed by look-up tables concretely
           deriving (G.Data, Generic, NFData)
 
 -- | Assign a rank to constant values, this is structural and helps with ordering
@@ -129,11 +127,9 @@
 cvRank CString   {} =  7
 cvRank CList     {} =  8
 cvRank CSet      {} =  9
-cvRank CUserSort {} = 10
+cvRank CADT      {} = 10
 cvRank CTuple    {} = 11
-cvRank CMaybe    {} = 12
-cvRank CEither   {} = 13
-cvRank CArray    {} = 14
+cvRank CArray    {} = 12
 
 -- | Eq instance for CVal. Note that we cannot simply derive Eq/Ord, since CVAlgReal doesn't have proper
 -- instances for these when values are infinitely precise reals. However, we do
@@ -149,10 +145,8 @@
   CString   a == CString   b = a == b
   CList     a == CList     b = a == b
   CSet      a == CSet      b = a `eqRCSet` b
-  CUserSort a == CUserSort b = a == b
   CTuple    a == CTuple    b = a == b
-  CMaybe    a == CMaybe    b = a == b
-  CEither   a == CEither   b = a == b
+  CADT      a == CADT      b = a == b
 
   -- This is legit since we don't use this equality for actual semantic" equality, but rather as an index into maps
   CArray    (ArrayModel a1 d1) == CArray (ArrayModel a2 d2) = (a1, d1) == (a2, d2)
@@ -179,10 +173,8 @@
   CString   a `compare` CString   b = a `compare`                  b
   CList     a `compare` CList     b = a `compare`                  b
   CSet      a `compare` CSet      b = a `compareRCSet`             b
-  CUserSort a `compare` CUserSort b = a `compare`                  b
   CTuple    a `compare` CTuple    b = a `compare`                  b
-  CMaybe    a `compare` CMaybe    b = a `compare`                  b
-  CEither   a `compare` CEither   b = a `compare`                  b
+  CADT      a `compare` CADT      b = a `compare`                  b
 
   -- This is legit since we don't use this equality for actual semantic order, but rather as an index into maps
   CArray    (ArrayModel a1 d1) `compare` CArray (ArrayModel a2 d2) = (a1, d1) `compare` (a2, d2)
@@ -201,8 +193,8 @@
 
 -- | A t'CV' represents a concrete word of a fixed size:
 -- For signed words, the most significant digit is considered to be the sign.
-data CV = CV { _cvKind  :: !Kind
-             , cvVal    :: !CVal
+data CV = CV { cvKind  :: !Kind
+             , cvVal   :: !CVal
              }
              deriving (Eq, Ord, G.Data, NFData, Generic)
 
@@ -251,8 +243,8 @@
            where par v | parens = '(' : v ++ ")"
                        | True   = v
                  withKind isInterval v | not shk    = v
-                                       | isInterval = v ++ " :: [" ++ showBaseKind (kindOf extCV) ++ "]"
-                                       | True       = v ++ " :: "  ++ showBaseKind (kindOf extCV)
+                                       | isInterval = v ++ " :: [" ++ T.unpack (showBaseKind (kindOf extCV)) ++ "]"
+                                       | True       = v ++ " :: "  ++ T.unpack (showBaseKind (kindOf extCV))
 
                  add :: String -> String -> String
                  add n ('-':v) = n ++ " - " ++ v
@@ -332,12 +324,10 @@
                                                     CRational a -> CRational (ra a)
                                                     CChar{}     -> error "Data.SBV.mapCV: Unexpected call through mapCV with chars!"
                                                     CString{}   -> error "Data.SBV.mapCV: Unexpected call through mapCV with strings!"
-                                                    CUserSort{} -> error "Data.SBV.mapCV: Unexpected call through mapCV with uninterpreted sorts!"
+                                                    CADT{}      -> error "Data.SBV.mapCV: Unexpected call through mapCV with ADTs!"
                                                     CList{}     -> error "Data.SBV.mapCV: Unexpected call through mapCV with lists!"
                                                     CSet{}      -> error "Data.SBV.mapCV: Unexpected call through mapCV with sets!"
                                                     CTuple{}    -> error "Data.SBV.mapCV: Unexpected call through mapCV with tuples!"
-                                                    CMaybe{}    -> error "Data.SBV.mapCV: Unexpected call through mapCV with maybe!"
-                                                    CEither{}   -> error "Data.SBV.mapCV: Unexpected call through mapCV with either!"
                                                     CArray{}    -> error "Data.SBV.mapCV: Unexpected call through mapCV with arrays!"
 
 -- | Map a binary function through a t'CV'.
@@ -357,11 +347,8 @@
                             (True, CRational a, CRational b) -> normCV $ CV (kindOf x) (CRational (ra a b))
                             (True, CChar{},     CChar{})     -> unexpected "chars!"
                             (True, CString{},   CString{})   -> unexpected "strings!"
-                            (True, CUserSort{}, CUserSort{}) -> unexpected "uninterpreted constants!"
                             (True, CList{},     CList{})     -> unexpected "lists!"
                             (True, CTuple{},    CTuple{})    -> unexpected "tuples!"
-                            (True, CMaybe{},    CMaybe{})    -> unexpected "maybes!"
-                            (True, CEither{},   CEither{})   -> unexpected "eithers!"
                             _                                -> unexpected $ "incompatible args: " ++ show (x, y)
    where unexpected w = error $ unlines [ ""
                                         , "*** Data.SBV.mapCV2: Unexpected call through mapCV2 with " ++ w
@@ -381,26 +368,24 @@
 showCV :: Bool -> CV -> String
 showCV shk w | isBoolean w = show (cvToBool w) ++ (if shk then " :: Bool" else "")
 showCV shk w = sh (cvVal w) ++ kInfo
-  where kInfo | shk  = " :: " ++ showBaseKind wk
+  where kInfo | shk  = " :: " ++ T.unpack (showBaseKind wk)
               | True = ""
 
         wk = kindOf w
 
-        sh (CAlgReal  v) = show v
-        sh (CInteger  v) = show v
-        sh (CFloat    v) = show v
-        sh (CDouble   v) = show v
-        sh (CFP       v) = show v
-        sh (CRational v) = show v
-        sh (CChar     v) = show v
-        sh (CString   v) = show v
-        sh (CUserSort v) = snd  v
-        sh (CList     v) = shL  v
-        sh (CSet      v) = shS  v
-        sh (CTuple    v) = shT  v
-        sh (CMaybe    v) = shM  v
-        sh (CEither   v) = shE  v
-        sh (CArray    v) = shA  v
+        sh (CAlgReal  v) = show  v
+        sh (CInteger  v) = show  v
+        sh (CFloat    v) = show  v
+        sh (CDouble   v) = show  v
+        sh (CFP       v) = show  v
+        sh (CRational v) = show  v
+        sh (CChar     v) = show  v
+        sh (CString   v) = show  v
+        sh (CADT      c) = shADT c
+        sh (CList     v) = shL   v
+        sh (CSet      v) = shS   v
+        sh (CTuple    v) = shT   v
+        sh (CArray    v) = shA   v
 
         shL xs = "[" ++ intercalate "," (map (showCV False . CV ke) xs) ++ "]"
           where ke = case wk of
@@ -424,34 +409,24 @@
                         KTuple ks | length ks == length xs -> zipWith (\k x -> showCV False (CV k x)) ks xs
                         _   -> error $ "Data.SBV.showCV: Impossible happened, expected tuple (of length " ++ show (length xs) ++ "), got: " ++ show wk
 
-        shM :: Maybe CVal -> String
-        shM c = case (c, wk) of
-                  (Nothing, KMaybe{}) -> "Nothing"
-                  (Just x,  KMaybe k) -> "Just " ++ paren (showCV False (CV k x))
-                  _                   -> error $ "Data.SBV.showCV: Impossible happened, expected maybe, got: " ++ show wk
-
-        shE :: Either CVal CVal -> String
-        shE val
-          | KEither k1 k2 <- wk = case val of
-                                    Left  x -> "Left "  ++ paren (showCV False (CV k1 x))
-                                    Right y -> "Right " ++ paren (showCV False (CV k2 y))
-          | True                = error $ "Data.SBV.showCV: Impossible happened, expected sum, got: " ++ show wk
-
         shA :: ArrayModel CVal CVal -> String
         shA (ArrayModel assocs def)
           | KArray k1 k2 <- wk = "([" ++ intercalate "," [showCV False (CV (KTuple [k1, k2]) (CTuple [a, b])) | (a, b) <- assocs] ++ "], " ++ showCV False (CV k2 def) ++ ")"
           | True               = error $ "Data.SBV.showCV: Impossible happened, expected array, got: " ++ show wk
 
-        -- kind of crude, but works ok
-        paren v
-          | needsParen = '(' : v ++ ")"
-          | True       = v
-          where needsParen = case dropWhile isSpace v of
-                               []         -> False
-                               rest@(x:_) -> x == '-' || (any isSpace rest && x `notElem` "{[(")
+        shADT (c, kvs)
+          | null @[] flds = c
+          | True          = unwords (c : map wrap flds)
+          where wrap v
+                 | take 1 v `elem` ["(", "[", "{"]  = v
+                 | any isSpace v || take 1 v == "-" = '(' : v ++ ")"
+                 | True                             = v
 
+                flds = map (\(k, v) -> showCV False (CV k v)) kvs
+
 -- | Create a constant word from an integral.
 mkConstCV :: Integral a => Kind -> a -> CV
+mkConstCV k@KVar{}        _ = error $ "mkConstCV: Unexpected kind: " ++ show k
 mkConstCV KBool           a = normCV $ CV KBool      (CInteger  (toInteger a))
 mkConstCV k@KBounded{}    a = normCV $ CV k          (CInteger  (toInteger a))
 mkConstCV KUnbounded      a = normCV $ CV KUnbounded (CInteger  (toInteger a))
@@ -462,18 +437,52 @@
 mkConstCV KRational       a = normCV $ CV KRational  (CRational (fromInteger (toInteger a)))
 mkConstCV KChar           a = error $ "Unexpected call to mkConstCV (Char) with value: "   ++ show (toInteger a)
 mkConstCV KString         a = error $ "Unexpected call to mkConstCV (String) with value: " ++ show (toInteger a)
-mkConstCV (KUserSort s _) a = error $ "Unexpected call to mkConstCV with user kind: " ++ s ++ " with value: " ++ show (toInteger a)
+mkConstCV (KApp s _)      a = error $ "Unexpected call to mkConstCV with kind: " ++ s ++ " with value: " ++ show (toInteger a)
+mkConstCV (KADT s _ _)    a = error $ "Unexpected call to mkConstCV with ADT: "  ++ s ++ " with value: " ++ show (toInteger a)
 mkConstCV k@KList{}       a = error $ "Unexpected call to mkConstCV (" ++ show k ++ ") with value: " ++ show (toInteger a)
 mkConstCV k@KSet{}        a = error $ "Unexpected call to mkConstCV (" ++ show k ++ ") with value: " ++ show (toInteger a)
 mkConstCV k@KTuple{}      a = error $ "Unexpected call to mkConstCV (" ++ show k ++ ") with value: " ++ show (toInteger a)
-mkConstCV k@KMaybe{}      a = error $ "Unexpected call to mkConstCV (" ++ show k ++ ") with value: " ++ show (toInteger a)
-mkConstCV k@KEither{}     a = error $ "Unexpected call to mkConstCV (" ++ show k ++ ") with value: " ++ show (toInteger a)
 mkConstCV k@KArray{}      a = error $ "Unexpected call to mkConstCV (" ++ show k ++ ") with value: " ++ show (toInteger a)
 
+-- | Create a constant value from a floating-point value.
+fpConstCV ::
+  -- | Must be 'KFloat', 'KDouble', or 'KFP'.
+  Kind ->
+  -- | The constant to use when the kind is 'KFloat'.
+  Float ->
+  -- | The constant to use when the kind is 'KDouble'.
+  Double ->
+  -- | The constant to make when the kind is 'KFP', where the 'Int's represent
+  -- the exponent and significand sizes.
+  (Int -> Int -> FP) ->
+  CV
+fpConstCV k cf cd cfp =
+  case k of
+    KFloat    -> CV k $ CFloat cf
+    KDouble   -> CV k $ CDouble cd
+    KFP eb sb -> CV k $ CFP $ cfp eb sb
+
+    KVar{} -> unexpected
+    KBool{} -> unexpected
+    KBounded{} -> unexpected
+    KUnbounded{} -> unexpected
+    KReal{} -> unexpected
+    KRational{} -> unexpected
+    KChar{} -> unexpected
+    KString{} -> unexpected
+    KApp{} -> unexpected
+    KADT{} -> unexpected
+    KList{} -> unexpected
+    KSet{} -> unexpected
+    KTuple{} -> unexpected
+    KArray{} -> unexpected
+  where unexpected = error $ "Data.SBV.fpConstCV: Unexpected kind: " ++ show k
+
 -- | Generate a random constant value ('CVal') of the correct kind. We error out for a completely uninterpreted type.
 randomCVal :: Kind -> IO CVal
 randomCVal k =
   case k of
+    KVar{}             -> error $ "randomCVal: Unexpected kind: " ++ show k
     KBool              -> CInteger  <$> randomRIO (0, 1)
     KBounded s w       -> CInteger  <$> randomRIO (bounds s w)
     KUnbounded         -> CInteger  <$> randomIO
@@ -494,36 +503,30 @@
                              CString <$> replicateM l (chr <$> randomRIO (0, 255))
     KChar              -> CChar . chr <$> randomRIO (0, 255)
 
-    KUserSort s es     -> case es of
-                            Just vs@(_:_) -> do i <- randomRIO (0, length vs - 1)
-                                                pure $ CUserSort (Just i, vs !! i)
-                            _             -> error $ "randomCVal: Not supported for completely uninterpreted type: " ++ s
+    -- TODO: Can we do something here?
+    KApp s _           -> error $ "randomCVal: Not supported for KApp: " ++ s
 
+    KADT _ _ cstrs@(_:_) -> do i <- randomRIO (0, length cstrs - 1)
+                               let (c, fks) = cstrs !! i
+                               vs <- mapM randomCVal fks
+                               pure $ CADT (c, zip fks vs)
+    KADT s _ _         -> error $ "randomCVal: Not supported for ADT:  " ++ s
+
     KList ek           -> do l <- randomRIO (0, 100)
                              CList <$> replicateM l (randomCVal ek)
 
     KSet  ek           -> do i <- randomIO                           -- regular or complement
                              l <- randomRIO (0, 100)                 -- some set upto 100 elements
                              vals <- Set.fromList <$> replicateM l (randomCVal ek)
-                             return $ CSet $ if i then RegularSet vals else ComplementSet vals
+                             pure $ CSet $ if i then RegularSet vals else ComplementSet vals
 
     KTuple ks          -> CTuple <$> traverse randomCVal ks
 
-    KMaybe ke          -> do i <- randomIO
-                             if i
-                                then return $ CMaybe Nothing
-                                else CMaybe . Just <$> randomCVal ke
-
-    KEither k1 k2      -> do i <- randomIO
-                             if i
-                                then CEither . Left  <$> randomCVal k1
-                                else CEither . Right <$> randomCVal k2
-
     KArray k1 k2       -> do l   <- randomRIO (0, 100)
                              ks  <- replicateM l (randomCVal k1)
                              vs  <- replicateM l (randomCVal k2)
                              def <- randomCVal k2
-                             return $ CArray $ ArrayModel (zip ks vs) def
+                             pure $ CArray $ ArrayModel (zip ks vs) def
   where
     bounds :: Bool -> Int -> (Integer, Integer)
     bounds False w = (0, 2^w - 1)
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
@@ -16,12 +16,13 @@
 {-# LANGUAGE DeriveGeneric         #-}
 {-# LANGUAGE FlexibleContexts      #-}
 {-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE GADTs                 #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE PatternGuards         #-}
+{-# LANGUAGE RankNTypes            #-}
 {-# LANGUAGE ScopedTypeVariables   #-}
 {-# LANGUAGE TypeApplications      #-}
-{-# LANGUAGE TypeOperators         #-}
 {-# LANGUAGE TypeFamilies          #-}
+{-# LANGUAGE TypeOperators         #-}
 {-# LANGUAGE UndecidableInstances  #-}
 
 {-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
@@ -32,14 +33,12 @@
  , SFloatingPoint, SFPHalf, SFPBFloat, SFPSingle, SFPDouble, SFPQuad
  , SWord, SInt, WordN, IntN
  , SRational
- , SChar, SString, SList
- , SEither, SMaybe, SArray, ArrayModel(..)
+ , SChar, SString, SList, (.:), nil
+ , SArray, ArrayModel(..)
  , STuple, STuple2, STuple3, STuple4, STuple5, STuple6, STuple7, STuple8
  , RCSet(..), SSet
  , nan, infinity, sNaN, sInfinity, RoundingMode(..), SRoundingMode
- , sRoundNearestTiesToEven, sRoundNearestTiesToAway, sRoundTowardPositive, sRoundTowardNegative, sRoundTowardZero
- , sRNE, sRNA, sRTP, sRTN, sRTZ
- , SymVal(..)
+ , SymVal(..), SymValInsts(..), symValKinds, SymVals(..)
  , CV(..), CVal(..), AlgReal(..), AlgRealPoly(..), ExtCV(..), GeneralizedCV(..), isRegularCV, cvSameType, cvToBool
  , mkConstCV , mapCV, mapCV2
  , SV(..), trueSV, falseSV, trueCV, falseCV, normCV
@@ -47,10 +46,12 @@
  , sTrue, sFalse, sNot, (.&&), (.||), (.<+>), (.~&), (.~|), (.=>), (.<=>), sAnd, sOr, sAny, sAll, fromBool
  , SBV(..), NodeId(..), mkSymSBV
  , sbvToSV, sbvToSymSV, forceSVArg
+ , RList(..), RNil, (:>), rlist2list
+ , SBVs(..), mapMSBVs, foldlSymSBVs
  , SBVExpr(..), newExpr
  , cache, Cached, uncache, HasKind(..)
  , Op(..), PBOp(..), FPOp(..), StrOp(..), RegExOp(..), SeqOp(..), RegExp(..), NamedSymVar(..), OvOp(..), getTableIndex
- , SBVPgm(..), Symbolic, runSymbolic, State, getPathCondition, extendPathCondition
+ , SBVPgm(..), Symbolic, runSymbolic, State, SInfo(..), getSInfo, getPathCondition
  , inSMTMode, SBVRunMode(..), Kind(..), Outputtable(..), Result(..)
  , SolverContext(..), internalConstraint, isCodeGenMode
  , SBVType(..), newUninterpreted
@@ -73,16 +74,19 @@
 import Control.Monad.Trans    (liftIO, MonadIO)
 import Data.Int               (Int8, Int16, Int32, Int64)
 import Data.Word              (Word8, Word16, Word32, Word64)
-import Data.List              (elemIndex)
 
 import Data.Kind (Type)
 import Data.Proxy
 import Data.Typeable          (Typeable)
 
+import Data.IORef
+import qualified Data.Set as Set (toList)
+
 import GHC.Generics (Generic, U1(..), M1(..), (:*:)(..), K1(..), (:+:)(..))
 import qualified GHC.Generics  as G
-import qualified Data.Generics as G (Data(..))
 
+import GHC.Exts (IsList(..))
+
 import System.Random
 
 import Data.SBV.Core.AlgReals
@@ -96,6 +100,7 @@
 import Data.SBV.Control.Types
 
 import Data.SBV.Utils.Lib
+import Data.SBV.Utils.Numeric (RoundingMode(..))
 
 import Test.QuickCheck (Arbitrary(..))
 
@@ -103,10 +108,6 @@
 getPathCondition :: State -> SBool
 getPathCondition st = SBV (getSValPathCondition st)
 
--- | Extend the path condition with the given test value.
-extendPathCondition :: State -> (SBool -> SBool) -> State
-extendPathCondition st f = extendSValPathCondition st (unSBV . f . SBV)
-
 -- | The "Symbolic" value. The parameter @a@ is phantom, but is
 -- extremely important in keeping the user interface strongly typed.
 newtype SBV a = SBV { unSBV :: SVal }
@@ -196,12 +197,43 @@
 -- Note that lists can be nested, i.e., we do allow lists of lists of ... items.
 type SList a = SBV [a]
 
--- | Symbolic 'Either'
-type SEither a b = SBV (Either a b)
+-- | Prepend an element, the traditional @cons@.
+--
+-- >>> 1 .: 2 .: 3 .: [4, 5, 6 :: SInteger]
+-- [1,2,3,4,5,6] :: [SInteger]
+infixr 5 .:
+(.:) :: forall a. (SymVal a, SymVal [a]) => SBV a -> SList a -> SList a
+a .: as
+  | Just av  <- unliteral a
+  , Just asv <- unliteral as
+  = literal (av : asv)
+  | Just asv <- unliteral as, null asv  -- singleton: skip the concat with empty
+  = SBV $ SVal kl $ Right $ cache $ \st -> do
+        sva <- sbvToSV st a
+        newExpr st kl (SBVApp (SeqOp (SeqUnit ka)) [sva])
+  | True
+  = SBV $ SVal kl $ Right $ cache r
+  where ka = kindOf (Proxy @a)
+        kl = kindOf (Proxy @[a])
+        r st = do sva  <- sbvToSV st a
+                  svs  <- newExpr st kl (SBVApp (SeqOp (SeqUnit ka)) [sva])
+                  svas <- sbvToSV st as
+                  newExpr st kl (SBVApp (SeqOp (SeqConcat kl)) [svs, svas])
 
--- | Symbolic 'Maybe'
-type SMaybe a = SBV (Maybe a)
+-- | Empty list. This value has the property that it's the only list with length 0. If you use @OverloadedLists@ extension,
+-- you can write it as the familiar @[]@.
+nil :: SymVal [a] => SList a
+nil = literal []
 
+-- | 'IsList' instance allows list literals to be written compactly.
+instance (SymVal a, SymVal [a]) => IsList (SList a) where
+  type Item (SList a) = SBV a
+
+  fromList = foldr (.:) nil -- Don't use [] here for nil, as this is the very definition of doing overloaded lists
+  toList x = case unliteral x of
+               Nothing -> error "IsList.toList used in a symbolic context"
+               Just xs -> map literal xs
+
 -- | Symbolic arrays. A symbolic array is more akin to a function in SMTLib (and thus in SBV),
 -- as opposed to contagious-storage with a finite range as found in many programming languages.
 -- Additionally, the domain uses object-equality in the SMTLib semantics. Object equality is
@@ -336,52 +368,9 @@
 sAll :: (a -> SBool) -> [a] -> SBool
 sAll f = sAnd . map f
 
--- | 'RoundingMode' can be used symbolically
-instance SymVal RoundingMode
-
 -- | The symbolic variant of 'RoundingMode'
 type SRoundingMode = SBV RoundingMode
 
--- | Symbolic variant of 'RoundNearestTiesToEven'
-sRoundNearestTiesToEven :: SRoundingMode
-sRoundNearestTiesToEven = literal RoundNearestTiesToEven
-
--- | Symbolic variant of 'RoundNearestTiesToAway'
-sRoundNearestTiesToAway :: SRoundingMode
-sRoundNearestTiesToAway = literal RoundNearestTiesToAway
-
--- | Symbolic variant of 'RoundTowardPositive'
-sRoundTowardPositive :: SRoundingMode
-sRoundTowardPositive = literal RoundTowardPositive
-
--- | Symbolic variant of 'RoundTowardNegative'
-sRoundTowardNegative :: SRoundingMode
-sRoundTowardNegative = literal RoundTowardNegative
-
--- | Symbolic variant of 'RoundTowardZero'
-sRoundTowardZero :: SRoundingMode
-sRoundTowardZero = literal RoundTowardZero
-
--- | Alias for 'sRoundNearestTiesToEven'
-sRNE :: SRoundingMode
-sRNE = sRoundNearestTiesToEven
-
--- | Alias for 'sRoundNearestTiesToAway'
-sRNA :: SRoundingMode
-sRNA = sRoundNearestTiesToAway
-
--- | Alias for 'sRoundTowardPositive'
-sRTP :: SRoundingMode
-sRTP = sRoundTowardPositive
-
--- | Alias for 'sRoundTowardNegative'
-sRTN :: SRoundingMode
-sRTN = sRoundTowardNegative
-
--- | Alias for 'sRoundTowardZero'
-sRTZ :: SRoundingMode
-sRTZ = sRoundTowardZero
-
 -- | A 'Show' instance is not particularly "desirable," when the value is symbolic,
 -- but we do need this instance as otherwise we cannot simply evaluate Haskell functions
 -- that return symbolic values and have their constant values printed easily!
@@ -395,6 +384,51 @@
 sbvToSV :: State -> SBV a -> IO SV
 sbvToSV st (SBV s) = svToSV st s
 
+-- | A datakind for lists with cons on the right
+data RList a = RNil | (RList a) :> a
+
+-- | Convert an 'RList' into a reversed standard list
+rlist2listRev :: RList a -> [a]
+rlist2listRev RNil = []
+rlist2listRev (as :> a) = a : rlist2listRev as
+
+-- | Convert an 'RList' into a standard list
+rlist2list :: RList a -> [a]
+rlist2list = reverse . rlist2listRev
+
+-- | Helper for writing types containing @RNil@
+type RNil = 'RNil
+
+-- | Helper for writing types containing @:>@
+type (:>) = '(:>)
+
+-- | A sequence of elements of types @SBV a1,...,SBV an@ given the list
+-- @[a1,...,an]@ of Haskell types
+data SBVs as where
+  SBVsNil  :: SBVs RNil
+  SBVsCons :: SBVs as -> SBV a -> SBVs (as :> a)
+
+-- | Fold a function over each SBV value in an SBVs sequence in a manner similar
+-- to 'foldr' for lists, except backwards because the lists are stored in
+-- reverse order
+foldlSBVs :: (forall a. r -> SBV a -> r) -> r -> SBVs as -> r
+foldlSBVs _ r SBVsNil             = r
+foldlSBVs f r (SBVsCons args arg) = f (foldlSBVs f r args) arg
+
+-- | Map a monadic function over the SBV values in an SBVs sequence in a
+-- manner similar to 'mapM' for lists
+mapMSBVs :: Monad m => (forall a. SBV a -> m r) -> SBVs as -> m (RList r)
+mapMSBVs f = foldlSBVs (\m arg -> (:>) <$> m <*> f arg) (pure RNil)
+
+-- | Fold a function over each SBV value in an SBVs sequence in a manner similar
+-- to 'foldr' for lists (but backwards because SBVs have cons on the right),
+-- using 'SymVal' instances for each value
+foldlSymSBVs :: (forall a. SymVal a => r -> SBV a -> r) -> r ->
+                SymValInsts as -> SBVs as -> r
+foldlSymSBVs _ r _                   SBVsNil             = r
+foldlSymSBVs f r (SymValsCons symvs) (SBVsCons args arg) =
+  f (foldlSymSBVs f r symvs args) arg
+
 -------------------------------------------------------------------------
 -- * Symbolic Computations
 -------------------------------------------------------------------------
@@ -436,7 +470,7 @@
 -- will be prefixed in front of @_1@, @_2@, ..., @_n@ to form the names of the variables.
 newtype ExistsN (n :: Nat) (nm :: Symbol) a = ExistsN [SBV a]
 
--- | Exactly @n@ universal symbolic variables, used in in building quantified constraints. The name attached
+-- | Exactly @n@ universal symbolic variables, used in building quantified constraints. The name attached
 -- will be prefixed in front of @_1@, @_2@, ..., @_n@ to form the names of the variables.
 newtype ForallN (n :: Nat) (nm :: Symbol) a = ForallN [SBV a]
 
@@ -444,7 +478,7 @@
 mkQArg :: forall m a. (HasKind a, MonadIO m) => State -> Quantifier -> m (SBV a)
 mkQArg st q = do let k = kindOf (Proxy @a)
                  sv <- liftIO $ quantVar q st k
-                 pure $ SBV $ SVal k (Right (cache (const (return sv))))
+                 pure $ SBV $ SVal k (Right (cache (const (pure sv))))
 
 -- | Functions of a single existential
 instance (SymVal a, Constraint m r) => Constraint m (Exists nm a -> r) where
@@ -485,7 +519,7 @@
   mkLambda st fn = mkArg >>= mkLambda st . fn
     where mkArg = do let k = kindOf (Proxy @a)
                      sv <- liftIO $ lambdaVar st k
-                     pure $ SBV $ SVal k (Right (cache (const (return sv))))
+                     pure $ SBV $ SVal k (Right (cache (const (pure sv))))
 
 -- | A value that can be used as a quantified boolean
 class QuantifiedBool a where
@@ -540,6 +574,13 @@
    -- | Get the state associated with this context
    contextState :: m State
 
+   -- | Register a kind, synchronizing declarations when already in query mode.
+   -- Implementation hook for 'registerType'; callers should use that public API.
+   registerKindInContext :: Kind -> m ()
+   default registerKindInContext :: MonadIO m => Kind -> m ()
+   registerKindInContext k = do st <- contextState
+                                liftIO $ registerKind st k
+
    -- | Get an internal-variable
    internalVariable :: Kind -> m (SBV a)
 
@@ -550,13 +591,21 @@
    setLogic     = setOption . SetLogic
    setInfo    k = setOption . SetInfo k
 
--- | Register a type with the solver. Like 'Data.SBV.Core.Model.registerFunction', This is typically not necessary
--- since SBV will register types as it encounters them automatically. But there are cases
--- where doing this can explicitly can come handy, typically in query contexts.
+-- | Register a type eagerly, either before or inside a query. SBV automatically
+-- registers types on first use, so ordinary symbolic computations do not need
+-- this call. It can be useful before sending custom SMT-Lib commands that refer
+-- to a type without first creating a symbolic value of that type.
 registerType :: forall a m. (MonadIO m, SolverContext m, HasKind a) => Proxy a -> m ()
-registerType _ = do st <- contextState
-                    liftIO $ registerKind st (kindOf (Proxy @a))
+registerType _ = registerKindInContext (kindOf (Proxy @a))
 
+-- | Various info we use in recoverKinded value
+newtype SInfo = SInfo { sInfoKinds :: [Kind] }
+
+-- | Turn state into SInfo
+getSInfo :: MonadIO m => State -> m SInfo
+getSInfo st = do rk <- liftIO $ readIORef (rUsedKinds st)
+                 pure $ SInfo { sInfoKinds = Set.toList rk }
+
 -- | A class representing what can be returned from a symbolic computation.
 class Outputtable a where
   -- | Generalization of 'Data.SBV.output'
@@ -565,13 +614,13 @@
 instance Outputtable (SBV a) where
   output i = do
           outputSVal (unSBV i)
-          return i
+          pure i
 
 instance Outputtable a => Outputtable [a] where
   output = mapM output
 
 instance Outputtable () where
-  output = return
+  output = pure
 
 instance (Outputtable a, Outputtable b) => Outputtable (a, b) where
   output = mlift2 (,) output output
@@ -602,6 +651,10 @@
   -- | Generalization of 'Data.SBV.mkSymVal'
   mkSymVal :: MonadSymbolic m => VarContext -> Maybe String -> m (SBV a)
 
+  -- | Certain types (ADTs) might need to do further initialization.
+  mkSymValInit :: State -> SBV a -> IO ()
+  mkSymValInit _ _ = pure ()
+
   -- | Turn a literal constant to symbolic
   literal :: a -> SBV a
 
@@ -615,32 +668,13 @@
   -- If the underlying type is bounded, we have a default below. Otherwise it's nothing.
   minMaxBound :: Maybe (a, a)
 
-  -- minimal complete definition: Nothing.
-  -- Giving no instances is okay when defining an uninterpreted/enumerated sort, but otherwise you really
-  -- want to define: literal, fromCV, mkSymVal
-
-  default mkSymVal :: (MonadSymbolic m, Read a, G.Data a) => VarContext -> Maybe String -> m (SBV a)
-  mkSymVal vc mbNm = SBV <$> (symbolicEnv >>= liftIO . svMkSymVar vc k mbNm)
-    where -- NB.A call of the form
-          --      constructUKind (Proxy @a)
-          -- would be wrong here, as it would uninterpret the Proxy datatype!
-          -- So, we have to use the dreaded undefined value in this case.
-          k = constructUKind (undefined :: a)
-
-  default literal :: Show a => a -> SBV a
-  literal x = let k  = kindOf x
-                  sx = show x
-                  conts = case k of
-                           KUserSort _ cts -> cts
-                           _               -> Nothing
-                  mbIdx = case conts of
-                            Just xs -> sx `elemIndex` xs
-                            Nothing -> Nothing
-              in SBV $ SVal k (Left (CV k (CUserSort (mbIdx, sx))))
+  {-# MINIMAL literal, fromCV #-}
 
-  default fromCV :: Read a => CV -> a
-  fromCV (CV _ (CUserSort (_, s))) = read s
-  fromCV cv                        = error $ "Cannot convert CV " ++ show cv ++ " to kind " ++ show (kindOf (Proxy @a))
+  default mkSymVal :: MonadSymbolic m => VarContext -> Maybe String -> m (SBV a)
+  mkSymVal vc mbNm = do st <- symbolicEnv
+                        liftIO $ do v <- SBV <$> svMkSymVar vc (kindOf (undefined :: a)) mbNm st
+                                    mkSymValInit st v
+                                    pure v
 
   default minMaxBound :: Bounded a => Maybe (a, a)
   minMaxBound = Just (minBound, maxBound)
@@ -674,6 +708,11 @@
   unliteral (SBV (SVal _ (Left c))) = Just $ fromCV c
   unliteral _                       = Nothing
 
+  -- | Get the underlying CV, if available
+  unlitCV :: SBV a -> Maybe (Kind, CVal)
+  unlitCV (SBV (SVal _ (Left (CV k v)))) = Just (k, v)
+  unlitCV _                              = Nothing
+
   -- | Is the symbolic word concrete?
   isConcrete :: SBV a -> Bool
   isConcrete (SBV (SVal _ (Left _))) = True
@@ -683,6 +722,31 @@
   isSymbolic :: SBV a -> Bool
   isSymbolic = not . isConcrete
 
+-- | A sequence of instance dictionaries for each type @ai@ in the type list
+-- @[a1,...,an]@
+data SymValInsts as where
+  SymValsNil :: SymValInsts RNil
+  SymValsCons :: SymVal a => SymValInsts as -> SymValInsts (as :> a)
+
+-- | Get the 'Kind' of each type in the type list of a 'SymValInsts' sequence
+symValKinds :: SymValInsts as -> [Kind]
+symValKinds = rlist2list . helper where
+  helper :: SymValInsts as -> RList Kind
+  helper SymValsNil = RNil
+  helper insts@(SymValsCons insts') = helper insts' :> kindOf (headPrx insts)
+  headPrx :: SymValInsts (bs :> b) -> Proxy b
+  headPrx _ = Proxy
+
+-- | A 'SymVals' is a list of types that all satisfy 'SymVal'
+class SymVals as where
+  symValInsts :: SymValInsts as
+
+instance SymVals RNil where
+  symValInsts = SymValsNil
+
+instance (SymVal a, SymVals as) => SymVals (as :> a) where
+  symValInsts = SymValsCons symValInsts
+
 instance (Random a, SymVal a) => Random (SBV a) where
   randomR (l, h) g = case (unliteral l, unliteral h) of
                        (Just lb, Just hb) -> let (v, g') = randomR (lb, hb) g in (literal (v :: a), g')
@@ -859,7 +923,7 @@
    where i  = fromIntegral (natVal start)
          j  = fromIntegral (natVal end)
 
--- | Join two bitvectors.
+-- | Join two bit-vectors.
 (#) :: ( KnownNat n, BVIsNonZero n, SymVal (bv n)
        , KnownNat m, BVIsNonZero m, SymVal (bv m)
        ) => SBV (bv n)                     -- ^ First input, of size @n@, becomes the left side
@@ -1001,7 +1065,7 @@
   type NegatesTo (ExistsN nm n a -> r) = ForallN nm n a -> NegatesTo r
   qNot f (ForallN xs) = qNot (f (ExistsN xs))
 
--- | Negate over an unique existential quantifier
+-- | Negate over a unique existential quantifier
 instance (QNot r, QuantifiedBool r, EqSymbolic (SBV a)) => QNot (ExistsUnique nm a -> r) where
   type NegatesTo (ExistsUnique nm a -> r) =  Forall nm a
                                           -> Exists (AppendSymbol nm "_eu1") a
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
@@ -11,16 +11,14 @@
 
 {-# LANGUAGE DefaultSignatures    #-}
 {-# LANGUAGE FlexibleContexts     #-}
-{-# LANGUAGE FlexibleInstances    #-}
 {-# LANGUAGE InstanceSigs         #-}
-{-# LANGUAGE Rank2Types           #-}
 {-# LANGUAGE ScopedTypeVariables  #-}
 {-# LANGUAGE TypeApplications     #-}
 {-# LANGUAGE TypeFamilies         #-}
 {-# LANGUAGE TypeOperators        #-}
 {-# LANGUAGE UndecidableInstances #-}
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans -Wno-incomplete-uni-patterns #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
 module Data.SBV.Core.Floating (
          IEEEFloating(..), IEEEFloatConvertible(..)
@@ -42,7 +40,7 @@
 
 import Data.SBV.Core.AlgReals (isExactRational)
 import Data.SBV.Core.Sized
-import Data.SBV.Core.SizedFloats
+import Data.SBV.Core.SizedFloats hiding (fpIsNaN, fpIsZero)
 
 import Data.SBV.Core.Data
 import Data.SBV.Core.Kind
@@ -173,36 +171,67 @@
   fromSFloat :: SRoundingMode -> SFloat -> SBV a
   fromSFloat = genericFromFloat
 
-  -- | Convert to an IEEE-754 Single-precision float.
+  -- | Convert to an IEEE-754 Single-precision float. Integral literals are
+  -- rounded directly to binary32 in the requested rounding mode.
+  --
+  -- >>> unliteral (toSFloat sRTP (16777217 :: SInteger))
+  -- Just 1.6777218e7
   toSFloat :: SRoundingMode -> SBV a -> SFloat
 
   -- default definition if we have an integral like
   default toSFloat :: Integral a => SRoundingMode -> SBV a -> SFloat
-  toSFloat = genericToFloat (onlyWhenRNE (Just . fromRational . fromIntegral))
+  toSFloat = genericToFloat (\rm -> Just . fpToFloat rm . roundIntegralFP 8 24 rm)
 
   -- | Convert from an IEEE74 double precision float.
   fromSDouble :: SRoundingMode -> SDouble -> SBV a
   fromSDouble = genericFromFloat
 
-  -- | Convert to an IEEE-754 Double-precision float.
+  -- | Convert to an IEEE-754 Double-precision float. Integral literals are
+  -- rounded directly to binary64 in the requested rounding mode.
+  --
+  -- >>> unliteral (toSDouble sRTN (-9007199254740993 :: SInteger))
+  -- Just (-9.007199254740994e15)
   toSDouble :: SRoundingMode -> SBV a -> SDouble
 
   -- default definition if we have an integral like
   default toSDouble :: Integral a => SRoundingMode -> SBV a -> SDouble
-  toSDouble = genericToFloat (onlyWhenRNE (Just . fromRational . fromIntegral))
+  toSDouble = genericToFloat (\rm -> Just . fpToDouble rm . roundIntegralFP 11 53 rm)
 
   -- | Convert from an arbitrary floating point.
   fromSFloatingPoint :: ValidFloat eb sb => SRoundingMode -> SFloatingPoint eb sb -> SBV a
   fromSFloatingPoint = genericFromFloat
 
-  -- | Convert to an arbitrary floating point.
+  -- | Convert to an arbitrary floating point. Integral literals are rounded
+  -- directly to the target format in the requested rounding mode.
+  --
+  -- >>> unliteral (toSFloatingPoint sRTP (2049 :: SInteger) :: SFPHalf)
+  -- Just 2050.0
+  --
+  -- >>> unliteral (toSFloatingPoint sRTN (-2049 :: SInteger) :: SFPHalf)
+  -- Just -2050.0
   toSFloatingPoint :: ValidFloat eb sb => SRoundingMode -> SBV a -> SFloatingPoint eb sb
 
-  -- -- default definition if we have an integral like
+  -- Default definition for integral sources.
   default toSFloatingPoint :: (Integral a, ValidFloat eb sb) => SRoundingMode -> SBV a -> SFloatingPoint eb sb
-  toSFloatingPoint = genericToFloat (const (Just . fromRational . fromIntegral))
+  toSFloatingPoint = integralToFloatingPoint
 
--- Run the function if the conversion is in RNE. Otherwise return Nothing.
+-- | Convert an integral source without an intermediate floating-point format.
+-- Concrete inputs round the exact integer once; symbolic inputs or rounding
+-- modes retain the ordinary floating-point cast expression.
+integralToFloatingPoint :: forall a eb sb. (Integral a, IEEEFloatConvertible a, ValidFloat eb sb)
+                       => SRoundingMode -> SBV a -> SFloatingPoint eb sb
+integralToFloatingPoint = genericToFloat convert
+ where convert rm value = Just $ FloatingPoint $ roundIntegralFP ei si rm value
+       ei = intOfProxy (Proxy @eb)
+       si = intOfProxy (Proxy @sb)
+
+-- | Round an exact integer once to the requested format. Converting the result
+-- to a matching native Float or Double is exact, including directed overflow.
+roundIntegralFP :: Integral a => Int -> Int -> RoundingMode -> a -> FP
+roundIntegralFP ei si rm value = FP ei si
+                              $ fst (bfRoundFloat (mkBFOpts ei si (roundingModeToRoundMode rm)) (bfFromInteger (toInteger value)))
+
+-- | Run the function if the conversion is in RNE. Otherwise return Nothing.
 onlyWhenRNE :: (a -> Maybe b) -> RoundingMode -> a -> Maybe b
 onlyWhenRNE f RoundNearestTiesToEven v = f v
 onlyWhenRNE _ _                      _ = Nothing
@@ -220,7 +249,8 @@
                    xsv <- sbvToSV st f
                    newExpr st kTo (SBVApp (IEEEFP (FP_Cast kFrom kTo msv)) [xsv])
 
--- | A generic to-float converter, which will constant-fold as necessary, but only in the sRNE mode for regular floats.
+-- | A generic to-float converter. Fold concrete operands and rounding modes
+-- when the supplied converter supports them; otherwise emit a symbolic cast.
 genericToFloat :: forall a r. (IEEEFloatConvertible a, IEEEFloating r)
                => (RoundingMode -> a -> Maybe r)     -- How to convert concretely, if possible
                -> SRoundingMode                      -- Rounding mode
@@ -384,9 +414,9 @@
 
 -- | Add the converted rounding mode if given as an argument
 addRM :: State -> Maybe SRoundingMode -> [SV] -> IO [SV]
-addRM _  Nothing   as = return as
+addRM _  Nothing   as = pure as
 addRM st (Just rm) as = do svm <- sbvToSV st rm
-                           return (svm : as)
+                           pure (svm : as)
 
 -- | Lift a 1 arg FP-op
 lift1 :: SymVal a => FPOp -> Maybe (a -> a) -> Maybe SRoundingMode -> SBV a -> SBV a
@@ -529,12 +559,17 @@
 -- and it works as long as you do not have a @NaN@.
 sFloatAsComparableSWord32 :: SFloat -> SWord32
 sFloatAsComparableSWord32 f = ite (fpIsNegativeZero f) (sFloatAsComparableSWord32 0) (fromBitsBE $ sNot sb : ite sb (map sNot rest) rest)
-  where (sb : rest) = blastBE $ sFloatAsSWord32 f
+  where (sb, rest) = case blastBE $ sFloatAsSWord32 f of
+                        b : bs -> (b, bs)
+                        []     -> error "sFloatAsComparableSWord32: impossible, blastBE produced empty list"
 
 -- | Inverse transformation to 'sFloatAsComparableSWord32'.
 sComparableSWord32AsSFloat :: SWord32 -> SFloat
 sComparableSWord32AsSFloat w = sWord32AsSFloat $ ite sb (fromBitsBE $ sFalse : rest) (fromBitsBE $ map sNot allBits)
-  where allBits@(sb : rest) = blastBE w
+  where allBits    = blastBE w
+        (sb, rest) = case allBits of
+                        b : bs -> (b, bs)
+                        []     -> error "sComparableSWord32AsSFloat: impossible, blastBE produced empty list"
 
 -- | Convert a double to a comparable 'SWord64'. The trick is to ignore the
 -- sign of -0, and if it's a negative value flip all the bits, and otherwise
@@ -542,13 +577,18 @@
 -- and it works as long as you do not have a @NaN@.
 sDoubleAsComparableSWord64 :: SDouble -> SWord64
 sDoubleAsComparableSWord64 d = ite (fpIsNegativeZero d) (sDoubleAsComparableSWord64 0) (fromBitsBE $ sNot sb : ite sb (map sNot rest) rest)
-  where (sb : rest) = blastBE $ sDoubleAsSWord64 d
+  where (sb, rest) = case blastBE $ sDoubleAsSWord64 d of
+                        b : bs -> (b, bs)
+                        []     -> error "sDoubleAsComparableSWord64: impossible, blastBE produced empty list"
 
 -- | 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:
 sComparableSWord64AsSDouble :: SWord64 -> SDouble
 sComparableSWord64AsSDouble w = sWord64AsSDouble $ ite sb (fromBitsBE $ sFalse : rest) (fromBitsBE $ map sNot allBits)
-  where allBits@(sb : rest) = blastBE w
+  where allBits    = blastBE w
+        (sb, rest) = case allBits of
+                        b : bs -> (b, bs)
+                        []     -> error "sComparableSWord64AsSDouble: impossible, blastBE produced empty list"
 
 -- | 'Float' instance for 'Metric' goes through the lexicographic ordering on 'Word32'.
 -- It implicitly makes sure that the value is not @NaN@.
@@ -561,12 +601,12 @@
    msMinimize nm o = do constrain $ sNot $ fpIsNaN o
                         let nm' = annotateForMS (Proxy @Float) nm
                         when (nm' /= nm) $ sObserve nm (unSBV o)
-                        addSValOptGoal $ unSBV `fmap` Minimize nm' (toMetricSpace o)
+                        addSValOptGoal $ unSBV <$> Minimize nm' (toMetricSpace o)
 
    msMaximize nm o = do constrain $ sNot $ fpIsNaN o
                         let nm' = annotateForMS (Proxy @Float) nm
                         when (nm' /= nm) $ sObserve nm (unSBV o)
-                        addSValOptGoal $ unSBV `fmap` Maximize nm' (toMetricSpace o)
+                        addSValOptGoal $ unSBV <$> Maximize nm' (toMetricSpace o)
 
    annotateForMS _ s = "toMetricSpace(" ++ s ++ ")"
 
@@ -581,12 +621,12 @@
    msMinimize nm o = do constrain $ sNot $ fpIsNaN o
                         let nm' = annotateForMS (Proxy @Double) nm
                         when (nm' /= nm) $ sObserve nm (unSBV o)
-                        addSValOptGoal $ unSBV `fmap` Minimize nm' (toMetricSpace o)
+                        addSValOptGoal $ unSBV <$> Minimize nm' (toMetricSpace o)
 
    msMaximize nm o = do constrain $ sNot $ fpIsNaN o
                         let nm' = annotateForMS (Proxy @Double) nm
                         when (nm' /= nm) $ sObserve nm (unSBV o)
-                        addSValOptGoal $ unSBV `fmap` Maximize nm' (toMetricSpace o)
+                        addSValOptGoal $ unSBV <$> Maximize nm' (toMetricSpace o)
 
    annotateForMS _ s = "toMetricSpace(" ++ s ++ ")"
 
@@ -615,13 +655,18 @@
 sFloatingPointAsComparableSWord :: forall eb sb. (ValidFloat eb sb, KnownNat (eb + sb), BVIsNonZero (eb + sb)) => SFloatingPoint eb sb -> SWord (eb + sb)
 sFloatingPointAsComparableSWord f = ite (fpIsNegativeZero f) posZero (fromBitsBE $ sNot sb : ite sb (map sNot rest) rest)
   where posZero     = sFloatingPointAsComparableSWord (0 :: SFloatingPoint eb sb)
-        (sb : rest) = blastBE (sFloatingPointAsSWord f :: SWord (eb + sb))
+        (sb, rest)  = case blastBE (sFloatingPointAsSWord f :: SWord (eb + sb)) of
+                         b : bs -> (b, bs)
+                         []     -> error "sFloatingPointAsComparableSWord: impossible, blastBE produced empty list"
 
 -- | 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:
 sComparableSWordAsSFloatingPoint :: forall eb sb. (KnownNat (eb + sb), BVIsNonZero (eb + sb), ValidFloat eb sb) => SWord (eb + sb) -> SFloatingPoint eb sb
 sComparableSWordAsSFloatingPoint w = sWordAsSFloatingPoint $ ite signBit (fromBitsBE $ sFalse : rest) (fromBitsBE $ map sNot allBits)
-  where allBits@(signBit : rest) = blastBE w
+  where allBits        = blastBE w
+        (signBit, rest) = case allBits of
+                             b : bs -> (b, bs)
+                             []     -> error "sComparableSWordAsSFloatingPoint: impossible, blastBE produced empty list"
 
 -- | Convert a word to an arbitrary float, by reinterpreting the bits of the word as the corresponding bits of the float.
 sWordAsSFloatingPoint :: forall eb sb. (KnownNat (eb + sb), BVIsNonZero (eb + sb), ValidFloat eb sb) => SWord (eb + sb) -> SFloatingPoint eb sb
@@ -655,23 +700,18 @@
    msMinimize nm o = do constrain $ sNot $ fpIsNaN o
                         let nm' = annotateForMS (Proxy @(FloatingPoint eb sb)) nm
                         when (nm' /= nm) $ sObserve nm (unSBV o)
-                        addSValOptGoal $ unSBV `fmap` Minimize nm' (toMetricSpace o)
+                        addSValOptGoal $ unSBV <$> Minimize nm' (toMetricSpace o)
 
    msMaximize nm o = do constrain $ sNot $ fpIsNaN o
                         let nm' = annotateForMS (Proxy @(FloatingPoint eb sb)) nm
                         when (nm' /= nm) $ sObserve nm (unSBV o)
-                        addSValOptGoal $ unSBV `fmap` Maximize nm' (toMetricSpace o)
+                        addSValOptGoal $ unSBV <$> Maximize nm' (toMetricSpace o)
 
    annotateForMS _ s = "toMetricSpace(" ++ s ++ ")"
 
 -- Map SBV's rounding modes to LibBF's
 rmToRM :: SRoundingMode -> Maybe RoundMode
-rmToRM srm = cvt <$> unliteral srm
-  where cvt RoundNearestTiesToEven = NearEven
-        cvt RoundNearestTiesToAway = NearAway
-        cvt RoundTowardPositive    = ToPosInf
-        cvt RoundTowardNegative    = ToNegInf
-        cvt RoundTowardZero        = ToZero
+rmToRM srm = roundingModeToRoundMode <$> unliteral srm
 
 -- | Lift a 1 arg Big-float op
 lift1FP :: forall eb sb. ValidFloat eb sb =>
diff --git a/Data/SBV/Core/Kind.hs b/Data/SBV/Core/Kind.hs
--- a/Data/SBV/Core/Kind.hs
+++ b/Data/SBV/Core/Kind.hs
@@ -11,39 +11,47 @@
 
 {-# LANGUAGE CPP                  #-}
 {-# LANGUAGE DataKinds            #-}
-{-# LANGUAGE DefaultSignatures    #-}
 {-# LANGUAGE DeriveAnyClass       #-}
 {-# LANGUAGE DeriveDataTypeable   #-}
 {-# LANGUAGE DeriveGeneric        #-}
+{-# LANGUAGE DeriveLift           #-}
 {-# LANGUAGE FlexibleInstances    #-}
 {-# LANGUAGE LambdaCase           #-}
+{-# LANGUAGE OverloadedStrings    #-}
+{-# LANGUAGE PatternSynonyms      #-}
 {-# LANGUAGE ScopedTypeVariables  #-}
-{-# LANGUAGE TypeFamilies         #-}
 {-# LANGUAGE TypeApplications     #-}
+{-# LANGUAGE TypeFamilies         #-}
 {-# LANGUAGE TypeOperators        #-}
 {-# LANGUAGE ViewPatterns         #-}
 {-# LANGUAGE UndecidableInstances #-}
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
 module Data.SBV.Core.Kind (
-          Kind(..), HasKind(..), constructUKind, smtType, hasUninterpretedSorts
+          Kind(KBool, KBounded, KUnbounded, KReal, KFloat, KDouble, KFP, KRational, KChar, KString, KVar, KApp, KADT, KList, KSet, KTuple, KArray)
+        , HasKind(..), smtType, hasUninterpretedSorts
+        , withADTDependencies, adtKindDependencies
         , BVIsNonZero, ValidFloat, intOfProxy
-        , showBaseKind, needsFlattening, RoundingMode(..), smtRoundingMode
+        , showBaseKind, needsFlattening
         , eqCheckIsObjectEq, containsFloats, isSomeKindOfFloat, expandKinds
+        , substituteADTVars
+        , kRoundingMode
         ) where
 
-import qualified Data.Generics as G (Data(..), DataType, dataTypeName, dataTypeOf, tyconUQname, dataTypeConstrs, constrFields)
+import qualified Data.Generics as G (Data(..), DataType, Constr, Fixity(Prefix), mkConstr, mkDataType, dataTypeName, tyconUQname)
 
 import Data.Char (isSpace)
 import Data.Int
 import Data.Word
 import Data.SBV.Core.AlgReals
+import Data.Text (Text)
+import qualified Data.Text as T
 
 import Data.Proxy
 import Data.Kind
 
-import Data.List (isPrefixOf, intercalate, sort)
+import Data.List (intercalate, sort)
 import Control.DeepSeq (NFData)
 
 import Data.Containers.ListUtils (nubOrd)
@@ -54,47 +62,140 @@
 
 import GHC.TypeLits
 
-import Data.SBV.Utils.Lib (isKString)
+import Data.SBV.Utils.Lib     (isKString, showText)
+import Data.SBV.Utils.Numeric (RoundingMode)
 
 import GHC.Generics
+import qualified Language.Haskell.TH.Syntax as TH
 import qualified Data.Generics.Uniplate.Data as G
 
-import Test.QuickCheck (Arbitrary(..), arbitraryBoundedEnum)
-
 -- | Kind of symbolic value
-data Kind = KBool
+data Kind =
+          -- Base types
+            KBool
+
+          -- Word and Int. Boolean is True for Int.
           | KBounded !Bool !Int
+
+          -- Unbounded integers
           | KUnbounded
+
+          -- Reals
           | KReal
-          | KUserSort String (Maybe [String])  -- name. Uninterpreted, or enumeration constants.
+
+          -- Floats, standard and generalized
           | KFloat
           | KDouble
           | KFP !Int !Int
+
+          -- Rationals
+          | KRational
+
+          -- Chars and strings
           | KChar
           | KString
+
+          -- Algebraic datatypes
+          | KVar String         -- only used temporarily during ADT construction
+          | KApp String [Kind]  -- Application of a constructor to a bunch of types
+          | KADTWithDependencies String
+                 [(String, Kind)]   -- Parameters, applied to these args
+                 [(String, [Kind])] -- Constructors, and their fields
+                 ADTDependencies   -- Additional declarations needed to register this type
+
+          -- Collections
           | KList Kind
           | KSet  Kind
           | KTuple [Kind]
-          | KMaybe  Kind
-          | KRational
-          | KEither Kind Kind
+
+          -- Arrays
           | KArray  Kind Kind
-          deriving (Eq, Ord, G.Data, NFData, Generic)
+          deriving (Eq, Ord, G.Data, NFData, Generic, TH.Lift)
 
--- Expand such that the resulting list has all the kinds we touch
+-- | Compatibility constructor and pattern for an ADT kind. Registration
+-- metadata does not change its symbolic identity or constructor fields.
+pattern KADT :: String -> [(String, Kind)] -> [(String, [Kind])] -> Kind
+pattern KADT typeName parameters constructors <- KADTWithDependencies typeName parameters constructors _
+  where KADT typeName parameters constructors = KADTWithDependencies typeName parameters constructors (ADTDependencies [])
+
+{-# COMPLETE KBool, KBounded, KUnbounded, KReal, KFloat, KDouble, KFP, KRational, KChar, KString, KVar, KApp, KADT, KList, KSet, KTuple, KArray #-}
+
+-- | A finite set of independent ADT declaration templates. These are
+-- registration metadata, not children of the annotated type: generic kind
+-- traversal and type-variable substitution must not enter their scopes.
+newtype ADTDependencies = ADTDependencies [Kind]
+                       deriving (NFData, Generic, TH.Lift)
+
+-- | Registration metadata does not participate in kind equality.
+-- For a given datatype name, generated dependency schemas are fixed and
+-- interchangeable; this annotation must not carry per-instantiation semantics.
+instance Eq ADTDependencies where
+  _ == _ = True
+
+-- | Registration metadata does not participate in kind ordering.
+-- This uses the same name-determined-schema invariant as the equality instance.
+instance Ord ADTDependencies where
+  compare _ _ = EQ
+
+-- | Keep independent declaration scopes opaque to generic transformations.
+-- Reconstructing the metadata's nullary generic representation yields the
+-- empty annotation; ordinary traversals preserve the existing annotation.
+instance G.Data ADTDependencies where
+  gfoldl _ z = z
+  gunfold _ z _ = z (ADTDependencies [])
+  toConstr _ = adtDependenciesConstr
+  dataTypeOf _ = adtDependenciesDataType
+
+-- | Opaque generic datatype for ADT registration metadata.
+adtDependenciesDataType :: G.DataType
+adtDependenciesDataType = G.mkDataType "Data.SBV.Core.Kind.ADTDependencies" [adtDependenciesConstr]
+
+-- | Nullary generic constructor for ADT registration metadata.
+adtDependenciesConstr :: G.Constr
+adtDependenciesConstr = G.mkConstr adtDependenciesDataType "ADTDependencies" [] G.Prefix
+
+-- | Attach the complete dependency registry generated by 'Data.SBV.mkSymbolic'.
+-- Strip annotations throughout each dependency so mutually recursive kinds
+-- remain finite even when recursion passes through a datatype parameter.
+withADTDependencies :: [Kind] -> Kind -> Kind
+withADTDependencies dependencies (KADT typeName parameters constructors)
+  = KADTWithDependencies typeName parameters constructors (ADTDependencies (map (G.transform strip) dependencies))
+  where strip (KADT n ps cs) = KADT n ps cs
+        strip kind          = kind
+withADTDependencies _ kind = error $ "SBV: Expected an ADT kind when attaching dependencies, received " ++ show kind
+
+-- | Return the independent declaration templates needed to register an ADT.
+adtKindDependencies :: Kind -> [Kind]
+adtKindDependencies (KADTWithDependencies _ _ _ (ADTDependencies dependencies)) = dependencies
+adtKindDependencies _ = []
+
+-- | Built in kind for rounding mode
+kRoundingMode :: Kind
+kRoundingMode = KADT "RoundingMode" [] (map (\r -> (show r, [])) [minBound .. maxBound :: RoundingMode])
+
+-- | Expand such that the resulting list has all the kinds we touch
 expandKinds :: Kind -> [Kind]
 expandKinds = sort . nubOrd . G.universe
 
--- | The interesting about the show instance is that it can tell apart two kinds nicely; since it conveniently
--- ignores the enumeration constructors. Also, when we construct a 'KUserSort', we make sure we don't use any of
--- the reserved names; see 'constructUKind' for details.
+-- | For an ADT kind, substitute kinds for the variables.
+substituteADTVars :: String -> [(String, Kind)] -> Kind -> Kind
+substituteADTVars t dict = G.transform sub
+  where sub :: Kind -> Kind
+        sub (KVar v)
+          | Just k <- v `lookup` dict = k
+          | True                      = error $ "Data.SBV.ADT: Kind find variable in param subst: " ++ show (t, v, dict)
+        sub k = k
+
+-- | The interesting about the show instance is that it can tell apart two kinds nicely. Otherwise the string produced isn't parsed back.
 instance Show Kind where
+  show (KVar s)           = s
   show KBool              = "SBool"
   show (KBounded False n) = pickType n "SWord" "SWord " ++ show n
   show (KBounded True n)  = pickType n "SInt"  "SInt "  ++ show n
   show KUnbounded         = "SInteger"
   show KReal              = "SReal"
-  show (KUserSort s _)    = s
+  show (KApp c ks)        = unwords (c : map (T.unpack . kindParen . showBaseKind      )  ks)
+  show (KADT s pks _)     = unwords (s : map (T.unpack . kindParen . showBaseKind . snd) pks)
   show KFloat             = "SFloat"
   show KDouble            = "SDouble"
   show (KFP eb sb)        = "SFloatingPoint " ++ show eb ++ " " ++ show sb
@@ -104,35 +205,34 @@
   show (KSet  e)          = "{" ++ show e ++ "}"
   show (KTuple m)         = "(" ++ intercalate ", " (show <$> m) ++ ")"
   show KRational          = "SRational"
-  show (KMaybe k)         = "SMaybe "  ++ kindParen (showBaseKind k)
-  show (KEither k1 k2)    = "SEither " ++ kindParen (showBaseKind k1) ++ " " ++ kindParen (showBaseKind k2)
-  show (KArray k1 k2)     = "SArray "  ++ kindParen (showBaseKind k1) ++ " " ++ kindParen (showBaseKind k2)
+  show (KArray k1 k2)     = "SArray "  ++ T.unpack (kindParen (showBaseKind k1)) ++ " " ++ T.unpack (kindParen (showBaseKind k2))
 
--- | A version of show for kinds that says Bool instead of SBool
-showBaseKind :: Kind -> String
+-- | A version of show for kinds that says Bool instead of SBool, Float instead of SFloat, etc.
+showBaseKind :: Kind -> Text
 showBaseKind = sh
-  where sh k@KBool            = noS (show k)
-        sh (KBounded False n) = pickType n "Word" "WordN " ++ show n
-        sh (KBounded True n)  = pickType n "Int"  "IntN "  ++ show n
-        sh k@KUnbounded       = noS (show k)
-        sh k@KReal            = noS (show k)
-        sh k@KUserSort{}      = show k     -- Leave user-sorts untouched!
-        sh k@KFloat           = noS (show k)
-        sh k@KDouble          = noS (show k)
-        sh k@KFP{}            = noS (show k)
-        sh k@KChar            = noS (show k)
-        sh k@KString          = noS (show k)
+  where sh (KVar s)           = T.pack s
+        sh k@KBool            = noS (showText k)
+        sh (KBounded False n) = T.pack (pickType n "Word" "WordN ") <> showText n
+        sh (KBounded True n)  = T.pack (pickType n "Int"  "IntN ")  <> showText n
+        sh (KApp s ks)        = T.unwords (T.pack s : map (kindParen . sh) ks)
+        sh k@KUnbounded       = noS (showText k)
+        sh k@KReal            = noS (showText k)
+        sh k@KADT{}           = showText k     -- Leave user-sorts untouched!
+        sh k@KFloat           = noS (showText k)
+        sh k@KDouble          = noS (showText k)
+        sh k@KFP{}            = noS (showText k)
+        sh k@KChar            = noS (showText k)
+        sh k@KString          = noS (showText k)
         sh KRational          = "Rational"
-        sh (KList k)          = "[" ++ sh k ++ "]"
-        sh (KSet k)           = "{" ++ sh k ++ "}"
-        sh (KTuple ks)        = "(" ++ intercalate ", " (map sh ks) ++ ")"
-        sh (KMaybe k)         = "Maybe "  ++ kindParen (sh k)
-        sh (KEither k1 k2)    = "Either " ++ kindParen (sh k1) ++ " " ++ kindParen (sh k2)
-        sh (KArray  k1 k2)    = "Array "  ++ kindParen (sh k1) ++ " " ++ kindParen (sh k2)
+        sh (KList k)          = "[" <> sh k <> "]"
+        sh (KSet k)           = "{" <> sh k <> "}"
+        sh (KTuple ks)        = "(" <> T.intercalate ", " (map sh ks) <> ")"
+        sh (KArray  k1 k2)    = "Array "  <> kindParen (sh k1) <> " " <> kindParen (sh k2)
 
         -- Drop the initial S if it's there
-        noS ('S':s) = s
-        noS s       = s
+        noS s = case T.uncons s of
+                  Just ('S', rest) -> rest
+                  _                -> s
 
 -- For historical reasons, we show 8-16-32-64 bit values with no space; others with a space.
 pickType :: Int -> String -> String -> String
@@ -141,34 +241,36 @@
   | True                     = other
 
 -- | Put parens if necessary. This test is rather crummy, but seems to work ok
-kindParen :: String -> String
-kindParen s@('[':_) = s
-kindParen s@('(':_) = s
-kindParen s | any isSpace s = '(' : s ++ ")"
-            | True          = s
+kindParen :: Text -> Text
+kindParen s = case T.uncons s of
+                Just ('[', _) -> s
+                Just ('(', _) -> s
+                _             -> if T.any isSpace s
+                                 then T.singleton '(' <> s <> T.singleton ')'
+                                 else s
 
 -- | How the type maps to SMT land
-smtType :: Kind -> String
+smtType :: Kind -> Text
+smtType (KVar s)        = T.pack s
 smtType KBool           = "Bool"
-smtType (KBounded _ sz) = "(_ BitVec " ++ show sz ++ ")"
+smtType (KBounded _ sz) = "(_ BitVec " <> showText sz <> ")"
 smtType KUnbounded      = "Int"
 smtType KReal           = "Real"
 smtType KFloat          = "(_ FloatingPoint  8 24)"
 smtType KDouble         = "(_ FloatingPoint 11 53)"
-smtType (KFP eb sb)     = "(_ FloatingPoint " ++ show eb ++ " " ++ show sb ++ ")"
+smtType (KFP eb sb)     = "(_ FloatingPoint " <> showText eb <> " " <> showText sb <> ")"
 smtType KString         = "String"
 smtType KChar           = "String"
-smtType (KList k)       = "(Seq "   ++ smtType k ++ ")"
-smtType (KSet  k)       = "(Array " ++ smtType k ++ " Bool)"
-smtType (KUserSort s _) = s
+smtType (KList k)       = "(Seq "   <> smtType k <> ")"
+smtType (KSet  k)       = "(Array " <> smtType k <> " Bool)"
+smtType (KApp s ks)     = kindParen $ T.unwords (T.pack s : map smtType          ks)
+smtType (KADT s pks _)  = kindParen $ T.unwords (T.pack s : map (smtType . snd) pks)
 smtType (KTuple [])     = "SBVTuple0"
-smtType (KTuple kinds)  = "(SBVTuple" ++ show (length kinds) ++ " " ++ unwords (smtType <$> kinds) ++ ")"
+smtType (KTuple kinds)  = "(SBVTuple" <> showText (length kinds) <> " " <> T.unwords (smtType <$> kinds) <> ")"
 smtType KRational       = "SBVRational"
-smtType (KMaybe k)      = "(SBVMaybe " ++ smtType k ++ ")"
-smtType (KEither k1 k2) = "(SBVEither "  ++ smtType k1 ++ " " ++ smtType k2 ++ ")"
-smtType (KArray  k1 k2) = "(Array "      ++ smtType k1 ++ " " ++ smtType k2 ++ ")"
+smtType (KArray  k1 k2) = "(Array " <> smtType k1 <> " " <> smtType k2 <> ")"
 
-instance Eq  G.DataType where
+instance Eq G.DataType where
    a == b = G.tyconUQname (G.dataTypeName a) == G.tyconUQname (G.dataTypeName b)
 
 instance Ord G.DataType where
@@ -176,7 +278,8 @@
 
 -- | Does this kind represent a signed quantity?
 kindHasSign :: Kind -> Bool
-kindHasSign = \case KBool        -> False
+kindHasSign = \case KVar _       -> False
+                    KBool        -> False
                     KBounded b _ -> b
                     KUnbounded   -> True
                     KReal        -> True
@@ -184,79 +287,49 @@
                     KDouble      -> True
                     KFP{}        -> True
                     KRational    -> True
-                    KUserSort{}  -> False
+                    KApp{}       -> False
+                    KADT{}       -> False
                     KString      -> False
                     KChar        -> False
                     KList{}      -> False
                     KSet{}       -> False
                     KTuple{}     -> False
-                    KMaybe{}     -> False
-                    KEither{}    -> False
                     KArray{}     -> False
 
--- | Construct an uninterpreted/enumerated kind from a piece of data; we distinguish simple enumerations as those
--- are mapped to proper SMT-Lib2 data-types; while others go completely uninterpreted
-constructUKind :: forall a. (Read a, G.Data a) => a -> Kind
-constructUKind a
-  | any (`isPrefixOf` sortName) badPrefixes
-  = error $ unlines [ "*** Data.SBV: Cannot construct user-sort with name: " ++ show sortName
-                    , "***"
-                    , "***  Must not start with any of: " ++ intercalate ", " badPrefixes
-                    ]
-  | True
-  = case (constrs, concatMap G.constrFields constrs) of
-      ([], _)  -> KUserSort sortName   Nothing
-      (cs, []) -> KUserSort sortName $ Just (map show cs)
-      _        -> error $ unlines [ "*** Data.SBV: " ++ sortName ++ " is not an enumeration."
-                                  , "***"
-                                  , "*** To declare an enumeration, constructors should not have any fields."
-                                  , "*** To declare an uninterpreted sort, use a datatype with no constructors."
-                                  ]
-
-  where -- make sure we don't step on ourselves:
-        -- NB. The sort "RoundingMode" is special. It's treated by SBV as a user-defined
-        -- sort, even though it's internally handled differently. So, that name doesn't appear
-        -- below.
-        badPrefixes = [ "SBool",   "SWord", "SInt", "SInteger", "SReal",  "SFloat", "SDouble"
-                      , "SString", "SChar", "[",    "SSet",     "STuple", "SMaybe", "SEither"
-                      , "SRational"
-                      ]
-
-        dataType    = G.dataTypeOf a
-        sortName    = G.tyconUQname . G.dataTypeName $ dataType
-        constrs     = G.dataTypeConstrs dataType
-
 -- | A class for capturing values that have a sign and a size (finite or infinite)
 -- minimal complete definition: kindOf, unless you can take advantage of the default
 -- signature: This class can be automatically derived for data-types that have
 -- a 'G.Data' instance; this is useful for creating uninterpreted sorts. So, in
 -- reality, end users should almost never need to define any methods.
 class HasKind a where
-  kindOf      :: a -> Kind
-  hasSign     :: a -> Bool
-  intSizeOf   :: a -> Int
-  isBoolean   :: a -> Bool
-  isBounded   :: a -> Bool   -- NB. This really means word/int; i.e., Real/Float will test False
-  isReal      :: a -> Bool
-  isFloat     :: a -> Bool
-  isDouble    :: a -> Bool
-  isRational  :: a -> Bool
-  isFP        :: a -> Bool
-  isUnbounded :: a -> Bool
-  isUserSort  :: a -> Bool
-  isChar      :: a -> Bool
-  isString    :: a -> Bool
-  isList      :: a -> Bool
-  isSet       :: a -> Bool
-  isTuple     :: a -> Bool
-  isMaybe     :: a -> Bool
-  isEither    :: a -> Bool
-  isArray     :: a -> Bool
-  showType    :: a -> String
+  kindOf          :: a -> Kind
+  hasSign         :: a -> Bool
+  intSizeOf       :: a -> Int
+  isBoolean       :: a -> Bool
+  isBounded       :: a -> Bool   -- NB. This really means word/int; i.e., Real/Float will test False
+  isReal          :: a -> Bool
+  isFloat         :: a -> Bool
+  isDouble        :: a -> Bool
+  isRational      :: a -> Bool
+  isFP            :: a -> Bool
+  isUnbounded     :: a -> Bool
+  isADT           :: a -> Bool
+  isChar          :: a -> Bool
+  isString        :: a -> Bool
+  isList          :: a -> Bool
+  isSet           :: a -> Bool
+  isTuple         :: a -> Bool
+  isArray         :: a -> Bool
+  isRoundingMode  :: a -> Bool
+  isUninterpreted :: a -> Bool
+
+  showType        :: a -> String
+
   -- defaults
   hasSign x = kindHasSign (kindOf x)
 
   intSizeOf x = case kindOf x of
+                  KVar{}        -> error "SBV.HasKind.intSizeOf(KVar)"
                   KBool         -> error "SBV.HasKind.intSizeOf((S)Bool)"
                   KBounded _ s  -> s
                   KUnbounded    -> error "SBV.HasKind.intSizeOf((S)Integer)"
@@ -265,14 +338,13 @@
                   KDouble       -> 64
                   KFP i j       -> i + j
                   KRational     -> error "SBV.HasKind.intSizeOf((S)Rational)"
-                  KUserSort s _ -> error $ "SBV.HasKind.intSizeOf: Uninterpreted sort: " ++ s
+                  KApp s _      -> error $ "SBV.HasKind.intSizeOf: Type application: "    ++ s
+                  KADT s _ _    -> error $ "SBV.HasKind.intSizeOf: Algebraic data type: " ++ s
                   KString       -> error "SBV.HasKind.intSizeOf((S)Double)"
                   KChar         -> error "SBV.HasKind.intSizeOf((S)Char)"
                   KList ek      -> error $ "SBV.HasKind.intSizeOf((S)List)"   ++ show ek
                   KSet  ek      -> error $ "SBV.HasKind.intSizeOf((S)Set)"    ++ show ek
                   KTuple tys    -> error $ "SBV.HasKind.intSizeOf((S)Tuple)"  ++ show tys
-                  KMaybe k      -> error $ "SBV.HasKind.intSizeOf((S)Maybe)"  ++ show k
-                  KEither k1 k2 -> error $ "SBV.HasKind.intSizeOf((S)Either)" ++ show (k1, k2)
                   KArray  k1 k2 -> error $ "SBV.HasKind.intSizeOf((S)Array)"  ++ show (k1, k2)
 
   isBoolean       (kindOf -> KBool{})      = True
@@ -299,8 +371,8 @@
   isUnbounded     (kindOf -> KUnbounded{}) = True
   isUnbounded     _                        = False
 
-  isUserSort      (kindOf -> KUserSort{})  = True
-  isUserSort      _                        = False
+  isADT           (kindOf -> KADT{})       = True
+  isADT           _                        = False
 
   isChar          (kindOf -> KChar{})      = True
   isChar          _                        = False
@@ -317,41 +389,40 @@
   isTuple         (kindOf -> KTuple{})     = True
   isTuple         _                        = False
 
-  isMaybe         (kindOf -> KMaybe{})     = True
-  isMaybe         _                        = False
-
-  isEither        (kindOf -> KEither{})    = True
-  isEither        _                        = False
-
   isArray         (kindOf -> KArray{})     = True
   isArray         _                        = False
 
+  -- Derived kinds
+  isRoundingMode  (kindOf -> k)            = k == kRoundingMode
+  isUninterpreted (kindOf -> k)            = case k of
+                                               KADT _ [] [] -> True
+                                               _            -> False
+
   showType = show . kindOf
 
-  -- default signature for uninterpreted/enumerated kinds
-  default kindOf :: (Read a, G.Data a) => a -> Kind
-  kindOf = constructUKind
+  {-# MINIMAL kindOf #-}
 
 -- | This instance allows us to use the `kindOf (Proxy @a)` idiom instead of
 -- the `kindOf (undefined :: a)`, which is safer and looks more idiomatic.
 instance HasKind a => HasKind (Proxy a) where
   kindOf _ = kindOf (undefined :: a)
 
-instance HasKind Bool     where kindOf _ = KBool
-instance HasKind Int8     where kindOf _ = KBounded True  8
-instance HasKind Word8    where kindOf _ = KBounded False 8
-instance HasKind Int16    where kindOf _ = KBounded True  16
-instance HasKind Word16   where kindOf _ = KBounded False 16
-instance HasKind Int32    where kindOf _ = KBounded True  32
-instance HasKind Word32   where kindOf _ = KBounded False 32
-instance HasKind Int64    where kindOf _ = KBounded True  64
-instance HasKind Word64   where kindOf _ = KBounded False 64
-instance HasKind Integer  where kindOf _ = KUnbounded
-instance HasKind AlgReal  where kindOf _ = KReal
-instance HasKind Rational where kindOf _ = KRational
-instance HasKind Float    where kindOf _ = KFloat
-instance HasKind Double   where kindOf _ = KDouble
-instance HasKind Char     where kindOf _ = KChar
+instance HasKind Bool         where kindOf _ = KBool
+instance HasKind Int8         where kindOf _ = KBounded True  8
+instance HasKind Word8        where kindOf _ = KBounded False 8
+instance HasKind Int16        where kindOf _ = KBounded True  16
+instance HasKind Word16       where kindOf _ = KBounded False 16
+instance HasKind Int32        where kindOf _ = KBounded True  32
+instance HasKind Word32       where kindOf _ = KBounded False 32
+instance HasKind Int64        where kindOf _ = KBounded True  64
+instance HasKind Word64       where kindOf _ = KBounded False 64
+instance HasKind Integer      where kindOf _ = KUnbounded
+instance HasKind AlgReal      where kindOf _ = KReal
+instance HasKind Rational     where kindOf _ = KRational
+instance HasKind Float        where kindOf _ = KFloat
+instance HasKind Double       where kindOf _ = KDouble
+instance HasKind Char         where kindOf _ = KChar
+instance HasKind RoundingMode where kindOf _ = kRoundingMode
 
 -- | Grab the bit-size from the proxy. If the nat is too large to fit in an int,
 -- we throw an error. (This would mean too big of a bit-size, that we can't
@@ -390,10 +461,7 @@
 
 -- | Do we have a completely uninterpreted sort lying around anywhere?
 hasUninterpretedSorts :: Kind -> Bool
-hasUninterpretedSorts = any check . expandKinds
-  where check (KUserSort _ Nothing)  = True   -- These are the completely uninterpreted sorts, which we are looking for here
-        check (KUserSort _ (Just{})) = False  -- These are the enumerated sorts, and they are perfectly fine
-        check _                      = False
+hasUninterpretedSorts = any isUninterpreted . expandKinds
 
 instance (Typeable a, HasKind a) => HasKind [a] where
    kindOf x | isKString @[a] x = KString
@@ -426,12 +494,6 @@
 instance (HasKind a, HasKind b, HasKind c, HasKind d, HasKind e, HasKind f, HasKind g, HasKind h) => HasKind (a, b, c, d, e, f, g, h) where
   kindOf _ = KTuple [kindOf (Proxy @a), kindOf (Proxy @b), kindOf (Proxy @c), kindOf (Proxy @d), kindOf (Proxy @e), kindOf (Proxy @f), kindOf (Proxy @g), kindOf (Proxy @h)]
 
-instance (HasKind a, HasKind b) => HasKind (Either a b) where
-  kindOf _ = KEither (kindOf (Proxy @a)) (kindOf (Proxy @b))
-
-instance HasKind a => HasKind (Maybe a) where
-  kindOf _ = KMaybe (kindOf (Proxy @a))
-
 instance (HasKind a, HasKind b) => HasKind (a -> b) where
   kindOf _ = KArray (kindOf (Proxy @a)) (kindOf (Proxy @b))
 
@@ -443,16 +505,16 @@
   where check KList{}     = True
         check KSet{}      = True
         check KTuple{}    = True
-        check KMaybe{}    = True
-        check KEither{}   = True
         check KArray{}    = True
+        check KApp{}      = True
+        check k@KADT{}    = not (isUninterpreted k || isRoundingMode k)
 
         -- no need to expand bases
+        check KVar{}      = False
         check KBool       = False
         check KBounded{}  = False
         check KUnbounded  = False
         check KReal       = False
-        check KUserSort{} = False
         check KFloat      = False
         check KDouble     = False
         check KFP{}       = False
@@ -522,33 +584,3 @@
                                             (() :: Constraint)
                                             (TypeError (InvalidFloat eb sb))
                                        )
-
--- | Rounding mode to be used for the IEEE floating-point operations.
--- Note that Haskell's default is 'RoundNearestTiesToEven'. If you use
--- a different rounding mode, then the counter-examples you get may not
--- match what you observe in Haskell.
-data RoundingMode = RoundNearestTiesToEven  -- ^ Round to nearest representable floating point value.
-                                            -- If precisely at half-way, pick the even number.
-                                            -- (In this context, /even/ means the lowest-order bit is zero.)
-                  | RoundNearestTiesToAway  -- ^ Round to nearest representable floating point value.
-                                            -- If precisely at half-way, pick the number further away from 0.
-                                            -- (That is, for positive values, pick the greater; for negative values, pick the smaller.)
-                  | RoundTowardPositive     -- ^ Round towards positive infinity. (Also known as rounding-up or ceiling.)
-                  | RoundTowardNegative     -- ^ Round towards negative infinity. (Also known as rounding-down or floor.)
-                  | RoundTowardZero         -- ^ Round towards zero. (Also known as truncation.)
-                  deriving (Eq, Ord, Show, Read, G.Data, Bounded, Enum)
-
--- | 'RoundingMode' kind
-instance HasKind RoundingMode
-
--- | An arbitrary rounding mode
-instance Arbitrary RoundingMode where
-  arbitrary = arbitraryBoundedEnum
-
--- | Convert a rounding mode to the format SMT-Lib2 understands.
-smtRoundingMode :: RoundingMode -> String
-smtRoundingMode RoundNearestTiesToEven = "roundNearestTiesToEven"
-smtRoundingMode RoundNearestTiesToAway = "roundNearestTiesToAway"
-smtRoundingMode RoundTowardPositive    = "roundTowardPositive"
-smtRoundingMode RoundTowardNegative    = "roundTowardNegative"
-smtRoundingMode RoundTowardZero        = "roundTowardZero"
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
@@ -9,3613 +9,4999 @@
 -- Instance declarations for our symbolic world
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE BangPatterns            #-}
-{-# LANGUAGE CPP                     #-}
-{-# LANGUAGE DataKinds               #-}
-{-# LANGUAGE DefaultSignatures       #-}
-{-# LANGUAGE DeriveFunctor           #-}
-{-# LANGUAGE FlexibleContexts        #-}
-{-# LANGUAGE FlexibleInstances       #-}
-{-# LANGUAGE InstanceSigs            #-}
-{-# LANGUAGE MultiParamTypeClasses   #-}
-{-# LANGUAGE NamedFieldPuns          #-}
-{-# LANGUAGE Rank2Types              #-}
-{-# LANGUAGE ScopedTypeVariables     #-}
-{-# LANGUAGE TypeApplications        #-}
-{-# LANGUAGE TypeFamilies            #-}
-{-# LANGUAGE TypeOperators           #-}
-{-# LANGUAGE UndecidableInstances    #-}
-
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans -Wno-incomplete-uni-patterns #-}
-
-module Data.SBV.Core.Model (
-    Mergeable(..), Equality(..), EqSymbolic(..), OrdSymbolic(..), SDivisible(..), SMTDefinable(..), QSaturate, qSaturateSavingObservables
-  , Metric(..), minimize, maximize, assertWithPenalty, SIntegral, SFiniteBits(..)
-  , ite, iteLazy, sFromIntegral, sShiftLeft, sShiftRight, sRotateLeft, sBarrelRotateLeft, sRotateRight, sBarrelRotateRight, sSignedShiftArithRight, (.^)
-  , some
-  , oneIf, genVar, genVar_
-  , pbAtMost, pbAtLeast, pbExactly, pbLe, pbGe, pbEq, pbMutexed, pbStronglyMutexed
-  , sBool, sBool_, sBools, sWord8, sWord8_, sWord8s, sWord16, sWord16_, sWord16s, sWord32, sWord32_, sWord32s
-  , sWord64, sWord64_, sWord64s, sInt8, sInt8_, sInt8s, sInt16, sInt16_, sInt16s, sInt32, sInt32_, sInt32s, sInt64, sInt64_
-  , sInt64s, sInteger, sInteger_, sIntegers, sReal, sReal_, sReals, sFloat, sFloat_, sFloats, sDouble, sDouble_, sDoubles
-  , sWord, sWord_, sWords, sInt, sInt_, sInts
-  , sFPHalf, sFPHalf_, sFPHalfs, sFPBFloat, sFPBFloat_, sFPBFloats, sFPSingle, sFPSingle_, sFPSingles, sFPDouble, sFPDouble_, sFPDoubles, sFPQuad, sFPQuad_, sFPQuads, sArray, sArray_, sArrays
-  , sFloatingPoint, sFloatingPoint_, sFloatingPoints
-  , sChar, sChar_, sChars, sString, sString_, sStrings, sList, sList_, sLists
-  , sRational, sRational_, sRationals
-  , SymTuple, sTuple, sTuple_, sTuples
-  , sEither, sEither_, sEithers, sMaybe, sMaybe_, sMaybes
-  , sSet, sSet_, sSets
-  , sEDivMod, sEDiv, sEMod
-  , sDivides
-  , solve
-  , slet
-  , sRealToSInteger, sRealToSIntegerTruncate, label, observe, observeIf, sObserve
-  , sAssert
-  , liftQRem, liftDMod, symbolicMergeWithKind
-  , genLiteral, genFromCV, genMkSymVar
-  , zeroExtend, signExtend
-  , sbvQuickCheck
-  , readArray, writeArray, lambdaArray, listArray
-  , FromSized, ToSized, FromSizedBV(..), ToSizedBV(..)
-  , smtHOFunction, Closure(..)
-  )
-  where
-
-import Control.Applicative    (ZipList(ZipList))
-import Control.Monad          (when, unless, mplus, replicateM)
-import Control.Monad.IO.Class (MonadIO, liftIO)
-
-import qualified Control.Exception as C
-
-import GHC.Generics (M1(..), U1(..), (:*:)(..), K1(..))
-import qualified GHC.Generics as G
-
-import GHC.Stack
-import GHC.TypeLits
-#if MIN_VERSION_base(4,18,0)
-                    hiding(SChar)
-#endif
-
-import Data.Array  (Array, Ix, elems, bounds, rangeSize)
-import qualified Data.Array as DA (listArray)
-
-import Data.Bits   (Bits(..))
-import Data.Int    (Int8, Int16, Int32, Int64)
-import Data.Kind   (Type, Constraint)
-import Data.List   (genericLength, genericIndex, genericTake, unzip4, unzip5, unzip6, unzip7, intercalate)
-import Data.Maybe  (fromMaybe, mapMaybe)
-import Data.String (IsString(..))
-import Data.Word   (Word8, Word16, Word32, Word64)
-
-import Data.List.NonEmpty (NonEmpty(..))
-import qualified Data.List.NonEmpty as NE
-
-import qualified Data.Set as Set
-
-import Data.Proxy
-import Data.Dynamic (fromDynamic, toDyn, Typeable)
-
-import Test.QuickCheck                         (Testable(..), Arbitrary(..))
-import qualified Test.QuickCheck.Test    as QC (isSuccess)
-import qualified Test.QuickCheck         as QC (quickCheckResult, counterexample)
-import qualified Test.QuickCheck.Monadic as QC (monadicIO, run, assert, pre, monitor)
-
-import qualified Data.Foldable as F (toList)
-
-import Data.SBV.Core.AlgReals
-import Data.SBV.Core.Sized
-import Data.SBV.Core.SizedFloats
-import Data.SBV.Core.Data hiding (Constraint)
-import Data.SBV.Core.Symbolic
-import Data.SBV.Core.Operations
-import Data.SBV.Core.Kind
-import Data.SBV.Lambda
-import Data.SBV.Utils.ExtractIO(ExtractIO)
-
-import Data.SBV.Provers.Prover (defaultSMTCfg, SafeResult(..), defs2smt, prove)
-import Data.SBV.SMT.SMT        (ThmResult, showModel)
-
-import Data.SBV.Utils.Numeric (fpIsEqualObjectH)
-
-import Data.IORef (readIORef, writeIORef)
-import Data.SBV.Utils.Lib
-
-import Data.Char
-
--- Symbolic-Word class instances
-
-import Crypto.Hash.SHA512 (hash)
-import qualified Data.ByteString.Base16 as B
-import qualified Data.ByteString.Char8  as BC
-
--- | Generate a variable, named
-genVar :: MonadSymbolic m => VarContext -> Kind -> String -> m (SBV a)
-genVar q k = mkSymSBV q k . Just
-
--- | Generate an unnamed variable
-genVar_ :: MonadSymbolic m => VarContext -> Kind -> m (SBV a)
-genVar_ q k = mkSymSBV q k Nothing
-
--- | Generate a finite constant bitvector
-genLiteral :: Integral a => Kind -> a -> SBV b
-genLiteral k = SBV . SVal k . Left . mkConstCV k
-
--- | Convert a constant to an integral value
-genFromCV :: Integral a => CV -> a
-genFromCV (CV _ (CInteger x)) = fromInteger x
-genFromCV c                   = error $ "genFromCV: Unsupported non-integral value: " ++ show c
-
--- | Generalization of 'Data.SBV.genMkSymVar'
-genMkSymVar :: MonadSymbolic m => Kind -> VarContext -> Maybe String -> m (SBV a)
-genMkSymVar k mbq Nothing  = genVar_ mbq k
-genMkSymVar k mbq (Just s) = genVar  mbq k s
-
-instance SymVal Bool where
-  mkSymVal = genMkSymVar KBool
-  literal  = SBV . svBool
-  fromCV   = cvToBool
-
-instance SymVal Word8 where
-  mkSymVal = genMkSymVar (KBounded False 8)
-  literal  = genLiteral  (KBounded False 8)
-  fromCV   = genFromCV
-
-instance SymVal Int8 where
-  mkSymVal = genMkSymVar (KBounded True 8)
-  literal  = genLiteral  (KBounded True 8)
-  fromCV   = genFromCV
-
-instance SymVal Word16 where
-  mkSymVal = genMkSymVar (KBounded False 16)
-  literal  = genLiteral  (KBounded False 16)
-  fromCV   = genFromCV
-
-instance SymVal Int16 where
-  mkSymVal = genMkSymVar (KBounded True 16)
-  literal  = genLiteral  (KBounded True 16)
-  fromCV   = genFromCV
-
-instance SymVal Word32 where
-  mkSymVal = genMkSymVar (KBounded False 32)
-  literal  = genLiteral  (KBounded False 32)
-  fromCV   = genFromCV
-
-instance SymVal Int32 where
-  mkSymVal = genMkSymVar (KBounded True 32)
-  literal  = genLiteral  (KBounded True 32)
-  fromCV   = genFromCV
-
-instance SymVal Word64 where
-  mkSymVal = genMkSymVar (KBounded False 64)
-  literal  = genLiteral  (KBounded False 64)
-  fromCV   = genFromCV
-
-instance SymVal Int64 where
-  mkSymVal = genMkSymVar (KBounded True 64)
-  literal  = genLiteral  (KBounded True 64)
-  fromCV   = genFromCV
-
-instance SymVal Integer where
-  mkSymVal    = genMkSymVar KUnbounded
-  literal     = SBV . SVal KUnbounded . Left . mkConstCV KUnbounded
-  fromCV      = genFromCV
-  minMaxBound = Nothing
-
-instance SymVal Rational where
-  mkSymVal                    = genMkSymVar KRational
-  literal                     = SBV . SVal KRational  . Left . CV KRational . CRational
-  fromCV (CV _ (CRational r)) = r
-  fromCV c                    = error $ "SymVal.Rational: Unexpected non-rational value: " ++ show c
-  minMaxBound                 = Nothing
-
-instance SymVal AlgReal where
-  mkSymVal                   = genMkSymVar KReal
-  literal                    = SBV . SVal KReal . Left . CV KReal . CAlgReal
-  fromCV (CV _ (CAlgReal a)) = a
-  fromCV c                   = error $ "SymVal.AlgReal: Unexpected non-real value: " ++ show c
-  minMaxBound               = Nothing
-
-  -- AlgReal needs its own definition of isConcretely
-  -- to make sure we avoid using unimplementable Haskell functions
-  isConcretely (SBV (SVal KReal (Left (CV KReal (CAlgReal v))))) p
-     | isExactRational v = p v
-  isConcretely _ _       = False
-
-instance SymVal Float where
-  mkSymVal                 = genMkSymVar KFloat
-  literal                  = SBV . SVal KFloat . Left . CV KFloat . CFloat
-  fromCV (CV _ (CFloat a)) = a
-  fromCV c                 = error $ "SymVal.Float: Unexpected non-float value: " ++ show c
-  minMaxBound              = Nothing
-
-  -- For Float, we conservatively return 'False' for isConcretely. The reason is that
-  -- this function is used for optimizations when only one of the argument is concrete,
-  -- and in the presence of NaN's it would be incorrect to do any optimization
-  isConcretely _ _ = False
-
-instance SymVal Double where
-  mkSymVal                  = genMkSymVar KDouble
-  literal                   = SBV . SVal KDouble . Left . CV KDouble . CDouble
-  fromCV (CV _ (CDouble a)) = a
-  fromCV c                  = error $ "SymVal.Double: Unexpected non-double value: " ++ show c
-  minMaxBound               = Nothing
-
-  -- For Double, we conservatively return 'False' for isConcretely. The reason is that
-  -- this function is used for optimizations when only one of the argument is concrete,
-  -- and in the presence of NaN's it would be incorrect to do any optimization
-  isConcretely _ _ = False
-
-instance SymVal Char where
-  mkSymVal                = genMkSymVar KChar
-  literal c               = SBV . SVal KChar . Left . CV KChar $ CChar c
-  fromCV (CV _ (CChar a)) = a
-  fromCV c                = error $ "SymVal.String: Unexpected non-char value: " ++ show c
-
-instance SymVal a => SymVal [a] where
-  mkSymVal
-    | isKString @[a] undefined = genMkSymVar KString
-    | True                     = genMkSymVar (KList (kindOf (Proxy @a)))
-
-  literal as
-    | isKString @[a] undefined = case fromDynamic (toDyn as) of
-                                   Just s  -> SBV . SVal KString . Left . CV KString . CString $ s
-                                   Nothing -> error "SString: Cannot construct literal string!"
-    | True                     = let k = KList (kindOf (Proxy @a))
-                                 in SBV $ SVal k $ Left $ CV k $ CList $ map toCV as
-
-  fromCV (CV _ (CString a)) = fromMaybe (error "SString: Cannot extract a literal string!")
-                                        (fromDynamic (toDyn a))
-  fromCV (CV _ (CList a))   = fromCV . CV (kindOf (Proxy @a)) <$> a
-  fromCV c                  = error $ "SymVal.fromCV: Unexpected non-list value: " ++ show c
-
-  minMaxBound               = Nothing
-
-instance ValidFloat eb sb => HasKind (FloatingPoint eb sb) where
-  kindOf _ = KFP (intOfProxy (Proxy @eb)) (intOfProxy (Proxy @sb))
-
-instance ValidFloat eb sb => SymVal (FloatingPoint eb sb) where
-  mkSymVal                   = genMkSymVar (KFP (intOfProxy (Proxy @eb)) (intOfProxy (Proxy @sb)))
-  literal (FloatingPoint r)  = let k = KFP (intOfProxy (Proxy @eb)) (intOfProxy (Proxy @sb))
-                               in SBV $ SVal k $ Left $ CV k (CFP r)
-  fromCV  (CV _ (CFP r))     = FloatingPoint r
-  fromCV  c                  = error $ "SymVal.FPR: Unexpected non-arbitrary-precision value: " ++ show c
-  minMaxBound                = Nothing
-
--- | 'SymVal' instance for 'WordN'
-instance (KnownNat n, BVIsNonZero n) => SymVal (WordN n) where
-   literal  x = genLiteral  (kindOf x) x
-   mkSymVal   = genMkSymVar (kindOf (undefined :: WordN n))
-   fromCV     = genFromCV
-
--- | 'SymVal' instance for 'IntN'
-instance (KnownNat n, BVIsNonZero n) => SymVal (IntN n) where
-   literal  x = genLiteral  (kindOf x) x
-   mkSymVal   = genMkSymVar (kindOf (undefined :: IntN n))
-   fromCV     = genFromCV
-
-toCV :: SymVal a => a -> CVal
-toCV a = case literal a of
-           SBV (SVal _ (Left cv)) -> cvVal cv
-           _                      -> error "SymVal.toCV: Impossible happened, couldn't produce a concrete value"
-
-mkCVTup :: Int -> Kind -> [CVal] -> SBV a
-mkCVTup i k@(KTuple ks) cs
-  | lks == lcs && lks == i
-  = SBV $ SVal k $ Left $ CV k $ CTuple cs
-  | True
-  = error $ "SymVal.mkCVTup: Impossible happened. Malformed tuple received: " ++ show (i, k)
-   where lks = length ks
-         lcs = length cs
-mkCVTup i k _
-  = error $ "SymVal.mkCVTup: Impossible happened. Non-tuple received: " ++ show (i, k)
-
-fromCVTup :: Int -> CV -> [CV]
-fromCVTup i inp@(CV (KTuple ks) (CTuple cs))
-   | lks == lcs && lks == i
-   = zipWith CV ks cs
-   | True
-   = error $ "SymVal.fromCTup: Impossible happened. Malformed tuple received: " ++ show (i, inp)
-   where lks = length ks
-         lcs = length cs
-fromCVTup i inp = error $ "SymVal.fromCVTup: Impossible happened. Non-tuple received: " ++ show (i, inp)
-
-instance (SymVal a, SymVal b) => SymVal (Either a b) where
-  mkSymVal = genMkSymVar (kindOf (Proxy @(Either a b)))
-
-  literal s
-    | Left  a <- s = mk $ Left  (toCV a)
-    | Right b <- s = mk $ Right (toCV b)
-    where k  = kindOf (Proxy @(Either a b))
-
-          mk = SBV . SVal k . Left . CV k . CEither
-
-  fromCV (CV (KEither k1 _ ) (CEither (Left c)))  = Left  $ fromCV $ CV k1 c
-  fromCV (CV (KEither _  k2) (CEither (Right c))) = Right $ fromCV $ CV k2 c
-  fromCV bad                                      = error $ "SymVal.fromCV (Either): Malformed either received: " ++ show bad
-
-  minMaxBound = Nothing
-
-instance SymVal a => SymVal (Maybe a) where
-  mkSymVal = genMkSymVar (kindOf (Proxy @(Maybe a)))
-
-  literal s
-    | Nothing <- s = mk Nothing
-    | Just  a <- s = mk $ Just (toCV a)
-    where k = kindOf (Proxy @(Maybe a))
-
-          mk = SBV . SVal k . Left . CV k . CMaybe
-
-  fromCV (CV (KMaybe _) (CMaybe Nothing))  = Nothing
-  fromCV (CV (KMaybe k) (CMaybe (Just x))) = Just $ fromCV $ CV k x
-  fromCV bad                               = error $ "SymVal.fromCV (Maybe): Malformed sum received: " ++ show bad
-
-  minMaxBound = Nothing
-
-instance (HasKind a, HasKind b, SymVal a, SymVal b) => SymVal (ArrayModel a b) where
-  mkSymVal = genMkSymVar (KArray (kindOf (Proxy @a)) (kindOf (Proxy @b)))
-
-  -- If the table has duplicate entries for keys, then the first one takes precedence.
-  -- That is, [(a, v1), (a, v2)] is equivalent to [(a, v1)]. The best way to think about
-  -- this is as a "stack" of writes. [(a, v1), (a, v2)] means we first "wrote" v2 at
-  -- a, and then wrote v1 at the same address; so the first write of v2 got overwritten.
-  literal (ArrayModel tbl def) = SBV . SVal knd . Left . CV knd $ CArray $ ArrayModel [(toCV k, toCV v) | (k, v) <- tbl] (toCV def)
-    where knd = kindOf (Proxy @(ArrayModel a b))
-
-  fromCV (CV (KArray k1 k2) (CArray (ArrayModel assocs def))) = ArrayModel [(fromCV (CV k1 a), fromCV (CV k2 b)) | (a, b) <- assocs]
-                                                                           (fromCV (CV k2 def))
-
-  fromCV bad = error $ "SymVal.fromCV (SArray): Malformed array received: " ++ show bad
-
-  minMaxBound = Nothing
-
-instance (Arbitrary a, Arbitrary b) => Arbitrary (ArrayModel a b) where
-  arbitrary = ArrayModel <$> arbitrary <*> arbitrary
-
-instance (Ord a, SymVal a) => SymVal (RCSet a) where
-  mkSymVal = genMkSymVar (kindOf (Proxy @(RCSet a)))
-
-  literal eur = SBV $ SVal k $ Left $ CV k $ CSet $ dir $ Set.map toCV s
-    where (dir, s) = case eur of
-                      RegularSet x    -> (RegularSet,    x)
-                      ComplementSet x -> (ComplementSet, x)
-          k        = kindOf (Proxy @(RCSet a))
-
-  fromCV (CV (KSet a) (CSet (RegularSet    s))) = RegularSet    $ Set.map (fromCV . CV a) s
-  fromCV (CV (KSet a) (CSet (ComplementSet s))) = ComplementSet $ Set.map (fromCV . CV a) s
-  fromCV bad                                    = error $ "SymVal.fromCV (Set): Malformed set received: " ++ show bad
-
-  minMaxBound = Nothing
-
--- | SymVal for 0-tuple (i.e., unit)
-instance SymVal () where
-  mkSymVal   = genMkSymVar (KTuple [])
-  literal () = mkCVTup 0   (kindOf (Proxy @())) []
-  fromCV cv  = fromCVTup 0 cv `seq` ()
-
--- | SymVal for 2-tuples
-instance (SymVal a, SymVal b) => SymVal (a, b) where
-   mkSymVal         = genMkSymVar (kindOf (Proxy @(a, b)))
-   literal (v1, v2) = mkCVTup 2   (kindOf (Proxy @(a, b))) [toCV v1, toCV v2]
-   fromCV  cv       = let ~[v1, v2] = fromCVTup 2 cv
-                      in (fromCV v1, fromCV v2)
-
-   minMaxBound = Nothing
-
--- | SymVal for 3-tuples
-instance (SymVal a, SymVal b, SymVal c) => SymVal (a, b, c) where
-   mkSymVal             = genMkSymVar (kindOf (Proxy @(a, b, c)))
-   literal (v1, v2, v3) = mkCVTup 3   (kindOf (Proxy @(a, b, c))) [toCV v1, toCV v2, toCV v3]
-   fromCV  cv           = let ~[v1, v2, v3] = fromCVTup 3 cv
-                          in (fromCV v1, fromCV v2, fromCV v3)
-   minMaxBound          = Nothing
-
--- | SymVal for 4-tuples
-instance (SymVal a, SymVal b, SymVal c, SymVal d) => SymVal (a, b, c, d) where
-   mkSymVal                 = genMkSymVar (kindOf (Proxy @(a, b, c, d)))
-   literal (v1, v2, v3, v4) = mkCVTup 4   (kindOf (Proxy @(a, b, c, d))) [toCV v1, toCV v2, toCV v3, toCV v4]
-   fromCV  cv               = let ~[v1, v2, v3, v4] = fromCVTup 4 cv
-                              in (fromCV v1, fromCV v2, fromCV v3, fromCV v4)
-   minMaxBound              = Nothing
-
--- | SymVal for 5-tuples
-instance (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e) => SymVal (a, b, c, d, e) where
-   mkSymVal                     = genMkSymVar (kindOf (Proxy @(a, b, c, d, e)))
-   literal (v1, v2, v3, v4, v5) = mkCVTup 5   (kindOf (Proxy @(a, b, c, d, e))) [toCV v1, toCV v2, toCV v3, toCV v4, toCV v5]
-   fromCV  cv                   = let ~[v1, v2, v3, v4, v5] = fromCVTup 5 cv
-                                  in (fromCV v1, fromCV v2, fromCV v3, fromCV v4, fromCV v5)
-   minMaxBound                  = Nothing
-
--- | SymVal for 6-tuples
-instance (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, SymVal f) => SymVal (a, b, c, d, e, f) where
-   mkSymVal                         = genMkSymVar (kindOf (Proxy @(a, b, c, d, e, f)))
-   literal (v1, v2, v3, v4, v5, v6) = mkCVTup 6   (kindOf (Proxy @(a, b, c, d, e, f))) [toCV v1, toCV v2, toCV v3, toCV v4, toCV v5, toCV v6]
-   fromCV  cv                       = let ~[v1, v2, v3, v4, v5, v6] = fromCVTup 6 cv
-                                      in (fromCV v1, fromCV v2, fromCV v3, fromCV v4, fromCV v5, fromCV v6)
-   minMaxBound                      = Nothing
-
--- | SymVal for 7-tuples
-instance (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, SymVal f, SymVal g) => SymVal (a, b, c, d, e, f, g) where
-   mkSymVal                             = genMkSymVar (kindOf (Proxy @(a, b, c, d, e, f, g)))
-   literal (v1, v2, v3, v4, v5, v6, v7) = mkCVTup 7   (kindOf (Proxy @(a, b, c, d, e, f, g))) [toCV v1, toCV v2, toCV v3, toCV v4, toCV v5, toCV v6, toCV v7]
-   fromCV  cv                           = let ~[v1, v2, v3, v4, v5, v6, v7] = fromCVTup 7 cv
-                                          in (fromCV v1, fromCV v2, fromCV v3, fromCV v4, fromCV v5, fromCV v6, fromCV v7)
-   minMaxBound                          = Nothing
-
--- | SymVal for 8-tuples
-instance (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, SymVal f, SymVal g, SymVal h) => SymVal (a, b, c, d, e, f, g, h) where
-   mkSymVal                                 = genMkSymVar (kindOf (Proxy @(a, b, c, d, e, f, g, h)))
-   literal (v1, v2, v3, v4, v5, v6, v7, v8) = mkCVTup 8   (kindOf (Proxy @(a, b, c, d, e, f, g, h))) [toCV v1, toCV v2, toCV v3, toCV v4, toCV v5, toCV v6, toCV v7, toCV v8]
-   fromCV  cv                               = let ~[v1, v2, v3, v4, v5, v6, v7, v8] = fromCVTup 8 cv
-                                              in (fromCV v1, fromCV v2, fromCV v3, fromCV v4, fromCV v5, fromCV v6, fromCV v7, fromCV v8)
-   minMaxBound                              = Nothing
-
-instance IsString SString where
-  fromString = literal
-
-------------------------------------------------------------------------------------
--- * Smart constructors for creating symbolic values. These are not strictly
--- necessary, as they are mere aliases for 'symbolic' and 'symbolics', but
--- they nonetheless make programming easier.
-------------------------------------------------------------------------------------
-
--- | Generalization of 'Data.SBV.sBool'
-sBool :: MonadSymbolic m => String -> m SBool
-sBool = symbolic
-
--- | Generalization of 'Data.SBV.sBool_'
-sBool_ :: MonadSymbolic m => m SBool
-sBool_ = free_
-
--- | Generalization of 'Data.SBV.sBools'
-sBools :: MonadSymbolic m => [String] -> m [SBool]
-sBools = symbolics
-
--- | Generalization of 'Data.SBV.sWord8'
-sWord8 :: MonadSymbolic m => String -> m SWord8
-sWord8 = symbolic
-
--- | Generalization of 'Data.SBV.sWord8_'
-sWord8_ :: MonadSymbolic m => m SWord8
-sWord8_ = free_
-
--- | Generalization of 'Data.SBV.sWord8s'
-sWord8s :: MonadSymbolic m => [String] -> m [SWord8]
-sWord8s = symbolics
-
--- | Generalization of 'Data.SBV.sWord16'
-sWord16 :: MonadSymbolic m => String -> m SWord16
-sWord16 = symbolic
-
--- | Generalization of 'Data.SBV.sWord16_'
-sWord16_ :: MonadSymbolic m => m SWord16
-sWord16_ = free_
-
--- | Generalization of 'Data.SBV.sWord16s'
-sWord16s :: MonadSymbolic m => [String] -> m [SWord16]
-sWord16s = symbolics
-
--- | Generalization of 'Data.SBV.sWord32'
-sWord32 :: MonadSymbolic m => String -> m SWord32
-sWord32 = symbolic
-
--- | Generalization of 'Data.SBV.sWord32_'
-sWord32_ :: MonadSymbolic m => m SWord32
-sWord32_ = free_
-
--- | Generalization of 'Data.SBV.sWord32s'
-sWord32s :: MonadSymbolic m => [String] -> m [SWord32]
-sWord32s = symbolics
-
--- | Generalization of 'Data.SBV.sWord64'
-sWord64 :: MonadSymbolic m => String -> m SWord64
-sWord64 = symbolic
-
--- | Generalization of 'Data.SBV.sWord64_'
-sWord64_ :: MonadSymbolic m => m SWord64
-sWord64_ = free_
-
--- | Generalization of 'Data.SBV.sWord64s'
-sWord64s :: MonadSymbolic m => [String] -> m [SWord64]
-sWord64s = symbolics
-
--- | Generalization of 'Data.SBV.sInt8'
-sInt8 :: MonadSymbolic m => String -> m SInt8
-sInt8 = symbolic
-
--- | Generalization of 'Data.SBV.sInt8_'
-sInt8_ :: MonadSymbolic m => m SInt8
-sInt8_ = free_
-
--- | Generalization of 'Data.SBV.sInt8s'
-sInt8s :: MonadSymbolic m => [String] -> m [SInt8]
-sInt8s = symbolics
-
--- | Generalization of 'Data.SBV.sInt16'
-sInt16 :: MonadSymbolic m => String -> m SInt16
-sInt16 = symbolic
-
--- | Generalization of 'Data.SBV.sInt16_'
-sInt16_ :: MonadSymbolic m => m SInt16
-sInt16_ = free_
-
--- | Generalization of 'Data.SBV.sInt16s'
-sInt16s :: MonadSymbolic m => [String] -> m [SInt16]
-sInt16s = symbolics
-
--- | Generalization of 'Data.SBV.sInt32'
-sInt32 :: MonadSymbolic m => String -> m SInt32
-sInt32 = symbolic
-
--- | Generalization of 'Data.SBV.sInt32_'
-sInt32_ :: MonadSymbolic m => m SInt32
-sInt32_ = free_
-
--- | Generalization of 'Data.SBV.sInt32s'
-sInt32s :: MonadSymbolic m => [String] -> m [SInt32]
-sInt32s = symbolics
-
--- | Generalization of 'Data.SBV.sInt64'
-sInt64 :: MonadSymbolic m => String -> m SInt64
-sInt64 = symbolic
-
--- | Generalization of 'Data.SBV.sInt64_'
-sInt64_ :: MonadSymbolic m => m SInt64
-sInt64_ = free_
-
--- | Generalization of 'Data.SBV.sInt64s'
-sInt64s :: MonadSymbolic m => [String] -> m [SInt64]
-sInt64s = symbolics
-
--- | Generalization of 'Data.SBV.sInteger'
-sInteger:: MonadSymbolic m => String -> m SInteger
-sInteger = symbolic
-
--- | Generalization of 'Data.SBV.sInteger_'
-sInteger_:: MonadSymbolic m => m SInteger
-sInteger_ = free_
-
--- | Generalization of 'Data.SBV.sIntegers'
-sIntegers :: MonadSymbolic m => [String] -> m [SInteger]
-sIntegers = symbolics
-
--- | Generalization of 'Data.SBV.sReal'
-sReal:: MonadSymbolic m => String -> m SReal
-sReal = symbolic
-
--- | Generalization of 'Data.SBV.sReal_'
-sReal_:: MonadSymbolic m => m SReal
-sReal_ = free_
-
--- | Generalization of 'Data.SBV.sReals'
-sReals :: MonadSymbolic m => [String] -> m [SReal]
-sReals = symbolics
-
--- | Generalization of 'Data.SBV.sFloat'
-sFloat :: MonadSymbolic m => String -> m SFloat
-sFloat = symbolic
-
--- | Generalization of 'Data.SBV.sFloat_'
-sFloat_ :: MonadSymbolic m => m SFloat
-sFloat_ = free_
-
--- | Generalization of 'Data.SBV.sFloats'
-sFloats :: MonadSymbolic m => [String] -> m [SFloat]
-sFloats = symbolics
-
--- | Generalization of 'Data.SBV.sDouble'
-sDouble :: MonadSymbolic m => String -> m SDouble
-sDouble = symbolic
-
--- | Generalization of 'Data.SBV.sDouble_'
-sDouble_ :: MonadSymbolic m => m SDouble
-sDouble_ = free_
-
--- | Generalization of 'Data.SBV.sDoubles'
-sDoubles :: MonadSymbolic m => [String] -> m [SDouble]
-sDoubles = symbolics
-
--- | Generalization of 'Data.SBV.sFPHalf'
-sFPHalf :: String -> Symbolic SFPHalf
-sFPHalf = symbolic
-
--- | Generalization of 'Data.SBV.sFPHalf_'
-sFPHalf_ :: Symbolic SFPHalf
-sFPHalf_ = free_
-
--- | Generalization of 'Data.SBV.sFPHalfs'
-sFPHalfs :: [String] -> Symbolic [SFPHalf]
-sFPHalfs = symbolics
-
--- | Generalization of 'Data.SBV.sFPBFloat'
-sFPBFloat :: String -> Symbolic SFPBFloat
-sFPBFloat = symbolic
-
--- | Generalization of 'Data.SBV.sFPBFloat_'
-sFPBFloat_ :: Symbolic SFPBFloat
-sFPBFloat_ = free_
-
--- | Generalization of 'Data.SBV.sFPBFloats'
-sFPBFloats :: [String] -> Symbolic [SFPBFloat]
-sFPBFloats = symbolics
-
--- | Generalization of 'Data.SBV.sFPSingle'
-sFPSingle :: String -> Symbolic SFPSingle
-sFPSingle = symbolic
-
--- | Generalization of 'Data.SBV.sFPSingle_'
-sFPSingle_ :: Symbolic SFPSingle
-sFPSingle_ = free_
-
--- | Generalization of 'Data.SBV.sFPSingles'
-sFPSingles :: [String] -> Symbolic [SFPSingle]
-sFPSingles = symbolics
-
--- | Generalization of 'Data.SBV.sFPDouble'
-sFPDouble :: String -> Symbolic SFPDouble
-sFPDouble = symbolic
-
--- | Generalization of 'Data.SBV.sFPDouble_'
-sFPDouble_ :: Symbolic SFPDouble
-sFPDouble_ = free_
-
--- | Generalization of 'Data.SBV.sFPDoubles'
-sFPDoubles :: [String] -> Symbolic [SFPDouble]
-sFPDoubles = symbolics
-
--- | Generalization of 'Data.SBV.sFPQuad'
-sFPQuad :: String -> Symbolic SFPQuad
-sFPQuad = symbolic
-
--- | Generalization of 'Data.SBV.sFPQuad_'
-sFPQuad_ :: Symbolic SFPQuad
-sFPQuad_ = free_
-
--- | Generalization of 'Data.SBV.sFPQuads'
-sFPQuads :: [String] -> Symbolic [SFPQuad]
-sFPQuads = symbolics
-
--- | Generalization of 'Data.SBV.sFloatingPoint'
-sFloatingPoint :: ValidFloat eb sb => String -> Symbolic (SFloatingPoint eb sb)
-sFloatingPoint = symbolic
-
--- | Generalization of 'Data.SBV.sFloatingPoint_'
-sFloatingPoint_ :: ValidFloat eb sb => Symbolic (SFloatingPoint eb sb)
-sFloatingPoint_ = free_
-
--- | Generalization of 'Data.SBV.sFloatingPoints'
-sFloatingPoints :: ValidFloat eb sb => [String] -> Symbolic [SFloatingPoint eb sb]
-sFloatingPoints = symbolics
-
--- | Generalization of 'Data.SBV.sWord'
-sWord :: (KnownNat n, BVIsNonZero n) => MonadSymbolic m => String -> m (SWord n)
-sWord = symbolic
-
--- | Generalization of 'Data.SBV.sWord_'
-sWord_ :: (KnownNat n, BVIsNonZero n) => MonadSymbolic m => m (SWord n)
-sWord_ = free_
-
--- | Generalization of 'Data.SBV.sWord64s'
-sWords :: (KnownNat n, BVIsNonZero n) => MonadSymbolic m => [String] -> m [SWord n]
-sWords = symbolics
-
--- | Generalization of 'Data.SBV.sInt'
-sInt :: (KnownNat n, BVIsNonZero n) => MonadSymbolic m => String -> m (SInt n)
-sInt = symbolic
-
--- | Generalization of 'Data.SBV.sInt_'
-sInt_ :: (KnownNat n, BVIsNonZero n) => MonadSymbolic m => m (SInt n)
-sInt_ = free_
-
--- | Generalization of 'Data.SBV.sInts'
-sInts :: (KnownNat n, BVIsNonZero n) => MonadSymbolic m => [String] -> m [SInt n]
-sInts = symbolics
-
--- | Generalization of 'Data.SBV.sChar'
-sChar :: MonadSymbolic m => String -> m SChar
-sChar = symbolic
-
--- | Generalization of 'Data.SBV.sChar_'
-sChar_ :: MonadSymbolic m => m SChar
-sChar_ = free_
-
--- | Generalization of 'Data.SBV.sChars'
-sChars :: MonadSymbolic m => [String] -> m [SChar]
-sChars = symbolics
-
--- | Generalization of 'Data.SBV.sString'
-sString :: MonadSymbolic m => String -> m SString
-sString = symbolic
-
--- | Generalization of 'Data.SBV.sString_'
-sString_ :: MonadSymbolic m => m SString
-sString_ = free_
-
--- | Generalization of 'Data.SBV.sStrings'
-sStrings :: MonadSymbolic m => [String] -> m [SString]
-sStrings = symbolics
-
--- | Generalization of 'Data.SBV.sList'
-sList :: (SymVal a, MonadSymbolic m) => String -> m (SList a)
-sList = symbolic
-
--- | Generalization of 'Data.SBV.sList_'
-sList_ :: (SymVal a, MonadSymbolic m) => m (SList a)
-sList_ = free_
-
--- | Generalization of 'Data.SBV.sLists'
-sLists :: (SymVal a, MonadSymbolic m) => [String] -> m [SList a]
-sLists = symbolics
-
--- | Generalization of 'Data.SBV.sAray'
-sArray :: (SymVal a, SymVal b, MonadSymbolic m) => String -> m (SArray a b)
-sArray = symbolic
-
--- | Generalization of 'Data.SBV.sList_'
-sArray_ :: (SymVal a, SymVal b, MonadSymbolic m) => m (SArray a b)
-sArray_ = free_
-
--- | Generalization of 'Data.SBV.sLists'
-sArrays :: (SymVal a, SymVal b, MonadSymbolic m) => [String] -> m [SArray a b]
-sArrays = symbolics
-
--- | Identify tuple like things. Note that there are no methods, just instances to control type inference
-class SymTuple a
-instance SymTuple ()
-instance SymTuple (a, b)
-instance SymTuple (a, b, c)
-instance SymTuple (a, b, c, d)
-instance SymTuple (a, b, c, d, e)
-instance SymTuple (a, b, c, d, e, f)
-instance SymTuple (a, b, c, d, e, f, g)
-instance SymTuple (a, b, c, d, e, f, g, h)
-
--- | Generalization of 'Data.SBV.sTuple'
-sTuple :: (SymTuple tup, SymVal tup, MonadSymbolic m) => String -> m (SBV tup)
-sTuple = symbolic
-
--- | Generalization of 'Data.SBV.sTuple_'
-sTuple_ :: (SymTuple tup, SymVal tup, MonadSymbolic m) => m (SBV tup)
-sTuple_ = free_
-
--- | Generalization of 'Data.SBV.sTuples'
-sTuples :: (SymTuple tup, SymVal tup, MonadSymbolic m) => [String] -> m [SBV tup]
-sTuples = symbolics
-
--- | Generalization of 'Data.SBV.sRational'
-sRational :: MonadSymbolic m => String -> m SRational
-sRational = symbolic
-
--- | Generalization of 'Data.SBV.sRational_'
-sRational_ :: MonadSymbolic m => m SRational
-sRational_ = free_
-
--- | Generalization of 'Data.SBV.sRationals'
-sRationals :: MonadSymbolic m => [String] -> m [SRational]
-sRationals = symbolics
-
--- | Generalization of 'Data.SBV.sEither'
-sEither :: (SymVal a, SymVal b, MonadSymbolic m) => String -> m (SEither a b)
-sEither = symbolic
-
--- | Generalization of 'Data.SBV.sEither_'
-sEither_ :: (SymVal a, SymVal b, MonadSymbolic m) => m (SEither a b)
-sEither_ = free_
-
--- | Generalization of 'Data.SBV.sEithers'
-sEithers :: (SymVal a, SymVal b, MonadSymbolic m) => [String] -> m [SEither a b]
-sEithers = symbolics
-
--- | Generalization of 'Data.SBV.sMaybe'
-sMaybe :: (SymVal a, MonadSymbolic m) => String -> m (SMaybe a)
-sMaybe = symbolic
-
--- | Generalization of 'Data.SBV.sMaybe_'
-sMaybe_ :: (SymVal a, MonadSymbolic m) => m (SMaybe a)
-sMaybe_ = free_
-
--- | Generalization of 'Data.SBV.sMaybes'
-sMaybes :: (SymVal a, MonadSymbolic m) => [String] -> m [SMaybe a]
-sMaybes = symbolics
-
--- | Generalization of 'Data.SBV.sSet'
-sSet :: (Ord a, SymVal a, MonadSymbolic m) => String -> m (SSet a)
-sSet = symbolic
-
--- | Generalization of 'Data.SBV.sMaybe_'
-sSet_ :: (Ord a, SymVal a, MonadSymbolic m) => m (SSet a)
-sSet_ = free_
-
--- | Generalization of 'Data.SBV.sMaybes'
-sSets :: (Ord a, SymVal a, MonadSymbolic m) => [String] -> m [SSet a]
-sSets = symbolics
-
--- | Generalization of 'Data.SBV.solve'
-solve :: MonadSymbolic m => [SBool] -> m SBool
-solve = return . sAnd
-
--- | Convert an SReal to an SInteger. That is, it computes the
--- largest integer @n@ that satisfies @sIntegerToSReal n <= r@
--- essentially giving us the @floor@.
---
--- For instance, @1.3@ will be @1@, but @-1.3@ will be @-2@.
-sRealToSInteger :: SReal -> SInteger
-sRealToSInteger x
-  | Just i <- unliteral x, isExactRational i
-  = literal $ floor (toRational i)
-  | True
-  = SBV (SVal KUnbounded (Right (cache y)))
-  where y st = do xsv <- sbvToSV st x
-                  newExpr st KUnbounded (SBVApp (KindCast KReal KUnbounded) [xsv])
-
--- | Convert an SReal to an SInteger, truncating version.
-sRealToSIntegerTruncate :: SReal -> SInteger
-sRealToSIntegerTruncate x = ite (x .< 0) (sRealToSInteger x) (- (sRealToSInteger (- x)))
-
--- | label: Label the result of an expression. This is essentially a no-op, but useful as it generates a comment in the generated C/SMT-Lib code.
--- Note that if the argument is a constant, then the label is dropped completely, per the usual constant folding strategy. Compare this to 'observe'
--- which is good for printing counter-examples.
-label :: SymVal a => String -> SBV a -> SBV a
-label m x
-   | Just _ <- unliteral x = x
-   | True                  = SBV $ SVal k $ Right $ cache r
-  where k    = kindOf x
-        r st = do xsv <- sbvToSV st x
-                  newExpr st k (SBVApp (Label m) [xsv])
-
-
--- | Observe the value of an expression, if the given condition holds.  Such values are useful in model construction, as they are printed part of a satisfying model, or a
--- counter-example. The same works for quick-check as well. Useful when we want to see intermediate values, or expected/obtained
--- pairs in a particular run. Note that an observed expression is always symbolic, i.e., it won't be constant folded. Compare this to 'label'
--- which is used for putting a label in the generated SMTLib-C code.
---
--- NB. If the observed expression happens under a SBV-lambda expression, then it is silently ignored; since
--- there's no way to access the value of such a value.
-observeIf :: SymVal a => (a -> Bool) -> String -> SBV a -> SBV a
-observeIf cond m x
-  | Just bad <- checkObservableName m
-  = error bad
-  | True
-  = SBV $ SVal k $ Right $ cache r
-  where k = kindOf x
-        r st = do xsv <- sbvToSV st (label ("Observing: " ++ m) x)
-                  recordObservable st m (cond . fromCV) xsv
-                  return xsv
-
--- | Observe the value of an expression, unconditionally. See 'observeIf' for a generalized version.
-observe :: SymVal a => String -> SBV a -> SBV a
-observe = observeIf (const True)
-
--- | Symbolic Comparisons. Similar to 'Eq', we cannot implement Haskell's 'Ord' class
--- since there is no way to return an 'Ordering' value from a symbolic comparison.
--- Furthermore, 'OrdSymbolic' requires 'Mergeable' to implement if-then-else, for the
--- benefit of implementing symbolic versions of 'max' and 'min' functions.
-infix 4 .<, .<=, .>, .>=
-class (Mergeable a, EqSymbolic a) => OrdSymbolic a where
-  -- | Symbolic less than.
-  (.<)  :: a -> a -> SBool
-  -- | Symbolic less than or equal to.
-  (.<=) :: a -> a -> SBool
-  -- | Symbolic greater than.
-  (.>)  :: a -> a -> SBool
-  -- | Symbolic greater than or equal to.
-  (.>=) :: a -> a -> SBool
-  -- | Symbolic minimum.
-  smin  :: a -> a -> a
-  -- | Symbolic maximum.
-  smax  :: a -> a -> a
-  -- | Is the value within the allowed /inclusive/ range?
-  inRange    :: a -> (a, a) -> SBool
-
-  {-# MINIMAL (.<) #-}
-
-  a .<= b    = a .< b .|| a .== b
-  a .>  b    = b .<  a
-  a .>= b    = b .<= a
-
-  a `smin` b = ite (a .<= b) a b
-  a `smax` b = ite (a .<= b) b a
-
-  inRange x (y, z) = x .>= y .&& x .<= z
-
-
-{- We can't have a generic instance of the form:
-
-instance Eq a => EqSymbolic a where
-  x .== y = if x == y then true else sFalse
-
-even if we're willing to allow Flexible/undecidable instances..
-This is because if we allow this it would imply EqSymbolic (SBV a);
-since (SBV a) has to be Eq as it must be a Num. But this wouldn't be
-the right choice obviously; as the Eq instance is bogus for SBV
-for natural reasons..
--}
-
--- It is tempting to put in an @Eq a@ superclass here. But doing so
--- is complicated, as it requires all underlying types to have equality,
--- which is at best shaky for algebraic reals and sets. So, leave it out.
-instance (HasKind a, SymVal a) => EqSymbolic (SBV a) where
-  SBV x .== SBV y = SBV (svEqual x y)
-  SBV x ./= SBV y = SBV (svNotEqual x y)
-
-  SBV x .=== SBV y = SBV (svStrongEqual x y)
-
-  -- Custom version of distinct that generates better code for base types
-  distinct []                                             = sTrue
-  distinct [_]                                            = sTrue
-  distinct xs | all isConc xs                             = checkDiff xs
-              | [SBV a, SBV b] <- xs, a `is` svBool True  = SBV $ svNot b
-              | [SBV a, SBV b] <- xs, b `is` svBool True  = SBV $ svNot a
-              | [SBV a, SBV b] <- xs, a `is` svBool False = SBV b
-              | [SBV a, SBV b] <- xs, b `is` svBool False = SBV a
-              -- 3 booleans can't be distinct!
-              | (x : _ : _ : _) <- xs, isBool x           = sFalse
-              | True                                      = SBV (SVal KBool (Right (cache r)))
-    where r st = do xsv <- mapM (sbvToSV st) xs
-                    newExpr st KBool (SBVApp NotEqual xsv)
-
-          -- We call this in case all are concrete, which will
-          -- reduce to a constant and generate no code at all!
-          -- Note that this is essentially the same as the default
-          -- definition, which unfortunately we can no longer call!
-          checkDiff []     = sTrue
-          checkDiff (a:as) = sAll (a ./=) as .&& checkDiff as
-
-          -- Sigh, we can't use isConcrete since that requires SymVal
-          -- constraint that we don't have here. (To support SBools.)
-          isConc (SBV (SVal _ (Left _))) = True
-          isConc _                       = False
-
-          -- Likewise here; need to go lower.
-          SVal k1 (Left c1) `is` SVal k2 (Left c2) = (k1, c1) == (k2, c2)
-          _                 `is` _                 = False
-
-          isBool (SBV (SVal KBool _)) = True
-          isBool _                    = False
-
-  -- Custom version of distinctExcept that generates better code for base types
-  distinctExcept []  _       = sTrue
-  distinctExcept [_] _       = sTrue
-  distinctExcept es  ignored
-    | all isConc (es ++ ignored)
-    = distinct (filter ignoreConc es)
-    | True
-    = SBV (SVal KBool (Right (cache r)))
-    where ignoreConc x = case x `sElem` ignored of
-                           SBV (SVal KBool (Left cv)) -> cvToBool cv
-                           _                          -> error $ "distinctExcept: Impossible happened, concrete sElem failed: " ++ show (es, ignored, x)
-
-          r st = do let incr x table = ite (x `sElem` ignored) (0 :: SInteger) (1 + readArrayNoEq table x)
-
-                        initArray :: SArray a Integer
-                        initArray = lambdaArray (const 0)
-
-                        finalArray = foldl (\table x -> writeArrayNoKnd table x (incr x table)) initArray es
-
-                    sbvToSV st $ sAll (\e -> readArrayNoEq finalArray e .<= (1 :: SInteger)) es
-
-          -- Sigh, we can't use isConcrete since that requires SymVal
-          -- constraint that we don't have here. (To support SBools.)
-          isConc (SBV (SVal _ (Left _))) = True
-          isConc _                       = False
-
-          -- Version of readArray that doesn't have the Eq constraint, since we don't have it here
-          readArrayNoEq array key = SBV . SVal KUnbounded . Right $ cache g
-             where g st = do f <- sbvToSV st array
-                             k <- sbvToSV st key
-                             newExpr st KUnbounded (SBVApp ReadArray [f, k])
-
-          writeArrayNoKnd :: forall key. HasKind key => SArray key Integer -> SBV key -> SInteger -> SArray key Integer
-          writeArrayNoKnd array key value = SBV . SVal k . Right $ cache g
-              where k  = KArray (kindOf (Proxy @key)) KUnbounded
-
-                    g st = do arr    <- sbvToSV st array
-                              keyVal <- sbvToSV st key
-                              val    <- sbvToSV st value
-                              newExpr st k (SBVApp WriteArray [arr, keyVal, val])
-
--- We don't want to do a generic OrdSymbolic (SBV a) instance; since that would be dangerous, like the case
--- for Num. So, we explicitly define for each type we care about.
-
-#define MKSORD(CSTR, TYPE)                                                            \
-instance CSTR => OrdSymbolic TYPE where {                                             \
-  a@(SBV x) .<  b@(SBV y) | smtComparable "<"   a b = SBV (svLessThan x y)            \
-                          | True                    = SBV (svStructuralLessThan x y); \
-                                                                                      \
-  a@(SBV x) .<= b@(SBV y) | smtComparable ".<=" a b = SBV (svLessEq x y)              \
-                          | True                    = a .< b .|| a .== b;             \
-                                                                                      \
-  a@(SBV x) .>  b@(SBV y) | smtComparable ">"   a b = SBV (svGreaterThan x y)         \
-                          | True                    = b .< a;                         \
-                                                                                      \
-  a@(SBV x) .>= b@(SBV y) | smtComparable ">="  a b = SBV (svGreaterEq x y)           \
-                          | True                    = b .<= a;                        \
-}                                                                                     \
-
--- Derive basic instances we need. NB. We don't give the SRational instance here. It's handled
--- in Data/SBV/Rational due to representation issues.
-MKSORD((),                          SInteger)
-MKSORD((),                          SWord8)
-MKSORD((),                          SWord16)
-MKSORD((),                          SWord32)
-MKSORD((),                          SWord64)
-MKSORD((),                          SInt8)
-MKSORD((),                          SInt16)
-MKSORD((),                          SInt32)
-MKSORD((),                          SInt64)
-MKSORD((),                          SFloat)
-MKSORD((),                          SChar)
-MKSORD((SymVal a),                  (SMaybe  a))
-MKSORD((SymVal a),                  (SList   a))
-MKSORD((SymVal a, SymVal b),        (SEither a b))
-MKSORD((),                          SDouble)
-MKSORD((),                          SReal)
-MKSORD((KnownNat n, BVIsNonZero n), (SWord n))
-MKSORD((KnownNat n, BVIsNonZero n), (SInt  n))
-MKSORD((ValidFloat eb sb),          (SFloatingPoint eb sb))
-
--- Tuples
-MKSORD((SymVal a, SymVal b),                                                             (SBV (a, b)))
-MKSORD((SymVal a, SymVal b, SymVal c),                                                   (SBV (a, b, c)))
-MKSORD((SymVal a, SymVal b, SymVal c, SymVal d),                                         (SBV (a, b, c, d)))
-MKSORD((SymVal a, SymVal b, SymVal c, SymVal d, SymVal e),                               (SBV (a, b, c, d, e)))
-MKSORD((SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, SymVal f),                     (SBV (a, b, c, d, e, f)))
-MKSORD((SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, SymVal f, SymVal g),           (SBV (a, b, c, d, e, f, g)))
-MKSORD((SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, SymVal f, SymVal g, SymVal h), (SBV (a, b, c, d, e, f, g, h)))
-#undef MKSORD
-
--- Is this a type that's comparable by underlying translation to SMTLib?
--- Note that we allow concrete versions to go through unless the type is a set, as there's really no reason not to.
-smtComparable :: (SymVal a, HasKind a) => String -> SBV a -> SBV a -> Bool
-smtComparable op x y
-  | isConcrete x && isConcrete y && not (isSet k)
-  = True
-  | True
-  = case k of
-      KBool         -> True
-      KBounded   {} -> True
-      KUnbounded {} -> True
-      KReal      {} -> True
-      KUserSort  {} -> True
-      KFloat        -> True
-      KDouble       -> True
-      KRational  {} -> True
-      KFP        {} -> True
-      KChar         -> True
-      KString       -> True
-      KList      {} -> nope     -- Unfortunately, no way for us to desugar this
-      KSet       {} -> nope     -- Ditto here..
-      KTuple     {} -> False
-      KMaybe     {} -> False
-      KEither    {} -> False
-      KArray     {} -> True
- where k    = kindOf x
-       nope = error $ "Data.SBV.OrdSymbolic: SMTLib does not support " ++ op ++ " for " ++ show k
-
--- Bool
-instance EqSymbolic Bool where
-  x .== y = fromBool $ x == y
-
--- Lists
-instance EqSymbolic a => EqSymbolic [a] where
-  []     .==  []     = sTrue
-  (x:xs) .==  (y:ys) = x .== y .&& xs .== ys
-  _      .==  _      = sFalse
-
-  []     .=== []     = sTrue
-  (x:xs) .=== (y:ys) = x .=== y .&& xs .=== ys
-  _      .=== _      = sFalse
-
-instance OrdSymbolic a => OrdSymbolic [a] where
-  []     .< []     = sFalse
-  []     .< _      = sTrue
-  _      .< []     = sFalse
-  (x:xs) .< (y:ys) = x .< y .|| (x .== y .&& xs .< ys)
-
--- NonEmpty
-instance EqSymbolic a => EqSymbolic (NonEmpty a) where
-  (x :| xs) .==  (y :| ys) = x : xs .==  y : ys
-  (x :| xs) .=== (y :| ys) = x : xs .=== y : ys
-
-instance OrdSymbolic a => OrdSymbolic (NonEmpty a) where
-   (x :| xs) .< (y :| ys) = x : xs .< y : ys
-
--- Maybe
-instance EqSymbolic a => EqSymbolic (Maybe a) where
-  Nothing .== Nothing = sTrue
-  Just a  .== Just b  = a .== b
-  _       .== _       = sFalse
-
-instance OrdSymbolic a => OrdSymbolic (Maybe a) where
-  Nothing .<  Nothing = sFalse
-  Nothing .<  _       = sTrue
-  Just _  .<  Nothing = sFalse
-  Just a  .<  Just b  = a .< b
-
--- Either
-instance (EqSymbolic a, EqSymbolic b) => EqSymbolic (Either a b) where
-  Left a  .==  Left b  = a .== b
-  Right a .==  Right b = a .== b
-  _       .==  _       = sFalse
-
-  Left a  .=== Left b  = a .=== b
-  Right a .=== Right b = a .=== b
-  _       .=== _       = sFalse
-
-instance (OrdSymbolic a, OrdSymbolic b) => OrdSymbolic (Either a b) where
-  Left a  .< Left b  = a .< b
-  Left _  .< Right _ = sTrue
-  Right _ .< Left _  = sFalse
-  Right a .< Right b = a .< b
-
--- 2-Tuple
-instance (EqSymbolic a, EqSymbolic b) => EqSymbolic (a, b) where
-  (a0, b0) .==  (a1, b1) = a0 .==  a1 .&& b0 .==  b1
-  (a0, b0) .=== (a1, b1) = a0 .=== a1 .&& b0 .=== b1
-
-instance (OrdSymbolic a, OrdSymbolic b) => OrdSymbolic (a, b) where
-  (a0, b0) .< (a1, b1) = a0 .< a1 .|| (a0 .== a1 .&& b0 .< b1)
-
--- 3-Tuple
-instance (EqSymbolic a, EqSymbolic b, EqSymbolic c) => EqSymbolic (a, b, c) where
-  (a0, b0, c0) .==  (a1, b1, c1) = (a0, b0) .==  (a1, b1) .&& c0 .==  c1
-  (a0, b0, c0) .=== (a1, b1, c1) = (a0, b0) .=== (a1, b1) .&& c0 .=== c1
-
-instance (OrdSymbolic a, OrdSymbolic b, OrdSymbolic c) => OrdSymbolic (a, b, c) where
-  (a0, b0, c0) .< (a1, b1, c1) = (a0, b0) .< (a1, b1) .|| ((a0, b0) .== (a1, b1) .&& c0 .< c1)
-
--- 4-Tuple
-instance (EqSymbolic a, EqSymbolic b, EqSymbolic c, EqSymbolic d) => EqSymbolic (a, b, c, d) where
-  (a0, b0, c0, d0) .==  (a1, b1, c1, d1) = (a0, b0, c0) .==  (a1, b1, c1) .&& d0 .==  d1
-  (a0, b0, c0, d0) .=== (a1, b1, c1, d1) = (a0, b0, c0) .=== (a1, b1, c1) .&& d0 .=== d1
-
-instance (OrdSymbolic a, OrdSymbolic b, OrdSymbolic c, OrdSymbolic d) => OrdSymbolic (a, b, c, d) where
-  (a0, b0, c0, d0) .< (a1, b1, c1, d1) = (a0, b0, c0) .< (a1, b1, c1) .|| ((a0, b0, c0) .== (a1, b1, c1) .&& d0 .< d1)
-
--- 5-Tuple
-instance (EqSymbolic a, EqSymbolic b, EqSymbolic c, EqSymbolic d, EqSymbolic e) => EqSymbolic (a, b, c, d, e) where
-  (a0, b0, c0, d0, e0) .==  (a1, b1, c1, d1, e1) = (a0, b0, c0, d0) .==  (a1, b1, c1, d1) .&& e0 .==  e1
-  (a0, b0, c0, d0, e0) .=== (a1, b1, c1, d1, e1) = (a0, b0, c0, d0) .=== (a1, b1, c1, d1) .&& e0 .=== e1
-
-instance (OrdSymbolic a, OrdSymbolic b, OrdSymbolic c, OrdSymbolic d, OrdSymbolic e) => OrdSymbolic (a, b, c, d, e) where
-  (a0, b0, c0, d0, e0) .< (a1, b1, c1, d1, e1) = (a0, b0, c0, d0) .< (a1, b1, c1, d1) .|| ((a0, b0, c0, d0) .== (a1, b1, c1, d1) .&& e0 .< e1)
-
--- 6-Tuple
-instance (EqSymbolic a, EqSymbolic b, EqSymbolic c, EqSymbolic d, EqSymbolic e, EqSymbolic f) => EqSymbolic (a, b, c, d, e, f) where
-  (a0, b0, c0, d0, e0, f0) .==  (a1, b1, c1, d1, e1, f1) = (a0, b0, c0, d0, e0) .==  (a1, b1, c1, d1, e1) .&& f0 .==  f1
-  (a0, b0, c0, d0, e0, f0) .=== (a1, b1, c1, d1, e1, f1) = (a0, b0, c0, d0, e0) .=== (a1, b1, c1, d1, e1) .&& f0 .=== f1
-
-instance (OrdSymbolic a, OrdSymbolic b, OrdSymbolic c, OrdSymbolic d, OrdSymbolic e, OrdSymbolic f) => OrdSymbolic (a, b, c, d, e, f) where
-  (a0, b0, c0, d0, e0, f0) .< (a1, b1, c1, d1, e1, f1) =    (a0, b0, c0, d0, e0) .<  (a1, b1, c1, d1, e1)
-                                                       .|| ((a0, b0, c0, d0, e0) .== (a1, b1, c1, d1, e1) .&& f0 .< f1)
-
--- 7-Tuple
-instance (EqSymbolic a, EqSymbolic b, EqSymbolic c, EqSymbolic d, EqSymbolic e, EqSymbolic f, EqSymbolic g) => EqSymbolic (a, b, c, d, e, f, g) where
-  (a0, b0, c0, d0, e0, f0, g0) .==  (a1, b1, c1, d1, e1, f1, g1) = (a0, b0, c0, d0, e0, f0) .==  (a1, b1, c1, d1, e1, f1) .&& g0 .==  g1
-  (a0, b0, c0, d0, e0, f0, g0) .=== (a1, b1, c1, d1, e1, f1, g1) = (a0, b0, c0, d0, e0, f0) .=== (a1, b1, c1, d1, e1, f1) .&& g0 .=== g1
-
-instance (OrdSymbolic a, OrdSymbolic b, OrdSymbolic c, OrdSymbolic d, OrdSymbolic e, OrdSymbolic f, OrdSymbolic g) => OrdSymbolic (a, b, c, d, e, f, g) where
-  (a0, b0, c0, d0, e0, f0, g0) .< (a1, b1, c1, d1, e1, f1, g1) =    (a0, b0, c0, d0, e0, f0) .<  (a1, b1, c1, d1, e1, f1)
-                                                               .|| ((a0, b0, c0, d0, e0, f0) .== (a1, b1, c1, d1, e1, f1) .&& g0 .< g1)
-
--- | Regular expressions can be compared for equality. Note that we diverge here from the equality
--- in the concrete sense; i.e., the Eq instance does not match the symbolic case. This is a bit unfortunate,
--- but unavoidable with the current design of how we "distinguish" operators. Hopefully shouldn't be a big deal,
--- though one should be careful.
-instance EqSymbolic RegExp where
-  r1 .== r2 = SBV $ SVal KBool $ Right $ cache r
-    where r st = newExpr st KBool $ SBVApp (RegExOp (RegExEq r1 r2))  []
-
-  r1 ./= r2 = SBV $ SVal KBool $ Right $ cache r
-    where r st = newExpr st KBool $ SBVApp (RegExOp (RegExNEq r1 r2)) []
-
--- | Symbolic Numbers. This is a simple class that simply incorporates all number like
--- base types together, simplifying writing polymorphic type-signatures that work for all
--- symbolic numbers, such as 'SWord8', 'SInt8' etc. For instance, we can write a generic
--- list-minimum function as follows:
---
--- @
---    mm :: SIntegral a => [SBV a] -> SBV a
---    mm = foldr1 (\a b -> ite (a .<= b) a b)
--- @
---
--- It is similar to the standard 'Integral' class, except ranging over symbolic instances.
-class (SymVal a, Num a, Num (SBV a), Bits a, Integral a) => SIntegral a
-
--- 'SIntegral' Instances, skips Real/Float/Bool
-instance SIntegral Word8
-instance SIntegral Word16
-instance SIntegral Word32
-instance SIntegral Word64
-instance SIntegral Int8
-instance SIntegral Int16
-instance SIntegral Int32
-instance SIntegral Int64
-instance SIntegral Integer
-instance (KnownNat n, BVIsNonZero n) => SIntegral (WordN n)
-instance (KnownNat n, BVIsNonZero n) => SIntegral (IntN n)
-
--- | Zero extend a bit-vector.
-zeroExtend :: forall n m bv. ( KnownNat n, BVIsNonZero n, SymVal (bv n)
-                             , KnownNat m, BVIsNonZero m, SymVal (bv m)
-                             , n + 1 <= m
-                             , SIntegral (bv (m - n))
-                             , BVIsNonZero (m - n)
-                             ) => SBV (bv n)    -- ^ Input, of size @n@
-                               -> SBV (bv m)    -- ^ Output, of size @m@. @n < m@ must hold
-zeroExtend n = SBV $ svZeroExtend i (unSBV n)
-  where nv = intOfProxy (Proxy @n)
-        mv = intOfProxy (Proxy @m)
-        i  = fromIntegral (mv - nv)
-
--- | Sign extend a bit-vector.
-signExtend :: forall n m bv. ( KnownNat n, BVIsNonZero n, SymVal (bv n)
-                             , KnownNat m, BVIsNonZero m, SymVal (bv m)
-                             , n + 1 <= m
-                             , SFiniteBits (bv n)
-                             , SIntegral   (bv (m - n))
-                             , BVIsNonZero (m - n)
-                             ) => SBV (bv n)  -- ^ Input, of size @n@
-                               -> SBV (bv m)  -- ^ Output, of size @m@. @n < m@ must hold
-signExtend n = SBV $ svSignExtend i (unSBV n)
-  where nv = intOfProxy (Proxy @n)
-        mv = intOfProxy (Proxy @m)
-        i  = fromIntegral (mv - nv)
-
-
--- | Finite bit-length symbolic values. Essentially the same as 'SIntegral', but further leaves out 'Integer'. Loosely
--- based on Haskell's @FiniteBits@ class, but with more methods defined and structured differently to fit into the
--- symbolic world view. Minimal complete definition: 'sFiniteBitSize'.
-class (Ord a, SymVal a, Num a, Num (SBV a), OrdSymbolic (SBV a), Bits a) => SFiniteBits a where
-    -- | Bit size.
-    sFiniteBitSize      :: SBV a -> Int
-    -- | Least significant bit of a word, always stored at index 0.
-    lsb                 :: SBV a -> SBool
-    -- | Most significant bit of a word, always stored at the last position.
-    msb                 :: SBV a -> SBool
-    -- | Big-endian blasting of a word into its bits.
-    blastBE             :: SBV a -> [SBool]
-    -- | Little-endian blasting of a word into its bits.
-    blastLE             :: SBV a -> [SBool]
-    -- | Reconstruct from given bits, given in little-endian.
-    fromBitsBE          :: [SBool] -> SBV a
-    -- | Reconstruct from given bits, given in little-endian.
-    fromBitsLE          :: [SBool] -> SBV a
-    -- | Replacement for 'testBit', returning 'SBool' instead of 'Bool'.
-    sTestBit            :: SBV a -> Int -> SBool
-    -- | Variant of 'sTestBit', where we want to extract multiple bit positions.
-    sExtractBits        :: SBV a -> [Int] -> [SBool]
-    -- | Variant of 'popCount', returning a symbolic value.
-    sPopCount           :: SBV a -> SWord8
-    -- | A combo of 'setBit' and 'clearBit', when the bit to be set is symbolic.
-    setBitTo            :: SBV a -> Int -> SBool -> SBV a
-    -- | Variant of 'setBitTo' when the index is symbolic. If the index it out-of-bounds,
-    -- then the result is underspecified.
-    sSetBitTo           :: Integral a => SBV a -> SBV a -> SBool -> SBV a
-    -- | Full adder, returns carry-out from the addition. Only for unsigned quantities.
-    fullAdder           :: SBV a -> SBV a -> (SBool, SBV a)
-    -- | Full multiplier, returns both high and low-order bits. Only for unsigned quantities.
-    fullMultiplier      :: SBV a -> SBV a -> (SBV a, SBV a)
-    -- | Count leading zeros in a word, big-endian interpretation.
-    sCountLeadingZeros  :: SBV a -> SWord8
-    -- | Count trailing zeros in a word, big-endian interpretation.
-    sCountTrailingZeros :: SBV a -> SWord8
-
-    {-# MINIMAL sFiniteBitSize #-}
-
-    -- Default implementations
-    lsb (SBV v) = SBV (svTestBit v 0)
-    msb x       = sTestBit x (sFiniteBitSize x - 1)
-
-    blastBE   = reverse . blastLE
-    blastLE x = map (sTestBit x) [0 .. intSizeOf x - 1]
-
-    fromBitsBE = fromBitsLE . reverse
-    fromBitsLE bs
-       | length bs /= w
-       = error $ "SBV.SFiniteBits.fromBitsLE/BE: Expected: " ++ show w ++ " bits, received: " ++ show (length bs)
-       | True
-       = result
-       where w = sFiniteBitSize result
-             result = go 0 0 bs
-
-             go !acc _  []     = acc
-             go !acc !i (x:xs) = go (ite x (setBit acc i) acc) (i+1) xs
-
-    sTestBit (SBV x) i = SBV (svTestBit x i)
-    sExtractBits x     = map (sTestBit x)
-
-    -- NB. 'sPopCount' returns an 'SWord8', which can overflow when used on quantities that have
-    -- more than 255 bits. For the regular interface, this suffices for all types we support.
-    -- For the Dynamic interface, if we ever implement this, this will fail for bit-vectors
-    -- larger than that many bits. The alternative would be to return SInteger here, but that
-    -- seems a total overkill for most use cases. If such is required, users are encouraged
-    -- to define their own variants, which is rather easy.
-    sPopCount x
-      | Just v <- unliteral x = go 0 v
-      | True                  = sum [ite b 1 0 | b <- blastLE x]
-      where -- concrete case
-            go !c 0 = c
-            go !c w = go (c+1) (w .&. (w-1))
-
-    setBitTo x i b = ite b (setBit x i) (clearBit x i)
-
-    sSetBitTo x idx b
-      | Just i <- unliteral idx, Just index <- safe i
-      = setBitTo x index b
-      | True
-      = go x [0 .. sFiniteBitSize x - 1]
-      where -- paranoia check: make sure index can fit in an int
-            safe i = let asInteger   = toInteger i
-                         asInt       = fromIntegral asInteger
-                         backInteger = toInteger asInt
-                     in if backInteger == asInteger
-                        then Just asInt
-                        else Nothing
-
-            go v []     = v
-            go v (i:is) = go (ite (idx .== literal (fromIntegral i)) (setBitTo v (fromIntegral i) b) v) is
-
-    fullAdder a b
-      | isSigned a = error "fullAdder: only works on unsigned numbers"
-      | True       = (a .> s .|| b .> s, s)
-      where s = a + b
-
-    -- N.B. The higher-order bits are determined using a simple shift-add multiplier,
-    -- thus involving bit-blasting. It'd be naive to expect SMT solvers to deal efficiently
-    -- with properties involving this function, at least with the current state of the art.
-    fullMultiplier a b
-      | isSigned a = error "fullMultiplier: only works on unsigned numbers"
-      | True       = (go (sFiniteBitSize a) 0 a, a*b)
-      where go 0 p _ = p
-            go n p x = let (c, p')  = ite (lsb x) (fullAdder p b) (sFalse, p)
-                           (o, p'') = shiftIn c p'
-                           (_, x')  = shiftIn o x
-                       in go (n-1) p'' x'
-            shiftIn k v = (lsb v, mask .|. (v `shiftR` 1))
-               where mask = ite k (bit (sFiniteBitSize v - 1)) 0
-
-    -- See the note for 'sPopCount' for a comment on why we return 'SWord8'
-    sCountLeadingZeros x = fromIntegral m - go m
-      where m = sFiniteBitSize x - 1
-
-            -- NB. When i is 0 below, which happens when x is 0 as we count all the way down,
-            -- we return -1, which is equal to 2^n-1, giving us: n-1-(2^n-1) = n-2^n = n, as required, i.e., the bit-size.
-            go :: Int -> SWord8
-            go i | i < 0 = i8
-                 | True  = ite (sTestBit x i) i8 (go (i-1))
-               where i8 = literal (fromIntegral i :: Word8)
-
-    -- See the note for 'sPopCount' for a comment on why we return 'SWord8'
-    sCountTrailingZeros x = go 0
-       where m = sFiniteBitSize x
-
-             go :: Int -> SWord8
-             go i | i >= m = i8
-                  | True   = ite (sTestBit x i) i8 (go (i+1))
-                where i8 = literal (fromIntegral i :: Word8)
-
--- 'SFiniteBits' Instances, skips Real/Float/Bool/Integer
-instance SFiniteBits Word8  where sFiniteBitSize _ =  8
-instance SFiniteBits Word16 where sFiniteBitSize _ = 16
-instance SFiniteBits Word32 where sFiniteBitSize _ = 32
-instance SFiniteBits Word64 where sFiniteBitSize _ = 64
-instance SFiniteBits Int8   where sFiniteBitSize _ =  8
-instance SFiniteBits Int16  where sFiniteBitSize _ = 16
-instance SFiniteBits Int32  where sFiniteBitSize _ = 32
-instance SFiniteBits Int64  where sFiniteBitSize _ = 64
-instance (KnownNat n, BVIsNonZero n) => SFiniteBits (WordN n) where sFiniteBitSize _ = intOfProxy (Proxy @n)
-instance (KnownNat n, BVIsNonZero n) => SFiniteBits (IntN  n) where sFiniteBitSize _ = intOfProxy (Proxy @n)
-
--- | Returns 1 if the boolean is 'sTrue', otherwise 0.
-oneIf :: (Ord a, Num (SBV a), SymVal a) => SBool -> SBV a
-oneIf t = ite t 1 0
-
--- | Lift a pseudo-boolean op, performing checks
-liftPB :: String -> PBOp -> [SBool] -> SBool
-liftPB w o xs
-  | Just e <- check o
-  = error $ "SBV." ++ w ++ ": " ++ e
-  | True
-  = result
-  where check (PB_AtMost  k) = pos k
-        check (PB_AtLeast k) = pos k
-        check (PB_Exactly k) = pos k
-        check (PB_Le cs   k) = pos k `mplus` match cs
-        check (PB_Ge cs   k) = pos k `mplus` match cs
-        check (PB_Eq cs   k) = pos k `mplus` match cs
-
-        pos k
-          | k < 0 = Just $ "comparison value must be positive, received: " ++ show k
-          | True  = Nothing
-
-        match cs
-          | any (< 0) cs = Just $ "coefficients must be non-negative. Received: " ++ show cs
-          | lxs /= lcs   = Just $ "coefficient length must match number of arguments. Received: " ++ show (lcs, lxs)
-          | True         = Nothing
-          where lxs = length xs
-                lcs = length cs
-
-        result = SBV (SVal KBool (Right (cache r)))
-        r st   = do xsv <- mapM (sbvToSV st) xs
-                    -- PseudoBoolean's implicitly require support for integers, so make sure to register that kind!
-                    registerKind st KUnbounded
-                    newExpr st KBool (SBVApp (PseudoBoolean o) xsv)
-
--- | 'sTrue' if at most @k@ of the input arguments are 'sTrue'
-pbAtMost :: [SBool] -> Int -> SBool
-pbAtMost xs k
- | k < 0             = error $ "SBV.pbAtMost: Non-negative value required, received: " ++ show k
- | all isConcrete xs = literal $ sum (map (pbToInteger "pbAtMost" 1) xs) <= fromIntegral k
- | True              = liftPB "pbAtMost" (PB_AtMost k) xs
-
--- | 'sTrue' if at least @k@ of the input arguments are 'sTrue'
-pbAtLeast :: [SBool] -> Int -> SBool
-pbAtLeast xs k
- | k < 0             = error $ "SBV.pbAtLeast: Non-negative value required, received: " ++ show k
- | all isConcrete xs = literal $ sum (map (pbToInteger "pbAtLeast" 1) xs) >= fromIntegral k
- | True              = liftPB "pbAtLeast" (PB_AtLeast k) xs
-
--- | 'sTrue' if exactly @k@ of the input arguments are 'sTrue'
-pbExactly :: [SBool] -> Int -> SBool
-pbExactly xs k
- | k < 0             = error $ "SBV.pbExactly: Non-negative value required, received: " ++ show k
- | all isConcrete xs = literal $ sum (map (pbToInteger "pbExactly" 1) xs) == fromIntegral k
- | True              = liftPB "pbExactly" (PB_Exactly k) xs
-
--- | 'sTrue' if the sum of coefficients for 'sTrue' elements is at most @k@. Generalizes 'pbAtMost'.
-pbLe :: [(Int, SBool)] -> Int -> SBool
-pbLe xs k
- | k < 0                     = error $ "SBV.pbLe: Non-negative value required, received: " ++ show k
- | all (isConcrete . snd) xs = literal $ sum [pbToInteger "pbLe" c b | (c, b) <- xs] <= fromIntegral k
- | True                      = liftPB "pbLe" (PB_Le (map fst xs) k) (map snd xs)
-
--- | 'sTrue' if the sum of coefficients for 'sTrue' elements is at least @k@. Generalizes 'pbAtLeast'.
-pbGe :: [(Int, SBool)] -> Int -> SBool
-pbGe xs k
- | k < 0                     = error $ "SBV.pbGe: Non-negative value required, received: " ++ show k
- | all (isConcrete . snd) xs = literal $ sum [pbToInteger "pbGe" c b | (c, b) <- xs] >= fromIntegral k
- | True                      = liftPB "pbGe" (PB_Ge (map fst xs) k) (map snd xs)
-
--- | 'sTrue' if the sum of coefficients for 'sTrue' elements is exactly least @k@. Useful for coding
--- /exactly K-of-N/ constraints, and in particular mutex constraints.
-pbEq :: [(Int, SBool)] -> Int -> SBool
-pbEq xs k
- | k < 0                     = error $ "SBV.pbEq: Non-negative value required, received: " ++ show k
- | all (isConcrete . snd) xs = literal $ sum [pbToInteger "pbEq" c b | (c, b) <- xs] == fromIntegral k
- | True                      = liftPB "pbEq" (PB_Eq (map fst xs) k) (map snd xs)
-
--- | 'sTrue' if there is at most one set bit
-pbMutexed :: [SBool] -> SBool
-pbMutexed xs = pbAtMost xs 1
-
--- | 'sTrue' if there is exactly one set bit
-pbStronglyMutexed :: [SBool] -> SBool
-pbStronglyMutexed xs = pbExactly xs 1
-
--- | Convert a concrete pseudo-boolean to given int; converting to integer
-pbToInteger :: String -> Int -> SBool -> Integer
-pbToInteger w c b
- | c < 0                 = error $ "SBV." ++ w ++ ": Non-negative coefficient required, received: " ++ show c
- | Just v <- unliteral b = if v then fromIntegral c else 0
- | True                  = error $ "SBV.pbToInteger: Received a symbolic boolean: " ++ show (c, b)
-
--- | Predicate for optimizing word operations like (+) and (*).
-isConcreteZero :: SBV a -> Bool
-isConcreteZero (SBV (SVal _     (Left (CV _     (CInteger n))))) = n == 0
-isConcreteZero (SBV (SVal KReal (Left (CV KReal (CAlgReal v))))) = isExactRational v && v == 0
-isConcreteZero _                                                 = False
-
--- | Predicate for optimizing word operations like (+) and (*).
-isConcreteOne :: SBV a -> Bool
-isConcreteOne (SBV (SVal _     (Left (CV _     (CInteger 1))))) = True
-isConcreteOne (SBV (SVal KReal (Left (CV KReal (CAlgReal v))))) = isExactRational v && v == 1
-isConcreteOne _                                                 = False
-
--- | Symbolic exponentiation using bit blasting and repeated squaring.
---
--- N.B. The exponent must be unsigned/bounded if symbolic. Signed exponents will be rejected.
-(.^) :: (Mergeable b, Num b, SIntegral e) => b -> SBV e -> b
-b .^ e
-  | isConcrete e, Just (x :: Integer) <- unliteral (sFromIntegral e)
-  = if x >= 0 then let go n v
-                        | n == 0 = 1
-                        | even n =     go (n `div` 2) (v * v)
-                        | True   = v * go (n `div` 2) (v * v)
-                   in  go x b
-              else error $ "(.^): exponentiation: negative exponent: " ++ show x
-  | not (isBounded e) || isSigned e
-  = error $ "(.^): exponentiation only works with unsigned bounded symbolic exponents, kind: " ++ show (kindOf e)
-  | True
-  =  -- NB. We can't simply use sTestBit and blastLE since they have SFiniteBit requirement
-     -- but we want to have SIntegral here only.
-     let SBV expt = e
-         expBit i = SBV (svTestBit expt i)
-         blasted  = map expBit [0 .. intSizeOf e - 1]
-     in product $ zipWith (\use n -> ite use n 1)
-                          blasted
-                          (iterate (\x -> x*x) b)
-infixr 8 .^
-
-instance (Ord a, Num (SBV a), SymVal a, Fractional a) => Fractional (SBV a) where
-  fromRational  = literal . fromRational
-  SBV x / sy@(SBV y) | div0 = ite (sy .== 0) 0 res
-                     | True = res
-       where res  = SBV (svDivide x y)
-             -- Identify those kinds where we have a div-0 equals 0 exception
-             div0 = case kindOf sy of
-                      KFloat             -> False
-                      KDouble            -> False
-                      KFP{}              -> False
-                      KReal              -> True
-                      KRational          -> True
-                      -- Following cases should not happen since these types should *not* be instances of Fractional
-                      k@KBounded{}  -> error $ "Unexpected Fractional case for: " ++ show k
-                      k@KUnbounded  -> error $ "Unexpected Fractional case for: " ++ show k
-                      k@KBool       -> error $ "Unexpected Fractional case for: " ++ show k
-                      k@KString     -> error $ "Unexpected Fractional case for: " ++ show k
-                      k@KChar       -> error $ "Unexpected Fractional case for: " ++ show k
-                      k@KList{}     -> error $ "Unexpected Fractional case for: " ++ show k
-                      k@KSet{}      -> error $ "Unexpected Fractional case for: " ++ show k
-                      k@KUserSort{} -> error $ "Unexpected Fractional case for: " ++ show k
-                      k@KTuple{}    -> error $ "Unexpected Fractional case for: " ++ show k
-                      k@KMaybe{}    -> error $ "Unexpected Fractional case for: " ++ show k
-                      k@KEither{}   -> error $ "Unexpected Fractional case for: " ++ show k
-                      k@KArray{}    -> error $ "Unexpected Fractional case for: " ++ show k
-
--- | Define Floating instance on SBV's; only for base types that are already floating; i.e., 'SFloat', 'SDouble', and 'SReal'.
--- (See the separate definition below for 'SFloatingPoint'.)  Note that unless you use delta-sat via 'Data.SBV.Provers.dReal' on 'SReal', most
--- of the fields are "undefined" for symbolic values. We will add methods as they are supported by SMTLib. Currently, the
--- only symbolically available function in this class is 'sqrt' for 'SFloat', 'SDouble' and 'SFloatingPoint'.
-instance (Ord a, Num (SBV a), SymVal a, Fractional a, Floating a) => Floating (SBV a) where
-  pi      = fromRational . toRational $ (pi :: Double)
-  exp     = lift1FNS "exp"     exp
-  log     = lift1FNS "log"     log
-  sqrt    = lift1F   FP_Sqrt   sqrt
-  sin     = lift1FNS "sin"     sin
-  cos     = lift1FNS "cos"     cos
-  tan     = lift1FNS "tan"     tan
-  asin    = lift1FNS "asin"    asin
-  acos    = lift1FNS "acos"    acos
-  atan    = lift1FNS "atan"    atan
-  sinh    = lift1FNS "sinh"    sinh
-  cosh    = lift1FNS "cosh"    cosh
-  tanh    = lift1FNS "tanh"    tanh
-  asinh   = lift1FNS "asinh"   asinh
-  acosh   = lift1FNS "acosh"   acosh
-  atanh   = lift1FNS "atanh"   atanh
-  (**)    = lift2FNS "**"      (**)
-  logBase = lift2FNS "logBase" logBase
-
-unsupported :: String -> a
-unsupported w = error $ "Data.SBV.FloatingPoint: Unsupported operation: " ++ w ++ ". Please request this as a feature!"
-
--- | We give a specific instance for 'SFloatingPoint', because the underlying floating-point type doesn't support
--- fromRational directly. The overlap with the above instance is unfortunate.
-instance {-# OVERLAPPING #-} ValidFloat eb sb => Floating (SFloatingPoint eb sb) where
-  -- Try from double; if there's enough precision this'll work, otherwise will bail out.
-  pi
-   | ei > 11 || si > 53 = unsupported $ "Floating.SFloatingPoint.pi (not-enough-precision for " ++ show (ei, si) ++ ")"
-   | True               = literal $ FloatingPoint $ fpFromRational ei si (toRational (pi :: Double))
-   where ei = intOfProxy (Proxy @eb)
-         si = intOfProxy (Proxy @sb)
-
-  -- Likewise, exponentiation is again limited to precision of double
-  exp i
-   | ei > 11 || si > 53 = unsupported $ "Floating.SFloatingPoint.exp (not-enough-precision for " ++ show (ei, si) ++ ")"
-   | True               = literal e ** i
-   where ei = intOfProxy (Proxy @eb)
-         si = intOfProxy (Proxy @sb)
-         e  = FloatingPoint $ fpFromRational ei si (toRational (exp 1 :: Double))
-
-  log     = lift1FNS "log"     log
-  sqrt    = lift1F   FP_Sqrt   sqrt
-  sin     = lift1FNS "sin"     sin
-  cos     = lift1FNS "cos"     cos
-  tan     = lift1FNS "tan"     tan
-  asin    = lift1FNS "asin"    asin
-  acos    = lift1FNS "acos"    acos
-  atan    = lift1FNS "atan"    atan
-  sinh    = lift1FNS "sinh"    sinh
-  cosh    = lift1FNS "cosh"    cosh
-  tanh    = lift1FNS "tanh"    tanh
-  asinh   = lift1FNS "asinh"   asinh
-  acosh   = lift1FNS "acosh"   acosh
-  atanh   = lift1FNS "atanh"   atanh
-  (**)    = lift2FNS "**"      (**)
-  logBase = lift2FNS "logBase" logBase
-
--- | Lift a 1 arg FP-op, using sRNE default
-lift1F :: SymVal a => FPOp -> (a -> a) -> SBV a -> SBV a
-lift1F w op a
-  | Just v <- unliteral a
-  = literal $ op v
-  | True
-  = SBV $ SVal k $ Right $ cache r
-  where k    = kindOf a
-        r st = do swa  <- sbvToSV st a
-                  swm  <- sbvToSV st sRNE
-                  newExpr st k (SBVApp (IEEEFP w) [swm, swa])
-
--- | Lift a float/double unary function, only over constants
-lift1FNS :: (SymVal a, Floating a) => String -> (a -> a) -> SBV a -> SBV a
-lift1FNS nm f sv
-  | Just v <- unliteral sv = literal $ f v
-  | True                   = error $ "SBV." ++ nm ++ ": not supported for symbolic values of type " ++ show (kindOf sv)
-
--- | Lift a float/double binary function, only over constants
-lift2FNS :: (SymVal a, Floating a) => String -> (a -> a -> a) -> SBV a -> SBV a -> SBV a
-lift2FNS nm f sv1 sv2
-  | Just v1 <- unliteral sv1
-  , Just v2 <- unliteral sv2 = literal $ f v1 v2
-  | True                     = error $ "SBV." ++ nm ++ ": not supported for symbolic values of type " ++ show (kindOf sv1)
-
--- | SReal Floating instance, used in conjunction with the dReal solver for delta-satisfiability. Note that
--- we do not constant fold these values (except for pi), as Haskell doesn't really have any means of computing
--- them for arbitrary rationals.
-instance {-# OVERLAPPING #-} Floating SReal where
-  pi      = fromRational . toRational $ (pi :: Double)  -- Perhaps not good enough?
-  exp     = lift1SReal NR_Exp
-  log     = lift1SReal NR_Log
-  sqrt    = lift1SReal NR_Sqrt
-  sin     = lift1SReal NR_Sin
-  cos     = lift1SReal NR_Cos
-  tan     = lift1SReal NR_Tan
-  asin    = lift1SReal NR_ASin
-  acos    = lift1SReal NR_ACos
-  atan    = lift1SReal NR_ATan
-  sinh    = lift1SReal NR_Sinh
-  cosh    = lift1SReal NR_Cosh
-  tanh    = lift1SReal NR_Tanh
-  asinh   = error "Data.SBV.SReal: asinh is currently not supported. Please request this as a feature!"
-  acosh   = error "Data.SBV.SReal: acosh is currently not supported. Please request this as a feature!"
-  atanh   = error "Data.SBV.SReal: atanh is currently not supported. Please request this as a feature!"
-  (**)    = lift2SReal NR_Pow
-
-  logBase x y = log y  / log x
-
--- | Lift an sreal unary function
-lift1SReal :: NROp -> SReal -> SReal
-lift1SReal w a = SBV $ SVal k $ Right $ cache r
-  where k    = kindOf a
-        r st = do swa <- sbvToSV st a
-                  newExpr st k (SBVApp (NonLinear w) [swa])
-
--- | Lift an sreal binary function
-lift2SReal :: NROp -> SReal -> SReal -> SReal
-lift2SReal w a b = SBV $ SVal k $ Right $ cache r
-  where k    = kindOf a
-        r st = do swa <- sbvToSV st a
-                  swb <- sbvToSV st b
-                  newExpr st k (SBVApp (NonLinear w) [swa, swb])
-
--- Bail out nicely.
-noEquals :: String -> String -> (String, String) -> a
-noEquals o n (l, r) = error $ unlines [ ""
-                                      , "*** Data.SBV: Comparing symbolic values using Haskell's Eq class!"
-                                      , "***"
-                                      , "*** Received:    (" ++ l ++ ")  " ++ o ++ " (" ++ r ++ ")"
-                                      , "*** Instead use: (" ++ l ++ ") "  ++ n ++ " (" ++ r ++ ")"
-                                      , "***"
-                                      , "*** The Eq instance for symbolic values are necessiated only because"
-                                      , "*** of the Bits class requirement. You must use symbolic equality"
-                                      , "*** operators instead. (And complain to Haskell folks that they"
-                                      , "*** remove the 'Eq' superclass from 'Bits'!.)"
-                                      ]
-
--- | This instance is only defined so that we can define an instance for
--- 'Data.Bits.Bits'. '==' and '/=' simply throw an error. Use
--- 'Data.SBV.EqSymbolic' instead.
-instance SymVal a => Eq (SBV a) where
-  a == b = fromMaybe (noEquals "==" ".==" (show a, show b)) (unliteral (a .== b))
-  a /= b = fromMaybe (noEquals "/=" "./=" (show a, show b)) (unliteral (a ./= b))
-
--- NB. In the optimizations below, use of -1 is valid as
--- -1 has all bits set to True for both signed and unsigned values
--- | Using 'popCount' or 'testBit' on non-concrete values will result in an
--- error. Use 'sPopCount' or 'sTestBit' instead.
-instance (Ord a, Num (SBV a), Num a, Bits a, SymVal a) => Bits (SBV a) where
-  SBV x .&. SBV y    = SBV (svAnd x y)
-  SBV x .|. SBV y    = SBV (svOr x y)
-  SBV x `xor` SBV y  = SBV (svXOr x y)
-  complement (SBV x) = SBV (svNot x)
-  bitSize  x         = intSizeOf x
-  bitSizeMaybe x     = Just $ intSizeOf x
-  isSigned x         = hasSign x
-  bit i              = 1 `shiftL` i
-  setBit        x i  = x .|. genLiteral (kindOf x) (bit i :: Integer)
-  clearBit      x i  = x .&. genLiteral (kindOf x) (complement (bit i) :: Integer)
-  complementBit x i  = x `xor` genLiteral (kindOf x) (bit i :: Integer)
-  shiftL  (SBV x) i  = SBV (svShl x i)
-  shiftR  (SBV x) i  = SBV (svShr x i)
-  rotateL (SBV x) i  = SBV (svRol x i)
-  rotateR (SBV x) i  = SBV (svRor x i)
-  -- NB. testBit is *not* implementable on non-concrete symbolic words
-  x `testBit` i
-    | SBV (SVal _ (Left (CV _ (CInteger n)))) <- x
-    = testBit n i
-    | True
-    = error $ "SBV.testBit: Called on symbolic value: " ++ show x ++ ". Use sTestBit instead."
-  -- NB. popCount is *not* implementable on non-concrete symbolic words
-  popCount x
-    | SBV (SVal _ (Left (CV (KBounded _ w) (CInteger n)))) <- x
-    = popCount (n .&. (bit w - 1))
-    | True
-    = error $ "SBV.popCount: Called on symbolic value: " ++ show x ++ ". Use sPopCount instead."
-
--- | Conversion between integral-symbolic values, akin to Haskell's `fromIntegral`
-sFromIntegral :: forall a b. (Integral a, HasKind a, Num a, SymVal a, HasKind b, Num b, SymVal b) => SBV a -> SBV b
-sFromIntegral x
-  | kFrom == kTo
-  = SBV (unSBV x)
-  | isReal x
-  = error "SBV.sFromIntegral: Called on a real value" -- can't really happen due to types, but being overcautious
-  | Just v <- unliteral x
-  = literal (fromIntegral v)
-  | True
-  = result
-  where result = SBV (SVal kTo (Right (cache y)))
-        kFrom  = kindOf x
-        kTo    = kindOf (Proxy @b)
-        y st   = do xsv <- sbvToSV st x
-                    newExpr st kTo (SBVApp (KindCast kFrom kTo) [xsv])
-
--- | Lift a binary operation thru it's dynamic counterpart. Note that
--- we still want the actual functions here as differ in their type
--- compared to their dynamic counterparts, but the implementations
--- are the same.
-liftViaSVal :: (SVal -> SVal -> SVal) -> SBV a -> SBV b -> SBV c
-liftViaSVal f (SBV a) (SBV b) = SBV $ f a b
-
--- | Generalization of 'shiftL', when the shift-amount is symbolic. Since Haskell's
--- 'shiftL' only takes an 'Int' as the shift amount, it cannot be used when we have
--- a symbolic amount to shift with.
-sShiftLeft :: (SIntegral a, SIntegral b) => SBV a -> SBV b -> SBV a
-sShiftLeft = liftViaSVal svShiftLeft
-
--- | Generalization of 'shiftR', when the shift-amount is symbolic. Since Haskell's
--- 'shiftR' only takes an 'Int' as the shift amount, it cannot be used when we have
--- a symbolic amount to shift with.
---
--- NB. If the shiftee is signed, then this is an arithmetic shift; otherwise it's logical,
--- following the usual Haskell convention. See 'sSignedShiftArithRight' for a variant
--- that explicitly uses the msb as the sign bit, even for unsigned underlying types.
-sShiftRight :: (SIntegral a, SIntegral b) => SBV a -> SBV b -> SBV a
-sShiftRight = liftViaSVal svShiftRight
-
--- | Arithmetic shift-right with a symbolic unsigned shift amount. This is equivalent
--- to 'sShiftRight' when the argument is signed. However, if the argument is unsigned,
--- then it explicitly treats its msb as a sign-bit, and uses it as the bit that
--- gets shifted in. Useful when using the underlying unsigned bit representation to implement
--- custom signed operations. Note that there is no direct Haskell analogue of this function.
-sSignedShiftArithRight:: (SFiniteBits a, SIntegral b) => SBV a -> SBV b -> SBV a
-sSignedShiftArithRight x i
-  | isSigned i = error "sSignedShiftArithRight: shift amount should be unsigned"
-  | isSigned x = ssa x i
-  | True       = ite (msb x)
-                     (complement (ssa (complement x) i))
-                     (ssa x i)
-  where ssa = liftViaSVal svShiftRight
-
--- | Generalization of 'rotateL', when the shift-amount is symbolic. Since Haskell's
--- 'rotateL' only takes an 'Int' as the shift amount, it cannot be used when we have
--- a symbolic amount to shift with. The first argument should be a bounded quantity.
-sRotateLeft :: (SIntegral a, SIntegral b) => SBV a -> SBV b -> SBV a
-sRotateLeft = liftViaSVal svRotateLeft
-
--- | An implementation of rotate-left, using a barrel shifter like design. Only works when both
--- arguments are finite bitvectors, and furthermore when the second argument is unsigned.
--- The first condition is enforced by the type, but the second is dynamically checked.
--- We provide this implementation as an alternative to `sRotateLeft` since SMTLib logic
--- does not support variable argument rotates (as opposed to shifts), and thus this
--- implementation can produce better code for verification compared to `sRotateLeft`.
-sBarrelRotateLeft :: (SFiniteBits a, SFiniteBits b) => SBV a -> SBV b -> SBV a
-sBarrelRotateLeft = liftViaSVal svBarrelRotateLeft
-
--- | Generalization of 'rotateR', when the shift-amount is symbolic. Since Haskell's
--- 'rotateR' only takes an 'Int' as the shift amount, it cannot be used when we have
--- a symbolic amount to shift with. The first argument should be a bounded quantity.
-sRotateRight :: (SIntegral a, SIntegral b) => SBV a -> SBV b -> SBV a
-sRotateRight = liftViaSVal svRotateRight
-
--- | An implementation of rotate-right, using a barrel shifter like design. See comments
--- for `sBarrelRotateLeft` for details.
-sBarrelRotateRight :: (SFiniteBits a, SFiniteBits b) => SBV a -> SBV b -> SBV a
-sBarrelRotateRight = liftViaSVal svBarrelRotateRight
-
--- | Capturing non-matching instances for better error messages, conversions from sized
-type FromSizedErr (arg :: Type) =     'Text "fromSized: Cannot convert from type: " ':<>: 'ShowType arg
-                                ':$$: 'Text "           Source type must be one of SInt N, SWord N, IntN N, WordN N"
-                                ':$$: 'Text "           where N is 8, 16, 32, or 64."
-
--- | Capturing non-matching instances for better error messages, conversions to sized
-type ToSizedErr (arg :: Type) =      'Text "toSized: Cannot convert from type: " ':<>: 'ShowType arg
-                              ':$$: 'Text "          Source type must be one of Int8/16/32/64"
-                              ':$$: 'Text "                                  OR Word8/16/32/64"
-                              ':$$: 'Text "                                  OR their symbolic variants."
-
--- | Capture the correspondence between sized and fixed-sized BVs
-type family FromSized (t :: Type) :: Type where
-   FromSized (WordN  8) = Word8
-   FromSized (WordN 16) = Word16
-   FromSized (WordN 32) = Word32
-   FromSized (WordN 64) = Word64
-   FromSized (IntN   8) = Int8
-   FromSized (IntN  16) = Int16
-   FromSized (IntN  32) = Int32
-   FromSized (IntN  64) = Int64
-   FromSized (SWord  8) = SWord8
-   FromSized (SWord 16) = SWord16
-   FromSized (SWord 32) = SWord32
-   FromSized (SWord 64) = SWord64
-   FromSized (SInt   8) = SInt8
-   FromSized (SInt  16) = SInt16
-   FromSized (SInt  32) = SInt32
-   FromSized (SInt  64) = SInt64
-
--- | Capture the correspondence, in terms of a constraint
-type family FromSizedCstr (t :: Type) :: Constraint where
-   FromSizedCstr (WordN  8) = ()
-   FromSizedCstr (WordN 16) = ()
-   FromSizedCstr (WordN 32) = ()
-   FromSizedCstr (WordN 64) = ()
-   FromSizedCstr (IntN   8) = ()
-   FromSizedCstr (IntN  16) = ()
-   FromSizedCstr (IntN  32) = ()
-   FromSizedCstr (IntN  64) = ()
-   FromSizedCstr (SWord  8) = ()
-   FromSizedCstr (SWord 16) = ()
-   FromSizedCstr (SWord 32) = ()
-   FromSizedCstr (SWord 64) = ()
-   FromSizedCstr (SInt   8) = ()
-   FromSizedCstr (SInt  16) = ()
-   FromSizedCstr (SInt  32) = ()
-   FromSizedCstr (SInt  64) = ()
-   FromSizedCstr arg        = TypeError (FromSizedErr arg)
-
--- | Conversion from a sized BV to a fixed-sized bit-vector.
-class FromSizedBV a where
-   -- | Convert a sized bit-vector to the corresponding fixed-sized bit-vector,
-   -- for instance 'SWord 16' to 'SWord16'. See also 'toSized'.
-   fromSized :: a -> FromSized a
-
-   default fromSized :: (Num (FromSized a), Integral a) => a -> FromSized a
-   fromSized = fromIntegral
-
-instance {-# OVERLAPPING  #-} FromSizedBV (WordN   8)
-instance {-# OVERLAPPING  #-} FromSizedBV (WordN  16)
-instance {-# OVERLAPPING  #-} FromSizedBV (WordN  32)
-instance {-# OVERLAPPING  #-} FromSizedBV (WordN  64)
-instance {-# OVERLAPPING  #-} FromSizedBV (IntN    8)
-instance {-# OVERLAPPING  #-} FromSizedBV (IntN   16)
-instance {-# OVERLAPPING  #-} FromSizedBV (IntN   32)
-instance {-# OVERLAPPING  #-} FromSizedBV (IntN   64)
-instance {-# OVERLAPPING  #-} FromSizedBV (SWord   8) where fromSized = sFromIntegral
-instance {-# OVERLAPPING  #-} FromSizedBV (SWord  16) where fromSized = sFromIntegral
-instance {-# OVERLAPPING  #-} FromSizedBV (SWord  32) where fromSized = sFromIntegral
-instance {-# OVERLAPPING  #-} FromSizedBV (SWord  64) where fromSized = sFromIntegral
-instance {-# OVERLAPPING  #-} FromSizedBV (SInt    8) where fromSized = sFromIntegral
-instance {-# OVERLAPPING  #-} FromSizedBV (SInt   16) where fromSized = sFromIntegral
-instance {-# OVERLAPPING  #-} FromSizedBV (SInt   32) where fromSized = sFromIntegral
-instance {-# OVERLAPPING  #-} FromSizedBV (SInt   64) where fromSized = sFromIntegral
-instance {-# OVERLAPPABLE #-} FromSizedCstr arg => FromSizedBV arg where fromSized = error "unreachable"
-
--- | Capture the correspondence between fixed-sized and sized BVs
-type family ToSized (t :: Type) :: Type where
-   ToSized Word8   = WordN  8
-   ToSized Word16  = WordN 16
-   ToSized Word32  = WordN 32
-   ToSized Word64  = WordN 64
-   ToSized Int8    = IntN   8
-   ToSized Int16   = IntN  16
-   ToSized Int32   = IntN  32
-   ToSized Int64   = IntN  64
-   ToSized SWord8  = SWord  8
-   ToSized SWord16 = SWord 16
-   ToSized SWord32 = SWord 32
-   ToSized SWord64 = SWord 64
-   ToSized SInt8   = SInt   8
-   ToSized SInt16  = SInt  16
-   ToSized SInt32  = SInt  32
-   ToSized SInt64  = SInt  64
-
--- | Capture the correspondence in terms of a constraint
-type family ToSizedCstr (t :: Type) :: Constraint where
-   ToSizedCstr Word8   = ()
-   ToSizedCstr Word16  = ()
-   ToSizedCstr Word32  = ()
-   ToSizedCstr Word64  = ()
-   ToSizedCstr Int8    = ()
-   ToSizedCstr Int16   = ()
-   ToSizedCstr Int32   = ()
-   ToSizedCstr Int64   = ()
-   ToSizedCstr SWord8  = ()
-   ToSizedCstr SWord16 = ()
-   ToSizedCstr SWord32 = ()
-   ToSizedCstr SWord64 = ()
-   ToSizedCstr SInt8   = ()
-   ToSizedCstr SInt16  = ()
-   ToSizedCstr SInt32  = ()
-   ToSizedCstr SInt64  = ()
-   ToSizedCstr arg     = TypeError (ToSizedErr arg)
-
--- | Conversion from a fixed-sized BV to a sized bit-vector.
-class ToSizedBV a where
-   -- | Convert a fixed-sized bit-vector to the corresponding sized bit-vector,
-   -- for instance 'SWord16' to 'SWord 16'. See also 'fromSized'.
-   toSized :: a -> ToSized a
-
-   default toSized :: (Num (ToSized a), Integral a) => (a -> ToSized a)
-   toSized = fromIntegral
-
-instance {-# OVERLAPPING  #-} ToSizedBV Word8
-instance {-# OVERLAPPING  #-} ToSizedBV Word16
-instance {-# OVERLAPPING  #-} ToSizedBV Word32
-instance {-# OVERLAPPING  #-} ToSizedBV Word64
-instance {-# OVERLAPPING  #-} ToSizedBV Int8
-instance {-# OVERLAPPING  #-} ToSizedBV Int16
-instance {-# OVERLAPPING  #-} ToSizedBV Int32
-instance {-# OVERLAPPING  #-} ToSizedBV Int64
-instance {-# OVERLAPPING  #-} ToSizedBV SWord8  where toSized = sFromIntegral
-instance {-# OVERLAPPING  #-} ToSizedBV SWord16 where toSized = sFromIntegral
-instance {-# OVERLAPPING  #-} ToSizedBV SWord32 where toSized = sFromIntegral
-instance {-# OVERLAPPING  #-} ToSizedBV SWord64 where toSized = sFromIntegral
-instance {-# OVERLAPPING  #-} ToSizedBV SInt8   where toSized = sFromIntegral
-instance {-# OVERLAPPING  #-} ToSizedBV SInt16  where toSized = sFromIntegral
-instance {-# OVERLAPPING  #-} ToSizedBV SInt32  where toSized = sFromIntegral
-instance {-# OVERLAPPING  #-} ToSizedBV SInt64  where toSized = sFromIntegral
-instance {-# OVERLAPPABLE #-} ToSizedCstr arg => ToSizedBV arg where toSized = error "unreachable"
-
--- | The 'SDivisible' class captures the essence of division.
--- Unfortunately we cannot use Haskell's 'Integral' class since the 'Real'
--- and 'Enum' superclasses are not implementable for symbolic bit-vectors.
--- However, 'quotRem' and 'divMod' both make perfect sense, and the 'SDivisible' class captures
--- this operation. One issue is how division by 0 behaves. The verification
--- technology requires total functions, and there are several design choices
--- here. We follow Isabelle/HOL approach of assigning the value 0 for division
--- by 0. Therefore, we impose the following pair of laws:
---
--- @
---      x `sQuotRem` 0 = (0, x)
---      x `sDivMod`  0 = (0, x)
--- @
---
--- Note that our instances implement this law even when @x@ is @0@ itself.
---
--- NB. 'quot' truncates toward zero, while 'div' truncates toward negative infinity.
---
--- === C code generation of division operations
---
--- In the case of division or modulo of a minimal signed value (e.g. @-128@ for
--- 'SInt8') by @-1@, SMTLIB and Haskell agree on what the result should be.
--- Unfortunately the result in C code depends on CPU architecture and compiler
--- settings, as this is undefined behaviour in C.  **SBV does not guarantee**
--- what will happen in generated C code in this corner case.
-class SDivisible a where
-  sQuotRem :: a -> a -> (a, a)
-  sDivMod  :: a -> a -> (a, a)
-  sQuot    :: a -> a -> a
-  sRem     :: a -> a -> a
-  sDiv     :: a -> a -> a
-  sMod     :: a -> a -> a
-
-  {-# MINIMAL sQuotRem, sDivMod #-}
-
-  x `sQuot` y = fst $ x `sQuotRem` y
-  x `sRem`  y = snd $ x `sQuotRem` y
-  x `sDiv`  y = fst $ x `sDivMod`  y
-  x `sMod`  y = snd $ x `sDivMod`  y
-
-instance SDivisible Word64 where
-  sQuotRem x 0 = (0, x)
-  sQuotRem x y = x `quotRem` y
-  sDivMod  x 0 = (0, x)
-  sDivMod  x y = x `divMod` y
-
-instance SDivisible Int64 where
-  sQuotRem x 0 = (0, x)
-  sQuotRem x y = x `quotRem` y
-  sDivMod  x 0 = (0, x)
-  sDivMod  x y = x `divMod` y
-
-instance SDivisible Word32 where
-  sQuotRem x 0 = (0, x)
-  sQuotRem x y = x `quotRem` y
-  sDivMod  x 0 = (0, x)
-  sDivMod  x y = x `divMod` y
-
-instance SDivisible Int32 where
-  sQuotRem x 0 = (0, x)
-  sQuotRem x y = x `quotRem` y
-  sDivMod  x 0 = (0, x)
-  sDivMod  x y = x `divMod` y
-
-instance SDivisible Word16 where
-  sQuotRem x 0 = (0, x)
-  sQuotRem x y = x `quotRem` y
-  sDivMod  x 0 = (0, x)
-  sDivMod  x y = x `divMod` y
-
-instance SDivisible Int16 where
-  sQuotRem x 0 = (0, x)
-  sQuotRem x y = x `quotRem` y
-  sDivMod  x 0 = (0, x)
-  sDivMod  x y = x `divMod` y
-
-instance SDivisible Word8 where
-  sQuotRem x 0 = (0, x)
-  sQuotRem x y = x `quotRem` y
-  sDivMod  x 0 = (0, x)
-  sDivMod  x y = x `divMod` y
-
-instance SDivisible Int8 where
-  sQuotRem x 0 = (0, x)
-  sQuotRem x y = x `quotRem` y
-  sDivMod  x 0 = (0, x)
-  sDivMod  x y = x `divMod` y
-
-instance SDivisible Integer where
-  sQuotRem x 0 = (0, x)
-  sQuotRem x y = x `quotRem` y
-  sDivMod  x 0 = (0, x)
-  sDivMod  x y = x `divMod` y
-
-instance SDivisible CV where
-  sQuotRem a b
-    | CInteger x <- cvVal a, CInteger y <- cvVal b
-    = let (r1, r2) = sQuotRem x y in (normCV a{ cvVal = CInteger r1 }, normCV b{ cvVal = CInteger r2 })
-  sQuotRem a b = error $ "SBV.sQuotRem: impossible, unexpected args received: " ++ show (a, b)
-  sDivMod a b
-    | CInteger x <- cvVal a, CInteger y <- cvVal b
-    = let (r1, r2) = sDivMod x y in (normCV a{ cvVal = CInteger r1 }, normCV b{ cvVal = CInteger r2 })
-  sDivMod a b = error $ "SBV.sDivMod: impossible, unexpected args received: " ++ show (a, b)
-
-instance SDivisible SWord64 where {sQuotRem = liftQRem; sDivMod  = liftDMod}
-instance SDivisible SWord32 where {sQuotRem = liftQRem; sDivMod  = liftDMod}
-instance SDivisible SWord16 where {sQuotRem = liftQRem; sDivMod  = liftDMod}
-instance SDivisible SWord8  where {sQuotRem = liftQRem; sDivMod  = liftDMod}
-instance SDivisible SInt64  where {sQuotRem = liftQRem; sDivMod  = liftDMod}
-instance SDivisible SInt32  where {sQuotRem = liftQRem; sDivMod  = liftDMod}
-instance SDivisible SInt16  where {sQuotRem = liftQRem; sDivMod  = liftDMod}
-instance SDivisible SInt8   where {sQuotRem = liftQRem; sDivMod  = liftDMod}
-
--- | 'SDivisible' instance for 'WordN'
-instance (KnownNat n, BVIsNonZero n) => SDivisible (WordN n) where
-  sQuotRem x 0 = (0, x)
-  sQuotRem x y = x `quotRem` y
-  sDivMod  x 0 = (0, x)
-  sDivMod  x y = x `divMod` y
-
--- | 'SDivisible' instance for 'IntN'
-instance (KnownNat n, BVIsNonZero n) => SDivisible (IntN n) where
-  sQuotRem x 0 = (0, x)
-  sQuotRem x y = x `quotRem` y
-  sDivMod  x 0 = (0, x)
-  sDivMod  x y = x `divMod` y
-
--- | 'SDivisible' instance for 'SWord'
-instance (KnownNat n, BVIsNonZero n) => SDivisible (SWord n) where
-  sQuotRem = liftQRem
-  sDivMod  = liftDMod
-
--- | 'SDivisible' instance for 'SInt'
-instance (KnownNat n, BVIsNonZero n) => SDivisible (SInt n) where
-  sQuotRem = liftQRem
-  sDivMod  = liftDMod
-
--- | Does the concrete positive number n divide the given integer?
-sDivides :: Integer -> SInteger -> SBool
-sDivides n v
-  | n < 0
-  = error $ "svDivides: First argument must be a strictly positive integer. Received: " ++ show n
-  | Just x <- unliteral v
-  = if x `mod` n == 0 then sTrue else sFalse
-  | True
-  = SBV $ svDivides n (unSBV v)
-
--- | Lift 'quotRem' to symbolic words. Division by 0 is defined s.t. @x/0 = 0@; which
--- holds even when @x@ is @0@ itself.
-liftQRem :: (Eq a, SymVal a) => SBV a -> SBV a -> (SBV a, SBV a)
-liftQRem x y
-  | isConcreteZero x
-  = (x, x)
-  | isConcreteOne y
-  = (x, z)
-{-------------------------------
- - N.B. The seemingly innocuous variant when y == -1 only holds if the type is signed;
- - and also is problematic around the minBound.. So, we refrain from that optimization
-  | isConcreteOnes y
-  = (-x, z)
---------------------------------}
-  | True
-  = ite (y .== z) (z, x) (qr x y)
-  where qr (SBV (SVal sgnsz (Left a))) (SBV (SVal _ (Left b))) = let (q, r) = sQuotRem a b in (SBV (SVal sgnsz (Left q)), SBV (SVal sgnsz (Left r)))
-        qr a@(SBV (SVal sgnsz _))      b                       = (SBV (SVal sgnsz (Right (cache (mk Quot)))), SBV (SVal sgnsz (Right (cache (mk Rem)))))
-                where mk o st = do sw1 <- sbvToSV st a
-                                   sw2 <- sbvToSV st b
-                                   mkSymOp o st sgnsz sw1 sw2
-        z = genLiteral (kindOf x) (0::Integer)
-
--- | Lift 'divMod' to symbolic words. Division by 0 is defined s.t. @x/0 = 0@; which
--- holds even when @x@ is @0@ itself. Essentially, this is conversion from quotRem
--- (truncate to 0) to divMod (truncate towards negative infinity)
-liftDMod :: (Ord a, SymVal a, Num a, Num (SBV a), SDivisible (SBV a)) => SBV a -> SBV a -> (SBV a, SBV a)
-liftDMod x y
-  | isConcreteZero x
-  = (x, x)
-  | isConcreteOne y
-  = (x, z)
-{-------------------------------
- - N.B. The seemingly innocuous variant when y == -1 only holds if the type is signed;
- - and also is problematic around the minBound.. So, we refrain from that optimization
-  | isConcreteOnes y
-  = (-x, z)
---------------------------------}
-  | True
-  = ite (y .== z) (z, x) $ ite (signum r .== negate (signum y)) (q-i, r+y) qr
- where qr@(q, r) = x `sQuotRem` y
-       z = genLiteral (kindOf x) (0::Integer)
-       i = genLiteral (kindOf x) (1::Integer)
-
--- SInteger instance for quotRem/divMod are tricky!
--- SMT-Lib only has Euclidean operations, but Haskell
--- uses "truncate to 0" for quotRem, and "truncate to negative infinity" for divMod.
--- So, we cannot just use the above liftings directly.
-instance SDivisible SInteger where
-  sDivMod x y = ite (y .> 0) (sEDivMod x y) (liftDMod x y)
-  sQuotRem x y
-    | not (isSymbolic x || isSymbolic y)
-    = liftQRem x y
-    | True
-    = ite (y .== 0) (0, x) (qE+i, rE-i*y)
-    where (qE, rE) = liftQRem x y   -- for integers, this is euclidean due to SMTLib semantics
-          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. Note that unlike regular division, Euclidian division by @0@
--- is unconstrained. i.e., it can take any value whatsoever.
-sEDiv :: SInteger -> SInteger -> SInteger
-sEDiv (SBV a) (SBV b) = SBV $ a `svQuot` b
-
--- | Euclidian modulus. Note that unlike regular modulus, Euclidian division by @0@
--- is unconstrained. i.e., it can take any value whatsoever.
-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
-
--- |  Symbolic conditionals are modeled by the 'Mergeable' class, describing
--- how to merge the results of an if-then-else call with a symbolic test. SBV
--- provides all basic types as instances of this class, so users only need
--- to declare instances for custom data-types of their programs as needed.
---
--- A 'Mergeable' instance may be automatically derived for a custom data-type
--- with a single constructor where the type of each field is an instance of
--- 'Mergeable', such as a record of symbolic values. Users only need to add
--- 'G.Generic' and 'Mergeable' to the @deriving@ clause for the data-type. See
--- 'Documentation.SBV.Examples.Puzzles.U2Bridge.Status' for an example and an
--- illustration of what the instance would look like if written by hand.
---
--- The function 'select' is a total-indexing function out of a list of choices
--- with a default value, simulating array/list indexing. It's an n-way generalization
--- of the 'ite' function.
---
--- Minimal complete definition: None, if the type is instance of @Generic@. Otherwise
--- 'symbolicMerge'. Note that most types subject to merging are likely to be
--- trivial instances of @Generic@.
-class Mergeable a where
-   -- | Merge two values based on the condition. The first argument states
-   -- whether we force the then-and-else branches before the merging, at the
-   -- word level. This is an efficiency concern; one that we'd rather not
-   -- make but unfortunately necessary for getting symbolic simulation
-   -- working efficiently.
-   symbolicMerge :: Bool -> SBool -> a -> a -> a
-
-   -- | Total indexing operation. @select xs default index@ is intuitively
-   -- the same as @xs !! index@, except it evaluates to @default@ if @index@
-   -- underflows/overflows.
-   select :: (Ord b, SymVal b, Num b, Num (SBV b), OrdSymbolic (SBV b)) => [a] -> a -> SBV b -> a
-
-   -- NB. Earlier implementation of select used the binary-search trick
-   -- on the index to chop down the search space. While that is a good trick
-   -- in general, it doesn't work for SBV since we do not have any notion of
-   -- "concrete" subwords: If an index is symbolic, then all its bits are
-   -- symbolic as well. So, the binary search only pays off only if the indexed
-   -- list is really humongous, which is not very common in general. (Also,
-   -- for the case when the list is bit-vectors, we use SMT tables anyhow.)
-   select xs err ind
-    | isReal   ind = bad "real"
-    | isFloat  ind = bad "float"
-    | isDouble ind = bad "double"
-    | hasSign  ind = ite (ind .< 0) err (walk xs ind err)
-    | True         =                     walk xs ind err
-    where bad w = error $ "SBV.select: unsupported " ++ w ++ " valued select/index expression"
-          walk []     _ acc = acc
-          walk (e:es) i acc = walk es (i-1) (ite (i .== 0) e acc)
-
-   -- Default implementation for 'symbolicMerge' if the type is 'Generic'
-   default symbolicMerge :: (G.Generic a, GMergeable (G.Rep a)) => Bool -> SBool -> a -> a -> a
-   symbolicMerge = symbolicMergeDefault
-
--- | If-then-else. This is by definition 'symbolicMerge' with both
--- branches forced. This is typically the desired behavior, but also
--- see 'iteLazy' should you need more laziness.
-ite :: Mergeable a => SBool -> a -> a -> a
-ite t a b
-  | Just r <- unliteral t = if r then a else b
-  | True                  = symbolicMerge True t a b
-
--- | A Lazy version of ite, which does not force its arguments. This might
--- cause issues for symbolic simulation with large thunks around, so use with
--- care.
-iteLazy :: Mergeable a => SBool -> a -> a -> a
-iteLazy t a b
-  | Just r <- unliteral t = if r then a else b
-  | True                  = symbolicMerge False t a b
-
--- | Symbolic assert. Check that the given boolean condition is always 'sTrue' in the given path. The
--- optional first argument can be used to provide call-stack info via GHC's location facilities.
-sAssert :: HasKind a => Maybe CallStack -> String -> SBool -> SBV a -> SBV a
-sAssert cs msg cond x
-   | Just mustHold <- unliteral cond
-   = if mustHold
-     then x
-     else error $ show $ SafeResult ((locInfo . getCallStack) `fmap` cs, msg, Satisfiable defaultSMTCfg (SMTModel [] Nothing [] []))
-   | True
-   = SBV $ SVal k $ Right $ cache r
-  where k     = kindOf x
-        r st  = do xsv <- sbvToSV st x
-                   let pc = getPathCondition st
-                       -- We're checking if there are any cases where the path-condition holds, but not the condition
-                       -- Any violations of this, should be signaled, i.e., whenever the following formula is satisfiable
-                       mustNeverHappen = pc .&& sNot cond
-                   cnd <- sbvToSV st mustNeverHappen
-                   addAssertion st cs msg cnd
-                   return xsv
-
-        locInfo ps = intercalate ",\n " (map loc ps)
-          where loc (f, sl) = concat [srcLocFile sl, ":", show (srcLocStartLine sl), ":", show (srcLocStartCol sl), ":", f]
-
--- | Merge two symbolic values, at kind @k@, possibly @force@'ing the branches to make
--- sure they do not evaluate to the same result. This should only be used for internal purposes;
--- as default definitions provided should suffice in many cases. (i.e., End users should
--- only need to define 'symbolicMerge' when needed; which should be rare to start with.)
-symbolicMergeWithKind :: Kind -> Bool -> SBool -> SBV a -> SBV a -> SBV a
-symbolicMergeWithKind k force (SBV t) (SBV a) (SBV b) = SBV (svSymbolicMerge k force t a b)
-
-instance SymVal a => Mergeable (SBV a) where
-    symbolicMerge force t x y
-    -- Carefully use the kindOf instance to avoid strictness issues.
-       | force = symbolicMergeWithKind (kindOf x)          True  t x y
-       | True  = symbolicMergeWithKind (kindOf (Proxy @a)) False t x y
-    -- Custom version of select that translates to SMT-Lib tables at the base type of words
-    select xs err ind
-      | SBV (SVal _ (Left c)) <- ind = case cvVal c of
-                                         CInteger i -> if i < 0 || i >= genericLength xs
-                                                       then err
-                                                       else xs `genericIndex` i
-                                         _          -> error $ "SBV.select: unsupported " ++ show (kindOf ind) ++ " valued select/index expression"
-    select xsOrig err ind = xs `seq` SBV (SVal kElt (Right (cache r)))
-      where kInd = kindOf ind
-            kElt = kindOf err
-            -- Based on the index size, we need to limit the elements. For instance if the index is 8 bits, but there
-            -- are 257 elements, that last element will never be used and we can chop it of..
-            xs   = case kindOf ind of
-                     KBounded False i -> genericTake ((2::Integer) ^ (fromIntegral i     :: Integer)) xsOrig
-                     KBounded True  i -> genericTake ((2::Integer) ^ (fromIntegral (i-1) :: Integer)) xsOrig
-                     KUnbounded       -> xsOrig
-                     _                -> error $ "SBV.select: unsupported " ++ show (kindOf ind) ++ " valued select/index expression"
-            r st  = do sws <- mapM (sbvToSV st) xs
-                       swe <- sbvToSV st err
-                       if all (== swe) sws  -- off-chance that all elts are the same. Note that this also correctly covers the case when list is empty.
-                          then return swe
-                          else do idx <- getTableIndex st kInd kElt sws
-                                  swi <- sbvToSV st ind
-                                  let len = length xs
-                                  -- NB. No need to worry here that the index might be < 0; as the SMTLib translation takes care of that automatically
-                                  newExpr st kElt (SBVApp (LkUp (idx, kInd, kElt, len) swi swe) [])
-
--- | Construct a useful error message if we hit an unmergeable case.
-cannotMerge :: String -> String -> String -> a
-cannotMerge typ why hint = error $ unlines [ ""
-                                           , "*** Data.SBV.Mergeable: Cannot merge instances of " ++ typ ++ "."
-                                           , "*** While trying to do a symbolic if-then-else with incompatible branch results."
-                                           , "***"
-                                           , "*** " ++ why
-                                           , "*** "
-                                           , "*** Hint: " ++ hint
-                                           ]
-
--- | Merge concrete values that can be checked for equality
-concreteMerge :: Show a => String -> String -> (a -> a -> Bool) -> a -> a -> a
-concreteMerge t st eq x y
-  | x `eq` y = x
-  | True     = cannotMerge t
-                           ("Concrete values can only be merged when equal. Got: " ++ show x ++ " vs. " ++ show y)
-                           ("Use an " ++ st ++ " field if the values can differ.")
-
--- Mergeable instances for List/Maybe/Either/Array are useful, but can
--- throw exceptions if there is no structural matching of the results
--- It's a question whether we should really keep them..
-
--- Lists
-instance Mergeable a => Mergeable [a] where
-  symbolicMerge f t xs ys
-    | lxs == lys = zipWith (symbolicMerge f t) xs ys
-    | True       = cannotMerge "lists"
-                               ("Branches produce different sizes: " ++ show lxs ++ " vs " ++ show lys ++ ". Must have the same length.")
-                               "Use the 'SList' type (and Data.SBV.List routines) to model fully symbolic lists."
-    where (lxs, lys) = (length xs, length ys)
-
--- NonEmpty
-instance Mergeable a => Mergeable (NonEmpty a) where
-   symbolicMerge f t xs ys
-     | lxs == lys = NE.zipWith (symbolicMerge f t) xs ys
-     | True       = cannotMerge "non-empty lists"
-                                ("Branches produce different sizes: " ++ show lxs ++ " vs " ++ show lys ++ ". Must have the same length.")
-                                "Use the 'SList' type (and Data.SBV.List routines) to model fully symbolic lists."
-     where (lxs, lys) = (length xs, length ys)
-
--- ZipList
-instance Mergeable a => Mergeable (ZipList a) where
-  symbolicMerge force test (ZipList xs) (ZipList ys)
-    = ZipList (symbolicMerge force test xs ys)
-
--- Maybe
-instance Mergeable a => Mergeable (Maybe a) where
-  symbolicMerge _ _ Nothing  Nothing  = Nothing
-  symbolicMerge f t (Just a) (Just b) = Just $ symbolicMerge f t a b
-  symbolicMerge _ _ a b = cannotMerge "'Maybe' values"
-                                      ("Branches produce different constructors: " ++ show (k a, k b))
-                                      "Instead of an option type, try using a valid bit to indicate when a result is valid."
-      where k Nothing = "Nothing"
-            k _       = "Just"
-
--- Either
-instance (Mergeable a, Mergeable b) => Mergeable (Either a b) where
-  symbolicMerge f t (Left a)  (Left b)  = Left  $ symbolicMerge f t a b
-  symbolicMerge f t (Right a) (Right b) = Right $ symbolicMerge f t a b
-  symbolicMerge _ _ a b = cannotMerge "'Either' values"
-                                      ("Branches produce different constructors: " ++ show (k a, k b))
-                                      "Consider using a product type by a tag instead."
-     where k (Left _)  = "Left"
-           k (Right _) = "Right"
-
--- Arrays
-instance (Ix a, Mergeable b) => Mergeable (Array a b) where
-  symbolicMerge f t a b
-    | ba == bb = DA.listArray ba (zipWith (symbolicMerge f t) (elems a) (elems b))
-    | True     = cannotMerge "'Array' values"
-                             ("Branches produce different ranges: " ++ show (k ba, k bb))
-                             "Consider using SBV's native 'SArray' abstraction."
-    where [ba, bb] = map bounds [a, b]
-          k = rangeSize
-
--- Functions
-instance Mergeable b => Mergeable (a -> b) where
-  symbolicMerge f t g h x = symbolicMerge f t (g x) (h x)
-  {- Following definition, while correct, is utterly inefficient. Since the
-     application is delayed, this hangs on to the inner list and all the
-     impending merges, even when ind is concrete. Thus, it's much better to
-     simply use the default definition for the function case.
-  -}
-  -- select xs err ind = \x -> select (map ($ x) xs) (err x) ind
-
--- 2-Tuple
-instance (Mergeable a, Mergeable b) => Mergeable (a, b) where
-  symbolicMerge f t (i0, i1) (j0, j1) = ( symbolicMerge f t i0 j0
-                                        , symbolicMerge f t i1 j1
-                                        )
-
-  select xs (err1, err2) ind = ( select as err1 ind
-                               , select bs err2 ind
-                               )
-    where (as, bs) = unzip xs
-
--- 3-Tuple
-instance (Mergeable a, Mergeable b, Mergeable c) => Mergeable (a, b, c) where
-  symbolicMerge f t (i0, i1, i2) (j0, j1, j2) = ( symbolicMerge f t i0 j0
-                                                , symbolicMerge f t i1 j1
-                                                , symbolicMerge f t i2 j2
-                                                )
-
-  select xs (err1, err2, err3) ind = ( select as err1 ind
-                                     , select bs err2 ind
-                                     , select cs err3 ind
-                                     )
-
-    where (as, bs, cs) = unzip3 xs
-
--- 4-Tuple
-instance (Mergeable a, Mergeable b, Mergeable c, Mergeable d) => Mergeable (a, b, c, d) where
-  symbolicMerge f t (i0, i1, i2, i3) (j0, j1, j2, j3) = ( symbolicMerge f t i0 j0
-                                                        , symbolicMerge f t i1 j1
-                                                        , symbolicMerge f t i2 j2
-                                                        , symbolicMerge f t i3 j3
-                                                        )
-
-  select xs (err1, err2, err3, err4) ind = ( select as err1 ind
-                                           , select bs err2 ind
-                                           , select cs err3 ind
-                                           , select ds err4 ind
-                                           )
-    where (as, bs, cs, ds) = unzip4 xs
-
--- 5-Tuple
-instance (Mergeable a, Mergeable b, Mergeable c, Mergeable d, Mergeable e) => Mergeable (a, b, c, d, e) where
-  symbolicMerge f t (i0, i1, i2, i3, i4) (j0, j1, j2, j3, j4) = ( symbolicMerge f t i0 j0
-                                                                , symbolicMerge f t i1 j1
-                                                                , symbolicMerge f t i2 j2
-                                                                , symbolicMerge f t i3 j3
-                                                                , symbolicMerge f t i4 j4
-                                                                )
-
-  select xs (err1, err2, err3, err4, err5) ind = ( select as err1 ind
-                                                 , select bs err2 ind
-                                                 , select cs err3 ind
-                                                 , select ds err4 ind
-                                                 , select es err5 ind
-                                                 )
-    where (as, bs, cs, ds, es) = unzip5 xs
-
--- 6-Tuple
-instance (Mergeable a, Mergeable b, Mergeable c, Mergeable d, Mergeable e, Mergeable f) => Mergeable (a, b, c, d, e, f) where
-  symbolicMerge f t (i0, i1, i2, i3, i4, i5) (j0, j1, j2, j3, j4, j5) = ( symbolicMerge f t i0 j0
-                                                                        , symbolicMerge f t i1 j1
-                                                                        , symbolicMerge f t i2 j2
-                                                                        , symbolicMerge f t i3 j3
-                                                                        , symbolicMerge f t i4 j4
-                                                                        , symbolicMerge f t i5 j5
-                                                                        )
-
-  select xs (err1, err2, err3, err4, err5, err6) ind = ( select as err1 ind
-                                                       , select bs err2 ind
-                                                       , select cs err3 ind
-                                                       , select ds err4 ind
-                                                       , select es err5 ind
-                                                       , select fs err6 ind
-                                                       )
-    where (as, bs, cs, ds, es, fs) = unzip6 xs
-
--- 7-Tuple
-instance (Mergeable a, Mergeable b, Mergeable c, Mergeable d, Mergeable e, Mergeable f, Mergeable g) => Mergeable (a, b, c, d, e, f, g) where
-  symbolicMerge f t (i0, i1, i2, i3, i4, i5, i6) (j0, j1, j2, j3, j4, j5, j6) = ( symbolicMerge f t i0 j0
-                                                                                , symbolicMerge f t i1 j1
-                                                                                , symbolicMerge f t i2 j2
-                                                                                , symbolicMerge f t i3 j3
-                                                                                , symbolicMerge f t i4 j4
-                                                                                , symbolicMerge f t i5 j5
-                                                                                , symbolicMerge f t i6 j6
-                                                                                )
-
-  select xs (err1, err2, err3, err4, err5, err6, err7) ind = ( select as err1 ind
-                                                             , select bs err2 ind
-                                                             , select cs err3 ind
-                                                             , select ds err4 ind
-                                                             , select es err5 ind
-                                                             , select fs err6 ind
-                                                             , select gs err7 ind
-                                                             )
-    where (as, bs, cs, ds, es, fs, gs) = unzip7 xs
-
--- Base types are mergeable so long as they are equal
-instance Mergeable ()      where symbolicMerge _ _ = concreteMerge "()"      "()"        (==)
-instance Mergeable Integer where symbolicMerge _ _ = concreteMerge "Integer" "SInteger"  (==)
-instance Mergeable Bool    where symbolicMerge _ _ = concreteMerge "Bool"    "SBool"     (==)
-instance Mergeable Char    where symbolicMerge _ _ = concreteMerge "Char"    "SChar"     (==)
-instance Mergeable Float   where symbolicMerge _ _ = concreteMerge "Float"   "SFloat"    fpIsEqualObjectH
-instance Mergeable Double  where symbolicMerge _ _ = concreteMerge "Double"  "SDouble"   fpIsEqualObjectH
-instance Mergeable Word8   where symbolicMerge _ _ = concreteMerge "Word8"   "SWord8"    (==)
-instance Mergeable Word16  where symbolicMerge _ _ = concreteMerge "Word16"  "SWord16"   (==)
-instance Mergeable Word32  where symbolicMerge _ _ = concreteMerge "Word32"  "SWord32"   (==)
-instance Mergeable Word64  where symbolicMerge _ _ = concreteMerge "Word64"  "SWord64"   (==)
-instance Mergeable Int8    where symbolicMerge _ _ = concreteMerge "Int8"    "SInt8"     (==)
-instance Mergeable Int16   where symbolicMerge _ _ = concreteMerge "Int16"   "SInt16"    (==)
-instance Mergeable Int32   where symbolicMerge _ _ = concreteMerge "Int32"   "SInt32"    (==)
-instance Mergeable Int64   where symbolicMerge _ _ = concreteMerge "Int64"   "SInt64"    (==)
-
--- Arbitrary product types, using GHC.Generics
---
--- NB: Because of the way GHC.Generics works, the implementation of
--- symbolicMerge' is recursive. The derived instance for @data T a = T a a a a@
--- resembles that for (a, (a, (a, a))), not the flat 4-tuple (a, a, a, a). This
--- difference should have no effect in practice. Note also that, unlike the
--- hand-rolled tuple instances, the generic instance does not provide a custom
--- 'select' implementation, and so does not benefit from the SMT-table
--- implementation in the 'SBV a' instance.
-
--- | Not exported. Symbolic merge using the generic representation provided by
--- 'G.Generics'.
-symbolicMergeDefault :: (G.Generic a, GMergeable (G.Rep a)) => Bool -> SBool -> a -> a -> a
-symbolicMergeDefault force t x y = G.to $ symbolicMerge' force t (G.from x) (G.from y)
-
--- | Not exported. Used only in 'symbolicMergeDefault'. Instances are provided for
--- the generic representations of product types where each element is Mergeable.
-class GMergeable f where
-  symbolicMerge' :: Bool -> SBool -> f a -> f a -> f a
-
-{-
- - N.B. A V1 instance like the below would be wrong!
- - Why? Because inSBV, we use empty data to mean "uninterpreted" sort; not
- - something that has no constructors. Perhaps that was a bad design
- - decision. So, do not allow merging of such values!
-instance GMergeable V1 where
-  symbolicMerge' _ _ x _ = x
--}
-
-instance GMergeable U1 where
-  symbolicMerge' _ _ _ _ = U1
-
-instance (Mergeable c) => GMergeable (K1 i c) where
-  symbolicMerge' force t (K1 x) (K1 y) = K1 $ symbolicMerge force t x y
-
-instance (GMergeable f) => GMergeable (M1 i c f) where
-  symbolicMerge' force t (M1 x) (M1 y) = M1 $ symbolicMerge' force t x y
-
-instance (GMergeable f, GMergeable g) => GMergeable (f :*: g) where
-  symbolicMerge' force t (x1 :*: y1) (x2 :*: y2) = symbolicMerge' force t x1 x2 :*: symbolicMerge' force t y1 y2
-
-{- A mergeable instance for sum-types isn't possible. Why? It would something like:
-
-instance (GMergeable f, GMergeable g) => GMergeable (f :+: g) where
-  symbolicMerge' force t (L1 x) (L1 y) = L1 $ symbolicMerge' force t x y
-  symbolicMerge' force t (R1 x) (R1 y) = R1 $ symbolicMerge' force t x y
-  symbolicMerge' force t l r
-    | Just tv <- unliteral t = if tv then l else r
-    | True                   = ????
-
-There's really no good code to put in ????. We have no way to ask the SMT solver to merge composite values that
-have different constructors. Calling "error" here would pass the type-checker, but that simply postpones the problem
-to run-time. If you need mergeable on sum-types, you better write one yourself, possibly using the SEither type yourself.
-As we have it, you'll get a type-error; which can be hard to read, but is preferable.
-
-NB. This isn't a problem with the generic version of symbolic equality; since we can simply return sFalse if we
-see different constructors. Such isn't the case when merging.
--}
-
--- Bounded instances
-instance {-# OVERLAPPABLE #-} (SymVal a, Bounded a) => Bounded (SBV a) where
-  minBound = literal minBound
-  maxBound = literal maxBound
-
--- Haskell and SMTLib differ in their default char ranges. In Haskell, maxbound is a lot larger.
--- But in SMTLib, we only go upto 0x2FFFF. So, we adopt the SMTLib variant here. This is hardly
--- an issue in practice, but the discrepancy is disconcerting.
-instance {-# OVERLAPPING #-} Bounded SChar where
-  minBound = literal (chr 0)
-  maxBound = literal (chr 0x2FFFF)
-
--- | Choose a value that satisfies the given predicate. This is Hillbert's choice, essentially. Note that
--- if the predicate given is not satisfiable (for instance @const sFalse@), then the element returned will be arbitrary.
--- The only guarantee is that if there's at least one element that satisfies the predicate, then the returned
--- element will be one of those that do. The returned element is not guaranteed to be unique, least, greatest etc, unless
--- there happens to be exactly one satisfying element.
-some :: forall a. (SymVal a, HasKind a) => String -> (SBV a -> SBool) -> SBV a
-some inpName cond = mk f
-  where mk = SBV . SVal k . Right . cache
-
-        k = kindOf (Proxy @a)
-
-
-        f st = do ctr <- incrementFreshNameCounter st
-                  let pre = atProxy (Proxy @a) inpName
-                      nm  | ctr == 0 = pre
-                          | True     = pre ++ "_" ++ show ctr
-                  nm' <- newUninterpreted st (UIGiven nm) Nothing (SBVType [k]) (UINone False)
-                  chosen <- newExpr st k $ SBVApp (Uninterpreted nm') []
-                  let ifExists  = quantifiedBool $ \(Exists ex) -> cond ex
-                  internalConstraint st False [] (unSBV (ifExists .=> cond (mk (pure (pure chosen)))))
-                  pure chosen
-
--- | SMT definable constants and functions, which can also be uninterpeted.
--- This class captures functions that we can generate standalone-code for
--- in the SMT solver. Note that we also allow uninterpreted constants and
--- functions too. An uninterpreted constant is a value that is indexed by its name. The only
--- property the prover assumes -- about these values are that they are equivalent to themselves; i.e., (for
--- functions) they return the same results when applied to same arguments.
--- We support uninterpreted-functions as a general means of black-box'ing
--- operations that are /irrelevant/ for the purposes of the proof; i.e., when
--- the proofs can be performed without any knowledge about the function itself.
---
--- Minimal complete definition: 'sbvDefineValue'. However, most instances in
--- practice are already provided by SBV, so end-users should not need to define their
--- own instances.
-class SMTDefinable a where
-  -- | Generate the code for this value as an SMTLib function, instead of
-  -- the usual unrolling semantics. This is useful for generating sub-functions
-  -- in generated SMTLib problem, or handling recursive (and mutually-recursive)
-  -- definitions that wouldn't terminate in an unrolling symbolic simulation context.
-  --
-  -- __IMPORTANT NOTE__ The string argument names this function. Note that SBV will identify
-  -- this function with that name, i.e., if you use this function twice (or use it recursively),
-  -- it will simply assume this name uniquely identifies the function being defined. Hence,
-  -- the user has to assure that this string is unique amongst all the functions you use.
-  -- Furthermore, if the call to 'smtFunction' happens in the scope of a parameter, you
-  -- must make sure the string is chosen to keep it unique per parameter value. For instance,
-  -- if you have:
-  --
-  -- @
-  --   bar :: SInteger -> SInteger -> SInteger
-  --   bar k = smtFunction "bar" (\x -> x+k)   -- Note the capture of k!
-  -- @
-  --
-  -- and you call @bar 2@ and @bar 3@, you *will* get the same SMTLib function. Obviously
-  -- this is unsound. The reason is that the parameter value isn't captured by the name. In general,
-  -- you should simply not do this, but if you must, have a concrete argument to make sure you can
-  -- create a unique name. Something like:
-  --
-  -- @
-  --   bar :: String -> SInteger -> SInteger -> SInteger
-  --   bar tag k = smtFunction ("bar_" ++ tag) (\x -> x+k)   -- Tag should make the name unique!
-  -- @
-  --
-  -- Then, make sure you use @bar "two" 2@ and @bar "three" 3@ etc. to preserve the invariant.
-  --
-  -- Furthermore, the function argument must not capture any non-constant variables in the context.
-  -- You can also define higher-order functions, see 'smtHOFunction' for that purpose.
-  --
-  -- Note that this is a design choice, to keep function creation as easy to use as possible. SBV
-  -- could've made 'smtFunction' a monadic call and generated the name itself to avoid all these issues.
-  -- But the ergonomics of that is worse, and doesn't fit with the general design philosophy. If you
-  -- can think of a solution (perhaps using some nifty GHC tricks?) to avoid this issue without making
-  -- 'smtFunction' return a monadic result, please get in touch!
-  smtFunction :: (Typeable a, Lambda Symbolic a) => String -> a -> a
-
-  -- | Register a function. This function is typically not needed as SBV will register functions used
-  -- automatically upon first use. However, there are scenarios (in particular query contexts)
-  -- where the definition isn't used before query-mode starts, and SBV (for historical reasons)
-  -- requires functions to be known before query-mode starts executing. In such cases, use this function
-  -- to register them with the system.
-  registerFunction :: a -> Symbolic ()
-
-  -- | Uninterpret a value, i.e., add this value as a completely undefined value/function that
-  -- the solver is free to instantiate to satisfy other constraints.
-  --
-  -- __Known issues__
-  --
-  -- Usually using an uninterpret function will register itself to the solver, but sometimes the lazyness
-  -- of the evaluation might render this unreliable.
-  --
-  -- For example, when working with quantifiers and uninterpreted functions with the following code:
-  --
-  -- > runSMTWith z3 $ do
-  -- >   let f = uninterpret "f" :: SInteger -> SInteger
-  -- >   query $ do
-  -- >     constrain $ \(Forall (b :: SInteger)) -> f b .== f b
-  -- >     checkSat
-  --
-  -- The solver will complain about the unknown constant @f (Int)@.
-  --
-  -- A workaround of this is to explicit register them with 'Data.SBV.Control.registerUISMTFunction':
-  --
-  -- > runSMTWith z3 $ do
-  -- >   let f = uninterpret "f" :: SInteger -> SInteger
-  -- >   registerUISMTFunction f
-  -- >   query $ do
-  -- >     constrain $ \(Forall (b :: SInteger)) -> f b .== f b
-  -- >     checkSat
-  --
-  -- See https://github.com/LeventErkok/sbv/issues/711 for more info.
-  uninterpret :: String -> a
-
-  -- | Uninterpret a value, with named arguments in case of functions. SBV will use these
-  -- names when it shows the values for the arguments. If the given names are more than needed
-  -- we ignore the excess. If not enough, we add from a stock set of variables.
-  uninterpretWithArgs :: String -> [String] -> a
-
-  -- | Uninterpret a value, only for the purposes of code-generation. For execution
-  -- and verification the value is used as is. For code-generation, the alternate
-  -- definition is used. This is useful when we want to take advantage of native
-  -- libraries on the target languages.
-  cgUninterpret :: String -> [String] -> a -> a
-
-  -- | Most generalized form of uninterpretation, this function should not be needed
-  -- by end-user-code, but is rather useful for the library development.
-  sbvDefineValue :: UIName -> Maybe [String] -> UIKind a -> a
-
-  -- | A synonym for 'uninterpret'. Allows us to create variables without
-  -- having to call 'free' explicitly, i.e., without being in the symbolic monad.
-  sym :: String -> a
-
-  -- | Render an uninterpeted value as an SMTLib definition
-  sbv2smt :: ExtractIO m => a -> m String
-
-  {-# MINIMAL sbvDefineValue, sbv2smt #-}
-
-  -- defaults:
-  uninterpret         nm         = sbvDefineValue (UIGiven nm) Nothing   $ UIFree True
-  uninterpretWithArgs nm  as     = sbvDefineValue (UIGiven nm) (Just as) $ UIFree True
-  cgUninterpret       nm  code v = sbvDefineValue (UIGiven nm) Nothing   $ UICodeC (v, code)
-  sym                            = uninterpret
-
-  smtFunction nm v = sbvDefineValue (UIGiven (atProxy (Proxy @a) nm)) Nothing $ UIFun (v, \st fk -> lambda st TopLevel fk v)
-
-  default registerFunction :: forall b c. (a ~ (SBV b -> c), SymVal b, SMTDefinable c) => a -> Symbolic ()
-  registerFunction f = do let k = kindOf (Proxy @b)
-                          st <- symbolicEnv
-                          v <- liftIO $ newInternalVariable st k
-                          let b = SBV $ SVal k $ Right $ cache (const (pure v))
-                          registerFunction $ f b
-
-
--- | Kind of uninterpretation
-data UIKind a = UIFree  Bool                            -- ^ completely uninterpreted. If Bool is true, then this is curried.
-              | UIFun   (a, State -> Kind -> IO SMTDef) -- ^ has code for SMTLib, with final type of kind (note this is the result
-                                                        -- , not the arguments), which can be generated by calling the function on the state.
-              | UICodeC (a, [String])                   -- ^ has code for code-generation, i.e., C
-              deriving Functor
-
--- Get the code associated with the UI, unless we've already did this once. (To support recursive defs.)
-retrieveUICode :: UIName -> State -> Kind -> UIKind a -> IO UICodeKind
-retrieveUICode _             _  _  (UIFree  c)      = pure $ UINone c
-retrieveUICode (UIGiven  nm) st fk (UIFun   (_, f)) = do userFuncs <- readIORef (rUserFuncs st)
-                                                         if nm `Set.member` userFuncs
-                                                            then pure $ UINone True
-                                                            else do modifyState st rUserFuncs (Set.insert nm) (pure ())
-                                                                    UISMT <$> f st fk
-retrieveUICode _             _  _  (UICodeC (_, c)) = pure $ UICgC c
-
--- Get the constant value associated with the UI
-retrieveConstCode :: UIKind a -> Maybe a
-retrieveConstCode UIFree{}         = Nothing
-retrieveConstCode (UIFun   (v, _)) = Just v
-retrieveConstCode (UICodeC (v, _)) = Just v
-
--- Plain constants
-instance (SymVal a, HasKind a) => SMTDefinable (SBV a) where
-  sbv2smt a = do st <- mkNewState defaultSMTCfg (LambdaGen (Just 0))
-                 s <- lambdaStr st TopLevel (kindOf a) a
-                 pure $ intercalate "\n" [ "; Automatically generated by SBV. Do not modify!"
-                                         , "; Type: " ++ smtType (kindOf a)
-                                         , show s
-                                         ]
-
-  registerFunction x = constrain $ x .== x
-
-  sbvDefineValue nm mbArgs uiKind
-     | Just v <- retrieveConstCode uiKind
-     = v
-     | True
-     = SBV $ SVal ka $ Right $ cache result
-    where ka = kindOf (Proxy @a)
-          result st = do isSMT <- inSMTMode st
-                         case (isSMT, uiKind) of
-                           (True, UICodeC (v, _)) -> sbvToSV st v
-                           _                      -> do nm' <- newUninterpreted st nm mbArgs (SBVType [ka]) =<< retrieveUICode nm st ka uiKind
-                                                        newExpr st ka $ SBVApp (Uninterpreted nm') []
-
--- Functions of one argument
-instance (SymVal b, SymVal a, HasKind a) => SMTDefinable (SBV b -> SBV a) where
-  sbv2smt fn = defs2smt $ \b -> fn b .== fn b
-
-  sbvDefineValue nm mbArgs uiKind = f
-    where f arg0
-           | Just v <- retrieveConstCode uiKind, isConcrete arg0
-           = v arg0
-           | True
-           = SBV $ SVal ka $ Right $ cache result
-           where ka = kindOf (Proxy @a)
-                 kb = kindOf (Proxy @b)
-                 result st = do isSMT <- inSMTMode st
-                                case (isSMT, uiKind) of
-                                  (True, UICodeC (v, _)) -> sbvToSV st (v arg0)
-                                  _                      -> do nm' <- newUninterpreted st nm mbArgs (SBVType [kb, ka]) =<< retrieveUICode nm st ka uiKind
-                                                               sw0 <- sbvToSV st arg0
-                                                               mapM_ forceSVArg [sw0]
-                                                               newExpr st ka $ SBVApp (Uninterpreted nm') [sw0]
-
--- Functions of two arguments
-instance (SymVal c, SymVal b, SymVal a, HasKind a) => SMTDefinable (SBV c -> SBV b -> SBV a) where
-  sbv2smt fn = defs2smt $ \c b -> fn c b .== fn c b
-
-  sbvDefineValue nm mbArgs uiKind = f
-    where f arg0 arg1
-           | Just v <- retrieveConstCode uiKind, isConcrete arg0, isConcrete arg1
-           = v arg0 arg1
-           | True
-           = SBV $ SVal ka $ Right $ cache result
-           where ka = kindOf (Proxy @a)
-                 kb = kindOf (Proxy @b)
-                 kc = kindOf (Proxy @c)
-                 result st = do isSMT <- inSMTMode st
-                                case (isSMT, uiKind) of
-                                  (True, UICodeC (v, _)) -> sbvToSV st (v arg0 arg1)
-                                  _                      -> do nm' <- newUninterpreted st nm mbArgs (SBVType [kc, kb, ka]) =<< retrieveUICode nm st ka uiKind
-                                                               sw0 <- sbvToSV st arg0
-                                                               sw1 <- sbvToSV st arg1
-                                                               mapM_ forceSVArg [sw0, sw1]
-                                                               newExpr st ka $ SBVApp (Uninterpreted nm') [sw0, sw1]
-
--- Functions of three arguments
-instance (SymVal d, SymVal c, SymVal b, SymVal a, HasKind a) => SMTDefinable (SBV d -> SBV c -> SBV b -> SBV a) where
-  sbv2smt fn = defs2smt $ \d c b -> fn d c b .== fn d c b
-
-  sbvDefineValue nm mbArgs uiKind = f
-    where f arg0 arg1 arg2
-           | Just v <- retrieveConstCode uiKind, isConcrete arg0, isConcrete arg1, isConcrete arg2
-           = v arg0 arg1 arg2
-           | True
-           = SBV $ SVal ka $ Right $ cache result
-           where ka = kindOf (Proxy @a)
-                 kb = kindOf (Proxy @b)
-                 kc = kindOf (Proxy @c)
-                 kd = kindOf (Proxy @d)
-                 result st = do isSMT <- inSMTMode st
-                                case (isSMT, uiKind) of
-                                  (True, UICodeC (v, _)) -> sbvToSV st (v arg0 arg1 arg2)
-                                  _                      -> do nm' <- newUninterpreted st nm mbArgs (SBVType [kd, kc, kb, ka]) =<< retrieveUICode nm st ka uiKind
-                                                               sw0 <- sbvToSV st arg0
-                                                               sw1 <- sbvToSV st arg1
-                                                               sw2 <- sbvToSV st arg2
-                                                               mapM_ forceSVArg [sw0, sw1, sw2]
-                                                               newExpr st ka $ SBVApp (Uninterpreted nm') [sw0, sw1, sw2]
-
--- Functions of four arguments
-instance (SymVal e, SymVal d, SymVal c, SymVal b, SymVal a, HasKind a) => SMTDefinable (SBV e -> SBV d -> SBV c -> SBV b -> SBV a) where
-  sbv2smt fn = defs2smt $ \e d c b -> fn e d c b .== fn e d c b
-
-  sbvDefineValue nm mbArgs uiKind = f
-    where f arg0 arg1 arg2 arg3
-           | Just v <- retrieveConstCode uiKind, isConcrete arg0, isConcrete arg1, isConcrete arg2, isConcrete arg3
-           = v arg0 arg1 arg2 arg3
-           | True
-           = SBV $ SVal ka $ Right $ cache result
-           where ka = kindOf (Proxy @a)
-                 kb = kindOf (Proxy @b)
-                 kc = kindOf (Proxy @c)
-                 kd = kindOf (Proxy @d)
-                 ke = kindOf (Proxy @e)
-                 result st = do isSMT <- inSMTMode st
-                                case (isSMT, uiKind) of
-                                  (True, UICodeC (v, _)) -> sbvToSV st (v arg0 arg1 arg2 arg3)
-                                  _                      -> do nm' <- newUninterpreted st nm mbArgs (SBVType [ke, kd, kc, kb, ka]) =<< retrieveUICode nm st ka uiKind
-                                                               sw0 <- sbvToSV st arg0
-                                                               sw1 <- sbvToSV st arg1
-                                                               sw2 <- sbvToSV st arg2
-                                                               sw3 <- sbvToSV st arg3
-                                                               mapM_ forceSVArg [sw0, sw1, sw2, sw3]
-                                                               newExpr st ka $ SBVApp (Uninterpreted nm') [sw0, sw1, sw2, sw3]
-
--- Functions of five arguments
-instance (SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, SymVal a, HasKind a) => SMTDefinable (SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a) where
-  sbv2smt fn = defs2smt $ \f e d c b -> fn f e d c b .== fn f e d c b
-
-  sbvDefineValue nm mbArgs uiKind = f
-    where f arg0 arg1 arg2 arg3 arg4
-           | Just v <- retrieveConstCode uiKind, isConcrete arg0, isConcrete arg1, isConcrete arg2, isConcrete arg3, isConcrete arg4
-           = v arg0 arg1 arg2 arg3 arg4
-           | True
-           = SBV $ SVal ka $ Right $ cache result
-           where ka = kindOf (Proxy @a)
-                 kb = kindOf (Proxy @b)
-                 kc = kindOf (Proxy @c)
-                 kd = kindOf (Proxy @d)
-                 ke = kindOf (Proxy @e)
-                 kf = kindOf (Proxy @f)
-                 result st = do isSMT <- inSMTMode st
-                                case (isSMT, uiKind) of
-                                  (True, UICodeC (v, _)) -> sbvToSV st (v arg0 arg1 arg2 arg3 arg4)
-                                  _                      -> do nm' <- newUninterpreted st nm mbArgs (SBVType [kf, ke, kd, kc, kb, ka]) =<< retrieveUICode nm st ka uiKind
-                                                               sw0 <- sbvToSV st arg0
-                                                               sw1 <- sbvToSV st arg1
-                                                               sw2 <- sbvToSV st arg2
-                                                               sw3 <- sbvToSV st arg3
-                                                               sw4 <- sbvToSV st arg4
-                                                               mapM_ forceSVArg [sw0, sw1, sw2, sw3, sw4]
-                                                               newExpr st ka $ SBVApp (Uninterpreted nm') [sw0, sw1, sw2, sw3, sw4]
-
--- Functions of six arguments
-instance (SymVal g, SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, SymVal a, HasKind a) => SMTDefinable (SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a) where
-  sbv2smt fn = defs2smt $ \f g e d c b -> fn g f e d c b .== fn g f e d c b
-
-  sbvDefineValue nm mbArgs uiKind = f
-    where f arg0 arg1 arg2 arg3 arg4 arg5
-           | Just v <- retrieveConstCode uiKind, isConcrete arg0, isConcrete arg1, isConcrete arg2, isConcrete arg3, isConcrete arg4, isConcrete arg5
-           = v arg0 arg1 arg2 arg3 arg4 arg5
-           | True
-           = SBV $ SVal ka $ Right $ cache result
-           where ka = kindOf (Proxy @a)
-                 kb = kindOf (Proxy @b)
-                 kc = kindOf (Proxy @c)
-                 kd = kindOf (Proxy @d)
-                 ke = kindOf (Proxy @e)
-                 kf = kindOf (Proxy @f)
-                 kg = kindOf (Proxy @g)
-                 result st = do isSMT <- inSMTMode st
-                                case (isSMT, uiKind) of
-                                  (True, UICodeC (v, _)) -> sbvToSV st (v arg0 arg1 arg2 arg3 arg4 arg5)
-                                  _                      -> do nm' <- newUninterpreted st nm mbArgs (SBVType [kg, kf, ke, kd, kc, kb, ka]) =<< retrieveUICode nm st ka uiKind
-                                                               sw0 <- sbvToSV st arg0
-                                                               sw1 <- sbvToSV st arg1
-                                                               sw2 <- sbvToSV st arg2
-                                                               sw3 <- sbvToSV st arg3
-                                                               sw4 <- sbvToSV st arg4
-                                                               sw5 <- sbvToSV st arg5
-                                                               mapM_ forceSVArg [sw0, sw1, sw2, sw3, sw4, sw5]
-                                                               newExpr st ka $ SBVApp (Uninterpreted nm') [sw0, sw1, sw2, sw3, sw4, sw5]
-
--- Functions of seven arguments
-instance (SymVal h, SymVal g, SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, SymVal a, HasKind a)
-            => SMTDefinable (SBV h -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a) where
-  sbv2smt fn = defs2smt $ \h g f e d c b -> fn h g f e d c b .== fn h g f e d c b
-
-  sbvDefineValue nm mbArgs uiKind = f
-    where f arg0 arg1 arg2 arg3 arg4 arg5 arg6
-           | Just v <- retrieveConstCode uiKind, isConcrete arg0, isConcrete arg1, isConcrete arg2, isConcrete arg3, isConcrete arg4, isConcrete arg5, isConcrete arg6
-           = v arg0 arg1 arg2 arg3 arg4 arg5 arg6
-           | True
-           = SBV $ SVal ka $ Right $ cache result
-           where ka = kindOf (Proxy @a)
-                 kb = kindOf (Proxy @b)
-                 kc = kindOf (Proxy @c)
-                 kd = kindOf (Proxy @d)
-                 ke = kindOf (Proxy @e)
-                 kf = kindOf (Proxy @f)
-                 kg = kindOf (Proxy @g)
-                 kh = kindOf (Proxy @h)
-                 result st = do isSMT <- inSMTMode st
-                                case (isSMT, uiKind) of
-                                  (True, UICodeC (v, _)) -> sbvToSV st (v arg0 arg1 arg2 arg3 arg4 arg5 arg6)
-                                  _                      -> do nm' <- newUninterpreted st nm mbArgs (SBVType [kh, kg, kf, ke, kd, kc, kb, ka]) =<< retrieveUICode nm st ka uiKind
-                                                               sw0 <- sbvToSV st arg0
-                                                               sw1 <- sbvToSV st arg1
-                                                               sw2 <- sbvToSV st arg2
-                                                               sw3 <- sbvToSV st arg3
-                                                               sw4 <- sbvToSV st arg4
-                                                               sw5 <- sbvToSV st arg5
-                                                               sw6 <- sbvToSV st arg6
-                                                               mapM_ forceSVArg [sw0, sw1, sw2, sw3, sw4, sw5, sw6]
-                                                               newExpr st ka $ SBVApp (Uninterpreted nm') [sw0, sw1, sw2, sw3, sw4, sw5, sw6]
-
--- Functions of eight arguments
-instance (SymVal i, SymVal h, SymVal g, SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, SymVal a, SymVal a, HasKind a)
-            => SMTDefinable (SBV i -> SBV h -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a) where
-  sbv2smt fn = defs2smt $ \i h g f e d c b -> fn i h g f e d c b .== fn i h g f e d c b
-
-  sbvDefineValue nm mbArgs uiKind = f
-    where f arg0 arg1 arg2 arg3 arg4 arg5 arg6 arg7
-           | Just v <- retrieveConstCode uiKind, isConcrete arg0, isConcrete arg1, isConcrete arg2, isConcrete arg3, isConcrete arg4, isConcrete arg5, isConcrete arg6, isConcrete arg7
-           = v arg0 arg1 arg2 arg3 arg4 arg5 arg6 arg7
-           | True
-           = SBV $ SVal ka $ Right $ cache result
-           where ka = kindOf (Proxy @a)
-                 kb = kindOf (Proxy @b)
-                 kc = kindOf (Proxy @c)
-                 kd = kindOf (Proxy @d)
-                 ke = kindOf (Proxy @e)
-                 kf = kindOf (Proxy @f)
-                 kg = kindOf (Proxy @g)
-                 kh = kindOf (Proxy @h)
-                 ki = kindOf (Proxy @i)
-                 result st = do isSMT <- inSMTMode st
-                                case (isSMT, uiKind) of
-                                  (True, UICodeC (v, _)) -> sbvToSV st (v arg0 arg1 arg2 arg3 arg4 arg5 arg6 arg7)
-                                  _                      -> do nm' <- newUninterpreted st nm mbArgs (SBVType [ki, kh, kg, kf, ke, kd, kc, kb, ka]) =<< retrieveUICode nm st ka uiKind
-                                                               sw0 <- sbvToSV st arg0
-                                                               sw1 <- sbvToSV st arg1
-                                                               sw2 <- sbvToSV st arg2
-                                                               sw3 <- sbvToSV st arg3
-                                                               sw4 <- sbvToSV st arg4
-                                                               sw5 <- sbvToSV st arg5
-                                                               sw6 <- sbvToSV st arg6
-                                                               sw7 <- sbvToSV st arg7
-                                                               mapM_ forceSVArg [sw0, sw1, sw2, sw3, sw4, sw5, sw6, sw7]
-                                                               newExpr st ka $ SBVApp (Uninterpreted nm') [sw0, sw1, sw2, sw3, sw4, sw5, sw6, sw7]
-
--- Functions of nine arguments
-instance (SymVal j, SymVal i, SymVal h, SymVal g, SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, SymVal a, HasKind a)
-            => SMTDefinable (SBV j -> SBV i -> SBV h -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a) where
-  sbv2smt fn = defs2smt $ \j i h g f e d c b -> fn j i h g f e d c b .== fn j i h g f e d c b
-
-  sbvDefineValue nm mbArgs uiKind = f
-    where f arg0 arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8
-           | Just v <- retrieveConstCode uiKind, isConcrete arg0, isConcrete arg1, isConcrete arg2, isConcrete arg3, isConcrete arg4, isConcrete arg5, isConcrete arg6, isConcrete arg7, isConcrete arg8
-           = v arg0 arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8
-           | True
-           = SBV $ SVal ka $ Right $ cache result
-           where ka = kindOf (Proxy @a)
-                 kb = kindOf (Proxy @b)
-                 kc = kindOf (Proxy @c)
-                 kd = kindOf (Proxy @d)
-                 ke = kindOf (Proxy @e)
-                 kf = kindOf (Proxy @f)
-                 kg = kindOf (Proxy @g)
-                 kh = kindOf (Proxy @h)
-                 ki = kindOf (Proxy @i)
-                 kj = kindOf (Proxy @j)
-                 result st = do isSMT <- inSMTMode st
-                                case (isSMT, uiKind) of
-                                  (True, UICodeC (v, _)) -> sbvToSV st (v arg0 arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8)
-                                  _                      -> do nm' <- newUninterpreted st nm mbArgs (SBVType [kj, ki, kh, kg, kf, ke, kd, kc, kb, ka]) =<< retrieveUICode nm st ka uiKind
-                                                               sw0 <- sbvToSV st arg0
-                                                               sw1 <- sbvToSV st arg1
-                                                               sw2 <- sbvToSV st arg2
-                                                               sw3 <- sbvToSV st arg3
-                                                               sw4 <- sbvToSV st arg4
-                                                               sw5 <- sbvToSV st arg5
-                                                               sw6 <- sbvToSV st arg6
-                                                               sw7 <- sbvToSV st arg7
-                                                               sw8 <- sbvToSV st arg8
-                                                               mapM_ forceSVArg [sw0, sw1, sw2, sw3, sw4, sw5, sw6, sw7, sw8]
-                                                               newExpr st ka $ SBVApp (Uninterpreted nm') [sw0, sw1, sw2, sw3, sw4, sw5, sw6, sw7, sw8]
-
--- Functions of ten arguments
-instance (SymVal k, SymVal j, SymVal i, SymVal h, SymVal g, SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, SymVal a, HasKind a)
-            => SMTDefinable (SBV k -> SBV j -> SBV i -> SBV h -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a) where
-  sbv2smt fn = defs2smt $ \k j i h g f e d c b -> fn k j i h g f e d c b .== fn k j i h g f e d c b
-
-  sbvDefineValue nm mbArgs uiKind = f
-    where f arg0 arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9
-           | Just v <- retrieveConstCode uiKind, isConcrete arg0, isConcrete arg1, isConcrete arg2, isConcrete arg3, isConcrete arg4, isConcrete arg5, isConcrete arg6, isConcrete arg7, isConcrete arg8, isConcrete arg9
-           = v arg0 arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9
-           | True
-           = SBV $ SVal ka $ Right $ cache result
-           where ka = kindOf (Proxy @a)
-                 kb = kindOf (Proxy @b)
-                 kc = kindOf (Proxy @c)
-                 kd = kindOf (Proxy @d)
-                 ke = kindOf (Proxy @e)
-                 kf = kindOf (Proxy @f)
-                 kg = kindOf (Proxy @g)
-                 kh = kindOf (Proxy @h)
-                 ki = kindOf (Proxy @i)
-                 kj = kindOf (Proxy @j)
-                 kk = kindOf (Proxy @k)
-                 result st = do isSMT <- inSMTMode st
-                                case (isSMT, uiKind) of
-                                  (True, UICodeC (v, _)) -> sbvToSV st (v arg0 arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9)
-                                  _                      -> do nm' <- newUninterpreted st nm mbArgs (SBVType [kk, kj, ki, kh, kg, kf, ke, kd, kc, kb, ka]) =<< retrieveUICode nm st ka uiKind
-                                                               sw0 <- sbvToSV st arg0
-                                                               sw1 <- sbvToSV st arg1
-                                                               sw2 <- sbvToSV st arg2
-                                                               sw3 <- sbvToSV st arg3
-                                                               sw4 <- sbvToSV st arg4
-                                                               sw5 <- sbvToSV st arg5
-                                                               sw6 <- sbvToSV st arg6
-                                                               sw7 <- sbvToSV st arg7
-                                                               sw8 <- sbvToSV st arg8
-                                                               sw9 <- sbvToSV st arg9
-                                                               mapM_ forceSVArg [sw0, sw1, sw2, sw3, sw4, sw5, sw6, sw7, sw8, sw9]
-                                                               newExpr st ka $ SBVApp (Uninterpreted nm') [sw0, sw1, sw2, sw3, sw4, sw5, sw6, sw7, sw8, sw9]
-
--- Functions of eleven arguments
-instance (SymVal l, SymVal k, SymVal j, SymVal i, SymVal h, SymVal g, SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, SymVal a, HasKind a)
-            => SMTDefinable (SBV l -> SBV k -> SBV j -> SBV i -> SBV h -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a) where
-  sbv2smt fn = defs2smt $ \l k j i h g f e d c b -> fn l k j i h g f e d c b .== fn l k j i h g f e d c b
-
-  sbvDefineValue nm mbArgs uiKind = f
-    where f arg0 arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
-           | Just v <- retrieveConstCode uiKind, isConcrete arg0, isConcrete arg1, isConcrete arg2, isConcrete arg3, isConcrete arg4, isConcrete arg5, isConcrete arg6, isConcrete arg7, isConcrete arg8, isConcrete arg9, isConcrete arg10
-           = v arg0 arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
-           | True
-           = SBV $ SVal ka $ Right $ cache result
-           where ka = kindOf (Proxy @a)
-                 kb = kindOf (Proxy @b)
-                 kc = kindOf (Proxy @c)
-                 kd = kindOf (Proxy @d)
-                 ke = kindOf (Proxy @e)
-                 kf = kindOf (Proxy @f)
-                 kg = kindOf (Proxy @g)
-                 kh = kindOf (Proxy @h)
-                 ki = kindOf (Proxy @i)
-                 kj = kindOf (Proxy @j)
-                 kk = kindOf (Proxy @k)
-                 kl = kindOf (Proxy @l)
-                 result st = do isSMT <- inSMTMode st
-                                case (isSMT, uiKind) of
-                                  (True, UICodeC (v, _)) -> sbvToSV st (v arg0 arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10)
-                                  _                      -> do nm' <- newUninterpreted st nm mbArgs (SBVType [kl, kk, kj, ki, kh, kg, kf, ke, kd, kc, kb, ka]) =<< retrieveUICode nm st ka uiKind
-                                                               sw0  <- sbvToSV st arg0
-                                                               sw1  <- sbvToSV st arg1
-                                                               sw2  <- sbvToSV st arg2
-                                                               sw3  <- sbvToSV st arg3
-                                                               sw4  <- sbvToSV st arg4
-                                                               sw5  <- sbvToSV st arg5
-                                                               sw6  <- sbvToSV st arg6
-                                                               sw7  <- sbvToSV st arg7
-                                                               sw8  <- sbvToSV st arg8
-                                                               sw9  <- sbvToSV st arg9
-                                                               sw10 <- sbvToSV st arg10
-                                                               mapM_ forceSVArg [sw0, sw1, sw2, sw3, sw4, sw5, sw6, sw7, sw8, sw9, sw10]
-                                                               newExpr st ka $ SBVApp (Uninterpreted nm') [sw0, sw1, sw2, sw3, sw4, sw5, sw6, sw7, sw8, sw9, sw10]
-
--- Functions of twelve arguments
-instance (SymVal m, SymVal l, SymVal k, SymVal j, SymVal i, SymVal h, SymVal g, SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, SymVal a, HasKind a)
-            => SMTDefinable (SBV m -> SBV l -> SBV k -> SBV j -> SBV i -> SBV h -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a) where
-  sbv2smt fn = defs2smt $ \m l k j i h g f e d c b -> fn m l k j i h g f e d c b .== fn m l k j i h g f e d c b
-
-  sbvDefineValue nm mbArgs uiKind = f
-    where f arg0 arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10 arg11
-           | Just v <- retrieveConstCode uiKind, isConcrete arg0, isConcrete arg1, isConcrete arg2, isConcrete arg3, isConcrete arg4, isConcrete arg5, isConcrete arg6, isConcrete arg7, isConcrete arg8, isConcrete arg9, isConcrete arg10, isConcrete arg11
-           = v arg0 arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10 arg11
-           | True
-           = SBV $ SVal ka $ Right $ cache result
-           where ka = kindOf (Proxy @a)
-                 kb = kindOf (Proxy @b)
-                 kc = kindOf (Proxy @c)
-                 kd = kindOf (Proxy @d)
-                 ke = kindOf (Proxy @e)
-                 kf = kindOf (Proxy @f)
-                 kg = kindOf (Proxy @g)
-                 kh = kindOf (Proxy @h)
-                 ki = kindOf (Proxy @i)
-                 kj = kindOf (Proxy @j)
-                 kk = kindOf (Proxy @k)
-                 kl = kindOf (Proxy @l)
-                 km = kindOf (Proxy @m)
-                 result st = do isSMT <- inSMTMode st
-                                case (isSMT, uiKind) of
-                                  (True, UICodeC (v, _)) -> sbvToSV st (v arg0 arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10 arg11)
-                                  _                      -> do nm' <- newUninterpreted st nm mbArgs (SBVType [km, kl, kk, kj, ki, kh, kg, kf, ke, kd, kc, kb, ka]) =<< retrieveUICode nm st ka uiKind
-                                                               sw0  <- sbvToSV st arg0
-                                                               sw1  <- sbvToSV st arg1
-                                                               sw2  <- sbvToSV st arg2
-                                                               sw3  <- sbvToSV st arg3
-                                                               sw4  <- sbvToSV st arg4
-                                                               sw5  <- sbvToSV st arg5
-                                                               sw6  <- sbvToSV st arg6
-                                                               sw7  <- sbvToSV st arg7
-                                                               sw8  <- sbvToSV st arg8
-                                                               sw9  <- sbvToSV st arg9
-                                                               sw10 <- sbvToSV st arg10
-                                                               sw11 <- sbvToSV st arg11
-                                                               mapM_ forceSVArg [sw0, sw1, sw2, sw3, sw4, sw5, sw6, sw7, sw8, sw9, sw10, sw11]
-                                                               newExpr st ka $ SBVApp (Uninterpreted nm') [sw0, sw1, sw2, sw3, sw4, sw5, sw6, sw7, sw8, sw9, sw10, sw11]
-
--- Mark the UIKind as uncurried
-mkUncurried :: UIKind a -> UIKind a
-mkUncurried (UIFree  _) = UIFree  False
-mkUncurried (UIFun   a) = UIFun   a
-mkUncurried (UICodeC a) = UICodeC a
-
--- Uncurried functions of two arguments
-instance (SymVal c, SymVal b, SymVal a, HasKind a) => SMTDefinable ((SBV c, SBV b) -> SBV a) where
-  sbv2smt fn                      = defs2smt $ \p -> fn p .== fn p
-  registerFunction                = registerFunction . curry2
-  sbvDefineValue nm mbArgs uiKind = let f = sbvDefineValue nm mbArgs (curry2 <$> mkUncurried uiKind) in uncurry2 f
-
--- Uncurried functions of three arguments
-instance (SymVal d, SymVal c, SymVal b, SymVal a, HasKind a) => SMTDefinable ((SBV d, SBV c, SBV b) -> SBV a) where
-  sbv2smt fn                      = defs2smt $ \p -> fn p .== fn p
-  registerFunction                = registerFunction . curry3
-  sbvDefineValue nm mbArgs uiKind = let f = sbvDefineValue nm mbArgs (curry3 <$> mkUncurried uiKind) in uncurry3 f
-
--- Uncurried functions of four arguments
-instance (SymVal e, SymVal d, SymVal c, SymVal b, SymVal a, HasKind a) => SMTDefinable ((SBV e, SBV d, SBV c, SBV b) -> SBV a) where
-  sbv2smt fn                      = defs2smt $ \p -> fn p .== fn p
-  registerFunction                = registerFunction . curry4
-  sbvDefineValue nm mbArgs uiKind = let f = sbvDefineValue nm mbArgs (curry4 <$> mkUncurried uiKind) in uncurry4 f
-
--- Uncurried functions of five arguments
-instance (SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, SymVal a, HasKind a) => SMTDefinable ((SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) where
-  sbv2smt fn                      = defs2smt $ \p -> fn p .== fn p
-  registerFunction                = registerFunction . curry5
-  sbvDefineValue nm mbArgs uiKind = let f = sbvDefineValue nm mbArgs (curry5 <$> mkUncurried uiKind) in uncurry5 f
-
--- Uncurried functions of six arguments
-instance (SymVal g, SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, SymVal a, HasKind a) => SMTDefinable ((SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) where
-  sbv2smt fn                      = defs2smt $ \p -> fn p .== fn p
-  registerFunction                = registerFunction . curry6
-  sbvDefineValue nm mbArgs uiKind = let f = sbvDefineValue nm mbArgs (curry6 <$> mkUncurried uiKind) in uncurry6 f
-
--- Uncurried functions of seven arguments
-instance (SymVal h, SymVal g, SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, SymVal a, HasKind a) => SMTDefinable ((SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) where
-  sbv2smt fn                      = defs2smt $ \p -> fn p .== fn p
-  registerFunction                = registerFunction . curry7
-  sbvDefineValue nm mbArgs uiKind = let f = sbvDefineValue nm mbArgs (curry7 <$> mkUncurried uiKind) in uncurry7 f
-
--- Uncurried functions of eight arguments
-instance (SymVal i, SymVal h, SymVal g, SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, SymVal a, HasKind a) => SMTDefinable ((SBV i, SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) where
-  sbv2smt fn                      = defs2smt $ \p -> fn p .== fn p
-  registerFunction                = registerFunction . curry8
-  sbvDefineValue nm mbArgs uiKind = let f = sbvDefineValue nm mbArgs (curry8 <$> mkUncurried uiKind) in uncurry8 f
-
--- Uncurried functions of nine arguments
-instance (SymVal j, SymVal i, SymVal h, SymVal g, SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, SymVal a, HasKind a) => SMTDefinable ((SBV j, SBV i, SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) where
-  sbv2smt fn                      = defs2smt $ \p -> fn p .== fn p
-  registerFunction                = registerFunction . curry9
-  sbvDefineValue nm mbArgs uiKind = let f = sbvDefineValue nm mbArgs (curry9 <$> mkUncurried uiKind) in uncurry9 f
-
--- Uncurried functions of ten arguments
-instance (SymVal k, SymVal j, SymVal i, SymVal h, SymVal g, SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, SymVal a, HasKind a) => SMTDefinable ((SBV k, SBV j, SBV i, SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) where
-  sbv2smt fn                      = defs2smt $ \p -> fn p .== fn p
-  registerFunction                = registerFunction . curry10
-  sbvDefineValue nm mbArgs uiKind = let f = sbvDefineValue nm mbArgs (curry10 <$> mkUncurried uiKind) in uncurry10 f
-
--- Uncurried functions of eleven arguments
-instance (SymVal l, SymVal k, SymVal j, SymVal i, SymVal h, SymVal g, SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, SymVal a, HasKind a) => SMTDefinable ((SBV l, SBV k, SBV j, SBV i, SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) where
-  sbv2smt fn                      = defs2smt $ \p -> fn p .== fn p
-  registerFunction                = registerFunction . curry11
-  sbvDefineValue nm mbArgs uiKind = let f = sbvDefineValue nm mbArgs (curry11 <$> mkUncurried uiKind) in uncurry11 f
-
--- Uncurried functions of twelve arguments
-instance (SymVal m, SymVal l, SymVal k, SymVal j, SymVal i, SymVal h, SymVal g, SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, SymVal a, HasKind a) => SMTDefinable ((SBV m, SBV l, SBV k, SBV j, SBV i, SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) where
-  sbv2smt fn                      = defs2smt $ \p -> fn p .== fn p
-  registerFunction                = registerFunction . curry12
-  sbvDefineValue nm mbArgs uiKind = let f = sbvDefineValue nm mbArgs (curry12 <$> mkUncurried uiKind) in uncurry12 f
-
--- | Symbolic computations provide a context for writing symbolic programs.
-instance MonadIO m => SolverContext (SymbolicT m) where
-   constrain                   = imposeConstraint False []               . unSBV . quantifiedBool
-   softConstrain               = imposeConstraint True  []               . unSBV . quantifiedBool
-   namedConstraint        nm   = imposeConstraint False [(":named", nm)] . unSBV . quantifiedBool
-   constrainWithAttribute atts = imposeConstraint False atts             . unSBV . quantifiedBool
-
-   contextState = symbolicEnv
-   setOption o  = addNewSMTOption  o
-
-   internalVariable k = contextState >>= \st -> liftIO $ do
-                           sv <- newInternalVariable st k
-                           pure $ SBV $ SVal k (Right (cache (const (pure sv))))
-
--- | Generalization of 'Data.SBV.assertWithPenalty'
-assertWithPenalty :: MonadSymbolic m => String -> SBool -> Penalty -> m ()
-assertWithPenalty nm o p = addSValOptGoal $ unSBV `fmap` AssertWithPenalty nm o p
-
--- | Class of metrics we can optimize for. Currently, booleans,
--- bounded signed/unsigned bit-vectors, unbounded integers,
--- algebraic reals and floats can be optimized. You can add
--- your instances, but bewared that the 'MetricSpace' should
--- map your type to something the backend solver understands, which
--- are limited to unsigned bit-vectors, reals, and unbounded integers
--- for z3.
---
--- A good reference on these features is given in the following paper:
--- <http://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/nbjorner-scss2014.pdf>.
---
--- Minimal completion: None. However, if @MetricSpace@ is not identical to the type, you want
--- to define 'toMetricSpace'/'annotateForMS', and possibly 'minimize'/'maximize' to add extra constraints as necessary.
-class Metric a where
-  -- | The metric space we optimize the goal over. Usually the same as the type itself, but not always!
-  -- For instance, signed bit-vectors are optimized over their unsigned counterparts, floats are
-  -- optimized over their 'Word32' comparable counterparts, etc.
-  type MetricSpace a :: Type
-  type MetricSpace a = a
-
-  -- | Compute the metric value to optimize.
-  toMetricSpace   :: SBV a -> SBV (MetricSpace a)
-
-  -- | Compute the value itself from the metric corresponding to it.
-  fromMetricSpace :: SBV (MetricSpace a) -> SBV a
-
-  -- | Annotate for the metric space, to clarify the new name. If this result is not identity,
-  -- we will add an sObserve on the original.
-  annotateForMS :: Proxy a -> String -> String
-
-  -- | Minimizing a metric space
-  msMinimize :: (MonadSymbolic m, SolverContext m) => String -> SBV a -> m ()
-  msMinimize nm o = do let nm' = annotateForMS (Proxy @a) nm
-                       when (nm' /= nm) $ sObserve nm (unSBV o)
-                       addSValOptGoal $ unSBV `fmap` Minimize nm' (toMetricSpace o)
-
-  -- | Maximizing a metric space
-  msMaximize :: (MonadSymbolic m, SolverContext m) => String -> SBV a -> m ()
-  msMaximize nm o = do let nm' = annotateForMS (Proxy @a) nm
-                       when (nm' /= nm) $ sObserve nm (unSBV o)
-                       addSValOptGoal $ unSBV `fmap` Maximize nm' (toMetricSpace o)
-
-  -- if MetricSpace is the same, we can give a default definition
-  default toMetricSpace :: (a ~ MetricSpace a) => SBV a -> SBV (MetricSpace a)
-  toMetricSpace = id
-
-  default fromMetricSpace :: (a ~ MetricSpace a) => SBV (MetricSpace a) -> SBV a
-  fromMetricSpace = id
-
-  -- Annotations to indicate if the metric space transition was needed
-  default annotateForMS :: (a ~ MetricSpace a) => Proxy a -> String -> String
-  annotateForMS _ s = s
-
--- Booleans assume True is greater than False
-instance Metric Bool where
-  type MetricSpace Bool = Word8
-  toMetricSpace t   = ite t 1 0
-  fromMetricSpace w = w ./= 0
-  annotateForMS _ s = "toMetricSpace(" ++ s ++ ")"
-
--- | Generalization of 'Data.SBV.minimize'
-minimize :: (Metric a, MonadSymbolic m, SolverContext m) => String -> SBV a -> m ()
-minimize = msMinimize
-
--- | Generalization of 'Data.SBV.maximize'
-maximize :: (Metric a, MonadSymbolic m, SolverContext m) => String -> SBV a -> m ()
-maximize = msMaximize
-
--- Unsigned types, integers, and reals directly optimize
-instance Metric Word8
-instance Metric Word16
-instance Metric Word32
-instance Metric Word64
-instance Metric Integer
-instance Metric AlgReal
-
--- To optimize signed bounded values, we have to adjust to the range
-instance Metric Int8 where
-  type MetricSpace Int8 = Word8
-  toMetricSpace   x = sFromIntegral x + 128  -- 2^7
-  fromMetricSpace x = sFromIntegral x - 128
-  annotateForMS _ s = "toMetricSpace(" ++ s ++ ")"
-
-instance Metric Int16 where
-  type MetricSpace Int16 = Word16
-  toMetricSpace   x = sFromIntegral x + 32768  -- 2^15
-  fromMetricSpace x = sFromIntegral x - 32768
-  annotateForMS _ s = "toMetricSpace(" ++ s ++ ")"
-
-instance Metric Int32 where
-  type MetricSpace Int32 = Word32
-  toMetricSpace   x = sFromIntegral x + 2147483648 -- 2^31
-  fromMetricSpace x = sFromIntegral x - 2147483648
-  annotateForMS _ s = "toMetricSpace(" ++ s ++ ")"
-
-instance Metric Int64 where
-  type MetricSpace Int64 = Word64
-  toMetricSpace   x = sFromIntegral x + 9223372036854775808  -- 2^63
-  fromMetricSpace x = sFromIntegral x - 9223372036854775808
-  annotateForMS _ s = "toMetricSpace(" ++ s ++ ")"
-
--- | Optimizing 'WordN'
-instance (KnownNat n, BVIsNonZero n) => Metric (WordN n)
-
--- | Optimizing 'IntN'
-instance (KnownNat n, BVIsNonZero n) => Metric (IntN n) where
-  type MetricSpace (IntN n) = WordN n
-  toMetricSpace   x = sFromIntegral x + 2 ^ (intOfProxy (Proxy @n) - 1)
-  fromMetricSpace x = sFromIntegral x - 2 ^ (intOfProxy (Proxy @n) - 1)
-  annotateForMS _ s = "toMetricSpace(" ++ s ++ ")"
-
--- Quickcheck interface on symbolic-booleans..
-instance Testable SBool where
-  property (SBV (SVal _ (Left b))) = property (cvToBool b)
-  property s                       = cantQuickCheck $ "Result did not evaluate to a concrete boolean: " ++ show s
-
-instance Testable (Symbolic SBool) where
-   property prop = QC.monadicIO $ do (cond, r, modelVals) <- QC.run test
-                                     QC.pre cond
-                                     unless (r || null modelVals) $ QC.monitor (QC.counterexample (complain modelVals))
-                                     QC.assert r
-     where test = do (r, Result{resTraces=tvals, resObservables=ovals, resConsts=(_, cs), resConstraints=cstrs, resUIConsts=unints}) <- 
-                                 C.catch (runSymbolic defaultSMTCfg (Concrete Nothing) prop)
-                                         (\(e :: C.SomeException) -> cantQuickCheck (show e))
-
-
-                     let cval = fromMaybe (cantQuickCheck "A constraint did not evaluate to a concrete boolean") . (`lookup` cs)
-                         cond = -- Only pick-up "hard" constraints, as indicated by False in the fist component
-                                and [cvToBool (cval v) | (False, _, v) <- F.toList cstrs]
-
-                         getObservable (nm, f, v) = case v `lookup` cs of
-                                                      Just cv -> if f cv then Just (nm, cv) else Nothing
-                                                      Nothing -> cantQuickCheck "An observable did not evaluate to a concrete value"
-
-                     case map fst unints of
-                       [] -> case unliteral r of
-                               Nothing -> cantQuickCheck "The result did not evaluate to a concrete value"
-                               Just b  -> return (cond, b, tvals ++ mapMaybe getObservable ovals)
-                       uis -> cantQuickCheck $ "Uninterpreted constants remain: " ++ unwords uis
-
-           complain qcInfo = showModel defaultSMTCfg (SMTModel [] Nothing qcInfo [])
-
--- Complain if what we got isn't something we can quick-check
-cantQuickCheck :: String -> a
-cantQuickCheck why = error $ unlines [ "*** Data.SBV: Cannot quickcheck the given property."
-                                     , "***"
-                                     , "*** Certain SBV properties cannot be quick-checked. In particular,"
-                                     , "*** SBV can't quick-check in the presence of:"
-                                     , "***"
-                                     , "***   - Uninterpreted constants."
-                                     , "***   - Uninterpreted types."
-                                     , "***   - Floating point operations with rounding modes other than RNE."
-                                     , "***   - Floating point FMA operation, regardless of rounding mode."
-                                     , "***   - Quantified booleans, i.e., uses of Forall/Exists/ExistsUnique."
-                                     , "***   - Uses of quantifiedBool"
-                                     , "***   - Calls to 'observe' (use 'sObserve' instead)"
-                                     , "***"
-                                     , "*** If you can't avoid the above features or run into an issue with"
-                                     , "*** quickcheck even though you haven't used these features, please report this as a bug!"
-                                     , "***"
-                                     , "*** Origin:"
-                                     , "***"
-                                     , why
-                                     ]
-
--- | Quick check an SBV property. Note that a regular @quickCheck@ call will work just as
--- well. Use this variant if you want to receive the boolean result.
-sbvQuickCheck :: Symbolic SBool -> IO Bool
-sbvQuickCheck prop = QC.isSuccess `fmap` QC.quickCheckResult prop
-
--- Quickcheck interface on dynamically-typed values. A run-time check
--- ensures that the value has boolean type.
-instance Testable (Symbolic SVal) where
-  property m = property $ do s <- m
-                             when (kindOf s /= KBool) $ error "Cannot quickcheck non-boolean value"
-                             return (SBV s :: SBool)
-
--- | Explicit sharing combinator. The SBV library has internal caching/hash-consing mechanisms
--- built in, based on Andy Gill's type-safe observable sharing technique (see: <http://ku-fpg.github.io/files/Gill-09-TypeSafeReification.pdf>).
--- However, there might be times where being explicit on the sharing can help, especially in experimental code. The 'slet' combinator
--- ensures that its first argument is computed once and passed on to its continuation, explicitly indicating the intent of sharing. Most
--- use cases of the SBV library should simply use Haskell's @let@ construct for this purpose.
-slet :: forall a b. (HasKind a, HasKind b) => SBV a -> (SBV a -> SBV b) -> SBV b
-slet x f = SBV $ SVal k $ Right $ cache r
-    where k    = kindOf (Proxy @b)
-          r st = do xsv <- sbvToSV st x
-                    let xsbv = SBV $ SVal (kindOf x) (Right (cache (const (return xsv))))
-                        res  = f xsbv
-                    sbvToSV st res
-
--- | Class of things that we can logically reduce to a boolean, by saturating and then asserting equivalance to itself
-class QSaturate m a where
-  qSaturate :: a -> m ()
-
--- | Base case; simple variable in the symbolic monad
-instance SolverContext m => QSaturate m SBool where
-  qSaturate b = constrain $ b .== b
-
--- | Saturate over a universal quantifier
-instance (HasKind a, Monad m, SolverContext m, QSaturate m r) => QSaturate m (Forall nm a -> r) where
-  qSaturate f = qSaturate . f . Forall =<< internalVariable (kindOf (Proxy @a))
-
--- | Saturate over a pair of universal quantifiers
-instance (HasKind a, HasKind b, Monad m, SolverContext m, QSaturate m r) => QSaturate m ((Forall na a, Forall nb b) -> r) where
-  qSaturate = qSaturate . curry
-
--- | Saturate over a pair of existential quantifiers
-instance (HasKind a, HasKind b, Monad m, SolverContext m, QSaturate m r) => QSaturate m ((Exists na a, Exists nb b) -> r) where
-  qSaturate = qSaturate . curry
-
--- | Saturate over a number of universal quantifiers
-instance (KnownNat n, HasKind a, Monad m, SolverContext m, QSaturate m r) => QSaturate m (ForallN n nm a -> r) where
-  qSaturate f = qSaturate . f . ForallN =<< replicateM (intOfProxy (Proxy @n)) (internalVariable (kindOf (Proxy @a)))
-
--- | Saturate over an existential quantifier
-instance (HasKind a, Monad m, SolverContext m, QSaturate m r) => QSaturate m (Exists nm a -> r) where
-  qSaturate f = qSaturate . f . Exists =<< internalVariable (kindOf (Proxy @a))
-
--- | Saturate over an a number of existential quantifiers
-instance (KnownNat n, HasKind a, Monad m, SolverContext m, QSaturate m r) => QSaturate m (ExistsN n nm a -> r) where
-  qSaturate f = qSaturate . f . ExistsN =<< replicateM (intOfProxy (Proxy @n)) (internalVariable (kindOf (Proxy @a)))
-
--- | Saturate over a unique-exists variable
-instance (HasKind a, Monad m, SolverContext m, QSaturate m r) => QSaturate m (ExistsUnique nm a -> r) where
-  qSaturate f = qSaturate . f . ExistsUnique =<< internalVariable (kindOf (Proxy @a))
-
--- | Saturate a predicate, but save/restore observables so they're not messed up.
-qSaturateSavingObservables :: (Monad m, MonadIO m, SolverContext m, QSaturate m a) => a -> m ()
-qSaturateSavingObservables p = do State{rObservables} <- contextState
-                                  curObservables <- liftIO $ readIORef rObservables
-                                  qSaturate p
-                                  liftIO $ writeIORef rObservables curObservables
-
--- | Equality as a proof method. Allows for
--- very concise construction of equivalence proofs, which is very typical in
--- bit-precise proofs.
-infix 4 ===
-class Equality a where
-  (===) :: a -> a -> IO ThmResult
-
-instance {-# OVERLAPPABLE #-} (SymVal a, EqSymbolic z) => Equality (SBV a -> z) where
-  k === l = prove $ \a -> k a .== l a
-
-instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, EqSymbolic z) => Equality (SBV a -> SBV b -> z) where
-  k === l = prove $ \a b -> k a b .== l a b
-
-instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, EqSymbolic z) => Equality ((SBV a, SBV b) -> z) where
-  k === l = prove $ \a b -> k (a, b) .== l (a, b)
-
-instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, SymVal c, EqSymbolic z) => Equality (SBV a -> SBV b -> SBV c -> z) where
-  k === l = prove $ \a b c -> k a b c .== l a b c
-
-instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, SymVal c, EqSymbolic z) => Equality ((SBV a, SBV b, SBV c) -> z) where
-  k === l = prove $ \a b c -> k (a, b, c) .== l (a, b, c)
-
-instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, SymVal c, SymVal d, EqSymbolic z) => Equality (SBV a -> SBV b -> SBV c -> SBV d -> z) where
-  k === l = prove $ \a b c d -> k a b c d .== l a b c d
-
-instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, SymVal c, SymVal d, EqSymbolic z) => Equality ((SBV a, SBV b, SBV c, SBV d) -> z) where
-  k === l = prove $ \a b c d -> k (a, b, c, d) .== l (a, b, c, d)
-
-instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, EqSymbolic z) => Equality (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> z) where
-  k === l = prove $ \a b c d e -> k a b c d e .== l a b c d e
-
-instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, EqSymbolic z) => Equality ((SBV a, SBV b, SBV c, SBV d, SBV e) -> z) where
-  k === l = prove $ \a b c d e -> k (a, b, c, d, e) .== l (a, b, c, d, e)
-
-instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, SymVal f, EqSymbolic z) => Equality (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> z) where
-  k === l = prove $ \a b c d e f -> k a b c d e f .== l a b c d e f
-
-instance {-# OVERLAPPABLE #-}
- (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, SymVal f, EqSymbolic z) => Equality ((SBV a, SBV b, SBV c, SBV d, SBV e, SBV f) -> z) where
-  k === l = prove $ \a b c d e f -> k (a, b, c, d, e, f) .== l (a, b, c, d, e, f)
-
-instance {-# OVERLAPPABLE #-}
- (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, SymVal f, SymVal g, EqSymbolic z) => Equality (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV g -> z) where
-  k === l = prove $ \a b c d e f g -> k a b c d e f g .== l a b c d e f g
-
-instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, SymVal f, SymVal g, EqSymbolic z) => Equality ((SBV a, SBV b, SBV c, SBV d, SBV e, SBV f, SBV g) -> z) where
-  k === l = prove $ \a b c d e f g -> k (a, b, c, d, e, f, g) .== l (a, b, c, d, e, f, g)
-
--- | Reading a value from an array.
-readArray :: forall key val. (Eq key, SymVal key, SymVal val, HasKind val) => SArray key val -> SBV key -> SBV val
-readArray array key
-   | eqCheckIsObjectEq ka, Just (ArrayModel tbl def) <- unliteral array, Just k <- unliteral key
-   = literal $ fromMaybe def (k `lookup` tbl) -- return the first value, since we don't bother deleting previous writes
-   | True
-   = symRes
-   where symRes = SBV . SVal kb . Right $ cache g
-         ka = kindOf (Proxy @key)
-         kb = kindOf (Proxy @val)
-         g st = do f <- sbvToSV st array
-                   k <- sbvToSV st key
-                   newExpr st kb (SBVApp ReadArray [f, k])
-
--- | Writing a value to an array. For the concrete case, we don't bother deleting earlier entries, we keep a history. The earlier a value is in the list, the "later" it happened; in a stack fashion.
-writeArray :: forall key val. (HasKind key, SymVal key, SymVal val, HasKind val) => SArray key val -> SBV key -> SBV val -> SArray key val
-writeArray array key value
-   | Just (ArrayModel tbl def) <- unliteral array, Just keyVal <- unliteral key, Just val <- unliteral value
-   = literal $ ArrayModel ((keyVal, val) : tbl) def  -- It's important that we "cons" the value here, since it takes precedence in a read
-   | True
-   = SBV . SVal k . Right $ cache g
-   where k  = KArray (kindOf (Proxy @key)) (kindOf (Proxy @val))
-
-         g st = do arr    <- sbvToSV st array
-                   keyVal <- sbvToSV st key
-                   val    <- sbvToSV st value
-                   newExpr st k (SBVApp WriteArray [arr, keyVal, val])
-
--- | Using a lambda as an array.
-lambdaArray :: forall a b. (SymVal a, HasKind b) => (SBV a -> SBV b) -> SArray a b
-lambdaArray f = SBV . SVal k . Right $ cache g
-  where k = KArray (kindOf (Proxy @a)) (kindOf (Proxy @b))
-
-        g st = do def <- lambdaStr st TopLevel (kindOf (Proxy @b)) f
-                  newExpr st k (SBVApp (ArrayLambda def) [])
-
--- | Turn a constant association-list and a default into a symbolic array.
-listArray :: (SymVal a, SymVal b) => [(a, b)] -> b -> SArray a b
-listArray ascs def = literal $ ArrayModel ascs def
-
--- | Create a closure, wrapping the free variables together with the function. When using higher-order functions
--- in SBV (like map), the function passed must be closed, i.e., not have any free variables. If you need to call
--- such a function with a function capturing a free variable, you should create a closure instead.
-data Closure env a = Closure { closureEnv :: env
-                             , closureFun :: env -> a
-                             }
-
--- | Define a higher-order function. Similar to 'smtFunction', but when we have a higher-order argument. Note that
--- the higher-order argument cannot have free variables. Also, if the function is recursive, you should call
--- the first argument of the defining function, which SBV uses to tie the recursive knot. (Note that recursive
--- functions defined via 'smtFunction' don't have this latter requirement as they can figure out the recursion
--- automatically. Higher-order functions, unfortunately, can't do this: They firstify their high-order argument,
--- giving the whole function a unique name; captured via the call to the recursive definition.)
-smtHOFunction :: forall a b f.
-                 ( SMTDefinable (a -> SBV b)
-                 , Lambda Symbolic f
-                 , Lambda Symbolic (a -> SBV b)
-                 , HasKind b
-                 , HasKind f
-                 , Typeable a
-                 , Typeable b
-                 , Typeable f
-                 ) => String       -- prefix to use
-                   -> f            -- The higher-order argument. We're very generic here!
-                   -> (a -> SBV b) -- The ho-function we're modeling
-                   ->  a -> SBV b  -- The resulting function, that can be used as is, and will be rendered in SMTLib without unfolding
-smtHOFunction nm f hof arg = SBV $ SVal (kindOf (Proxy @(SBV b))) $ Right $ cache r
-  where r st = do SMTLambda lam <- lambdaStr st HigherOrderArg (resKindOf (kindOf (Proxy @f))) f
-                  let uniqLen = firstifyUniqueLen $ stCfg st
-                      uniq    = take uniqLen (BC.unpack (B.encode (hash (BC.pack (unwords (words lam))))))
-                  sbvToSV st (smtFunction (atProxy (Proxy @f) nm <> "_" <> uniq) hof arg)
-
-        -- we get the functions as arrays here, so chase to find the result
-        resKindOf (KArray _ k) = resKindOf k
-        resKindOf k            = k
-
-{- HLint ignore module "Reduce duplication"   -}
-{- HLint ignore module "Eta reduce"           -}
-{- HLint ignore module "Avoid NonEmpty.unzip" -}
-{- HLint ignore module "Redundant id"         -}
+{-# LANGUAGE AllowAmbiguousTypes     #-}
+{-# LANGUAGE BangPatterns            #-}
+{-# LANGUAGE CPP                     #-}
+{-# LANGUAGE DataKinds               #-}
+{-# LANGUAGE DefaultSignatures       #-}
+{-# LANGUAGE DeriveFunctor           #-}
+{-# LANGUAGE FlexibleContexts        #-}
+{-# LANGUAGE FlexibleInstances       #-}
+{-# LANGUAGE GADTs                   #-}
+{-# LANGUAGE MultiParamTypeClasses   #-}
+{-# LANGUAGE NamedFieldPuns          #-}
+{-# LANGUAGE OverloadedStrings       #-}
+{-# LANGUAGE RankNTypes              #-}
+{-# LANGUAGE ScopedTypeVariables     #-}
+{-# LANGUAGE TypeApplications        #-}
+{-# LANGUAGE TypeFamilies            #-}
+{-# LANGUAGE TypeOperators           #-}
+{-# LANGUAGE UndecidableInstances    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
+
+module Data.SBV.Core.Model (
+    Mergeable(..), Equality(..), EqSymbolic(..), OrdSymbolic(..)
+  , Zero(..), MeasureOf, Measure(..), MeasureHelper(..)
+  , ContractOf, smtFunction, smtFunctionWithMeasure, smtFunctionWithContract, smtProductiveFunction, smtFunctionNoTermination
+  , checkMutualGroup
+  , SDivisible(..), SMTDefinable(..), QSaturate, qSaturateSavingObservables
+  , Metric(..), minimize, maximize, assertWithPenalty, SIntegral, SFiniteBits(..)
+  , ite, iteLazy, sFromIntegral, sShiftLeft, sShiftRight, sRotateLeft, sBarrelRotateLeft, sRotateRight, sBarrelRotateRight, sSignedShiftArithRight, (.^), (.**)
+  , some
+  , oneIf, genVar, genVar_
+  , pbAtMost, pbAtLeast, pbExactly, pbLe, pbGe, pbEq, pbMutexed, pbStronglyMutexed
+  , sBool, sBool_, sBools, sWord8, sWord8_, sWord8s, sWord16, sWord16_, sWord16s, sWord32, sWord32_, sWord32s
+  , sWord64, sWord64_, sWord64s, sInt8, sInt8_, sInt8s, sInt16, sInt16_, sInt16s, sInt32, sInt32_, sInt32s, sInt64, sInt64_
+  , sInt64s, sInteger, sInteger_, sIntegers, sReal, sReal_, sReals, sFloat, sFloat_, sFloats, sDouble, sDouble_, sDoubles
+  , sWord, sWord_, sWords, sInt, sInt_, sInts
+  , sFPHalf, sFPHalf_, sFPHalfs, sFPBFloat, sFPBFloat_, sFPBFloats, sFPSingle, sFPSingle_, sFPSingles, sFPDouble, sFPDouble_, sFPDoubles, sFPQuad, sFPQuad_, sFPQuads, sArray, sArray_, sArrays
+  , sFloatingPoint, sFloatingPoint_, sFloatingPoints
+  , sRoundNearestTiesToEven, sRoundNearestTiesToAway, sRoundTowardPositive, sRoundTowardNegative, sRoundTowardZero
+  , sRNE, sRNA, sRTP, sRTN, sRTZ
+  , sCaseRoundingMode
+  , sChar, sChar_, sChars, sString, sString_, sStrings, sList, sList_, sLists
+  , sRational, sRational_, sRationals
+  , SymTuple, sTuple, sTuple_, sTuples
+  , sSet, sSet_, sSets
+  , sEDivMod, sEDiv, sEMod
+  , sDivides
+  , solve
+  , slet
+  , sRealToSIntegerFloor, sRealToSIntegerCeiling, sRealToSIntegerTruncate
+  , sRealToSIntegerRoundAway, sRealToSIntegerRoundToEven, sRealToSIntegerRM
+  , label, observe, observeIf, sObserve
+  , sAssert
+  , liftQRem, liftDMod, symbolicMergeWithKind
+  , genLiteral, genFromCV, genMkSymVar
+  , zeroExtend, signExtend
+  , sbvQuickCheck
+  , readArray, writeArray, constArray, freeArray, lambdaArray, listArray
+  , FromSized, ToSized, FromSizedBV(..), ToSizedBV(..)
+  , smtHOFunction, smtHOFunctionWithMeasure, Closure(..)
+  )
+  where
+
+import Control.Applicative    (ZipList(ZipList))
+import Control.Monad          (when, unless, mplus, replicateM)
+import Control.Monad.IO.Class (MonadIO, liftIO)
+
+import qualified Control.Exception as C
+
+import GHC.Generics (M1(..), U1(..), (:*:)(..), K1(..))
+import qualified GHC.Generics as G
+
+import GHC.Stack
+import GHC.TypeLits hiding(SChar)
+
+import Data.Array  (Array, Ix, elems, bounds, rangeSize)
+import qualified Data.Array as DA (listArray)
+
+import Data.Bifunctor (first)
+
+import Data.Bits   (Bits(..))
+import Data.Int    (Int8, Int16, Int32, Int64)
+import Data.Kind   (Type, Constraint)
+import Data.List   (genericLength, genericIndex, genericTake, unzip4, unzip5, unzip6, unzip7
+                   , intercalate, dropWhileEnd, isPrefixOf, partition, nubBy
+#if !MIN_VERSION_base(4,20,0)
+                   , foldl'
+#endif
+                   )
+import Data.Maybe  (fromMaybe, mapMaybe, isJust)
+import Data.String (IsString(..))
+import Data.Word   (Word8, Word16, Word32, Word64)
+
+import Data.List.NonEmpty (NonEmpty(..))
+import qualified Data.List.NonEmpty as NE
+
+import qualified Data.Set as Set
+import qualified Data.Graph as DG
+
+import Data.Proxy
+import Data.Dynamic (fromDynamic, toDyn, Typeable)
+
+import Test.QuickCheck                         (Testable(..), Arbitrary(..))
+import qualified Test.QuickCheck.Test    as QC (isSuccess)
+import qualified Test.QuickCheck         as QC (quickCheckResult, counterexample)
+import qualified Test.QuickCheck.Monadic as QC (monadicIO, run, assert, pre, monitor)
+
+import qualified Data.Foldable as F (toList, for_)
+import qualified Data.Map.Strict as Map
+import qualified Data.Sequence as Seq
+import qualified Data.Text as T
+
+import Data.SBV.Core.AlgReals
+import Data.SBV.Core.Sized
+import Data.SBV.Core.SizedFloats
+import Data.SBV.Core.Data hiding (Constraint)
+import Data.SBV.Core.Symbolic
+import Data.SBV.Core.Operations
+import Data.SBV.Core.Kind
+import Data.SBV.Lambda
+import Data.SBV.Utils.ExtractIO (ExtractIO)
+
+import Data.SBV.Provers.Prover (defaultSMTCfg, SafeResult(..), defs2smt, prove, proveWith)
+import Data.SBV.SMT.SMT        (ThmResult(..), showModel)
+import Data.SBV.SMT.Utils      (debug)
+
+import Data.SBV.Utils.Numeric (fpIsEqualObjectH, roundAway)
+
+import Data.IORef (readIORef, writeIORef, modifyIORef')
+import System.Mem.StableName (makeStableName, hashStableName)
+import Data.SBV.Utils.Lib
+
+import Data.Char
+
+import System.FilePath (dropExtension, takeExtension)
+
+-- Symbolic-Word class instances
+
+import Crypto.Hash.SHA512 (hash)
+import qualified Data.ByteString.Base16 as B
+import qualified Data.ByteString.Char8  as BC
+
+-- | Generate a variable, named
+genVar :: MonadSymbolic m => VarContext -> Kind -> String -> m (SBV a)
+genVar q k = mkSymSBV q k . Just
+
+-- | Generate an unnamed variable
+genVar_ :: MonadSymbolic m => VarContext -> Kind -> m (SBV a)
+genVar_ q k = mkSymSBV q k Nothing
+
+-- | Generate a finite constant bitvector
+genLiteral :: Integral a => Kind -> a -> SBV b
+genLiteral k = SBV . SVal k . Left . mkConstCV k
+
+-- | Convert a constant to an integral value
+genFromCV :: Integral a => CV -> a
+genFromCV (CV _ (CInteger x)) = fromInteger x
+genFromCV c                   = error $ "genFromCV: Unsupported non-integral value: " ++ show c
+
+-- | Generalization of 'Data.SBV.genMkSymVar'
+genMkSymVar :: MonadSymbolic m => Kind -> VarContext -> Maybe String -> m (SBV a)
+genMkSymVar k mbq Nothing  = genVar_ mbq k
+genMkSymVar k mbq (Just s) = genVar  mbq k s
+
+instance SymVal Bool where
+  mkSymVal = genMkSymVar KBool
+  literal  = SBV . svBool
+  fromCV   = cvToBool
+
+instance SymVal Word8 where
+  mkSymVal = genMkSymVar (KBounded False 8)
+  literal  = genLiteral  (KBounded False 8)
+  fromCV   = genFromCV
+
+instance SymVal Int8 where
+  mkSymVal = genMkSymVar (KBounded True 8)
+  literal  = genLiteral  (KBounded True 8)
+  fromCV   = genFromCV
+
+instance SymVal Word16 where
+  mkSymVal = genMkSymVar (KBounded False 16)
+  literal  = genLiteral  (KBounded False 16)
+  fromCV   = genFromCV
+
+instance SymVal Int16 where
+  mkSymVal = genMkSymVar (KBounded True 16)
+  literal  = genLiteral  (KBounded True 16)
+  fromCV   = genFromCV
+
+instance SymVal Word32 where
+  mkSymVal = genMkSymVar (KBounded False 32)
+  literal  = genLiteral  (KBounded False 32)
+  fromCV   = genFromCV
+
+instance SymVal Int32 where
+  mkSymVal = genMkSymVar (KBounded True 32)
+  literal  = genLiteral  (KBounded True 32)
+  fromCV   = genFromCV
+
+instance SymVal Word64 where
+  mkSymVal = genMkSymVar (KBounded False 64)
+  literal  = genLiteral  (KBounded False 64)
+  fromCV   = genFromCV
+
+instance SymVal Int64 where
+  mkSymVal = genMkSymVar (KBounded True 64)
+  literal  = genLiteral  (KBounded True 64)
+  fromCV   = genFromCV
+
+instance SymVal Integer where
+  mkSymVal    = genMkSymVar KUnbounded
+  literal     = SBV . SVal KUnbounded . Left . mkConstCV KUnbounded
+  fromCV      = genFromCV
+  minMaxBound = Nothing
+
+instance SymVal Rational where
+  mkSymVal                    = genMkSymVar KRational
+  literal                     = SBV . SVal KRational  . Left . CV KRational . CRational
+  fromCV (CV _ (CRational r)) = r
+  fromCV c                    = error $ "SymVal.Rational: Unexpected non-rational value: " ++ show c
+  minMaxBound                 = Nothing
+
+instance SymVal AlgReal where
+  mkSymVal                   = genMkSymVar KReal
+  literal                    = SBV . SVal KReal . Left . CV KReal . CAlgReal
+  fromCV (CV _ (CAlgReal a)) = a
+  fromCV c                   = error $ "SymVal.AlgReal: Unexpected non-real value: " ++ show c
+  minMaxBound               = Nothing
+
+  -- AlgReal needs its own definition of isConcretely
+  -- to make sure we avoid using unimplementable Haskell functions
+  isConcretely (SBV (SVal KReal (Left (CV KReal (CAlgReal v))))) p
+     | isExactRational v = p v
+  isConcretely _ _       = False
+
+instance SymVal Float where
+  mkSymVal                 = genMkSymVar KFloat
+  literal                  = SBV . SVal KFloat . Left . CV KFloat . CFloat
+  fromCV (CV _ (CFloat a)) = a
+  fromCV c                 = error $ "SymVal.Float: Unexpected non-float value: " ++ show c
+  minMaxBound              = Nothing
+
+  -- For Float, we conservatively return 'False' for isConcretely. The reason is that
+  -- this function is used for optimizations when only one of the argument is concrete,
+  -- and in the presence of NaN's it would be incorrect to do any optimization
+  isConcretely _ _ = False
+
+instance SymVal Double where
+  mkSymVal                  = genMkSymVar KDouble
+  literal                   = SBV . SVal KDouble . Left . CV KDouble . CDouble
+  fromCV (CV _ (CDouble a)) = a
+  fromCV c                  = error $ "SymVal.Double: Unexpected non-double value: " ++ show c
+  minMaxBound               = Nothing
+
+  -- For Double, we conservatively return 'False' for isConcretely. The reason is that
+  -- this function is used for optimizations when only one of the argument is concrete,
+  -- and in the presence of NaN's it would be incorrect to do any optimization
+  isConcretely _ _ = False
+
+instance SymVal RoundingMode where
+  literal = SBV . svRoundingMode
+  fromCV c =
+    case cvAsRoundingMode c of
+      Just mode -> mode
+      Nothing   -> error $ "SymVal.RoundingMode: Unexpected non-rounding mode value: " ++ show c
+
+-- | Symbolic variant of 'RoundNearestTiesToEven'
+sRoundNearestTiesToEven :: SRoundingMode
+sRoundNearestTiesToEven = literal RoundNearestTiesToEven
+
+-- | Symbolic variant of 'RoundNearestTiesToAway'
+sRoundNearestTiesToAway :: SRoundingMode
+sRoundNearestTiesToAway = literal RoundNearestTiesToAway
+
+-- | Symbolic variant of 'RoundTowardPositive'
+sRoundTowardPositive :: SRoundingMode
+sRoundTowardPositive = literal RoundTowardPositive
+
+-- | Symbolic variant of 'RoundTowardNegative'
+sRoundTowardNegative :: SRoundingMode
+sRoundTowardNegative = literal RoundTowardNegative
+
+-- | Symbolic variant of 'RoundTowardZero'
+sRoundTowardZero :: SRoundingMode
+sRoundTowardZero = literal RoundTowardZero
+
+-- | Alias for 'sRoundNearestTiesToEven'
+sRNE :: SRoundingMode
+sRNE = sRoundNearestTiesToEven
+
+-- | Alias for 'sRoundNearestTiesToAway'
+sRNA :: SRoundingMode
+sRNA = sRoundNearestTiesToAway
+
+-- | Alias for 'sRoundTowardPositive'
+sRTP :: SRoundingMode
+sRTP = sRoundTowardPositive
+
+-- | Alias for 'sRoundTowardNegative'
+sRTN :: SRoundingMode
+sRTN = sRoundTowardNegative
+
+-- | Alias for 'sRoundTowardZero'
+sRTZ :: SRoundingMode
+sRTZ = sRoundTowardZero
+
+-- | Case analyzer for the type 'RoundingMode'.
+sCaseRoundingMode ::
+  Mergeable r => r              -- ^ What to return in the 'sRoundNearestTiesToEven' case.
+              -> r              -- ^ What to return in the 'sRoundNearestTiesToAway' case.
+              -> r              -- ^ What to return in the 'sRoundTowardPositive' case.
+              -> r              -- ^ What to return in the 'sRoundTowardNegative' case.
+              -> r              -- ^ What to return in the 'sRoundTowardZero' case.
+              -> SRoundingMode
+              -> r
+sCaseRoundingMode fRNE fRNA fRTP fRTN fRTZ rm =
+  ite (rm .== sRNE) fRNE $
+  ite (rm .== sRNA) fRNA $
+  ite (rm .== sRTP) fRTP $
+  ite (rm .== sRTN) fRTN
+                    fRTZ
+
+
+instance SymVal Char where
+  mkSymVal                = genMkSymVar KChar
+  literal c               = SBV . SVal KChar . Left . CV KChar $ CChar c
+  fromCV (CV _ (CChar a)) = a
+  fromCV c                = error $ "SymVal.String: Unexpected non-char value: " ++ show c
+
+instance SymVal a => SymVal [a] where
+  mkSymVal
+    | isKString @[a] undefined = genMkSymVar KString
+    | True                     = genMkSymVar (KList (kindOf (Proxy @a)))
+
+  literal as
+    | isKString @[a] undefined = case fromDynamic (toDyn as) of
+                                   Just s  -> SBV . SVal KString . Left . CV KString . CString $ s
+                                   Nothing -> error "SString: Cannot construct literal string!"
+    | True                     = let k = KList (kindOf (Proxy @a))
+                                 in SBV $ SVal k $ Left $ CV k $ CList $ map toCV as
+
+  fromCV (CV _ (CString a)) = fromMaybe (error "SString: Cannot extract a literal string!")
+                                        (fromDynamic (toDyn a))
+  fromCV (CV _ (CList a))   = fromCV . CV (kindOf (Proxy @a)) <$> a
+  fromCV c                  = error $ "SymVal.fromCV: Unexpected non-list value: " ++ show c
+
+  minMaxBound               = Nothing
+
+instance ValidFloat eb sb => HasKind (FloatingPoint eb sb) where
+  kindOf _ = KFP (intOfProxy (Proxy @eb)) (intOfProxy (Proxy @sb))
+
+instance ValidFloat eb sb => SymVal (FloatingPoint eb sb) where
+  mkSymVal                   = genMkSymVar (KFP (intOfProxy (Proxy @eb)) (intOfProxy (Proxy @sb)))
+  literal (FloatingPoint r)  = let k = KFP (intOfProxy (Proxy @eb)) (intOfProxy (Proxy @sb))
+                               in SBV $ SVal k $ Left $ CV k (CFP r)
+  fromCV  (CV _ (CFP r))     = FloatingPoint r
+  fromCV  c                  = error $ "SymVal.FPR: Unexpected non-arbitrary-precision value: " ++ show c
+  minMaxBound                = Nothing
+
+-- | 'SymVal' instance for 'WordN'
+instance (KnownNat n, BVIsNonZero n) => SymVal (WordN n) where
+   literal  x = genLiteral  (kindOf x) x
+   mkSymVal   = genMkSymVar (kindOf (undefined :: WordN n))
+   fromCV     = genFromCV
+
+-- | 'SymVal' instance for 'IntN'
+instance (KnownNat n, BVIsNonZero n) => SymVal (IntN n) where
+   literal  x = genLiteral  (kindOf x) x
+   mkSymVal   = genMkSymVar (kindOf (undefined :: IntN n))
+   fromCV     = genFromCV
+
+toCV :: SymVal a => a -> CVal
+toCV a = case literal a of
+           SBV (SVal _ (Left cv)) -> cvVal cv
+           _                      -> error "SymVal.toCV: Impossible happened, couldn't produce a concrete value"
+
+mkCVTup :: Int -> Kind -> [CVal] -> SBV a
+mkCVTup i k@(KTuple ks) cs
+  | lks == lcs && lks == i
+  = SBV $ SVal k $ Left $ CV k $ CTuple cs
+  | True
+  = error $ "SymVal.mkCVTup: Impossible happened. Malformed tuple received: " ++ show (i, k)
+   where lks = length ks
+         lcs = length cs
+mkCVTup i k _
+  = error $ "SymVal.mkCVTup: Impossible happened. Non-tuple received: " ++ show (i, k)
+
+fromCVTup :: Int -> CV -> [CV]
+fromCVTup i inp@(CV (KTuple ks) (CTuple cs))
+   | lks == lcs && lks == i
+   = zipWith CV ks cs
+   | True
+   = error $ "SymVal.fromCTup: Impossible happened. Malformed tuple received: " ++ show (i, inp)
+   where lks = length ks
+         lcs = length cs
+fromCVTup i inp = error $ "SymVal.fromCVTup: Impossible happened. Non-tuple received: " ++ show (i, inp)
+
+instance (HasKind a, HasKind b, SymVal a, SymVal b) => SymVal (ArrayModel a b) where
+  mkSymVal = genMkSymVar (KArray (kindOf (Proxy @a)) (kindOf (Proxy @b)))
+
+  -- If the table has duplicate entries for keys, then the first one takes precedence.
+  -- That is, [(a, v1), (a, v2)] is equivalent to [(a, v1)]. The best way to think about
+  -- this is as a "stack" of writes. [(a, v1), (a, v2)] means we first "wrote" v2 at
+  -- a, and then wrote v1 at the same address; so the first write of v2 got overwritten.
+  literal (ArrayModel tbl def) = SBV . SVal knd . Left . CV knd $ CArray $ ArrayModel [(toCV k, toCV v) | (k, v) <- tbl] (toCV def)
+    where knd = kindOf (Proxy @(ArrayModel a b))
+
+  fromCV (CV (KArray k1 k2) (CArray (ArrayModel assocs def))) = ArrayModel [(fromCV (CV k1 a), fromCV (CV k2 b)) | (a, b) <- assocs]
+                                                                           (fromCV (CV k2 def))
+
+  fromCV bad = error $ "SymVal.fromCV (SArray): Malformed array received: " ++ show bad
+
+  minMaxBound = Nothing
+
+instance (Arbitrary a, Arbitrary b) => Arbitrary (ArrayModel a b) where
+  arbitrary = ArrayModel <$> arbitrary <*> arbitrary
+
+instance (Ord a, SymVal a) => SymVal (RCSet a) where
+  mkSymVal = genMkSymVar (kindOf (Proxy @(RCSet a)))
+
+  literal eur = SBV $ SVal k $ Left $ CV k $ CSet $ dir $ Set.map toCV s
+    where (dir, s) = case eur of
+                      RegularSet x    -> (RegularSet,    x)
+                      ComplementSet x -> (ComplementSet, x)
+          k        = kindOf (Proxy @(RCSet a))
+
+  fromCV (CV (KSet a) (CSet (RegularSet    s))) = RegularSet    $ Set.map (fromCV . CV a) s
+  fromCV (CV (KSet a) (CSet (ComplementSet s))) = ComplementSet $ Set.map (fromCV . CV a) s
+  fromCV bad                                    = error $ "SymVal.fromCV (Set): Malformed set received: " ++ show bad
+
+  minMaxBound = Nothing
+
+-- | SymVal for 0-tuple (i.e., unit)
+instance SymVal () where
+  mkSymVal   = genMkSymVar (KTuple [])
+  literal () = mkCVTup 0   (kindOf (Proxy @())) []
+  fromCV cv  = fromCVTup 0 cv `seq` ()
+
+-- | SymVal for 2-tuples
+instance (SymVal a, SymVal b) => SymVal (a, b) where
+   mkSymVal         = genMkSymVar (kindOf (Proxy @(a, b)))
+   literal (v1, v2) = mkCVTup 2   (kindOf (Proxy @(a, b))) [toCV v1, toCV v2]
+   fromCV  cv       = case fromCVTup 2 cv of
+                        [v1, v2] -> (fromCV v1, fromCV v2)
+                        res      -> error $ "Data.SBV.SymVal-Tuple2: Unexpected result: " ++ show res
+
+   minMaxBound = Nothing
+
+-- | SymVal for 3-tuples
+instance (SymVal a, SymVal b, SymVal c) => SymVal (a, b, c) where
+   mkSymVal             = genMkSymVar (kindOf (Proxy @(a, b, c)))
+   literal (v1, v2, v3) = mkCVTup 3   (kindOf (Proxy @(a, b, c))) [toCV v1, toCV v2, toCV v3]
+   fromCV  cv           = case fromCVTup 3 cv of
+                            [v1, v2, v3] -> (fromCV v1, fromCV v2, fromCV v3)
+                            res          -> error $ "Data.SBV.SymVal-Tuple3: Unexpected result: " ++ show res
+   minMaxBound          = Nothing
+
+-- | SymVal for 4-tuples
+instance (SymVal a, SymVal b, SymVal c, SymVal d) => SymVal (a, b, c, d) where
+   mkSymVal                 = genMkSymVar (kindOf (Proxy @(a, b, c, d)))
+   literal (v1, v2, v3, v4) = mkCVTup 4   (kindOf (Proxy @(a, b, c, d))) [toCV v1, toCV v2, toCV v3, toCV v4]
+   fromCV  cv               = case fromCVTup 4 cv of
+                                [v1, v2, v3, v4] -> (fromCV v1, fromCV v2, fromCV v3, fromCV v4)
+                                res              -> error $ "Data.SBV.SymVal-Tuple4: Unexpected result: " ++ show res
+   minMaxBound              = Nothing
+
+-- | SymVal for 5-tuples
+instance (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e) => SymVal (a, b, c, d, e) where
+   mkSymVal                     = genMkSymVar (kindOf (Proxy @(a, b, c, d, e)))
+   literal (v1, v2, v3, v4, v5) = mkCVTup 5   (kindOf (Proxy @(a, b, c, d, e))) [toCV v1, toCV v2, toCV v3, toCV v4, toCV v5]
+   fromCV  cv                   = case fromCVTup 5 cv of
+                                    [v1, v2, v3, v4, v5] -> (fromCV v1, fromCV v2, fromCV v3, fromCV v4, fromCV v5)
+                                    res                  -> error $ "Data.SBV.SymVal-Tuple5: Unexpected result: " ++ show res
+   minMaxBound                  = Nothing
+
+-- | SymVal for 6-tuples
+instance (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, SymVal f) => SymVal (a, b, c, d, e, f) where
+   mkSymVal                         = genMkSymVar (kindOf (Proxy @(a, b, c, d, e, f)))
+   literal (v1, v2, v3, v4, v5, v6) = mkCVTup 6   (kindOf (Proxy @(a, b, c, d, e, f))) [toCV v1, toCV v2, toCV v3, toCV v4, toCV v5, toCV v6]
+   fromCV  cv                       = case fromCVTup 6 cv of
+                                        [v1, v2, v3, v4, v5, v6] -> (fromCV v1, fromCV v2, fromCV v3, fromCV v4, fromCV v5, fromCV v6)
+                                        res                      -> error $ "Data.SBV.SymVal-Tuple6: Unexpected result: " ++ show res
+   minMaxBound                      = Nothing
+
+-- | SymVal for 7-tuples
+instance (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, SymVal f, SymVal g) => SymVal (a, b, c, d, e, f, g) where
+   mkSymVal                             = genMkSymVar (kindOf (Proxy @(a, b, c, d, e, f, g)))
+   literal (v1, v2, v3, v4, v5, v6, v7) = mkCVTup 7   (kindOf (Proxy @(a, b, c, d, e, f, g))) [toCV v1, toCV v2, toCV v3, toCV v4, toCV v5, toCV v6, toCV v7]
+   fromCV  cv                           = case fromCVTup 7 cv of
+                                            [v1, v2, v3, v4, v5, v6, v7] -> (fromCV v1, fromCV v2, fromCV v3, fromCV v4, fromCV v5, fromCV v6, fromCV v7)
+                                            res                          -> error $ "Data.SBV.SymVal-Tuple7: Unexpected result: " ++ show res
+   minMaxBound                          = Nothing
+
+-- | SymVal for 8-tuples
+instance (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, SymVal f, SymVal g, SymVal h) => SymVal (a, b, c, d, e, f, g, h) where
+   mkSymVal                                 = genMkSymVar (kindOf (Proxy @(a, b, c, d, e, f, g, h)))
+   literal (v1, v2, v3, v4, v5, v6, v7, v8) = mkCVTup 8   (kindOf (Proxy @(a, b, c, d, e, f, g, h))) [toCV v1, toCV v2, toCV v3, toCV v4, toCV v5, toCV v6, toCV v7, toCV v8]
+   fromCV  cv                               = case fromCVTup 8 cv of
+                                                [v1, v2, v3, v4, v5, v6, v7, v8] -> (fromCV v1, fromCV v2, fromCV v3, fromCV v4, fromCV v5, fromCV v6, fromCV v7, fromCV v8)
+                                                res                              -> error $ "Data.SBV.SymVal-Tuple8: Unexpected result: " ++ show res
+   minMaxBound                              = Nothing
+
+instance IsString SString where
+  fromString = literal
+
+------------------------------------------------------------------------------------
+-- * Smart constructors for creating symbolic values. These are not strictly
+-- necessary, as they are mere aliases for 'symbolic' and 'symbolics', but
+-- they nonetheless make programming easier.
+------------------------------------------------------------------------------------
+
+-- | Generalization of 'Data.SBV.sBool'
+sBool :: MonadSymbolic m => String -> m SBool
+sBool = symbolic
+
+-- | Generalization of 'Data.SBV.sBool_'
+sBool_ :: MonadSymbolic m => m SBool
+sBool_ = free_
+
+-- | Generalization of 'Data.SBV.sBools'
+sBools :: MonadSymbolic m => [String] -> m [SBool]
+sBools = symbolics
+
+-- | Generalization of 'Data.SBV.sWord8'
+sWord8 :: MonadSymbolic m => String -> m SWord8
+sWord8 = symbolic
+
+-- | Generalization of 'Data.SBV.sWord8_'
+sWord8_ :: MonadSymbolic m => m SWord8
+sWord8_ = free_
+
+-- | Generalization of 'Data.SBV.sWord8s'
+sWord8s :: MonadSymbolic m => [String] -> m [SWord8]
+sWord8s = symbolics
+
+-- | Generalization of 'Data.SBV.sWord16'
+sWord16 :: MonadSymbolic m => String -> m SWord16
+sWord16 = symbolic
+
+-- | Generalization of 'Data.SBV.sWord16_'
+sWord16_ :: MonadSymbolic m => m SWord16
+sWord16_ = free_
+
+-- | Generalization of 'Data.SBV.sWord16s'
+sWord16s :: MonadSymbolic m => [String] -> m [SWord16]
+sWord16s = symbolics
+
+-- | Generalization of 'Data.SBV.sWord32'
+sWord32 :: MonadSymbolic m => String -> m SWord32
+sWord32 = symbolic
+
+-- | Generalization of 'Data.SBV.sWord32_'
+sWord32_ :: MonadSymbolic m => m SWord32
+sWord32_ = free_
+
+-- | Generalization of 'Data.SBV.sWord32s'
+sWord32s :: MonadSymbolic m => [String] -> m [SWord32]
+sWord32s = symbolics
+
+-- | Generalization of 'Data.SBV.sWord64'
+sWord64 :: MonadSymbolic m => String -> m SWord64
+sWord64 = symbolic
+
+-- | Generalization of 'Data.SBV.sWord64_'
+sWord64_ :: MonadSymbolic m => m SWord64
+sWord64_ = free_
+
+-- | Generalization of 'Data.SBV.sWord64s'
+sWord64s :: MonadSymbolic m => [String] -> m [SWord64]
+sWord64s = symbolics
+
+-- | Generalization of 'Data.SBV.sInt8'
+sInt8 :: MonadSymbolic m => String -> m SInt8
+sInt8 = symbolic
+
+-- | Generalization of 'Data.SBV.sInt8_'
+sInt8_ :: MonadSymbolic m => m SInt8
+sInt8_ = free_
+
+-- | Generalization of 'Data.SBV.sInt8s'
+sInt8s :: MonadSymbolic m => [String] -> m [SInt8]
+sInt8s = symbolics
+
+-- | Generalization of 'Data.SBV.sInt16'
+sInt16 :: MonadSymbolic m => String -> m SInt16
+sInt16 = symbolic
+
+-- | Generalization of 'Data.SBV.sInt16_'
+sInt16_ :: MonadSymbolic m => m SInt16
+sInt16_ = free_
+
+-- | Generalization of 'Data.SBV.sInt16s'
+sInt16s :: MonadSymbolic m => [String] -> m [SInt16]
+sInt16s = symbolics
+
+-- | Generalization of 'Data.SBV.sInt32'
+sInt32 :: MonadSymbolic m => String -> m SInt32
+sInt32 = symbolic
+
+-- | Generalization of 'Data.SBV.sInt32_'
+sInt32_ :: MonadSymbolic m => m SInt32
+sInt32_ = free_
+
+-- | Generalization of 'Data.SBV.sInt32s'
+sInt32s :: MonadSymbolic m => [String] -> m [SInt32]
+sInt32s = symbolics
+
+-- | Generalization of 'Data.SBV.sInt64'
+sInt64 :: MonadSymbolic m => String -> m SInt64
+sInt64 = symbolic
+
+-- | Generalization of 'Data.SBV.sInt64_'
+sInt64_ :: MonadSymbolic m => m SInt64
+sInt64_ = free_
+
+-- | Generalization of 'Data.SBV.sInt64s'
+sInt64s :: MonadSymbolic m => [String] -> m [SInt64]
+sInt64s = symbolics
+
+-- | Generalization of 'Data.SBV.sInteger'
+sInteger:: MonadSymbolic m => String -> m SInteger
+sInteger = symbolic
+
+-- | Generalization of 'Data.SBV.sInteger_'
+sInteger_:: MonadSymbolic m => m SInteger
+sInteger_ = free_
+
+-- | Generalization of 'Data.SBV.sIntegers'
+sIntegers :: MonadSymbolic m => [String] -> m [SInteger]
+sIntegers = symbolics
+
+-- | Generalization of 'Data.SBV.sReal'
+sReal:: MonadSymbolic m => String -> m SReal
+sReal = symbolic
+
+-- | Generalization of 'Data.SBV.sReal_'
+sReal_:: MonadSymbolic m => m SReal
+sReal_ = free_
+
+-- | Generalization of 'Data.SBV.sReals'
+sReals :: MonadSymbolic m => [String] -> m [SReal]
+sReals = symbolics
+
+-- | Generalization of 'Data.SBV.sFloat'
+sFloat :: MonadSymbolic m => String -> m SFloat
+sFloat = symbolic
+
+-- | Generalization of 'Data.SBV.sFloat_'
+sFloat_ :: MonadSymbolic m => m SFloat
+sFloat_ = free_
+
+-- | Generalization of 'Data.SBV.sFloats'
+sFloats :: MonadSymbolic m => [String] -> m [SFloat]
+sFloats = symbolics
+
+-- | Generalization of 'Data.SBV.sDouble'
+sDouble :: MonadSymbolic m => String -> m SDouble
+sDouble = symbolic
+
+-- | Generalization of 'Data.SBV.sDouble_'
+sDouble_ :: MonadSymbolic m => m SDouble
+sDouble_ = free_
+
+-- | Generalization of 'Data.SBV.sDoubles'
+sDoubles :: MonadSymbolic m => [String] -> m [SDouble]
+sDoubles = symbolics
+
+-- | Generalization of 'Data.SBV.sFPHalf'
+sFPHalf :: String -> Symbolic SFPHalf
+sFPHalf = symbolic
+
+-- | Generalization of 'Data.SBV.sFPHalf_'
+sFPHalf_ :: Symbolic SFPHalf
+sFPHalf_ = free_
+
+-- | Generalization of 'Data.SBV.sFPHalfs'
+sFPHalfs :: [String] -> Symbolic [SFPHalf]
+sFPHalfs = symbolics
+
+-- | Generalization of 'Data.SBV.sFPBFloat'
+sFPBFloat :: String -> Symbolic SFPBFloat
+sFPBFloat = symbolic
+
+-- | Generalization of 'Data.SBV.sFPBFloat_'
+sFPBFloat_ :: Symbolic SFPBFloat
+sFPBFloat_ = free_
+
+-- | Generalization of 'Data.SBV.sFPBFloats'
+sFPBFloats :: [String] -> Symbolic [SFPBFloat]
+sFPBFloats = symbolics
+
+-- | Generalization of 'Data.SBV.sFPSingle'
+sFPSingle :: String -> Symbolic SFPSingle
+sFPSingle = symbolic
+
+-- | Generalization of 'Data.SBV.sFPSingle_'
+sFPSingle_ :: Symbolic SFPSingle
+sFPSingle_ = free_
+
+-- | Generalization of 'Data.SBV.sFPSingles'
+sFPSingles :: [String] -> Symbolic [SFPSingle]
+sFPSingles = symbolics
+
+-- | Generalization of 'Data.SBV.sFPDouble'
+sFPDouble :: String -> Symbolic SFPDouble
+sFPDouble = symbolic
+
+-- | Generalization of 'Data.SBV.sFPDouble_'
+sFPDouble_ :: Symbolic SFPDouble
+sFPDouble_ = free_
+
+-- | Generalization of 'Data.SBV.sFPDoubles'
+sFPDoubles :: [String] -> Symbolic [SFPDouble]
+sFPDoubles = symbolics
+
+-- | Generalization of 'Data.SBV.sFPQuad'
+sFPQuad :: String -> Symbolic SFPQuad
+sFPQuad = symbolic
+
+-- | Generalization of 'Data.SBV.sFPQuad_'
+sFPQuad_ :: Symbolic SFPQuad
+sFPQuad_ = free_
+
+-- | Generalization of 'Data.SBV.sFPQuads'
+sFPQuads :: [String] -> Symbolic [SFPQuad]
+sFPQuads = symbolics
+
+-- | Generalization of 'Data.SBV.sFloatingPoint'
+sFloatingPoint :: ValidFloat eb sb => String -> Symbolic (SFloatingPoint eb sb)
+sFloatingPoint = symbolic
+
+-- | Generalization of 'Data.SBV.sFloatingPoint_'
+sFloatingPoint_ :: ValidFloat eb sb => Symbolic (SFloatingPoint eb sb)
+sFloatingPoint_ = free_
+
+-- | Generalization of 'Data.SBV.sFloatingPoints'
+sFloatingPoints :: ValidFloat eb sb => [String] -> Symbolic [SFloatingPoint eb sb]
+sFloatingPoints = symbolics
+
+-- | Generalization of 'Data.SBV.sWord'
+sWord :: (KnownNat n, BVIsNonZero n) => MonadSymbolic m => String -> m (SWord n)
+sWord = symbolic
+
+-- | Generalization of 'Data.SBV.sWord_'
+sWord_ :: (KnownNat n, BVIsNonZero n) => MonadSymbolic m => m (SWord n)
+sWord_ = free_
+
+-- | Generalization of 'Data.SBV.sWord64s'
+sWords :: (KnownNat n, BVIsNonZero n) => MonadSymbolic m => [String] -> m [SWord n]
+sWords = symbolics
+
+-- | Generalization of 'Data.SBV.sInt'
+sInt :: (KnownNat n, BVIsNonZero n) => MonadSymbolic m => String -> m (SInt n)
+sInt = symbolic
+
+-- | Generalization of 'Data.SBV.sInt_'
+sInt_ :: (KnownNat n, BVIsNonZero n) => MonadSymbolic m => m (SInt n)
+sInt_ = free_
+
+-- | Generalization of 'Data.SBV.sInts'
+sInts :: (KnownNat n, BVIsNonZero n) => MonadSymbolic m => [String] -> m [SInt n]
+sInts = symbolics
+
+-- | Generalization of 'Data.SBV.sChar'
+sChar :: MonadSymbolic m => String -> m SChar
+sChar = symbolic
+
+-- | Generalization of 'Data.SBV.sChar_'
+sChar_ :: MonadSymbolic m => m SChar
+sChar_ = free_
+
+-- | Generalization of 'Data.SBV.sChars'
+sChars :: MonadSymbolic m => [String] -> m [SChar]
+sChars = symbolics
+
+-- | Generalization of 'Data.SBV.sString'
+sString :: MonadSymbolic m => String -> m SString
+sString = symbolic
+
+-- | Generalization of 'Data.SBV.sString_'
+sString_ :: MonadSymbolic m => m SString
+sString_ = free_
+
+-- | Generalization of 'Data.SBV.sStrings'
+sStrings :: MonadSymbolic m => [String] -> m [SString]
+sStrings = symbolics
+
+-- | Generalization of 'Data.SBV.sList'
+sList :: (SymVal a, MonadSymbolic m) => String -> m (SList a)
+sList = symbolic
+
+-- | Generalization of 'Data.SBV.sList_'
+sList_ :: (SymVal a, MonadSymbolic m) => m (SList a)
+sList_ = free_
+
+-- | Generalization of 'Data.SBV.sLists'
+sLists :: (SymVal a, MonadSymbolic m) => [String] -> m [SList a]
+sLists = symbolics
+
+-- | Generalization of 'Data.SBV.sAray'
+sArray :: (SymVal a, SymVal b, MonadSymbolic m) => String -> m (SArray a b)
+sArray = symbolic
+
+-- | Generalization of 'Data.SBV.sList_'
+sArray_ :: (SymVal a, SymVal b, MonadSymbolic m) => m (SArray a b)
+sArray_ = free_
+
+-- | Generalization of 'Data.SBV.sLists'
+sArrays :: (SymVal a, SymVal b, MonadSymbolic m) => [String] -> m [SArray a b]
+sArrays = symbolics
+
+-- | Identify tuple like things. Note that there are no methods, just instances to control type inference
+class SymTuple a
+instance SymTuple ()
+instance SymTuple (a, b)
+instance SymTuple (a, b, c)
+instance SymTuple (a, b, c, d)
+instance SymTuple (a, b, c, d, e)
+instance SymTuple (a, b, c, d, e, f)
+instance SymTuple (a, b, c, d, e, f, g)
+instance SymTuple (a, b, c, d, e, f, g, h)
+
+-- | Generalization of 'Data.SBV.sTuple'
+sTuple :: (SymTuple tup, SymVal tup, MonadSymbolic m) => String -> m (SBV tup)
+sTuple = symbolic
+
+-- | Generalization of 'Data.SBV.sTuple_'
+sTuple_ :: (SymTuple tup, SymVal tup, MonadSymbolic m) => m (SBV tup)
+sTuple_ = free_
+
+-- | Generalization of 'Data.SBV.sTuples'
+sTuples :: (SymTuple tup, SymVal tup, MonadSymbolic m) => [String] -> m [SBV tup]
+sTuples = symbolics
+
+-- | Generalization of 'Data.SBV.sRational'
+sRational :: MonadSymbolic m => String -> m SRational
+sRational = symbolic
+
+-- | Generalization of 'Data.SBV.sRational_'
+sRational_ :: MonadSymbolic m => m SRational
+sRational_ = free_
+
+-- | Generalization of 'Data.SBV.sRationals'
+sRationals :: MonadSymbolic m => [String] -> m [SRational]
+sRationals = symbolics
+
+-- | Generalization of 'Data.SBV.sSet'
+sSet :: (Ord a, SymVal a, MonadSymbolic m) => String -> m (SSet a)
+sSet = symbolic
+
+-- | Generalization of 'Data.SBV.sMaybe_'
+sSet_ :: (Ord a, SymVal a, MonadSymbolic m) => m (SSet a)
+sSet_ = free_
+
+-- | Generalization of 'Data.SBV.sMaybes'
+sSets :: (Ord a, SymVal a, MonadSymbolic m) => [String] -> m [SSet a]
+sSets = symbolics
+
+-- | Generalization of 'Data.SBV.solve'
+solve :: MonadSymbolic m => [SBool] -> m SBool
+solve = pure . sAnd
+
+-- | Convert an SReal to an SInteger, @floor@ version. That is, it computes the
+-- largest integer @n@ that satisfies @sIntegerToSReal n <= r@.
+--
+-- For instance, @1.3@ will be @1@, but @-1.3@ will be @-2@.
+--
+-- See 'sRealToSIntegerRM' to select the rounding mode with a symbolic 'SRoundingMode'.
+sRealToSIntegerFloor :: SReal -> SInteger
+sRealToSIntegerFloor x
+  | Just i <- unliteral x, isExactRational i
+  = literal $ floor $ toRational i
+  | True
+  = SBV (SVal KUnbounded (Right (cache y)))
+  where y st = do xsv <- sbvToSV st x
+                  newExpr st KUnbounded (SBVApp (KindCast KReal KUnbounded) [xsv])
+
+-- | Convert an SReal to an SInteger, @ceiling@ version. That is, it computes
+-- the smallest integer @n@ that satisfies @r <= sIntegerToSReal n@.
+--
+-- For instance, @1.3@ will be @2@, but @-1.3@ will be @-1@.
+--
+-- See 'sRealToSIntegerRM' to select the rounding mode with a symbolic 'SRoundingMode'.
+sRealToSIntegerCeiling :: SReal -> SInteger
+sRealToSIntegerCeiling x
+  | Just i <- unliteral x, isExactRational i
+  = literal $ ceiling $ toRational i
+  | True
+  = - sRealToSIntegerFloor (-x)
+
+-- | Convert an SReal to an SInteger, truncating version. Truncate simply chops off the
+-- fractional part, essentially rounding towards zero.
+--
+-- For instance, @1.3@ will be @1@, and @-1.3@ will be @-1@.
+--
+-- See 'sRealToSIntegerRM' to select the rounding mode with a symbolic 'SRoundingMode'.
+sRealToSIntegerTruncate :: SReal -> SInteger
+sRealToSIntegerTruncate x
+  | Just i <- unliteral x, isExactRational i
+  = literal $ truncate $ toRational i
+  | True
+  = ite (x .>= 0) (sRealToSIntegerFloor x) (sRealToSIntegerCeiling x)
+
+-- | Convert an SReal to an SInteger by converting to the nearest integer. If
+-- there is a tie (i.e., if the fractional component of the SReal is equal to
+-- 0.5), then round away from zero.
+--
+-- For instance:
+--
+-- * @1.3@ will be @1@
+-- * @1.5@ will be @2@ (because @abs 1 < abs 2@)
+-- * @1.7@ will be @2@
+-- * @2.3@ will be @2@
+-- * @2.5@ will be @3@ (because @abs 2 < abs 3@)
+-- * @2.7@ will be @3@
+-- * @-1.3@ will be @-1@
+-- * @-1.5@ will be @-2@ (because @abs (-1) < abs (-2)@)
+-- * @-1.7@ will be @-2@
+-- * @-2.3@ will be @-2@
+-- * @-2.5@ will be @-3@ (because @abs (-2) < abs (-3)@)
+-- * @-2.7@ will be @-3@
+--
+-- See 'sRealToSIntegerRM' to select the rounding mode with a symbolic 'SRoundingMode'.
+sRealToSIntegerRoundAway :: SReal -> SInteger
+sRealToSIntegerRoundAway x
+  | Just i <- unliteral x, isExactRational i
+  = literal $ roundAway (toRational i)
+  | True
+  = ite
+      (x .>= 0)
+      (sRealToSIntegerFloor   (x + half))
+      (sRealToSIntegerCeiling (x - half))
+  where
+    half :: SReal
+    half = 0.5
+
+-- | Convert an SReal to an SInteger by converting to the nearest integer. If
+-- there is a tie (i.e., if the fractional component of the SReal is equal to
+-- 0.5), then round to the nearest even integer.
+--
+-- For instance:
+--
+-- * @1.3@ will be @1@
+-- * @1.5@ will be @2@ (because @2@ is even)
+-- * @1.7@ will be @2@
+-- * @2.3@ will be @2@
+-- * @2.5@ will be @2@ (because @2@ is even)
+-- * @2.7@ will be @3@
+-- * @-1.3@ will be @-1@
+-- * @-1.5@ will be @-2@ (because @-2@ is even)
+-- * @-1.7@ will be @-2@
+-- * @-2.3@ will be @-2@
+-- * @-2.5@ will be @-2@ (because @-2@ is even)
+-- * @-2.7@ will be @-3@
+--
+-- See 'sRealToSIntegerRM' to select the rounding mode with a symbolic 'SRoundingMode'.
+sRealToSIntegerRoundToEven :: SReal -> SInteger
+sRealToSIntegerRoundToEven x
+  | Just i <- unliteral x, isExactRational i
+  = literal $ round $ toRational i
+  | True
+  = ite (diff .< half) lo $
+    ite (diff .> half) hi $
+    ite (sDivides 2 lo) lo hi
+  where
+    half :: SReal
+    half = 0.5
+
+    lo, hi :: SInteger
+    lo = sRealToSIntegerFloor x
+    hi = lo+1
+
+    diff :: SReal
+    diff = x - sFromIntegral lo
+
+-- | Convert an 'SReal' to an 'SInteger' according to the supplied
+-- 'SRoundingMode'. This dispatches to 'sRealToSIntegerRoundToEven',
+-- 'sRealToSIntegerRoundAway', 'sRealToSIntegerCeiling', 'sRealToSIntegerFloor',
+-- and 'sRealToSIntegerTruncate' for the round-nearest-even, round-nearest-away,
+-- round-toward-positive, round-toward-negative, and round-toward-zero modes
+-- respectively.
+--
+-- Note that we re-use the 'SRoundingMode' type here, even though
+-- 'SRoundingMode' is normally associated with floating-point operations. The
+-- floating-point resemblance is superficial, as this function does not use any
+-- floating-point functionality behind the scenes.
+sRealToSIntegerRM :: SRoundingMode -> SReal -> SInteger
+sRealToSIntegerRM rm x =
+  sCaseRoundingMode
+    (sRealToSIntegerRoundToEven x)
+    (sRealToSIntegerRoundAway   x)
+    (sRealToSIntegerCeiling     x)
+    (sRealToSIntegerFloor       x)
+    (sRealToSIntegerTruncate    x)
+    rm
+
+-- | label: Label the result of an expression. This is essentially a no-op, but useful as it generates a comment in the generated C/SMT-Lib code.
+-- Note that if the argument is a constant, then the label is dropped completely, per the usual constant folding strategy. Compare this to 'observe'
+-- which is good for printing counter-examples.
+label :: SymVal a => String -> SBV a -> SBV a
+label m x
+   | Just _ <- unliteral x = x
+   | True                  = SBV $ SVal k $ Right $ cache r
+  where k    = kindOf x
+        r st = do xsv <- sbvToSV st x
+                  newExpr st k (SBVApp (Label m) [xsv])
+
+
+-- | Observe the value of an expression, if the given condition holds.  Such values are useful in model construction, as they are printed part of a satisfying model, or a
+-- counter-example. The same works for quick-check as well. Useful when we want to see intermediate values, or expected/obtained
+-- pairs in a particular run. Note that an observed expression is always symbolic, i.e., it won't be constant folded. Compare this to 'label'
+-- which is used for putting a label in the generated SMTLib-C code.
+--
+-- NB. If the observed expression happens under a SBV-lambda expression, then it is silently ignored; since
+-- there's no way to access the value of such a value.
+observeIf :: SymVal a => (a -> Bool) -> String -> SBV a -> SBV a
+observeIf cond m x
+  | Just bad <- checkObservableName m
+  = error bad
+  | True
+  = SBV $ SVal k $ Right $ cache r
+  where k = kindOf x
+        r st = do xsv <- sbvToSV st (label ("Observing: " ++ m) x)
+                  recordObservable st (T.pack m) (cond . fromCV) xsv
+                  pure xsv
+
+-- | Observe the value of an expression, unconditionally. See 'observeIf' for a generalized version.
+observe :: SymVal a => String -> SBV a -> SBV a
+observe = observeIf (const True)
+
+-- | Symbolic Comparisons. Similar to 'Eq', we cannot implement Haskell's 'Ord' class
+-- since there is no way to return an 'Ordering' value from a symbolic comparison.
+-- Furthermore, 'OrdSymbolic' requires 'Mergeable' to implement if-then-else, for the
+-- benefit of implementing symbolic versions of 'max' and 'min' functions.
+infix 4 .<, .<=, .>, .>=
+class (Mergeable a, EqSymbolic a) => OrdSymbolic a where
+  -- | Symbolic less than.
+  (.<)  :: a -> a -> SBool
+  -- | Symbolic less than or equal to.
+  (.<=) :: a -> a -> SBool
+  -- | Symbolic greater than.
+  (.>)  :: a -> a -> SBool
+  -- | Symbolic greater than or equal to.
+  (.>=) :: a -> a -> SBool
+  -- | Symbolic minimum.
+  smin  :: a -> a -> a
+  -- | Symbolic maximum.
+  smax  :: a -> a -> a
+  -- | Is the value within the allowed /inclusive/ range?
+  inRange    :: a -> (a, a) -> SBool
+
+  {-# MINIMAL (.<) #-}
+
+  a .<= b    = a .< b .|| a .== b
+  a .>  b    = b .<  a
+  a .>= b    = b .<= a
+
+  a `smin` b = ite (a .<= b) a b
+  a `smax` b = ite (a .<= b) b a
+
+  inRange x (y, z) = x .>= y .&& x .<= z
+
+
+{- We can't have a generic instance of the form:
+
+instance Eq a => EqSymbolic a where
+  x .== y = if x == y then true else sFalse
+
+even if we're willing to allow Flexible/undecidable instances..
+This is because if we allow this it would imply EqSymbolic (SBV a);
+since (SBV a) has to be Eq as it must be a Num. But this wouldn't be
+the right choice obviously; as the Eq instance is bogus for SBV
+for natural reasons..
+-}
+
+-- It is tempting to put in an @Eq a@ superclass here. But doing so
+-- is complicated, as it requires all underlying types to have equality,
+-- which is at best shaky for algebraic reals and sets. So, leave it out.
+instance (HasKind a, SymVal a) => EqSymbolic (SBV a) where
+  SBV x .== SBV y = SBV (svEqual x y)
+  SBV x ./= SBV y = SBV (svNotEqual x y)
+
+  SBV x .=== SBV y = SBV (svStrongEqual x y)
+
+  -- Custom version of distinct that generates better code for base types
+  distinct []                                             = sTrue
+  distinct [_]                                            = sTrue
+  distinct xs | all isConc xs                             = checkDiff xs
+              | [SBV a, SBV b] <- xs, a `is` svBool True  = SBV $ svNot b
+              | [SBV a, SBV b] <- xs, b `is` svBool True  = SBV $ svNot a
+              | [SBV a, SBV b] <- xs, a `is` svBool False = SBV b
+              | [SBV a, SBV b] <- xs, b `is` svBool False = SBV a
+              -- 3 booleans can't be distinct!
+              | (x : _ : _ : _) <- xs, isBool x           = sFalse
+              | True                                      = SBV (SVal KBool (Right (cache r)))
+    where r st = do xsv <- mapM (sbvToSV st) xs
+                    newExpr st KBool (SBVApp NotEqual xsv)
+
+          -- We call this in case all are concrete, which will
+          -- reduce to a constant and generate no code at all!
+          -- Note that this is essentially the same as the default
+          -- definition, which unfortunately we can no longer call!
+          checkDiff []     = sTrue
+          checkDiff (a:as) = sAll (a ./=) as .&& checkDiff as
+
+          -- Sigh, we can't use isConcrete since that requires SymVal
+          -- constraint that we don't have here. (To support SBools.)
+          isConc (SBV (SVal _ (Left _))) = True
+          isConc _                       = False
+
+          -- Likewise here; need to go lower.
+          SVal k1 (Left c1) `is` SVal k2 (Left c2) = (k1, c1) == (k2, c2)
+          _                 `is` _                 = False
+
+          isBool (SBV (SVal KBool _)) = True
+          isBool _                    = False
+
+  -- Custom version of distinctExcept that generates better code for base types
+  distinctExcept []  _       = sTrue
+  distinctExcept [_] _       = sTrue
+  distinctExcept es  ignored
+    | all isConc (es ++ ignored)
+    = distinct (filter ignoreConc es)
+    | True
+    = SBV (SVal KBool (Right (cache r)))
+    where ignoreConc x = case x `sElem` ignored of
+                           SBV (SVal KBool (Left cv)) -> cvToBool cv
+                           _                          -> error $ "distinctExcept: Impossible happened, concrete sElem failed: " ++ show (es, ignored, x)
+
+          r st = do let incr x table = ite (x `sElem` ignored) (0 :: SInteger) (1 + readArrayNoEq table x)
+
+                        initArray :: SArray a Integer
+                        initArray = constArray 0
+
+                        finalArray = foldl' (\table x -> writeArrayNoKnd table x (incr x table)) initArray es
+
+                    sbvToSV st $ sAll (\e -> readArrayNoEq finalArray e .<= (1 :: SInteger)) es
+
+          -- Sigh, we can't use isConcrete since that requires SymVal
+          -- constraint that we don't have here. (To support SBools.)
+          isConc (SBV (SVal _ (Left _))) = True
+          isConc _                       = False
+
+          -- Version of readArray that doesn't have the Eq constraint, since we don't have it here
+          readArrayNoEq array key = SBV . SVal KUnbounded . Right $ cache g
+             where g st = do f <- sbvToSV st array
+                             k <- sbvToSV st key
+                             newExpr st KUnbounded (SBVApp ReadArray [f, k])
+
+          writeArrayNoKnd :: forall key. HasKind key => SArray key Integer -> SBV key -> SInteger -> SArray key Integer
+          writeArrayNoKnd array key value = SBV . SVal k . Right $ cache g
+              where k  = KArray (kindOf (Proxy @key)) KUnbounded
+
+                    g st = do arr    <- sbvToSV st array
+                              keyVal <- sbvToSV st key
+                              val    <- sbvToSV st value
+                              newExpr st k (SBVApp WriteArray [arr, keyVal, val])
+
+-- We don't want to do a generic OrdSymbolic (SBV a) instance; since that would be dangerous, like the case
+-- for Num. So, we explicitly define for each type we care about.
+
+#define MKSORD(CSTR, TYPE)                                                            \
+instance CSTR => OrdSymbolic TYPE where {                                             \
+  a@(SBV x) .<  b@(SBV y) | smtComparable "<"   a b = SBV (svLessThan x y)            \
+                          | True                    = SBV (svStructuralLessThan x y); \
+                                                                                      \
+  a@(SBV x) .<= b@(SBV y) | smtComparable ".<=" a b = SBV (svLessEq x y)              \
+                          | True                    = a .< b .|| a .== b;             \
+                                                                                      \
+  a@(SBV x) .>  b@(SBV y) | smtComparable ">"   a b = SBV (svGreaterThan x y)         \
+                          | True                    = b .< a;                         \
+                                                                                      \
+  a@(SBV x) .>= b@(SBV y) | smtComparable ">="  a b = SBV (svGreaterEq x y)           \
+                          | True                    = b .<= a;                        \
+}                                                                                     \
+
+-- Derive basic instances we need. NB. We don't give the SRational instance here. It's handled
+-- in Data/SBV/Rational due to representation issues.
+MKSORD((),                          SInteger)
+MKSORD((),                          SWord8)
+MKSORD((),                          SWord16)
+MKSORD((),                          SWord32)
+MKSORD((),                          SWord64)
+MKSORD((),                          SInt8)
+MKSORD((),                          SInt16)
+MKSORD((),                          SInt32)
+MKSORD((),                          SInt64)
+MKSORD((),                          SFloat)
+MKSORD((),                          SChar)
+MKSORD((SymVal a),                  (SList a))
+MKSORD((),                          SDouble)
+MKSORD((),                          SReal)
+MKSORD((KnownNat n, BVIsNonZero n), (SWord n))
+MKSORD((KnownNat n, BVIsNonZero n), (SInt  n))
+MKSORD((ValidFloat eb sb),          (SFloatingPoint eb sb))
+
+-- Tuples
+MKSORD((SymVal a, SymVal b),                                                             (SBV (a, b)))
+MKSORD((SymVal a, SymVal b, SymVal c),                                                   (SBV (a, b, c)))
+MKSORD((SymVal a, SymVal b, SymVal c, SymVal d),                                         (SBV (a, b, c, d)))
+MKSORD((SymVal a, SymVal b, SymVal c, SymVal d, SymVal e),                               (SBV (a, b, c, d, e)))
+MKSORD((SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, SymVal f),                     (SBV (a, b, c, d, e, f)))
+MKSORD((SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, SymVal f, SymVal g),           (SBV (a, b, c, d, e, f, g)))
+MKSORD((SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, SymVal f, SymVal g, SymVal h), (SBV (a, b, c, d, e, f, g, h)))
+#undef MKSORD
+
+-- Is this a type that's comparable by underlying translation to SMTLib?
+-- Note that we allow concrete versions to go through unless the type is a set, as there's really no reason not to.
+smtComparable :: (SymVal a, HasKind a) => String -> SBV a -> SBV a -> Bool
+smtComparable op x y
+  | isConcrete x && isConcrete y && not (isSet k)
+  = True
+  | True
+  = case k of
+      KVar       {} -> False
+      KBool         -> True
+      KBounded   {} -> True
+      KUnbounded {} -> True
+      KReal      {} -> True
+      KApp       {} -> True
+      KADT       {} -> True
+      KFloat        -> True
+      KDouble       -> True
+      KRational  {} -> True
+      KFP        {} -> True
+      KChar         -> True
+      KString       -> True
+      KList      {} -> nope     -- Unfortunately, no way for us to desugar this
+      KSet       {} -> nope     -- Ditto here..
+      KTuple     {} -> False
+      KArray     {} -> True
+ where k    = kindOf x
+       nope = error $ "Data.SBV.OrdSymbolic: SMTLib does not support " ++ op ++ " for " ++ show k
+
+-- Bool
+instance EqSymbolic Bool where
+  x .== y = fromBool $ x == y
+
+-- Lists
+instance EqSymbolic a => EqSymbolic [a] where
+  []     .==  []     = sTrue
+  (x:xs) .==  (y:ys) = x .== y .&& xs .== ys
+  _      .==  _      = sFalse
+
+  []     .=== []     = sTrue
+  (x:xs) .=== (y:ys) = x .=== y .&& xs .=== ys
+  _      .=== _      = sFalse
+
+instance OrdSymbolic a => OrdSymbolic [a] where
+  []     .< []     = sFalse
+  []     .< _      = sTrue
+  _      .< []     = sFalse
+  (x:xs) .< (y:ys) = x .< y .|| (x .== y .&& xs .< ys)
+
+-- NonEmpty
+instance EqSymbolic a => EqSymbolic (NonEmpty a) where
+  (x :| xs) .==  (y :| ys) = x : xs .==  y : ys
+  (x :| xs) .=== (y :| ys) = x : xs .=== y : ys
+
+instance OrdSymbolic a => OrdSymbolic (NonEmpty a) where
+   (x :| xs) .< (y :| ys) = x : xs .< y : ys
+
+-- Maybe
+instance EqSymbolic a => EqSymbolic (Maybe a) where
+  Nothing .== Nothing = sTrue
+  Just a  .== Just b  = a .== b
+  _       .== _       = sFalse
+
+instance OrdSymbolic a => OrdSymbolic (Maybe a) where
+  Nothing .<  Nothing = sFalse
+  Nothing .<  _       = sTrue
+  Just _  .<  Nothing = sFalse
+  Just a  .<  Just b  = a .< b
+
+-- Either
+instance (EqSymbolic a, EqSymbolic b) => EqSymbolic (Either a b) where
+  Left a  .==  Left b  = a .== b
+  Right a .==  Right b = a .== b
+  _       .==  _       = sFalse
+
+  Left a  .=== Left b  = a .=== b
+  Right a .=== Right b = a .=== b
+  _       .=== _       = sFalse
+
+instance (OrdSymbolic a, OrdSymbolic b) => OrdSymbolic (Either a b) where
+  Left a  .< Left b  = a .< b
+  Left _  .< Right _ = sTrue
+  Right _ .< Left _  = sFalse
+  Right a .< Right b = a .< b
+
+-- 2-Tuple
+instance (EqSymbolic a, EqSymbolic b) => EqSymbolic (a, b) where
+  (a0, b0) .==  (a1, b1) = a0 .==  a1 .&& b0 .==  b1
+  (a0, b0) .=== (a1, b1) = a0 .=== a1 .&& b0 .=== b1
+
+instance (OrdSymbolic a, OrdSymbolic b) => OrdSymbolic (a, b) where
+  (a0, b0) .< (a1, b1) = a0 .< a1 .|| (a0 .== a1 .&& b0 .< b1)
+
+-- 3-Tuple
+instance (EqSymbolic a, EqSymbolic b, EqSymbolic c) => EqSymbolic (a, b, c) where
+  (a0, b0, c0) .==  (a1, b1, c1) = (a0, b0) .==  (a1, b1) .&& c0 .==  c1
+  (a0, b0, c0) .=== (a1, b1, c1) = (a0, b0) .=== (a1, b1) .&& c0 .=== c1
+
+instance (OrdSymbolic a, OrdSymbolic b, OrdSymbolic c) => OrdSymbolic (a, b, c) where
+  (a0, b0, c0) .< (a1, b1, c1) = (a0, b0) .< (a1, b1) .|| ((a0, b0) .== (a1, b1) .&& c0 .< c1)
+
+-- 4-Tuple
+instance (EqSymbolic a, EqSymbolic b, EqSymbolic c, EqSymbolic d) => EqSymbolic (a, b, c, d) where
+  (a0, b0, c0, d0) .==  (a1, b1, c1, d1) = (a0, b0, c0) .==  (a1, b1, c1) .&& d0 .==  d1
+  (a0, b0, c0, d0) .=== (a1, b1, c1, d1) = (a0, b0, c0) .=== (a1, b1, c1) .&& d0 .=== d1
+
+instance (OrdSymbolic a, OrdSymbolic b, OrdSymbolic c, OrdSymbolic d) => OrdSymbolic (a, b, c, d) where
+  (a0, b0, c0, d0) .< (a1, b1, c1, d1) = (a0, b0, c0) .< (a1, b1, c1) .|| ((a0, b0, c0) .== (a1, b1, c1) .&& d0 .< d1)
+
+-- 5-Tuple
+instance (EqSymbolic a, EqSymbolic b, EqSymbolic c, EqSymbolic d, EqSymbolic e) => EqSymbolic (a, b, c, d, e) where
+  (a0, b0, c0, d0, e0) .==  (a1, b1, c1, d1, e1) = (a0, b0, c0, d0) .==  (a1, b1, c1, d1) .&& e0 .==  e1
+  (a0, b0, c0, d0, e0) .=== (a1, b1, c1, d1, e1) = (a0, b0, c0, d0) .=== (a1, b1, c1, d1) .&& e0 .=== e1
+
+instance (OrdSymbolic a, OrdSymbolic b, OrdSymbolic c, OrdSymbolic d, OrdSymbolic e) => OrdSymbolic (a, b, c, d, e) where
+  (a0, b0, c0, d0, e0) .< (a1, b1, c1, d1, e1) = (a0, b0, c0, d0) .< (a1, b1, c1, d1) .|| ((a0, b0, c0, d0) .== (a1, b1, c1, d1) .&& e0 .< e1)
+
+-- 6-Tuple
+instance (EqSymbolic a, EqSymbolic b, EqSymbolic c, EqSymbolic d, EqSymbolic e, EqSymbolic f) => EqSymbolic (a, b, c, d, e, f) where
+  (a0, b0, c0, d0, e0, f0) .==  (a1, b1, c1, d1, e1, f1) = (a0, b0, c0, d0, e0) .==  (a1, b1, c1, d1, e1) .&& f0 .==  f1
+  (a0, b0, c0, d0, e0, f0) .=== (a1, b1, c1, d1, e1, f1) = (a0, b0, c0, d0, e0) .=== (a1, b1, c1, d1, e1) .&& f0 .=== f1
+
+instance (OrdSymbolic a, OrdSymbolic b, OrdSymbolic c, OrdSymbolic d, OrdSymbolic e, OrdSymbolic f) => OrdSymbolic (a, b, c, d, e, f) where
+  (a0, b0, c0, d0, e0, f0) .< (a1, b1, c1, d1, e1, f1) =    (a0, b0, c0, d0, e0) .<  (a1, b1, c1, d1, e1)
+                                                       .|| ((a0, b0, c0, d0, e0) .== (a1, b1, c1, d1, e1) .&& f0 .< f1)
+
+-- 7-Tuple
+instance (EqSymbolic a, EqSymbolic b, EqSymbolic c, EqSymbolic d, EqSymbolic e, EqSymbolic f, EqSymbolic g) => EqSymbolic (a, b, c, d, e, f, g) where
+  (a0, b0, c0, d0, e0, f0, g0) .==  (a1, b1, c1, d1, e1, f1, g1) = (a0, b0, c0, d0, e0, f0) .==  (a1, b1, c1, d1, e1, f1) .&& g0 .==  g1
+  (a0, b0, c0, d0, e0, f0, g0) .=== (a1, b1, c1, d1, e1, f1, g1) = (a0, b0, c0, d0, e0, f0) .=== (a1, b1, c1, d1, e1, f1) .&& g0 .=== g1
+
+instance (OrdSymbolic a, OrdSymbolic b, OrdSymbolic c, OrdSymbolic d, OrdSymbolic e, OrdSymbolic f, OrdSymbolic g) => OrdSymbolic (a, b, c, d, e, f, g) where
+  (a0, b0, c0, d0, e0, f0, g0) .< (a1, b1, c1, d1, e1, f1, g1) =    (a0, b0, c0, d0, e0, f0) .<  (a1, b1, c1, d1, e1, f1)
+                                                               .|| ((a0, b0, c0, d0, e0, f0) .== (a1, b1, c1, d1, e1, f1) .&& g0 .< g1)
+
+-- | A class of values that capture the notion of a zero for measure values.
+-- Used in termination checking for recursive SMT functions.
+class OrdSymbolic (SBV a) => Zero a where
+  zero   :: SBV a
+  -- | Component-wise non-negativity check. For scalars this is simply @>= 0@.
+  -- For tuples, every component must be @>= 0@, which is stronger than
+  -- lexicographic @>= (0, 0, ..)@. This is required for well-foundedness
+  -- of the lexicographic ordering on the non-negative part.
+  nonNeg :: SBV a -> SBool
+  nonNeg x = x .>= zero
+
+-- | An integer as a measure
+instance Zero Integer where
+   zero = literal 0
+
+-- | Bounded bit-vectors as measures. These are all sound: each is a finite type, so a
+-- non-negative, strictly-decreasing chain of values is necessarily finite. (The default
+-- @nonNeg x = x .>= 0@ works for both the unsigned and signed cases.)
+instance Zero Word8  where zero = literal 0
+instance Zero Word16 where zero = literal 0
+instance Zero Word32 where zero = literal 0
+instance Zero Word64 where zero = literal 0
+instance Zero Int8   where zero = literal 0
+instance Zero Int16  where zero = literal 0
+instance Zero Int32  where zero = literal 0
+instance Zero Int64  where zero = literal 0
+instance (KnownNat n, BVIsNonZero n) => Zero (WordN n) where zero = literal 0
+instance (KnownNat n, BVIsNonZero n) => Zero (IntN  n) where zero = literal 0
+
+-- NB. We would like to use 'Data.SBV.Tuple.untuple' in the 'nonNeg' definitions below,
+-- but 'Data.SBV.Tuple' imports 'Data.SBV.Core.Model', creating a circular dependency.
+-- So we extract components at the SVal level using 'TupleAccess' directly.
+
+-- | A tuple of integers as a measure
+instance Zero (Integer, Integer) where
+  zero   = literal (0, 0)
+  nonNeg = tupleNonNeg 2
+
+-- | A triple of integers as a measure
+instance Zero (Integer, Integer, Integer) where
+  zero   = literal (0, 0, 0)
+  nonNeg = tupleNonNeg 3
+
+-- | A quadruple of integers as a measure
+instance Zero (Integer, Integer, Integer, Integer) where
+  zero   = literal (0, 0, 0, 0)
+  nonNeg = tupleNonNeg 4
+
+-- | A quintuple of integers as a measure
+instance Zero (Integer, Integer, Integer, Integer, Integer) where
+  zero   = literal (0, 0, 0, 0, 0)
+  nonNeg = tupleNonNeg 5
+
+-- | A float as a measure
+instance Zero Float where
+   zero = literal 0
+
+-- | A double as a measure
+instance Zero Double where
+   zero = literal 0
+
+-- | Algebraic reals are /not/ permitted as measures, and we reject them at compile time.
+-- The reals are dense, hence not well-ordered: a merely non-negative and strictly-decreasing
+-- real measure does not imply termination (e.g. the chain @1, 1\/2, 1\/4, ...@ descends forever
+-- without reaching a minimum). Use an integer-valued measure instead.
+instance TypeError (     'Text "A termination measure may not have a real-valued result."
+                   ':$$: 'Text ""
+                   ':$$: 'Text "The reals are not well-ordered: an infinite descending chain such as"
+                   ':$$: 'Text "1, 1/2, 1/4, ... has no least element, so a non-negative and strictly"
+                   ':$$: 'Text "decreasing real measure does not imply termination."
+                   ':$$: 'Text ""
+                   ':$$: 'Text "Use an integer-valued measure instead (e.g. a count of remaining steps)."
+                   ) => Zero AlgReal where
+   zero = error "Data.SBV.Zero(AlgReal): unreachable"
+
+-- | A floating-point as a measure
+instance ValidFloat eb sb => Zero (FloatingPoint eb sb) where
+   zero = literal 0
+
+-- | Component-wise non-negativity for an n-tuple of integers.
+-- Extracts each component via 'TupleAccess' and checks @>= 0@.
+tupleNonNeg :: SymVal a => Int -> SBV a -> SBool
+tupleNonNeg n t = sAll (.>= (0 :: SInteger)) [acc i | i <- [1..n]]
+  where acc i = SBV $ SVal KUnbounded $ Right $ cache $ \st -> do
+                  sv <- sbvToSV st t
+                  newExpr st KUnbounded (SBVApp (TupleAccess i n) [sv])
+
+-- | Type family that maps a function type to its corresponding measure type.
+-- The measure function takes the same arguments but returns a different type.
+type family MeasureOf f r where
+  MeasureOf (SBV a -> r) r' = SBV a -> MeasureOf r r'
+  MeasureOf (SBV a)      r  = SBV r
+
+-- | Apply a measure function to a list of SVal arguments, producing the measure value.
+-- This is used internally during measure verification.
+class ApplyMeasure a r where
+  applyMeasure :: MeasureOf a r -> [SVal] -> SBV r
+
+instance ApplyMeasure (SBV a) r where
+  applyMeasure m [] = m
+  applyMeasure _ _  = error "Data.SBV.applyMeasure: too many arguments"
+
+instance ApplyMeasure b r => ApplyMeasure (SBV a -> b) r where
+  applyMeasure _ []       = error "Data.SBV.applyMeasure: not enough arguments"
+  applyMeasure m (sv:svs) = applyMeasure @b @r (m (SBV sv)) svs
+
+-- | Type family that maps a function type to its corresponding contract type.
+-- A contract takes the same arguments as the function, plus the result, and returns 'SBool'.
+-- For example, a contract for @SBV Integer -> SBV Integer@ has type @SBV Integer -> SBV Integer -> SBool@
+-- (first arg is the input, second is the output).
+type family ContractOf f where
+  ContractOf (SBV a)      = SBV a -> SBool
+  ContractOf (SBV a -> r) = SBV a -> ContractOf r
+
+-- | Apply a contract function to a list of input t'SVal' arguments and a result t'SVal'.
+class ApplyContract a where
+  applyContract :: ContractOf a -> [SVal] -> SVal -> SBool
+
+instance ApplyContract (SBV a) where
+  applyContract c [] sv = c (SBV sv)
+  applyContract _ _  _  = error "Data.SBV.applyContract: too many arguments"
+
+instance ApplyContract b => ApplyContract (SBV a -> b) where
+  applyContract _ []       _ = error "Data.SBV.applyContract: not enough arguments"
+  applyContract c (sv:svs) r = applyContract @b (c (SBV sv)) svs r
+
+-- | An evaluated measure: captures the ability to apply the measure function
+-- to a list of arguments, along with the ordering and zero constraints.
+data MeasureEval where
+  MeasureEval :: (Zero r, OrdSymbolic (SBV r), SymVal r) => ([SVal] -> SBV r) -> MeasureEval
+
+-- | An evaluated contract: captures the ability to apply a contract predicate
+-- to a list of input arguments and a result value. Used during measure verification
+-- for nested recursive functions, where the inductive hypothesis provides the contract
+-- on recursive call results.
+data ContractEval where
+  ContractEval :: ([SVal] -> SVal -> SBool) -> ContractEval
+
+-- | A measure for a function, used to prove termination of recursive definitions.
+--
+--   * 'AutoMeasure': The function either doesn't need a measure (because it's not recursive),
+--     or SBV will automatically guess one based on argument types.
+--   * 'HasMeasure': The user provided an explicit measure function.
+--   * 'HasContract': The user provided a measure and a contract. The contract is a predicate
+--     on the function's inputs and output that is proven simultaneously with the measure decrease
+--     via well-founded induction. This handles nested recursion (e.g., McCarthy 91) where the
+--     termination argument depends on the function's return value at smaller inputs.
+--   * 'Productive': The function is corecursive (productive). Instead of proving termination via a
+--     measure, SBV checks that every recursive call is guarded by a data constructor (list cons,
+--     ADT constructor, etc.), ensuring the function always produces output incrementally.
+--   * 'Unverified': No termination or productivity check is performed. The function is emitted as
+--     @define-fun-rec@ and the user takes responsibility for well-definedness. Use this for functions
+--     where termination is believed but cannot be proven (e.g., Collatz).
+data Measure f where
+  AutoMeasure  :: Measure f
+  HasMeasure   :: MeasureEval -> [MeasureHelper] -> Measure f
+  HasContract  :: MeasureEval -> ContractEval -> [MeasureHelper] -> Measure f
+  Productive   :: Measure f
+  Unverified   :: Measure f
+
+-- | A helper axiom for measure verification. When a measure's correctness depends on
+-- properties that require induction to prove (e.g., @ifComplexity f > 0@), the user
+-- provides these properties along with their proofs. During the measure check, each
+-- helper is run: the TP proof is executed to confirm the property holds, and the
+-- proven property is asserted as an axiom in the measure verification session.
+--
+-- Use the 'Data.SBV.TP.measureLemma' smart constructor to create these from TP proofs.
+newtype MeasureHelper = MeasureHelper { runMeasureHelper :: SMTConfig -> IO SBool }
+
+-- | Verify that a measure decreases at each recursive call site.
+-- Walks the expression DAG to find recursive calls, computes reaching conditions
+-- via ITE analysis, and verifies the measure property in a separate solver session.
+-- Throws an error with a detailed message if verification fails.
+verifyMeasure :: SMTConfig -> String -> LambdaInfo -> MeasureEval -> [MeasureHelper] -> IO ()
+verifyMeasure cfg funcNm info meval helpers = do
+   -- Run each helper with funcNm added to measuresBeingVerified, preventing re-entrant verification.
+   -- This is needed when a measureLemma proof uses the function whose measure is being checked
+   -- (e.g., revPreservesLen proves length(rev xs) == length xs, using rev itself).
+   let curVerifying = measuresBeingVerified (tpOptions cfg)
+       cfg'         = cfg{tpOptions = (tpOptions cfg){measuresBeingVerified = Set.insert funcNm curVerifying}}
+
+   debug cfg ["[MEASURE] " <> T.pack funcNm <> ": verifying with " <> showText (length helpers) <> " helper(s)"
+              <> if Set.null curVerifying then "" else ", already verifying: " <> showText (Set.toList curVerifying)]
+   axioms <- mapM (`runMeasureHelper` cfg') helpers
+   debug cfg ["[MEASURE] " <> T.pack funcNm <> ": " <> showText (length axioms) <> " helper axiom(s) collected, checking measure"]
+   result <- checkMeasure cfg funcNm False info meval axioms
+   let prettyNm = prettyFuncNm funcNm
+   case result of
+     MeasureOK              -> pure ()
+     MeasureNotNonNeg r     -> error $ unlines $
+        [ ""
+        , "*** Data.SBV: Termination measure is not non-negative."
+        , "***"
+        , "***   Function: " ++ prettyNm
+        , "***"
+        ]
+        ++ ["***   " ++ l | l <- lines (show r)]
+        ++
+        [ "***"
+        , "*** The measure must be non-negative for all inputs."
+        ]
+     MeasureNotDecreasing r -> error $ unlines $
+        [ ""
+        , "*** Data.SBV: Termination measure does not strictly decrease at a recursive call site."
+        , "***"
+        , "***   Function: " ++ prettyNm
+        , "***"
+        ]
+        ++ ["***   " ++ l | l <- lines (show r)]
+        ++
+        [ "***"
+        , "*** The measure must strictly decrease at every recursive call."
+        ]
+
+-- | Result of checking a measure.
+data MeasureCheckResult = MeasureOK                         -- ^ Measure is valid
+                        | MeasureNotNonNeg     ThmResult    -- ^ Measure can be negative
+                        | MeasureNotDecreasing ThmResult    -- ^ Measure doesn't strictly decrease
+
+-- | Check that a measure is valid: non-negative and strictly decreasing at each recursive call.
+-- Returns 'MeasureOK' if valid, or the specific failure otherwise.
+-- If @skipNonNeg@ is 'True', the non-negativity check is skipped (used for ADT size measures
+-- where non-negativity is guaranteed by construction).
+-- The @axioms@ list contains additional properties to assert in the verification session
+-- (used for user-provided measures that depend on inductively-proven helper properties).
+checkMeasure :: SMTConfig -> String -> Bool -> LambdaInfo -> MeasureEval -> [SBool] -> IO MeasureCheckResult
+checkMeasure cfgIn funcNm skipNonNeg LambdaInfo{liAssignments, liParams, liOutput, liConsts} (MeasureEval applyM) axioms = do
+   let -- Use a separate transcript for the measure check, so it doesn't clobber the main one
+       addSuffix s fp = dropExtension fp ++ "_measure_" ++ map (\c -> if c == ' ' then '_' else c) funcNm ++ "_" ++ s ++ takeExtension fp
+       cfgNonNeg      = cfgIn{transcript = addSuffix "nonNeg"   <$> transcript cfgIn}
+       cfgDecrease    = cfgIn{transcript = addSuffix "decrease"  <$> transcript cfgIn}
+       barFuncNm      = barify funcNm
+       recCalls  = [(sv, args) | (sv, SBVApp (Uninterpreted nm) args) <- F.toList liAssignments, nm == T.pack barFuncNm]
+
+   if null recCalls
+     then pure MeasureOK
+     else do
+       let reachConds = computeReachingConditions liAssignments liOutput
+           paramSVs   = map snd liParams
+
+           -- Set up the proving environment: create fresh symbolic parameters,
+           -- constrain any axioms (which may register function definitions in this
+           -- session via the SVal cache mechanism), then replay the function body DAG.
+           -- The order matters: axioms must be constrained BEFORE replaying the DAG,
+           -- so that replayDAG knows which functions are available in this session.
+           mkProveEnv = do
+              st <- symbolicEnv
+              liftIO $ writeIORef (rSkipMeasureChecks st) True
+
+              let singleParam = length paramSVs == 1
+              freshParams <- liftIO $ sequence [svToSV st =<< svMkSymVar (NonQueryVar Nothing) (kindOf sv) (Just (if singleParam then "arg" else "arg" ++ show i)) st
+                                               | (i, sv) <- zip [(0::Int)..] paramSVs
+                                               ]
+              freshConsts <- liftIO $ mapM (\(_, cv) -> svToSV st (SVal (kindOf cv) (Left cv))) liConsts
+
+              -- Constrain axioms first: forcing axiom SBools triggers newUninterpreted
+              -- for any functions they reference, registering those definitions in this session.
+              mapM_ constrain axioms
+
+              -- Now read which functions are actually available in this session
+              sessionDefns <- liftIO $ readIORef (rDefns st)
+              let sessionFuncs = Map.keysSet sessionDefns
+
+              let constMapping = zip (map fst liConsts) freshConsts
+                  paramMapping = zip paramSVs freshParams
+                  initMap      = Map.fromList (constMapping ++ paramMapping)
+                  builtinMap   = Map.fromList [(trueSV, trueSV), (falseSV, falseSV)]
+                  startMap     = Map.union initMap builtinMap
+
+              svMap <- liftIO $ replayDAG cfgIn st (Set.singleton barFuncNm) sessionFuncs startMap (F.toList liAssignments)
+
+              let formalSVals = map (\sv -> SVal (kindOf sv) (Right (cache (\_ -> pure sv)))) freshParams
+                  mFormal     = applyM formalSVals
+
+              pure (svMap, mFormal)
+
+       -- Check 1: Non-negativity (skipped for ADT size measures, which are non-negative by construction)
+       nonNegOK <- if skipNonNeg
+                   then pure (Right ())
+                   else do nonNegResult <- proveWith cfgNonNeg (do
+                              (_, mFormal) <- mkProveEnv
+                              sObserve "measure" (unSBV mFormal)
+                              pure $ nonNeg mFormal :: Symbolic SBool)
+                           pure $ case nonNegResult of
+                             ThmResult Unsatisfiable{} -> Right ()
+                             _                         -> Left nonNegResult
+
+       case nonNegOK of
+         Right () -> do
+           -- Check 2: Strict decrease at each recursive call
+           decResult <- proveWith cfgDecrease (do
+              (svMap, mFormal) <- mkProveEnv
+
+              -- When we have axioms from measure helpers that reference the function being
+              -- verified (e.g., revPreservesLen references rev), the axioms register the
+              -- function definition in this session via the SVal cache mechanism. We then
+              -- connect the fresh variables (created by replayDAG for recursive calls) to
+              -- actual function calls, so the axioms can reason about them.
+              -- For example, the axiom len(rev(xs)) = len(xs) needs to know that fresh_1
+              -- is actually rev(as) in order to derive len(fresh_1) = len(as).
+              st <- symbolicEnv
+              defns <- liftIO $ readIORef (rDefns st)
+              let funcRegistered = Map.member barFuncNm defns
+              when funcRegistered $
+                liftIO $ mapM_ (\(rcSV, callArgSVs) -> do
+                    let freshSV    = Map.findWithDefault rcSV rcSV svMap
+                        mappedArgs = map (\sv -> Map.findWithDefault sv sv svMap) callArgSVs
+                        k          = kindOf rcSV
+                    -- Create the actual function call: f(mapped_args)
+                    actualSV <- newExpr st k (SBVApp (Uninterpreted (T.pack barFuncNm)) mappedArgs)
+                    -- Assert fresh_var == f(mapped_args)
+                    let freshSVal  = SVal k (Right (cache (const (pure freshSV))))
+                        actualSVal = SVal k (Right (cache (const (pure actualSV))))
+                    internalConstraint st False [] (svEqual freshSVal actualSVal)
+                  ) recCalls
+
+              let singleCall = length recCalls == 1
+                  mkObligation (i, (rcSV, callArgSVs)) = do
+                    let mappedArgs = map (\sv -> Map.findWithDefault sv sv svMap) callArgSVs
+                        argSVals   = map (\sv -> SVal (kindOf sv) (Right (cache (\_ -> pure sv)))) mappedArgs
+                        mCall      = applyM argSVals
+
+                        reachSVal  = case Map.lookup rcSV reachConds of
+                                       Just conds -> sAnd [ let sv' = Map.findWithDefault condSV condSV svMap
+                                                                s   = SBV (SVal KBool (Right (cache (\_ -> pure sv'))))
+                                                            in if pol then s else sNot s
+                                                          | (condSV, pol) <- conds
+                                                          ]
+                                       Nothing    -> sTrue
+
+                        tag nm | singleCall = nm
+                               | True       = nm ++ "[" ++ show (i :: Int) ++ "]"
+
+                    sObserve (tag "then")   (unSBV mCall)
+                    pure $ reachSVal .=> mFormal .> mCall
+
+              sObserve "before" (unSBV mFormal)
+              obligations <- mapM mkObligation (zip [1..] recCalls)
+              pure $ sAnd obligations :: Symbolic SBool)
+
+           case decResult of
+             ThmResult Unsatisfiable{} -> pure MeasureOK
+             _                         -> pure $ MeasureNotDecreasing decResult
+
+         Left nonNegResult -> pure $ MeasureNotNonNeg nonNegResult
+
+-- | Verify a measure with a contract for nested recursive functions.
+-- Uses well-founded induction: the inductive hypothesis provides the contract
+-- on recursive call results, and we prove both measure decrease and contract simultaneously.
+-- One-step unfolding of the function body at each recursive call site gives the solver
+-- information about base-case behavior without assuming totality.
+verifyMeasureWithContract :: SMTConfig -> String -> LambdaInfo -> MeasureEval -> ContractEval -> [MeasureHelper] -> IO ()
+verifyMeasureWithContract cfg funcNm info meval ceval helpers = do
+   -- Run helpers with funcNm added to measuresBeingVerified, same as verifyMeasure
+   let curVerifying = measuresBeingVerified (tpOptions cfg)
+       cfg'         = cfg{tpOptions = (tpOptions cfg){measuresBeingVerified = Set.insert funcNm curVerifying}}
+
+   debug cfg ["[MEASURE] " <> T.pack funcNm <> " (contract): verifying with " <> showText (length helpers) <> " helper(s)"]
+   axioms <- mapM (`runMeasureHelper` cfg') helpers
+   debug cfg ["[MEASURE] " <> T.pack funcNm <> " (contract): " <> showText (length axioms) <> " helper axiom(s) collected, checking measure+contract"]
+   result <- checkMeasureWithContract cfg funcNm False info meval ceval axioms
+   let prettyNm = prettyFuncNm funcNm
+   case result of
+     MeasureOK              -> pure ()
+     MeasureNotNonNeg r     -> error $ unlines $
+        [ ""
+        , "*** Data.SBV: Termination measure is not non-negative."
+        , "***"
+        , "***   Function: " ++ prettyNm
+        , "***"
+        ]
+        ++ ["***   " ++ l | l <- lines (show r)]
+        ++
+        [ "***"
+        , "*** The measure must be non-negative for all inputs."
+        ]
+     MeasureNotDecreasing r -> error $ unlines $
+        [ ""
+        , "*** Data.SBV: Measure+contract verification failed."
+        , "***"
+        , "***   Function: " ++ prettyNm
+        , "***"
+        ]
+        ++ ["***   " ++ l | l <- lines (show r)]
+        ++
+        [ "***"
+        , "*** The measure must strictly decrease at every recursive call,"
+        , "*** and the contract must hold for the function's output."
+        , "*** The inductive hypothesis provides the contract on recursive call"
+        , "*** results for inputs with strictly smaller measure."
+        ]
+
+-- | Check a measure with contract: non-negative, strictly decreasing, and contract holds.
+-- Uses one-step unfolding at each recursive call site to give the solver base-case behavior,
+-- and assumes the inductive hypothesis (contract on recursive call results) to handle
+-- nested recursion where a call's argument depends on another call's result.
+checkMeasureWithContract :: SMTConfig -> String -> Bool -> LambdaInfo -> MeasureEval -> ContractEval -> [SBool] -> IO MeasureCheckResult
+checkMeasureWithContract cfgIn funcNm skipNonNeg LambdaInfo{liAssignments, liParams, liOutput, liConsts} (MeasureEval applyM) (ContractEval applyC) axioms = do
+   let addSuffix s fp = dropExtension fp ++ "_measure_" ++ map (\c -> if c == ' ' then '_' else c) funcNm ++ "_" ++ s ++ takeExtension fp
+       cfgNonNeg      = cfgIn{transcript = addSuffix "nonNeg"   <$> transcript cfgIn}
+       cfgDecrease    = cfgIn{transcript = addSuffix "decrease"  <$> transcript cfgIn}
+       barFuncNm      = barify funcNm
+       recCalls  = [(sv, args) | (sv, SBVApp (Uninterpreted nm) args) <- F.toList liAssignments, nm == T.pack barFuncNm]
+
+   if null recCalls
+     then pure MeasureOK
+     else do
+       -- Non-negativity: same as checkMeasure
+       nonNegOK <- if skipNonNeg
+                   then pure (Right ())
+                   else do nonNegResult <- proveWith cfgNonNeg (do
+                              st <- symbolicEnv
+                              liftIO $ writeIORef (rSkipMeasureChecks st) True
+
+                              let singleParam = length paramSVs == 1
+                              freshParams <- liftIO $ sequence [svToSV st =<< svMkSymVar (NonQueryVar Nothing) (kindOf sv) (Just (if singleParam then "arg" else "arg" ++ show i)) st
+                                                                | (i, sv) <- zip [(0::Int)..] paramSVs
+                                                                ]
+                              freshConsts <- liftIO $ mapM (\(_, cv) -> svToSV st (SVal (kindOf cv) (Left cv))) liConsts
+
+                              mapM_ constrain axioms
+                              sessionDefns <- liftIO $ readIORef (rDefns st)
+                              let sessionFuncs = Map.keysSet sessionDefns
+
+                              let constMapping = zip (map fst liConsts) freshConsts
+                                  paramMapping = zip paramSVs freshParams
+                                  initMap      = Map.fromList (constMapping ++ paramMapping)
+                                  builtinMap   = Map.fromList [(trueSV, trueSV), (falseSV, falseSV)]
+                                  startMap     = Map.union initMap builtinMap
+
+                              _ <- liftIO $ replayDAG cfgIn st (Set.singleton barFuncNm) sessionFuncs startMap (F.toList liAssignments)
+
+                              let formalSVals = map (\sv -> SVal (kindOf sv) (Right (cache (\_ -> pure sv)))) freshParams
+                                  mFormal     = applyM formalSVals
+
+                              sObserve "measure" (unSBV mFormal)
+                              pure $ nonNeg mFormal :: Symbolic SBool)
+                           pure $ case nonNegResult of
+                             ThmResult Unsatisfiable{} -> Right ()
+                             _                         -> Left nonNegResult
+
+       case nonNegOK of
+         Right () -> do
+           -- Decrease + contract check
+           decResult <- proveWith cfgDecrease (do
+              st <- symbolicEnv
+              liftIO $ writeIORef (rSkipMeasureChecks st) True
+
+              let singleParam = length paramSVs == 1
+              freshParams <- liftIO $ sequence [svToSV st =<< svMkSymVar (NonQueryVar Nothing) (kindOf sv) (Just (if singleParam then "arg" else "arg" ++ show i)) st
+                                                | (i, sv) <- zip [(0::Int)..] paramSVs
+                                                ]
+              freshConsts <- liftIO $ mapM (\(_, cv) -> svToSV st (SVal (kindOf cv) (Left cv))) liConsts
+
+              mapM_ constrain axioms
+              sessionDefns <- liftIO $ readIORef (rDefns st)
+              let sessionFuncs = Map.keysSet sessionDefns
+
+              let constMapping = zip (map fst liConsts) freshConsts
+                  paramMapping = zip paramSVs freshParams
+                  initMap      = Map.fromList (constMapping ++ paramMapping)
+                  builtinMap   = Map.fromList [(trueSV, trueSV), (falseSV, falseSV)]
+                  startMap     = Map.union initMap builtinMap
+
+              svMap <- liftIO $ replayDAG cfgIn st (Set.singleton barFuncNm) sessionFuncs startMap (F.toList liAssignments)
+
+              let formalSVals = map (\sv -> SVal (kindOf sv) (Right (cache (\_ -> pure sv)))) freshParams
+                  mFormal     = applyM formalSVals
+
+              -- One-step unfolding: for each recursive call, replay the function body
+              -- with the call's arguments substituted for the formal parameters.
+              -- This gives the solver base-case behavior without assuming totality.
+              let dagList = F.toList liAssignments
+              liftIO $ F.for_ recCalls $ \(rcSV, callArgSVs) -> do
+                let -- Map the call's arguments through svMap to get the fresh session SVs
+                    mappedCallArgs = map (\sv -> Map.findWithDefault sv sv svMap) callArgSVs
+                    -- Build the initial map for the unfolded body: formal params -> call args
+                    unfoldParamMapping = zip paramSVs mappedCallArgs
+                    unfoldConstMapping = zip (map fst liConsts) freshConsts
+                    unfoldInitMap      = Map.fromList (unfoldConstMapping ++ unfoldParamMapping)
+                    unfoldStartMap     = Map.union unfoldInitMap builtinMap
+
+                -- Replay the entire function body with the call's args
+                unfoldSvMap <- replayDAG cfgIn st (Set.singleton barFuncNm) sessionFuncs unfoldStartMap dagList
+
+                -- The unfolded output SV
+                let unfoldedOutputSV = Map.findWithDefault liOutput liOutput unfoldSvMap
+                    -- The fresh variable that was assigned to this recursive call
+                    freshCallSV = Map.findWithDefault rcSV rcSV svMap
+                    -- Assert: fresh_call = unfolded_output
+                    freshSVal    = SVal (kindOf rcSV) (Right (cache (const (pure freshCallSV))))
+                    unfoldedSVal = SVal (kindOf rcSV) (Right (cache (const (pure unfoldedOutputSV))))
+                internalConstraint st False [] (svEqual freshSVal unfoldedSVal)
+
+              -- IH contract: for each recursive call, assume the contract holds on its result.
+              -- This is sound because we also prove measure decrease at each call site.
+              liftIO $ F.for_ recCalls $ \(rcSV, callArgSVs) -> do
+                let mappedArgs    = map (\sv -> Map.findWithDefault sv sv svMap) callArgSVs
+                    argSVals      = map (\sv -> SVal (kindOf sv) (Right (cache (\_ -> pure sv)))) mappedArgs
+                    freshCallSV   = Map.findWithDefault rcSV rcSV svMap
+                    freshResult   = SVal (kindOf rcSV) (Right (cache (const (pure freshCallSV))))
+                    contractHolds = applyC argSVals freshResult
+                internalConstraint st False [] (unSBV contractHolds)
+
+              -- Proof obligations:
+              -- 1. Measure strictly decreases at each reachable recursive call site
+              let reachConds = computeReachingConditions liAssignments liOutput
+                  singleCall = length recCalls == 1
+                  mkDecreaseObligation (i, (rcSV, callArgSVs)) = do
+                    let mappedArgs = map (\sv -> Map.findWithDefault sv sv svMap) callArgSVs
+                        argSVals   = map (\sv -> SVal (kindOf sv) (Right (cache (\_ -> pure sv)))) mappedArgs
+                        mCall      = applyM argSVals
+
+                        reachSVal  = case Map.lookup rcSV reachConds of
+                                       Just conds -> sAnd [ let sv' = Map.findWithDefault condSV condSV svMap
+                                                                s   = SBV (SVal KBool (Right (cache (\_ -> pure sv'))))
+                                                            in if pol then s else sNot s
+                                                          | (condSV, pol) <- conds
+                                                          ]
+                                       Nothing    -> sTrue
+
+                        tag nm | singleCall = nm
+                               | True       = nm ++ "[" ++ show (i :: Int) ++ "]"
+
+                    sObserve (tag "then")   (unSBV mCall)
+                    pure $ reachSVal .=> mFormal .> mCall
+
+              sObserve "before" (unSBV mFormal)
+              decreaseObligations <- mapM mkDecreaseObligation (zip [1..] recCalls)
+
+              -- 2. Contract holds for the function's output
+              let mappedOutput  = Map.findWithDefault liOutput liOutput svMap
+                  resultSVal   = SVal (kindOf liOutput) (Right (cache (const (pure mappedOutput))))
+                  contractObl  = applyC formalSVals resultSVal
+
+              pure $ sAnd decreaseObligations .&& contractObl :: Symbolic SBool)
+
+           case decResult of
+             ThmResult Unsatisfiable{} -> pure MeasureOK
+             _                         -> pure $ MeasureNotDecreasing decResult
+
+         Left nonNegResult -> pure $ MeasureNotNonNeg nonNegResult
+   where paramSVs = map snd liParams
+
+-- | Verify that a function marked as productive is guarded-recursive:
+-- every recursive call must be a direct argument to a data constructor.
+verifyGuardedness :: SMTConfig -> String -> LambdaInfo -> IO ()
+verifyGuardedness cfg funcNm info
+  | isGuardedRecursive (Set.singleton (barify funcNm)) info
+  = debug cfg ["[MEASURE] " <> T.pack funcNm <> ": productive (all recursive calls are guarded by constructors)"]
+  | True
+  = error $ unlines
+      [ ""
+      , "*** Data.SBV: Function marked as productive is not guarded-recursive."
+      , "***"
+      , "***   Function: " ++ prettyFuncNm funcNm
+      , "***"
+      , "*** Every recursive call must be a direct argument to a data constructor"
+      , "*** (list cons, ADT constructor, etc.) to ensure productivity."
+      ]
+
+-- | Check if a recursive function is guarded: every recursive call's result
+-- is consumed by a data constructor (list cons, ADT constructor, tuple constructor).
+-- This ensures the function is productive — it always makes progress by producing
+-- at least one constructor before recursing. The set of barified names covers
+-- all functions in the mutual recursion group (or just the function itself for self-recursion).
+isGuardedRecursive :: Set.Set String -> LambdaInfo -> Bool
+isGuardedRecursive barFuncNms LambdaInfo{liAssignments} = all isGuarded recCallSVs
+  where
+    dagList    = F.toList liAssignments
+    recCallSVs = [sv | (sv, SBVApp (Uninterpreted nm) _) <- dagList, nm `Set.member` Set.map T.pack barFuncNms]
+
+    -- Build a map from SV to the set of operations that consume it
+    consumers :: Map.Map SV [(SV, Op)]
+    consumers = foldl' addConsumers Map.empty dagList
+      where addConsumers m (sv, SBVApp op args) =
+              foldl' (\m' a -> Map.insertWith (\_ old -> (sv, op) : old) a [(sv, op)] m') m args
+
+    -- A recursive call is guarded if at least one of its consumers is a constructor
+    isGuarded sv = case Map.lookup sv consumers of
+                     Nothing   -> False
+                     Just cons -> any (isConstructorOp . snd) cons
+
+    isConstructorOp (SeqOp SeqConcat{})      = True
+    isConstructorOp (ADTOp ADTConstructor{}) = True
+    isConstructorOp (TupleConstructor _)     = True
+    isConstructorOp _                        = False
+
+-- | Generate candidate measures based on parameter kinds.
+-- For list args, we use @length@. For integer args, we use @abs@. For recursive ADTs, we use @sbv.dt.size@.
+-- ADT size measures are tried first (most likely to succeed for structural recursion).
+-- If there are multiple scalar candidates, we also try their sum.
+-- For two or more scalar candidates, we also try lexicographic (tuple) measures
+-- using all pairs and triples, which handles functions like Ackermann that
+-- decrease lexicographically.
+guessMeasures :: [(Quantifier, SV)] -> [(String, MeasureEval, Maybe Int)]
+guessMeasures params = map (\(d, f, mi) -> (d, MeasureEval f, mi)) (adtSingles ++ otherSingles ++ summed) ++ lexPairs ++ lexTriples
+  where
+    singles :: [(String, [SVal] -> SInteger, Maybe Int)]
+    singles = concatMap mkCandidates (zip [0..] params)
+
+    -- ADT size measures are most likely to succeed for ADT-recursive functions, so try them first
+    (adtSingles, otherSingles) = partition (\(_, _, mi) -> isJust mi) singles
+
+    mkCandidates :: (Int, (Quantifier, SV)) -> [(String, [SVal] -> SInteger, Maybe Int)]
+    mkCandidates (i, (_, sv)) = case kindOf sv of
+      KList elemK -> [("length arg" ++ show (i+1), \svs ->
+                       let listSVal = svs !! i
+                       in SBV $ SVal KUnbounded $ Right $ cache $ \st -> do
+                            s <- sbvToSV st (SBV listSVal)
+                            newExpr st KUnbounded (SBVApp (SeqOp (SeqLen elemK)) [s]), Nothing)]
+
+      -- Strings are sequences of characters in SMTLib
+      KString      -> [("length arg" ++ show (i+1), \svs ->
+                       let strSVal = svs !! i
+                       in SBV $ SVal KUnbounded $ Right $ cache $ \st -> do
+                            s <- sbvToSV st (SBV strSVal)
+                            newExpr st KUnbounded (SBVApp (SeqOp (SeqLen KChar)) [s]), Nothing)]
+
+      -- Unbounded integers: try abs and smax 0 as measures
+      KUnbounded       -> [ ("abs arg"     ++ show (i+1), \svs ->      abs (SBV (svs !! i)), Nothing)
+                          , ("smax 0 arg"  ++ show (i+1), \svs -> 0 `smax` SBV (svs !! i), Nothing)
+                          ]
+
+      -- Bounded bitvectors: cast to Integer for the measure. Unsigned values are
+      -- already non-negative; signed values need abs to ensure non-negativity.
+      KBounded False _ -> [("arg" ++ show (i+1),     \svs ->      SBV (svFromIntegral KUnbounded (svs !! i)),  Nothing)]
+      KBounded True  _ -> [("abs arg" ++ show (i+1), \svs -> abs (SBV (svFromIntegral KUnbounded (svs !! i))), Nothing)]
+
+      KTuple ks   -> concatMap (mkTupleComponent i (length ks)) (zip [1..] ks)
+      KADT adtName _ ctors
+        | any (any (isRecKind adtName) . snd) ctors ->
+            let sizeName = "sbv.dt.size." ++ adtName
+                adtKind  = kindOf sv
+            in [(sizeName ++ " arg" ++ show (i+1), \svs ->
+                 SBV $ SVal KUnbounded $ Right $ cache $ \st -> do
+                      ensureADTSizeDefined st sizeName adtKind ctors
+                      s <- sbvToSV st (SBV (svs !! i))
+                      newExpr st KUnbounded (SBVApp (Uninterpreted (T.pack sizeName)) [s]), Just i)]
+      _           -> []
+
+    mkTupleComponent :: Int -> Int -> (Int, Kind) -> [(String, [SVal] -> SInteger, Maybe Int)]
+    mkTupleComponent argIdx nFields (compIdx, compKind) = case compKind of
+      KList elemK -> [("length arg" ++ show (argIdx+1) ++ "._" ++ show compIdx, \svs ->
+                       let comp = SBV $ SVal compKind $ Right $ cache $ \st -> do
+                                    tupSV <- sbvToSV st (SBV (svs !! argIdx))
+                                    newExpr st compKind (SBVApp (TupleAccess compIdx nFields) [tupSV])
+                       in SBV $ SVal KUnbounded $ Right $ cache $ \st -> do
+                            s <- sbvToSV st comp
+                            newExpr st KUnbounded (SBVApp (SeqOp (SeqLen elemK)) [s]), Nothing)]
+      KUnbounded  -> [("abs arg" ++ show (argIdx+1) ++ "._" ++ show compIdx, \svs ->
+                       abs $ SBV $ SVal KUnbounded $ Right $ cache $ \st -> do
+                         tupSV <- sbvToSV st (SBV (svs !! argIdx))
+                         newExpr st KUnbounded (SBVApp (TupleAccess compIdx nFields) [tupSV]), Nothing)]
+      _           -> []
+
+    summed | length singles > 1 = [( intercalate " + " [d | (d, _, _) <- singles]
+                                   , \svs -> sum [f svs | (_, f, _) <- singles]
+                                   , Nothing
+                                   )]
+           | True               = []
+
+    -- Lexicographic pair measures: try all ordered pairs from the scalar candidates
+    lexPairs :: [(String, MeasureEval, Maybe Int)]
+    lexPairs
+      | length singles < 2 = []
+      | True                = [ ( "(" ++ d1 ++ ", " ++ d2 ++ ")"
+                                , MeasureEval (\svs -> mkPair (f1 svs) (f2 svs))
+                                , Nothing
+                                )
+                              | (d1, f1, _) <- singles
+                              , (d2, f2, _) <- singles
+                              , d1 /= d2
+                              ]
+
+    -- Lexicographic triple measures: try all ordered triples from the scalar candidates
+    lexTriples :: [(String, MeasureEval, Maybe Int)]
+    lexTriples
+      | length singles < 3 = []
+      | True                = [ ( "(" ++ d1 ++ ", " ++ d2 ++ ", " ++ d3 ++ ")"
+                                , MeasureEval (\svs -> mkTriple (f1 svs) (f2 svs) (f3 svs))
+                                , Nothing
+                                )
+                              | (d1, f1, _) <- singles
+                              , (d2, f2, _) <- singles
+                              , d1 /= d2
+                              , (d3, f3, _) <- singles
+                              , d1 /= d3, d2 /= d3
+                              ]
+
+    -- Build an SBV (Integer, Integer) from two SIntegers
+    mkPair :: SInteger -> SInteger -> SBV (Integer, Integer)
+    mkPair a b = SBV $ SVal (KTuple [KUnbounded, KUnbounded]) $ Right $ cache $ \st -> do
+      sa <- sbvToSV st a
+      sb <- sbvToSV st b
+      newExpr st (KTuple [KUnbounded, KUnbounded]) (SBVApp (TupleConstructor 2) [sa, sb])
+
+    -- Build an SBV (Integer, Integer, Integer) from three SIntegers
+    mkTriple :: SInteger -> SInteger -> SInteger -> SBV (Integer, Integer, Integer)
+    mkTriple a b c = SBV $ SVal (KTuple [KUnbounded, KUnbounded, KUnbounded]) $ Right $ cache $ \st -> do
+      sa <- sbvToSV st a
+      sb <- sbvToSV st b
+      sc <- sbvToSV st c
+      newExpr st (KTuple [KUnbounded, KUnbounded, KUnbounded]) (SBVApp (TupleConstructor 3) [sa, sb, sc])
+
+-- | Check if a kind refers back to a given ADT name (i.e., is a recursive field).
+-- Recursive fields in constructor kinds use 'KApp', not 'KADT'.
+isRecKind :: String -> Kind -> Bool
+isRecKind adtName (KApp n _)   = n == adtName
+isRecKind adtName (KADT n _ _) = n == adtName
+isRecKind _       _            = False
+
+-- | Ensure that an ADT size function is defined in the given state. The size function
+-- maps ADT values to non-negative integers, returning 0 for base constructors and
+-- @1 + sum(sizes of recursive fields)@ for recursive constructors.
+-- This is used as a termination measure for functions that recurse on ADT values.
+ensureADTSizeDefined :: State -> String -> Kind -> [(String, [Kind])] -> IO ()
+ensureADTSizeDefined st sizeName adtKind ctors = do
+   defs <- readIORef (rDefns st)
+   unless (Map.member sizeName defs) $ do
+      let argNm      = "x"
+          smtArgType = T.unpack (smtType adtKind)
+
+          -- Build the SMT-Lib body for the size function
+          body = buildBody ctors
+
+          buildBody []  = "0"
+          buildBody [c] = caseExpr c
+          buildBody (c:cs) = "(ite " ++ testerExpr c ++ " " ++ caseExpr c ++ " " ++ buildBody cs ++ ")"
+
+          testerExpr (cName, _) = "(is-" ++ cName ++ " " ++ argNm ++ ")"
+
+          caseExpr (cName, flds) =
+            let recIdxs = [j | (j, k) <- zip [1::Int ..] flds, isRecKind (adtNameOf adtKind) k]
+            in if null recIdxs
+               then "0"
+               else let recCalls = ["(" ++ sizeName ++ " (get" ++ cName ++ "_" ++ show j ++ " " ++ argNm ++ "))" | j <- recIdxs]
+                    in "(+ 1 " ++ smtSum recCalls ++ ")"
+
+          smtSum [x]    = x
+          smtSum (x:xs) = "(+ " ++ x ++ " " ++ smtSum xs ++ ")"
+          smtSum []     = "0"
+
+          paramStr = T.pack $ "((" ++ argNm ++ " " ++ smtArgType ++ "))"
+          smtDef   = SMTDef KUnbounded [sizeName] (Just paramStr) (\n -> T.pack (replicate n ' ' ++ body))
+          sbvTy    = SBVType [adtKind, KUnbounded]
+
+      modifyIORef' (rDefns st) (Map.insert sizeName (smtDef, sbvTy))
+      modifyState st rUIMap (Map.insert sizeName (True, Nothing, sbvTy)) (pure ())
+
+-- | Extract the ADT name from a KADT kind.
+adtNameOf :: Kind -> String
+adtNameOf (KADT n _ _) = n
+adtNameOf _            = ""
+
+-- | Check if a function is structurally recursive on a given parameter.
+-- Returns 'True' if every recursive call passes a strict sub-term of the
+-- formal parameter (obtained via one or more 'ADTAccessor' operations) as
+-- the argument at that parameter position. Structural recursion on an ADT
+-- guarantees termination by the well-foundedness of the datatype, so the
+-- measure check can be skipped.
+isStructurallyDecreasing :: String -> LambdaInfo -> Int -> Bool
+isStructurallyDecreasing funcNm LambdaInfo{liAssignments, liParams} paramIdx =
+    not (null recCalls) && all checkCall recCalls
+  where
+    barFuncNm = barify funcNm
+    paramSV   = snd (liParams !! paramIdx)
+    asgns     = F.toList liAssignments
+    defMap    = Map.fromList asgns
+
+    recCalls = [args | (_, SBVApp (Uninterpreted nm) args) <- asgns, nm == T.pack barFuncNm]
+
+    checkCall callArgs
+      | paramIdx < length callArgs = isProperSubTerm (callArgs !! paramIdx)
+      | True                       = False
+
+    -- An SV is a proper sub-term of the parameter if it is obtained by applying
+    -- one or more ADTAccessor operations to the parameter.
+    isProperSubTerm sv = case Map.lookup sv defMap of
+       Just (SBVApp (ADTOp (ADTAccessor _ _)) [parent]) ->
+            parent == paramSV || isProperSubTerm parent
+       _ -> False
+
+-- | Try to auto-guess a termination measure for a recursive function. Generates candidates
+-- based on parameter kinds and tries each one. Returns the first measure that passes both
+-- non-negativity and strict decrease checks, or 'Nothing' if no guess works.
+autoGuess :: SMTConfig -> String -> LambdaInfo -> IO (Maybe MeasureEval)
+autoGuess cfg funcNm info = do
+    let barFuncNm = barify funcNm
+        recCalls  = [(sv, args) | (sv, SBVApp (Uninterpreted nm) args) <- F.toList (liAssignments info), nm == T.pack barFuncNm]
+        allUIs    = [(nm, length args) | (_, SBVApp (Uninterpreted nm) args) <- F.toList (liAssignments info)]
+    debug cfg ["[MEASURE] " <> T.pack funcNm <> ": barified = " <> showText barFuncNm]
+    debug cfg ["[MEASURE] " <> T.pack funcNm <> ": Uninterpreted ops in DAG: " <> showText allUIs]
+    debug cfg ["[MEASURE] " <> T.pack funcNm <> ": recursive calls found = " <> showText (length recCalls)]
+    go candidates
+  where
+    candidates = guessMeasures (liParams info)
+    go []                    = pure Nothing
+    go ((desc, m, mbIdx):ms) = do let skipNonNeg = "sbv.dt.size." `isPrefixOf` desc
+                                  debug cfg ["[MEASURE] " <> T.pack funcNm <> ": trying " <> T.pack desc]
+                                  -- For ADT size measures, try syntactic sub-term check first.
+                                  -- This avoids calling the solver, which can hang on recursive
+                                  -- define-fun-rec definitions.
+                                  result <- case mbIdx of
+                                              Just idx | isStructurallyDecreasing funcNm info idx -> do
+                                                 debug cfg ["[MEASURE] " <> T.pack funcNm <> ": " <> T.pack desc <> " -> OK (structural recursion)"]
+                                                 pure MeasureOK
+                                              _ -> checkMeasure cfg funcNm skipNonNeg info m []
+                                  case result of
+                                    MeasureOK              -> do debug cfg ["[MEASURE] " <> T.pack funcNm <> ": " <> T.pack desc <> " -> OK"]
+                                                                 pure (Just m)
+                                    MeasureNotNonNeg r     -> do debug cfg ["[MEASURE] " <> T.pack funcNm <> ": " <> T.pack desc <> " failed non-negativity: " <> showText r]
+                                                                 debug cfg ["[MEASURE] " <> T.pack funcNm <> ": trying next candidate.."]
+                                                                 go ms
+                                    MeasureNotDecreasing r -> do debug cfg ["[MEASURE] " <> T.pack funcNm <> ": " <> T.pack desc <> " failed strict decrease: " <> showText r]
+                                                                 debug cfg ["[MEASURE] " <> T.pack funcNm <> ": trying next candidate.."]
+                                                                 go ms
+
+-- | Auto-guess a termination measure, or fail with a helpful error message.
+autoGuessOrFail :: SMTConfig -> String -> LambdaInfo -> IO ()
+autoGuessOrFail cfg funcNm info = do
+   mbMeasure <- autoGuess cfg funcNm info
+   case mbMeasure of
+     Just _  -> pure ()
+     Nothing -> error $ unlines $
+        [ ""
+        , "*** Data.SBV: Cannot determine a termination measure."
+        , "***"
+        , "***   Function: " ++ prettyFuncNm funcNm
+        ]
+        ++ guessLines
+        ++
+        [ "***"
+        , "*** Please use 'smtFunctionWithMeasure' to provide an explicit measure."
+        ]
+  where candidates  = guessMeasures (liParams info)
+        guessLines
+          | null candidates = [ "***"
+                              , "***   No measure candidates could be derived from the argument types."
+                              ]
+          | True            = [ "***"
+                              , "***   Measures tried:"
+                              ]
+                              ++ [ "***     " ++ d | (d, _, _) <- candidates]
+
+-- | Check mutual recursion for a function by computing the SCC from State.
+-- This is called as a deferred closure from rMeasureChecks. It computes the SCC
+-- of the function graph, finds the group containing the given function, and
+-- verifies the whole group if it's a multi-member cycle. Multiple members of the
+-- same group may register this check, but only the first execution does work;
+-- after successful verification, verified members are removed from rFuncLambdaInfos,
+-- so subsequent closures find insufficient infos and skip.
+--
+-- The optional t'MeasureEval' is a user-provided measure (from 'smtFunctionWithMeasure').
+-- If given, it is tried first before falling back to auto-guessing.
+checkMutualFromState :: SMTConfig -> String -> State -> Maybe MeasureEval -> IO ()
+checkMutualFromState cfg funcNm st mbMeasure = do
+   defns     <- readIORef (rDefns st)
+   funcInfos <- readIORef (rFuncLambdaInfos st)
+
+   let barFuncNm = barify funcNm
+       nodes = [(nm, nm, deps) | (nm, (SMTDef _ deps _ _, _)) <- Map.toList defns]
+       sccs  = DG.stronglyConnComp nodes
+
+       -- Find the SCC containing our function (using barified name since rDefns keys are barified)
+       mySCC = [members | DG.CyclicSCC members <- sccs, barFuncNm `elem` members]
+
+   case mySCC of
+     [members] | length members >= 2 -> do
+       -- rFuncLambdaInfos uses plain names, so unbar the SCC member names for lookup.
+       -- Build the infos map with plain names as keys (matching rFuncLambdaInfos convention).
+       let plainMembers = map unBar members
+           infos = Map.fromList [(pnm, v) | pnm <- plainMembers, Just v <- [Map.lookup pnm funcInfos]]
+       if Map.size infos >= 2
+         then do checkMutualGroup cfg infos mbMeasure
+                 -- Remove verified members from rFuncLambdaInfos so that subsequent closures
+                 -- for the same group (registered by other members) find insufficient infos and skip.
+                 modifyIORef' (rFuncLambdaInfos st) (\m -> foldl' (flip Map.delete) m plainMembers)
+         else do debug cfg ["[MEASURE] " <> T.pack funcNm <> ": mutual group already verified, skipping"]
+                 modifyIORef' (rFuncLambdaInfos st) (Map.delete funcNm)
+     _ -> do debug cfg ["[MEASURE] " <> T.pack funcNm <> ": not in a multi-member cycle, skipping mutual check"]
+             modifyIORef' (rFuncLambdaInfos st) (Map.delete funcNm)
+
+-- | Reject mutual recursion for contract-based functions. Deferred to SCC computation time
+-- so that non-mutual cross-refs (helper functions, uninterpreted constants) don't cause false positives.
+rejectMutualContractFromState :: SMTConfig -> String -> State -> IO ()
+rejectMutualContractFromState cfg funcNm st = do
+   defns <- readIORef (rDefns st)
+
+   let barFuncNm = barify funcNm
+       nodes = [(nm, nm, deps) | (nm, (SMTDef _ deps _ _, _)) <- Map.toList defns]
+       sccs  = DG.stronglyConnComp nodes
+       mySCC = [members | DG.CyclicSCC members <- sccs, barFuncNm `elem` members]
+
+   case mySCC of
+     [members] | length members >= 2 ->
+       error $ unlines [ ""
+                        , "*** Data.SBV: smtFunctionWithContract does not support mutual recursion."
+                        , "***"
+                        , "***   Function: " ++ prettyFuncNm funcNm
+                        , "***"
+                        , "*** Please use smtFunction or smtFunctionWithMeasure for mutual recursion groups."
+                        , ""
+                        ]
+     _ -> debug cfg ["[MEASURE] " <> T.pack funcNm <> ": not in a multi-member cycle, skipping mutual contract check"]
+
+-- | Check that all members of a mutual recursion group marked as productive are guarded-recursive,
+-- considering cross-calls as well as self-calls.
+checkMutualProductiveFromState :: SMTConfig -> String -> State -> IO ()
+checkMutualProductiveFromState cfg funcNm st = do
+   defns     <- readIORef (rDefns st)
+   funcInfos <- readIORef (rFuncLambdaInfos st)
+
+   let barFuncNm = barify funcNm
+       nodes = [(nm, nm, deps) | (nm, (SMTDef _ deps _ _, _)) <- Map.toList defns]
+       sccs  = DG.stronglyConnComp nodes
+       mySCC = [members | DG.CyclicSCC members <- sccs, barFuncNm `elem` members]
+
+   case mySCC of
+     [members] | length members >= 2 -> do
+       let plainMembers = map unBar members
+           infos = Map.fromList [(pnm, v) | pnm <- plainMembers, Just v <- [Map.lookup pnm funcInfos]]
+       if Map.size infos >= 2
+         then do let barNames = Set.fromList members
+                     memberNamesStr = intercalate ", " (map prettyFuncNm plainMembers)
+                 debug cfg ["[MEASURE] Checking mutual productive group: {" <> T.pack memberNamesStr <> "}"]
+                 let failed = [(pnm, info) | (pnm, info) <- Map.toList infos, not (isGuardedRecursive barNames info)]
+                 case failed of
+                   [] -> do debug cfg ["[MEASURE] Mutual productive group: all members are guarded"]
+
+                            modifyIORef' (rFuncLambdaInfos st) (\m -> foldl' (flip Map.delete) m plainMembers)
+                   _  -> error $ unlines $
+                            [ ""
+                            , "*** Data.SBV: Mutual productive group has unguarded recursive calls."
+                            , "***"
+                            ]
+                            ++ groupLines (Map.toList infos)
+                            ++
+                            [ "***   Unguarded: " ++ intercalate ", " (map (prettyFuncNm . fst) failed)
+                            , "***"
+                            , "*** Every recursive call (self or cross) must be a direct argument to a data constructor."
+                            , ""
+                            ]
+         else do debug cfg ["[MEASURE] " <> T.pack funcNm <> ": mutual productive group already verified, skipping"]
+                 modifyIORef' (rFuncLambdaInfos st) (Map.delete funcNm)
+     _ -> do debug cfg ["[MEASURE] " <> T.pack funcNm <> ": not in a multi-member cycle, skipping mutual productive check"]
+             modifyIORef' (rFuncLambdaInfos st) (Map.delete funcNm)
+
+-- | Check termination for a mutual recursion group. Each function in the group
+-- gets an auto-guessed measure, and we verify that at every call edge (self or cross),
+-- the caller's measure at formal parameters strictly exceeds the callee's measure at actual arguments.
+--
+-- If a user-provided measure is given ('Just'), it is tried first before auto-guessing.
+checkMutualGroup :: SMTConfig -> Map.Map String LambdaInfo -> Maybe MeasureEval -> IO ()
+checkMutualGroup cfg members mbMeasure = do
+   let memberNames = Map.keys members
+       memberNamesStr = intercalate ", " (map prettyFuncNm memberNames)
+   debug cfg ["[MEASURE] Checking mutual recursion group: {" <> T.pack memberNamesStr <> "}"]
+
+   -- If a user-provided measure is given, try it first
+   let memberList = Map.toList members
+   userOK <- case mbMeasure of
+     Nothing -> pure False
+     Just m  -> do
+       debug cfg ["[MEASURE] Mutual group: trying user-provided measure for all members"]
+       ok <- checkMutualMeasure cfg memberList m
+       if ok
+         then do debug cfg ["[MEASURE] Mutual group: user-provided measure works for all members"]
+                 pure True
+         else do debug cfg ["[MEASURE] Mutual group: user-provided measure failed, falling back to auto-guess"]
+                 pure False
+
+   unless userOK $ do
+     -- Auto-guess: for each function, generate measure candidates
+     let memberCandidates = [(nm, info, guessMeasures (liParams info)) | (nm, info) <- memberList]
+
+     -- Check if any member has no candidates at all
+     case [(nm, info) | (nm, info, []) <- memberCandidates] of
+       (nm, _):_ -> error $ unlines $
+          [ ""
+          , "*** Data.SBV: Cannot determine a termination measure for mutual recursion group."
+          , "***"
+          ]
+          ++ groupLines memberList
+          ++
+          [ "***   Function with no measure candidates: " ++ prettyFuncNm nm
+          , "***"
+          , if isJust mbMeasure
+            then "*** The user-provided measure did not work, and no auto-guess candidates are available."
+            else "*** Please use 'smtFunctionWithMeasure' to provide explicit measures."
+          ]
+       [] -> pure ()
+
+     -- Try to find a working combination. For efficiency, when all members have the same
+     -- parameter kinds, we try the same candidate for all. Otherwise we try combinations.
+     let allCandidateLists = [(nm, info, cs) | (nm, info, cs) <- memberCandidates]
+     tryMeasures allCandidateLists
+
+ where
+   tryMeasures :: [(String, LambdaInfo, [(String, MeasureEval, Maybe Int)])] -> IO ()
+   tryMeasures memberInfos = do
+     -- Collect all unique candidates from all members (by description).
+     -- Different members may have different parameter kinds, yielding different candidates.
+     let allCandidates = nubBy (\(d1,_,_) (d2,_,_) -> d1 == d2)
+                              $ concatMap (\(_, _, cs) -> cs) memberInfos
+
+     result <- go allCandidates
+     case result of
+       Just _  -> pure ()
+       Nothing -> do
+         error $ unlines $
+           [ ""
+           , "*** Data.SBV: Cannot determine a termination measure for mutual recursion group."
+           , "***"
+           ]
+           ++ groupLines (Map.toList members)
+           ++
+           [ "***"
+           , if isJust mbMeasure
+             then "*** The user-provided measure did not work, and auto-guessing also failed."
+             else "*** Please use 'smtFunctionWithMeasure' to provide explicit measures."
+           ]
+
+    where
+     go [] = pure Nothing
+     go ((desc, m, _mbIdx):rest) = do
+       debug cfg ["[MEASURE] Mutual group: trying measure " <> T.pack desc <> " for all members"]
+       -- Try the same measure for all members. Catch exceptions from kind mismatches
+       -- (e.g., applying abs to a list parameter) and treat them as failure.
+       let memberList = [(nm, info) | (nm, info, _) <- memberInfos]
+       result <- C.try $ checkMutualMeasure cfg memberList m
+       case result of
+         Right True -> do debug cfg ["[MEASURE] Mutual group: measure " <> T.pack desc <> " works for all members"]
+                          pure (Just m)
+         Right False -> do debug cfg ["[MEASURE] Mutual group: measure " <> T.pack desc <> " failed, trying next"]
+                           go rest
+         Left (e :: C.SomeException) -> do
+                           debug cfg ["[MEASURE] Mutual group: measure " <> T.pack desc <> " incompatible: " <> showText e]
+                           go rest
+
+-- | Verify that a given measure works for all functions in a mutual recursion group.
+-- Uses the same measure for all members. For each function f, check that at every call
+-- site to any function g in the group, measure(f's formals) > measure(g's actuals).
+checkMutualMeasure :: SMTConfig -> [(String, LambdaInfo)] -> MeasureEval -> IO Bool
+checkMutualMeasure cfgIn members (MeasureEval applyM) = go members
+  where
+    -- Set of barified names of all group members
+    groupBarNames = Set.fromList [barify nm | (nm, _) <- members]
+
+    go [] = pure True
+    go ((funcNm, LambdaInfo{liAssignments, liParams, liOutput, liConsts}):rest) = do
+       -- Find all calls to any member of the mutual group
+       let allGroupCalls = [(sv, args)
+                           | (sv, SBVApp (Uninterpreted calleeNm) args) <- F.toList liAssignments
+                           , calleeNm `Set.member` Set.map T.pack groupBarNames
+                           ]
+
+       if null allGroupCalls
+         then go rest  -- No calls to group members, no decrease needed
+         else do
+           let addSuffix s fp = dropExtension fp ++ "_measure_" ++ map (\c -> if c == ' ' then '_' else c) funcNm ++ "_" ++ s ++ takeExtension fp
+               cfgDecrease    = cfgIn{transcript = addSuffix "mutual_decrease" <$> transcript cfgIn}
+               cfgNonNeg      = cfgIn{transcript = addSuffix "mutual_nonNeg"   <$> transcript cfgIn}
+               paramSVs       = map snd liParams
+               reachConds     = computeReachingConditions liAssignments liOutput
+
+               mkProveEnv = do
+                  st <- symbolicEnv
+                  liftIO $ writeIORef (rSkipMeasureChecks st) True
+                  let singleParam = length paramSVs == 1
+                  freshParams <- liftIO $ sequence
+                    [svToSV st =<< svMkSymVar (NonQueryVar Nothing) (kindOf sv)
+                                              (Just (if singleParam then "arg" else "arg" ++ show i)) st
+                    | (i, sv) <- zip [(0::Int)..] paramSVs
+                    ]
+                  freshConsts <- liftIO $ mapM (\(_, cv) -> svToSV st (SVal (kindOf cv) (Left cv))) liConsts
+                  sessionDefns <- liftIO $ readIORef (rDefns st)
+                  let sessionFuncs = Map.keysSet sessionDefns
+                      constMapping = zip (map fst liConsts) freshConsts
+                      paramMapping = zip paramSVs freshParams
+                      initMap      = Map.fromList (constMapping ++ paramMapping)
+                      builtinMap   = Map.fromList [(trueSV, trueSV), (falseSV, falseSV)]
+                      startMap     = Map.union initMap builtinMap
+                  svMap <- liftIO $ replayDAG cfgIn st groupBarNames sessionFuncs startMap (F.toList liAssignments)
+                  let formalSVals = map (\sv -> SVal (kindOf sv) (Right (cache (\_ -> pure sv)))) freshParams
+                      mFormal     = applyM formalSVals
+                  pure (svMap, mFormal)
+
+           -- Check 1: Non-negativity of caller's measure
+           nonNegResult <- proveWith cfgNonNeg (do
+               (_, mFormal) <- mkProveEnv
+               sObserve "measure" (unSBV mFormal)
+               pure $ nonNeg mFormal :: Symbolic SBool)
+
+           case nonNegResult of
+             ThmResult Unsatisfiable{} -> do
+               -- Check 2: Strict decrease at each call site
+               decResult <- proveWith cfgDecrease (do
+                   (svMap, mFormal) <- mkProveEnv
+                   let singleCall = length allGroupCalls == 1
+                       mkObligation (i, (rcSV, callArgSVs)) = do
+                         let mappedArgs = map (\sv -> Map.findWithDefault sv sv svMap) callArgSVs
+                             argSVals   = map (\sv -> SVal (kindOf sv) (Right (cache (\_ -> pure sv)))) mappedArgs
+                             mCall      = applyM argSVals
+                             reachSVal  = case Map.lookup rcSV reachConds of
+                                            Just conds -> sAnd [ let sv' = Map.findWithDefault condSV condSV svMap
+                                                                     s   = SBV (SVal KBool (Right (cache (\_ -> pure sv'))))
+                                                                 in if pol then s else sNot s
+                                                               | (condSV, pol) <- conds
+                                                               ]
+                                            Nothing    -> sTrue
+                             tag nm | singleCall = nm
+                                    | True       = nm ++ "[" ++ show (i :: Int) ++ "]"
+                         sObserve (tag "then") (unSBV mCall)
+                         pure $ reachSVal .=> mFormal .> mCall
+                   sObserve "before" (unSBV mFormal)
+                   obligations <- mapM mkObligation (zip [1..] allGroupCalls)
+                   pure $ sAnd obligations :: Symbolic SBool)
+               case decResult of
+                 ThmResult Unsatisfiable{} -> do
+                   debug cfgIn ["[MEASURE] Mutual group: decrease verified for " <> T.pack funcNm]
+                   go rest
+                 _ -> do
+                   debug cfgIn ["[MEASURE] Mutual group: decrease failed for " <> T.pack funcNm <> ": " <> showText decResult]
+                   pure False
+             _ -> do
+               debug cfgIn ["[MEASURE] Mutual group: non-negativity failed for " <> T.pack funcNm]
+               pure False
+
+-- | Pretty-print a function name: turn @"insert @(SBV Integer -> SBV [Integer])"@ into @"insert :: SBV Integer -> SBV [Integer]"@
+prettyFuncNm :: String -> String
+prettyFuncNm m = case break (== '@') m of
+                   (nm, '@':'(':tp) | not (null tp) -> dropWhileEnd (== ' ') nm ++ " :: " ++ init tp
+                   _                                -> m
+
+-- | Format group members on separate lines, aligned on @::@.
+groupLines :: [(String, LambdaInfo)] -> [String]
+groupLines ms = case map (prettyFuncNm . fst) ms of
+  []    -> []
+  names -> let parts    = [(nm, tp) | n <- names, let (nm, tp) = case break (== ':') n of
+                                                                    (a, ':':':':b) -> (dropWhileEnd (== ' ') a, " ::" ++ b)
+                                                                    _              -> (n, "")]
+               maxNm    = maximum (map (length . fst) parts)
+               pad s    = s ++ replicate (maxNm - length s) ' '
+               fmt (n, t) = "***     " ++ pad n ++ " " ++ t
+           in map fmt parts
+
+-- | Replay the DAG in a new state, building up an SV mapping from old to new.
+-- Recursive calls to the functions being verified are replaced with fresh variables.
+-- Calls to other DEFINED functions (present in the parent state's rDefns) are replayed as actual calls.
+-- All other Uninterpreted references (uninterpreted constants, free functions, sentinels)
+-- are replaced with fresh variables since they aren't defined in the fresh proveWith session.
+replayDAG :: SMTConfig -> State -> Set.Set String -> Set.Set String -> Map.Map SV SV -> [(SV, SBVExpr)] -> IO (Map.Map SV SV)
+replayDAG cfg st recFuncNames definedFuncs startMap dag = do
+  let n = length dag
+  let nms = intercalate ", " (map unBar (Set.toList recFuncNames))
+  debug cfg ["[MEASURE] replayDAG {" <> T.pack nms <> "}: replaying " <> showText n <> " node(s)"]
+  go startMap dag
+  where -- Map an SV through the svMap. If it's not found, it's an external captured variable
+        -- (e.g., from a higher-order function's closure). Create a fresh unconstrained variable
+        -- for it to avoid leaking foreign-context SVals into the current state.
+        mapArg svMap a = case Map.lookup a svMap of
+                           Just a' -> pure (a', svMap)
+                           Nothing -> do fresh <- newInternalVariable st (kindOf a)
+                                         pure (fresh, Map.insert a fresh svMap)
+
+        mapArgs svMap []     = pure ([], svMap)
+        mapArgs svMap (a:as) = do (a',  svMap')  <- mapArg svMap a
+                                  (as', svMap'') <- mapArgs svMap' as
+                                  pure (a':as', svMap'')
+
+        go svMap []                = pure svMap
+        go svMap ((sv, expr):rest) = do
+          let SBVApp op args = expr
+          (mappedArgs, svMap') <- mapArgs svMap args
+          newSV' <- case op of
+                      -- For recursive calls (self or mutual), create a fresh uninterpreted value instead of replaying
+                      Uninterpreted nm | nm `Set.member` Set.map T.pack recFuncNames -> newInternalVariable st (kindOf sv)
+                      -- For calls to other defined functions (e.g., partition), replay properly
+                      Uninterpreted nm | nm `Set.member` Set.map T.pack definedFuncs -> do
+                                          let mappedOp = mapOpSVs (\a -> Map.findWithDefault a a svMap') op
+                                          newExpr st (kindOf sv) (SBVApp mappedOp mappedArgs)
+                      -- For everything else that's Uninterpreted (free functions, sentinels, etc.),
+                      -- create fresh values since they aren't defined in the proveWith session
+                      Uninterpreted{} -> newInternalVariable st (kindOf sv)
+                      -- For all other operations (arithmetic, list ops, etc.), replay properly
+                      _ -> do let mappedOp = mapOpSVs (\a -> Map.findWithDefault a a svMap') op
+                              newExpr st (kindOf sv) (SBVApp mappedOp mappedArgs)
+          go (Map.insert sv newSV' svMap') rest
+
+-- | Map any SVs embedded directly in an Op (e.g., in LkUp, FP_Cast)
+mapOpSVs :: (SV -> SV) -> Op -> Op
+mapOpSVs f (LkUp p sv1 sv2)                  = LkUp p (f sv1) (f sv2)
+mapOpSVs f (IEEEFP (FP_Cast fk tk sv))       = IEEEFP (FP_Cast fk tk (f sv))
+mapOpSVs _ (ArrayInit (Right lambdaDef))       = ArrayInit (Right lambdaDef)  -- Lambda-local SVs must not be mapped in the enclosing DAG.
+mapOpSVs _ op                                 = op
+
+-- | Compute the reaching condition for each SV: under what boolean condition
+-- does the SV's value contribute to the output? Propagates conditions top-down
+-- through ITE, AND, and OR nodes. Each reaching condition is a list of
+-- @(condSV, polarity)@ pairs; the actual condition is the conjunction: for each
+-- pair, @condSV@ if polarity is 'True', @not condSV@ if polarity is 'False'.
+computeReachingConditions :: Seq.Seq (SV, SBVExpr) -> SV -> Map.Map SV [(SV, Bool)]
+computeReachingConditions asgns outSV = go initMap (reverse $ F.toList asgns)
+  where
+    -- The output's reaching condition is True (empty conjunction)
+    initMap = Map.singleton outSV []
+
+    go condMap [] = condMap
+    go condMap ((sv, SBVApp op args) : rest) =
+      case Map.lookup sv condMap of
+        Nothing -> go condMap rest  -- This SV doesn't contribute to the output
+        Just rc ->
+          let condMap' = case (op, args) of
+                (Ite, [c, t, e]) ->
+                  let condMapT = addReach t ((c, True)  : rc) condMap
+                      condMapE = addReach e ((c, False) : rc) condMapT
+                  in condMapE
+                -- For AND: each arg is only relevant when the other is True
+                (And, [a, b]) ->
+                  let condMapA = addReach a ((b, True) : rc) condMap
+                      condMapB = addReach b ((a, True) : rc) condMapA
+                  in condMapB
+                -- For OR: each arg is only relevant when the other is False
+                (Or, [a, b]) ->
+                  let condMapA = addReach a ((b, False) : rc) condMap
+                      condMapB = addReach b ((a, False) : rc) condMapA
+                  in condMapB
+                _ -> foldl' (\m a -> addReach a rc m) condMap args
+          in go condMap' rest
+
+    -- Add a reaching condition to an SV. For shared nodes, keep the first condition found
+    -- (most direct path from the output).
+    addReach sv rc m = Map.insertWith (\_ old -> old) sv rc m
+
+-- | Regular expressions can be compared for equality. Note that we diverge here from the equality
+-- in the concrete sense; i.e., the Eq instance does not match the symbolic case. This is a bit unfortunate,
+-- but unavoidable with the current design of how we "distinguish" operators. Hopefully shouldn't be a big deal,
+-- though one should be careful.
+instance EqSymbolic RegExp where
+  r1 .== r2 = SBV $ SVal KBool $ Right $ cache r
+    where r st = newExpr st KBool $ SBVApp (RegExOp (RegExEq r1 r2))  []
+
+  r1 ./= r2 = SBV $ SVal KBool $ Right $ cache r
+    where r st = newExpr st KBool $ SBVApp (RegExOp (RegExNEq r1 r2)) []
+
+-- | Symbolic Numbers. This is a simple class that simply incorporates all number like
+-- base types together, simplifying writing polymorphic type-signatures that work for all
+-- symbolic numbers, such as 'SWord8', 'SInt8' etc. For instance, we can write a generic
+-- list-minimum function as follows:
+--
+-- @
+--    mm :: SIntegral a => [SBV a] -> SBV a
+--    mm = foldr1 (\a b -> ite (a .<= b) a b)
+-- @
+--
+-- It is similar to the standard 'Integral' class, except ranging over symbolic instances.
+class (SymVal a, Num a, Num (SBV a), Bits a, Integral a) => SIntegral a
+
+-- 'SIntegral' Instances, skips Real/Float/Bool
+instance SIntegral Word8
+instance SIntegral Word16
+instance SIntegral Word32
+instance SIntegral Word64
+instance SIntegral Int8
+instance SIntegral Int16
+instance SIntegral Int32
+instance SIntegral Int64
+instance SIntegral Integer
+instance (KnownNat n, BVIsNonZero n) => SIntegral (WordN n)
+instance (KnownNat n, BVIsNonZero n) => SIntegral (IntN n)
+
+-- | Zero extend a bit-vector.
+zeroExtend :: forall n m bv. ( KnownNat n, BVIsNonZero n, SymVal (bv n)
+                             , KnownNat m, BVIsNonZero m, SymVal (bv m)
+                             , n + 1 <= m
+                             , SIntegral (bv (m - n))
+                             , BVIsNonZero (m - n)
+                             ) => SBV (bv n)    -- ^ Input, of size @n@
+                               -> SBV (bv m)    -- ^ Output, of size @m@. @n < m@ must hold
+zeroExtend n = SBV $ svZeroExtend i (unSBV n)
+  where nv = intOfProxy (Proxy @n)
+        mv = intOfProxy (Proxy @m)
+        i  = fromIntegral (mv - nv)
+
+-- | Sign extend a bit-vector.
+signExtend :: forall n m bv. ( KnownNat n, BVIsNonZero n, SymVal (bv n)
+                             , KnownNat m, BVIsNonZero m, SymVal (bv m)
+                             , n + 1 <= m
+                             , SFiniteBits (bv n)
+                             , SIntegral   (bv (m - n))
+                             , BVIsNonZero (m - n)
+                             ) => SBV (bv n)  -- ^ Input, of size @n@
+                               -> SBV (bv m)  -- ^ Output, of size @m@. @n < m@ must hold
+signExtend n = SBV $ svSignExtend i (unSBV n)
+  where nv = intOfProxy (Proxy @n)
+        mv = intOfProxy (Proxy @m)
+        i  = fromIntegral (mv - nv)
+
+
+-- | Finite bit-length symbolic values. Essentially the same as 'SIntegral', but further leaves out 'Integer'. Loosely
+-- based on Haskell's @FiniteBits@ class, but with more methods defined and structured differently to fit into the
+-- symbolic world view. Minimal complete definition: 'sFiniteBitSize'.
+class (Ord a, SymVal a, Num a, Num (SBV a), OrdSymbolic (SBV a), Bits a) => SFiniteBits a where
+    -- | Bit size.
+    sFiniteBitSize      :: SBV a -> Int
+    -- | Least significant bit of a word, always stored at index 0.
+    lsb                 :: SBV a -> SBool
+    -- | Most significant bit of a word, always stored at the last position.
+    msb                 :: SBV a -> SBool
+    -- | Big-endian blasting of a word into its bits.
+    blastBE             :: SBV a -> [SBool]
+    -- | Little-endian blasting of a word into its bits.
+    blastLE             :: SBV a -> [SBool]
+    -- | Reconstruct from given bits, given in little-endian.
+    fromBitsBE          :: [SBool] -> SBV a
+    -- | Reconstruct from given bits, given in little-endian.
+    fromBitsLE          :: [SBool] -> SBV a
+    -- | Replacement for 'testBit', returning 'SBool' instead of 'Bool'.
+    sTestBit            :: SBV a -> Int -> SBool
+    -- | Variant of 'sTestBit', where we want to extract multiple bit positions.
+    sExtractBits        :: SBV a -> [Int] -> [SBool]
+    -- | Variant of 'popCount', returning a symbolic value.
+    sPopCount           :: SBV a -> SWord8
+    -- | A combo of 'setBit' and 'clearBit', when the bit to be set is symbolic.
+    setBitTo            :: SBV a -> Int -> SBool -> SBV a
+    -- | Variant of 'setBitTo' when the index is symbolic. If the index it out-of-bounds,
+    -- then the result is underspecified.
+    sSetBitTo           :: Integral a => SBV a -> SBV a -> SBool -> SBV a
+    -- | Full adder, returns carry-out from the addition. Only for unsigned quantities.
+    fullAdder           :: SBV a -> SBV a -> (SBool, SBV a)
+    -- | Full multiplier, returns both high and low-order bits. Only for unsigned quantities.
+    fullMultiplier      :: SBV a -> SBV a -> (SBV a, SBV a)
+    -- | Count leading zeros in a word, big-endian interpretation.
+    sCountLeadingZeros  :: SBV a -> SWord8
+    -- | Count trailing zeros in a word, big-endian interpretation.
+    sCountTrailingZeros :: SBV a -> SWord8
+
+    {-# MINIMAL sFiniteBitSize #-}
+
+    -- Default implementations
+    lsb (SBV v) = SBV (svTestBit v 0)
+    msb x       = sTestBit x (sFiniteBitSize x - 1)
+
+    blastBE   = reverse . blastLE
+    blastLE x = map (sTestBit x) [0 .. intSizeOf x - 1]
+
+    fromBitsBE = fromBitsLE . reverse
+    fromBitsLE bs
+       | length bs /= w
+       = error $ "SBV.SFiniteBits.fromBitsLE/BE: Expected: " ++ show w ++ " bits, received: " ++ show (length bs)
+       | True
+       = result
+       where w = sFiniteBitSize result
+             result = go 0 0 bs
+
+             go !acc _  []     = acc
+             go !acc !i (x:xs) = go (ite x (setBit acc i) acc) (i+1) xs
+
+    sTestBit (SBV x) i = SBV (svTestBit x i)
+    sExtractBits x     = map (sTestBit x)
+
+    -- NB. 'sPopCount' returns an 'SWord8', which can overflow when used on quantities that have
+    -- more than 255 bits. For the regular interface, this suffices for all types we support.
+    -- For the Dynamic interface, if we ever implement this, this will fail for bit-vectors
+    -- larger than that many bits. The alternative would be to return SInteger here, but that
+    -- seems a total overkill for most use cases. If such is required, users are encouraged
+    -- to define their own variants, which is rather easy.
+    sPopCount x
+      | Just v <- unliteral x = go 0 v
+      | True                  = sum [ite b 1 0 | b <- blastLE x]
+      where -- concrete case
+            go !c 0 = c
+            go !c w = go (c+1) (w .&. (w-1))
+
+    setBitTo x i b = ite b (setBit x i) (clearBit x i)
+
+    sSetBitTo x idx b
+      | Just i <- unliteral idx, Just index <- safe i
+      = setBitTo x index b
+      | True
+      = go x [0 .. sFiniteBitSize x - 1]
+      where -- paranoia check: make sure index can fit in an int
+            safe i = let asInteger   = toInteger i
+                         asInt       = fromIntegral asInteger
+                         backInteger = toInteger asInt
+                     in if backInteger == asInteger
+                        then Just asInt
+                        else Nothing
+
+            go v []     = v
+            go v (i:is) = go (ite (idx .== literal (fromIntegral i)) (setBitTo v (fromIntegral i) b) v) is
+
+    fullAdder a b
+      | isSigned a = error "fullAdder: only works on unsigned numbers"
+      | True       = (a .> s .|| b .> s, s)
+      where s = a + b
+
+    -- N.B. The higher-order bits are determined using a simple shift-add multiplier,
+    -- thus involving bit-blasting. It'd be naive to expect SMT solvers to deal efficiently
+    -- with properties involving this function, at least with the current state of the art.
+    fullMultiplier a b
+      | isSigned a = error "fullMultiplier: only works on unsigned numbers"
+      | True       = (go (sFiniteBitSize a) 0 a, a*b)
+      where go 0 p _ = p
+            go n p x = let (c, p')  = ite (lsb x) (fullAdder p b) (sFalse, p)
+                           (o, p'') = shiftIn c p'
+                           (_, x')  = shiftIn o x
+                       in go (n-1) p'' x'
+            shiftIn k v = (lsb v, mask .|. (v `shiftR` 1))
+               where mask = ite k (bit (sFiniteBitSize v - 1)) 0
+
+    -- See the note for 'sPopCount' for a comment on why we return 'SWord8'
+    sCountLeadingZeros x = fromIntegral m - go m
+      where m = sFiniteBitSize x - 1
+
+            -- NB. When i is 0 below, which happens when x is 0 as we count all the way down,
+            -- we return -1, which is equal to 2^n-1, giving us: n-1-(2^n-1) = n-2^n = n, as required, i.e., the bit-size.
+            go :: Int -> SWord8
+            go i | i < 0 = i8
+                 | True  = ite (sTestBit x i) i8 (go (i-1))
+               where i8 = literal (fromIntegral i :: Word8)
+
+    -- See the note for 'sPopCount' for a comment on why we return 'SWord8'
+    sCountTrailingZeros x = go 0
+       where m = sFiniteBitSize x
+
+             go :: Int -> SWord8
+             go i | i >= m = i8
+                  | True   = ite (sTestBit x i) i8 (go (i+1))
+                where i8 = literal (fromIntegral i :: Word8)
+
+-- 'SFiniteBits' Instances, skips Real/Float/Bool/Integer
+instance SFiniteBits Word8  where sFiniteBitSize _ =  8
+instance SFiniteBits Word16 where sFiniteBitSize _ = 16
+instance SFiniteBits Word32 where sFiniteBitSize _ = 32
+instance SFiniteBits Word64 where sFiniteBitSize _ = 64
+instance SFiniteBits Int8   where sFiniteBitSize _ =  8
+instance SFiniteBits Int16  where sFiniteBitSize _ = 16
+instance SFiniteBits Int32  where sFiniteBitSize _ = 32
+instance SFiniteBits Int64  where sFiniteBitSize _ = 64
+instance (KnownNat n, BVIsNonZero n) => SFiniteBits (WordN n) where sFiniteBitSize _ = intOfProxy (Proxy @n)
+instance (KnownNat n, BVIsNonZero n) => SFiniteBits (IntN  n) where sFiniteBitSize _ = intOfProxy (Proxy @n)
+
+-- | Returns 1 if the boolean is 'sTrue', otherwise 0.
+oneIf :: (Ord a, Num (SBV a), SymVal a) => SBool -> SBV a
+oneIf t = ite t 1 0
+
+-- | Lift a pseudo-boolean op, performing checks
+liftPB :: String -> PBOp -> [SBool] -> SBool
+liftPB w o xs
+  | Just e <- check o
+  = error $ "SBV." ++ w ++ ": " ++ e
+  | True
+  = result
+  where check (PB_AtMost  k) = pos k
+        check (PB_AtLeast k) = pos k
+        check (PB_Exactly k) = pos k
+        check (PB_Le cs   k) = pos k `mplus` match cs
+        check (PB_Ge cs   k) = pos k `mplus` match cs
+        check (PB_Eq cs   k) = pos k `mplus` match cs
+
+        pos k
+          | k < 0 = Just $ "comparison value must be positive, received: " ++ show k
+          | True  = Nothing
+
+        match cs
+          | any (< 0) cs = Just $ "coefficients must be non-negative. Received: " ++ show cs
+          | lxs /= lcs   = Just $ "coefficient length must match number of arguments. Received: " ++ show (lcs, lxs)
+          | True         = Nothing
+          where lxs = length xs
+                lcs = length cs
+
+        result = SBV (SVal KBool (Right (cache r)))
+        r st   = do xsv <- mapM (sbvToSV st) xs
+                    -- PseudoBoolean's implicitly require support for integers, so make sure to register that kind!
+                    registerKind st KUnbounded
+                    newExpr st KBool (SBVApp (PseudoBoolean o) xsv)
+
+-- | 'sTrue' if at most @k@ of the input arguments are 'sTrue'
+pbAtMost :: [SBool] -> Int -> SBool
+pbAtMost xs k
+ | k < 0             = error $ "SBV.pbAtMost: Non-negative value required, received: " ++ show k
+ | all isConcrete xs = literal $ sum (map (pbToInteger "pbAtMost" 1) xs) <= fromIntegral k
+ | True              = liftPB "pbAtMost" (PB_AtMost k) xs
+
+-- | 'sTrue' if at least @k@ of the input arguments are 'sTrue'
+pbAtLeast :: [SBool] -> Int -> SBool
+pbAtLeast xs k
+ | k < 0             = error $ "SBV.pbAtLeast: Non-negative value required, received: " ++ show k
+ | all isConcrete xs = literal $ sum (map (pbToInteger "pbAtLeast" 1) xs) >= fromIntegral k
+ | True              = liftPB "pbAtLeast" (PB_AtLeast k) xs
+
+-- | 'sTrue' if exactly @k@ of the input arguments are 'sTrue'
+pbExactly :: [SBool] -> Int -> SBool
+pbExactly xs k
+ | k < 0             = error $ "SBV.pbExactly: Non-negative value required, received: " ++ show k
+ | all isConcrete xs = literal $ sum (map (pbToInteger "pbExactly" 1) xs) == fromIntegral k
+ | True              = liftPB "pbExactly" (PB_Exactly k) xs
+
+-- | 'sTrue' if the sum of coefficients for 'sTrue' elements is at most @k@. Generalizes 'pbAtMost'.
+pbLe :: [(Int, SBool)] -> Int -> SBool
+pbLe xs k
+ | k < 0                     = error $ "SBV.pbLe: Non-negative value required, received: " ++ show k
+ | all (isConcrete . snd) xs = literal $ sum [pbToInteger "pbLe" c b | (c, b) <- xs] <= fromIntegral k
+ | True                      = liftPB "pbLe" (PB_Le (map fst xs) k) (map snd xs)
+
+-- | 'sTrue' if the sum of coefficients for 'sTrue' elements is at least @k@. Generalizes 'pbAtLeast'.
+pbGe :: [(Int, SBool)] -> Int -> SBool
+pbGe xs k
+ | k < 0                     = error $ "SBV.pbGe: Non-negative value required, received: " ++ show k
+ | all (isConcrete . snd) xs = literal $ sum [pbToInteger "pbGe" c b | (c, b) <- xs] >= fromIntegral k
+ | True                      = liftPB "pbGe" (PB_Ge (map fst xs) k) (map snd xs)
+
+-- | 'sTrue' if the sum of coefficients for 'sTrue' elements is exactly least @k@. Useful for coding
+-- /exactly K-of-N/ constraints, and in particular mutex constraints.
+pbEq :: [(Int, SBool)] -> Int -> SBool
+pbEq xs k
+ | k < 0                     = error $ "SBV.pbEq: Non-negative value required, received: " ++ show k
+ | all (isConcrete . snd) xs = literal $ sum [pbToInteger "pbEq" c b | (c, b) <- xs] == fromIntegral k
+ | True                      = liftPB "pbEq" (PB_Eq (map fst xs) k) (map snd xs)
+
+-- | 'sTrue' if there is at most one set bit
+pbMutexed :: [SBool] -> SBool
+pbMutexed xs = pbAtMost xs 1
+
+-- | 'sTrue' if there is exactly one set bit
+pbStronglyMutexed :: [SBool] -> SBool
+pbStronglyMutexed xs = pbExactly xs 1
+
+-- | Convert a concrete pseudo-boolean to given int; converting to integer
+pbToInteger :: String -> Int -> SBool -> Integer
+pbToInteger w c b
+ | c < 0                 = error $ "SBV." ++ w ++ ": Non-negative coefficient required, received: " ++ show c
+ | Just v <- unliteral b = if v then fromIntegral c else 0
+ | True                  = error $ "SBV.pbToInteger: Received a symbolic boolean: " ++ show (c, b)
+
+-- | Predicate for optimizing word operations like (+) and (*).
+isConcreteZero :: SBV a -> Bool
+isConcreteZero (SBV (SVal _     (Left (CV _     (CInteger n))))) = n == 0
+isConcreteZero (SBV (SVal KReal (Left (CV KReal (CAlgReal v))))) = isExactRational v && v == 0
+isConcreteZero _                                                 = False
+
+-- | Predicate for optimizing word operations like (+) and (*).
+isConcreteOne :: SBV a -> Bool
+isConcreteOne (SBV (SVal _     (Left (CV _     (CInteger 1))))) = True
+isConcreteOne (SBV (SVal KReal (Left (CV KReal (CAlgReal v))))) = isExactRational v && v == 1
+isConcreteOne _                                                 = False
+
+-- | Symbolic exponentiation using bit blasting and repeated squaring.
+--
+-- N.B. The exponent must be unsigned/bounded if symbolic. Signed exponents will be rejected.
+(.^) :: (Mergeable b, Num b, SIntegral e) => b -> SBV e -> b
+b .^ e
+  | isConcrete e, Just (x :: Integer) <- unliteral (sFromIntegral e)
+  = if x >= 0 then let go n v
+                        | n == 0 = 1
+                        | even n =     go (n `div` 2) (v * v)
+                        | True   = v * go (n `div` 2) (v * v)
+                   in  go x b
+              else error $ "(.^): exponentiation: negative exponent: " ++ show x
+  | not (isBounded e) || isSigned e
+  = error $ "(.^): exponentiation only works with unsigned bounded symbolic exponents, kind: " ++ show (kindOf e)
+  | True
+  =  -- NB. We can't simply use sTestBit and blastLE since they have SFiniteBit requirement
+     -- but we want to have SIntegral here only.
+     let SBV expt = e
+         expBit i = SBV (svTestBit expt i)
+         blasted  = map expBit [0 .. intSizeOf e - 1]
+     in product $ zipWith (\use n -> ite use n 1)
+                          blasted
+                          (iterate (\x -> x*x) b)
+infixr 8 .^
+
+-- | Integer exponentiation, emitted as SMT-LIB's @**@ over the @Int@ theory. Unlike '.^' (which
+-- mirrors Haskell's @^@), @.**@ places no restriction on the exponent: it may be negative or
+-- symbolic.
+--
+-- If both arguments are concrete and the exponent is non-negative, the result is computed and
+-- returned as a literal. Otherwise the application is emitted as SMT-LIB's @**@, whose @Int@-theory
+-- semantics are: for @n >= 0@, ordinary exponentiation (with @0 .** 0 == 1@); for @n < 0@, @0@ when
+-- @m == 0@ or @abs m > 1@, and @m .** abs n@ when @abs m == 1@.
+--
+-- N.B. Symbolic (or negative) integer exponentiation via @**@ is not supported by all solvers, so
+-- such a query may come back as @unknown@ (or the solver may reject it outright).
+--
+-- Concrete, non-negative exponents fold directly:
+--
+-- >>> 2 .** 3
+-- 8 :: SInteger
+-- >>> (-2) .** 3
+-- -8 :: SInteger
+-- >>> 0 .** 0
+-- 1 :: SInteger
+--
+-- Symbolic and negative exponents are handed to the solver, so they need a backend that
+-- implements SMT-LIB's @**@. No solver supports it yet (as of July 2026), so the following
+-- are illustrative only:
+--
+-- @
+-- prove $ \\x -> x .** 2 .== x * x     -- Q.E.D.
+-- prove $ 2 .** (-3) .== 0             -- Q.E.D.
+-- prove $ (-1) .** (-3) .== -1         -- Q.E.D.
+-- @
+(.**) :: SInteger -> SInteger -> SInteger
+m .** n
+  | Just b <- unliteral m, Just e <- unliteral n, e >= 0
+  = literal (b ^ e)
+  | True
+  = SBV $ SVal KUnbounded $ Right $ cache r
+  where r st = do sm <- sbvToSV st m
+                  sn <- sbvToSV st n
+                  newExpr st KUnbounded (SBVApp (NonLinear NR_IntPow) [sm, sn])
+infixr 8 .**
+
+instance (Ord a, Num (SBV a), SymVal a, Fractional a) => Fractional (SBV a) where
+  fromRational  = literal . fromRational
+  SBV x / sy@(SBV y) | div0 = ite (sy .== 0) 0 res
+                     | True = res
+       where res  = SBV (svDivide x y)
+             -- Identify those kinds where we have a div-0 equals 0 exception
+             div0 = case kindOf sy of
+                      KVar{}             -> error $ "Unexpected Fractional case for: " ++ show (kindOf sy)
+                      KFloat             -> False
+                      KDouble            -> False
+                      KFP{}              -> False
+                      KReal              -> True
+                      KRational          -> True
+                      -- Following cases should not happen since these types should *not* be instances of Fractional
+                      k@KBounded{}  -> error $ "Unexpected Fractional case for: " ++ show k
+                      k@KUnbounded  -> error $ "Unexpected Fractional case for: " ++ show k
+                      k@KBool       -> error $ "Unexpected Fractional case for: " ++ show k
+                      k@KString     -> error $ "Unexpected Fractional case for: " ++ show k
+                      k@KChar       -> error $ "Unexpected Fractional case for: " ++ show k
+                      k@KList{}     -> error $ "Unexpected Fractional case for: " ++ show k
+                      k@KSet{}      -> error $ "Unexpected Fractional case for: " ++ show k
+                      k@KApp{}      -> error $ "Unexpected Fractional case for: " ++ show k
+                      k@KADT{}      -> error $ "Unexpected Fractional case for: " ++ show k
+                      k@KTuple{}    -> error $ "Unexpected Fractional case for: " ++ show k
+                      k@KArray{}    -> error $ "Unexpected Fractional case for: " ++ show k
+
+-- | Define Floating instance on SBV's; only for base types that are already floating; i.e., 'SFloat', 'SDouble', and 'SReal'.
+-- (See the separate definition below for 'SFloatingPoint'.)  Note that unless you use delta-sat via 'Data.SBV.Provers.dReal' on 'SReal', most
+-- of the fields are "undefined" for symbolic values. We will add methods as they are supported by SMTLib. Currently, the
+-- only symbolically available function in this class is 'sqrt' for 'SFloat', 'SDouble' and 'SFloatingPoint'.
+instance (Ord a, Num (SBV a), SymVal a, Fractional a, Floating a) => Floating (SBV a) where
+  pi      = fromRational . toRational $ (pi :: Double)
+  exp     = lift1FNS "exp"     exp
+  log     = lift1FNS "log"     log
+  sqrt    = lift1F   FP_Sqrt   sqrt
+  sin     = lift1FNS "sin"     sin
+  cos     = lift1FNS "cos"     cos
+  tan     = lift1FNS "tan"     tan
+  asin    = lift1FNS "asin"    asin
+  acos    = lift1FNS "acos"    acos
+  atan    = lift1FNS "atan"    atan
+  sinh    = lift1FNS "sinh"    sinh
+  cosh    = lift1FNS "cosh"    cosh
+  tanh    = lift1FNS "tanh"    tanh
+  asinh   = lift1FNS "asinh"   asinh
+  acosh   = lift1FNS "acosh"   acosh
+  atanh   = lift1FNS "atanh"   atanh
+  (**)    = lift2FNS "**"      (**)
+  logBase = lift2FNS "logBase" logBase
+
+unsupported :: String -> a
+unsupported w = error $ "Data.SBV.FloatingPoint: Unsupported operation: " ++ w ++ ". Please request this as a feature!"
+
+-- | We give a specific instance for 'SFloatingPoint', because the underlying floating-point type doesn't support
+-- fromRational directly. The overlap with the above instance is unfortunate.
+instance {-# OVERLAPPING #-} ValidFloat eb sb => Floating (SFloatingPoint eb sb) where
+  -- Try from double; if there's enough precision this'll work, otherwise will bail out.
+  pi
+   | ei > 11 || si > 53 = unsupported $ "Floating.SFloatingPoint.pi (not-enough-precision for " ++ show (ei, si) ++ ")"
+   | True               = literal $ FloatingPoint $ fpFromRational ei si (toRational (pi :: Double))
+   where ei = intOfProxy (Proxy @eb)
+         si = intOfProxy (Proxy @sb)
+
+  -- Likewise, exponentiation is again limited to precision of double
+  exp i
+   | ei > 11 || si > 53 = unsupported $ "Floating.SFloatingPoint.exp (not-enough-precision for " ++ show (ei, si) ++ ")"
+   | True               = literal e ** i
+   where ei = intOfProxy (Proxy @eb)
+         si = intOfProxy (Proxy @sb)
+         e  = FloatingPoint $ fpFromRational ei si (toRational (exp 1 :: Double))
+
+  log     = lift1FNS "log"     log
+  sqrt    = lift1F   FP_Sqrt   sqrt
+  sin     = lift1FNS "sin"     sin
+  cos     = lift1FNS "cos"     cos
+  tan     = lift1FNS "tan"     tan
+  asin    = lift1FNS "asin"    asin
+  acos    = lift1FNS "acos"    acos
+  atan    = lift1FNS "atan"    atan
+  sinh    = lift1FNS "sinh"    sinh
+  cosh    = lift1FNS "cosh"    cosh
+  tanh    = lift1FNS "tanh"    tanh
+  asinh   = lift1FNS "asinh"   asinh
+  acosh   = lift1FNS "acosh"   acosh
+  atanh   = lift1FNS "atanh"   atanh
+  (**)    = lift2FNS "**"      (**)
+  logBase = lift2FNS "logBase" logBase
+
+-- | Lift a 1 arg FP-op, using sRNE default
+lift1F :: SymVal a => FPOp -> (a -> a) -> SBV a -> SBV a
+lift1F w op a
+  | Just v <- unliteral a
+  = literal $ op v
+  | True
+  = SBV $ SVal k $ Right $ cache r
+  where k    = kindOf a
+        r st = do swa  <- sbvToSV st a
+                  swm  <- sbvToSV st sRNE
+                  newExpr st k (SBVApp (IEEEFP w) [swm, swa])
+
+-- | Lift a float/double unary function, only over constants
+lift1FNS :: (SymVal a, Floating a) => String -> (a -> a) -> SBV a -> SBV a
+lift1FNS nm f sv
+  | Just v <- unliteral sv = literal $ f v
+  | True                   = error $ "SBV." ++ nm ++ ": not supported for symbolic values of type " ++ show (kindOf sv)
+
+-- | Lift a float/double binary function, only over constants
+lift2FNS :: (SymVal a, Floating a) => String -> (a -> a -> a) -> SBV a -> SBV a -> SBV a
+lift2FNS nm f sv1 sv2
+  | Just v1 <- unliteral sv1
+  , Just v2 <- unliteral sv2 = literal $ f v1 v2
+  | True                     = error $ "SBV." ++ nm ++ ": not supported for symbolic values of type " ++ show (kindOf sv1)
+
+-- | SReal Floating instance, used in conjunction with the dReal solver for delta-satisfiability. Note that
+-- we do not constant fold these values (except for pi), as Haskell doesn't really have any means of computing
+-- them for arbitrary rationals.
+instance {-# OVERLAPPING #-} Floating SReal where
+  -- Should we support pi? It's a transcendental value, and our SReal type has no way of representing
+  -- this quantity with the required fidelity. (SReal can only support roots of polynomials and rationals
+  -- correctly, not transcendentals.) One option is to use an approximation here. But that goes against the
+  -- whole idea of Real being infinitely precise. Another option is to see if the solver has support for it, such
+  -- as CVC5, which has the constant real.pi. Alas, that has its problems: In models CVC5 uses real.pi as a
+  -- model value, which we have no way of properly supporting back as a Haskell value. Worse: It uses it in
+  -- expressions like 1 + real.pi, which we don't have an evaluator for. So, we simply say not supported.
+  -- If you want it for reals, you'll have to plugin your own "approximation" for it, and thus be aware of the
+  -- limitations of that choice.
+  pi      = error $ unlines [ ""
+                            , "*** Data.SBV.SReal: Cannot represent pi as an SReal value."
+                            , "***"
+                            , "*** Usual trick is to use an approximation if that suits your purpose,"
+                            , "*** or use solver-specific constants when applicable. Please get in touch"
+                            , "*** if you'd like to explore ideas here."
+                            ]
+
+  exp     = lift1SReal NR_Exp
+  log     = lift1SReal NR_Log
+  sqrt    = lift1SReal NR_Sqrt
+  sin     = lift1SReal NR_Sin
+  cos     = lift1SReal NR_Cos
+  tan     = lift1SReal NR_Tan
+  asin    = lift1SReal NR_ASin
+  acos    = lift1SReal NR_ACos
+  atan    = lift1SReal NR_ATan
+  sinh    = lift1SReal NR_Sinh
+  cosh    = lift1SReal NR_Cosh
+  tanh    = lift1SReal NR_Tanh
+  asinh   = error "Data.SBV.SReal: asinh is currently not supported. Please request this as a feature!"
+  acosh   = error "Data.SBV.SReal: acosh is currently not supported. Please request this as a feature!"
+  atanh   = error "Data.SBV.SReal: atanh is currently not supported. Please request this as a feature!"
+  (**)    = lift2SReal NR_Pow
+
+  logBase x y = log y  / log x
+
+-- | Lift an sreal unary function
+lift1SReal :: NROp -> SReal -> SReal
+lift1SReal w a = SBV $ SVal k $ Right $ cache r
+  where k    = kindOf a
+        r st = do swa <- sbvToSV st a
+                  newExpr st k (SBVApp (NonLinear w) [swa])
+
+-- | Lift an sreal binary function
+lift2SReal :: NROp -> SReal -> SReal -> SReal
+lift2SReal w a b = SBV $ SVal k $ Right $ cache r
+  where k    = kindOf a
+        r st = do swa <- sbvToSV st a
+                  swb <- sbvToSV st b
+                  newExpr st k (SBVApp (NonLinear w) [swa, swb])
+
+-- Bail out nicely.
+noEquals :: String -> String -> (String, String) -> a
+noEquals o n (l, r) = error $ unlines [ ""
+                                      , "*** Data.SBV: Comparing symbolic values using Haskell's Eq class!"
+                                      , "***"
+                                      , "*** Received:    (" ++ l ++ ")  " ++ o ++ " (" ++ r ++ ")"
+                                      , "*** Instead use: (" ++ l ++ ") "  ++ n ++ " (" ++ r ++ ")"
+                                      , "***"
+                                      , "*** The Eq instance for symbolic values are necessiated only because"
+                                      , "*** of the Bits class requirement. You must use symbolic equality"
+                                      , "*** operators instead. (And complain to Haskell folks that they"
+                                      , "*** remove the 'Eq' superclass from 'Bits'!.)"
+                                      ]
+
+-- | This instance is only defined so that we can define an instance for
+-- 'Data.Bits.Bits'. '==' and '/=' simply throw an error. Use
+-- 'Data.SBV.EqSymbolic' instead.
+instance SymVal a => Eq (SBV a) where
+  a == b = fromMaybe (noEquals "==" ".==" (show a, show b)) (unliteral (a .== b))
+  a /= b = fromMaybe (noEquals "/=" "./=" (show a, show b)) (unliteral (a ./= b))
+
+-- NB. In the optimizations below, use of -1 is valid as
+-- -1 has all bits set to True for both signed and unsigned values
+-- | Using 'popCount' or 'testBit' on non-concrete values will result in an
+-- error. Use 'sPopCount' or 'sTestBit' instead.
+instance (Ord a, Num (SBV a), Num a, Bits a, SymVal a) => Bits (SBV a) where
+  SBV x .&. SBV y    = SBV (svAnd x y)
+  SBV x .|. SBV y    = SBV (svOr x y)
+  SBV x `xor` SBV y  = SBV (svXOr x y)
+  complement (SBV x) = SBV (svNot x)
+  bitSize  x         = intSizeOf x
+  bitSizeMaybe x     = Just $ intSizeOf x
+  isSigned x         = hasSign x
+  bit i              = 1 `shiftL` i
+  setBit        x i  = x .|. genLiteral (kindOf x) (bit i :: Integer)
+  clearBit      x i  = x .&. genLiteral (kindOf x) (complement (bit i) :: Integer)
+  complementBit x i  = x `xor` genLiteral (kindOf x) (bit i :: Integer)
+  shiftL  (SBV x) i  = SBV (svShl x i)
+  shiftR  (SBV x) i  = SBV (svShr x i)
+  rotateL (SBV x) i  = SBV (svRol x i)
+  rotateR (SBV x) i  = SBV (svRor x i)
+  -- NB. testBit is *not* implementable on non-concrete symbolic words
+  x `testBit` i
+    | SBV (SVal _ (Left (CV _ (CInteger n)))) <- x
+    = testBit n i
+    | True
+    = error $ "SBV.testBit: Called on symbolic value: " ++ show x ++ ". Use sTestBit instead."
+  -- NB. popCount is *not* implementable on non-concrete symbolic words
+  popCount x
+    | SBV (SVal _ (Left (CV (KBounded _ w) (CInteger n)))) <- x
+    = popCount (n .&. (bit w - 1))
+    | True
+    = error $ "SBV.popCount: Called on symbolic value: " ++ show x ++ ". Use sPopCount instead."
+
+-- | Conversion between integral-symbolic values, akin to Haskell's `fromIntegral`
+sFromIntegral :: forall a b. (Integral a, HasKind a, Num a, SymVal a, HasKind b, Num b, SymVal b) => SBV a -> SBV b
+sFromIntegral x
+  | kFrom == kTo
+  = SBV (unSBV x)
+  | isReal x
+  = error "SBV.sFromIntegral: Called on a real value" -- can't really happen due to types, but being overcautious
+  | Just v <- unliteral x
+  = literal (fromIntegral v)
+  | True
+  = result
+  where result = SBV (SVal kTo (Right (cache y)))
+        kFrom  = kindOf x
+        kTo    = kindOf (Proxy @b)
+        y st   = do xsv <- sbvToSV st x
+                    newExpr st kTo (SBVApp (KindCast kFrom kTo) [xsv])
+
+-- | Lift a binary operation thru its dynamic counterpart. Note that
+-- we still want the actual functions here as differ in their type
+-- compared to their dynamic counterparts, but the implementations
+-- are the same.
+liftViaSVal :: (SVal -> SVal -> SVal) -> SBV a -> SBV b -> SBV c
+liftViaSVal f (SBV a) (SBV b) = SBV $ f a b
+
+-- | Generalization of 'shiftL', when the shift-amount is symbolic. Since Haskell's
+-- 'shiftL' only takes an 'Int' as the shift amount, it cannot be used when we have
+-- a symbolic amount to shift with.
+sShiftLeft :: (SIntegral a, SIntegral b) => SBV a -> SBV b -> SBV a
+sShiftLeft = liftViaSVal svShiftLeft
+
+-- | Generalization of 'shiftR', when the shift-amount is symbolic. Since Haskell's
+-- 'shiftR' only takes an 'Int' as the shift amount, it cannot be used when we have
+-- a symbolic amount to shift with.
+--
+-- NB. If the shiftee is signed, then this is an arithmetic shift; otherwise it's logical,
+-- following the usual Haskell convention. See 'sSignedShiftArithRight' for a variant
+-- that explicitly uses the msb as the sign bit, even for unsigned underlying types.
+sShiftRight :: (SIntegral a, SIntegral b) => SBV a -> SBV b -> SBV a
+sShiftRight = liftViaSVal svShiftRight
+
+-- | Arithmetic shift-right with a symbolic unsigned shift amount. This is equivalent
+-- to 'sShiftRight' when the argument is signed. However, if the argument is unsigned,
+-- then it explicitly treats its msb as a sign-bit, and uses it as the bit that
+-- gets shifted in. Useful when using the underlying unsigned bit representation to implement
+-- custom signed operations. Note that there is no direct Haskell analogue of this function.
+sSignedShiftArithRight:: (SFiniteBits a, SIntegral b) => SBV a -> SBV b -> SBV a
+sSignedShiftArithRight x i
+  | isSigned i = error "sSignedShiftArithRight: shift amount should be unsigned"
+  | isSigned x = ssa x i
+  | True       = ite (msb x)
+                     (complement (ssa (complement x) i))
+                     (ssa x i)
+  where ssa = liftViaSVal svShiftRight
+
+-- | Generalization of 'rotateL', when the shift-amount is symbolic. Since Haskell's
+-- 'rotateL' only takes an 'Int' as the shift amount, it cannot be used when we have
+-- a symbolic amount to shift with. The first argument should be a bounded quantity.
+sRotateLeft :: (SIntegral a, SIntegral b) => SBV a -> SBV b -> SBV a
+sRotateLeft = liftViaSVal svRotateLeft
+
+-- | An implementation of rotate-left, using a barrel shifter like design. Only works when both
+-- arguments are finite bit-vectors, and furthermore when the second argument is unsigned.
+-- The first condition is enforced by the type, but the second is dynamically checked.
+-- We provide this implementation as an alternative to `sRotateLeft` since SMTLib logic
+-- does not support variable argument rotates (as opposed to shifts), and thus this
+-- implementation can produce better code for verification compared to `sRotateLeft`.
+sBarrelRotateLeft :: (SFiniteBits a, SFiniteBits b) => SBV a -> SBV b -> SBV a
+sBarrelRotateLeft = liftViaSVal svBarrelRotateLeft
+
+-- | Generalization of 'rotateR', when the shift-amount is symbolic. Since Haskell's
+-- 'rotateR' only takes an 'Int' as the shift amount, it cannot be used when we have
+-- a symbolic amount to shift with. The first argument should be a bounded quantity.
+sRotateRight :: (SIntegral a, SIntegral b) => SBV a -> SBV b -> SBV a
+sRotateRight = liftViaSVal svRotateRight
+
+-- | An implementation of rotate-right, using a barrel shifter like design. See comments
+-- for `sBarrelRotateLeft` for details.
+sBarrelRotateRight :: (SFiniteBits a, SFiniteBits b) => SBV a -> SBV b -> SBV a
+sBarrelRotateRight = liftViaSVal svBarrelRotateRight
+
+-- | Capturing non-matching instances for better error messages, conversions from sized
+type FromSizedErr (arg :: Type) =     'Text "fromSized: Cannot convert from type: " ':<>: 'ShowType arg
+                                ':$$: 'Text "           Source type must be one of SInt N, SWord N, IntN N, WordN N"
+                                ':$$: 'Text "           where N is 8, 16, 32, or 64."
+
+-- | Capturing non-matching instances for better error messages, conversions to sized
+type ToSizedErr (arg :: Type) =      'Text "toSized: Cannot convert from type: " ':<>: 'ShowType arg
+                              ':$$: 'Text "          Source type must be one of Int8/16/32/64"
+                              ':$$: 'Text "                                  OR Word8/16/32/64"
+                              ':$$: 'Text "                                  OR their symbolic variants."
+
+-- | Capture the correspondence between sized and fixed-sized BVs
+type family FromSized (t :: Type) :: Type where
+   FromSized (WordN  8) = Word8
+   FromSized (WordN 16) = Word16
+   FromSized (WordN 32) = Word32
+   FromSized (WordN 64) = Word64
+   FromSized (IntN   8) = Int8
+   FromSized (IntN  16) = Int16
+   FromSized (IntN  32) = Int32
+   FromSized (IntN  64) = Int64
+   FromSized (SWord  8) = SWord8
+   FromSized (SWord 16) = SWord16
+   FromSized (SWord 32) = SWord32
+   FromSized (SWord 64) = SWord64
+   FromSized (SInt   8) = SInt8
+   FromSized (SInt  16) = SInt16
+   FromSized (SInt  32) = SInt32
+   FromSized (SInt  64) = SInt64
+
+-- | Capture the correspondence, in terms of a constraint
+type family FromSizedCstr (t :: Type) :: Constraint where
+   FromSizedCstr (WordN  8) = ()
+   FromSizedCstr (WordN 16) = ()
+   FromSizedCstr (WordN 32) = ()
+   FromSizedCstr (WordN 64) = ()
+   FromSizedCstr (IntN   8) = ()
+   FromSizedCstr (IntN  16) = ()
+   FromSizedCstr (IntN  32) = ()
+   FromSizedCstr (IntN  64) = ()
+   FromSizedCstr (SWord  8) = ()
+   FromSizedCstr (SWord 16) = ()
+   FromSizedCstr (SWord 32) = ()
+   FromSizedCstr (SWord 64) = ()
+   FromSizedCstr (SInt   8) = ()
+   FromSizedCstr (SInt  16) = ()
+   FromSizedCstr (SInt  32) = ()
+   FromSizedCstr (SInt  64) = ()
+   FromSizedCstr arg        = TypeError (FromSizedErr arg)
+
+-- | Conversion from a sized BV to a fixed-sized bit-vector.
+class FromSizedBV a where
+   -- | Convert a sized bit-vector to the corresponding fixed-sized bit-vector,
+   -- for instance 'SWord 16' to 'SWord16'. See also 'toSized'.
+   fromSized :: a -> FromSized a
+
+   default fromSized :: (Num (FromSized a), Integral a) => a -> FromSized a
+   fromSized = fromIntegral
+
+instance {-# OVERLAPPING  #-} FromSizedBV (WordN   8)
+instance {-# OVERLAPPING  #-} FromSizedBV (WordN  16)
+instance {-# OVERLAPPING  #-} FromSizedBV (WordN  32)
+instance {-# OVERLAPPING  #-} FromSizedBV (WordN  64)
+instance {-# OVERLAPPING  #-} FromSizedBV (IntN    8)
+instance {-# OVERLAPPING  #-} FromSizedBV (IntN   16)
+instance {-# OVERLAPPING  #-} FromSizedBV (IntN   32)
+instance {-# OVERLAPPING  #-} FromSizedBV (IntN   64)
+instance {-# OVERLAPPING  #-} FromSizedBV (SWord   8) where fromSized = sFromIntegral
+instance {-# OVERLAPPING  #-} FromSizedBV (SWord  16) where fromSized = sFromIntegral
+instance {-# OVERLAPPING  #-} FromSizedBV (SWord  32) where fromSized = sFromIntegral
+instance {-# OVERLAPPING  #-} FromSizedBV (SWord  64) where fromSized = sFromIntegral
+instance {-# OVERLAPPING  #-} FromSizedBV (SInt    8) where fromSized = sFromIntegral
+instance {-# OVERLAPPING  #-} FromSizedBV (SInt   16) where fromSized = sFromIntegral
+instance {-# OVERLAPPING  #-} FromSizedBV (SInt   32) where fromSized = sFromIntegral
+instance {-# OVERLAPPING  #-} FromSizedBV (SInt   64) where fromSized = sFromIntegral
+instance {-# OVERLAPPABLE #-} FromSizedCstr arg => FromSizedBV arg where fromSized = error "unreachable"
+
+-- | Capture the correspondence between fixed-sized and sized BVs
+type family ToSized (t :: Type) :: Type where
+   ToSized Word8   = WordN  8
+   ToSized Word16  = WordN 16
+   ToSized Word32  = WordN 32
+   ToSized Word64  = WordN 64
+   ToSized Int8    = IntN   8
+   ToSized Int16   = IntN  16
+   ToSized Int32   = IntN  32
+   ToSized Int64   = IntN  64
+   ToSized SWord8  = SWord  8
+   ToSized SWord16 = SWord 16
+   ToSized SWord32 = SWord 32
+   ToSized SWord64 = SWord 64
+   ToSized SInt8   = SInt   8
+   ToSized SInt16  = SInt  16
+   ToSized SInt32  = SInt  32
+   ToSized SInt64  = SInt  64
+
+-- | Capture the correspondence in terms of a constraint
+type family ToSizedCstr (t :: Type) :: Constraint where
+   ToSizedCstr Word8   = ()
+   ToSizedCstr Word16  = ()
+   ToSizedCstr Word32  = ()
+   ToSizedCstr Word64  = ()
+   ToSizedCstr Int8    = ()
+   ToSizedCstr Int16   = ()
+   ToSizedCstr Int32   = ()
+   ToSizedCstr Int64   = ()
+   ToSizedCstr SWord8  = ()
+   ToSizedCstr SWord16 = ()
+   ToSizedCstr SWord32 = ()
+   ToSizedCstr SWord64 = ()
+   ToSizedCstr SInt8   = ()
+   ToSizedCstr SInt16  = ()
+   ToSizedCstr SInt32  = ()
+   ToSizedCstr SInt64  = ()
+   ToSizedCstr arg     = TypeError (ToSizedErr arg)
+
+-- | Conversion from a fixed-sized BV to a sized bit-vector.
+class ToSizedBV a where
+   -- | Convert a fixed-sized bit-vector to the corresponding sized bit-vector,
+   -- for instance 'SWord16' to 'SWord 16'. See also 'fromSized'.
+   toSized :: a -> ToSized a
+
+   default toSized :: (Num (ToSized a), Integral a) => (a -> ToSized a)
+   toSized = fromIntegral
+
+instance {-# OVERLAPPING  #-} ToSizedBV Word8
+instance {-# OVERLAPPING  #-} ToSizedBV Word16
+instance {-# OVERLAPPING  #-} ToSizedBV Word32
+instance {-# OVERLAPPING  #-} ToSizedBV Word64
+instance {-# OVERLAPPING  #-} ToSizedBV Int8
+instance {-# OVERLAPPING  #-} ToSizedBV Int16
+instance {-# OVERLAPPING  #-} ToSizedBV Int32
+instance {-# OVERLAPPING  #-} ToSizedBV Int64
+instance {-# OVERLAPPING  #-} ToSizedBV SWord8  where toSized = sFromIntegral
+instance {-# OVERLAPPING  #-} ToSizedBV SWord16 where toSized = sFromIntegral
+instance {-# OVERLAPPING  #-} ToSizedBV SWord32 where toSized = sFromIntegral
+instance {-# OVERLAPPING  #-} ToSizedBV SWord64 where toSized = sFromIntegral
+instance {-# OVERLAPPING  #-} ToSizedBV SInt8   where toSized = sFromIntegral
+instance {-# OVERLAPPING  #-} ToSizedBV SInt16  where toSized = sFromIntegral
+instance {-# OVERLAPPING  #-} ToSizedBV SInt32  where toSized = sFromIntegral
+instance {-# OVERLAPPING  #-} ToSizedBV SInt64  where toSized = sFromIntegral
+instance {-# OVERLAPPABLE #-} ToSizedCstr arg => ToSizedBV arg where toSized = error "unreachable"
+
+-- | The 'SDivisible' class captures the essence of division.
+-- Unfortunately we cannot use Haskell's 'Integral' class since the 'Real'
+-- and 'Enum' superclasses are not implementable for symbolic bit-vectors.
+-- However, 'quotRem' and 'divMod' both make perfect sense, and the 'SDivisible' class captures
+-- this operation. One issue is how division by 0 behaves. The verification
+-- technology requires total functions, and there are several design choices
+-- here. We follow Isabelle/HOL approach of assigning the value 0 for division
+-- by 0. Therefore, we impose the following pair of laws:
+--
+-- @
+--      x `sQuotRem` 0 = (0, x)
+--      x `sDivMod`  0 = (0, x)
+-- @
+--
+-- Note that our instances implement this law even when @x@ is @0@ itself.
+--
+-- NB. 'sQuot' truncates toward zero (i.e., it implements truncating division),
+-- while 'sDiv' truncates toward negative infinity (i.e., it implements
+-- flooring division). These match the conventions of Haskell's 'quot' and
+-- 'div' functions, respectively.
+--
+-- Similarly, 'sRem' and 'sMod' match the conventions of Haskell's 'rem' and
+-- 'mod' functions, respectively. That is:
+--
+-- @
+--      (x `sQuot` y)*y + (x `sRem` y) .== x
+--      (x `sDiv`  y)*y + (x `sMod` y) .== x
+-- @
+--
+-- === C code generation of division operations
+--
+-- In the case of division or modulo of a minimal signed value (e.g. @-128@ for
+-- 'SInt8') by @-1@, SMTLIB and Haskell agree on what the result should be.
+-- Unfortunately the result in C code depends on CPU architecture and compiler
+-- settings, as this is undefined behaviour in C.  **SBV does not guarantee**
+-- what will happen in generated C code in this corner case.
+class SDivisible a where
+  sQuotRem :: a -> a -> (a, a)
+  sDivMod  :: a -> a -> (a, a)
+  sQuot    :: a -> a -> a
+  sRem     :: a -> a -> a
+  sDiv     :: a -> a -> a
+  sMod     :: a -> a -> a
+
+  {-# MINIMAL sQuotRem, sDivMod #-}
+
+  x `sQuot` y = fst $ x `sQuotRem` y
+  x `sRem`  y = snd $ x `sQuotRem` y
+  x `sDiv`  y = fst $ x `sDivMod`  y
+  x `sMod`  y = snd $ x `sDivMod`  y
+
+instance SDivisible Word64 where
+  sQuotRem x 0 = (0, x)
+  sQuotRem x y = x `quotRem` y
+  sDivMod  x 0 = (0, x)
+  sDivMod  x y = x `divMod` y
+
+instance SDivisible Int64 where
+  sQuotRem x 0 = (0, x)
+  sQuotRem x y = x `quotRem` y
+  sDivMod  x 0 = (0, x)
+  sDivMod  x y = x `divMod` y
+
+instance SDivisible Word32 where
+  sQuotRem x 0 = (0, x)
+  sQuotRem x y = x `quotRem` y
+  sDivMod  x 0 = (0, x)
+  sDivMod  x y = x `divMod` y
+
+instance SDivisible Int32 where
+  sQuotRem x 0 = (0, x)
+  sQuotRem x y = x `quotRem` y
+  sDivMod  x 0 = (0, x)
+  sDivMod  x y = x `divMod` y
+
+instance SDivisible Word16 where
+  sQuotRem x 0 = (0, x)
+  sQuotRem x y = x `quotRem` y
+  sDivMod  x 0 = (0, x)
+  sDivMod  x y = x `divMod` y
+
+instance SDivisible Int16 where
+  sQuotRem x 0 = (0, x)
+  sQuotRem x y = x `quotRem` y
+  sDivMod  x 0 = (0, x)
+  sDivMod  x y = x `divMod` y
+
+instance SDivisible Word8 where
+  sQuotRem x 0 = (0, x)
+  sQuotRem x y = x `quotRem` y
+  sDivMod  x 0 = (0, x)
+  sDivMod  x y = x `divMod` y
+
+instance SDivisible Int8 where
+  sQuotRem x 0 = (0, x)
+  sQuotRem x y = x `quotRem` y
+  sDivMod  x 0 = (0, x)
+  sDivMod  x y = x `divMod` y
+
+instance SDivisible Integer where
+  sQuotRem x 0 = (0, x)
+  sQuotRem x y = x `quotRem` y
+  sDivMod  x 0 = (0, x)
+  sDivMod  x y = x `divMod` y
+
+instance SDivisible CV where
+  sQuotRem a b
+    | CInteger x <- cvVal a, CInteger y <- cvVal b
+    = let (r1, r2) = sQuotRem x y in (normCV a{ cvVal = CInteger r1 }, normCV b{ cvVal = CInteger r2 })
+  sQuotRem a b = error $ "SBV.sQuotRem: impossible, unexpected args received: " ++ show (a, b)
+  sDivMod a b
+    | CInteger x <- cvVal a, CInteger y <- cvVal b
+    = let (r1, r2) = sDivMod x y in (normCV a{ cvVal = CInteger r1 }, normCV b{ cvVal = CInteger r2 })
+  sDivMod a b = error $ "SBV.sDivMod: impossible, unexpected args received: " ++ show (a, b)
+
+instance SDivisible SWord64 where {sQuotRem = liftQRem; sDivMod  = liftDMod}
+instance SDivisible SWord32 where {sQuotRem = liftQRem; sDivMod  = liftDMod}
+instance SDivisible SWord16 where {sQuotRem = liftQRem; sDivMod  = liftDMod}
+instance SDivisible SWord8  where {sQuotRem = liftQRem; sDivMod  = liftDMod}
+instance SDivisible SInt64  where {sQuotRem = liftQRem; sDivMod  = liftDMod}
+instance SDivisible SInt32  where {sQuotRem = liftQRem; sDivMod  = liftDMod}
+instance SDivisible SInt16  where {sQuotRem = liftQRem; sDivMod  = liftDMod}
+instance SDivisible SInt8   where {sQuotRem = liftQRem; sDivMod  = liftDMod}
+
+-- | 'SDivisible' instance for 'WordN'
+instance (KnownNat n, BVIsNonZero n) => SDivisible (WordN n) where
+  sQuotRem x 0 = (0, x)
+  sQuotRem x y = x `quotRem` y
+  sDivMod  x 0 = (0, x)
+  sDivMod  x y = x `divMod` y
+
+-- | 'SDivisible' instance for 'IntN'
+instance (KnownNat n, BVIsNonZero n) => SDivisible (IntN n) where
+  sQuotRem x 0 = (0, x)
+  sQuotRem x y = x `quotRem` y
+  sDivMod  x 0 = (0, x)
+  sDivMod  x y = x `divMod` y
+
+-- | 'SDivisible' instance for 'SWord'
+instance (KnownNat n, BVIsNonZero n) => SDivisible (SWord n) where
+  sQuotRem = liftQRem
+  sDivMod  = liftDMod
+
+-- | 'SDivisible' instance for 'SInt'
+instance (KnownNat n, BVIsNonZero n) => SDivisible (SInt n) where
+  sQuotRem = liftQRem
+  sDivMod  = liftDMod
+
+-- | Does the concrete positive number n divide the given integer?
+sDivides :: Integer -> SInteger -> SBool
+sDivides n v
+  | n < 0
+  = error $ "svDivides: First argument must be a strictly positive integer. Received: " ++ show n
+  | Just x <- unliteral v
+  = if x `mod` n == 0 then sTrue else sFalse
+  | True
+  = SBV $ svDivides n (unSBV v)
+
+-- | Lift 'quotRem' to symbolic words. Division by 0 is defined s.t. @x/0 = 0@; which
+-- holds even when @x@ is @0@ itself.
+liftQRem :: (Eq a, SymVal a) => SBV a -> SBV a -> (SBV a, SBV a)
+liftQRem x y
+  | isConcreteZero x
+  = (x, x)
+  | isConcreteOne y
+  = (x, z)
+{-------------------------------
+ - N.B. The seemingly innocuous variant when y == -1 only holds if the type is signed;
+ - and also is problematic around the minBound.. So, we refrain from that optimization
+  | isConcreteOnes y
+  = (-x, z)
+--------------------------------}
+  | True
+  = ite (y .== z) (z, x) (qr x y)
+  where qr (SBV (SVal sgnsz (Left a))) (SBV (SVal _ (Left b))) = let (q, r) = sQuotRem a b in (SBV (SVal sgnsz (Left q)), SBV (SVal sgnsz (Left r)))
+        qr a@(SBV (SVal sgnsz _))      b                       = (SBV (SVal sgnsz (Right (cache (mk Quot)))), SBV (SVal sgnsz (Right (cache (mk Rem)))))
+                where mk o st = do sw1 <- sbvToSV st a
+                                   sw2 <- sbvToSV st b
+                                   mkSymOp o st sgnsz sw1 sw2
+        z = genLiteral (kindOf x) (0::Integer)
+
+-- | Lift 'divMod' to symbolic words. Division by 0 is defined s.t. @x/0 = 0@; which
+-- holds even when @x@ is @0@ itself. Essentially, this is conversion from quotRem
+-- (truncate to 0) to divMod (truncate towards negative infinity)
+liftDMod :: (Ord a, SymVal a, Num a, Num (SBV a), SDivisible (SBV a)) => SBV a -> SBV a -> (SBV a, SBV a)
+liftDMod x y
+  | isConcreteZero x
+  = (x, x)
+  | isConcreteOne y
+  = (x, z)
+{-------------------------------
+ - N.B. The seemingly innocuous variant when y == -1 only holds if the type is signed;
+ - and also is problematic around the minBound.. So, we refrain from that optimization
+  | isConcreteOnes y
+  = (-x, z)
+--------------------------------}
+  | True
+  = ite (y .== z) (z, x) $ ite (signum r .== negate (signum y)) (q-i, r+y) qr
+ where qr@(q, r) = x `sQuotRem` y
+       z = genLiteral (kindOf x) (0::Integer)
+       i = genLiteral (kindOf x) (1::Integer)
+
+-- SInteger instance for quotRem/divMod are tricky!
+-- SMT-Lib only has Euclidean operations, but Haskell
+-- uses "truncate to 0" for quotRem, and "truncate to negative infinity" for divMod.
+-- So, we cannot just use the above liftings directly.
+instance SDivisible SInteger where
+  sDivMod x y = ite (y .> 0) (sEDivMod x y) (liftDMod x y)
+  sQuotRem x y
+    | not (isSymbolic x || isSymbolic y)
+    = liftQRem x y
+    | True
+    = ite (y .== 0) (0, x) (qE+i, rE-i*y)
+    where (qE, rE) = liftQRem x y   -- for integers, this is euclidean due to SMTLib semantics
+          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. Note that unlike regular division, Euclidian division by @0@
+-- is unconstrained. i.e., it can take any value whatsoever.
+sEDiv :: SInteger -> SInteger -> SInteger
+sEDiv (SBV a) (SBV b) = SBV $ a `svQuot` b
+
+-- | Euclidian modulus. Note that unlike regular modulus, Euclidian division by @0@
+-- is unconstrained. i.e., it can take any value whatsoever.
+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 <$> arbitrary
+
+-- |  Symbolic conditionals are modeled by the 'Mergeable' class, describing
+-- how to merge the results of an if-then-else call with a symbolic test. SBV
+-- provides all basic types as instances of this class, so users only need
+-- to declare instances for custom data-types of their programs as needed.
+--
+-- A 'Mergeable' instance may be automatically derived for a custom data-type
+-- with a single constructor where the type of each field is an instance of
+-- 'Mergeable', such as a record of symbolic values. Users only need to add
+-- 'G.Generic' and 'Mergeable' to the @deriving@ clause for the data-type. See
+-- 'Documentation.SBV.Examples.Puzzles.U2Bridge.Status' for an example and an
+-- illustration of what the instance would look like if written by hand.
+--
+-- The function 'select' is a total-indexing function out of a list of choices
+-- with a default value, simulating array/list indexing. It's an n-way generalization
+-- of the 'ite' function.
+--
+-- Minimal complete definition: None, if the type is instance of @Generic@. Otherwise
+-- 'symbolicMerge'. Note that most types subject to merging are likely to be
+-- trivial instances of @Generic@.
+class Mergeable a where
+   -- | Merge two values based on the condition. The first argument states
+   -- whether we force the then-and-else branches before the merging, at the
+   -- word level. This is an efficiency concern; one that we'd rather not
+   -- make but unfortunately necessary for getting symbolic simulation
+   -- working efficiently.
+   symbolicMerge :: Bool -> SBool -> a -> a -> a
+
+   -- | Total indexing operation. @select xs default index@ is intuitively
+   -- the same as @xs !! index@, except it evaluates to @default@ if @index@
+   -- underflows/overflows.
+   select :: (Ord b, SymVal b, Num b, Num (SBV b), OrdSymbolic (SBV b)) => [a] -> a -> SBV b -> a
+
+   -- NB. Earlier implementation of select used the binary-search trick
+   -- on the index to chop down the search space. While that is a good trick
+   -- in general, it doesn't work for SBV since we do not have any notion of
+   -- "concrete" subwords: If an index is symbolic, then all its bits are
+   -- symbolic as well. So, the binary search only pays off only if the indexed
+   -- list is really humongous, which is not very common in general. (Also,
+   -- for the case when the list is bit-vectors, we use SMT tables anyhow.)
+   select xs err ind
+    | isReal   ind = bad "real"
+    | isFloat  ind = bad "float"
+    | isDouble ind = bad "double"
+    | hasSign  ind = ite (ind .< 0) err (walk xs ind err)
+    | True         =                     walk xs ind err
+    where bad w = error $ "SBV.select: unsupported " ++ w ++ " valued select/index expression"
+          walk []     _ acc = acc
+          walk (e:es) i acc = walk es (i-1) (ite (i .== 0) e acc)
+
+   -- Default implementation for 'symbolicMerge' if the type is 'Generic'
+   default symbolicMerge :: (G.Generic a, GMergeable (G.Rep a)) => Bool -> SBool -> a -> a -> a
+   symbolicMerge = symbolicMergeDefault
+
+-- | If-then-else. This is by definition 'symbolicMerge' with both
+-- branches forced. This is typically the desired behavior, but also
+-- see 'iteLazy' should you need more laziness.
+ite :: Mergeable a => SBool -> a -> a -> a
+ite t a b
+  | Just r <- unliteral t = if r then a else b
+  | True                  = symbolicMerge True t a b
+
+-- | A Lazy version of ite, which does not force its arguments. This might
+-- cause issues for symbolic simulation with large thunks around, so use with
+-- care.
+iteLazy :: Mergeable a => SBool -> a -> a -> a
+iteLazy t a b
+  | Just r <- unliteral t = if r then a else b
+  | True                  = symbolicMerge False t a b
+
+-- | Symbolic assert. Check that the given boolean condition is always 'sTrue' in the given path. The
+-- optional first argument can be used to provide call-stack info via GHC's location facilities.
+sAssert :: HasKind a => Maybe CallStack -> String -> SBool -> SBV a -> SBV a
+sAssert cs msg cond x
+   | Just mustHold <- unliteral cond
+   = if mustHold
+     then x
+     else error $ show $ SafeResult (locInfo . getCallStack <$> cs, msg, Satisfiable defaultSMTCfg (SMTModel [] Nothing [] []))
+   | True
+   = SBV $ SVal k $ Right $ cache r
+  where k     = kindOf x
+        r st  = do xsv <- sbvToSV st x
+                   let pc = getPathCondition st
+                       -- We're checking if there are any cases where the path-condition holds, but not the condition
+                       -- Any violations of this, should be signaled, i.e., whenever the following formula is satisfiable
+                       mustNeverHappen = pc .&& sNot cond
+                   cnd <- sbvToSV st mustNeverHappen
+                   addAssertion st cs msg cnd
+                   pure xsv
+
+        locInfo ps = intercalate ",\n " (map loc ps)
+          where loc (f, sl) = concat [srcLocFile sl, ":", show (srcLocStartLine sl), ":", show (srcLocStartCol sl), ":", f]
+
+-- | Merge two symbolic values, at kind @k@, possibly @force@'ing the branches to make
+-- sure they do not evaluate to the same result. This should only be used for internal purposes;
+-- as default definitions provided should suffice in many cases. (i.e., End users should
+-- only need to define 'symbolicMerge' when needed; which should be rare to start with.)
+symbolicMergeWithKind :: Kind -> Bool -> SBool -> SBV a -> SBV a -> SBV a
+symbolicMergeWithKind k force (SBV t) (SBV a) (SBV b) = SBV (svSymbolicMerge k force t a b)
+
+instance SymVal a => Mergeable (SBV a) where
+    symbolicMerge force t x y
+    -- Carefully use the kindOf instance to avoid strictness issues.
+       | force = symbolicMergeWithKind (kindOf x)          True  t x y
+       | True  = symbolicMergeWithKind (kindOf (Proxy @a)) False t x y
+    -- Custom version of select that translates to SMT-Lib tables at the base type of words
+    select xs err ind
+      | SBV (SVal _ (Left c)) <- ind = case cvVal c of
+                                         CInteger i -> if i < 0 || i >= genericLength xs
+                                                       then err
+                                                       else xs `genericIndex` i
+                                         _          -> error $ "SBV.select: unsupported " ++ show (kindOf ind) ++ " valued select/index expression"
+    select xsOrig err ind = xs `seq` SBV (SVal kElt (Right (cache r)))
+      where kInd = kindOf ind
+            kElt = kindOf err
+            -- Based on the index size, we need to limit the elements. For instance if the index is 8 bits, but there
+            -- are 257 elements, that last element will never be used and we can chop it of..
+            xs   = case kindOf ind of
+                     KBounded False i -> genericTake ((2::Integer) ^ (fromIntegral i     :: Integer)) xsOrig
+                     KBounded True  i -> genericTake ((2::Integer) ^ (fromIntegral (i-1) :: Integer)) xsOrig
+                     KUnbounded       -> xsOrig
+                     _                -> error $ "SBV.select: unsupported " ++ show (kindOf ind) ++ " valued select/index expression"
+            r st  = do sws <- mapM (sbvToSV st) xs
+                       swe <- sbvToSV st err
+                       if all (== swe) sws  -- off-chance that all elts are the same. Note that this also correctly covers the case when list is empty.
+                          then pure swe
+                          else do idx <- getTableIndex st kInd kElt sws
+                                  swi <- sbvToSV st ind
+                                  let len = length xs
+                                  -- NB. No need to worry here that the index might be < 0; as the SMTLib translation takes care of that automatically
+                                  newExpr st kElt (SBVApp (LkUp (idx, kInd, kElt, len) swi swe) [])
+
+-- | Construct a useful error message if we hit an unmergeable case.
+cannotMerge :: String -> String -> String -> a
+cannotMerge typ why hint = error $ unlines [ ""
+                                           , "*** Data.SBV.Mergeable: Cannot merge instances of " ++ typ ++ "."
+                                           , "*** While trying to do a symbolic if-then-else with incompatible branch results."
+                                           , "***"
+                                           , "*** " ++ why
+                                           , "*** "
+                                           , "*** Hint: " ++ hint
+                                           ]
+
+-- | Merge concrete values that can be checked for equality
+concreteMerge :: Show a => String -> String -> (a -> a -> Bool) -> a -> a -> a
+concreteMerge t st eq x y
+  | x `eq` y = x
+  | True     = cannotMerge t
+                           ("Concrete values can only be merged when equal. Got: " ++ show x ++ " vs. " ++ show y)
+                           ("Use an " ++ st ++ " field if the values can differ.")
+
+-- Mergeable instances for List/Maybe/Either/Array are useful, but can
+-- throw exceptions if there is no structural matching of the results
+-- It's a question whether we should really keep them..
+
+-- Lists
+instance Mergeable a => Mergeable [a] where
+  symbolicMerge f t xs ys
+    | lxs == lys = zipWith (symbolicMerge f t) xs ys
+    | True       = cannotMerge "lists"
+                               ("Branches produce different sizes: " ++ show lxs ++ " vs " ++ show lys ++ ". Must have the same length.")
+                               "Use the 'SList' type (and Data.SBV.List routines) to model fully symbolic lists."
+    where (lxs, lys) = (length xs, length ys)
+
+-- NonEmpty
+instance Mergeable a => Mergeable (NonEmpty a) where
+   symbolicMerge f t xs ys
+     | lxs == lys = NE.zipWith (symbolicMerge f t) xs ys
+     | True       = cannotMerge "non-empty lists"
+                                ("Branches produce different sizes: " ++ show lxs ++ " vs " ++ show lys ++ ". Must have the same length.")
+                                "Use the 'SList' type (and Data.SBV.List routines) to model fully symbolic lists."
+     where (lxs, lys) = (length xs, length ys)
+
+-- ZipList
+instance Mergeable a => Mergeable (ZipList a) where
+  symbolicMerge force test (ZipList xs) (ZipList ys)
+    = ZipList (symbolicMerge force test xs ys)
+
+-- Maybe
+instance Mergeable a => Mergeable (Maybe a) where
+  symbolicMerge _ _ Nothing  Nothing  = Nothing
+  symbolicMerge f t (Just a) (Just b) = Just $ symbolicMerge f t a b
+  symbolicMerge _ _ a b = cannotMerge "'Maybe' values"
+                                      ("Branches produce different constructors: " ++ show (k a, k b))
+                                      "Instead of an option type, try using a valid bit to indicate when a result is valid."
+      where k :: Maybe a -> String
+            k Nothing = "Nothing"
+            k _       = "Just"
+
+-- Either
+instance (Mergeable a, Mergeable b) => Mergeable (Either a b) where
+  symbolicMerge f t (Left a)  (Left b)  = Left  $ symbolicMerge f t a b
+  symbolicMerge f t (Right a) (Right b) = Right $ symbolicMerge f t a b
+  symbolicMerge _ _ a b = cannotMerge "'Either' values"
+                                      ("Branches produce different constructors: " ++ show (k a, k b))
+                                      "Consider using a product type by a tag instead."
+     where k :: Either a b -> String
+           k (Left _)  = "Left"
+           k (Right _) = "Right"
+
+-- Arrays
+instance (Ix a, Mergeable b) => Mergeable (Array a b) where
+  symbolicMerge f t a b
+    | ba == bb = DA.listArray ba (zipWith (symbolicMerge f t) (elems a) (elems b))
+    | True     = cannotMerge "'Array' values"
+                             ("Branches produce different ranges: " ++ show (k ba, k bb))
+                             "Consider using SBV's native 'SArray' abstraction."
+    where ba = bounds a
+          bb = bounds b
+          k = rangeSize
+
+-- Functions
+instance Mergeable b => Mergeable (a -> b) where
+  symbolicMerge f t g h x = symbolicMerge f t (g x) (h x)
+  {- Following definition, while correct, is utterly inefficient. Since the
+     application is delayed, this hangs on to the inner list and all the
+     impending merges, even when ind is concrete. Thus, it's much better to
+     simply use the default definition for the function case.
+  -}
+  -- select xs err ind = \x -> select (map ($ x) xs) (err x) ind
+
+-- 2-Tuple
+instance (Mergeable a, Mergeable b) => Mergeable (a, b) where
+  symbolicMerge f t (i0, i1) (j0, j1) = ( symbolicMerge f t i0 j0
+                                        , symbolicMerge f t i1 j1
+                                        )
+
+  select xs (err1, err2) ind = ( select as err1 ind
+                               , select bs err2 ind
+                               )
+    where (as, bs) = unzip xs
+
+-- 3-Tuple
+instance (Mergeable a, Mergeable b, Mergeable c) => Mergeable (a, b, c) where
+  symbolicMerge f t (i0, i1, i2) (j0, j1, j2) = ( symbolicMerge f t i0 j0
+                                                , symbolicMerge f t i1 j1
+                                                , symbolicMerge f t i2 j2
+                                                )
+
+  select xs (err1, err2, err3) ind = ( select as err1 ind
+                                     , select bs err2 ind
+                                     , select cs err3 ind
+                                     )
+
+    where (as, bs, cs) = unzip3 xs
+
+-- 4-Tuple
+instance (Mergeable a, Mergeable b, Mergeable c, Mergeable d) => Mergeable (a, b, c, d) where
+  symbolicMerge f t (i0, i1, i2, i3) (j0, j1, j2, j3) = ( symbolicMerge f t i0 j0
+                                                        , symbolicMerge f t i1 j1
+                                                        , symbolicMerge f t i2 j2
+                                                        , symbolicMerge f t i3 j3
+                                                        )
+
+  select xs (err1, err2, err3, err4) ind = ( select as err1 ind
+                                           , select bs err2 ind
+                                           , select cs err3 ind
+                                           , select ds err4 ind
+                                           )
+    where (as, bs, cs, ds) = unzip4 xs
+
+-- 5-Tuple
+instance (Mergeable a, Mergeable b, Mergeable c, Mergeable d, Mergeable e) => Mergeable (a, b, c, d, e) where
+  symbolicMerge f t (i0, i1, i2, i3, i4) (j0, j1, j2, j3, j4) = ( symbolicMerge f t i0 j0
+                                                                , symbolicMerge f t i1 j1
+                                                                , symbolicMerge f t i2 j2
+                                                                , symbolicMerge f t i3 j3
+                                                                , symbolicMerge f t i4 j4
+                                                                )
+
+  select xs (err1, err2, err3, err4, err5) ind = ( select as err1 ind
+                                                 , select bs err2 ind
+                                                 , select cs err3 ind
+                                                 , select ds err4 ind
+                                                 , select es err5 ind
+                                                 )
+    where (as, bs, cs, ds, es) = unzip5 xs
+
+-- 6-Tuple
+instance (Mergeable a, Mergeable b, Mergeable c, Mergeable d, Mergeable e, Mergeable f) => Mergeable (a, b, c, d, e, f) where
+  symbolicMerge f t (i0, i1, i2, i3, i4, i5) (j0, j1, j2, j3, j4, j5) = ( symbolicMerge f t i0 j0
+                                                                        , symbolicMerge f t i1 j1
+                                                                        , symbolicMerge f t i2 j2
+                                                                        , symbolicMerge f t i3 j3
+                                                                        , symbolicMerge f t i4 j4
+                                                                        , symbolicMerge f t i5 j5
+                                                                        )
+
+  select xs (err1, err2, err3, err4, err5, err6) ind = ( select as err1 ind
+                                                       , select bs err2 ind
+                                                       , select cs err3 ind
+                                                       , select ds err4 ind
+                                                       , select es err5 ind
+                                                       , select fs err6 ind
+                                                       )
+    where (as, bs, cs, ds, es, fs) = unzip6 xs
+
+-- 7-Tuple
+instance (Mergeable a, Mergeable b, Mergeable c, Mergeable d, Mergeable e, Mergeable f, Mergeable g) => Mergeable (a, b, c, d, e, f, g) where
+  symbolicMerge f t (i0, i1, i2, i3, i4, i5, i6) (j0, j1, j2, j3, j4, j5, j6) = ( symbolicMerge f t i0 j0
+                                                                                , symbolicMerge f t i1 j1
+                                                                                , symbolicMerge f t i2 j2
+                                                                                , symbolicMerge f t i3 j3
+                                                                                , symbolicMerge f t i4 j4
+                                                                                , symbolicMerge f t i5 j5
+                                                                                , symbolicMerge f t i6 j6
+                                                                                )
+
+  select xs (err1, err2, err3, err4, err5, err6, err7) ind = ( select as err1 ind
+                                                             , select bs err2 ind
+                                                             , select cs err3 ind
+                                                             , select ds err4 ind
+                                                             , select es err5 ind
+                                                             , select fs err6 ind
+                                                             , select gs err7 ind
+                                                             )
+    where (as, bs, cs, ds, es, fs, gs) = unzip7 xs
+
+-- Base types are mergeable so long as they are equal
+instance Mergeable ()      where symbolicMerge _ _ = concreteMerge "()"      "()"        (==)
+instance Mergeable Integer where symbolicMerge _ _ = concreteMerge "Integer" "SInteger"  (==)
+instance Mergeable Bool    where symbolicMerge _ _ = concreteMerge "Bool"    "SBool"     (==)
+instance Mergeable Char    where symbolicMerge _ _ = concreteMerge "Char"    "SChar"     (==)
+instance Mergeable Float   where symbolicMerge _ _ = concreteMerge "Float"   "SFloat"    fpIsEqualObjectH
+instance Mergeable Double  where symbolicMerge _ _ = concreteMerge "Double"  "SDouble"   fpIsEqualObjectH
+instance Mergeable Word8   where symbolicMerge _ _ = concreteMerge "Word8"   "SWord8"    (==)
+instance Mergeable Word16  where symbolicMerge _ _ = concreteMerge "Word16"  "SWord16"   (==)
+instance Mergeable Word32  where symbolicMerge _ _ = concreteMerge "Word32"  "SWord32"   (==)
+instance Mergeable Word64  where symbolicMerge _ _ = concreteMerge "Word64"  "SWord64"   (==)
+instance Mergeable Int8    where symbolicMerge _ _ = concreteMerge "Int8"    "SInt8"     (==)
+instance Mergeable Int16   where symbolicMerge _ _ = concreteMerge "Int16"   "SInt16"    (==)
+instance Mergeable Int32   where symbolicMerge _ _ = concreteMerge "Int32"   "SInt32"    (==)
+instance Mergeable Int64   where symbolicMerge _ _ = concreteMerge "Int64"   "SInt64"    (==)
+
+-- Arbitrary product types, using GHC.Generics
+--
+-- NB: Because of the way GHC.Generics works, the implementation of
+-- symbolicMerge' is recursive. The derived instance for @data T a = T a a a a@
+-- resembles that for (a, (a, (a, a))), not the flat 4-tuple (a, a, a, a). This
+-- difference should have no effect in practice. Note also that, unlike the
+-- hand-rolled tuple instances, the generic instance does not provide a custom
+-- 'select' implementation, and so does not benefit from the SMT-table
+-- implementation in the 'SBV a' instance.
+
+-- | Not exported. Symbolic merge using the generic representation provided by
+-- 'G.Generics'.
+symbolicMergeDefault :: (G.Generic a, GMergeable (G.Rep a)) => Bool -> SBool -> a -> a -> a
+symbolicMergeDefault force t x y = G.to $ symbolicMerge' force t (G.from x) (G.from y)
+
+-- | Not exported. Used only in 'symbolicMergeDefault'. Instances are provided for
+-- the generic representations of product types where each element is Mergeable.
+class GMergeable f where
+  symbolicMerge' :: Bool -> SBool -> f a -> f a -> f a
+
+{-
+ - N.B. A V1 instance like the below would be wrong!
+ - Why? Because inSBV, we use empty data to mean "uninterpreted" sort; not
+ - something that has no constructors. Perhaps that was a bad design
+ - decision. So, do not allow merging of such values!
+instance GMergeable V1 where
+  symbolicMerge' _ _ x _ = x
+-}
+
+instance GMergeable U1 where
+  symbolicMerge' _ _ _ _ = U1
+
+instance (Mergeable c) => GMergeable (K1 i c) where
+  symbolicMerge' force t (K1 x) (K1 y) = K1 $ symbolicMerge force t x y
+
+instance (GMergeable f) => GMergeable (M1 i c f) where
+  symbolicMerge' force t (M1 x) (M1 y) = M1 $ symbolicMerge' force t x y
+
+instance (GMergeable f, GMergeable g) => GMergeable (f :*: g) where
+  symbolicMerge' force t (x1 :*: y1) (x2 :*: y2) = symbolicMerge' force t x1 x2 :*: symbolicMerge' force t y1 y2
+
+{- A mergeable instance for sum-types isn't possible. Why? It would something like:
+
+instance (GMergeable f, GMergeable g) => GMergeable (f :+: g) where
+  symbolicMerge' force t (L1 x) (L1 y) = L1 $ symbolicMerge' force t x y
+  symbolicMerge' force t (R1 x) (R1 y) = R1 $ symbolicMerge' force t x y
+  symbolicMerge' force t l r
+    | Just tv <- unliteral t = if tv then l else r
+    | True                   = ????
+
+There's really no good code to put in ????. We have no way to ask the SMT solver to merge composite values that
+have different constructors. Calling "error" here would pass the type-checker, but that simply postpones the problem
+to run-time. If you need mergeable on sum-types, you better write one yourself, possibly using the SEither type yourself.
+As we have it, you'll get a type-error; which can be hard to read, but is preferable.
+
+NB. This isn't a problem with the generic version of symbolic equality; since we can simply return sFalse if we
+see different constructors. Such isn't the case when merging.
+-}
+
+-- Bounded instances
+instance {-# OVERLAPPABLE #-} (SymVal a, Bounded a) => Bounded (SBV a) where
+  minBound = literal minBound
+  maxBound = literal maxBound
+
+-- Haskell and SMTLib differ in their default char ranges. In Haskell, maxbound is a lot larger.
+-- But in SMTLib, we only go upto 0x2FFFF. So, we adopt the SMTLib variant here. This is hardly
+-- an issue in practice, but the discrepancy is disconcerting.
+instance {-# OVERLAPPING #-} Bounded SChar where
+  minBound = literal (chr 0)
+  maxBound = literal (chr 0x2FFFF)
+
+-- | Choose a value that satisfies the given predicate. This is Hillbert's choice, essentially. Note that
+-- if the predicate given is not satisfiable (for instance @const sFalse@), then the element returned will be arbitrary.
+-- The only guarantee is that if there's at least one element that satisfies the predicate, then the returned
+-- element will be one of those that do. The returned element is not guaranteed to be unique, least, greatest etc, unless
+-- there happens to be exactly one satisfying element.
+some :: forall a. (SymVal a, HasKind a) => String -> (SBV a -> SBool) -> SBV a
+some inpName cond = mk f
+  where mk = SBV . SVal k . Right . cache
+
+        k = kindOf (Proxy @a)
+
+
+        f st = do ctr <- incrementFreshNameCounter st
+                  let pre = atProxy (Proxy @a) inpName
+                      nm  | ctr == 0 = pre
+                          | True     = pre ++ "_" ++ show ctr
+                  op <- newUninterpreted st (UIGiven nm) Nothing (SBVType [k]) (UINone False)
+                  chosen <- newExpr st k $ SBVApp op []
+                  let ifExists  = quantifiedBool $ \(Exists ex) -> cond ex
+                  internalConstraint st False [] (unSBV (ifExists .=> cond (mk (pure (pure chosen)))))
+                  pure chosen
+
+-- | Find the final part of a kind that looks like an array
+resKind :: Kind -> Kind
+resKind (KArray _ k) = resKind k
+resKind k            = k
+
+-- | SMT definable constants and functions, which can also be uninterpreted.
+-- This class captures functions that we can generate standalone-code for
+-- in the SMT solver. Note that we also allow uninterpreted constants and
+-- functions too. An uninterpreted constant is a value that is indexed by its name. The only
+-- property the prover assumes -- about these values are that they are equivalent to themselves; i.e., (for
+-- functions) they return the same results when applied to same arguments.
+-- We support uninterpreted-functions as a general means of black-box'ing
+-- operations that are /irrelevant/ for the purposes of the proof; i.e., when
+-- the proofs can be performed without any knowledge about the function itself.
+--
+-- Minimal complete definition: 'sbvDefineValue'. However, most instances in
+-- practice are already provided by SBV, so end-users should not need to define their
+-- own instances.
+class SMTDefinable a where
+  -- | Generate the code for this value as an SMTLib function, instead of
+  -- the usual unrolling semantics. This is useful for generating sub-functions
+  -- in generated SMTLib problem, or handling recursive (and mutually-recursive)
+  -- definitions that wouldn't terminate in an unrolling symbolic simulation context.
+  --
+  -- __IMPORTANT NOTE__ The string argument names this function. SBV identifies
+  -- the function by this name: if you use this function twice (or use it recursively),
+  -- it will simply assume this name uniquely identifies the function being defined.
+  -- If two calls to 'smtFunction' (or its variants) use the same name but different
+  -- bodies, SBV will raise an error at runtime.
+  --
+  -- Furthermore, if the call to 'smtFunction' happens in the scope of a parameter, you
+  -- must make sure the string is chosen to keep it unique per parameter value. For instance,
+  -- if you have:
+  --
+  -- @
+  --   bar :: SInteger -> SInteger -> SInteger
+  --   bar k = smtFunction "bar" (\x -> x+k)   -- Note the capture of k!
+  -- @
+  --
+  -- and you call @bar 2@ and @bar 3@, SBV will detect that the two bodies differ and
+  -- raise an error. You should use a concrete argument to make the name unique:
+  --
+  -- @
+  --   bar :: String -> SInteger -> SInteger -> SInteger
+  --   bar tag k = smtFunction ("bar_" ++ tag) (\x -> x+k)   -- Tag should make the name unique!
+  -- @
+  --
+  -- Then, make sure you use @bar "two" 2@ and @bar "three" 3@ etc. to preserve the invariant.
+  --
+  -- Additionally, the function argument must not capture any non-constant variables in the context.
+  -- You can also define higher-order functions, see 'smtHOFunction' for that purpose.
+  smtFunctionDef :: (Typeable a, Lambda Symbolic a) => String -> Measure a -> a -> a
+
+  -- | Register a function eagerly. This function is typically not needed, since SBV registers functions
+  -- automatically upon first use, including uses first encountered in query mode. Use it to include an
+  -- otherwise unused uninterpreted function in 'Data.SBV.allSat' enumeration, or to declare one before
+  -- checking satisfiability and retrieving its interpretation with 'Data.SBV.Control.getFunction'.
+  -- It also lets you request definition validation and any termination or productivity checks before
+  -- the function is otherwise needed. Registration does not constrain the function's result.
+  -- Internally, it applies the function to fresh internal arguments to discover its definition;
+  -- these argument declarations and the application can appear in SMT transcripts.
+  registerFunction :: a -> Symbolic ()
+
+  -- | Uninterpret a value, i.e., add this value as a completely undefined value/function that
+  -- the solver is free to instantiate to satisfy other constraints.
+  uninterpret :: String -> a
+
+  -- | Uninterpret a value, with named arguments in case of functions. SBV will use these
+  -- names when it shows the values for the arguments. If the given names are more than needed
+  -- we ignore the excess. If not enough, we add from a stock set of variables.
+  uninterpretWithArgs :: String -> [String] -> a
+
+  -- | Uninterpret a value, only for the purposes of code-generation. For execution
+  -- and verification the value is used as is. For code-generation, the alternate
+  -- definition is used. This is useful when we want to take advantage of native
+  -- libraries on the target languages.
+  cgUninterpret :: String -> [String] -> a -> a
+
+  -- | More generalized form of uninterpretation that wraps 'sbvDefineValueFun';
+  -- this function should not be needed by end-user-code
+  sbvDefineValue :: UIName -> Maybe [String] -> UIKind a -> a
+
+  -- | The most generalized form of uninterpretation, that generates an
+  -- uninterpreted function over a sequence of 'SBVs' values; this function is
+  -- internal-only, and should not be needed by end-user-code
+  sbvDefineValueFun :: UIName -> Maybe [String] -> SymValInsts as ->
+                       UIKind (SBVs as -> a) -> SBVs as -> a
+
+  -- | A synonym for 'uninterpret'. Allows us to create variables without
+  -- having to call 'free' explicitly, i.e., without being in the symbolic monad.
+  sym :: String -> a
+
+  -- | Like 'sym', but appends the type's kind to the name, ensuring uniqueness across
+  -- different type instantiations of the same polymorphic definition. Used internally by sCase.
+  symWithKind :: String -> a
+  symWithKind = sym
+
+  -- | Render an uninterpreted value as an SMTLib definition
+  sbv2smt :: ExtractIO m => a -> m String
+
+  -- | Render an uninterpreted value function as an SMTLib definition
+  sbvFun2smt :: (SymVals as, ExtractIO m) => (SBVs as -> a) -> m String
+
+  -- | Make this name a constructor, coming from an ADT. Only used internally
+  mkADTConstructor :: HasKind a => String -> a
+  mkADTTester      :: HasKind a => String -> a
+  mkADTAccessor    :: HasKind a => String -> a
+
+  {-# MINIMAL sbvDefineValueFun, sbvFun2smt, registerFunction #-}
+
+  -- defaults:
+  uninterpret         nm        = sbvDefineValue (UIGiven nm) Nothing   $ UIFree True
+  uninterpretWithArgs nm as     = sbvDefineValue (UIGiven nm) (Just as) $ UIFree True
+  cgUninterpret       nm code v = sbvDefineValue (UIGiven nm) Nothing   $ UICodeC (v, code)
+  sym                           = uninterpret
+  sbv2smt             a         = sbvFun2smt (\(_ :: SBVs RNil) -> a)
+
+  sbvDefineValue nm mbArgs k    =
+    sbvDefineValueFun nm mbArgs SymValsNil (const <$> k) SBVsNil
+
+  mkADTConstructor nm = let k = resKind (kindOf v); v = sbvDefineValue (UIADT (ADTConstructor (T.pack nm) k)) Nothing $ UIFree True in v
+  mkADTTester      nm = let k = resKind (kindOf v); v = sbvDefineValue (UIADT (ADTTester      (T.pack nm) k)) Nothing $ UIFree True in v
+  mkADTAccessor    nm = let k = resKind (kindOf v); v = sbvDefineValue (UIADT (ADTAccessor    (T.pack nm) k)) Nothing $ UIFree True in v
+
+  smtFunctionDef nm msr v = sbvDefineValue (UIGiven (atProxy (Proxy @a) nm)) Nothing
+                       $ UIFun (v, \st fk -> do
+                          let funcNm = atProxy (Proxy @a) nm
+                          (def, info) <- lambdaWithInfo st TopLevel fk v
+                          -- Record LambdaInfo for SCC-aware mutual recursion checking
+                          modifyIORef' (rFuncLambdaInfos st) (Map.insert funcNm info)
+                          let rootState    = getRootState st
+                              barFuncNm    = barify funcNm
+                              tBarFuncNm   = T.pack barFuncNm
+                              addMeasureCheck check = modifyState rootState rMeasureChecks (check :)
+                                                                 $ modifyIncState rootState rNewMeasureChecks (check :)
+                              isSelfRec    = any (\(_, SBVApp op _) -> case op of
+                                                    Uninterpreted n -> n == tBarFuncNm
+                                                    _               -> False)
+                                                 (liAssignments info)
+                              hasCrossRefs = any (\(_, SBVApp op _) -> case op of
+                                                    Uninterpreted n -> n /= tBarFuncNm
+                                                    _               -> False)
+                                                 (liAssignments info)
+                          case msr of
+                            AutoMeasure -> do
+                              when isSelfRec $
+                                addMeasureCheck (funcNm, False, \cfg -> autoGuessOrFail cfg funcNm info)
+                              when hasCrossRefs $
+                                addMeasureCheck (funcNm, False, \cfg -> checkMutualFromState cfg funcNm st Nothing)
+                              pure def
+
+                            HasMeasure eval helpers -> do
+                              when isSelfRec $
+                                addMeasureCheck (funcNm, False, \cfg -> verifyMeasure cfg funcNm info eval helpers)
+                              when hasCrossRefs $
+                                addMeasureCheck (funcNm, False, \cfg -> checkMutualFromState cfg funcNm st (Just eval))
+                              pure def
+
+                            HasContract eval ceval helpers -> do
+                              when hasCrossRefs $
+                                addMeasureCheck (funcNm, False, \cfg -> rejectMutualContractFromState cfg funcNm st)
+                              addMeasureCheck (funcNm, False, \cfg -> verifyMeasureWithContract cfg funcNm info eval ceval helpers)
+                              pure def
+
+                            Productive -> do
+                              when isSelfRec $
+                                addMeasureCheck (funcNm, True, \cfg -> verifyGuardedness cfg funcNm info)
+                              when hasCrossRefs $
+                                addMeasureCheck (funcNm, True, \cfg -> checkMutualProductiveFromState cfg funcNm st)
+                              pure def
+
+                            Unverified -> do modifyIORef' (rNoTermCheckFunctions st) (Set.insert nm)
+                                             debug (stCfg st) ["[MEASURE] " <> T.pack funcNm <> ": no termination check (smtFunctionNoTermination)"]
+                                             pure def)
+
+
+-- | Define an SMT function. If the function is recursive, SBV will automatically try to
+-- prove termination by guessing a measure based on argument types. If the guess fails,
+-- use 'smtFunctionWithMeasure' to provide an explicit measure.
+smtFunction :: (SMTDefinable a, Typeable a, Lambda Symbolic a) => String -> a -> a
+smtFunction nm = smtFunctionDef nm AutoMeasure
+
+-- | Define an SMT function with an explicit termination measure. Use this when 'smtFunction'
+-- cannot automatically determine a suitable measure. The measure function takes the same
+-- arguments as the original function but returns a value that must be non-negative and
+-- strictly decrease at each recursive call.
+--
+-- The pair @(measure, helpers)@ provides the measure function and a list of auxiliary
+-- t'MeasureHelper' properties needed to verify the measure. Each helper is first proven
+-- (by running its TP proof), then asserted as an axiom in the measure verification session.
+-- Use 'Data.SBV.TP.measureLemma' to create helpers from TP proofs. Pass @[]@ when no helpers are needed.
+smtFunctionWithMeasure :: forall f r. (SMTDefinable f, Typeable f, Lambda Symbolic f, Zero r, OrdSymbolic (SBV r), SymVal r, ApplyMeasure f r)
+                       => String -> (MeasureOf f r, [MeasureHelper]) -> f -> f
+smtFunctionWithMeasure nm (mf, helpers) = smtFunctionDef nm (HasMeasure (MeasureEval (applyMeasure @f @r mf)) helpers)
+
+-- | Define an SMT function with a termination measure and a contract (post-condition).
+-- Use this for nested recursive functions (like McCarthy's 91 function) where the termination
+-- argument depends on the function's return value at smaller inputs.
+--
+-- The triple @(measure, contract, helpers)@ provides:
+--
+--   * A measure function (same as 'smtFunctionWithMeasure')
+--   * A contract: a predicate on the function's inputs and output that is proven simultaneously
+--     with the measure decrease via well-founded induction. The inductive hypothesis provides
+--     the contract for all inputs with strictly smaller measure.
+--   * A list of auxiliary t'MeasureHelper' properties (pass @[]@ when none are needed)
+--
+-- For example, for McCarthy's 91 function:
+--
+-- @
+-- mcCarthy91 = smtFunctionWithContract \"mcCarthy91\"
+--     ( \\n -> 0 \`smax\` (101 - n)
+--     , \\n r -> n .<= 100 .=> r .== 91
+--     , []
+--     )
+--   $ \\n -> ite (n .> 100) (n - 10) (mcCarthy91 (mcCarthy91 (n + 11)))
+-- @
+--
+-- Here the contract says \"for inputs ≤ 100, the result is 91\". This is needed because the outer
+-- recursive call @mcCarthy91(mcCarthy91(n + 11))@ requires knowing what @mcCarthy91(n + 11)@ returns
+-- in order to verify that the measure decreases.
+smtFunctionWithContract :: forall f r. (SMTDefinable f, Typeable f, Lambda Symbolic f, Zero r, OrdSymbolic (SBV r), SymVal r, ApplyMeasure f r, ApplyContract f)
+                        => String -> (MeasureOf f r, ContractOf f, [MeasureHelper]) -> f -> f
+smtFunctionWithContract nm (mf, cf, helpers) = smtFunctionDef nm (HasContract (MeasureEval (applyMeasure @f @r mf))
+                                                                              (ContractEval (applyContract @f cf))
+                                                                              helpers)
+
+-- | Define a productive (corecursive) SMT function. Use this for functions that intentionally
+-- don't terminate but produce output incrementally, such as infinite list generators.
+-- SBV verifies that every recursive call is guarded by a data constructor (list cons, ADT
+-- constructor, etc.), ensuring the function is productive.
+--
+-- @
+-- go = smtProductiveFunction \"go\" $ \\start delta -> start .: go (start + delta) delta
+-- @
+smtProductiveFunction :: (SMTDefinable a, Typeable a, Lambda Symbolic a) => String -> a -> a
+smtProductiveFunction nm = smtFunctionDef nm Productive
+
+-- | Define a recursive SMT function without any termination check. The function
+-- is emitted as @define-fun-rec@ and the user takes responsibility for well-definedness.
+-- Use this for functions where termination is believed but cannot be proven, such as
+-- the Collatz function. See "Documentation.SBV.Examples.TP.Collatz" for an example use case.
+smtFunctionNoTermination :: (SMTDefinable a, Typeable a, Lambda Symbolic a) => String -> a -> a
+smtFunctionNoTermination nm = smtFunctionDef nm Unverified
+
+-- | Kind of uninterpretation
+data UIKind a = UIFree  Bool                            -- ^ completely uninterpreted. If Bool is true, then this is curried.
+              | UIFun   (a, State -> Kind -> IO SMTDef) -- ^ has code for SMTLib, with final type of kind (note this is the result
+                                                        -- , not the arguments), which can be generated by calling the function on the state.
+              | UICodeC (a, [String])                   -- ^ has code for code-generation, i.e., C
+              deriving Functor
+
+-- Get the code associated with the UI, unless we've already did this once. (To support recursive defs.)
+retrieveUICode :: UIName -> State -> Kind -> UIKind a -> IO UICodeKind
+retrieveUICode _            _  _  (UIFree  c)      = pure $ UINone c
+retrieveUICode (UIADT   _)  _  _  _                = pure $ UINone True
+retrieveUICode (UIGiven nm) st fk (UIFun   (_, f)) = do
+  compilingFuncs <- readIORef (rCompilingFuncs st)
+  if nm `Set.member` compilingFuncs
+    then -- This name is currently being compiled, so this is a recursive (or mutually recursive) self-call.
+         -- Break the cycle by skipping code generation.
+         pure $ UINone True
+    else do userFuncs <- readIORef (rUserFuncs st)
+            sn <- hashStableName <$> makeStableName f
+            case Map.lookup nm userFuncs of
+              Just (knownHashes, origLevel)
+                | sn `Set.member` knownHashes
+                -> -- Same closure we've seen before; skip immediately.
+                   pure $ UINone True
+                | True
+                -> do -- New closure for an already-compiled name. Compile body in an isolated
+                      -- throwaway state (to avoid side-effects like duplicate measure registrations
+                      -- and context-dependent body differences), then compare with the existing definition.
+                      -- We use the SAME lambda level as the original compilation so that SV names
+                      -- in the body text match exactly; this avoids fragile string normalization.
+                      throwaway <- mkNewState ((stCfg st) {verbose = False}) (LambdaGen origLevel)
+                      modifyIORef' (rCompilingFuncs throwaway) (Set.insert nm)
+                      -- If the body captures SVals from the live state's context, the throwaway
+                      -- compilation will throw (e.g., context-mismatch). That is a definite conflict:
+                      -- the body references different state-bound variables.
+                      mbD <- C.try (f throwaway fk)
+                      case mbD of
+                        Left (_ :: C.SomeException)
+                          -> conflictError nm
+                        Right d
+                          -> do defs <- readIORef (rDefns st)
+                                case Map.lookup (barify nm) defs of
+                                  Just (oldDef, _)
+                                    | not (smtDefEq d oldDef)
+                                    -> conflictError nm
+                                  _ -> pure ()
+                                -- Body matches; memoize this StableName hash so future calls
+                                -- with the same closure skip instantly.
+                                modifyState st rUserFuncs (Map.adjust (first (Set.insert sn)) nm) (pure ())
+                      pure $ UINone True
+              Nothing
+                -> do -- First time seeing this name. Record lambda level for future comparison.
+                      ll <- readIORef (rLambdaLevel st)
+                      modifyState st rUserFuncs      (Map.insert nm (Set.singleton sn, ll)) (pure ())
+                      modifyState st rCompilingFuncs (Set.insert nm) (pure ())
+                      d <- UISMT <$> f st fk
+                      modifyState st rCompilingFuncs (Set.delete nm) (pure ())
+                      pure d
+retrieveUICode _            _  _  (UICodeC (_, c)) = pure $ UICgC c
+
+-- Get the constant value associated with the UI
+retrieveConstCode :: UIKind a -> Maybe a
+retrieveConstCode UIFree{}         = Nothing
+retrieveConstCode (UIFun   (v, _)) = Just v
+retrieveConstCode (UICodeC (v, _)) = Just v
+
+instance SymVal a => SMTDefinable (SBV a) where
+  sbvFun2smt (fn :: SBVs as -> SBV a)
+    | SymValsNil <- symValInsts :: SymValInsts as
+    , a <- fn SBVsNil
+    = do st <- mkNewState defaultSMTCfg (LambdaGen (Just 0))
+         s <- lambdaStr st TopLevel (kindOf a) a
+         pure $ intercalate "\n" [ "; Automatically generated by SBV. Do not modify!"
+                                 , "; Type: " ++ T.unpack (smtType (kindOf a))
+                                 , show s
+                                 ]
+  sbvFun2smt fn = defs2smt (\args -> fn args .== fn args)
+
+  sbvDefineValueFun nm mbArgs insts uiKind args
+    | Just v <- retrieveConstCode uiKind
+    , foldlSymSBVs (\r x -> r && isConcrete x) True insts args
+    = v args
+    | ka <- kindOf (Proxy @a)
+    = SBV $ SVal ka $ Right $ cache $ \st ->
+        do isSMT <- inSMTMode st
+           case (isSMT, uiKind) of
+             (True, UICodeC (v, _)) -> sbvToSV st (v args)
+             _                      -> do let ks = symValKinds insts ++ [ka]
+                                          ui <- retrieveUICode nm st ka uiKind
+                                          op <- newUninterpreted st nm mbArgs (SBVType ks) ui
+                                          svs <- rlist2list <$> mapMSBVs (sbvToSV st) args
+                                          mapM_ forceSVArg svs
+                                          newExpr st ka $ SBVApp op svs
+
+  registerFunction x = do st <- symbolicEnv
+                          liftIO $ sbvToSV st x >>= forceSVArg
+
+  symWithKind nm = sym (nm ++ "_" ++ show (kindOf (Proxy @a)))
+
+
+instance (SymVal a, SMTDefinable b) => SMTDefinable (SBV a -> b) where
+  sbvFun2smt (fn :: SBVs as -> SBV a -> b) =
+    sbvFun2smt (\((SBVsCons as a) :: SBVs (as :> a)) -> fn as a)
+
+  sbvDefineValueFun nm mbArgs insts uiKind args a =
+    sbvDefineValueFun nm mbArgs (SymValsCons insts)
+    ((\f (SBVsCons xs x) -> f xs x) <$> uiKind) (SBVsCons args a)
+
+  registerFunction f = do let k = kindOf (Proxy @a)
+                          st <- symbolicEnv
+                          v <- liftIO $ newInternalVariable st k
+                          let a = SBV $ SVal k $ Right $ cache (const (pure v))
+                          registerFunction $ f a
+
+-- Mark the UIKind as uncurried
+mkUncurried :: UIKind a -> UIKind a
+mkUncurried (UIFree  _) = UIFree  False
+mkUncurried (UIFun   a) = UIFun   a
+mkUncurried (UICodeC a) = UICodeC a
+
+
+uncurrySBVs2 :: (SBVs as -> (SBV c, SBV b) -> SBV a) ->
+                (SBVs (as :> c :> b) -> SBV a)
+uncurrySBVs2 fn (SBVsCons (SBVsCons as c) b) = fn as (c,b)
+
+-- Uncurried functions of two arguments
+instance (SymVal c, SymVal b, SymVal a, HasKind a) => SMTDefinable ((SBV c, SBV b) -> SBV a) where
+  sbvFun2smt = sbvFun2smt . uncurrySBVs2
+
+  registerFunction = registerFunction . curry2
+  sbvDefineValueFun nm mbArgs insts uiKind = uncurry2 <$> sbvDefineValueFun nm mbArgs insts (fmap curry2 <$> mkUncurried uiKind)
+
+-- Uncurried functions of three arguments
+instance (SymVal d, SymVal c, SymVal b, SymVal a, HasKind a) => SMTDefinable ((SBV d, SBV c, SBV b) -> SBV a) where
+  sbvFun2smt = sbvFun2smt . uncurrySBVs3
+    where uncurrySBVs3 :: (SBVs as -> (SBV d, SBV c, SBV b) -> SBV a) -> (SBVs (as :> d :> c :> b) -> SBV a)
+          uncurrySBVs3 fn (SBVsCons (SBVsCons (SBVsCons as d) c) b) = fn as (d,c,b)
+  registerFunction = registerFunction . curry3
+  sbvDefineValueFun nm mbArgs insts uiKind = uncurry3 <$> sbvDefineValueFun nm mbArgs insts (fmap curry3 <$> mkUncurried uiKind)
+
+-- Uncurried functions of four arguments
+instance (SymVal e, SymVal d, SymVal c, SymVal b, SymVal a, HasKind a) => SMTDefinable ((SBV e, SBV d, SBV c, SBV b) -> SBV a) where
+  sbvFun2smt = sbvFun2smt . uncurrySBVs4
+   where uncurrySBVs4 :: (SBVs as -> (SBV e, SBV d, SBV c, SBV b) -> SBV a) -> (SBVs (as :> e :> d :> c :> b) -> SBV a)
+         uncurrySBVs4 fn (SBVsCons (SBVsCons (SBVsCons (SBVsCons as e) d) c) b) = fn as (e,d,c,b)
+  registerFunction = registerFunction . curry4
+  sbvDefineValueFun nm mbArgs insts uiKind = uncurry4 <$> sbvDefineValueFun nm mbArgs insts (fmap curry4 <$> mkUncurried uiKind)
+
+-- Uncurried functions of five arguments
+instance (SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, SymVal a, HasKind a) => SMTDefinable ((SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) where
+  sbvFun2smt = sbvFun2smt . uncurrySBVs5
+   where uncurrySBVs5 :: (SBVs as -> (SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) -> (SBVs (as :> f :> e :> d :> c :> b) -> SBV a)
+         uncurrySBVs5 fn (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons as f) e) d) c) b) = fn as (f,e,d,c,b)
+  registerFunction = registerFunction . curry5
+  sbvDefineValueFun nm mbArgs insts uiKind = uncurry5 <$> sbvDefineValueFun nm mbArgs insts (fmap curry5 <$> mkUncurried uiKind)
+
+-- Uncurried functions of six arguments
+instance (SymVal g, SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, SymVal a, HasKind a) => SMTDefinable ((SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) where
+  sbvFun2smt = sbvFun2smt . uncurrySBVs6
+   where uncurrySBVs6 :: (SBVs as -> (SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) -> (SBVs (as :> g :> f :> e :> d :> c :> b) -> SBV a)
+         uncurrySBVs6 fn (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons as g) f) e) d) c) b) = fn as (g,f,e,d,c,b)
+
+  registerFunction = registerFunction . curry6
+  sbvDefineValueFun nm mbArgs insts uiKind = uncurry6 <$> sbvDefineValueFun nm mbArgs insts (fmap curry6 <$> mkUncurried uiKind)
+
+-- Uncurried functions of seven arguments
+instance (SymVal h, SymVal g, SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, SymVal a, HasKind a) => SMTDefinable ((SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) where
+  sbvFun2smt = sbvFun2smt . uncurrySBVs7
+   where uncurrySBVs7 :: (SBVs as -> (SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) -> (SBVs (as :> h :> g :> f :> e :> d :> c :> b) -> SBV a)
+         uncurrySBVs7 fn (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons as h) g) f) e) d) c) b) = fn as (h,g,f,e,d,c,b)
+  registerFunction = registerFunction . curry7
+  sbvDefineValueFun nm mbArgs insts uiKind = uncurry7 <$> sbvDefineValueFun nm mbArgs insts (fmap curry7 <$> mkUncurried uiKind)
+
+-- Uncurried functions of eight arguments
+instance (SymVal i, SymVal h, SymVal g, SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, SymVal a, HasKind a) => SMTDefinable ((SBV i, SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) where
+  sbvFun2smt = sbvFun2smt . uncurrySBVs8
+   where uncurrySBVs8 :: (SBVs as -> (SBV i, SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) -> (SBVs (as :> i :> h :> g :> f :> e :> d :> c :> b) -> SBV a)
+         uncurrySBVs8 fn (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons as i) h) g) f) e) d) c) b) = fn as (i,h,g,f,e,d,c,b)
+  registerFunction = registerFunction . curry8
+  sbvDefineValueFun nm mbArgs insts uiKind = uncurry8 <$> sbvDefineValueFun nm mbArgs insts (fmap curry8 <$> mkUncurried uiKind)
+
+-- Uncurried functions of nine arguments
+instance (SymVal j, SymVal i, SymVal h, SymVal g, SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, SymVal a, HasKind a) => SMTDefinable ((SBV j, SBV i, SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) where
+  sbvFun2smt = sbvFun2smt . uncurrySBVs9
+   where uncurrySBVs9 :: (SBVs as -> (SBV j, SBV i, SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) -> (SBVs (as :> j :> i :> h :> g :> f :> e :> d :> c :> b) -> SBV a)
+         uncurrySBVs9 fn (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons as j) i) h) g) f) e) d) c) b) = fn as (j,i,h,g,f,e,d,c,b)
+  registerFunction = registerFunction . curry9
+  sbvDefineValueFun nm mbArgs insts uiKind = uncurry9 <$> sbvDefineValueFun nm mbArgs insts (fmap curry9 <$> mkUncurried uiKind)
+
+-- Uncurried functions of ten arguments
+instance (SymVal k, SymVal j, SymVal i, SymVal h, SymVal g, SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, SymVal a, HasKind a) => SMTDefinable ((SBV k, SBV j, SBV i, SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) where
+  sbvFun2smt = sbvFun2smt . uncurrySBVs10
+   where uncurrySBVs10 :: (SBVs as -> (SBV k, SBV j, SBV i, SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) -> (SBVs (as :> k :> j :> i :> h :> g :> f :> e :> d :> c :> b) -> SBV a)
+         uncurrySBVs10 fn (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons as k) j) i) h) g) f) e) d) c) b) = fn as (k,j,i,h,g,f,e,d,c,b)
+  registerFunction = registerFunction . curry10
+  sbvDefineValueFun nm mbArgs insts uiKind = uncurry10 <$> sbvDefineValueFun nm mbArgs insts (fmap curry10 <$> mkUncurried uiKind)
+
+-- Uncurried functions of eleven arguments
+instance (SymVal l, SymVal k, SymVal j, SymVal i, SymVal h, SymVal g, SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, SymVal a, HasKind a) => SMTDefinable ((SBV l, SBV k, SBV j, SBV i, SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) where
+  sbvFun2smt = sbvFun2smt . uncurrySBVs11
+   where uncurrySBVs11 :: (SBVs as -> (SBV l, SBV k, SBV j, SBV i, SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) -> (SBVs (as :> l :> k :> j :> i :> h :> g :> f :> e :> d :> c :> b) -> SBV a)
+         uncurrySBVs11 fn (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons as l) k) j) i) h) g) f) e) d) c) b) = fn as (l,k,j,i,h,g,f,e,d,c,b)
+  registerFunction = registerFunction . curry11
+  sbvDefineValueFun nm mbArgs insts uiKind = uncurry11 <$> sbvDefineValueFun nm mbArgs insts (fmap curry11 <$> mkUncurried uiKind)
+
+-- Uncurried functions of twelve arguments
+instance (SymVal m, SymVal l, SymVal k, SymVal j, SymVal i, SymVal h, SymVal g, SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, SymVal a, HasKind a) => SMTDefinable ((SBV m, SBV l, SBV k, SBV j, SBV i, SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) where
+  sbvFun2smt = sbvFun2smt . uncurrySBVs12
+    where uncurrySBVs12 :: (SBVs as -> (SBV m, SBV l, SBV k, SBV j, SBV i, SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) -> (SBVs (as :> m :> l :> k :> j :> i :> h :> g :> f :> e :> d :> c :> b) -> SBV a)
+          uncurrySBVs12 fn (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons (SBVsCons as m) l) k) j) i) h) g) f) e) d) c) b) = fn as (m,l,k,j,i,h,g,f,e,d,c,b)
+  registerFunction = registerFunction . curry12
+  sbvDefineValueFun nm mbArgs insts uiKind = uncurry12 <$> sbvDefineValueFun nm mbArgs insts (fmap curry12 <$> mkUncurried uiKind)
+
+-- | Symbolic computations provide a context for writing symbolic programs.
+instance MonadIO m => SolverContext (SymbolicT m) where
+   constrain                   = imposeConstraint False []               . unSBV . quantifiedBool
+   softConstrain               = imposeConstraint True  []               . unSBV . quantifiedBool
+   namedConstraint        nm   = imposeConstraint False [(":named", nm)] . unSBV . quantifiedBool
+   constrainWithAttribute atts = imposeConstraint False atts             . unSBV . quantifiedBool
+
+   contextState = symbolicEnv
+   setOption o  = addNewSMTOption  o
+
+   internalVariable k = contextState >>= \st -> liftIO $ do
+                           sv <- newInternalVariable st k
+                           pure $ SBV $ SVal k (Right (cache (const (pure sv))))
+
+-- | Generalization of 'Data.SBV.assertWithPenalty'
+assertWithPenalty :: MonadSymbolic m => String -> SBool -> Penalty -> m ()
+assertWithPenalty nm o p = addSValOptGoal $ unSBV <$> AssertWithPenalty nm o p
+
+-- | Class of metrics we can optimize for. Currently, booleans,
+-- bounded signed/unsigned bit-vectors, unbounded integers,
+-- algebraic reals and floats can be optimized. You can add
+-- your instances, but bewared that the 'MetricSpace' should
+-- map your type to something the backend solver understands, which
+-- are limited to unsigned bit-vectors, reals, and unbounded integers
+-- for z3.
+--
+-- A good reference on these features is given in the following paper:
+-- <http://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/nbjorner-scss2014.pdf>.
+--
+-- Minimal completion: None. However, if @MetricSpace@ is not identical to the type, you want
+-- to define 'toMetricSpace'/'annotateForMS', and possibly 'minimize'/'maximize' to add extra constraints as necessary.
+class Metric a where
+  -- | The metric space we optimize the goal over. Usually the same as the type itself, but not always!
+  -- For instance, signed bit-vectors are optimized over their unsigned counterparts, floats are
+  -- optimized over their 'Word32' comparable counterparts, etc.
+  type MetricSpace a :: Type
+  type MetricSpace a = a
+
+  -- | Compute the metric value to optimize.
+  toMetricSpace   :: SBV a -> SBV (MetricSpace a)
+
+  -- | Compute the value itself from the metric corresponding to it.
+  fromMetricSpace :: SBV (MetricSpace a) -> SBV a
+
+  -- | Annotate for the metric space, to clarify the new name. If this result is not identity,
+  -- we will add an sObserve on the original.
+  annotateForMS :: Proxy a -> String -> String
+
+  -- | Minimizing a metric space
+  msMinimize :: (MonadSymbolic m, SolverContext m) => String -> SBV a -> m ()
+  msMinimize nm o = do let nm' = annotateForMS (Proxy @a) nm
+                       when (nm' /= nm) $ sObserve nm (unSBV o)
+                       addSValOptGoal $ unSBV <$> Minimize nm' (toMetricSpace o)
+
+  -- | Maximizing a metric space
+  msMaximize :: (MonadSymbolic m, SolverContext m) => String -> SBV a -> m ()
+  msMaximize nm o = do let nm' = annotateForMS (Proxy @a) nm
+                       when (nm' /= nm) $ sObserve nm (unSBV o)
+                       addSValOptGoal $ unSBV <$> Maximize nm' (toMetricSpace o)
+
+  -- if MetricSpace is the same, we can give a default definition
+  default toMetricSpace :: (a ~ MetricSpace a) => SBV a -> SBV (MetricSpace a)
+  toMetricSpace = id
+
+  default fromMetricSpace :: (a ~ MetricSpace a) => SBV (MetricSpace a) -> SBV a
+  fromMetricSpace = id
+
+  -- Annotations to indicate if the metric space transition was needed
+  default annotateForMS :: (a ~ MetricSpace a) => Proxy a -> String -> String
+  annotateForMS _ s = s
+
+-- Booleans assume True is greater than False
+instance Metric Bool where
+  type MetricSpace Bool = Word8
+  toMetricSpace t   = ite t 1 0
+  fromMetricSpace w = w ./= 0
+  annotateForMS _ s = "toMetricSpace(" ++ s ++ ")"
+
+-- | Generalization of 'Data.SBV.minimize'
+minimize :: (Metric a, MonadSymbolic m, SolverContext m) => String -> SBV a -> m ()
+minimize = msMinimize
+
+-- | Generalization of 'Data.SBV.maximize'
+maximize :: (Metric a, MonadSymbolic m, SolverContext m) => String -> SBV a -> m ()
+maximize = msMaximize
+
+-- Unsigned types, integers, and reals directly optimize
+instance Metric Word8
+instance Metric Word16
+instance Metric Word32
+instance Metric Word64
+instance Metric Integer
+instance Metric AlgReal
+
+-- To optimize signed bounded values, we have to adjust to the range
+instance Metric Int8 where
+  type MetricSpace Int8 = Word8
+  toMetricSpace   x = sFromIntegral x + 128  -- 2^7
+  fromMetricSpace x = sFromIntegral x - 128
+  annotateForMS _ s = "toMetricSpace(" ++ s ++ ")"
+
+instance Metric Int16 where
+  type MetricSpace Int16 = Word16
+  toMetricSpace   x = sFromIntegral x + 32768  -- 2^15
+  fromMetricSpace x = sFromIntegral x - 32768
+  annotateForMS _ s = "toMetricSpace(" ++ s ++ ")"
+
+instance Metric Int32 where
+  type MetricSpace Int32 = Word32
+  toMetricSpace   x = sFromIntegral x + 2147483648 -- 2^31
+  fromMetricSpace x = sFromIntegral x - 2147483648
+  annotateForMS _ s = "toMetricSpace(" ++ s ++ ")"
+
+instance Metric Int64 where
+  type MetricSpace Int64 = Word64
+  toMetricSpace   x = sFromIntegral x + 9223372036854775808  -- 2^63
+  fromMetricSpace x = sFromIntegral x - 9223372036854775808
+  annotateForMS _ s = "toMetricSpace(" ++ s ++ ")"
+
+-- | Optimizing 'WordN'
+instance (KnownNat n, BVIsNonZero n) => Metric (WordN n)
+
+-- | Optimizing 'IntN'
+instance (KnownNat n, BVIsNonZero n) => Metric (IntN n) where
+  type MetricSpace (IntN n) = WordN n
+  toMetricSpace   x = sFromIntegral x + 2 ^ (intOfProxy (Proxy @n) - 1)
+  fromMetricSpace x = sFromIntegral x - 2 ^ (intOfProxy (Proxy @n) - 1)
+  annotateForMS _ s = "toMetricSpace(" ++ s ++ ")"
+
+-- Quickcheck interface on symbolic-booleans..
+instance Testable SBool where
+  property (SBV (SVal _ (Left b))) = property (cvToBool b)
+  property s                       = cantQuickCheck $ "Result did not evaluate to a concrete boolean: " ++ show s
+
+instance Testable (Symbolic SBool) where
+   property prop = QC.monadicIO $ do (cond, r, modelVals) <- QC.run test
+                                     QC.pre cond
+                                     unless (r || null modelVals) $ QC.monitor (QC.counterexample (complain modelVals))
+                                     QC.assert r
+     where test = do (r, Result{resTraces=tvals, resObservables=ovals, resConsts=(_, cs), resConstraints=cstrs, resUIConsts=unints}) <-
+                                 C.catch (runSymbolic defaultSMTCfg (Concrete Nothing) prop)
+                                         (\(e :: C.SomeException) -> cantQuickCheck (show e))
+
+
+                     let cval = fromMaybe (cantQuickCheck "A constraint did not evaluate to a concrete boolean") . (`lookup` cs)
+                         cond = -- Only pick-up "hard" constraints, as indicated by False in the fist component
+                                and [cvToBool (cval v) | (False, _, v) <- F.toList cstrs]
+
+                         getObservable (nm, f, v) = case v `lookup` cs of
+                                                      Just cv -> if f cv then Just (nm, cv) else Nothing
+                                                      Nothing -> cantQuickCheck "An observable did not evaluate to a concrete value"
+
+                     case map fst unints of
+                       [] -> case unliteral r of
+                               Nothing -> cantQuickCheck "The result did not evaluate to a concrete value"
+                               Just b  -> pure (cond, b, tvals ++ mapMaybe getObservable ovals)
+                       uis -> cantQuickCheck $ "Uninterpreted constants remain: " ++ unwords uis
+
+           complain qcInfo = showModel defaultSMTCfg (SMTModel [] Nothing qcInfo [])
+
+-- Complain if what we got isn't something we can quick-check
+cantQuickCheck :: String -> a
+cantQuickCheck why = error $ unlines [ "*** Data.SBV: Cannot quickcheck the given property."
+                                     , "***"
+                                     , "*** Certain SBV properties cannot be quick-checked. In particular,"
+                                     , "*** SBV can't quick-check in the presence of:"
+                                     , "***"
+                                     , "***   - Uninterpreted constants."
+                                     , "***   - Uninterpreted types."
+                                     , "***   - Floating point operations with rounding modes other than RNE."
+                                     , "***   - Floating point FMA operation, regardless of rounding mode."
+                                     , "***   - Quantified booleans, i.e., uses of Forall/Exists/ExistsUnique."
+                                     , "***   - Uses of quantifiedBool"
+                                     , "***   - Calls to 'observe' (use 'sObserve' instead)"
+                                     , "***"
+                                     , "*** If you can't avoid the above features or run into an issue with"
+                                     , "*** quickcheck even though you haven't used these features, please report this as a bug!"
+                                     , "***"
+                                     , "*** Origin:"
+                                     , "***"
+                                     , why
+                                     ]
+
+-- | Quick check an SBV property. Note that a regular @quickCheck@ call will work just as
+-- well. Use this variant if you want to receive the boolean result.
+sbvQuickCheck :: Symbolic SBool -> IO Bool
+sbvQuickCheck prop = QC.isSuccess <$> QC.quickCheckResult prop
+
+-- Quickcheck interface on dynamically-typed values. A run-time check
+-- ensures that the value has boolean type.
+instance Testable (Symbolic SVal) where
+  property m = property $ do s <- m
+                             when (kindOf s /= KBool) $ error "Cannot quickcheck non-boolean value"
+                             pure (SBV s :: SBool)
+
+-- | Explicit sharing combinator. The SBV library has internal caching/hash-consing mechanisms
+-- built in, based on Andy Gill's type-safe observable sharing technique (see: <http://ku-fpg.github.io/files/Gill-09-TypeSafeReification.pdf>).
+-- However, there might be times where being explicit on the sharing can help, especially in experimental code. The 'slet' combinator
+-- ensures that its first argument is computed once and passed on to its continuation, explicitly indicating the intent of sharing. Most
+-- use cases of the SBV library should simply use Haskell's @let@ construct for this purpose.
+slet :: forall a b. (HasKind a, HasKind b) => SBV a -> (SBV a -> SBV b) -> SBV b
+slet x f = SBV $ SVal k $ Right $ cache r
+    where k    = kindOf (Proxy @b)
+          r st = do xsv <- sbvToSV st x
+                    let xsbv = SBV $ SVal (kindOf x) (Right (cache (const (pure xsv))))
+                        res  = f xsbv
+                    sbvToSV st res
+
+-- | Class of things that we can logically reduce to a boolean, by saturating and then asserting equivalence to itself
+class QSaturate m a where
+  qSaturate :: a -> m ()
+
+-- | Base case; simple variable in the symbolic monad
+instance SolverContext m => QSaturate m SBool where
+  qSaturate b = constrain $ b .== b
+
+-- | Saturate over a universal quantifier
+instance (HasKind a, Monad m, SolverContext m, QSaturate m r) => QSaturate m (Forall nm a -> r) where
+  qSaturate f = qSaturate . f . Forall =<< internalVariable (kindOf (Proxy @a))
+
+-- | Saturate over a pair of universal quantifiers
+instance (HasKind a, HasKind b, Monad m, SolverContext m, QSaturate m r) => QSaturate m ((Forall na a, Forall nb b) -> r) where
+  qSaturate = qSaturate . curry
+
+-- | Saturate over a pair of existential quantifiers
+instance (HasKind a, HasKind b, Monad m, SolverContext m, QSaturate m r) => QSaturate m ((Exists na a, Exists nb b) -> r) where
+  qSaturate = qSaturate . curry
+
+-- | Saturate over a number of universal quantifiers
+instance (KnownNat n, HasKind a, Monad m, SolverContext m, QSaturate m r) => QSaturate m (ForallN n nm a -> r) where
+  qSaturate f = qSaturate . f . ForallN =<< replicateM (intOfProxy (Proxy @n)) (internalVariable (kindOf (Proxy @a)))
+
+-- | Saturate over an existential quantifier
+instance (HasKind a, Monad m, SolverContext m, QSaturate m r) => QSaturate m (Exists nm a -> r) where
+  qSaturate f = qSaturate . f . Exists =<< internalVariable (kindOf (Proxy @a))
+
+-- | Saturate over an a number of existential quantifiers
+instance (KnownNat n, HasKind a, Monad m, SolverContext m, QSaturate m r) => QSaturate m (ExistsN n nm a -> r) where
+  qSaturate f = qSaturate . f . ExistsN =<< replicateM (intOfProxy (Proxy @n)) (internalVariable (kindOf (Proxy @a)))
+
+-- | Saturate over a unique-exists variable
+instance (HasKind a, Monad m, SolverContext m, QSaturate m r) => QSaturate m (ExistsUnique nm a -> r) where
+  qSaturate f = qSaturate . f . ExistsUnique =<< internalVariable (kindOf (Proxy @a))
+
+-- | Saturate a predicate, but save/restore observables so they're not messed up.
+qSaturateSavingObservables :: (Monad m, MonadIO m, SolverContext m, QSaturate m a) => a -> m ()
+qSaturateSavingObservables p = do State{rObservables} <- contextState
+                                  curObservables <- liftIO $ readIORef rObservables
+                                  qSaturate p
+                                  liftIO $ writeIORef rObservables curObservables
+
+-- | Equality as a proof method. Allows for
+-- very concise construction of equivalence proofs, which is very typical in
+-- bit-precise proofs.
+infix 4 ===
+class Equality a where
+  (===) :: a -> a -> IO ThmResult
+
+instance {-# OVERLAPPABLE #-} (SymVal a, EqSymbolic z) => Equality (SBV a -> z) where
+  k === l = prove $ \a -> k a .== l a
+
+instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, EqSymbolic z) => Equality (SBV a -> SBV b -> z) where
+  k === l = prove $ \a b -> k a b .== l a b
+
+instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, EqSymbolic z) => Equality ((SBV a, SBV b) -> z) where
+  k === l = prove $ \a b -> k (a, b) .== l (a, b)
+
+instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, SymVal c, EqSymbolic z) => Equality (SBV a -> SBV b -> SBV c -> z) where
+  k === l = prove $ \a b c -> k a b c .== l a b c
+
+instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, SymVal c, EqSymbolic z) => Equality ((SBV a, SBV b, SBV c) -> z) where
+  k === l = prove $ \a b c -> k (a, b, c) .== l (a, b, c)
+
+instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, SymVal c, SymVal d, EqSymbolic z) => Equality (SBV a -> SBV b -> SBV c -> SBV d -> z) where
+  k === l = prove $ \a b c d -> k a b c d .== l a b c d
+
+instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, SymVal c, SymVal d, EqSymbolic z) => Equality ((SBV a, SBV b, SBV c, SBV d) -> z) where
+  k === l = prove $ \a b c d -> k (a, b, c, d) .== l (a, b, c, d)
+
+instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, EqSymbolic z) => Equality (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> z) where
+  k === l = prove $ \a b c d e -> k a b c d e .== l a b c d e
+
+instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, EqSymbolic z) => Equality ((SBV a, SBV b, SBV c, SBV d, SBV e) -> z) where
+  k === l = prove $ \a b c d e -> k (a, b, c, d, e) .== l (a, b, c, d, e)
+
+instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, SymVal f, EqSymbolic z) => Equality (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> z) where
+  k === l = prove $ \a b c d e f -> k a b c d e f .== l a b c d e f
+
+instance {-# OVERLAPPABLE #-}
+ (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, SymVal f, EqSymbolic z) => Equality ((SBV a, SBV b, SBV c, SBV d, SBV e, SBV f) -> z) where
+  k === l = prove $ \a b c d e f -> k (a, b, c, d, e, f) .== l (a, b, c, d, e, f)
+
+instance {-# OVERLAPPABLE #-}
+ (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, SymVal f, SymVal g, EqSymbolic z) => Equality (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV g -> z) where
+  k === l = prove $ \a b c d e f g -> k a b c d e f g .== l a b c d e f g
+
+instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, SymVal f, SymVal g, EqSymbolic z) => Equality ((SBV a, SBV b, SBV c, SBV d, SBV e, SBV f, SBV g) -> z) where
+  k === l = prove $ \a b c d e f g -> k (a, b, c, d, e, f, g) .== l (a, b, c, d, e, f, g)
+
+-- | Reading a value from an array.
+readArray :: forall key val. (SymVal key, SymVal val, HasKind val) => SArray key val -> SBV key -> SBV val
+readArray array key
+   | eqCheckIsObjectEq ka, Just (ArrayModel tbl def) <- unliteral array, Just _ <- unliteral key, Just r <- locate (unSBV key) def tbl
+   = r
+   | True
+   = symRes
+   where symRes = SBV . SVal kb . Right $ cache g
+         ka = kindOf (Proxy @key)
+         kb = kindOf (Proxy @val)
+         g st = do f <- sbvToSV st array
+                   k <- sbvToSV st key
+                   newExpr st kb (SBVApp ReadArray [f, k])
+
+         -- return the first value, since we don't bother deleting previous writes. Note that this might
+         -- fail if we don't have equality; but that's OK; in that case we'll go symbolic.
+         locate skey def vals = go vals
+            where go []              = Just $ literal def
+                  go ((k, v) : rest) = case unliteral (SBV (svStrongEqual skey (unSBV (literal k)))) of
+                                          Nothing    -> Nothing
+                                          Just True  -> Just $ literal v
+                                          Just False -> go rest
+
+-- | Writing a value to an array. For the concrete case, we don't bother deleting earlier entries, we keep a history. The earlier a value is in the list, the "later" it happened; in a stack fashion.
+writeArray :: forall key val. (HasKind key, SymVal key, SymVal val, HasKind val) => SArray key val -> SBV key -> SBV val -> SArray key val
+writeArray array key value
+   | Just (ArrayModel tbl def) <- unliteral array, Just keyVal <- unliteral key, Just val <- unliteral value
+   = literal $ ArrayModel ((keyVal, val) : tbl) def  -- It's important that we "cons" the value here, since it takes precedence in a read
+   | True
+   = SBV . SVal k . Right $ cache g
+   where k  = KArray (kindOf (Proxy @key)) (kindOf (Proxy @val))
+
+         g st = do arr    <- sbvToSV st array
+                   keyVal <- sbvToSV st key
+                   val    <- sbvToSV st value
+                   newExpr st k (SBVApp WriteArray [arr, keyVal, val])
+
+-- | Create a constant array. This is a special case of 'lambdaArray', but it creates a
+-- simpler expression in the case of constants.
+constArray :: forall key val. (SymVal key, SymVal val) => SBV val -> SArray key val
+constArray v
+  | Just v' <- unliteral v
+  = literal $ ArrayModel [] v'
+  | True
+  = SBV . SVal k . Right $ cache g
+  where ka = kindOf (Proxy @key)
+        kb = kindOf (Proxy @val)
+        k  = KArray ka kb
+
+        g st = do sv <- sbvToSV st v
+                  newExpr st k (SBVApp (ArrayInit (Left (ka, kb))) [sv])
+
+-- | Create a completely free array, with no constraints on it, as an expression.
+-- Note that you can create an array in the symbolic context with the regular 'free'
+-- calls. (Or 'sArray' if you prefer.) This variant creates it as an expression, i.e.,
+-- without having to be in the monadic context. We take a name identifier here as an
+-- argument which uniquely identifies this array. Note that this is necessary, as otherwise
+-- there would be no way to distinguish two different calls in the pure context. If you
+-- use the same name, then you'll get the same array, much like uninterpreted functions.
+freeArray :: forall key val. (SymVal key, SymVal val) => String -> SArray key val
+freeArray = lambdaArray . uninterpret
+
+-- | Using a lambda as an array. We can turn a function into an array, relating indexes
+-- to their values. (That is, passing @f@ would create an array where entry @i@
+-- is initialized to value @f i@.) For the special case of initializing with a constant
+-- value, either pass @const val@, or use 'constArray'.
+--
+-- __Arrays vs. uninterpreted functions:__ The basic array theory provides only
+-- @select@ ('readArray'), @store@ ('writeArray'), and @const@ ('constArray'). These operations
+-- can only construct arrays that differ from a constant in finitely many positions. For instance,
+-- the identity array (where @a[i] = i@ for every @i@) cannot be built from 'constArray' plus
+-- finitely many 'writeArray' calls. The @lambdaArray@ function goes beyond this: it uses the
+-- solver's ability to identify arrays with function spaces, allowing the creation of arrays like
+-- @lambdaArray id@ that correspond to arbitrary functions.
+--
+-- This identification has a model-theoretic consequence. The pure array theory (with only
+-- @select@\/@store@\/@const@) is a weaker theory: it admits models where the array sort does
+-- not contain all functions, only those reachable by finitely many stores on constants. This means
+-- certain formulas are satisfiable in the pure theory (because the solver has more freedom in choosing
+-- what arrays exist) that become unsatisfiable when arrays are identified with functions (because the
+-- richer array sort can provide counterexamples). In practice, modern solvers use the stronger
+-- identification, so @lambdaArray@, 'constArray', and 'writeArray' all operate in this richer setting.
+lambdaArray :: forall a b. (SymVal a, HasKind b) => (SBV a -> SBV b) -> SArray a b
+lambdaArray f = SBV . SVal k . Right $ cache g
+  where k = KArray (kindOf (Proxy @a)) (kindOf (Proxy @b))
+
+        g st = do def <- lambdaStr st TopLevel (kindOf (Proxy @b)) f
+                  newExpr st k (SBVApp (ArrayInit (Right def)) [])
+
+-- | Turn a constant association-list and a default into a symbolic array.
+listArray :: (SymVal a, SymVal b) => [(a, b)] -> b -> SArray a b
+listArray ascs def = literal $ ArrayModel ascs def
+
+-- | Create a closure, wrapping the free variables together with the function. When using higher-order functions
+-- in SBV (like map), the function passed must be closed, i.e., not have any free variables. If you need to call
+-- such a function with a function capturing a free variable, you should create a closure instead.
+data Closure env a = Closure { closureEnv :: env
+                             , closureFun :: env -> a
+                             }
+
+-- | Define a higher-order function. Similar to 'smtFunction', but when we have a higher-order argument. Note that
+-- the higher-order argument cannot have free variables. Also, if the function is recursive, you should call
+-- the first argument of the defining function, which SBV uses to tie the recursive knot. (Note that recursive
+-- functions defined via 'smtFunction' don't have this latter requirement as they can figure out the recursion
+-- automatically. Higher-order functions, unfortunately, can't do this: They firstify their high-order argument,
+-- giving the whole function a unique name; captured via the call to the recursive definition.)
+smtHOFunction :: forall a b f.
+                 ( SMTDefinable (a -> SBV b)
+                 , Lambda Symbolic f
+                 , Lambda Symbolic (a -> SBV b)
+                 , HasKind b
+                 , HasKind f
+                 , Typeable a
+                 , Typeable b
+                 , Typeable f
+                 ) => String       -- prefix to use
+                   -> f            -- The higher-order argument. We're very generic here!
+                   -> (a -> SBV b) -- The ho-function we're modeling
+                   ->  a -> SBV b  -- The resulting function, that can be used as is, and will be rendered in SMTLib without unfolding
+smtHOFunction nm f = smtHOFunctionGen nm f AutoMeasure
+
+-- | Like 'smtHOFunction', but with an explicit termination measure. Use this when the
+-- auto-guess measure doesn't work for a higher-order recursive function.
+smtHOFunctionWithMeasure :: forall a b f r.
+                 ( SMTDefinable (a -> SBV b)
+                 , Lambda Symbolic f
+                 , Lambda Symbolic (a -> SBV b)
+                 , HasKind b
+                 , HasKind f
+                 , Typeable a
+                 , Typeable b
+                 , Typeable f
+                 , Zero r, OrdSymbolic (SBV r), SymVal r
+                 , ApplyMeasure (a -> SBV b) r
+                 ) => String                      -- ^ prefix to use
+                   -> f                           -- ^ The higher-order argument
+                   -> MeasureOf (a -> SBV b) r    -- ^ Termination measure
+                   -> (a -> SBV b)                -- ^ The ho-function we're modeling
+                   ->  a -> SBV b                 -- ^ The resulting function
+smtHOFunctionWithMeasure nm f msr = smtHOFunctionGen nm f (HasMeasure (MeasureEval (applyMeasure @(a -> SBV b) @r msr)) [])
+
+-- | Common implementation for higher-order SMT function definitions.
+smtHOFunctionGen :: forall a b f.
+                 ( SMTDefinable (a -> SBV b)
+                 , Lambda Symbolic f
+                 , Lambda Symbolic (a -> SBV b)
+                 , HasKind b
+                 , HasKind f
+                 , Typeable a
+                 , Typeable b
+                 , Typeable f
+                 ) => String               -- ^ prefix to use
+                   -> f                    -- ^ The higher-order argument
+                   -> Measure (a -> SBV b) -- ^ Termination measure
+                   -> (a -> SBV b)         -- ^ The ho-function we're modeling
+                   ->  a -> SBV b          -- ^ The resulting function
+smtHOFunctionGen nm f measure hof arg = SBV $ SVal (kindOf (Proxy @(SBV b))) $ Right $ cache r
+  where r st = do lambdaDef <- lambdaStr st HigherOrderArg (arrayResultKind (kindOf (Proxy @f))) f
+                  let uniq = lambdaFingerprint st (T.unpack (smtLambdaText lambdaDef))
+                  sbvToSV st (smtFunctionDef (atProxy (Proxy @f) nm <> "_" <> uniq) measure hof arg)
+
+-- | Chase through nested array kinds to find the final result kind. Higher-order
+-- arguments are firstified into arrays, so we peel off the array wrappers.
+arrayResultKind :: Kind -> Kind
+arrayResultKind (KArray _ k) = arrayResultKind k
+arrayResultKind k            = k
+
+-- | Generate a short fingerprint from a lambda body string, used to give
+-- unique names to firstified higher-order function instantiations.
+lambdaFingerprint :: State -> String -> String
+lambdaFingerprint st lam = take uniqLen (BC.unpack (B.encode (hash (BC.pack (unwords (words lam))))))
+  where uniqLen = firstifyUniqueLen $ stCfg st
+
+{- HLint ignore module "Reduce duplication"   -}
+{- HLint ignore module "Eta reduce"           -}
+{- HLint ignore module "Avoid NonEmpty.unzip" -}
+{- HLint ignore module "Redundant id"         -}
+{- HLint ignore module "Use second"           -}
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
@@ -12,6 +12,7 @@
 {-# LANGUAGE BangPatterns        #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TupleSections       #-}
+{-# LANGUAGE ViewPatterns        #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -19,9 +20,12 @@
   (
   -- ** Basic constructors
     svTrue, svFalse, svBool
-  , svInteger, svFloat, svDouble, svFloatingPoint, svReal, svEnumFromThenTo, svString, svChar
+  , svInteger, svFloat, svDouble, svFloatingPoint, svRoundingMode
+  , svReal, svEnumFromThenTo, svString, svChar
   -- ** Basic destructors
-  , svAsBool, svAsInteger, svNumerator, svDenominator
+  , svAsBool, svAsInteger
+  , svAsFloat, svAsDouble, svAsFP, svAsRoundingMode, cvAsRoundingMode
+  , svNumerator, svDenominator
   -- ** Basic operations
   , svPlus, svTimes, svMinus, svUNeg, svAbs, svSignum
   , svDivide, svQuot, svRem, svQuotRem, svDivides
@@ -34,6 +38,13 @@
   , svSelect
   , svSign, svUnsign, svSetBit, svWordFromBE, svWordFromLE
   , svExp, svFromIntegral
+  , svFPNaN, svFPInf, svFPZero
+  , svFPFromIntegerLit, svFPFromRationalLit
+  , svFPIsZero, svFPIsInfinite, svFPIsNegative, svFPIsPositive
+  , svFPIsNaN, svFPIsNormal, svFPIsSubnormal
+  , svFPAdd, svFPSub, svFPMul, svFPDiv, svFPRem, svFPMin, svFPMax
+  , svFPFMA, svFPAbs, svFPNeg, svFPRoundToIntegral, svFPSqrt
+  , svCastToFP, svCastFromFP
   -- ** Overflows
   , svMkOverflow1, svMkOverflow2
   -- ** Derived operations
@@ -43,6 +54,7 @@
   , svBarrelRotateLeft, svBarrelRotateRight
   , svBlastLE, svBlastBE
   , svAddConstant, svIncrement, svDecrement
+  , svSWord32AsFloat, svSWord64AsDouble, svSWordAsFloatingPoint
   , svFloatAsSWord32, svDoubleAsSWord64, svFloatingPointAsSWord
   -- Utils
   , mkSymOp
@@ -51,8 +63,10 @@
 
 import Prelude hiding (Foldable(..))
 import Data.Bits (Bits(..))
-import Data.List (genericIndex, genericLength, genericTake, foldr, length, foldl', elem, nub, sort)
+import Data.List (genericIndex, genericLength, genericTake, foldr, length, foldl', elem, nub, sort, null, elemIndex)
 
+import Data.Maybe (isNothing)
+
 import Data.SBV.Core.AlgReals
 import Data.SBV.Core.Kind
 import Data.SBV.Core.Concrete
@@ -61,7 +75,7 @@
 
 import Data.Ratio
 
-import Data.SBV.Utils.Numeric (fpIsEqualObjectH, floatToWord, doubleToWord)
+import Data.SBV.Utils.Numeric (RoundingMode(..), divEucl, modEucl, {-fp2fp,-} fpIsEqualObjectH, fpIsNormalizedH, fpMaxH, fpMinH, fpRemH, fpRoundToIntegralH, floatToWord, doubleToWord, wordToFloat, wordToDouble)
 
 import LibBF
 
@@ -97,6 +111,10 @@
 svFloatingPoint f@(FP eb sb _) = SVal k (Left $! CV k (CFP f))
   where k  = KFP eb sb
 
+-- | Convert from a rounding mode
+svRoundingMode :: RoundingMode -> SVal
+svRoundingMode s = SVal kRoundingMode $ Left $ CV kRoundingMode $ CADT (show s, [])
+
 -- | Convert from a String
 svString :: String -> SVal
 svString s = SVal KString (Left $! CV KString (CString s))
@@ -122,6 +140,35 @@
 svAsInteger (SVal _ (Left (CV _ (CInteger n)))) = Just n
 svAsInteger _                                   = Nothing
 
+-- | Extract a float from a concrete value.
+svAsFloat :: SVal -> Maybe Float
+svAsFloat (SVal _ (Left (CV _ (CFloat f)))) = Just f
+svAsFloat _ = Nothing
+
+-- | Extract a double from a concrete value.
+svAsDouble :: SVal -> Maybe Double
+svAsDouble (SVal _ (Left (CV _ (CDouble d)))) = Just d
+svAsDouble _ = Nothing
+
+-- | Extract an t'FP' from a concrete value.
+svAsFP :: SVal -> Maybe FP
+svAsFP (SVal _ (Left (CV _ (CFP fp)))) = Just fp
+svAsFP _ = Nothing
+
+-- | Extract a rounding mode from an t'SVal'.
+svAsRoundingMode :: SVal -> Maybe RoundingMode
+svAsRoundingMode (SVal _ (Left cv)) = cvAsRoundingMode cv
+svAsRoundingMode _ = Nothing
+
+-- | Extract a rounding mode from a t'CV'.
+cvAsRoundingMode :: CV -> Maybe RoundingMode
+cvAsRoundingMode (CV k (CADT (s, [])))
+  | k == kRoundingMode
+  , mbMode <- s `lookup` [(show m, m) | m <- [minBound .. maxBound :: RoundingMode]]
+  = mbMode
+cvAsRoundingMode _
+  = Nothing
+
 -- | Grab the numerator of an SReal, if available
 svNumerator :: SVal -> Maybe Integer
 svNumerator (SVal KReal (Left (CV KReal (CAlgReal (AlgRational True r))))) = Just $ numerator r
@@ -191,12 +238,16 @@
         z = SVal k $ Left $ mkConstCV k (0 :: Integer)
         i = SVal k $ Left $ mkConstCV k (1 :: Integer)
 
--- | Division.
+-- | Division. For integers, this behaves like 'svQuot', except that this
+-- ensures @'svQuot' a 0 = a@.
 svDivide :: SVal -> SVal -> SVal
-svDivide = liftSym2 (mkSymOp Quot) [rationalCheck] (/) idiv (/) (/) (/) (/)
-   where idiv x 0 = x
-         idiv x y = x `div` y
+svDivide x y = liftSym2 (mkSymOp Quot) [rationalCheck] (/) idiv (/) (/) (/) (/) x y
+   where isInteger = kindOf x == KUnbounded
 
+         idiv a 0 = a
+         idiv a b | isInteger = a `divEucl` b
+                  | True      = a `quot` b
+
 -- | Divides predicate
 svDivides :: Integer -> SVal -> SVal
 svDivides n v
@@ -269,6 +320,12 @@
 -- non-negative remainder). For unsigned bitvectors, it is "bvudiv";
 -- and for signed bitvectors it is "bvsdiv", which rounds toward zero.
 -- Note that this variant does not respect the division/reminder by 0. That's handled at the SBV level.
+--
+-- Note that despite the similarities in their names, the semantics of 'svQuot'
+-- are different from those of the higher-level 'Data.SBV.sQuot' function when dealing
+-- with unbounded integers. 'svQuot' implements Euclidean division (which
+-- always has a non-negative remainder), whereas 'Data.SBV.sQuot' implements truncating
+-- division (which may have a negative remainder).
 svQuot :: SVal -> SVal -> SVal
 svQuot x y
   | not isInteger && isConcreteZero x = x
@@ -280,15 +337,22 @@
   where
     isInteger = kindOf x == KUnbounded
 
-    quot' a b | isInteger = div a (abs b) * signum b
-              | otherwise = quot a b
+    quot' a b | isInteger = divEucl a b
+              | True      = quot a b
 
 -- | Remainder: Overloaded operation whose meaning depends on the kind at which
 -- it is used: For unbounded integers, it corresponds to the SMT-Lib
--- "mod" operator (always non-negative). For unsigned bitvectors, it
--- is "bvurem"; and for signed bitvectors it is "bvsrem", which rounds
--- toward zero (sign of remainder matches that of @x@). Division by 0 is
--- defined s.t. @x/0 = 0@, which holds even when @x@ itself is @0@.
+-- "mod" operator ("Euclidean" modular division, which always has a
+-- non-negative remainder). For unsigned bitvectors, it is "bvurem"; and for
+-- signed bitvectors it is "bvsrem", which rounds toward zero (sign of
+-- remainder matches that of @x@). Division by 0 is defined s.t. @x/0 = 0@,
+-- which holds even when @x@ itself is @0@.
+--
+-- Note that despite the similarities in their names, the semantics of 'svRem'
+-- are different from those of the higher-level 'Data.SBV.sRem' function when dealing
+-- with unbounded integers. 'svRem' implements Euclidean modular division
+-- (which always has a non-negative remainder), whereas 'Data.SBV.sRem' implements
+-- truncating modular division (which may have a negative remainder).
 svRem :: SVal -> SVal -> SVal
 svRem x y
   | not isInteger && isConcreteZero x = x
@@ -300,10 +364,10 @@
   where
     isInteger = kindOf x == KUnbounded
 
-    rem' a b | isInteger = mod a (abs b)
-             | otherwise = rem a b
+    rem' a b | isInteger = modEucl a b
+             | True      = rem a b
 
--- | Combination of quot and rem
+-- | Combination of 'svQuot' and 'svRem'
 svQuotRem :: SVal -> SVal -> (SVal, SVal)
 svQuotRem x y = (x `svQuot` y, x `svRem` y)
 
@@ -492,29 +556,6 @@
       (CAlgReal     a, CAlgReal  b) | isExactRational a && isExactRational b -> Just $ a `compare` b
                                     | True                                   -> Nothing
 
-      -- Structural cases
-      (CMaybe       a, CMaybe    b) -> case (a, b) of
-                                         (Nothing, Nothing) -> Just EQ
-                                         (Nothing, Just{})  -> Just LT
-                                         (Just{},  Nothing) -> Just GT
-                                         (Just av, Just bv) -> case k of
-                                                                 KMaybe ke -> cCompare ke op av bv
-                                                                 _         -> error $ "Unexpected kind in cCompare for maybe's: " ++ show k
-
-      (CEither      a, CEither   b) -> let (kl, kr) = case k of
-                                                        KEither l r -> (l, r)
-                                                        _           -> error $ "Unexpected kind in cCompare for either's: " ++ show k
-                                       in case (a, b) of
-                                            (Left{},   Right{})  -> Just LT
-                                            (Right{},  Left{})   -> Just GT
-                                            (Left av,  Left  bv) -> cCompare kl op av bv
-                                            (Right av, Right bv) -> cCompare kr op av bv
-
-      -- Uninterpreted sorts use the index
-      (CUserSort    a, CUserSort b) -> case (a, b) of
-                                         ((Just i, _), (Just j, _)) -> Just $ i `compare` j
-                                         _                          -> error $ "cCompare: Impossible happened while trying to compare: " ++ show (op, a, b)
-
       -- Lists and tuples use lexicographic ordering
       (CList        a, CList b) -> case k of
                                      KList ke -> lexCmp (map (ke,) a) (map (ke,) b)
@@ -532,9 +573,7 @@
                            -> case svSetEqual ke a b of
                                  Nothing    -> Nothing  -- We don't know
                                  Just True  -> Just EQ  -- They're equal
-                                 Just False -> Just $ if op `elem` [Equal True, Equal False]
-                                                         then GT  -- Pick GT, So equality    test will fail
-                                                         else EQ  -- Pick EQ, So in-equality test will fail
+                                 Just False -> Just GT  -- Pick GT; so equality test will fail, inequality will pass
                            | True
                            -> error $ "cCompare: Received unexpected set comparison: " ++ show (op, k)
 
@@ -543,16 +582,48 @@
                            -> case svArrEqual k1 k2 a b of
                                 Nothing    -> Nothing  -- We don't know
                                 Just True  -> Just EQ  -- They're equal
-                                Just False -> Just $ if op `elem` [Equal True, Equal False]
-                                                        then GT  -- Pick GT, So equality    test will fail
-                                                        else EQ  -- Pick EQ, So in-equality test will fail
+                                Just False -> Just GT  -- Pick GT; so equality test will fail, inequality will pass
                            | True
                            -> error $ "cCompare: Received unexpected array comparison: " ++ show (op, k)
 
+
+      -- ADTs. Only equal/inequal on full ADTs. Compares on enumerations.
+      (CADT (s, fks), CADT (s', fks'))
+         -> case k of
+              -- Enumerations. We do a straight comparison on the constructor index
+              KADT _ _ cstrs | all (null . snd) cstrs
+                             -> let cnms = map fst cstrs
+                                in case (s `elemIndex` cnms, s' `elemIndex` cnms) of
+                                     (Just i, Just j) -> Just (i `compare` j)
+                                     r                -> error $ "cCompare: Unable to locate indexes for CADT: " ++ show (k, s, s', r)
+
+              -- Arbitrary ADTs. Only allow equality/inequality
+              _ | op `notElem` [Equal True, Equal False, NotEqual]
+                -> error $ "cCompare: Received unexpected ADT comparison: " ++ show (op, k)
+
+                -- Different constructor
+                | s /= s'
+                -> Just GT -- Pick GT; so equality test will fail, inequality will pass
+
+                -- Same constructor
+                | map fst fks /= map fst fks'
+                -> error $ "cCompare: Mismatching ADT field kinds in comparison: " ++ show (op, k, map fst fks, map fst fks')
+                | True
+                -> let fmatch    = zipWith (\(fk, v1) (_, v2) -> cCompare fk op v1 v2) fks fks'
+                       undecided = any isNothing fmatch   -- Field comparison undecided
+                       allEq     = all (== Just EQ) fmatch -- All fields Equal
+                   in if undecided
+                      then Nothing
+                      else if allEq
+                           then Just EQ
+                           else -- all compared fine, but not all equal
+                                Just GT -- Pick GT; so equality test will fail, inequality will pass
+
+      -- Shouldn't happen:
       _ -> error $ unlines [ ""
                            , "*** Data.SBV.cCompare: Bug in SBV: Unhandled rank in comparison fallthru"
                            , "***"
-                           , "***   Ranks Received: " ++ show (cvRank x, cvRank y)
+                           , "***   Ranks Received: " ++ show (cvRank x, cvRank y, op)
                            , "***"
                            , "*** Please report this as a bug!"
                            ]
@@ -594,7 +665,7 @@
                defsMatch = def1 == def2
 
                -- Check if keys cover everything. Clearly, we can't do this for all kinds; but only finite ones
-               -- For the time being, we're retricting ourselves to bool only. Might want to extend this later.
+               -- For the time being, we're restricting ourselves to bool only. Might want to extend this later.
                complete  = case k1 of
                              KBool -> let bools       = map cvVal [falseCV, trueCV]
                                           covered asc = all (`elem` map fst asc) bools
@@ -923,8 +994,8 @@
 
                              -- merge, but simplify for certain boolean cases:
                              case () of
-                               () | swa == swb                      -> return swa                                     -- if t then a      else a     ==> a
-                               () | swa == trueSV && swb == falseSV -> return swt                                     -- if t then true   else false ==> t
+                               () | swa == swb                      -> pure swa                                       -- if t then a      else a     ==> a
+                               () | swa == trueSV && swb == falseSV -> pure swt                                       -- if t then true   else false ==> t
                                () | swa == falseSV && swb == trueSV -> newExpr st k (SBVApp Not [swt])                -- if t then false  else true  ==> not t
                                () | swa == trueSV                   -> newExpr st k (SBVApp Or  [swt, swb])           -- if t then true   else b     ==> t OR b
                                () | swa == falseSV                  -> do swt' <- newExpr st KBool (SBVApp Not [swt])
@@ -960,7 +1031,7 @@
     r st = do sws <- mapM (svToSV st) xs
               swe <- svToSV st err
               if all (== swe) sws  -- off-chance that all elts are the same
-                 then return swe
+                 then pure swe
                  else do idx <- getTableIndex st kInd kElt sws
                          swi <- svToSV st ind
                          let len = length xs
@@ -1002,6 +1073,260 @@
         y st   = do xsw <- svToSV st x
                     newExpr st kTo (SBVApp (KindCast kFrom kTo) [xsw])
 
+-- | Create a NaN floating-point value of the given kind.
+svFPNaN :: Kind -> SVal
+svFPNaN k = SVal k $ Left $ fpConstCV k nan nan fpNaN
+  where
+    nan :: forall a. Floating a => a
+    nan = 0/0
+
+-- | Create an infinite floating-point value of the given kind. If the 'Bool'
+-- argument is 'True', then use negative infinity; otherwise, use positive
+-- infinity.
+svFPInf :: Kind -> Bool -> SVal
+svFPInf k neg = SVal k $ Left $ fpConstCV k signedInfinity signedInfinity (fpInf neg)
+  where
+    infinity :: forall a. Floating a => a
+    infinity = 1/0
+
+    signedInfinity :: forall a. Floating a => a
+    signedInfinity = if neg then -infinity else infinity
+
+-- | Create a signed zero value of the given kind. If the 'Bool' argument is
+-- 'True', then use negative zero; otherwise, use positive zero.
+svFPZero :: Kind -> Bool -> SVal
+svFPZero k neg = SVal k $ Left $ fpConstCV k signedZero signedZero (fpZero neg)
+  where
+    signedZero :: forall a. Num a => a
+    signedZero = if neg then -0 else 0
+
+-- | Create a float-point value of the given kind from an 'Integer' literal.
+svFPFromIntegerLit :: Kind -> Integer -> SVal
+svFPFromIntegerLit k r = SVal k $ Left $ fpConstCV k (fromInteger r) (fromInteger r) (\eb sb -> fpFromInteger eb sb r)
+
+-- | Create a float-point value of the given kind from a 'Rational' literal.
+svFPFromRationalLit :: Kind -> Rational -> SVal
+svFPFromRationalLit k r = SVal k $ Left $ fpConstCV k (fromRational r) (fromRational r) (\eb sb -> fpFromRational eb sb r)
+
+-- | Is the given floating-point value a zero value?
+svFPIsZero :: SVal -> SVal
+svFPIsZero = liftFPPred (mkSymOp1 (IEEEFP FP_IsZero)) isZero isZero fpIsZero
+  where
+    isZero :: forall a. RealFloat a => a -> Bool
+    isZero x = x == 0
+
+-- | Is the given floating-point value infinite?
+svFPIsInfinite :: SVal -> SVal
+svFPIsInfinite = liftFPPred (mkSymOp1 (IEEEFP FP_IsInfinite)) isInfinite isInfinite fpIsInf
+
+-- | Is the given floating-point value negative?
+svFPIsNegative :: SVal -> SVal
+svFPIsNegative = liftFPPred (mkSymOp1 (IEEEFP FP_IsNegative)) isNegative isNegative fpIsNeg
+  where
+    isNegative :: forall a. RealFloat a => a -> Bool
+    isNegative x = x < 0 || isNegativeZero x
+
+-- | Is the given floating-point value positive?
+svFPIsPositive :: SVal -> SVal
+svFPIsPositive = liftFPPred (mkSymOp1 (IEEEFP FP_IsPositive)) isPositive isPositive fpIsPos
+  where
+    isPositive :: forall a. RealFloat a => a -> Bool
+    isPositive x = x >= 0 && not (isNegativeZero x)
+
+-- | Is the given floating-point value a NaN value?
+svFPIsNaN :: SVal -> SVal
+svFPIsNaN = liftFPPred (mkSymOp1 (IEEEFP FP_IsNaN)) isNaN isNaN fpIsNaN
+
+-- | Is the given floating-point value \"normal\"? That is, is the value not
+-- zero, infinite, NaN, or subnormal?
+svFPIsNormal :: SVal -> SVal
+svFPIsNormal = liftFPPred (mkSymOp1 (IEEEFP FP_IsNormal)) fpIsNormalizedH fpIsNormalizedH fpIsNormal
+
+-- | Is the given floating-point value subnormal (i.e., denormalized)?
+svFPIsSubnormal :: SVal -> SVal
+svFPIsSubnormal = liftFPPred (mkSymOp1 (IEEEFP FP_IsSubnormal)) isDenormalized isDenormalized fpIsSubnormal
+
+-- | Floating-point addition.
+svFPAdd :: SVal -- ^ Rounding mode
+        -> SVal -> SVal -> SVal
+svFPAdd = liftFPSymRM2 "add" (mkSymOp3 (IEEEFP FP_Add)) (+) (+) fpAdd
+
+-- | Floating-point subtraction.
+svFPSub :: SVal -- ^ Rounding mode
+        -> SVal -> SVal -> SVal
+svFPSub = liftFPSymRM2 "sub" (mkSymOp3 (IEEEFP FP_Sub)) (-) (-) fpSub
+
+-- | Floating-point multiplication.
+svFPMul :: SVal -- ^ Rounding mode
+        -> SVal -> SVal -> SVal
+svFPMul = liftFPSymRM2 "mul" (mkSymOp3 (IEEEFP FP_Mul)) (*) (*) fpMul
+
+-- | Floating-point division.
+svFPDiv :: SVal -- ^ Rounding mode
+        -> SVal -> SVal -> SVal
+svFPDiv = liftFPSymRM2 "div" (mkSymOp3 (IEEEFP FP_Div)) (/) (/) fpDiv
+
+-- | Floating-point remainder.
+svFPRem :: SVal -> SVal -> SVal
+svFPRem = liftFPSym2 "rem" (mkSymOp (IEEEFP FP_Rem)) fpRemH fpRemH (fpRem RoundNearestTiesToEven)
+
+-- | Floating-point minimum.
+svFPMin :: SVal -> SVal -> SVal
+svFPMin = liftFPSym2 "min" (mkSymOp (IEEEFP FP_Min)) fpMinH fpMinH fpMin
+
+-- | Floating-point maximum.
+svFPMax :: SVal -> SVal -> SVal
+svFPMax = liftFPSym2 "max" (mkSymOp (IEEEFP FP_Max)) fpMaxH fpMaxH fpMax
+
+-- | Floating-point fused-multiply-add (FMA).
+
+-- Note that this operation is defined somewhat unusually because Haskell lacks
+-- a native FMA operation to use for concrete evaluation of 'Float's and
+-- 'Double's. See https://github.com/LeventErkok/sbv/issues/777 for more
+-- discussion. As such, concrete FMA evaluation is only supported for t'FP'
+-- values.
+svFPFMA :: SVal -- ^ Rounding mode
+        -> SVal -> SVal -> SVal -> SVal
+svFPFMA (svAsRoundingMode -> Just rm)
+        (SVal k (Left (cvVal -> CFP a)))
+        (SVal _ (Left (cvVal -> CFP b)))
+        (SVal _ (Left (cvVal -> CFP c))) =
+  SVal k $ Left $ CV k $ CFP $ fpFMA rm a b c
+svFPFMA rm a@(SVal k _) b c = SVal k $ Right $ cache ca
+   where ca st = do svrm <- svToSV st rm
+                    sva <- svToSV st a
+                    svb <- svToSV st b
+                    svc <- svToSV st c
+                    newExpr st k (SBVApp (IEEEFP FP_FMA) [svrm, sva, svb, svc])
+
+-- | Floating-point absolute value.
+svFPAbs :: SVal -> SVal
+svFPAbs = liftFPSym1 "abs" (mkSymOp1 (IEEEFP FP_Abs)) abs abs fpAbs
+
+-- | Floating-point negation.
+svFPNeg :: SVal -> SVal
+svFPNeg = liftFPSym1 "negate" (mkSymOp1 (IEEEFP FP_Neg)) negate negate fpNeg
+
+-- | Round the given floating-point value to the nearest integer (represented
+-- as a float with a zero decimal component) using the given rounding mode.
+svFPRoundToIntegral :: SVal -- ^ Rounding mode
+                    -> SVal -> SVal
+svFPRoundToIntegral = liftFPSymRM1 "roundToIntegral" (mkSymOp (IEEEFP FP_RoundToIntegral)) fpRoundToIntegralH fpRoundToIntegralH fpRoundInt
+
+-- | Floating-point square root.
+svFPSqrt :: SVal -- ^ Rounding mode
+         -> SVal -> SVal
+svFPSqrt = liftFPSymRM1 "sqrt" (mkSymOp (IEEEFP FP_Sqrt)) sqrt sqrt fpSqrt
+
+-- | Cast an t'FP' value to a t'CV' of the given floating-point 'Kind' using the
+-- given 'RoundingMode'. This will error if given a non-floating-point 'Kind'.
+cvCastFromFP :: Kind -> RoundingMode -> FP -> CV
+cvCastFromFP kindTo rm fp =
+  fpConstCV
+    kindTo
+    (fpToFloat rm (fpRoundFloat 8 24 rm fp))
+    (fpToDouble rm (fpRoundFloat 11 53 rm fp))
+    (\eb sb -> fpRoundFloat eb sb rm fp)
+
+-- | Cast a 'Rational' value to a t'CV' of the given floating-point 'Kind'. This
+-- will error if given a non-floating-point 'Kind'.
+cvCastFromRational :: Kind -> Rational -> CV
+cvCastFromRational kindTo r =
+  fpConstCV
+    kindTo
+    (fromRational r)
+    (fromRational r)
+    (\eb sb -> fpFromRational eb sb r)
+
+-- | Convert a 'CVal' to an t'FP' value of the appropriate size. This will error
+-- if the 'CVal' is not a floating-point value.
+cvalToFP :: CVal -> FP
+cvalToFP (CFloat f) = fpFromFloat 8 24 f
+cvalToFP (CDouble d) = fpFromDouble 11 53 d
+cvalToFP (CFP fp) = fp
+cvalToFP _ = error "cvalToFP: non-float value"
+
+-- | Convert a value to a floating-point value. The type being converted from
+-- must be one of 'KFloat', 'KDouble', 'KFP', 'KBounded', 'KUnbounded', or
+-- 'KReal'.
+--
+-- Note that converting from a 'KBounded' value returns a float with the same
+-- numeric value as the input bitvector. For a conversion that returns a float
+-- with the same bit pattern as the input bitvector, see 'svSWord32AsFloat',
+-- 'svSWord64AsDouble', and 'svSWordAsFloatingPoint'.
+svCastToFP :: Kind -- ^ The kind to cast to. Must be a floating-point kind.
+           -> SVal -- ^ Rounding mode
+           -> SVal -- ^ The value to be casted.
+           -> SVal
+svCastToFP kindTo (svAsRoundingMode -> Just rm) x@(SVal kindFrom (Left (CV _ x')))
+  | kindFrom == kindTo
+  = x
+
+  | KFloat {} <- kindFrom
+  = fpCastFromFloat
+  | KDouble {} <- kindFrom
+  = fpCastFromFloat
+  | KFP {} <- kindFrom
+  = fpCastFromFloat
+
+  | RoundNearestTiesToEven <- rm
+  , KBounded {} <- kindFrom
+  , CInteger w <- x'
+  = fpCastFromIntegral w
+  | RoundNearestTiesToEven <- rm
+  , KUnbounded {} <- kindFrom
+  , CInteger i <- x'
+  = fpCastFromIntegral i
+
+  | RoundNearestTiesToEven <- rm
+  , CAlgReal r <- x'
+  , isExactRational r
+  = SVal kindTo $ Left $ cvCastFromRational kindTo $ toRational r
+  where fpCastFromFloat :: SVal
+        fpCastFromFloat = SVal kindTo $ Left $ cvCastFromFP kindTo rm $ cvalToFP x'
+
+        fpCastFromIntegral :: forall a. Integral a => a -> SVal
+        fpCastFromIntegral =
+          SVal kindTo . Left . cvCastFromRational kindTo . fromIntegral
+svCastToFP kindTo rm x@(SVal kindFrom _)
+  = SVal kindTo $ Right $ cache y
+  where y st = do svrm <- svToSV st rm
+                  svx <- svToSV st x
+                  mkSymOp (IEEEFP (FP_Cast kindFrom kindTo svrm)) st kindTo svrm svx
+
+-- | Convert a floating-point value to a value of a different type. The type to
+-- convert to must be one of 'KFloat', 'KDouble', 'KFP', 'KBounded',
+-- 'KUnbounded', or 'KReal'.
+--
+-- Note that converting to 'KBounded' returns a bitvector with the same numeric
+-- value as the input float (appropriately rounded). For a lossless conversion
+-- that returns a bitvector with the same bit pattern as the input float, see
+-- 'svFloatAsSWord32', 'svDoubleAsSWord64', and 'svFloatingPointAsSWord'.
+svCastFromFP :: Kind -- ^ The kind to cast to.
+             -> SVal -- ^ Rounding mode
+             -> SVal -- ^ The value to be casted. Must be a floating-point value.
+             -> SVal
+svCastFromFP kindTo (svAsRoundingMode -> Just rm) x@(SVal kindFrom (Left (CV _ x')))
+  | kindFrom == kindTo
+  = x
+
+  | KFloat {} <- kindTo
+  = fpCastToFloat
+  | KDouble {} <- kindTo
+  = fpCastToFloat
+  | KFP {} <- kindTo
+  = fpCastToFloat
+  -- No constant-folding for KBounded, KUnbounded, or KReal, as each of these
+  -- conversions are partial. Rather than painstakingly check which inputs are
+  -- valid, we simply defer to the underlying SMT-LIB operations.
+  where fpCastToFloat :: SVal
+        fpCastToFloat = SVal kindTo $ Left $ cvCastFromFP kindTo rm $ cvalToFP x'
+svCastFromFP kindTo rm x@(SVal kindFrom _)
+  = SVal kindTo $ Right $ cache y
+  where y st = do svrm <- svToSV st rm
+                  svx <- svToSV st x
+                  mkSymOp (IEEEFP (FP_Cast kindFrom kindTo svrm)) st kindTo svrm svx
+
 --------------------------------------------------------------------------------
 -- Derived operations
 
@@ -1132,7 +1457,7 @@
                                        | True   = Shr
 
                                 adjustedShift <- if kx == ki
-                                                 then return sw2
+                                                 then pure sw2
                                                  else newExpr st kx (SBVApp (KindCast ki kx) [sw2])
 
                                 newExpr st kx (SBVApp op [sw1, adjustedShift])
@@ -1358,20 +1683,119 @@
 liftSym2 _   okCV opCR opCI opCF opCD opFP opRA (SVal k (Left a)) (SVal _ (Left b)) | and [f a b | f <- okCV] = SVal k . Left  $! mapCV2 opCR opCI opCF opCD opFP opRA a b
 liftSym2 opS _    _    _    _    _    _  _      a@(SVal k _)      b                                           = SVal k $ Right $  liftSV2 opS k a b
 
+-- | Lift a unary floating-point operation that can work over 'Float',
+-- 'Double', and t'FP' values.
+liftFPSym1 :: String
+           -> (State -> Kind -> SV -> IO SV)
+           -> (Float -> Float)
+           -> (Double -> Double)
+           -> (FP -> FP)
+           -> SVal -> SVal
+liftFPSym1 o _ opCF opCD opFP (SVal k (Left a))
+  = SVal k . Left  $! mapCV (noRealUnary o) (noIntUnary o) opCF opCD opFP (noRatUnary o) a
+liftFPSym1 _ opS _ _ _ a@(SVal k _) = SVal k $ Right $ cache c
+   where c st = do sva <- svToSV st a
+                   opS st k sva
+
+-- | Like 'liftFPSym1', but with an explicit rounding mode. Note that concrete
+-- evaluation of 'Float's or 'Double's is only supported when the
+-- 'RoundNearestTiesToEven' rounding mode is used (see the Haddocks for
+-- 'floatDoubleRneCheck').
+liftFPSymRM1 :: String
+             -> (State -> Kind -> SV -> SV -> IO SV)
+             -> (Float -> Float)
+             -> (Double -> Double)
+             -> (RoundingMode -> FP -> FP)
+             -> SVal -> SVal -> SVal
+liftFPSymRM1 o _ opCF opCD opFP rm (SVal k (Left a))
+  | Just rm'@RoundNearestTiesToEven <- svAsRoundingMode rm
+  , floatDoubleRneCheck rm' a
+  = SVal k . Left $! mapCV (noRealUnary o) (noIntUnary o) opCF opCD (opFP rm') (noRatUnary o) a
+liftFPSymRM1 _ opS _ _ _ rm a@(SVal k _) = SVal k $ Right $ cache c
+   where c st = do svrm <- svToSV st rm
+                   sva <- svToSV st a
+                   opS st k svrm sva
+
+-- | Lift a binary floating-point operation that can work over 'Float',
+-- 'Double', and t'FP' values.
+liftFPSym2 :: String
+           -> (State -> Kind -> SV -> SV -> IO SV)
+           -> (Float -> Float -> Float)
+           -> (Double -> Double -> Double)
+           -> (FP -> FP -> FP)
+           -> SVal -> SVal -> SVal
+liftFPSym2 o _ opCF opCD opFP (SVal k (Left a)) (SVal _ (Left b))
+  = SVal k . Left $! mapCV2 (noReal o) (noInt o) opCF opCD opFP (noRat o) a b
+liftFPSym2 _ opS _ _ _ a@(SVal k _) b = SVal k $ Right $ cache c
+   where c st = do sva <- svToSV st a
+                   svb <- svToSV st b
+                   opS st k sva svb
+
+-- | Like 'liftFPSym2', but with an explicit rounding mode. Note that concrete
+-- evaluation of 'Float's or 'Double's is only supported when the
+-- 'RoundNearestTiesToEven' rounding mode is used (see the Haddocks for
+-- 'floatDoubleRneCheck').
+liftFPSymRM2 :: String
+             -> (State -> Kind -> SV -> SV -> SV -> IO SV)
+             -> (Float -> Float -> Float)
+             -> (Double -> Double -> Double)
+             -> (RoundingMode -> FP -> FP -> FP)
+             -> SVal -> SVal -> SVal -> SVal
+liftFPSymRM2 o _ opCF opCD opFP rm (SVal k (Left a)) (SVal _ (Left b))
+  | Just rm'@RoundNearestTiesToEven <- svAsRoundingMode rm
+  , floatDoubleRneCheck rm' a
+  = SVal k . Left $! mapCV2 (noReal o) (noInt o) opCF opCD (opFP rm') (noRat o) a b
+liftFPSymRM2 _ opS _ _ _ rm a@(SVal k _) b = SVal k $ Right $ cache c
+   where c st = do svrm <- svToSV st rm
+                   sva <- svToSV st a
+                   svb <- svToSV st b
+                   opS st k svrm sva svb
+
+-- | Lift a unary floating-point predicate that can work over 'Float',
+-- 'Double', and t'FP' values.
+liftFPPred :: (State -> Kind -> SV -> IO SV)
+           -> (Float -> Bool)
+           -> (Double -> Bool)
+           -> (FP -> Bool)
+           -> SVal -> SVal
+liftFPPred _ opCF opCD opFP (SVal k (Left a)) =
+  case cvVal a of
+    CFloat f -> svBool $ opCF f
+    CDouble d -> svBool $ opCD d
+    CFP fp -> svBool $ opFP fp
+
+    CAlgReal {} -> unexpected
+    CInteger {} -> unexpected
+    CRational {} -> unexpected
+    CChar {} -> unexpected
+    CString {} -> unexpected
+    CList {} -> unexpected
+    CSet {} -> unexpected
+    CADT {} -> unexpected
+    CTuple {} -> unexpected
+    CArray {} -> unexpected
+  where unexpected = error $ "Data.SBV.liftFPPred: Unexpected kind: " ++ show k
+liftFPPred opS _ _ _ a = SVal KBool $ Right $ cache c
+   where c st = do sva <- svToSV st a
+                   opS st KBool sva
+
 -- | Create a symbolic two argument operation; with shortcut optimizations
 mkSymOpSC :: (SV -> SV -> Maybe SV) -> Op -> State -> Kind -> SV -> SV -> IO SV
-mkSymOpSC shortCut op st k a b = maybe (newExpr st k (SBVApp op [a, b])) return (shortCut a b)
+mkSymOpSC shortCut op st k a b = maybe (newExpr st k (SBVApp op [a, b])) pure (shortCut a b)
 
 -- | Create a symbolic two argument operation; no shortcut optimizations
 mkSymOp :: Op -> State -> Kind -> SV -> SV -> IO SV
 mkSymOp = mkSymOpSC (const (const Nothing))
 
 mkSymOp1SC :: (SV -> Maybe SV) -> Op -> State -> Kind -> SV -> IO SV
-mkSymOp1SC shortCut op st k a = maybe (newExpr st k (SBVApp op [a])) return (shortCut a)
+mkSymOp1SC shortCut op st k a = maybe (newExpr st k (SBVApp op [a])) pure (shortCut a)
 
 mkSymOp1 :: Op -> State -> Kind -> SV -> IO SV
 mkSymOp1 = mkSymOp1SC (const Nothing)
 
+mkSymOp3 :: Op -> State -> Kind -> SV -> SV -> SV -> IO SV
+mkSymOp3 op st k a b c = newExpr st k (SBVApp op [a, b, c])
+
 -- | Predicate to check if a value is concrete
 isConcrete :: SVal -> Bool
 isConcrete (SVal _ Left{}) = True
@@ -1434,6 +1858,26 @@
 rationalSBVCheck (SVal KReal (Left a)) (SVal KReal (Left b)) = rationalCheck a b
 rationalSBVCheck _                     _                     = True
 
+-- | Predicate to check if a concrete 'Float' or 'Double' value uses the
+-- 'RoundNearestTiesToEven' rounding mode. This is necessary because we assume
+-- this rounding mode when concretely evaluating 'Float's and 'Double's, so
+-- concrete evaluation is not supported for other rounding modes.
+--
+-- Note that this check skips concrete t'FP' values, which support concrete
+-- evaluation with any rounding mode.
+floatDoubleRneCheck :: RoundingMode -> CV -> Bool
+floatDoubleRneCheck rm cv =
+  case cvKind cv of
+    KFloat -> rmIsRne
+    KDouble -> rmIsRne
+    _ -> True
+  where
+    rmIsRne | RoundNearestTiesToEven <- rm = True
+            | True                         = False
+
+noInt :: String -> Integer -> Integer -> a
+noInt o a b = error $ "SBV.Integer." ++ o ++ ": Unexpected arguments: " ++ show (a, b)
+
 noReal :: String -> AlgReal -> AlgReal -> a
 noReal o a b = error $ "SBV.AlgReal." ++ o ++ ": Unexpected arguments: " ++ show (a, b)
 
@@ -1449,6 +1893,9 @@
 noRat:: String -> Rational -> Rational -> a
 noRat o a b = error $ "SBV.Rational." ++ o ++ ": Unexpected arguments: " ++ show (a, b)
 
+noIntUnary :: String -> Integer -> a
+noIntUnary o a = error $ "SBV.Integer." ++ o ++ ": Unexpected argument: " ++ show a
+
 noRealUnary :: String -> AlgReal -> a
 noRealUnary o a = error $ "SBV.AlgReal." ++ o ++ ": Unexpected argument: " ++ show a
 
@@ -1471,10 +1918,6 @@
    = x `svLessThan` y
    | KTuple{} <- kx
    = tupleLT x y
-   | KMaybe{}  <- kx
-   = maybeLT x y
-   | KEither{} <- kx
-   = eitherLT x y
    | True
    = x `svLessThan` y
    where kx = kindOf x
@@ -1503,52 +1946,58 @@
 
                     svToSV st $ walk $ zipWith chkElt [1..] ks
 
--- | Structural less-than for maybes
-maybeLT :: SVal -> SVal -> SVal
-maybeLT x y = sMaybeCase (       sMaybeCase svFalse (const svTrue)    y)
-                         (\jx -> sMaybeCase svFalse (jx `svStructuralLessThan`) y)
-                         x
-  where ka = case kindOf x of
-               KMaybe k' -> k'
-               k         -> error $ "Data.SBV: Impossible happened, maybeLT called with: " ++ show (k, x, y)
-
-        sMaybeCase brNothing brJust s = SVal KBool $ Right $ cache res
-           where res st = do sv <- svToSV st s
-
-                             let justVal = SVal ka $ Right $ cache $ \_ -> newExpr st ka $ SBVApp MaybeAccess [sv]
-                                 justRes = brJust justVal
-
-                             br1 <- svToSV st brNothing
-                             br2 <- svToSV st justRes
-
-                             -- Do we have a value?
-                             noVal <- newExpr st KBool $ SBVApp (MaybeIs ka False) [sv]
-                             newExpr st KBool $ SBVApp Ite [noVal, br1, br2]
-
--- | Structural less-than for either
-eitherLT :: SVal -> SVal -> SVal
-eitherLT x y = sEitherCase (\lx -> sEitherCase (lx `svStructuralLessThan`) (const svTrue)              y)
-                           (\rx -> sEitherCase (const svFalse)             (rx `svStructuralLessThan`) y)
-                           x
-  where (ka, kb) = case kindOf x of
-                     KEither k1 k2 -> (k1, k2)
-                     k             -> error $ "Data.SBV: Impossible happened, eitherLT called with: " ++ show (k, x, y)
-
-        sEitherCase brA brB sab = SVal KBool $ Right $ cache res
-          where res st = do abv <- svToSV st sab
-
-                            let leftVal  = SVal ka $ Right $ cache $ \_ -> newExpr st ka $ SBVApp (EitherAccess False) [abv]
-                                rightVal = SVal kb $ Right $ cache $ \_ -> newExpr st kb $ SBVApp (EitherAccess True)  [abv]
-
-                                leftRes  = brA leftVal
-                                rightRes = brB rightVal
+-- | Convert an 'Data.SBV.SWord32' to an 'Data.SBV.SFloat', preserving the
+-- bit-correspondence. Note that since the representation for @NaN@s are not
+-- unique, there are multiple word values for which this function will return a
+-- single, distinguished @NaN@ value.
+svSWord32AsFloat :: SVal -> SVal
+svSWord32AsFloat w@(SVal kindFrom x)
+  | KBounded _ 32 <- kindFrom
+  = case x of
+      Left (CV _ (CInteger w'))
+        -> SVal kindTo $ Left $ CV kindTo $ CFloat $ wordToFloat $ fromInteger w'
+      _ -> SVal kindTo $ Right $ cache y
+  | True
+  = error $ "svSWord32AsFloat: not a 32-bit word type: " ++ show kindFrom
+  where kindTo = KFloat
+        y st = do svw <- svToSV st w
+                  mkSymOp1 (IEEEFP (FP_Reinterpret kindFrom kindTo)) st kindTo svw
 
-                            br1 <- svToSV st leftRes
-                            br2 <- svToSV st rightRes
+-- | Convert an 'Data.SBV.SWord64' to an 'Data.SBV.SDouble', preserving the
+-- bit-correspondence. Note that since the representation for @NaN@s are not
+-- unique, there are multiple word values for which this function will return a
+-- single, distinguished @NaN@ value.
+svSWord64AsDouble :: SVal -> SVal
+svSWord64AsDouble w@(SVal kindFrom x)
+  | KBounded _ 64 <- kindFrom
+  = case x of
+      Left (CV _ (CInteger w'))
+        -> SVal kindTo $ Left $ CV kindTo $ CDouble $ wordToDouble $ fromInteger w'
+      _ -> SVal kindTo $ Right $ cache y
+  | True
+  = error $ "svSWord64AsDouble: not a 64-bit word type: " ++ show kindFrom
+  where kindTo = KDouble
+        y st = do svw <- svToSV st w
+                  mkSymOp1 (IEEEFP (FP_Reinterpret kindFrom kindTo)) st kindTo svw
 
-                            --  Which branch are we in? Return the appropriate value:
-                            onLeft <- newExpr st KBool $ SBVApp (EitherIs ka kb False) [abv]
-                            newExpr st KBool $ SBVApp Ite [onLeft, br1, br2]
+-- | Convert a word to a float (using the given exponent and significand sizes)
+-- containing the word's corresponding bit pattern. Note that since the
+-- representation for @NaN@s are not unique, there are multiple word values for
+-- which this function will return a single, distinguished @NaN@ value.
+svSWordAsFloatingPoint :: Int -- ^ Exponent size
+                       -> Int -- ^ Significand size
+                       -> SVal -> SVal
+svSWordAsFloatingPoint eb sb w@(SVal kindFrom x)
+  | KBounded _ _ <- kindFrom
+  = case x of
+      Left (CV _ (CInteger w'))
+        -> SVal kindTo $ Left $ CV kindTo $ CFP $ fpFromBits eb sb $ fromInteger w'
+      _ -> SVal kindTo $ Right $ cache y
+  | True
+  = error $ "svSWordAsFloatingPoint: non-word type: " ++ show kindFrom
+  where kindTo = KFP eb sb
+        y st = do svw <- svToSV st w
+                  mkSymOp1 (IEEEFP (FP_Reinterpret kindFrom kindTo)) st kindTo svw
 
 -- | Convert an 'Data.SBV.SFloat' to an 'Data.SBV.SWord32', preserving the bit-correspondence. Note that since the
 -- representation for @NaN@s are not unique, this function will return a symbolic value when given a
@@ -1572,8 +2021,8 @@
                              newExpr st w32 (SBVApp (IEEEFP (FP_Reinterpret KFloat w32)) [f])
                      else do n   <- newInternalVariable st w32
                              ysw <- newExpr st KFloat (SBVApp (IEEEFP (FP_Reinterpret w32 KFloat)) [n])
-                             internalConstraint st False [] $ fVal `svStrongEqual` SVal KFloat (Right (cache (\_ -> return ysw)))
-                             return n
+                             internalConstraint st False [] $ fVal `svStrongEqual` SVal KFloat (Right (cache (\_ -> pure ysw)))
+                             pure n
 svFloatAsSWord32 (SVal k _) = error $ "svFloatAsSWord32: non-float type: " ++ show k
 
 -- | Convert an 'Data.SBV.SDouble' to an 'Data.SBV.SWord64', preserving the bit-correspondence. Note that since the
@@ -1598,8 +2047,8 @@
                              newExpr st w64 (SBVApp (IEEEFP (FP_Reinterpret KDouble w64)) [f])
                      else do n   <- newInternalVariable st w64
                              ysw <- newExpr st KDouble (SBVApp (IEEEFP (FP_Reinterpret w64 KDouble)) [n])
-                             internalConstraint st False [] $ fVal `svStrongEqual` SVal KDouble (Right (cache (\_ -> return ysw)))
-                             return n
+                             internalConstraint st False [] $ fVal `svStrongEqual` SVal KDouble (Right (cache (\_ -> pure ysw)))
+                             pure n
 svDoubleAsSWord64 (SVal k _) = error $ "svDoubleAsSWord64: non-float type: " ++ show k
 
 -- | Convert a float to the word containing the corresponding bit pattern
@@ -1617,8 +2066,8 @@
                              newExpr st kTo (SBVApp (IEEEFP (FP_Reinterpret kFrom kTo)) [f])
                      else do n   <- newInternalVariable st kTo
                              ysw <- newExpr st kFrom (SBVApp (IEEEFP (FP_Reinterpret kTo kFrom)) [n])
-                             internalConstraint st False [] $ fVal `svStrongEqual` SVal kFrom (Right (cache (\_ -> return ysw)))
-                             return n
+                             internalConstraint st False [] $ fVal `svStrongEqual` SVal kFrom (Right (cache (\_ -> pure ysw)))
+                             pure n
 svFloatingPointAsSWord (SVal k _) = error $ "svFloatingPointAsSWord: non-float type: " ++ show k
 
 {- HLint ignore svIte     "Eta reduce"         -}
diff --git a/Data/SBV/Core/Sized.hs b/Data/SBV/Core/Sized.hs
--- a/Data/SBV/Core/Sized.hs
+++ b/Data/SBV/Core/Sized.hs
@@ -11,7 +11,6 @@
 -----------------------------------------------------------------------------
 
 {-# LANGUAGE DataKinds            #-}
-{-# LANGUAGE FlexibleInstances    #-}
 {-# LANGUAGE ScopedTypeVariables  #-}
 {-# LANGUAGE TypeApplications     #-}
 {-# LANGUAGE TypeFamilies         #-}
@@ -218,7 +217,7 @@
 
 -- | Quickcheck instance for WordN
 instance KnownNat n => Arbitrary (WordN n) where
-  arbitrary = (WordN . norm . abs) `fmap` arbitrary
+  arbitrary = WordN . norm . abs <$> arbitrary
     where sz = intOfProxy (Proxy @n)
 
           norm v | sz == 0 = 0
@@ -226,7 +225,7 @@
 
 -- | Quickcheck instance for IntN
 instance KnownNat n => Arbitrary (IntN n) where
-  arbitrary = (IntN . norm) `fmap` arbitrary
+  arbitrary = IntN . norm <$> arbitrary
     where sz = intOfProxy (Proxy @n)
 
           norm v | sz == 0 = 0
diff --git a/Data/SBV/Core/SizedFloats.hs b/Data/SBV/Core/SizedFloats.hs
--- a/Data/SBV/Core/SizedFloats.hs
+++ b/Data/SBV/Core/SizedFloats.hs
@@ -9,9 +9,8 @@
 -- Type-level sized floats.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DeriveDataTypeable   #-}
 {-# LANGUAGE DataKinds            #-}
-{-# LANGUAGE FlexibleInstances    #-}
+{-# LANGUAGE DeriveDataTypeable   #-}
 {-# LANGUAGE ScopedTypeVariables  #-}
 {-# LANGUAGE TypeApplications     #-}
 {-# LANGUAGE TypeFamilies         #-}
@@ -24,13 +23,22 @@
           FloatingPoint(..), FP(..), FPHalf, FPBFloat, FPSingle, FPDouble, FPQuad
 
         -- * Constructing values
-        , fpFromRawRep, fpFromBigFloat, fpNaN, fpInf, fpZero
+        , fpFromRawRep, fpFromBigFloat, fpFromBits, fpNaN, fpInf, fpZero
 
         -- * Operations
-        , fpFromInteger, fpFromRational, fpFromFloat, fpFromDouble, fpEncodeFloat
+        , fpFromInteger, fpFromRational, fpFromFloat, fpFromDouble
+        , fpToFloat, fpToDouble
+        , fpEncodeFloat
+        , fpIsFinite, fpIsInf, fpIsZero, fpIsNaN
+        , fpIsNormal, fpIsSubnormal, fpIsNeg, fpIsPos
+        , fpNeg, fpAbs, fpSignum
+        , fpAdd, fpSub, fpMul, fpDiv, fpPow, fpRem, fpSqrt, fpFMA
+        , fpRoundFloat, fpRoundInt
+        , fpMax, fpMin
 
         -- * Internal operations
        , arbFPIsEqualObjectH, arbFPCompareObjectH, fprToSMTLib2, mkBFOpts, bfToString, bfRemoveRedundantExp
+       , roundingModeToRoundMode
        ) where
 
 import Data.Char (intToDigit)
@@ -43,7 +51,7 @@
 import Numeric
 
 import Data.SBV.Core.Kind
-import Data.SBV.Utils.Numeric (floatToWord)
+import Data.SBV.Utils.Numeric (RoundingMode(..), floatToWord, fp2fp)
 
 import LibBF (BigFloat, BFOpts, RoundMode, Status, BFRep(..), BFNum(..), bfToRep, Sign(Neg))
 import qualified LibBF as BF
@@ -101,7 +109,7 @@
 -- | Abbreviation for IEEE double precision float, bit width 64 = 11 + 53.
 type FPDouble = FloatingPoint 11 53
 
--- | Abbreviation for IEEE quadruble precision float, bit width 128 = 15 + 113.
+-- | Abbreviation for IEEE quadruple precision float, bit width 128 = 15 + 113.
 type FPQuad = FloatingPoint 15 113
 
 -- | Show instance for Floats. By default we print in base 10, with standard scientific notation.
@@ -114,8 +122,8 @@
 -- then the total number of floats is 2^sb*(2^eb-1) + 3: All exponents except 11..11
 -- is allowed. So we get, 2^eb-1, different combinations, each with a sign, giving
 -- us 2^sb*(2^eb-1) totals. Then we have two infinities, and one NaN, adding 3 more.
-data FP = FP { fpExponentSize    :: Int
-             , fpSignificandSize :: Int
+data FP = FP { fpExponentSize    :: !Int
+             , fpSignificandSize :: !Int
              , fpValue           :: BigFloat
              }
              deriving (Eq, G.Data)
@@ -134,7 +142,7 @@
 
 -- Manually implemented instance as GHC generated a non-IEEE 754 compliant instance.
 -- Note that we cannot pack the values in a tuple and then compare them as that will
--- also give non-IEEE 754 compilant results.
+-- also give non-IEEE 754 compliant results.
 --
 -- NB. Refrain from letting GHC derive @>@ and @>=@ and define
 -- it ourselves. Why? Because the default definition of @x > y@
@@ -208,11 +216,15 @@
 fpFromBigFloat :: Int -> Int -> BigFloat -> FP
 fpFromBigFloat eb sb r = FP eb sb $ fst $ BF.bfRoundFloat (mkBFOpts eb sb BF.NearEven) r
 
+-- | Convert an integer to a big-float, preserving the bit-correspondence.
+fpFromBits :: Int -> Int -> Integer -> FP
+fpFromBits eb sb val = FP eb sb $ BF.bfFromBits (mkBFOpts eb sb BF.NearEven) val
+
 -- | Convert from an sign/exponent/mantissa representation to a float. The values are the integers
 -- representing the bit-patterns of these values, i.e., the raw representation. We assume that these
 -- integers fit into the ranges given, i.e., no overflow checking is done here.
 fpFromRawRep :: Bool -> (Integer, Int) -> (Integer, Int) -> FP
-fpFromRawRep sign (e, eb) (s, sb) = FP eb sb $ BF.bfFromBits (mkBFOpts eb sb BF.NearEven) val
+fpFromRawRep sign (e, eb) (s, sb) = fpFromBits eb sb val
   where es, val :: Integer
         es = (e `shiftL` (sb - 1)) .|. s
         val | sign = (1 `shiftL` (eb + sb - 1)) .|. es
@@ -294,23 +306,23 @@
 
 -- | Num instance for big-floats
 instance Num FP where
-  (+)           = lift2 BF.bfAdd
-  (-)           = lift2 BF.bfSub
-  (*)           = lift2 BF.bfMul
-  abs           = lift1 BF.bfAbs
-  signum        = lift1 bfSignum
+  (+)           = fpAdd RoundNearestTiesToEven
+  (-)           = fpSub RoundNearestTiesToEven
+  (*)           = fpMul RoundNearestTiesToEven
+  abs           = fpAbs
+  signum        = fpSignum
   fromInteger i = error $ "FP.fromInteger: Not supported for arbitrary floats. Use fpFromInteger instead, specifying the precision. Called on: " ++ show i
-  negate        = lift1 BF.bfNeg
+  negate        = fpNeg
 
 -- | Fractional instance for big-floats
 instance Fractional FP where
   fromRational = error "FP.fromRational: Not supported for arbitrary floats. Use fpFromRational instead, specifying the precision"
-  (/)          = lift2 BF.bfDiv
+  (/)          = fpDiv RoundNearestTiesToEven
 
 -- | Floating instance for big-floats
 instance Floating FP where
-  sqrt (FP eb sb a)      = FP eb sb $ fst $ BF.bfSqrt (mkBFOpts eb sb BF.NearEven) a
-  FP eb sb a ** FP _ _ b = FP eb sb $ fst $ BF.bfPow  (mkBFOpts eb sb BF.NearEven) a b
+  sqrt = fpSqrt RoundNearestTiesToEven
+  (**) = fpPow RoundNearestTiesToEven
 
   pi    = unsupported "Floating.FP.pi"
   exp   = unsupported "Floating.FP.exp"
@@ -336,11 +348,11 @@
      where v :: Integer
            v = 2 ^ ((fromIntegral eb :: Integer) - 1)
 
-  isNaN          (FP _ _   r) = BF.bfIsNaN r
-  isInfinite     (FP _ _   r) = BF.bfIsInf r
-  isDenormalized (FP eb sb r) = BF.bfIsSubnormal (mkBFOpts eb sb BF.NearEven) r
-  isNegativeZero (FP _  _  r) = BF.bfIsZero r && BF.bfIsNeg r
-  isIEEE         _            = True
+  isNaN            = fpIsNaN
+  isInfinite       = fpIsInf
+  isDenormalized   = fpIsSubnormal
+  isNegativeZero f = fpIsZero f && fpIsNeg f
+  isIEEE         _ = True
 
   decodeFloat i@(FP _ _ r) = case BF.bfToRep r of
                                BF.BFNaN     -> decodeFloat (0/0 :: Double)
@@ -361,6 +373,123 @@
     where n' :: Integer
           n' = (2 :: Integer) ^ abs (fromIntegral n :: Integer)
 
+-- | Is a big-float finite?
+fpIsFinite :: FP -> Bool
+fpIsFinite (FP _ _ r) = BF.bfIsFinite r
+
+-- | Is a big-float infinite?
+fpIsInf :: FP -> Bool
+fpIsInf (FP _ _ r) = BF.bfIsInf r
+
+-- | Is a big-float a zero value?
+fpIsZero :: FP -> Bool
+fpIsZero (FP _ _ r) = BF.bfIsZero r
+
+-- | Is a big-float a NaN value?
+fpIsNaN :: FP -> Bool
+fpIsNaN (FP _ _ r) = BF.bfIsNaN r
+
+-- | Is a big-float \"normal\"? That is, is the value not zero, infinite, NaN,
+-- or subnormal?
+fpIsNormal :: FP -> Bool
+fpIsNormal (FP eb sb r) = BF.bfIsNormal (mkBFOpts eb sb BF.NearEven) r
+
+-- | Is a big-float subnormal (i.e., denormalized)?
+fpIsSubnormal :: FP -> Bool
+fpIsSubnormal (FP eb sb r) = BF.bfIsSubnormal (mkBFOpts eb sb BF.NearEven) r
+
+-- | Is a big-float negative?
+fpIsNeg :: FP -> Bool
+fpIsNeg (FP _ _ r) = BF.bfIsNeg r
+
+-- | Is a big-float positive?
+fpIsPos :: FP -> Bool
+fpIsPos (FP _ _ r) = BF.bfIsPos r
+
+-- | Big-float negation.
+fpNeg :: FP -> FP
+fpNeg = lift1 BF.bfNeg
+
+-- | Big-float absolute value.
+fpAbs :: FP -> FP
+fpAbs = lift1 BF.bfAbs
+
+-- | Big-float signum.
+fpSignum :: FP -> FP
+fpSignum = lift1 bfSignum
+
+-- | Big-float addition.
+fpAdd :: RoundingMode -> FP -> FP -> FP
+fpAdd = liftRM2 BF.bfAdd
+
+-- | Big-float subtraction.
+fpSub :: RoundingMode -> FP -> FP -> FP
+fpSub = liftRM2 BF.bfSub
+
+-- | Big-float multiplication.
+fpMul :: RoundingMode -> FP -> FP -> FP
+fpMul = liftRM2 BF.bfMul
+
+-- | Big-float division.
+fpDiv :: RoundingMode -> FP -> FP -> FP
+fpDiv = liftRM2 BF.bfDiv
+
+-- | Big-float exponentiation.
+fpPow :: RoundingMode -> FP -> FP -> FP
+fpPow = liftRM2 BF.bfPow
+
+-- | Big-float remainder.
+fpRem :: RoundingMode -> FP -> FP -> FP
+fpRem = liftRM2 BF.bfRem
+
+-- | Big-float square root.
+fpSqrt :: RoundingMode -> FP -> FP
+fpSqrt = liftRM1 BF.bfSqrt
+
+-- | Big-float fused-multiply-add (FMA).
+fpFMA :: RoundingMode -> FP -> FP -> FP -> FP
+fpFMA = liftRM3 BF.bfFMA
+
+-- | Round a big-float to a float of the given exponent and significand sizes
+-- using the given rounding mode.
+fpRoundFloat :: Int -> Int -> RoundingMode -> FP -> FP
+fpRoundFloat eb sb rm (FP _ _ r) = FP eb sb $ fst $ BF.bfRoundFloat (mkBFOpts eb sb (roundingModeToRoundMode rm)) r
+
+-- | Round a big-float to the nearest integer (represented as a big-float with
+-- a zero decimal component) using the given rounding mode.
+fpRoundInt :: RoundingMode -> FP -> FP
+fpRoundInt rm (FP eb sa a) = FP eb sa $ fst $ BF.bfRoundInt (roundingModeToRoundMode rm) a
+
+-- | SMTLib compliant definition for 'Data.SBV.fpMax'. This is very nearly
+-- identical to 'Data.SBV.Utils.Numeric.fpMaxH', except that this uses
+-- 'fpIsZero' instead of checking for equality against a @0@ literal. (The
+-- latter is not supported for t'FP' values as t'FP' does not implement
+-- 'fromInteger'.)
+fpMax :: FP -> FP -> FP
+fpMax x y
+   | isNaN x                                  = y
+   | isNaN y                                  = x
+   | (isN0 x && isP0 y) || (isN0 y && isP0 x) = error "fpMax: Called with alternating-sign 0's. Not supported"
+   | x > y                                    = x
+   | True                                     = y
+   where isN0   = isNegativeZero
+         isP0 a = fpIsZero a && not (isN0 a)
+
+-- | SMTLib compliant definition for 'Data.SBV.fpMin'. This is very nearly
+-- identical to 'Data.SBV.Utils.Numeric.fpMinH', except that this uses
+-- 'fpIsZero' instead of checking for equality against a @0@ literal. (The
+-- latter is not supported for t'FP' values as t'FP' does not implement
+-- 'fromInteger'.)
+fpMin :: FP -> FP -> FP
+fpMin x y
+   | isNaN x                                  = y
+   | isNaN y                                  = x
+   | (isN0 x && isP0 y) || (isN0 y && isP0 x) = error "fpMin: Called with alternating-sign 0's. Not supported"
+   | x < y                                    = x
+   | True                                     = y
+   where isN0   = isNegativeZero
+         isP0 a = fpIsZero a && not (isN0 a)
+
 -- | Real instance for big-floats. Beware, not that well tested!
 instance Real FP where
   toRational i
@@ -371,7 +500,7 @@
 -- | Real-frac instance for big-floats. Beware, not that well tested!
 instance RealFrac FP where
   properFraction (FP eb sb r) = (getInt r', FP eb sb r - FP eb sb r')
-       where (r', _)  = BF.bfRoundInt BF.ToNegInf r
+       where (r', _)  = BF.bfRoundInt BF.ToZero r
              getInt x = case BF.bfToRep x of
                           BF.BFNaN     -> error $ "Data.SBV.FloatingPoint.properFraction: Failed to convert: " ++ show (r, x)
                           BF.BFRep s n -> case n of
@@ -451,10 +580,18 @@
 lift1 :: (BigFloat -> BigFloat) -> FP -> FP
 lift1 f (FP eb sb a) = fpFromBigFloat eb sb $ f a
 
--- Lift a binary operation. Here we don't call fpFromBigFloat, because the result is correctly rounded.
-lift2 :: (BFOpts -> BigFloat -> BigFloat -> (BigFloat, Status)) -> FP -> FP -> FP
-lift2 f (FP eb sb a) (FP _ _ b) = FP eb sb $ fst $ f (mkBFOpts eb sb BF.NearEven) a b
+-- | Lift a unary operation that returns a big-float and a status.
+liftRM1 :: (BFOpts -> BigFloat -> (BigFloat, Status)) -> RoundingMode -> FP -> FP
+liftRM1 f rm (FP eb sb a) = FP eb sb $ fst $ f (mkBFOpts eb sb (roundingModeToRoundMode rm)) a
 
+-- | Lift a binary operation that returns a big-float and a status.
+liftRM2 :: (BFOpts -> BigFloat -> BigFloat -> (BigFloat, Status)) -> RoundingMode -> FP -> FP -> FP
+liftRM2 f rm (FP eb sb a) (FP _ _ b) = FP eb sb $ fst $ f (mkBFOpts eb sb (roundingModeToRoundMode rm)) a b
+
+-- | Lift a trinary operation that returns a big-float and a status.
+liftRM3 :: (BFOpts -> BigFloat -> BigFloat -> BigFloat -> (BigFloat, Status)) -> RoundingMode -> FP -> FP -> FP -> FP
+liftRM3 f rm (FP eb sb a) (FP _ _ b) (FP _ _ c) = FP eb sb $ fst $ f (mkBFOpts eb sb (roundingModeToRoundMode rm)) a b c
+
 -- | Convert from a IEEE float.
 fpFromFloat :: Int -> Int -> Float -> FP
 fpFromFloat  8 24 f = let fw          = floatToWord f
@@ -466,3 +603,19 @@
 fpFromDouble :: Int -> Int -> Double -> FP
 fpFromDouble 11 53 d = FP 11 54 $ BF.bfFromDouble d
 fpFromDouble eb sb d = error $ "SBV.fpFromDouble: Unexpected input: " ++ show (eb, sb, d)
+
+-- | Convert to a IEEE float using the given rounding mode.
+fpToFloat :: RoundingMode -> FP -> Float
+fpToFloat rm (FP _ _ r) = fp2fp $ fst $ BF.bfToDouble (roundingModeToRoundMode rm) r
+
+-- | Convert to a IEEE double using the given rounding mode.
+fpToDouble :: RoundingMode -> FP -> Double
+fpToDouble rm (FP _ _ r) = fst $ BF.bfToDouble (roundingModeToRoundMode rm) r
+
+-- | Map SBV's rounding modes to LibBF's.
+roundingModeToRoundMode :: RoundingMode -> RoundMode
+roundingModeToRoundMode RoundNearestTiesToEven = BF.NearEven
+roundingModeToRoundMode RoundNearestTiesToAway = BF.NearAway
+roundingModeToRoundMode RoundTowardPositive    = BF.ToPosInf
+roundingModeToRoundMode RoundTowardNegative    = BF.ToNegInf
+roundingModeToRoundMode RoundTowardZero        = BF.ToZero
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
@@ -10,2311 +10,2411 @@
 -----------------------------------------------------------------------------
 
 {-# LANGUAGE BangPatterns               #-}
-{-# LANGUAGE CPP                        #-}
-{-# LANGUAGE DefaultSignatures          #-}
-{-# LANGUAGE DeriveAnyClass             #-}
-{-# LANGUAGE DeriveDataTypeable         #-}
-{-# LANGUAGE DeriveFunctor              #-}
-{-# LANGUAGE DeriveGeneric              #-}
-{-# LANGUAGE DerivingStrategies         #-}
-{-# LANGUAGE FlexibleInstances          #-}
-{-# LANGUAGE GADTs                      #-}
-{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-{-# LANGUAGE MultiParamTypeClasses      #-}
-{-# LANGUAGE NamedFieldPuns             #-}
-{-# LANGUAGE OverloadedStrings          #-}
-{-# LANGUAGE PatternGuards              #-}
-{-# LANGUAGE Rank2Types                 #-}
-{-# LANGUAGE ScopedTypeVariables        #-}
-{-# LANGUAGE StandaloneDeriving         #-}
-{-# LANGUAGE TypeFamilies               #-}
-{-# LANGUAGE TypeOperators              #-}
-{-# LANGUAGE UndecidableInstances       #-}
-{-# LANGUAGE ViewPatterns               #-}
-
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
-
-module Data.SBV.Core.Symbolic
-  ( NodeId(..)
-  , SV(..), swKind, trueSV, falseSV, contextOfSV
-  , Op(..), PBOp(..), OvOp(..), FPOp(..), NROp(..), StrOp(..), RegExOp(..), SeqOp(..), SetOp(..), SpecialRelOp(..)
-  , RegExp(..), regExpToSMTString, SMTLambda(..)
-  , Quantifier(..), needsExistentials, SBVContext(..), checkCompatibleContext, VarContext(..)
-  , RoundingMode(..)
-  , SBVType(..), svUninterpreted, svUninterpretedNamedArgs, newUninterpreted, prefixNameToUnique
-  , SVal(..)
-  , svMkSymVar, sWordN, sWordN_, sIntN, sIntN_
-  , svToSV, svToSymSV, forceSVArg
-  , SBVExpr(..), newExpr, isCodeGenMode, isSafetyCheckingIStage, isRunIStage, isSetupIStage
-  , Cached, cache, uncache, modifyState, modifyIncState
-  , NamedSymVar(..), Name, UserInputs, Inputs(..), getSV, swNodeId, namedNodeId
-  , addInternInput, addUserInput
-  , getUserName', getUserName
-  , lookupInput , getSValPathCondition, extendSValPathCondition
-  , getTableIndex, sObserve
-  , SBVPgm(..), MonadSymbolic(..), SymbolicT, Symbolic, runSymbolic, mkNewState, runSymbolicInState, State(..), SMTDef(..), withNewIncState, IncState(..), incrementInternalCounter, incrementFreshNameCounter
-  , inSMTMode, SBVRunMode(..), IStage(..), Result(..), ResultInp(..), UICodeKind(..), UIName(..)
-  , registerKind, registerLabel, recordObservable
-  , addAssertion, addNewSMTOption, imposeConstraint, internalConstraint, newInternalVariable, lambdaVar, quantVar
-  , SMTLibPgm(..), SMTLibVersion(..), smtLibVersionExtension
-  , SolverCapabilities(..)
-  , extractSymbolicSimulationState, CnstMap
-  , OptimizeStyle(..), Objective(..), Penalty(..), objectiveName, addSValOptGoal
-  , MonadQuery(..), QueryT(..), Query, QueryState(..), QueryContext(..)
-  , SMTScript(..), Solver(..), SMTSolver(..), SMTResult(..), SMTModel(..), SMTConfig(..), TPOptions(..), SMTEngine, isEmptyModel
-  , validationRequested, outputSVal, ProgInfo(..), mustIgnoreVar, getRootState
-  ) where
-
-import Control.DeepSeq             (NFData(..))
-import Control.Monad               (when)
-import Control.Monad.Except        (MonadError, ExceptT)
-import Control.Monad.Reader        (MonadReader(..), ReaderT, runReaderT,
-                                    mapReaderT)
-import Control.Monad.State.Lazy    (MonadState)
-import Control.Monad.Trans         (MonadIO(liftIO), MonadTrans(lift))
-import Control.Monad.Trans.Maybe   (MaybeT)
-import Control.Monad.Writer.Strict (MonadWriter)
-import Data.IORef                  (IORef, newIORef, readIORef)
-import Data.List                   (intercalate, sortBy, isPrefixOf)
-import Data.Maybe                  (fromMaybe)
-import Data.String                 (IsString(fromString))
-
-import Data.Time (getCurrentTime, UTCTime)
-
-import Data.Int (Int64)
-
-import GHC.Stack
-import GHC.Stack.Types
-import GHC.Generics (Generic)
-
-import qualified Control.Exception as C
-import qualified Control.Monad.State.Lazy    as LS
-import qualified Control.Monad.State.Strict  as SS
-import qualified Control.Monad.Writer.Lazy   as LW
-import qualified Control.Monad.Writer.Strict as SW
-import qualified Data.IORef                  as R    (modifyIORef')
-import qualified Data.Generics               as G    (Data(..))
-import qualified Data.Generics.Uniplate.Data as G
-import qualified Data.IntMap.Strict          as IMap (IntMap, empty, lookup, insertWith)
-import qualified Data.Map.Strict             as Map  (Map, empty, toList, lookup, insert, size, notMember)
-import qualified Data.Set                    as Set  (Set, empty, toList, insert, member)
-import qualified Data.Foldable               as F    (toList)
-import qualified Data.Sequence               as S    (Seq, empty, (|>), (<|), lookup, elemIndexL)
-import qualified Data.Text                   as T
-
-import System.Mem.StableName
-import System.Random
-
-import Data.SBV.Core.Kind
-import Data.SBV.Core.Concrete
-import Data.SBV.SMT.SMTLibNames
-import Data.SBV.Utils.TDiff (Timing)
-import Data.SBV.Utils.Lib   (stringToQFS, checkObservableName, barify)
-
-import Data.Containers.ListUtils (nubOrd)
-
-import Data.SBV.Control.Types
-
-#if MIN_VERSION_base(4,11,0)
-import Control.Monad.Fail as Fail
-#endif
-
--- | Context identifier. 0 is reserved global context
-newtype SBVContext = SBVContext Int64 deriving (Eq, Ord, G.Data, Show)
-
-instance NFData SBVContext where
-  rnf (SBVContext i) = i `seq` ()
-
--- | Global context
-globalSBVContext :: SBVContext
-globalSBVContext = SBVContext 0
-
--- | Generate context. We make sure it isn't 0, i.e., the global context
--- The "hope" here is that each time we call this we get a different context number.
--- A random number doesn't necessarily have to do that, but I think the pseudo-generator
--- has a large enough period for this to go through OK.
-genSBVContext :: IO SBVContext
-genSBVContext = do ctx <- SBVContext <$> randomIO
-                   if ctx == globalSBVContext   -- unlikely, but possible
-                      then genSBVContext
-                      else pure ctx
-
--- | A symbolic node id
-newtype NodeId = NodeId { getId :: (SBVContext, Maybe Int, Int) } -- Lambda-level, and node-id
-  deriving (Ord, G.Data)
-
--- Equality is pair-wise, except we accommodate for negative node-id; which is reserved for true/false
-instance Eq NodeId where
-  NodeId n1@(_, _, i) == NodeId n2@(_, _, j)
-     | i < 0 && j < 0
-     = i == j
-     | True
-     = n1 == n2
-
--- | A symbolic word, tracking its kind and node representing it
-data SV = SV !Kind !NodeId
-        deriving G.Data
-
--- | Which context are we using this var at?
-contextOfSV :: SV -> SBVContext
-contextOfSV (SV _ (NodeId (c, _, _))) = c
-
--- | For equality, we merely use the lambda-level/node-id
-instance Eq SV where
-  SV _ n1 == SV _ n2 = n1 == n2
-
--- | Again, simply use the lambda-level/node-id for ordering
-instance Ord SV where
-  SV _ n1 `compare` SV _ n2 = n1 `compare` n2
-
-instance HasKind SV where
-  kindOf (SV k _) = k
-
-instance Show SV where
-  show (SV _ (NodeId (_, l, n))) = case n of
-                                     -2 -> "false"
-                                     -1 -> "true"
-                                     _  -> prefix ++ 's' : show n
-        where prefix = case l of
-                         Nothing -> "arg"   -- top-level lambda
-                         Just 0  -> ""
-                         Just i  -> 'l' : show i ++ "_"
-
--- | Kind of a symbolic word.
-swKind :: SV -> Kind
-swKind (SV k _) = k
-
--- | retrieve the node id of a symbolic word
-swNodeId :: SV -> NodeId
-swNodeId (SV _ nid) = nid
-
--- | Forcing an argument; this is a necessary evil to make sure all the arguments
--- to an uninterpreted function are evaluated before called; the semantics of uinterpreted
--- functions is necessarily strict; deviating from Haskell's
-forceSVArg :: SV -> IO ()
-forceSVArg (SV k n) = k `seq` n `seq` return ()
-
--- | Constant False as an t'SV'. Note that this value always occupies slot -2 and level 0.
-falseSV :: SV
-falseSV = SV KBool $ NodeId (globalSBVContext, Just 0, -2)
-
--- | Constant True as an t'SV'. Note that this value always occupies slot -1 and level 0.
-trueSV :: SV
-trueSV  = SV KBool $ NodeId (globalSBVContext, Just 0, -1)
-
--- | Symbolic operations
-data Op = Plus
-        | Times
-        | Minus
-        | UNeg
-        | Abs
-        | Quot
-        | Rem
-        | Equal Bool   -- ^ If bool is True then this is strong (i.e., object equality). Matters for floats or structures containing them.
-        | Implies
-        | NotEqual
-        | LessThan
-        | GreaterThan
-        | LessEq
-        | GreaterEq
-        | Ite
-        | And
-        | Or
-        | XOr
-        | Not
-        | Shl
-        | Shr
-        | Rol Int
-        | Ror Int
-        | Divides Integer                       -- divides k n is True if k divides n. k must be > 0 constant
-        | Extract Int Int                       -- Extract i j: extract bits i to j. Least significant bit is 0 (big-endian)
-        | Join                                  -- Concat two words to form a bigger one, in the order given
-        | ZeroExtend Int
-        | SignExtend Int
-        | LkUp (Int, Kind, Kind, Int) !SV !SV   -- (table-index, arg-type, res-type, length of the table) index out-of-bounds-value
-        | KindCast Kind Kind
-        | Uninterpreted String
-        | QuantifiedBool String                 -- When we generate a forall/exists (nested etc.) boolean value. NB. This used to be "QuantifiedBool [Op] String", keeping track of Ops. That turned out to cause memory leaks. So avoid that.
-        | SpecialRelOp Kind SpecialRelOp        -- Generate the equality to the internal operation
-        | Label String                          -- Essentially no-op; useful for code generation to emit comments.
-        | IEEEFP FPOp                           -- Floating-point ops, categorized separately
-        | NonLinear NROp                        -- Non-linear ops (mostly trigonometric), categorized separately
-        | OverflowOp    OvOp                    -- Overflow-ops, categorized separately
-        | PseudoBoolean PBOp                    -- Pseudo-boolean ops, categorized separately
-        | RegExOp RegExOp                       -- RegEx operations, categorized separately
-        | StrOp StrOp                           -- String ops, categorized separately
-        | SeqOp SeqOp                           -- Sequence ops, categorized separately
-        | SetOp SetOp                           -- Set operations, categorized separately
-        | TupleConstructor Int                  -- Construct an n-tuple
-        | TupleAccess Int Int                   -- Access element i of an n-tuple; second argument is n
-        | EitherConstructor Kind Kind Bool      -- Construct a sum; False: left, True: right
-        | EitherIs Kind Kind Bool               -- Either branch tester; False: left, True: right
-        | EitherAccess Bool                     -- Either branch access; False: left, True: right
-        | RationalConstructor                   -- Construct a rational. Note that there's no access to numerator or denumerator, since we cannot store rationals in canonical form
-        | MaybeConstructor Kind Bool            -- Construct a maybe value; False: Nothing, True: Just
-        | MaybeIs Kind Bool                     -- Maybe tester; False: nothing, True: just
-        | MaybeAccess                           -- Maybe branch access; grab the contents of the just
-        | ArrayLambda SMTLambda                 -- An array value, created from a lambda
-        | ReadArray                             -- Reading an array value
-        | WriteArray                            -- Writing to an array
-        deriving (Eq, Ord, Generic, G.Data, NFData)
-
--- | Special relations supported by z3
-data SpecialRelOp = IsPartialOrder         String
-                  | IsLinearOrder          String
-                  | IsTreeOrder            String
-                  | IsPiecewiseLinearOrder String
-                  deriving (Eq, Ord, G.Data, Show)
-
-instance NFData SpecialRelOp where
-  rnf (IsPartialOrder         n) = rnf n
-  rnf (IsLinearOrder          n) = rnf n
-  rnf (IsTreeOrder            n) = rnf n
-  rnf (IsPiecewiseLinearOrder n) = rnf n
-
--- | Floating point operations
-data FPOp = FP_Cast        Kind Kind SV   -- From-Kind, To-Kind, RoundingMode. This is "value" conversion
-          | FP_Reinterpret Kind Kind      -- From-Kind, To-Kind. This is bit-reinterpretation using IEEE-754 interchange format
-          | FP_Abs
-          | FP_Neg
-          | FP_Add
-          | FP_Sub
-          | FP_Mul
-          | FP_Div
-          | FP_FMA
-          | FP_Sqrt
-          | FP_Rem
-          | FP_RoundToIntegral
-          | FP_Min
-          | FP_Max
-          | FP_ObjEqual
-          | FP_IsNormal
-          | FP_IsSubnormal
-          | FP_IsZero
-          | FP_IsInfinite
-          | FP_IsNaN
-          | FP_IsNegative
-          | FP_IsPositive
-          deriving (Eq, Ord, G.Data, NFData, Generic)
-
--- Note that the show instance maps to the SMTLib names. We need to make sure
--- this mapping stays correct through SMTLib changes. The only exception
--- is FP_Cast; where we handle different source/origins explicitly later on.
-instance Show FPOp where
-   show (FP_Cast f t r)      = "(FP_Cast: " ++ show f ++ " -> " ++ show t ++ ", using RM [" ++ show r ++ "])"
-   show (FP_Reinterpret f t) = case t of
-                                  KFloat    -> "(_ to_fp 8 24)"
-                                  KDouble   -> "(_ to_fp 11 53)"
-                                  KFP eb sb -> "(_ to_fp " ++ show eb ++ " " ++ show sb ++ ")"
-                                  _         -> error $ "SBV.FP_Reinterpret: Unexpected conversion: " ++ show f ++ " to " ++ show t
-   show FP_Abs               = "fp.abs"
-   show FP_Neg               = "fp.neg"
-   show FP_Add               = "fp.add"
-   show FP_Sub               = "fp.sub"
-   show FP_Mul               = "fp.mul"
-   show FP_Div               = "fp.div"
-   show FP_FMA               = "fp.fma"
-   show FP_Sqrt              = "fp.sqrt"
-   show FP_Rem               = "fp.rem"
-   show FP_RoundToIntegral   = "fp.roundToIntegral"
-   show FP_Min               = "fp.min"
-   show FP_Max               = "fp.max"
-   show FP_ObjEqual          = "="
-   show FP_IsNormal          = "fp.isNormal"
-   show FP_IsSubnormal       = "fp.isSubnormal"
-   show FP_IsZero            = "fp.isZero"
-   show FP_IsInfinite        = "fp.isInfinite"
-   show FP_IsNaN             = "fp.isNaN"
-   show FP_IsNegative        = "fp.isNegative"
-   show FP_IsPositive        = "fp.isPositive"
-
--- | Non-linear operations
-data NROp = NR_Sin
-          | NR_Cos
-          | NR_Tan
-          | NR_ASin
-          | NR_ACos
-          | NR_ATan
-          | NR_Sqrt
-          | NR_Sinh
-          | NR_Cosh
-          | NR_Tanh
-          | NR_Exp
-          | NR_Log
-          | NR_Pow
-          deriving (Eq, Ord, G.Data, NFData, Generic)
-
--- | The show instance carefully arranges for these to be printed as it can be understood by dreal
-instance Show NROp where
-  show NR_Sin  = "sin"
-  show NR_Cos  = "cos"
-  show NR_Tan  = "tan"
-  show NR_ASin = "asin"
-  show NR_ACos = "acos"
-  show NR_ATan = "atan"
-  show NR_Sinh = "sinh"
-  show NR_Cosh = "cosh"
-  show NR_Tanh = "tanh"
-  show NR_Sqrt = "sqrt"
-  show NR_Exp  = "exp"
-  show NR_Log  = "log"
-  show NR_Pow  = "pow"
-
--- | Pseudo-boolean operations
-data PBOp = PB_AtMost  Int        -- ^ At most k
-          | PB_AtLeast Int        -- ^ At least k
-          | PB_Exactly Int        -- ^ Exactly k
-          | PB_Le      [Int] Int  -- ^ At most k,  with coefficients given. Generalizes PB_AtMost
-          | PB_Ge      [Int] Int  -- ^ At least k, with coefficients given. Generalizes PB_AtLeast
-          | PB_Eq      [Int] Int  -- ^ Exactly k,  with coefficients given. Generalized PB_Exactly
-          deriving (Eq, Ord, Show, G.Data, NFData, Generic)
-
--- | Overflow operations
-data OvOp = PlusOv Bool           -- ^ Addition    overflow.    Bool is True if signed.
-          | SubOv  Bool           -- ^ Subtraction overflow.    Bool is True if signed.
-          | MulOv  Bool           -- ^ Multiplication overflow. Bool is True if signed.
-          | DivOv                 -- ^ Division overflow.       Only signed, since unsigned division does not overflow.
-          | NegOv                 -- ^ Unary negation overflow. Only signed, since unsigned negation does not overflow.
-          deriving (Eq, Ord, G.Data, NFData, Generic)
-
--- | Show instance. It's important that these follow the SMTLib names.
-instance Show OvOp where
-  show (PlusOv signed) = "bv" ++ (if signed then "s" else "u") ++ "addo"
-  show (SubOv  signed) = "bv" ++ (if signed then "s" else "u") ++ "subo"
-  show (MulOv  signed) = "bv" ++ (if signed then "s" else "u") ++ "mulo"
-  show DivOv           = "bvsdivo" -- This is confusing, the division is called bvsdivo, but negation is bvnego
-  show NegOv           = "bvnego"  -- But SMTLib's choice is deliberate: https://groups.google.com/u/0/g/smt-lib/c/J4D99wT0aKI
-
--- | String operations.
-data StrOp = StrStrToNat     -- ^ Retrieve integer encoded by string @s@ (ground rewriting only)
-           | StrNatToStr     -- ^ Retrieve string encoded by integer @i@ (ground rewriting only)
-           | StrToCode       -- ^ Equivalent to Haskell's ord
-           | StrFromCode     -- ^ Equivalent to Haskell's chr
-           | StrInRe RegExp  -- ^ Check if string is in the regular expression
-           deriving (Eq, Ord, G.Data, NFData, Generic)
-
--- | Regular-expression operators. The only thing we can do is to compare for equality/disequality.
-data RegExOp = RegExEq  RegExp RegExp
-             | RegExNEq RegExp RegExp
-             deriving (Eq, Ord, G.Data, NFData, Generic)
-
--- | Regular expressions. Note that regular expressions themselves are
--- concrete, but the 'Data.SBV.RegExp.match' function from the 'Data.SBV.RegExp.RegExpMatchable' class
--- can check membership against a symbolic string/character. Also, we
--- are preferring a datatype approach here, as opposed to coming up with
--- some string-representation; there are way too many alternatives
--- already so inventing one isn't a priority. Please get in touch if you
--- would like a parser for this type as it might be easier to use.
-data RegExp = Literal String       -- ^ Precisely match the given string
-            | All                  -- ^ Accept every string
-            | AllChar              -- ^ Accept every single character
-            | None                 -- ^ Accept no strings
-            | Range Char Char      -- ^ Accept range of characters
-            | Conc  [RegExp]       -- ^ Concatenation
-            | KStar RegExp         -- ^ Kleene Star: Zero or more
-            | KPlus RegExp         -- ^ Kleene Plus: One or more
-            | Opt   RegExp         -- ^ Zero or one
-            | Comp  RegExp         -- ^ Complement of regular expression
-            | Diff  RegExp RegExp  -- ^ Difference of regular expressions
-            | Loop  Int Int RegExp -- ^ From @n@ repetitions to @m@ repetitions
-            | Power Int     RegExp -- ^ Exactly @n@ repetitions, i.e., nth power
-            | Union [RegExp]       -- ^ Union of regular expressions
-            | Inter RegExp RegExp  -- ^ Intersection of regular expressions
-            deriving (Eq, Ord, G.Data, Generic, NFData)
-
--- | With overloaded strings, we can have direct literal regular expressions.
-instance IsString RegExp where
-  fromString = Literal
-
--- | Regular expressions as a 'Num' instance. Note that only some operations make sense and
--- not in the most obvious way. For instance, we would typically expect @a - b@ to be the
--- same as @a + negate b@, but that equality does not hold in general. So, use the @Num@
--- instance only as constructing syntax, not doing algebraic manipulations.
-instance Num RegExp where
-  -- flatten the concats to make them simpler
-  Conc xs * y = Conc (xs ++ [y])
-  x * Conc ys = Conc (x  :  ys)
-  x * y       = Conc [x, y]
-
-  -- flatten the unions to make them simpler
-  Union xs + y = Union (xs ++ [y])
-  x + Union ys = Union (x  : ys)
-  x + y        = Union [x, y]
-
-  x - y = Diff x y
-
-  abs         = error "Num.RegExp: no abs method"
-  signum      = error "Num.RegExp: no signum method"
-
-  fromInteger x
-    | x == 0    = None
-    | x == 1    = Literal ""   -- Unit for concatenation is the empty string
-    | True      = error $ "Num.RegExp: Only 0 and 1 makes sense as a reg-exp, no meaning for: " ++ show x
-
-  negate = Comp
-
--- | Convert a reg-exp to a Haskell-like string
-instance Show RegExp where
-  show = regExpToString show
-
--- | Convert a reg-exp to a SMT-lib acceptable representation
-regExpToSMTString :: RegExp -> String
-regExpToSMTString = regExpToString (\s -> '"' : stringToQFS s ++ "\"")
-
--- | Convert a RegExp to a string, parameterized by how strings are converted
-regExpToString :: (String -> String) -> RegExp -> String
-regExpToString fs (Literal s)       = "(str.to.re " ++ fs s ++ ")"
-regExpToString _  All               = "re.all"
-regExpToString _  AllChar           = "re.allchar"
-regExpToString _  None              = "re.nostr"
-regExpToString fs (Range ch1 ch2)   = "(re.range " ++ fs [ch1] ++ " " ++ fs [ch2] ++ ")"
-regExpToString _  (Conc [])         = show (1 :: Integer)
-regExpToString fs (Conc [x])        = regExpToString fs x
-regExpToString fs (Conc xs)         = "(re.++ " ++ unwords (map (regExpToString fs) xs) ++ ")"
-regExpToString fs (KStar r)         = "(re.* " ++ regExpToString fs r ++ ")"
-regExpToString fs (KPlus r)         = "(re.+ " ++ regExpToString fs r ++ ")"
-regExpToString fs (Opt   r)         = "(re.opt " ++ regExpToString fs r ++ ")"
-regExpToString fs (Comp  r)         = "(re.comp " ++ regExpToString fs r ++ ")"
-regExpToString fs (Diff  r1 r2)     = "(re.diff " ++ regExpToString fs r1 ++ " " ++ regExpToString fs r2 ++ ")"
-regExpToString fs (Loop  lo hi r)
-   | lo >= 0, hi >= lo = "((_ re.loop " ++ show lo ++ " " ++ show hi ++ ") " ++ regExpToString fs r ++ ")"
-   | True              = error $ "Invalid regular-expression Loop with arguments: " ++ show (lo, hi)
-regExpToString fs (Power n r)
-   | n >= 0            = regExpToString fs (Loop n n r)
-   | True              = error $ "Invalid regular-expression Power with arguments: " ++ show n
-regExpToString fs (Inter r1 r2)     = "(re.inter " ++ regExpToString fs r1 ++ " " ++ regExpToString fs r2 ++ ")"
-regExpToString _  (Union [])        = "re.nostr"
-regExpToString fs (Union [x])       = regExpToString fs x
-regExpToString fs (Union xs)        = "(re.union " ++ unwords (map (regExpToString fs) xs) ++ ")"
-
--- | Show instance for @StrOp@. Note that the mapping here is important to match the SMTLib equivalents.
-instance Show StrOp where
-  show StrStrToNat = "str.to.int"    -- NB. SMTLib uses "int" here though only nats are supported
-  show StrNatToStr = "int.to.str"    -- NB. SMTLib uses "int" here though only nats are supported
-  show StrToCode   = "str.to_code"
-  show StrFromCode = "str.from_code"
-  -- Note the breakage here with respect to argument order. We fix this explicitly later.
-  show (StrInRe s) = "str.in.re " ++ regExpToSMTString s
-
--- | Show instance for @RegExOp@.
-instance Show RegExOp where
-  show (RegExEq  r1 r2) = "(= "        ++ regExpToSMTString r1 ++ " " ++ regExpToSMTString r2 ++ ")"
-  show (RegExNEq r1 r2) = "(distinct " ++ regExpToSMTString r1 ++ " " ++ regExpToSMTString r2 ++ ")"
-
--- | For now, we represent lambda functions in op with their SMTLib equivalent strings.
--- This might change in the future.
-newtype SMTLambda = SMTLambda String
-                  deriving (Eq, Ord, G.Data, Generic)
-                  deriving newtype NFData
-
--- | Simple show instance for SMTLambda
-instance Show SMTLambda where
-  show (SMTLambda s) = s
-
--- | Sequence operations. Indexed by the element kind.
-data SeqOp = SeqLen      Kind
-           | SeqConcat   Kind
-           | SeqNth      Kind
-           | SeqUnit     Kind
-           | SeqSubseq   Kind
-           | SeqIndexOf  Kind
-           | SeqContains Kind
-           | SeqPrefixOf Kind
-           | SeqSuffixOf Kind
-           | SeqReplace  Kind
-  deriving (Eq, Ord, G.Data, NFData, Generic)
-
--- | Pick the correct operator
-pickSeqOp :: Kind -> String -> String -> String
-pickSeqOp KChar st _  = st
-pickSeqOp _     _  sq = sq
-
--- | Show instance for SeqOp. Again, mapping is important.
-instance Show SeqOp where
-  show (SeqLen      k) = pickSeqOp k "str.len"      "seq.len"
-  show (SeqConcat   k) = pickSeqOp k "str.++"       "seq.++"
-  show (SeqNth      k) = pickSeqOp k "str.at"       "seq.nth"
-  show (SeqUnit     k) = pickSeqOp k "str.unit"     "seq.unit"
-  show (SeqSubseq   k) = pickSeqOp k "str.substr"   "seq.extract"
-  show (SeqIndexOf  k) = pickSeqOp k "str.indexof"  "seq.indexof"
-  show (SeqContains k) = pickSeqOp k "str.contains" "seq.contains"
-  show (SeqPrefixOf k) = pickSeqOp k "str.prefixof" "seq.prefixof"
-  show (SeqSuffixOf k) = pickSeqOp k "str.suffixof" "seq.suffixof"
-  show (SeqReplace  k) = pickSeqOp k "str.replace"  "seq.replace"
-
--- | Set operations.
-data SetOp = SetEqual
-           | SetMember
-           | SetInsert
-           | SetDelete
-           | SetIntersect
-           | SetUnion
-           | SetSubset
-           | SetDifference
-           | SetComplement
-        deriving (Eq, Ord, G.Data, NFData, Generic)
-
--- The show instance for 'SetOp' is merely for debugging, we map them separately so
--- the mapped strings are less important here.
-instance Show SetOp where
-  show SetEqual      = "=="
-  show SetMember     = "Set.member"
-  show SetInsert     = "Set.insert"
-  show SetDelete     = "Set.delete"
-  show SetIntersect  = "Set.intersect"
-  show SetUnion      = "Set.union"
-  show SetSubset     = "Set.subset"
-  show SetDifference = "Set.difference"
-  show SetComplement = "Set.complement"
-
--- Show instance for 'Op'. Note that this is largely for debugging purposes, not used
--- for being read by any tool.
-instance Show Op where
-  show Shl    = "<<"
-  show Shr    = ">>"
-
-  show (Rol i) = "<<<" ++ show i
-  show (Ror i) = ">>>" ++ show i
-
-  show (Extract i j) = "choose [" ++ show i ++ ":" ++ show j ++ "]"
-
-  show (LkUp (ti, at, rt, l) i e)
-        = "lookup(" ++ tinfo ++ ", " ++ show i ++ ", " ++ show e ++ ")"
-        where tinfo = "table" ++ show ti ++ "(" ++ show at ++ " -> " ++ show rt ++ ", " ++ show l ++ ")"
-
-  show (KindCast fr to)     = "cast_" ++ show fr ++ "_" ++ show to
-  show (Uninterpreted i)    = "[uninterpreted] " ++ i
-  show (QuantifiedBool i)   = "[quantified boolean] " ++ i
-
-  show (Label s)            = "[label] " ++ s
-
-  show (IEEEFP w)           = show w
-
-  show (NonLinear w)        = show w
-
-  show (PseudoBoolean p)    = show p
-
-  show (OverflowOp o)       = show o
-
-  show (StrOp s)            = show s
-  show (RegExOp s)          = show s
-  show (SeqOp s)            = show s
-  show (SetOp s)            = show s
-
-  show (TupleConstructor   0) = "mkSBVTuple0"
-  show (TupleConstructor   n) = "mkSBVTuple" ++ show n
-  show (TupleAccess      i n) = "proj_" ++ show i ++ "_SBVTuple" ++ show n
-
-  -- Remember, while we try to maintain SMTLib compabitibility here, these output
-  -- is merely for debugging purposes. For how we actually render these in SMTLib,
-  -- look at the file SBV/SMT/SMTLib2.hs for these constructors.
-  show (EitherConstructor k1 k2  False) = "(_ left_SBVEither "  ++ show (KEither k1 k2) ++ ")"
-  show (EitherConstructor k1 k2  True ) = "(_ right_SBVEither " ++ show (KEither k1 k2) ++ ")"
-  show (EitherIs          k1 k2  False) = "(_ is (left_SBVEither ("  ++ show k1 ++ ") " ++ show (KEither k1 k2) ++ "))"
-  show (EitherIs          k1 k2  True ) = "(_ is (right_SBVEither (" ++ show k2 ++ ") " ++ show (KEither k1 k2) ++ "))"
-  show (EitherAccess             False) = "get_left_SBVEither"
-  show (EitherAccess             True ) = "get_right_SBVEither"
-  show RationalConstructor              = "SBV.Rational"
-  show (MaybeConstructor k False)       = "(_ nothing_SBVMaybe " ++ show (KMaybe k) ++ ")"
-  show (MaybeConstructor k True)        = "(_ just_SBVMaybe "    ++ show (KMaybe k) ++ ")"
-  show (MaybeIs          k False)       = "(_ is (nothing_SBVMaybe () "              ++ show (KMaybe k) ++ "))"
-  show (MaybeIs          k True )       = "(_ is (just_SBVMaybe (" ++ show k ++ ") " ++ show (KMaybe k) ++ "))"
-  show MaybeAccess                      = "get_just_SBVMaybe"
-  show (ArrayLambda s)                  = show s
-  show ReadArray                        = "select"
-  show WriteArray                       = "store"
-
-  show op
-    | Just s <- op `lookup` syms = s
-    | True                       = error "impossible happened; can't find op!" -- NB. Can't display the OP here! it's the show instance after all.
-    where syms = [ (Plus, "+"), (Times, "*"), (Minus, "-"), (UNeg, "-"), (Abs, "abs")
-                 , (Quot, "quot")
-                 , (Rem,  "rem")
-                 , (Equal True, "==="), (Equal False, "=="), (NotEqual, "/="), (Implies, "=>")
-                 , (LessThan, "<"), (GreaterThan, ">"), (LessEq, "<="), (GreaterEq, ">=")
-                 , (Ite, "if_then_else")
-                 , (And, "&"), (Or, "|"), (XOr, "^"), (Not, "~")
-                 , (Join, "#")
-                 ]
-
--- | Quantifiers: forall or exists. Note that we allow arbitrary nestings.
-data Quantifier = ALL | EX deriving (Eq, G.Data)
-
--- | Show instance for 'Quantifier'
-instance Show Quantifier where
-  show ALL = "Forall"
-  show EX  = "Exists"
-
--- | Which context is this variable being created?
-data VarContext = NonQueryVar (Maybe Quantifier)  -- in this case, it can be quantified
-                | QueryVar                        -- in this case, it is always existential
-
--- | Are there any existential quantifiers?
-needsExistentials :: [Quantifier] -> Bool
-needsExistentials = (EX `elem`)
-
--- | A simple type for SBV computations, used mainly for uninterpreted constants.
--- We keep track of the signedness/size of the arguments. A non-function will
--- have just one entry in the list.
-newtype SBVType = SBVType [Kind]
-                deriving (Eq, Ord, G.Data)
-
-instance Show SBVType where
-  show (SBVType []) = error "SBV: internal error, empty SBVType"
-  show (SBVType xs) = intercalate " -> " $ map show xs
-
--- | A symbolic expression
-data SBVExpr = SBVApp !Op ![SV]
-             deriving (Eq, Ord, G.Data)
-
--- | To improve hash-consing, take advantage of commutative operators by
--- reordering their arguments.
-reorder :: SBVExpr -> SBVExpr
-reorder s = case s of
-              SBVApp op [a, b] | isCommutative op && a > b -> SBVApp op [b, a]
-              _ -> s
-  where isCommutative :: Op -> Bool
-        isCommutative o = o `elem` [Plus, Times, Equal True, Equal False, NotEqual, And, Or, XOr]
-
--- Show instance for 'SBVExpr'. Again, only for debugging purposes.
-instance Show SBVExpr where
-  show (SBVApp Ite [t, a, b])           = unwords ["if", show t, "then", show a, "else", show b]
-  show (SBVApp Shl     [a, i])          = unwords [show a, "<<", show i]
-  show (SBVApp Shr     [a, i])          = unwords [show a, ">>", show i]
-  show (SBVApp (Rol i) [a])             = unwords [show a, "<<<", show i]
-  show (SBVApp (Ror i) [a])             = unwords [show a, ">>>", show i]
-  show (SBVApp (PseudoBoolean pb) args) = unwords (show pb : map show args)
-  show (SBVApp (OverflowOp op)    args) = unwords (show op : map show args)
-
-  show (SBVApp op args) | showOpInfix op, length args == 2 = unwords (map show (take 1 args) ++ show op : map show (drop 1 args))
-                        | True                             = unwords (show op : map show args)
-
--- | Should we display this Op infix?
-showOpInfix :: Op -> Bool
-showOpInfix = (`elem` infixOps)
-  where infixOps = [ Plus, Times, Minus, Quot, Rem, Implies
-                   , Equal True, Equal False, NotEqual, LessThan, GreaterThan, LessEq, GreaterEq
-                   , And, Or, XOr, Join
-                   ]
-
--- | A program is a sequence of assignments
-newtype SBVPgm = SBVPgm {pgmAssignments :: S.Seq (SV, SBVExpr)}
-               deriving G.Data
-
--- | Helper synonym for text, in case we switch to something else later.
-type Name = T.Text
-
--- | t'NamedSymVar' pairs symbolic values and user given/automatically generated names
-data NamedSymVar = NamedSymVar !SV !Name
-                 deriving (Show, Generic, G.Data)
-
--- | For comparison purposes, we simply use the SV and ignore the name
-instance Eq NamedSymVar where
-  (==) (NamedSymVar l _) (NamedSymVar r _) = l == r
-
-instance Ord NamedSymVar where
-  compare (NamedSymVar l _) (NamedSymVar r _) = compare l r
-
--- | Convert to a named symvar, from string
-toNamedSV' :: SV -> String -> NamedSymVar
-toNamedSV' s = NamedSymVar s . T.pack
-
--- | Convert to a named symvar, from text
-toNamedSV :: SV -> Name -> NamedSymVar
-toNamedSV = NamedSymVar
-
--- | Get the node id from a named sym var
-namedNodeId :: NamedSymVar -> NodeId
-namedNodeId = swNodeId . getSV
-
--- | Get the SV from a named sym var
-getSV :: NamedSymVar -> SV
-getSV (NamedSymVar s _) = s
-
--- | Get the user-name typed value from named sym var
-getUserName :: NamedSymVar -> Name
-getUserName (NamedSymVar _ nm) = nm
-
--- | Get the string typed value from named sym var
-getUserName' :: NamedSymVar -> String
-getUserName' = T.unpack . getUserName
-
--- | Style of optimization. Note that in the pareto case the user is allowed
--- to specify a max number of fronts to query the solver for, since there might
--- potentially be an infinite number of them and there is no way to know exactly
--- how many ahead of time. If 'Nothing' is given, SBV will possibly loop forever
--- if the number is really infinite.
-data OptimizeStyle = Lexicographic      -- ^ Objectives are optimized in the order given, earlier objectives have higher priority.
-                   | Independent        -- ^ Each objective is optimized independently.
-                   | Pareto (Maybe Int) -- ^ Objectives are optimized according to pareto front: That is, no objective can be made better without making some other worse.
-                   deriving (Eq, Show)
-
--- | Penalty for a soft-assertion. The default penalty is @1@, with all soft-assertions belonging
--- to the same objective goal. A positive weight and an optional group can be provided by using
--- the v'Penalty' constructor.
-data Penalty = DefaultPenalty                  -- ^ Default: Penalty of @1@ and no group attached
-             | Penalty Rational (Maybe String) -- ^ Penalty with a weight and an optional group
-             deriving Show
-
--- | Objective of optimization. We can minimize, maximize, or give a soft assertion with a penalty
--- for not satisfying it.
-data Objective a = Minimize          String a         -- ^ Minimize this metric
-                 | Maximize          String a         -- ^ Maximize this metric
-                 | AssertWithPenalty String a Penalty -- ^ A soft assertion, with an associated penalty
-                 deriving (Show, Functor)
-
--- | The name of the objective
-objectiveName :: Objective a -> String
-objectiveName (Minimize          s _)   = s
-objectiveName (Maximize          s _)   = s
-objectiveName (AssertWithPenalty s _ _) = s
-
--- | The state we keep track of as we interact with the solver
-data QueryState = QueryState { queryAsk                 :: Maybe Int -> String -> IO String
-                             , querySend                :: Maybe Int -> String -> IO ()
-                             , queryRetrieveResponse    :: Maybe Int -> IO String
-                             , queryConfig              :: SMTConfig
-                             , queryTerminate           :: Maybe C.SomeException -> IO ()
-                             , queryTimeOutValue        :: Maybe Int
-                             , queryAssertionStackDepth :: Int
-                             }
-
--- | Computations which support query operations.
-class Monad m => MonadQuery m where
-  queryState :: m State
-
-  default queryState :: (MonadTrans t, MonadQuery m', m ~ t m') => m State
-  queryState = lift queryState
-
-instance MonadQuery m             => MonadQuery (ExceptT e m)
-instance MonadQuery m             => MonadQuery (MaybeT m)
-instance MonadQuery m             => MonadQuery (ReaderT r m)
-instance MonadQuery m             => MonadQuery (SS.StateT s m)
-instance MonadQuery m             => MonadQuery (LS.StateT s m)
-instance (MonadQuery m, Monoid w) => MonadQuery (SW.WriterT w m)
-instance (MonadQuery m, Monoid w) => MonadQuery (LW.WriterT w m)
-
--- | A query is a user-guided mechanism to directly communicate and extract
--- results from the solver. A generalization of 'Data.SBV.Query'.
-newtype QueryT m a = QueryT { runQueryT :: ReaderT State m a }
-    deriving newtype (Applicative, Functor, Monad, MonadIO, MonadTrans, MonadError e, MonadState s, MonadWriter w)
-
-instance Monad m => MonadQuery (QueryT m) where
-  queryState = QueryT ask
-
-mapQueryT :: (ReaderT State m a -> ReaderT State n b) -> QueryT m a -> QueryT n b
-mapQueryT f = QueryT . f . runQueryT
-{-# INLINE mapQueryT #-}
-
--- Have to define this one by hand, because we use ReaderT in the implementation
-instance MonadReader r m => MonadReader r (QueryT m) where
-  ask = lift ask
-  local f = mapQueryT $ mapReaderT $ local f
-
--- | A query is a user-guided mechanism to directly communicate and extract
--- results from the solver.
-type Query = QueryT IO
-
-instance MonadSymbolic Query where
-   symbolicEnv = queryState
-
-instance NFData OptimizeStyle where
-   rnf x = x `seq` ()
-
-instance NFData Penalty where
-   rnf DefaultPenalty  = ()
-   rnf (Penalty p mbs) = rnf p `seq` rnf mbs
-
-instance NFData a => NFData (Objective a) where
-   rnf (Minimize          s a)   = rnf s `seq` rnf a
-   rnf (Maximize          s a)   = rnf s `seq` rnf a
-   rnf (AssertWithPenalty s a p) = rnf s `seq` rnf a `seq` rnf p
-
--- | A result can either produce something at the top or as a lambda/constraint. Distinguish by inputs
-data ResultInp = ResultTopInps ([NamedSymVar], [NamedSymVar])  -- user inputs -- trackers
-               | ResultLamInps [(Quantifier, NamedSymVar)]     -- for constraints, we can have quantifiers
-               deriving G.Data
-
-instance NFData ResultInp where
-   rnf (ResultTopInps xs) = rnf xs
-   rnf (ResultLamInps xs) = rnf xs
-
--- | Several data about the program
-data ProgInfo = ProgInfo { hasQuants         :: Bool
-                         , progSpecialRels   :: [SpecialRelOp]
-                         , progTransClosures :: [(String, String)]
-                         }
-                         deriving G.Data
-
-instance NFData ProgInfo where
-   rnf (ProgInfo a b c) = rnf a `seq` rnf b `seq` rnf c
-
-deriving instance G.Data CallStack
-deriving instance G.Data SrcLoc
-
--- | Result of running a symbolic computation
-data Result = Result { progInfo       :: ProgInfo                                     -- ^ various info we collect about the program
-                     , reskinds       :: Set.Set Kind                                 -- ^ kinds used in the program
-                     , resTraces      :: [(String, CV)]                               -- ^ quick-check counter-example information (if any)
-                     , resObservables :: [(String, CV -> Bool, SV)]                   -- ^ observable expressions (part of the model)
-                     , resUISegs      :: [(String, [String])]                         -- ^ uninterpeted code segments
-                     , resParams      :: ResultInp                                    -- ^ top-inputs or lambda params
-                     , resConsts      :: (CnstMap, [(SV, CV)])                        -- ^ constants
-                     , resTables      :: [((Int, Kind, Kind), [SV])]                  -- ^ tables (automatically constructed) (tableno, index-type, result-type) elts
-                     , resUIConsts    :: [(String, (Bool, Maybe [String], SBVType))]  -- ^ uninterpreted constants
-                     , resDefinitions :: [(String, (SMTDef, SBVType))]                -- ^ definitions created via smtFunction
-                     , resAsgns       :: SBVPgm                                       -- ^ assignments
-                     , resConstraints :: S.Seq (Bool, [(String, String)], SV)         -- ^ additional constraints (boolean)
-                     , resAssertions  :: [(String, Maybe CallStack, SV)]              -- ^ assertions
-                     , resOutputs     :: [SV]                                         -- ^ outputs
-                     }
-                     deriving G.Data
-
--- Show instance for 'Result'. Only for debugging purposes.
-instance Show Result where
-  -- If there's nothing interesting going on, just print the constant. Note that the
-  -- definition of interesting here is rather subjective; but essentially if we reduced
-  -- the result to a single constant already, without any reference to anything.
-  show Result{resConsts=(_, cs), resOutputs=[r]}
-    | Just c <- r `lookup` cs
-    = show c
-  show (Result _ kinds _ _ cgs params (_, cs) ts uis defns xs cstrs asserts os) = intercalate "\n" $
-                   (if null usorts then [] else "SORTS" : map ("  " ++) usorts)
-                ++ (case params of
-                      ResultTopInps (i, t) -> "INPUTS" : map shn i ++ (if null t then [] else "TRACKER VARS" : map shn t)
-                      ResultLamInps qs     -> "LAMBDA-CONSTRAINT PARAMS" : map shq qs
-                   )
-                ++ ["CONSTANTS"]
-                ++ concatMap shc cs
-                ++ ["TABLES"]
-                ++ map sht ts
-                ++ ["UNINTERPRETED CONSTANTS"]
-                ++ map shui uis
-                ++ ["USER GIVEN CODE SEGMENTS"]
-                ++ concatMap shcg cgs
-                ++ ["AXIOMS-DEFINITIONS"]
-                ++ map show defns
-                ++ ["DEFINE"]
-                ++ map (\(s, e) -> "  " ++ shs s ++ " = " ++ show e) (F.toList (pgmAssignments xs))
-                ++ ["CONSTRAINTS"]
-                ++ map (("  " ++) . shCstr) (F.toList cstrs)
-                ++ ["ASSERTIONS"]
-                ++ map (("  "++) . shAssert) asserts
-                ++ ["OUTPUTS"]
-                ++ sh2 os
-    where sh2 :: Show a => [a] -> [String]
-          sh2 = map (("  "++) . show)
-
-          usorts = [sh s t | KUserSort s t <- Set.toList kinds]
-                   where sh s Nothing   = s
-                         sh s (Just es) = s ++ " (" ++ intercalate ", " es ++ ")"
-
-          shs sv = show sv ++ " :: " ++ show (swKind sv)
-
-          sht ((i, at, rt), es)  = "  Table " ++ show i ++ " : " ++ show at ++ "->" ++ show rt ++ " = " ++ show es
-
-          shc (sv, cv)
-            | sv == falseSV || sv == trueSV
-            = []
-            | True
-            = ["  " ++ show sv ++ " = " ++ show cv]
-
-          shcg (s, ss) = ("Variable: " ++ s) : map ("  " ++) ss
-
-          shn (NamedSymVar sv nm) = "  " <> ni <> " :: " ++ show (swKind sv) ++ alias
-            where ni = show sv
-
-                  alias | ni == T.unpack nm = ""
-                        | True              = ", aliasing " ++ show nm
-
-          shq (q, v) = shn v ++ ", " ++ if q == ALL then "universal" else "existential"
-
-          shui (nm, t) = "  [uninterpreted] " ++ nm ++ " :: " ++ show t
-
-          shCstr (isSoft, [], c)               = soft isSoft ++ show c
-          shCstr (isSoft, [(":named", nm)], c) = soft isSoft ++ nm ++ ": " ++ show c
-          shCstr (isSoft, attrs, c)            = soft isSoft ++ show c ++ " (attributes: " ++ show attrs ++ ")"
-
-          soft True  = "[SOFT] "
-          soft False = ""
-
-          shAssert (nm, stk, p) = "  -- assertion: " ++ nm ++ " " ++ maybe "[No location]"
-#if MIN_VERSION_base(4,9,0)
-                prettyCallStack
-#else
-                showCallStack
-#endif
-                stk ++ ": " ++ show p
-
--- | Expression map, used for hash-consing
-type ExprMap = Map.Map SBVExpr SV
-
--- | Constants are stored in a map, for hash-consing.
-type CnstMap = Map.Map CV SV
-
--- | Kinds used in the program; used for determining the final SMT-Lib logic to pick
-type KindSet = Set.Set Kind
-
--- | Tables generated during a symbolic run
-type TableMap = Map.Map (Kind, Kind, [SV]) Int
-
--- | Uninterpreted-constants generated during a symbolic run
-type UIMap = Map.Map String (Bool, Maybe [String], SBVType)   -- If Bool is true, then this is a curried function
-
--- | Code-segments for Uninterpreted-constants, as given by the user
-type CgMap = Map.Map String [String]
-
--- | Cached values, implementing sharing
-type Cache a = IMap.IntMap [(StableName (State -> IO a), a)]
-
--- | Stage of an interactive run
-data IStage = ISetup        -- Before we initiate contact.
-            | ISafe         -- In the context of a safe/safeWith call
-            | IRun          -- After the contact is started
-
--- | Are we checking safety
-isSafetyCheckingIStage :: IStage -> Bool
-isSafetyCheckingIStage s = case s of
-                             ISetup -> False
-                             ISafe  -> True
-                             IRun   -> False
-
--- | Are we in setup?
-isSetupIStage :: IStage -> Bool
-isSetupIStage s = case s of
-                   ISetup -> True
-                   ISafe  -> False
-                   IRun   -> True
-
--- | Are we in a run?
-isRunIStage :: IStage -> Bool
-isRunIStage s = case s of
-                  ISetup -> False
-                  ISafe  -> False
-                  IRun   -> True
-
--- | Different means of running a symbolic piece of code
-data SBVRunMode = SMTMode QueryContext IStage Bool SMTConfig   -- ^ In regular mode, with a stage. Bool is True if this is SAT.
-                | CodeGen                                      -- ^ Code generation mode.
-                | LambdaGen (Maybe Int)                        -- ^ Inside a lambda-expression at level. If Nothing, then closed lambda.
-                | Concrete (Maybe (Bool, [(NamedSymVar, CV)])) -- ^ Concrete simulation mode, with given environment if any. If Nothing: Random.
-
--- Show instance for SBVRunMode; debugging purposes only
-instance Show SBVRunMode where
-   show (SMTMode qc ISetup True  _)  = "Satisfiability setup (" ++ show qc ++ ")"
-   show (SMTMode qc ISafe  True  _)  = "Safety setup (" ++ show qc ++ ")"
-   show (SMTMode qc IRun   True  _)  = "Satisfiability (" ++ show qc ++ ")"
-   show (SMTMode qc ISetup False _)  = "Proof setup (" ++ show qc ++ ")"
-   show (SMTMode qc ISafe  False _)  = error $ "ISafe-False is not an expected/supported combination for SBVRunMode! (" ++ show qc ++ ")"
-   show (SMTMode qc IRun   False _)  = "Proof (" ++ show qc ++ ")"
-   show CodeGen                      = "Code generation"
-   show LambdaGen{}                  = "Lambda generation"
-   show (Concrete Nothing)           = "Concrete evaluation with random values"
-   show (Concrete (Just (True, _)))  = "Concrete evaluation during model validation for sat"
-   show (Concrete (Just (False, _))) = "Concrete evaluation during model validation for prove"
-
--- | Is this a CodeGen run? (i.e., generating code)
-isCodeGenMode :: State -> IO Bool
-isCodeGenMode State{runMode} = do rm <- readIORef runMode
-                                  return $ case rm of
-                                             Concrete{}  -> False
-                                             SMTMode{}   -> False
-                                             LambdaGen{} -> False
-                                             CodeGen     -> True
-
--- | The state in query mode, i.e., additional context
-data IncState = IncState { rNewInps        :: IORef [NamedSymVar]   -- always existential!
-                         , rNewKinds       :: IORef KindSet
-                         , rNewConsts      :: IORef CnstMap
-                         , rNewTbls        :: IORef TableMap
-                         , rNewUIs         :: IORef UIMap
-                         , rNewAsgns       :: IORef SBVPgm
-                         , rNewConstraints :: IORef (S.Seq (Bool, [(String, String)], SV))
-                         }
-
--- | Get a new IncState
-newIncState :: IO IncState
-newIncState = do
-        is    <- newIORef []
-        ks    <- newIORef Set.empty
-        nc    <- newIORef Map.empty
-        tm    <- newIORef Map.empty
-        ui    <- newIORef Map.empty
-        pgm   <- newIORef (SBVPgm S.empty)
-        cstrs <- newIORef S.empty
-        return IncState { rNewInps        = is
-                        , rNewKinds       = ks
-                        , rNewConsts      = nc
-                        , rNewTbls        = tm
-                        , rNewUIs         = ui
-                        , rNewAsgns       = pgm
-                        , rNewConstraints = cstrs
-                        }
-
--- | Get a new IncState
-withNewIncState :: State -> (State -> IO a) -> IO (IncState, a)
-withNewIncState st cont = do
-        is <- newIncState
-        R.modifyIORef' (rIncState st) (const is)
-        r  <- cont st
-        finalIncState <- readIORef (rIncState st)
-        return (finalIncState, r)
-
--- | User defined inputs
-type UserInputs = S.Seq NamedSymVar
-
--- | Internally declared
-type InternInps = S.Seq NamedSymVar
-
--- | Entire set of names, for faster lookup
-type AllInps = Set.Set Name
-
--- | Inputs as a record of maps and sets. See above type-synonyms for their roles.
-data Inputs = Inputs { userInputs   :: !UserInputs
-                     , internInputs :: !InternInps
-                     , allInputs    :: !AllInps
-                     } deriving (Eq,Show)
-
--- | Inputs to a lambda-abstraction. These are quantified to handle constraints
-type LambdaInputs = S.Seq (Quantifier, NamedSymVar)
-
--- | Semigroup instance; combining according to indexes.
-instance Semigroup Inputs where
-  (Inputs lui lii lai) <> (Inputs rui rii rai) = Inputs (lui <> rui) (lii <> rii) (lai <> rai)
-
--- | Monoid instance, we start with no maps.
-instance Monoid Inputs where
-  mempty = Inputs { userInputs   = mempty
-                  , internInputs = mempty
-                  , allInputs    = mempty
-                  }
-
--- | Modify the user-inputs field
-onUserInputs :: (UserInputs -> UserInputs) -> Inputs -> Inputs
-onUserInputs f inp@Inputs{userInputs} = inp{userInputs = f userInputs}
-
--- | Modify the internal-inputs field
-onInternInputs :: (InternInps -> InternInps) -> Inputs -> Inputs
-onInternInputs f inp@Inputs{internInputs} = inp{internInputs = f internInputs}
-
--- | Modify the all-inputs field
-onAllInputs :: (AllInps -> AllInps) -> Inputs -> Inputs
-onAllInputs f inp@Inputs{allInputs} = inp{allInputs = f allInputs}
-
--- | Add a new internal input
-addInternInput :: SV -> Name -> Inputs -> Inputs
-addInternInput sv nm = goAll . goIntern
-  where !new = toNamedSV sv nm
-        goIntern = onInternInputs (S.|> new)
-        goAll    = onAllInputs    (Set.insert nm)
-
--- | Add a new user input
-addUserInput :: SV -> Name -> Inputs -> Inputs
-addUserInput sv nm = goAll . goUser
-  where new    = toNamedSV sv nm
-        goUser = onUserInputs (S.|> new)        -- add to the end of the sequence
-        goAll  = onAllInputs  (Set.insert nm)
-
--- | Find a user-input from its SV. Note that only level-0 vars
--- can be found this way.
-lookupInput :: (a -> SV) -> SV -> S.Seq a -> Maybe a
-lookupInput f sv ns
-   | l == Just 0 = res
-   | True        = Nothing  -- l != Just 0, a lambda var, whether top-level or in a scope, so we ignore
-  where
-    (_, l, i) = getId (swNodeId sv)
-    svs       = fmap f ns
-    res       = case S.lookup i ns of -- Nothing on negative Int or Int > length seq
-                  Nothing    -> secondLookup
-                  x@(Just e) -> if sv == f e then x else secondLookup
-                    -- we try the fast lookup first, if the node ids don't match then
-                    -- we use the more expensive O (n) to find the index and the elem
-    secondLookup = S.elemIndexL sv svs >>= flip S.lookup ns
-
--- | A defined function/value
-data SMTDef = SMTDef Kind             -- ^ Final kind of the definition (resulting kind, not the params)
-                     [String]         -- ^ other definitions it refers to
-                     (Maybe String)   -- ^ parameter string
-                     (Int -> String)  -- ^ Body, in SMTLib syntax, given the tab amount
-            deriving G.Data
-
--- | For debug purposes
-instance Show SMTDef where
-  show (SMTDef fk frees p body) = unlines [ "-- User defined function:"
-                                          , "-- Final return type    : " ++ show fk
-                                          , "-- Refers to            : " ++ intercalate ", " frees
-                                          , "-- Parameters           : " ++ fromMaybe "NONE" p
-                                          , "-- Body                 : "
-                                          , body 2
-                                          ]
-
--- | NFData instance for SMTDef
-instance NFData SMTDef where
-  rnf (SMTDef fk frees params body) = rnf fk `seq` rnf frees `seq` rnf params `seq` rnf body
-
--- | The state of the symbolic interpreter
-data State  = State { sbvContext          :: SBVContext
-                    , pathCond            :: SVal                             -- ^ kind KBool
-                    , stCfg               :: SMTConfig
-                    , startTime           :: UTCTime
-                    , rProgInfo           :: IORef ProgInfo
-                    , runMode             :: IORef SBVRunMode
-                    , rIncState           :: IORef IncState
-                    , rCInfo              :: IORef [(String, CV)]
-                    , rObservables        :: IORef (S.Seq (Name, CV -> Bool, SV))
-                    , rctr                :: IORef Int             -- Used for numbering SVs
-                    , freshNameCtr        :: IORef Int             -- Used for calls to some
-                    , rLambdaLevel        :: IORef (Maybe Int)     -- If Nothing, then top-level lambda
-                    , rUsedKinds          :: IORef KindSet
-                    , rUsedLbls           :: IORef (Set.Set String)
-                    , rinps               :: IORef Inputs
-                    , rlambdaInps         :: IORef LambdaInputs
-                    , rConstraints        :: IORef (S.Seq (Bool, [(String, String)], SV))
-                    , rPartitionVars      :: IORef [String]
-                    , routs               :: IORef [SV]
-                    , rtblMap             :: IORef TableMap
-                    , spgm                :: IORef SBVPgm
-                    , rconstMap           :: IORef CnstMap
-                    , rexprMap            :: IORef ExprMap
-                    , rUIMap              :: IORef UIMap
-                    , rUserFuncs          :: IORef (Set.Set String) -- Functions that the user wanted explicit code generation for
-                    , rCgMap              :: IORef CgMap
-                    , rDefns              :: IORef [(String, (SMTDef, SBVType))]
-                    , rSMTOptions         :: IORef [SMTOption]
-                    , rOptGoals           :: IORef [Objective (SV, SV)]
-                    , rAsserts            :: IORef [(String, Maybe CallStack, SV)]
-                    , rOutstandingAsserts :: IORef Bool            -- Did we send an assert after the last check-sat call?
-                    , rSVCache            :: IORef (Cache SV)
-                    , rQueryState         :: IORef (Maybe QueryState)
-                    , parentState         :: Maybe State  -- Pointer to our parent if we're in a sublevel
-                    }
-
--- | Chase to the root state. No infinite chains!
-getRootState :: State -> State
-getRootState st = maybe st getRootState (parentState st)
-
--- NFData is a bit of a lie, but it's sufficient, most of the content is iorefs that we don't want to touch
-instance NFData State where
-   rnf State{} = ()
-
--- | Get the current path condition
-getSValPathCondition :: State -> SVal
-getSValPathCondition = pathCond
-
--- | Extend the path condition with the given test value.
-extendSValPathCondition :: State -> (SVal -> SVal) -> State
-extendSValPathCondition st f = st{pathCond = f (pathCond st)}
-
--- | Are we running in proof mode?
-inSMTMode :: State -> IO Bool
-inSMTMode State{runMode} = do rm <- readIORef runMode
-                              return $ case rm of
-                                         CodeGen     -> False
-                                         LambdaGen{} -> False
-                                         Concrete{}  -> False
-                                         SMTMode{}   -> True
-
--- | The "Symbolic" value. Either a constant (@Left@) or a symbolic
--- value (@Right Cached@). Note that caching is essential for making
--- sure sharing is preserved.
-data SVal = SVal !Kind !(Either CV (Cached SV))
-
--- | Kind instance for SVal simply passes the kind out
-instance HasKind SVal where
-  kindOf (SVal k _) = k
-
--- Show instance for t'SVal'. Not particularly "desirable", but will do if needed
--- NB. We do not show the type info on constant KBool values, since there's no
--- implicit "fromBoolean" applied to Booleans in Haskell; and thus a statement
--- of the form "True :: SBool" is just meaningless. (There should be a fromBoolean!)
-instance Show SVal where
-  show (SVal KBool (Left c))  = showCV False c
-  show (SVal k     (Left c))  = showCV False c ++ " :: " ++ show k
-  show (SVal k     (Right _)) =         "<symbolic> :: " ++ show k
-
--- | Things we do not support in interactive mode, at least for now!
-noInteractive :: [String] -> a
-noInteractive ss = error $ unlines $  ""
-                                   :  "*** Data.SBV: Unsupported interactive/query mode feature."
-                                   :  map ("***  " ++) ss
-                                   ++ ["*** Data.SBV: Please report this as a feature request!"]
-
--- | Things we do not support in interactive mode, nor we ever intend to
-noInteractiveEver :: [String] -> a
-noInteractiveEver ss = error $ unlines $  ""
-                                       :  "*** Data.SBV: Unsupported interactive/query mode feature."
-                                       :  map ("***  " ++) ss
-
--- | Modification of the state, but carefully handling the interactive tasks.
--- Note that the state is always updated regardless of the mode, but we get
--- to also perform extra operation in interactive mode. (Typically error out, but also simply
--- ignore if it has no impact.)
-modifyState :: State -> (State -> IORef a) -> (a -> a) -> IO () -> IO ()
-modifyState st@State{runMode} field update interactiveUpdate = do
-        R.modifyIORef' (field st) update
-        rm <- readIORef runMode
-        case rm of
-          SMTMode _ IRun _ _ -> interactiveUpdate
-          _                  -> return ()
-
--- | Modify the incremental state
-modifyIncState  :: State -> (IncState -> IORef a) -> (a -> a) -> IO ()
-modifyIncState State{rIncState} field update = do
-        incState <- readIORef rIncState
-        R.modifyIORef' (field incState) update
-
--- | Add an observable
--- notice that we cons like a list, we should build at the end of the seq, but cons to preserve semantics for now
-recordObservable :: State -> String -> (CV -> Bool) -> SV -> IO ()
-recordObservable st (T.pack -> nm) chk sv = modifyState st rObservables ((nm, chk, sv) S.<|) (return ())
-
--- | Increment the variable counter
-incrementInternalCounter :: State -> IO Int
-incrementInternalCounter st = do ctr <- readIORef (rctr st)
-                                 modifyState st rctr (+1) (return ())
-                                 return ctr
-{-# INLINE incrementInternalCounter #-}
-
--- | Increment the fresh-var counter
-incrementFreshNameCounter :: State -> IO Int
-incrementFreshNameCounter st = do ctr <- readIORef (freshNameCtr st)
-                                  modifyState st freshNameCtr (+1) (return ())
-                                  return ctr
-{-# INLINE incrementFreshNameCounter #-}
-
--- | Kind of code we have for uninterpretation
-data UICodeKind = UINone Bool     -- no code. If bool is true, then curried.
-                | UISMT  SMTDef   -- SMTLib, first argument are the free-variables in it
-                | UICgC  [String] -- Code-gen, currently only C
-
--- | A newtype wrapper for uninterpreted function names. This is in preparation
--- for a possibility of having other alternatives here, which we haven't needed so far.
-newtype UIName = UIGiven String -- ^ Full name
-
--- | Uninterpreted constants and functions. An uninterpreted constant is
--- a value that is indexed by its name. The only property the prover assumes
--- about these values are that they are equivalent to themselves; i.e., (for
--- functions) they return the same results when applied to same arguments.
--- We support uninterpreted-functions as a general means of black-box'ing
--- operations that are /irrelevant/ for the purposes of the proof; i.e., when
--- the proofs can be performed without any knowledge about the function itself.
-svUninterpreted :: Kind -> UIName -> UICodeKind -> [SVal] -> SVal
-svUninterpreted k nm code args = svUninterpretedGen k nm code args Nothing
-
-svUninterpretedNamedArgs :: Kind -> UIName -> UICodeKind -> [(SVal, String)] -> SVal
-svUninterpretedNamedArgs k nm code args = svUninterpretedGen k nm code (map fst args) (Just (map snd args))
-
-svUninterpretedGen :: Kind -> UIName -> UICodeKind -> [SVal] -> Maybe [String] -> SVal
-svUninterpretedGen k nm code args mbArgNames = SVal k $ Right $ cache result
-  where result st = do let ty = SBVType (map kindOf args ++ [k])
-                       nm' <- newUninterpreted st nm mbArgNames ty code
-                       sws <- mapM (svToSV st) args
-                       mapM_ forceSVArg sws
-                       newExpr st k $ SBVApp (Uninterpreted nm') sws
-
--- | Generate a unique name for the fiven function based on the object's stable name
-prefixNameToUnique :: State -> String -> IO String
-prefixNameToUnique st pre = do
-   uiMap <- readIORef (rUIMap st)
-
-   let suffix 0 = pre
-       suffix i = pre ++ "_" ++ show i
-
-   case [cand | i <- [0::Int ..], let cand = suffix i, cand `Map.notMember` uiMap] of
-      (n:_) -> pure n
-      []    -> error $ "genUniqueName: Can't generate a unique name for prefix: " ++ pre   -- can't happen
-
--- | Create a new uninterpreted symbol, possibly with user given code. This function might change
--- the name given, putting bars around it if needed. That's the name returned.
-newUninterpreted :: State -> UIName -> Maybe [String] -> SBVType -> UICodeKind -> IO String
-newUninterpreted st uiName mbArgNames t uiCode = do
-
-  candName <- case uiName of
-                UIGiven n -> pure n
-
-      -- determine the final name
-  let nm = case () of
-             () | "__internal_sbv_" `isPrefixOf` candName -> candName                -- internal names go thru
-                | True                                    -> barify candName         -- surround with bars if not legitimate in SMTLib
-
-      extraComment = case uiName of
-                      UIGiven  n | nm /= n -> " (Given: " ++ n ++ ")"
-                      _                    -> ""
-
-  -- Check if reserved:
-  when (isReserved nm) $
-      error $ unlines [ ""
-                      , "*** Data.SBV: User given name " ++ show nm ++ " is a reserved name in SMTLib."
-                      , "***"
-                      , "*** Please use a different name to avoid collisions."
-                      ]
-
-  isCurried <- case uiCode of
-                 UINone c -> pure c
-                 UISMT d  -> do modifyState st rDefns (\defs -> (nm, (d, t)) : filter (\(onm, _) -> onm /= nm) defs)
-                                  $ noInteractive [ "Defined functions (smtFunction):"
-                                                  , "  Name: " ++ nm ++ extraComment
-                                                  , "  Type: " ++ show t
-                                                  , ""
-                                                  , "You should explicitly register these functions by calling"
-                                                  , "the function 'registerFunction' on them before starting the query section."
-                                                  ]
-                                pure True
-                 UICgC c  -> -- No need to record the code in interactive mode: CodeGen doesn't use interactive
-                             do modifyState st rCgMap (Map.insert nm c) (return ())
-                                pure True
-
-  let checkType :: SBVType -> r -> r
-      checkType t' cont
-        | t /= t' = error $  "Uninterpreted constant " ++ show nm ++ extraComment ++ " used at incompatible types\n"
-                          ++ "      Current type      : " ++ show t ++ "\n"
-                          ++ "      Previously used at: " ++ show t'
-        | True    = cont
-
-  uiMap <- readIORef (rUIMap st)
-  case nm `Map.lookup` uiMap of
-    Just (_, _, t') -> checkType t' (return ())
-    Nothing         -> modifyState st rUIMap (Map.insert nm (isCurried, mbArgNames, t))
-                         $ modifyIncState st rNewUIs
-                                            (\newUIs -> case nm `Map.lookup` newUIs of
-                                                          Just (_, _, t') -> checkType t' newUIs
-                                                          Nothing         -> Map.insert nm (isCurried, mbArgNames, t) newUIs)
-
-  pure nm
-
--- | Add a new sAssert based constraint
-addAssertion :: State -> Maybe CallStack -> String -> SV -> IO ()
-addAssertion st cs msg cond = modifyState st rAsserts ((msg, cs, cond):)
-                                        $ noInteractive [ "Named assertions (sAssert):"
-                                                        , "  Tag: " ++ msg
-                                                        , "  Loc: " ++ maybe "Unknown" show cs
-                                                        ]
-
--- | Create an internal variable, which acts as an input but isn't visible to the user.
--- Such variables are existentially quantified in a SAT context, and universally quantified
--- in a proof context.
-newInternalVariable :: State -> Kind -> IO SV
-newInternalVariable st k = do NamedSymVar sv nm <- newSV st k
-                              let n = "__internal_sbv_" <> nm
-                                  v = NamedSymVar sv n
-                              modifyState st rinps (addUserInput sv n) $ modifyIncState st rNewInps (v :)
-                              return sv
-{-# INLINE newInternalVariable #-}
-
--- | Create a variable to be used in a constraint-expression
-quantVar :: Quantifier -> State -> Kind -> IO SV
-quantVar q st k = do v@(NamedSymVar sv _) <- newSV st k
-                     modifyState st rlambdaInps (S.|> (q, v)) (return ())
-                     return sv
-{-# INLINE quantVar #-}
-
--- | Create a variable to be used in a lambda-expression
-lambdaVar :: State -> Kind -> IO SV
-lambdaVar = quantVar ALL
-{-# INLINE lambdaVar #-}
-
--- | Create a new SV
-newSV :: State -> Kind -> IO NamedSymVar
-newSV st k = do ctr <- incrementInternalCounter st
-                ll  <- readIORef (rLambdaLevel st)
-                let sv = SV k (NodeId (sbvContext st, ll, ctr))
-                registerKind st k
-                return $ NamedSymVar sv $ T.pack (show sv)
-{-# INLINE newSV #-}
-
--- | Register a new kind with the system, used for uninterpreted sorts.
--- NB: Is it safe to have new kinds in query mode? It could be that
--- the new kind might introduce a constraint that effects the logic. For
--- instance, if we're seeing 'Double' for the first time and using a BV
--- logic, then things would fall apart. But this should be rare, and hopefully
--- the success-response checking mechanism will catch the rare cases where this
--- is an issue. In either case, the user can always arrange for the right
--- logic by calling 'Data.SBV.setLogic' appropriately, so it seems safe to just
--- allow for this.
-registerKind :: State -> Kind -> IO ()
-registerKind st k
-  | KUserSort sortName _ <- k, isReserved sortName
-  = error $ "SBV: " ++ show sortName ++ " is a reserved sort; please use a different name."
-  | True
-  = do -- Adding a kind to the incState is tricky; we only need to add it
-       --     *    If it's an uninterpreted sort that's not already in the general state
-       --     * OR If it's a tuple-sort whose cardinality isn't already in the general state
-       --     * OR If it's a list that's not already in the general state (so we can send the flatten commands)
-
-       existingKinds <- readIORef (rUsedKinds st)
-
-       modifyState st rUsedKinds (Set.insert k) $ do
-
-                          -- Why do we discriminate here? Because the incremental context is sensitive to the
-                          -- order: In particular, if an uninterpreted kind is already in there, we don't
-                          -- want to re-add because double-declaration would be wrong. See 'cvtInc' for details.
-                          let needsAdding = case k of
-                                              KUserSort{} -> k `notElem` existingKinds
-                                              KList{}     -> k `notElem` existingKinds
-                                              KTuple nks  -> length nks `notElem` [length oks | KTuple oks <- Set.toList existingKinds]
-                                              KMaybe{}    -> k `notElem` existingKinds
-                                              KEither{}   -> k `notElem` existingKinds
-                                              _           -> False
-
-                          when needsAdding $ modifyIncState st rNewKinds (Set.insert k)
-
-       -- Don't forget to register subkinds!
-       case k of
-         KBool     {}    -> return ()
-         KBounded  {}    -> return ()
-         KUnbounded{}    -> return ()
-         KReal     {}    -> return ()
-         KUserSort {}    -> return ()
-         KFloat    {}    -> return ()
-         KDouble   {}    -> return ()
-         KFP       {}    -> return ()
-         KRational {}    -> return ()
-         KChar     {}    -> return ()
-         KString   {}    -> return ()
-         KList     ek    -> registerKind st ek
-         KSet      ek    -> registerKind st ek
-         KTuple    eks   -> mapM_ (registerKind st) eks
-         KMaybe    ke    -> registerKind st ke
-         KEither   k1 k2 -> mapM_ (registerKind st) [k1, k2]
-         KArray    k1 k2 -> mapM_ (registerKind st) [k1, k2]
-
--- | Register a new label with the system, making sure they are unique and have no '|'s in them
-registerLabel :: String -> State -> String -> IO ()
-registerLabel whence st nm
-  | isReserved nm
-  = err "is a reserved string; please use a different name."
-  | '|' `elem` nm
-  = err "contains the character `|', which is not allowed!"
-  | '\\' `elem` nm
-  = err "contains the character `\\', which is not allowed!"
-  | True
-  = do old <- readIORef $ rUsedLbls st
-       if nm `Set.member` old
-          then err "is used multiple times. Please do not use duplicate names!"
-          else modifyState st rUsedLbls (Set.insert nm) (return ())
-
-  where err w = error $ "SBV (" ++ whence ++ "): " ++ show nm ++ " " ++ w
-
--- | Create a new constant; hash-cons as necessary
-newConst :: State -> CV -> IO SV
-newConst st c = do
-  constMap <- readIORef (rconstMap st)
-  case c `Map.lookup` constMap of
-    -- NB. Unlike in 'newExpr', we don't have to make sure the returned sv
-    -- has the kind we asked for, because the constMap stores the full CV
-    -- which already has a kind field in it.
-    Just sv -> return sv
-    Nothing -> do (NamedSymVar sv _) <- newSV st (kindOf c)
-                  let ins = Map.insert c sv
-                  modifyState st rconstMap ins $ modifyIncState st rNewConsts ins
-                  return sv
-{-# INLINE newConst #-}
-
--- | Create a new table; hash-cons as necessary
-getTableIndex :: State -> Kind -> Kind -> [SV] -> IO Int
-getTableIndex st at rt elts = do
-  let key = (at, rt, elts)
-  tblMap <- readIORef (rtblMap st)
-  case key `Map.lookup` tblMap of
-    Just i -> return i
-    _      -> do let i   = Map.size tblMap
-                     upd = Map.insert key i
-                 modifyState st rtblMap upd $ modifyIncState st rNewTbls upd
-                 return i
-
--- | Create a new expression; hash-cons as necessary
-newExpr :: State -> Kind -> SBVExpr -> IO SV
-newExpr st k app = do
-   let e = reorder app
-   exprMap <- readIORef (rexprMap st)
-   case e `Map.lookup` exprMap of
-     -- NB. Check to make sure that the kind of the hash-consed value
-     -- is the same kind as we're requesting. This might look unnecessary,
-     -- at first, but `svSign` and `svUnsign` rely on this as we can
-     -- get the same expression but at a different type. See
-     -- <http://github.com/GaloisInc/cryptol/issues/566> as an example.
-     Just sv | kindOf sv == k -> return sv
-     _                        -> do (NamedSymVar sv _) <- newSV st k
-                                    checkConsistent sv e
-                                    let append (SBVPgm xs) = SBVPgm (xs S.|> (sv, e))
-                                    modifyState st spgm append $ modifyIncState st rNewAsgns append
-                                    modifyState st rexprMap (Map.insert e sv) (return ())
-                                    return sv
-{-# INLINE newExpr #-}
-
--- | In rare cases, we can get a context mismatch; so make sure the expression is well-formed.
--- This isn't a full solution, but handles the common case (hopefully!)
-checkConsistent :: SV -> SBVExpr -> IO ()
-checkConsistent lhs (SBVApp _ args) = mapM_ check args
-   where SV _ (NodeId (lhsContext, _, _)) = lhs
-         check (SV _ (NodeId (rhsContext, _, _)))
-           | lhsContext `compatibleContext` rhsContext
-           = pure ()
-           | True
-           = contextMismatchError lhsContext rhsContext
-{-# INLINE checkConsistent #-}
-
--- | Are these compatible contexts? Either the same, or one of them is global
-compatibleContext :: SBVContext -> SBVContext -> Bool
-compatibleContext c1 c2 = c1 == c2 || c1 == globalSBVContext || c2 == globalSBVContext
-{-# INLINE compatibleContext #-}
-
--- | Same as checkConsistent above, except in an array context
-checkCompatibleContext :: SBVContext -> SBVContext -> IO ()
-checkCompatibleContext ctx1 ctx2
-   | ctx1 `compatibleContext` ctx2
-   = pure ()
-   | True
-   = contextMismatchError ctx1 ctx2
-{-# INLINE checkCompatibleContext #-}
-
--- | Convert a symbolic value to an internal SV
-svToSV :: State -> SVal -> IO SV
-svToSV st (SVal _ (Left c))  = newConst st c
-svToSV st (SVal _ (Right f)) = uncache f st
-
--- | Generalization of 'Data.SBV.svToSymSV'
-svToSymSV :: MonadSymbolic m => SVal -> m SV
-svToSymSV sbv = do st <- symbolicEnv
-                   liftIO $ svToSV st sbv
-
--------------------------------------------------------------------------
--- * Symbolic Computations
--------------------------------------------------------------------------
--- | A Symbolic computation. Represented by a reader monad carrying the
--- state of the computation, layered on top of IO for creating unique
--- references to hold onto intermediate results.
-
--- | Computations which support symbolic operations
-class MonadIO m => MonadSymbolic m where
-  symbolicEnv :: m State
-
-  default symbolicEnv :: (MonadTrans t, MonadSymbolic m', m ~ t m') => m State
-  symbolicEnv = lift symbolicEnv
-
-instance MonadSymbolic m             => MonadSymbolic (ExceptT e m)
-instance MonadSymbolic m             => MonadSymbolic (MaybeT m)
-instance MonadSymbolic m             => MonadSymbolic (ReaderT r m)
-instance MonadSymbolic m             => MonadSymbolic (SS.StateT s m)
-instance MonadSymbolic m             => MonadSymbolic (LS.StateT s m)
-instance (MonadSymbolic m, Monoid w) => MonadSymbolic (SW.WriterT w m)
-instance (MonadSymbolic m, Monoid w) => MonadSymbolic (LW.WriterT w m)
-
--- | A generalization of 'Data.SBV.Symbolic'.
-newtype SymbolicT m a = SymbolicT { runSymbolicT :: ReaderT State m a }
-                   deriving newtype ( Applicative, Functor, Monad, MonadIO, MonadTrans
-                            , MonadError e, MonadState s, MonadWriter w
-#if MIN_VERSION_base(4,11,0)
-                            , Fail.MonadFail
-#endif
-                            )
-
--- | `MonadSymbolic` instance for `SymbolicT m`
-instance MonadIO m => MonadSymbolic (SymbolicT m) where
-  symbolicEnv = SymbolicT ask
-
--- | Map a computation over the symbolic transformer.
-mapSymbolicT :: (ReaderT State m a -> ReaderT State n b) -> SymbolicT m a -> SymbolicT n b
-mapSymbolicT f = SymbolicT . f . runSymbolicT
-{-# INLINE mapSymbolicT #-}
-
--- Have to define this one by hand, because we use ReaderT in the implementation
-instance MonadReader r m => MonadReader r (SymbolicT m) where
-  ask = lift ask
-  local f = mapSymbolicT $ mapReaderT $ local f
-
--- | 'Symbolic' is specialization of t'SymbolicT' to the `IO` monad. Unless you are using
--- transformers explicitly, this is the type you should prefer.
-type Symbolic = SymbolicT IO
-
--- | Create a symbolic value, based on the quantifier we have. If an
--- explicit quantifier is given, we just use that. If not, then we
--- pick the quantifier appropriately based on the run-mode.
--- @randomCV@ is used for generating random values for this variable
--- when used for @quickCheck@ or 'Data.SBV.Tools.GenTest.genTest' purposes.
-svMkSymVar :: VarContext -> Kind -> Maybe String -> State -> IO SVal
-svMkSymVar = svMkSymVarGen False
-
--- | Create an existentially quantified tracker variable
-svMkTrackerVar :: Kind -> String -> State -> IO SVal
-svMkTrackerVar k nm = svMkSymVarGen True (NonQueryVar (Just EX)) k (Just nm)
-
--- | Generalization of 'Data.SBV.sWordN'
-sWordN :: MonadSymbolic m => Int -> String -> m SVal
-sWordN w nm = symbolicEnv >>= liftIO . svMkSymVar (NonQueryVar Nothing) (KBounded False w) (Just nm)
-
--- | Generalization of 'Data.SBV.sWordN_'
-sWordN_ :: MonadSymbolic m => Int -> m SVal
-sWordN_ w = symbolicEnv >>= liftIO . svMkSymVar (NonQueryVar Nothing) (KBounded False w) Nothing
-
--- | Generalization of 'Data.SBV.sIntN'
-sIntN :: MonadSymbolic m => Int -> String -> m SVal
-sIntN w nm = symbolicEnv >>= liftIO . svMkSymVar (NonQueryVar Nothing) (KBounded True w) (Just nm)
-
--- | Generalization of 'Data.SBV.sIntN_'
-sIntN_ :: MonadSymbolic m => Int -> m SVal
-sIntN_ w = symbolicEnv >>= liftIO . svMkSymVar (NonQueryVar Nothing) (KBounded True w) Nothing
-
--- | Create a symbolic value, based on the quantifier we have. If an
--- explicit quantifier is given, we just use that. If not, then we
--- pick the quantifier appropriately based on the run-mode.
--- @randomCV@ is used for generating random values for this variable
--- when used for @quickCheck@ or 'Data.SBV.Tools.GenTest.genTest' purposes.
-svMkSymVarGen :: Bool -> VarContext -> Kind -> Maybe String -> State -> IO SVal
-svMkSymVarGen isTracker varContext k mbNm st = do
-        rm <- readIORef (runMode st)
-
-        let varInfo = case mbNm of
-                        Nothing -> "While defining a variable of type " ++ show k
-                        Just nm -> "While defining: " ++ nm ++ " :: " ++ show k
-
-            disallow what  = error $ unlines [ "*** Data.SBV: Unsupported: " ++ what
-                                             , "***"
-                                             , "*** " ++ varInfo
-                                             , "*** "
-                                             , "*** In mode: " ++ show rm
-                                             ]
-
-            noUI cont
-              | isUserSort k  = disallow "User defined sorts"
-              | True          = cont
-
-            (isQueryVar, mbQ) = case varContext of
-                                  NonQueryVar mq -> (False, mq)
-                                  QueryVar       -> (True,  Just EX)
-
-            mkS q = do (NamedSymVar sv internalName) <- newSV st k
-                       let nm = fromMaybe (T.unpack internalName) mbNm
-                       introduceUserName st (isQueryVar, isTracker) nm k q sv
-
-            mkC cv = do registerKind st k
-                        modifyState st rCInfo ((fromMaybe "_" mbNm, cv):) (return ())
-                        return $ SVal k (Left cv)
-
-        case (mbQ, rm) of
-          (Just q,  SMTMode{}          ) -> mkS q
-          (Nothing, SMTMode _ _ isSAT _) -> mkS (if isSAT then EX else ALL)
-
-          (Just EX, CodeGen{})           -> disallow "Existentially quantified variables"
-          (_      , CodeGen)             -> noUI $ mkS ALL  -- code generation, pick universal
-
-          (Just EX, Concrete Nothing)    -> disallow "Existentially quantified variables"
-          (_      , Concrete Nothing)    -> noUI (randomCV k >>= mkC)
-
-          (Just EX, LambdaGen{})         -> disallow "Existentially quantified variables"
-          (_,       LambdaGen{})         -> noUI $ mkS ALL
-
-          -- Model validation:
-          (_      , Concrete (Just (_isSat, env))) -> do
-                        let bad why conc = error $ unlines [ ""
-                                                           , "*** Data.SBV: " ++ why
-                                                           , "***"
-                                                           , "***   To turn validation off, use `cfg{validateModel = False}`"
-                                                           , "***"
-                                                           , "*** " ++ conc
-                                                           ]
-
-                            cant   = "Validation engine is not capable of handling this case. Failed to validate."
-                            report = "Please report this as a bug in SBV!"
-
-                        case () of
-                          () | isUserSort k -> bad ("Cannot validate models in the presence of user defined kinds, saw: "             ++ show k) cant
-
-                          _  -> do (NamedSymVar sv internalName) <- newSV st k
-
-                                   let nm = fromMaybe (T.unpack internalName) mbNm
-                                       nsv = toNamedSV' sv nm
-
-                                       -- Ignore the context equivalence check here. When validating, we are in a different
-                                       -- context; so they won't match
-                                       same (NamedSymVar (SV _ (NodeId (_, ll1, li1))) _)
-                                            (NamedSymVar (SV _ (NodeId (_, ll2, li2))) _) = (ll1, li1) == (ll2, li2)
-
-                                       cv = case [v | (nsv', v) <- env, nsv `same` nsv'] of
-                                              []    -> if isTracker
-                                                       then  -- The sole purpose of a tracker variable is to send the optimization
-                                                             -- directive to the solver, so we can name "expressions" that are minimized
-                                                             -- or maximized. There will be no constraints on these when we are doing
-                                                             -- the validation; in fact they will not even be used anywhere during a
-                                                             -- validation run. So, simply push a zero value that inhabits all metrics.
-                                                             mkConstCV k (0::Integer)
-                                                       else bad ("Cannot locate variable: " ++ show (nsv, k)) report
-                                              [c]  -> c
-                                              r    -> bad (   "Found multiple matching values for variable: " ++ show nsv
-                                                           ++ "\n*** " ++ show r) report
-
-                                   mkC cv
-
--- | Introduce a new user name. We simply append a suffix if we have seen this variable before.
-introduceUserName :: State -> (Bool, Bool) -> String -> Kind -> Quantifier -> SV -> IO SVal
-introduceUserName st@State{runMode} (isQueryVar, isTracker) nmOrig k q sv = do
-        old <- allInputs <$> readIORef (rinps st)
-
-        let nm  = mkUnique (T.pack nmOrig) old
-
-        -- If this is not a query variable and we're in a query, reject it.
-        -- See https://github.com/LeventErkok/sbv/issues/554 for the rationale.
-        -- In theory, it should be possible to support this, but fixing it is
-        -- rather costly as we'd have to track the regular updates and sync the
-        -- incremental state appropriately. Instead, we issue an error message
-        -- and ask the user to obey the query mode rules.
-        rm <- readIORef runMode
-        case rm of
-          SMTMode _ IRun _ _ | not isQueryVar -> noInteractiveEver [ "Adding a new input variable in query mode: " ++ show nm
-                                                                   , ""
-                                                                   , "Hint: Use freshVar/freshVar_ for introducing new inputs in query mode."
-                                                                   ]
-          _                                   -> pure ()
-
-        if isTracker && q == ALL
-           then error $ "SBV: Impossible happened! A universally quantified tracker variable is being introduced: " ++ show nm
-           else do let newInp olds = case q of
-                                      EX  -> toNamedSV sv nm : olds
-                                      ALL -> noInteractive [ "Adding a new universally quantified variable: "
-                                                           , "  Name      : " ++ show nm
-                                                           , "  Kind      : " ++ show k
-                                                           , "  Quantifier: Universal"
-                                                           , "  Node      : " ++ show sv
-                                                           , "Only existential variables are supported in query mode."
-                                                           ]
-                   if isTracker
-                      then modifyState st rinps (addInternInput sv nm)
-                                     $ noInteractive ["Adding a new tracker variable in interactive mode: " ++ show nm]
-                      else modifyState st rinps (addUserInput sv nm)
-                                     $ modifyIncState st rNewInps newInp
-                   return $ SVal k $ Right $ cache (const (return sv))
-
-   where -- The following can be rather slow if we keep reusing the same prefix, but I doubt it'll be a problem in practice
-         -- Also, the following will fail if we span the range of integers without finding a match, but your computer would
-         -- die way ahead of that happening if that's the case!
-         mkUnique :: T.Text -> Set.Set Name -> T.Text
-         mkUnique prefix names = case dropWhile (`Set.member` names) (prefix : [prefix <> "_" <> T.pack (show i) | i <- [(0::Int)..]]) of
-                                   h:_ -> h
-                                   _   -> error $ "mkUnique: Impossible happened! Couldn't get a unique name for " ++ show (prefix, names)
-
--- | Create a new state
-mkNewState :: MonadIO m => SMTConfig -> SBVRunMode -> m State
-mkNewState cfg currentRunMode = liftIO $ do
-     currTime           <- getCurrentTime
-     progInfo           <- newIORef ProgInfo { hasQuants         = False
-                                             , progSpecialRels   = []
-                                             , progTransClosures = []
-                                             }
-     rm                 <- newIORef currentRunMode
-     ctr                <- newIORef (-2) -- start from -2; False and True will always occupy the first two elements
-     fnctr              <- newIORef 0
-     lambda             <- newIORef $ case currentRunMode of
-                                        SMTMode{}     -> Just 0
-                                        CodeGen{}     -> Just 0
-                                        Concrete{}    -> Just 0
-                                        LambdaGen mbi -> mbi
-     cInfo              <- newIORef []
-     observes           <- newIORef mempty
-     pgm                <- newIORef (SBVPgm S.empty)
-     emap               <- newIORef Map.empty
-     cmap               <- newIORef Map.empty
-     inps               <- newIORef mempty
-     lambdaInps         <- newIORef mempty
-     outs               <- newIORef []
-     tables             <- newIORef Map.empty
-     userFuncs          <- newIORef Set.empty
-     uis                <- newIORef Map.empty
-     cgs                <- newIORef Map.empty
-     defns              <- newIORef []
-     swCache            <- newIORef IMap.empty
-     usedKinds          <- newIORef Set.empty
-     usedLbls           <- newIORef Set.empty
-     cstrs              <- newIORef S.empty
-     pvs                <- newIORef []
-     smtOpts            <- newIORef []
-     optGoals           <- newIORef []
-     asserts            <- newIORef []
-     outstandingAsserts <- newIORef False
-     istate             <- newIORef =<< newIncState
-     qstate             <- newIORef Nothing
-     ctx                <- genSBVContext
-     pure $ State { sbvContext          = ctx
-                  , runMode             = rm
-                  , stCfg               = cfg
-                  , startTime           = currTime
-                  , rProgInfo           = progInfo
-                  , pathCond            = SVal KBool (Left trueCV)
-                  , rIncState           = istate
-                  , rCInfo              = cInfo
-                  , rObservables        = observes
-                  , rctr                = ctr
-                  , freshNameCtr        = fnctr
-                  , rLambdaLevel        = lambda
-                  , rUsedKinds          = usedKinds
-                  , rUsedLbls           = usedLbls
-                  , rinps               = inps
-                  , rlambdaInps         = lambdaInps
-                  , routs               = outs
-                  , rtblMap             = tables
-                  , spgm                = pgm
-                  , rconstMap           = cmap
-                  , rexprMap            = emap
-                  , rUserFuncs          = userFuncs
-                  , rUIMap              = uis
-                  , rCgMap              = cgs
-                  , rDefns              = defns
-                  , rSVCache            = swCache
-                  , rConstraints        = cstrs
-                  , rPartitionVars      = pvs
-                  , rSMTOptions         = smtOpts
-                  , rOptGoals           = optGoals
-                  , rAsserts            = asserts
-                  , rOutstandingAsserts = outstandingAsserts
-                  , rQueryState         = qstate
-                  , parentState         = Nothing
-                  }
-
--- | Generalization of 'Data.SBV.runSymbolic'
-runSymbolic :: MonadIO m => SMTConfig -> SBVRunMode -> SymbolicT m a -> m (a, Result)
-runSymbolic cfg currentRunMode comp = do
-   st <- mkNewState cfg currentRunMode
-   runSymbolicInState st comp
-
--- | Catch the catastrophic case of context mismatch
-contextMismatchError :: SBVContext -> SBVContext -> a
-contextMismatchError ctx1 ctx2 = error $ unlines [
-                               "Data.SBV: Mismatched contexts detected."
-                             , "***"
-                             , "***   Current context: " ++ show ctx1
-                             , "***   Mixed with     : " ++ show ctx2
-                             , "***"
-                             , "*** This happens if you call a proof-function (prove/sat/runSMT/isSatisfiable) etc."
-                             , "*** while another one is in execution, or use results from one such call in another."
-                             , "*** Please avoid such nested calls, all interactions should be from the same context."
-                             , "*** See https://github.com/LeventErkok/sbv/issues/71 for several examples."
-                             ]
-
--- | Run a symbolic computation in a given state
-runSymbolicInState :: MonadIO m => State -> SymbolicT m a -> m (a, Result)
-runSymbolicInState st (SymbolicT c) = do
-   _ <- liftIO $ newConst st falseCV -- s(-2) == falseSV
-   _ <- liftIO $ newConst st trueCV  -- s(-1) == trueSV
-   r <- runReaderT c st
-   res <- liftIO $ extractSymbolicSimulationState st
-
-   -- Check that the state wasn't clobbered in any way
-   let check ctx | ctx == sbvContext st || ctx == globalSBVContext
-                 = pure ()
-                 | True
-                 = contextMismatchError (sbvContext st) ctx
-
-   mapM_ check $ nubOrd $ G.universeBi res
-
-   return (r, res)
-
--- | Grab the program from a running symbolic simulation state.
-extractSymbolicSimulationState :: State -> IO Result
-extractSymbolicSimulationState st@State{ runMode=rrm
-                                       , spgm=pgm, rinps=inps, rlambdaInps=linps, routs=outs, rtblMap=tables
-                                       , rUIMap=uis, rDefns=defns
-                                       , rAsserts=asserts, rUsedKinds=usedKinds, rCgMap=cgs, rCInfo=cInfo, rConstraints=cstrs
-                                       , rObservables=observes, rProgInfo=progInfo
-                                       } = do
-   SBVPgm rpgm  <- readIORef pgm
-
-   rm <- readIORef rrm
-
-   inpsO <- do Inputs{userInputs, internInputs} <- readIORef inps
-               ls <- readIORef linps
-
-               let lambdaOnly = case rm of
-                                  SMTMode{}   -> False
-                                  CodeGen{}   -> False
-                                  Concrete{}  -> False
-                                  LambdaGen{} -> True
-                   topInps = (F.toList userInputs, F.toList internInputs)
-                   lamInps = F.toList ls
-
-               if lambdaOnly
-                  then case topInps of
-                          ([], []) -> pure $ ResultLamInps (F.toList ls)
-                          (xs, ys) -> error $ unlines [ ""
-                                                      , "*** Data.SBV: Impossible happened; saw inputs in lambda mode."
-                                                      , "***"
-                                                      , "***   Inps    : " ++ show xs
-                                                      , "***   Trackers: " ++ show ys
-                                                      ]
-                  else case lamInps of
-                          [] -> pure $ ResultTopInps topInps
-                          _  -> error $ unlines [ ""
-                                                , "*** Data.SBV: Impossible happened; saw lambda inputs in regular mode."
-                                                , "***"
-                                                , "***   Params: " ++ show lamInps
-                                                ]
-
-   outsO <- reverse <$> readIORef outs
-
-   let swap  (a, b)              = (b, a)
-       cmp   (a, _) (b, _)       = a `compare` b
-       arrange (i, (at, rt, es)) = ((i, at, rt), es)
-
-   constMap <- readIORef (rconstMap st)
-   let cnsts = sortBy cmp . map swap . Map.toList $ constMap
-
-   tbls  <- map arrange . sortBy cmp . map swap . Map.toList <$> readIORef tables
-   ds    <- reverse <$> readIORef defns
-   unint <- do unints <- Map.toList <$> readIORef uis
-               -- drop those that has a definition associated with it
-               let defineds = map fst ds
-               pure [ui | ui@(nm, _) <- unints, nm `notElem` defineds]
-   knds  <- readIORef usedKinds
-   cgMap <- Map.toList <$> readIORef cgs
-
-   traceVals   <- reverse <$> readIORef cInfo
-   observables <- reverse . fmap (\(n,f,sv) -> (T.unpack n, f, sv)) . F.toList
-                  <$> readIORef observes
-   extraCstrs  <- readIORef cstrs
-   assertions  <- reverse <$> readIORef asserts
-
-   pinfo <- readIORef progInfo
-
-   return $ Result pinfo knds traceVals observables cgMap inpsO (constMap, cnsts) tbls unint ds (SBVPgm rpgm) extraCstrs assertions outsO
-
--- | Generalization of 'Data.SBV.addNewSMTOption'
-addNewSMTOption :: MonadSymbolic m => SMTOption -> m ()
-addNewSMTOption o = do st <- symbolicEnv
-                       liftIO $ modifyState st rSMTOptions (o:) (return ())
-
--- | Generalization of 'Data.SBV.imposeConstraint'
-imposeConstraint :: MonadSymbolic m => Bool -> [(String, String)] -> SVal -> m ()
-imposeConstraint isSoft attrs c = do st <- symbolicEnv
-                                     rm <- liftIO $ readIORef (runMode st)
-
-                                     case rm of
-                                       CodeGen -> error "SBV: constraints are not allowed in code-generation"
-                                       _       -> liftIO $ do mapM_ (registerLabel "Constraint" st) [nm | (":named",  nm) <- attrs]
-                                                              internalConstraint st isSoft attrs c
-
--- | Require a boolean condition to be true in the state. Only used for internal purposes.
-internalConstraint :: State -> Bool -> [(String, String)] -> SVal -> IO ()
-internalConstraint st isSoft attrs b = do v <- svToSV st b
-
-                                          rm <- liftIO $ readIORef (runMode st)
-
-                                          -- Are we running validation? If so, we always want to
-                                          -- add the constraint for debug purposes. Otherwise
-                                          -- we only add it if it's interesting; i.e., not directly
-                                          -- true or has some attributes.
-                                          let isValidating = case rm of
-                                                               SMTMode _ _ _ cfg -> validationRequested cfg
-                                                               CodeGen           -> False
-                                                               LambdaGen{}       -> False
-                                                               Concrete Nothing  -> False
-                                                               Concrete (Just _) -> True   -- The case when we *are* running the validation
-
-                                          let c           = (isSoft, attrs, v)
-                                              interesting = v /= trueSV || not (null attrs)
-
-                                          when (isValidating || interesting) $
-                                               modifyState st rConstraints (S.|> c)
-                                                            $ modifyIncState st rNewConstraints (S.|> c)
-
--- | Generalization of 'Data.SBV.addSValOptGoal'
-addSValOptGoal :: MonadSymbolic m => Objective SVal -> m ()
-addSValOptGoal obj = do st <- symbolicEnv
-
-                        -- create the tracking variable here for the metric
-                        let mkGoal nm orig = liftIO $ do origSV  <- svToSV st orig
-                                                         track   <- svMkTrackerVar (kindOf orig) nm st
-                                                         trackSV <- svToSV st track
-                                                         return (origSV, trackSV)
-
-                        let walk (Minimize          nm v)     = Minimize nm                     <$> mkGoal nm v
-                            walk (Maximize          nm v)     = Maximize nm                     <$> mkGoal nm v
-                            walk (AssertWithPenalty nm v mbP) = flip (AssertWithPenalty nm) mbP <$> mkGoal nm v
-
-                        !obj' <- walk obj
-                        liftIO $ modifyState st rOptGoals (obj' :)
-                                           $ noInteractive [ "Adding an optimization objective:"
-                                                           , "  Objective: " ++ show obj
-                                                           ]
-
--- | Generalization of 'Data.SBV.sObserve'
-sObserve :: MonadSymbolic m => String -> SVal -> m ()
-sObserve m x
-  | Just bad <- checkObservableName m
-  = error bad
-  | True
-  = do st <- symbolicEnv
-       liftIO $ do xsv <- svToSV st x
-                   recordObservable st m (const True) xsv
-
--- | Generalization of 'Data.SBV.outputSVal'
-outputSVal :: MonadSymbolic m => SVal -> m ()
-outputSVal (SVal _ (Left c)) = do
-  st <- symbolicEnv
-  sv <- liftIO $ newConst st c
-  liftIO $ modifyState st routs (sv:) (return ())
-outputSVal (SVal _ (Right f)) = do
-  st <- symbolicEnv
-  sv <- liftIO $ uncache f st
-  liftIO $ modifyState st routs (sv:) (return ())
-
----------------------------------------------------------------------------------
--- * Cached values
----------------------------------------------------------------------------------
-
--- | We implement a peculiar caching mechanism, applicable to the use case in
--- implementation of SBV's.  Whenever we do a state based computation, we do
--- not want to keep on evaluating it in the then-current state. That will
--- produce essentially a semantically equivalent value. Thus, we want to run
--- it only once, and reuse that result, capturing the sharing at the Haskell
--- level. This is similar to the "type-safe observable sharing" work, but also
--- takes into the account of how symbolic simulation executes.
---
--- See Andy Gill's type-safe observable sharing trick for the inspiration behind
--- this technique: <http://ku-fpg.github.io/files/Gill-09-TypeSafeReification.pdf>
---
--- Note that this is *not* a general memo utility!
-newtype Cached a = Cached (State -> IO a)
-
--- | Cache a state-based computation
-cache :: (State -> IO a) -> Cached a
-cache = Cached
-
--- | Uncache a previously cached computation
-uncache :: Cached SV -> State -> IO SV
-uncache = uncacheGen rSVCache
-
--- | Generic uncaching. Note that this is entirely safe, since we do it in the IO monad.
-uncacheGen :: (State -> IORef (Cache a)) -> Cached a -> State -> IO a
-uncacheGen getCache (Cached f) st = do
-        let rCache = getCache st
-        stored <- readIORef rCache
-        sn <- f `seq` makeStableName f
-        let h = hashStableName sn
-        case (h `IMap.lookup` stored) >>= (sn `lookup`) of
-          Just r  -> return r
-          Nothing -> do r <- f st
-                        r `seq` R.modifyIORef' rCache (IMap.insertWith (++) h [(sn, r)])
-                        return r
-
--- | Representation of SMTLib Program versions. As of June 2015, we're dropping support
--- for SMTLib1, and supporting SMTLib2 only. We keep this data-type around in case
--- SMTLib3 comes along and we want to support 2 and 3 simultaneously.
-data SMTLibVersion = SMTLib2
-                   deriving (Bounded, Enum, Eq, Show)
-
--- | The extension associated with the version
-smtLibVersionExtension :: SMTLibVersion -> String
-smtLibVersionExtension SMTLib2 = "smt2"
-
--- | Representation of an SMT-Lib program. The second [String] are the function definitions,
--- which is *replicated* in the first one. There are cases where that we need the second part on its own.
-data SMTLibPgm = SMTLibPgm SMTLibVersion [String] [String]
-
-instance NFData SMTLibVersion where rnf a                 = a `seq` ()
-instance NFData SMTLibPgm     where rnf (SMTLibPgm v p d) = rnf v `seq` rnf p `seq` rnf d
-
-instance Show SMTLibPgm where
-  show (SMTLibPgm _ pgm _) = intercalate "\n" pgm
-
--- Other Technicalities..
-instance NFData GeneralizedCV where
-  rnf (ExtendedCV e) = e `seq` ()
-  rnf (RegularCV  c) = c `seq` ()
-
-#if MIN_VERSION_base(4,9,0)
-#else
--- Can't really force this, but not a big deal
-instance NFData CallStack where
-  rnf _ = ()
-#endif
-
-instance NFData NamedSymVar where
-  rnf (NamedSymVar s n) = rnf s `seq` rnf n
-
-instance NFData Result where
-  rnf (Result hasQuants kindInfo qcInfo obs cgs inps consts tbls uis axs pgm cstr asserts outs)
-        = rnf hasQuants `seq` rnf kindInfo `seq` rnf qcInfo  `seq` rnf obs    `seq` rnf cgs
-                        `seq` rnf inps     `seq` rnf consts  `seq` rnf tbls
-                        `seq` rnf uis      `seq` rnf axs     `seq` rnf pgm
-                        `seq` rnf cstr     `seq` rnf asserts `seq` rnf outs
-instance NFData SV           where rnf a          = seq a ()
-instance NFData SBVExpr      where rnf a          = seq a ()
-instance NFData Quantifier   where rnf a          = seq a ()
-instance NFData SBVType      where rnf a          = seq a ()
-instance NFData SBVPgm       where rnf a          = seq a ()
-instance NFData (Cached a)   where rnf (Cached f) = f `seq` ()
-instance NFData SVal         where rnf (SVal x y) = rnf x `seq` rnf y
-
-instance NFData SMTResult where
-  rnf (Unsatisfiable _   m   ) = rnf m
-  rnf (Satisfiable   _   m   ) = rnf m
-  rnf (DeltaSat      _ p m   ) = rnf m `seq` rnf p
-  rnf (SatExtField   _   m   ) = rnf m
-  rnf (Unknown       _   m   ) = rnf m
-  rnf (ProofError    _   m mr) = rnf m `seq` rnf mr
-
-instance NFData SMTModel where
-  rnf (SMTModel objs bndgs assocs uifuns) = rnf objs `seq` rnf bndgs `seq` rnf assocs `seq` rnf uifuns
-
-instance NFData SMTScript where
-  rnf (SMTScript b m) = rnf b `seq` rnf m
-
--- | Translation tricks needed for specific capabilities afforded by each solver
-data SolverCapabilities = SolverCapabilities {
-         supportsQuantifiers        :: Bool           -- ^ Supports SMT-Lib2 style quantifiers?
-       , supportsDefineFun          :: Bool           -- ^ Supports define-fun construct?
-       , supportsDistinct           :: Bool           -- ^ Supports calls to distinct?
-       , supportsBitVectors         :: Bool           -- ^ Supports bit-vectors?
-       , supportsUninterpretedSorts :: Bool           -- ^ Supports SMT-Lib2 style uninterpreted-sorts
-       , supportsUnboundedInts      :: Bool           -- ^ Supports unbounded integers?
-       , supportsReals              :: Bool           -- ^ Supports reals?
-       , supportsApproxReals        :: Bool           -- ^ Supports printing of approximations of reals?
-       , supportsDeltaSat           :: Maybe String   -- ^ Supports delta-satisfiability? (With given precision query)
-       , supportsIEEE754            :: Bool           -- ^ Supports floating point numbers?
-       , supportsSets               :: Bool           -- ^ Supports set operations?
-       , supportsOptimization       :: Bool           -- ^ Supports optimization routines?
-       , supportsPseudoBooleans     :: Bool           -- ^ Supports pseudo-boolean operations?
-       , supportsCustomQueries      :: Bool           -- ^ Supports interactive queries per SMT-Lib?
-       , supportsGlobalDecls        :: Bool           -- ^ Supports global declarations? (Needed for push-pop.)
-       , supportsDataTypes          :: Bool           -- ^ Supports datatypes?
-       , supportsLambdas            :: Bool           -- ^ Does it support lambdas?
-       , supportsSpecialRels        :: Bool           -- ^ Does it support special relations (orders, transitive closure etc.)
-       , supportsDirectAccessors    :: Bool           -- ^ Supports data-type accessors without full ascription?
-       , supportsFlattenedModels    :: Maybe [String] -- ^ Supports flattened model output? (With given config lines.)
-       }
-
--- | Solver configuration. See also 'Data.SBV.z3', 'Data.SBV.yices', 'Data.SBV.cvc4', 'Data.SBV.boolector', 'Data.SBV.mathSAT', etc.
--- which are instantiations of this type for those solvers, with reasonable defaults. In particular, custom configuration can be
--- created by varying those values. (Such as @z3{verbose=True}@.)
---
--- Most fields are self explanatory. The notion of precision for printing algebraic reals stems from the fact that such values does
--- not necessarily have finite decimal representations, and hence we have to stop printing at some depth. It is important to
--- emphasize that such values always have infinite precision internally. The issue is merely with how we print such an infinite
--- precision value on the screen. The field 'printRealPrec' controls the printing precision, by specifying the number of digits after
--- the decimal point. The default value is 16, but it can be set to any positive integer.
---
--- When printing, SBV will add the suffix @...@ at the end of a real-value, if the given bound is not sufficient to represent the real-value
--- exactly. Otherwise, the number will be written out in standard decimal notation. Note that SBV will always print the whole value if it
--- is precise (i.e., if it fits in a finite number of digits), regardless of the precision limit. The limit only applies if the representation
--- of the real value is not finite, i.e., if it is not rational.
---
--- The 'printBase' field can be used to print numbers in base 2, 10, or 16.
---
--- The 'crackNum' field can be used to display numbers in detail, all its bits and how they are laid out in memory. Works with all bounded number types
--- (i.e., SWord and SInt), but also with floats. It is particularly useful with floating-point numbers, as it shows you how they are laid out in
--- memory following the IEEE754 rules.
-data SMTConfig = SMTConfig {
-         verbose                     :: Bool                -- ^ Debug mode
-       , timing                      :: Timing              -- ^ Print timing information on how long different phases took (construction, solving, etc.)
-       , printBase                   :: Int                 -- ^ Print integral literals in this base (2, 10, and 16 are supported.)
-       , printRealPrec               :: Int                 -- ^ Print algebraic real values with this precision. (SReal, default: 16)
-       , crackNum                    :: Bool                -- ^ For each numeric value, show it in detail in the model with its bits spliced out. Good for floats.
-       , crackNumSurfaceVals         :: [(String, Integer)] -- ^ For crackNum: The surface representation of variables, if available
-       , satCmd                      :: String              -- ^ Usually "(check-sat)". However, users might tweak it based on solver characteristics.
-       , allSatMaxModelCount         :: Maybe Int           -- ^ In a 'Data.SBV.allSat' call, return at most this many models. If nothing, return all.
-       , allSatPrintAlong            :: Bool                -- ^ In a 'Data.SBV.allSat' call, print models as they are found.
-       , allSatTrackUFs              :: Bool                -- ^ In a 'Data.SBV.allSat' call, should we try to extract values of uninterpreted functions?
-       , isNonModelVar               :: String -> Bool      -- ^ When constructing a model, ignore variables whose name satisfy this predicate. (Default: (const False), i.e., don't ignore anything)
-       , validateModel               :: Bool                -- ^ If set, SBV will attempt to validate the model it gets back from the solver.
-       , optimizeValidateConstraints :: Bool                -- ^ Validate optimization results. NB: Does NOT make sure the model is optimal, just checks they satisfy the constraints.
-       , transcript                  :: Maybe FilePath      -- ^ If Just, the entire interaction will be recorded as a playable file (for debugging purposes mostly)
-       , smtLibVersion               :: SMTLibVersion       -- ^ What version of SMT-lib we use for the tool
-       , dsatPrecision               :: Maybe Double        -- ^ Delta-sat precision
-       , solver                      :: SMTSolver           -- ^ The actual SMT solver.
-       , extraArgs                   :: [String]            -- ^ Extra command line arguments to pass to the solver.
-       , roundingMode                :: RoundingMode        -- ^ Rounding mode to use for floating-point conversions
-       , solverSetOptions            :: [SMTOption]         -- ^ Options to set as we start the solver
-       , ignoreExitCode              :: Bool                -- ^ If true, we shall ignore the exit code upon exit. Otherwise we require ExitSuccess.
-       , redirectVerbose             :: Maybe FilePath      -- ^ Redirect the verbose output to this file if given. If Nothing, stdout is implied.
-       , firstifyUniqueLen           :: Int                 -- ^ Unique length used for firstified higher-order function names
-       , tpOptions                   :: TPOptions           -- ^ TP specific options
-       }
-
--- | Configuration for TP
-data TPOptions = TPOptions {
-         ribbonLength :: Int  -- ^ Line length for TP proofs
-       , quiet        :: Bool -- ^ No messages what-so-ever for successful steps. (Will print if something fails)
-       , printAsms    :: Bool -- ^ Print assumptions as they are proven as separate steps.
-       , printStats   :: Bool -- ^ Print time/statistics. If quiet is True, then measureTime is ignored.
-       , cacheProofs  :: Bool -- ^ Treat lemma names as unique, and cache the results. Default: False. Note that this
-                              -- feature is unsound unless you make sure (by some other mechanism) that your lemma names
-                              -- are indeed unique.
-       }
-
--- | Ignore internal names and those the user told us to
-mustIgnoreVar :: SMTConfig -> String -> Bool
-mustIgnoreVar cfg s = "__internal_sbv" `isPrefixOf` s || isNonModelVar cfg s
-
--- | We show the name of the solver for the config. Arguably this is misleading, but better than nothing.
-instance Show SMTConfig where
-  show = show . name . solver
-
--- | Returns true if we have to perform validation
-validationRequested :: SMTConfig -> Bool
-validationRequested SMTConfig{validateModel, optimizeValidateConstraints} = validateModel || optimizeValidateConstraints
-
--- We're just seq'ing top-level here, it shouldn't really matter. (i.e., no need to go deeper.)
-instance NFData SMTConfig where
-  rnf SMTConfig{} = ()
-
--- | A model, as returned by a solver
-data SMTModel = SMTModel {
-       modelObjectives :: [(String, GeneralizedCV)]                                     -- ^ Mapping of symbolic values to objective values.
-     , modelBindings   :: Maybe [(NamedSymVar, CV)]                                     -- ^ Mapping of input variables as reported by the solver. Only collected if model validation is requested.
-     , modelAssocs     :: [(String, CV)]                                                -- ^ Mapping of symbolic values to constants.
-     , modelUIFuns     :: [(String, (Bool, SBVType, Either String ([([CV], CV)], CV)))] -- ^ Mapping of uninterpreted functions to association lists in the model.
-                                                                                        -- Note that an uninterpreted constant (function of arity 0) will be stored
-                                                                                        -- in the 'modelAssocs' field. Left is used when the function returned is too
-                                                                                        -- difficult for SBV to figure out what it means
-     }
-     deriving Show
-
--- | Is it the case that the model is really uninteresting? This is the case when there are no assocs nor ui's
-isEmptyModel :: SMTModel -> Bool
-isEmptyModel SMTModel{modelAssocs, modelUIFuns} = null modelAssocs && null modelUIFuns
-
--- | The result of an SMT solver call. Each constructor is tagged with
--- the t'SMTConfig' that created it so that further tools can inspect it
--- and build layers of results, if needed. For ordinary uses of the library,
--- this type should not be needed, instead use the accessor functions on
--- it. (Custom Show instances and model extractors.)
-data SMTResult = Unsatisfiable SMTConfig (Maybe [String])            -- ^ Unsatisfiable. If unsat-cores are enabled, they will be returned in the second parameter.
-               | Satisfiable   SMTConfig SMTModel                    -- ^ Satisfiable with model
-               | DeltaSat      SMTConfig (Maybe String) SMTModel     -- ^ Delta satisfiable with queried string if available and model
-               | SatExtField   SMTConfig SMTModel                    -- ^ Prover returned a model, but in an extension field containing Infinite/epsilon
-               | Unknown       SMTConfig SMTReasonUnknown            -- ^ Prover returned unknown, with the given reason
-               | ProofError    SMTConfig [String] (Maybe SMTResult)  -- ^ Prover errored out, with possibly a bogus result
-
--- | A script, to be passed to the solver.
-data SMTScript = SMTScript {
-          scriptBody  :: String   -- ^ Initial feed
-        , scriptModel :: [String] -- ^ Continuation script, to extract results
-        }
-
--- | An SMT engine
-type SMTEngine =  forall res.
-                  SMTConfig         -- ^ current configuration
-               -> State             -- ^ the state in which to run the engine
-               -> String            -- ^ program
-               -> (State -> IO res) -- ^ continuation
-               -> IO res
-
--- | Solvers that SBV is aware of
-data Solver = ABC
-            | Boolector
-            | Bitwuzla
-            | CVC4
-            | CVC5
-            | DReal
-            | MathSAT
-            | Yices
-            | Z3
-            | OpenSMT
-            deriving (Show, Enum, Bounded)
-
--- | An SMT solver
-data SMTSolver = SMTSolver {
-         name           :: Solver                -- ^ The solver in use
-       , executable     :: String                -- ^ The path to its executable
-       , preprocess     :: String -> String      -- ^ Each line sent to the solver will be passed through this function (typically id)
+{-# LANGUAGE DefaultSignatures          #-}
+{-# LANGUAGE DeriveAnyClass             #-}
+{-# LANGUAGE DeriveDataTypeable         #-}
+{-# LANGUAGE DeriveFunctor              #-}
+{-# LANGUAGE DeriveGeneric              #-}
+{-# LANGUAGE DerivingStrategies         #-}
+{-# LANGUAGE FlexibleInstances          #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE LambdaCase                 #-}
+{-# LANGUAGE MultiParamTypeClasses      #-}
+{-# LANGUAGE NamedFieldPuns             #-}
+{-# LANGUAGE OverloadedStrings          #-}
+{-# LANGUAGE PatternSynonyms            #-}
+{-# LANGUAGE RankNTypes                 #-}
+{-# LANGUAGE ScopedTypeVariables        #-}
+{-# LANGUAGE StandaloneDeriving         #-}
+{-# LANGUAGE TypeOperators              #-}
+{-# LANGUAGE UndecidableInstances       #-}
+{-# LANGUAGE ViewPatterns               #-}
+
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
+
+module Data.SBV.Core.Symbolic
+  ( NodeId(..)
+  , SV(..), swKind, trueSV, falseSV
+  , Op(..), PBOp(..), OvOp(..), FPOp(..), NROp(..), StrOp(..), RegExOp(..), SeqOp(..), SetOp(..), SpecialRelOp(..), ADTOp(..)
+  , RegExp(..), regExpToSMTString, validateRegExp
+  , SMTLambda(SMTLambda), smtLambdaWithInfo, smtLambdaText, smtLambdaInfo
+  , Quantifier(..), needsExistentials, SBVContext(..), globalSBVContext, VarContext(..)
+  , SBVType(..), svUninterpreted, svUninterpretedNamedArgs, newUninterpreted
+  , SVal(..)
+  , svMkSymVar, sWordN, sWordN_, sIntN, sIntN_
+  , svToSV, svToSymSV, forceSVArg
+  , SBVExpr(..), newExpr, isCodeGenMode, isSafetyCheckingIStage, isRunIStage, isSetupIStage
+  , Cached, cache, uncache, modifyState, modifyIncState
+  , NamedSymVar(..), Name, UserInputs, Inputs(..), getSV, swNodeId
+  , getUserName', getUserName
+  , lookupInput , getSValPathCondition, extendSValPathCondition
+  , getTableIndex, sObserve
+  , SBVPgm(..), MonadSymbolic(..), SymbolicT, Symbolic, runSymbolic, mkNewState, runSymbolicInState, State(..), SMTDef(SMTDef), smtDefWithInfo, smtDefInfo, smtDefEq, conflictError, withNewIncState, IncState(..), incrementInternalCounter, incrementFreshNameCounter
+  , inSMTMode, SBVRunMode(..), IStage(..), Result(..), ResultInp(..), UICodeKind(..), UIName(..)
+  , registerKind, registerLabel, recordObservable
+  , addAssertion, addNewSMTOption, imposeConstraint, internalConstraint, newInternalVariable, lambdaVar, quantVar
+  , SMTLibPgm(..), SMTLibVersion(..), smtLibVersionExtension, smtLibPgmText
+  , SolverCapabilities(..)
+  , extractSymbolicSimulationState, CnstMap
+  , OptimizeStyle(..), Objective(..), Penalty(..), objectiveName, addSValOptGoal
+  , MonadQuery(..), QueryT(..), Query, QueryState(..), QueryContext(..)
+  , SMTScript(..), Solver(..), SMTSolver(..), SMTResult(..), SMTModel(..), SMTConfig(..), TPOptions(..), SMTEngine
+  , validationRequested, outputSVal, ProgInfo(..), mustIgnoreVar, getRootState
+  , LambdaInfo(..), showNROp
+  ) where
+
+import Control.DeepSeq             (NFData(..))
+import Control.Monad               (when, unless)
+import Control.Monad.Except        (MonadError, ExceptT)
+import Control.Monad.Reader        (MonadReader(..), ReaderT, runReaderT,
+                                    mapReaderT)
+import Control.Monad.State.Lazy    (MonadState)
+import Control.Monad.Trans         (MonadIO(liftIO), MonadTrans(lift))
+import Control.Monad.Trans.Maybe   (MaybeT)
+import Control.Monad.Writer.Strict (MonadWriter)
+import Data.IORef                  (IORef, newIORef, readIORef)
+import Data.List                   (intercalate, isPrefixOf)
+import Data.Maybe                  (fromMaybe)
+import Data.String                 (IsString(fromString))
+
+import Data.Time (getCurrentTime, UTCTime)
+
+import Data.Int (Int64)
+
+import GHC.Stack
+import GHC.Stack.Types
+import GHC.Generics (Generic)
+
+import qualified Control.Exception as C
+import qualified Control.Monad.State.Lazy    as LS
+import qualified Control.Monad.State.Strict  as SS
+import qualified Control.Monad.Writer.Lazy   as LW
+import qualified Control.Monad.Writer.Strict as SW
+import qualified Data.IORef                  as R    (modifyIORef')
+import qualified Data.Generics               as G    (Data(..))
+import qualified Data.Generics.Uniplate.Data as G
+import qualified Data.IntMap.Strict          as IMap (IntMap, empty, lookup, insertWith)
+import qualified Data.Map.Strict             as Map  (Map, empty, toList, lookup, insert, size, keysSet)
+import qualified Data.Set                    as Set  (Set, empty, toList, insert, member, notMember)
+import qualified Data.Foldable               as F    (toList)
+import qualified Data.Sequence               as S    (Seq, empty, (|>), lookup, elemIndexL)
+import qualified Data.Text                   as T
+import           Data.Text                   (Text)
+
+import System.Mem.StableName
+import System.Random
+
+import Data.SBV.Core.Kind
+import Data.SBV.Core.Concrete
+import Data.SBV.SMT.SMTLibNames
+import Data.SBV.Utils.TDiff   (Timing)
+import Data.SBV.Utils.Lib     (stringToQFS, checkObservableName, barify, mapToSortedList, showText)
+import Data.SBV.Utils.Numeric (RoundingMode)
+
+import Data.Containers.ListUtils (nubOrd)
+
+import Data.SBV.Control.Types
+
+
+-- | Context identifier. 0 is reserved global context
+newtype SBVContext = SBVContext Int64 deriving (Eq, Ord, G.Data, Show)
+
+instance NFData SBVContext where
+  rnf (SBVContext i) = i `seq` ()
+
+-- | Global context
+globalSBVContext :: SBVContext
+globalSBVContext = SBVContext 0
+
+-- | Generate context. We make sure it isn't 0, i.e., the global context
+-- The "hope" here is that each time we call this we get a different context number.
+-- A random number doesn't necessarily have to do that, but I think the pseudo-generator
+-- has a large enough period for this to go through OK.
+genSBVContext :: IO SBVContext
+genSBVContext = do ctx <- SBVContext <$> randomIO
+                   if ctx == globalSBVContext   -- unlikely, but possible
+                      then genSBVContext
+                      else pure ctx
+
+-- | A symbolic node id
+newtype NodeId = NodeId { getId :: (SBVContext, Maybe Int, Int) } -- Lambda-level, and node-id
+  deriving (Ord, G.Data)
+
+-- Equality is pair-wise, except we accommodate for negative node-id; which is reserved for true/false
+instance Eq NodeId where
+  NodeId n1@(_, _, i) == NodeId n2@(_, _, j)
+     | i < 0 && j < 0
+     = i == j
+     | True
+     = n1 == n2
+
+-- | A symbolic word, tracking its kind and node representing it
+data SV = SV !Kind !NodeId
+        deriving G.Data
+
+-- | For equality, we merely use the lambda-level/node-id
+instance Eq SV where
+  SV _ n1 == SV _ n2 = n1 == n2
+
+-- | Again, simply use the lambda-level/node-id for ordering
+instance Ord SV where
+  SV _ n1 `compare` SV _ n2 = n1 `compare` n2
+
+instance HasKind SV where
+  kindOf (SV k _) = k
+
+instance Show SV where
+  show (SV _ (NodeId (_, l, n))) = case n of
+                                     -2 -> "false"
+                                     -1 -> "true"
+                                     _  -> prefix ++ 's' : show n
+        where prefix = case l of
+                         Nothing -> "arg"   -- top-level lambda
+                         Just 0  -> ""
+                         Just i  -> 'l' : show i ++ "_"
+
+-- | Kind of a symbolic word.
+swKind :: SV -> Kind
+swKind (SV k _) = k
+
+-- | retrieve the node id of a symbolic word
+swNodeId :: SV -> NodeId
+swNodeId (SV _ nid) = nid
+
+-- | Forcing an argument; this is a necessary evil to make sure all the arguments
+-- to an uninterpreted function are evaluated before called; the semantics of uninterpreted
+-- functions is necessarily strict; deviating from Haskell's
+forceSVArg :: SV -> IO ()
+forceSVArg (SV k n) = k `seq` n `seq` pure ()
+
+-- | Constant False as an t'SV'. Note that this value always occupies slot -2 and level 0.
+falseSV :: SV
+falseSV = SV KBool $ NodeId (globalSBVContext, Just 0, -2)
+
+-- | Constant True as an t'SV'. Note that this value always occupies slot -1 and level 0.
+trueSV :: SV
+trueSV  = SV KBool $ NodeId (globalSBVContext, Just 0, -1)
+
+-- | Symbolic operations
+data Op = Plus
+        | Times
+        | Minus
+        | UNeg
+        | Abs
+        | Quot
+        | Rem
+        | Equal Bool   -- ^ If bool is True then this is strong (i.e., object equality). Matters for floats or structures containing them.
+        | Implies
+        | NotEqual
+        | LessThan
+        | GreaterThan
+        | LessEq
+        | GreaterEq
+        | Ite
+        | And
+        | Or
+        | XOr
+        | Not
+        | Shl
+        | Shr
+        | Rol Int
+        | Ror Int
+        | Divides Integer                       -- divides k n is True if k divides n. k must be > 0 constant
+        | Extract Int Int                       -- Extract i j: extract bits i to j. Least significant bit is 0 (big-endian)
+        | Join                                  -- Concat two words to form a bigger one, in the order given
+        | ZeroExtend Int
+        | SignExtend Int
+        | LkUp (Int, Kind, Kind, Int) !SV !SV   -- (table-index, arg-type, res-type, length of the table) index out-of-bounds-value
+        | KindCast Kind Kind
+        | Uninterpreted T.Text
+        | QuantifiedBool T.Text                 -- When we generate a forall/exists (nested etc.) boolean value. NB. This used to be "QuantifiedBool [Op] String", keeping track of Ops. That turned out to cause memory leaks. So avoid that.
+        | SpecialRelOp Kind SpecialRelOp        -- Generate the equality to the internal operation
+        | Label String                          -- Essentially no-op; useful for code generation to emit comments.
+        | IEEEFP FPOp                           -- Floating-point ops, categorized separately
+        | NonLinear NROp                        -- Non-linear ops (mostly trigonometric), categorized separately
+        | OverflowOp    OvOp                    -- Overflow-ops, categorized separately
+        | PseudoBoolean PBOp                    -- Pseudo-boolean ops, categorized separately
+        | RegExOp RegExOp                       -- RegEx operations, categorized separately
+        | StrOp StrOp                           -- String ops, categorized separately
+        | SeqOp SeqOp                           -- Sequence ops, categorized separately
+        | SetOp SetOp                           -- Set operations, categorized separately
+        | TupleConstructor Int                  -- Construct an n-tuple
+        | TupleAccess Int Int                   -- Access element i of an n-tuple; second argument is n
+        | RationalConstructor                   -- Construct a rational. Note that there's no access to numerator or denominator, since we cannot store rationals in canonical form
+        | ADTOp ADTOp                           -- ADT access/construction/testing
+
+        -- Arrays
+        | ArrayInit (Either (Kind, Kind) SMTLambda) -- An array value, created either from a lambda or a symbolic value. Kind is the
+        | ReadArray                                 -- Reading an array value
+        | WriteArray                                -- Writing to an array
+        deriving (Eq, Ord, Generic, G.Data, NFData)
+
+-- | ADT operations
+data ADTOp = ADTConstructor T.Text Kind    -- Construct an ADT. Kind is the kind of the result.
+           | ADTTester      T.Text Kind    -- Check if top-level constructor matches. Kind is the kind of the result.
+           | ADTAccessor    T.Text Kind    -- Extract a field from an ADT value. Kind is the kind of the result.
+           deriving (Eq, Ord, Generic, G.Data, NFData)
+
+-- | Special relations supported by z3
+data SpecialRelOp = IsPartialOrder         String
+                  | IsLinearOrder          String
+                  | IsTreeOrder            String
+                  | IsPiecewiseLinearOrder String
+                  deriving (Eq, Ord, G.Data, Show)
+
+instance NFData SpecialRelOp where
+  rnf (IsPartialOrder         n) = rnf n
+  rnf (IsLinearOrder          n) = rnf n
+  rnf (IsTreeOrder            n) = rnf n
+  rnf (IsPiecewiseLinearOrder n) = rnf n
+
+-- | Floating point operations
+data FPOp = FP_Cast        Kind Kind SV   -- From-Kind, To-Kind, RoundingMode. This is "value" conversion
+          | FP_Reinterpret Kind Kind      -- From-Kind, To-Kind. This is bit-reinterpretation using IEEE-754 interchange format
+          | FP_Abs
+          | FP_Neg
+          | FP_Add
+          | FP_Sub
+          | FP_Mul
+          | FP_Div
+          | FP_FMA
+          | FP_Sqrt
+          | FP_Rem
+          | FP_RoundToIntegral
+          | FP_Min
+          | FP_Max
+          | FP_ObjEqual
+          | FP_IsNormal
+          | FP_IsSubnormal
+          | FP_IsZero
+          | FP_IsInfinite
+          | FP_IsNaN
+          | FP_IsNegative
+          | FP_IsPositive
+          deriving (Eq, Ord, G.Data, NFData, Generic)
+
+-- Note that the show instance maps to the SMTLib names. We need to make sure
+-- this mapping stays correct through SMTLib changes. The only exception
+-- is FP_Cast; where we handle different source/origins explicitly later on.
+instance Show FPOp where
+   show (FP_Cast f t r)      = "(FP_Cast: " ++ show f ++ " -> " ++ show t ++ ", using RM [" ++ show r ++ "])"
+   show (FP_Reinterpret f t) = case t of
+                                  KFloat    -> "(_ to_fp 8 24)"
+                                  KDouble   -> "(_ to_fp 11 53)"
+                                  KFP eb sb -> "(_ to_fp " ++ show eb ++ " " ++ show sb ++ ")"
+                                  _         -> error $ "SBV.FP_Reinterpret: Unexpected conversion: " ++ show f ++ " to " ++ show t
+   show FP_Abs               = "fp.abs"
+   show FP_Neg               = "fp.neg"
+   show FP_Add               = "fp.add"
+   show FP_Sub               = "fp.sub"
+   show FP_Mul               = "fp.mul"
+   show FP_Div               = "fp.div"
+   show FP_FMA               = "fp.fma"
+   show FP_Sqrt              = "fp.sqrt"
+   show FP_Rem               = "fp.rem"
+   show FP_RoundToIntegral   = "fp.roundToIntegral"
+   show FP_Min               = "fp.min"
+   show FP_Max               = "fp.max"
+   show FP_ObjEqual          = "="
+   show FP_IsNormal          = "fp.isNormal"
+   show FP_IsSubnormal       = "fp.isSubnormal"
+   show FP_IsZero            = "fp.isZero"
+   show FP_IsInfinite        = "fp.isInfinite"
+   show FP_IsNaN             = "fp.isNaN"
+   show FP_IsNegative        = "fp.isNegative"
+   show FP_IsPositive        = "fp.isPositive"
+
+-- | Non-linear operations. We do *not* on purpose deriving Show here, nor give a show instance,
+-- since different solvers call these functions with different names.
+data NROp = NR_Sin
+          | NR_Cos
+          | NR_Tan
+          | NR_ASin
+          | NR_ACos
+          | NR_ATan
+          | NR_Sqrt
+          | NR_Sinh
+          | NR_Cosh
+          | NR_Tanh
+          | NR_Exp
+          | NR_Log
+          | NR_Pow
+          | NR_IntPow
+          deriving (Eq, Ord, G.Data, NFData, Generic)
+
+-- | Show a non-linear op. Unfortunately this can't be generically done since different
+-- solvers use different names for some of these ops.
+showNROp :: Solver -> NROp -> String
+showNROp slvr = sh
+  where sh NR_Sin    = "sin"
+        sh NR_Cos    = "cos"
+        sh NR_Tan    = "tan"
+        sh NR_ASin   = arc ++ "sin"
+        sh NR_ACos   = arc ++ "cos"
+        sh NR_ATan   = arc ++ "tan"
+        sh NR_Sinh   = "sinh"
+        sh NR_Cosh   = "cosh"
+        sh NR_Tanh   = "tanh"
+        sh NR_Sqrt   = "sqrt"
+        sh NR_Exp    = "exp"
+        sh NR_Log    = "log"
+        sh NR_Pow    = "pow"
+        sh NR_IntPow = "**"   -- SMT-LIB Int-theory exponentiation
+
+        -- DReal uses asin/acos etc. CVC5 uses arcsin. Other solvers probably
+        -- don't even support these. But this isn't the right place to bail-out
+        -- about it; so we just put "arc" following CVC5 here.
+        arc = case slvr of
+                DReal -> "a"
+                _     -> "arc"
+
+-- | Pseudo-boolean operations
+data PBOp = PB_AtMost  Int        -- ^ At most k
+          | PB_AtLeast Int        -- ^ At least k
+          | PB_Exactly Int        -- ^ Exactly k
+          | PB_Le      [Int] Int  -- ^ At most k,  with coefficients given. Generalizes PB_AtMost
+          | PB_Ge      [Int] Int  -- ^ At least k, with coefficients given. Generalizes PB_AtLeast
+          | PB_Eq      [Int] Int  -- ^ Exactly k,  with coefficients given. Generalized PB_Exactly
+          deriving (Eq, Ord, Show, G.Data, NFData, Generic)
+
+-- | Overflow operations
+data OvOp = PlusOv Bool           -- ^ Addition    overflow.    Bool is True if signed.
+          | SubOv  Bool           -- ^ Subtraction overflow.    Bool is True if signed.
+          | MulOv  Bool           -- ^ Multiplication overflow. Bool is True if signed.
+          | DivOv                 -- ^ Division overflow.       Only signed, since unsigned division does not overflow.
+          | NegOv                 -- ^ Unary negation overflow. Only signed, since unsigned negation does not overflow.
+          deriving (Eq, Ord, G.Data, NFData, Generic)
+
+-- | Show instance. It's important that these follow the SMTLib names.
+instance Show OvOp where
+  show (PlusOv signed) = "bv" ++ (if signed then "s" else "u") ++ "addo"
+  show (SubOv  signed) = "bv" ++ (if signed then "s" else "u") ++ "subo"
+  show (MulOv  signed) = "bv" ++ (if signed then "s" else "u") ++ "mulo"
+  show DivOv           = "bvsdivo" -- This is confusing, the division is called bvsdivo, but negation is bvnego
+  show NegOv           = "bvnego"  -- But SMTLib's choice is deliberate: https://groups.google.com/u/0/g/smt-lib/c/J4D99wT0aKI
+
+-- | String operations.
+data StrOp = StrStrToNat     -- ^ Retrieve integer encoded by string @s@ (ground rewriting only)
+           | StrNatToStr     -- ^ Retrieve string encoded by integer @i@ (ground rewriting only)
+           | StrToCode       -- ^ Equivalent to Haskell's ord
+           | StrFromCode     -- ^ Equivalent to Haskell's chr
+           | StrInRe RegExp  -- ^ Check if string is in the regular expression
+           deriving (Eq, Ord, G.Data, NFData, Generic)
+
+-- | Regular-expression operators. The only thing we can do is to compare for equality/disequality.
+data RegExOp = RegExEq  RegExp RegExp
+             | RegExNEq RegExp RegExp
+             deriving (Eq, Ord, G.Data, NFData, Generic)
+
+-- | Regular expressions. Note that regular expressions themselves are
+-- concrete, but the 'Data.SBV.RegExp.match' function from the 'Data.SBV.RegExp.RegExpMatchable' class
+-- can check membership against a symbolic string/character. Also, we
+-- are preferring a datatype approach here, as opposed to coming up with
+-- some string-representation; there are way too many alternatives
+-- already so inventing one isn't a priority. Please get in touch if you
+-- would like a parser for this type as it might be easier to use.
+data RegExp = Literal String       -- ^ Precisely match the given string
+            | All                  -- ^ Accept every string
+            | AllChar              -- ^ Accept every single character
+            | None                 -- ^ Accept no strings
+            | Range Char Char      -- ^ Accept range of characters
+            | Conc  [RegExp]       -- ^ Concatenation; the empty list matches exactly the empty string
+            | KStar RegExp         -- ^ Kleene Star: Zero or more
+            | KPlus RegExp         -- ^ Kleene Plus: One or more
+            | Opt   RegExp         -- ^ Zero or one
+            | Comp  RegExp         -- ^ Complement of regular expression
+            | Diff  RegExp RegExp  -- ^ Difference of regular expressions
+            | Loop  Int Int RegExp -- ^ From @n@ repetitions to @m@ repetitions; requires @0 <= n <= m@
+            | Power Int     RegExp -- ^ Exactly @n@ repetitions, i.e., nth power; requires @n >= 0@
+            | Union [RegExp]       -- ^ Union of regular expressions
+            | Inter RegExp RegExp  -- ^ Intersection of regular expressions
+            deriving (Eq, Ord, G.Data, Generic, NFData)
+
+-- | With overloaded strings, we can have direct literal regular expressions.
+instance IsString RegExp where
+  fromString = Literal
+
+-- | Regular expressions as a 'Num' instance. Note that only some operations make sense and
+-- not in the most obvious way. For instance, we would typically expect @a - b@ to be the
+-- same as @a + negate b@, but that equality does not hold in general. So, use the @Num@
+-- instance only as constructing syntax, not doing algebraic manipulations.
+instance Num RegExp where
+  -- flatten the concats to make them simpler
+  Conc xs * y = Conc (xs ++ [y])
+  x * Conc ys = Conc (x  :  ys)
+  x * y       = Conc [x, y]
+
+  -- flatten the unions to make them simpler
+  Union xs + y = Union (xs ++ [y])
+  x + Union ys = Union (x  : ys)
+  x + y        = Union [x, y]
+
+  x - y = Diff x y
+
+  abs         = error "Num.RegExp: no abs method"
+  signum      = error "Num.RegExp: no signum method"
+
+  fromInteger x
+    | x == 0    = None
+    | x == 1    = Literal ""   -- Unit for concatenation is the empty string
+    | True      = error $ "Num.RegExp: Only 0 and 1 makes sense as a reg-exp, no meaning for: " ++ show x
+
+  negate = Comp
+
+-- | Convert a reg-exp to a Haskell-like string
+instance Show RegExp where
+  show r = validateRegExp r `seq` T.unpack (regExpToText (T.pack . show) r)
+
+-- | Reject invalid repetition bounds throughout a regex, even in branches
+-- that literal matching could skip. Sharing this check keeps literal matching
+-- and SMT serialization consistent without constructing text during folding.
+validateRegExp :: RegExp -> ()
+validateRegExp (Literal _) = ()
+validateRegExp All         = ()
+validateRegExp AllChar     = ()
+validateRegExp None        = ()
+validateRegExp (Range _ _) = ()
+validateRegExp (Conc rs)   = foldr (seq . validateRegExp) () rs
+validateRegExp (KStar r)   = validateRegExp r
+validateRegExp (KPlus r)   = validateRegExp r
+validateRegExp (Opt r)     = validateRegExp r
+validateRegExp (Comp r)    = validateRegExp r
+validateRegExp (Diff a b)  = validateRegExp a `seq` validateRegExp b
+validateRegExp (Loop lo hi r)
+  | lo >= 0, hi >= lo     = validateRegExp r
+  | True                 = error $ "Invalid regular-expression Loop with arguments: " ++ show (lo, hi)
+validateRegExp (Power n r)
+  | n >= 0               = validateRegExp r
+  | True                 = error $ "Invalid regular-expression Power with arguments: " ++ show n
+validateRegExp (Union rs)  = foldr (seq . validateRegExp) () rs
+validateRegExp (Inter a b) = validateRegExp a `seq` validateRegExp b
+
+-- | Convert a reg-exp to a SMT-lib acceptable representation
+regExpToSMTString :: RegExp -> Text
+regExpToSMTString r = validateRegExp r `seq` regExpToText (\s -> "\"" <> T.pack (stringToQFS s) <> "\"") r
+
+-- | Convert a RegExp to text, parameterized by how strings are converted
+regExpToText :: (String -> Text) -> RegExp -> Text
+regExpToText fs (Literal s)       = "(str.to_re " <> fs s <> ")"
+regExpToText _  All               = "re.all"
+regExpToText _  AllChar           = "re.allchar"
+regExpToText _  None              = "re.nostr"
+regExpToText fs (Range ch1 ch2)   = "(re.range " <> fs [ch1] <> " " <> fs [ch2] <> ")"
+regExpToText fs (Conc [])         = regExpToText fs (Literal "")
+regExpToText fs (Conc [x])        = regExpToText fs x
+regExpToText fs (Conc xs)         = "(re.++ " <> T.unwords (map (regExpToText fs) xs) <> ")"
+regExpToText fs (KStar r)         = "(re.* " <> regExpToText fs r <> ")"
+regExpToText fs (KPlus r)         = "(re.+ " <> regExpToText fs r <> ")"
+regExpToText fs (Opt   r)         = "(re.opt " <> regExpToText fs r <> ")"
+regExpToText fs (Comp  r)         = "(re.comp " <> regExpToText fs r <> ")"
+regExpToText fs (Diff  r1 r2)     = "(re.diff " <> regExpToText fs r1 <> " " <> regExpToText fs r2 <> ")"
+regExpToText fs (Loop lo hi r)    = "((_ re.loop " <> showText lo <> " " <> showText hi <> ") " <> regExpToText fs r <> ")"
+regExpToText fs (Power n r)       = regExpToText fs (Loop n n r)
+regExpToText fs (Inter r1 r2)     = "(re.inter " <> regExpToText fs r1 <> " " <> regExpToText fs r2 <> ")"
+regExpToText _  (Union [])        = "re.nostr"
+regExpToText fs (Union [x])       = regExpToText fs x
+regExpToText fs (Union xs)        = "(re.union " <> T.unwords (map (regExpToText fs) xs) <> ")"
+
+-- | Show instance for @StrOp@. Note that the mapping here is important to match the SMTLib equivalents.
+instance Show StrOp where
+  show StrStrToNat = "str.to.int"    -- NB. SMTLib uses "int" here though only nats are supported
+  show StrNatToStr = "int.to.str"    -- NB. SMTLib uses "int" here though only nats are supported
+  show StrToCode   = "str.to_code"
+  show StrFromCode = "str.from_code"
+  -- Note the breakage here with respect to argument order. We fix this explicitly later.
+  show (StrInRe s) = "str.in_re " ++ T.unpack (regExpToSMTString s)
+
+-- | Show instance for @RegExOp@.
+instance Show RegExOp where
+  show (RegExEq  r1 r2) = "(= "        ++ T.unpack (regExpToSMTString r1) ++ " " ++ T.unpack (regExpToSMTString r2) ++ ")"
+  show (RegExNEq r1 r2) = "(distinct " ++ T.unpack (regExpToSMTString r1) ++ " " ++ T.unpack (regExpToSMTString r2) ++ ")"
+
+-- | A lambda's canonical SMT-Lib representation, optionally accompanied by
+-- the expression DAG from which it was rendered. The structured form lets
+-- non-SMT backends consume lambdas without parsing SMT-Lib.
+data SMTLambda = SMTLambdaValue T.Text (Maybe LambdaInfo)
+               deriving (G.Data, Generic)
+
+-- | Compatibility constructor and pattern for an SMT-text-only lambda. The
+-- pattern also matches lambdas carrying retained backend metadata.
+pattern SMTLambda :: T.Text -> SMTLambda
+pattern SMTLambda textValue <- (smtLambdaText -> textValue)
+  where SMTLambda textValue = SMTLambdaValue textValue Nothing
+
+{-# COMPLETE SMTLambda #-}
+
+-- | Construct a lambda with both its canonical SMT-Lib text and retained
+-- expression DAG.
+smtLambdaWithInfo :: T.Text -> LambdaInfo -> SMTLambda
+smtLambdaWithInfo textValue lambdaInfo = SMTLambdaValue textValue (Just lambdaInfo)
+
+-- | Compare lambdas by their canonical SMT-Lib representation. The retained
+-- DAG is backend metadata and does not affect symbolic identity.
+instance Eq SMTLambda where
+  left == right = smtLambdaText left == smtLambdaText right
+
+-- | Order lambdas by their canonical SMT-Lib representation. The retained
+-- DAG is backend metadata and does not affect symbolic identity.
+instance Ord SMTLambda where
+  compare left right = compare (smtLambdaText left) (smtLambdaText right)
+
+-- | Fully evaluate both the canonical text and any retained expression DAG.
+instance NFData SMTLambda where
+  rnf (SMTLambdaValue textValue lambdaInfo) = rnf textValue `seq` rnf lambdaInfo
+
+-- | Return the canonical SMT-Lib rendering of a lambda.
+smtLambdaText :: SMTLambda -> T.Text
+smtLambdaText (SMTLambdaValue textValue _) = textValue
+
+-- | Return a lambda's retained expression DAG when it was constructed by
+-- SBV rather than directly from an SMT-Lib string.
+smtLambdaInfo :: SMTLambda -> Maybe LambdaInfo
+smtLambdaInfo (SMTLambdaValue _ lambdaInfo) = lambdaInfo
+
+-- | Simple show instance for SMTLambda
+instance Show SMTLambda where
+  show = T.unpack . smtLambdaText
+
+-- | Sequence operations. Indexed by the element kind.
+data SeqOp = SeqLen      Kind
+           | SeqConcat   Kind
+           | SeqNth      Kind
+           | SeqUnit     Kind
+           | SeqSubseq   Kind
+           | SeqIndexOf  Kind
+           | SeqContains Kind
+           | SeqPrefixOf Kind
+           | SeqSuffixOf Kind
+           | SeqReplace  Kind
+  deriving (Eq, Ord, G.Data, NFData, Generic)
+
+-- | Pick the correct operator
+pickSeqOp :: Kind -> String -> String -> String
+pickSeqOp KChar st _  = st
+pickSeqOp _     _  sq = sq
+
+-- | Show instance for SeqOp. Again, mapping is important.
+instance Show SeqOp where
+  show (SeqLen      k) = pickSeqOp k "str.len"      "seq.len"
+  show (SeqConcat   k) = pickSeqOp k "str.++"       "seq.++"
+  show (SeqNth      k) = pickSeqOp k "str.at"       "seq.nth"
+  show (SeqUnit     k) = pickSeqOp k "str.unit"     "seq.unit"
+  show (SeqSubseq   k) = pickSeqOp k "str.substr"   "seq.extract"
+  show (SeqIndexOf  k) = pickSeqOp k "str.indexof"  "seq.indexof"
+  show (SeqContains k) = pickSeqOp k "str.contains" "seq.contains"
+  show (SeqPrefixOf k) = pickSeqOp k "str.prefixof" "seq.prefixof"
+  show (SeqSuffixOf k) = pickSeqOp k "str.suffixof" "seq.suffixof"
+  show (SeqReplace  k) = pickSeqOp k "str.replace"  "seq.replace"
+
+-- | Set operations.
+data SetOp = SetEqual
+           | SetMember
+           | SetInsert
+           | SetDelete
+           | SetIntersect
+           | SetUnion
+           | SetSubset
+           | SetDifference
+           | SetComplement
+        deriving (Eq, Ord, G.Data, NFData, Generic)
+
+-- The show instance for 'SetOp' is merely for debugging, we map them separately so
+-- the mapped strings are less important here.
+instance Show SetOp where
+  show SetEqual      = "=="
+  show SetMember     = "Set.member"
+  show SetInsert     = "Set.insert"
+  show SetDelete     = "Set.delete"
+  show SetIntersect  = "Set.intersect"
+  show SetUnion      = "Set.union"
+  show SetSubset     = "Set.subset"
+  show SetDifference = "Set.difference"
+  show SetComplement = "Set.complement"
+
+-- Show instance for 'Op'. Note that this is largely for debugging purposes, not used
+-- for being read by any tool.
+instance Show Op where
+  show Shl    = "<<"
+  show Shr    = ">>"
+
+  show (Rol i) = "<<<" ++ show i
+  show (Ror i) = ">>>" ++ show i
+
+  show (Extract i j) = "choose [" ++ show i ++ ":" ++ show j ++ "]"
+
+  show (LkUp (ti, at, rt, l) i e)
+        = "lookup(" ++ tinfo ++ ", " ++ show i ++ ", " ++ show e ++ ")"
+        where tinfo = "table" ++ show ti ++ "(" ++ show at ++ " -> " ++ show rt ++ ", " ++ show l ++ ")"
+
+  show (KindCast fr to)     = "cast_" ++ show fr ++ "_" ++ show to
+  show (Uninterpreted i)    = "[uninterpreted] " ++ T.unpack i
+  show (QuantifiedBool i)   = "[quantified boolean] " ++ T.unpack i
+
+  show (Label s)            = "[label] " ++ s
+
+  show (IEEEFP w)           = show w
+
+  show (NonLinear w)        = showNROp DReal w -- Just use DReal here, only used for debugging
+
+  show (PseudoBoolean p)    = show p
+
+  show (OverflowOp o)       = show o
+
+  show (StrOp s)            = show s
+  show (RegExOp s)          = show s
+  show (SeqOp s)            = show s
+  show (SetOp s)            = show s
+
+  show (TupleConstructor   0) = "mkSBVTuple0"
+  show (TupleConstructor   n) = "mkSBVTuple" ++ show n
+  show (TupleAccess      i n) = "proj_" ++ show i ++ "_SBVTuple" ++ show n
+
+  show RationalConstructor    = "SBV.Rational"
+  show (ArrayInit k)          = case k of
+                                  Left (a, b) -> "const-array[" ++ show a ++ " -> " ++ show b ++ "]"
+                                  Right s     -> show s
+  show ReadArray              = "select"
+  show WriteArray             = "store"
+
+  show op
+    | Just s <- op `lookup` syms = s
+    | True                       = error "impossible happened; can't find op!" -- NB. Can't display the OP here! it's the show instance after all.
+    where syms = [ (Plus, "+"), (Times, "*"), (Minus, "-"), (UNeg, "-"), (Abs, "abs")
+                 , (Quot, "quot")
+                 , (Rem,  "rem")
+                 , (Equal True, "==="), (Equal False, "=="), (NotEqual, "/="), (Implies, "=>")
+                 , (LessThan, "<"), (GreaterThan, ">"), (LessEq, "<="), (GreaterEq, ">=")
+                 , (Ite, "if_then_else")
+                 , (And, "&"), (Or, "|"), (XOr, "^"), (Not, "~")
+                 , (Join, "#")
+                 ]
+
+-- | Quantifiers: forall or exists. Note that we allow arbitrary nestings.
+data Quantifier = ALL | EX deriving (Eq, G.Data)
+
+-- | Show instance for 'Quantifier'
+instance Show Quantifier where
+  show ALL = "Forall"
+  show EX  = "Exists"
+
+-- | Which context is this variable being created?
+data VarContext = NonQueryVar (Maybe Quantifier)  -- in this case, it can be quantified
+                | QueryVar                        -- in this case, it is always existential
+
+-- | Are there any existential quantifiers?
+needsExistentials :: [Quantifier] -> Bool
+needsExistentials = (EX `elem`)
+
+-- | A simple type for SBV computations, used mainly for uninterpreted constants.
+-- We keep track of the signedness/size of the arguments. A non-function will
+-- have just one entry in the list.
+newtype SBVType = SBVType [Kind]
+                deriving (Eq, Ord, G.Data)
+
+instance Show SBVType where
+  show (SBVType []) = error "SBV: internal error, empty SBVType"
+  show (SBVType xs) = intercalate " -> " $ map show xs
+
+-- | A symbolic expression
+data SBVExpr = SBVApp !Op ![SV]
+             deriving (Eq, Ord, G.Data)
+
+-- | To improve hash-consing, take advantage of commutative operators by
+-- reordering their arguments.
+reorder :: SBVExpr -> SBVExpr
+reorder s = case s of
+              SBVApp op [a, b] | isCommutative op && a > b -> SBVApp op [b, a]
+              _ -> s
+  where isCommutative :: Op -> Bool
+        isCommutative o = o `elem` [Plus, Times, Equal True, Equal False, NotEqual, And, Or, XOr]
+
+-- Show instance for 'SBVExpr'. Again, only for debugging purposes.
+instance Show SBVExpr where
+  show (SBVApp Ite [t, a, b])           = unwords ["if", show t, "then", show a, "else", show b]
+  show (SBVApp Shl     [a, i])          = unwords [show a, "<<", show i]
+  show (SBVApp Shr     [a, i])          = unwords [show a, ">>", show i]
+  show (SBVApp (Rol i) [a])             = unwords [show a, "<<<", show i]
+  show (SBVApp (Ror i) [a])             = unwords [show a, ">>>", show i]
+  show (SBVApp (PseudoBoolean pb) args) = unwords (show pb : map show args)
+  show (SBVApp (OverflowOp op)    args) = unwords (show op : map show args)
+
+  show (SBVApp op args) | showOpInfix op, length args == 2 = unwords (map show (take 1 args) ++ show op : map show (drop 1 args))
+                        | True                             = unwords (show op : map show args)
+
+-- | Should we display this Op infix?
+showOpInfix :: Op -> Bool
+showOpInfix = (`elem` infixOps)
+  where infixOps = [ Plus, Times, Minus, Quot, Rem, Implies
+                   , Equal True, Equal False, NotEqual, LessThan, GreaterThan, LessEq, GreaterEq
+                   , And, Or, XOr, Join
+                   ]
+
+-- | A program is a sequence of assignments
+newtype SBVPgm = SBVPgm {pgmAssignments :: S.Seq (SV, SBVExpr)}
+               deriving G.Data
+
+-- | Helper synonym for text, in case we switch to something else later.
+type Name = T.Text
+
+-- | t'NamedSymVar' pairs symbolic values and user given/automatically generated names
+data NamedSymVar = NamedSymVar !SV !Name
+                 deriving (Show, Generic, G.Data)
+
+-- | For comparison purposes, we simply use the SV and ignore the name
+instance Eq NamedSymVar where
+  (==) (NamedSymVar l _) (NamedSymVar r _) = l == r
+
+instance Ord NamedSymVar where
+  compare (NamedSymVar l _) (NamedSymVar r _) = compare l r
+
+-- | Convert to a named symvar, from text
+toNamedSV :: SV -> Name -> NamedSymVar
+toNamedSV = NamedSymVar
+
+-- | Get the SV from a named sym var
+getSV :: NamedSymVar -> SV
+getSV (NamedSymVar s _) = s
+
+-- | Get the user-name typed value from named sym var
+getUserName :: NamedSymVar -> Name
+getUserName (NamedSymVar _ nm) = nm
+
+-- | Get the string typed value from named sym var
+getUserName' :: NamedSymVar -> String
+getUserName' = T.unpack . getUserName
+
+-- | Style of optimization. Note that in the pareto case the user is allowed
+-- to specify a max number of fronts to query the solver for, since there might
+-- potentially be an infinite number of them and there is no way to know exactly
+-- how many ahead of time. If 'Nothing' is given, SBV will possibly loop forever
+-- if the number is really infinite.
+data OptimizeStyle = Lexicographic      -- ^ Objectives are optimized in the order given, earlier objectives have higher priority.
+                   | Independent        -- ^ Each objective is optimized independently.
+                   | Pareto (Maybe Int) -- ^ Objectives are optimized according to pareto front: That is, no objective can be made better without making some other worse.
+                   deriving (Eq, Show)
+
+-- | Penalty for a soft-assertion. The default penalty is @1@, with all soft-assertions belonging
+-- to the same objective goal. A positive weight and an optional group can be provided by using
+-- the v'Penalty' constructor.
+data Penalty = DefaultPenalty                  -- ^ Default: Penalty of @1@ and no group attached
+             | Penalty Rational (Maybe String) -- ^ Penalty with a weight and an optional group
+             deriving Show
+
+-- | Objective of optimization. We can minimize, maximize, or give a soft assertion with a penalty
+-- for not satisfying it.
+data Objective a = Minimize          String a         -- ^ Minimize this metric
+                 | Maximize          String a         -- ^ Maximize this metric
+                 | AssertWithPenalty String a Penalty -- ^ A soft assertion, with an associated penalty
+                 deriving (Show, Functor)
+
+-- | The name of the objective
+objectiveName :: Objective a -> String
+objectiveName (Minimize          s _)   = s
+objectiveName (Maximize          s _)   = s
+objectiveName (AssertWithPenalty s _ _) = s
+
+-- | The state we keep track of as we interact with the solver
+data QueryState = QueryState { queryAsk                 :: Maybe Int -> Text -> IO String
+                             , querySend                :: Maybe Int -> Text -> IO ()
+                             , queryRetrieveResponse    :: Maybe Int -> IO String
+                             , queryConfig              :: SMTConfig
+                             , queryTerminate           :: Maybe C.SomeException -> IO ()
+                             , queryTimeOutValue        :: Maybe Int
+                             , queryAssertionStackDepth :: !Int
+                             }
+
+-- | Computations which support query operations.
+class Monad m => MonadQuery m where
+  queryState :: m State
+
+  default queryState :: (MonadTrans t, MonadQuery m', m ~ t m') => m State
+  queryState = lift queryState
+
+instance MonadQuery m             => MonadQuery (ExceptT e m)
+instance MonadQuery m             => MonadQuery (MaybeT m)
+instance MonadQuery m             => MonadQuery (ReaderT r m)
+instance MonadQuery m             => MonadQuery (SS.StateT s m)
+instance MonadQuery m             => MonadQuery (LS.StateT s m)
+instance (MonadQuery m, Monoid w) => MonadQuery (SW.WriterT w m)
+instance (MonadQuery m, Monoid w) => MonadQuery (LW.WriterT w m)
+
+-- | A query is a user-guided mechanism to directly communicate and extract
+-- results from the solver. A generalization of 'Data.SBV.Query'.
+newtype QueryT m a = QueryT { runQueryT :: ReaderT State m a }
+    deriving newtype (Applicative, Functor, Monad, MonadIO, MonadTrans, MonadError e, MonadState s, MonadWriter w)
+
+instance Monad m => MonadQuery (QueryT m) where
+  queryState = QueryT ask
+
+mapQueryT :: (ReaderT State m a -> ReaderT State n b) -> QueryT m a -> QueryT n b
+mapQueryT f = QueryT . f . runQueryT
+{-# INLINE mapQueryT #-}
+
+-- Have to define this one by hand, because we use ReaderT in the implementation
+instance MonadReader r m => MonadReader r (QueryT m) where
+  ask = lift ask
+  local f = mapQueryT $ mapReaderT $ local f
+
+-- | A query is a user-guided mechanism to directly communicate and extract
+-- results from the solver.
+type Query = QueryT IO
+
+instance MonadSymbolic Query where
+   symbolicEnv = queryState
+
+instance NFData OptimizeStyle where
+   rnf x = x `seq` ()
+
+instance NFData Penalty where
+   rnf DefaultPenalty  = ()
+   rnf (Penalty p mbs) = rnf p `seq` rnf mbs
+
+instance NFData a => NFData (Objective a) where
+   rnf (Minimize          s a)   = rnf s `seq` rnf a
+   rnf (Maximize          s a)   = rnf s `seq` rnf a
+   rnf (AssertWithPenalty s a p) = rnf s `seq` rnf a `seq` rnf p
+
+-- | A result can either produce something at the top or as a lambda/constraint. Distinguish by inputs
+data ResultInp = ResultTopInps ([NamedSymVar], [NamedSymVar])  -- user inputs -- trackers
+               | ResultLamInps [(Quantifier, NamedSymVar)]     -- for constraints, we can have quantifiers
+               deriving G.Data
+
+instance NFData ResultInp where
+   rnf (ResultTopInps xs) = rnf xs
+   rnf (ResultLamInps xs) = rnf xs
+
+-- | Several data about the program
+data ProgInfo = ProgInfo { hasQuants         :: !Bool
+                         , progSpecialRels   :: ![SpecialRelOp]
+                         , progTransClosures :: ![(String, String)]
+                         }
+                         deriving G.Data
+
+instance NFData ProgInfo where
+   rnf (ProgInfo a b c) = rnf a `seq` rnf b `seq` rnf c
+
+deriving instance G.Data CallStack
+deriving instance G.Data SrcLoc
+
+-- | Result of running a symbolic computation
+data Result = Result { progInfo       :: ProgInfo                                     -- ^ various info we collect about the program
+                     , reskinds       :: Set.Set Kind                                 -- ^ kinds used in the program
+                     , resTraces      :: [(String, CV)]                               -- ^ quick-check counter-example information (if any)
+                     , resObservables :: [(String, CV -> Bool, SV)]                   -- ^ observable expressions (part of the model)
+                     , resUISegs      :: [(String, [String])]                         -- ^ uninterpreted code segments
+                     , resParams      :: ResultInp                                    -- ^ top-inputs or lambda params
+                     , resConsts      :: (CnstMap, [(SV, CV)])                        -- ^ constants
+                     , resTables      :: [((Int, Kind, Kind), [SV])]                  -- ^ tables (automatically constructed) (tableno, index-type, result-type) elts
+                     , resUIConsts    :: [(String, (Bool, Maybe [String], SBVType))]  -- ^ uninterpreted constants
+                     , resDefinitions :: [(String, (SMTDef, SBVType))]                -- ^ definitions created via smtFunction
+                     , resAsgns       :: SBVPgm                                       -- ^ assignments
+                     , resConstraints :: S.Seq (Bool, [(String, String)], SV)         -- ^ additional constraints (boolean)
+                     , resAssertions  :: [(String, Maybe CallStack, SV)]              -- ^ assertions
+                     , resOutputs     :: [SV]                                         -- ^ outputs
+                     }
+                     deriving G.Data
+
+-- Show instance for 'Result'. Only for debugging purposes.
+instance Show Result where
+  -- If there's nothing interesting going on, just print the constant. Note that the
+  -- definition of interesting here is rather subjective; but essentially if we reduced
+  -- the result to a single constant already, without any reference to anything.
+  show Result{resConsts=(_, cs), resOutputs=[r]}
+    | Just c <- r `lookup` cs
+    = show c
+  show (Result _ kinds _ _ cgs params (_, cs) ts uis defns xs cstrs asserts os) = intercalate "\n" $
+                   (if null usorts then [] else "SORTS" : map ("  " ++) usorts)
+                ++ (case params of
+                      ResultTopInps (i, t) -> "INPUTS" : map shn i ++ (if null t then [] else "TRACKER VARS" : map shn t)
+                      ResultLamInps qs     -> "LAMBDA-CONSTRAINT PARAMS" : map shq qs
+                   )
+                ++ ["CONSTANTS"]
+                ++ concatMap shc cs
+                ++ ["TABLES"]
+                ++ map sht ts
+                ++ ["UNINTERPRETED CONSTANTS"]
+                ++ map shui uis
+                ++ ["USER GIVEN CODE SEGMENTS"]
+                ++ concatMap shcg cgs
+                ++ ["AXIOMS-DEFINITIONS"]
+                ++ map show defns
+                ++ ["DEFINE"]
+                ++ map (\(s, e) -> "  " ++ shs s ++ " = " ++ show e) (F.toList (pgmAssignments xs))
+                ++ ["CONSTRAINTS"]
+                ++ map (("  " ++) . shCstr) (F.toList cstrs)
+                ++ ["ASSERTIONS"]
+                ++ map (("  "++) . shAssert) asserts
+                ++ ["OUTPUTS"]
+                ++ sh2 os
+    where sh2 :: Show a => [a] -> [String]
+          sh2 = map (("  "++) . show)
+
+          usorts = [s | KADT s _ _ <- filter isUninterpreted (Set.toList kinds)]
+
+          shs sv = show sv ++ " :: " ++ show (swKind sv)
+
+          sht ((i, at, rt), es)  = "  Table " ++ show i ++ " : " ++ show at ++ "->" ++ show rt ++ " = " ++ show es
+
+          shc (sv, cv)
+            | sv == falseSV || sv == trueSV
+            = []
+            | True
+            = ["  " ++ show sv ++ " = " ++ show cv]
+
+          shcg (s, ss) = ("Variable: " ++ s) : map ("  " ++) ss
+
+          shn (NamedSymVar sv nm) = "  " ++ ni ++ " :: " ++ show (swKind sv) ++ alias
+            where ni = show sv
+
+                  alias | T.pack ni == nm = ""
+                        | True              = ", aliasing " ++ show nm
+
+          shq (q, v) = shn v ++ ", " ++ if q == ALL then "universal" else "existential"
+
+          shui (nm, t) = "  [uninterpreted] " ++ nm ++ " :: " ++ show t
+
+          shCstr (isSoft, [], c)               = soft isSoft ++ show c
+          shCstr (isSoft, [(":named", nm)], c) = soft isSoft ++ nm ++ ": " ++ show c
+          shCstr (isSoft, attrs, c)            = soft isSoft ++ show c ++ " (attributes: " ++ show attrs ++ ")"
+
+          soft True  = "[SOFT] "
+          soft False = ""
+
+          shAssert (nm, stk, p) = "  -- assertion: " ++ nm ++ " " ++ maybe "[No location]"
+                prettyCallStack
+                stk ++ ": " ++ show p
+
+-- | Expression map, used for hash-consing
+type ExprMap = Map.Map SBVExpr SV
+
+-- | Constants are stored in a map, for hash-consing.
+type CnstMap = Map.Map CV SV
+
+-- | Kinds used in the program; used for determining the final SMT-Lib logic to pick
+type KindSet = Set.Set Kind
+
+-- | Tables generated during a symbolic run
+type TableMap = Map.Map (Kind, Kind, [SV]) Int
+
+-- | Uninterpreted-constants generated during a symbolic run
+type UIMap = Map.Map String (Bool, Maybe [String], SBVType)   -- If Bool is true, then this is a curried function
+
+-- | Code-segments for Uninterpreted-constants, as given by the user
+type CgMap = Map.Map String [String]
+
+-- | Cached values, implementing sharing
+type Cache a = IMap.IntMap [(StableName (State -> IO a), a)]
+
+-- | Stage of an interactive run
+data IStage = ISetup        -- Before we initiate contact.
+            | ISafe         -- In the context of a safe/safeWith call
+            | IRun          -- After the contact is started
+
+-- | Are we checking safety
+isSafetyCheckingIStage :: IStage -> Bool
+isSafetyCheckingIStage s = case s of
+                             ISetup -> False
+                             ISafe  -> True
+                             IRun   -> False
+
+-- | Are we in setup?
+isSetupIStage :: IStage -> Bool
+isSetupIStage s = case s of
+                   ISetup -> True
+                   ISafe  -> False
+                   IRun   -> True
+
+-- | Are we in a run?
+isRunIStage :: IStage -> Bool
+isRunIStage s = case s of
+                  ISetup -> False
+                  ISafe  -> False
+                  IRun   -> True
+
+-- | Different means of running a symbolic piece of code
+data SBVRunMode = SMTMode QueryContext IStage Bool SMTConfig   -- ^ In regular mode, with a stage. Bool is True if this is SAT.
+                | CodeGen                                      -- ^ Code generation mode.
+                | LambdaGen (Maybe Int)                        -- ^ Inside a lambda-expression at level. If Nothing, then closed lambda.
+                | Concrete (Maybe (Bool, [(NamedSymVar, CV)])) -- ^ Concrete simulation mode, with given environment if any. If Nothing: Random.
+
+-- Show instance for SBVRunMode; debugging purposes only
+instance Show SBVRunMode where
+   show (SMTMode qc ISetup True  _)  = "Satisfiability setup (" ++ show qc ++ ")"
+   show (SMTMode qc ISafe  True  _)  = "Safety setup (" ++ show qc ++ ")"
+   show (SMTMode qc IRun   True  _)  = "Satisfiability (" ++ show qc ++ ")"
+   show (SMTMode qc ISetup False _)  = "Proof setup (" ++ show qc ++ ")"
+   show (SMTMode qc ISafe  False _)  = error $ "ISafe-False is not an expected/supported combination for SBVRunMode! (" ++ show qc ++ ")"
+   show (SMTMode qc IRun   False _)  = "Proof (" ++ show qc ++ ")"
+   show CodeGen                      = "Code generation"
+   show LambdaGen{}                  = "Lambda generation"
+   show (Concrete Nothing)           = "Concrete evaluation with random values"
+   show (Concrete (Just (True, _)))  = "Concrete evaluation during model validation for sat"
+   show (Concrete (Just (False, _))) = "Concrete evaluation during model validation for prove"
+
+-- | Is this a CodeGen run? (i.e., generating code)
+isCodeGenMode :: State -> IO Bool
+isCodeGenMode State{runMode} = do rm <- readIORef runMode
+                                  pure $ case rm of
+                                           Concrete{}  -> False
+                                           SMTMode{}   -> False
+                                           LambdaGen{} -> False
+                                           CodeGen     -> True
+
+-- | The state in query mode, i.e., additional context
+data IncState = IncState { rNewInps          :: IORef [NamedSymVar]   -- always existential!
+                         , rNewKinds         :: IORef KindSet
+                         , rNewConsts        :: IORef CnstMap
+                         , rNewTbls          :: IORef TableMap
+                         , rNewUIs           :: IORef UIMap
+                         , rNewDefns         :: IORef (Map.Map String (SMTDef, SBVType))
+                         , rNewMeasureChecks :: IORef [(String, Bool, SMTConfig -> IO ())]
+                         , rNewAsgns         :: IORef SBVPgm
+                         , rNewConstraints   :: IORef (S.Seq (Bool, [(String, String)], SV))
+                         }
+
+-- | Get a new IncState
+newIncState :: IO IncState
+newIncState = do
+        is    <- newIORef []
+        ks    <- newIORef Set.empty
+        nc    <- newIORef Map.empty
+        tm    <- newIORef Map.empty
+        ui    <- newIORef Map.empty
+        ds    <- newIORef Map.empty
+        ms    <- newIORef []
+        pgm   <- newIORef (SBVPgm S.empty)
+        cstrs <- newIORef S.empty
+        pure IncState { rNewInps          = is
+                      , rNewKinds         = ks
+                      , rNewConsts        = nc
+                      , rNewTbls          = tm
+                      , rNewUIs           = ui
+                      , rNewDefns         = ds
+                      , rNewMeasureChecks = ms
+                      , rNewAsgns         = pgm
+                      , rNewConstraints   = cstrs
+                      }
+
+-- | Get a new IncState
+withNewIncState :: State -> (State -> IO a) -> IO (IncState, a)
+withNewIncState st cont = do
+        is <- newIncState
+        R.modifyIORef' (rIncState st) (const is)
+        r  <- cont st
+        finalIncState <- readIORef (rIncState st)
+        pure (finalIncState, r)
+
+-- | User defined inputs
+type UserInputs = S.Seq NamedSymVar
+
+-- | Internally declared
+type InternInps = S.Seq NamedSymVar
+
+-- | Entire set of names, for faster lookup
+type AllInps = Set.Set Name
+
+-- | Inputs as a record of maps and sets. See above type-synonyms for their roles.
+data Inputs = Inputs { userInputs   :: !UserInputs
+                     , internInputs :: !InternInps
+                     , allInputs    :: !AllInps
+                     } deriving (Eq,Show)
+
+-- | Inputs to a lambda-abstraction. These are quantified to handle constraints
+type LambdaInputs = S.Seq (Quantifier, NamedSymVar)
+
+-- | Semigroup instance; combining according to indexes.
+instance Semigroup Inputs where
+  (Inputs lui lii lai) <> (Inputs rui rii rai) = Inputs (lui <> rui) (lii <> rii) (lai <> rai)
+
+-- | Monoid instance, we start with no maps.
+instance Monoid Inputs where
+  mempty = Inputs { userInputs   = mempty
+                  , internInputs = mempty
+                  , allInputs    = mempty
+                  }
+
+-- | Modify the user-inputs field
+onUserInputs :: (UserInputs -> UserInputs) -> Inputs -> Inputs
+onUserInputs f inp@Inputs{userInputs} = inp{userInputs = f userInputs}
+
+-- | Modify the internal-inputs field
+onInternInputs :: (InternInps -> InternInps) -> Inputs -> Inputs
+onInternInputs f inp@Inputs{internInputs} = inp{internInputs = f internInputs}
+
+-- | Modify the all-inputs field
+onAllInputs :: (AllInps -> AllInps) -> Inputs -> Inputs
+onAllInputs f inp@Inputs{allInputs} = inp{allInputs = f allInputs}
+
+-- | Add a new internal input
+addInternInput :: SV -> Name -> Inputs -> Inputs
+addInternInput sv nm = goAll . goIntern
+  where !new = toNamedSV sv nm
+        goIntern = onInternInputs (S.|> new)
+        goAll    = onAllInputs    (Set.insert nm)
+
+-- | Add a new user input
+addUserInput :: SV -> Name -> Inputs -> Inputs
+addUserInput sv nm = goAll . goUser
+  where !new   = toNamedSV sv nm
+        goUser = onUserInputs (S.|> new)        -- add to the end of the sequence
+        goAll  = onAllInputs  (Set.insert nm)
+
+-- | Find a user-input from its SV. Note that only level-0 vars
+-- can be found this way.
+lookupInput :: (a -> SV) -> SV -> S.Seq a -> Maybe a
+lookupInput f sv ns
+   | l == Just 0 = res
+   | True        = Nothing  -- l != Just 0, a lambda var, whether top-level or in a scope, so we ignore
+  where
+    (_, l, i) = getId (swNodeId sv)
+    svs       = f <$> ns
+    res       = case S.lookup i ns of -- Nothing on negative Int or Int > length seq
+                  Nothing    -> secondLookup
+                  x@(Just e) -> if sv == f e then x else secondLookup
+                    -- we try the fast lookup first, if the node ids don't match then
+                    -- we use the more expensive O (n) to find the index and the elem
+    secondLookup = S.elemIndexL sv svs >>= flip S.lookup ns
+
+-- | A defined function/value, optionally retaining its structured expression
+-- DAG for consumers other than SMT-Lib.
+data SMTDef = SMTDefValue Kind               -- ^ Final kind of the definition (resulting kind, not the params)
+                          [String]           -- ^ other definitions it refers to
+                          (Maybe Text)       -- ^ parameter string
+                          (Int -> Text)      -- ^ Body, in SMTLib syntax, given the tab amount
+                          (Maybe LambdaInfo) -- ^ Structured function body, when constructed by SBV
+            deriving G.Data
+
+-- | Compatibility constructor and pattern for an SMT-text definition. The
+-- pattern also matches definitions carrying retained backend metadata.
+pattern SMTDef :: Kind -> [String] -> Maybe Text -> (Int -> Text) -> SMTDef
+pattern SMTDef resultKind dependencies parameters body <- SMTDefValue resultKind dependencies parameters body _
+  where SMTDef resultKind dependencies parameters body = SMTDefValue resultKind dependencies parameters body Nothing
+
+{-# COMPLETE SMTDef #-}
+
+-- | Attach a structured expression DAG to an SMT definition.
+smtDefWithInfo :: SMTDef -> LambdaInfo -> SMTDef
+smtDefWithInfo (SMTDefValue resultKind dependencies parameters body _) lambdaInfo
+  = SMTDefValue resultKind dependencies parameters body (Just lambdaInfo)
+
+-- | Return a definition's retained expression DAG, when it was constructed by
+-- SBV rather than supplied only as SMT-Lib text.
+smtDefInfo :: SMTDef -> Maybe LambdaInfo
+smtDefInfo (SMTDefValue _ _ _ _ lambdaInfo) = lambdaInfo
+
+-- | For debug purposes
+instance Show SMTDef where
+  show (SMTDefValue fk frees p body _) = unlines [ "-- User defined function:"
+                                                      , "-- Final return type    : " ++ show fk
+                                                      , "-- Refers to            : " ++ intercalate ", " frees
+                                                      , "-- Parameters           : " ++ maybe "NONE" T.unpack p
+                                                      , "-- Body                 : "
+                                                      , T.unpack (body 2)
+                                                      ]
+
+-- | NFData instance for SMTDef
+instance NFData SMTDef where
+  rnf (SMTDefValue fk frees params body lambdaInfo)
+    = rnf fk `seq` rnf frees `seq` rnf params `seq` rnf body `seq` rnf lambdaInfo
+
+-- | Compare two SMTDef values for semantic equality.
+-- The body is @(Int -> Text)@ where @Int@ is indentation; we compare rendered output at indent 0.
+smtDefEq :: SMTDef -> SMTDef -> Bool
+smtDefEq (SMTDefValue k1 refs1 params1 body1 _) (SMTDefValue k2 refs2 params2 body2 _)
+  = k1 == k2 && refs1 == refs2 && params1 == params2 && body1 0 == body2 0
+
+-- | Error for conflicting smtFunction definitions with the same name.
+conflictError :: String -> a
+conflictError nm = error $ unlines [ ""
+                                   , "*** Data.SBV: Function '" ++ nm ++ "' defined with conflicting bodies."
+                                   , "***"
+                                   , "*** Two calls to smtFunction (or related) used the name '" ++ nm ++ "'"
+                                   , "*** but with different definitions. This would generate conflicting"
+                                   , "*** SMTLib define-fun-rec declarations."
+                                   , "***"
+                                   , "*** Please use a unique name for each distinct function."
+                                   ]
+
+-- | Structured information about a compiled lambda body, used for measure
+-- verification and by backends that should not parse its SMT-Lib rendering.
+data LambdaInfo = LambdaInfo
+  { liAssignments :: S.Seq (SV, SBVExpr)        -- ^ The expression DAG
+  , liParams      :: [(Quantifier, SV)]          -- ^ Formal parameters with quantifier
+  , liOutput      :: SV                          -- ^ The output node
+  , liConsts      :: [(SV, CV)]                  -- ^ Constants used
+  , liTables      :: [((Int, Kind, Kind), [SV])] -- ^ Finite lookup tables used by the body
+  } deriving G.Data
+
+-- | Fully evaluate the retained pieces of a compiled lambda body.
+instance NFData LambdaInfo where
+  rnf LambdaInfo{liAssignments, liParams, liOutput, liConsts, liTables}
+    = rnf liAssignments `seq` rnf liParams `seq` rnf liOutput `seq` rnf liConsts `seq` rnf liTables
+
+-- | The state of the symbolic interpreter
+data State  = State { sbvContext            :: SBVContext
+                    , pathCond              :: SVal                             -- ^ kind KBool
+                    , stCfg                 :: SMTConfig
+                    , startTime             :: UTCTime
+                    , rProgInfo             :: IORef ProgInfo
+                    , runMode               :: IORef SBVRunMode
+                    , rIncState             :: IORef IncState
+                    , rCInfo                :: IORef [(String, CV)]
+                    , rObservables          :: IORef (S.Seq (Name, CV -> Bool, SV))
+                    , rctr                  :: IORef Int             -- Used for numbering SVs
+                    , freshNameCtr          :: IORef Int             -- Used for calls to some
+                    , rLambdaLevel          :: IORef (Maybe Int)     -- If Nothing, then top-level lambda
+                    , rUsedKinds            :: IORef KindSet
+                    , rUsedLbls             :: IORef (Set.Set String)
+                    , rinps                 :: IORef Inputs
+                    , rlambdaInps           :: IORef LambdaInputs
+                    , rConstraints          :: IORef (S.Seq (Bool, [(String, String)], SV))
+                    , rPartitionVars        :: IORef [String]
+                    , routs                 :: IORef [SV]
+                    , rtblMap               :: IORef TableMap
+                    , spgm                  :: IORef SBVPgm
+                    , rconstMap             :: IORef CnstMap
+                    , rexprMap              :: IORef ExprMap
+                    , rUIMap                :: IORef UIMap
+                    , rUserFuncs            :: IORef (Map.Map String (Set.Set Int, Maybe Int)) -- Functions with explicit code generation; maps name to (verified StableName hashes, lambda level at first compilation)
+                    , rCompilingFuncs       :: IORef (Set.Set String)     -- Functions currently being compiled (used to detect recursive self-calls vs. genuine conflicts)
+                    , rCgMap                :: IORef CgMap
+                    , rDefns                :: IORef (Map.Map String (SMTDef, SBVType))
+                    , rMeasureChecks        :: IORef [(String, Bool, SMTConfig -> IO ())]  -- Measure checks for recursive functions. Bool is True for productive (guarded), False for terminating.
+                    , rFuncLambdaInfos      :: IORef (Map.Map String LambdaInfo)            -- LambdaInfo for all smtFunction definitions, used for mutual recursion checking
+                    , rSkipMeasureChecks    :: IORef Bool                                   -- If True, skip measure checking (used by TP and checker itself)
+                    , rNoTermCheckFunctions :: IORef (Set.Set String)                      -- Functions defined with smtFunctionNoTermination (no termination check)
+                    , rSMTOptions           :: IORef [SMTOption]
+                    , rOptGoals             :: IORef [Objective (SV, SV)]
+                    , rAsserts              :: IORef [(String, Maybe CallStack, SV)]
+                    , rOutstandingAsserts   :: IORef Bool            -- Did we send an assert after the last check-sat call?
+                    , rSVCache              :: IORef (Cache SV)
+                    , rQueryState           :: IORef (Maybe QueryState)
+                    , parentState           :: Maybe State  -- Pointer to our parent if we're in a sublevel
+                    }
+
+-- | Chase to the root state. No infinite chains!
+getRootState :: State -> State
+getRootState st = maybe st getRootState (parentState st)
+
+-- NFData is a bit of a lie, but it's sufficient, most of the content is iorefs that we don't want to touch
+instance NFData State where
+   rnf State{} = ()
+
+-- | Get the current path condition
+getSValPathCondition :: State -> SVal
+getSValPathCondition = pathCond
+
+-- | Extend the path condition with the given test value.
+extendSValPathCondition :: State -> (SVal -> SVal) -> State
+extendSValPathCondition st f = st{pathCond = f (pathCond st)}
+
+-- | Are we running in proof mode?
+inSMTMode :: State -> IO Bool
+inSMTMode State{runMode} = do rm <- readIORef runMode
+                              pure $ case rm of
+                                       CodeGen     -> False
+                                       LambdaGen{} -> False
+                                       Concrete{}  -> False
+                                       SMTMode{}   -> True
+
+-- | The "Symbolic" value. Either a constant (@Left@) or a symbolic
+-- value (@Right Cached@). Note that caching is essential for making
+-- sure sharing is preserved.
+data SVal = SVal !Kind !(Either CV (Cached SV))
+
+-- | Kind instance for SVal simply passes the kind out
+instance HasKind SVal where
+  kindOf (SVal k _) = k
+
+-- Show instance for t'SVal'. Not particularly "desirable", but will do if needed
+-- NB. We do not show the type info on constant KBool values, since there's no
+-- implicit "fromBoolean" applied to Booleans in Haskell; and thus a statement
+-- of the form "True :: SBool" is just meaningless. (There should be a fromBoolean!)
+instance Show SVal where
+  show (SVal KBool (Left c))  = showCV False c
+  show (SVal k     (Left c))  = showCV False c ++ " :: " ++ show k
+  show (SVal k     (Right _)) =         "<symbolic> :: " ++ show k
+
+-- | Things we do not support in interactive mode, at least for now!
+noInteractive :: [String] -> a
+noInteractive ss = error $ unlines $  ""
+                                   :  "*** Data.SBV: Unsupported interactive/query mode feature."
+                                   :  map ("***  " ++) ss
+                                   ++ ["*** Data.SBV: Please report this as a feature request!"]
+
+-- | Things we do not support in interactive mode, nor we ever intend to
+noInteractiveEver :: [String] -> a
+noInteractiveEver ss = error $ unlines $  ""
+                                       :  "*** Data.SBV: Unsupported interactive/query mode feature."
+                                       :  map ("***  " ++) ss
+
+-- | Modification of the state, but carefully handling the interactive tasks.
+-- Note that the state is always updated regardless of the mode, but we get
+-- to also perform extra operation in interactive mode. (Typically error out, but also simply
+-- ignore if it has no impact.)
+modifyState :: State -> (State -> IORef a) -> (a -> a) -> IO () -> IO ()
+modifyState st@State{runMode} field update interactiveUpdate = do
+        R.modifyIORef' (field st) update
+        rm <- readIORef runMode
+        case rm of
+          SMTMode _ IRun _ _ -> interactiveUpdate
+          _                  -> pure ()
+
+-- | Modify the incremental state
+modifyIncState  :: State -> (IncState -> IORef a) -> (a -> a) -> IO ()
+modifyIncState State{rIncState} field update = do
+        incState <- readIORef rIncState
+        R.modifyIORef' (field incState) update
+
+-- | Add an observable
+recordObservable :: State -> Text -> (CV -> Bool) -> SV -> IO ()
+recordObservable st nm chk sv = modifyState st rObservables (S.|> (nm, chk, sv)) (pure ())
+
+-- | Increment the variable counter
+incrementInternalCounter :: State -> IO Int
+incrementInternalCounter st = do ctr <- readIORef (rctr st)
+                                 modifyState st rctr (+1) (pure ())
+                                 pure ctr
+{-# INLINE incrementInternalCounter #-}
+
+-- | Increment the fresh-var counter
+incrementFreshNameCounter :: State -> IO Int
+incrementFreshNameCounter st = do ctr <- readIORef (freshNameCtr st)
+                                  modifyState st freshNameCtr (+1) (pure ())
+                                  pure ctr
+{-# INLINE incrementFreshNameCounter #-}
+
+-- | Kind of code we have for uninterpretation
+data UICodeKind = UINone Bool     -- no code. If bool is true, then curried.
+                | UISMT  SMTDef   -- SMTLib, first argument are the free-variables in it
+                | UICgC  [String] -- Code-gen, currently only C
+
+-- | A newtype wrapper for uninterpreted function names. We distinguish between user names and those of constructors
+data UIName = UIGiven String -- ^ Full name
+            | UIADT   ADTOp  -- ^ The name of an ADT operation based on the constructor
+
+-- | Uninterpreted constants and functions. An uninterpreted constant is
+-- a value that is indexed by its name. The only property the prover assumes
+-- about these values are that they are equivalent to themselves; i.e., (for
+-- functions) they return the same results when applied to same arguments.
+-- We support uninterpreted-functions as a general means of black-box'ing
+-- operations that are /irrelevant/ for the purposes of the proof; i.e., when
+-- the proofs can be performed without any knowledge about the function itself.
+svUninterpreted :: Kind -> UIName -> UICodeKind -> [SVal] -> SVal
+svUninterpreted k nm code args = svUninterpretedGen k nm code args Nothing
+
+svUninterpretedNamedArgs :: Kind -> UIName -> UICodeKind -> [(SVal, String)] -> SVal
+svUninterpretedNamedArgs k nm code args = svUninterpretedGen k nm code (map fst args) (Just (map snd args))
+
+svUninterpretedGen :: Kind -> UIName -> UICodeKind -> [SVal] -> Maybe [String] -> SVal
+svUninterpretedGen k nm code args mbArgNames = SVal k $ Right $ cache result
+  where result st = do let ty = SBVType (map kindOf args ++ [k])
+                       op <- newUninterpreted st nm mbArgNames ty code
+                       sws <- mapM (svToSV st) args
+                       mapM_ forceSVArg sws
+                       newExpr st k $ SBVApp op sws
+
+-- | Create a new value, possibly with user given code. This function might change
+-- the name given, putting bars around it if needed. That's the name returned.
+newUninterpreted :: State -> UIName -> Maybe [String] -> SBVType -> UICodeKind -> IO Op
+newUninterpreted st uiName mbArgNames t uiCode = do
+
+  let rootState = getRootState st
+
+      (adtOp, candName) = case uiName of
+                            UIGiven n -> (False, n)
+                            UIADT   o -> case o of
+                                           ADTConstructor n _ -> (True, T.unpack n)
+                                           ADTTester      n _ -> (True, T.unpack n)
+                                           ADTAccessor    n _ -> (True, T.unpack n)
+
+  -- determine the final name. We leave constructors alone.
+  let nm = case () of
+             () | "__internal_sbv_" `isPrefixOf` candName -> candName        -- internal names go thru
+                | adtOp                                   -> candName        -- ADT names go thru
+                | True                                    -> barify candName -- surround with bars if not legitimate in SMTLib
+
+      extraComment = case uiName of
+                      UIGiven  n | nm /= n -> " (Given: " ++ n ++ ")"
+                      _                    -> ""
+
+  -- Check if reserved:
+  when (isReserved nm) $
+      error $ unlines [ ""
+                      , "*** Data.SBV: User given name " ++ show nm ++ " is a reserved name in SMTLib."
+                      , "***"
+                      , "*** Please use a different name to avoid collisions."
+                      ]
+
+  isCurried <- case uiCode of
+                 UINone c -> pure c
+                 UISMT d  -> do -- Check for conflicting definitions with the same name
+                                defs <- readIORef (rDefns st)
+                                case Map.lookup nm defs of
+                                  Just (oldDef, _)
+                                    | not (smtDefEq d oldDef)
+                                    -> conflictError nm
+                                  Just{}  -> pure ()
+                                  Nothing -> modifyState rootState rDefns (Map.insert nm (d, t))
+                                               $ modifyIncState rootState rNewDefns (Map.insert nm (d, t))
+                                pure True
+                 UICgC c  -> -- No need to record the code in interactive mode: CodeGen doesn't use interactive
+                             do modifyState st rCgMap (Map.insert nm c) (pure ())
+                                pure True
+
+  let checkType :: SBVType -> r -> r
+      checkType t' cont
+        | t /= t' = error $  "Uninterpreted constant " ++ show nm ++ extraComment ++ " used at incompatible types\n"
+                          ++ "      Current type      : " ++ show t ++ "\n"
+                          ++ "      Previously used at: " ++ show t'
+        | True    = cont
+
+  -- If we're not a constructor, register it:
+  unless adtOp $ do
+    uiMap <- readIORef (rUIMap st)
+    case nm `Map.lookup` uiMap of
+      Just (_, _, t') -> checkType t' (pure ())
+      Nothing         -> modifyState rootState rUIMap (Map.insert nm (isCurried, mbArgNames, t))
+                           $ modifyIncState rootState rNewUIs
+                                              (\newUIs -> case nm `Map.lookup` newUIs of
+                                                            Just (_, _, t') -> checkType t' newUIs
+                                                            Nothing         -> Map.insert nm (isCurried, mbArgNames, t) newUIs)
+
+  pure $ let tnm = T.pack nm
+         in case uiName of
+              UIGiven{}                  -> Uninterpreted tnm
+              UIADT (ADTConstructor _ k) -> ADTOp (ADTConstructor tnm k)
+              UIADT (ADTTester      _ k) -> ADTOp (ADTTester      tnm k)
+              UIADT (ADTAccessor    _ k) -> ADTOp (ADTAccessor    tnm k)
+
+-- | Add a new sAssert based constraint
+addAssertion :: State -> Maybe CallStack -> String -> SV -> IO ()
+addAssertion st cs msg cond = modifyState st rAsserts ((msg, cs, cond):)
+                                        $ noInteractive [ "Named assertions (sAssert):"
+                                                        , "  Tag: " ++ msg
+                                                        , "  Loc: " ++ maybe "Unknown" show cs
+                                                        ]
+
+-- | Create an internal variable, which acts as an input but isn't visible to the user.
+-- Such variables are existentially quantified in a SAT context, and universally quantified
+-- in a proof context.
+newInternalVariable :: State -> Kind -> IO SV
+newInternalVariable st k = do NamedSymVar sv nm <- newSV st k
+                              let n = "__internal_sbv_" <> nm
+                                  v = NamedSymVar sv n
+                              modifyState st rinps (addUserInput sv n) $ modifyIncState st rNewInps (v :)
+                              pure sv
+{-# INLINE newInternalVariable #-}
+
+-- | Create a variable to be used in a constraint-expression
+quantVar :: Quantifier -> State -> Kind -> IO SV
+quantVar q st k = do v@(NamedSymVar sv _) <- newSV st k
+                     modifyState st rlambdaInps (S.|> (q, v)) (pure ())
+                     pure sv
+{-# INLINE quantVar #-}
+
+-- | Create a variable to be used in a lambda-expression
+lambdaVar :: State -> Kind -> IO SV
+lambdaVar = quantVar ALL
+{-# INLINE lambdaVar #-}
+
+-- | Create a new SV
+newSV :: State -> Kind -> IO NamedSymVar
+newSV st k = do ctr <- incrementInternalCounter st
+                ll  <- readIORef (rLambdaLevel st)
+                let sv = SV k (NodeId (sbvContext st, ll, ctr))
+                registerKind st k
+                pure $ NamedSymVar sv $ showText sv
+{-# INLINE newSV #-}
+
+-- | Register a new kind with the system, used for uninterpreted sorts.
+-- NB: Is it safe to have new kinds in query mode? It could be that
+-- the new kind might introduce a constraint that effects the logic. For
+-- instance, if we're seeing 'Double' for the first time and using a BV
+-- logic, then things would fall apart. But this should be rare, and hopefully
+-- the success-response checking mechanism will catch the rare cases where this
+-- is an issue. In either case, the user can always arrange for the right
+-- logic by calling 'Data.SBV.setLogic' appropriately, so it seems safe to just
+-- allow for this.
+registerKind :: State -> Kind -> IO ()
+registerKind st k
+  | KADT sortName _ _ <- k, isReserved sortName
+  = error $ "SBV: " ++ show sortName ++ " is a reserved sort; please use a different name."
+  | True
+  = do -- Adding a kind to the incState is tricky; we only need to add it
+       --     *    If it's an uninterpreted sort that's not already in the general state
+       --     * OR If it's a tuple-sort whose cardinality isn't already in the general state
+       --     * OR If it's a list that's not already in the general state (so we can send the flatten commands)
+       --     * OR If rationals are first used, so we can declare their datatype and equality helpers
+
+       let rootState = getRootState st
+
+       existingKinds <- readIORef (rUsedKinds rootState)
+
+       -- For ADTs we need to make sure we haven't added it before
+       let adtNameExists s = any (\case KADT s' _ _ -> s == s'; _ -> False) existingKinds
+
+           adtExists = case k of
+                         KADT s _ _  -> adtNameExists s
+                         _           -> False
+
+       unless adtExists $
+          modifyState rootState rUsedKinds (Set.insert k) $ do
+
+              -- Why do we discriminate here? Because the incremental context is sensitive to the
+              -- order: In particular, if an uninterpreted kind is already in there, we don't
+              -- want to re-add because double-declaration would be wrong. See 'cvtInc' for details.
+              let needsAdding = case k of
+                                  KADT s _ _  -> not (adtNameExists s)
+                                  KList{}     -> k `Set.notMember` existingKinds
+                                  KRational   -> k `Set.notMember` existingKinds
+                                  KTuple nks  -> not $ any (\case KTuple oks -> length nks == length oks; _ -> False) existingKinds
+                                  _           -> False
+
+              when needsAdding $ modifyIncState rootState rNewKinds (Set.insert k)
+
+       -- Don't forget to register subkinds!
+       case k of
+         KVar      {}    -> pure ()
+         KBool     {}    -> pure ()
+         KBounded  {}    -> pure ()
+         KUnbounded{}    -> pure ()
+         KReal     {}    -> pure ()
+         KFloat    {}    -> pure ()
+         KDouble   {}    -> pure ()
+         KFP       {}    -> pure ()
+         KRational {}    -> pure ()
+         KChar     {}    -> pure ()
+         KString   {}    -> pure ()
+
+         KApp _ ks       -> mapM_ (registerKind st) ks
+         KADT _ pks cks  -> mapM_ (registerKind st) (map snd pks ++ concatMap snd cks ++ adtKindDependencies k)
+         KList     ek    -> registerKind st ek
+         KSet      ek    -> registerKind st ek
+         KTuple    eks   -> mapM_ (registerKind st) eks
+         KArray    k1 k2 -> mapM_ (registerKind st) [k1, k2]
+
+-- | Register a new label with the system, making sure they are unique and have no '|'s in them
+registerLabel :: String -> State -> String -> IO ()
+registerLabel whence st nm
+  | isReserved nm
+  = err "is a reserved string; please use a different name."
+  | '|' `elem` nm
+  = err "contains the character `|', which is not allowed!"
+  | '\\' `elem` nm
+  = err "contains the character `\\', which is not allowed!"
+  | True
+  = do old <- readIORef $ rUsedLbls st
+       if nm `Set.member` old
+          then err "is used multiple times. Please do not use duplicate names!"
+          else modifyState st rUsedLbls (Set.insert nm) (pure ())
+
+  where err w = error $ "SBV (" ++ whence ++ "): " ++ show nm ++ " " ++ w
+
+-- | Create a new constant; hash-cons as necessary
+newConst :: State -> CV -> IO SV
+newConst st c = do
+  constMap <- readIORef (rconstMap st)
+  case c `Map.lookup` constMap of
+    -- NB. Unlike in 'newExpr', we don't have to make sure the returned sv
+    -- has the kind we asked for, because the constMap stores the full CV
+    -- which already has a kind field in it.
+    Just sv -> pure sv
+    Nothing -> do (NamedSymVar sv _) <- newSV st (kindOf c)
+                  let ins = Map.insert c sv
+                  modifyState st rconstMap ins $ modifyIncState st rNewConsts ins
+                  pure sv
+{-# INLINE newConst #-}
+
+-- | Create a new table; hash-cons as necessary
+getTableIndex :: State -> Kind -> Kind -> [SV] -> IO Int
+getTableIndex st at rt elts = do
+  let key = (at, rt, elts)
+  tblMap <- readIORef (rtblMap st)
+  case key `Map.lookup` tblMap of
+    Just i -> pure i
+    _      -> do let i   = Map.size tblMap
+                     upd = Map.insert key i
+                 modifyState st rtblMap upd $ modifyIncState st rNewTbls upd
+                 pure i
+
+-- | Create a new expression; hash-cons as necessary
+newExpr :: State -> Kind -> SBVExpr -> IO SV
+newExpr st k app = do
+   let e = reorder app
+   exprMap <- readIORef (rexprMap st)
+   case e `Map.lookup` exprMap of
+     -- NB. Check to make sure that the kind of the hash-consed value
+     -- is the same kind as we're requesting. This might look unnecessary,
+     -- at first, but `svSign` and `svUnsign` rely on this as we can
+     -- get the same expression but at a different type. See
+     -- <http://github.com/GaloisInc/cryptol/issues/566> as an example.
+     Just sv | kindOf sv == k -> pure sv
+     _                        -> do (NamedSymVar sv _) <- newSV st k
+                                    checkConsistent sv e
+                                    let append (SBVPgm xs) = SBVPgm (xs S.|> (sv, e))
+                                    modifyState st spgm append $ modifyIncState st rNewAsgns append
+                                    modifyState st rexprMap (Map.insert e sv) (pure ())
+                                    pure sv
+{-# INLINE newExpr #-}
+
+-- | In rare cases, we can get a context mismatch; so make sure the expression is well-formed.
+-- This isn't a full solution, but handles the common case (hopefully!)
+checkConsistent :: SV -> SBVExpr -> IO ()
+checkConsistent lhs (SBVApp _ args) = mapM_ check args
+   where SV _ (NodeId (lhsContext, _, _)) = lhs
+         check (SV _ (NodeId (rhsContext, _, _)))
+           | lhsContext `compatibleContext` rhsContext
+           = pure ()
+           | True
+           = contextMismatchError lhsContext rhsContext
+{-# INLINE checkConsistent #-}
+
+-- | Are these compatible contexts? Either the same, or one of them is global
+compatibleContext :: SBVContext -> SBVContext -> Bool
+compatibleContext c1 c2 = c1 == c2 || c1 == globalSBVContext || c2 == globalSBVContext
+{-# INLINE compatibleContext #-}
+
+-- | Convert a symbolic value to an internal SV
+svToSV :: State -> SVal -> IO SV
+svToSV st (SVal _ (Left c))  = newConst st c
+svToSV st (SVal _ (Right f)) = uncache f st
+
+-- | Generalization of 'Data.SBV.svToSymSV'
+svToSymSV :: MonadSymbolic m => SVal -> m SV
+svToSymSV sbv = do st <- symbolicEnv
+                   liftIO $ svToSV st sbv
+
+-------------------------------------------------------------------------
+-- * Symbolic Computations
+-------------------------------------------------------------------------
+-- | A Symbolic computation. Represented by a reader monad carrying the
+-- state of the computation, layered on top of IO for creating unique
+-- references to hold onto intermediate results.
+
+-- | Computations which support symbolic operations
+class MonadIO m => MonadSymbolic m where
+  symbolicEnv :: m State
+
+  default symbolicEnv :: (MonadTrans t, MonadSymbolic m', m ~ t m') => m State
+  symbolicEnv = lift symbolicEnv
+
+instance MonadSymbolic m             => MonadSymbolic (ExceptT e m)
+instance MonadSymbolic m             => MonadSymbolic (MaybeT m)
+instance MonadSymbolic m             => MonadSymbolic (ReaderT r m)
+instance MonadSymbolic m             => MonadSymbolic (SS.StateT s m)
+instance MonadSymbolic m             => MonadSymbolic (LS.StateT s m)
+instance (MonadSymbolic m, Monoid w) => MonadSymbolic (SW.WriterT w m)
+instance (MonadSymbolic m, Monoid w) => MonadSymbolic (LW.WriterT w m)
+
+-- | A generalization of 'Data.SBV.Symbolic'.
+newtype SymbolicT m a = SymbolicT { runSymbolicT :: ReaderT State m a }
+                   deriving newtype ( Applicative, Functor, Monad, MonadIO, MonadTrans
+                            , MonadError e, MonadState s, MonadWriter w
+                            , MonadFail
+                            )
+
+-- | `MonadSymbolic` instance for `SymbolicT m`
+instance MonadIO m => MonadSymbolic (SymbolicT m) where
+  symbolicEnv = SymbolicT ask
+
+-- | Map a computation over the symbolic transformer.
+mapSymbolicT :: (ReaderT State m a -> ReaderT State n b) -> SymbolicT m a -> SymbolicT n b
+mapSymbolicT f = SymbolicT . f . runSymbolicT
+{-# INLINE mapSymbolicT #-}
+
+-- Have to define this one by hand, because we use ReaderT in the implementation
+instance MonadReader r m => MonadReader r (SymbolicT m) where
+  ask = lift ask
+  local f = mapSymbolicT $ mapReaderT $ local f
+
+-- | 'Symbolic' is specialization of t'SymbolicT' to the `IO` monad. Unless you are using
+-- transformers explicitly, this is the type you should prefer.
+type Symbolic = SymbolicT IO
+
+-- | Create a symbolic value, based on the quantifier we have. If an
+-- explicit quantifier is given, we just use that. If not, then we
+-- pick the quantifier appropriately based on the run-mode.
+-- @randomCV@ is used for generating random values for this variable
+-- when used for @quickCheck@ or 'Data.SBV.Tools.GenTest.genTest' purposes.
+svMkSymVar :: VarContext -> Kind -> Maybe String -> State -> IO SVal
+svMkSymVar = svMkSymVarGen False
+
+-- | Create an existentially quantified tracker variable
+svMkTrackerVar :: Kind -> String -> State -> IO SVal
+svMkTrackerVar k nm = svMkSymVarGen True (NonQueryVar (Just EX)) k (Just nm)
+
+-- | Generalization of 'Data.SBV.sWordN'
+sWordN :: MonadSymbolic m => Int -> String -> m SVal
+sWordN w nm = symbolicEnv >>= liftIO . svMkSymVar (NonQueryVar Nothing) (KBounded False w) (Just nm)
+
+-- | Generalization of 'Data.SBV.sWordN_'
+sWordN_ :: MonadSymbolic m => Int -> m SVal
+sWordN_ w = symbolicEnv >>= liftIO . svMkSymVar (NonQueryVar Nothing) (KBounded False w) Nothing
+
+-- | Generalization of 'Data.SBV.sIntN'
+sIntN :: MonadSymbolic m => Int -> String -> m SVal
+sIntN w nm = symbolicEnv >>= liftIO . svMkSymVar (NonQueryVar Nothing) (KBounded True w) (Just nm)
+
+-- | Generalization of 'Data.SBV.sIntN_'
+sIntN_ :: MonadSymbolic m => Int -> m SVal
+sIntN_ w = symbolicEnv >>= liftIO . svMkSymVar (NonQueryVar Nothing) (KBounded True w) Nothing
+
+-- | Create a symbolic value, based on the quantifier we have. If an
+-- explicit quantifier is given, we just use that. If not, then we
+-- pick the quantifier appropriately based on the run-mode.
+-- @randomCV@ is used for generating random values for this variable
+-- when used for @quickCheck@ or 'Data.SBV.Tools.GenTest.genTest' purposes.
+svMkSymVarGen :: Bool -> VarContext -> Kind -> Maybe String -> State -> IO SVal
+svMkSymVarGen isTracker varContext k mbNm st = do
+        registerKind st k
+
+        rm <- readIORef (runMode st)
+
+        let varInfo = case mbNm of
+                        Nothing -> "While defining a variable of type " ++ show k
+                        Just nm -> "While defining: " ++ nm ++ " :: " ++ show k
+
+            disallow what  = error $ unlines [ "*** Data.SBV: Unsupported: " ++ what
+                                             , "***"
+                                             , "*** " ++ varInfo
+                                             , "*** "
+                                             , "*** In mode: " ++ show rm
+                                             ]
+
+            (isQueryVar, mbQ) = case varContext of
+                                  NonQueryVar mq -> (False, mq)
+                                  QueryVar       -> (True,  Just EX)
+
+            mkS q = do (NamedSymVar sv internalName) <- newSV st k
+                       let nm = maybe internalName T.pack mbNm
+                       introduceUserName st (isQueryVar, isTracker) nm k q sv
+
+            mkC cv = do modifyState st rCInfo ((fromMaybe "_" mbNm, cv):) (pure ())
+                        pure $ SVal k (Left cv)
+
+        case (mbQ, rm) of
+          (Just q,  SMTMode{}          ) -> mkS q
+          (Nothing, SMTMode _ _ isSAT _) -> mkS (if isSAT then EX else ALL)
+
+          (Just EX, CodeGen{})           -> disallow "Existentially quantified variables"
+          (_      , CodeGen)             -> mkS ALL  -- code generation, pick universal
+
+          (Just EX, Concrete Nothing)    -> disallow "Existentially quantified variables"
+          (_      , Concrete Nothing)    -> randomCV k >>= mkC
+
+          (Just EX, LambdaGen{})         -> disallow "Existentially quantified variables"
+          (_,       LambdaGen{})         -> mkS ALL
+
+          -- Model validation:
+          (_      , Concrete (Just (_isSat, env))) -> do
+                        let bad why conc = error $ unlines [ ""
+                                                           , "*** Data.SBV: " ++ why
+                                                           , "***"
+                                                           , "***   To turn validation off, use `cfg{validateModel = False}`"
+                                                           , "***"
+                                                           , "*** " ++ conc
+                                                           ]
+
+                            report = "Please report this as a bug in SBV!"
+
+                        (NamedSymVar sv internalName) <- newSV st k
+
+                        let nm = maybe internalName T.pack mbNm
+                            nsv = NamedSymVar sv nm
+
+                            -- Ignore the context equivalence check here. When validating, we are in a different
+                            -- context; so they won't match
+                            same (NamedSymVar (SV _ (NodeId (_, ll1, li1))) _)
+                                 (NamedSymVar (SV _ (NodeId (_, ll2, li2))) _) = (ll1, li1) == (ll2, li2)
+
+                            cv = case [v | (nsv', v) <- env, nsv `same` nsv'] of
+                                   []    -> if isTracker
+                                            then  -- The sole purpose of a tracker variable is to send the optimization
+                                                  -- directive to the solver, so we can name "expressions" that are minimized
+                                                  -- or maximized. There will be no constraints on these when we are doing
+                                                  -- the validation; in fact they will not even be used anywhere during a
+                                                  -- validation run. So, simply push a zero value that inhabits all metrics.
+                                                  mkConstCV k (0::Integer)
+                                            else bad ("Cannot locate variable: " ++ show (nsv, k)) report
+                                   [c]  -> c
+                                   r    -> bad (   "Found multiple matching values for variable: " ++ show nsv
+                                                ++ "\n*** " ++ show r) report
+
+                        mkC cv
+
+-- | Introduce a new user name. We simply append a suffix if we have seen this variable before.
+introduceUserName :: State -> (Bool, Bool) -> Text -> Kind -> Quantifier -> SV -> IO SVal
+introduceUserName st@State{runMode} (isQueryVar, isTracker) nmOrig k q sv = do
+        old <- allInputs <$> readIORef (rinps st)
+
+        let nm  = mkUnique nmOrig old
+
+        -- If this is not a query variable and we're in a query, reject it.
+        -- See https://github.com/LeventErkok/sbv/issues/554 for the rationale.
+        -- In theory, it should be possible to support this, but fixing it is
+        -- rather costly as we'd have to track the regular updates and sync the
+        -- incremental state appropriately. Instead, we issue an error message
+        -- and ask the user to obey the query mode rules.
+        rm <- readIORef runMode
+        case rm of
+          SMTMode _ IRun _ _ | not isQueryVar -> noInteractiveEver [ "Adding a new input variable in query mode: " ++ show nm
+                                                                   , ""
+                                                                   , "Hint: Use freshVar/freshVar_ for introducing new inputs in query mode."
+                                                                   ]
+          _                                   -> pure ()
+
+        if isTracker && q == ALL
+           then error $ "SBV: Impossible happened! A universally quantified tracker variable is being introduced: " ++ show nm
+           else do let newInp olds = case q of
+                                      EX  -> toNamedSV sv nm : olds
+                                      ALL -> noInteractive [ "Adding a new universally quantified variable: "
+                                                           , "  Name      : " ++ show nm
+                                                           , "  Kind      : " ++ show k
+                                                           , "  Quantifier: Universal"
+                                                           , "  Node      : " ++ show sv
+                                                           , "Only existential variables are supported in query mode."
+                                                           ]
+                   if isTracker
+                      then modifyState st rinps (addInternInput sv nm)
+                                     $ noInteractive ["Adding a new tracker variable in interactive mode: " ++ show nm]
+                      else modifyState st rinps (addUserInput sv nm)
+                                     $ modifyIncState st rNewInps newInp
+                   pure $ SVal k $ Right $ cache (const (pure sv))
+
+   where -- The following can be rather slow if we keep reusing the same prefix, but I doubt it'll be a problem in practice
+         -- Also, the following will fail if we span the range of integers without finding a match, but your computer would
+         -- die way ahead of that happening if that's the case!
+         mkUnique :: T.Text -> Set.Set Name -> T.Text
+         mkUnique prefix names = case dropWhile (`Set.member` names) (prefix : [prefix <> "_" <> showText i | i <- [(0::Int)..]]) of
+                                   h:_ -> h
+                                   _   -> error $ "mkUnique: Impossible happened! Couldn't get a unique name for " ++ show (prefix, names)
+
+-- | Create a new state
+mkNewState :: MonadIO m => SMTConfig -> SBVRunMode -> m State
+mkNewState cfg currentRunMode = liftIO $ do
+     currTime           <- getCurrentTime
+     progInfo           <- newIORef ProgInfo { hasQuants         = False
+                                             , progSpecialRels   = []
+                                             , progTransClosures = []
+                                             }
+     rm                 <- newIORef currentRunMode
+     ctr                <- newIORef (-2) -- start from -2; False and True will always occupy the first two elements
+     fnctr              <- newIORef 0
+     lambda             <- newIORef $ case currentRunMode of
+                                        SMTMode{}     -> Just 0
+                                        CodeGen{}     -> Just 0
+                                        Concrete{}    -> Just 0
+                                        LambdaGen mbi -> mbi
+     cInfo              <- newIORef []
+     observes           <- newIORef mempty
+     pgm                <- newIORef (SBVPgm S.empty)
+     emap               <- newIORef Map.empty
+     cmap               <- newIORef Map.empty
+     inps               <- newIORef mempty
+     lambdaInps         <- newIORef mempty
+     outs               <- newIORef []
+     tables             <- newIORef Map.empty
+     userFuncs          <- newIORef Map.empty
+     compilingFuncs     <- newIORef Set.empty
+     uis                <- newIORef Map.empty
+     cgs                <- newIORef Map.empty
+     defns              <- newIORef Map.empty
+     measureChecks      <- newIORef []
+     funcLambdaInfos    <- newIORef Map.empty
+     skipMeasureChecks  <- newIORef False
+     noTermCheckFuncs   <- newIORef Set.empty
+     swCache            <- newIORef IMap.empty
+     usedKinds          <- newIORef Set.empty
+     usedLbls           <- newIORef Set.empty
+     cstrs              <- newIORef S.empty
+     pvs                <- newIORef []
+     smtOpts            <- newIORef []
+     optGoals           <- newIORef []
+     asserts            <- newIORef []
+     outstandingAsserts <- newIORef False
+     istate             <- newIORef =<< newIncState
+     qstate             <- newIORef Nothing
+     ctx                <- genSBVContext
+     pure $ State { sbvContext            = ctx
+                  , runMode               = rm
+                  , stCfg                 = cfg
+                  , startTime             = currTime
+                  , rProgInfo             = progInfo
+                  , pathCond              = SVal KBool (Left trueCV)
+                  , rIncState             = istate
+                  , rCInfo                = cInfo
+                  , rObservables          = observes
+                  , rctr                  = ctr
+                  , freshNameCtr          = fnctr
+                  , rLambdaLevel          = lambda
+                  , rUsedKinds            = usedKinds
+                  , rUsedLbls             = usedLbls
+                  , rinps                 = inps
+                  , rlambdaInps           = lambdaInps
+                  , routs                 = outs
+                  , rtblMap               = tables
+                  , spgm                  = pgm
+                  , rconstMap             = cmap
+                  , rexprMap              = emap
+                  , rUserFuncs            = userFuncs
+                  , rCompilingFuncs       = compilingFuncs
+                  , rUIMap                = uis
+                  , rCgMap                = cgs
+                  , rDefns                = defns
+                  , rMeasureChecks        = measureChecks
+                  , rFuncLambdaInfos      = funcLambdaInfos
+                  , rSkipMeasureChecks    = skipMeasureChecks
+                  , rNoTermCheckFunctions = noTermCheckFuncs
+                  , rSVCache              = swCache
+                  , rConstraints          = cstrs
+                  , rPartitionVars        = pvs
+                  , rSMTOptions           = smtOpts
+                  , rOptGoals             = optGoals
+                  , rAsserts              = asserts
+                  , rOutstandingAsserts   = outstandingAsserts
+                  , rQueryState           = qstate
+                  , parentState           = Nothing
+                  }
+
+-- | Generalization of 'Data.SBV.runSymbolic'
+runSymbolic :: MonadIO m => SMTConfig -> SBVRunMode -> SymbolicT m a -> m (a, Result)
+runSymbolic cfg currentRunMode comp = do
+   st <- mkNewState cfg currentRunMode
+   runSymbolicInState st comp
+
+-- | Catch the catastrophic case of context mismatch
+-- NB. We're not printing _ctx1/_ctx2 here (hence the underscored variables).
+-- The reason is that they can get different values; causing test-suite failures with no helpful info.
+contextMismatchError :: SBVContext -> SBVContext -> a
+contextMismatchError _ctx1 _ctx2 = error $ unlines [
+                               "Data.SBV: Mismatched contexts detected."
+                             , "***"
+                             , "*** This happens if you call a proof-function (prove/sat/runSMT/isSatisfiable) etc."
+                             , "*** while another one is in execution, or use results from one such call in another."
+                             , "*** Please avoid such nested calls, all interactions should be from the same context."
+                             , "*** See https://github.com/LeventErkok/sbv/issues/71 for several examples."
+                             ]
+
+-- | Run a symbolic computation in a given state
+runSymbolicInState :: MonadIO m => State -> SymbolicT m a -> m (a, Result)
+runSymbolicInState st (SymbolicT c) = do
+   _ <- liftIO $ newConst st falseCV -- s(-2) == falseSV
+   _ <- liftIO $ newConst st trueCV  -- s(-1) == trueSV
+   r <- runReaderT c st
+   res <- liftIO $ extractSymbolicSimulationState st
+
+   -- Check that the state wasn't clobbered in any way
+   let check ctx | ctx == sbvContext st || ctx == globalSBVContext
+                 = pure ()
+                 | True
+                 = contextMismatchError (sbvContext st) ctx
+
+   mapM_ check $ nubOrd $ G.universeBi res
+
+   pure (r, res)
+
+-- | Grab the program from a running symbolic simulation state.
+extractSymbolicSimulationState :: State -> IO Result
+extractSymbolicSimulationState st@State{ runMode=rrm
+                                       , spgm=pgm, rinps=inps, rlambdaInps=linps, routs=outs, rtblMap=tables
+                                       , rUIMap=uis, rDefns=defns
+                                       , rAsserts=asserts, rUsedKinds=usedKinds, rCgMap=cgs, rCInfo=cInfo, rConstraints=cstrs
+                                       , rObservables=observes, rProgInfo=progInfo
+                                       } = do
+   SBVPgm rpgm  <- readIORef pgm
+
+   rm <- readIORef rrm
+
+   inpsO <- do Inputs{userInputs, internInputs} <- readIORef inps
+               ls <- readIORef linps
+
+               let lambdaOnly = case rm of
+                                  SMTMode{}   -> False
+                                  CodeGen{}   -> False
+                                  Concrete{}  -> False
+                                  LambdaGen{} -> True
+                   topInps = (F.toList userInputs, F.toList internInputs)
+                   lamInps = F.toList ls
+
+               if lambdaOnly
+                  then case topInps of
+                          ([], []) -> pure $ ResultLamInps (F.toList ls)
+                          (xs, ys) -> error $ unlines [ ""
+                                                      , "*** Data.SBV: Impossible happened; saw inputs in lambda mode."
+                                                      , "***"
+                                                      , "***   Inps    : " ++ show xs
+                                                      , "***   Trackers: " ++ show ys
+                                                      ]
+                  else case lamInps of
+                          [] -> pure $ ResultTopInps topInps
+                          _  -> error $ unlines [ ""
+                                                , "*** Data.SBV: Impossible happened; saw lambda inputs in regular mode."
+                                                , "***"
+                                                , "***   Params: " ++ show lamInps
+                                                ]
+
+   outsO <- reverse <$> readIORef outs
+
+   let arrange (i, (at, rt, es)) = ((i, at, rt), es)
+
+   constMap <- readIORef (rconstMap st)
+   let cnsts = mapToSortedList constMap
+
+   tbls  <- map arrange . mapToSortedList <$> readIORef tables
+   defnMap <- readIORef defns
+   let ds         = Map.toList defnMap
+       definedSet = Map.keysSet defnMap
+   unint <- do unints <- Map.toList <$> readIORef uis
+               -- drop those that has a definition associated with it
+               pure [ui | ui@(nm, _) <- unints, nm `Set.notMember` definedSet]
+   knds  <- readIORef usedKinds
+   cgMap <- Map.toList <$> readIORef cgs
+
+   traceVals   <- reverse <$> readIORef cInfo
+   observables <- fmap (\(n,f,sv) -> (T.unpack n, f, sv)) . F.toList <$> readIORef observes
+   extraCstrs  <- readIORef cstrs
+   assertions  <- reverse <$> readIORef asserts
+
+   pinfo <- readIORef progInfo
+
+   pure $ Result pinfo knds traceVals observables cgMap inpsO (constMap, cnsts) tbls unint ds (SBVPgm rpgm) extraCstrs assertions outsO
+
+-- | Generalization of 'Data.SBV.addNewSMTOption'
+addNewSMTOption :: MonadSymbolic m => SMTOption -> m ()
+addNewSMTOption o = do st <- symbolicEnv
+                       codeGeneration <- liftIO $ isCodeGenMode st
+                       when codeGeneration $ error "SBV->C: SMT solver options have no executable C semantics; remove setOption from the code-generation program."
+                       liftIO $ modifyState st rSMTOptions (o:) (pure ())
+
+-- | Generalization of 'Data.SBV.imposeConstraint'
+imposeConstraint :: MonadSymbolic m => Bool -> [(String, String)] -> SVal -> m ()
+imposeConstraint isSoft attrs c = do st <- symbolicEnv
+                                     liftIO $ do mapM_ (registerLabel "Constraint" st) [nm | (":named",  nm) <- attrs]
+                                                 internalConstraint st isSoft attrs c
+
+-- | Require a boolean condition to be true in the state. Only used for internal purposes.
+internalConstraint :: State -> Bool -> [(String, String)] -> SVal -> IO ()
+internalConstraint st isSoft attrs b = do v <- svToSV st b
+
+                                          rm <- liftIO $ readIORef (runMode st)
+
+                                          -- Are we running validation? If so, we always want to
+                                          -- add the constraint for debug purposes. Otherwise
+                                          -- we only add it if it's interesting; i.e., not directly
+                                          -- true or has some attributes.
+                                          let isValidating = case rm of
+                                                               SMTMode _ _ _ cfg -> validationRequested cfg
+                                                               CodeGen           -> False
+                                                               LambdaGen{}       -> False
+                                                               Concrete Nothing  -> False
+                                                               Concrete (Just _) -> True   -- The case when we *are* running the validation
+
+                                          let c           = (isSoft, attrs, v)
+                                              interesting = v /= trueSV || not (null attrs)
+
+                                          when (isValidating || interesting) $
+                                               modifyState st rConstraints (S.|> c)
+                                                            $ modifyIncState st rNewConstraints (S.|> c)
+
+-- | Generalization of 'Data.SBV.addSValOptGoal'
+addSValOptGoal :: MonadSymbolic m => Objective SVal -> m ()
+addSValOptGoal obj = do st <- symbolicEnv
+                        mode <- liftIO $ readIORef (runMode st)
+                        case mode of
+                          CodeGen -> error "SBV->C: Optimization objectives require a solver and cannot be compiled to executable C."
+                          _       -> pure ()
+
+                        -- create the tracking variable here for the metric
+                        let mkGoal nm orig = liftIO $ do origSV  <- svToSV st orig
+                                                         track   <- svMkTrackerVar (kindOf orig) nm st
+                                                         trackSV <- svToSV st track
+                                                         pure (origSV, trackSV)
+
+                        let walk (Minimize          nm v)     = Minimize nm                     <$> mkGoal nm v
+                            walk (Maximize          nm v)     = Maximize nm                     <$> mkGoal nm v
+                            walk (AssertWithPenalty nm v mbP) = flip (AssertWithPenalty nm) mbP <$> mkGoal nm v
+
+                        !obj' <- walk obj
+                        liftIO $ modifyState st rOptGoals (obj' :)
+                                           $ noInteractive [ "Adding an optimization objective:"
+                                                           , "  Objective: " ++ show obj
+                                                           ]
+
+-- | Generalization of 'Data.SBV.sObserve'
+sObserve :: MonadSymbolic m => String -> SVal -> m ()
+sObserve m x
+  | Just bad <- checkObservableName m
+  = error bad
+  | True
+  = do st <- symbolicEnv
+       liftIO $ do xsv <- svToSV st x
+                   recordObservable st (T.pack m) (const True) xsv
+
+-- | Generalization of 'Data.SBV.outputSVal'
+outputSVal :: MonadSymbolic m => SVal -> m ()
+outputSVal (SVal _ (Left c)) = do
+  st <- symbolicEnv
+  sv <- liftIO $ newConst st c
+  liftIO $ modifyState st routs (sv:) (pure ())
+outputSVal (SVal _ (Right f)) = do
+  st <- symbolicEnv
+  sv <- liftIO $ uncache f st
+  liftIO $ modifyState st routs (sv:) (pure ())
+
+---------------------------------------------------------------------------------
+-- * Cached values
+---------------------------------------------------------------------------------
+
+-- | We implement a peculiar caching mechanism, applicable to the use case in
+-- implementation of SBV's.  Whenever we do a state based computation, we do
+-- not want to keep on evaluating it in the then-current state. That will
+-- produce essentially a semantically equivalent value. Thus, we want to run
+-- it only once, and reuse that result, capturing the sharing at the Haskell
+-- level. This is similar to the "type-safe observable sharing" work, but also
+-- takes into the account of how symbolic simulation executes.
+--
+-- See Andy Gill's type-safe observable sharing trick for the inspiration behind
+-- this technique: <http://ku-fpg.github.io/files/Gill-09-TypeSafeReification.pdf>
+--
+-- Note that this is *not* a general memo utility!
+newtype Cached a = Cached (State -> IO a)
+
+-- | Cache a state-based computation
+cache :: (State -> IO a) -> Cached a
+cache = Cached
+
+-- | Uncache a previously cached computation
+uncache :: Cached SV -> State -> IO SV
+uncache = uncacheGen rSVCache
+
+-- | Generic uncaching. Note that this is entirely safe, since we do it in the IO monad.
+uncacheGen :: (State -> IORef (Cache a)) -> Cached a -> State -> IO a
+uncacheGen getCache (Cached f) st = do
+        let rCache = getCache st
+        stored <- readIORef rCache
+        sn <- f `seq` makeStableName f
+        let h = hashStableName sn
+        case (h `IMap.lookup` stored) >>= (sn `lookup`) of
+          Just r  -> pure r
+          Nothing -> do r <- f st
+                        r `seq` R.modifyIORef' rCache (IMap.insertWith (\_ old -> (sn, r) : old) h [(sn, r)])
+                        pure r
+
+-- | Representation of SMTLib Program versions. As of June 2015, we're dropping support
+-- for SMTLib1, and supporting SMTLib2 only. We keep this data-type around in case
+-- SMTLib3 comes along and we want to support 2 and 3 simultaneously.
+data SMTLibVersion = SMTLib2
+                   deriving (Bounded, Enum, Eq, Show)
+
+-- | The extension associated with the version
+smtLibVersionExtension :: SMTLibVersion -> String
+smtLibVersionExtension SMTLib2 = "smt2"
+
+-- | Representation of an SMT-Lib program. The second Text are the function definitions,
+-- which is *replicated* in the first one. There are cases where that we need the second part on its own.
+data SMTLibPgm = SMTLibPgm SMTLibVersion Text Text
+
+instance NFData SMTLibVersion where rnf a                 = a `seq` ()
+instance NFData SMTLibPgm     where rnf (SMTLibPgm v p d) = rnf v `seq` rnf p `seq` rnf d
+
+instance Show SMTLibPgm where
+  show (SMTLibPgm _ pgm _) = T.unpack pgm
+
+-- | Extract the program text from an SMTLibPgm without converting to String.
+smtLibPgmText :: SMTLibPgm -> Text
+smtLibPgmText (SMTLibPgm _ pgm _) = pgm
+
+-- Other Technicalities..
+instance NFData GeneralizedCV where
+  rnf (ExtendedCV e) = e `seq` ()
+  rnf (RegularCV  c) = c `seq` ()
+
+instance NFData NamedSymVar where
+  rnf (NamedSymVar s n) = rnf s `seq` rnf n
+
+instance NFData Result where
+  rnf (Result hasQuants kindInfo qcInfo obs cgs inps consts tbls uis axs pgm cstr asserts outs)
+        = rnf hasQuants `seq` rnf kindInfo `seq` rnf qcInfo  `seq` rnf obs    `seq` rnf cgs
+                        `seq` rnf inps     `seq` rnf consts  `seq` rnf tbls
+                        `seq` rnf uis      `seq` rnf axs     `seq` rnf pgm
+                        `seq` rnf cstr     `seq` rnf asserts `seq` rnf outs
+instance NFData SV           where rnf a          = seq a ()
+instance NFData SBVExpr      where rnf a          = seq a ()
+instance NFData Quantifier   where rnf a          = seq a ()
+instance NFData SBVType      where rnf a          = seq a ()
+instance NFData SBVPgm       where rnf a          = seq a ()
+instance NFData (Cached a)   where rnf (Cached f) = f `seq` ()
+instance NFData SVal         where rnf (SVal x y) = rnf x `seq` rnf y
+
+instance NFData SMTResult where
+  rnf (Unsatisfiable _   m   ) = rnf m
+  rnf (Satisfiable   _   m   ) = rnf m
+  rnf (DeltaSat      _ p m   ) = rnf m `seq` rnf p
+  rnf (SatExtField   _   m   ) = rnf m
+  rnf (Unknown       _   m   ) = rnf m
+  rnf (ProofError    _   m mr) = rnf m `seq` rnf mr
+
+instance NFData SMTModel where
+  rnf (SMTModel objs bndgs assocs uifuns) = rnf objs `seq` rnf bndgs `seq` rnf assocs `seq` rnf uifuns
+
+instance NFData SMTScript where
+  rnf (SMTScript b m) = rnf b `seq` rnf m
+
+-- | Translation tricks needed for specific capabilities afforded by each solver
+data SolverCapabilities = SolverCapabilities {
+         supportsQuantifiers     :: Bool           -- ^ Supports SMT-Lib2 style quantifiers?
+       , supportsDefineFun       :: Bool           -- ^ Supports define-fun construct?
+       , supportsDistinct        :: Bool           -- ^ Supports calls to distinct?
+       , supportsBitVectors      :: Bool           -- ^ Supports bit-vectors?
+       , supportsADTs            :: Bool           -- ^ Supports SMT-Lib2 style uninterpreted-sorts and ADTs
+       , supportsUnboundedInts   :: Bool           -- ^ Supports unbounded integers?
+       , supportsReals           :: Bool           -- ^ Supports reals?
+       , supportsApproxReals     :: Bool           -- ^ Supports printing of approximations of reals?
+       , supportsDeltaSat        :: Maybe String   -- ^ Supports delta-satisfiability? (With given precision query)
+       , supportsIEEE754         :: Bool           -- ^ Supports floating point numbers?
+       , supportsSets            :: Bool           -- ^ Supports set operations?
+       , supportsOptimization    :: Bool           -- ^ Supports optimization routines?
+       , supportsPseudoBooleans  :: Bool           -- ^ Supports pseudo-boolean operations?
+       , supportsCustomQueries   :: Bool           -- ^ Supports interactive queries per SMT-Lib?
+       , supportsGlobalDecls     :: Bool           -- ^ Supports global declarations? (Needed for push-pop.)
+       , supportsDataTypes       :: Bool           -- ^ Supports datatypes?
+       , supportsLambdas         :: Bool           -- ^ Does it support lambdas?
+       , supportsSpecialRels     :: Bool           -- ^ Does it support special relations (orders, transitive closure etc.)
+       , supportsDirectTesters   :: Bool           -- ^ Supports data-type testers without full ascription?
+       , supportsFlattenedModels :: Maybe [String] -- ^ Supports flattened model output? (With given config lines.)
+       }
+
+-- | Solver configuration. See also 'Data.SBV.z3', 'Data.SBV.yices', 'Data.SBV.cvc4', 'Data.SBV.boolector', 'Data.SBV.mathSAT', etc.
+-- which are instantiations of this type for those solvers, with reasonable defaults. In particular, custom configuration can be
+-- created by varying those values. (Such as @z3{verbose=True}@.)
+--
+-- Most fields are self explanatory. The notion of precision for printing algebraic reals stems from the fact that such values does
+-- not necessarily have finite decimal representations, and hence we have to stop printing at some depth. It is important to
+-- emphasize that such values always have infinite precision internally. The issue is merely with how we print such an infinite
+-- precision value on the screen. The field 'printRealPrec' controls the printing precision, by specifying the number of digits after
+-- the decimal point. The default value is 16, but it can be set to any positive integer.
+--
+-- When printing, SBV will add the suffix @...@ at the end of a real-value, if the given bound is not sufficient to represent the real-value
+-- exactly. Otherwise, the number will be written out in standard decimal notation. Note that SBV will always print the whole value if it
+-- is precise (i.e., if it fits in a finite number of digits), regardless of the precision limit. The limit only applies if the representation
+-- of the real value is not finite, i.e., if it is not rational.
+--
+-- The 'printBase' field can be used to print numbers in base 2, 10, or 16.
+--
+-- The 'crackNum' field can be used to display numbers in detail, all its bits and how they are laid out in memory. Works with all bounded number types
+-- (i.e., SWord and SInt), but also with floats. It is particularly useful with floating-point numbers, as it shows you how they are laid out in
+-- memory following the IEEE754 rules.
+data SMTConfig = SMTConfig {
+         verbose                     :: Bool                -- ^ Debug mode
+       , timing                      :: Timing              -- ^ Print timing information on how long different phases took (construction, solving, etc.)
+       , printBase                   :: Int                 -- ^ Print integral literals in this base (2, 10, and 16 are supported.)
+       , printRealPrec               :: Int                 -- ^ Print algebraic real values with this precision. (SReal, default: 16)
+       , crackNum                    :: Bool                -- ^ For each numeric value, show it in detail in the model with its bits spliced out. Good for floats.
+       , crackNumSurfaceVals         :: [(String, Integer)] -- ^ For crackNum: The surface representation of variables, if available
+       , satCmd                      :: String              -- ^ Usually "(check-sat)". However, users might tweak it based on solver characteristics.
+       , allSatMaxModelCount         :: Maybe Int           -- ^ In a 'Data.SBV.allSat' call, return at most this many models. If nothing, return all.
+       , allSatPrintAlong            :: Bool                -- ^ In a 'Data.SBV.allSat' call, print models as they are found.
+       , allSatTrackUFs              :: Bool                -- ^ In a 'Data.SBV.allSat' call, should we try to extract values of uninterpreted functions?
+       , isNonModelVar               :: String -> Bool      -- ^ When constructing a model, ignore variables whose name satisfy this predicate. (Default: (const False), i.e., don't ignore anything)
+       , validateModel               :: Bool                -- ^ If set, SBV will attempt to validate the model it gets back from the solver.
+       , optimizeValidateConstraints :: Bool                -- ^ Validate optimization results. NB: Does NOT make sure the model is optimal, just checks they satisfy the constraints.
+       , transcript                  :: Maybe FilePath      -- ^ If Just, the entire interaction will be recorded as a playable file (for debugging purposes mostly)
+       , smtLibVersion               :: SMTLibVersion       -- ^ What version of SMT-lib we use for the tool
+       , dsatPrecision               :: Maybe Double        -- ^ Delta-sat precision
+       , solver                      :: SMTSolver           -- ^ The actual SMT solver.
+       , extraArgs                   :: [String]            -- ^ Extra command line arguments to pass to the solver.
+       , roundingMode                :: RoundingMode        -- ^ Rounding mode to use for floating-point calculations. Defaults to RNE.
+       , solverSetOptions            :: [SMTOption]         -- ^ Options to set as we start the solver
+       , smtLib2Compliant            :: Bool                -- ^ Ask the solver to be strictly SMTLib2 compliant. (Default: True.)
+       , ignoreExitCode              :: Bool                -- ^ If true, we shall ignore the exit code upon exit. Otherwise we require ExitSuccess.
+       , redirectVerbose             :: Maybe FilePath      -- ^ Redirect the verbose output to this file if given. If Nothing, stdout is implied.
+       , firstifyUniqueLen           :: Int                 -- ^ Unique length used for firstified higher-order function names
+       , tpOptions                   :: TPOptions           -- ^ TP specific options
+       }
+
+-- | Configuration for TP
+data TPOptions = TPOptions {
+         ribbonLength          :: Int            -- ^ Line length for TP proofs
+       , quiet                 :: Bool           -- ^ No messages what-so-ever for successful steps. (Will print if something fails)
+       , printAsms             :: Bool           -- ^ Print assumptions as they are proven as separate steps.
+       , printStats            :: Bool           -- ^ Print time/statistics. If quiet is True, then measureTime is ignored.
+       , measuresBeingVerified :: Set.Set String -- ^ Functions whose measures are currently being verified. Used to prevent infinite
+                                                 -- recursion when a measureLemma proof uses the function whose measure is being checked.
+       }
+
+-- | Ignore internal names and those the user told us to
+mustIgnoreVar :: SMTConfig -> T.Text -> Bool
+mustIgnoreVar cfg s = "__internal_sbv" `T.isPrefixOf` s || isNonModelVar cfg (T.unpack s)
+
+-- | We show the name of the solver for the config. Arguably this is misleading, but better than nothing.
+instance Show SMTConfig where
+  show = show . name . solver
+
+-- | Returns true if we have to perform validation
+validationRequested :: SMTConfig -> Bool
+validationRequested SMTConfig{validateModel, optimizeValidateConstraints} = validateModel || optimizeValidateConstraints
+
+-- We're just seq'ing top-level here, it shouldn't really matter. (i.e., no need to go deeper.)
+instance NFData SMTConfig where
+  rnf SMTConfig{} = ()
+
+-- | A model, as returned by a solver
+data SMTModel = SMTModel {
+       modelObjectives :: [(String, GeneralizedCV)]                                     -- ^ Mapping of symbolic values to objective values.
+     , modelBindings   :: Maybe [(NamedSymVar, CV)]                                     -- ^ Mapping of input variables as reported by the solver. Only collected if model validation is requested.
+     , modelAssocs     :: [(String, CV)]                                                -- ^ Mapping of symbolic values to constants.
+     , modelUIFuns     :: [(String, (Bool, SBVType, Either String ([([CV], CV)], CV)))] -- ^ Mapping of uninterpreted functions to association lists in the model.
+                                                                                        -- Note that an uninterpreted constant (function of arity 0) will be stored
+                                                                                        -- in the 'modelAssocs' field. Left is used when the function returned is too
+                                                                                        -- difficult for SBV to figure out what it means
+     }
+     deriving Show
+
+-- | The result of an SMT solver call. Each constructor is tagged with
+-- the t'SMTConfig' that created it so that further tools can inspect it
+-- and build layers of results, if needed. For ordinary uses of the library,
+-- this type should not be needed, instead use the accessor functions on
+-- it. (Custom Show instances and model extractors.)
+data SMTResult = Unsatisfiable SMTConfig (Maybe [String])            -- ^ Unsatisfiable. If unsat-cores are enabled, they will be returned in the second parameter.
+               | Satisfiable   SMTConfig SMTModel                    -- ^ Satisfiable with model
+               | DeltaSat      SMTConfig (Maybe String) SMTModel     -- ^ Delta satisfiable with queried string if available and model
+               | SatExtField   SMTConfig SMTModel                    -- ^ Prover returned a model, but in an extension field containing Infinite/epsilon
+               | Unknown       SMTConfig SMTReasonUnknown            -- ^ Prover returned unknown, with the given reason
+               | ProofError    SMTConfig [String] (Maybe SMTResult)  -- ^ Prover errored out, with possibly a bogus result
+
+-- | A script, to be passed to the solver.
+data SMTScript = SMTScript {
+          scriptBody  :: String   -- ^ Initial feed
+        , scriptModel :: [String] -- ^ Continuation script, to extract results
+        }
+
+-- | An SMT engine
+type SMTEngine =  forall res.
+                  SMTConfig         -- ^ current configuration
+               -> State             -- ^ the state in which to run the engine
+               -> Text              -- ^ program
+               -> (State -> IO res) -- ^ continuation
+               -> IO res
+
+-- | Solvers that SBV is aware of
+data Solver = ABC
+            | Boolector
+            | Bitwuzla
+            | CVC4
+            | CVC5
+            | DReal
+            | MathSAT
+            | Yices
+            | Z3
+            | OpenSMT
+            deriving (Show, Enum, Bounded)
+
+-- | An SMT solver
+data SMTSolver = SMTSolver {
+         name           :: Solver                -- ^ The solver in use
+       , executable     :: String                -- ^ The path to its executable
+       , preprocess     :: Text -> Text          -- ^ Each line sent to the solver will be passed through this function (typically id)
        , options        :: SMTConfig -> [String] -- ^ Options to provide to the solver
        , engine         :: SMTEngine             -- ^ The solver engine, responsible for interpreting solver output
        , capabilities   :: SolverCapabilities    -- ^ Various capabilities of the solver
diff --git a/Data/SBV/Core/TH.hs b/Data/SBV/Core/TH.hs
new file mode 100644
--- /dev/null
+++ b/Data/SBV/Core/TH.hs
@@ -0,0 +1,142 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Data.SBV.Core.TH
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Template Haskell utilities for extracting constructor information from
+-- algebraic data types. Factored out to avoid circular dependencies.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE LambdaCase              #-}
+{-# LANGUAGE PackageImports          #-}
+{-# LANGUAGE ScopedTypeVariables     #-}
+{-# LANGUAGE TemplateHaskellQuotes   #-}
+{-# LANGUAGE TupleSections           #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Data.SBV.Core.TH (
+         getConstructors
+       , bad
+       , report
+       , sbvName
+       ) where
+
+import Data.Maybe (fromMaybe)
+
+import qualified "template-haskell" Language.Haskell.TH        as TH
+import           "template-haskell" Language.Haskell.TH.Syntax as THS (Name(..), OccName(..), NameFlavour(..), PkgName, ModName(..), NameSpace(..))
+
+import Language.Haskell.TH.ExpandSyns as TH
+
+import Data.SBV.Core.Kind (smtType)
+
+-- | Construct a TH name for a value\/function in the @sbv@ package, given
+-- the fully qualified module name and the unqualified identifier. This avoids
+-- importing the target module (which would create import cycles) while still
+-- producing exact 'NameG' names that resolve correctly in generated TH splices.
+sbvName :: String -> String -> TH.Name
+sbvName modNm fnNm = THS.Name (THS.OccName fnNm) (THS.NameG THS.VarName sbvPkg (THS.ModName modNm))
+  where -- Extract the package key from a known cross-module name in the sbv package
+        sbvPkg :: THS.PkgName
+        sbvPkg = case 'smtType of
+                   THS.Name _ (THS.NameG _ pkg _) -> pkg
+                   _                              -> error "Data.SBV.Core.TH.sbvName: unexpected name flavour"
+
+bad :: MonadFail m => String -> [String] -> m a
+bad what extras = fail $ unlines $ ("mkSymbolic: " ++ what) : map ("      " ++) extras
+
+report :: String
+report = "Please report this as a feature request."
+
+-- | Collect the constructors
+getConstructors :: TH.Name -> TH.Q ([TH.Name], [(TH.Name, [(Maybe TH.Name, TH.Type)])])
+getConstructors typeName = do res@(_, cstrs) <- getConstructorsFromType (TH.ConT typeName)
+
+                              -- make sure accessors are unique
+                              let noDup [] = pure ()
+                                  noDup (n:ns)
+                                    | n `elem` ns = bad "Unsupported field accessor definition."
+                                                        [ "Multiply used: " ++ TH.nameBase n
+                                                        , ""
+                                                        , "SBV does not support cases where accessor fields are replicated."
+                                                        , "Please use each accessor only once."
+                                                        ]
+                                    | True        = noDup ns
+                              noDup [n | (_, fs) <- cstrs, (Just n, _) <- fs]
+
+                              pure res
+
+  where getConstructorsFromType :: TH.Type -> TH.Q ([TH.Name], [(TH.Name, [(Maybe TH.Name, TH.Type)])])
+        getConstructorsFromType ty = do ty' <- expandSyns ty
+                                        case headCon ty' of
+                                          Just (n, args) -> reifyFromHead n args
+                                          Nothing        -> bad "Not a type constructor"
+                                                                [ "Name    : " ++ show typeName
+                                                                , "Type    : " ++ show ty
+                                                                , "Expanded: " ++ show ty'
+                                                                ]
+
+        headCon :: TH.Type -> Maybe (TH.Name, [TH.Type])
+        headCon = go []
+          where go args (TH.ConT n)    = Just (n, reverse args)
+                go args (TH.AppT t a)  = go   (a:args) t
+                go args (TH.SigT t _)  = go      args t
+                go args (TH.ParensT t) = go      args t
+                go _    _              = Nothing
+
+        reifyFromHead :: TH.Name -> [TH.Type] -> TH.Q ([TH.Name], [(TH.Name, [(Maybe TH.Name, TH.Type)])])
+        reifyFromHead n args = do info <- TH.reify n
+                                  case info of
+                                    TH.TyConI (TH.DataD    _ _ tvs _ cons _) -> (map tvName tvs,) <$> mapM (expandCon (mkSubst tvs args)) cons
+                                    TH.TyConI (TH.NewtypeD _ _ tvs _ con  _) -> (map tvName tvs,) <$> mapM (expandCon (mkSubst tvs args)) [con]
+                                    TH.TyConI (TH.TySynD _ tvs rhs)          -> getConstructorsFromType (applySubst (mkSubst tvs args) rhs)
+                                    _ -> bad "Unsupported kind"
+                                             [ "Type : " ++ show typeName
+                                             , "Name : " ++ show n
+                                             , "Kind : " ++ show info
+                                             ]
+
+        onSnd f (a, b) = (a,) <$> f b
+
+        expandCon :: [(TH.Name, TH.Type)] -> TH.Con -> TH.Q (TH.Name, [(Maybe TH.Name, TH.Type)])
+        expandCon sub (TH.NormalC  n fields)          = (n,) <$> mapM (onSnd (expandSyns . applySubst sub) . (\(   _,t) -> (Nothing, t))) fields
+        expandCon sub (TH.RecC     n fields)          = (n,) <$> mapM (onSnd (expandSyns . applySubst sub) . (\(fn,_,t) -> (Just fn, t))) fields
+        expandCon sub (TH.InfixC   (_, t1) n (_, t2)) = (n,) <$> mapM (onSnd (expandSyns . applySubst sub)) [(Nothing, t1), (Nothing, t2)]
+        {- These don't have proper correspondences in SMTLib; so ignore.
+        expandCon sub (TH.ForallC  _ _ c)             = expandCon sub c
+        expandCon sub (TH.GadtC    [n] fields _)      = (n,) <$> mapM (onSnd (expandSyns . applySubst sub) . (\(   _,t) -> (Nothing, t))) fields
+        expandCon sub (TH.RecGadtC [n] fields _)      = (n,) <$> mapM (onSnd (expandSyns . applySubst sub) . (\(fn,_,t) -> (Just fn, t))) fields
+        -}
+        expandCon _   c                               = bad "Unsupported constructor form: "
+                                                            [ "Type       : " ++ show typeName
+                                                            , "Constructor: " ++ show c
+                                                            , ""
+                                                            , report
+                                                            ]
+
+        tvName :: TH.TyVarBndr TH.BndrVis -> TH.Name
+        tvName (TH.PlainTV  n _)   = n
+        tvName (TH.KindedTV n _ _) = n
+
+        -- | Make substitution from type variables to actual args
+        mkSubst :: [TH.TyVarBndr TH.BndrVis] -> [TH.Type] -> [(TH.Name, TH.Type)]
+        mkSubst tvs = zip (map tvName tvs)
+
+        -- | Apply substitution to a Type
+        applySubst :: [(TH.Name, TH.Type)] -> TH.Type -> TH.Type
+        applySubst sub = go
+          where go (TH.VarT    n)        = fromMaybe  (TH.VarT n) (n `lookup` sub)
+                go (TH.AppT    t1 t2)    = TH.AppT    (go t1) (go t2)
+                go (TH.SigT    t k)      = TH.SigT    (go t)  k
+                go (TH.ParensT t)        = TH.ParensT (go t)
+                go (TH.InfixT  t1 n t2)  = TH.InfixT  (go t1) n (go t2)
+                go (TH.UInfixT t1 n t2)  = TH.UInfixT (go t1) n (go t2)
+                go (TH.ForallT bs ctx t) = TH.ForallT bs (map goPred ctx) (go t)
+                go t                     = t
+
+                goPred (TH.AppT t1 t2) = TH.AppT (go t1) (go t2)
+                goPred p               = p
diff --git a/Data/SBV/Dynamic.hs b/Data/SBV/Dynamic.hs
--- a/Data/SBV/Dynamic.hs
+++ b/Data/SBV/Dynamic.hs
@@ -32,7 +32,9 @@
   -- *** Integer literals
   , svInteger, svAsInteger
   -- *** Float literals
-  , svFloat, svDouble, svFloatingPoint
+  , svFloat, svDouble, svFloatingPoint, svAsFloat, svAsDouble, svAsFP
+  -- *** Rounding mode literals
+  , svRoundingMode, svAsRoundingMode
   -- *** Algebraic reals (only from rationals)
   , svReal, svNumerator, svDenominator
   -- *** Symbolic equality
@@ -63,6 +65,16 @@
   , svBarrelRotateLeft, svBarrelRotateRight
   , svWordFromBE, svWordFromLE
   , svBlastLE, svBlastBE
+  -- *** Floating-point operations
+  , svFPNaN, svFPInf, svFPZero
+  , svFPFromIntegerLit, svFPFromRationalLit
+  , svFPIsZero, svFPIsInfinite, svFPIsNegative, svFPIsPositive
+  , svFPIsNaN, svFPIsNormal, svFPIsSubnormal
+  , svFPAdd, svFPSub, svFPMul, svFPDiv, svFPRem, svFPMin, svFPMax
+  , svFPFMA, svFPAbs, svFPNeg, svFPRoundToIntegral, svFPSqrt
+  , svCastToFP, svCastFromFP
+  , svSWord32AsFloat, svSWord64AsDouble, svSWordAsFloatingPoint
+  , svFloatAsSWord32, svDoubleAsSWord64, svFloatingPointAsSWord
   -- ** Conditionals: Mergeable values
   , svIte, svLazyIte, svSymbolicMerge
   -- * Uninterpreted sorts, constants, and functions
@@ -99,7 +111,7 @@
   , SBVCodeGen
 
   -- ** Setting code-generation options
-  , cgPerformRTCs, cgSetDriverValues, cgGenerateDriver, cgGenerateMakefile
+  , cgPerformRTCs, cgSetDriverValues, cgArrayEqualityLimit, cgRegexLimits, cgGenerateDriver, cgGenerateMakefile
 
   -- ** Designating inputs
   , svCgInput, svCgInputArr
@@ -136,7 +148,7 @@
                                   , svCgInput, svCgInputArr
                                   , svCgOutput, svCgOutputArr
                                   , svCgReturn, svCgReturnArr
-                                  , cgPerformRTCs, cgSetDriverValues, cgGenerateDriver, cgGenerateMakefile
+                                  , cgPerformRTCs, cgSetDriverValues, cgArrayEqualityLimit, cgRegexLimits, cgGenerateDriver, cgGenerateMakefile
                                   , cgAddPrototype, cgAddDecl, cgAddLDFlags, cgIgnoreSAssert
                                   , cgIntegerSize, cgSRealType, CgSRealType(..)
                                   )
@@ -166,78 +178,78 @@
 
 -- | Create SMT-Lib benchmark for a sat call
 generateSMTBenchmarkSat :: Symbolic SVal -> IO String
-generateSMTBenchmarkSat s = SBV.generateSMTBenchmarkSat (fmap toSBool s)
+generateSMTBenchmarkSat s = SBV.generateSMTBenchmarkSat (toSBool <$> s)
 
 -- | Create SMT-Lib benchmark for a proof call
 generateSMTBenchmarkProof :: Symbolic SVal -> IO String
-generateSMTBenchmarkProof s = SBV.generateSMTBenchmarkProof (fmap toSBool s)
+generateSMTBenchmarkProof s = SBV.generateSMTBenchmarkProof (toSBool <$> s)
 
 -- | Proves the predicate using the given SMT-solver
 proveWith :: SMTConfig -> Symbolic SVal -> IO ThmResult
-proveWith cfg s = SBV.proveWith cfg (fmap toSBool s)
+proveWith cfg s = SBV.proveWith cfg (toSBool <$> s)
 
 -- | Find a satisfying assignment using the given SMT-solver
 satWith :: SMTConfig -> Symbolic SVal -> IO SatResult
-satWith cfg s = SBV.satWith cfg (fmap toSBool s)
+satWith cfg s = SBV.satWith cfg (toSBool <$> s)
 
 -- | Check safety using the given SMT-solver
 safeWith :: SMTConfig -> Symbolic SVal -> IO [SafeResult]
-safeWith cfg s = SBV.safeWith cfg (fmap toSBool s)
+safeWith cfg s = SBV.safeWith cfg (toSBool <$> s)
 
 -- | Find all satisfying assignments using the given SMT-solver
 allSatWith :: SMTConfig -> Symbolic SVal -> IO AllSatResult
-allSatWith cfg s = SBV.allSatWith cfg (fmap toSBool s)
+allSatWith cfg s = SBV.allSatWith cfg (toSBool <$> s)
 
 -- | Prove a property with multiple solvers, running them in separate threads. The
 -- results will be returned in the order produced.
 proveWithAll :: [SMTConfig] -> Symbolic SVal -> IO [(Solver, NominalDiffTime, ThmResult)]
-proveWithAll cfgs s = SBV.proveWithAll cfgs (fmap toSBool s)
+proveWithAll cfgs s = SBV.proveWithAll cfgs (toSBool <$> s)
 
 -- | Prove a property with multiple solvers, running them in separate
 -- threads. Only the result of the first one to finish will be
 -- returned, remaining threads will be killed.
 proveWithAny :: [SMTConfig] -> Symbolic SVal -> IO (Solver, NominalDiffTime, ThmResult)
-proveWithAny cfgs s = SBV.proveWithAny cfgs (fmap toSBool s)
+proveWithAny cfgs s = SBV.proveWithAny cfgs (toSBool <$> s)
 
 -- | Prove a property with query mode using multiple threads. Each query
 -- computation will spawn a thread and a unique instance of your solver to run
 -- asynchronously. The 'Symbolic' t'SVal' is duplicated for each thread. This
 -- function will block until all child threads return.
 proveConcurrentWithAll :: SMTConfig -> Symbolic SVal -> [Query SVal] -> IO [(Solver, NominalDiffTime, ThmResult)]
-proveConcurrentWithAll cfg s queries = SBV.proveConcurrentWithAll cfg queries (fmap toSBool s)
+proveConcurrentWithAll cfg s queries = SBV.proveConcurrentWithAll cfg queries (toSBool <$> s)
 
 -- | Prove a property with query mode using multiple threads. Each query
 -- computation will spawn a thread and a unique instance of your solver to run
 -- asynchronously. The 'Symbolic' t'SVal' is duplicated for each thread. This
 -- function will return the first query computation that completes, killing the others.
 proveConcurrentWithAny :: SMTConfig -> Symbolic SVal -> [Query SVal] -> IO (Solver, NominalDiffTime, ThmResult)
-proveConcurrentWithAny cfg s queries = SBV.proveConcurrentWithAny cfg queries (fmap toSBool s)
+proveConcurrentWithAny cfg s queries = SBV.proveConcurrentWithAny cfg queries (toSBool <$> s)
 
 -- | Find a satisfying assignment to a property with multiple solvers,
 -- running them in separate threads. The results will be returned in
 -- the order produced.
 satWithAll :: [SMTConfig] -> Symbolic SVal -> IO [(Solver, NominalDiffTime, SatResult)]
-satWithAll cfgs s = SBV.satWithAll cfgs (fmap toSBool s)
+satWithAll cfgs s = SBV.satWithAll cfgs (toSBool <$> s)
 
 -- | Find a satisfying assignment to a property with multiple solvers,
 -- running them in separate threads. Only the result of the first one
 -- to finish will be returned, remaining threads will be killed.
 satWithAny :: [SMTConfig] -> Symbolic SVal -> IO (Solver, NominalDiffTime, SatResult)
-satWithAny cfgs s = SBV.satWithAny cfgs (fmap toSBool s)
+satWithAny cfgs s = SBV.satWithAny cfgs (toSBool <$> s)
 
 -- | Find a satisfying assignment to a property with multiple threads in query
 -- mode. The 'Symbolic' t'SVal' represents what is known to all child query threads.
 -- Each query thread will spawn a unique instance of the solver. Only the first
 -- one to finish will be returned and the other threads will be killed.
 satConcurrentWithAny :: SMTConfig -> [Query b] -> Symbolic SVal -> IO (Solver, NominalDiffTime, SatResult)
-satConcurrentWithAny cfg qs s = SBV.satConcurrentWithAny cfg qs (fmap toSBool s)
+satConcurrentWithAny cfg qs s = SBV.satConcurrentWithAny cfg qs (toSBool <$> s)
 
 -- | Find a satisfying assignment to a property with multiple threads in query
 -- mode. The 'Symbolic' t'SVal' represents what is known to all child query threads.
 -- Each query thread will spawn a unique instance of the solver. This function
 -- will block until all child threads have completed.
 satConcurrentWithAll :: SMTConfig -> [Query b] -> Symbolic SVal -> IO [(Solver, NominalDiffTime, SatResult)]
-satConcurrentWithAll cfg qs s = SBV.satConcurrentWithAll cfg qs (fmap toSBool s)
+satConcurrentWithAll cfg qs s = SBV.satConcurrentWithAll cfg qs (toSBool <$> s)
 
 -- | Extract a model, the result is a tuple where the first argument (if True)
 -- indicates whether the model was "probable". (i.e., if the solver returned unknown.)
diff --git a/Data/SBV/Either.hs b/Data/SBV/Either.hs
--- a/Data/SBV/Either.hs
+++ b/Data/SBV/Either.hs
@@ -11,30 +11,35 @@
 -----------------------------------------------------------------------------
 
 {-# LANGUAGE CPP                 #-}
-{-# LANGUAGE Rank2Types          #-}
+{-# LANGUAGE FlexibleContexts    #-}
+{-# LANGUAGE FlexibleInstances   #-}
+{-# LANGUAGE QuasiQuotes         #-}
 {-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TemplateHaskell     #-}
 {-# LANGUAGE TypeApplications    #-}
 
-{-# OPTIONS_GHC -Wall -Werror #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
 module Data.SBV.Either (
     -- * Constructing sums
-      sLeft, sRight, liftEither
+      sLeft, sRight, liftEither, SEither, sEither, sEither_, sEithers
     -- * Destructing sums
     , either
     -- * Mapping functions
     , bimap, first, second
     -- * Scrutinizing branches of a sum
     , isLeft, isRight, fromLeft, fromRight
+    -- * Case analysis (for sCase quasi-quoter)
+    , sCaseEither, getLeft_1, getRight_1
   ) where
 
 import           Prelude hiding (either)
 import qualified Prelude
 
-import Data.Proxy (Proxy(Proxy))
-
+import Data.SBV.Client
 import Data.SBV.Core.Data
-import Data.SBV.Core.Model () -- instances only
+import Data.SBV.Core.Model (OrdSymbolic(..))
+import Data.SBV.SCase      (sCase)
 
 #ifdef DOCTEST
 -- $setup
@@ -42,64 +47,40 @@
 -- >>> import Data.SBV
 #endif
 
--- | Construct an @SEither a b@ from an @SBV a@
+-- | Make 'Either' symbolic.
 --
 -- >>> sLeft 3 :: SEither Integer Bool
--- Left 3 :: SEither Integer Bool
-sLeft :: forall a b. (SymVal a, SymVal b) => SBV a -> SEither a b
-sLeft sa
-  | Just a <- unliteral sa
-  = literal (Left a)
-  | True
-  = SBV $ SVal k $ Right $ cache res
-  where k1 = kindOf (Proxy @a)
-        k2 = kindOf (Proxy @b)
-        k  = KEither k1 k2
-
-        res st = do asv <- sbvToSV st sa
-                    newExpr st k $ SBVApp (EitherConstructor k1 k2 False) [asv]
-
--- | Return 'sTrue' if the given symbolic value is 'Left', 'sFalse' otherwise
---
+-- Left 3 :: Either Integer Bool
 -- >>> isLeft (sLeft 3 :: SEither Integer Bool)
 -- True
 -- >>> isLeft (sRight sTrue :: SEither Integer Bool)
 -- False
-isLeft :: (SymVal a, SymVal b) => SEither a b -> SBV Bool
-isLeft = either (const sTrue) (const sFalse)
-
--- | Construct an @SEither a b@ from an @SBV b@
---
 -- >>> sRight sFalse :: SEither Integer Bool
--- Right False :: SEither Integer Bool
-sRight :: forall a b. (SymVal a, SymVal b) => SBV b -> SEither a b
-sRight sb
-  | Just b <- unliteral sb
-  = literal (Right b)
-  | True
-  = SBV $ SVal k $ Right $ cache res
-  where k1 = kindOf (Proxy @a)
-        k2 = kindOf (Proxy @b)
-        k  = KEither k1 k2
-
-        res st = do bsv <- sbvToSV st sb
-                    newExpr st k $ SBVApp (EitherConstructor k1 k2 True) [bsv]
-
--- | Return 'sTrue' if the given symbolic value is 'Right', 'sFalse' otherwise
---
+-- Right False :: Either Integer Bool
 -- >>> isRight (sLeft 3 :: SEither Integer Bool)
 -- False
 -- >>> isRight (sRight sTrue :: SEither Integer Bool)
 -- True
-isRight :: (SymVal a, SymVal b) => SEither a b -> SBV Bool
-isRight = either (const sFalse) (const sTrue)
+mkSymbolic [''Either]
 
+-- | Declare a symbolic either.
+sEither :: (SymVal a, SymVal b) => String -> Symbolic (SEither a b)
+sEither = free
+
+-- | Declare a symbolic either, unnamed.
+sEither_ :: (SymVal a, SymVal b) => Symbolic (SEither a b)
+sEither_ = free_
+
+-- | Declare a list of symbolic eithers.
+sEithers :: (SymVal a, SymVal b) => [String] -> Symbolic [SEither a b]
+sEithers = symbolics
+
 -- | Construct an @SEither a b@ from an @Either (SBV a) (SBV b)@
 --
 -- >>> liftEither (Left 3 :: Either SInteger SBool)
--- Left 3 :: SEither Integer Bool
+-- Left 3 :: Either Integer Bool
 -- >>> liftEither (Right sTrue :: Either SInteger SBool)
--- Right True :: SEither Integer Bool
+-- Right True :: Either Integer Bool
 liftEither :: (SymVal a, SymVal b) => Either (SBV a) (SBV b) -> SEither a b
 liftEither = Prelude.either sLeft sRight
 
@@ -121,31 +102,10 @@
        -> (SBV b -> SBV c)
        -> SEither a b
        -> SBV c
-either brA brB sab
-  | Just (Left  a) <- unliteral sab
-  = brA $ literal a
-  | Just (Right b) <- unliteral sab
-  = brB $ literal b
-  | True
-  = SBV $ SVal kc $ Right $ cache res
-  where ka = kindOf (Proxy @a)
-        kb = kindOf (Proxy @b)
-        kc = kindOf (Proxy @c)
-
-        res st = do abv <- sbvToSV st sab
-
-                    let leftVal  = SBV $ SVal ka $ Right $ cache $ \_ -> newExpr st ka $ SBVApp (EitherAccess False) [abv]
-                        rightVal = SBV $ SVal kb $ Right $ cache $ \_ -> newExpr st kb $ SBVApp (EitherAccess True)  [abv]
-
-                        leftRes  = brA leftVal
-                        rightRes = brB rightVal
-
-                    br1 <- sbvToSV st leftRes
-                    br2 <- sbvToSV st rightRes
-
-                    --  Which branch are we in? Return the appropriate value:
-                    onLeft <- newExpr st KBool $ SBVApp (EitherIs ka kb False) [abv]
-                    newExpr st kc $ SBVApp Ite [onLeft, br1, br2]
+either brA brB sab = [sCase| sab of
+                        Left x  -> brA x
+                        Right x -> brB x
+                     |]
 
 -- | Map over both sides of a symbolic 'Either' at the same time
 --
@@ -197,14 +157,7 @@
 -- is unspecified, thus the SMT solver picks whatever satisfies the
 -- constraints, if there is one.
 fromLeft :: forall a b. (SymVal a, SymVal b) => SEither a b -> SBV a
-fromLeft sab
-  | Just (Left a) <- unliteral sab
-  = literal a
-  | True
-  = SBV $ SVal ka $ Right $ cache res
-  where ka      = kindOf (Proxy @a)
-        res st = do ms <- sbvToSV st sab
-                    newExpr st ka (SBVApp (EitherAccess False) [ms])
+fromLeft = getLeft_1
 
 -- | Return the value from the right component. The behavior is undefined if
 -- passed a left value, i.e., it can return any value.
@@ -221,13 +174,12 @@
 -- is unspecified, thus the SMT solver picks whatever satisfies the
 -- constraints, if there is one.
 fromRight :: forall a b. (SymVal a, SymVal b) => SEither a b -> SBV b
-fromRight sab
-  | Just (Right b) <- unliteral sab
-  = literal b
-  | True
-  = SBV $ SVal kb $ Right $ cache res
-  where kb      = kindOf (Proxy @b)
-        res st = do ms <- sbvToSV st sab
-                    newExpr st kb (SBVApp (EitherAccess True) [ms])
+fromRight = getRight_1
+
+-- | Custom 'OrdSymbolic' instance over 'SEither'.
+instance (OrdSymbolic (SBV a), OrdSymbolic (SBV b), SymVal a, SymVal b) => OrdSymbolic (SBV (Either a b)) where
+  eab .< ecd = either (\a -> either (a .<)         (const sTrue) ecd)
+                      (\b -> either (const sFalse) (b .<)        ecd)
+                      eab
 
 {- 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
@@ -19,7 +19,7 @@
 
 {-# LANGUAGE CPP              #-}
 {-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE Rank2Types       #-}
+{-# LANGUAGE RankNTypes       #-}
 {-# LANGUAGE TypeOperators    #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
@@ -41,6 +41,9 @@
   , genLiteral, genFromCV, CV(..), genMkSymVar, genParse, showModel, SMTModel(..), liftQRem, liftDMod, registerKind, svToSV
   , ProvableM(), SatisfiableM(), UICodeKind(..)
 
+  -- * Kind traversal and ADT registration metadata
+  , expandKinds, substituteADTVars, withADTDependencies, adtKindDependencies
+
   -- * Compilation to C, extras
   , compileToC', compileToCLib'
 
@@ -60,6 +63,9 @@
   -- $coordinateSolverInfo
   , sendStringToSolver, sendRequestToSolver, retrieveResponseFromSolver
 
+  -- * Parsing and formatting solver responses
+  , SExpr(..), parseSExpr, formatFunctionResponse
+
   -- * Defining new metrics
   , addSValOptGoal
   , sFloatAsComparableSWord32,  sDoubleAsComparableSWord64,  sFloatingPointAsComparableSWord
@@ -68,15 +74,18 @@
   -- * Generalized floats
   , svFloatingPointAsSWord
 
-  -- * lambdas and axioms
+  -- * Lambdas and axioms
   , lambda, lambdaStr, constraint, constraintStr, Lambda(..), Constraint(..), LambdaScope(..)
+
+  -- * TP induction extras
+  , HasInductionSchema(..), internalAxiom
   ) where
 
 import Control.Monad.IO.Class (MonadIO)
 
 import Data.SBV.Core.Data hiding (Forall(..), Exists(..), ForallN(..), ExistsN(..), ExistsUnique(..), Skolemize(..), QNot(..))
 
-import Data.SBV.Core.Kind       (BVIsNonZero, ValidFloat)
+import Data.SBV.Core.Kind       (BVIsNonZero, ValidFloat, expandKinds, substituteADTVars, withADTDependencies, adtKindDependencies)
 import Data.SBV.Core.Model      (genLiteral, genFromCV, genMkSymVar, liftQRem, liftDMod)
 import Data.SBV.Core.Symbolic   (IStage(..), QueryContext(..), MonadQuery, addSValOptGoal, registerKind, VarContext(..), svToSV, mkNewState, UICodeKind(..), UIName(..))
 
@@ -96,13 +105,17 @@
 
 import Data.SBV.Utils.TDiff
 import Data.SBV.Utils.PrettyNum
+import Data.SBV.Utils.SExpr (SExpr(..), parseSExpr, formatFunctionResponse)
 
 import GHC.TypeLits
 
 import qualified Data.SBV.Control.Utils as Query
+import qualified Data.Text              as T
 
 import Data.SBV.Lambda
 
+import Data.SBV.TP.Kernel
+
 #ifdef DOCTEST
 --- $setup
 --  >>> :set -XScopedTypeVariables
@@ -113,7 +126,7 @@
 -- Note that this is inherently dangerous as it can put the solver in an arbitrary
 -- state and confuse SBV. If you use this feature, you are on your own!
 sendStringToSolver :: (MonadIO m, MonadQuery m) => String -> m ()
-sendStringToSolver = Query.send False
+sendStringToSolver = Query.send False . T.pack
 
 -- | Retrieve multiple responses from the solver, until it responds with a user given
 -- tag that we shall arrange for internally. The optional timeout is in milliseconds.
@@ -127,7 +140,7 @@
 -- Note that this is inherently dangerous as it can put the solver in an arbitrary
 -- state and confuse SBV.
 sendRequestToSolver :: (MonadIO m, MonadQuery m) => String -> m String
-sendRequestToSolver = Query.ask
+sendRequestToSolver = Query.ask . T.pack
 
 {- $coordinateSolverInfo
 In rare cases it might be necessary to send an arbitrary string down to the solver. Needless to say, this
diff --git a/Data/SBV/Lambda.hs b/Data/SBV/Lambda.hs
--- a/Data/SBV/Lambda.hs
+++ b/Data/SBV/Lambda.hs
@@ -10,18 +10,18 @@
 -- higher-order function support in SBV.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE FlexibleContexts      #-}
-{-# LANGUAGE FlexibleInstances     #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE NamedFieldPuns        #-}
-{-# LANGUAGE ScopedTypeVariables   #-}
-{-# LANGUAGE TupleSections         #-}
-{-# LANGUAGE UndecidableInstances  #-}
+{-# LANGUAGE FlexibleContexts     #-}
+{-# LANGUAGE FlexibleInstances    #-}
+{-# LANGUAGE NamedFieldPuns       #-}
+{-# LANGUAGE OverloadedStrings    #-}
+{-# LANGUAGE TupleSections        #-}
+{-# LANGUAGE UndecidableInstances #-}
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
 module Data.SBV.Lambda (
             lambda,      lambdaStr
+          , lambdaWithInfo, LambdaInfo(..)
           , constraint,  constraintStr
           , LambdaScope(..)
         ) where
@@ -29,9 +29,12 @@
 import Control.Monad       (join)
 import Control.Monad.Trans (liftIO, MonadIO)
 
+import qualified Data.Text as T
+
 import Data.SBV.Core.Data
 import Data.SBV.Core.Kind
 import Data.SBV.SMT.SMTLib2
+import Data.SBV.Utils.Lib       (mapToSortedList, showText)
 import Data.SBV.Utils.PrettyNum
 
 import           Data.SBV.Core.Symbolic hiding   (mkNewState)
@@ -40,6 +43,7 @@
 import Data.IORef (readIORef, modifyIORef')
 import Data.List
 import Data.Maybe (fromMaybe)
+import qualified Data.Map.Strict as Map
 
 import qualified Data.Foldable as F
 import qualified Data.Set      as Set
@@ -50,12 +54,14 @@
 data LambdaScope = HigherOrderArg   -- This lambda will be firstified, hence can't have any free variables
                  | TopLevel         -- This lambda is used to represent a quantified axiom, can have free vars
 
+-- LambdaInfo is defined in Data.SBV.Core.Symbolic and re-exported from here for backwards compatibility.
+
 data Defn = Defn [String]                        -- The uninterpreted names referred to in the body
                  [String]                        -- Free variables (i.e., not uninterpreted nor bound in the definition itself)
-                 (Maybe [(Quantifier, String)])  -- Param declaration groups, if any
-                 (Int -> String)                 -- Body, given the tab amount.
+                 (Maybe [(Quantifier, T.Text)])  -- Param declaration groups, if any
+                 (Int -> T.Text)                 -- Body, given the tab amount.
 
--- | Maka a new substate from the incoming state, sharing parts as necessary
+-- | Make a new substate from the incoming state, sharing parts as necessary
 inSubState :: MonadIO m => LambdaScope -> State -> (State -> m b) -> m b
 inSubState scope inState comp = do
 
@@ -87,128 +93,179 @@
         -- don't really impact anything.
         comp State {
                    -- These are not IORefs; so we share by copying  the value; changes won't be copied back
-                     sbvContext          = share sbvContext
-                   , pathCond            = share pathCond
-                   , startTime           = share startTime
+                     sbvContext = share sbvContext
+                   , pathCond   = share pathCond
+                   , startTime  = share startTime
 
                    -- These are shared IORef's; and is shared, so they will be copied back to the parent state
-                   , rProgInfo           = share rProgInfo
-                   , rIncState           = share rIncState
-                   , rCInfo              = share rCInfo
-                   , rUsedKinds          = share rUsedKinds
-                   , rUsedLbls           = share rUsedLbls
-                   , rUIMap              = share rUIMap
-                   , rUserFuncs          = share rUserFuncs
-                   , rCgMap              = share rCgMap
-                   , rDefns              = share rDefns
-                   , rSMTOptions         = share rSMTOptions
-                   , rOptGoals           = share rOptGoals
-                   , rAsserts            = share rAsserts
-                   , rOutstandingAsserts = share rOutstandingAsserts
-                   , rPartitionVars      = share rPartitionVars
+                   , rProgInfo             = share rProgInfo
+                   , rIncState             = share rIncState
+                   , rCInfo                = share rCInfo
+                   , rUsedKinds            = share rUsedKinds
+                   , rUsedLbls             = share rUsedLbls
+                   , rUIMap                = share rUIMap
+                   , rUserFuncs            = share rUserFuncs
+                   , rCompilingFuncs       = share rCompilingFuncs
+                   , rCgMap                = share rCgMap
+                   , rDefns                = share rDefns
+                   , rMeasureChecks        = share rMeasureChecks
+                   , rFuncLambdaInfos      = share rFuncLambdaInfos
+                   , rSkipMeasureChecks    = share rSkipMeasureChecks
+                   , rNoTermCheckFunctions = share rNoTermCheckFunctions
+                   , rSMTOptions           = share rSMTOptions
+                   , rOptGoals             = share rOptGoals
+                   , rAsserts              = share rAsserts
+                   , rOutstandingAsserts   = share rOutstandingAsserts
+                   , rPartitionVars        = share rPartitionVars
 
                    -- Everything else is fresh in the substate; i.e., will not copy back
-                   , stCfg               = fresh stCfg
-                   , runMode             = fresh runMode
-                   , rctr                = fresh rctr
-                   , freshNameCtr        = fresh freshNameCtr
-                   , rLambdaLevel        = fresh rLambdaLevel
-                   , rtblMap             = fresh rtblMap
-                   , rinps               = fresh rinps
-                   , rlambdaInps         = fresh rlambdaInps
-                   , rConstraints        = fresh rConstraints
-                   , rObservables        = fresh rObservables
-                   , routs               = fresh routs
-                   , spgm                = fresh spgm
-                   , rconstMap           = fresh rconstMap
-                   , rexprMap            = fresh rexprMap
-                   , rSVCache            = fresh rSVCache
-                   , rQueryState         = fresh rQueryState
+                   , stCfg        = fresh stCfg
+                   , runMode      = fresh runMode
+                   , rctr         = fresh rctr
+                   , freshNameCtr = fresh freshNameCtr
+                   , rLambdaLevel = fresh rLambdaLevel
+                   , rtblMap      = fresh rtblMap
+                   , rinps        = fresh rinps
+                   , rlambdaInps  = fresh rlambdaInps
+                   , rConstraints = fresh rConstraints
+                   , rObservables = fresh rObservables
+                   , routs        = fresh routs
+                   , spgm         = fresh spgm
+                   , rconstMap    = fresh rconstMap
+                   , rexprMap     = fresh rexprMap
+                   , rSVCache     = fresh rSVCache
+                   , rQueryState  = fresh rQueryState
 
                    -- keep track of our parent
-                   , parentState         = Just inState
+                   , parentState = Just inState
                    }
 
 -- In this case, we expect just one group of parameters, with universal quantification
-extractAllUniversals :: [(Quantifier, String)] -> String
+extractAllUniversals :: [(Quantifier, T.Text)] -> T.Text
 extractAllUniversals [(ALL, s)] = s
 extractAllUniversals other      = error $ unlines [ ""
                                                   , "*** Data.SBV.Lambda: Impossible happened. Got existential quantifiers."
                                                   , "***"
-                                                  , "***  Params: " ++ show other
+                                                  , "***  Params: " ++ show (map (\(q, t) -> (q, T.unpack t)) other)
                                                   , "***"
                                                   , "*** Please report this as a bug!"
                                                   ]
 
 
--- | Generic creator for anonymous lamdas.
+-- | Generic creator for anonymous lambdas.
 lambdaGen :: (MonadIO m, Lambda (SymbolicT m) a) => LambdaScope -> (Defn -> b) -> State -> Kind -> a -> m b
-lambdaGen scope trans inState fk f = inSubState scope inState $ \st -> handle <$> convert st fk (mkLambda st f)
-  where handle d@(Defn _ frees _ _)
-            | null frees
-            = trans d
-            | True
-            = error $ unlines [ ""
-                              , "*** Data.SBV.Lambda: Detected free variables passed to a lambda."
-                              , "***"
-                              , "***  Free vars : " ++ unwords frees
-                              , "***  Definition: " ++ shift (lines (sh d))
-                              , "***"
-                              , "*** SBV currently does not support lambda-functions that capture variables. For"
-                              , "*** instance, consider:"
-                              , "***"
-                              , "***     map (\\x -> map (\\y -> x + y))"
-                              , "***"
-                              , "*** where the inner 'map' uses 'x', bound by the outer 'map'. Instead, create"
-                              , "*** a closure instead:"
-                              , "***"
-                              , "***     map (\\x -> map (Closure { closureEnv = x"
-                              , "***                             , closureFun = \\env y -> env + y"
-                              , "***                             }))"
-                              , "***"
-                              , "*** which will explicitly create the closure before calling 'map'. The environment can"
-                              , "*** be any symbolic value: You can use a tuple to support multiple free variables."
-                              , "***"
-                              , "*** (SBV firstifies higher-order functions via a simple translation to make it fit with"
-                              , "*** SMTLib's first-order logic. This translation does not currently support free"
-                              , "*** variables. In technical terms, we would need to do closure conversion and lambda-lifting."
-                              , "*** SBV isn't capable of doing the closure-conversion part, relying on the user to do so.)"
-                              , "***"
-                              , "*** Please rewrite your program to create a closure and use that as an argument."
-                              , "*** If this solution isn't applicable, or if you'd like help doing so, please get in"
-                              , "*** touch for further possible enhancements."
-                              ]
+lambdaGen scope trans inState fk f = inSubState scope inState $ \st -> handleLambdaDefn trans <$> convert st fk (mkLambda st f)
 
-        sh (Defn _unints _frees Nothing       body) = body 0
-        sh (Defn _unints _frees (Just params) body) = "(lambda " ++ extractAllUniversals params ++ "\n" ++ body 2 ++ ")"
+-- | Apply a lambda translation after enforcing SBV's no-captured-variables
+-- rule and preserving its established diagnostic.
+handleLambdaDefn :: (Defn -> b) -> Defn -> b
+handleLambdaDefn trans d@(Defn _ frees _ _)
+  | null frees
+  = trans d
+  | True
+  = error $ unlines [ ""
+                    , "*** Data.SBV.Lambda: Detected free variables passed to a lambda."
+                    , "***"
+                    , "***  Free vars : " ++ unwords frees
+                    , "***  Definition: " ++ shift (lines (sh d))
+                    , "***"
+                    , "*** SBV currently does not support lambda-functions that capture variables. For"
+                    , "*** instance, consider:"
+                    , "***"
+                    , "***     map (\\x -> map (\\y -> x + y))"
+                    , "***"
+                    , "*** where the inner 'map' uses 'x', bound by the outer 'map'. Instead, create"
+                    , "*** a closure instead:"
+                    , "***"
+                    , "***     map (\\x -> map (Closure { closureEnv = x"
+                    , "***                             , closureFun = \\env y -> env + y"
+                    , "***                             }))"
+                    , "***"
+                    , "*** which will explicitly create the closure before calling 'map'. The environment can"
+                    , "*** be any symbolic value: You can use a tuple to support multiple free variables."
+                    , "***"
+                    , "*** (SBV firstifies higher-order functions via a simple translation to make it fit with"
+                    , "*** SMTLib's first-order logic. This translation does not currently support free"
+                    , "*** variables. In technical terms, we would need to do closure conversion and lambda-lifting."
+                    , "*** SBV isn't capable of doing the closure-conversion part, relying on the user to do so.)"
+                    , "***"
+                    , "*** Please rewrite your program to create a closure and use that as an argument."
+                    , "*** If this solution isn't applicable, or if you'd like help doing so, please get in"
+                    , "*** touch for further possible enhancements."
+                    ]
+ where sh (Defn _unints _frees Nothing       body) = T.unpack (body 0)
+       sh (Defn _unints _frees (Just params) body) = "(lambda " ++ T.unpack (extractAllUniversals params) ++ "\n" ++ T.unpack (body 2) ++ ")"
 
-        shift []     = []
-        shift (x:xs) = intercalate "\n" (x : map tab xs)
-          where tab s = "***              " ++ s
+       shift []     = []
+       shift (x:xs) = intercalate "\n" (x : map tab xs)
+         where tab s = "***              " ++ s
 
 -- | Create an SMTLib lambda, in the given state.
 lambda :: (MonadIO m, Lambda (SymbolicT m) a) => State -> LambdaScope -> Kind -> a -> m SMTDef
 lambda inState scope fk = lambdaGen scope mkLam inState fk
    where mkLam (Defn unints _frees params body) = SMTDef fk unints (extractAllUniversals <$> params) body
 
+-- | Like 'lambda', but also returns the sub-state's DAG info for measure verification.
+lambdaWithInfo :: (MonadIO m, Lambda (SymbolicT m) a) => State -> LambdaScope -> Kind -> a -> m (SMTDef, LambdaInfo)
+lambdaWithInfo inState scope fk f = inSubState scope inState $ \st -> do
+   defn <- handleDefn <$> convert st fk (mkLambda st f)
+   info <- liftIO $ extractLambdaInfo st
+   pure (smtDefWithInfo defn info, info)
+   where handleDefn d@(Defn _ frees _ _)
+            | null frees = mkLam d
+            | True       = error $ unlines [ ""
+                                           , "*** Data.SBV.Lambda: Detected free variables in a function with a measure."
+                                           , "***  Free vars: " ++ unwords frees
+                                           ]
+         mkLam (Defn unints _frees params body) = SMTDef fk unints (extractAllUniversals <$> params) body
+
+-- | Extract DAG information from a lambda sub-state.
+extractLambdaInfo :: State -> IO LambdaInfo
+extractLambdaInfo st = do
+   SBVPgm asgns <- readIORef (spgm st)
+   linps        <- readIORef (rlambdaInps st)
+   outs         <- readIORef (routs st)
+   cmap         <- readIORef (rconstMap st)
+   tables       <- map arrange . mapToSortedList <$> readIORef (rtblMap st)
+   let params = [(q, getSV nsv) | (q, nsv) <- F.toList linps]
+       outSV  = case F.toList outs of
+                  [o] -> o
+                  os  -> error $ "Data.SBV.Lambda.extractLambdaInfo: expected exactly one output, got " ++ show (length os)
+   pure LambdaInfo { liAssignments = asgns
+                   , liParams      = params
+                   , liOutput      = outSV
+                   , liConsts      = map swap $ Map.toList cmap
+                   , liTables      = tables
+                   }
+   where arrange (i, (indexKind, resultKind, elements)) = ((i, indexKind, resultKind), elements)
+         swap (a, b) = (b, a)
+
 -- | Create an anonymous lambda, rendered as n SMTLib string. The kind passed is the kind of the final result.
 lambdaStr :: (MonadIO m, Lambda (SymbolicT m) a) => State -> LambdaScope -> Kind -> a -> m SMTLambda
-lambdaStr st scope k a = SMTLambda <$> lambdaGen scope mkLam st k a
-   where mkLam (Defn _unints _frees Nothing       body) = body 0
-         mkLam (Defn _unints _frees (Just params) body) = "(lambda " ++ extractAllUniversals params ++ "\n" ++ body 2 ++ ")"
+lambdaStr inState HigherOrderArg fk f = SMTLambda <$> lambdaGen HigherOrderArg renderLambdaDefn inState fk f
+lambdaStr inState TopLevel       fk f = inSubState TopLevel inState $ \st -> do
+  defn <- convert st fk (mkLambda st f)
+  let rendered = handleLambdaDefn renderLambdaDefn defn
+  rendered `seq` do lambdaInfo <- liftIO $ extractLambdaInfo st
+                    pure (smtLambdaWithInfo rendered lambdaInfo)
 
+-- | Render a validated anonymous lambda in its canonical SMT-Lib form.
+renderLambdaDefn :: Defn -> T.Text
+renderLambdaDefn (Defn _unints _frees Nothing       body) = body 0
+renderLambdaDefn (Defn _unints _frees (Just params) body) = "(lambda " <> extractAllUniversals params <> "\n" <> body 2 <> ")"
+
 -- | Generic constraint generator.
-constraintGen :: (MonadIO m, Constraint (SymbolicT m) a) => LambdaScope -> ([String] -> (Int -> String) -> b) -> State -> a -> m b
+constraintGen :: (MonadIO m, Constraint (SymbolicT m) a) => LambdaScope -> ([String] -> (Int -> T.Text) -> b) -> State -> a -> m b
 constraintGen scope trans inState@State{rProgInfo} f = do
    -- indicate we have quantifiers
    liftIO $ modifyIORef' rProgInfo (\u -> u{hasQuants = True})
 
    let mkDef (Defn deps _frees Nothing       body) = trans deps body
-       mkDef (Defn deps _frees (Just params) body) = trans deps $ \i -> unwords (map mkGroup params) ++ "\n"
-                                                                     ++ body (i + 2)
-                                                                     ++ replicate (length params) ')'
-       mkGroup (ALL, s) = "(forall " ++ s
-       mkGroup (EX,  s) = "(exists " ++ s
+       mkDef (Defn deps _frees (Just params) body) = trans deps $ \i -> T.unwords (map mkGroup params) <> "\n"
+                                                                     <> body (i + 2)
+                                                                     <> T.replicate (length params) ")"
+       mkGroup (ALL, s) = "(forall " <> s
+       mkGroup (EX,  s) = "(exists " <> s
 
    inSubState scope inState $ \st -> mkDef <$> convert st KBool (mkConstraint st f >>= output >> pure ())
 
@@ -227,9 +284,9 @@
 -- We allow free variables here (first arg of constraintGen). This might prove to be not kosher!
 constraintStr :: (MonadIO m, Constraint (SymbolicT m) a) => State -> a -> m String
 constraintStr = constraintGen TopLevel toStr
-   where toStr deps body = intercalate "\n" [ "; user defined axiom: " ++ depInfo deps
-                                            , "(assert " ++ body 2 ++ ")"
-                                            ]
+   where toStr deps body = T.unpack $ T.intercalate "\n" [ "; user defined axiom: " <> T.pack (depInfo deps)
+                                                          , "(assert " <> body 2 <> ")"
+                                                          ]
 
          depInfo [] = ""
          depInfo ds = "[Refers to: " ++ intercalate ", " ds ++ "]"
@@ -269,7 +326,7 @@
 
                   tbls          -- Tables
 
-                  _uis          -- Uninterpeted constants: nothing to do with them
+                  _uis          -- Uninterpreted constants: nothing to do with them
                   _axs          -- Axioms definitions    : nothing to do with them
 
                   pgm           -- Assignments
@@ -303,7 +360,7 @@
                ]
          | True
          = res
-         where res = Defn (nub [nm | Uninterpreted nm <- G.universeBi allOps])
+         where res = Defn (nub [T.unpack nm | Uninterpreted nm <- G.universeBi allOps])
                           frees
                           mbParam
                           body
@@ -320,9 +377,9 @@
 
                frees = map show badFrees
                  where (defs, uses) = unzip [(d, u) | (d, SBVApp _ u) <- F.toList asgnsSeq]
-                       allDefs      = defs ++ map snd params ++ map fst constants
-                       allUses      = concat uses
-                       allFrees     = nub allUses \\ nub allDefs
+                       defSet       = Set.fromList (defs ++ map snd params ++ map fst constants)
+                       useSet       = Set.fromList (concat uses)
+                       allFrees     = Set.toList (useSet `Set.difference` defSet)
                        badFrees     = filter (not . global . getId . swNodeId) allFrees
 
                        -- is this a global?
@@ -333,29 +390,29 @@
                  | null params = Nothing
                  | True        = Just [(q, paramList (map snd l)) | l@((q, _) : _)  <- pGroups]
                  where pGroups = groupBy (\(q1, _) (q2, _) -> q1 == q2) params
-                       paramList ps = '(' : unwords (map (\p -> '(' : show p ++ " " ++ smtType (kindOf p) ++ ")")  ps) ++ ")"
+                       paramList ps = "(" <> T.unwords (map (\p -> "(" <> showText p <> " " <> smtType (kindOf p) <> ")")  ps) <> ")"
 
                body tabAmnt
                  | null constTables
                  , null nonConstTables
                  , Just e <- simpleBody (map (, Nothing) constBindings ++ svBindings) out
-                 = tab ++ e
+                 = tab <> e
                  | True
-                 = intercalate "\n" $ map (tab ++) $  [mkLet sv  | sv <- constBindings]
-                                                   ++ [mkTable t | t  <- constTables]
-                                                   ++ walk svBindings nonConstTables
-                                                   ++ [shift ++ show out ++ replicate totalClose ')']
+                 = T.intercalate "\n" $ map (tab <>)  $  [mkLet sv  | sv <- constBindings]
+                                                       ++ [mkTable t | t  <- constTables]
+                                                       ++ walk svBindings nonConstTables
+                                                       ++ [shift <> showText out <> T.replicate totalClose ")"]
 
-                 where tab  = replicate tabAmnt ' '
+                 where tab  = T.replicate tabAmnt " "
 
-                       mkBind l r   = shift ++ "(let ((" ++ l ++ " " ++ r ++ "))"
-                       mkLet (s, v) = mkBind (show s) v
+                       mkBind l r   = shift <> "(let ((" <> l <> " " <> r <> "))"
+                       mkLet (s, v) = mkBind (showText s) v
 
                        -- Align according to level.
-                       shift = replicate (24 + 16 * (fromMaybe 0 level - 1)) ' '
+                       shift = T.replicate (24 + 16 * (fromMaybe 0 level - 1)) " "
 
-                       mkTable (((i, ak, rk), elts), _) = mkBind nm (lambdaTable (map (const ' ') nm) ak rk elts)
-                          where nm = "table" ++ show i
+                       mkTable (((i, ak, rk), elts), _) = mkBind nm (lambdaTable (T.map (const ' ') nm) ak rk elts)
+                          where nm = "table" <> showText i
 
                        totalClose = length constBindings
                                   + length svBindings
@@ -369,7 +426,7 @@
                                                                       ++ walk rest notReady
                           where (ready, notReady) = partition (\(need, _) -> need < getLLI nd) remaining
                                 mkLocalBind (b, Nothing) = mkLet b
-                                mkLocalBind (b, Just l)  = mkLet b ++ " ; " ++ l
+                                mkLocalBind (b, Just l)  = mkLet b <> " ; " <> T.pack l
 
                getLLI :: NodeId -> (Int, Int)
                getLLI (NodeId (_, mbl, i)) = (fromMaybe 0 mbl, i)
@@ -379,20 +436,20 @@
                -- (see https://github.com/LeventErkok/sbv/issues/733), so only do it if we're being verbose for debugging purposes.
                mkPretty = verbose cfg
 
-               simpleBody :: [((SV, String), Maybe String)] -> SV -> Maybe String
-               simpleBody [((v, e), Nothing)] o | v == o, not mkPretty || '\n' `notElem` e = Just e
-               simpleBody _                   _                                            = Nothing
+               simpleBody :: [((SV, T.Text), Maybe String)] -> SV -> Maybe T.Text
+               simpleBody [((v, e), Nothing)] o | v == o, not mkPretty || not (T.any (== '\n') e) = Just e
+               simpleBody _                   _                                                   = Nothing
 
                assignments = F.toList (pgmAssignments pgm)
 
                constants = filter ((`notElem` [falseSV, trueSV]) . fst) consts
 
-               constBindings :: [(SV, String)]
+               constBindings :: [(SV, T.Text)]
                constBindings = map mkConst constants
-                 where mkConst :: (SV, CV) -> (SV, String)
-                       mkConst (sv, cv) = (sv, cvToSMTLib (roundingMode cfg) cv)
+                 where mkConst :: (SV, CV) -> (SV, T.Text)
+                       mkConst (sv, cv) = (sv, cvToSMTLib cv)
 
-               svBindings :: [((SV, String), Maybe String)]
+               svBindings :: [((SV, T.Text), Maybe String)]
                svBindings = map mkAsgn assignments
                  where mkAsgn (sv, e@(SBVApp (Label l) _)) = ((sv, converter e), Just l)
                        mkAsgn (sv, e)                      = ((sv, converter e), Nothing)
@@ -409,18 +466,18 @@
 
                rm = roundingMode cfg
 
-               -- NB. The following is dead-code, since we ensure tbls is empty
-               -- We used to support this, but there are issues, so dropping support
-               -- See, for instance, https://github.com/LeventErkok/sbv/issues/664
-               (tableMap, constTables, nonConstTablesUnindexed) = constructTables rm consts tbls
+               -- Tables are local to this lambda. Constant tables can be bound
+               -- immediately, while tables containing symbolic elements must be
+               -- introduced after their last element has been defined.
+               (tableMap, constTables, nonConstTablesUnindexed) = constructTables consts tbls
 
                -- Index each non-const table with the largest index of SV it needs
                nonConstTables = [ (maximum ((0, 0) : [getLLI n | SV _ n <- elts]), nct)
                                 | nct@((_, elts), _) <- nonConstTablesUnindexed]
 
-               lambdaTable :: String -> Kind -> Kind -> [SV] -> String
-               lambdaTable extraSpace ak rk elts = "(lambda ((" ++ lv ++ " " ++ smtType ak ++ "))" ++ space ++ chain 0 elts ++ ")"
-                 where cnst k i = cvtCV rm (mkConstCV k (i::Integer))
+               lambdaTable :: T.Text -> Kind -> Kind -> [SV] -> T.Text
+               lambdaTable extraSpace ak rk elts = "(lambda ((" <> lv <> " " <> smtType ak <> "))" <> space <> chain 0 elts <> ")"
+                 where cnst k i = cvtCV (mkConstCV k (i::Integer))
 
                        lv = "idx"
 
@@ -428,15 +485,15 @@
                        long = not (null (drop 5 elts))
                        space
                          | long
-                         = "\n                  " ++ extraSpace
+                         = "\n                  " <> extraSpace
                          | True
                          = " "
 
                        chain _ []     = cnst rk 0
-                       chain _ [x]    = show x
-                       chain i (x:xs) = "(ite (= " ++ lv ++ " " ++ cnst ak i ++ ") "
-                                           ++ show x ++ space
-                                           ++ chain (i+1) xs
-                                           ++ ")"
+                       chain _ [x]    = showText x
+                       chain i (x:xs) = "(ite (= " <> lv <> " " <> cnst ak i <> ") "
+                                           <> showText x <> space
+                                           <> chain (i+1) xs
+                                           <> ")"
 
 {- 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
@@ -22,13 +22,13 @@
 {-# LANGUAGE FunctionalDependencies #-}
 {-# LANGUAGE NamedFieldPuns         #-}
 {-# LANGUAGE OverloadedLists        #-}
-{-# LANGUAGE Rank2Types             #-}
+{-# LANGUAGE QuasiQuotes            #-}
 {-# LANGUAGE ScopedTypeVariables    #-}
 {-# LANGUAGE TypeApplications       #-}
 {-# LANGUAGE TypeFamilies           #-}
 {-# LANGUAGE UndecidableInstances   #-}
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
 module Data.SBV.List (
         -- * Length, emptiness
@@ -37,6 +37,9 @@
         -- * Deconstructing/Reconstructing
         , nil, (.:), snoc, head, tail, uncons, init, last, singleton, listToListAt, elemAt, (!!), implode, concat, (++)
 
+        -- * Case analysis (for sCase quasi-quoter)
+        , list
+
         -- * Containment
         , elem, notElem, isInfixOf, isSuffixOf, isPrefixOf
 
@@ -76,6 +79,9 @@
         -- * Sum and product
         , sum, product
 
+        -- * Minimum and maximum of a list
+        , minimum, maximum
+
         -- * Conversion between strings and naturals
         , strToNat, natToStr
 
@@ -86,7 +92,7 @@
 import Prelude hiding (head, tail, init, last, length, take, drop, splitAt, concat, null, elem,
                        notElem, reverse, (++), (!!), map, concatMap, foldl, foldr, zip, zipWith, filter,
                        all, any, and, or, replicate, fst, snd, sum, product, Enum(..), lookup,
-                       takeWhile, dropWhile)
+                       takeWhile, dropWhile, minimum, maximum, uncurry)
 import qualified Prelude as P
 
 import Data.SBV.Core.Kind
@@ -94,7 +100,7 @@
 import Data.SBV.Core.Model
 import Data.SBV.Core.SizedFloats
 import Data.SBV.Core.Floating
-
+import Data.SBV.SCase (sCase)
 import Data.SBV.Tuple
 
 import Data.Maybe (isNothing, catMaybes)
@@ -105,11 +111,9 @@
 
 import Data.Proxy
 
-import GHC.Exts (IsList(..))
-
 #ifdef DOCTEST
 -- $setup
--- >>> import Prelude hiding (head, tail, init, last, length, take, drop, concat, null, elem, notElem, reverse, (++), (!!), map, foldl, foldr, zip, zipWith, filter, all, any, replicate, lookup, splitAt, concatMap, and, or, sum, product, takeWhile, dropWhile)
+-- >>> import Prelude hiding (head, tail, init, last, length, take, drop, concat, null, elem, notElem, reverse, (++), (!!), map, foldl, foldr, zip, zipWith, filter, all, any, replicate, lookup, splitAt, concatMap, and, or, sum, product, takeWhile, dropWhile, minimum, maximum)
 -- >>> import qualified Prelude as P(map)
 -- >>> import Data.SBV
 -- >>> :set -XDataKinds
@@ -120,15 +124,6 @@
 -- >>> :set -XQuasiQuotes
 #endif
 
--- | IsList instance allows list literals to be written compactly.
-instance SymVal a => IsList (SList a) where
-  type Item (SList a) = SBV a
-
-  fromList = P.foldr (.:) nil -- Don't use [] here for nil, as this is the very definition of doing overloaded lists
-  toList x = case unliteral x of
-               Nothing -> error "IsList.toList used in a symbolic context"
-               Just xs -> P.map literal xs
-
 -- | Length of a list.
 --
 -- >>> sat $ \(l :: SList Word16) -> length l .== 2
@@ -206,6 +201,21 @@
 uncons :: SymVal a => SList a -> (SBV a, SList a)
 uncons l = (head l, tail l)
 
+-- | Case analysis on a symbolic list. If the list is empty, return the first argument.
+-- Otherwise, apply the second argument to the head and tail of the list.
+--
+-- >>> list (0 :: SInteger) (\h _ -> h) ([] :: SList Integer)
+-- 0 :: SInteger
+-- >>> list (0 :: SInteger) (\h _ -> h) ([3, 4, 5] :: SList Integer)
+-- 3 :: SInteger
+-- >>> prove $ \(l :: SList Integer) -> null l .|| list sFalse (\_ _ -> sTrue) l
+-- Q.E.D.
+list :: (SymVal a, SymVal b) => SBV b -> (SBV a -> SList a -> SBV b) -> SList a -> SBV b
+list nilCase consCase xs = [sCase| xs of
+                              []   -> nilCase
+                              h:ts -> consCase h ts
+                           |]
+
 -- | @`init`@ returns all but the last element of the list. Unspecified if the list is empty.
 --
 -- >>> prove $ \(h :: SInteger) t -> init (t ++ [h]) .== t
@@ -282,14 +292,6 @@
 implode :: SymVal a => [SBV a] -> SList a
 implode = P.foldr ((++) . \x -> [x]) (literal [])
 
--- | Prepend an element, the traditional @cons@.
---
--- >>> 1 .: 2 .: 3 .: [4, 5, 6 :: SInteger]
--- [1,2,3,4,5,6] :: [SInteger]
-infixr 5 .:
-(.:) :: SymVal a => SBV a -> SList a -> SList a
-a .: as = singleton a ++ as  -- NB. Don't do "[a] ++ as" here. That type-checks but is recursive due to how overloaded-lists work.
-
 -- | Append an element
 --
 -- >>> [1, 2, 3 :: SInteger] `snoc` 4 `snoc` 5 `snoc` 6
@@ -297,15 +299,7 @@
 snoc :: SymVal a => SList a -> SBV a -> SList a
 as `snoc` a = as ++ [a]
 
--- | Empty list. This value has the property that it's the only list with length 0. If you use @OverloadedLists@ extension,
--- you can write it as the familiar `[]`.
---
--- >>> prove $ \(l :: SList Integer) -> length l .== 0 .<=> l .== []
--- Q.E.D.
--- >>> prove $ \(l :: SString) -> length l .== 0 .<=> l .== []
--- Q.E.D.
-nil :: SymVal a => SList a
-nil = literal []
+-- nil is defined in Data.SBV.Core.Data and re-exported here.
 
 -- | Append two lists.
 --
@@ -376,10 +370,19 @@
 -- | @listEq@ is a variant of equality that you can use for lists of floats. It respects @NaN /= NaN@. The reason
 -- we do not do this automatically is that it complicates proof objectives usually, as it does not simply resolve to
 -- the native equality check.
+--
+-- NB. We case-split on @x@ only and use a guard for @y@ being empty, rather than case-splitting on the
+-- tuple @(x, y)@. A 4-way tuple match produces a larger and\/or\/not SMTLib tree that z3 struggles with.
 listEq :: forall a. SymVal a => SList a -> SList a -> SBool
 listEq
   | containsFloats (kindOf (Proxy @a))
-  = smtFunction "listEq" $ \xs ys -> ite (null xs) (null ys) (head xs .== head ys .&& listEq (tail xs) (tail ys))
+  = smtFunction "listEq"
+  $ \x y -> [sCase| x of
+                []   -> null y
+                a:xs -> case y of
+                          []     -> sFalse
+                          b : ys -> a .== b .&& xs `listEq` ys
+            |]
   | True
   = (.==)
 
@@ -473,7 +476,7 @@
   | True                                     -- either symbolic, or something is out-of-bounds
   = lift3 False (SeqSubseq (kindOf (Proxy @a))) Nothing l offset len
 
--- | @`replace` l src dst@. Replace the first occurrence of @src@ by @dst@ in @s@
+-- | @`replace` l src dst@. Replace the first occurrence of @src@ by @dst@ in @l@
 --
 -- >>> prove $ \l -> replace [sEnum|1..5|] l [sEnum|6..10|] .== [sEnum|6..10|] .=> l .== [sEnum|1..5::SWord8|]
 -- Q.E.D.
@@ -563,7 +566,11 @@
   = literal (P.reverse l')
   | True
   = def l
-  where def = smtFunction "sbv.reverse" $ \xs -> ite (null xs) [] (let (h, t) = uncons xs in def t ++ [h])
+  where def = smtFunction "sbv.reverse"
+            $ \xs -> [sCase| xs of
+                        []   -> []
+                        h:ts -> def ts ++ [h]
+                      |]
 
 -- | A class of mappable functions. In SBV, we make a distinction between closures and regular functions, and
 -- we instantiate this class appropriately so it can handle both cases.
@@ -605,7 +612,11 @@
     = literal concResult
     | True
     = sbvMap l
-    where sbvMap = smtHOFunction "sbv.map" f $ \xs -> ite (null xs) [] (let (h, t) = uncons xs in f h .: sbvMap t)
+    where sbvMap = smtHOFunction "sbv.map" f
+                 $ \xs -> [sCase| xs of
+                             []    -> []
+                             h : t -> f h .: sbvMap t
+                          |]
 
 -- | Mapping symbolic closures.
 instance (SymVal env, SymVal a, SymVal b) => SMap (Closure (SBV env) (SBV a -> SBV b)) a b where
@@ -615,9 +626,10 @@
     | True
     = sbvMap (tuple (closureEnv, l))
     where sbvMap = smtHOFunction "sbv.closureMap" closureFun
-                 $ \envxs -> let (cEnv, xs) = untuple envxs
-                                 (h, t)     = uncons xs
-                             in ite (null xs) [] (closureFun cEnv h .: sbvMap (tuple (cEnv, t)))
+                 $ \envxs -> [sCase| envxs of
+                                (_,    [])    -> []
+                                (cEnv, h : t) -> closureFun cEnv h .: sbvMap (tuple (cEnv, t))
+                            |]
 
 -- | @concatMap f xs@ maps f over elements and concats the result.
 --
@@ -638,7 +650,7 @@
   -- >>> foldl (\soFar elt -> [elt] ++ soFar) ([] :: SList Integer) [sEnum|1 .. 5|]
   -- [5,4,3,2,1] :: [SInteger]
   --
-  -- Again, we can use 'Data.SBV.List.foldl' in the reverse too:
+  -- Again, we can use 'sbv.foldl' in the reverse too:
   --
   -- >>> sat $ \l -> foldl (\soFar elt -> [elt] ++ soFar) ([] :: SList Integer) l .== [5, 4, 3, 2, 1 :: SInteger]
   -- Satisfiable. Model:
@@ -665,12 +677,11 @@
     = literal concResult
     | True
     = sbvFoldl $ tuple (base, l)
-    where sbvFoldl = smtHOFunction "sbv.foldl" (uncurry f . untuple)
-                   $ \exs -> let (e, xs) = untuple exs
-                                 (h, t)  = uncons xs
-                             in ite (null xs)
-                                    e
-                                    (sbvFoldl (tuple (e `f` h, t)))
+    where sbvFoldl = smtHOFunction "sbv.foldl" (uncurry f)
+                   $ \exs -> [sCase| exs of
+                                (e, [])    -> e
+                                (e, h : t) -> sbvFoldl (tuple (e `f` h, t))
+                             |]
 
 -- | Folding left with symbolic closures.
 instance (SymVal env, SymVal a, SymVal b) => SFoldL (Closure (SBV env) (SBV b -> SBV a -> SBV b)) a b where
@@ -680,11 +691,10 @@
     | True
     = sbvFoldl $ tuple (closureEnv, base, l)
     where sbvFoldl = smtHOFunction "sbv.closureFoldl" closureFun
-                   $ \envxs -> let (cEnv, e, xs) = untuple envxs
-                                   (h, t)        = uncons xs
-                               in ite (null xs)
-                                      e
-                                      (sbvFoldl (tuple (cEnv, closureFun closureEnv e h, t)))
+                   $ \envxs -> [sCase| envxs of
+                                  (_,    e, [])    -> e
+                                  (cEnv, e, h : t) -> sbvFoldl (tuple (cEnv, closureFun closureEnv e h, t))
+                               |]
 
 -- | A class of right foldable functions. In SBV, we make a distinction between closures and regular functions, and
 -- we instantiate this class appropriately so it can handle both cases.
@@ -699,7 +709,7 @@
   -- [5,4,3,2,1] :: [SInteger]
   foldr :: func -> SBV b -> SList a -> SBV b
 
-  -- | Handle the concrete case for folding left. Used internally only.
+  -- | Handle the concrete case for folding right. Used internally only.
   concreteFoldr :: func -> (SBV a -> SBV b -> SBV b) -> SBV b -> SList a -> Maybe b
   concreteFoldr _ f sb sas
      | Just b <- unliteral sb, Just as <- unliteral sas
@@ -719,12 +729,11 @@
     = literal concResult
     | True
     = sbvFoldr $ tuple (base, l)
-    where sbvFoldr = smtHOFunction "sbv.foldr" (uncurry f . untuple)
-                   $ \exs -> let (e, xs) = untuple exs
-                                 (h, t)  = uncons xs
-                             in ite (null xs)
-                                    e
-                                    (h `f` sbvFoldr (tuple (e, t)))
+    where sbvFoldr = smtHOFunction "sbv.foldr" (uncurry f)
+                   $ \exs -> [sCase| exs of
+                                (e, [])    -> e
+                                (e, h : t) -> h `f` sbvFoldr (tuple (e, t))
+                             |]
 
 -- | Folding right with symbolic closures.
 instance (SymVal env, SymVal a, SymVal b) => SFoldR (Closure (SBV env) (SBV a -> SBV b -> SBV b)) a b where
@@ -734,14 +743,13 @@
     | True
     = sbvFoldr $ tuple (closureEnv, base, l)
     where sbvFoldr = smtHOFunction "sbv.closureFoldr" closureFun
-                   $ \envxs -> let (cEnv, e, xs) = untuple envxs
-                                   (h, t)        = uncons xs
-                               in ite (null xs)
-                                      e
-                                      (closureFun closureEnv h (sbvFoldr (tuple (cEnv, e, t))))
+                   $ \envxs -> [sCase| envxs of
+                                  (_,    e, [])    -> e
+                                  (cEnv, e, h : t) -> closureFun closureEnv h (sbvFoldr (tuple (cEnv, e, t)))
+                               |]
 
 -- | @`zip` xs ys@ zips the lists to give a list of pairs. The length of the final list is
--- the minumum of the lengths of the given lists.
+-- the minimum of the lengths of the given lists.
 --
 -- >>> zip [sEnum|1..10 :: SInteger|] [sEnum|11..20 :: SInteger|]
 -- [(1,11),(2,12),(3,13),(4,14),(5,15),(6,16),(7,17),(8,18),(9,19),(10,20)] :: [(SInteger, SInteger)]
@@ -754,13 +762,18 @@
  = literal $ P.zip xs' ys'
  | True
  = def xs ys
- where def = smtFunction "sbv.zip" $ \as bs -> ite (null as .|| null bs) [] (tuple (head as, head bs) .: def (tail as) (tail bs))
+ where def = smtFunction "sbv.zip"
+           $ \x y -> [sCase| tuple (x, y) of
+                         ([],   _   ) -> []
+                         (_,    []  ) -> []
+                         (a:as, b:bs) -> tuple (a, b) .: def as bs
+                     |]
 
 -- | A class of function that we can zip-with. In SBV, we make a distinction between closures and regular
 -- functions, and we instantiate this class appropriately so it can handle both cases.
 class (SymVal a, SymVal b, SymVal c) => SZipWith func a b c | func -> a b c where
   -- | @`zipWith` f xs ys@ zips the lists to give a list of pairs, applying the function to each pair of elements.
-  -- The length of the final list is the minumum of the lengths of the given lists.
+  -- The length of the final list is the minimum of the lengths of the given lists.
    --
    -- >>> zipWith ((+) @SInteger) ([sEnum|1..10::SInteger|]) ([sEnum|11..20::SInteger|])
    -- [12,14,16,18,20,22,24,26,28,30] :: [SInteger]
@@ -787,11 +800,12 @@
     = literal concResult
     | True
     = sbvZipWith $ tuple (xs, ys)
-    where sbvZipWith = smtHOFunction "sbv.zipWith" (uncurry f . untuple)
-                     $ \asbs -> let (as, bs) = untuple asbs
-                                in ite (null as .|| null bs)
-                                       []
-                                       (f (head as) (head bs) .: sbvZipWith (tuple (tail as, tail bs)))
+    where sbvZipWith = smtHOFunction "sbv.zipWith" (uncurry f)
+                     $ \asbs -> [sCase| asbs of
+                                   ([],   _   ) -> []
+                                   (_,    []  ) -> []
+                                   (a:as, b:bs) -> f a b .: sbvZipWith (tuple (as, bs))
+                                |]
 
 -- | Zipping with closures.
 instance (SymVal env, SymVal a, SymVal b, SymVal c) => SZipWith (Closure (SBV env) (SBV a -> SBV b -> SBV c)) a b c where
@@ -801,10 +815,11 @@
     | True
     = sbvZipWith $ tuple (closureEnv, xs, ys)
     where sbvZipWith = smtHOFunction "sbv.closureZipWith" closureFun
-                     $ \envasbs -> let (cEnv, as, bs) = untuple envasbs
-                                   in ite (null as .|| null bs)
-                                          []
-                                          (closureFun cEnv (head as) (head bs) .: sbvZipWith (tuple (cEnv, tail as, tail bs)))
+                     $ \envasbs -> [sCase| envasbs of
+                                      (_,    [],   _   ) -> []
+                                      (_,    _,    []  ) -> []
+                                      (cEnv, a:as, b:bs) -> closureFun cEnv a b .: sbvZipWith (tuple (cEnv, as, bs))
+                                   |]
 
 -- | Concatenate list of lists.
 --
@@ -863,7 +878,11 @@
  = literal (genericReplicate c' e')
  | True
  = def c e
- where def = smtFunction "sbv.replicate" $ \count elt -> ite (count .<= 0) [] (elt .: def (count - 1) elt)
+ where def = smtFunction "sbv.replicate"
+           $ \count elt -> [sCase| count of
+                               _ | count .<= 0 -> []
+                               _               -> elt .: def (count - 1) elt
+                           |]
 
 -- | inits of a list.
 --
@@ -877,7 +896,11 @@
  = literal (L.inits xs')
  | True
  = def xs
- where def = smtFunction "sbv.inits" $ \l -> ite (null l) [[]] (def (init l) ++ [l])
+ where def = smtFunction "sbv.inits"
+           $ \l -> [sCase| l of
+                      []    -> [[]]
+                      _ : _ -> def (init l) ++ [l]
+                   |]
 
 -- | tails of a list.
 --
@@ -891,8 +914,42 @@
  = literal (L.tails xs')
  | True
  = def xs
- where def = smtFunction "sbv.tails" $ \l -> ite (null l) [[]] (l .: def (tail l))
+ where def = smtFunction "sbv.tails"
+           $ \l -> [sCase| l of
+                      []      -> [[]]
+                      _ : tl  -> l .: def tl
+                   |]
 
+-- | Minimum of a list that has symbolic-ordering. If the list is empty, then
+-- the result is underspecified, i.e., it is an arbitrary element of the element type.
+--
+-- >>> minimum ([1,2,3] :: SList Integer)
+-- 1 :: SInteger
+-- >>> sat $ 512 .== minimum (literal [] :: SList Integer)
+-- Satisfiable. Model:
+--   SList.minimum @Integer = 512 :: Integer
+minimum :: forall a. (SymVal a, Ord a, OrdSymbolic (SBV a)) => SList a -> SBV a
+minimum xs
+  | Just lxs@(_:_) <- unliteral xs
+  = literal (P.minimum lxs)
+  | True
+  = foldr (smin @(SBV a)) (some "SList.minimum" (const sTrue)) xs
+
+-- | Maximum of a list that has symbolic-ordering. If the list is empty, then
+-- the result is underspecified, i.e., it is an arbitrary element of the element type.
+--
+-- >>> maximum ([1,2,3] :: SList Integer)
+-- 3 :: SInteger
+-- >>> sat $ 512 .== maximum (literal [] :: SList Integer)
+-- Satisfiable. Model:
+--   SList.maximum @Integer = 512 :: Integer
+maximum :: forall a. (SymVal a, Ord a, OrdSymbolic (SBV a)) => SList a -> SBV a
+maximum xs
+  | Just lxs@(_:_) <- unliteral xs
+  = literal (P.maximum lxs)
+  | True
+  = foldr (smax @(SBV a)) (some "SList.maximum" (const sTrue)) xs
+
 -- | Difference.
 --
 -- >>> [1, 2] \\ [3, 4 :: SInteger]
@@ -905,11 +962,12 @@
  = literal (xs' L.\\ ys')
  | True
  = def xs ys
- where def = smtFunction "sbv.diff" $ \x y -> ite (null x)
-                                                  []
-                                                  (let (h, t) = uncons x
-                                                       r      = def t y
-                                                   in ite (h `elem` y) r (h .: r))
+ where def = smtFunction "sbv.diff"
+           $ \x y -> [sCase| x of
+                        []    -> []
+                        h : t -> let r = def t y
+                                 in ite (h `elem` y) r (h .: r)
+                     |]
 infix 5 \\  -- CPP: do not eat the final newline
 
 -- | A class of filtering-like functions. In SBV, we make a distinction between closures and regular functions,
@@ -975,7 +1033,7 @@
   -- [2,3,4,5,6,7,8,9,10] :: [SInteger]
   dropWhile :: func -> SList a -> SList a
 
-  -- | Handle the concrete case of take-while. Used internally only.
+  -- | Handle the concrete case of drop-while. Used internally only.
   concreteDropWhile :: func -> (SBV a -> SBool) -> SList a -> Maybe [a]
   concreteDropWhile _ f sas
    | Just as <- unliteral sas
@@ -993,11 +1051,12 @@
     = literal concResult
     | True
     = sbvFilter l
-    where sbvFilter = smtHOFunction "sbv.filter" f $ \xs -> ite (null xs)
-                                                                []
-                                                                (let (h, t) = uncons xs
-                                                                     r      = sbvFilter t
-                                                                 in ite (f h) (h .: r) r)
+    where sbvFilter = smtHOFunction "sbv.filter" f
+                    $ \xs -> [sCase| xs of
+                                []    -> []
+                                h : t -> let r = sbvFilter t
+                                         in ite (f h) (h .: r) r
+                             |]
 
   -- | @partition f xs@ splits the list into two and returns those that satisfy the predicate in the
   -- first element, and those that don't in the second.
@@ -1006,13 +1065,13 @@
     = literal concResult
     | True
     = sbvPartition l
-    where sbvPartition = smtHOFunction "sbv.partition" f $ \xs -> ite (null xs)
-                                                                      (tuple ([], []))
-                                                                      (let (h, t)   = uncons xs
-                                                                           (as, bs) = untuple $ sbvPartition t
-                                                                       in ite (f h)
-                                                                              (tuple (h .: as, bs))
-                                                                              (tuple (as, h .: bs)))
+    where sbvPartition = smtHOFunction "sbv.partition" f
+                       $ \xs -> [sCase| xs of
+                                   []    -> tuple ([], [])
+                                   h : t -> case sbvPartition t of
+                                              (as, bs) | f h  -> tuple (h .: as, bs)
+                                                       | True -> tuple (as, h .: bs)
+                                |]
 
   -- | @takeWhile f xs@ takes the prefix of @xs@ that satisfy the predicate.
   takeWhile f l
@@ -1020,10 +1079,12 @@
     = literal concResult
     | True
     = sbvTakeWhile l
-    where sbvTakeWhile = smtHOFunction "sbv.takeWhile" f $ \xs -> ite (null xs)
-                                                                      []
-                                                                      (let (h, t) = uncons xs
-                                                                       in ite (f h) (h .: sbvTakeWhile t) [])
+    where sbvTakeWhile = smtHOFunction "sbv.takeWhile" f
+                       $ \xs -> [sCase| xs of
+                                   []           -> []
+                                   h : t | f h  -> h .: sbvTakeWhile t
+                                         | True -> []
+                                |]
 
   -- | @dropWhile f xs@ drops the prefix of @xs@ that satisfy the predicate.
   dropWhile f l
@@ -1031,10 +1092,12 @@
     = literal concResult
     | True
     = sbvDropWhile l
-    where sbvDropWhile = smtHOFunction "sbv.dropWhile" f $ \xs -> ite (null xs)
-                                                                      []
-                                                                      (let (h, t) = uncons xs
-                                                                       in ite (f h) (sbvDropWhile t) xs)
+    where sbvDropWhile = smtHOFunction "sbv.dropWhile" f
+                       $ \xs -> [sCase| xs of
+                                   []           -> []
+                                   h : t | f h  -> sbvDropWhile t
+                                         | True -> xs
+                                |]
 
 -- | Filtering with closures.
 instance (SymVal env, SymVal a) => SFilter (Closure (SBV env) (SBV a -> SBool)) a where
@@ -1044,10 +1107,11 @@
     | True
     = sbvFilter (tuple (closureEnv, l))
     where sbvFilter = smtHOFunction "sbv.closureFilter" closureFun
-                    $ \envxs -> let (cEnv, xs) = untuple envxs
-                                    (h, t)     = uncons xs
-                                    r          = sbvFilter (tuple (cEnv, t))
-                                in ite (closureFun cEnv h) (h .: r) r
+                    $ \envxs -> [sCase| envxs of
+                                   (_,    [])    -> []
+                                   (cEnv, h : t) -> let r = sbvFilter (tuple (cEnv, t))
+                                                    in ite (closureFun cEnv h) (h .: r) r
+                                |]
 
   partition cls@Closure{closureEnv, closureFun} l
     | Just concResult <- concretePartition cls (closureFun closureEnv) l
@@ -1055,12 +1119,12 @@
     | True
     = sbvPartition (tuple (closureEnv, l))
     where sbvPartition = smtHOFunction "sbv.closurePartition" closureFun
-                       $ \envxs -> let (cEnv, xs) = untuple envxs
-                                       (h,    t)  = uncons xs
-                                       (as,   bs) = untuple $ sbvPartition (tuple (cEnv, t))
-                                   in ite (closureFun cEnv h)
-                                          (tuple (h .: as, bs))
-                                          (tuple (as, h .: bs))
+                       $ \envxs -> [sCase| envxs of
+                                      (_, [])       -> tuple ([], [])
+                                      (cEnv, h : t) -> case sbvPartition (tuple (cEnv, t)) of
+                                                          (as, bs) | closureFun cEnv h -> tuple (h .: as, bs)
+                                                                   | True              -> tuple (as, h .: bs)
+                                   |]
 
   takeWhile cls@Closure{closureEnv, closureFun} l
     | Just concResult <- concreteTakeWhile cls (closureFun closureEnv) l
@@ -1068,9 +1132,11 @@
     | True
     = sbvTakeWhile (tuple (closureEnv, l))
     where sbvTakeWhile = smtHOFunction "sbv.closureTakeWhile" closureFun
-                       $ \envxs -> let (cEnv, xs) = untuple envxs
-                                       (h, t)     = uncons xs
-                                in ite (closureFun cEnv h) (h .: sbvTakeWhile (tuple (cEnv, t))) []
+                       $ \envxs -> [sCase| envxs of
+                                      (_,    [])                        -> []
+                                      (cEnv, h : t) | closureFun cEnv h -> h .: sbvTakeWhile (tuple (cEnv, t))
+                                                    | True              -> []
+                                   |]
 
   dropWhile cls@Closure{closureEnv, closureFun} l
     | Just concResult <- concreteDropWhile cls (closureFun closureEnv) l
@@ -1078,9 +1144,11 @@
     | True
     = sbvDropWhile (tuple (closureEnv, l))
     where sbvDropWhile = smtHOFunction "sbv.closureDropWhile" closureFun
-                       $ \envxs -> let (cEnv, xs) = untuple envxs
-                                       (h, t)     = uncons xs
-                                in ite (closureFun cEnv h) (sbvDropWhile (tuple (cEnv, t))) xs
+                       $ \envxs -> [sCase| envxs of
+                                      (_,    [])                              -> []
+                                      (cEnv, lst@(h : t)) | closureFun cEnv h -> sbvDropWhile (tuple (cEnv, t))
+                                                          | True              -> lst
+                                   |]
 
 -- | @`sum` s@. Sum the given sequence.
 --
@@ -1132,6 +1200,16 @@
    -- | @`enumFromThenTo` m n@. Symbolic version of @[m, m' .. n]@
    enumFromThenTo :: SymVal a => SBV a -> SBV a -> SBV a -> SList a
 
+   -- | @`enumFromThenTo`@ with an optionally statically-known integer step. The sEnum quasiquoter
+   -- supplies @`Just` d@ for @[m, m' .. n]@ when @m'@ is @m@ shifted by a compile-time integer
+   -- constant (e.g. @[m, m-1 .. n]@ gives @-1@); otherwise it supplies `Nothing`. Instances with
+   -- exact arithmetic (integers, reals) use the hint to constant-fold the step, so the @step == 0@
+   -- infinite-list branch (and its productive helper) drops out; every other instance ignores the
+   -- hint and falls back to 'enumFromThenTo', preserving its exact semantics. Not meant to be called
+   -- directly; the default is correct for any instance.
+   enumFromThenToH :: SymVal a => SBV a -> SBV a -> SBV a -> Maybe Integer -> SList a
+   enumFromThenToH from thn to _ = enumFromThenTo from thn to
+
 -- | 'EnumSymbolic' instance for words
 instance {-# OVERLAPPABLE #-} (SymVal a, Bounded a, Integral a, Num a, Num (SBV a)) => EnumSymbolic a where
   succ = smtFunction "EnumSymbolic.succ" (\x -> ite (x .== maxBound) (some "EnumSymbolic.succ.maxBound" (const sTrue)) (x+1))
@@ -1164,19 +1242,34 @@
    toEnum   = id
    fromEnum = id
 
-   enumFrom   n = enumFromThen   n (n+1)
-   enumFromTo n = enumFromThenTo n (n+1)
+   enumFrom   n   = enumFromThen          n (n+1)
+   enumFromTo n m = enumFromThenToInteger n m 1
 
    enumFromThen x y = go x (y-x)
-     where go = smtFunction "EnumSymbolic.Integer.enumFromThen" $ \start delta -> start .: go (start+delta) delta
+     where go = smtProductiveFunction "EnumSymbolic.Integer.enumFromThen" $ \start delta -> start .: go (start+delta) delta
 
-   enumFromThenTo x y z = ite (delta .>= 0) (up x delta z) (down x delta z)
-     where delta = y - x
+   enumFromThenTo x y z = enumFromThenToInteger x z (y - x)
 
-           up, down :: SInteger -> SInteger -> SInteger -> SList Integer
-           up    = smtFunction "EnumSymbolic.Integer.enumFromThenTo.up"   $ \start d end -> ite (start .> end) [] (start .: up   (start + d) d end)
-           down  = smtFunction "EnumSymbolic.Integer.enumFromThenTo.down" $ \start d end -> ite (start .< end) [] (start .: down (start + d) d end)
+   enumFromThenToH x y z mStep = enumFromThenToInteger x z (maybe (y - x) fromIntegral mStep)
 
+-- When the step is 0 (i.e., y == x), Haskell produces an infinite list of x's
+-- if x <= z, and the empty list otherwise. We mirror that here.
+enumFromThenToInteger :: SInteger -> SInteger -> SInteger -> SList Integer
+enumFromThenToInteger x z delta = ite (delta .== 0)
+                                      (ite (x .<= z) (enumFromThen x x) [])
+                                $ ite (delta .>  0) (up x delta z) (down x delta z)
+  where -- The d==0 case is handled: 'up'/'down' are only *called* with d>0/d<0 (the d==0 case
+        -- is routed to the infinite-list branch above), and the guard's @d .<= 0@/@d .>= 0@ test
+        -- puts @d>0@/@d<0@ into the reaching condition, so measure verification never sees d==0.
+        -- (The integer measure does not divide by d, so there's no zero-denominator to worry about.)
+        up, down :: SInteger -> SInteger -> SInteger -> SList Integer
+        up    = smtFunctionWithMeasure "EnumSymbolic.Integer.enumFromThenTo.up"
+                                       (\start _d end -> 0 `smax` (end - start + 1), [])
+              $ \start d end -> ite (start .> end .|| d .<= 0) [] (start .: up   (start + d) d end)
+        down  = smtFunctionWithMeasure "EnumSymbolic.Integer.enumFromThenTo.down"
+                                       (\start _d end -> 0 `smax` (start - end + 1), [])
+              $ \start d end -> ite (start .< end .|| d .>= 0) [] (start .: down (start + d) d end)
+
 -- | 'EnumSymbolic instance for 'Float'. Note that the termination requirement as defined by the Haskell standard for floats state:
 --      > For Float and Double, the semantics of the enumFrom family is given by the rules for Int above,
 --      > except that the list terminates when the elements become greater than @e3 + i/2@ for positive increment @i@,
@@ -1188,21 +1281,39 @@
    toEnum   = sFromIntegral
    fromEnum = fromSFloat sRTZ
 
-   enumFrom   n = enumFromThen   n (n+1)
-   enumFromTo n = enumFromThenTo n (n+1)
+   enumFrom   n   = enumFromThen        n (n+1)
+   enumFromTo n m = enumFromThenToFloat n m 1
 
    enumFromThen x y = go 0 x (y-x)
-     where go = smtFunction "EnumSymbolic.Float.enumFromThen" $ \k n d -> (n + k * d) .: go (k+1) n d
+     where go = smtProductiveFunction "EnumSymbolic.Float.enumFromThen" $ \k n d -> (n + k * d) .: go (k+1) n d
 
-   enumFromThenTo x y zIn = ite (delta .>= 0) (up 0 x delta z) (down 0 x delta z)
-     where delta, z :: SFloat
-           delta = y - x
-           z     = zIn + delta / 2
+   enumFromThenTo x y zIn = enumFromThenToFloat x zIn (y - x)
 
-           up, down :: SFloat -> SFloat -> SFloat -> SFloat -> SList Float
-           up    = smtFunction "EnumSymbolic.Float.enumFromThenTo.up"   $ \k n d end -> let c = n + k * d in ite (c .> end) [] (c .: up   (k+1) n d end)
-           down  = smtFunction "EnumSymbolic.Float.enumFromThenTo.down" $ \k n d end -> let c = n + k * d in ite (c .< end) [] (c .: down (k+1) n d end)
+-- When the step is 0 (i.e., y == x), Haskell produces an infinite list of x's
+-- if x <= z, and the empty list otherwise. We mirror that here.
+enumFromThenToFloat :: SFloat -> SFloat -> SFloat -> SList Float
+enumFromThenToFloat x zIn delta = ite (delta .== 0)
+                                      (ite (x .<= z) (enumFromThen x x) [])
+                                $ ite (delta .>  0) (up 0 x delta z) (down 0 x delta z)
+  where z :: SFloat
+        z = zIn + delta / 2
 
+        -- Unlike the Integer/AlgReal instances, these are NOT given a termination measure:
+        -- floating-point enumeration is genuinely partial. The step @k * d@ can saturate (once
+        -- @k * d@ falls below the ULP of @n@, or once the float @k@ itself stops incrementing),
+        -- so for some inputs @n + k * d@ never exceeds @end@ and the recursion does not terminate
+        -- -- exactly as Haskell's own float enumeration diverges in those cases. A termination
+        -- measure would therefore be unsound: no measure can certify termination of a function
+        -- that does not always terminate. Instead we mark these productive -- each recursive call
+        -- is guarded by a cons, so the definition is well-formed corecursion (finite when the
+        -- enumeration terminates, infinite when it saturates). The d==0 case never reaches here:
+        -- it is routed to the infinite-list branch above.
+        up, down :: SFloat -> SFloat -> SFloat -> SFloat -> SList Float
+        up   = smtProductiveFunction "EnumSymbolic.Float.enumFromThenTo.up"
+             $ \k n d end -> let c = n + k * d in ite (c .> end) [] (c .: up   (k+1) n d end)
+        down = smtProductiveFunction "EnumSymbolic.Float.enumFromThenTo.down"
+             $ \k n d end -> let c = n + k * d in ite (c .< end) [] (c .: down (k+1) n d end)
+
 -- | 'EnumSymbolic instance for 'Double'
 instance {-# OVERLAPPING #-} EnumSymbolic Double where
    succ x = x + 1
@@ -1211,21 +1322,33 @@
    toEnum   = sFromIntegral
    fromEnum = fromSDouble sRTZ
 
-   enumFrom   n = enumFromThen   n (n+1)
-   enumFromTo n = enumFromThenTo n (n+1)
+   enumFrom   n   = enumFromThen         n (n+1)
+   enumFromTo n m = enumFromThenToDouble n m 1
 
    enumFromThen x y = go 0 x (y-x)
-     where go = smtFunction "EnumSymbolic.Double.enumFromThen" $ \k n d -> (n + k * d) .: go (k+1) n d
+     where go = smtProductiveFunction "EnumSymbolic.Double.enumFromThen" $ \k n d -> (n + k * d) .: go (k+1) n d
 
-   enumFromThenTo x y zIn = ite (delta .>= 0) (up 0 x delta z) (down 0 x delta z)
-     where delta, z :: SDouble
-           delta = y - x
-           z     = zIn + delta / 2
+   enumFromThenTo x y zIn = enumFromThenToDouble x zIn (y - x)
 
-           up, down :: SDouble -> SDouble -> SDouble -> SDouble -> SList Double
-           up    = smtFunction "EnumSymbolic.Double.enumFromThenTo.up"   $ \k n d end -> let c = n + k * d in ite (c .> end) [] (c .: up   (k+1) n d end)
-           down  = smtFunction "EnumSymbolic.Double.enumFromThenTo.down" $ \k n d end -> let c = n + k * d in ite (c .< end) [] (c .: down (k+1) n d end)
+-- When the step is 0 (i.e., y == x), Haskell produces an infinite list of x's
+-- if x <= z, and the empty list otherwise. We mirror that here.
+enumFromThenToDouble :: SDouble -> SDouble -> SDouble -> SList Double
+enumFromThenToDouble x zIn delta = ite (delta .== 0)
+                                       (ite (x .<= z) (enumFromThen x x) [])
+                                 $ ite (delta .>  0) (up 0 x delta z) (down 0 x delta z)
+  where z :: SDouble
+        z = zIn + delta / 2
 
+        -- See the Float instance for why these are productive rather than measured:
+        -- floating-point enumeration is genuinely partial (the @k * d@ step can saturate), so a
+        -- termination measure would be unsound. Each recursive call is guarded by a cons, so the
+        -- definition is well-formed corecursion. The d==0 case is routed to the branch above.
+        up, down :: SDouble -> SDouble -> SDouble -> SDouble -> SList Double
+        up   = smtProductiveFunction "EnumSymbolic.Double.enumFromThenTo.up"
+             $ \k n d end -> let c = n + k * d in ite (c .> end) [] (c .: up   (k+1) n d end)
+        down = smtProductiveFunction "EnumSymbolic.Double.enumFromThenTo.down"
+             $ \k n d end -> let c = n + k * d in ite (c .< end) [] (c .: down (k+1) n d end)
+
 -- | 'EnumSymbolic instance for arbitrary floats
 instance {-# OVERLAPPING #-} ValidFloat eb sb => EnumSymbolic (FloatingPoint eb sb) where
    succ x = x + 1
@@ -1234,21 +1357,33 @@
    toEnum   = sFromIntegral
    fromEnum = fromSFloatingPoint sRTZ
 
-   enumFrom   n = enumFromThen   n (n+1)
-   enumFromTo n = enumFromThenTo n (n+1)
+   enumFrom   n   = enumFromThen                 n (n+1)
+   enumFromTo n m = enumFromThenToFloatingPoint  n m 1
 
    enumFromThen x y = go 0 x (y-x)
-     where go = smtFunction "EnumSymbolic.FloatingPoint.enumFromThen" $ \k n d -> (n + k * d) .: go (k+1) n d
+     where go = smtProductiveFunction "EnumSymbolic.FloatingPoint.enumFromThen" $ \k n d -> (n + k * d) .: go (k+1) n d
 
-   enumFromThenTo x y zIn = ite (delta .>= 0) (up 0 x delta z) (down 0 x delta z)
-     where delta, z :: SFloatingPoint eb sb
-           delta = y - x
-           z     = zIn + delta / 2
+   enumFromThenTo x y zIn = enumFromThenToFloatingPoint x zIn (y - x)
 
-           up, down :: SFloatingPoint eb sb -> SFloatingPoint eb sb -> SFloatingPoint eb sb -> SFloatingPoint eb sb -> SList (FloatingPoint eb sb)
-           up    = smtFunction "EnumSymbolic.FloatingPoint.enumFromThenTo.up"   $ \k n d end -> let c = n + k * d in ite (c .> end) [] (c .: up   (k+1) n d end)
-           down  = smtFunction "EnumSymbolic.FloatingPoint.enumFromThenTo.down" $ \k n d end -> let c = n + k * d in ite (c .< end) [] (c .: down (k+1) n d end)
+-- When the step is 0 (i.e., y == x), Haskell produces an infinite list of x's
+-- if x <= z, and the empty list otherwise. We mirror that here.
+enumFromThenToFloatingPoint :: forall eb sb. ValidFloat eb sb => SFloatingPoint eb sb -> SFloatingPoint eb sb -> SFloatingPoint eb sb -> SList (FloatingPoint eb sb)
+enumFromThenToFloatingPoint x zIn delta = ite (delta .== 0)
+                                              (ite (x .<= z) (enumFromThen x x) [])
+                                        $ ite (delta .>  0) (up 0 x delta z) (down 0 x delta z)
+  where z :: SFloatingPoint eb sb
+        z = zIn + delta / 2
 
+        -- See the Float instance for why these are productive rather than measured:
+        -- floating-point enumeration is genuinely partial (the @k * d@ step can saturate), so a
+        -- termination measure would be unsound. Each recursive call is guarded by a cons, so the
+        -- definition is well-formed corecursion. The d==0 case is routed to the branch above.
+        up, down :: SFloatingPoint eb sb -> SFloatingPoint eb sb -> SFloatingPoint eb sb -> SFloatingPoint eb sb -> SList (FloatingPoint eb sb)
+        up   = smtProductiveFunction "EnumSymbolic.FloatingPoint.enumFromThenTo.up"
+             $ \k n d end -> let c = n + k * d in ite (c .> end) [] (c .: up   (k+1) n d end)
+        down = smtProductiveFunction "EnumSymbolic.FloatingPoint.enumFromThenTo.down"
+             $ \k n d end -> let c = n + k * d in ite (c .< end) [] (c .: down (k+1) n d end)
+
 -- | 'EnumSymbolic instance for arbitrary AlgReal. We don't have to use the multiplicative trick here
 -- since alg-reals are precise. But, following rational in Haskell, we do use the stopping point of @z + delta / 2@.
 instance {-# OVERLAPPING #-} EnumSymbolic AlgReal where
@@ -1258,34 +1393,58 @@
    toEnum   = sFromIntegral
    fromEnum = sRealToSIntegerTruncate
 
-   enumFrom   n = enumFromThen   n (n+1)
-   enumFromTo n = enumFromThenTo n (n+1)
+   enumFrom   n   = enumFromThen          n (n+1)
+   enumFromTo n m = enumFromThenToAlgReal n m 1
 
    enumFromThen x y = go x (y-x)
-     where go = smtFunction "EnumSymbolic.AlgReal.enumFromThen" $ \start delta -> start .: go (start+delta) delta
+     where go = smtProductiveFunction "EnumSymbolic.AlgReal.enumFromThen" $ \start delta -> start .: go (start+delta) delta
 
-   enumFromThenTo x y zIn = ite (delta .>= 0) (up x delta z) (down x delta z)
-     where delta, z :: SReal
-           delta = y - x
-           z     = zIn + delta / 2
+   enumFromThenTo x y zIn = enumFromThenToAlgReal x zIn (y - x)
 
-           up, down :: SReal -> SReal -> SReal -> SList AlgReal
-           up    = smtFunction "EnumSymbolic.AlgReal.enumFromThenTo.up"   $ \start d end -> ite (start .> end) [] (start .: up   (start + d) d end)
-           down  = smtFunction "EnumSymbolic.AlgReal.enumFromThenTo.down" $ \start d end -> ite (start .< end) [] (start .: down (start + d) d end)
+   enumFromThenToH x y zIn mStep = enumFromThenToAlgReal x zIn (maybe (y - x) fromIntegral mStep)
 
+-- When the step is 0 (i.e., y == x), Haskell produces an infinite list of x's
+-- if x <= z, and the empty list otherwise. We mirror that here.
+enumFromThenToAlgReal :: SReal -> SReal -> SReal -> SList AlgReal
+enumFromThenToAlgReal x zIn delta = ite (delta .== 0)
+                                        (ite (x .<= z) (enumFromThen x x) [])
+                                  $ ite (delta .>  0) (up x delta z) (down x delta z)
+  where z :: SReal
+        z = zIn + delta / 2
+
+        -- The measure is the number of remaining recursive steps, which is an INTEGER:
+        -- @floor ((end - start) / d) + 1@ (clamped at 0). A real-valued measure would be
+        -- unsound here, since the reals are not well-ordered (an infinite descending chain
+        -- like 1, 1/2, 1/4, ... never reaches a minimum). 'sRealToSIntegerFloor' is @floor@, and
+        -- @(end - start) / d@ is non-negative in both the up (d>0) and down (d<0) regimes, so
+        -- the same expression serves both.
+        --
+        -- The d==0 case is handled: 'up'/'down' are only *called* with d>0/d<0 (the d==0 case is
+        -- routed to the infinite-list branch above), and for measure *verification* the guard's
+        -- @d .<= 0@/@d .>= 0@ test puts @d>0@/@d<0@ into the reaching condition, so the decrease
+        -- obligation never sees d==0; the @0 `smax`@ keeps non-negativity vacuously true even for
+        -- the unreachable zero-denominator value of @(end - start) / d@.
+        up, down :: SReal -> SReal -> SReal -> SList AlgReal
+        up   = smtFunctionWithMeasure "EnumSymbolic.AlgReal.enumFromThenTo.up"   (\start d end -> 0 `smax` (sRealToSIntegerFloor ((end - start) / d) + 1), [])
+             $ \start d end -> ite (start .> end .|| d .<= 0) [] (start .: up   (start + d) d end)
+        down = smtFunctionWithMeasure "EnumSymbolic.AlgReal.enumFromThenTo.down" (\start d end -> 0 `smax` (sRealToSIntegerFloor ((end - start) / d) + 1), [])
+             $ \start d end -> ite (start .< end .|| d .>= 0) [] (start .: down (start + d) d end)
+
 -- | Lookup. If we can't find, then the result is unspecified.
 --
 -- >>> lookup (4 :: SInteger) (literal [(5, 12), (4, 3), (2, 6 :: Integer)])
 -- 3 :: SInteger
 -- >>> prove  $ \(x :: SInteger) -> x .== lookup 9 (literal [(5, 12), (4, 3), (2, 6 :: Integer)])
 -- Falsifiable. Counter-example:
---   Data.SBV.List.lookup_notFound @Integer = 0 :: Integer
---   s0                                     = 1 :: Integer
+--   sbv.lookup_notFound @Integer = 0 :: Integer
+--   s0                           = 1 :: Integer
 lookup :: (SymVal k, SymVal v) => SBV k -> SList (k, v) -> SBV v
-lookup = smtFunction "Data.SBV.List.lookup" $ \k lst -> ite (null lst)
-                                                            (some "Data.SBV.List.lookup_notFound" (const sTrue))
-                                                            (let (k', v) = untuple (head lst)
-                                                             in ite (k .== k') v (lookup k (tail lst)))
+lookup = smtFunction "sbv.lookup"
+       $ \k lst -> [sCase| lst of
+                       []                        -> some "sbv.lookup_notFound" (const sTrue)
+                       (k', v) : rest | k .== k' -> v
+                                      | True     -> lookup k rest
+                   |]
 
 -- | @`strToNat` s@. Retrieve integer encoded by string @s@ (ground rewriting only).
 -- Note that by definition this function only works when @s@ only contains digits,
@@ -1385,4 +1544,5 @@
         r st = do sva <- sbvToSV st a
                   newExpr st k (SBVApp (StrOp w) [sva])
 
-{- HLint ignore implode "Use :" -}
+{- HLint ignore implode   "Use :" -}
+{- HLint ignore replicate "Use const" -}
diff --git a/Data/SBV/Maybe.hs b/Data/SBV/Maybe.hs
--- a/Data/SBV/Maybe.hs
+++ b/Data/SBV/Maybe.hs
@@ -13,30 +13,37 @@
 {-# LANGUAGE CPP                 #-}
 {-# LANGUAGE FlexibleContexts    #-}
 {-# LANGUAGE FlexibleInstances   #-}
-{-# LANGUAGE Rank2Types          #-}
+{-# LANGUAGE QuasiQuotes         #-}
 {-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TemplateHaskell     #-}
 {-# LANGUAGE TypeApplications    #-}
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
 module Data.SBV.Maybe (
   -- * Constructing optional values
-    sJust, sNothing, liftMaybe
+    sJust, sNothing, liftMaybe, SMaybe, sMaybe, sMaybe_, sMaybes
+
   -- * Destructing optionals
   , maybe
+
   -- * Mapping functions
   , map, map2
+
   -- * Scrutinizing the branches of an option
   , isNothing, isJust, fromMaybe, fromJust
+
+  -- * Case analysis (for sCase quasi-quoter)
+  , sCaseMaybe, getJust_1
   ) where
 
 import           Prelude hiding (maybe, map)
 import qualified Prelude
 
-import Data.Proxy (Proxy(Proxy))
-
+import Data.SBV.Client
 import Data.SBV.Core.Data
-import Data.SBV.Core.Model (ite)
+import Data.SBV.Core.Model (ite, OrdSymbolic(..))
+import Data.SBV.SCase      (sCase)
 
 #ifdef DOCTEST
 -- $setup
@@ -44,56 +51,43 @@
 -- >>> import Data.SBV
 #endif
 
--- | The symbolic 'Nothing'.
+-- | Make 'Maybe' symbolic.
 --
 -- >>> sNothing :: SMaybe Integer
--- Nothing :: SMaybe Integer
-sNothing :: forall a. SymVal a => SMaybe a
-sNothing = SBV $ SVal k $ Left $ CV k $ CMaybe Nothing
-  where k = kindOf (Proxy @(Maybe a))
-
--- | Check if the symbolic value is nothing.
---
+-- Nothing :: Maybe Integer
 -- >>> isNothing (sNothing :: SMaybe Integer)
 -- True
 -- >>> isNothing (sJust (literal "nope"))
 -- False
-isNothing :: SymVal a => SMaybe a -> SBool
-isNothing = maybe sTrue (const sFalse)
-
--- | Construct an @SMaybe a@ from an @SBV a@.
---
 -- >>> sJust (3 :: SInteger)
--- Just 3 :: SMaybe Integer
-sJust :: forall a. SymVal a => SBV a -> SMaybe a
-sJust sa
-  | Just a <- unliteral sa
-  = literal (Just a)
-  | True
-  = SBV $ SVal kMaybe $ Right $ cache res
-  where ka     = kindOf (Proxy @a)
-        kMaybe = KMaybe ka
-
-        res st = do asv <- sbvToSV st sa
-                    newExpr st kMaybe $ SBVApp (MaybeConstructor ka True) [asv]
-
--- | Check if the symbolic value is not nothing.
---
+-- Just 3 :: Maybe Integer
 -- >>> isJust (sNothing :: SMaybe Integer)
 -- False
 -- >>> isJust (sJust (literal "yep"))
 -- True
 -- >>> prove $ \x -> isJust (sJust (x :: SInteger))
 -- Q.E.D.
-isJust :: SymVal a => SMaybe a -> SBool
-isJust = maybe sFalse (const sTrue)
+mkSymbolic [''Maybe]
 
+-- | Declare a symbolic maybe.
+sMaybe :: SymVal a => String -> Symbolic (SMaybe a)
+sMaybe = free
+
+-- | Declare a symbolic maybe, unnamed.
+sMaybe_ :: SymVal a => Symbolic (SMaybe a)
+sMaybe_ = free_
+
+-- | Declare a list of symbolic maybes.
+sMaybes :: SymVal a => [String] -> Symbolic [SMaybe a]
+sMaybes = symbolics
+
 -- | Return the value of an optional value. The default is returned if Nothing. Compare to 'fromJust'.
 --
 -- >>> fromMaybe 2 (sNothing :: SMaybe Integer)
 -- 2 :: SInteger
--- >>> fromMaybe 2 (sJust 5 :: SMaybe Integer)
--- 5 :: SInteger
+-- >>> sat $ \x -> fromMaybe 2 (sJust 5 :: SMaybe Integer) .== x
+-- Satisfiable. Model:
+--   s0 = 5 :: Integer
 -- >>> prove $ \x -> fromMaybe x (sNothing :: SMaybe Integer) .== x
 -- Q.E.D.
 -- >>> prove $ \x -> fromMaybe (x+1) (sJust x :: SMaybe Integer) .== x
@@ -104,8 +98,9 @@
 -- | Return the value of an optional value. The behavior is undefined if
 -- passed Nothing, i.e., it can return any value. Compare to 'fromMaybe'.
 --
--- >>> fromJust (sJust (literal 'a'))
--- 'a' :: SChar
+-- >>> sat $ \x -> fromJust (sJust (literal 'a')) .== x
+-- Satisfiable. Model:
+--   s0 = 'a' :: Char
 -- >>> prove $ \x -> fromJust (sJust x) .== (x :: SChar)
 -- Q.E.D.
 -- >>> sat $ \x -> x .== (fromJust sNothing :: SChar)
@@ -116,21 +111,14 @@
 -- is unspecified, thus the SMT solver picks whatever satisfies the
 -- constraints, if there is one.
 fromJust :: forall a. SymVal a => SMaybe a -> SBV a
-fromJust ma
-  | Just (Just x) <- unliteral ma
-  = literal x
-  | True
-  = SBV $ SVal ka $ Right $ cache res
-  where ka     = kindOf (Proxy @a)
-        res st = do ms <- sbvToSV st ma
-                    newExpr st ka (SBVApp MaybeAccess [ms])
+fromJust = getJust_1
 
 -- | Construct an @SMaybe a@ from a @Maybe (SBV a)@.
 --
 -- >>> liftMaybe (Just (3 :: SInteger))
--- Just 3 :: SMaybe Integer
+-- Just 3 :: Maybe Integer
 -- >>> liftMaybe (Nothing :: Maybe SInteger)
--- Nothing :: SMaybe Integer
+-- Nothing :: Maybe Integer
 liftMaybe :: SymVal a => Maybe (SBV a) -> SMaybe a
 liftMaybe = Prelude.maybe (literal Nothing) sJust
 
@@ -158,10 +146,12 @@
 -- | Case analysis for symbolic 'Maybe's. If the value 'isNothing', return the
 -- default value; if it 'isJust', apply the function.
 --
--- >>> maybe 0 (`sMod` 2) (sJust (3 :: SInteger))
--- 1 :: SInteger
--- >>> maybe 0 (`sMod` 2) (sNothing :: SMaybe Integer)
--- 0 :: SInteger
+-- >>> sat $ \x -> x .== maybe 0 (`sMod` 2) (sJust (3 :: SInteger))
+-- Satisfiable. Model:
+--   s0 = 1 :: Integer
+-- >>> sat $ \x -> x .== maybe 0 (`sMod` 2) (sNothing :: SMaybe Integer)
+-- Satisfiable. Model:
+--   s0 = 0 :: Integer
 -- >>> let f = uninterpret "f" :: SInteger -> SBool
 -- >>> prove $ \x d -> maybe d f (sJust x) .== f x
 -- Q.E.D.
@@ -172,28 +162,10 @@
       -> (SBV a -> SBV b)
       -> SMaybe a
       -> SBV b
-maybe brNothing brJust ma
-  | Just (Just a) <- unliteral ma
-  = brJust (literal a)
-  | Just Nothing  <- unliteral ma
-  = brNothing
-  | True
-  = SBV $ SVal kb $ Right $ cache res
-  where ka = kindOf (Proxy @a)
-        kb = kindOf (Proxy @b)
-
-        res st = do mav <- sbvToSV st ma
-
-                    let justVal = SBV $ SVal ka $ Right $ cache $ \_ -> newExpr st ka $ SBVApp MaybeAccess [mav]
-
-                        justRes = brJust justVal
-
-                    br1 <- sbvToSV st brNothing
-                    br2 <- sbvToSV st justRes
-
-                    -- Do we have a value?
-                    noVal <- newExpr st KBool $ SBVApp (MaybeIs ka False) [mav]
-                    newExpr st kb $ SBVApp Ite [noVal, br1, br2]
+maybe brNothing brJust ma = [sCase| ma of
+                               Nothing -> brNothing
+                               Just x  -> brJust x
+                            |]
 
 -- | Custom 'Num' instance over 'SMaybe'
 instance (Ord a, SymVal a, Num a, Num (SBV a)) => Num (SBV (Maybe a)) where
@@ -203,3 +175,7 @@
   abs         = map  abs
   signum      = map  signum
   fromInteger = sJust . fromInteger
+
+-- | Custom 'OrdSymbolic' instance over 'SMaybe'.
+instance (OrdSymbolic (SBV a), SymVal a) => OrdSymbolic (SBV (Maybe a)) where
+  ma .< mb = maybe sFalse (\b -> maybe sTrue (.< b) ma) mb
diff --git a/Data/SBV/Provers/ABC.hs b/Data/SBV/Provers/ABC.hs
--- a/Data/SBV/Provers/ABC.hs
+++ b/Data/SBV/Provers/ABC.hs
@@ -29,25 +29,25 @@
          , options      = const ["-S", "%blast; &sweep -C 5000; &syn4; &cec -s -m -C 2000"]
          , engine       = standardEngine "SBV_ABC" "SBV_ABC_OPTIONS"
          , capabilities = SolverCapabilities {
-                                supportsQuantifiers        = False
-                              , supportsDefineFun          = True
-                              , supportsDistinct           = True
-                              , supportsBitVectors         = True
-                              , supportsUninterpretedSorts = False
-                              , supportsUnboundedInts      = False
-                              , supportsReals              = False
-                              , supportsApproxReals        = False
-                              , supportsDeltaSat           = Nothing
-                              , supportsIEEE754            = False
-                              , supportsSets               = False
-                              , supportsOptimization       = False
-                              , supportsPseudoBooleans     = False
-                              , supportsCustomQueries      = False
-                              , supportsGlobalDecls        = False
-                              , supportsDataTypes          = False
-                              , supportsLambdas            = False
-                              , supportsSpecialRels        = False
-                              , supportsDirectAccessors    = False
-                              , supportsFlattenedModels    = Nothing
+                                supportsQuantifiers     = False
+                              , supportsDefineFun       = True
+                              , supportsDistinct        = True
+                              , supportsBitVectors      = True
+                              , supportsADTs            = False
+                              , supportsUnboundedInts   = False
+                              , supportsReals           = False
+                              , supportsApproxReals     = False
+                              , supportsDeltaSat        = Nothing
+                              , supportsIEEE754         = False
+                              , supportsSets            = False
+                              , supportsOptimization    = False
+                              , supportsPseudoBooleans  = False
+                              , supportsCustomQueries   = False
+                              , supportsGlobalDecls     = False
+                              , supportsDataTypes       = False
+                              , supportsLambdas         = False
+                              , supportsSpecialRels     = False
+                              , supportsDirectTesters   = False
+                              , supportsFlattenedModels = Nothing
                               }
          }
diff --git a/Data/SBV/Provers/Bitwuzla.hs b/Data/SBV/Provers/Bitwuzla.hs
--- a/Data/SBV/Provers/Bitwuzla.hs
+++ b/Data/SBV/Provers/Bitwuzla.hs
@@ -27,25 +27,25 @@
          , options      = const ["--produce-models"]
          , engine       = standardEngine "SBV_BITWUZLA" "SBV_BITWUZLA_OPTIONS"
          , capabilities = SolverCapabilities {
-                                supportsQuantifiers        = False
-                              , supportsDefineFun          = True
-                              , supportsDistinct           = True
-                              , supportsBitVectors         = True
-                              , supportsUninterpretedSorts = True
-                              , supportsUnboundedInts      = False
-                              , supportsReals              = False
-                              , supportsApproxReals        = False
-                              , supportsDeltaSat           = Nothing
-                              , supportsIEEE754            = True
-                              , supportsSets               = False
-                              , supportsOptimization       = False
-                              , supportsPseudoBooleans     = False
-                              , supportsCustomQueries      = True
-                              , supportsGlobalDecls        = True
-                              , supportsDataTypes          = False
-                              , supportsLambdas            = False
-                              , supportsSpecialRels        = False
-                              , supportsDirectAccessors    = False
-                              , supportsFlattenedModels    = Nothing
+                                supportsQuantifiers     = False
+                              , supportsDefineFun       = True
+                              , supportsDistinct        = True
+                              , supportsBitVectors      = True
+                              , supportsADTs            = True
+                              , supportsUnboundedInts   = False
+                              , supportsReals           = False
+                              , supportsApproxReals     = False
+                              , supportsDeltaSat        = Nothing
+                              , supportsIEEE754         = True
+                              , supportsSets            = False
+                              , supportsOptimization    = False
+                              , supportsPseudoBooleans  = False
+                              , supportsCustomQueries   = True
+                              , supportsGlobalDecls     = True
+                              , supportsDataTypes       = False
+                              , supportsLambdas         = False
+                              , supportsSpecialRels     = False
+                              , supportsDirectTesters   = False
+                              , supportsFlattenedModels = Nothing
                               }
          }
diff --git a/Data/SBV/Provers/Boolector.hs b/Data/SBV/Provers/Boolector.hs
--- a/Data/SBV/Provers/Boolector.hs
+++ b/Data/SBV/Provers/Boolector.hs
@@ -27,25 +27,25 @@
          , options      = const ["--smt2", "-m", "--output-format=smt2", "--no-exit-codes", "--incremental"]
          , engine       = standardEngine "SBV_BOOLECTOR" "SBV_BOOLECTOR_OPTIONS"
          , capabilities = SolverCapabilities {
-                                supportsQuantifiers        = False
-                              , supportsDefineFun          = True
-                              , supportsDistinct           = True
-                              , supportsBitVectors         = True
-                              , supportsUninterpretedSorts = False
-                              , supportsUnboundedInts      = False
-                              , supportsReals              = False
-                              , supportsApproxReals        = False
-                              , supportsDeltaSat           = Nothing
-                              , supportsIEEE754            = False
-                              , supportsSets               = False
-                              , supportsOptimization       = False
-                              , supportsPseudoBooleans     = False
-                              , supportsCustomQueries      = True
-                              , supportsGlobalDecls        = True
-                              , supportsDataTypes          = False
-                              , supportsLambdas            = False
-                              , supportsSpecialRels        = False
-                              , supportsDirectAccessors    = False
-                              , supportsFlattenedModels    = Nothing
+                                supportsQuantifiers     = False
+                              , supportsDefineFun       = True
+                              , supportsDistinct        = True
+                              , supportsBitVectors      = True
+                              , supportsADTs            = False
+                              , supportsUnboundedInts   = False
+                              , supportsReals           = False
+                              , supportsApproxReals     = False
+                              , supportsDeltaSat        = Nothing
+                              , supportsIEEE754         = False
+                              , supportsSets            = False
+                              , supportsOptimization    = False
+                              , supportsPseudoBooleans  = False
+                              , supportsCustomQueries   = True
+                              , supportsGlobalDecls     = True
+                              , supportsDataTypes       = False
+                              , supportsLambdas         = False
+                              , supportsSpecialRels     = False
+                              , supportsDirectTesters   = False
+                              , supportsFlattenedModels = Nothing
                               }
          }
diff --git a/Data/SBV/Provers/CVC4.hs b/Data/SBV/Provers/CVC4.hs
--- a/Data/SBV/Provers/CVC4.hs
+++ b/Data/SBV/Provers/CVC4.hs
@@ -9,7 +9,7 @@
 -- The connection to the CVC4 SMT solver
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE OverloadedStrings #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -17,6 +17,8 @@
 
 import Data.Char (isSpace)
 
+import qualified Data.Text as T
+
 import Data.SBV.Core.Data
 import Data.SBV.SMT.SMT
 
@@ -31,34 +33,37 @@
          , options      = const ["--lang", "smt", "--incremental", "--interactive", "--no-interactive-prompt", "--model-witness-value"]
          , engine       = standardEngine "SBV_CVC4" "SBV_CVC4_OPTIONS"
          , capabilities = SolverCapabilities {
-                                supportsQuantifiers        = True
-                              , supportsDefineFun          = True
-                              , supportsDistinct           = True
-                              , supportsBitVectors         = True
-                              , supportsUninterpretedSorts = True
-                              , supportsUnboundedInts      = True
-                              , supportsReals              = True  -- Not quite the same capability as Z3; but works more or less..
-                              , supportsApproxReals        = False
-                              , supportsDeltaSat           = Nothing
-                              , supportsIEEE754            = True
-                              , supportsSets               = False
-                              , supportsOptimization       = False
-                              , supportsPseudoBooleans     = False
-                              , supportsCustomQueries      = True
-                              , supportsGlobalDecls        = True
-                              , supportsDataTypes          = True
-                              , supportsLambdas            = False
-                              , supportsSpecialRels        = False
-                              , supportsDirectAccessors    = True
-                              , supportsFlattenedModels    = Nothing
+                                supportsQuantifiers     = True
+                              , supportsDefineFun       = True
+                              , supportsDistinct        = True
+                              , supportsBitVectors      = True
+                              , supportsADTs            = True
+                              , supportsUnboundedInts   = True
+                              , supportsReals           = True  -- Not quite the same capability as Z3; but works more or less..
+                              , supportsApproxReals     = False
+                              , supportsDeltaSat        = Nothing
+                              , supportsIEEE754         = True
+                              , supportsSets            = False
+                              , supportsOptimization    = False
+                              , supportsPseudoBooleans  = False
+                              , supportsCustomQueries   = True
+                              , supportsGlobalDecls     = True
+                              , supportsDataTypes       = True
+                              , supportsLambdas         = False
+                              , supportsSpecialRels     = False
+                              , supportsDirectTesters   = True
+                              , supportsFlattenedModels = Nothing
                               }
          }
   where -- CVC4 wants all input on one line
-        clean = map simpleSpace . noComment
+        clean = T.map simpleSpace . noComment
 
-        noComment ""       = ""
-        noComment (';':cs) = noComment $ dropWhile (/= '\n') cs
-        noComment (c:cs)   = c : noComment cs
+        noComment t
+          | T.null t  = T.empty
+          | True      = case T.break (== ';') t of
+                          (before, rest)
+                            | T.null rest -> before
+                            | True        -> before <> noComment (T.dropWhile (/= '\n') (T.tail rest))
 
         simpleSpace c
           | isSpace c = ' '
diff --git a/Data/SBV/Provers/CVC5.hs b/Data/SBV/Provers/CVC5.hs
--- a/Data/SBV/Provers/CVC5.hs
+++ b/Data/SBV/Provers/CVC5.hs
@@ -9,7 +9,7 @@
 -- The connection to the CVC5 SMT solver
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE OverloadedStrings #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -17,6 +17,8 @@
 
 import Data.Char (isSpace)
 
+import qualified Data.Text as T
+
 import Data.SBV.Core.Data
 import Data.SBV.SMT.SMT
 
@@ -31,34 +33,37 @@
          , options      = const ["--lang", "smt", "--incremental", "--nl-cov"]
          , engine       = standardEngine "SBV_CVC5" "SBV_CVC5_OPTIONS"
          , capabilities = SolverCapabilities {
-                                supportsQuantifiers        = True
-                              , supportsDefineFun          = True
-                              , supportsDistinct           = True
-                              , supportsBitVectors         = True
-                              , supportsUninterpretedSorts = True
-                              , supportsUnboundedInts      = True
-                              , supportsReals              = True  -- Not quite the same capability as Z3; but works more or less..
-                              , supportsApproxReals        = False
-                              , supportsDeltaSat           = Nothing
-                              , supportsIEEE754            = True
-                              , supportsSets               = False
-                              , supportsOptimization       = False
-                              , supportsPseudoBooleans     = False
-                              , supportsCustomQueries      = True
-                              , supportsGlobalDecls        = True
-                              , supportsDataTypes          = True
-                              , supportsLambdas            = True
-                              , supportsSpecialRels        = False
-                              , supportsDirectAccessors    = True
-                              , supportsFlattenedModels    = Nothing
+                                supportsQuantifiers     = True
+                              , supportsDefineFun       = True
+                              , supportsDistinct        = True
+                              , supportsBitVectors      = True
+                              , supportsADTs            = True
+                              , supportsUnboundedInts   = True
+                              , supportsReals           = True  -- Not quite the same capability as Z3; but works more or less..
+                              , supportsApproxReals     = False
+                              , supportsDeltaSat        = Nothing
+                              , supportsIEEE754         = True
+                              , supportsSets            = False
+                              , supportsOptimization    = False
+                              , supportsPseudoBooleans  = False
+                              , supportsCustomQueries   = True
+                              , supportsGlobalDecls     = True
+                              , supportsDataTypes       = True
+                              , supportsLambdas         = True
+                              , supportsSpecialRels     = False
+                              , supportsDirectTesters   = True
+                              , supportsFlattenedModels = Nothing
                               }
          }
   where -- CVC5 wants all input on one line
-        clean = map simpleSpace . noComment
+        clean = T.map simpleSpace . noComment
 
-        noComment ""       = ""
-        noComment (';':cs) = noComment $ dropWhile (/= '\n') cs
-        noComment (c:cs)   = c : noComment cs
+        noComment t
+          | T.null t  = T.empty
+          | True      = case T.break (== ';') t of
+                          (before, rest)
+                            | T.null rest -> before
+                            | True        -> before <> noComment (T.dropWhile (/= '\n') (T.tail rest))
 
         simpleSpace c
           | isSpace c = ' '
diff --git a/Data/SBV/Provers/DReal.hs b/Data/SBV/Provers/DReal.hs
--- a/Data/SBV/Provers/DReal.hs
+++ b/Data/SBV/Provers/DReal.hs
@@ -9,8 +9,6 @@
 -- The connection to the dReal SMT solver
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE ScopedTypeVariables #-}
-
 {-# OPTIONS_GHC -Wall -Werror #-}
 
 module Data.SBV.Provers.DReal(dReal) where
@@ -31,26 +29,26 @@
          , options      = modConfig ["--in", "--format", "smt2"]
          , engine       = standardEngine "SBV_DREAL" "SBV_DREAL_OPTIONS"
          , capabilities = SolverCapabilities {
-                                supportsQuantifiers        = False
-                              , supportsDefineFun          = True
-                              , supportsDistinct           = False
-                              , supportsBitVectors         = False
-                              , supportsUninterpretedSorts = False
-                              , supportsUnboundedInts      = True
-                              , supportsReals              = True
-                              , supportsApproxReals        = False
-                              , supportsDeltaSat           = Just "(get-option :precision)"
-                              , supportsIEEE754            = False
-                              , supportsSets               = False
-                              , supportsOptimization       = False
-                              , supportsPseudoBooleans     = False
-                              , supportsCustomQueries      = False
-                              , supportsGlobalDecls        = False
-                              , supportsDataTypes          = False
-                              , supportsLambdas            = False
-                              , supportsSpecialRels        = False
-                              , supportsDirectAccessors    = False
-                              , supportsFlattenedModels    = Nothing
+                                supportsQuantifiers     = False
+                              , supportsDefineFun       = True
+                              , supportsDistinct        = False
+                              , supportsBitVectors      = False
+                              , supportsADTs            = False
+                              , supportsUnboundedInts   = True
+                              , supportsReals           = True
+                              , supportsApproxReals     = False
+                              , supportsDeltaSat        = Just "(get-option :precision)"
+                              , supportsIEEE754         = False
+                              , supportsSets            = False
+                              , supportsOptimization    = False
+                              , supportsPseudoBooleans  = False
+                              , supportsCustomQueries   = False
+                              , supportsGlobalDecls     = False
+                              , supportsDataTypes       = False
+                              , supportsLambdas         = False
+                              , supportsSpecialRels     = False
+                              , supportsDirectTesters   = False
+                              , supportsFlattenedModels = Nothing
                               }
          }
   where -- If dsat precision is given, pass that as an argument
diff --git a/Data/SBV/Provers/MathSAT.hs b/Data/SBV/Provers/MathSAT.hs
--- a/Data/SBV/Provers/MathSAT.hs
+++ b/Data/SBV/Provers/MathSAT.hs
@@ -9,8 +9,6 @@
 -- The connection to the MathSAT SMT solver
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE ScopedTypeVariables #-}
-
 {-# OPTIONS_GHC -Wall -Werror #-}
 
 module Data.SBV.Provers.MathSAT(mathSAT) where
@@ -31,26 +29,26 @@
          , options      = modConfig ["-input=smt2", "-theory.fp.minmax_zero_mode=4"]
          , engine       = standardEngine "SBV_MATHSAT" "SBV_MATHSAT_OPTIONS"
          , capabilities = SolverCapabilities {
-                                supportsQuantifiers        = True
-                              , supportsDefineFun          = True
-                              , supportsDistinct           = True
-                              , supportsBitVectors         = True
-                              , supportsUninterpretedSorts = True
-                              , supportsUnboundedInts      = True
-                              , supportsReals              = True
-                              , supportsApproxReals        = False
-                              , supportsDeltaSat           = Nothing
-                              , supportsIEEE754            = True
-                              , supportsSets               = False
-                              , supportsOptimization       = False
-                              , supportsPseudoBooleans     = False
-                              , supportsCustomQueries      = True
-                              , supportsGlobalDecls        = True
-                              , supportsDataTypes          = True
-                              , supportsLambdas            = False
-                              , supportsSpecialRels        = False
-                              , supportsDirectAccessors    = True
-                              , supportsFlattenedModels    = Nothing
+                                supportsQuantifiers     = True
+                              , supportsDefineFun       = True
+                              , supportsDistinct        = True
+                              , supportsBitVectors      = True
+                              , supportsADTs            = True
+                              , supportsUnboundedInts   = True
+                              , supportsReals           = True
+                              , supportsApproxReals     = False
+                              , supportsDeltaSat        = Nothing
+                              , supportsIEEE754         = True
+                              , supportsSets            = False
+                              , supportsOptimization    = False
+                              , supportsPseudoBooleans  = False
+                              , supportsCustomQueries   = True
+                              , supportsGlobalDecls     = True
+                              , supportsDataTypes       = True
+                              , supportsLambdas         = False
+                              , supportsSpecialRels     = False
+                              , supportsDirectTesters   = True
+                              , supportsFlattenedModels = Nothing
                               }
          }
 
diff --git a/Data/SBV/Provers/OpenSMT.hs b/Data/SBV/Provers/OpenSMT.hs
--- a/Data/SBV/Provers/OpenSMT.hs
+++ b/Data/SBV/Provers/OpenSMT.hs
@@ -27,26 +27,26 @@
          , options      = modConfig []
          , engine       = standardEngine "SBV_OpenSMT" "SBV_OpenSMT_OPTIONS"
          , capabilities = SolverCapabilities {
-                                supportsQuantifiers        = False
-                              , supportsDefineFun          = True
-                              , supportsDistinct           = True
-                              , supportsBitVectors         = False
-                              , supportsUninterpretedSorts = True
-                              , supportsUnboundedInts      = True
-                              , supportsReals              = True
-                              , supportsApproxReals        = False
-                              , supportsDeltaSat           = Nothing
-                              , supportsIEEE754            = False
-                              , supportsSets               = False
-                              , supportsOptimization       = False
-                              , supportsPseudoBooleans     = False
-                              , supportsCustomQueries      = True
-                              , supportsGlobalDecls        = True
-                              , supportsDataTypes          = False
-                              , supportsLambdas            = False
-                              , supportsSpecialRels        = False
-                              , supportsDirectAccessors    = False
-                              , supportsFlattenedModels    = Nothing
+                                supportsQuantifiers     = False
+                              , supportsDefineFun       = True
+                              , supportsDistinct        = True
+                              , supportsBitVectors      = False
+                              , supportsADTs            = True
+                              , supportsUnboundedInts   = True
+                              , supportsReals           = True
+                              , supportsApproxReals     = False
+                              , supportsDeltaSat        = Nothing
+                              , supportsIEEE754         = False
+                              , supportsSets            = False
+                              , supportsOptimization    = False
+                              , supportsPseudoBooleans  = False
+                              , supportsCustomQueries   = True
+                              , supportsGlobalDecls     = True
+                              , supportsDataTypes       = False
+                              , supportsLambdas         = False
+                              , supportsSpecialRels     = False
+                              , supportsDirectTesters   = False
+                              , supportsFlattenedModels = Nothing
                               }
          }
 
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
@@ -9,15 +9,15 @@
 -- Provable abstraction and the connection to SMT solvers
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE CPP                   #-}
 {-# LANGUAGE ConstraintKinds       #-}
 {-# LANGUAGE FlexibleContexts      #-}
 {-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE GADTs                 #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE NamedFieldPuns        #-}
+{-# LANGUAGE OverloadedStrings     #-}
 {-# LANGUAGE ScopedTypeVariables   #-}
 {-# LANGUAGE TupleSections         #-}
-{-# LANGUAGE UndecidableInstances  #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -29,14 +29,14 @@
        , SExecutable(..), isSafe
        , runSMT, runSMTWith
        , SatModel(..), Modelable(..), displayModels, extractModels
-       , getModelDictionaries, getModelValues, getModelUninterpretedValues
+       , getModelDictionaries, getModelValues
        , abc, boolector, bitwuzla, cvc4, cvc5, dReal, mathSAT, yices, z3, openSMT, defaultSMTCfg, defaultDeltaSMTCfg
        , proveWithAny, proveWithAll, proveConcurrentWithAny, proveConcurrentWithAll
        , satWithAny,   satWithAll,   satConcurrentWithAny,   satConcurrentWithAll
        ) where
 
 
-import Control.Monad          (when, unless)
+import Control.Monad          (unless)
 import Control.Monad.IO.Class (MonadIO, liftIO)
 import Control.DeepSeq        (rnf, NFData(..))
 
@@ -52,6 +52,8 @@
 
 import Data.Maybe (mapMaybe, listToMaybe)
 
+import qualified Data.Set as Set (empty)
+
 import qualified Data.Foldable   as S (toList)
 import qualified Data.Text       as T
 
@@ -60,6 +62,7 @@
 import Data.SBV.SMT.SMT
 import Data.SBV.SMT.Utils (debug, alignPlain)
 import Data.SBV.Utils.ExtractIO
+import Data.SBV.Utils.Lib    (showText)
 import Data.SBV.Utils.TDiff
 
 import Data.SBV.Lambda () -- instances only
@@ -104,14 +107,15 @@
                                             , optimizeValidateConstraints = False
                                             , roundingMode                = RoundNearestTiesToEven
                                             , solverSetOptions            = startOpts
+                                            , smtLib2Compliant            = True
                                             , ignoreExitCode              = False
                                             , redirectVerbose             = Nothing
                                             , firstifyUniqueLen           = 10
-                                            , tpOptions                   = TPOptions { ribbonLength = 40
-                                                                                      , quiet        = False
-                                                                                      , printAsms    = False
-                                                                                      , printStats   = False
-                                                                                      , cacheProofs  = False
+                                            , tpOptions                   = TPOptions { ribbonLength          = 40
+                                                                                      , quiet                 = False
+                                                                                      , printAsms             = False
+                                                                                      , printStats            = False
+                                                                                      , measuresBeingVerified = Set.empty
                                                                                       }
                                             }
 
@@ -208,7 +212,7 @@
   satWith cfg a = do r <- runWithQuery satArgReduce True (checkNoOptimizations >> Control.getSMTResult) cfg a
                      SatResult <$> if validationRequested cfg
                                    then validate satArgReduce True cfg a r
-                                   else return r
+                                   else pure r
 
   -- | Generalization of 'Data.SBV.sat'
   dsat :: a -> m SatResult
@@ -219,7 +223,7 @@
   dsatWith cfg a = do r <- runWithQuery satArgReduce True (checkNoOptimizations >> Control.getSMTResult) cfg a
                       SatResult <$> if validationRequested cfg
                                     then validate satArgReduce True cfg a r
-                                    else return r
+                                    else pure r
 
   -- | Generalization of 'Data.SBV.allSat'
   allSat :: a -> m AllSatResult
@@ -230,8 +234,8 @@
   allSatWith cfg a = do asr <- runWithQuery satArgReduce True (checkNoOptimizations >> Control.getAllSatResult) cfg a
                         if validationRequested cfg
                            then do rs' <- mapM (validate satArgReduce True cfg a) (allSatResults asr)
-                                   return asr{allSatResults = rs'}
-                           else return asr
+                                   pure asr{allSatResults = rs'}
+                           else pure asr
 
   -- | Generalization of 'Data.SBV.isSatisfiable'
   isSatisfiable :: a -> m Bool
@@ -241,8 +245,8 @@
   isSatisfiableWith :: SMTConfig -> a -> m Bool
   isSatisfiableWith cfg p = do r <- satWith cfg p
                                case r of
-                                 SatResult Satisfiable{}   -> return True
-                                 SatResult Unsatisfiable{} -> return False
+                                 SatResult Satisfiable{}   -> pure True
+                                 SatResult Unsatisfiable{} -> pure False
                                  _                         -> error $ "SBV.isSatisfiable: Received: " ++ show r
 
   -- | Generalization of 'Data.SBV.optimize'
@@ -254,67 +258,30 @@
   optimizeWith config style optGoal = do
                    res <- runWithQuery satArgReduce True opt config optGoal
                    if not (optimizeValidateConstraints config)
-                      then return res
+                      then pure res
                       else let v :: SMTResult -> m SMTResult
                                v = validate satArgReduce True config optGoal
                            in case res of
                                 LexicographicResult m -> LexicographicResult <$> v m
-                                IndependentResult xs  -> let w []            sofar = return (reverse sofar)
+                                IndependentResult xs  -> let w []            sofar = pure (reverse sofar)
                                                              w ((n, m):rest) sofar = v m >>= \m' -> w rest ((n, m') : sofar)
                                                          in IndependentResult <$> w xs []
                                 ParetoResult (b, rs)  -> ParetoResult . (b, ) <$> mapM v rs
 
-    where opt = do objectives <- Control.getObjectives
-
-                   when (null objectives) $
-                          error $ unlines [ ""
-                                          , "*** Data.SBV: Unsupported call to optimize when no objectives are present."
-                                          , "*** Use \"sat\" for plain satisfaction"
-                                          ]
-
-                   unless (supportsOptimization (capabilities (solver config))) $
-                          error $ unlines [ ""
-                                          , "*** Data.SBV: The backend solver " ++ show (name (solver config)) ++ "does not support optimization goals."
-                                          , "*** Please use a solver that has support, such as z3"
-                                          ]
-
-                   when (validateModel config && not (optimizeValidateConstraints config)) $
-                          error $ unlines [ ""
-                                          , "*** Data.SBV: Model validation is not supported in optimization calls."
-                                          , "***"
-                                          , "*** Instead, use `cfg{optimizeValidateConstraints = True}`"
-                                          , "***"
-                                          , "*** which checks that the results satisfy the constraints but does"
-                                          , "*** NOT ensure that they are optimal."
-                                          ]
-
-
-                   let optimizerDirectives = concatMap minmax objectives ++ priority style
-                         where mkEq (x, y) = "(assert (= " ++ show x ++ " " ++ show y ++ "))"
-
-                               minmax (Minimize          _  xy@(_, v))     = [mkEq xy, "(minimize "    ++ show v                 ++ ")"]
-                               minmax (Maximize          _  xy@(_, v))     = [mkEq xy, "(maximize "    ++ show v                 ++ ")"]
-                               minmax (AssertWithPenalty nm xy@(_, v) mbp) = [mkEq xy, "(assert-soft " ++ show v ++ penalize mbp ++ ")"]
-                                 where penalize DefaultPenalty    = ""
-                                       penalize (Penalty w mbGrp)
-                                          | w <= 0         = error $ unlines [ "SBV.AssertWithPenalty: Goal " ++ show nm ++ " is assigned a non-positive penalty: " ++ shw
-                                                                             , "All soft goals must have > 0 penalties associated."
-                                                                             ]
-                                          | True           = " :weight " ++ shw ++ maybe "" group mbGrp
-                                          where shw = show (fromRational w :: Double)
-
-                                       group g = " :id " ++ g
-
-                               priority Lexicographic = [] -- default, no option needed
-                               priority Independent   = ["(set-option :opt.priority box)"]
-                               priority (Pareto _)    = ["(set-option :opt.priority pareto)"]
+    where opt = do mbDirs <- Control.startOptimizer config style
 
-                   mapM_ (Control.send True) optimizerDirectives
+                   case mbDirs of
+                     Nothing   -> error $ unlines [ ""
+                                                  , "*** Data.SBV: Unsupported call to optimize when no objectives are present."
+                                                  , "*** Use \"sat\" for plain satisfaction"
+                                                  ]
+                     Just (objectives, optimizerDirectives) -> do
+                       mapM_ (Control.send True . T.pack) optimizerDirectives
 
-                   case style of
-                     Lexicographic -> LexicographicResult <$> Control.getLexicographicOptResults
-                     Independent   -> IndependentResult   <$> Control.getIndependentOptResults (map objectiveName objectives)
-                     Pareto mbN    -> ParetoResult        <$> Control.getParetoOptResults mbN
+                       case style of
+                         Lexicographic -> LexicographicResult <$> Control.getLexicographicOptResults
+                         Independent   -> IndependentResult   <$> Control.getIndependentOptResults (map objectiveName objectives)
+                         Pareto mbN    -> ParetoResult        <$> Control.getParetoOptResults mbN
 
 -- | Find a satisfying assignment to a property with multiple solvers, running them in separate threads. The
 -- results will be returned in the order produced.
@@ -338,7 +305,7 @@
 -- performance benefit.
 satConcurrentWithAny :: Satisfiable a => SMTConfig -> [Query b] -> a -> IO (Solver, NominalDiffTime, SatResult)
 satConcurrentWithAny solver qs a = do (slvr,time,result) <- sbvConcurrentWithAny solver go qs a
-                                      return (slvr, time, SatResult result)
+                                      pure (slvr, time, SatResult result)
   where go cfg a' q = runWithQuery satArgReduce True (do _ <- q; checkNoOptimizations >> Control.getSMTResult) cfg a'
 
 -- | Find a satisfying assignment to a property using a single solver, but run
@@ -346,7 +313,7 @@
 -- finish. See 'satConcurrentWithAny' for more details.
 satConcurrentWithAll :: Satisfiable a => SMTConfig -> [Query b] -> a -> IO [(Solver, NominalDiffTime, SatResult)]
 satConcurrentWithAll solver qs a = do results <- sbvConcurrentWithAll solver go qs a
-                                      return $ (\(a',b,c) -> (a',b,SatResult c)) <$> results
+                                      pure $ (\(a',b,c) -> (a',b,SatResult c)) <$> results
   where go cfg a' q = runWithQuery satArgReduce True (do _ <- q; checkNoOptimizations >> Control.getSMTResult) cfg a'
 
 -- | A type @a@ is provable if we can turn it into a predicate, i.e., it has to return a boolean.
@@ -364,7 +331,7 @@
   proveWith cfg a = do r <- runWithQuery proofArgReduce False (checkNoOptimizations >> Control.getSMTResult) cfg a
                        ThmResult <$> if validationRequested cfg
                                      then validate proofArgReduce False cfg a r
-                                     else return r
+                                     else pure r
 
   -- | Generalization of 'Data.SBV.dprove'
   dprove :: a -> m ThmResult
@@ -375,7 +342,7 @@
   dproveWith cfg a = do r <- runWithQuery proofArgReduce False (checkNoOptimizations >> Control.getSMTResult) cfg a
                         ThmResult <$> if validationRequested cfg
                                       then validate proofArgReduce False cfg a r
-                                      else return r
+                                      else pure r
 
   -- | Generalization of 'Data.SBV.isVacuousProof'
   isVacuousProof :: a -> m Bool
@@ -388,9 +355,9 @@
      where
        check = do cs <- Control.checkSat
                   case cs of
-                    Control.Unsat  -> return True
-                    Control.Sat    -> return False
-                    Control.DSat{} -> return False
+                    Control.Unsat  -> pure True
+                    Control.Sat    -> pure False
+                    Control.DSat{} -> pure False
                     Control.Unk    -> error "SBV: isVacuous: Solver returned unknown!"
 
   -- | Generalization of 'Data.SBV.isTheorem'
@@ -402,10 +369,10 @@
   isTheoremWith cfg p = do r <- proveWith cfg p
                            let bad = error $ "SBV.isTheorem: Received:\n" ++ show r
                            case r of
-                             ThmResult Unsatisfiable{} -> return True
-                             ThmResult Satisfiable{}   -> return False
-                             ThmResult DeltaSat{}      -> return False
-                             ThmResult SatExtField{}   -> return False
+                             ThmResult Unsatisfiable{} -> pure True
+                             ThmResult Satisfiable{}   -> pure False
+                             ThmResult DeltaSat{}      -> pure False
+                             ThmResult SatExtField{}   -> pure False
                              ThmResult Unknown{}       -> bad
                              ThmResult ProofError{}    -> bad
 
@@ -426,21 +393,21 @@
 -- concurrently and return the first that finishes, killing the others
 proveConcurrentWithAny :: Provable a => SMTConfig -> [Query b] -> a -> IO (Solver, NominalDiffTime, ThmResult)
 proveConcurrentWithAny solver qs a = do (slvr,time,result) <- sbvConcurrentWithAny solver go qs a
-                                        return (slvr, time, ThmResult result)
+                                        pure (slvr, time, ThmResult result)
   where go cfg a' q = runWithQuery proofArgReduce False (do _ <- q;  checkNoOptimizations >> Control.getSMTResult) cfg a'
 
 -- | Prove a property by running many queries each isolated to their own thread
 -- concurrently and wait for each to finish returning all results
 proveConcurrentWithAll :: Provable a => SMTConfig -> [Query b] -> a -> IO [(Solver, NominalDiffTime, ThmResult)]
 proveConcurrentWithAll solver qs a = do results <- sbvConcurrentWithAll solver go qs a
-                                        return $ (\(a',b,c) -> (a',b,ThmResult c)) <$> results
+                                        pure $ (\(a',b,c) -> (a',b,ThmResult c)) <$> results
   where go cfg a' q = runWithQuery proofArgReduce False (do _ <- q; checkNoOptimizations >> Control.getSMTResult) cfg a'
 
 -- | Validate a model obtained from the solver
 validate :: MonadIO m => (a -> SymbolicT m SBool) -> Bool -> SMTConfig -> a -> SMTResult -> m SMTResult
 validate reducer isSAT cfg p res =
      case res of
-       Unsatisfiable{} -> return res
+       Unsatisfiable{} -> pure res
        Satisfiable _ m -> case modelBindings m of
                             Nothing  -> error "Data.SBV.validate: Impossible happened; no bindings generated during model validation."
                             Just env -> check env
@@ -455,10 +422,10 @@
                                , "To turn validation off, use `cfg{optimizeValidateConstraints = False}`"
                                ]
 
-       Unknown{}       -> return res
-       ProofError{}    -> return res
+       Unknown{}       -> pure res
+       ProofError{}    -> pure res
 
-  where cant msg = return $ ProofError cfg (msg ++ [ ""
+  where cant msg = pure $ ProofError cfg (msg ++ [ ""
                                                    , "Unable to validate the produced model."
                                                    ]) (Just res)
 
@@ -466,8 +433,8 @@
                               where modelBinds = [(T.unpack n, RegularCV v) | (NamedSymVar _ n, v) <- env]
 
                            notify s
-                             | not (verbose cfg) = return ()
-                             | True              = debug cfg ["[VALIDATE] " `alignPlain` s]
+                             | not (verbose cfg) = pure ()
+                             | True              = debug cfg ["[VALIDATE] " `alignPlain` T.pack s]
 
                        notify $ "Validating the model. " ++ if null env then "There are no assignments." else "Assignment:"
                        mapM_ notify ["    " ++ l | l <- lines envShown]
@@ -481,7 +448,7 @@
                                    ++ [ "    " ++ l | l <- lines envShown]
                                    ++ [ "" ]
 
-                           wrap tag extras = return $ ProofError cfg (tag : explain ++ extras) (Just res)
+                           wrap tag extras = pure $ ProofError cfg (tag : explain ++ extras) (Just res)
 
                            giveUp   s     = wrap ("Data.SBV: Cannot validate the model: " ++ s)
                                                  [ "SBV's model validator is incomplete, and cannot handle this particular case."
@@ -513,11 +480,13 @@
                                       why s = case s `lookup` S.toList (pgmAssignments (resAsgns result)) of
                                                 Nothing            -> Nothing
                                                 Just (SBVApp o as) -> case o of
-                                                                        Uninterpreted v  -> Just $ "The value depends on the uninterpreted constant " ++ show v ++ "."
                                                                         QuantifiedBool{} -> Just "The value depends on a quantified variable."
                                                                         IEEEFP FP_FMA    -> Just "Floating point FMA operation is not supported concretely."
                                                                         IEEEFP _         -> Just "Not all floating point operations are supported concretely."
                                                                         OverflowOp _     -> Just "Overflow-checking is not done concretely."
+                                                                        Uninterpreted v
+                                                                          | any isADT as -> Just "Models containing ADTs are currently only partially supported."
+                                                                          | True         -> Just $ "The value depends on the uninterpreted constant " ++ T.unpack v ++ "."
                                                                         _                -> listToMaybe $ mapMaybe why as
 
                            cstrs = S.toList $ resConstraints result
@@ -541,7 +510,7 @@
                            -- SAT: All outputs must be true
                            satLoop []
                              = do notify "All outputs are satisfied. Validation complete."
-                                  return res
+                                  pure res
                            satLoop (sv:svs)
                              | kindOf sv /= KBool
                              = giveUp $ "Output tied to " ++ show sv ++ " is non-boolean."
@@ -555,7 +524,7 @@
                            -- Proof: At least one output must be false
                            proveLoop [] somethingFailed
                              | somethingFailed = do notify "Counterexample is validated."
-                                                    return res
+                                                    pure res
                              | True            = do notify "Counterexample violates none of the outputs."
                                                     badModel "Counter-example violates no constraints."
                            proveLoop (sv:svs) somethingFailed
@@ -586,7 +555,7 @@
 -- | Given a satisfiability problem, extract the function definitions in it
 defs2smt :: SatisfiableM m a => a -> m String
 defs2smt = generateSMTBenchMarkGen True satArgReduce defs
-  where defs (SMTLibPgm _ _ ds) = intercalate "\n" ds
+  where defs (SMTLibPgm _ _ ds) = T.unpack ds
 
 -- | Create an SMT-Lib2 benchmark, for a SAT query.
 generateSMTBenchmarkSat :: SatisfiableM m a => a -> m String
@@ -608,7 +577,7 @@
 
       let SMTProblem{smtLibPgm} = Control.runProofOn (SMTMode QueryInternal IRun isSat cfg) QueryInternal comments res
 
-      return $ render (smtLibPgm cfg)
+      pure $ render (smtLibPgm cfg)
 
 checkNoOptimizations :: MonadIO m => QueryT m ()
 checkNoOptimizations = do objectives <- Control.getObjectives
@@ -625,8 +594,8 @@
 instance ExtractIO m => SatisfiableM m (SymbolicT m SBool) where satArgReduce   = id
 instance ExtractIO m => ProvableM    m (SymbolicT m SBool) where proofArgReduce = id
 
-instance ExtractIO m => SatisfiableM m SBool where satArgReduce   = return
-instance ExtractIO m => ProvableM    m SBool where proofArgReduce = return
+instance ExtractIO m => SatisfiableM m SBool where satArgReduce   = pure
+instance ExtractIO m => ProvableM    m SBool where proofArgReduce = pure
 
 instance {-# OVERLAPPABLE #-} (ExtractIO m, SatisfiableM m a) => SatisfiableM m (SymbolicT m a) where satArgReduce   a = a >>= satArgReduce
 instance {-# OVERLAPPABLE #-} (ExtractIO m, ProvableM    m a) => ProvableM    m (SymbolicT m a) where proofArgReduce a = a >>= proofArgReduce
@@ -665,7 +634,7 @@
 -- The following is a possible definition, but it lets us write properties that
 -- are not useful.. Such as: prove $ \x y -> (x::SInt8) == y
 -- Running that will throw an exception since Haskell's equality is not be supported by symbolic things. (Needs .==).
--- So, we avoid these insteances.
+-- So, we avoid these instances.
 instance ExtractIO m => ProvableM m Bool where
   proofArgReduce x  = proofArgReduce (if x then sTrue else sFalse :: SBool)
 
@@ -684,6 +653,18 @@
 instance (SymVal a, ProvableM m p) => ProvableM m (SBV a -> p) where
   proofArgReduce fn = mkArg >>= \a -> proofArgReduce $ fn a
 
+-- | Create an 'SBVs' sequence of arguments
+mkArgs :: MonadSymbolic m => SymValInsts as -> m (SBVs as)
+mkArgs SymValsNil = pure SBVsNil
+mkArgs (SymValsCons insts) = SBVsCons <$> mkArgs insts <*> mkArg
+
+-- Multi-arity Functions
+instance (SymVals as, SatisfiableM m p) => SatisfiableM m (SBVs as -> p) where
+  satArgReduce fn = mkArgs symValInsts >>= \args -> satArgReduce $ fn args
+
+instance (SymVals as, ProvableM m p) => ProvableM m (SBVs as -> p) where
+  proofArgReduce fn = mkArgs symValInsts >>= \args -> proofArgReduce $ fn args
+
 -- 2 Tuple
 instance (SymVal a, SymVal b, SatisfiableM m p) => SatisfiableM m ((SBV a, SBV b) -> p) where
   satArgReduce fn = mkArg >>= \a -> satArgReduce $ \b -> fn (a, b)
@@ -790,14 +771,14 @@
 runInThread beginTime action config = async $ do
                 result  <- action config
                 endTime <- rnf result `seq` getCurrentTime
-                return (name (solver config), endTime `diffUTCTime` beginTime, result)
+                pure (name (solver config), endTime `diffUTCTime` beginTime, result)
 
 -- | Perform action for all given configs, return the first one that wins. Note that we do
 -- not wait for the other asyncs to terminate; hopefully they'll do so quickly.
 sbvWithAny :: NFData b => [SMTConfig] -> (SMTConfig -> a -> IO b) -> a -> IO (Solver, NominalDiffTime, b)
 sbvWithAny []      _    _ = error "SBV.withAny: No solvers given!"
 sbvWithAny solvers what a = do beginTime <- getCurrentTime
-                               snd `fmap` (mapM (runInThread beginTime (`what` a)) solvers >>= waitAnyFastCancel)
+                               snd <$> (mapM (runInThread beginTime (`what` a)) solvers >>= waitAnyFastCancel)
    where -- Async's `waitAnyCancel` nicely blocks; so we use this variant to ignore the
          -- wait part for killed threads.
          waitAnyFastCancel asyncs = waitAny asyncs `finally` mapM_ cancelFast asyncs
@@ -805,7 +786,7 @@
 
 
 sbvConcurrentWithAny :: NFData c => SMTConfig -> (SMTConfig -> a -> QueryT m b -> IO c) -> [QueryT m b] -> a -> IO (Solver, NominalDiffTime, c)
-sbvConcurrentWithAny solver what queries a = snd `fmap` (mapM runQueryInThread queries >>= waitAnyFastCancel)
+sbvConcurrentWithAny solver what queries a = snd <$> (mapM runQueryInThread queries >>= waitAnyFastCancel)
   where  -- Async's `waitAnyCancel` nicely blocks; so we use this variant to ignore the
          -- wait part for killed threads.
          waitAnyFastCancel asyncs = waitAny asyncs `finally` mapM_ cancelFast asyncs
@@ -819,7 +800,7 @@
   where  runQueryInThread q = do beginTime <- getCurrentTime
                                  runInThread beginTime (\cfg -> what cfg a q) solver
 
-         go []  = return []
+         go []  = pure []
          go as  = do (d, r) <- waitAny as
                      -- The following filter works because the Eq instance on Async
                      -- checks the thread-id; so we know that we're removing the
@@ -827,13 +808,13 @@
                      -- running the same-solver (with different options), since
                      -- they will get different thread-ids.
                      rs <- unsafeInterleaveIO $ go (filter (/= d) as)
-                     return (r : rs)
+                     pure (r : rs)
 
 -- | Perform action for all given configs, return all the results.
 sbvWithAll :: NFData b => [SMTConfig] -> (SMTConfig -> a -> IO b) -> a -> IO [(Solver, NominalDiffTime, b)]
 sbvWithAll solvers what a = do beginTime <- getCurrentTime
                                mapM (runInThread beginTime (`what` a)) solvers >>= (unsafeInterleaveIO . go)
-   where go []  = return []
+   where go []  = pure []
          go as  = do (d, r) <- waitAny as
                      -- The following filter works because the Eq instance on Async
                      -- checks the thread-id; so we know that we're removing the
@@ -841,7 +822,7 @@
                      -- running the same-solver (with different options), since
                      -- they will get different thread-ids.
                      rs <- unsafeInterleaveIO $ go (filter (/= d) as)
-                     return (r : rs)
+                     pure (r : rs)
 
 -- | Symbolically executable program fragments. This class is mainly used for 'safe' calls, and is sufficiently populated internally to cover most use
 -- cases. Users can extend it as they wish to allow 'safe' checks for SBV programs that return/take types that are user-defined.
@@ -869,18 +850,18 @@
            verify mkRelative (msg, cs, cond) = do
                    let locInfo ps = let loc (f, sl) = concat [mkRelative (srcLocFile sl), ":", show (srcLocStartLine sl), ":", show (srcLocStartCol sl), ":", f]
                                     in intercalate ",\n " (map loc ps)
-                       location   = (locInfo . getCallStack) `fmap` cs
+                       location   = locInfo . getCallStack <$> cs
 
                    result <- do Control.push 1
-                                Control.send True $ "(assert " ++ show cond ++ ")"
+                                Control.send True $ "(assert " <> showText cond <> ")"
                                 r <- Control.getSMTResult
                                 Control.pop 1
-                                return r
+                                pure r
 
-                   return $ SafeResult (location, msg, result)
+                   pure $ SafeResult (location, msg, result)
 
 instance (ExtractIO m, NFData a) => SExecutable m (SymbolicT m a) where
-   sName a = a >>= \r -> rnf r `seq` return ()
+   sName a = a >>= \r -> rnf r `seq` pure ()
 
 instance ExtractIO m => SExecutable m (SBV a) where
    sName v = sName (output v :: SymbolicT m (SBV a))
diff --git a/Data/SBV/Provers/Yices.hs b/Data/SBV/Provers/Yices.hs
--- a/Data/SBV/Provers/Yices.hs
+++ b/Data/SBV/Provers/Yices.hs
@@ -9,8 +9,6 @@
 -- The connection to the Yices SMT solver
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE ScopedTypeVariables #-}
-
 {-# OPTIONS_GHC -Wall -Werror #-}
 
 module Data.SBV.Provers.Yices(yices) where
@@ -29,25 +27,25 @@
          , options      = const ["--incremental"]
          , engine       = standardEngine "SBV_YICES" "SBV_YICES_OPTIONS"
          , capabilities = SolverCapabilities {
-                                supportsQuantifiers        = False
-                              , supportsDefineFun          = True
-                              , supportsDistinct           = True
-                              , supportsBitVectors         = True
-                              , supportsUninterpretedSorts = True
-                              , supportsUnboundedInts      = True
-                              , supportsReals              = True
-                              , supportsApproxReals        = False
-                              , supportsDeltaSat           = Nothing
-                              , supportsIEEE754            = False
-                              , supportsSets               = False
-                              , supportsOptimization       = False
-                              , supportsPseudoBooleans     = False
-                              , supportsCustomQueries      = True
-                              , supportsGlobalDecls        = True
-                              , supportsDataTypes          = False
-                              , supportsLambdas            = False
-                              , supportsSpecialRels        = False
-                              , supportsDirectAccessors    = False
-                              , supportsFlattenedModels    = Nothing
+                                supportsQuantifiers     = False
+                              , supportsDefineFun       = True
+                              , supportsDistinct        = True
+                              , supportsBitVectors      = True
+                              , supportsADTs            = True
+                              , supportsUnboundedInts   = True
+                              , supportsReals           = True
+                              , supportsApproxReals     = False
+                              , supportsDeltaSat        = Nothing
+                              , supportsIEEE754         = False
+                              , supportsSets            = False
+                              , supportsOptimization    = False
+                              , supportsPseudoBooleans  = False
+                              , supportsCustomQueries   = True
+                              , supportsGlobalDecls     = True
+                              , supportsDataTypes       = False
+                              , supportsLambdas         = False
+                              , supportsSpecialRels     = False
+                              , supportsDirectTesters   = False
+                              , supportsFlattenedModels = Nothing
                               }
          }
diff --git a/Data/SBV/Provers/Z3.hs b/Data/SBV/Provers/Z3.hs
--- a/Data/SBV/Provers/Z3.hs
+++ b/Data/SBV/Provers/Z3.hs
@@ -9,8 +9,6 @@
 -- The connection to the Z3 SMT solver
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE ScopedTypeVariables #-}
-
 {-# OPTIONS_GHC -Wall -Werror #-}
 
 module Data.SBV.Provers.Z3(z3) where
@@ -29,29 +27,29 @@
          , options      = modConfig ["-nw", "-in", "-smt2"]
          , engine       = standardEngine "SBV_Z3" "SBV_Z3_OPTIONS"
          , capabilities = SolverCapabilities {
-                                supportsQuantifiers        = True
-                              , supportsDefineFun          = True
-                              , supportsDistinct           = True
-                              , supportsBitVectors         = True
-                              , supportsUninterpretedSorts = True
-                              , supportsUnboundedInts      = True
-                              , supportsReals              = True
-                              , supportsApproxReals        = True
-                              , supportsDeltaSat           = Nothing
-                              , supportsIEEE754            = True
-                              , supportsSets               = True
-                              , supportsOptimization       = True
-                              , supportsPseudoBooleans     = True
-                              , supportsCustomQueries      = True
-                              , supportsGlobalDecls        = True
-                              , supportsDataTypes          = True
-                              , supportsLambdas            = True
-                              , supportsSpecialRels        = True
-                              , supportsDirectAccessors    = False -- Needs ascriptions. (See the CVC4 version of this)
-                              , supportsFlattenedModels    = Just [ "(set-option :pp.max_depth      4294967295)"
-                                                                  , "(set-option :pp.min_alias_size 4294967295)"
-                                                                  , "(set-option :model.inline_def  true      )"
-                                                                  ]
+                                supportsQuantifiers     = True
+                              , supportsDefineFun       = True
+                              , supportsDistinct        = True
+                              , supportsBitVectors      = True
+                              , supportsADTs            = True
+                              , supportsUnboundedInts   = True
+                              , supportsReals           = True
+                              , supportsApproxReals     = True
+                              , supportsDeltaSat        = Nothing
+                              , supportsIEEE754         = True
+                              , supportsSets            = True
+                              , supportsOptimization    = True
+                              , supportsPseudoBooleans  = True
+                              , supportsCustomQueries   = True
+                              , supportsGlobalDecls     = True
+                              , supportsDataTypes       = True
+                              , supportsLambdas         = True
+                              , supportsSpecialRels     = True
+                              , supportsDirectTesters   = False -- Needs ascriptions. (See the CVC4 version of this)
+                              , supportsFlattenedModels = Just [ "(set-option :pp.max_depth      4294967295)"
+                                                               , "(set-option :pp.min_alias_size 4294967295)"
+                                                               , "(set-option :model.inline_def  true      )"
+                                                               ]
                               }
          }
 
diff --git a/Data/SBV/Rational.hs b/Data/SBV/Rational.hs
--- a/Data/SBV/Rational.hs
+++ b/Data/SBV/Rational.hs
@@ -10,18 +10,27 @@
 -----------------------------------------------------------------------------
 
 {-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE OverloadedStrings #-}
 
 {-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
 module Data.SBV.Rational (
     -- * Constructing rationals
       (.%)
-  ) where
+    -- * Rounding rationals
+    , sRationalToSIntegerFloor, sRationalToSIntegerCeiling, sRationalToSIntegerTruncate
+    , sRationalToSIntegerRoundAway, sRationalToSIntegerRoundToEven, sRationalToSIntegerRM
+    -- * Converting between rationals and reals
+    , sRationalToSReal, sRealToSRational
+    ) where
 
 import qualified Data.Ratio as R
 
+import Data.SBV.Core.AlgReals (isExactRational)
 import Data.SBV.Core.Data
 import Data.SBV.Core.Model
+import Data.SBV.Core.Symbolic (newInternalVariable)
+import Data.SBV.Utils.Numeric (roundAway)
 
 infixl 7 .%
 
@@ -41,6 +50,165 @@
                    b <- sbvToSV st bot
                    newExpr st KRational $ SBVApp RationalConstructor [t, b]
 
+-- | Convert an SRational to an SInteger, @floor@ version. That is, it computes
+-- the largest integer @n@ that satisfies @(n .% 1) <= r@.
+--
+-- For instance, @1.3@ will be @1@, but @-1.3@ will be @-2@.
+--
+-- See 'sRationalToSIntegerRM' to select the rounding mode with a symbolic 'SRoundingMode'.
+sRationalToSIntegerFloor :: SRational -> SInteger
+-- NB: We use @sDiv@ below because it implements division that truncates
+-- towards negative infinity, which is exactly what @floor@ needs.
+sRationalToSIntegerFloor = lift1 floor (uncurry sDiv)
+
+-- | Convert an SRational to an SInteger, @ceiling@ version. That is, it
+-- computes the smallest integer @n@ that satisfies @r <= (n .% 1)@.
+--
+-- For instance, @1.3@ will be @2@, but @-1.3@ will be @-1@.
+--
+-- See 'sRationalToSIntegerRM' to select the rounding mode with a symbolic 'SRoundingMode'.
+sRationalToSIntegerCeiling :: SRational -> SInteger
+sRationalToSIntegerCeiling x
+  | Just i <- unliteral x
+  = literal $ ceiling i
+  | True
+  = - (sRationalToSIntegerFloor (- x))
+
+-- | Convert an SRational to an SInteger, truncating version. Truncate simply
+-- chops off the fractional part, essentially rounding towards zero.
+--
+-- For instance, @1.3@ will be @1@, and @-1.3@ will be @-1@.
+--
+-- See 'sRationalToSIntegerRM' to select the rounding mode with a symbolic 'SRoundingMode'.
+sRationalToSIntegerTruncate :: SRational -> SInteger
+sRationalToSIntegerTruncate x
+  | Just i <- unliteral x
+  = literal $ truncate i
+  | True
+  = ite (x .>= 0) (sRationalToSIntegerFloor x) (sRationalToSIntegerCeiling x)
+
+-- | Convert an SRational to an SInteger by converting to the nearest integer.
+-- If there is a tie (i.e., if the fractional component of the SRational is
+-- equal to 0.5), then round away from zero.
+--
+-- For instance:
+--
+-- * @1.3@ will be @1@
+-- * @1.5@ will be @2@ (because @abs 1 < abs 2@)
+-- * @1.7@ will be @2@
+-- * @2.3@ will be @2@
+-- * @2.5@ will be @3@ (because @abs 2 < abs 3@)
+-- * @2.7@ will be @3@
+-- * @-1.3@ will be @-1@
+-- * @-1.5@ will be @-2@ (because @abs (-1) < abs (-2)@)
+-- * @-1.7@ will be @-2@
+-- * @-2.3@ will be @-2@
+-- * @-2.5@ will be @-3@ (because @abs (-2) < abs (-3)@)
+-- * @-2.7@ will be @-3@
+--
+-- See 'sRationalToSIntegerRM' to select the rounding mode with a symbolic 'SRoundingMode'.
+sRationalToSIntegerRoundAway :: SRational -> SInteger
+sRationalToSIntegerRoundAway x
+  | Just i <- unliteral x
+  = literal $ roundAway i
+  | True
+  = ite
+      (x .>= 0)
+      (sRationalToSIntegerFloor   (x + half))
+      (sRationalToSIntegerCeiling (x - half))
+  where
+    half :: SRational
+    half = 0.5
+
+-- | Convert an SRational to an SInteger by converting to the nearest integer.
+-- If there is a tie (i.e., if the fractional component of the SRational is
+-- equal to 0.5), then round to the nearest even integer.
+--
+-- For instance:
+--
+-- * @1.3@ will be @1@
+-- * @1.5@ will be @2@ (because @2@ is even)
+-- * @1.7@ will be @2@
+-- * @2.3@ will be @2@
+-- * @2.5@ will be @2@ (because @2@ is even)
+-- * @2.7@ will be @3@
+-- * @-1.3@ will be @-1@
+-- * @-1.5@ will be @-2@ (because @-2@ is even)
+-- * @-1.7@ will be @-2@
+-- * @-2.3@ will be @-2@
+-- * @-2.5@ will be @-2@ (because @-2@ is even)
+-- * @-2.7@ will be @-3@
+--
+-- See 'sRationalToSIntegerRM' to select the rounding mode with a symbolic 'SRoundingMode'.
+sRationalToSIntegerRoundToEven :: SRational -> SInteger
+sRationalToSIntegerRoundToEven x
+  | Just i <- unliteral x
+  = literal $ round i
+  | True
+  = ite (diff .< half) lo $
+    ite (diff .> half) hi $
+    ite (sDivides 2 lo) lo hi
+  where
+    half :: SRational
+    half = 0.5
+
+    lo, hi :: SInteger
+    lo = sRationalToSIntegerFloor x
+    hi = lo+1
+
+    diff :: SRational
+    diff = x - (lo .% 1)
+
+-- | Convert an 'SRational' to an 'SInteger' according to the supplied
+-- 'SRoundingMode'. This dispatches to 'sRationalToSIntegerRoundToEven',
+-- 'sRationalToSIntegerRoundAway', 'sRationalToSIntegerCeiling',
+-- 'sRationalToSIntegerFloor', and 'sRationalToSIntegerTruncate' for the
+-- round-nearest-even, round-nearest-away, round-toward-positive,
+-- round-toward-negative, and round-toward-zero modes respectively.
+--
+-- Note that we re-use the 'SRoundingMode' type here, even though
+-- 'SRoundingMode' is normally associated with floating-point operations. The
+-- floating-point resemblance is superficial, as this function does not use any
+-- floating-point functionality behind the scenes.
+sRationalToSIntegerRM :: SRoundingMode -> SRational -> SInteger
+sRationalToSIntegerRM rm x =
+  sCaseRoundingMode
+    (sRationalToSIntegerRoundToEven x)
+    (sRationalToSIntegerRoundAway x)
+    (sRationalToSIntegerCeiling x)
+    (sRationalToSIntegerFloor x)
+    (sRationalToSIntegerTruncate x)
+    rm
+
+-- | Convert an 'SRational' to an 'SReal'. This conversion is always exact: the
+-- rational @t .% b@ maps to the real @t \/ b@. (Recall that denominators are
+-- always positive, so no division-by-zero can arise here.)
+sRationalToSReal :: SRational -> SReal
+sRationalToSReal = lift1 fromRational (\(t, b) -> sFromIntegral t / sFromIntegral b)
+
+-- | Convert an 'SReal' to an 'SRational'. The conversion is /exact/ for reals
+-- that are rational: a concrete rational is converted directly, while a
+-- symbolic (or non-literal) real is handled by introducing a fresh symbolic
+-- rational @r@ and constraining @'sRationalToSReal' r '.==' x@. Thus, whenever
+-- the input real is representable as the ratio of two integers, the result
+-- denotes exactly that same value---no precision is lost.
+--
+-- Note the caveat implied by this encoding: if the input real is /irrational/
+-- (i.e., not expressible as a ratio of two integers), then the introduced
+-- equality constraint is unsatisfiable, which renders the entire problem
+-- @UNSAT@. In other words, using this function is an implicit assertion that
+-- its argument is a rational number.
+sRealToSRational :: SReal -> SRational
+sRealToSRational x
+  | Just v <- unliteral x, isExactRational v
+  = literal (toRational v)
+  | True
+  = SBV $ SVal KRational $ Right $ cache res
+  where res st = do n <- newInternalVariable st KRational
+                    let r = SBV (SVal KRational (Right (cache (const (pure n))))) :: SRational
+                    internalConstraint st False [] $ unSBV $ sRationalToSReal r .== x
+                    pure n
+
 -- | Get the numerator. Note that this is always symbolic since we don't have a concrete representation.
 -- Furthermore this is only used internally and is not exported to the user, since it is not canonical.
 doNotExport_numerator :: SRational -> SInteger
@@ -64,6 +232,23 @@
   abs            = lift1 abs    (\(t, b) -> abs    t .% b)
   negate         = lift1 negate (\(t, b) -> negate t .% b)
   signum a       = ite (a .> 0) 1 $ ite (a .< 0) (-1) 0
+
+-- | Fractional instance for SRational. Just like the 'Num' instance, division is
+-- implemented at the SBV level via cross-multiplication, since SMTLib has no direct
+-- support for our rational representation. Note that we keep the denominator positive:
+-- dividing by @t2 .% b2@ multiplies the denominator by @t2@, which may be negative, so
+-- we flip the signs of both parts when needed. Following the SBV convention for reals,
+-- division by zero is defined to be zero.
+--
+-- We mark this @OVERLAPPING@ as it takes precedence over the generic instance in "Data.SBV.Core.Model",
+-- which would otherwise try to translate rational division as an SMTLib @Quot@ (which doesn't exist for our rationals).
+instance {-# OVERLAPPING #-} Fractional SRational where
+  fromRational = literal . fromRational
+  a / b        = ite (b .== 0) 0 (lift2 (/) divRat a b)
+    where divRat (t1, b1) (t2, b2) = ite (t2 .> 0) (        num .%         den)
+                                                   (negate  num .% negate  den)
+             where num = t1 * b2
+                   den = b1 * t2
 
 -- | Symbolic ordering for SRational. Note that denominators are always positive.
 instance OrdSymbolic SRational where
diff --git a/Data/SBV/RegExp.hs b/Data/SBV/RegExp.hs
--- a/Data/SBV/RegExp.hs
+++ b/Data/SBV/RegExp.hs
@@ -17,7 +17,6 @@
 {-# LANGUAGE CPP                 #-}
 {-# LANGUAGE FlexibleInstances   #-}
 {-# LANGUAGE OverloadedStrings   #-}
-{-# LANGUAGE Rank2Types          #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeApplications    #-}
 
@@ -57,6 +56,7 @@
 import qualified Data.List as L
 
 import Data.SBV.Core.Data
+import Data.SBV.Core.Symbolic (validateRegExp)
 
 import Data.SBV.List
 import qualified Data.Char as C
@@ -89,9 +89,28 @@
 -- >>> let phone = pre * "-" * post
 -- >>> sat $ \(s :: SString) -> s `match` phone
 -- Satisfiable. Model:
---   s0 = "800-8000" :: String
+--   s0 = "100-1000" :: String
+--
+-- Literal matching preserves concatenation: 'All' can consume any prefix,
+-- but the rest of the expression must still match the remaining suffix.
+--
+-- >>> ("a" :: SString) `match` Conc [All, "b"]
+-- False
+--
+-- Boolean operations apply to the same prefix, not to separate matches of
+-- the entire concatenation:
+--
+-- >>> ("ab" :: SString) `match` Conc [Diff "ab" "a", Opt "b"]
+-- True
+-- >>> ("ab" :: SString) `match` Conc [Inter "a" "ab", All]
+-- False
 class RegExpMatchable a where
    -- | @`match` s r@ checks whether @s@ is in the language generated by @r@.
+   -- Invalid 'Loop' or 'Power' bounds are rejected, including in unused branches.
+   -- An empty concatenation is the identity for concatenation:
+   --
+   -- >>> prove $ \(s :: SString) -> match s (Conc []) .== (s .== "")
+   -- Q.E.D.
    match :: a -> RegExp -> SBool
 
 -- | Matching a character simply means the singleton string matches the regex.
@@ -100,11 +119,12 @@
 
 -- | Matching symbolic strings.
 instance RegExpMatchable SString where
-   match input regExp = lift1 (StrInRe regExp) (Just (go regExp P.null)) input
-     where -- This isn't super efficient, but it gets the job done.
+   match input regExp = validateRegExp regExp `seq` lift1 (StrInRe regExp) (Just (go regExp P.null)) input
+     where -- Match a prefix of the input, then pass the remaining suffix to
+           -- the continuation. The initial continuation requires an empty suffix.
            go :: RegExp -> (String -> Bool) -> String -> Bool
            go (Literal l)    k s      = l `L.isPrefixOf` s && k (P.drop (P.length l) s)
-           go All            _ _      = True
+           go All            k s      = P.any k (L.tails s)
            go AllChar        k s      = not (P.null s) && k (P.drop 1 s)
            go None           _ _      = False
            go (Range _ _)    _ []     = False
@@ -114,15 +134,20 @@
            go (KStar r)      k s      = k s || go r (smaller (P.length s) (go (KStar r) k)) s
            go (KPlus r)      k s      = go (Conc [r, KStar r]) k s
            go (Opt r)        k s      = k s || go r k s
-           go (Comp r)       k s      = not $ go r k s
-           go (Diff r1 r2)   k s      = go r1 k s && not (go r2 k s)
+           go (Comp r)       k s      = matchingPrefix (not . go r P.null) k s
+           go (Diff r1 r2)   k s      = matchingPrefix (\p -> go r1 P.null p && not (go r2 P.null p)) k s
            go (Loop i j r)   k s      = go (Conc (P.replicate i r P.++ P.replicate (j - i) (Opt r))) k s
            go (Power n r)    k s      = go (Loop n n r) k s
            go (Union [])     _ _      = False
            go (Union [x])    k s      = go x k s
            go (Union (x:xs)) k s      = go x k s || go (Union xs) k s
-           go (Inter a b)    k s      = go a k s && go b k s
+           go (Inter a b)    k s      = matchingPrefix (\p -> go a P.null p && go b P.null p) k s
 
+           -- Boolean language operations must inspect exactly the same prefix.
+           -- Only after accepting that prefix may we check the continuation.
+           matchingPrefix :: (String -> Bool) -> (String -> Bool) -> String -> Bool
+           matchingPrefix accepts k s = P.or [accepts p && k suffix | (p, suffix) <- P.zip (L.inits s) (L.tails s)]
+
            -- In the KStar case, make sure the continuation is called with something
            -- smaller to avoid infinite recursion!
            smaller orig k inp = P.length inp < orig && k inp
@@ -167,7 +192,7 @@
 -- | Recognize a newline. Also includes carriage-return and form-feed.
 --
 -- >>> newline
--- (re.union (str.to.re "\n") (str.to.re "\r") (str.to.re "\f"))
+-- (re.union (str.to_re "\n") (str.to_re "\r") (str.to_re "\f"))
 -- >>> prove $ \c -> c `match` newline .=> isSpaceL1 c
 -- Q.E.D.
 newline :: RegExp
@@ -176,7 +201,7 @@
 -- | Recognize a tab.
 --
 -- >>> tab
--- (str.to.re "\t")
+-- (str.to_re "\t")
 -- >>> prove $ \c -> c `match` tab .=> c .== literal '\t'
 -- Q.E.D.
 tab :: RegExp
@@ -282,7 +307,7 @@
 -- | Recognize an octal number. Must have a prefix of the form @0o@\/@0O@.
 --
 -- >>> octal
--- (re.++ (re.union (str.to.re "0o") (str.to.re "0O")) (re.+ (re.range "0" "7")))
+-- (re.++ (re.union (str.to_re "0o") (str.to_re "0O")) (re.+ (re.range "0" "7")))
 -- >>> prove $ \(s :: SString) -> s `match` octal .=> sAny (.== take 2 s) ["0o", "0O"]
 -- Q.E.D.
 octal :: RegExp
@@ -291,7 +316,7 @@
 -- | Recognize a hexadecimal number. Must have a prefix of the form @0x@\/@0X@.
 --
 -- >>> hexadecimal
--- (re.++ (re.union (str.to.re "0x") (str.to.re "0X")) (re.+ (re.union (re.range "0" "9") (re.range "a" "f") (re.range "A" "F"))))
+-- (re.++ (re.union (str.to_re "0x") (str.to_re "0X")) (re.+ (re.union (re.range "0" "9") (re.range "a" "f") (re.range "A" "F"))))
 -- >>> prove $ \(s :: SString) -> s `match` hexadecimal .=> sAny (.== take 2 s) ["0x", "0X"]
 -- Q.E.D.
 hexadecimal :: RegExp
diff --git a/Data/SBV/SCase.hs b/Data/SBV/SCase.hs
new file mode 100644
--- /dev/null
+++ b/Data/SBV/SCase.hs
@@ -0,0 +1,1409 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Data.SBV.SCase
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Add support for symbolic case expressions. Constructed with the help of ChatGPT,
+-- which was remarkably good at giving me the basic structure.
+--
+-- Provides a quasiquoter  `[sCase| expr of ... |]` for symbolic cases
+-- where @Expr@ is the underlying type. Plain @case@ expressions inside
+-- @sCase@ are automatically treated as symbolic case-splits, enabling
+-- nested symbolic pattern matching.
+--
+-- Also provides `[pCase| expr of ... |]` for proof case-splits. Plain
+-- @case@ expressions inside @pCase@ are automatically treated as nested
+-- proof case-splits (generating @cases [...]@ calls).
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE LambdaCase            #-}
+{-# LANGUAGE TemplateHaskellQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Data.SBV.SCase (sCase, pCase) where
+
+import Language.Haskell.TH
+import Language.Haskell.TH.Quote
+import qualified Language.Haskell.Meta.Parse            as Meta
+import qualified Language.Haskell.Meta.Syntax.Translate as Meta
+
+import qualified Language.Haskell.Exts as E
+
+import Control.Monad (unless, when, zipWithM)
+
+import Data.SBV.Core.TH    (getConstructors, sbvName)
+import Data.SBV.Core.Model (ite, symWithKind)
+import Data.SBV.Core.Data  (sTrue, sNot, (.&&), (.||), (.==), (.===), (.:), literal)
+
+import Data.Char  (isDigit)
+import Data.List  (intercalate, stripPrefix)
+import Data.Maybe (isJust, fromMaybe, catMaybes)
+
+import Prelude hiding (fail)
+import qualified Prelude as P(fail)
+
+import Data.Generics (everywhereM, mkM)
+import qualified Data.Map.Strict as Map
+import qualified Data.Set as Set
+import Data.Set (Set)
+
+import System.FilePath
+
+-- | Conjoin a list of TH boolean expressions with (.&&), filtering out trivially true guards.
+sAndAll :: [Exp] -> Exp
+sAndAll = go . filter (not . isTriviallyTrue)
+  where go []  = VarE 'sTrue
+        go [g] = g
+        go gs  = foldr1 (\a b -> foldl1 AppE [VarE '(.&&), a, b]) gs
+
+        isTriviallyTrue (VarE nm) = nameBase nm == nameBase 'sTrue
+        isTriviallyTrue (ConE nm) = nameBase nm == "True"
+        isTriviallyTrue _         = False
+
+-- | TH parse trees don't have location. Let's have a simple mechanism to keep track of them for our use case
+data Offset = Unknown | OffBy Int Int Int
+ deriving Show
+
+-- | Better fail method, keeping track of offsets
+fail :: Offset -> String -> Q a
+fail Unknown     s = P.fail s
+fail off@OffBy{} s = do loc <- location
+                        P.fail (fmtLoc loc off ++ ": " ++  s)
+
+-- | Format a given location by the offset
+fmtLoc :: Loc -> Offset -> String
+fmtLoc loc@Loc{loc_start = (sl, _)} off = takeFileName (loc_filename newLoc) ++ ":" ++ sh (loc_start newLoc) (loc_end newLoc)
+  where sh ab@(a, b) cd@(c, d) | a == c = show a ++ ":" ++ show b ++ if b == d then "" else '-' : show d
+                               | True   = show ab ++ "-" ++ show cd
+
+        newLoc = case off of
+                   Unknown       -> loc
+                   OffBy lo co w -> loc {loc_start = (sl + lo, co + 1), loc_end = (sl + lo, co + w)}
+
+-- | Built-in types recognized by sCase/pCase. Maybe and Either do have mkSymbolic-generated
+-- infrastructure, but we treat them as built-in so that the generated code uses TH-quoted names
+-- (which resolve at SCase.hs compile time) instead of mkName-based references (which would
+-- require the user to have the testers/accessors in scope at the splice site).
+data BuiltinType = BTBool | BTMaybe | BTEither | BTList | BTTuple Int
+  deriving Show
+
+-- | Compare two Names by their base (unqualified) name. This is needed because
+-- built-in constructor names (created with mkName) won't match the fully-qualified
+-- names that GHC resolves patterns to (e.g., mkName "Nothing" vs GHC.Internal.Maybe.Nothing).
+-- Since constructor names are unique within a type, comparing by nameBase is safe.
+sameBase :: Name -> Name -> Bool
+sameBase a b = nameBase a == nameBase b
+
+-- | Lookup by nameBase instead of Name equality.
+lookupBase :: Name -> [(Name, a)] -> Maybe a
+lookupBase _  []          = Nothing
+lookupBase nm ((k,v):kvs)
+  | sameBase nm k = Just v
+  | True          = lookupBase nm kvs
+
+-- | Recognize built-in type names.
+recognizeBuiltin :: String -> Maybe BuiltinType
+recognizeBuiltin "Bool"   = Just BTBool
+recognizeBuiltin "Maybe"  = Just BTMaybe
+recognizeBuiltin "Either" = Just BTEither
+recognizeBuiltin "List"   = Just BTList
+recognizeBuiltin s
+  | Just n <- stripPrefix "Tuple" s, not (null n), all isDigit n, let k = read n, k >= 2, k <= 8
+  = Just (BTTuple k)
+recognizeBuiltin _ = Nothing
+
+-- | Recognize a constructor name as belonging to a built-in type. Used in flattenPat
+-- to generate TH-quoted tester/accessor references for nested built-in constructors.
+recognizeBuiltinCon :: String -> Maybe BuiltinType
+recognizeBuiltinCon "True"    = Just BTBool
+recognizeBuiltinCon "False"   = Just BTBool
+recognizeBuiltinCon "Nothing" = Just BTMaybe
+recognizeBuiltinCon "Just"    = Just BTMaybe
+recognizeBuiltinCon "Left"    = Just BTEither
+recognizeBuiltinCon "Right"   = Just BTEither
+recognizeBuiltinCon "[]"      = Just BTList
+recognizeBuiltinCon ":"       = Just BTList
+recognizeBuiltinCon _         = Nothing
+
+-- | Infer the type from the constructor names used in the pattern matches.
+-- Examines top-level patterns to find the first informative one (i.e., not a wildcard),
+-- then resolves the constructor via TH to determine the parent type.
+-- Returns 'Nothing' if all branches use wildcards (wildcard-only mode).
+inferType :: String -> [Match] -> Q (Maybe (String, Maybe BuiltinType))
+inferType label matches = case firstInfo matches of
+    Just (Left n)            -> pure $ Just ("Tuple" ++ show n, Just (BTTuple n))
+    Just (Right Nothing)     -> pure $ Just ("List", Just BTList)
+    Just (Right (Just name)) -> Just <$> resolveConType name
+    Nothing                  -> pure Nothing
+  where
+    -- Left n = tuple of arity n, Right Nothing = list, Right (Just name) = constructor name
+    firstInfo [] = Nothing
+    firstInfo (Match pat _ _ : rest) = case patInfo pat of
+                                         Just info -> Just info
+                                         Nothing   -> firstInfo rest
+
+    patInfo (ConP n _ _)                              = Just (Right (Just n))
+    patInfo (RecP n _)                                = Just (Right (Just n))
+    patInfo (InfixP _ n _)  | nameBase n == ":"       = Just (Right Nothing)
+    patInfo (UInfixP _ n _) | nameBase n == ":"       = Just (Right Nothing)
+    patInfo (TupP ps)                                 = Just (Left (length ps))
+    patInfo (ListP _)                                 = Just (Right Nothing)
+    patInfo (ParensP p)                               = patInfo p
+    patInfo (AsP _ p)                                 = patInfo p
+    patInfo _                                         = Nothing
+
+    -- Resolve a constructor name to its parent type via TH
+    resolveConType conName = do
+      let base = nameBase conName
+      -- Check if it's a known built-in constructor first (for cases where lookupValueName
+      -- might not resolve, e.g., "[]" as a value name)
+      case recognizeBuiltinCon base of
+        Just bt -> pure (builtinTypeName bt, Just bt)
+        Nothing -> do
+          mbResolved <- lookupValueName base
+          case mbResolved of
+            Nothing -> fail Unknown $ unlines [ label ++ ": Unknown constructor: " ++ base
+                                              , ""
+                                              , "        Cannot find this constructor in scope."
+                                              , "        Make sure the type is declared and mkSymbolic is called."
+                                              ]
+            Just resolved -> do
+              info <- reify resolved
+              case info of
+                DataConI _ _ parentName -> let typName = nameBase parentName
+                                           in pure (typName, recognizeBuiltin typName)
+                _ -> fail Unknown $ label ++ ": " ++ base ++ " is not a data constructor."
+
+    builtinTypeName BTBool      = "Bool"
+    builtinTypeName BTMaybe     = "Maybe"
+    builtinTypeName BTEither    = "Either"
+    builtinTypeName BTList      = "List"
+    builtinTypeName (BTTuple n) = "Tuple" ++ show n
+
+-- | Constructor info for a built-in type: (name, arity).
+builtinConstructors :: BuiltinType -> [(Name, Int)]
+builtinConstructors BTBool        = [(mkName "True", 0), (mkName "False", 0)]
+builtinConstructors BTMaybe       = [(mkName "Nothing", 0), (mkName "Just", 1)]
+builtinConstructors BTEither      = [(mkName "Left", 1), (mkName "Right", 1)]
+builtinConstructors BTList        = [(mkName "[]", 0), (mkName ":", 2)]
+builtinConstructors (BTTuple n)   = [(tupleDataName n, n)]
+
+-- | Generate a tester expression for a built-in type constructor.
+builtinTester :: BuiltinType -> Name -> Exp -> Exp
+builtinTester BTBool nm scrut
+  | nameBase nm == "True"  = scrut
+  | nameBase nm == "False" = AppE (VarE 'sNot) scrut
+builtinTester BTMaybe nm scrut
+  | nameBase nm == "Nothing" = AppE (VarE (sbvName "Data.SBV.Maybe" "isNothing")) scrut
+  | nameBase nm == "Just"    = AppE (VarE (sbvName "Data.SBV.Maybe" "isJust"))    scrut
+builtinTester BTEither nm scrut
+  | nameBase nm == "Left"  = AppE (VarE (sbvName "Data.SBV.Either" "isLeft"))  scrut
+  | nameBase nm == "Right" = AppE (VarE (sbvName "Data.SBV.Either" "isRight")) scrut
+builtinTester BTList nm scrut
+  | nameBase nm == "[]" = AppE (VarE (sbvName "Data.SBV.List" "null")) scrut
+  | nameBase nm == ":"  = AppE (VarE 'sNot) (AppE (VarE (sbvName "Data.SBV.List" "null")) scrut)
+builtinTester (BTTuple _) _ _ = VarE 'sTrue
+builtinTester bt nm _ = error $ "sCase: builtinTester: unexpected constructor " ++ nameBase nm ++ " for " ++ show bt
+
+-- | Generate an accessor expression for a built-in type constructor field.
+builtinAccessor :: BuiltinType -> Name -> Int -> Exp -> Exp
+builtinAccessor BTBool nm _ _ = error $ "sCase: builtinAccessor: Bool constructor " ++ nameBase nm ++ " has no fields"
+builtinAccessor BTMaybe nm i scrut
+  | nameBase nm == "Just", i == 1 = AppE (VarE (sbvName "Data.SBV.Maybe" "getJust_1")) scrut
+builtinAccessor BTEither nm i scrut
+  | nameBase nm == "Left",  i == 1 = AppE (VarE (sbvName "Data.SBV.Either" "getLeft_1"))  scrut
+  | nameBase nm == "Right", i == 1 = AppE (VarE (sbvName "Data.SBV.Either" "getRight_1")) scrut
+builtinAccessor BTList nm i scrut
+  | nameBase nm == ":", i == 1 = AppE (VarE (sbvName "Data.SBV.List" "head")) scrut
+  | nameBase nm == ":", i == 2 = AppE (VarE (sbvName "Data.SBV.List" "tail")) scrut
+builtinAccessor (BTTuple _) _ i scrut
+  -- Simplify _i (tuple (a, b, ...)) to just the i-th component
+  | AppE (VarE f) (TupE components) <- scrut
+  , nameBase f == "tuple"
+  , let cs = catMaybes components
+  , i >= 1, i <= length cs
+  = cs !! (i - 1)
+  | True
+  = AppE (VarE (tupleAccessorName i)) scrut
+  where tupleAccessorName 1 = sbvName "Data.SBV.Tuple" "_1"
+        tupleAccessorName 2 = sbvName "Data.SBV.Tuple" "_2"
+        tupleAccessorName 3 = sbvName "Data.SBV.Tuple" "_3"
+        tupleAccessorName 4 = sbvName "Data.SBV.Tuple" "_4"
+        tupleAccessorName 5 = sbvName "Data.SBV.Tuple" "_5"
+        tupleAccessorName 6 = sbvName "Data.SBV.Tuple" "_6"
+        tupleAccessorName 7 = sbvName "Data.SBV.Tuple" "_7"
+        tupleAccessorName 8 = sbvName "Data.SBV.Tuple" "_8"
+        tupleAccessorName n = error $ "sCase: tupleAccessorName: unsupported index " ++ show n
+builtinAccessor bt nm i _ = error $ "sCase: builtinAccessor: unexpected constructor " ++ nameBase nm ++ " field " ++ show i ++ " for " ++ show bt
+
+-- | Generate a tester expression for a constructor, dispatching to builtinTester for
+-- recognized built-in constructors or falling back to @is\<Con\>@ for user ADTs.
+mkTester :: Name -> Exp -> Exp
+mkTester nm scrut = case recognizeBuiltinCon (nameBase nm) of
+    Just bt -> builtinTester bt nm scrut
+    Nothing -> AppE (VarE (mkName ("is" ++ nameBase nm))) scrut
+
+-- | Generate an accessor expression for a constructor field, dispatching to builtinAccessor for
+-- recognized built-in constructors or falling back to @get\<Con\>_i@ for user ADTs.
+mkAccessor :: Name -> Int -> Exp -> Exp
+mkAccessor nm i scrut = case recognizeBuiltinCon (nameBase nm) of
+    Just bt -> builtinAccessor bt nm i scrut
+    Nothing -> AppE (VarE (mkName ("get" ++ nameBase nm ++ "_" ++ show i))) scrut
+
+-- | Like 'mkTester', but when the built-in type is already known from the scrutinee type.
+-- Used in top-level sCase/pCase code generation.
+mkTesterFor :: Maybe BuiltinType -> Name -> Exp -> Exp
+mkTesterFor (Just bt) nm scrut = builtinTester bt nm scrut
+mkTesterFor Nothing   nm scrut = AppE (VarE (mkName ("is" ++ nameBase nm))) scrut
+
+-- | Like 'mkAccessor', but when the built-in type is already known from the scrutinee type.
+mkAccessorFor :: Maybe BuiltinType -> Name -> Int -> Exp -> Exp
+mkAccessorFor (Just bt) nm i scrut = builtinAccessor bt nm i scrut
+mkAccessorFor Nothing   nm i scrut = AppE (VarE (mkName ("get" ++ nameBase nm ++ "_" ++ show i))) scrut
+
+-- | What kind of case-match are we given. In each case, the last maybe exp is the possible guard.
+data Case = CMatch Offset          -- regular match
+                   Name            -- name of the constructor
+                   (Maybe [Pat])   -- [a, b, c] in C a b c. Or Nothing if C{}
+                   (Maybe Exp)     -- guard
+                   Exp             -- rhs
+                   (Set Name)      -- All variables used all RHSs and All guards
+          | CWild  Offset          -- wild card
+                   (Maybe Exp)     -- guard
+                   Exp             -- rhs
+
+-- | What's the offset?
+caseOffset :: Case -> Offset
+caseOffset (CMatch o _ _ _ _ _) = o
+caseOffset (CWild  o       _ _) = o
+
+-- | Show a case nicely
+showCase :: Case -> String
+showCase = showCaseGen Nothing
+
+-- | Show a case nicely, with location
+showCaseGen :: Maybe Loc -> Case -> String
+showCaseGen mbLoc sc = case sc of
+                         CMatch _ c (Just ps) mbG _ _ -> loc ++ unwords (nameBase c : map pprint ps ++ shGuard mbG)
+                         CMatch _ c Nothing   mbG _ _ -> loc ++ unwords (nameBase c : "{}"           : shGuard mbG)
+                         CWild  _             mbG _   -> loc ++ unwords ("_"                         : shGuard mbG)
+ where shGuard Nothing  = []
+       shGuard (Just e) = ["|", pprint e]
+
+       loc = case mbLoc of
+               Nothing -> ""
+               Just l  -> fmtLoc l (caseOffset sc) ++ ": "
+
+-- | Get the name of the constructor, if any
+getCaseConstructor :: Case -> Maybe Name
+getCaseConstructor (CMatch _ nm _ _ _ _) = Just nm
+getCaseConstructor CWild{}               = Nothing
+
+-- | Get the guard, if any
+getCaseGuard :: Case -> Maybe Exp
+getCaseGuard (CMatch _ _ _ mbg _ _) = mbg
+getCaseGuard (CWild  _     mbg _  ) = mbg
+
+-- | Is there a guard?
+isGuarded :: Case -> Bool
+isGuarded = isJust . getCaseGuard
+
+-- | Find offset of each successive match. This isn't perfect, but it does the job
+findOffsets :: String -> [Offset]
+findOffsets s = analyze $ E.parseExpWithMode E.defaultParseMode $ "case ()" ++ tab ++ rest
+  where rest = relevant s
+        -- there's a chance the replication below might yield a negative value, which can make our
+        -- offset calculation slightly off. But this should be exceedingly rare because it'd have to be that
+        -- matches are on the same line and the "Type expr" part of the original must be shorter than 7 chars.
+        -- Let's ignore that possibility.
+        tab  = replicate (length s - length rest - 7) ' '
+        relevant r@(' ':'o':'f':_) = r
+        relevant ""                = ""
+        relevant (_:cs)            = relevant cs
+
+        analyze E.ParseFailed{} = [] -- Just ignore
+        analyze (E.ParseOk e)   = case e of
+                                   E.Case _ _ alts -> map getOff alts
+                                   _               -> []
+          where getOff (E.Alt l p _ _) = OffBy (E.srcSpanStartLine as - 1) (E.srcSpanStartColumn as - 1) w
+                   where as = E.srcInfoSpan l
+                         cs = E.srcInfoSpan (E.ann p)
+                         w  = E.srcSpanEndColumn cs - E.srcSpanStartColumn cs
+
+-- * Shared parsing infrastructure
+
+-- | Parse a Haskell expression using haskell-src-exts
+metaParse :: String -> Either String Exp
+metaParse = fmap Meta.toExp . Meta.parseResultToEither . E.parseExpWithMode pm
+  where pm = E.defaultParseMode { E.parseFilename = []
+                                , E.baseLanguage  = E.Haskell2010
+                                , E.extensions = map E.EnableExtension (exts ++ extras)
+                                }
+        exts = [ E.PostfixOperators
+               , E.QuasiQuotes
+               , E.UnicodeSyntax
+               , E.PatternSignatures
+               , E.MagicHash
+               , E.ForeignFunctionInterface
+               , E.TemplateHaskell
+               , E.RankNTypes
+               , E.MultiParamTypeClasses
+               , E.RecursiveDo
+               , E.TypeApplications
+               ]
+
+        -- The above just mimics the defaults. These our extras.
+        extras = [E.DataKinds]
+
+-- | Handle a metaParse error by mapping the parse-error column back to the source file.
+-- metaParse operates on @"case " <> src@ (5 extra chars), so we subtract 5 from its column.
+-- For line 1 errors, we also add the quasi-quote content's starting column since the first
+-- line of src is offset from the start of the source line. For subsequent lines, the columns
+-- in the quasi-quote content already correspond to source file columns.
+handleParseError :: String -> String -> Q a
+handleParseError label err = do
+    loc <- location
+    let qqCol = snd (loc_start loc) -- 1-based column where quasi-quote content starts
+    case lines err of
+      (_:locLine:res) | ["SrcLoc", _, l, c] <- words locLine, all isDigit l, all isDigit c
+         -> let mc    = read c
+                line  = read l
+                -- Line 1: column is relative to "case " <> src, need to add quasi-quote offset
+                -- Lines 2+: column is already a source file column (verbatim from source)
+                col = if line == 1 then qqCol + mc - 7 else mc - 1
+            in fail (OffBy (line - 1) col 1) (unlines res)
+      _  -> fail Unknown $ label ++ " parse error: " <> err
+
+
+-- | Extract guards from a match body
+getGuards :: Body -> [Dec] -> Q [(Maybe Exp, Exp)]
+getGuards (NormalB  rhs)  locals = pure [(Nothing, addLocals locals rhs)]
+getGuards (GuardedB exps) locals = mapM get exps
+  where get (NormalG e,  rhs)
+          | isSTrue e
+          = pure (Nothing, addLocals locals rhs)
+          | True
+          = pure (Just e, addLocals locals rhs)
+        get (PatG stmts, rhs)
+          | all isNoBindS stmts
+          = let guards = [e | NoBindS e <- stmts]
+                conj   = sAndAll guards
+            in pure (if isSTrue conj then Nothing else Just conj, addLocals locals rhs)
+          | True
+          = fail Unknown $ unlines $  "sCase/pCase: Pattern guards are not supported: "
+                                   : ["        " ++ pprint s | s <- stmts]
+          where isNoBindS (NoBindS _) = True
+                isNoBindS _           = False
+
+        -- Is this literally sTrue (or True)? This is a bit dangerous since
+        -- we just look at the base-name, but good enough
+        isSTrue (VarE  nm) = nameBase nm == nameBase 'sTrue
+        isSTrue (ConE  nm) = nameBase nm == "True"
+        isSTrue _          = False
+
+-- | Turn where clause into simple let
+addLocals :: [Dec] -> Exp -> Exp
+addLocals [] e = e
+addLocals ds e = LetE ds e
+
+-- | Given an occurrence of a name, find what it refers to
+getReference :: Offset -> Name -> Q Name
+getReference off refName = do mbN <- lookupValueName (nameBase refName)
+                              case mbN of
+                                Nothing -> fail off $ "sCase/pCase: Not in scope: data constructor: " <> pprint refName
+                                Just n  -> pure n
+
+-- | Convert a match into a list of cases
+matchToPair :: Exp -> Offset -> Match -> Q [Case]
+matchToPair scrut off (Match pat grhs locals) = do
+  rhss <- getGuards grhs locals
+  let allUsed = Set.unions (map (\(mbG, e) -> maybe Set.empty freeVars mbG `Set.union` freeVars e) rhss)
+
+      -- Common logic for constructor-like patterns: flatten sub-patterns, merge synthetic guards
+      flattenAndMerge :: Name -> (Int -> Exp) -> [Pat] -> Q [Case]
+      flattenAndMerge con accessor subpats = do
+          flatResults <- zipWithM (flattenPat off . accessor) [(1::Int)..] subpats
+          let ps      = map fstOf3 flatResults
+              subGrds = concatMap sndOf3 flatResults
+              subDecs = concatMap thdOf3 flatResults
+
+              merge (mbG, rhs) =
+                let usedInRhs  = freeVars rhs
+                    usedInGrd  = maybe Set.empty freeVars mbG
+                    decsFor s  = [ d | d@(ValD (VarP v) _ _) <- subDecs, v `Set.member` s ]
+                    rhs' = addLocals (decsFor usedInRhs) rhs
+                    mbG' = case (subGrds, mbG) of
+                              ([], Nothing) -> Nothing
+                              ([], Just g ) -> Just (addLocals (decsFor usedInGrd) g)
+                              (gs, Nothing) -> Just (sAndAll gs)
+                              (gs, Just g ) -> Just (sAndAll (gs ++ [addLocals (decsFor usedInGrd) g]))
+                in (mbG', rhs')
+
+          pure [CMatch off con (Just ps) mbG rhs allUsed | (mbG, rhs) <- map merge rhss]
+
+  case pat of
+    ConP conName _ subpats -> do
+      con <- getReference off conName
+      flattenAndMerge con (\i -> mkAccessor con i scrut) subpats
+
+    RecP conName []        -> do con <- getReference off conName
+                                 pure [CMatch off con Nothing   mbG rhs allUsed | (mbG, rhs) <- rhss]
+
+    WildP                  ->    pure [CWild  off               mbG rhs         | (mbG, rhs) <- rhss]
+
+    -- List cons pattern: y : ys  (InfixP or UInfixP from the parser)
+    InfixP p1 conName p2
+      | nameBase conName == ":" -> let con = mkName ":" in flattenAndMerge con (\i -> mkAccessorFor (Just BTList) con i scrut) [p1, p2]
+    UInfixP p1 conName p2
+      | nameBase conName == ":" -> let con = mkName ":" in flattenAndMerge con (\i -> mkAccessorFor (Just BTList) con i scrut) [p1, p2]
+
+    -- Tuple pattern: (a, b, ...)
+    TupP subpats -> do
+          let n   = length subpats
+              con = tupleDataName n
+          flattenAndMerge con (\i -> mkAccessorFor (Just (BTTuple n)) con i scrut) subpats
+
+    -- List nil pattern: []
+    ListP [] ->        pure [CMatch off (mkName "[]") (Just []) mbG rhs allUsed | (mbG, rhs) <- rhss]
+
+    -- List pattern with elements: [a], [a, b], etc. Desugar to nested cons: a : (b : [])
+    ListP ps -> let desugar []     = ListP []
+                    desugar (p:rest) = InfixP p (mkName ":") (desugar rest)
+                in matchToPair scrut off (Match (desugar ps) grhs locals)
+
+    -- Parenthesized pattern: unwrap and recurse
+    ParensP p -> matchToPair scrut off (Match p grhs locals)
+
+    -- Literal pattern at top level: 0, 1, "hello", etc.
+    -- Treated as a wildcard with a guard: scrut .== literal
+    LitP lit -> do eq <- litToEq off scrut lit
+                   pure [CWild off (Just (maybe eq (\g -> sAndAll [eq, g]) mbG)) rhs | (mbG, rhs) <- rhss]
+
+    -- Variable pattern at top level: binds the scrutinee (only when used)
+    VarP v   -> let bindScrut e | v `Set.member` freeVars e = LetE [ValD (VarP v) (NormalB scrut) []] e
+                                | True                      = e
+                in pure [CWild off (bindScrut <$> mbG) (bindScrut rhs) | (mbG, rhs) <- rhss]
+
+    -- As-pattern at top level: name@subpat — bind name to scrutinee, then process inner pattern
+    AsP name subpat -> do
+        cases <- matchToPair scrut off (Match subpat grhs locals)
+        let bindAs e | name `Set.member` freeVars e = LetE [ValD (VarP name) (NormalB scrut) []] e
+                     | True                         = e
+            addBind (CMatch o cn ps mbG' rhs' used) = CMatch o cn ps (bindAs <$> mbG') (bindAs rhs') used
+            addBind (CWild  o        mbG' rhs')     = CWild  o        (bindAs <$> mbG') (bindAs rhs')
+        pure (map addBind cases)
+
+    _ -> fail Unknown $ unlines [ "sCase/pCase: Unsupported pattern:"
+                                , "            Saw: " <> pprint pat
+                                , ""
+                                , "        Supported patterns: constructors (Cstr a b _ d),"
+                                , "        empty records (Cstr{}), wildcards (_), variables,"
+                                , "        as-patterns (x@pat), and integer/string literals."
+                                ]
+
+-- | Flatten a sub-pattern against a given accessor expression.
+-- Returns: a simple VarP/WildP for the flat pattern list, a list of
+-- synthetic isCstr guard expressions, and let-bindings that bring
+-- nested-pattern variables into scope.
+flattenPat :: Offset -> Exp -> Pat -> Q (Pat, [Exp], [Dec])
+flattenPat _   _   WildP                    = pure (WildP, [], [])
+flattenPat _   _   p@(VarP _)               = pure (p,     [], [])
+flattenPat off arg (ParensP p)              = flattenPat off arg p
+flattenPat off arg (ConP conName _ subpats) = do
+  con   <- getReference off conName
+  -- Arity check: reify the constructor to find its actual field count
+  DataConI _ conType parentName <- reify con
+  let arity = countArgs conType
+  unless (arity == length subpats) $
+    fail off $ unlines [ "sCase/pCase: Arity mismatch in nested pattern."
+                       , "        Constructor: " ++ nameBase con
+                       , "        Expected   : " ++ show arity
+                       , "        Given      : " ++ show (length subpats)
+                       ]
+  -- Check if the parent type has only one constructor; if so, the tester is trivially true
+  singleCon <- isSingleConstructorType parentName
+  let tester      = mkTester con arg
+      accessor i  = mkAccessor con i arg
+  subResults <- zipWithM (flattenPat off . accessor) [(1::Int)..] subpats
+  let subGrds = concatMap sndOf3 subResults
+      subDecs = concatMap thdOf3 subResults
+      subPats = map fstOf3 subResults
+      patDecs = [ ValD (VarP v) (NormalB (accessor i)) []
+                | (i, VarP v) <- zip [(1::Int)..] subPats ]
+      -- Skip the tester guard for single-constructor types (it's always true)
+      guards  = (if singleCon then id else (tester :)) subGrds
+  pure (WildP, guards, patDecs ++ subDecs)
+flattenPat off arg (LitP lit) = do
+  eq <- litToEq off arg lit
+  pure (WildP, [eq], [])
+-- Nested list cons pattern: x : xs (InfixP or UInfixP from the parser)
+flattenPat off arg (InfixP p1 conName p2)
+  | nameBase conName == ":" = flattenCons off arg p1 p2
+flattenPat off arg (UInfixP p1 conName p2)
+  | nameBase conName == ":" = flattenCons off arg p1 p2
+-- Nested empty list pattern: []
+flattenPat _   arg (ListP []) =
+  pure (WildP, [AppE (VarE (sbvName "Data.SBV.List" "null")) arg], [])
+-- Nested list pattern with elements: [a], [a, b], etc. Desugar to nested cons.
+flattenPat off arg (ListP (p:ps)) =
+  flattenPat off arg (InfixP p (mkName ":") (ListP ps))
+-- Nested tuple pattern: (a, b, ...)
+flattenPat off arg (TupP pats) = do
+  let n = length pats
+      accessor i = mkAccessorFor (Just (BTTuple n)) (tupleDataName n) i arg
+  subResults <- zipWithM (flattenPat off . accessor) [(1::Int)..] pats
+  let subGrds = concatMap sndOf3 subResults
+      subDecs = concatMap thdOf3 subResults
+      patDecs = [ ValD (VarP v) (NormalB (accessor i)) []
+                | (i, VarP v) <- zip [(1::Int)..] (map fstOf3 subResults) ]
+  pure (WildP, subGrds, patDecs ++ subDecs)
+-- Nested as-pattern: name@subpat — bind name to accessor, then process inner pattern
+flattenPat off arg (AsP name subpat) = do
+    (pat', guards, decs) <- flattenPat off arg subpat
+    let asDec = ValD (VarP name) (NormalB arg) []
+    pure (pat', guards, asDec : decs)
+-- Nested empty record pattern: Cstr{} — equivalent to Cstr with all wildcards
+flattenPat off arg (RecP conName []) = do
+    con <- getReference off conName
+    DataConI _ conType _ <- reify con
+    let arity = countArgs conType
+    flattenPat off arg (ConP con [] (replicate arity WildP))
+flattenPat o _ p = fail o $ unlines [ "sCase/pCase: Unsupported complex pattern match."
+                                    , "        Saw: " <> pprint p
+                                    , ""
+                                    , "      Only variables, wildcards, as-patterns, nested constructors, and integer/string literals are supported."
+                                    ]
+
+-- | Flatten a nested list cons pattern (x : xs) against an accessor expression.
+-- We include a destructuring equality (arg .=== head arg .: tail arg) because lists use
+-- SMT Seq, not declare-datatypes, so the solver doesn't automatically know this relationship.
+-- This is critical for pCase proof progress; harmless for sCase (redundant guard in ite-chain).
+-- NB. For top-level list cons patterns in pCase, the same equality is added by processProofCases.
+flattenCons :: Offset -> Exp -> Pat -> Pat -> Q (Pat, [Exp], [Dec])
+flattenCons off arg p1 p2 = do
+    let headExpr = mkAccessorFor (Just BTList) (mkName ":") 1 arg
+        tailExpr = mkAccessorFor (Just BTList) (mkName ":") 2 arg
+        tester   = mkTesterFor (Just BTList) (mkName ":") arg
+        destruct = foldl1 AppE [VarE '(.===), arg, InfixE (Just headExpr) (VarE '(.:)) (Just tailExpr)]
+    sub1 <- flattenPat off headExpr p1
+    sub2 <- flattenPat off tailExpr p2
+    let subGrds = sndOf3 sub1 ++ sndOf3 sub2
+        subDecs = thdOf3 sub1 ++ thdOf3 sub2
+        patDecs = [ ValD (VarP v) (NormalB headExpr) [] | VarP v <- [fstOf3 sub1] ]
+               ++ [ ValD (VarP v) (NormalB tailExpr) [] | VarP v <- [fstOf3 sub2] ]
+    pure (WildP, tester : destruct : subGrds, patDecs ++ subDecs)
+
+-- | Check if a type has only one constructor. Used to skip trivially-true tester guards
+-- in nested patterns (e.g., @Just (Pocket n3 n5)@ where @Pocket@ is the sole constructor).
+isSingleConstructorType :: Name -> Q Bool
+isSingleConstructorType tyName = do
+  info <- reify tyName
+  pure $ case info of
+    TyConI (DataD    _ _ _ _ [_] _) -> True
+    TyConI (NewtypeD {})            -> True
+    _                               -> False
+
+fstOf3 :: (a, b, c) -> a
+fstOf3 (a, _, _) = a
+
+sndOf3 :: (a, b, c) -> b
+sndOf3 (_, b, _) = b
+
+thdOf3 :: (a, b, c) -> c
+thdOf3 (_, _, c) = c
+
+-- | Get the constructor list for a type. For built-in types, return synthetic entries;
+-- for user ADTs, reify via getConstructors.
+getCstrs :: Maybe BuiltinType -> String -> Q [(Name, [Type])]
+getCstrs (Just bt) _   = pure [(nm, replicate ar WildCardT) | (nm, ar) <- builtinConstructors bt]
+getCstrs Nothing   typ = let dropFieldNames (c, nts) = (c, map snd nts)
+                          in map dropFieldNames . snd <$> getConstructors (mkName typ)
+
+-- | Validate wildcard placement: unguarded wildcard must be last.
+checkWildcard :: String -> Loc -> [Case] -> Q ()
+checkWildcard label loc cs = do go cs; checkExhaustive cs
+  where go []                         = pure ()
+        go (CMatch{}          : rest) = go rest
+        go (CWild _ Just{}  _ : rest) = go rest
+        go (CWild o Nothing _ : rest) =
+              case rest of
+                []  -> pure ()
+                red -> fail o $ unlines $ (label ++ ": Wildcard makes the remaining matches redundant:")
+                                         : ["        " ++ showCaseGen (Just loc) r | r <- red]
+
+        -- If all cases are wildcards (no CMatch), then we need an unguarded wildcard
+        -- as a catch-all. Otherwise, guarded-only wildcards on an infinite domain
+        -- (Integer, String, etc.) silently produce a free variable for unmatched cases.
+        checkExhaustive cases
+          | any isCMatch cases           = pure ()  -- Has constructor patterns; exhaustiveness checked elsewhere
+          | any isUnguardedWild cases    = pure ()  -- Has an unguarded catch-all
+          | True                         = fail (headOffset cases) $ unlines
+              [ label ++ ": Non-exhaustive pattern match."
+              , "        All branches are guarded; add an unguarded wildcard or variable"
+              , "        as the last branch to ensure all cases are covered."
+              ]
+
+        isCMatch CMatch{} = True
+        isCMatch _        = False
+
+        isUnguardedWild (CWild _ Nothing _) = True
+        isUnguardedWild _                   = False
+
+        headOffset (c:_) = caseOffset c
+        headOffset []    = Unknown
+
+-- | Validate that each constructor exists and has the right arity.
+checkArities :: String -> String -> [(Name, [Type])] -> [Case] -> Q ()
+checkArities label typ cstrs = mapM_ chk1
+  where chk1 c = case c of
+                    CMatch o nm ps _ _ _ -> isSafe o nm (length <$> ps)
+                    CWild  {}            -> pure ()
+        isSafe o nm mbLen
+          | Just ts <- lookupBase nm cstrs
+          = case mbLen of
+               Nothing  -> pure ()
+               Just cnt -> unless (length ts == cnt)
+                                $ fail o $ unlines [ label ++ ": Arity mismatch."
+                                                   , "        Type       : " ++ typ
+                                                   , "        Constructor: " ++ nameBase nm
+                                                   , "        Expected   : " ++ show (length ts)
+                                                   , "        Given      : " ++ show cnt
+                                                   ]
+          | True
+          = fail o $ unlines [ label ++ ": Unknown constructor:"
+                             , "        Type          : " ++ typ
+                             , "        Saw           : " ++ pprint nm
+                             , "        Must be one of: " ++ intercalate ", " (map (pprint . fst) cstrs)
+                             ]
+
+-- * sCase
+
+-- | Quasi-quoter for symbolic case expressions.
+sCase :: QuasiQuoter
+sCase = QuasiQuoter
+  { quoteExp  = extract
+  , quotePat  = bad "pattern"
+  , quoteType = bad "type"
+  , quoteDec  = bad "declaration"
+  }
+  where
+    bad ctx _ = fail Unknown $ "sCase: not usable in " <> ctx <> " context"
+
+    extract :: String -> ExpQ
+    extract src = do
+      let fullCase = "case " <> src
+          offsets  = findOffsets src
+      case metaParse fullCase of
+        Right (CaseE scrut matches) -> processCaseExp offsets scrut matches
+        Right _  -> fail Unknown "sCase: Parse error, cannot extract a case-expression."
+        Left err -> handleParseError "sCase" err
+
+-- | Core sCase pipeline: given a scrutinee and matches (already in TH AST form),
+-- run type inference, match conversion, validation, and code generation.
+-- Factored out of 'sCase' so that 'transformNestedCases' can call it for
+-- inner @case@ expressions.
+processCaseExp :: [Offset] -> Exp -> [Match] -> Q Exp
+processCaseExp offsets scrut0 matches0 = do
+    -- Transform any nested case expressions in the RHS/guards of each match.
+    -- This ensures inner cases become symbolic before the outer case processes them.
+    matches <- transformMatches matches0
+    scrut   <- transformNestedCases scrut0
+    mbTypeInfo <- inferType "sCase" matches
+    case mbTypeInfo of
+      Nothing -> do
+        -- Wildcard-only: no type needed, generate ite-chain directly
+        allCases <- concat <$> zipWithM (matchToPair scrut) (offsets ++ repeat Unknown) matches
+        loc <- location
+        checkWildcard "sCase" loc allCases
+        let wilds = [(mbG, rhs) | CWild _ mbG rhs <- allCases]
+            -- An unguarded wildcard is the base case (no ite wrapper needed).
+            -- checkWildcard guarantees an unguarded wildcard is last if present.
+            iteChain []                       = do uniq <- newName "u"
+                                                   let suffix = drop 2 (show uniq)
+                                                   pure $ AppE (VarE 'symWithKind) (LitE (StringL ("unmatched_sCase_wildcard_" ++ suffix)))
+            iteChain ((Nothing, rhs) : _)     = pure rhs
+            iteChain ((Just g,  rhs) : rest)  = do r <- iteChain rest
+                                                   pure $ foldl AppE (VarE 'ite) [g, rhs, r]
+        iteChain wilds
+      Just (typ, mbt) -> do
+        mbFnName <- case mbt of
+          Just BTBool      -> pure Nothing
+          Just BTList      -> pure Nothing  -- Strategy B; see noAnalyzer comment above
+          Just BTMaybe     -> pure (Just (VarE (sbvName "Data.SBV.Maybe"  "sCaseMaybe")))
+          Just BTEither    -> pure (Just (VarE (sbvName "Data.SBV.Either" "sCaseEither")))
+          Just (BTTuple _) -> pure Nothing
+          Nothing -> let fnTok = "sCase" <> typ
+                     in lookupValueName fnTok >>= \case
+                          Just n  -> pure (Just (VarE n))
+                          Nothing -> fail Unknown $ unlines [ "sCase: Unknown symbolic ADT: " <> typ
+                                                            , ""
+                                                            , "        To use a symbolic case expression, declare your ADT, and then:"
+                                                            , "             mkSymbolic [''" <> typ <> "]"
+                                                            , "        In a template-haskell context."
+                                                            ]
+        let anyUserGuards = any (\(Match _ grhs _) -> case grhs of { GuardedB{} -> True; _ -> False }) matches
+        cases <- zipWithM (matchToPair scrut) (offsets ++ repeat Unknown) matches >>= checkCase scrut typ mbt anyUserGuards . concat
+        buildCase typ mbFnName scrut cases
+  where
+    buildCase :: String -> Maybe Exp -> Exp -> Either [Exp] [(Exp, Exp)] -> ExpQ
+    buildCase _    (Just caseFunc) s (Left  cases) = pure $ AppE (foldl AppE caseFunc cases) s
+    buildCase _    Nothing         _     (Left  _)     = error "sCase: impossible: Strategy A without case function"
+    buildCase typ  _               _scrut (Right cases) = do
+        uniq <- newName "u"
+        let suffix = drop 2 (show uniq)
+            fallback  = AppE (VarE 'symWithKind) (LitE (StringL ("unmatched_sCase_" ++ typ ++ "_" ++ suffix)))
+
+            iteChain []              = pure fallback
+            iteChain ((t, e) : rest)
+              -- Last branch with a trivially-true guard (e.g., unguarded wildcard, or the last
+              -- constructor in a complete match): use its rhs directly as the default,
+              -- avoiding an unreachable fallback variable.
+              | null rest, isTriviallyTrue t = pure e
+              | True                         = do r <- iteChain rest
+                                                  pure $ foldl AppE (VarE 'ite) [t, e, r]
+
+            isTriviallyTrue (VarE nm) = nameBase nm == nameBase 'sTrue
+            isTriviallyTrue (ConE nm) = nameBase nm == "True"
+            isTriviallyTrue _         = False
+        iteChain cases
+
+    -- Make sure things are in good-shape and decide if we have guards
+    checkCase :: Exp -> String -> Maybe BuiltinType -> Bool -> [Case] -> Q (Either [Exp] [(Exp, Exp)])
+    checkCase s typ mbt anyUserGuards cases = do
+        loc   <- location
+        cstrs <- getCstrs mbt typ
+
+        -- Is there a catch all clause?
+        let hasCatchAll = or [True | CWild _ Nothing _ <- cases]
+
+        checkWildcard "sCase" loc cases
+        checkArities  "sCase" typ cstrs cases
+
+        -- Step 2: Make sure constructor matches are not overlapping
+        let problem w extras x = fail (caseOffset x) $ unlines $ [ "sCase: " ++ w ++ ":"
+                                                                 , "        Type       : " ++ typ
+                                                                 , "        Constructor: " ++ showCase x
+                                                                 ]
+                                                              ++ [ "      " ++ e | e <- extras]
+
+            overlap x xs = problem "Overlapping case constructors" extras x
+              where extras = "Overlaps with:" : ["  " ++ p | p <- map (showCaseGen (Just loc)) xs]
+
+            unmatched x
+             | isGuarded x = problem "Non-exhaustive match" ["NB. Guarded match might fail."] x
+             | True        = problem "Non-exhaustive match" []                                x
+
+            nonExhaustive o cstr = fail o $ unlines [ "sCase: Pattern match(es) are non-exhaustive."
+                                                    , "        Not matched     : " ++ nameBase cstr
+                                                    , "        Patterns of type: " ++ typ
+                                                    , "        Must match each : " ++ intercalate ", " (map (nameBase . fst) cstrs)
+                                                    , ""
+                                                    , "      You can use a '_' to match multiple cases."
+                                                    ]
+            -- We're done
+            chk2 _ [] = pure ()
+
+            -- If we have a non-guarded match, then there must be no matches for this constructor later on. If so, they're redundant.
+            chk2 seen (c@(CMatch _ nm _ Nothing _ _) : rest)
+              = case filter (maybe False (sameBase nm) . getCaseConstructor) rest of
+                  [] -> chk2 (Set.insert (nameBase nm) seen) rest
+                  os -> overlap (last os) (c : init os)
+
+            -- If we have a guarded match, then this guard can fail. So either there must be a match
+            -- for it later on, or there must be a catch-all. We also accept it if the same constructor
+            -- was seen earlier (e.g., multiple nested-pattern alternatives like Left (x:_) / Left []).
+            chk2 seen (c@(CMatch _ nm _ Just{} _ _) : rest)
+              | hasCatchAll || any (maybe False (sameBase nm) . getCaseConstructor) rest || nameBase nm `Set.member` seen
+              = chk2 (Set.insert (nameBase nm) seen) rest
+              | True
+              = unmatched c
+
+            -- If there's a guarded wildcard, must make sure there's a catch all afterwards
+            chk2 seen (c@(CWild _ Just{} _) : rest)
+              | hasCatchAll
+              = chk2 seen rest
+              | True
+              = unmatched c
+
+            -- No need to worry about anything following catch-all, since we already covered that before
+            chk2 seen (CWild _ Nothing _ : rest) = chk2 seen rest
+
+        chk2 Set.empty cases
+
+        -- At this point, we either have a simple case with no guards, in which case
+        -- we translate this to an sCase for that type. So find all alternatives.
+        -- Otherwise, this will become an ite-chain.
+        -- Bool, List, and Tuple use the ite-chain path (Strategy B) directly.
+        -- List is excluded from Strategy A because the case-analysis combinator 'list' is itself
+        -- a candidate for sCase rewriting; calling it here would create a circular dependency.
+        -- Maybe, Either, and user ADTs can use Strategy A (calling sCaseMaybe/sCaseEither/sCaseADT).
+        let hasGuards    = any isGuarded cases
+            noAnalyzer   = case mbt of { Just BTBool -> True; Just BTList -> True; Just (BTTuple _) -> True; _ -> False }
+            useIteChain  = hasGuards || noAnalyzer
+
+        if not useIteChain
+           then do defaultCase <- case [((e, mbg), c) | c@(CWild _ mbg e) <- cases] of
+                                    []                  -> pure Nothing
+                                    [((e, Nothing), c)] -> pure $ Just (caseOffset c, e)
+                                    cs@((_, c):_)       -> fail (caseOffset c)
+                                                         $ unlines $   "sCase: Impossible happened; found unexpected cases:"
+                                                                   :  [ "        " ++ showCase curc | curc <- map snd cs]
+                                                                   ++ [ ""
+                                                                      , "      Please report this as a bug."
+                                                                      ]
+                   let find _ []     = Nothing
+                       find w (c:cs)
+                         | mtches = Just c
+                         | True   = find w cs
+                         where mtches = case c of
+                                          CMatch _ nm _ _ _ _ -> sameBase nm w
+                                          CWild  {}           -> False
+
+                       case2rhs :: Case -> [Type] -> (Maybe Exp, Exp)
+                       case2rhs cs ts = (LamE pats <$> mbGuard, LamE pats e)
+                         where (mbGuard, e, pats) = case cs of
+                                                      CMatch _ _ (Just ps) mbG rhs _ -> (mbG, rhs, ps)
+                                                      CMatch _ _ Nothing   mbG rhs _ -> (mbG, rhs, map (const WildP) ts)
+                                                      CWild  _             mbG rhs   -> (mbG, rhs, map (const WildP) ts)
+
+                       collect (cstr, ts)
+                         | Just e <- find cstr cases
+                         = pure $ case2rhs e ts
+                         | True
+                         = case defaultCase of
+                             Nothing -> nonExhaustive Unknown cstr
+                             Just (_, de) -> do let ps = map (const WildP) ts
+                                                pure (Nothing, LamE ps de)
+
+                   res <- mapM collect cstrs
+
+                   -- If we reached here, all is well; except we might have an extra wildcard that we did not use
+                   when (length cases > length cstrs) $
+                     case defaultCase of
+                       Nothing     -> pure ()
+                       Just (o, _) -> fail o "sCase: Wildcard match is redundant"
+
+                   -- Double check that we had no guards and return the cases
+                   case [r | (Just{}, r) <- res] of
+                     [] -> pure $ Left $ map snd res
+                     rs -> fail Unknown $ unlines $    "sCase: Impossible happened; found a guard in no-guard case."
+                                                  :  [ "        " ++ pprint r | r <- rs]
+                                                  ++ [ ""
+                                                    , "      Please report this as a bug."
+                                                    ]
+
+           else do -- We have guards.
+                   defaultCase <- case [(c, e) | c@(CWild _ Nothing e) <- cases] of
+                                    []         -> pure Nothing
+                                    ((c, e):_) -> pure $ Just (caseOffset c, e)
+
+                   -- Collect, for each constructor, the corresponding cases:
+                   let cstrMatches :: [(Name, ([Type], [Case]))]
+                       cstrMatches = map (\(cstr, ts) -> (cstr, (ts, concatMap (mtches cstr) cases))) cstrs
+                         where mtches cstr c | Just n <- getCaseConstructor c, sameBase n cstr = [c]
+                                             | True                                            = []
+
+                   -- Make sure we have a match for every constructor or a catch-all
+                   unless hasCatchAll $ case [nm | (nm, (_, [])) <- cstrMatches] of
+                                          []    -> pure ()
+                                          (x:_) -> nonExhaustive Unknown x
+
+                   -- If every constructor have a full match, then catch-all, if exists, is redundant:
+                   case defaultCase of
+                     Nothing     -> pure ()
+                     Just (o, _)
+                       | map fst cstrs == [nm | (nm, (_, cs)) <- cstrMatches, not (all isGuarded cs)]
+                       -> fail o "sCase: Wildcard match is redundant"
+                       | True
+                       -> pure ()
+
+                   let collect :: Case -> Q (Exp, Exp)
+                       collect (CWild  _        mbG rhs        ) = pure (fromMaybe (VarE 'sTrue) mbG, rhs)
+                       collect (CMatch o nm mbp mbG rhs allUsed) = do
+                           case lookupBase nm cstrs of
+                             Nothing -> fail o $ unlines [ "sCase: Impossible happened."
+                                                         , "        Unable to determine params for: " <> pprint nm
+                                                         ]
+                             Just ts -> do let pats = fromMaybe (map (const WildP) ts) mbp
+                                               args = [mkAccessorFor mbt nm i s | (i, _) <- zip [(1 :: Int) ..] ts]
+                                               testerExpr = mkTesterFor mbt nm s
+
+                                               -- What are the free variables in the guard and the rhs that we bind?
+                                               used    = Set.fromList [n | VarP n <- pats] `Set.intersection` allUsed
+                                               close e = foldr1 (AppE . AppE (VarE 'const)) (e:extras)
+                                                 where extras = map VarE $ Set.toList (used Set.\\ freeVars e)
+
+                                               mkApp f | null pats = f
+                                                       | True      = foldl AppE (LamE pats f) args
+
+                                               grd :: Exp
+                                               grd = case mbG of
+                                                       Nothing -> testerExpr
+                                                       Just g  -> sAndAll [testerExpr, mkApp (close g)]
+
+                                           pure (grd, mkApp (close rhs))
+
+                   pairs <- mapM collect cases
+
+                   -- When every constructor has at least one unguarded match, the pattern
+                   -- is exhaustive. The last entry's tester is then redundant — replace it
+                   -- with sTrue so buildCase uses it as the default, avoiding an unreachable
+                   -- fallback variable.
+                   -- For single-constructor types (tuples), all branches match the sole
+                   -- constructor, with guards from nested patterns only. When there are no
+                   -- user-provided guards, the nested patterns partition the space and the
+                   -- last branch is the default.
+                   let allCovered = all hasUnguarded cstrs
+                                 || (length cstrs == 1 && not anyUserGuards)
+                       hasUnguarded (cstr, _) = any (\case CMatch _ nm _ Nothing _ _ -> sameBase nm cstr; _ -> False) cases
+                       optimize ps | allCovered, not (null ps)
+                                   = init ps ++ [(VarE 'sTrue, snd (last ps))]
+                                   | True      = ps
+
+                   pure $ Right (optimize pairs)
+
+-- | Transform nested @case@ expressions inside a TH 'Exp' into symbolic case expressions.
+-- Walks the expression bottom-up: inner cases are transformed before outer ones.
+-- This is what enables @case@ expressions inside @[sCase| ... |]@ to work as symbolic cases.
+transformNestedCases :: Exp -> Q Exp
+transformNestedCases = everywhereM (mkM go)
+  where go :: Exp -> Q Exp
+        go (CaseE s ms) = processCaseExp (repeat Unknown) s ms
+        go e            = pure e
+
+-- | Transform nested @case@ expressions inside a TH 'Exp' into proof case-splits.
+-- Like 'transformNestedCases', but generates @cases [cond ==> rhs, ...]@ instead of
+-- @ite@ chains. This is what enables @case@ expressions inside @[pCase| ... |]@ to work
+-- as nested proof case-splits.
+transformNestedCasesProof :: Exp -> Q Exp
+transformNestedCasesProof = everywhereM (mkM go)
+  where go :: Exp -> Q Exp
+        go (CaseE s ms) = processProofCaseExp s ms
+        go e            = pure e
+
+-- | Transform the matches of an outer sCase expression, resolving any nested
+-- @case@ expressions in the RHS and guards before the outer case processes them.
+transformMatches :: [Match] -> Q [Match]
+transformMatches = transformMatchesWith transformNestedCases
+
+-- | Transform the matches of an outer pCase expression, resolving any nested
+-- @case@ expressions in the RHS and guards as proof case-splits.
+transformMatchesProof :: [Match] -> Q [Match]
+transformMatchesProof = transformMatchesWith transformNestedCasesProof
+
+-- | Generic match transformer parameterized by the nested-case handler.
+transformMatchesWith :: (Exp -> Q Exp) -> [Match] -> Q [Match]
+transformMatchesWith xform = mapM transformMatch
+  where transformMatch (Match pat body locals) = do
+          body'   <- transformBody body
+          locals' <- mapM transformDec locals
+          pure (Match pat body' locals')
+
+        transformBody (NormalB e)    = NormalB <$> xform e
+        transformBody (GuardedB gs)  = GuardedB <$> mapM transformGuarded gs
+
+        transformGuarded (g, e) = do g' <- transformGuard g
+                                     e' <- xform e
+                                     pure (g', e')
+
+        transformGuard (NormalG e) = NormalG <$> xform e
+        transformGuard (PatG ss)   = PatG <$> mapM transformStmt ss
+
+        transformStmt (NoBindS e)  = NoBindS <$> xform e
+        transformStmt s            = pure s
+
+        transformDec (ValD p b ls) = do b'  <- transformBody b
+                                        ls' <- mapM transformDec ls
+                                        pure (ValD p b' ls')
+        transformDec (FunD n cs)   = FunD n <$> mapM transformClause cs
+        transformDec d             = pure d
+
+        transformClause (Clause ps b ls) = do b'  <- transformBody b
+                                              ls' <- mapM transformDec ls
+                                              pure (Clause ps b' ls')
+
+-- | Core proof-case pipeline: given a scrutinee and matches (in TH AST form),
+-- generate @cases [cond ==> rhs, ...]@. This is the proof-level counterpart of
+-- 'processCaseExp', used by 'transformNestedCasesProof' to handle inner @case@
+-- expressions inside @[pCase| ... |]@.
+processProofCaseExp :: Exp -> [Match] -> Q Exp
+processProofCaseExp scrut0 matches0 = do
+    -- Recursively transform any nested case expressions as proof case-splits.
+    matches <- transformMatchesProof matches0
+    scrut   <- transformNestedCasesProof scrut0
+    mbTypeInfo <- inferType "pCase" matches
+    let offsets = repeat Unknown
+    case mbTypeInfo of
+      Nothing -> do
+        allCases <- concat <$> zipWithM (matchToPair scrut) (offsets ++ repeat Unknown) matches
+        loc <- location
+        checkWildcard "pCase" loc allCases
+        allPairs <- processProofCases scrut [] Nothing [] allCases
+        let casesName   = mkName "cases"
+            impliesName = mkName "==>"
+            mkPair (g, r) = InfixE (Just g) (VarE impliesName) (Just r)
+        pure $ AppE (VarE casesName) (ListE (map mkPair allPairs))
+      Just (typ, mbt) -> do
+        cs <- zipWithM (matchToPair scrut) (offsets ++ repeat Unknown) matches
+        let cases = concat cs
+        loc <- location
+        cstrs <- getCstrs mbt typ
+        checkWildcard "pCase" loc cases
+        checkArities  "pCase" typ cstrs cases
+        allPairs <- processProofCases scrut cstrs mbt [] cases
+        let casesName   = mkName "cases"
+            impliesName = mkName "==>"
+            mkPair (g, r) = InfixE (Just g) (VarE impliesName) (Just r)
+        pure $ AppE (VarE casesName) (ListE (map mkPair allPairs))
+
+-- * pCase
+
+-- | Quasi-quoter for proof case-splits.
+--
+-- Like 'sCase', but generates @cases [cond ==> proof, ...]@ instead of
+-- @ite@ chains. Wildcards are allowed as the last scrutinee (with or
+-- without guards), and exhaustiveness is checked at proof time by the
+-- @cases@ combinator rather than at compile time.
+--
+-- Guards within the same constructor accumulate negations: a second guard
+-- implicitly assumes the first guard failed. A wildcard guard is the
+-- negation of the disjunction of all prior guards (De Morgan).
+pCase :: QuasiQuoter
+pCase = QuasiQuoter
+  { quoteExp  = extractProof
+  , quotePat  = bad "pattern"
+  , quoteType = bad "type"
+  , quoteDec  = bad "declaration"
+  }
+  where
+    bad ctx _ = fail Unknown $ "pCase: not usable in " <> ctx <> " context"
+
+    extractProof :: String -> ExpQ
+    extractProof src = do
+      let fullCase = "case " <> src
+          offsets  = findOffsets src
+      case metaParse fullCase of
+        Right (CaseE scrut0 matches0) -> do
+          -- Transform any nested case expressions in the RHS/guards of each match.
+          -- Inner case expressions become proof case-splits (cases [...]),
+          -- just like inner cases in sCase become symbolic ite-chains.
+          matches <- transformMatchesProof matches0
+          scrut   <- transformNestedCasesProof scrut0
+          mbTypeInfo <- inferType "pCase" matches
+          case mbTypeInfo of
+            Nothing -> do
+              -- Wildcard-only: no type needed, build proof cases directly
+              allCases <- concat <$> zipWithM (matchToPair scrut) (offsets ++ repeat Unknown) matches
+              loc <- location
+              checkWildcard "pCase" loc allCases
+              allPairs <- processProofCases scrut [] Nothing [] allCases
+              let casesName   = mkName "cases"
+                  impliesName = mkName "==>"
+                  mkPair (g, r) = InfixE (Just g) (VarE impliesName) (Just r)
+              pure $ AppE (VarE casesName) (ListE (map mkPair allPairs))
+            Just (typ, mbt) -> do
+              cs <- zipWithM (matchToPair scrut) (offsets ++ repeat Unknown) matches
+              validated <- checkProofCase typ mbt (concat cs)
+              buildProofCase scrut typ mbt validated
+        Right _  -> fail Unknown "pCase: Parse error, cannot extract a case-expression."
+        Left err -> handleParseError "pCase" err
+
+    -- | Validate cases for proof context
+    checkProofCase :: String -> Maybe BuiltinType -> [Case] -> Q [Case]
+    checkProofCase typ mbt cases = do
+        loc <- location
+        cstrs <- getCstrs mbt typ
+
+        checkWildcard "pCase" loc cases
+        checkArities  "pCase" typ cstrs cases
+
+        -- Wildcards must come after all explicit constructor matches
+        let checkWildBeforeCstr [] = pure ()
+            checkWildBeforeCstr (CWild o _ _ : rest)
+              | any (\case CMatch{} -> True; _ -> False) rest
+              = fail o $ unlines $ "pCase: Wildcard must come after all constructor matches:"
+                                 : ["        " ++ showCaseGen (Just loc) r | r <- filter (\case CMatch{} -> True; _ -> False) rest]
+            checkWildBeforeCstr (_ : rest) = checkWildBeforeCstr rest
+        checkWildBeforeCstr cases
+
+        -- Check overlap: unguarded constructor match followed by same constructor
+        let chk2 [] = pure ()
+            chk2 (c@(CMatch _ nm _ Nothing _ _) : rest)
+              = case filter (maybe False (sameBase nm) . getCaseConstructor) rest of
+                  [] -> chk2 rest
+                  os -> overlap loc (last os) (c : init os)
+            chk2 (_ : rest) = chk2 rest
+
+        chk2 cases
+
+        -- If every constructor has an unguarded match, any wildcard is redundant
+        let fullyCovered = [ cstr | (cstr, _) <- cstrs
+                                  , any (\c -> maybe False (sameBase cstr) (getCaseConstructor c) && not (isGuarded c)) cases
+                                  ]
+        case [c | c@CWild{} <- cases] of
+          []    -> pure ()
+          (c:_) | length fullyCovered == length cstrs
+                -> fail (caseOffset c) "pCase: Wildcard match is redundant"
+                | True
+                -> pure ()
+
+        -- No exhaustiveness check: the `cases` combinator checks completeness at proof time.
+        pure cases
+
+    overlap loc x xs = fail (caseOffset x) $ unlines $ [ "pCase: Overlapping case constructors:"
+                                                        , "        Constructor: " ++ showCase x
+                                                        ]
+                                                     ++ [ "      Overlaps with:" ]
+                                                     ++ [ "        " ++ showCaseGen (Just loc) p | p <- xs]
+
+    -- | Build the proof case expression
+    buildProofCase :: Exp -> String -> Maybe BuiltinType -> [Case] -> ExpQ
+    buildProofCase scrut typ mbt cases = do
+        cstrs <- getCstrs mbt typ
+        allPairs <- processProofCases scrut cstrs mbt [] cases
+        let casesName   = mkName "cases"
+            impliesName = mkName "==>"
+            mkPair (g, r) = InfixE (Just g) (VarE impliesName) (Just r)
+        pure $ AppE (VarE casesName) (ListE (map mkPair allPairs))
+
+-- * Proof case processing
+
+-- | Process all proof cases linearly, accumulating prior guards.
+-- Shared between the top-level @pCase@ quasi-quoter and 'processProofCaseExp'
+-- (which handles nested @case@ expressions inside @[pCase| ... |]@).
+--
+-- Prior guards are tagged with their constructor name (Nothing for wildcards).
+-- Each entry stores (constructor, fullGuard, userGuardOnly):
+--
+--   * fullGuard    = the complete guard expression (used for wildcard De Morgan negation)
+--   * userGuardOnly = Just the user guard part (used for same-constructor negation),
+--                     Nothing if unguarded (same-constructor arms don't negate unguarded matches)
+processProofCases :: Exp -> [(Name, [Type])] -> Maybe BuiltinType -> [(Maybe Name, Exp, Maybe Exp)] -> [Case] -> Q [(Exp, Exp)]
+processProofCases scrut cstrs mbt priorGuards0 cases0 = go priorGuards0 cases0
+  where
+    -- Aggregate, per constructor, the variables used in any guard or RHS across all arms with that constructor.
+    -- A pattern var used in *some* same-constructor arm but not in *this* arm's RHS is dropped from the
+    -- RHS bindings (the guard handles its own bindings via 'grdBindings'), avoiding false unused-binding
+    -- warnings. A pattern var truly unused everywhere is kept so GHC can flag the user oversight.
+    cstrUsedVars :: Map.Map Name (Set Name)
+    cstrUsedVars = Map.fromListWith Set.union
+                     [ (nm, allUsed) | CMatch _ nm _ _ _ allUsed <- cases0 ]
+
+    go _           []         = pure []
+    go priorGuards (c:rest) = case c of
+      CWild _ mbG rhs -> do
+        -- Wildcard: negate the disjunction of ALL prior full guards (De Morgan)
+        let allGuards  = [g | (_, g, _) <- priorGuards]
+            baseGuard  = negateAllGuards allGuards
+            finalGuard = case mbG of
+                           Nothing -> baseGuard
+                           Just g  -> sAndAll [baseGuard, g]
+        rest' <- go (priorGuards ++ [(Nothing, finalGuard, Nothing)]) rest
+        pure $ (finalGuard, rhs) : rest'
+
+      CMatch _o nm mbp mbG rhs _allUsed -> do
+        let ts   = case lookupBase nm cstrs of
+                     Just t  -> t
+                     Nothing -> error $ "pCase: impossible: unknown constructor " ++ nameBase nm
+            pats = fromMaybe (map (const WildP) ts) mbp
+
+            -- Build let-bindings for pattern variables
+            args    = [(i, mkAccessorFor mbt nm i scrut) | (i, _) <- zip [(1 :: Int) ..] ts]
+            bindings = [ ValD (VarP v) (NormalB acc) []
+                       | (i, acc) <- args, VarP v <- [pats !! (i - 1)] ]
+
+            testerGuard = mkTesterFor mbt nm scrut
+
+            -- For list cons patterns in pCase, add a destructuring equality:
+            --   scrut .=== head scrut .: tail scrut
+            -- Lists use SMT Seq (not declare-datatypes), so the solver doesn't automatically
+            -- know that xs = head xs .: tail xs from sNot (null xs). We must add an explicit
+            -- equality to give the solver this information, mirroring what 'split' does.
+            -- All other types (ADTs, Maybe, Either, Tuple) use declare-datatypes and get
+            -- these axioms for free.
+            -- NB. For nested list cons patterns, the same equality is added by 'flattenCons'.
+            destructEq
+              | Just BTList <- mbt, nameBase nm == ":"
+              = let hd = AppE (VarE (sbvName "Data.SBV.List" "head")) scrut
+                    tl = AppE (VarE (sbvName "Data.SBV.List" "tail")) scrut
+                in [foldl1 AppE [VarE '(.===), scrut, InfixE (Just hd) (VarE '(.:)) (Just tl)]]
+              | True
+              = []
+
+            -- Only negate prior USER guards for the SAME constructor (others are mutually exclusive)
+            sameUserGuards = [ ug | (Just cn, _, Just ug) <- priorGuards, sameBase cn nm ]
+            negPriors      = map (AppE (VarE 'sNot)) sameUserGuards
+
+            -- Build the final guard (wrap user guard in bindings so pattern vars are in scope)
+            grdVars     = maybe Set.empty freeVars mbG
+            grdBindings = filter (\case
+                                     ValD (VarP v) _ _ -> v `Set.member` grdVars
+                                     _                 -> True) bindings
+            guardParts  = [testerGuard] ++ destructEq ++ negPriors ++ maybe [] (pure . addLocals grdBindings) mbG
+            finalGuard  = sAndAll guardParts
+
+            -- Wrap RHS with let-bindings. Keep a binding when the variable is used in this RHS, OR when
+            -- it isn't used in any same-constructor arm (so GHC can warn about a truly unused pattern var).
+            -- Drop it when used in some same-constructor arm but not here, to avoid spurious warnings.
+            cstrUsed = Map.findWithDefault Set.empty nm cstrUsedVars
+            rhsVars  = freeVars rhs
+            rhs'     = addLocals (filter (\case
+                                             ValD (VarP v) _ _ -> v `Set.member` rhsVars
+                                                               || not (v `Set.member` cstrUsed)
+                                             _                 -> True) bindings) rhs
+
+            -- Track: full guard for wildcard negation, user guard for same-constructor negation
+            userGuardOnly = case mbG of
+                              Just g  -> Just (addLocals grdBindings g)
+                              Nothing -> Nothing
+            priorGuards' = priorGuards ++ [(Just nm, finalGuard, userGuardOnly)]
+
+        rest' <- go priorGuards' rest
+        pure $ (finalGuard, rhs') : rest'
+
+-- | Negate the disjunction of all given guards using De Morgan: sNot (g1 .|| g2 .|| ...)
+negateAllGuards :: [Exp] -> Exp
+negateAllGuards [] = VarE 'sTrue
+negateAllGuards gs = AppE (VarE 'sNot) (foldl1 (\a b -> foldl1 AppE [VarE '(.||), a, b]) gs)
+
+-- * Standalone helpers
+
+-- | Free variables of an expression, respecting lexical scope.
+-- A variable is free if it is used (VarE) and not bound by any enclosing
+-- LetE, LamE, or CaseE at its use site.
+freeVars :: Exp -> Set Name
+freeVars = go Set.empty
+ where
+   go :: Set Name -> Exp -> Set Name
+   go bound = \case
+     VarE n          -> if n `Set.member` bound then Set.empty else Set.singleton n
+     ConE {}         -> Set.empty
+     LitE {}         -> Set.empty
+     AppE f x        -> go bound f <> go bound x
+     AppTypeE e _    -> go bound e
+     InfixE ml o mr  -> maybe Set.empty (go bound) ml <> go bound o <> maybe Set.empty (go bound) mr
+     UInfixE l o r   -> go bound l <> go bound o <> go bound r
+     ParensE e       -> go bound e
+     CondE c t f     -> go bound c <> go bound t <> go bound f
+     TupE mes        -> foldMap (maybe Set.empty (go bound)) mes
+     UnboxedTupE mes -> foldMap (maybe Set.empty (go bound)) mes
+     ListE es        -> foldMap (go bound) es
+     SigE e _        -> go bound e
+     RecConE _ fes   -> foldMap (go bound . snd) fes
+     RecUpdE e fes   -> go bound e <> foldMap (go bound . snd) fes
+     -- Binding forms: extend the bound set in the appropriate scope
+     LamE ps body    -> go (bound <> patsNames ps) body
+     LetE ds body    -> let bound' = bound <> decsNames ds
+                        in foldMap (goDec bound') ds <> go bound' body
+     CaseE scr ms    -> go bound scr <> foldMap (goMatch bound) ms
+     -- Fallback for other expression forms: conservatively report all
+     -- VarE names minus known bound (may over-report, never under-report)
+     other           -> allVarE other Set.\\ bound
+
+   goMatch :: Set Name -> Match -> Set Name
+   goMatch bound (Match pat body ds) =
+     let bound' = bound <> patNames pat <> decsNames ds
+     in goBody bound' body <> foldMap (goDec bound') ds
+
+   goBody :: Set Name -> Body -> Set Name
+   goBody bound (NormalB e)   = go bound e
+   goBody bound (GuardedB gs) = foldMap (\(g, e) -> goGuard bound g <> go bound e) gs
+
+   goGuard :: Set Name -> Guard -> Set Name
+   goGuard bound (NormalG e) = go bound e
+   goGuard _     _           = Set.empty
+
+   goDec :: Set Name -> Dec -> Set Name
+   goDec bound (ValD _ body ds)       = goBody bound body <> foldMap (goDec bound) ds
+   goDec bound (FunD _ cs)            = foldMap (goClause bound) cs
+   goDec _     _                      = Set.empty
+
+   goClause :: Set Name -> Clause -> Set Name
+   goClause bound (Clause ps body ds) =
+     let bound' = bound <> patsNames ps <> decsNames ds
+     in goBody bound' body <> foldMap (goDec bound') ds
+
+   -- Extract bound names from patterns
+   patNames :: Pat -> Set Name
+   patNames (VarP n)          = Set.singleton n
+   patNames (AsP n p)         = Set.singleton n <> patNames p
+   patNames (ConP _ _ ps)     = patsNames ps
+   patNames (InfixP p1 _ p2)  = patNames p1 <> patNames p2
+   patNames (UInfixP p1 _ p2) = patNames p1 <> patNames p2
+   patNames (TupP ps)         = patsNames ps
+   patNames (UnboxedTupP ps)  = patsNames ps
+   patNames (ListP ps)        = patsNames ps
+   patNames (SigP p _)        = patNames p
+   patNames (ParensP p)       = patNames p
+   patNames (TildeP p)        = patNames p
+   patNames (BangP p)         = patNames p
+   patNames (ViewP _ p)       = patNames p
+   patNames WildP             = Set.empty
+   patNames (LitP _)          = Set.empty
+   patNames _                 = Set.empty
+
+   patsNames :: [Pat] -> Set Name
+   patsNames = foldMap patNames
+
+   -- Extract bound names from declarations
+   decsNames :: [Dec] -> Set Name
+   decsNames ds = Set.fromList $ [n | ValD (VarP n) _ _ <- ds] ++ [n | FunD n _ <- ds]
+
+   -- Collect all VarE names in an expression (scope-unaware, for fallback only)
+   allVarE :: Exp -> Set Name
+   allVarE = \case
+     VarE n          -> Set.singleton n
+     AppE f x        -> allVarE f <> allVarE x
+     AppTypeE e _    -> allVarE e
+     InfixE ml o mr  -> maybe Set.empty allVarE ml <> allVarE o <> maybe Set.empty allVarE mr
+     UInfixE l o r   -> allVarE l <> allVarE o <> allVarE r
+     ParensE e       -> allVarE e
+     CondE c t f     -> allVarE c <> allVarE t <> allVarE f
+     TupE mes        -> foldMap (maybe Set.empty allVarE) mes
+     UnboxedTupE mes -> foldMap (maybe Set.empty allVarE) mes
+     ListE es        -> foldMap allVarE es
+     SigE e _        -> allVarE e
+     RecConE _ fes   -> foldMap (allVarE . snd) fes
+     RecUpdE e fes   -> allVarE e <> foldMap (allVarE . snd) fes
+     LamE _ body     -> allVarE body
+     LetE ds body    -> foldMap allVarEDec ds <> allVarE body
+     CaseE scr ms    -> allVarE scr <> foldMap allVarEMatch ms
+     _               -> Set.empty
+
+   allVarEMatch :: Match -> Set Name
+   allVarEMatch (Match _ body ds) = allVarEBody body <> foldMap allVarEDec ds
+
+   allVarEBody :: Body -> Set Name
+   allVarEBody (NormalB e)   = allVarE e
+   allVarEBody (GuardedB gs) = foldMap (\(_, e) -> allVarE e) gs
+
+   allVarEDec :: Dec -> Set Name
+   allVarEDec (ValD _ body ds) = allVarEBody body <> foldMap allVarEDec ds
+   allVarEDec (FunD _ cs)      = foldMap (\(Clause _ body ds) -> allVarEBody body <> foldMap allVarEDec ds) cs
+   allVarEDec _                = Set.empty
+
+-- | Count the number of arguments in a constructor type by counting arrows.
+-- e.g., @Integer -> String -> Bool@ has 2 arguments.
+-- Handles both plain ArrowT and multiplicity-annotated arrows (MulArrowT).
+countArgs :: Type -> Int
+countArgs (AppT (AppT ArrowT _) rest)            = 1 + countArgs rest
+countArgs (AppT (AppT (AppT MulArrowT _) _) rest) = 1 + countArgs rest
+countArgs (ForallT _ _ t)                         = countArgs t
+countArgs _                                       = 0
+
+-- | Generate a symbolic equality guard for a literal pattern.
+-- @litToEq off arg lit@ produces the expression @arg .== litVal@.
+-- For integers, the literal is used directly (relying on @fromInteger@).
+-- For characters and strings, the literal is wrapped with @literal@.
+litToEq :: Offset -> Exp -> Lit -> Q Exp
+litToEq _   arg (IntegerL n) = pure $ foldl1 AppE [VarE '(.==), arg, LitE (IntegerL n)]
+litToEq _   arg (CharL    c) = pure $ foldl1 AppE [VarE '(.==), arg, AppE (VarE 'literal) (LitE (CharL c))]
+litToEq _   arg (StringL  s) = pure $ foldl1 AppE [VarE '(.==), arg, AppE (VarE 'literal) (LitE (StringL s))]
+litToEq off _   lit          = fail off $ unlines
+  [ "sCase/pCase: Unsupported literal in pattern: " ++ show lit
+  , "       Only integer, character, and string literals are supported."
+  ]
diff --git a/Data/SBV/SEnum.hs b/Data/SBV/SEnum.hs
--- a/Data/SBV/SEnum.hs
+++ b/Data/SBV/SEnum.hs
@@ -39,7 +39,7 @@
 import Data.Char (isSpace)
 
 import Prelude hiding (enumFrom, enumFromThen, enumFromTo, enumFromThenTo)
-import Data.SBV.List  (enumFrom, enumFromThen, enumFromTo, enumFromThenTo)
+import Data.SBV.List  (enumFrom, enumFromThen, enumFromTo, enumFromThenToH)
 
 import Control.Monad (unless)
 import Data.List (isInfixOf, intercalate)
@@ -108,7 +108,13 @@
     ([a],    Nothing) -> varE 'enumFrom       `appE` parseHaskellExpr loc a
     ([a, b], Nothing) -> varE 'enumFromThen   `appE` parseHaskellExpr loc a `appE` parseHaskellExpr loc b
     ([a],    Just c)  -> varE 'enumFromTo     `appE` parseHaskellExpr loc a `appE`                               parseHaskellExpr loc c
-    ([a, b], Just c)  -> varE 'enumFromThenTo `appE` parseHaskellExpr loc a `appE` parseHaskellExpr loc b `appE` parseHaskellExpr loc c
+    ([a, b], Just c)  -> do ea <- parseHaskellExpr loc a
+                            eb <- parseHaskellExpr loc b
+                            ec <- parseHaskellExpr loc c
+                            -- Pass the from/then step as a hint when it's a statically-known integer
+                            -- (e.g. @[m, m-1 .. n]@ => @-1@). Exact-arithmetic instances fold it; the
+                            -- rest ignore it. See 'constStep'.
+                            varE 'enumFromThenToH `appE` pure ea `appE` pure eb `appE` pure ec `appE` liftMStep (constStep ea eb)
 
     _ -> errorWithLoc loc $ unlines [ "Data.SBV.Enum: Invalid format. Use one of:"
                                     , ""
@@ -117,6 +123,50 @@
                                     , "  [sEnum| a    .. c |]"
                                     , "  [sEnum| a, b .. c |]"
                                     ]
+
+-- | Read a parsed expression as @base + offset@: a single opaque atom plus an integer constant.
+-- @Nothing@ base means the whole thing is a pure integer constant. We only look through @+@ and @-@
+-- of integer literals; anything else is treated as an atom. This is intentionally a single-base
+-- peel, not a general linear normalizer -- it's exactly enough to recognize @m@, @m-1@, @m+k@, etc.
+peel :: Exp -> (Maybe Exp, Integer)
+peel (LitE (IntegerL n)) = (Nothing, n)
+peel (ParensE e)         = peel e
+peel (SigE e _)          = peel e
+peel (InfixE  (Just l)               (VarE op) (Just (LitE (IntegerL n)))) = shift op l n
+peel (UInfixE l                      (VarE op)       (LitE (IntegerL n)))   = shift op l n
+peel (InfixE  (Just (LitE (IntegerL n))) (VarE op) (Just r)) | base op == "+" = add (peel r) n
+peel (UInfixE (LitE (IntegerL n))        (VarE op)       r)  | base op == "+" = add (peel r) n
+peel e                   = (Just e, 0)
+
+-- | Helper for 'peel': fold a @base <op> lit@ where @op@ is @+@ or @-@.
+shift :: Name -> Exp -> Integer -> (Maybe Exp, Integer)
+shift op l n = case base op of
+                 "+" -> add (peel l) n
+                 "-" -> add (peel l) (negate n)
+                 _   -> (Just (UInfixE l (VarE op) (LitE (IntegerL n))), 0)
+
+-- | Add a constant to a peeled @(base, offset)@.
+add :: (Maybe Exp, Integer) -> Integer -> (Maybe Exp, Integer)
+add (b, k) n = (b, k + n)
+
+-- | Unqualified name of an operator (haskell-src-meta may leave it unqualified, so compare by base).
+base :: Name -> String
+base = nameBase
+
+-- | The from->then step @then - from@, when it's a statically-known integer (same atom on both
+-- sides, so the atoms cancel). Returns @Nothing@ for genuinely-symbolic steps (distinct atoms),
+-- in which case the quasiquoter falls back to the ordinary, hint-free behavior.
+constStep :: Exp -> Exp -> Maybe Integer
+constStep from thn
+  | bf == bt  = Just (kt - kf)
+  | True      = Nothing
+  where (bf, kf) = peel from
+        (bt, kt) = peel thn
+
+-- | Splice a @`Maybe` `Integer`@ step hint into the generated call.
+liftMStep :: Maybe Integer -> Q Exp
+liftMStep Nothing  = conE 'Nothing
+liftMStep (Just n) = conE 'Just `appE` litE (integerL n)
 
 -- | Parses a string into a Haskell TH Exp using haskell-src-meta
 parseHaskellExpr :: Loc -> String -> Q Exp
diff --git a/Data/SBV/SMT/SMT.hs b/Data/SBV/SMT/SMT.hs
--- a/Data/SBV/SMT/SMT.hs
+++ b/Data/SBV/SMT/SMT.hs
@@ -9,12 +9,13 @@
 -- Abstraction of SMT solvers
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DefaultSignatures          #-}
+{-# LANGUAGE BangPatterns               #-}
 {-# LANGUAGE FlexibleInstances          #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE NamedFieldPuns             #-}
+{-# LANGUAGE NumericUnderscores         #-}
 {-# LANGUAGE OverloadedStrings          #-}
-{-# LANGUAGE Rank2Types                 #-}
+{-# LANGUAGE RankNTypes                 #-}
 {-# LANGUAGE ScopedTypeVariables        #-}
 {-# LANGUAGE TypeApplications           #-}
 {-# LANGUAGE UndecidableInstances       #-}
@@ -27,7 +28,7 @@
          Modelable(..)
        , SatModel(..), genParse
        , extractModels, getModelValues
-       , getModelDictionaries, getModelUninterpretedValues
+       , getModelDictionaries
        , displayModels, showModel, shCV, showModelDictionary
 
        -- * Standard prover engine
@@ -61,13 +62,14 @@
 import Data.Either (rights)
 
 import System.Directory   (findExecutable)
-import System.Environment (getEnv)
+import System.Environment (getEnv, lookupEnv)
 import System.Exit        (ExitCode(..))
-import System.IO          (hClose, hFlush, hPutStrLn, hGetContents, hGetLine, hReady, hGetChar)
+import System.IO          (hClose, hFlush, hGetContents, hGetLine, hReady, hGetChar)
 import System.Process     (runInteractiveProcess, waitForProcess, terminateProcess)
 
 import qualified Data.Map.Strict as M
 import qualified Data.Text       as T
+import qualified Data.Text.IO    as TIO
 import Text.Read (readMaybe)
 
 import Data.SBV.Core.AlgReals
@@ -83,7 +85,7 @@
                               )
 
 import Data.SBV.Utils.PrettyNum
-import Data.SBV.Utils.Lib       (joinArgs, splitArgs, needsBars)
+import Data.SBV.Utils.Lib       (joinArgs, splitArgs, needsBars, showText, unQuote)
 import Data.SBV.Utils.SExpr     (parenDeficit, nameSupply)
 
 import qualified System.Timeout as Timeout (timeout)
@@ -111,10 +113,10 @@
                   deriving NFData
 
 -- | An 'Data.SBV.allSat' call results in a t'AllSatResult'
-data AllSatResult = AllSatResult { allSatMaxModelCountReached  :: Bool          -- ^ Did we reach the user given model count limit?
-                                 , allSatSolverReturnedUnknown :: Bool          -- ^ Did the solver report unknown at the end?
-                                 , allSatSolverReturnedDSat    :: Bool          -- ^ Did the solver report delta-satisfiable at the end?
-                                 , allSatResults               :: [SMTResult]   -- ^ All satisfying models
+data AllSatResult = AllSatResult { allSatMaxModelCountReached  :: !Bool          -- ^ Did we reach the user given model count limit?
+                                 , allSatSolverReturnedUnknown :: !Bool          -- ^ Did the solver report unknown at the end?
+                                 , allSatSolverReturnedDSat    :: !Bool          -- ^ Did the solver report delta-satisfiable at the end?
+                                 , allSatResults               :: ![SMTResult]   -- ^ All satisfying models
                                  }
 
 -- | A 'Data.SBV.safe' call results in a t'SafeResult'
@@ -144,7 +146,7 @@
                                      "Falsifiable in an extension field:\n"
                                      r
 
--- User friendly way of printing satisfiablity results
+-- User friendly way of printing satisfiability results
 instance Show SatResult where
   show (SatResult r) = showSMTResult "Unsatisfiable"
                                      "Unknown"
@@ -233,15 +235,14 @@
   -- | Given a sequence of constant-words, extract one instance of the type @a@, returning
   -- the remaining elements untouched. If the next element is not what's expected for this
   -- type you should return 'Nothing'
-  parseCVs  :: [CV] -> Maybe (a, [CV])
+  parseCVs :: [CV] -> Maybe (a, [CV])
+
   -- | Given a parsed model instance, transform it using @f@, and return the result.
   -- The default definition for this method should be sufficient in most use cases.
-  cvtModel  :: (a -> Maybe b) -> Maybe (a, [CV]) -> Maybe (b, [CV])
-  cvtModel f x = x >>= \(a, r) -> f a >>= \b -> return (b, r)
+  cvtModel :: (a -> Maybe b) -> Maybe (a, [CV]) -> Maybe (b, [CV])
+  cvtModel f x = x >>= \(a, r) -> f a >>= \b -> pure (b, r)
 
-  default parseCVs :: Read a => [CV] -> Maybe (a, [CV])
-  parseCVs (CV _ (CUserSort (_, s)) : r) = Just (read s, r)
-  parseCVs _                             = Nothing
+  {-# MINIMAL parseCVs #-}
 
 -- | Parse a signed/sized value from a sequence of CVs
 genParse :: Integral a => Kind -> [CV] -> Maybe (a, [CV])
@@ -250,12 +251,12 @@
 
 -- | Base case for 'SatModel' at unit type. Comes in handy if there are no real variables.
 instance SatModel () where
-  parseCVs xs = return ((), xs)
+  parseCVs xs = pure ((), xs)
 
 -- | 'Bool' as extracted from a model
 instance SatModel Bool where
   parseCVs xs = do (x, r) <- genParse KBool xs
-                   return ((x :: Integer) /= 0, r)
+                   pure ((x :: Integer) /= 0, r)
 
 -- | 'Word8' as extracted from a model
 instance SatModel Word8 where
@@ -322,13 +323,30 @@
 instance (KnownNat n, BVIsNonZero n) => SatModel (IntN n) where
   parseCVs = genParse (kindOf (undefined :: IntN n))
 
+-- | Constructing models for t'ArrayModel'
+instance (SatModel k, SatModel v) => SatModel (ArrayModel k v) where
+  parseCVs (CV (KArray kk kv) (CArray (ArrayModel tbl def)) : r)
+    | Just (def', _) <- parseCVs @v [CV kv def]
+    , let convert (k, v) = do
+            (k', _) <- parseCVs @k [CV kk k]
+            (v', _) <- parseCVs @v [CV kv v]
+            pure (k', v')
+    , Just tbl' <- traverse convert tbl
+    = Just (ArrayModel tbl' def', r)
+  parseCVs _ = Nothing
+
 -- | @CV@ as extracted from a model; trivial definition
 instance SatModel CV where
   parseCVs (cv : r) = Just (cv, r)
   parseCVs []       = Nothing
 
 -- | A rounding mode, extracted from a model. (Default definition suffices)
-instance SatModel RoundingMode
+instance SatModel RoundingMode where
+  parseCVs (CV k (CADT (s, [])) : r)
+    | isRoundingMode k
+    , Just mode <- s `lookup` [(show m, m) | m <- [minBound .. maxBound :: RoundingMode]]
+    = Just (mode, r)
+  parseCVs _ = Nothing
 
 -- | 'String' as extracted from a model
 instance {-# OVERLAPS #-} SatModel [Char] where
@@ -355,37 +373,37 @@
 instance (SatModel a, SatModel b) => SatModel (a, b) where
   parseCVs as = do (a, bs) <- parseCVs as
                    (b, cs) <- parseCVs bs
-                   return ((a, b), cs)
+                   pure ((a, b), cs)
 
 -- | 3-Tuples extracted from a model
 instance (SatModel a, SatModel b, SatModel c) => SatModel (a, b, c) where
   parseCVs as = do (a,      bs) <- parseCVs as
                    ((b, c), ds) <- parseCVs bs
-                   return ((a, b, c), ds)
+                   pure ((a, b, c), ds)
 
 -- | 4-Tuples extracted from a model
 instance (SatModel a, SatModel b, SatModel c, SatModel d) => SatModel (a, b, c, d) where
   parseCVs as = do (a,         bs) <- parseCVs as
                    ((b, c, d), es) <- parseCVs bs
-                   return ((a, b, c, d), es)
+                   pure ((a, b, c, d), es)
 
 -- | 5-Tuples extracted from a model
 instance (SatModel a, SatModel b, SatModel c, SatModel d, SatModel e) => SatModel (a, b, c, d, e) where
   parseCVs as = do (a, bs)            <- parseCVs as
                    ((b, c, d, e), fs) <- parseCVs bs
-                   return ((a, b, c, d, e), fs)
+                   pure ((a, b, c, d, e), fs)
 
 -- | 6-Tuples extracted from a model
 instance (SatModel a, SatModel b, SatModel c, SatModel d, SatModel e, SatModel f) => SatModel (a, b, c, d, e, f) where
   parseCVs as = do (a, bs)               <- parseCVs as
                    ((b, c, d, e, f), gs) <- parseCVs bs
-                   return ((a, b, c, d, e, f), gs)
+                   pure ((a, b, c, d, e, f), gs)
 
 -- | 7-Tuples extracted from a model
 instance (SatModel a, SatModel b, SatModel c, SatModel d, SatModel e, SatModel f, SatModel g) => SatModel (a, b, c, d, e, f, g) where
   parseCVs as = do (a, bs)                  <- parseCVs as
                    ((b, c, d, e, f, g), hs) <- parseCVs bs
-                   return ((a, b, c, d, e, f, g), hs)
+                   pure ((a, b, c, d, e, f, g), hs)
 
 -- | Various SMT results that we can extract models out of.
 class Modelable a where
@@ -402,15 +420,7 @@
 
   -- | Extract a model value for a given element. Also see `getModelValues`.
   getModelValue :: SymVal b => String -> a -> Maybe b
-  getModelValue v r = fromCV `fmap` (v `M.lookup` getModelDictionary r)
-
-  -- | Extract a representative name for the model value of an uninterpreted kind.
-  -- This is supposed to correspond to the value as computed internally by the
-  -- SMT solver; and is unportable from solver to solver. Also see `getModelUninterpretedValues`.
-  getModelUninterpretedValue :: String -> a -> Maybe String
-  getModelUninterpretedValue v r = case v `M.lookup` getModelDictionary r of
-                                     Just (CV _ (CUserSort (_, s))) -> Just s
-                                     _                              -> Nothing
+  getModelValue v r = fromCV <$> (v `M.lookup` getModelDictionary r)
 
   -- | A simpler variant of 'getModelAssignment' to get a model out without the fuss.
   extractModel :: SatModel b => a -> Maybe b
@@ -445,10 +455,6 @@
 getModelValues :: SymVal b => String -> AllSatResult -> [Maybe b]
 getModelValues s AllSatResult{allSatResults = xs} =  map (s `getModelValue`) xs
 
--- | Extract value of an uninterpreted variable from an all-sat call. Similar to `getModelUninterpretedValue`.
-getModelUninterpretedValues :: String -> AllSatResult -> [Maybe String]
-getModelUninterpretedValues s AllSatResult{allSatResults = xs} =  map (s `getModelUninterpretedValue`) xs
-
 -- | t'ThmResult' as a generic model provider
 instance Modelable ThmResult where
   getModelAssignment (ThmResult r) = getModelAssignment r
@@ -515,8 +521,8 @@
 displayModels arrange disp AllSatResult{allSatResults = ms} = do
     let models = rights (map (getModelAssignment . SatResult) ms)
     inds <- zipWithM display (arrange models) [(1::Int)..]
-    return $ last (0:inds)
-  where display r i = disp i r >> return i
+    pure $ last (0:inds)
+  where display r i = disp i r >> pure i
 
 -- | Show an SMTResult; generic version
 showSMTResult :: String -> String -> String -> String -> (Maybe String -> String) -> String -> SMTResult -> String
@@ -526,7 +532,7 @@
   Satisfiable _   m                  -> satMsgModel    ++ showModel cfg m
   DeltaSat    _ p m                  -> dSatMsgModel p ++ showModel cfg m
   SatExtField _ (SMTModel b _ _ _)   -> satExtMsg   ++ showModelDictionary True False cfg b
-  Unknown     _ r                    -> unkMsg ++ ".\n" ++ "  Reason: " `alignPlain` show r
+  Unknown     _ r                    -> unkMsg ++ ".\n" ++ T.unpack ("  Reason: " `alignPlain` showText r)
   ProofError  _ [] Nothing           -> "*** An error occurred. No additional information available. Try running in verbose mode."
   ProofError  _ ls Nothing           -> "*** An error occurred.\n" ++ intercalate "\n" (map ("***  " ++) ls)
   ProofError  _ ls (Just r)          -> intercalate "\n" $  [ "*** " ++ l | l <- ls]
@@ -567,7 +573,7 @@
         relevantVars  = filter (not . ignore) allVars
         ignore (T.pack -> s, _)
           | includeEverything = False
-          | True              = mustIgnoreVar cfg (T.unpack s)
+          | True              = mustIgnoreVar cfg s
 
         shM (s, RegularCV v) = let vs = shCV cfg s v in ((length s, s), (vlength vs, vs))
         shM (s, other)       = let vs = show other   in ((length s, s), (vlength vs, vs))
@@ -599,7 +605,7 @@
 
         trim = reverse . dropWhile isSpace . reverse
 
-        (ats, rt) = case map showBaseKind ts of
+        (ats, rt) = case map (T.unpack . showBaseKind) ts of
                      []  -> error $ "showModelUI: Unexpected type: " ++ show (SBVType ts)
                      tss -> (init tss, last tss)
 
@@ -636,9 +642,9 @@
         -- NB. We'll ignore crackNum here. Seems to be overkill while displaying an
         -- uninterpreted function.
         scv = sh (printBase cfg)
-          where sh 2  = binP
+          where sh 2  = T.unpack . binP
                 sh 10 = showCV False
-                sh 16 = hexP
+                sh 16 = T.unpack . hexP
                 sh _  = show
 
         -- NB. If we have a float NaN/Infinity/+0/-0 etc. these will
@@ -658,9 +664,9 @@
 -- | Show a constant value, in the user-specified base
 shCV :: SMTConfig -> String -> CV -> String
 shCV SMTConfig{printBase, crackNum, verbose, crackNumSurfaceVals} nm cv = cracked (sh printBase cv)
-  where sh 2  = binS
+  where sh 2  = T.unpack . binS
         sh 10 = show
-        sh 16 = hexS
+        sh 16 = T.unpack . hexS
         sh n  = \w -> show w ++ " -- Ignoring unsupported printBase " ++ show n ++ ", use 2, 10, or 16."
 
         cracked def
@@ -670,7 +676,7 @@
                              Just cs -> def ++ "\n" ++ cs
 
 -- | Helper function to spin off to an SMT solver.
-pipeProcess :: SMTConfig -> State -> String -> [String] -> String -> (State -> IO a) -> IO a
+pipeProcess :: SMTConfig -> State -> String -> [String] -> T.Text -> (State -> IO a) -> IO a
 pipeProcess cfg ctx execName opts pgm continuation = do
     mbExecPath <- findExecutable execName
     case mbExecPath of
@@ -688,14 +694,42 @@
                                                                                                 ])
                         ]
 
+-- Communication-level timeouts (microseconds). These are NOT solver timeouts
+-- (i.e., how long check-sat takes); they govern how long SBV waits for the
+-- solver process to respond to individual IPC commands.
+--
+-- Adjust via the @SBV_COMM_TIMEOUT_FACTOR@ environment variable (default: 1).
+-- For instance, setting it to 2 doubles all communication timeouts.
+
+-- | Timeout for @set-option@ commands (expected to be fast).
+setCommandTimeOut :: Int
+setCommandTimeOut = 2_000_000   -- 2 seconds
+
+-- | Timeout for subsequent response lines once the solver starts responding,
+--   and for heartbeat\/sync-point reads.
+defaultLineTimeOut :: Int
+defaultLineTimeOut = 5_000_000  -- 5 seconds
+
+-- | Read @SBV_COMM_TIMEOUT_FACTOR@ and return a function that scales timeout values.
+-- If the variable is unset, the identity function is returned. If set to an invalid
+-- value (not a positive number), an error is raised.
+commTimeOutScaler :: IO (Int -> Int)
+commTimeOutScaler = do
+   mbFactor <- lookupEnv "SBV_COMM_TIMEOUT_FACTOR"
+   case mbFactor of
+     Nothing -> pure id
+     Just s  -> case reads s of
+                  [(f, "")] | f > (0 :: Double) -> pure (round . (f *) . fromIntegral)
+                  _                              -> error $ "SBV_COMM_TIMEOUT_FACTOR: invalid value " ++ show s ++ ". Must be a positive number."
+
 -- | A standard engine interface. Most solvers follow-suit here in how we "chat" to them..
 standardEngine :: String
                -> String
                -> SMTEngine
 standardEngine envName envOptName cfg ctx pgm continuation = do
 
-    execName <-                    getEnv envName     `C.catch` (\(e :: C.SomeException) -> handleAsync e (return (executable (solver cfg))))
-    execOpts <- (splitArgs `fmap`  getEnv envOptName) `C.catch` (\(e :: C.SomeException) -> handleAsync e (return (options (solver cfg) cfg)))
+    execName <-                    getEnv envName     `C.catch` (\(e :: C.SomeException) -> handleAsync e (pure (executable (solver cfg))))
+    execOpts <- (splitArgs <$> getEnv envOptName) `C.catch` (\(e :: C.SomeException) -> handleAsync e (pure (options (solver cfg) cfg)))
 
     let cfg' = cfg {solver = (solver cfg) {executable = execName, options = const execOpts}}
 
@@ -705,15 +739,15 @@
 -- communicating with it.
 standardSolver :: SMTConfig       -- ^ The current configuration
                -> State           -- ^ Context in which we are running
-               -> String          -- ^ The program
+               -> T.Text          -- ^ The program
                -> (State -> IO a) -- ^ The continuation
                -> IO a
 standardSolver config ctx pgm continuation = do
-    let msg s    = debug config ["** " ++ s]
+    let msg s    = debug config ["** " <> s]
         smtSolver= solver config
         exec     = executable smtSolver
         opts     = options smtSolver config ++ extraArgs config
-    msg $ "Calling: "  ++ (exec ++ (if null opts then "" else " ") ++ joinArgs opts)
+    msg $ "Calling: "  <> T.pack (exec ++ (if null opts then "" else " ") ++ joinArgs opts)
     rnf pgm `seq` pipeProcess config ctx exec opts pgm continuation
 
 -- | An internal type to track of solver interactions
@@ -722,21 +756,48 @@
                 | SolverException String -- ^ Something else went wrong
 
 -- | A variant of @readProcessWithExitCode@; except it deals with SBV continuations
-runSolver :: SMTConfig -> State -> FilePath -> [String] -> String -> (State -> IO a) -> IO a
+runSolver :: SMTConfig -> State -> FilePath -> [String] -> T.Text -> (State -> IO a) -> IO a
 runSolver cfg ctx execPath opts pgm continuation
- = do let nm  = show (name (solver cfg))
-          msg = debug cfg . map ("*** " ++)
+ = do scaler <- commTimeOutScaler
 
+      let nm  = show (name (solver cfg))
+          msg = debug cfg . map ("*** " <>)
+
           clean = preprocess (solver cfg)
 
           -- the very first command we send
           heartbeat = "(set-option :print-success true)"
 
+          -- Scaled communication timeouts
+          setCommandTO  = Just (scaler setCommandTimeOut)
+          defaultLineTO = Just (scaler defaultLineTimeOut)
+
+          -- Default SBVException with solver config baked in; callers override fields as needed
+          solverException desc =
+             let (errOut, description)
+                    | "(error" `isPrefixOf` desc
+                    = ( Just $ unQuote (dropWhile isSpace (dropWhile (not . isSpace) (init desc)))
+                      , "Unexpected solver error"
+                      )
+                    | True
+                    = (Nothing, desc)
+             in SBVException { sbvExceptionDescription = description
+                             , sbvExceptionSent        = Nothing
+                             , sbvExceptionExpected    = Nothing
+                             , sbvExceptionReceived    = Nothing
+                             , sbvExceptionStdOut      = Nothing
+                             , sbvExceptionStdErr      = errOut
+                             , sbvExceptionExitCode    = Nothing
+                             , sbvExceptionConfig      = cfg { solver = (solver cfg) { executable = execPath } }
+                             , sbvExceptionReason      = Nothing
+                             , sbvExceptionHint        = Nothing
+                             }
+
       (send, ask, getResponseFromSolver, terminateSolver, cleanUp, pid) <- do
                 (inh, outh, errh, pid) <- runInteractiveProcess execPath opts Nothing Nothing
 
-                let send :: Maybe Int -> String -> IO ()
-                    send mbTimeOut command = do hPutStrLn inh (clean command)
+                let send :: Maybe Int -> T.Text -> IO ()
+                    send mbTimeOut command = do TIO.hPutStrLn inh (clean command)
                                                 hFlush inh
                                                 recordTranscript (transcript cfg) $ SentMsg command mbTimeOut
 
@@ -745,40 +806,34 @@
                       where chk cmd = cmd /= heartbeat && "(set-option :" `isPrefixOf` cmd
 
                     -- Send a line, get a whole s-expr. We ignore the pathetic case that there might be a string with an unbalanced parentheses in it in a response.
-                    ask :: Maybe Int -> String -> IO String
-                    ask mbTimeOutGiven command =
-                                  let -- If the command is a set-option call, make sure there's a timeout on it
-                                      -- This ensures that if we try to set an option before diagnostic-output
-                                      -- is redirected to stdout and the solver chokes, then we can catch it
-                                      mbTimeOut | isSetCommand (Just command) = Just 1000000
-                                                | True                        = mbTimeOutGiven
-
-                                      -- solvers don't respond to empty lines or comments; we just pass back
+                    ask :: Maybe Int -> T.Text -> IO String
+                    ask mbTimeOut command =
+                                  let -- solvers don't respond to empty lines or comments; we just pass back
                                       -- success in these cases to keep the illusion of everything has a response
-                                      cmd = dropWhile isSpace command
+                                      cmd = T.dropWhile isSpace command
 
-                                  in if null cmd || ";" `isPrefixOf` cmd
-                                     then return "success"
+                                  in if T.null cmd || ";" `T.isPrefixOf` cmd
+                                     then pure "success"
                                      else do send mbTimeOut command
-                                             getResponseFromSolver (Just command) mbTimeOut
+                                             getResponseFromSolver (Just (T.unpack command)) mbTimeOut
 
                     -- Get a response from the solver, with an optional time-out on how long
-                    -- to wait. Note that there's *always* a time-out of 5 seconds once we get the
-                    -- first line of response, as while the solver might take it's time to respond,
+                    -- to wait. Note that there's *always* a time-out once we get the
+                    -- first line of response, as while the solver might take its time to respond,
                     -- once it starts responding successive lines should come quickly.
                     getResponseFromSolver :: Maybe String -> Maybe Int -> IO String
                     getResponseFromSolver mbCommand mbTimeOut = do
                                 response <- go True 0 []
                                 let collated = intercalate "\n" $ reverse response
                                 recordTranscript (transcript cfg) $ RecvMsg collated
-                                return collated
+                                pure collated
 
                       where safeGetLine isFirst h =
-                                         let timeOutToUse | isSetCommand mbCommand = Just 2000000
+                                         let timeOutToUse | isSetCommand mbCommand = setCommandTO
                                                           | isFirst                = mbTimeOut
-                                                          | True                   = Just 5000000
-                                             timeOutMsg t | isFirst = "User specified timeout of " ++ showTimeoutValue t ++ " exceeded"
-                                                          | True    = "A multiline complete response wasn't received before " ++ showTimeoutValue t ++ " exceeded"
+                                                          | True                   = defaultLineTO
+                                             timeOutMsg t | isFirst = "User specified timeout of " ++ T.unpack (showTimeoutValue t) ++ " exceeded"
+                                                          | True    = "A multiline complete response wasn't received before " ++ T.unpack (showTimeoutValue t) ++ " exceeded"
 
                                              -- Like hGetLine, except it keeps getting lines if inside a string.
                                              getFullLine :: IO String
@@ -795,7 +850,7 @@
 
                                                                                   if stillInside
                                                                                      then collect True sofar'
-                                                                                     else return sofar'
+                                                                                     else pure sofar'
 
                                              -- Carefully grab things as they are ready. But don't block!
                                              collectH handle = reverse <$> coll ""
@@ -809,10 +864,14 @@
                                                               pure $ dropWhile isSpace <$> mbCts
 
                                          in case timeOutToUse of
-                                              Nothing -> SolverRegular <$> getFullLine
+                                              Nothing -> do l <- getFullLine
+                                                            -- If we see the line starting with error, we're about to die, so give up:
+                                                            pure $ if "(error" `isPrefixOf` l
+                                                                      then SolverException l
+                                                                      else SolverRegular   l
                                               Just t  -> do r <- Timeout.timeout t getFullLine
                                                             case r of
-                                                              Just l  -> return $ SolverRegular l
+                                                              Just l  -> pure $ SolverRegular l
                                                               Nothing -> do out <- grab outh
                                                                             err <- grab errh
                                                                             -- in this case, if we have something on out/err pass that back as regular
@@ -821,104 +880,87 @@
                                                                               _                     -> pure $ SolverTimeout (timeOutMsg t)
 
                             go isFirst i sofar = do
-                                            errln <- safeGetLine isFirst outh `C.catch` (\(e :: C.SomeException) -> handleAsync e (return (SolverException (show e))))
+                                            errln <- safeGetLine isFirst outh `C.catch` (\(e :: C.SomeException) -> handleAsync e (pure (SolverException (show e))))
                                             case errln of
-                                              SolverRegular ln -> let need  = i + parenDeficit ln
+                                              SolverRegular ln -> let !need = i + parenDeficit ln
                                                                       -- make sure we get *something*
                                                                       empty = case dropWhile isSpace ln of
                                                                                 []      -> True
                                                                                 (';':_) -> True   -- yes this does happen! I've seen z3 print out comments on stderr.
                                                                                 _       -> False
                                                                   in case (empty, need <= 0) of
-                                                                        (True, _)      -> do debug cfg ["[SKIP] " `alignPlain` ln]
+                                                                        (True, _)      -> do debug cfg ["[SKIP] " `alignPlain` T.pack ln]
                                                                                              go isFirst need sofar
                                                                         (False, False) -> go False   need (ln:sofar)
-                                                                        (False, True)  -> return (ln:sofar)
+                                                                        (False, True)  -> pure (ln:sofar)
 
                                               SolverException e -> do terminateProcess pid
-                                                                      C.throwIO SBVException { sbvExceptionDescription = e
-                                                                                             , sbvExceptionSent        = mbCommand
-                                                                                             , sbvExceptionExpected    = Nothing
-                                                                                             , sbvExceptionReceived    = Just $ unlines (reverse sofar)
-                                                                                             , sbvExceptionStdOut      = Nothing
-                                                                                             , sbvExceptionStdErr      = Nothing
-                                                                                             , sbvExceptionExitCode    = Nothing
-                                                                                             , sbvExceptionConfig      = cfg { solver = (solver cfg) { executable = execPath } }
-                                                                                             , sbvExceptionReason      = Nothing
-                                                                                             , sbvExceptionHint        = if "hGetLine: end of file" `isInfixOf` e
-                                                                                                                         then Just [ "Solver process prematurely ended communication."
-                                                                                                                                   , ""
-                                                                                                                                   , "It is likely it was terminated because of a seg-fault."
-                                                                                                                                   , "Run with 'transcript=Just \"bad.smt2\"' option, and feed"
-                                                                                                                                   , "the generated \"bad.smt2\" file directly to the solver"
-                                                                                                                                   , "outside of SBV for further information."
-                                                                                                                                   ]
-                                                                                                                         else Nothing
-                                                                                             }
+                                                                      C.throwIO (solverException e)
+                                                                                { sbvExceptionSent     = mbCommand
+                                                                                , sbvExceptionReceived = Just $ unlines (reverse sofar)
+                                                                                , sbvExceptionHint     = if "hGetLine: end of file" `isInfixOf` e
+                                                                                                         then Just [ "Solver process prematurely ended communication."
+                                                                                                                   , ""
+                                                                                                                   , "It is likely it was terminated because of a seg-fault."
+                                                                                                                   , "Run with 'transcript=Just \"bad.smt2\"' option, and feed"
+                                                                                                                   , "the generated \"bad.smt2\" file directly to the solver"
+                                                                                                                   , "outside of SBV for further information."
+                                                                                                                   ]
+                                                                                                         else Nothing
+                                                                                }
 
                                               SolverTimeout e -> do terminateProcess pid -- NB. Do not *wait* for the process, just quit.
 
-                                                                    C.throwIO SBVException { sbvExceptionDescription = "Timeout! " ++ e
-                                                                                           , sbvExceptionSent        = mbCommand
-                                                                                           , sbvExceptionExpected    = Nothing
-                                                                                           , sbvExceptionReceived    = Just $ unlines (reverse sofar)
-                                                                                           , sbvExceptionStdOut      = Nothing
-                                                                                           , sbvExceptionStdErr      = Nothing
-                                                                                           , sbvExceptionExitCode    = Nothing
-                                                                                           , sbvExceptionConfig      = cfg { solver = (solver cfg) { executable = execPath } }
-                                                                                           , sbvExceptionReason      = Nothing
-                                                                                           , sbvExceptionHint        = if not (verbose cfg)
-                                                                                                                       then Just ["Run with 'verbose=True' for further information"]
-                                                                                                                       else Nothing
-                                                                                           }
+                                                                    C.throwIO (solverException ("Timeout! " ++ e))
+                                                                              { sbvExceptionSent     = mbCommand
+                                                                              , sbvExceptionReceived = Just $ unlines (reverse sofar)
+                                                                              , sbvExceptionHint     = if not (verbose cfg)
+                                                                                                       then Just ["Run with 'verbose=True' for further information"]
+                                                                                                       else Nothing
+                                                                              }
 
                     terminateSolver = do hClose inh
                                          outMVar <- newEmptyMVar
-                                         out <- hGetContents outh `C.catch`  (\(e :: C.SomeException) -> handleAsync e (return (show e)))
+                                         out <- hGetContents outh `C.catch`  (\(e :: C.SomeException) -> handleAsync e (pure (show e)))
                                          _ <- forkIO $ C.evaluate (length out) >> putMVar outMVar ()
-                                         err <- hGetContents errh `C.catch`  (\(e :: C.SomeException) -> handleAsync e (return (show e)))
+                                         err <- hGetContents errh `C.catch`  (\(e :: C.SomeException) -> handleAsync e (pure (show e)))
                                          _ <- forkIO $ C.evaluate (length err) >> putMVar outMVar ()
                                          takeMVar outMVar
                                          takeMVar outMVar
-                                         hClose outh `C.catch`  (\(e :: C.SomeException) -> handleAsync e (return ()))
-                                         hClose errh `C.catch`  (\(e :: C.SomeException) -> handleAsync e (return ()))
-                                         ex <- waitForProcess pid `C.catch` (\(e :: C.SomeException) -> handleAsync e (return (ExitFailure (-999))))
-                                         return (out, err, ex)
+                                         hClose outh `C.catch`  (\(e :: C.SomeException) -> handleAsync e (pure ()))
+                                         hClose errh `C.catch`  (\(e :: C.SomeException) -> handleAsync e (pure ()))
+                                         ex <- waitForProcess pid `C.catch` (\(e :: C.SomeException) -> handleAsync e (pure (ExitFailure (-999))))
+                                         pure (out, err, ex)
 
                     cleanUp maybeForwardedException
                       = do (out, err, ex) <- terminateSolver
 
-                           msg $   [ "Solver   : " ++ nm
-                                   , "Exit code: " ++ show ex
+                           msg $   [ "Solver   : " <> T.pack nm
+                                   , "Exit code: " <> showText ex
                                    ]
-                                ++ [ "Std-out  : " ++ intercalate "\n           " (lines out) | not (null out)]
-                                ++ [ "Std-err  : " ++ intercalate "\n           " (lines err) | not (null err)]
+                                <> [ "Std-out  : " <> T.pack (intercalate "\n           " (lines out)) | not (null out)]
+                                <> [ "Std-err  : " <> T.pack (intercalate "\n           " (lines err)) | not (null err)]
 
                            finalizeTranscript (transcript cfg) ex
                            recordEndTime cfg ctx
 
                            case (ex, maybeForwardedException) of
                              (_,           Just forwardedException) -> C.throwIO forwardedException
-                             (ExitSuccess, _)                       -> return ()
+                             (ExitSuccess, _)                       -> pure ()
                              _                                      -> if ignoreExitCode cfg
-                                                                          then msg ["Ignoring non-zero exit code of " ++ show ex ++ " per user request!"]
-                                                                          else C.throwIO SBVException { sbvExceptionDescription = "Failed to complete the call to " ++ nm
-                                                                                                      , sbvExceptionSent        = Nothing
-                                                                                                      , sbvExceptionExpected    = Nothing
-                                                                                                      , sbvExceptionReceived    = Nothing
-                                                                                                      , sbvExceptionStdOut      = Just out
-                                                                                                      , sbvExceptionStdErr      = Just err
-                                                                                                      , sbvExceptionExitCode    = Just ex
-                                                                                                      , sbvExceptionConfig      = cfg { solver = (solver cfg) { executable = execPath } }
-                                                                                                      , sbvExceptionReason      = Nothing
-                                                                                                      , sbvExceptionHint        = if not (verbose cfg)
-                                                                                                                                  then Just ["Run with 'verbose=True' for further information"]
-                                                                                                                                  else Nothing
+                                                                          then msg ["Ignoring non-zero exit code of " <> showText ex <> " per user request!"]
+                                                                          else C.throwIO (solverException ("Failed to complete the call to " ++ nm))
+                                                                                                      { sbvExceptionStdOut    = Just out
+                                                                                                      , sbvExceptionStdErr    = Just err
+                                                                                                      , sbvExceptionExitCode  = Just ex
+                                                                                                      , sbvExceptionHint      = if not (verbose cfg)
+                                                                                                                                then Just ["Run with 'verbose=True' for further information"]
+                                                                                                                                else Nothing
                                                                                                       }
 
-                return (send, ask, getResponseFromSolver, terminateSolver, cleanUp, pid)
+                pure (send, ask, getResponseFromSolver, terminateSolver, cleanUp, pid)
 
-      let executeSolver = do let sendAndGetSuccess :: Maybe Int -> String -> IO ()
+      let executeSolver = do let sendAndGetSuccess :: Maybe Int -> T.Text -> IO ()
                                  sendAndGetSuccess mbTimeOut l
                                    -- The pathetic case when the solver doesn't support queries, so we pretend it responded "success"
                                    -- Currently ABC is the only such solver.
@@ -931,7 +973,7 @@
                                           ["success"] -> debug cfg ["[GOOD] " `alignPlain` l]
                                           _           -> do debug cfg ["[FAIL] " `alignPlain` l]
 
-                                                            let isOption = "(set-option" `isPrefixOf` dropWhile isSpace l
+                                                            let isOption = T.isPrefixOf "(set-option" (T.dropWhile isSpace l)
 
                                                                 reason | isOption = [ "Backend solver reports it does not support this option."
                                                                                     , "Check the spelling, and if correct please report this as a"
@@ -942,8 +984,8 @@
                                                                                     ]
 
                                                             -- put a sync point here before we die so we consume everything
-                                                            mbExtras <- (Right <$> getResponseFromSolver Nothing (Just 5000000))
-                                                                        `C.catch` (\(e :: C.SomeException) -> handleAsync e (return (Left (show e))))
+                                                            mbExtras <- (Right <$> getResponseFromSolver Nothing defaultLineTO)
+                                                                        `C.catch` (\(e :: C.SomeException) -> handleAsync e (pure (Left (show e))))
 
                                                             -- Ignore any exceptions from last sync, pointless.
                                                             let extras = case mbExtras of
@@ -954,16 +996,14 @@
                                                             let out = intercalate "\n" . lines $ outOrig
                                                                 err = intercalate "\n" . lines $ errOrig
 
-                                                                exc = SBVException { sbvExceptionDescription = "Unexpected non-success response from " ++ nm
-                                                                                   , sbvExceptionSent        = Just l
-                                                                                   , sbvExceptionExpected    = Just "success"
-                                                                                   , sbvExceptionReceived    = Just $ r ++ "\n" ++ extras
-                                                                                   , sbvExceptionStdOut      = Just out
-                                                                                   , sbvExceptionStdErr      = Just err
-                                                                                   , sbvExceptionExitCode    = Just ex
-                                                                                   , sbvExceptionConfig      = cfg { solver = (solver cfg) {executable = execPath } }
-                                                                                   , sbvExceptionReason      = Just reason
-                                                                                   , sbvExceptionHint        = Nothing
+                                                                exc = (solverException ("Unexpected non-success response from " ++ nm))
+                                                                                   { sbvExceptionSent     = Just (T.unpack l)
+                                                                                   , sbvExceptionExpected = Just "success"
+                                                                                   , sbvExceptionReceived = Just $ r ++ "\n" ++ extras
+                                                                                   , sbvExceptionStdOut   = Just out
+                                                                                   , sbvExceptionStdErr   = Just err
+                                                                                   , sbvExceptionExitCode = Just ex
+                                                                                   , sbvExceptionReason   = Just reason
                                                                                    }
 
                                                             C.throwIO exc
@@ -974,10 +1014,10 @@
                              -- First check that the solver supports :print-success
                              let backend = name $ solver cfg
                              if not (supportsCustomQueries (capabilities (solver cfg)))
-                                then debug cfg ["** Skipping heart-beat for the solver " ++ show backend]
-                                else do r <- ask (Just 5000000) heartbeat  -- Give the solver 5s to respond, this should be plenty enough!
+                                then debug cfg ["** Skipping heart-beat for the solver " <> showText backend]
+                                else do r <- ask defaultLineTO (T.pack heartbeat)
                                         case words r of
-                                          ["success"]     -> debug cfg ["[GOOD] " ++ heartbeat]
+                                          ["success"]     -> debug cfg ["[GOOD] " <> T.pack heartbeat]
                                           ["unsupported"] -> error $ unlines [ ""
                                                                              , "*** Backend solver (" ++  show backend ++ ") does not support the command:"
                                                                              , "***"
@@ -999,13 +1039,13 @@
                              -- For push/pop support, we require :global-declarations to be true. But not all solvers
                              -- support this. Issue it if supported. (If not, we'll reject pop calls.)
                              if not (supportsGlobalDecls (capabilities (solver cfg)))
-                                then debug cfg [ "** Backend solver " ++ show backend ++ " does not support global decls."
+                                then debug cfg [ "** Backend solver " <> showText backend <> " does not support global decls."
                                                , "** Some incremental calls, such as pop, will be limited."
                                                ]
                                 else sendAndGetSuccess Nothing "(set-option :global-declarations true)"
 
                              -- Now dump the program!
-                             mapM_ (sendAndGetSuccess Nothing) (mergeSExpr (lines pgm))
+                             mapM_ (sendAndGetSuccess Nothing) (mergeSExpr (T.lines pgm))
 
                              -- Prepare the query context and ship it off
                              let qs = QueryState { queryAsk                 = ask
diff --git a/Data/SBV/SMT/SMTLib.hs b/Data/SBV/SMT/SMTLib.hs
--- a/Data/SBV/SMT/SMTLib.hs
+++ b/Data/SBV/SMT/SMTLib.hs
@@ -23,6 +23,7 @@
 
 import Data.SBV.SMT.Utils
 import qualified Data.SBV.SMT.SMTLib2 as SMT2
+import           Data.Text            (Text)
 
 -- | Convert to SMT-Lib, in a full program context.
 toSMTLib :: SMTConfig -> SMTLibConverter SMTLibPgm
@@ -30,7 +31,7 @@
                                       SMTLib2 -> toSMTLib2
 
 -- | Convert to SMT-Lib, in an incremental query context.
-toIncSMTLib :: SMTConfig -> SMTLibIncConverter [String]
+toIncSMTLib :: SMTConfig -> SMTLibIncConverter [Text]
 toIncSMTLib SMTConfig{smtLibVersion} = case smtLibVersion of
                                          SMTLib2 -> toIncSMTLib2
 -- | Convert to SMTLib-2 format
@@ -42,6 +43,6 @@
                (pgm, defs) = converter ctx progInfo kindInfo isSat comments qinps consts tbls uis axs asgnsSeq cstrs out config
 
 -- | Convert to SMTLib-2 format
-toIncSMTLib2 :: SMTLibIncConverter [String]
+toIncSMTLib2 :: SMTLibIncConverter [Text]
 toIncSMTLib2 = cvt SMTLib2
   where cvt SMTLib2 = SMT2.cvtInc
diff --git a/Data/SBV/SMT/SMTLib2.hs b/Data/SBV/SMT/SMTLib2.hs
--- a/Data/SBV/SMT/SMTLib2.hs
+++ b/Data/SBV/SMT/SMTLib2.hs
@@ -10,1333 +10,1389 @@
 -----------------------------------------------------------------------------
 
 {-# LANGUAGE NamedFieldPuns      #-}
-{-# LANGUAGE PatternGuards       #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE ViewPatterns        #-}
-
-{-# OPTIONS_GHC -Wall -Werror #-}
-
-module Data.SBV.SMT.SMTLib2(cvt, cvtExp, cvtCV, cvtInc, declUserFuns, constructTables, setSMTOption) where
-
-import Data.List  (intercalate, partition, nub, elemIndex)
-import Data.Maybe (listToMaybe, catMaybes)
-
-import qualified Data.Foldable as F (toList, foldl')
-import qualified Data.Map.Strict      as M
-import qualified Data.IntMap.Strict   as IM
-import           Data.Set             (Set)
-import qualified Data.Set             as Set
-
-import Data.SBV.Core.Data
-import Data.SBV.Core.Kind (smtType, needsFlattening, expandKinds)
-import Data.SBV.Control.Types
-
-import Data.SBV.SMT.Utils
-
-import Data.SBV.Core.Symbolic ( QueryContext(..), SetOp(..), getUserName', getSV, regExpToSMTString, NROp(..)
-                              , SMTDef(..), ResultInp(..), ProgInfo(..), SpecialRelOp(..)
-                              )
-
-import Data.SBV.Utils.PrettyNum (smtRoundingMode, cvToSMTLib)
-
-import qualified Data.Generics.Uniplate.Data as G
-
-import qualified Data.Graph as DG
-
--- | Translate a problem into an SMTLib2 script
-cvt :: SMTLibConverter ([String], [String])
-cvt ctx curProgInfo kindInfo isSat comments allInputs (_, consts) tbls uis defs (SBVPgm asgnsSeq) cstrs out cfg = (pgm, exportedDefs)
-  where allKinds       = Set.toList kindInfo
-
-        -- Below can simply be defined as: nub (sort (G.universeBi asgnsSeq))
-        -- Alas, it turns out this is really expensive when we have nested lambdas, so we do an explicit walk
-        allTopOps = Set.toList $ F.foldl' (\sofar (_, SBVApp o _) -> Set.insert o sofar) Set.empty asgnsSeq
-
-        hasInteger     = KUnbounded `Set.member` kindInfo
-        hasArrays      = not (null [() | KArray{}     <- allKinds])
-        hasNonBVArrays = not (null [() | KArray k1 k2 <- allKinds, not (isBounded k1 && isBounded k2)])
-        hasReal        = KReal      `Set.member` kindInfo
-        hasFP          =  not (null [() | KFP{} <- allKinds])
-                       || KFloat     `Set.member` kindInfo
-                       || KDouble    `Set.member` kindInfo
-        hasString      = KString     `Set.member` kindInfo
-        hasRegExp      = (not . null) [() | (_ :: RegExOp) <- G.universeBi allTopOps]
-        hasChar        = KChar      `Set.member` kindInfo
-        hasRounding    = not $ null [s | (s, _) <- usorts, s == "RoundingMode"]
-        hasBVs         = not (null [() | KBounded{} <- allKinds])
-        usorts         = [(s, dt) | KUserSort s dt <- allKinds]
-        trueUSorts     = [s | (s, _) <- usorts, s /= "RoundingMode"]
-        tupleArities   = findTupleArities kindInfo
-        hasOverflows   = (not . null) [() | (_ :: OvOp) <- G.universeBi allTopOps]
-        hasQuantBools  = (not . null) [() | QuantifiedBool{} <- G.universeBi allTopOps]
-        hasList        = any isList kindInfo
-        hasSets        = any isSet kindInfo
-        hasTuples      = not . null $ tupleArities
-        hasEither      = any isEither kindInfo
-        hasMaybe       = any isMaybe  kindInfo
-        hasRational    = any isRational kindInfo
-        rm             = roundingMode cfg
-        solverCaps     = capabilities (solver cfg)
-
-        (needsQuantifiers, needsSpecialRels) = case curProgInfo of
-           ProgInfo hasQ srs tcs -> (hasQ, not (null srs && null tcs))
-
-        -- Is there a reason why we can't handle this problem?
-        -- NB. There's probably a lot more checking we can do here, but this is a start:
-        doesntHandle = listToMaybe [nope w | (w, have, need) <- checks, need && not (have solverCaps)]
-           where checks = [ ("data types",             supportsDataTypes,          hasTuples || hasEither || hasMaybe)
-                          , ("set operations",         supportsSets,               hasSets)
-                          , ("bit vectors",            supportsBitVectors,         hasBVs)
-                          , ("special relations",      supportsSpecialRels,        needsSpecialRels)
-                          , ("needs quantifiers",      supportsQuantifiers,        needsQuantifiers)
-                          , ("unbounded integers",     supportsUnboundedInts,      hasInteger)
-                          , ("algebraic reals",        supportsReals,              hasReal)
-                          , ("floating-point numbers", supportsIEEE754,            hasFP)
-                          , ("uninterpreted sorts",    supportsUninterpretedSorts, not (null trueUSorts))
-                          ]
-
-                 nope w = [ "***     Given problem requires support for " ++ w
-                          , "***     But the chosen solver (" ++ show (name (solver cfg)) ++ ") doesn't support this feature."
-                          ]
-
-        -- Some cases require all, some require none.
-        setAll reason = ["(set-logic " ++ showLogic Logic_ALL ++ ") ; "  ++ reason ++ ", using catch-all."]
-
-        isCVC5 = case name (solver cfg) of
-                   CVC5 -> True
-                   _    -> False
-
-        -- If ALL is selected, use HO_ALL for CVC5 to get support for higher-order features. Yet another discrepancy.
-        showLogic Logic_ALL | isCVC5 = "HO_ALL"
-        showLogic l                  = show l
-
-        -- Determining the logic is surprisingly tricky!
-        logic
-           -- user told us what to do: so just take it:
-           | Just l <- case [l | SetLogic l <- solverSetOptions cfg] of
-                         []  -> Nothing
-                         [l] -> Just l
-                         ls  -> error $ unlines [ ""
-                                                , "*** Only one setOption call to 'setLogic' is allowed, found: " ++ show (length ls)
-                                                , "***  " ++ unwords (map show ls)
-                                                ]
-           = case l of
-               Logic_NONE -> ["; NB. Not setting the logic per user request of Logic_NONE"]
-               _          -> ["(set-logic " ++ showLogic l ++ ") ; NB. User specified."]
-
-           -- There's a reason why we can't handle this problem:
-           | Just cantDo <- doesntHandle
-           = error $ unlines $   [ ""
-                                 , "*** SBV is unable to choose a proper solver configuration:"
-                                 , "***"
-                                 ]
-                             ++ cantDo
-                             ++ [ "***"
-                                , "*** Please report this as a feature request, either for SBV or the backend solver."
-                                ]
-
-           -- Otherwise, we try to determine the most suitable logic.
-           -- NB. This isn't really fool proof!
-
-           -- we never set QF_S (ALL seems to work better in all cases)
-
-           | needsSpecialRels      = ["; has special relations, no logic set."]
-
-           -- Things that require ALL
-           | hasInteger            = setAll "has unbounded values"
-           | hasRational           = setAll "has rational values"
-           | hasReal               = setAll "has algebraic reals"
-           | not (null trueUSorts) = setAll "has user-defined sorts"
-           | hasNonBVArrays        = setAll "has non-bitvector arrays"
-           | hasTuples             = setAll "has tuples"
-           | hasEither             = setAll "has either type"
-           | hasMaybe              = setAll "has maybe type"
-           | hasSets               = setAll "has sets"
-           | hasList               = setAll "has lists"
-           | hasChar               = setAll "has chars"
-           | hasString             = setAll "has strings"
-           | hasRegExp             = setAll "has regular expressions"
-           | hasOverflows          = setAll "has overflow checks"
-           | hasQuantBools         = setAll "has quantified booleans"
-
-           | hasFP || hasRounding
-           = if needsQuantifiers
-             then ["(set-logic ALL)"]
-             else if hasBVs
-                  then ["(set-logic QF_FPBV)"]
-                  else ["(set-logic QF_FP)"]
-
-           -- If we're in a user query context, we'll pick ALL, otherwise
-           -- we'll stick to some bit-vector logic based on what we see in the problem.
-           -- This is controversial, but seems to work well in practice.
-           | True
-           = case ctx of
-               QueryExternal -> ["(set-logic ALL) ; external query, using all logics."]
-               QueryInternal -> if supportsBitVectors solverCaps
-                                then ["(set-logic " ++ qs ++ as ++ ufs ++ "BV)"]
-                                else ["(set-logic ALL)"] -- fall-thru
-          where qs  | not needsQuantifiers  = "QF_"
-                    | True                  = ""
-                as  | not hasArrays         = ""
-                    | True                  = "A"
-                ufs | null uis && null tbls = ""     -- we represent tables as UFs
-                    | True                  = "UF"
-
-        -- SBV always requires the production of models!
-        getModels   = "(set-option :produce-models true)"
-                    : concat [flattenConfig | any needsFlattening kindInfo, Just flattenConfig <- [supportsFlattenedModels solverCaps]]
-
-        -- process all other settings we're given. If an option cannot be repeated, we only take the last one.
-        userSettings = map (setSMTOption cfg) $ filter (not . isLogic) $ foldr comb [] $ solverSetOptions cfg
-           where -- Logic is already processed, so drop it:
-                 isLogic SetLogic{} = True
-                 isLogic _          = False
-
-                 -- SBV sets diagnostic-output channel on some solvers. If the user also gives it, let's just
-                 -- take it by only taking the last one
-                 isDiagOutput DiagnosticOutputChannel{} = True
-                 isDiagOutput _                         = False
-
-                 comb o rest
-                   | isDiagOutput o && any isDiagOutput rest =     rest
-                   | True                                    = o : rest
-
-        settings =  userSettings        -- NB. Make sure this comes first!
-                 ++ getModels
-                 ++ logic
-
-        (inputs, trackerVars)
-            = case allInputs of
-                ResultTopInps ists -> ists
-                ResultLamInps ps   -> error $ unlines [ ""
-                                                      , "*** Data.SBV.smtLib2: Unexpected lambda inputs in conversion"
-                                                      , "***"
-                                                      , "*** Saw: " ++ show ps
-                                                      ]
-
-        pgm  =  map ("; " ++) comments
-             ++ settings
-             ++ [ "; --- uninterpreted sorts ---" ]
-             ++ concatMap declSort usorts
-             ++ [ "; --- tuples ---" ]
-             ++ concatMap declTuple tupleArities
-             ++ [ "; --- sums ---" ]
-             ++ (if containsSum       kindInfo then declSum       else [])
-             ++ (if containsMaybe     kindInfo then declMaybe     else [])
-             ++ (if containsRationals kindInfo then declRationals else [])
-             ++ [ "; --- literal constants ---" ]
-             ++ concatMap (declConst cfg) consts
-             ++ [ "; --- top level inputs ---"]
-             ++ concat [declareFun s (SBVType [kindOf s]) (userName s) | var <- inputs, let s = getSV var]
-             ++ [ "; --- optimization tracker variables ---" | not (null trackerVars) ]
-             ++ concat [declareFun s (SBVType [kindOf s]) (Just ("tracks " <> nm)) | var <- trackerVars, let s = getSV var, let nm = getUserName' var]
-             ++ [ "; --- constant tables ---" ]
-             ++ concatMap (uncurry (:) . mkTable) constTables
-             ++ [ "; --- non-constant tables ---" ]
-             ++ map nonConstTable nonConstTables
-             ++ [ "; --- uninterpreted constants ---" ]
-             ++ concatMap (declUI curProgInfo) uis
-             ++ [ "; --- user defined functions ---"]
-             ++ userDefs
-             ++ [ "; --- assignments ---" ]
-             ++ concatMap (declDef curProgInfo cfg tableMap) asgns
-             ++ [ "; --- delayedEqualities ---" ]
-             ++ map (\s -> "(assert " ++ s ++ ")") delayedEqualities
-             ++ [ "; --- formula ---" ]
-             ++ finalAssert
-
-        userDefs = declUserFuns defs
-        exportedDefs
-          | null userDefs
-          = ["; No calls to 'smtFunction' found."]
-          | True
-          = "; Automatically generated by SBV. Do not modify!" : userDefs
-
-
-        (tableMap, constTables, nonConstTables) = constructTables rm consts tbls
-
-        delayedEqualities = concatMap snd nonConstTables
-
-        finalAssert
-          | noConstraints = []
-          | True          =    map (\(attr, v) -> "(assert "      ++ addAnnotations attr (mkLiteral v) ++ ")") hardAsserts
-                            ++ map (\(attr, v) -> "(assert-soft " ++ addAnnotations attr (mkLiteral v) ++ ")") softAsserts
-          where mkLiteral (Left  v) =            cvtSV v
-                mkLiteral (Right v) = "(not " ++ cvtSV v ++ ")"
-
-                (noConstraints, assertions) = finalAssertions
-
-                hardAsserts, softAsserts :: [([(String, String)], Either SV SV)]
-                hardAsserts = [(attr, v) | (False, attr, v) <- assertions]
-                softAsserts = [(attr, v) | (True,  attr, v) <- assertions]
-
-        finalAssertions :: (Bool, [(Bool, [(String, String)], Either SV SV)])  -- If Left: positive, Right: negative
-        finalAssertions
-           | null finals = (True,  [(False, [], Left trueSV)])
-           | True        = (False, finals)
-
-           where finals  = cstrs' ++ maybe [] (\r -> [(False, [], r)]) mbO
-
-                 cstrs' =  [(isSoft, attrs, c') | (isSoft, attrs, c) <- F.toList cstrs, Just c' <- [pos c]]
-
-                 mbO | isSat = pos out
-                     | True  = neg out
-
-                 neg s
-                  | s == falseSV = Nothing
-                  | s == trueSV  = Just $ Left falseSV
-                  | True         = Just $ Right s
-
-                 pos s
-                  | s == trueSV  = Nothing
-                  | s == falseSV = Just $ Left falseSV
-                  | True         = Just $ Left s
-
-        asgns = F.toList asgnsSeq
-
-        userNameMap = M.fromList $ map (\nSymVar -> (getSV nSymVar, getUserName' nSymVar)) inputs
-        userName s = case M.lookup s userNameMap of
-                        Just u  | show s /= u -> Just $ "tracks user variable " ++ show u
-                        _                     -> Nothing
-
--- | Declare new sorts
-declSort :: (String, Maybe [String]) -> [String]
-declSort (s, _)
-  | s == "RoundingMode" -- built-in-sort; so don't declare.
-  = []
-declSort (s, Nothing) = [ "(declare-sort " ++ s ++ " 0)  ; N.B. Uninterpreted sort."
-                        , "(declare-fun " ++ witnessName s ++ " () " ++ s ++ ")"
-                        ]
-declSort (s, Just fs) = [ "(declare-datatypes ((" ++ s ++ " 0)) ((" ++ unwords (map (\c -> "(" ++ c ++ ")") fs) ++ ")))"
-                        , "(define-fun " ++ s ++ "_constrIndex ((x " ++ s ++ ")) Int"
-                        ] ++ ["   " ++ body fs (0::Int)] ++ [")"]
-        where body []     _ = ""
-              body [_]    i = show i
-              body (c:cs) i = "(ite (= x " ++ c ++ ") " ++ show i ++ " " ++ body cs (i+1) ++ ")"
-
--- | Declare tuple datatypes
---
--- eg:
---
--- @
--- (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
---                                     ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
---                                                   (proj_2_SBVTuple2 T2))))))
--- @
-declTuple :: Int -> [String]
-declTuple arity
-  | arity == 0 = ["(declare-datatypes ((SBVTuple0 0)) (((mkSBVTuple0))))"]
-  | arity == 1 = error "Data.SBV.declTuple: Unexpected one-tuple"
-  | True       =    (l1 ++ "(par (" ++ unwords [param i | i <- [1..arity]] ++ ")")
-                 :  [pre i ++ proj i ++ post i    | i <- [1..arity]]
-  where l1     = "(declare-datatypes ((SBVTuple" ++ show arity ++ " " ++ show arity ++ ")) ("
-        l2     = replicate (length l1) ' ' ++ "((mkSBVTuple" ++ show arity ++ " "
-        tab    = replicate (length l2) ' '
-
-        pre 1  = l2
-        pre _  = tab
-
-        proj i = "(proj_" ++ show i ++ "_SBVTuple" ++ show arity ++ " " ++ param i ++ ")"
-
-        post i = if i == arity then ")))))" else ""
-
-        param i = "T" ++ show i
-
--- | Find the set of tuple sizes to declare, eg (2-tuple, 5-tuple).
--- NB. We do *not* need to recursively go into list/tuple kinds here,
--- because register-kind function automatically registers all subcomponent
--- kinds, thus everything we need is available at the top-level.
-findTupleArities :: Set Kind -> [Int]
-findTupleArities ks = Set.toAscList
-                    $ Set.map length
-                    $ Set.fromList [ tupKs | KTuple tupKs <- Set.toList ks ]
-
--- | Is @Either@ being used?
-containsSum :: Set Kind -> Bool
-containsSum = not . Set.null . Set.filter isEither
-
--- | Is @Maybe@ being used?
-containsMaybe :: Set Kind -> Bool
-containsMaybe = not . Set.null . Set.filter isMaybe
-
--- | Is @Rational@ being used?
-containsRationals :: Set Kind -> Bool
-containsRationals = not . Set.null . Set.filter isRational
-
-declSum :: [String]
-declSum = [ "(declare-datatypes ((SBVEither 2)) ((par (T1 T2)"
-          , "                                    ((left_SBVEither  (get_left_SBVEither  T1))"
-          , "                                     (right_SBVEither (get_right_SBVEither T2))))))"
-          ]
-
-declMaybe :: [String]
-declMaybe = [ "(declare-datatypes ((SBVMaybe 1)) ((par (T)"
-            , "                                    ((nothing_SBVMaybe)"
-            , "                                     (just_SBVMaybe (get_just_SBVMaybe T))))))"
-            ]
-
--- Internally, we do *not* keep the rationals in reduced form! So, the boolean operators explicitly do the math
--- to make sure equivalent values are treated correctly.
-declRationals :: [String]
-declRationals = [ "(declare-datatype SBVRational ((SBV.Rational (sbv.rat.numerator Int) (sbv.rat.denominator Int))))"
-                , ""
-                , "(define-fun sbv.rat.eq ((x SBVRational) (y SBVRational)) Bool"
-                , "   (= (* (sbv.rat.numerator   x) (sbv.rat.denominator y))"
-                , "      (* (sbv.rat.denominator x) (sbv.rat.numerator   y)))"
-                , ")"
-                , ""
-                , "(define-fun sbv.rat.notEq ((x SBVRational) (y SBVRational)) Bool"
-                , "   (not (sbv.rat.eq x y))"
-                , ")"
-                ]
-
--- | Convert in a query context.
--- NB. We do not store everything in @newKs@ below, but only what we need
--- to do as an extra in the incremental context. See `Data.SBV.Core.Symbolic.registerKind`
--- for a list of what we include, in case something doesn't show up
--- and you need it!
-cvtInc :: SMTLibIncConverter [String]
-cvtInc curProgInfo inps newKs (_, consts) tbls uis (SBVPgm asgnsSeq) cstrs cfg =
-            -- any new settings?
-               settings
-            -- sorts
-            ++ concatMap declSort [(s, dt) | KUserSort s dt <- newKinds]
-            -- tuples. NB. Only declare the new sizes, old sizes persist.
-            ++ concatMap declTuple (findTupleArities newKs)
-            -- sums
-            ++ (if containsSum   newKs then declSum   else [])
-            ++ (if containsMaybe newKs then declMaybe else [])
-            -- constants
-            ++ concatMap (declConst cfg) consts
-            -- inputs
-            ++ concatMap declInp inps
-            -- uninterpreteds
-            ++ concatMap (declUI curProgInfo) uis
-            -- table declarations
-            ++ tableDecls
-            -- expressions
-            ++ concatMap (declDef curProgInfo cfg tableMap) asgnsSeq
-            -- table setups
-            ++ concat tableAssigns
-            -- extra constraints
-            ++ map (\(isSoft, attr, v) -> "(assert" ++ (if isSoft then "-soft " else " ") ++ addAnnotations attr (cvtSV v) ++ ")") (F.toList cstrs)
-  where rm = roundingMode cfg
-
-        newKinds = Set.toList newKs
-
-        declInp (getSV -> s) = declareFun s (SBVType [kindOf s]) Nothing
-
-        (tableMap, allTables) = (tm, ct ++ nct)
-            where (tm, ct, nct) = constructTables rm consts tbls
-
-        (tableDecls, tableAssigns) = unzip $ map mkTable allTables
-
-        -- If we need flattening in models, do emit the required lines if preset
-        settings
-          | any needsFlattening newKinds
-          = concat (catMaybes [supportsFlattenedModels solverCaps])
-          | True
-          = []
-          where solverCaps = capabilities (solver cfg)
-
-declDef :: ProgInfo -> SMTConfig -> TableMap -> (SV, SBVExpr) -> [String]
-declDef curProgInfo cfg tableMap (s, expr) =
-        case expr of
-          SBVApp  (Label m) [e] -> defineFun cfg (s, cvtSV                                   e) (Just m)
-          e                     -> defineFun cfg (s, cvtExp cfg curProgInfo caps rm tableMap e) Nothing
-  where caps = capabilities (solver cfg)
-        rm   = roundingMode cfg
-
-defineFun :: SMTConfig -> (SV, String) -> Maybe String -> [String]
-defineFun cfg (s, def) mbComment
-   | hasDefFun = ["(define-fun "  ++ varT ++ " " ++ def ++ ")" ++ cmnt]
-   | True      = [ "(declare-fun " ++ varT ++ ")" ++ cmnt
-                 , "(assert (= " ++ var ++ " " ++ def ++ "))"
-                 ]
-  where var  = show s
-        varT = var ++ " " ++ svFunType [] s
-        cmnt = maybe "" (" ; " ++) mbComment
-
-        hasDefFun = supportsDefineFun $ capabilities (solver cfg)
-
--- Declare constants. NB. We don't declare true/false; but just inline those as necessary
-declConst :: SMTConfig -> (SV, CV) -> [String]
-declConst cfg (s, c)
-  | s == falseSV || s == trueSV
-  = []
-  | True
-  = defineFun cfg (s, cvtCV (roundingMode cfg) c) Nothing
-
--- Make a function equality of nm against the internal function fun
-mkRelEq :: String -> (String, String) -> Kind -> String
-mkRelEq nm (fun, order) ak = res
-   where lhs = "(" ++ nm ++ " x y)"
-         rhs = "((_ " ++ fun ++ " " ++ order ++ ") x y)"
-         tk  = smtType ak
-         res = "(forall ((x " ++ tk ++ ") (y " ++ tk ++ ")) (= " ++ lhs ++ " " ++ rhs ++ "))"
-
-declUI :: ProgInfo -> (String, (Bool, Maybe [String], SBVType)) -> [String]
-declUI ProgInfo{progTransClosures} (i, (_, _, t)) = declareName i t Nothing ++ declClosure
-  where declClosure | Just external <- lookup i progTransClosures
-                    =  declareName external t Nothing
-                    ++ ["(assert " ++ mkRelEq external ("transitive-closure", i) (argKind t) ++ ")"]
-                    | True
-                    = []
-
-        argKind (SBVType [ka, _, KBool]) = ka
-        argKind _                        = error $ "declUI: Unexpected type for name: " ++ show (i, t)
-
--- Note that even though we get all user defined-functions here (i.e., lambda and axiom), we can only have defined-functions
--- and axioms. We spit axioms as is; and topologically sort the definitions.
-declUserFuns :: [(String, (SMTDef, SBVType))] -> [String]
-declUserFuns ds = map declGroup sorted
-  where mkNode d = (d, fst d, getDeps d)
-
-        getDeps (_, (SMTDef _ d _ _, _)) = d
-
-        mkDecl Nothing  rt = "() "    ++ rt
-        mkDecl (Just p) rt = p ++ " " ++ rt
-
-        sorted = DG.stronglyConnComp (map mkNode ds)
-
-        declGroup (DG.AcyclicSCC b)  = declUserDef False b
-        declGroup (DG.CyclicSCC  bs) = case bs of
-                                         []  -> error "Data.SBV.declFuns: Impossible happened: an empty cyclic group was returned!"
-                                         [x] -> declUserDef True x
-                                         xs  -> declUserDefMulti xs
-
-        declUserDef isRec (nm, (SMTDef fk deps param body, ty)) = ("; " ++ nm ++ " :: " ++ show ty ++ recursive ++ frees ++ "\n") ++ s
-           where (recursive, definer) | isRec = (" [Recursive]", "define-fun-rec")
-                                      | True  = ("",             "define-fun")
-
-                 otherDeps = filter (/= nm) deps
-                 frees | null otherDeps = ""
-                       | True           = " [Refers to: " ++ intercalate ", " otherDeps ++ "]"
-
-                 decl = mkDecl param (smtType fk)
-
-                 s = "(" ++ definer ++ " " ++ nm ++ " " ++ decl ++ "\n" ++ body 2 ++ ")"
-
-        -- declare a bunch of mutually-recursive functions
-        declUserDefMulti bs = render $ map collect bs
-          where collect (nm, (SMTDef fk deps param body, ty)) = (deps, nm, ty, '(' : nm ++ " " ++  decl ++ ")", body 3)
-                  where decl = mkDecl param (smtType fk)
-
-                render defs = intercalate "\n" $
-                                  [ "; " ++ intercalate ", " [n ++ " :: " ++ show ty | (_, n, ty, _, _) <- defs]
-                                  , "(define-funs-rec"
-                                  ]
-                               ++ [ open i ++ param d ++ close1 i | (i, d) <- zip [1..] defs]
-                               ++ [ open i ++ dump  d ++ close2 i | (i, d) <- zip [1..] defs]
-                     where open 1 = "  ("
-                           open _ = "   "
-
-                           param (_deps, _nm, _ty, p, _body) = p
-
-                           dump (deps, nm, ty, _, body) = "; Definition of: " ++ nm ++ " :: " ++ show ty ++ ". [Refers to: " ++ intercalate ", " deps ++ "]"
-                                                        ++ "\n" ++ body
-
-                           ld = length defs
-
-                           close1 n = if n == ld then ")"  else ""
-                           close2 n = if n == ld then "))" else ""
-
-mkTable :: (((Int, Kind, Kind), [SV]), [String]) -> (String, [String])
-mkTable (((i, ak, rk), _elts), is) = (decl, zipWith wrap [(0::Int)..] is ++ setup)
-  where t       = "table" ++ show i
-        decl    = "(declare-fun " ++ t ++ " (" ++ smtType ak ++ ") " ++ smtType rk ++ ")"
-
-        -- Arrange for initializers
-        mkInit idx   = "table" ++ show i ++ "_initializer_" ++ show (idx :: Int)
-        initializer  = "table" ++ show i ++ "_initializer"
-
-        wrap index s = "(define-fun " ++ mkInit index ++ " () Bool " ++ s ++ ")"
-
-        lis  = length is
-
-        setup
-          | lis == 0       = [ "(define-fun " ++ initializer ++ " () Bool true) ; no initialization needed"
-                             ]
-          | lis == 1       = [ "(define-fun " ++ initializer ++ " () Bool " ++ mkInit 0 ++ ")"
-                             , "(assert " ++ initializer ++ ")"
-                             ]
-          | True           = [ "(define-fun " ++ initializer ++ " () Bool (and " ++ unwords (map mkInit [0..lis - 1]) ++ "))"
-                             , "(assert " ++ initializer ++ ")"
-                             ]
-nonConstTable :: (((Int, Kind, Kind), [SV]), [String]) -> String
-nonConstTable (((i, ak, rk), _elts), _) = decl
-  where t    = "table" ++ show i
-        decl = "(declare-fun " ++ t ++ " (" ++ smtType ak ++ ") " ++ smtType rk ++ ")"
-
-constructTables :: RoundingMode -> [(SV, CV)] -> [((Int, Kind, Kind), [SV])]
-                -> ( IM.IntMap String                            -- table enumeration
-                   , [(((Int, Kind, Kind), [SV]), [String])]     -- constant tables
-                   , [(((Int, Kind, Kind), [SV]), [String])]     -- non-constant tables
-                   )
-constructTables rm consts tbls = (tableMap, constTables, nonConstTables)
- where allTables      = [(t, genTableData rm (map fst consts) t) | t <- tbls]
-       constTables    = [(t, d) | (t, Left  d) <- allTables]
-       nonConstTables = [(t, d) | (t, Right d) <- allTables]
-       tableMap       = IM.fromList $ map grab allTables
-
-       grab (((t, _, _), _), _) = (t, "table" ++ show t)
-
--- Left if all constants, Right if otherwise
-genTableData :: RoundingMode -> [SV] -> ((Int, Kind, Kind), [SV]) -> Either [String] [String]
-genTableData rm consts ((i, aknd, _), elts)
-  | null post = Left  (map (mkEntry . snd) pre)
-  | True      = Right (map (mkEntry . snd) (pre ++ post))
-  where (pre, post) = partition fst (zipWith mkElt elts [(0::Int)..])
-        t           = "table" ++ show i
-
-        mkElt x k   = (isReady, (idx, cvtSV x))
-          where idx = cvtCV rm (mkConstCV aknd k)
-                isReady = x `Set.member` constsSet
-
-        mkEntry (idx, v) = "(= (" ++ t ++ " " ++ idx ++ ") " ++ v ++ ")"
-
-        constsSet = Set.fromList consts
-
-svType :: SV -> String
-svType s = smtType (kindOf s)
-
-svFunType :: [SV] -> SV -> String
-svFunType ss s = "(" ++ unwords (map svType ss) ++ ") " ++ svType s
-
-cvtType :: SBVType -> String
-cvtType (SBVType []) = error "SBV.SMT.SMTLib2.cvtType: internal: received an empty type!"
-cvtType (SBVType xs) = "(" ++ unwords (map smtType body) ++ ") " ++ smtType ret
-  where (body, ret) = (init xs, last xs)
-
-type TableMap = IM.IntMap String
-
--- Present an SV, simply show
-cvtSV :: SV -> String
-cvtSV = show
-
-cvtCV :: RoundingMode -> CV -> String
-cvtCV = cvToSMTLib
-
-getTable :: TableMap -> Int -> String
-getTable m i
-  | Just tn <- i `IM.lookup` m = tn
-  | True                       = "table" ++ show i  -- constant tables are always named this way
-
-cvtExp :: SMTConfig -> ProgInfo -> SolverCapabilities -> RoundingMode -> TableMap -> SBVExpr -> String
-cvtExp cfg curProgInfo caps rm tableMap expr@(SBVApp _ arguments) = sh expr
-  where hasPB       = supportsPseudoBooleans caps
-        hasDistinct = supportsDistinct       caps
-        specialRels = progSpecialRels        curProgInfo
-
-        bvOp     = all isBounded   arguments
-        intOp    = any isUnbounded arguments
-        ratOp    = any isRational  arguments
-        realOp   = any isReal      arguments
-        fpOp     = any (\a -> isDouble a || isFloat a || isFP a) arguments
-        boolOp   = all isBoolean   arguments
-        charOp   = any isChar      arguments
-        stringOp = any isString    arguments
-        listOp   = any isList      arguments
-
-        bad | intOp = error $ "SBV.SMTLib2: Unsupported operation on unbounded integers: " ++ show expr
-            | True  = error $ "SBV.SMTLib2: Unsupported operation on real values: " ++ show expr
-
-        ensureBVOrBool = bvOp || boolOp || bad
-        ensureBV       = bvOp || bad
-
-        addRM s = s ++ " " ++ smtRoundingMode rm
-
-        isZ3 = case name (solver cfg) of
-                 Z3 -> True
-                 _  -> False
-
-        isCVC5 = case name (solver cfg) of
-                   CVC5 -> True
-                   _    -> False
-
-        hd _ (a:_) = a
-        hd w []    = error $ "Impossible: " ++ w ++ ": Received empty list of args!"
-
-        -- lift a binary op
-        lift2  o _ [x, y] = "(" ++ o ++ " " ++ x ++ " " ++ y ++ ")"
-        lift2  o _ sbvs   = error $ "SBV.SMTLib2.sh.lift2: Unexpected arguments: "   ++ show (o, sbvs)
-
-        -- lift an arbitrary arity operator
-        liftN o _ xs = "(" ++ o ++ " " ++ unwords xs ++ ")"
-
-        -- lift a binary operation with rounding-mode added; used for floating-point arithmetic
-        lift2WM o fo | fpOp = lift2 (addRM fo)
-                     | True = lift2 o
-
-        lift1FP o fo | fpOp = lift1 fo
-                     | True = lift1 o
-
-        liftAbs sgned args | fpOp        = lift1 "fp.abs" sgned args
-                           | intOp       = lift1 "abs"    sgned args
-                           | bvOp, sgned = mkAbs fArg "bvslt" "bvneg"
-                           | bvOp        = fArg
-                           | True        = mkAbs fArg "<"     "-"
-          where fArg = hd "liftAbs" args
-                mkAbs x cmp neg = "(ite " ++ ltz ++ " " ++ nx ++ " " ++ x ++ ")"
-                  where ltz = "(" ++ cmp ++ " " ++ x ++ " " ++ z ++ ")"
-                        nx  = "(" ++ neg ++ " " ++ x ++ ")"
-                        z   = cvtCV rm (mkConstCV (kindOf (hd "liftAbs.arguments" arguments)) (0::Integer))
-
-        lift2B bOp vOp
-          | boolOp = lift2 bOp
-          | True   = lift2 vOp
-
-        lift1B bOp vOp
-          | boolOp = lift1 bOp
-          | True   = lift1 vOp
-
-        eqBV  = lift2 "="
-        neqBV = liftN "distinct"
-
-        equal sgn sbvs
-          | fpOp = lift2 "fp.eq" sgn sbvs
-          | True = lift2 "="     sgn sbvs
-
-        -- Do not use distinct on floats; because +0/-0, and NaNs mess
-        -- up the meaning. Just go with reqular equals.
-        notEqual sgn sbvs
-          | fpOp || not hasDistinct = liftP sbvs
-          | True                    = liftN "distinct" sgn sbvs
-          where liftP xs@[_, _] = "(not " ++ equal sgn xs ++ ")"
-                liftP args      = "(and " ++ unwords (walk args) ++ ")"
-
-                walk []     = []
-                walk (e:es) = map (\e' -> liftP [e, e']) es ++ walk es
-
-        lift2S oU oS sgn = lift2 (if sgn then oS else oU) sgn
-        liftNS oU oS sgn = liftN (if sgn then oS else oU) sgn
-
-        lift2Cmp o fo | fpOp = lift2 fo
-                      | True = lift2 o
-
-        unintComp o [a, b]
-          | KUserSort s (Just _) <- kindOf (hd "unintComp" arguments)
-          = let idx v = "(" ++ s ++ "_constrIndex " ++ v ++ ")" in "(" ++ o ++ " " ++ idx a ++ " " ++ idx b ++ ")"
-        unintComp o sbvs = error $ "SBV.SMT.SMTLib2.sh.unintComp: Unexpected arguments: "   ++ show (o, sbvs, map kindOf arguments)
-
-        stringOrChar KString = True
-        stringOrChar KChar   = True
-        stringOrChar _       = False
-        stringCmp swap o [a, b]
-          | stringOrChar (kindOf (hd "stringCmp" arguments))
-          = let (a1, a2) | swap = (b, a)
-                         | True = (a, b)
-            in "(" ++ o ++ " " ++ a1 ++ " " ++ a2 ++ ")"
-        stringCmp _ o sbvs = error $ "SBV.SMT.SMTLib2.sh.stringCmp: Unexpected arguments: " ++ show (o, sbvs)
-
-        -- NB. Likewise for sequences
-        seqCmp swap o [a, b]
-          | KList{} <- kindOf (hd "seqCmp" arguments)
-          = let (a1, a2) | swap = (b, a)
-                         | True = (a, b)
-            in "(" ++ o ++ " " ++ a1 ++ " " ++ a2 ++ ")"
-        seqCmp _ o sbvs = error $ "SBV.SMT.SMTLib2.sh.seqCmp: Unexpected arguments: " ++ show (o, sbvs)
-
-        lift1  o _ [x]    = "(" ++ o ++ " " ++ x ++ ")"
-        lift1  o _ sbvs   = error $ "SBV.SMT.SMTLib2.sh.lift1: Unexpected arguments: "   ++ show (o, sbvs)
-
-        -- We fully qualify the constructor with their types to work around type checking issues
-        -- Note that this is rather bizarre, as we're tagging the constructor with its *result* type,
-        -- not its full function type as one would expect. But this is per the spec: Pg. 27 of SMTLib 2.6 spec
-        -- says:
-        --
-        --    To simplify sort checking, a function symbol in a term can be annotated with one of its result sorts sigma.
-        --
-        -- I wish it was the full type here not just the result, but we go with the spec. Also see: <http://github.com/Z3Prover/z3/issues/2135>
-        -- and in particular <http://github.com/Z3Prover/z3/issues/2135#issuecomment-477636435>
-        dtConstructor fld args res = "((as " ++ fld ++ " " ++ smtType res ++ ") " ++ unwords (map cvtSV args) ++ ")"
-
-        -- Similarly, we fully qualify the accessors with their types to work around type checking issues
-        -- Unfortunately, z3 and CVC4 are behaving differently, so we tie this ascription to a solver capability.
-        dtAccessor fld params res
-           | supportsDirectAccessors caps = dResult
-           | True                         = aResult
-          where dResult = "(_ is " ++ fld ++ ")"
-                ps      = " (" ++ unwords (map smtType params) ++ ") "
-                aResult = "(_ is (" ++ fld ++ ps ++ smtType res ++ "))"
-
-        sh (SBVApp Ite [a, b, c]) = "(ite " ++ cvtSV a ++ " " ++ cvtSV b ++ " " ++ cvtSV c ++ ")"
-
-        sh (SBVApp (LkUp (t, aKnd, _, l) i e) [])
-          | needsCheck = "(ite " ++ cond ++ cvtSV e ++ " " ++ lkUp ++ ")"
-          | True       = lkUp
-          where needsCheck = case aKnd of
-                              KBool         -> (2::Integer) > fromIntegral l
-                              KBounded _ n  -> (2::Integer)^n > fromIntegral l
-                              KUnbounded    -> True
-                              KUserSort s _ -> error $ "SBV.SMT.SMTLib2.cvtExp: unexpected uninterpreted valued index: " ++ s
-                              KReal         -> error "SBV.SMT.SMTLib2.cvtExp: unexpected real valued index"
-                              KFloat        -> error "SBV.SMT.SMTLib2.cvtExp: unexpected float valued index"
-                              KDouble       -> error "SBV.SMT.SMTLib2.cvtExp: unexpected double valued index"
-                              KFP{}         -> error "SBV.SMT.SMTLib2.cvtExp: unexpected arbitrary float valued index"
-                              KRational{}   -> error "SBV.SMT.SMTLib2.cvtExp: unexpected rational valued index"
-                              KChar         -> error "SBV.SMT.SMTLib2.cvtExp: unexpected char valued index"
-                              KString       -> error "SBV.SMT.SMTLib2.cvtExp: unexpected string valued index"
-                              KList k       -> error $ "SBV.SMT.SMTLib2.cvtExp: unexpected list valued: " ++ show k
-                              KSet  k       -> error $ "SBV.SMT.SMTLib2.cvtExp: unexpected set valued: " ++ show k
-                              KTuple k      -> error $ "SBV.SMT.SMTLib2.cvtExp: unexpected tuple valued: " ++ show k
-                              KMaybe k      -> error $ "SBV.SMT.SMTLib2.cvtExp: unexpected maybe valued: " ++ show k
-                              KEither k1 k2 -> error $ "SBV.SMT.SMTLib2.cvtExp: unexpected sum valued: " ++ show (k1, k2)
-                              KArray  k1 k2 -> error $ "SBV.SMT.SMTLib2.cvtExp: unexpected array valued: " ++ show (k1, k2)
-
-                lkUp = "(" ++ getTable tableMap t ++ " " ++ cvtSV i ++ ")"
-
-                cond
-                 | hasSign i = "(or " ++ le0 ++ " " ++ gtl ++ ") "
-                 | True      = gtl ++ " "
-
-                (less, leq) = case aKnd of
-                                KBool         -> error "SBV.SMT.SMTLib2.cvtExp: unexpected boolean valued index"
-                                KBounded{}    -> if hasSign i then ("bvslt", "bvsle") else ("bvult", "bvule")
-                                KUnbounded    -> ("<", "<=")
-                                KReal         -> ("<", "<=")
-                                KFloat        -> ("fp.lt", "fp.leq")
-                                KDouble       -> ("fp.lt", "fp.leq")
-                                KRational     -> ("sbv.rat.lt", "sbv.rat.leq")
-                                KFP{}         -> ("fp.lt", "fp.leq")
-                                KChar         -> error "SBV.SMT.SMTLib2.cvtExp: unexpected string valued index"
-                                KString       -> error "SBV.SMT.SMTLib2.cvtExp: unexpected string valued index"
-                                KUserSort s _ -> error $ "SBV.SMT.SMTLib2.cvtExp: unexpected uninterpreted valued index: " ++ s
-                                KList k       -> error $ "SBV.SMT.SMTLib2.cvtExp: unexpected sequence valued index: " ++ show k
-                                KSet  k       -> error $ "SBV.SMT.SMTLib2.cvtExp: unexpected set valued index: " ++ show k
-                                KTuple k      -> error $ "SBV.SMT.SMTLib2.cvtExp: unexpected tuple valued index: " ++ show k
-                                KMaybe k      -> error $ "SBV.SMT.SMTLib2.cvtExp: unexpected maybe valued index: " ++ show k
-                                KEither k1 k2 -> error $ "SBV.SMT.SMTLib2.cvtExp: unexpected sum valued index: " ++ show (k1, k2)
-                                KArray  k1 k2 -> error $ "SBV.SMT.SMTLib2.cvtExp: unexpected array valued index: " ++ show (k1, k2)
-
-                mkCnst = cvtCV rm . mkConstCV (kindOf i)
-                le0  = "(" ++ less ++ " " ++ cvtSV i ++ " " ++ mkCnst 0 ++ ")"
-                gtl  = "(" ++ leq  ++ " " ++ mkCnst l ++ " " ++ cvtSV i ++ ")"
-
-        sh (SBVApp (KindCast f t) [a]) = handleKindCast f t (cvtSV a)
-
-        sh (SBVApp (ArrayLambda s) [])        = show s
-        sh (SBVApp ReadArray       [a, i])    = "(select " ++ cvtSV a ++ " " ++ cvtSV i ++ ")"
-        sh (SBVApp WriteArray      [a, i, e]) = "(store "  ++ cvtSV a ++ " " ++ cvtSV i ++ " " ++ cvtSV e ++ ")"
-
-        sh (SBVApp (Uninterpreted nm) [])   = nm
-        sh (SBVApp (Uninterpreted nm) args) = "(" ++ nm ++ " " ++ unwords (map cvtSV args) ++ ")"
-
-        sh (SBVApp (QuantifiedBool i) [])   = i
-        sh (SBVApp (QuantifiedBool i) args) = error $ "SBV.SMT.SMTLib2.cvtExp: unexpected arguments to quantified boolean: " ++ show (i, args)
-
-        sh a@(SBVApp (SpecialRelOp k o) args)
-          | not (null args)
-          = error $ "SBV.SMT.SMTLib2.cvtExp: unexpected arguments to special op: " ++ show a
-          | True
-          = let order = case o `elemIndex` specialRels of
-                          Just i -> i
-                          Nothing -> error $ unlines [ "SBV.SMT.SMTLib2.cvtExp: Cannot find " ++ show o ++ " in the special-relations list."
-                                                     , "Known relations: " ++ intercalate ", " (map show specialRels)
-                                                     ]
-                asrt nm fun = mkRelEq nm (fun, show order) k
-            in case o of
-                 IsPartialOrder         nm -> asrt nm "partial-order"
-                 IsLinearOrder          nm -> asrt nm "linear-order"
-                 IsTreeOrder            nm -> asrt nm "tree-order"
-                 IsPiecewiseLinearOrder nm -> asrt nm "piecewise-linear-order"
-
-        sh (SBVApp (Divides n) [a]) = "((_ divisible " ++ show n ++ ") " ++ cvtSV a ++ ")"
-
-        sh (SBVApp (Extract i j) [a]) | ensureBV = "((_ extract " ++ show i ++ " " ++ show j ++ ") " ++ cvtSV a ++ ")"
-
-        sh (SBVApp (Rol i) [a])
-           | bvOp  = rot "rotate_left"  i a
-           | True  = bad
-
-        sh (SBVApp (Ror i) [a])
-           | bvOp  = rot  "rotate_right" i a
-           | True  = bad
-
-        sh (SBVApp Shl [a, i])
-           | bvOp   = shft "bvshl"  "bvshl" a i
-           | True   = bad
-
-        sh (SBVApp Shr [a, i])
-           | bvOp  = shft "bvlshr" "bvashr" a i
-           | True  = bad
-
-        sh (SBVApp (ZeroExtend i) [a])
-          | bvOp = "((_ zero_extend " ++ show i ++ ") " ++ cvtSV a ++ ")"
-          | True = bad
-
-        sh (SBVApp (SignExtend i) [a])
-          | bvOp = "((_ sign_extend " ++ show i ++ ") " ++ cvtSV a ++ ")"
-          | True = bad
-
-        sh (SBVApp op args)
-          | Just f <- lookup op smtBVOpTable, ensureBVOrBool
-          = f (any hasSign args) (map cvtSV args)
-          where -- The first 4 operators below do make sense for Integer's in Haskell, but there's
-                -- no obvious counterpart for them in the SMTLib translation.
-                -- TODO: provide support for these.
-                smtBVOpTable = [ (And,  lift2B "and" "bvand")
-                               , (Or,   lift2B "or"  "bvor")
-                               , (XOr,  lift2B "xor" "bvxor")
-                               , (Not,  lift1B "not" "bvnot")
-                               , (Join, lift2 "concat")
-                               ]
-
-        sh (SBVApp (Label _) [a]) = cvtSV a  -- This won't be reached; but just in case!
-
-        sh (SBVApp (IEEEFP (FP_Cast kFrom kTo m)) args) = handleFPCast kFrom kTo (cvtSV m) (unwords (map cvtSV args))
-        sh (SBVApp (IEEEFP w                    ) args) = "(" ++ show w ++ " " ++ unwords (map cvtSV args) ++ ")"
-
-        -- Some non-linear operators are supported by z3/CVC5 specifically, so do the custom translation Otherwise
-        -- we pass them along.
-        sh (SBVApp (NonLinear NR_Sqrt) [a])    | isZ3   = "(^ "    ++ cvtSV a ++ " 0.5)"
-                                               | isCVC5 = "(sqrt " ++ cvtSV a ++     ")"
-
-        sh (SBVApp (NonLinear NR_Pow)  [a, b]) | isZ3 || isCVC5  = "(^  " ++ cvtSV a ++ " " ++ cvtSV b ++ ")"
-
-        sh (SBVApp (NonLinear w) args) = "(" ++ show w ++ " " ++ unwords (map cvtSV args) ++ ")"
-
-        sh (SBVApp (PseudoBoolean pb) args)
-          | hasPB = handlePB pb args'
-          | True  = reducePB pb args'
-          where args' = map cvtSV args
-
-        sh (SBVApp (OverflowOp op) args) = "(" ++ show op ++ " " ++ unwords (map cvtSV args) ++ ")"
-
-        -- Note the unfortunate reversal in StrInRe..
-        sh (SBVApp (StrOp (StrInRe r)) args) = "(str.in.re " ++ unwords (map cvtSV args) ++ " " ++ regExpToSMTString r ++ ")"
-        sh (SBVApp (StrOp op)          args) = "(" ++ show op ++ " " ++ unwords (map cvtSV args) ++ ")"
-
-        sh (SBVApp (RegExOp o@RegExEq{})  []) = show o
-        sh (SBVApp (RegExOp o@RegExNEq{}) []) = show o
-
-        -- Sequences. The only interesting thing here is that unit over KChar is a no-op since SMTLib doesn't distinguish
-        -- Strings and Characters, but SBV does.
-        sh (SBVApp (SeqOp (SeqUnit KChar)) [a]) = cvtSV a
-        sh (SBVApp (SeqOp op)             args) = "(" ++ show op ++ " " ++ unwords (map cvtSV args) ++ ")"
-
-        sh (SBVApp (SetOp SetEqual)      args)   = "(= "      ++ unwords (map cvtSV args) ++ ")"
-        sh (SBVApp (SetOp SetMember)     [e, s]) = "(select " ++ cvtSV s ++ " " ++ cvtSV e ++ ")"
-        sh (SBVApp (SetOp SetInsert)     [e, s]) = "(store "  ++ cvtSV s ++ " " ++ cvtSV e ++ " true)"
-        sh (SBVApp (SetOp SetDelete)     [e, s]) = "(store "  ++ cvtSV s ++ " " ++ cvtSV e ++ " false)"
-        sh (SBVApp (SetOp SetIntersect)  args)   = "(intersection " ++ unwords (map cvtSV args) ++ ")"
-        sh (SBVApp (SetOp SetUnion)      args)   = "(union "        ++ unwords (map cvtSV args) ++ ")"
-        sh (SBVApp (SetOp SetSubset)     args)   = "(subset "       ++ unwords (map cvtSV args) ++ ")"
-        sh (SBVApp (SetOp SetDifference) args)   = "(setminus "     ++ unwords (map cvtSV args) ++ ")"
-        sh (SBVApp (SetOp SetComplement) args)   = "(complement "   ++ unwords (map cvtSV args) ++ ")"
-
-        sh (SBVApp (TupleConstructor 0)   [])    = "mkSBVTuple0"
-        sh (SBVApp (TupleConstructor n)   args)  = "((as mkSBVTuple" ++ show n ++ " " ++ smtType (KTuple (map kindOf args)) ++ ") " ++ unwords (map cvtSV args) ++ ")"
-        sh (SBVApp (TupleAccess      i n) [tup]) = "(proj_" ++ show i ++ "_SBVTuple" ++ show n ++ " " ++ cvtSV tup ++ ")"
-
-        sh (SBVApp (EitherConstructor k1 k2 False) [arg]) =       dtConstructor "left_SBVEither"  [arg] (KEither k1 k2)
-        sh (SBVApp (EitherConstructor k1 k2 True ) [arg]) =       dtConstructor "right_SBVEither" [arg] (KEither k1 k2)
-        sh (SBVApp (EitherIs          k1 k2 False) [arg]) = '(' : dtAccessor    "left_SBVEither"  [k1]  (KEither k1 k2) ++ " " ++ cvtSV arg ++ ")"
-        sh (SBVApp (EitherIs          k1 k2 True ) [arg]) = '(' : dtAccessor    "right_SBVEither" [k2]  (KEither k1 k2) ++ " " ++ cvtSV arg ++ ")"
-        sh (SBVApp (EitherAccess            False) [arg]) = "(get_left_SBVEither "  ++ cvtSV arg ++ ")"
-        sh (SBVApp (EitherAccess            True ) [arg]) = "(get_right_SBVEither " ++ cvtSV arg ++ ")"
-
-        sh (SBVApp  RationalConstructor    [t, b]) = "(SBV.Rational " ++ cvtSV t ++ " " ++ cvtSV b ++ ")"
-
-        sh (SBVApp (MaybeConstructor k False) [])    =       dtConstructor "nothing_SBVMaybe" []    (KMaybe k)
-        sh (SBVApp (MaybeConstructor k True)  [arg]) =       dtConstructor "just_SBVMaybe"    [arg] (KMaybe k)
-        sh (SBVApp (MaybeIs          k False) [arg]) = '(' : dtAccessor    "nothing_SBVMaybe" []    (KMaybe k) ++ " " ++ cvtSV arg ++ ")"
-        sh (SBVApp (MaybeIs          k True ) [arg]) = '(' : dtAccessor    "just_SBVMaybe"    [k]   (KMaybe k) ++ " " ++ cvtSV arg ++ ")"
-        sh (SBVApp MaybeAccess                [arg]) = "(get_just_SBVMaybe " ++ cvtSV arg ++ ")"
-
-        sh (SBVApp Implies [a, b]) = "(=> " ++ cvtSV a ++ " " ++ cvtSV b ++ ")"
-
-        sh inp@(SBVApp op args)
-          | intOp, Just f <- lookup op smtOpIntTable
-          = f True (map cvtSV args)
-          | boolOp, Just f <- lookup op boolComps
-          = f (map cvtSV args)
-          | bvOp, Just f <- lookup op smtOpBVTable
-          = f (any hasSign args) (map cvtSV args)
-          | realOp, Just f <- lookup op smtOpRealTable
-          = f (any hasSign args) (map cvtSV args)
-          | ratOp, Just f <- lookup op ratOpTable
-          = f (map cvtSV args)
-          | fpOp, Just f <- lookup op smtOpFloatDoubleTable
-          = f (any hasSign args) (map cvtSV args)
-          | charOp || stringOp, Just f <- lookup op smtStringTable
-          = f (map cvtSV args)
-          | listOp, Just f <- lookup op smtListTable
-          = f (map cvtSV args)
-          | Just f <- lookup op uninterpretedTable
-          = f (map cvtSV args)
-          | True
-          = if not (null args) && isUserSort (hd "isUserSort" args)
-            then error $ unlines [ ""
-                                 , "*** Cannot translate operator        : " ++ show op
-                                 , "*** When applied to arguments of kind: " ++ intercalate ", " (nub (map (show . kindOf) args))
-                                 , "*** Found as part of the expression  : " ++ show inp
-                                 , "***"
-                                 , "*** Note that uninterpreted kinds only support equality."
-                                 , "*** If you believe this is in error, please report!"
-                                 ]
-            else error $ unlines [ ""
-                                 , "*** SBV.SMT.SMTLib2.cvtExp.sh: impossible happened; can't translate: " ++ show inp
-                                 , "***"
-                                 , "*** Applied to arguments of type: " ++ intercalate ", " (nub (map (show . kindOf) args))
-                                 , "***"
-                                 , "*** This can happen if the Num instance isn't properly defined for a lifted kind."
-                                 , "*** (See https://github.com/LeventErkok/sbv/issues/698 for a discussion.)"
-                                 , "***"
-                                 , "*** If you believe this is in error, please report!"
-                                 ]
-          where smtOpBVTable  = [ (Plus,          lift2   "bvadd")
-                                , (Minus,         lift2   "bvsub")
-                                , (Times,         lift2   "bvmul")
-                                , (UNeg,          lift1B  "not"    "bvneg")
-                                , (Abs,           liftAbs)
-                                , (Quot,          lift2S  "bvudiv" "bvsdiv")
-                                , (Rem,           lift2S  "bvurem" "bvsrem")
-                                , (Equal True,    eqBV)
-                                , (Equal False,   eqBV)
-                                , (NotEqual,      neqBV)
-                                , (LessThan,      lift2S  "bvult" "bvslt")
-                                , (GreaterThan,   lift2S  "bvugt" "bvsgt")
-                                , (LessEq,        lift2S  "bvule" "bvsle")
-                                , (GreaterEq,     lift2S  "bvuge" "bvsge")
-                                ]
-
-                -- Boolean comparisons.. SMTLib's bool type doesn't do comparisons, but Haskell does.. Sigh
-                boolComps      = [ (LessThan,      blt)
-                                 , (GreaterThan,   blt . swp)
-                                 , (LessEq,        blq)
-                                 , (GreaterEq,     blq . swp)
-                                 ]
-                               where blt [x, y] = "(and (not " ++ x ++ ") " ++ y ++ ")"
-                                     blt xs     = error $ "SBV.SMT.SMTLib2.boolComps.blt: Impossible happened, incorrect arity (expected 2): " ++ show xs
-                                     blq [x, y] = "(or (not " ++ x ++ ") " ++ y ++ ")"
-                                     blq xs     = error $ "SBV.SMT.SMTLib2.boolComps.blq: Impossible happened, incorrect arity (expected 2): " ++ show xs
-                                     swp [x, y] = [y, x]
-                                     swp xs     = error $ "SBV.SMT.SMTLib2.boolComps.swp: Impossible happened, incorrect arity (expected 2): " ++ show xs
-
-                smtOpRealTable =  smtIntRealShared
-                               ++ [ (Quot,        lift2WM "/" "fp.div")
-                                  ]
-
-                smtOpIntTable  = smtIntRealShared
-                               ++ [ (Quot,        lift2   "div")
-                                  , (Rem,         lift2   "mod")
-                                  ]
-
-                smtOpFloatDoubleTable = smtIntRealShared
-                                  ++ [(Quot, lift2WM "/" "fp.div")]
-
-                smtIntRealShared  = [ (Plus,          lift2WM "+" "fp.add")
-                                    , (Minus,         lift2WM "-" "fp.sub")
-                                    , (Times,         lift2WM "*" "fp.mul")
-                                    , (UNeg,          lift1FP "-" "fp.neg")
-                                    , (Abs,           liftAbs)
-                                    , (Equal True,    equal)
-                                    , (Equal False,   equal)
-                                    , (NotEqual,      notEqual)
-                                    , (LessThan,      lift2Cmp  "<"  "fp.lt")
-                                    , (GreaterThan,   lift2Cmp  ">"  "fp.gt")
-                                    , (LessEq,        lift2Cmp  "<=" "fp.leq")
-                                    , (GreaterEq,     lift2Cmp  ">=" "fp.geq")
-                                    ]
-
-                ratOpTable = [ (Equal True,  lift2Rat "sbv.rat.eq")
-                             , (Equal False, lift2Rat "sbv.rat.eq")
-                             , (NotEqual,    lift2Rat "sbv.rat.notEq")
-                             ]
-                        where lift2Rat o [x, y] = "(" ++ o ++ " " ++ x ++ " " ++ y ++ ")"
-                              lift2Rat o sbvs   = error $ "SBV.SMTLib2.sh.lift2Rat: Unexpected arguments: "   ++ show (o, sbvs)
-
-                -- equality and comparisons are the only thing that works on uninterpreted sorts and pretty much everything else
-                uninterpretedTable = [ (Equal True,  lift2S "="        "="        True)
-                                     , (Equal False, lift2S "="        "="        True)
-                                     , (NotEqual,    liftNS "distinct" "distinct" True)
-                                     , (LessThan,    unintComp "<")
-                                     , (GreaterThan, unintComp ">")
-                                     , (LessEq,      unintComp "<=")
-                                     , (GreaterEq,   unintComp ">=")
-                                     ]
-
-                -- For strings, equality and comparisons are the only operators
-                smtStringTable = [ (Equal True,  lift2S "="        "="        True)
-                                 , (Equal False, lift2S "="        "="        True)
-                                 , (NotEqual,    liftNS "distinct" "distinct" True)
-                                 , (LessThan,    stringCmp False "str.<")
-                                 , (GreaterThan, stringCmp True  "str.<")
-                                 , (LessEq,      stringCmp False "str.<=")
-                                 , (GreaterEq,   stringCmp True  "str.<=")
-                                 ]
-
-                -- For lists, equality is really the only operator. Also, not strong-equality due to lists of floats.
-                -- Likewise here, things might change for comparisons
-                smtListTable = [ (Equal False, lift2S "="        "="        True)
-                               , (NotEqual,    liftNS "distinct" "distinct" True)
-                               , (LessThan,    seqCmp False "seq.<")
-                               , (GreaterThan, seqCmp True  "seq.<")
-                               , (LessEq,      seqCmp False "seq.<=")
-                               , (GreaterEq,   seqCmp True  "seq.<=")
-                               ]
-
-declareFun :: SV -> SBVType -> Maybe String -> [String]
-declareFun = declareName . show
-
--- If we have a char, we have to make sure it's and SMTLib string of length exactly one
--- If we have a rational, we have to make sure the denominator is > 0
--- Otherwise, we just declare the name
-declareName :: String -> SBVType -> Maybe String -> [String]
-declareName s t@(SBVType inputKS) mbCmnt = decl : restrict
-  where decl        = "(declare-fun " ++ s ++ " " ++ cvtType t ++ ")" ++ maybe "" (" ; " ++) mbCmnt
-
-        (args, result) = case inputKS of
-                          [] -> error $ "SBV.declareName: Unexpected empty type for: " ++ show s
-                          _  -> (init inputKS, last inputKS)
-
-        -- Does the kind KChar and KRational *not* occur in the kind anywhere?
-        charRatFree k = all notCharOrRat (expandKinds k)
-           where notCharOrRat KChar     = False
-                 notCharOrRat KRational = False
-                 notCharOrRat _         = True
-
-        noCharOrRat   = charRatFree result
-        needsQuant    = not $ null args
-
-        resultVar | needsQuant = "result"
-                  | True       = s
-
-        argList   = ["a" ++ show i | (i, _) <- zip [1::Int ..] args]
-        argTList  = ["(" ++ a ++ " " ++ smtType k ++ ")" | (a, k) <- zip argList args]
-        resultExp = "(" ++ s ++ " " ++ unwords argList ++ ")"
-
-        restrict | noCharOrRat = []
-                 | needsQuant  =    [               "(assert (forall (" ++ unwords argTList ++ ")"
-                                    ,               "                (let ((" ++ resultVar ++ " " ++ resultExp ++ "))"
-                                    ]
-                                 ++ (case constraints of
-                                       []     ->  [ "                     true"]
-                                       [x]    ->  [ "                     " ++ x]
-                                       (x:xs) ->  ( "                     (and " ++ x)
-                                               :  [ "                          " ++ c | c <- xs]
-                                               ++ [ "                     )"])
-                                 ++ [        "                )))"]
-                 | True        = case constraints of
-                                  []     -> []
-                                  [x]    -> ["(assert " ++ x ++ ")"]
-                                  (x:xs) -> ( "(assert (and " ++ x)
-                                         :  [ "             " ++ c | c <- xs]
-                                         ++ [ "        ))"]
-
-        constraints = walk 0 resultVar cstr result
-          where cstr KChar     nm = ["(= 1 (str.len " ++ nm ++ "))"]
-                cstr KRational nm = ["(< 0 (sbv.rat.denominator " ++ nm ++ "))"]
-                cstr _         _  = []
-
-        mkAnd [] _context = []
-        mkAnd [c] context = context c
-        mkAnd cs  context = context $ "(and " ++ unwords cs ++ ")"
-
-        walk :: Int -> String -> (Kind -> String -> [String]) -> Kind -> [String]
-        walk _d nm f k@KBool     {}         = f k nm
-        walk _d nm f k@KBounded  {}         = f k nm
-        walk _d nm f k@KUnbounded{}         = f k nm
-        walk _d nm f k@KReal     {}         = f k nm
-        walk _d nm f k@KUserSort {}         = f k nm
-        walk _d nm f k@KFloat    {}         = f k nm
-        walk _d nm f k@KDouble   {}         = f k nm
-        walk _d nm f k@KRational {}         = f k nm
-        walk _d nm f k@KFP       {}         = f k nm
-        walk _d nm f k@KChar     {}         = f k nm
-        walk _d nm f k@KString   {}         = f k nm
-        walk  d nm f  (KList k)
-          | charRatFree k                 = []
-          | True                          = let fnm   = "seq" ++ show d
-                                                cstrs = walk (d+1) ("(seq.nth " ++ nm ++ " " ++ fnm ++ ")") f k
-                                            in mkAnd cstrs $ \hole -> ["(forall ((" ++ fnm ++ " " ++ smtType KUnbounded ++ ")) (=> (and (>= " ++ fnm ++ " 0) (< " ++ fnm ++ " (seq.len " ++ nm ++ "))) " ++ hole ++ "))"]
-        walk  d  nm f (KSet k)
-          | charRatFree k                 = []
-          | True                          = let fnm    = "set" ++ show d
-                                                cstrs  = walk (d+1) nm (\sk snm -> ["(=> (select " ++ snm ++ " " ++ fnm ++ ") " ++ c ++ ")" | c <- f sk fnm]) k
-                                            in mkAnd cstrs $ \hole -> ["(forall ((" ++ fnm ++ " " ++ smtType k ++ ")) " ++ hole ++ ")"]
-        walk  d  nm  f (KTuple ks)        = let tt        = "SBVTuple" ++ show (length ks)
-                                                project i = "(proj_" ++ show i ++ "_" ++ tt ++ " " ++ nm ++ ")"
-                                                nmks      = [(project i, k) | (i, k) <- zip [1::Int ..] ks]
-                                            in concatMap (\(n, k) -> walk (d+1) n f k) nmks
-        walk  d  nm  f km@(KMaybe k)      = let n = "(get_just_SBVMaybe " ++ nm ++ ")"
-                                            in  ["(=> " ++ "((_ is (just_SBVMaybe (" ++ smtType k ++ ") " ++ smtType km ++ ")) " ++ nm ++ ") " ++ c ++ ")" | c <- walk (d+1) n f k]
-        walk  d  nm  f ke@(KEither k1 k2) = let n1 = "(get_left_SBVEither "  ++ nm ++ ")"
-                                                n2 = "(get_right_SBVEither " ++ nm ++ ")"
-                                                c1 = ["(=> " ++ "((_ is (left_SBVEither ("  ++ smtType k1 ++ ") " ++ smtType ke ++ ")) " ++ nm ++ ") " ++ c ++ ")" | c <- walk (d+1) n1 f k1]
-                                                c2 = ["(=> " ++ "((_ is (right_SBVEither (" ++ smtType k2 ++ ") " ++ smtType ke ++ ")) " ++ nm ++ ") " ++ c ++ ")" | c <- walk (d+1) n2 f k2]
-                                            in c1 ++ c2
-        walk d  nm f  (KArray k1 k2)
-          | all charRatFree [k1, k2]      = []
-          | True                          = let fnm   = "array" ++ show d
-                                                cstrs = walk (d+1) ("(select " ++ nm ++ " " ++ fnm ++ ")") f k2
-                                            in mkAnd cstrs $ \hole -> ["(forall ((" ++ fnm ++ " " ++ smtType k1 ++ ")) " ++ hole ++ ")"]
-
------------------------------------------------------------------------------------------------
--- Casts supported by SMTLib. (From: <https://smt-lib.org/theories-FloatingPoint.shtml>)
---   ; from another floating point sort
---   ((_ to_fp eb sb) RoundingMode (_ FloatingPoint mb nb) (_ FloatingPoint eb sb))
---
---   ; from real
---   ((_ to_fp eb sb) RoundingMode Real (_ FloatingPoint eb sb))
---
---   ; from signed machine integer, represented as a 2's complement bit vector
---   ((_ to_fp eb sb) RoundingMode (_ BitVec m) (_ FloatingPoint eb sb))
---
---   ; from unsigned machine integer, represented as bit vector
---   ((_ to_fp_unsigned eb sb) RoundingMode (_ BitVec m) (_ FloatingPoint eb sb))
---
---   ; to unsigned machine integer, represented as a bit vector
---   ((_ fp.to_ubv m) RoundingMode (_ FloatingPoint eb sb) (_ BitVec m))
---
---   ; to signed machine integer, represented as a 2's complement bit vector
---   ((_ fp.to_sbv m) RoundingMode (_ FloatingPoint eb sb) (_ BitVec m))
---
---   ; to real
---   (fp.to_real (_ FloatingPoint eb sb) Real)
------------------------------------------------------------------------------------------------
-
-handleFPCast :: Kind -> Kind -> String -> String -> String
-handleFPCast kFromIn kToIn rm input
-  | kFrom == kTo
-  = input
-  | True
-  = "(" ++ cast kFrom kTo input ++ ")"
-  where addRM a s = s ++ " " ++ rm ++ " " ++ a
-
-        kFrom = simplify kFromIn
-        kTo   = simplify kToIn
-
-        simplify KFloat  = KFP   8 24
-        simplify KDouble = KFP  11 53
-        simplify k       = k
-
-        size (eb, sb) = show eb ++ " " ++ show sb
-
-        -- To go and back from Ints, we detour through reals
-        cast KUnbounded (KFP eb sb) a = "(_ to_fp " ++ size (eb, sb) ++ ") "  ++ rm ++ " (to_real " ++ a ++ ")"
-        cast KFP{}      KUnbounded  a = "to_int (fp.to_real " ++ a ++ ")"
-
-        -- To floats
-        cast (KBounded False _) (KFP eb sb) a = addRM a $ "(_ to_fp_unsigned " ++ size (eb, sb) ++ ")"
-        cast (KBounded True  _) (KFP eb sb) a = addRM a $ "(_ to_fp "          ++ size (eb, sb) ++ ")"
-        cast KReal              (KFP eb sb) a = addRM a $ "(_ to_fp "          ++ size (eb, sb) ++ ")"
-        cast KFP{}              (KFP eb sb) a = addRM a $ "(_ to_fp "          ++ size (eb, sb) ++ ")"
-
-        -- From float/double
-        cast KFP{} (KBounded False m) a = addRM a $ "(_ fp.to_ubv " ++ show m ++ ")"
-        cast KFP{} (KBounded True  m) a = addRM a $ "(_ fp.to_sbv " ++ show m ++ ")"
-
-        -- To real
-        cast KFP{} KReal a = "fp.to_real" ++ " " ++ a
-
-        -- Nothing else should come up:
-        cast f  d  _ = error $ "SBV.SMTLib2: Unexpected FPCast from: " ++ show f ++ " to " ++ show d
-
-rot :: String -> Int -> SV -> String
-rot o c x = "((_ " ++ o ++ " " ++ show c ++ ") " ++ cvtSV x ++ ")"
-
-shft :: String -> String -> SV -> SV -> String
-shft oW oS x c = "(" ++ o ++ " " ++ cvtSV x ++ " " ++ cvtSV c ++ ")"
-   where o = if hasSign x then oS else oW
-
--- Various casts
-handleKindCast :: Kind -> Kind -> String -> String
-handleKindCast kFrom kTo a
-  | kFrom == kTo
-  = a
-  | True
-  = case kFrom of
-      KBounded s m -> case kTo of
-                        KBounded _ n -> fromBV (if s then signExtend else zeroExtend) m n
-                        KUnbounded   -> if s then "(sbv_to_int " ++ a ++ ")"
-                                             else "(ubv_to_int " ++ a ++ ")"
-                        _            -> tryFPCast
-
-      KUnbounded   -> case kTo of
-                        KReal        -> "(to_real " ++ a ++ ")"
-                        KBounded _ n -> "((_ int_to_bv " ++ show n ++ ") " ++ a ++ ")"
-                        _            -> tryFPCast
-
-      KReal        -> case kTo of
-                        KUnbounded   -> "(to_int " ++ a ++ ")"
-                        _            -> tryFPCast
-
-      _            -> tryFPCast
-
-  where -- See if we can push this down to a float-cast, using sRNE. This happens if one of the kinds is a float/double.
-        -- Otherwise complain
-        tryFPCast
-          | any (\k -> isFloat k || isDouble k) [kFrom, kTo]
-          = handleFPCast kFrom kTo (smtRoundingMode RoundNearestTiesToEven) a
-          | True
-          = error $ "SBV.SMTLib2: Unexpected cast from: " ++ show kFrom ++ " to " ++ show kTo
-
-        fromBV upConv m n
-         | n > m  = upConv  (n - m)
-         | m == n = a
-         | True   = extract (n - 1)
-
-        signExtend i = "((_ sign_extend " ++ show i ++  ") "  ++ a ++ ")"
-        zeroExtend i = "((_ zero_extend " ++ show i ++  ") "  ++ a ++ ")"
-        extract    i = "((_ extract "     ++ show i ++ " 0) " ++ a ++ ")"
-
--- Translation of pseudo-booleans, in case the solver supports them
-handlePB :: PBOp -> [String] -> String
-handlePB (PB_AtMost  k) args = "((_ at-most "  ++ show k                                             ++ ") " ++ unwords args ++ ")"
-handlePB (PB_AtLeast k) args = "((_ at-least " ++ show k                                             ++ ") " ++ unwords args ++ ")"
-handlePB (PB_Exactly k) args = "((_ pbeq "     ++ unwords (map show (k : replicate (length args) 1)) ++ ") " ++ unwords args ++ ")"
-handlePB (PB_Eq cs   k) args = "((_ pbeq "     ++ unwords (map show (k : cs))                        ++ ") " ++ unwords args ++ ")"
-handlePB (PB_Le cs   k) args = "((_ pble "     ++ unwords (map show (k : cs))                        ++ ") " ++ unwords args ++ ")"
-handlePB (PB_Ge cs   k) args = "((_ pbge "     ++ unwords (map show (k : cs))                        ++ ") " ++ unwords args ++ ")"
-
--- Translation of pseudo-booleans, in case the solver does *not* support them
-reducePB :: PBOp -> [String] -> String
-reducePB op args = case op of
-                     PB_AtMost  k -> "(<= " ++ addIf (repeat 1) ++ " " ++ show k ++ ")"
-                     PB_AtLeast k -> "(>= " ++ addIf (repeat 1) ++ " " ++ show k ++ ")"
-                     PB_Exactly k -> "(=  " ++ addIf (repeat 1) ++ " " ++ show k ++ ")"
-                     PB_Le cs   k -> "(<= " ++ addIf cs         ++ " " ++ show k ++ ")"
-                     PB_Ge cs   k -> "(>= " ++ addIf cs         ++ " " ++ show k ++ ")"
-                     PB_Eq cs   k -> "(=  " ++ addIf cs         ++ " " ++ show k ++ ")"
-
-  where addIf :: [Int] -> String
-        addIf cs = "(+ " ++ unwords ["(ite " ++ a ++ " " ++ show c ++ " 0)" | (a, c) <- zip args cs] ++ ")"
-
--- | Translate an option setting to SMTLib. Note the SetLogic/SetInfo discrepancy.
-setSMTOption :: SMTConfig -> SMTOption -> String
-setSMTOption cfg = set
-  where set (DiagnosticOutputChannel   f) = opt   [":diagnostic-output-channel",   show f]
-        set (ProduceAssertions         b) = opt   [":produce-assertions",          smtBool b]
-        set (ProduceAssignments        b) = opt   [":produce-assignments",         smtBool b]
-        set (ProduceProofs             b) = opt   [":produce-proofs",              smtBool b]
-        set (ProduceInterpolants       b) = opt   [":produce-interpolants",        smtBool b]
-        set (ProduceUnsatAssumptions   b) = opt   [":produce-unsat-assumptions",   smtBool b]
-        set (ProduceUnsatCores         b) = opt   [":produce-unsat-cores",         smtBool b]
-        set (ProduceAbducts            b) = opt   [":produce-abducts",             smtBool b]
-        set (RandomSeed                i) = opt   [":random-seed",                 show i]
-        set (ReproducibleResourceLimit i) = opt   [":reproducible-resource-limit", show i]
-        set (SMTVerbosity              i) = opt   [":verbosity",                   show i]
-        set (OptionKeyword          k as) = opt   (k : as)
-        set (SetLogic                  l) = logic l
-        set (SetInfo                k as) = info  (k : as)
-        set (SetTimeOut                i) = opt   $ timeOut i
-
-        opt   xs = "(set-option " ++ unwords xs ++ ")"
-        info  xs = "(set-info "   ++ unwords xs ++ ")"
-
-        logic Logic_NONE = "; NB. not setting the logic per user request of Logic_NONE"
-        logic l          = "(set-logic " ++ show l ++ ")"
-
-        -- timeout is not standard. We distinguish between CVC/Z3. All else follows z3
-        -- The value is in milliseconds, which is how z3/CVC interpret it
-        timeOut i = case name (solver cfg) of
-                     CVC4 -> [":tlimit-per", show i]
-                     CVC5 -> [":tlimit-per", show i]
-                     _    -> [":timeout",    show i]
-
-        -- SMTLib's True/False is spelled differently than Haskell's.
-        smtBool :: Bool -> String
-        smtBool True  = "true"
-        smtBool False = "false"
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE ViewPatterns        #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Data.SBV.SMT.SMTLib2(cvt, cvtExp, cvtCV, cvtInc, declUserFuns, constructTables, setSMTOption) where
+
+import Data.List  (intercalate, partition, nub, elemIndex)
+import Data.Maybe (listToMaybe, catMaybes)
+
+import qualified Data.Foldable as F (toList, foldl')
+import qualified Data.Map.Strict      as M
+import qualified Data.IntMap.Strict   as IM
+import           Data.Set             (Set)
+import qualified Data.Set             as Set
+import qualified Data.Text            as T
+import           Data.Text            (Text)
+
+import Data.SBV.Core.Data
+import Data.SBV.Core.Kind (smtType, needsFlattening, expandKinds, substituteADTVars)
+import Data.SBV.Control.Types
+
+import Data.SBV.SMT.Utils
+
+import Data.SBV.Core.Symbolic ( QueryContext(..), SetOp(..), getUserName, getUserName', getSV, regExpToSMTString, NROp(..), showNROp
+                              , SMTDef(..), smtLambdaText, ResultInp(..), ProgInfo(..), SpecialRelOp(..), ADTOp(..)
+                              )
+
+import Data.SBV.Utils.PrettyNum (smtRoundingMode, cvToSMTLib)
+import Data.SBV.Utils.Lib       (showText)
+
+import qualified Data.Generics.Uniplate.Data as G
+
+import qualified Data.Graph as DG
+
+
+-- Check that all ADT subkinds are registered. If not, tell the user to do so
+-- NB. This should not be the case as we "automatically" register the subkinds
+-- as we encounter them. But this is mostly a if-something-goes-wrong check.
+checkKinds :: [Kind] -> Maybe String
+checkKinds ks = case [m | m@(n, _) <- apps, n `notElem` defs] of
+                  []       -> Nothing
+                  xs@(f:_) -> let (h, cnt) = case [p | p@(_, i) <- xs, i > 0] of
+                                               (p:_) -> p
+                                               _     -> f
+                                  plu | length xs > 1 = "s are"
+                                      | True          = " is"
+                                  msg = T.unlines $ [
+                                      "Data.SBV.mkSymbolic: Impossible happened! Unregistered subkinds."
+                                    , "***"
+                                    , "*** The following kind" <> plu <> " not registered: " <> T.unwords (map (T.pack . fst) xs)
+                                    , "***"
+                                    , "*** Please report this as a bug."
+                                    , "***"
+                                    , "*** As a workaround, you can try registering each ADT subfield, using: "
+                                    , "***"
+                                    , "***    {-# LANGUAGE TypeApplications #-}"
+                                    , "***"
+                                    , "***    import Data.Proxy"
+                                    , "***    registerType (Proxy @" <> mkProxy h cnt <> ")"
+                                    ]
+                                    ++ extras cnt
+                                    ++ [ "***"
+                                       , "*** Even if the workaround does the trick for you, it should not"
+                                       , "*** be needed. Please report this as a bug!"
+                                       ]
+                              in Just $ T.unpack msg
+
+
+  where apps = nub [(n, length as) | KApp n as <- concatMap expandKinds ks]
+        defs = nub [n | KADT n _ _ <- ks]
+        mkProxy h 0 = T.pack h
+        mkProxy h n = "(" <> T.unwords (T.pack h : replicate n "Integer") <> ")"
+
+        extras 0 = []
+        extras _ = [ "***"
+                   , "*** NB. You can use any base type as arguments, not just 'Integer'."
+                   , "*** It does not need to match the actual use cases, just one instance"
+                   , "*** at some base type is sufficent."
+                   ]
+
+-- | Translate a problem into an SMTLib2 script
+cvt :: SMTLibConverter (Text, Text)
+cvt ctx curProgInfo kindInfo isSat comments allInputs (_, consts) tbls uis defs (SBVPgm asgnsSeq) cstrs out cfg
+   | Just s <- checkKinds allKinds
+   = error s
+   | True
+   = (T.intercalate "\n" pgm, T.intercalate "\n" exportedDefs)
+  where allKinds       = Set.toList kindInfo
+
+        -- Below can simply be defined as: nub (sort (G.universeBi asgnsSeq))
+        -- Alas, it turns out this is really expensive when we have nested lambdas, so we do an explicit walk
+        allTopOps = Set.toList $ F.foldl' (\sofar (_, SBVApp o _) -> Set.insert o sofar) Set.empty asgnsSeq
+
+        hasInteger     = KUnbounded `Set.member` kindInfo
+        hasArrays      = not (null [() | KArray{}     <- allKinds])
+        hasNonBVArrays = not (null [() | KArray k1 k2 <- allKinds, not (isBounded k1 && isBounded k2)])
+        hasReal        = KReal      `Set.member` kindInfo
+        hasFP          =  not (null [() | KFP{} <- allKinds])
+                       || KFloat     `Set.member` kindInfo
+                       || KDouble    `Set.member` kindInfo
+        hasString      = KString     `Set.member` kindInfo
+        hasRegExp      = (not . null) [() | (_ :: RegExOp) <- G.universeBi allTopOps]
+        hasChar        = KChar      `Set.member` kindInfo
+        hasRounding    = any isRoundingMode allKinds
+        hasBVs         = not (null [() | KBounded{} <- allKinds])
+        adtsNoRM       = [(s, ps, cs) | k@(KADT s ps cs) <- allKinds, not (isRoundingMode k)]
+        tupleArities   = findTupleArities kindInfo
+        hasOverflows   = (not . null) [() | (_ :: OvOp) <- G.universeBi allTopOps]
+        hasQuantBools  = (not . null) [() | QuantifiedBool{} <- G.universeBi allTopOps]
+        hasList        = any isList kindInfo
+        hasSets        = any isSet kindInfo
+        hasTuples      = not . null $ tupleArities
+        hasRational    = any isRational kindInfo
+        hasADTs        = not . null $ adtsNoRM
+        solverCaps     = capabilities (solver cfg)
+
+        (needsQuantifiers, needsSpecialRels) = case curProgInfo of
+           ProgInfo hasQ srs tcs -> (hasQ, not (null srs && null tcs))
+
+        -- Is there a reason why we can't handle this problem?
+        -- NB. There's probably a lot more checking we can do here, but this is a start:
+        doesntHandle = listToMaybe [nope w | (w, have, need) <- checks, need && not (have solverCaps)]
+           where checks = [ ("data types",             supportsDataTypes,          hasTuples || hasADTs)
+                          , ("set operations",         supportsSets,               hasSets)
+                          , ("bit vectors",            supportsBitVectors,         hasBVs)
+                          , ("special relations",      supportsSpecialRels,        needsSpecialRels)
+                          , ("needs quantifiers",      supportsQuantifiers,        needsQuantifiers)
+                          , ("unbounded integers",     supportsUnboundedInts,      hasInteger)
+                          , ("algebraic reals",        supportsReals,              hasReal)
+                          , ("floating-point numbers", supportsIEEE754,            hasFP)
+                          , ("has data-types/sorts",   supportsADTs,               not (null adtsNoRM))
+                          ]
+
+                 nope w = [ "***     Given problem requires support for " <> T.pack w
+                          , "***     But the chosen solver (" <> showText (name (solver cfg)) <> ") doesn't support this feature."
+                          ]
+
+        -- Some cases require all, some require none.
+        setAll reason = [logicString cfg Logic_ALL <> " ; "  <> T.pack reason <> ", using catch-all."]
+
+        -- Determining the logic is surprisingly tricky!
+        logic :: [Text]
+        logic
+           -- user told us what to do: so just take it:
+           | Just l <- case [l | SetLogic l <- solverSetOptions cfg] of
+                         []  -> Nothing
+                         [l] -> Just l
+                         ls  -> error $ T.unpack $ T.unlines [ ""
+                                                             , "*** Only one setOption call to 'setLogic' is allowed, found: " <> showText (length ls)
+                                                             , "***  " <> T.unwords (map showText ls)
+                                                             ]
+           = case l of
+               Logic_NONE -> ["; NB. Not setting the logic per user request of Logic_NONE"]
+               _          -> [logicString cfg l <> " ; NB. User specified."]
+
+           -- There's a reason why we can't handle this problem:
+           | Just cantDo <- doesntHandle
+           = let msg = T.unlines $   [ ""
+                                 , "*** SBV is unable to choose a proper solver configuration:"
+                                 , "***"
+                                 ]
+                             <> cantDo
+                             <> [ "***"
+                                , "*** Please report this as a feature request, either for SBV or the backend solver."
+                                ]
+             in error $ T.unpack msg
+
+           -- Otherwise, we try to determine the most suitable logic.
+           -- NB. This isn't really fool proof!
+
+           -- we never set QF_S (ALL seems to work better in all cases)
+
+           | needsSpecialRels      = ["; has special relations, no logic set."]
+
+           -- Things that require ALL
+           | hasInteger            = setAll "has unbounded values"
+           | hasRational           = setAll "has rational values"
+           | hasReal               = setAll "has algebraic reals"
+           | hasADTs               = setAll "has user-defined data-types"
+           | hasNonBVArrays        = setAll "has non-bitvector arrays"
+           | hasTuples             = setAll "has tuples"
+           | hasSets               = setAll "has sets"
+           | hasList               = setAll "has lists"
+           | hasChar               = setAll "has chars"
+           | hasString             = setAll "has strings"
+           | hasRegExp             = setAll "has regular expressions"
+           | hasOverflows          = setAll "has overflow checks"
+           | hasQuantBools         = setAll "has quantified booleans"
+
+           | hasFP || hasRounding
+           = if needsQuantifiers
+             then [logicString cfg Logic_ALL]
+             else [logicString cfg (if hasBVs then QF_FPBV else QF_FP)]
+
+           -- If we're in a user query context, we'll pick ALL, otherwise
+           -- we'll stick to some bit-vector logic based on what we see in the problem.
+           -- This is controversial, but seems to work well in practice.
+           | True
+           = case ctx of
+               QueryExternal -> [logicString cfg Logic_ALL <> " ; external query, using all logics."]
+               QueryInternal -> if supportsBitVectors solverCaps
+                                then [logicString cfg picked]
+                                else [logicString cfg Logic_ALL] -- fall-thru
+          where picked
+                  | needsQuantifiers = Logic_ALL
+                  | True             = case (hasArrays, null uis && null tbls) of
+                                         (False, False) -> QF_UFBV
+                                         (False, True)  -> QF_BV
+                                         (True,  False) -> QF_AUFBV
+                                         (True,  True)  -> QF_ABV
+
+        -- SBV always requires the production of models!
+        getModels :: [Text]
+        getModels   = "(set-option :produce-models true)"
+                    : concat [map T.pack flattenConfig | any needsFlattening kindInfo, Just flattenConfig <- [supportsFlattenedModels solverCaps]]
+
+        -- process all other settings we're given. If an option cannot be repeated, we only take the last one.
+        userSettings = filter (not . T.null) $ map (setSMTOption cfg) $ filter (not . isLogic) $ foldr comb [] $ solverSetOptions cfg
+           where -- Logic is already processed, so drop it:
+                 isLogic SetLogic{} = True
+                 isLogic _          = False
+
+                 -- SBV sets diagnostic-output channel on some solvers. If the user also gives it, let's just
+                 -- take it by only taking the last one
+                 isDiagOutput DiagnosticOutputChannel{} = True
+                 isDiagOutput _                         = False
+
+                 comb o rest
+                   | isDiagOutput o && any isDiagOutput rest =     rest
+                   | True                                    = o : rest
+
+        settings =  userSettings        -- NB. Make sure this comes first!
+                 <> getModels
+                 <> logic
+
+        (inputs, trackerVars)
+            = case allInputs of
+                ResultTopInps ists -> ists
+                ResultLamInps ps   -> error $ unlines [ ""
+                                                      , "*** Data.SBV.smtLib2: Unexpected lambda inputs in conversion"
+                                                      , "***"
+                                                      , "*** Saw: " ++ show ps
+                                                      ]
+
+        pgm  =  map (T.pack . ("; " <>)) comments
+             <> settings
+             <> [ "; --- tuples ---" ]
+             <> concatMap declTuple tupleArities
+             <> [ "; --- sums ---" ]
+             <> (if containsRationals kindInfo then declRationals else [])
+             <> [ "; --- ADTs  --- " | not (null adtsNoRM)]
+             <> declADT adtsNoRM
+             <> [ "; --- literal constants ---" ]
+             <> concatMap (declConst cfg) consts
+             <> [ "; --- top level inputs ---"]
+             <> concat [declareFun s (SBVType [kindOf s]) (userName s) | var <- inputs, let s = getSV var]
+             <> [ "; --- optimization tracker variables ---" | not (null trackerVars) ]
+             <> concat [declareFun s (SBVType [kindOf s]) (Just ("tracks " <> getUserName var)) | var <- trackerVars, let s = getSV var]
+             <> [ "; --- constant tables ---" ]
+             <> concatMap (uncurry (:) . mkTable) constTables
+             <> [ "; --- non-constant tables ---" ]
+             <> map nonConstTable nonConstTables
+             <> [ "; --- uninterpreted constants ---" ]
+             <> concatMap (declUI curProgInfo) uis
+             <> [ "; --- user defined functions ---"]
+             <> userDefs
+             <> [ "; --- assignments ---" ]
+             <> concatMap (declDef curProgInfo cfg tableMap) asgns
+             <> [ "; --- delayedEqualities ---" ]
+             <> map (\s -> "(assert " <> s <> ")") delayedEqualities
+             <> [ "; --- formula ---" ]
+             <> finalAssert
+
+        userDefs = declUserFuns defs
+        exportedDefs
+          | null userDefs
+          = ["; No calls to 'smtFunction' found."]
+          | True
+          = "; Automatically generated by SBV. Do not modify!" : userDefs
+
+
+        (tableMap, constTables, nonConstTables) = constructTables consts tbls
+
+        delayedEqualities = concatMap snd nonConstTables
+
+        finalAssert
+          | noConstraints = []
+          | True          =    map (\(attr, v) -> "(assert "      <> addAnnotations attr (mkLiteral v) <> ")") hardAsserts
+                            <> map (\(attr, v) -> "(assert-soft " <> addAnnotations attr (mkLiteral v) <> ")") softAsserts
+          where mkLiteral (Left  v) =            cvtSV v
+                mkLiteral (Right v) = "(not " <> cvtSV v <> ")"
+
+                (noConstraints, assertions) = finalAssertions
+
+                hardAsserts, softAsserts :: [([(String, String)], Either SV SV)]
+                hardAsserts = [(attr, v) | (False, attr, v) <- assertions]
+                softAsserts = [(attr, v) | (True,  attr, v) <- assertions]
+
+        finalAssertions :: (Bool, [(Bool, [(String, String)], Either SV SV)])  -- If Left: positive, Right: negative
+        finalAssertions
+           | null finals = (True,  [(False, [], Left trueSV)])
+           | True        = (False, finals)
+
+           where finals  = cstrs' ++ maybe [] (\r -> [(False, [], r)]) mbO
+
+                 cstrs' =  [(isSoft, attrs, c') | (isSoft, attrs, c) <- F.toList cstrs, Just c' <- [pos c]]
+
+                 mbO | isSat = pos out
+                     | True  = neg out
+
+                 neg s
+                  | s == falseSV = Nothing
+                  | s == trueSV  = Just $ Left falseSV
+                  | True         = Just $ Right s
+
+                 pos s
+                  | s == trueSV  = Nothing
+                  | s == falseSV = Just $ Left falseSV
+                  | True         = Just $ Left s
+
+        asgns = F.toList asgnsSeq
+
+        userNameMap = M.fromList $ map (\nSymVar -> (getSV nSymVar, getUserName' nSymVar)) inputs
+        userName s = case M.lookup s userNameMap of
+                        Just u  | show s /= u -> Just $ "tracks user variable " <> showText u
+                        _                     -> Nothing
+
+-- | Declare ADTs
+declADT :: [(String, [(String, Kind)], [(String, [Kind])])] -> [Text]
+declADT = concatMap declGroup . DG.stronglyConnComp . map mkNode
+  where mkNode adt@(n, pks, cstrs) = (adt, n, [s | KApp s _ <- concatMap expandKinds (map snd pks ++ concatMap snd cstrs)])
+
+        declGroup (DG.AcyclicSCC d )  = singleADT d
+        declGroup (DG.CyclicSCC  ds)
+            = case ds of
+                []  -> error "Data.SBV.declADT: Impossible happened: an empty cyclic group was returned!"
+                [d] -> singleADT d
+                _   -> multiADT ds
+
+        parParens :: [(String, Kind)] -> (Text, Text)
+        parParens [] = ("", "")
+        parParens ps = (" (par (" <> T.unwords (map (T.pack . fst) ps) <> ")", ")")
+
+        mkC (nm, []) = T.pack nm
+        mkC (nm, ts) = T.pack nm <> " " <> T.unwords ['(' `T.cons` mkF (nm <> "_" <> show i) t <> ")" | (i, t) <- zip [(1::Int)..] ts]
+          where mkF a t  = "get" <> T.pack a <> " " <> smtType t
+
+        singleADT :: (String, [(String, Kind)], [(String, [Kind])]) -> [Text]
+        singleADT (tName, [], []) = ["(declare-sort " <> T.pack tName <> " 0) ; N.B. Uninterpreted sort."]
+        singleADT (tName, pks, cstrs) = ("; User defined ADT: " <> T.pack tName) : decl
+          where decl =  ("(declare-datatype " <> T.pack tName <> parOpen <> " (")
+                     :  ["    (" <> mkC c <> ")" | c <- cstrs]
+                     <> ["))" <> parClose]
+
+                (parOpen, parClose) = parParens pks
+
+        multiADT :: [(String, [(String, Kind)], [(String, [Kind])])] -> [Text]
+        multiADT adts = ("; User defined mutually-recursive ADTs: " <> T.intercalate ", " (map (\(a, _, _) -> T.pack a) adts)) : decl
+          where decl = ("(declare-datatypes (" <> typeDecls <> ") (")
+                     : concatMap adtBody adts
+                    <> ["))"]
+
+                typeDecls = T.unwords ['(' `T.cons` T.pack name <> " " <> showText (length pks) <> ")" | (name, pks, _) <- adts]
+
+                adtBody (_, pks, cstrs) = body
+                  where (parOpen, parClose) = parParens pks
+                        body =  ("    " <> parOpen <> " (")
+                             :  ["        (" <> mkC c <> ")" | c <- cstrs]
+                             <> ["     )" <> parClose]
+
+-- | Declare tuple datatypes
+--
+-- eg:
+--
+-- @
+-- (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+--                                     ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+--                                                   (proj_2_SBVTuple2 T2))))))
+-- @
+declTuple :: Int -> [Text]
+declTuple arity
+  | arity == 0 = ["(declare-datatypes ((SBVTuple0 0)) (((mkSBVTuple0))))"]
+  | arity == 1 = error "Data.SBV.declTuple: Unexpected one-tuple"
+  | True       =    (l1 <> "(par (" <> T.unwords [param i | i <- [1..arity]] <> ")")
+                 :  [pre i <> proj i <> post i    | i <- [1..arity]]
+  where l1     = "(declare-datatypes ((SBVTuple" <> showText arity <> " " <> showText arity <> ")) ("
+        l2     = T.replicate (T.length l1) " " <> "((mkSBVTuple" <> showText arity <> " "
+        tab    = T.replicate (T.length l2) " "
+
+        pre 1  = l2
+        pre _  = tab
+
+        proj i = "(proj_" <> showText i <> "_SBVTuple" <> showText arity <> " " <> param i <> ")"
+
+        post i = if i == arity then ")))))" else ""
+
+        param i = "T" <> showText i
+
+-- | Find the set of tuple sizes to declare, eg (2-tuple, 5-tuple).
+-- NB. We do *not* need to recursively go into list/tuple kinds here,
+-- because register-kind function automatically registers all subcomponent
+-- kinds, thus everything we need is available at the top-level.
+findTupleArities :: Set Kind -> [Int]
+findTupleArities ks = Set.toAscList
+                    $ Set.map length
+                    $ Set.fromList [ tupKs | KTuple tupKs <- Set.toList ks ]
+
+-- | Is @Rational@ being used?
+containsRationals :: Set Kind -> Bool
+containsRationals = not . Set.null . Set.filter isRational
+
+-- Internally, we do *not* keep the rationals in reduced form! So, the boolean operators explicitly do the math
+-- to make sure equivalent values are treated correctly.
+declRationals :: [Text]
+declRationals = [ "(declare-datatype SBVRational ((SBV.Rational (sbv.rat.numerator Int) (sbv.rat.denominator Int))))"
+                , ""
+                , "(define-fun sbv.rat.eq ((x SBVRational) (y SBVRational)) Bool"
+                , "   (= (* (sbv.rat.numerator   x) (sbv.rat.denominator y))"
+                , "      (* (sbv.rat.denominator x) (sbv.rat.numerator   y)))"
+                , ")"
+                , ""
+                , "(define-fun sbv.rat.notEq ((x SBVRational) (y SBVRational)) Bool"
+                , "   (not (sbv.rat.eq x y))"
+                , ")"
+                ]
+
+-- | Convert in a query context.
+-- NB. We do not store everything in @newKs@ below, but only what we need
+-- to do as an extra in the incremental context. See `Data.SBV.Core.Symbolic.registerKind`
+-- for a list of what we include, in case something doesn't show up
+-- and you need it!
+cvtInc :: SMTLibIncConverter [Text]
+cvtInc curProgInfo inps newKs (_, consts) tbls uis defs (SBVPgm asgnsSeq) cstrs cfg =
+            -- any new settings?
+               settings
+            -- Tuples precede ADTs that may use them, as in non-incremental output.
+            -- Only declare the new sizes; old sizes persist.
+            <> concatMap declTuple (findTupleArities newKs)
+            -- Rationals precede ADTs that may contain rational fields.
+            <> (if containsRationals newKs then declRationals else [])
+            -- sorts
+            <> declADT [(s, pks, cs) | k@(KADT s pks cs) <- newKinds, not (isRoundingMode k)]
+            -- constants
+            <> concatMap (declConst cfg) consts
+            -- inputs
+            <> concatMap declInp inps
+            -- table declarations
+            <> tableDecls
+            -- uninterpreteds
+            <> concatMap (declUI curProgInfo) uis
+            -- user defined functions
+            <> concatMap T.lines (declUserFuns defs)
+            -- expressions
+            <> concatMap (declDef curProgInfo cfg tableMap) asgnsSeq
+            -- table setups
+            <> concat tableAssigns
+            -- extra constraints
+            <> map (\(isSoft, attr, v) -> "(assert" <> (if isSoft then "-soft " else " ") <> addAnnotations attr (cvtSV v) <> ")") (F.toList cstrs)
+  where newKinds = Set.toList newKs
+
+        declInp (getSV -> s) = declareFun s (SBVType [kindOf s]) Nothing
+
+        (tableMap, allTables) = (tm, ct <> nct)
+            where (tm, ct, nct) = constructTables consts tbls
+
+        (tableDecls, tableAssigns) = unzip $ map mkTable allTables
+
+        -- If we need flattening in models, do emit the required lines if preset
+        settings
+          | any needsFlattening newKinds
+          = concat (catMaybes [map T.pack <$> supportsFlattenedModels solverCaps])
+          | True
+          = []
+          where solverCaps = capabilities (solver cfg)
+
+declDef :: ProgInfo -> SMTConfig -> TableMap -> (SV, SBVExpr) -> [Text]
+declDef curProgInfo cfg tableMap (s, expr) =
+        case expr of
+          SBVApp  (Label m) [e] -> defineFun cfg (s, cvtSV                                   e) (Just $ T.pack m)
+          e                     -> defineFun cfg (s, cvtExp cfg curProgInfo caps rm tableMap e) Nothing
+  where caps = capabilities (solver cfg)
+        rm   = roundingMode cfg
+
+defineFun :: SMTConfig -> (SV, Text) -> Maybe Text -> [Text]
+defineFun cfg (s, def) mbComment
+   | hasDefFun = ["(define-fun "  <> varT <> " " <> def <> ")" <> cmnt]
+   | True      = [ "(declare-fun " <> varT <> ")" <> cmnt
+                 , "(assert (= " <> var <> " " <> def <> "))"
+                 ]
+  where var  = showText s
+        varT = var <> " " <> svFunType [] s
+        cmnt = maybe "" (" ; " <>) mbComment
+
+        hasDefFun = supportsDefineFun $ capabilities (solver cfg)
+
+-- Declare constants. NB. We don't declare true/false; but just inline those as necessary
+declConst :: SMTConfig -> (SV, CV) -> [Text]
+declConst cfg (s, c)
+  | s == falseSV || s == trueSV
+  = []
+  | True
+  = defineFun cfg (s, cvtCV c) Nothing
+
+-- Make a function equality of nm against the internal function fun
+mkRelEq :: Text -> (Text, Text) -> Kind -> Text
+mkRelEq nm (fun, order) ak = res
+   where lhs = "(" <> nm <> " x y)"
+         rhs = "((_ " <> fun <> " " <> order <> ") x y)"
+         tk  = smtType ak
+         res = "(forall ((x " <> tk <> ") (y " <> tk <> ")) (= " <> lhs <> " " <> rhs <> "))"
+
+declUI :: ProgInfo -> (String, (Bool, Maybe [String], SBVType)) -> [Text]
+declUI ProgInfo{progTransClosures} (i, (_, _, t)) = declareName (T.pack i) t Nothing <> declClosure
+  where declClosure | Just external <- lookup i progTransClosures
+                    =  declareName (T.pack external) t Nothing
+                    <> ["(assert " <> mkRelEq (T.pack external) ("transitive-closure", T.pack i) (argKind t) <> ")"]
+                    | True
+                    = []
+
+        argKind (SBVType [ka, _, KBool]) = ka
+        argKind _                        = error $ "declUI: Unexpected type for name: " <> show (i, t)
+
+-- Note that even though we get all user defined-functions here (i.e., lambda and axiom), we can only have defined-functions
+-- and axioms. We spit axioms as is; and topologically sort the definitions.
+declUserFuns :: [(String, (SMTDef, SBVType))] -> [Text]
+declUserFuns ds = map declGroup sorted
+  where mkNode d = (d, fst d, getDeps d)
+
+        getDeps (_, (SMTDef _ d _ _, _)) = d
+
+        mkDecl Nothing  rt = "() " <> rt
+        mkDecl (Just p) rt = p <> " " <> rt
+
+        sorted = DG.stronglyConnComp (map mkNode ds)
+
+        declGroup (DG.AcyclicSCC b)  = declUserDef False b
+        declGroup (DG.CyclicSCC  bs) = case bs of
+                                         []  -> error "Data.SBV.declFuns: Impossible happened: an empty cyclic group was returned!"
+                                         [x] -> declUserDef True x
+                                         xs  -> declUserDefMulti xs
+
+        declUserDef isRec (nm, (SMTDef fk deps param body, ty)) =
+          "; " <> T.pack nm <> " :: " <> showText ty <> recursive <> frees <> "\n" <> s
+           where (recursive, definer) | isRec = (" [Recursive]", "define-fun-rec")
+                                      | True  = ("",             "define-fun")
+
+                 otherDeps = filter (/= nm) deps
+                 frees | null otherDeps = ""
+                       | True           = " [Refers to: " <> T.intercalate ", " (map T.pack otherDeps) <> "]"
+
+                 decl = mkDecl param (smtType fk)
+
+                 s = "(" <> definer <> " " <> T.pack nm <> " " <> decl <> "\n" <> body 2 <> ")"
+
+        -- declare a bunch of mutually-recursive functions
+        declUserDefMulti bs = render $ map collect bs
+          where collect (nm, (SMTDef fk deps param body, ty)) = (deps, nm, ty, "(" <> T.pack nm <> " " <> decl <> ")", body 3)
+                  where decl = mkDecl param (smtType fk)
+
+                render defs = T.intercalate "\n" $
+                                  [ "; " <> T.intercalate ", " [T.pack n <> " :: " <> showText ty | (_, n, ty, _, _) <- defs]
+                                  , "(define-funs-rec"
+                                  ]
+                               <> [ open i <> param d <> close1 i | (i, d) <- zip [1..] defs]
+                               <> [ open i <> dump  d <> close2 i | (i, d) <- zip [1..] defs]
+                     where open 1 = "  ("
+                           open _ = "   "
+
+                           param (_deps, _nm, _ty, p, _body) = p
+
+                           dump (deps, nm, ty, _, body) = "; Definition of: " <> T.pack nm <> " :: " <> showText ty <> ". [Refers to: " <> T.intercalate ", " (map T.pack deps) <> "]"
+                                                        <> "\n" <> body
+
+                           ld = length defs
+
+                           close1 n = if n == ld then ")"  else ""
+                           close2 n = if n == ld then "))" else ""
+
+mkTable :: (((Int, Kind, Kind), [SV]), [Text]) -> (Text, [Text])
+mkTable (((i, ak, rk), _elts), is) = (decl, zipWith wrap [(0::Int)..] is <> setup)
+  where t       = "table" <> showText i
+        decl    = "(declare-fun " <> t <> " (" <> smtType ak <> ") " <> smtType rk <> ")"
+
+        -- Arrange for initializers
+        mkInit idx   = "table" <> showText i <> "_initializer_" <> showText (idx :: Int)
+        initializer  = "table" <> showText i <> "_initializer"
+
+        wrap index s = "(define-fun " <> mkInit index <> " () Bool " <> s <> ")"
+
+        lis  = length is
+
+        setup
+          | lis == 0       = [ "(define-fun " <> initializer <> " () Bool true) ; no initialization needed"
+                             ]
+          | lis == 1       = [ "(define-fun " <> initializer <> " () Bool " <> mkInit 0 <> ")"
+                             , "(assert " <> initializer <> ")"
+                             ]
+          | True           = [ "(define-fun " <> initializer <> " () Bool (and " <> T.unwords (map mkInit [0..lis - 1]) <> "))"
+                             , "(assert " <> initializer <> ")"
+                             ]
+nonConstTable :: (((Int, Kind, Kind), [SV]), [Text]) -> Text
+nonConstTable (((i, ak, rk), _elts), _) = decl
+  where t    = "table" <> showText i
+        decl = "(declare-fun " <> t <> " (" <> smtType ak <> ") " <> smtType rk <> ")"
+
+constructTables :: [(SV, CV)] -> [((Int, Kind, Kind), [SV])]
+                -> ( IM.IntMap Text                              -- table enumeration
+                   , [(((Int, Kind, Kind), [SV]), [Text])]       -- constant tables
+                   , [(((Int, Kind, Kind), [SV]), [Text])]       -- non-constant tables
+                   )
+constructTables consts tbls = (tableMap, constTables, nonConstTables)
+ where allTables      = [(t, genTableData (map fst consts) t) | t <- tbls]
+       constTables    = [(t, d) | (t, Left  d) <- allTables]
+       nonConstTables = [(t, d) | (t, Right d) <- allTables]
+       tableMap       = IM.fromList $ map grab allTables
+
+       grab (((t, _, _), _), _) = (t, "table" <> showText t)
+
+-- Left if all constants, Right if otherwise
+genTableData :: [SV] -> ((Int, Kind, Kind), [SV]) -> Either [Text] [Text]
+genTableData consts ((i, aknd, _), elts)
+  | null post = Left  (map (mkEntry . snd) pre)
+  | True      = Right (map (mkEntry . snd) (pre ++ post))
+  where (pre, post) = partition fst (zipWith mkElt elts [(0::Int)..])
+        t           = "table" <> showText i
+
+        mkElt x k   = (isReady, (idx, cvtSV x))
+          where idx = cvtCV (mkConstCV aknd k)
+                isReady = x `Set.member` constsSet
+
+        mkEntry (idx, v) = "(= (" <> t <> " " <> idx <> ") " <> v <> ")"
+
+        constsSet = Set.fromList consts
+
+svType :: SV -> Text
+svType s = smtType (kindOf s)
+
+svFunType :: [SV] -> SV -> Text
+svFunType ss s = "(" <> T.unwords (map svType ss) <> ") " <> svType s
+
+cvtType :: SBVType -> Text
+cvtType (SBVType []) = error "SBV.SMT.SMTLib2.cvtType: internal: received an empty type!"
+cvtType (SBVType xs) = "(" <> T.unwords (map smtType body) <> ") " <> smtType ret
+  where (body, ret) = (init xs, last xs)
+
+type TableMap = IM.IntMap Text
+
+-- Present an SV, simply show
+cvtSV :: SV -> Text
+cvtSV = showText
+
+cvtCV :: CV -> Text
+cvtCV = cvToSMTLib
+
+getTable :: TableMap -> Int -> Text
+getTable m i
+  | Just tn <- i `IM.lookup` m = tn
+  | True                       = "table" <> showText i
+
+cvtExp :: SMTConfig -> ProgInfo -> SolverCapabilities -> RoundingMode -> TableMap -> SBVExpr -> Text
+cvtExp cfg curProgInfo caps rm tableMap expr@(SBVApp _ arguments) = sh expr
+  where hasPB       = supportsPseudoBooleans caps
+        hasDistinct = supportsDistinct       caps
+        specialRels = progSpecialRels        curProgInfo
+
+        bvOp     = all isBounded   arguments
+        intOp    = any isUnbounded arguments
+        ratOp    = any isRational  arguments
+        realOp   = any isReal      arguments
+        fpOp     = any (\a -> isDouble a || isFloat a || isFP a) arguments
+        boolOp   = all isBoolean   arguments
+        charOp   = any isChar      arguments
+        stringOp   = any isString    arguments
+        listOp   = any isList      arguments
+
+        bad | intOp = error $ "SBV.SMTLib2: Unsupported operation on unbounded integers: " ++ show expr
+            | True  = error $ "SBV.SMTLib2: Unsupported operation on real values: " ++ show expr
+
+        ensureBVOrBool = bvOp || boolOp || bad
+        ensureBV       = bvOp || bad
+
+        addRM s = s <> " " <> smtRoundingMode rm
+
+        isZ3 = case name (solver cfg) of
+                 Z3 -> True
+                 _  -> False
+
+        isCVC5 = case name (solver cfg) of
+                   CVC5 -> True
+                   _    -> False
+
+        hd _ (a:_) = a
+        hd w []    = error $ "Impossible: " ++ w ++ ": Received empty list of args!"
+
+        -- lift a binary op
+        lift2  o _ [x, y] = "(" <> o <> " " <> x <> " " <> y <> ")"
+        lift2  o _ sbvs   = error $ "SBV.SMTLib2.sh.lift2: Unexpected arguments: " ++ show (o, sbvs)
+
+        -- lift an arbitrary arity operator
+        liftN o _ xs = "(" <> o <> " " <> T.unwords xs <> ")"
+
+        -- lift a binary operation with rounding-mode added; used for floating-point arithmetic
+        lift2WM o fo | fpOp = lift2 (addRM fo)
+                     | True = lift2 o
+
+        lift1FP o fo | fpOp = lift1 fo
+                     | True = lift1 o
+
+        liftAbs sgned args | fpOp        = lift1 "fp.abs" sgned args
+                           | intOp       = lift1 "abs"    sgned args
+                           | bvOp, sgned = mkAbs fArg "bvslt" "bvneg"
+                           | bvOp        = fArg
+                           | True        = mkAbs fArg "<"     "-"
+          where fArg = hd "liftAbs" args
+                mkAbs x cmp neg = "(ite " <> ltz <> " " <> nx <> " " <> x <> ")"
+                  where ltz = "(" <> cmp <> " " <> x <> " " <> z <> ")"
+                        nx  = "(" <> neg <> " " <> x <> ")"
+                        z   = cvtCV (mkConstCV (kindOf (hd "liftAbs.arguments" arguments)) (0::Integer))
+
+        lift2B bOp vOp
+          | boolOp = lift2 bOp
+          | True   = lift2 vOp
+
+        lift1B bOp vOp
+          | boolOp = lift1 bOp
+          | True   = lift1 vOp
+
+        eqBV  = lift2 "="
+        neqBV = liftN "distinct"
+
+        equal sgn sbvs
+          | fpOp = lift2 "fp.eq" sgn sbvs
+          | True = lift2 "="     sgn sbvs
+
+        -- Do not use distinct on floats; because +0/-0, and NaNs mess
+        -- up the meaning. Just go with regular equals.
+        notEqual sgn sbvs
+          | fpOp || not hasDistinct = liftP sbvs
+          | True                    = liftN "distinct" sgn sbvs
+          where liftP xs@[_, _] = "(not " <> equal sgn xs <> ")"
+                liftP args      = "(and " <> T.unwords (walk args) <> ")"
+
+                walk []     = []
+                walk (e:es) = map (\e' -> liftP [e, e']) es <> walk es
+
+        lift2S oU oS sgn = lift2 (if sgn then oS else oU) sgn
+        liftNS oU oS sgn = liftN (if sgn then oS else oU) sgn
+
+        lift2Cmp o fo | fpOp = lift2 fo
+                      | True = lift2 o
+
+        stringOrChar KString = True
+        stringOrChar KChar   = True
+        stringOrChar _       = False
+        stringCmp swap o [a, b]
+          | stringOrChar (kindOf (hd "stringCmp" arguments))
+          = let (a1, a2) | swap = (b, a)
+                         | True = (a, b)
+            in "(" <> o <> " " <> a1 <> " " <> a2 <> ")"
+        stringCmp _ o sbvs = error $ "SBV.SMT.SMTLib2.sh.stringCmp: Unexpected arguments: " ++ show (o, sbvs)
+
+        -- NB. Likewise for sequences
+        seqCmp swap o [a, b]
+          | KList{} <- kindOf (hd "seqCmp" arguments)
+          = let (a1, a2) | swap = (b, a)
+                         | True = (a, b)
+            in "(" <> o <> " " <> a1 <> " " <> a2 <> ")"
+        seqCmp _ o sbvs = error $ "SBV.SMT.SMTLib2.sh.seqCmp: Unexpected arguments: " ++ show (o, sbvs)
+
+        lift1  o _ [x]    = "(" <> o <> " " <> x <> ")"
+        lift1  o _ sbvs   = error $ "SBV.SMTLib2.sh.lift1: Unexpected arguments: " ++ show (o, sbvs)
+
+        sh (SBVApp Ite [a, b, c]) = "(ite " <> cvtSV a <> " " <> cvtSV b <> " " <> cvtSV c <> ")"
+
+        sh (SBVApp (LkUp (t, aKnd, _, l) i e) [])
+          | needsCheck = "(ite " <> cond <> cvtSV e <> " " <> lkUp <> ")"
+          | True       = lkUp
+          where unexpected = error $ "SBV.SMT.SMTLib2.cvtExp: Unexpected: " ++ show aKnd
+                needsCheck = case aKnd of
+                              KVar{}        -> unexpected
+                              KBool         -> (2::Integer) > fromIntegral l
+                              KBounded _ n  -> (2::Integer)^n > fromIntegral l
+                              KUnbounded    -> True
+                              KApp _ _      -> unexpected
+                              KADT _ _ _    -> unexpected
+                              KReal         -> unexpected
+                              KFloat        -> unexpected
+                              KDouble       -> unexpected
+                              KFP _ _       -> unexpected
+                              KRational     -> unexpected
+                              KChar         -> unexpected
+                              KString       -> unexpected
+                              KList _       -> unexpected
+                              KSet  _       -> unexpected
+                              KTuple _      -> unexpected
+                              KArray  _ _   -> unexpected
+
+                lkUp = "(" <> getTable tableMap t <> " " <> cvtSV i <> ")"
+
+                cond
+                 | hasSign i = "(or " <> le0 <> " " <> gtl <> ") "
+                 | True      = gtl <> " "
+
+                (less, leq) = case aKnd of
+                                KVar{}        -> error "SBV.SMT.SMTLib2.cvtExp: unexpected variable index"
+                                KBool         -> error "SBV.SMT.SMTLib2.cvtExp: unexpected boolean valued index"
+                                KBounded{}    -> if hasSign i then ("bvslt", "bvsle") else ("bvult", "bvule")
+                                KUnbounded    -> ("<", "<=")
+                                KReal         -> ("<", "<=")
+                                KFloat        -> ("fp.lt", "fp.leq")
+                                KDouble       -> ("fp.lt", "fp.leq")
+                                KRational     -> ("sbv.rat.lt", "sbv.rat.leq")
+                                KFP{}         -> ("fp.lt", "fp.leq")
+                                KChar         -> error "SBV.SMT.SMTLib2.cvtExp: unexpected string valued index"
+                                KString       -> error "SBV.SMT.SMTLib2.cvtExp: unexpected string valued index"
+                                KApp  s _     -> error $ "SBV.SMT.SMTLib2.cvtExp: unexpected ADT applied index: " ++ s
+                                KADT  s _ _   -> error $ "SBV.SMT.SMTLib2.cvtExp: unexpected ADT valued index: " ++ s
+                                KList k       -> error $ "SBV.SMT.SMTLib2.cvtExp: unexpected sequence valued index: " ++ show k
+                                KSet  k       -> error $ "SBV.SMT.SMTLib2.cvtExp: unexpected set valued index: " ++ show k
+                                KTuple k      -> error $ "SBV.SMT.SMTLib2.cvtExp: unexpected tuple valued index: " ++ show k
+                                KArray  k1 k2 -> error $ "SBV.SMT.SMTLib2.cvtExp: unexpected array valued index: " ++ show (k1, k2)
+
+                mkCnst = cvtCV . mkConstCV (kindOf i)
+                le0  = "(" <> less <> " " <> cvtSV i <> " " <> mkCnst 0 <> ")"
+                gtl  = "(" <> leq  <> " " <> mkCnst l <> " " <> cvtSV i <> ")"
+
+        sh (SBVApp (KindCast f t) [a]) = handleKindCast f t (cvtSV a)
+
+        sh (SBVApp (ArrayInit (Left (f, t))) [a])         = "((as const (Array " <> smtType f <> " " <> smtType t <> ")) " <> cvtSV a <> ")"
+        sh (SBVApp (ArrayInit (Right lambdaDef)) [])      = smtLambdaText lambdaDef
+        sh (SBVApp ReadArray                    [a, i])    = "(select " <> cvtSV a <> " " <> cvtSV i <> ")"
+        sh (SBVApp WriteArray                   [a, i, e]) = "(store "  <> cvtSV a <> " " <> cvtSV i <> " " <> cvtSV e <> ")"
+
+        sh (SBVApp (Uninterpreted nm) [])   = nm
+        sh (SBVApp (Uninterpreted nm) args) = "(" <> nm <> " " <> T.unwords (map cvtSV args) <> ")"
+
+        sh (SBVApp (ADTOp aop) args) = handleADT caps aop args
+
+        sh (SBVApp (QuantifiedBool i) [])   = i
+        sh (SBVApp (QuantifiedBool i) args) = error $ "SBV.SMT.SMTLib2.cvtExp: unexpected arguments to quantified boolean: " ++ show (T.unpack i, args)
+
+        sh a@(SBVApp (SpecialRelOp k o) args)
+          | not (null args)
+          = error $ "SBV.SMT.SMTLib2.cvtExp: unexpected arguments to special op: " ++ show a
+          | True
+          = let order = case o `elemIndex` specialRels of
+                          Just i -> i
+                          Nothing -> error $ unlines [ "SBV.SMT.SMTLib2.cvtExp: Cannot find " ++ show o ++ " in the special-relations list."
+                                                     , "Known relations: " ++ intercalate ", " (map show specialRels)
+                                                     ]
+                asrt nm fun = mkRelEq (T.pack nm) (T.pack fun, showText order) k
+            in case o of
+                 IsPartialOrder         nm -> asrt nm "partial-order"
+                 IsLinearOrder          nm -> asrt nm "linear-order"
+                 IsTreeOrder            nm -> asrt nm "tree-order"
+                 IsPiecewiseLinearOrder nm -> asrt nm "piecewise-linear-order"
+
+        sh (SBVApp (Divides n) [a]) = "((_ divisible " <> showText n <> ") " <> cvtSV a <> ")"
+
+        sh (SBVApp (Extract i j) [a]) | ensureBV = "((_ extract " <> showText i <> " " <> showText j <> ") " <> cvtSV a <> ")"
+
+        sh (SBVApp (Rol i) [a])
+           | bvOp  = rot "rotate_left"  i a
+           | True  = bad
+
+        sh (SBVApp (Ror i) [a])
+           | bvOp  = rot  "rotate_right" i a
+           | True  = bad
+
+        sh (SBVApp Shl [a, i])
+           | bvOp   = shft "bvshl"  "bvshl" a i
+           | True   = bad
+
+        sh (SBVApp Shr [a, i])
+           | bvOp  = shft "bvlshr" "bvashr" a i
+           | True  = bad
+
+        sh (SBVApp (ZeroExtend i) [a])
+          | bvOp = "((_ zero_extend " <> showText i <> ") " <> cvtSV a <> ")"
+          | True = bad
+
+        sh (SBVApp (SignExtend i) [a])
+          | bvOp = "((_ sign_extend " <> showText i <> ") " <> cvtSV a <> ")"
+          | True = bad
+
+        sh (SBVApp op args)
+          | Just f <- lookup op smtBVOpTable, ensureBVOrBool
+          = f (any hasSign args) (map cvtSV args)
+          where -- The first 4 operators below do make sense for Integer's in Haskell, but there's
+                -- no obvious counterpart for them in the SMTLib translation.
+                -- TODO: provide support for these.
+                smtBVOpTable = [ (And,  lift2B "and" "bvand")
+                               , (Or,   lift2B "or"  "bvor")
+                               , (XOr,  lift2B "xor" "bvxor")
+                               , (Not,  lift1B "not" "bvnot")
+                               , (Join, lift2 "concat")
+                               ]
+
+        sh (SBVApp (Label _) [a]) = cvtSV a  -- This won't be reached; but just in case!
+
+        sh (SBVApp (IEEEFP (FP_Cast kFrom kTo m)) args) = handleFPCast kFrom kTo (cvtSV m) (T.unwords (map cvtSV args))
+        sh (SBVApp (IEEEFP w                    ) args) = "(" <> showText w <> " " <> T.unwords (map cvtSV args) <> ")"
+
+        -- Some non-linear operators are supported by z3/CVC5 specifically, so do the custom translation Otherwise
+        -- we pass them along.
+        sh (SBVApp (NonLinear NR_Sqrt) [a])    | isZ3   = "(^ "    <> cvtSV a <> " 0.5)"
+                                               | isCVC5 = "(sqrt " <> cvtSV a <>     ")"
+
+        sh (SBVApp (NonLinear NR_Pow)  [a, b]) | isZ3 || isCVC5  = "(^  " <> cvtSV a <> " " <> cvtSV b <> ")"
+
+        sh (SBVApp (NonLinear w) [])   =        T.pack (showNROp (name (solver cfg)) w)
+        sh (SBVApp (NonLinear w) args) = "(" <> T.pack (showNROp (name (solver cfg)) w) <> " " <> T.unwords (map cvtSV args) <> ")"
+
+        sh (SBVApp (PseudoBoolean pb) args)
+          | hasPB = handlePB pb args'
+          | True  = reducePB pb args'
+          where args' = map cvtSV args
+
+        sh (SBVApp (OverflowOp op) args) = "(" <> showText op <> " " <> T.unwords (map cvtSV args) <> ")"
+
+        -- Note the unfortunate reversal in StrInRe..
+        sh (SBVApp (StrOp (StrInRe r)) args) = "(str.in_re " <> T.unwords (map cvtSV args) <> " " <> regExpToSMTString r <> ")"
+        sh (SBVApp (StrOp op)          args) = "(" <> showText op <> " " <> T.unwords (map cvtSV args) <> ")"
+
+        sh (SBVApp (RegExOp o@RegExEq{})  []) = showText o
+        sh (SBVApp (RegExOp o@RegExNEq{}) []) = showText o
+
+        -- Sequences. The only interesting thing here is that unit over KChar is a no-op since SMTLib doesn't distinguish
+        -- Strings and Characters, but SBV does.
+        sh (SBVApp (SeqOp (SeqUnit KChar)) [a]) = cvtSV a
+        sh (SBVApp (SeqOp op)             args) = "(" <> showText op <> " " <> T.unwords (map cvtSV args) <> ")"
+
+        sh (SBVApp (SetOp SetEqual)      args)   = "(= "      <> T.unwords (map cvtSV args) <> ")"
+        sh (SBVApp (SetOp SetMember)     [e, s]) = "(select " <> cvtSV s <> " " <> cvtSV e <> ")"
+        sh (SBVApp (SetOp SetInsert)     [e, s]) = "(store "  <> cvtSV s <> " " <> cvtSV e <> " true)"
+        sh (SBVApp (SetOp SetDelete)     [e, s]) = "(store "  <> cvtSV s <> " " <> cvtSV e <> " false)"
+        sh (SBVApp (SetOp SetIntersect)  args)   = "(intersection " <> T.unwords (map cvtSV args) <> ")"
+        sh (SBVApp (SetOp SetUnion)      args)   = "(union "        <> T.unwords (map cvtSV args) <> ")"
+        sh (SBVApp (SetOp SetSubset)     args)   = "(subset "       <> T.unwords (map cvtSV args) <> ")"
+        sh (SBVApp (SetOp SetDifference) args)   = "(setminus "     <> T.unwords (map cvtSV args) <> ")"
+        sh (SBVApp (SetOp SetComplement) args)   = "(complement "   <> T.unwords (map cvtSV args) <> ")"
+
+        sh (SBVApp (TupleConstructor 0)   [])    = "mkSBVTuple0"
+        sh (SBVApp (TupleConstructor n)   args)  = "((as mkSBVTuple" <> showText n <> " " <> smtType (KTuple (map kindOf args)) <> ") " <> T.unwords (map cvtSV args) <> ")"
+        sh (SBVApp (TupleAccess      i n) [tup]) = "(proj_" <> showText i <> "_SBVTuple" <> showText n <> " " <> cvtSV tup <> ")"
+
+        sh (SBVApp  RationalConstructor    [t, b]) = "(SBV.Rational " <> cvtSV t <> " " <> cvtSV b <> ")"
+
+        sh (SBVApp Implies [a, b]) = "(=> " <> cvtSV a <> " " <> cvtSV b <> ")"
+
+        sh inp@(SBVApp op args)
+          | intOp, Just f <- lookup op smtOpIntTable
+          = f True (map cvtSV args)
+          | boolOp, Just f <- lookup op boolComps
+          = f (map cvtSV args)
+          | bvOp, Just f <- lookup op smtOpBVTable
+          = f (any hasSign args) (map cvtSV args)
+          | realOp, Just f <- lookup op smtOpRealTable
+          = f (any hasSign args) (map cvtSV args)
+          | ratOp, Just f <- lookup op ratOpTable
+          = f (map cvtSV args)
+          | fpOp, Just f <- lookup op smtOpFloatDoubleTable
+          = f (any hasSign args) (map cvtSV args)
+          | charOp || stringOp, Just f <- lookup op smtStringTable
+          = f (map cvtSV args)
+          | listOp, Just f <- lookup op smtListTable
+          = f (map cvtSV args)
+          | Just f <- lookup op uninterpretedTable
+          = f (map cvtSV args)
+          | True
+          = error $ unlines [ ""
+                            , "*** SBV.SMT.SMTLib2.cvtExp.sh: impossible happened; can't translate: " ++ show inp
+                            , "***"
+                            , "*** Applied to arguments of type: " ++ intercalate ", " (nub (map (show . kindOf) args))
+                            , "***"
+                            , "*** This can happen if the Num instance isn't properly defined for a lifted kind."
+                            , "*** (See https://github.com/LeventErkok/sbv/issues/698 for a discussion.)"
+                            , "***"
+                            , "*** If you believe this is in error, please report!"
+                            ]
+          where smtOpBVTable  = [ (Plus,          lift2   "bvadd")
+                                , (Minus,         lift2   "bvsub")
+                                , (Times,         lift2   "bvmul")
+                                , (UNeg,          lift1B  "not"    "bvneg")
+                                , (Abs,           liftAbs)
+                                , (Quot,          lift2S  "bvudiv" "bvsdiv")
+                                , (Rem,           lift2S  "bvurem" "bvsrem")
+                                , (Equal True,    eqBV)
+                                , (Equal False,   eqBV)
+                                , (NotEqual,      neqBV)
+                                , (LessThan,      lift2S  "bvult" "bvslt")
+                                , (GreaterThan,   lift2S  "bvugt" "bvsgt")
+                                , (LessEq,        lift2S  "bvule" "bvsle")
+                                , (GreaterEq,     lift2S  "bvuge" "bvsge")
+                                ]
+
+                -- Boolean comparisons.. SMTLib's bool type doesn't do comparisons, but Haskell does.. Sigh
+                boolComps      = [ (LessThan,      blt)
+                                 , (GreaterThan,   blt . swp)
+                                 , (LessEq,        blq)
+                                 , (GreaterEq,     blq . swp)
+                                 ]
+                               where blt [x, y] = "(and (not " <> x <> ") " <> y <> ")"
+                                     blt xs     = error $ "SBV.SMT.SMTLib2.boolComps.blt: Impossible happened, incorrect arity (expected 2): " ++ show xs
+                                     blq [x, y] = "(or (not " <> x <> ") " <> y <> ")"
+                                     blq xs     = error $ "SBV.SMT.SMTLib2.boolComps.blq: Impossible happened, incorrect arity (expected 2): " ++ show xs
+                                     swp [x, y] = [y, x]
+                                     swp xs     = error $ "SBV.SMT.SMTLib2.boolComps.swp: Impossible happened, incorrect arity (expected 2): " ++ show xs
+
+                smtOpRealTable =  smtIntRealShared
+                               ++ [ (Quot,        lift2WM "/" "fp.div")
+                                  ]
+
+                smtOpIntTable  = smtIntRealShared
+                               ++ [ (Quot,        lift2   "div")
+                                  , (Rem,         lift2   "mod")
+                                  ]
+
+                smtOpFloatDoubleTable = smtIntRealShared
+                                  ++ [(Quot, lift2WM "/" "fp.div")]
+
+                smtIntRealShared  = [ (Plus,          lift2WM "+" "fp.add")
+                                    , (Minus,         lift2WM "-" "fp.sub")
+                                    , (Times,         lift2WM "*" "fp.mul")
+                                    , (UNeg,          lift1FP "-" "fp.neg")
+                                    , (Abs,           liftAbs)
+                                    , (Equal True,    equal)
+                                    , (Equal False,   equal)
+                                    , (NotEqual,      notEqual)
+                                    , (LessThan,      lift2Cmp  "<"  "fp.lt")
+                                    , (GreaterThan,   lift2Cmp  ">"  "fp.gt")
+                                    , (LessEq,        lift2Cmp  "<=" "fp.leq")
+                                    , (GreaterEq,     lift2Cmp  ">=" "fp.geq")
+                                    ]
+
+                ratOpTable = [ (Equal True,  lift2Rat "sbv.rat.eq")
+                             , (Equal False, lift2Rat "sbv.rat.eq")
+                             , (NotEqual,    lift2Rat "sbv.rat.notEq")
+                             ]
+                        where lift2Rat o [x, y] = "(" <> o <> " " <> x <> " " <> y <> ")"
+                              lift2Rat o sbvs   = error $ "SBV.SMTLib2.sh.lift2Rat: Unexpected arguments: " ++ show (o, sbvs)
+
+                -- equality and comparisons are the only thing that works on uninterpreted sorts and pretty much everything else
+                uninterpretedTable = [ (Equal True,  lift2S "="        "="        True)
+                                     , (Equal False, lift2S "="        "="        True)
+                                     , (NotEqual,    liftNS "distinct" "distinct" True)
+                                     ]
+
+                -- For strings, equality and comparisons are the only operators
+                smtStringTable = [ (Equal True,  lift2S "="        "="        True)
+                                 , (Equal False, lift2S "="        "="        True)
+                                 , (NotEqual,    liftNS "distinct" "distinct" True)
+                                 , (LessThan,    stringCmp False "str.<")
+                                 , (GreaterThan, stringCmp True  "str.<")
+                                 , (LessEq,      stringCmp False "str.<=")
+                                 , (GreaterEq,   stringCmp True  "str.<=")
+                                 ]
+
+                -- For lists, equality is really the only operator. Also, not strong-equality due to lists of floats.
+                -- Likewise here, things might change for comparisons
+                smtListTable = [ (Equal False, lift2S "="        "="        True)
+                               , (NotEqual,    liftNS "distinct" "distinct" True)
+                               , (LessThan,    seqCmp False "seq.<")
+                               , (GreaterThan, seqCmp True  "seq.<")
+                               , (LessEq,      seqCmp False "seq.<=")
+                               , (GreaterEq,   seqCmp True  "seq.<=")
+                               ]
+
+declareFun :: SV -> SBVType -> Maybe Text -> [Text]
+declareFun sv = declareName (showText sv)
+
+-- If we have a char, we have to make sure it's and SMTLib string of length exactly one
+-- If we have a rational, we have to make sure the denominator is > 0
+-- Otherwise, we just declare the name
+declareName :: Text -> SBVType -> Maybe Text -> [Text]
+declareName s t@(SBVType inputKS) mbCmnt = decl : restrict
+  where decl = "(declare-fun " <> s <> " " <> cvtType t <> ")" <> maybe "" (" ; " <>) mbCmnt
+
+        (args, result) = case inputKS of
+                          [] -> error $ "SBV.declareName: Unexpected empty type for: " ++ T.unpack s
+                          _  -> (init inputKS, last inputKS)
+
+        -- Does the kind KChar and KRational *not* occur in the kind anywhere?
+        charRatFree k = all notCharOrRat (expandKinds k)
+           where notCharOrRat KChar     = False
+                 notCharOrRat KRational = False
+                 notCharOrRat _         = True
+
+        noCharOrRat   = charRatFree result
+        needsQuant    = not $ null args
+
+        resultVar | needsQuant = "result"
+                  | True       = s
+
+        argList   = ["a" <> showText i | (i, _) <- zip [1::Int ..] args]
+        argTList  = ["(" <> a <> " " <> smtType k <> ")" | (a, k) <- zip argList args]
+        resultExp = "(" <> s <> " " <> T.unwords argList <> ")"
+
+        restrict | noCharOrRat = []
+                 | needsQuant  =    [               "(assert (forall (" <> T.unwords argTList <> ")"
+                                    ,               "                (let ((" <> resultVar <> " " <> resultExp <> "))"
+                                    ]
+                                 <> (case constraints of
+                                       []     ->  [ "                     true"]
+                                       [x]    ->  [ "                     " <> x]
+                                       (x:xs) ->  ( "                     (and " <> x)
+                                               :  [ "                          " <> c | c <- xs]
+                                               <> [ "                     )"])
+                                 <> [        "                )))"]
+                 | True        = case constraints of
+                                  []     -> []
+                                  [x]    -> ["(assert " <> x <> ")"]
+                                  (x:xs) -> ( "(assert (and " <> x)
+                                         :  [ "             " <> c | c <- xs]
+                                         <> [ "        ))"]
+
+        constraints = walk 0 resultVar cstr result
+          where cstr KChar     nm = ["(= 1 (str.len " <> nm <> "))"]
+                cstr KRational nm = ["(< 0 (sbv.rat.denominator " <> nm <> "))"]
+                cstr _         _  = []
+
+        mkAnd [] _context = []
+        mkAnd [c] context = context c
+        mkAnd cs  context = context $ "(and " <> T.unwords cs <> ")"
+
+        walk :: Int -> Text -> (Kind -> Text -> [Text]) -> Kind -> [Text]
+        walk _d nm f k@KVar      {}         = f k nm
+        walk _d nm f k@KBool     {}         = f k nm
+        walk _d nm f k@KBounded  {}         = f k nm
+        walk _d nm f k@KUnbounded{}         = f k nm
+        walk _d nm f k@KReal     {}         = f k nm
+        walk _d nm f k@KApp      {}         = f k nm
+        walk _d nm f k@KFloat    {}         = f k nm
+        walk _d nm f k@KDouble   {}         = f k nm
+        walk _d nm f k@KRational {}         = f k nm
+        walk _d nm f k@KFP       {}         = f k nm
+        walk _d nm f k@KChar     {}         = f k nm
+        walk _d nm f k@KString   {}         = f k nm
+        walk  d nm f  (KList k)
+          | charRatFree k                 = []
+          | True                          = let fnm   = "seq" <> showText d
+                                                cstrs = walk (d+1) ("(seq.nth " <> nm <> " " <> fnm <> ")") f k
+                                            in mkAnd cstrs $ \hole -> ["(forall ((" <> fnm <> " " <> smtType KUnbounded <> ")) (=> (and (>= " <> fnm <> " 0) (< " <> fnm <> " (seq.len " <> nm <> "))) " <> hole <> "))"]
+        walk  d  nm f (KSet k)
+          | charRatFree k                 = []
+          | True                          = let fnm    = "set" <> showText d
+                                                cstrs  = walk (d+1) nm (\sk snm -> ["(=> (select " <> snm <> " " <> fnm <> ") " <> c <> ")" | c <- f sk fnm]) k
+                                            in mkAnd cstrs $ \hole -> ["(forall ((" <> fnm <> " " <> smtType k <> ")) " <> hole <> ")"]
+        walk  d  nm  f (KTuple ks)        = let tt        = "SBVTuple" <> showText (length ks)
+                                                project i = "(proj_" <> showText i <> "_" <> tt <> " " <> nm <> ")"
+                                                nmks      = [(project i, k) | (i, k) <- zip [1::Int ..] ks]
+                                            in concatMap (\(n, k) -> walk (d+1) n f k) nmks
+        walk d  nm f  (KArray k1 k2)
+          | all charRatFree [k1, k2]      = []
+          | True                          = let fnm   = "array" <> showText d
+                                                cstrs = walk (d+1) ("(select " <> nm <> " " <> fnm <> ")") f k2
+                                            in mkAnd cstrs $ \hole -> ["(forall ((" <> fnm <> " " <> smtType k1 <> ")) " <> hole <> ")"]
+        walk d nm f (KADT ty dict pureFS) = let fs = [(c, map (substituteADTVars ty dict) ks) | (c, ks) <- pureFS]
+                                                nmks  = [("(get" <> T.pack c <> "_" <> showText i <> " " <> nm <> ")", k) | (c, ks) <- fs, (i, k) <- zip [(1::Int)..] ks]
+                                            in concatMap (\(n, k) -> walk (d+1) n f k) nmks
+
+-----------------------------------------------------------------------------------------------
+-- Casts supported by SMTLib. (From: <https://smt-lib.org/theories-FloatingPoint.shtml>)
+--   ; from another floating point sort
+--   ((_ to_fp eb sb) RoundingMode (_ FloatingPoint mb nb) (_ FloatingPoint eb sb))
+--
+--   ; from real
+--   ((_ to_fp eb sb) RoundingMode Real (_ FloatingPoint eb sb))
+--
+--   ; from signed machine integer, represented as a 2's complement bit vector
+--   ((_ to_fp eb sb) RoundingMode (_ BitVec m) (_ FloatingPoint eb sb))
+--
+--   ; from unsigned machine integer, represented as bit vector
+--   ((_ to_fp_unsigned eb sb) RoundingMode (_ BitVec m) (_ FloatingPoint eb sb))
+--
+--   ; to unsigned machine integer, represented as a bit vector
+--   ((_ fp.to_ubv m) RoundingMode (_ FloatingPoint eb sb) (_ BitVec m))
+--
+--   ; to signed machine integer, represented as a 2's complement bit vector
+--   ((_ fp.to_sbv m) RoundingMode (_ FloatingPoint eb sb) (_ BitVec m))
+--
+--   ; to real
+--   (fp.to_real (_ FloatingPoint eb sb) Real)
+-----------------------------------------------------------------------------------------------
+
+handleFPCast :: Kind -> Kind -> Text -> Text -> Text
+handleFPCast kFromIn kToIn rm input
+  | kFrom == kTo
+  = input
+  | True
+  = "(" <> cast kFrom kTo input <> ")"
+  where addRM a s = s <> " " <> rm <> " " <> a
+
+        kFrom = simplify kFromIn
+        kTo   = simplify kToIn
+
+        simplify KFloat  = KFP   8 24
+        simplify KDouble = KFP  11 53
+        simplify k       = k
+
+        size (eb, sb) = showText eb <> " " <> showText sb
+
+        -- To go and back from Ints, we detour through reals
+        cast KUnbounded (KFP eb sb) a = "(_ to_fp " <> size (eb, sb) <> ") "  <> rm <> " (to_real " <> a <> ")"
+        cast KFP{}      KUnbounded  a = "to_int (fp.to_real (fp.roundToIntegral " <> rm <> " " <> a <> "))"
+
+        -- To floats
+        cast (KBounded False _) (KFP eb sb) a = addRM a $ "(_ to_fp_unsigned " <> size (eb, sb) <> ")"
+        cast (KBounded True  _) (KFP eb sb) a = addRM a $ "(_ to_fp "          <> size (eb, sb) <> ")"
+        cast KReal              (KFP eb sb) a = addRM a $ "(_ to_fp "          <> size (eb, sb) <> ")"
+        cast KFP{}              (KFP eb sb) a = addRM a $ "(_ to_fp "          <> size (eb, sb) <> ")"
+
+        -- From float/double
+        cast KFP{} (KBounded False m) a = addRM a $ "(_ fp.to_ubv " <> showText m <> ")"
+        cast KFP{} (KBounded True  m) a = addRM a $ "(_ fp.to_sbv " <> showText m <> ")"
+
+        -- To real
+        cast KFP{} KReal a = "fp.to_real" <> " " <> a
+
+        -- Nothing else should come up:
+        cast f  d  _ = error $ "SBV.SMTLib2: Unexpected FPCast from: " ++ show f ++ " to " ++ show d
+
+rot :: Text -> Int -> SV -> Text
+rot o c x = "((_ " <> o <> " " <> showText c <> ") " <> cvtSV x <> ")"
+
+shft :: Text -> Text -> SV -> SV -> Text
+shft oW oS x c = "(" <> o <> " " <> cvtSV x <> " " <> cvtSV c <> ")"
+   where o = if hasSign x then oS else oW
+
+-- ADT operations
+handleADT :: SolverCapabilities -> ADTOp -> [SV] -> Text
+handleADT caps op args = case args of
+                          [] -> f
+                          _  -> "(" <> f <> " " <> T.unwords (map cvtSV args) <> ")"
+  where f = case op of
+              ADTConstructor nm k -> ascribe nm k
+              ADTTester      nm k -> if supportsDirectTesters caps
+                                     then nm
+                                     else ascribe nm k
+              ADTAccessor    nm _ -> nm
+
+        ascribe nm k = "(as " <> nm <> " " <> smtType k <> ")"
+
+-- | Handle a kind-cast. This function only needs to cover the conversions that the type-safe API can actually
+-- produce; the dynamic 'Data.SBV.Dynamic.svFromIntegral' can request other combinations, which we reject with an error.
+--
+-- The type-safe generators of a 'KindCast' are:
+--
+--     * 'Data.SBV.sFromIntegral' : @Integral a => SBV a -> SBV b@. The source is 'Integral', so it is always 'KBounded'
+--       or 'KUnbounded'; the target is any @Num@/@SymVal@ kind (bounded, unbounded, real, rational, or float/double/FP).
+--     * 'Data.SBV.sRealToSIntegerFloor': only ever emits @KReal -> KUnbounded@.
+--     * shift-amount adjustment: only ever emits @KBounded -> KBounded@.
+--
+-- So the reachable (from, to) pairs are exactly:
+--
+--     * @KBounded   -> {KBounded, KUnbounded, KReal, KRational, KFloat/KDouble/KFP}@
+--     * @KUnbounded -> {KBounded, KUnbounded, KReal, KRational, KFloat/KDouble/KFP}@
+--     * @KReal      -> KUnbounded@
+--
+-- All of these are handled below (float/double/FP targets are routed through 'handleFPCast' via @tryFPCast@). Note
+-- that a real or rational can never be a source (reals only appear via 'Data.SBV.sRealToSIntegerFloor', which targets 'KUnbounded';
+-- rationals are not 'Integral'), so those directions are unreachable and left to 'error'.
+handleKindCast :: Kind -> Kind -> Text -> Text
+handleKindCast kFrom kTo a
+  | kFrom == kTo
+  = a
+  | True
+  = case kFrom of
+      KBounded s m -> case kTo of
+                        KReal        -> handleKindCast KUnbounded KReal     (handleKindCast kFrom KUnbounded a)
+                        KRational    -> handleKindCast KUnbounded KRational (handleKindCast kFrom KUnbounded a)
+                        KBounded _ n -> fromBV (if s then signExtend else zeroExtend) m n
+                        KUnbounded   -> if s then "(sbv_to_int " <> a <> ")"
+                                             else "(ubv_to_int " <> a <> ")"
+                        _            -> tryFPCast
+
+      KUnbounded   -> case kTo of
+                        KReal        -> "(to_real " <> a <> ")"
+                        KBounded _ n -> "((_ int_to_bv " <> showText n <> ") " <> a <> ")"
+                        KRational    -> "(SBV.Rational " <> a <> " 1)"
+                        _            -> tryFPCast
+
+      KReal        -> case kTo of
+                        KUnbounded   -> "(to_int " <> a <> ")"
+                        _            -> tryFPCast
+
+      _            -> tryFPCast
+
+  where -- See if we can push this down to a float-cast, using sRNE. This happens if one of the kinds is a float/double.
+        -- Otherwise complain
+        tryFPCast
+          | any (\k -> isFloat k || isDouble k) [kFrom, kTo]
+          = handleFPCast kFrom kTo (smtRoundingMode RoundNearestTiesToEven) a
+          | True
+          = error $ "SBV.SMTLib2: Unexpected cast from: " ++ show kFrom ++ " to " ++ show kTo
+
+        fromBV upConv m n
+         | n > m  = upConv  (n - m)
+         | m == n = a
+         | True   = extract (n - 1)
+
+        signExtend i = "((_ sign_extend " <> showText i <> ") "   <> a <> ")"
+        zeroExtend i = "((_ zero_extend " <> showText i <> ") "   <> a <> ")"
+        extract    i = "((_ extract "     <> showText i <> " 0) " <> a <> ")"
+
+-- Translation of pseudo-booleans, in case the solver supports them
+handlePB :: PBOp -> [Text] -> Text
+handlePB (PB_AtMost  k) args = "((_ at-most "  <> showText k                                               <> ") " <> T.unwords args <> ")"
+handlePB (PB_AtLeast k) args = "((_ at-least " <> showText k                                               <> ") " <> T.unwords args <> ")"
+handlePB (PB_Exactly k) args = "((_ pbeq "     <> T.unwords (map showText (k : replicate (length args) 1)) <> ") " <> T.unwords args <> ")"
+handlePB (PB_Eq cs   k) args = "((_ pbeq "     <> T.unwords (map showText (k : cs))                        <> ") " <> T.unwords args <> ")"
+handlePB (PB_Le cs   k) args = "((_ pble "     <> T.unwords (map showText (k : cs))                        <> ") " <> T.unwords args <> ")"
+handlePB (PB_Ge cs   k) args = "((_ pbge "     <> T.unwords (map showText (k : cs))                        <> ") " <> T.unwords args <> ")"
+
+-- Translation of pseudo-booleans, in case the solver does *not* support them
+reducePB :: PBOp -> [Text] -> Text
+reducePB op args = case op of
+                     PB_AtMost  k -> "(<= " <> addIf (repeat 1) <> " " <> showText k <> ")"
+                     PB_AtLeast k -> "(>= " <> addIf (repeat 1) <> " " <> showText k <> ")"
+                     PB_Exactly k -> "(=  " <> addIf (repeat 1) <> " " <> showText k <> ")"
+                     PB_Le cs   k -> "(<= " <> addIf cs         <> " " <> showText k <> ")"
+                     PB_Ge cs   k -> "(>= " <> addIf cs         <> " " <> showText k <> ")"
+                     PB_Eq cs   k -> "(=  " <> addIf cs         <> " " <> showText k <> ")"
+
+  where addIf :: [Int] -> Text
+        addIf cs = "(+ " <> T.unwords ["(ite " <> a <> " " <> showText c <> " 0)" | (a, c) <- zip args cs] <> ")"
+
+-- | Translate an option setting to SMTLib. Note the SetLogic/SetInfo discrepancy.
+setSMTOption :: SMTConfig -> SMTOption -> Text
+setSMTOption cfg = set
+  where set (DiagnosticOutputChannel   f)           = opt [":diagnostic-output-channel",   showText f]
+        set (ProduceAssertions         b)           = opt [":produce-assertions",          smtBool b]
+        set (ProduceAssignments        b)           = opt [":produce-assignments",         smtBool b]
+        set (ProduceProofs             b)           = opt [":produce-proofs",              smtBool b]
+        set (ProduceInterpolants       b)           = opt [":produce-interpolants",        smtBool b]
+        set (ProduceUnsatAssumptions   b)           = opt [":produce-unsat-assumptions",   smtBool b]
+        set (ProduceUnsatCores         b)           = opt [":produce-unsat-cores",         smtBool b]
+        set (ProduceAbducts            b)           = opt [":produce-abducts",             smtBool b]
+        set (RandomSeed                i)           = opt [":random-seed",                 showText i]
+        set (ReproducibleResourceLimit i)           = opt [":reproducible-resource-limit", showText i]
+        set (SMTVerbosity              i)           = opt [":verbosity",                   showText i]
+        set (OptionKeyword ":smtlib2_compliant" _)
+          | not (smtLib2Compliant cfg)              = ""
+        set (OptionKeyword          k as)           = opt (T.pack k : map T.pack as)
+        set (SetLogic                  l)           = logicString cfg l
+        set (SetInfo                k as)           = info (T.pack k : map T.pack as)
+        set (SetTimeOut                i)           = opt $ timeOut i
+
+        opt   xs = "(set-option " <> T.unwords xs <> ")"
+        info  xs = "(set-info "   <> T.unwords xs <> ")"
+
+        -- timeout is not standard. We distinguish between CVC/Z3. All else follows z3
+        -- The value is in milliseconds, which is how z3/CVC interpret it
+        timeOut i = case name (solver cfg) of
+                     CVC4 -> [":tlimit-per", showText i]
+                     CVC5 -> [":tlimit-per", showText i]
+                     _    -> [":timeout",    showText i]
+
+        -- SMTLib's True/False is spelled differently than Haskell's.
+        smtBool :: Bool -> Text
+        smtBool True  = "true"
+        smtBool False = "false"
+
+-- | Set the logic, accounting for solver inconsistencies.
+logicString :: SMTConfig -> Logic -> Text
+logicString cfg = pick
+  where
+    slvr = name (solver cfg)
+
+    -- This is more or less showText, but with exceptions:
+    --
+    --    Logic_ALL : HO_ALL for CVC5 to get support for higher-order features.
+    --    QF_FPBV   : Bitwuzla calls it QF_BVFP. See: https://github.com/LeventErkok/sbv/issues/774
+    --    Logic_NONE: Sets nothing, just sets a comment
+    pick Logic_ALL | CVC5     <- slvr = wrap "HO_ALL"
+    pick QF_FPBV   | Bitwuzla <- slvr = wrap "QF_BVFP"
+    pick Logic_NONE                   = "; NB. not setting the logic per user request of Logic_NONE"
+
+    -- Fall thru
+    pick l = wrap (showText l)
+
+    wrap l = "(set-logic " <> l <> ")"
+
+{- HLint ignore module "Use record patterns" -}
diff --git a/Data/SBV/SMT/Utils.hs b/Data/SBV/SMT/Utils.hs
--- a/Data/SBV/SMT/Utils.hs
+++ b/Data/SBV/SMT/Utils.hs
@@ -9,17 +9,16 @@
 -- A few internally used types/routines
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE NamedFieldPuns      #-}
+{-# LANGUAGE OverloadedStrings   #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
 module Data.SBV.SMT.Utils (
           SMTLibConverter
         , SMTLibIncConverter
-        , witnessName
         , addAnnotations
         , showTimeoutValue
-        , alignDiagnostic
         , alignPlain
         , debug
         , mergeSExpr
@@ -35,13 +34,12 @@
 
 import qualified Control.Exception as C
 
-import Control.Monad (zipWithM_)
 import Control.Monad.Trans (MonadIO, liftIO)
 
 import Data.SBV.Core.Data
 import Data.SBV.Core.Symbolic (QueryContext, CnstMap, SMTDef, ResultInp(..), ProgInfo(..), startTime)
 
-import Data.SBV.Utils.Lib   (joinArgs)
+import Data.SBV.Utils.Lib   (joinArgs, showText)
 import Data.SBV.Utils.TDiff (Timing(..), showTDiff)
 
 import Data.IORef (writeIORef)
@@ -49,11 +47,14 @@
 
 import Data.Char  (isSpace)
 import Data.Maybe (fromMaybe)
-import Data.List  (intercalate)
 
 import qualified Data.Set      as Set (Set)
 import qualified Data.Sequence as S   (Seq)
 
+import qualified Data.Text    as T
+import qualified Data.Text.IO as TIO
+import           Data.Text (Text)
+
 import System.Directory (findExecutable)
 import System.Exit      (ExitCode(..))
 
@@ -81,83 +82,83 @@
                           -> (CnstMap, [(SV, CV)])                       -- ^ all constants sofar, and new constants
                           -> [((Int, Kind, Kind), [SV])]                 -- ^ newly created tables
                           -> [(String, (Bool, Maybe [String], SBVType))] -- ^ newly created uninterpreted functions/constants
+                          -> [(String, (SMTDef, SBVType))]               -- ^ newly created user definitions
                           -> SBVPgm                                      -- ^ assignments
                           -> S.Seq (Bool, [(String, String)], SV)        -- ^ extra constraints
                           -> SMTConfig                                   -- ^ configuration
                           -> a
 
--- | The name of a witness for a type. We should make sure this doesn't conflict any reserved names, but I think the chances of that is
--- pretty low anyhow.
-witnessName :: String -> String
-witnessName = (++ "_witness")
-
 -- | Create an annotated term
-addAnnotations :: [(String, String)] -> String -> String
+addAnnotations :: [(String, String)] -> Text -> Text
 addAnnotations []   x = x
-addAnnotations atts x = "(! " ++ x ++ " " ++ unwords (map mkAttr atts) ++ ")"
+addAnnotations atts x = "(! " <> x <> " " <> T.unwords (map (T.pack . mkAttr) atts) <> ")"
   where mkAttr (a, v) = a ++ " |" ++ concatMap sanitize v ++ "|"
         sanitize '|'  = "_bar_"
         sanitize '\\' = "_backslash_"
         sanitize c    = [c]
 
 -- | Show a millisecond time-out value somewhat nicely
-showTimeoutValue :: Int -> String
+showTimeoutValue :: Int -> Text
 showTimeoutValue i = case (i `quotRem` 1000000, i `quotRem` 500000) of
-                       ((s, 0), _)  -> shows s                              "s"
-                       (_, (hs, 0)) -> shows (fromIntegral hs / (2::Float)) "s"
-                       _            -> shows i "ms"
+                       ((s, 0), _)  -> showText s                              <> "s"
+                       (_, (hs, 0)) -> showText (fromIntegral hs / (2::Float)) <> "s"
+                       _            -> showText i <> "ms"
 
 -- | Nicely align a potentially multi-line message with some tag, but prefix with three stars
-alignDiagnostic :: String -> String -> String
+alignDiagnostic :: Text -> Text -> Text
 alignDiagnostic = alignWithPrefix "*** "
 
 -- | Nicely align a potentially multi-line message with some tag, no prefix.
-alignPlain :: String -> String -> String
+alignPlain :: Text -> Text -> Text
 alignPlain = alignWithPrefix ""
 
 -- | Align with some given prefix
-alignWithPrefix :: String -> String -> String -> String
-alignWithPrefix pre tag multi = intercalate "\n" $ zipWith (++) (tag : repeat (pre ++ replicate (length tag - length pre) ' ')) (filter (not . null) (lines multi))
+alignWithPrefix :: Text -> Text -> Text -> Text
+alignWithPrefix pre tag multi = T.intercalate "\n" $ zipWith (<>) (tag : repeat (pre <> T.replicate (T.length tag - T.length pre) " ")) (filter (not . T.null) (T.lines multi))
 
 -- | Diagnostic message when verbose
-debug :: MonadIO m => SMTConfig -> [String] -> m ()
+debug :: MonadIO m => SMTConfig -> [Text] -> m ()
 debug cfg
-  | not (verbose cfg)             = const (return ())
-  | Just f <- redirectVerbose cfg = liftIO . mapM_ (appendFile f . (++ "\n"))
-  | True                          = liftIO . mapM_ putStrLn
+  | not (verbose cfg)             = const (pure ())
+  | Just f <- redirectVerbose cfg = liftIO . mapM_ (\t -> TIO.appendFile f (t <> "\n"))
+  | True                          = liftIO . mapM_ TIO.putStrLn
 
 -- | In case the SMT-Lib solver returns a response over multiple lines, compress them so we have
 -- each S-Expression spanning only a single line.
-mergeSExpr :: [String] -> [String]
+mergeSExpr :: [Text] -> [Text]
 mergeSExpr []       = []
 mergeSExpr (x:xs)
  | d == 0 = x : mergeSExpr xs
- | True   = let (f, r) = grab d xs in unlines (x:f) : mergeSExpr r
+ | True   = let (f, r) = grab d xs in T.unlines (x:f) : mergeSExpr r
  where d = parenDiff x
 
-       parenDiff :: String -> Int
+       parenDiff :: Text -> Int
        parenDiff = go 0
-         where go i ""       = i
-               go i ('(':cs) = let i'= i+1 in i' `seq` go i' cs
-               go i (')':cs) = let i'= i-1 in i' `seq` go i' cs
-               go i ('"':cs) = go i (skipString cs)
-               go i ('|':cs) = go i (skipBar cs)
-               go i (';':cs) = go i (drop 1 (dropWhile (/= '\n') cs))
-               go i (_  :cs) = go i cs
+         where go i t = case T.uncons t of
+                 Nothing       -> i
+                 Just ('(', r) -> let i' = i+1 in i' `seq` go i' r
+                 Just (')', r) -> let i' = i-1 in i' `seq` go i' r
+                 Just ('"', r) -> go i (skipString r)
+                 Just ('|', r) -> go i (skipBar r)
+                 Just (';', r) -> go i (T.drop 1 (T.dropWhile (/= '\n') r))
+                 Just (_,   r) -> go i r
 
        grab i ls
          | i <= 0    = ([], ls)
        grab _ []     = ([], [])
        grab i (l:ls) = let (a, b) = grab (i+parenDiff l) ls in (l:a, b)
 
-       skipString ('"':'"':cs)   = skipString cs
-       skipString ('"':cs)       = cs
-       skipString (_:cs)         = skipString cs
-       skipString []             = []             -- Oh dear, line finished, but the string didn't. We're in trouble. Ignore!
+       skipString t = case T.uncons t of
+         Nothing       -> T.empty             -- Oh dear, line finished, but the string didn't. We're in trouble. Ignore!
+         Just ('"', r) -> case T.uncons r of
+           Just ('"', r') -> skipString r'    -- escaped quote
+           _              -> r                -- end of string
+         Just (_,   r) -> skipString r
 
-       skipBar ('|':cs) = cs
-       skipBar (_:cs)   = skipBar cs
-       skipBar []       = []                     -- Oh dear, line finished, but the string didn't. We're in trouble. Ignore!
+       skipBar t = case T.uncons t of
+         Nothing       -> T.empty             -- Oh dear, line finished, but the bar didn't. We're in trouble. Ignore!
+         Just ('|', r) -> r
+         Just (_,   r) -> skipBar r
 
 -- | An exception thrown from SBV. If the solver ever responds with a non-success value for a command,
 -- SBV will throw an t'SBVException', it so the user can process it as required. The provided 'Show' instance
@@ -195,42 +196,42 @@
                    }
 
          = let grp1 = [ ""
-                      , "*** Data.SBV: " ++ sbvExceptionDescription ++ ":"
+                      , "*** Data.SBV: " <> T.pack sbvExceptionDescription <> ":"
                       ]
 
-               grp2 =  ["***    Sent      : " `alignDiagnostic` snt     | Just snt  <- [sbvExceptionSent],     not $ null snt ]
-                    ++ ["***    Expected  : " `alignDiagnostic` excp    | Just excp <- [sbvExceptionExpected], not $ null excp]
-                    ++ ["***    Received  : " `alignDiagnostic` rcvd    | Just rcvd <- [sbvExceptionReceived], not $ null rcvd]
+               grp2 =  ["***    Sent      : " `alignDiagnostic` T.pack snt  | Just snt  <- [sbvExceptionSent],     not $ null snt ]
+                    <> ["***    Expected  : " `alignDiagnostic` T.pack excp | Just excp <- [sbvExceptionExpected], not $ null excp]
+                    <> ["***    Received  : " `alignDiagnostic` T.pack rcvd | Just rcvd <- [sbvExceptionReceived], not $ null rcvd]
 
-               grp3 =  ["***    Stdout    : " `alignDiagnostic` out     | Just out  <- [sbvExceptionStdOut],   not $ null out ]
-                    ++ ["***    Stderr    : " `alignDiagnostic` err     | Just err  <- [sbvExceptionStdErr],   not $ null err ]
-                    ++ ["***    Exit code : " `alignDiagnostic` show ec | Just ec   <- [sbvExceptionExitCode]                 ]
-                    ++ ["***    Executable: " `alignDiagnostic` executable (solver sbvExceptionConfig)                                   ]
-                    ++ ["***    Options   : " `alignDiagnostic` joinArgs (options (solver sbvExceptionConfig) sbvExceptionConfig)        ]
+               grp3 =  ["***    Stdout    : " `alignDiagnostic` T.pack out  | Just out  <- [sbvExceptionStdOut],   not $ null out ]
+                    <> ["***    Stderr    : " `alignDiagnostic` T.pack err  | Just err  <- [sbvExceptionStdErr],   not $ null err ]
+                    <> ["***    Exit code : " `alignDiagnostic` showText ec | Just ec   <- [sbvExceptionExitCode]                 ]
+                    <> ["***    Executable: " `alignDiagnostic` T.pack (executable (solver sbvExceptionConfig))                           ]
+                    <> ["***    Options   : " `alignDiagnostic` T.pack (joinArgs (options (solver sbvExceptionConfig) sbvExceptionConfig))]
 
-               grp4 =  ["***    Reason    : " `alignDiagnostic` unlines rsn | Just rsn <- [sbvExceptionReason]]
-                    ++ ["***    Hint      : " `alignDiagnostic` unlines hnt | Just hnt <- [sbvExceptionHint  ]]
+               grp4 =  ["***    Reason    : " `alignDiagnostic` T.pack (unlines rsn) | Just rsn <- [sbvExceptionReason]]
+                    <> ["***    Hint      : " `alignDiagnostic` T.pack (unlines hnt) | Just hnt <- [sbvExceptionHint  ]]
 
                join []     = []
                join [x]    = x
                join (g:gs) = case join gs of
                                []    -> g
-                               rest  -> g ++ ["***"] ++ rest
+                               rest  -> g <> ["***"] <> rest
 
-          in unlines $ join [grp1, grp2, grp3, grp4]
+          in T.unpack $ T.unlines $ join [grp1, grp2, grp3, grp4]
 
 -- | Compute and report the end time
 recordEndTime :: SMTConfig -> State -> IO ()
 recordEndTime SMTConfig{timing} state = case timing of
-                                           NoTiming        -> return ()
+                                           NoTiming        -> pure ()
                                            PrintTiming     -> do e <- elapsed
                                                                  putStrLn $ "*** SBV: Elapsed time: " ++ showTDiff e
                                            SaveTiming here -> writeIORef here =<< elapsed
-  where elapsed = getCurrentTime >>= \end -> return $ diffUTCTime end (startTime state)
+  where elapsed = getCurrentTime >>= \end -> pure $ diffUTCTime end (startTime state)
 
 -- | Start a transcript file, if requested.
 startTranscript :: Maybe FilePath -> SMTConfig -> IO ()
-startTranscript Nothing  _   = return ()
+startTranscript Nothing  _   = pure ()
 startTranscript (Just f) cfg = do ts <- show <$> getZonedTime
                                   mbExecPath <- findExecutable (executable (solver cfg))
                                   writeFile f $ start ts mbExecPath
@@ -249,7 +250,7 @@
 
 -- | Finish up the transcript file.
 finalizeTranscript :: Maybe FilePath -> ExitCode -> IO ()
-finalizeTranscript Nothing  _  = return ()
+finalizeTranscript Nothing  _  = pure ()
 finalizeTranscript (Just f) ec = do ts <- show <$> getZonedTime
                                     appendFile f $ end ts
   where end ts = unlines [ ""
@@ -263,31 +264,31 @@
                          ]
 
 -- Kind of things we can record
-data TranscriptMsg = SentMsg  String (Maybe Int) -- ^ Message sent, and time-out if any
+data TranscriptMsg = SentMsg  Text   (Maybe Int) -- ^ Message sent, and time-out if any
                    | RecvMsg  String             -- ^ Message received
-                   | DebugMsg String             -- ^ A debug message; neither sent nor received
+                   | DebugMsg Text               -- ^ A debug message; neither sent nor received
 
 -- If requested, record in the transcript file
 recordTranscript :: Maybe FilePath -> TranscriptMsg -> IO ()
-recordTranscript Nothing  _ = return ()
+recordTranscript Nothing  _ = pure ()
 recordTranscript (Just f) m = do tsPre <- formatTime defaultTimeLocale "; [%T%Q" <$> getZonedTime
                                  let ts = take 15 $ tsPre ++ repeat '0'
                                  case m of
-                                   SentMsg sent mbTimeOut  -> appendFile f $ unlines $ (ts ++ "] " ++ to mbTimeOut ++ "Sending:") : lines sent
+                                   SentMsg sent mbTimeOut  -> TIO.appendFile f $ T.unlines $ (T.pack ts <> "] " <> to mbTimeOut <> "Sending:") : T.lines sent
                                    RecvMsg recv            -> appendFile f $ unlines $ case lines (dropWhile isSpace recv) of
                                                                                         []  -> [ts ++ "] Received: <NO RESPONSE>"]  -- can't really happen.
                                                                                         [x] -> [ts ++ "] Received: " ++ x]
                                                                                         xs  -> (ts ++ "] Received: ") : map (";   " ++) xs
-                                   DebugMsg msg            -> let tag = ts ++ "] "
-                                                                  emp = ';' : drop 1 (map (const ' ') tag)
-                                                              in zipWithM_ (\t l -> appendFile f (t ++ l ++ "\n")) (tag : repeat emp) (lines msg)
+                                   DebugMsg msg            -> let tag = T.pack ts <> "] "
+                                                                  emp = T.cons ';' (T.replicate (T.length tag - 1) " ")
+                                                              in TIO.appendFile f $ T.unlines $ zipWith (<>) (tag : repeat emp) (T.lines msg)
         where to Nothing  = ""
-              to (Just i) = "[Timeout: " ++ showTimeoutValue i ++ "] "
+              to (Just i) = "[Timeout: " <> showTimeoutValue i <> "] "
 {-# INLINE recordTranscript #-}
 
 -- Record the exception
 recordException :: Maybe FilePath -> String -> IO ()
-recordException Nothing  _ = return ()
+recordException Nothing  _ = pure ()
 recordException (Just f) m = do ts <- show <$> getZonedTime
                                 appendFile f $ exc ts
   where exc ts = unlines $ [ ""
diff --git a/Data/SBV/Set.hs b/Data/SBV/Set.hs
--- a/Data/SBV/Set.hs
+++ b/Data/SBV/Set.hs
@@ -22,7 +22,7 @@
 -----------------------------------------------------------------------------
 
 {-# LANGUAGE CPP                 #-}
-{-# LANGUAGE Rank2Types          #-}
+{-# LANGUAGE RankNTypes          #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeApplications    #-}
 
@@ -62,6 +62,7 @@
 -- >>> -- For doctest purposes only:
 -- >>> import Prelude hiding(null)
 -- >>> import Data.SBV hiding(complement)
+-- >>> import Data.SBV.Maybe
 -- >>> :set -XScopedTypeVariables
 #endif
 
@@ -293,8 +294,8 @@
 --
 -- >>> prove $ \x -> isFull (observe "set" (x `delete` (full :: SSet Integer)))
 -- Falsifiable. Counter-example:
---   s0  =       2 :: Integer
---   set = U - {2} :: {Integer}
+--   s0  =       0 :: Integer
+--   set = U - {0} :: {Integer}
 --
 -- >>> isFull (full :: SSet Integer)
 -- True
@@ -514,7 +515,7 @@
 False
 >>> sat $ \(x::SSet (Maybe Integer)) y z -> distinct [x, y, z]
 Satisfiable. Model:
-  s0 = {Just 3} :: {Maybe Integer}
+  s0 = {Just 2} :: {Maybe Integer}
   s1 =       {} :: {Maybe Integer}
   s2 =        U :: {Maybe Integer}
 
diff --git a/Data/SBV/TP.hs b/Data/SBV/TP.hs
--- a/Data/SBV/TP.hs
+++ b/Data/SBV/TP.hs
@@ -29,24 +29,36 @@
        -- * Basic proofs
        , lemma, lemmaWith
 
+       -- * Basic proofs, with induction schema
+       , inductiveLemma, inductiveLemmaWith
+
        -- * Reasoning via calculation
        , calc, calcWith
 
-       -- * Reasoning via regular induction
+       -- * Reasoning via explicit regular induction
        , induct, inductWith
 
-       -- * Reasoning via measure-based strong induction
+       -- * Reasoning via explicit measure-based strong induction
        , sInduct, sInductWith
 
        -- * Creating instances of proofs
        , at, Inst(..)
 
+       -- * Naming proofs at specific types
+       , atProxy
+
        -- * Faking proofs
        , sorry
 
        -- * Running TP proofs
-       , TP, runTP, runTPWith, tpQuiet, tpRibbon, tpStats, tpAsms, tpCache
+       , TP, runTP, runTPWith, tpQuiet, tpStats, tpAsms
 
+       -- * Dry run guards
+       , whenDryRun, unlessDryRun
+
+       -- * Measure helpers for smtFunctionWithMeasure
+       , measureLemma, measureLemmaWith
+
        -- * Starting a calculation proof
        , (|-), (⊢), (|->)
 
@@ -68,8 +80,9 @@
        -- * Displaying intermediate values of expressions
        , disp
 
-       -- * Recall an old proof, quietly proving it
-       , recall
+       -- * Recall an old proof, using the cache
+       , recall, recallWith
        ) where
 
 import Data.SBV.TP.TP
+import Data.SBV.Utils.Lib (atProxy)
diff --git a/Data/SBV/TP/Kernel.hs b/Data/SBV/TP/Kernel.hs
--- a/Data/SBV/TP/Kernel.hs
+++ b/Data/SBV/TP/Kernel.hs
@@ -9,25 +9,28 @@
 -- Kernel of the TP prover API.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE ConstraintKinds      #-}
-{-# LANGUAGE DataKinds            #-}
-{-# LANGUAGE FlexibleContexts     #-}
-{-# LANGUAGE FlexibleInstances    #-}
-{-# LANGUAGE NamedFieldPuns       #-}
-{-# LANGUAGE ScopedTypeVariables  #-}
-{-# LANGUAGE TypeAbstractions     #-}
+{-# LANGUAGE ConstraintKinds     #-}
+{-# LANGUAGE FlexibleContexts    #-}
+{-# LANGUAGE FlexibleInstances   #-}
+{-# LANGUAGE NamedFieldPuns      #-}
+{-# LANGUAGE OverloadedLists     #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications    #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
 module Data.SBV.TP.Kernel (
          Proposition,  Proof(..)
        , axiom
-       , lemma
-       , lemmaWith
+       , lemma,          lemmaWith
+       , inductiveLemma, inductiveLemmaWith
        , internalAxiom
-       , TPProofContext (..), smtProofStep
+       , TPProofContext (..), smtProofStep, HasInductionSchema(..)
+       , tpMergeCfg, checkNewMeasures
        ) where
 
+import Control.Monad        (unless)
 import Control.Monad.Trans  (liftIO, MonadIO)
 
 import Data.List  (intercalate)
@@ -35,11 +38,12 @@
 
 import Data.SBV.Core.Data     hiding (None)
 import Data.SBV.Trans.Control hiding (getProof)
-import Data.SBV.Core.Symbolic (MonadSymbolic)
+import Data.SBV.Core.Symbolic (MonadSymbolic(..), rSkipMeasureChecks, rMeasureChecks, rNoTermCheckFunctions)
 
 import Data.SBV.SMT.SMT
 import Data.SBV.Core.Model
 import Data.SBV.Provers.Prover
+import Data.SBV.Utils.Lib     (showText)
 
 import Data.SBV.TP.Utils
 
@@ -47,7 +51,11 @@
 import Data.SBV.Utils.TDiff
 
 import Data.Dynamic
+import Data.IORef (readIORef, writeIORef, modifyIORef')
+import qualified Data.Set as Set
 
+import Type.Reflection (typeRep)
+
 -- | A proposition is something SBV is capable of proving/disproving in TP.
 type Proposition a = ( QNot a
                      , QuantifiedBool a
@@ -58,7 +66,110 @@
                      , Typeable a
                      )
 
--- | Accept the given definition as a fact. Usually used to introduce definitial axioms,
+-- | An inductive proposition is a proposition that has an induction scheme associated with it.
+type Inductive a = (HasInductionSchema a, Proposition a)
+
+-- | A class of values that has an associated induction schema. SBV manages this internally.
+class HasInductionSchema a where
+  inductionSchema :: a -> ProofObj
+
+-- | Induction schema for integers. Note that this is good for proving properties over naturals really.
+-- There are other instances that would apply to all integers, but this one is really the most useful
+-- in practice.
+instance HasInductionSchema (Forall nm Integer -> SBool) where
+   inductionSchema p = proofOf $ internalAxiom "inductInteger" ax
+     where pf = p . Forall
+           ax =   sAnd [pf 0, quantifiedBool (\(Forall i) -> (i .>= 0 .=> pf i) .=> pf (i + 1))]
+              .=> quantifiedBool (\(Forall i) -> pf i)
+
+-- | Induction schema for integers with one extra argument
+instance SymVal at => HasInductionSchema (Forall nm Integer -> Forall an at -> SBool) where
+   inductionSchema p = proofOf $ internalAxiom "inductInteger1" ax
+     where pf i a = p (Forall i) (Forall a)
+           ax     = sAnd [ quantifiedBool (\           (Forall a) -> pf 0 a)
+                         , quantifiedBool (\(Forall i) (Forall a) -> (i .>= 0 .=> pf i a) .=> pf (i + 1) a)]
+                    .=>    quantifiedBool (\(Forall i) (Forall a) -> pf i a)
+
+-- | Induction schema for integers with two extra arguments
+instance (SymVal at, SymVal bt) => HasInductionSchema (Forall nm Integer -> Forall an at -> Forall bn bt -> SBool) where
+   inductionSchema p = proofOf $ internalAxiom "inductInteger2" ax
+     where pf i a b = p (Forall i) (Forall a) (Forall b)
+           ax       = sAnd [ quantifiedBool (\           (Forall a) (Forall b) -> pf 0 a b)
+                           , quantifiedBool (\(Forall i) (Forall a) (Forall b) -> (i .>= 0 .=> pf i a b) .=> pf (i + 1) a b)]
+                      .=>    quantifiedBool (\(Forall i) (Forall a) (Forall b) -> pf i a b)
+
+-- | Induction schema for integers with three extra arguments
+instance (SymVal at, SymVal bt, SymVal ct) => HasInductionSchema (Forall nm Integer -> Forall an at -> Forall bn bt -> Forall cn ct -> SBool) where
+   inductionSchema p = proofOf $ internalAxiom "inductInteger3" ax
+     where pf i a b c = p (Forall i) (Forall a) (Forall b) (Forall c)
+           ax         = sAnd [ quantifiedBool (\           (Forall a) (Forall b) (Forall c) -> pf 0 a b c)
+                             , quantifiedBool (\(Forall i) (Forall a) (Forall b) (Forall c) -> (i .>= 0 .=> pf i a b c) .=> pf (i + 1) a b c)]
+                        .=>    quantifiedBool (\(Forall i) (Forall a) (Forall b) (Forall c) -> pf i a b c)
+
+-- | Induction schema for integers with four extra arguments
+instance (SymVal at, SymVal bt, SymVal ct, SymVal dt) => HasInductionSchema (Forall nm Integer -> Forall an at -> Forall bn bt -> Forall cn ct -> Forall dn dt -> SBool) where
+   inductionSchema p = proofOf $ internalAxiom "inductInteger4" ax
+     where pf i a b c d = p (Forall i) (Forall a) (Forall b) (Forall c) (Forall d)
+           ax           = sAnd [ quantifiedBool (\           (Forall a) (Forall b) (Forall c) (Forall d) -> pf 0 a b c d)
+                               , quantifiedBool (\(Forall i) (Forall a) (Forall b) (Forall c) (Forall d) -> (i .>= 0 .=> pf i a b c d) .=> pf (i + 1) a b c d)]
+                          .=>    quantifiedBool (\(Forall i) (Forall a) (Forall b) (Forall c) (Forall d) -> pf i a b c d)
+
+-- | Induction schema for integers with five extra arguments
+instance (SymVal at, SymVal bt, SymVal ct, SymVal dt, SymVal et) => HasInductionSchema (Forall nm Integer -> Forall an at -> Forall bn bt -> Forall cn ct -> Forall dn dt -> Forall en et -> SBool) where
+   inductionSchema p = proofOf $ internalAxiom "inductInteger5" ax
+     where pf i a b c d e = p (Forall i) (Forall a) (Forall b) (Forall c) (Forall d) (Forall e)
+           ax             = sAnd [ quantifiedBool (\           (Forall a) (Forall b) (Forall c) (Forall d) (Forall e) -> pf 0 a b c d e)
+                                 , quantifiedBool (\(Forall i) (Forall a) (Forall b) (Forall c) (Forall d) (Forall e) -> (i .>= 0 .=> pf i a b c d e) .=> pf (i + 1) a b c d e)]
+                            .=>    quantifiedBool (\(Forall i) (Forall a) (Forall b) (Forall c) (Forall d) (Forall e) -> pf i a b c d e)
+
+-- | Induction schema for lists.
+instance SymVal x => HasInductionSchema (Forall nm [x] -> SBool) where
+   inductionSchema p = proofOf $ internalAxiom ("induct" ++ show (typeRep @[x])) ax
+     where pf = p . Forall
+           ax =   sAnd [pf [], quantifiedBool (\(Forall x) (Forall xs) -> pf xs .=> pf (x .: xs))]
+              .=> quantifiedBool (\(Forall xs) -> pf xs)
+
+-- | Induction schema for lists with one extra argument
+instance (SymVal x, SymVal at) => HasInductionSchema (Forall nm [x] -> Forall an at -> SBool) where
+   inductionSchema p = proofOf $ internalAxiom ("induct" ++ show (typeRep @[x]) ++ "1") ax
+     where pf xs a = p (Forall xs) (Forall a)
+           ax      = sAnd [ quantifiedBool (\                       (Forall a) -> pf [] a)
+                          , quantifiedBool (\(Forall x) (Forall xs) (Forall a) -> pf xs a .=> pf (x .: xs) a)]
+                     .=>    quantifiedBool (\(Forall xs) (Forall a) -> pf xs a)
+
+-- | Induction schema for lists with two extra arguments
+instance (SymVal x, SymVal at, SymVal bt) => HasInductionSchema (Forall nm [x] -> Forall an at -> Forall bn bt -> SBool) where
+   inductionSchema p = proofOf $ internalAxiom ("induct" ++ show (typeRep @[x]) ++ "2") ax
+     where pf xs a b = p (Forall xs) (Forall a) (Forall b)
+           ax        = sAnd [ quantifiedBool (\                       (Forall a) (Forall b) -> pf [] a b)
+                            , quantifiedBool (\(Forall x) (Forall xs) (Forall a) (Forall b) -> pf xs a b .=> pf (x .: xs) a b)]
+                       .=>    quantifiedBool (\(Forall xs) (Forall a) (Forall b) -> pf xs a b)
+
+-- | Induction schema for lists with three extra arguments
+instance (SymVal x, SymVal at, SymVal bt, SymVal ct) => HasInductionSchema (Forall nm [x] -> Forall an at -> Forall bn bt -> Forall cn ct -> SBool) where
+   inductionSchema p = proofOf $ internalAxiom ("induct" ++ show (typeRep @[x]) ++ "3") ax
+     where pf xs a b c = p (Forall xs) (Forall a) (Forall b) (Forall c)
+           ax          = sAnd [ quantifiedBool (\                       (Forall a) (Forall b) (Forall c) -> pf [] a b c)
+                              , quantifiedBool (\(Forall x) (Forall xs) (Forall a) (Forall b) (Forall c) -> pf xs a b c .=> pf (x .: xs) a b c)]
+                         .=>    quantifiedBool (\(Forall xs) (Forall a) (Forall b) (Forall c) -> pf xs a b c)
+
+-- | Induction schema for lists with four extra arguments
+instance (SymVal x, SymVal at, SymVal bt, SymVal ct, SymVal dt) => HasInductionSchema (Forall nm [x] -> Forall an at -> Forall bn bt -> Forall cn ct -> Forall dn dt -> SBool) where
+   inductionSchema p = proofOf $ internalAxiom ("induct" ++ show (typeRep @[x]) ++ "4") ax
+     where pf xs a b c d = p (Forall xs) (Forall a) (Forall b) (Forall c) (Forall d)
+           ax            = sAnd [ quantifiedBool (\                       (Forall a) (Forall b) (Forall c) (Forall d) -> pf [] a b c d)
+                                , quantifiedBool (\(Forall x) (Forall xs) (Forall a) (Forall b) (Forall c) (Forall d) -> pf xs a b c d .=> pf (x .: xs) a b c d)]
+                           .=>    quantifiedBool (\(Forall xs) (Forall a) (Forall b) (Forall c) (Forall d) -> pf xs a b c d)
+
+-- | Induction schema for lists with five extra arguments
+instance (SymVal x, SymVal at, SymVal bt, SymVal ct, SymVal dt, SymVal et) => HasInductionSchema (Forall nm [x] -> Forall an at -> Forall bn bt -> Forall cn ct -> Forall dn dt -> Forall en et -> SBool) where
+   inductionSchema p = proofOf $ internalAxiom ("induct" ++ show (typeRep @[x]) ++ "5") ax
+     where pf xs a b c d e = p (Forall xs) (Forall a) (Forall b) (Forall c) (Forall d) (Forall e)
+           ax              = sAnd [ quantifiedBool (\                       (Forall a) (Forall b) (Forall c) (Forall d) (Forall e) -> pf [] a b c d e)
+                                  , quantifiedBool (\(Forall x) (Forall xs) (Forall a) (Forall b) (Forall c) (Forall d) (Forall e) -> pf xs a b c d e .=> pf (x .: xs) a b c d e)]
+                             .=>    quantifiedBool (\(Forall xs) (Forall a) (Forall b) (Forall c) (Forall d) (Forall e) -> pf xs a b c d e)
+
+-- | Accept the given definition as a fact. Usually used to introduce definitional axioms,
 -- giving meaning to uninterpreted symbols. Note that we perform no checks on these propositions,
 -- if you assert nonsense, then you get nonsense back. So, calls to 'axiom' should be limited to
 -- definitions, or basic axioms (like commutativity, associativity) of uninterpreted function symbols.
@@ -77,36 +188,110 @@
                                       , getProp      = toDyn p
                                       , proofName    = nm
                                       , uniqId       = TPInternal
-                                      , isCached     = False
+                                      , aliases      = []
+                                      , wasCached    = False
                                       }
 
--- | Prove a lemma, using the given configuration
-lemmaWith :: Proposition a => SMTConfig -> String -> a -> [ProofObj] -> TP (Proof a)
-lemmaWith cfg@SMTConfig{tpOptions = TPOptions{printStats}} nm inputProp by = withProofCache nm $ do
-                 tpSt <- getTPState
-                 u    <- tpGetNextUnique
-                 liftIO $ getTimeStampIf printStats >>= runSMTWith cfg . go tpSt u
-  where go tpSt u mbStartTime = do qSaturateSavingObservables inputProp
-                                   mapM_ (constrain . getObjProof) by
-                                   query $ smtProofStep cfg tpSt "Lemma" 0 (TPProofOneShot nm by) Nothing inputProp [] (good mbStartTime u)
-
-        -- What to do if all goes well
-        good mbStart u d = do mbElapsed <- getElapsedTime mbStart
-                              liftIO $ finishTP cfg ("Q.E.D." ++ concludeModulo by) d $ catMaybes [mbElapsed]
-                              pure $ Proof $ ProofObj { dependencies = by
-                                                      , isUserAxiom  = False
-                                                      , getObjProof  = label nm (quantifiedBool inputProp)
-                                                      , getProp      = toDyn inputProp
-                                                      , proofName    = nm
-                                                      , uniqId       = u
-                                                      , isCached     = False
-                                                      }
+-- | Propagate the settings for ribbon/timing from top to current. Because in any subsequent configuration
+-- in a lemmaWith, inductWith etc., we just want to change the solver, not the actual settings for TP.
+tpMergeCfg :: SMTConfig -> SMTConfig -> SMTConfig
+tpMergeCfg cur top = cur{verbose = verbose top, tpOptions = tpOptions top}
 
 -- | Prove a given statement, using auxiliaries as helpers. Using the default solver.
 lemma :: Proposition a => String -> a -> [ProofObj] -> TP (Proof a)
 lemma nm f by = do cfg <- getTPConfig
                    lemmaWith cfg nm f by
 
+-- | Prove a lemma, using the given configuration.
+lemmaWith :: Proposition a => SMTConfig -> String -> a -> [ProofObj] -> TP (Proof a)
+lemmaWith cfgIn nm inputProp by = do
+                 cached <- lookupProofCache inputProp
+                 topCfg <- getTPConfig
+                 case cached of
+                   Just prf -> do let cfg = cfgIn `tpMergeCfg` topCfg
+                                  returnCachedProof cfg nm prf
+                   Nothing  -> do let cfg@SMTConfig{tpOptions = TPOptions{printStats}} = cfgIn `tpMergeCfg` topCfg
+                                  tpSt <- getTPState
+                                  u    <- tpGetNextUnique
+                                  result <- liftIO $ getTimeStampIf printStats >>= runSMTWith cfg . go tpSt cfg u
+                                  addToProofCache inputProp (proofOf result)
+                                  pure result
+  where go tpSt cfg u mbStartTime = do st <- symbolicEnv
+                                       -- Skip measure checks in the normal runWithQuery path; we handle them here
+                                       liftIO $ writeIORef (rSkipMeasureChecks st) True
+                                       qSaturateSavingObservables inputProp
+                                       mapM_ (constrain . getObjProof) by
+
+                                       -- Run measure checks for any newly encountered recursive functions
+                                       liftIO $ checkNewMeasures cfg st tpSt
+
+                                       -- Read no-term-check functions from this proof's State (not TPState, which accumulates)
+                                       noTermFns <- liftIO $ readIORef (rNoTermCheckFunctions st)
+
+                                       query $ smtProofStep cfg tpSt "Lemma" 0 (TPProofOneShot nm by) Nothing inputProp [] (good noTermFns cfg mbStartTime u)
+
+        -- What to do if all goes well
+        good noTermFns cfg mbStart u d = do
+                                       mbElapsed <- getElapsedTime mbStart
+                                       let ntcDeps = map noTermCheckProof (Set.toList noTermFns)
+                                           allBy   = by ++ ntcDeps
+                                       liftIO $ finishTP cfg ("Q.E.D." ++ concludeModulo allBy) d $ catMaybes [mbElapsed]
+                                       pure $ Proof $ ProofObj { dependencies = allBy
+                                                               , isUserAxiom  = False
+                                                               , getObjProof  = label nm (quantifiedBool inputProp)
+                                                               , getProp      = toDyn inputProp
+                                                               , proofName    = nm
+                                                               , uniqId       = u
+                                                               , aliases      = []
+                                                               , wasCached    = False
+                                                               }
+
+-- | Prove a given statement, using the induction schema for the proposition. Using the default solver.
+inductiveLemma :: Inductive a => String -> a -> [ProofObj] -> TP (Proof a)
+inductiveLemma nm f by = do cfg <- getTPConfig
+                            inductiveLemmaWith cfg nm f by
+
+-- | Prove a given statement, using the induction schema for the proposition. Using the default solver.
+inductiveLemmaWith :: Inductive a => SMTConfig -> String -> a -> [ProofObj] -> TP (Proof a)
+inductiveLemmaWith cfg nm f by = lemmaWith cfg nm f (inductionSchema f : by)
+
+-- | Check any newly encountered recursive function measures. This reads deferred checks
+-- from 'rMeasureChecks', runs those not yet verified, and records them as verified.
+-- Skips functions in 'measuresBeingVerified' to prevent infinite recursion when a
+-- measureLemma proof uses the function whose measure is currently being checked.
+checkNewMeasures :: SMTConfig -> State -> TPState -> IO ()
+checkNewMeasures cfg@SMTConfig{tpOptions = TPOptions{measuresBeingVerified}} st tpSt = do
+   isDry <- readIORef (dryRun tpSt)
+   unless isDry $ do
+     checks     <- readIORef (rMeasureChecks st)
+     verified   <- readIORef (measuresVerified tpSt)
+     productive <- readIORef (productiveVerified tpSt)
+     let allVerified = verified `Set.union` productive
+         allNames    = Set.fromList (map (\(n, _, _) -> n) checks)
+         new         = [(n, p, c) | (n, p, c) <- checks, n `Set.notMember` allVerified, n `Set.notMember` measuresBeingVerified]
+         skipped     = [n | (n, _, _) <- checks, n `Set.notMember` allVerified, n `Set.member` measuresBeingVerified]
+
+         msg s | not (verbose cfg)
+               = pure ()
+               | Just f <- redirectVerbose cfg
+               = appendFile f (s ++ "\n")
+               | True
+               = putStrLn s
+
+     unless (null new && null skipped) $
+        msg $ "[MEASURE] checkNewMeasures: " ++ show (length new) ++ " to verify"
+              ++ (if null skipped then "" else ", " ++ show (length skipped) ++ " skipped (being verified): " ++ show skipped)
+
+     modifyIORef' (measuresEncountered tpSt) (Set.union allNames)
+     let verify (n, isProductive, c) = do
+           msg $ "[MEASURE] checkNewMeasures: verifying " ++ n
+           () <- c cfg
+           msg $ "[MEASURE] checkNewMeasures: " ++ n ++ " verified"
+           if isProductive
+              then modifyIORef' (productiveVerified tpSt) (Set.insert n)
+              else modifyIORef' (measuresVerified   tpSt) (Set.insert n)
+     mapM_ verify new
+
 -- | Capture the general flow of a proof-step. Note that this is the only point where we call the backend solver
 -- in a TP proof.
 smtProofStep :: (SolverContext m, MonadIO m, MonadQuery m, MonadSymbolic m, Proposition a)
@@ -122,12 +307,18 @@
    -> m r
 smtProofStep cfg@SMTConfig{verbose, tpOptions = TPOptions{printStats}} tpState tag level ctx mbAssumptions prop disps unsat = do
 
-        case mbAssumptions of
-           Nothing  -> do queryDebug ["; smtProofStep: No context value to push."]
-                          check
-           Just asm -> do queryDebug ["; smtProofStep: Pushing in the context: " ++ show asm]
-                          inNewAssertionStack $ do constrain asm
-                                                   check
+        isDry <- liftIO $ readIORef (dryRun tpState)
+        if isDry
+           then do -- Dry run: record width, skip solver, report success
+                   tab <- liftIO $ startTP cfg verbose tag level ctx
+                   liftIO $ modifyIORef' (maxRibbon tpState) (max tab)
+                   liftIO $ unsat (tab, Nothing)
+           else case mbAssumptions of
+                   Nothing  -> do queryDebug ["; smtProofStep: No context value to push."]
+                                  check
+                   Just asm -> do queryDebug ["; smtProofStep: Pushing in the context: " <> showText asm]
+                                  inNewAssertionStack $ do constrain asm
+                                                           check
 
  where check = do
            tab <- liftIO $ startTP cfg verbose tag level ctx
@@ -158,13 +349,13 @@
                   TPProofStep    False s _ ss ->                       intercalate "." (s : ss)
 
        unknown = do r <- getUnknownReason
-                    liftIO $ do putStrLn $ "\n*** Failed to prove " ++ fullNm ++ "."
-                                putStrLn $ "\n*** Solver reported: " ++ show r
+                    liftIO $ do message cfg $ "\n*** Failed to prove " ++ fullNm ++ ".\n"
+                                message cfg $ "\n*** Solver reported: " ++ show r ++ "\n"
                                 die
 
        -- What to do if the proof fails
        cex = do
-         liftIO $ putStrLn $ "\n*** Failed to prove " ++ fullNm ++ "."
+         liftIO $ message cfg $ "\n*** Failed to prove " ++ fullNm ++ ".\n"
 
          res <- case ctx of
                   TPProofStep{} -> do mapM_ (uncurry sObserve) disps
@@ -183,6 +374,6 @@
                                            pure $ skolemize (qNot prop)
                         pure res
 
-         liftIO $ print $ ThmResult res
+         liftIO $ message cfg $ show (ThmResult res) ++ "\n"
 
          die
diff --git a/Data/SBV/TP/List.hs b/Data/SBV/TP/List.hs
deleted file mode 100644
--- a/Data/SBV/TP/List.hs
+++ /dev/null
@@ -1,1948 +0,0 @@
------------------------------------------------------------------------------
--- |
--- Module    : Data.SBV.TP.List
--- Copyright : (c) Levent Erkok
--- License   : BSD3
--- Maintainer: erkokl@gmail.com
--- Stability : experimental
---
--- A variety of TP proofs on list processing functions. Note that
--- these proofs only hold for finite lists. SMT-solvers do not model infinite
--- lists, and hence all claims are for finite (but arbitrary-length) lists.
------------------------------------------------------------------------------
-
-{-# LANGUAGE CPP                 #-}
-{-# LANGUAGE DataKinds           #-}
-{-# LANGUAGE OverloadedLists     #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE QuasiQuotes         #-}
-{-# LANGUAGE TypeAbstractions    #-}
-{-# LANGUAGE TypeApplications    #-}
-
-{-# OPTIONS_GHC -Wall -Werror #-}
-
-module Data.SBV.TP.List (
-     -- * Append
-     appendNull, consApp, appendAssoc, initsLength, tailsLength, tailsAppend
-
-     -- * Reverse
-   , revLen, revApp, revCons, revSnoc, revRev, enumLen, revNM
-
-     -- * Length
-   , lengthTail, lenAppend, lenAppend2
-
-     -- * Replicate
-   , replicateLength
-
-     -- * All and any
-   , allAny
-
-     -- * Map
-   , mapEquiv, mapAppend, mapReverse, mapCompose
-
-     -- * Foldr and foldl
-   , foldrMapFusion, foldrFusion, foldrOverAppend, foldlOverAppend, foldrFoldlDuality, foldrFoldlDualityGeneralized, foldrFoldl
-   , bookKeeping
-
-     -- * Filter
-   , filterAppend, filterConcat, takeDropWhile
-
-     -- * Stutter removal
-   , destutter, destutterIdempotent
-
-     -- * Difference
-   , appendDiff, diffAppend, diffDiff
-
-     -- * Partition
-   , partition1, partition2
-
-    -- * Take and drop
-   , take_take, drop_drop, take_drop, take_cons, take_map, drop_cons, drop_map, length_take, length_drop, take_all, drop_all
-   , take_append, drop_append
-
-   -- * Zip
-   , map_fst_zip
-   , map_snd_zip
-   , map_fst_zip_take
-   , map_snd_zip_take
-
-   -- * Counting elements
-   , count, countAppend, takeDropCount, countNonNeg, countElem, elemCount
-
-   -- * Disjointness
-   , disjoint, disjointDiff
-
-   -- * Interleaving
-   , interleave, uninterleave, interleaveLen, interleaveRoundTrip
- ) where
-
-import Prelude (Integer, Bool, Eq, ($), Num(..), id, (.), flip)
-
-import Data.SBV
-import Data.SBV.List
-import Data.SBV.Tuple
-import Data.SBV.TP
-
-#ifdef DOCTEST
--- $setup
--- >>> :set -XScopedTypeVariables
--- >>> :set -XTypeApplications
--- >>> import Data.SBV
--- >>> import Data.SBV.TP
--- >>> import Control.Exception
-#endif
-
--- | @xs ++ [] == xs@
---
--- >>> runTP $ appendNull @Integer
--- Lemma: appendNull                       Q.E.D.
--- [Proven] appendNull :: Ɐxs ∷ [Integer] → Bool
-appendNull :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> SBool))
-appendNull = lemma "appendNull"
-                   (\(Forall xs) -> xs ++ nil .== xs)
-                   []
-
--- | @(x : xs) ++ ys == x : (xs ++ ys)@
---
--- >>> runTP $ consApp @Integer
--- Lemma: consApp                          Q.E.D.
--- [Proven] consApp :: Ɐx ∷ Integer → Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool
-consApp :: forall a. SymVal a => TP (Proof (Forall "x" a -> Forall "xs" [a] -> Forall "ys" [a] -> SBool))
-consApp = lemma "consApp"
-                (\(Forall x) (Forall xs) (Forall ys) -> (x .: xs) ++ ys .== x .: (xs ++ ys))
-                []
-
--- | @(xs ++ ys) ++ zs == xs ++ (ys ++ zs)@
---
--- >>> runTP $ appendAssoc @Integer
--- Lemma: appendAssoc                      Q.E.D.
--- [Proven] appendAssoc :: Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Ɐzs ∷ [Integer] → Bool
---
--- Surprisingly, z3 can prove this without any induction. (Since SBV's append translates directly to
--- the concatenation of sequences in SMTLib, it must trigger an internal heuristic in z3
--- that proves it right out-of-the-box!)
-appendAssoc :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> Forall "ys" [a] -> Forall "zs" [a] -> SBool))
-appendAssoc =
-   lemma "appendAssoc"
-         (\(Forall xs) (Forall ys) (Forall zs) -> xs ++ (ys ++ zs) .== (xs ++ ys) ++ zs)
-         []
-
--- | @length (inits xs) == 1 + length xs@
---
--- >>> runTP $ initsLength @Integer
--- Inductive lemma (strong): initsLength
---   Step: Measure is non-negative         Q.E.D.
---   Step: 1                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] initsLength :: Ɐxs ∷ [Integer] → Bool
-initsLength :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> SBool))
-initsLength =
-   sInduct "initsLength"
-           (\(Forall xs) -> length (inits xs) .== 1 + length xs)
-           (length @a) $
-           \ih xs -> [] |- length (inits xs)
-                        ?? ih
-                        =: 1 + length xs
-                        =: qed
-
--- | @length (tails xs) == 1 + length xs@
---
--- >>> runTP $ tailsLength @Integer
--- Inductive lemma: tailsLength
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] tailsLength :: Ɐxs ∷ [Integer] → Bool
-tailsLength :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> SBool))
-tailsLength =
-   induct "tailsLength"
-          (\(Forall xs) -> length (tails xs) .== 1 + length xs) $
-          \ih (x, xs) -> [] |- length (tails (x .: xs))
-                            =: length (tails xs ++ [x .: xs])
-                            =: length (tails xs) + 1
-                            ?? ih
-                            =: 1 + length xs + 1
-                            =: 1 + length (x .: xs)
-                            =: qed
-
--- | @tails (xs ++ ys) == map (++ ys) (tails xs) ++ tail (tails ys)@
---
--- This property comes from Richard Bird's "Pearls of functional Algorithm Design" book, chapter 2.
--- Note that it is not exactly as stated there, as the definition of @tail@ Bird uses is different
--- than the standard Haskell function @tails@: Bird's version does not return the empty list as the
--- tail. So, we slightly modify it to fit the standard definition. (NB. z3 is finicky on this
--- problem, while cvc5 works much better.)
---
--- >>> runTPWith cvc5 $ tailsAppend @Integer
--- Inductive lemma: base case
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: helper
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Result:                               Q.E.D.
--- Inductive lemma: tailsAppend
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] tailsAppend :: Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool
-tailsAppend :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> Forall "ys" [a] -> SBool))
-tailsAppend = do
-
-   let -- Ideally, we would like to define appendEach like this:
-       --
-       --       appendEach xs ys = map (++ ys) xs
-       --
-       -- But capture of ys is not allowed when we use the higher-order
-       -- function map in SBV. So, we create a closure instead.
-       appendEach :: SList a -> SList [a] -> SList [a]
-       appendEach ys = map $ Closure { closureEnv = ys
-                                     , closureFun = \env xs -> xs ++ env
-                                     }
-
-   -- Even proving the base case of induction is hard due to recursive definition. So we first prove the base case by induction.
-   bc <- induct "base case"
-                (\(Forall @"ys" (ys :: SList a)) -> tails ys .== [ys] ++ tail (tails ys)) $
-                \ih (y, ys) -> [] |- tails (y .: ys)
-                                  =: [y .: ys] ++ tails ys
-                                  ?? ih
-                                  =: [y .: ys] ++ [ys] ++ tail (tails ys)
-                                  =: [y .: ys] ++ tail (tails (y .: ys))
-                                  =: qed
-
-   -- Also need a helper to relate how appendEach and tails work together
-   helper <- calc "helper"
-                   (\(Forall @"xs" xs) (Forall @"ys" ys) (Forall @"x" x) ->
-                        appendEach ys (tails (x .: xs)) .== [(x .: xs) ++ ys] ++ appendEach ys (tails xs)) $
-                   \xs ys x -> [] |- appendEach ys (tails (x .: xs))
-                                  =: appendEach ys ([x .: xs] ++ tails xs)
-                                  =: [(x .: xs) ++ ys] ++ appendEach ys (tails xs)
-                                  =: qed
-
-   induct "tailsAppend"
-          (\(Forall xs) (Forall ys) -> tails (xs ++ ys) .== appendEach ys (tails xs) ++ tail (tails ys)) $
-          \ih (x, xs) ys -> [assumptionFromProof bc]
-                         |- tails ((x .: xs) ++ ys)
-                         =: tails (x .: (xs ++ ys))
-                         =: [x .: (xs ++ ys)] ++ tails (xs ++ ys)
-                         ?? ih
-                         =: [(x .: xs) ++ ys] ++ appendEach ys (tails xs) ++ tail (tails ys)
-                         ?? helper
-                         =: appendEach ys (tails (x .: xs)) ++ tail (tails ys)
-                         =: qed
-
--- | @length xs == length (reverse xs)@
---
--- >>> runTP $ revLen @Integer
--- Inductive lemma: revLen
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] revLen :: Ɐxs ∷ [Integer] → Bool
-revLen :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> SBool))
-revLen = induct "revLen"
-                (\(Forall xs) -> length (reverse xs) .== length xs) $
-                \ih (x, xs) -> [] |- length (reverse (x .: xs))
-                                  =: length (reverse xs ++ [x])
-                                  =: length (reverse xs) + length [x]
-                                  ?? ih
-                                  =: length xs + 1
-                                  =: length (x .: xs)
-                                  =: qed
-
--- | @reverse (xs ++ ys) .== reverse ys ++ reverse xs@
---
--- >>> runTP $ revApp @Integer
--- Inductive lemma: revApp
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] revApp :: Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool
-revApp :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> Forall "ys" [a] -> SBool))
-revApp = induct "revApp"
-                 (\(Forall xs) (Forall ys) -> reverse (xs ++ ys) .== reverse ys ++ reverse xs) $
-                 \ih (x, xs) ys -> [] |- reverse ((x .: xs) ++ ys)
-                                      =: reverse (x .: (xs ++ ys))
-                                      =: reverse (xs ++ ys) ++ [x]
-                                      ?? ih
-                                      =: (reverse ys ++ reverse xs) ++ [x]
-                                      =: reverse ys ++ (reverse xs ++ [x])
-                                      =: reverse ys ++ reverse (x .: xs)
-                                      =: qed
-
--- | @reverse (x:xs) == reverse xs ++ [x]@
---
--- >>> runTP $ revCons @Integer
--- Lemma: revCons                          Q.E.D.
--- [Proven] revCons :: Ɐx ∷ Integer → Ɐxs ∷ [Integer] → Bool
-revCons :: forall a. SymVal a => TP (Proof (Forall "x" a -> Forall "xs" [a] -> SBool))
-revCons = lemma "revCons"
-                (\(Forall x) (Forall xs) -> reverse (x .: xs) .== reverse xs ++ [x])
-                []
-
--- | @reverse (xs ++ [x]) == x : reverse xs@
---
--- >>> runTP $ revSnoc @Integer
--- Inductive lemma: revApp
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: revSnoc                          Q.E.D.
--- [Proven] revSnoc :: Ɐx ∷ Integer → Ɐxs ∷ [Integer] → Bool
-revSnoc :: forall a. SymVal a => TP (Proof (Forall "x" a -> Forall "xs" [a] -> SBool))
-revSnoc = do
-   ra <- revApp @a
-
-   lemma "revSnoc"
-         (\(Forall x) (Forall xs) -> reverse (xs ++ [x]) .== x .: reverse xs)
-         [proofOf ra]
-
--- | @reverse (reverse xs) == xs@
---
--- >>> runTP $ revRev @Integer
--- Inductive lemma: revApp
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Result:                               Q.E.D.
--- Inductive lemma: revRev
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] revRev :: Ɐxs ∷ [Integer] → Bool
-revRev :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> SBool))
-revRev = do
-
-   ra <- revApp @a
-
-   induct "revRev"
-          (\(Forall xs) -> reverse (reverse xs) .== xs) $
-          \ih (x, xs) -> [] |- reverse (reverse (x .: xs))
-                            =: reverse (reverse xs ++ [x])
-                            ?? ra
-                            =: reverse [x] ++ reverse (reverse xs)
-                            ?? ih
-                            =: [x] ++ xs
-                            =: x .: xs
-                            =: qed
-
--- | \(\text{length } [n \dots m] = \max(0,\; m - n + 1)\)
---
--- The proof uses the metric @|m-n|@.
---
--- >>> runTP enumLen
--- Inductive lemma (strong): enumLen
---   Step: Measure is non-negative         Q.E.D.
---   Step: 1 (2 way case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.2.3                         Q.E.D.
---     Step: 1.2.4                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] enumLen :: Ɐn ∷ Integer → Ɐm ∷ Integer → Bool
-enumLen :: TP (Proof (Forall "n" Integer -> Forall "m" Integer -> SBool))
-enumLen =
-  sInduct "enumLen"
-          (\(Forall n) (Forall m) -> length [sEnum|n .. m|] .== 0 `smax` (m - n + 1))
-          (\n m -> abs (m - n)) $
-          \ih n m -> [] |- length [sEnum|n+1 .. m|]
-                        =: cases [ n+1 .>  m ==> trivial
-                                 , n+1 .<= m ==> length (n+1 .: [sEnum|n+2 .. m|])
-                                              =: 1 + length [sEnum|n+2 .. m|]
-                                              ?? ih
-                                              =: 1 + (0 `smax` (m - (n+2) + 1))
-                                              =: 0 `smax` (m - (n+1) + 1)
-                                              =: qed
-                                 ]
-
--- | @reverse [n .. m] == [m, m-1 .. n]@
---
--- The proof uses the metric @|m-n|@.
---
--- >>> runTP $ revNM
--- Inductive lemma (strong): helper
---   Step: Measure is non-negative         Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
--- Inductive lemma (strong): revNM
---   Step: Measure is non-negative         Q.E.D.
---   Step: 1 (2 way case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.2.3                         Q.E.D.
---     Step: 1.2.4                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] revNM :: Ɐn ∷ Integer → Ɐm ∷ Integer → Bool
-revNM :: TP (Proof (Forall "n" Integer -> Forall "m" Integer -> SBool))
-revNM = do
-
-  helper <- sInduct "helper"
-                    (\(Forall @"m" (m :: SInteger)) (Forall @"n" n) ->
-                          n .< m .=> [sEnum|m, m-1 .. n+1|] ++ [n] .== [sEnum|m, m-1 .. n|])
-                    (\m n -> abs (m - n)) $
-                    \ih m n -> [n .< m] |- [sEnum|m, m-1 .. n+1|] ++ [n]
-                                        =: m .: [sEnum|m-1, m-2 .. n+1|] ++ [n]
-                                        ?? ih
-                                        =: m .: [sEnum|m-1, m-2 .. n|]
-                                        =: [sEnum|m, m-1 .. n|]
-                                        =: qed
-
-  sInduct "revNM"
-          (\(Forall n) (Forall m) -> reverse [sEnum|n .. m|] .== [sEnum|m, m-1 .. n|])
-          (\n m -> abs (m - n)) $
-          \ih n m -> [] |- reverse [sEnum|n .. m|]
-                        =: cases [ n .>  m ==> trivial
-                                 , n .<= m ==> reverse (n .: [sEnum|(n+1) .. m|])
-                                            =: reverse [sEnum|(n+1) .. m|] ++ [n]
-                                            ?? ih
-                                            =: [sEnum|m, m-1 .. n+1|] ++ [n]
-                                            ?? helper
-                                            =: [sEnum|m, m-1 .. n|]
-                                            =: qed
-                                 ]
-
--- | @length (x : xs) == 1 + length xs@
---
--- >>> runTP $ lengthTail @Integer
--- Lemma: lengthTail                       Q.E.D.
--- [Proven] lengthTail :: Ɐx ∷ Integer → Ɐxs ∷ [Integer] → Bool
-lengthTail :: forall a. SymVal a => TP (Proof (Forall "x" a -> Forall "xs" [a] -> SBool))
-lengthTail = lemma "lengthTail"
-                   (\(Forall x) (Forall xs) -> length (x .: xs) .== 1 + length xs)
-                   []
-
--- | @length (xs ++ ys) == length xs + length ys@
---
--- >>> runTP $ lenAppend @Integer
--- Lemma: lenAppend                        Q.E.D.
--- [Proven] lenAppend :: Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool
-lenAppend :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> Forall "ys" [a] -> SBool))
-lenAppend = lemma "lenAppend"
-                  (\(Forall xs) (Forall ys) -> length (xs ++ ys) .== length xs + length ys)
-                  []
-
--- | @length xs == length ys -> length (xs ++ ys) == 2 * length xs@
---
--- >>> runTP $ lenAppend2 @Integer
--- Lemma: lenAppend2                       Q.E.D.
--- [Proven] lenAppend2 :: Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool
-lenAppend2 :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> Forall "ys" [a] -> SBool))
-lenAppend2 = lemma "lenAppend2"
-                   (\(Forall xs) (Forall ys) -> length xs .== length ys .=> length (xs ++ ys) .== 2 * length xs)
-                   []
-
--- | @length (replicate k x) == max (0, k)@
---
--- >>> runTP $ replicateLength @Integer
--- Inductive lemma: replicateLength
---   Step: Base                            Q.E.D.
---   Step: 1 (2 way case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.2.3                         Q.E.D.
---     Step: 1.2.4                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] replicateLength :: Ɐk ∷ Integer → Ɐx ∷ Integer → Bool
-replicateLength :: forall a. SymVal a => TP (Proof (Forall "k" Integer -> Forall "x" a -> SBool))
-replicateLength = induct "replicateLength"
-                         (\(Forall k) (Forall x) -> length (replicate k x) .== 0 `smax` k) $
-                         \ih k x -> [] |- length (replicate (k+1) x)
-                                       =: cases [ k .< 0  ==> trivial
-                                                , k .>= 0 ==> length (x .: replicate k x)
-                                                           =: 1 + length (replicate k x)
-                                                           ?? ih
-                                                           =: 1 + 0 `smax` k
-                                                           =: 0 `smax` (k+1)
-                                                           =: qed
-                                                ]
-
--- | @not (all id xs) == any not xs@
---
--- A list of booleans is not all true, if any of them is false.
---
--- >>> runTP allAny
--- Inductive lemma: allAny
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] allAny :: Ɐxs ∷ [Bool] → Bool
-allAny :: TP (Proof (Forall "xs" [Bool] -> SBool))
-allAny = induct "allAny"
-                (\(Forall xs) -> sNot (all id xs) .== any sNot xs) $
-                \ih (x, xs) -> [] |- sNot (all id (x .: xs))
-                                  =: sNot (x .&& all id xs)
-                                  =: (sNot x .|| sNot (all id xs))
-                                  ?? ih
-                                  =: sNot x .|| any sNot xs
-                                  =: any sNot (x .: xs)
-                                  =: qed
-
--- | @f == g ==> map f xs == map g xs@
---
--- >>> runTP $ mapEquiv @Integer @Integer (uninterpret "f") (uninterpret "g")
--- Inductive lemma: mapEquiv
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] mapEquiv :: Ɐxs ∷ [Integer] → Bool
-mapEquiv :: forall a b. (SymVal a, SymVal b) => (SBV a -> SBV b) -> (SBV a -> SBV b) -> TP (Proof (Forall "xs" [a] -> SBool))
-mapEquiv f g = do
-   let f'eq'g :: SBool
-       f'eq'g = quantifiedBool $ \(Forall x) -> f x .== g x
-
-   induct "mapEquiv"
-          (\(Forall xs) -> f'eq'g .=> map f xs .== map g xs) $
-          \ih (x, xs) -> [f'eq'g] |- map f (x .: xs) .== map g (x .: xs)
-                                  =: f x .: map f xs .== g x .: map g xs
-                                  =: f x .: map f xs .== f x .: map g xs
-                                  ?? ih
-                                  =: f x .: map f xs .== f x .: map f xs
-                                  =: map f (x .: xs) .== map f (x .: xs)
-                                  =: qed
-
--- | @map f (xs ++ ys) == map f xs ++ map f ys@
---
--- >>> runTP $ mapAppend @Integer @Integer (uninterpret "f")
--- Inductive lemma: mapAppend
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] mapAppend :: Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool
-mapAppend :: forall a b. (SymVal a, SymVal b) => (SBV a -> SBV b) -> TP (Proof (Forall "xs" [a] -> Forall "ys" [a] -> SBool))
-mapAppend f =
-   induct "mapAppend"
-          (\(Forall xs) (Forall ys) -> map f (xs ++ ys) .== map f xs ++ map f ys) $
-          \ih (x, xs) ys -> [] |- map f ((x .: xs) ++ ys)
-                               =: map f (x .: (xs ++ ys))
-                             =: f x .: map f (xs ++ ys)
-                             ?? ih
-                             =: f x .: (map f xs  ++ map f ys)
-                             =: (f x .: map f xs) ++ map f ys
-                             =: map f (x .: xs) ++ map f ys
-                             =: qed
-
--- | @map f . reverse == reverse . map f@
---
--- >>> runTP $ mapReverse @Integer @String (uninterpret "f")
--- Inductive lemma: mapAppend
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Result:                               Q.E.D.
--- Inductive lemma: mapReverse
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Step: 6                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] mapReverse :: Ɐxs ∷ [Integer] → Bool
-mapReverse :: forall a b. (SymVal a, SymVal b) => (SBV a -> SBV b) -> TP (Proof (Forall "xs" [a] -> SBool))
-mapReverse f = do
-     mApp <- mapAppend f
-
-     induct "mapReverse"
-            (\(Forall xs) -> reverse (map f xs) .== map f (reverse xs)) $
-            \ih (x, xs) -> [] |- reverse (map f (x .: xs))
-                              =: reverse (f x .: map f xs)
-                              =: reverse (map f xs) ++ [f x]
-                              ?? ih
-                              =: map f (reverse xs) ++ [f x]
-                              =: map f (reverse xs) ++ map f [x]
-                              ?? mApp
-                              =: map f (reverse xs ++ [x])
-                              =: map f (reverse (x .: xs))
-                              =: qed
-
--- | @map f . map g == map (f . g)@
---
--- >>> runTP $ mapCompose @Integer @Bool @String (uninterpret "f") (uninterpret "g")
--- Inductive lemma: mapCompose
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] mapCompose :: Ɐxs ∷ [Integer] → Bool
-mapCompose :: forall a b c. (SymVal a, SymVal b, SymVal c) => (SBV a -> SBV b) -> (SBV b -> SBV c) -> TP (Proof (Forall "xs" [a] -> SBool))
-mapCompose f g =
-  induct "mapCompose"
-         (\(Forall xs) -> map g (map f xs) .== map (g . f) xs) $
-         \ih (x, xs) -> [] |- map g (map f (x .: xs))
-                           =: map g (f x .: map f xs)
-                           =: g (f x) .: map g (map f xs)
-                           ?? ih
-                           =: g (f x) .: map (g . f) xs
-                           =: (g . f) x .: map (g . f) xs
-                           =: map (g . f) (x .: xs)
-                           =: qed
-
--- | @foldr f a . map g == foldr (f . g) a@
---
--- >>> runTP $ foldrMapFusion @String @Bool @Integer (uninterpret "a") (uninterpret "b") (uninterpret "c")
--- Inductive lemma: foldrMapFusion
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] foldrMapFusion :: Ɐxs ∷ [[Char]] → Bool
-foldrMapFusion :: forall a b c. (SymVal a, SymVal b, SymVal c) => SBV c -> (SBV a -> SBV b) -> (SBV b -> SBV c -> SBV c) -> TP (Proof (Forall "xs" [a] -> SBool))
-foldrMapFusion a g f =
-  induct "foldrMapFusion"
-         (\(Forall xs) -> foldr f a (map g xs) .== foldr (f . g) a xs) $
-         \ih (x, xs) -> [] |- foldr f a (map g (x .: xs))
-                           =: foldr f a (g x .: map g xs)
-                           =: g x `f` foldr f a (map g xs)
-                           ?? ih
-                           =: g x `f` foldr (f . g) a xs
-                           =: foldr (f . g) a (x .: xs)
-                           =: qed
-
--- |
---
--- @
---   f . foldr g a == foldr h b
---   provided, f a = b and for all x and y, f (g x y) == h x (f y).
--- @
---
--- >>> runTP $ foldrFusion @String @Bool @Integer (uninterpret "a") (uninterpret "b") (uninterpret "f") (uninterpret "g") (uninterpret "h")
--- Inductive lemma: foldrFusion
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] foldrFusion :: Ɐxs ∷ [[Char]] → Bool
-foldrFusion :: forall a b c. (SymVal a, SymVal b, SymVal c) => SBV c -> SBV b -> (SBV c -> SBV b) -> (SBV a -> SBV c -> SBV c) -> (SBV a -> SBV b -> SBV b) -> TP (Proof (Forall "xs" [a] -> SBool))
-foldrFusion a b f g h = do
-   let -- Assumptions under which the equality holds
-       h1 = f a .== b
-       h2 = quantifiedBool $ \(Forall x) (Forall y) -> f (g x y) .== h x (f y)
-
-   induct "foldrFusion"
-          (\(Forall xs) -> h1 .&& h2 .=> f (foldr g a xs) .== foldr h b xs) $
-          \ih (x, xs) -> [h1, h2] |- f (foldr g a (x .: xs))
-                                  =: f (g x (foldr g a xs))
-                                  =: h x (f (foldr g a xs))
-                                  ?? ih
-                                  =: h x (foldr h b xs)
-                                  =: foldr h b (x .: xs)
-                                  =: qed
-
--- | @foldr f a (xs ++ ys) == foldr f (foldr f a ys) xs@
---
--- >>> runTP $ foldrOverAppend @Integer (uninterpret "a") (uninterpret "f")
--- Inductive lemma: foldrOverAppend
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] foldrOverAppend :: Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool
-foldrOverAppend :: forall a. SymVal a => SBV a -> (SBV a -> SBV a -> SBV a) -> TP (Proof (Forall "xs" [a] -> Forall "ys" [a] -> SBool))
-foldrOverAppend a f =
-   induct "foldrOverAppend"
-          (\(Forall xs) (Forall ys) -> foldr f a (xs ++ ys) .== foldr f (foldr f a ys) xs) $
-          \ih (x, xs) ys -> [] |- foldr f a ((x .: xs) ++ ys)
-                               =: foldr f a (x .: (xs ++ ys))
-                               =: x `f` foldr f a (xs ++ ys)
-                               ?? ih
-                               =: x `f` foldr f (foldr f a ys) xs
-                               =: foldr f (foldr f a ys) (x .: xs)
-                               =: qed
-
--- | @foldl f e (xs ++ ys) == foldl f (foldl f e xs) ys@
---
--- >>> runTP $ foldlOverAppend @Integer @Bool (uninterpret "f")
--- Inductive lemma: foldlOverAppend
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] foldlOverAppend :: Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Ɐe ∷ Bool → Bool
-foldlOverAppend :: forall a b. (SymVal a, SymVal b) => (SBV b -> SBV a -> SBV b) -> TP (Proof (Forall "xs" [a] -> Forall "ys" [a] -> Forall "e" b -> SBool))
-foldlOverAppend f =
-   induct "foldlOverAppend"
-          (\(Forall xs) (Forall ys) (Forall a) -> foldl f a (xs ++ ys) .== foldl f (foldl f a xs) ys) $
-          \ih (x, xs) ys a -> [] |- foldl f a ((x .: xs) ++ ys)
-                                 =: foldl f a (x .: (xs ++ ys))
-                                 =: foldl f (a `f` x) (xs ++ ys)
-                                 -- z3 is smart enough to instantiate the IH correctly below, but we're
-                                 -- using an explicit instantiation to be clear about the use of @a@ at a different value
-                                 ?? ih `at` (Inst @"ys" ys, Inst @"e" (a `f` x))
-                                 =: foldl f (foldl f (a `f` x) xs) ys
-                                 =: qed
-
--- | @foldr f e xs == foldl (flip f) e (reverse xs)@
---
--- >>> runTP $ foldrFoldlDuality @Integer @String (uninterpret "f")
--- Inductive lemma: foldlOverAppend
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
--- Inductive lemma: foldrFoldlDuality
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Step: 6                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] foldrFoldlDuality :: Ɐxs ∷ [Integer] → Ɐe ∷ [Char] → Bool
-foldrFoldlDuality :: forall a b. (SymVal a, SymVal b) => (SBV a -> SBV b -> SBV b) -> TP (Proof (Forall "xs" [a] -> Forall "e" b -> SBool))
-foldrFoldlDuality f = do
-   foa <- foldlOverAppend (flip f)
-
-   induct "foldrFoldlDuality"
-          (\(Forall xs) (Forall e) -> foldr f e xs .== foldl (flip f) e (reverse xs)) $
-          \ih (x, xs) e -> [] |- let ff  = flip f
-                                     rxs = reverse xs
-                                 in foldr f e (x .: xs)
-                                 =: x `f` foldr f e xs
-                                 ?? ih
-                                 =: x `f` foldl ff e rxs
-                                 =: foldl ff e rxs `ff` x
-                                 =: foldl ff (foldl ff e rxs) [x]
-                                 ?? foa
-                                 =: foldl ff e (rxs ++ [x])
-                                 =: foldl ff e (reverse (x .: xs))
-                                 =: qed
-
--- | Given:
---
--- @
---     x \@ (y \@ z) = (x \@ y) \@ z     (associativity of @)
--- and e \@ x = x                     (left unit)
--- and x \@ e = x                     (right unit)
--- @
---
--- Proves:
---
--- @
---     foldr (\@) e xs == foldl (\@) e xs
--- @
---
--- >>> runTP $ foldrFoldlDualityGeneralized @Integer (uninterpret "e") (uninterpret "|@|")
--- Inductive lemma: helper
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Result:                               Q.E.D.
--- Inductive lemma: foldrFoldlDuality
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Step: 6                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] foldrFoldlDuality :: Ɐxs ∷ [Integer] → Bool
-foldrFoldlDualityGeneralized :: forall a. SymVal a => SBV a -> (SBV a -> SBV a -> SBV a) -> TP (Proof (Forall "xs" [a] -> SBool))
-foldrFoldlDualityGeneralized e (@) = do
-   -- Assumptions under which the equality holds
-   let assoc = quantifiedBool $ \(Forall x) (Forall y) (Forall z) -> x @ (y @ z) .== (x @ y) @ z
-       lunit = quantifiedBool $ \(Forall x) -> e @ x .== x
-       runit = quantifiedBool $ \(Forall x) -> x @ e .== x
-
-   -- Helper: foldl (@) (y @ z) xs = y @ foldl (@) z xs
-   -- Note the instantiation of the IH at a different value for z. It turns out
-   -- we don't have to actually specify this since z3 can figure it out by itself, but we're being explicit.
-   helper <- induct "helper"
-                    (\(Forall @"xs" xs) (Forall @"y" y) (Forall @"z" z) -> assoc .=> foldl (@) (y @ z) xs .== y @ foldl (@) z xs) $
-                    \ih (x, xs) y z -> [assoc] |- foldl (@) (y @ z) (x .: xs)
-                                               =: foldl (@) ((y @ z) @ x) xs
-                                               ?? assoc
-                                               =: foldl (@) (y @ (z @ x)) xs
-                                               ?? ih `at` (Inst @"y" y, Inst @"z" (z @ x))
-                                               =: y @ foldl (@) (z @ x) xs
-                                               =: y @ foldl (@) z (x .: xs)
-                                               =: qed
-
-   induct "foldrFoldlDuality"
-          (\(Forall xs) -> assoc .&& lunit .&& runit .=> foldr (@) e xs .== foldl (@) e xs) $
-          \ih (x, xs) -> [assoc, lunit, runit] |- foldr (@) e (x .: xs)
-                                               =: x @ foldr (@) e xs
-                                               ?? ih
-                                               =: x @ foldl (@) e xs
-                                               ?? helper
-                                               =: foldl (@) (x @ e) xs
-                                               ?? runit
-                                               =: foldl (@) x xs
-                                               ?? lunit
-                                               =: foldl (@) (e @ x) xs
-                                               =: foldl (@) e (x .: xs)
-                                               =: qed
-
--- | Given:
---
--- @
---        (x \<+> y) \<*> z = x \<+> (y \<*> z)
---   and  x \<+> e = e \<*> x
--- @
---
--- Proves:
---
--- @
---    foldr (\<+>) e xs = foldl (\<*>) e xs
--- @
---
--- In Bird's Introduction to Functional Programming book (2nd edition) this is called the second duality theorem:
---
--- >>> runTP $ foldrFoldl @Integer @String (uninterpret "<+>") (uninterpret "<*>") (uninterpret "e")
--- Inductive lemma: foldl over <*>/<+>
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Result:                               Q.E.D.
--- Inductive lemma: foldrFoldl
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] foldrFoldl :: Ɐxs ∷ [Integer] → Bool
-foldrFoldl :: forall a b. (SymVal a, SymVal b) => (SBV a -> SBV b -> SBV b) -> (SBV b -> SBV a -> SBV b) -> SBV b -> TP (Proof (Forall "xs" [a] -> SBool))
-foldrFoldl (<+>) (<*>) e = do
-   -- Assumptions about the operators
-   let -- (x <+> y) <*> z == x <+> (y <*> z)
-       assoc = quantifiedBool $ \(Forall x) (Forall y) (Forall z) -> (x <+> y) <*> z .== x <+> (y <*> z)
-
-       -- x <+> e == e <*> x
-       unit  = quantifiedBool $ \(Forall x) -> x <+> e .== e <*> x
-
-   -- Helper: x <+> foldl (<*>) y xs == foldl (<*>) (x <+> y) xs
-   helper <-
-      induct "foldl over <*>/<+>"
-             (\(Forall @"xs" xs) (Forall @"x" x) (Forall @"y" y) -> assoc .=> x <+> foldl (<*>) y xs .== foldl (<*>) (x <+> y) xs) $
-
-             -- Using z to avoid confusion with the variable x already present, following Bird.
-             -- z3 can figure out the proper instantiation of ih so the at call is unnecessary, but being explicit is helpful.
-             \ih (z, xs) x y -> [assoc] |- x <+> foldl (<*>) y (z .: xs)
-                                        =: x <+> foldl (<*>) (y <*> z) xs
-                                        ?? ih `at` (Inst @"x" x, Inst @"y" (y <*> z))
-                                        =: foldl (<*>) (x <+> (y <*> z)) xs
-                                        ?? assoc
-                                        =: foldl (<*>) ((x <+> y) <*> z) xs
-                                        =: foldl (<*>) (x <+> y) (z .: xs)
-                                        =: qed
-
-   -- Final proof:
-   induct "foldrFoldl"
-          (\(Forall xs) -> assoc .&& unit .=> foldr (<+>) e xs .== foldl (<*>) e xs) $
-          \ih (x, xs) -> [assoc, unit] |- foldr (<+>) e (x .: xs)
-                                       =: x <+> foldr (<+>) e xs
-                                       ?? ih
-                                       =: x <+> foldl (<*>) e xs
-                                       ?? helper
-                                       =: foldl (<*>) (x <+> e) xs
-                                       =: foldl (<*>) (e <*> x) xs
-                                       =: foldl (<*>) e (x .: xs)
-                                       =: qed
-
--- | Provided @f@ is associative and @a@ is its both left and right-unit:
---
--- @foldr f a . concat == foldr f a . map (foldr f a)@
---
--- >>> runTP $ bookKeeping @Integer (uninterpret "a") (uninterpret "f")
--- Inductive lemma: foldBase
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Result:                               Q.E.D.
--- Inductive lemma: foldrOverAppend
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Result:                               Q.E.D.
--- Inductive lemma: bookKeeping
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Step: 6                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] bookKeeping :: Ɐxss ∷ [[Integer]] → Bool
---
--- NB. This theorem does not hold if @f@ does not have a left-unit! Consider the input @[[], [x]]@. Left hand side reduces to
--- @x@, while the right hand side reduces to: @f a x@. And unless @f@ is commutative or @a@ is not also a left-unit,
--- then one can find a counter-example. (Aside: if both left and right units exist for a binary operator, then they
--- are necessarily the same element, since @l = f l r = r@. So, an equivalent statement could simply say @f@ has
--- both left and right units.) A concrete counter-example is:
---
--- @
---   data T = A | B | C
---
---   f :: T -> T -> T
---   f C A = A
---   f C B = A
---   f x _ = x
--- @
---
--- You can verify @f@ is associative. Also note that @C@ is the right-unit for @f@, but it isn't the left-unit.
--- In fact, @f@ has no-left unit by the above argument. In this case, the bookkeeping law produces @B@ for
--- the left-hand-side, and @A@ for the right-hand-side for the input @[[], [B]]@.
-bookKeeping :: forall a. SymVal a => SBV a -> (SBV a -> SBV a -> SBV a) -> TP (Proof (Forall "xss" [[a]] -> SBool))
-bookKeeping a f = do
-
-   -- Assumptions about f
-   let assoc = quantifiedBool $ \(Forall x) (Forall y) (Forall z) -> x `f` (y `f` z) .== (x `f` y) `f` z
-       rUnit = quantifiedBool $ \(Forall x) -> x `f` a .== x
-       lUnit = quantifiedBool $ \(Forall x) -> a `f` x .== x
-
-   -- Helper: @foldr f y xs = foldr f a xs `f` y@
-   helper <- induct "foldBase"
-                    (\(Forall xs) (Forall y) -> lUnit .&& assoc .=> foldr f y xs .== foldr f a xs `f` y) $
-                    \ih (x, xs) y -> [lUnit, assoc] |- foldr f y (x .: xs)
-                                                    =: x `f` foldr f y xs
-                                                    ?? ih
-                                                    =: x `f` (foldr f a xs `f` y)
-                                                    =: (x `f` foldr f a xs) `f` y
-                                                    =: foldr f a (x .: xs) `f` y
-                                                    =: qed
-
-   foa <- foldrOverAppend a f
-
-   induct "bookKeeping"
-          (\(Forall xss) -> assoc .&& rUnit .&& lUnit .=> foldr f a (concat xss) .== foldr f a (map (foldr f a) xss)) $
-          \ih (xs, xss) -> [assoc, rUnit, lUnit] |- foldr f a (concat (xs .: xss))
-                                                 =: foldr f a (xs ++ concat xss)
-                                                 ?? foa
-                                                 =: foldr f (foldr f a (concat xss)) xs
-                                                 ?? ih
-                                                 =: foldr f (foldr f a (map (foldr f a) xss)) xs
-                                                 ?? helper `at` (Inst @"xs" xs, Inst @"y" (foldr f a (map (foldr f a) xss)))
-                                                 =: foldr f a xs `f` foldr f a (map (foldr f a) xss)
-                                                 =: foldr f a (foldr f a xs .: map (foldr f a) xss)
-                                                 =: foldr f a (map (foldr f a) (xs .: xss))
-                                                 =: qed
-
--- | @filter p (xs ++ ys) == filter p xs ++ filter p ys@
---
--- >>> runTP $ filterAppend @Integer (uninterpret "p")
--- Inductive lemma: filterAppend
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] filterAppend :: Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool
-filterAppend :: forall a. SymVal a => (SBV a -> SBool) -> TP (Proof (Forall "xs" [a] -> Forall "ys" [a] -> SBool))
-filterAppend p =
-   induct "filterAppend"
-          (\(Forall xs) (Forall ys) -> filter p xs ++ filter p ys .== filter p (xs ++ ys)) $
-          \ih (x, xs) ys -> [] |- filter p (x .: xs) ++ filter p ys
-                               =: ite (p x) (x .: filter p xs) (filter p xs) ++ filter p ys
-                               =: ite (p x) (x .: filter p xs ++ filter p ys) (filter p xs ++ filter p ys)
-                               ?? ih
-                               =: ite (p x) (x .: filter p (xs ++ ys)) (filter p (xs ++ ys))
-                               =: filter p (x .: (xs ++ ys))
-                               =: filter p ((x .: xs) ++ ys)
-                               =: qed
-
--- | @filter p (concat xss) == concatMap (filter p xss)@
---
--- >>> runTP $ filterConcat @Integer (uninterpret "f")
--- Inductive lemma: filterAppend
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Result:                               Q.E.D.
--- Inductive lemma: filterConcat
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] filterConcat :: Ɐxss ∷ [[Integer]] → Bool
-filterConcat :: forall a. SymVal a => (SBV a -> SBool) -> TP (Proof (Forall "xss" [[a]] -> SBool))
-filterConcat p = do
-  fa <- filterAppend p
-
-  inductWith cvc5 "filterConcat"
-         (\(Forall xss) -> filter p (concat xss) .== concatMap (filter p) xss) $
-         \ih (xs, xss) -> [] |- filter p (concat (xs .: xss))
-                             =: filter p (xs ++ concat xss)
-                             ?? fa
-                             =: filter p xs ++ filter p (concat xss)
-                             ?? ih
-                             =: concatMap (filter p) (xs .: xss)
-                             =: qed
-
--- | @takeWhile f xs ++ dropWhile f xs == xs@
---
--- >>> runTP $ takeDropWhile @Integer (uninterpret "f")
--- Inductive lemma: takeDropWhile
---   Step: Base                            Q.E.D.
---   Step: 1 (2 way case split)
---     Step: 1.1.1                         Q.E.D.
---     Step: 1.1.2                         Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] takeDropWhile :: Ɐxs ∷ [Integer] → Bool
-takeDropWhile :: forall a. SymVal a => (SBV a -> SBool) -> TP (Proof (Forall "xs" [a] -> SBool))
-takeDropWhile f =
-   induct "takeDropWhile"
-          (\(Forall xs) -> takeWhile f xs ++ dropWhile f xs .== xs) $
-          \ih (x, xs) -> [] |- takeWhile f (x .: xs) ++ dropWhile f (x .: xs)
-                            =: cases [ f x        ==> x .: takeWhile f xs ++ dropWhile f xs
-                                                   ?? ih
-                                                   =: x .: xs
-                                                   =: qed
-                                     , sNot (f x) ==> [] ++ x .: xs
-                                                   =: x .: xs
-                                                   =: qed
-                                     ]
--- | Remove adjacent duplicates.
-destutter :: SymVal a => SList a -> SList a
-destutter = smtFunction "destutter" $ \xs -> ite (null xs .|| null (tail xs))
-                                                 xs
-                                                 (let (a, as) = uncons xs
-                                                      r       = destutter as
-                                                  in ite (a .== head as) r (a .: r))
-
--- | @destutter (destutter xs) == destutter xs@
---
--- >>> runTP $ destutterIdempotent @Integer
--- Inductive lemma: helper1
---   Step: Base                            Q.E.D.
---   Step: 1 (2 way case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
--- Inductive lemma: helper2
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Result:                               Q.E.D.
--- Inductive lemma (strong): helper3
---   Step: Measure is non-negative         Q.E.D.
---   Step: 1 (2 way full case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2 (2 way full case split)
---       Step: 1.2.1                       Q.E.D.
---       Step: 1.2.2.1                     Q.E.D.
---       Step: 1.2.2.2 (2 way case split)
---         Step: 1.2.2.2.1.1               Q.E.D.
---         Step: 1.2.2.2.1.2               Q.E.D.
---         Step: 1.2.2.2.2.1               Q.E.D.
---         Step: 1.2.2.2.2.2               Q.E.D.
---         Step: 1.2.2.2.Completeness      Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: destutterIdempotent              Q.E.D.
--- [Proven] destutterIdempotent :: Ɐxs ∷ [Integer] → Bool
-destutterIdempotent :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> SBool))
-destutterIdempotent = do
-
-   -- No adjacent duplicates
-   let noAdd = smtFunction "noAdd" $ \xs -> null xs .|| null (tail xs) .|| (head xs ./= head (tail xs) .&& noAdd (tail xs))
-
-   -- Helper: The head of a destuttered non-empty list does not change
-   helper1 <- induct "helper1"
-                     (\(Forall @"xs" (xs :: SList a)) (Forall @"h" h) -> head (destutter (h .: xs)) .== h) $
-                     \ih (x, xs) h -> []
-                                   |- head (destutter (h .: x .: xs))
-                                   =: cases [ h ./= x ==> trivial
-                                            , h .== x ==> head (destutter (x .: xs))
-                                                       ?? ih
-                                                       =: x
-                                                       =: qed
-                                            ]
-
-   -- Helper: show that if a list has no adjacent duplicates, then destutter leaves it unchanged:
-   helper2 <- induct "helper2"
-                     (\(Forall @"xs" (xs :: SList a)) -> noAdd xs .=> destutter xs .== xs) $
-                     \ih (x, xs) -> [noAdd (x .: xs)]
-                                 |- destutter (x .: xs)
-                                 ?? ih
-                                 =: x .: xs
-                                 =: qed
-
-   -- Helper: prove that noAdd is true for the result of destutter
-   helper3 <- sInductWith cvc5 "helper3"
-                  (\(Forall @"xs" (xs :: SList a)) -> noAdd (destutter xs))
-                  length $
-                  \ih xs -> []
-                         |- noAdd (destutter xs)
-                         =: split xs
-                                  trivial
-                                  (\a as -> split as
-                                                  trivial
-                                                  (\b bs -> noAdd (destutter (a .: b .: bs))
-                                                         =: cases [a .== b  ==> noAdd (destutter (b .: bs))
-                                                                             ?? ih
-                                                                             =: sTrue
-                                                                             =: qed
-                                                                  , a ./= b ==> noAdd (a .: destutter (b .: bs))
-                                                                             ?? helper1 `at` (Inst @"xs" bs, Inst @"h" b)
-                                                                             ?? ih
-                                                                             =: sTrue
-                                                                             =: qed
-                                                                  ]))
-
-   -- Now we can prove idempotency easily:
-   lemma "destutterIdempotent"
-          (\(Forall xs) -> destutter (destutter xs) .== destutter xs)
-          [proofOf helper2, proofOf helper3]
-
--- | @(as ++ bs) \\ cs == (as \\ cs) ++ (bs \\ cs)@
---
--- >>> runTP $ appendDiff @Integer
--- Inductive lemma: appendDiff
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] appendDiff :: Ɐas ∷ [Integer] → Ɐbs ∷ [Integer] → Ɐcs ∷ [Integer] → Bool
-appendDiff :: forall a. (Eq a, SymVal a) => TP (Proof (Forall "as" [a] -> Forall "bs" [a] -> Forall "cs" [a] -> SBool))
-appendDiff = induct "appendDiff"
-                    (\(Forall as) (Forall bs) (Forall cs) -> (as ++ bs) \\ cs .== (as \\ cs) ++ (bs \\ cs)) $
-                    \ih (a, as) bs cs -> [] |- (a .: as ++ bs) \\ cs
-                                            =: (a .: (as ++ bs)) \\ cs
-                                            =: ite (a `elem` cs) ((as ++ bs) \\ cs) (a .: ((as ++ bs) \\ cs))
-                                            ?? ih
-                                            =: ((a .: as) \\ cs) ++ (bs \\ cs)
-                                            =: qed
-
--- | @as \\ (bs ++ cs) == (as \\ bs) \\ cs@
---
--- >>> runTP $ diffAppend @Integer
--- Inductive lemma: diffAppend
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] diffAppend :: Ɐas ∷ [Integer] → Ɐbs ∷ [Integer] → Ɐcs ∷ [Integer] → Bool
-diffAppend :: forall a. (Eq a, SymVal a) => TP (Proof (Forall "as" [a] -> Forall "bs" [a] -> Forall "cs" [a] -> SBool))
-diffAppend = induct "diffAppend"
-                    (\(Forall as) (Forall bs) (Forall cs) -> as \\ (bs ++ cs) .== (as \\ bs) \\ cs) $
-                    \ih (a, as) bs cs -> [] |- (a .: as) \\ (bs ++ cs)
-                                            =: ite (a `elem` (bs ++ cs)) (as \\ (bs ++ cs)) (a .: (as \\ (bs ++ cs)))
-                                            ?? ih `at` (Inst @"bs" bs, Inst @"cs" cs)
-                                            =: ite (a `elem` (bs ++ cs)) ((as \\ bs) \\ cs) (a .: (as \\ (bs ++ cs)))
-                                            ?? ih `at` (Inst @"bs" bs, Inst @"cs" cs)
-                                            =: ite (a `elem` (bs ++ cs)) ((as \\ bs) \\ cs) (a .: ((as \\ bs) \\ cs))
-                                            =: ((a .: as) \\ bs) \\ cs
-                                            =: qed
-
--- | @(as \\ bs) \\ cs == (as \\ cs) \\ bs@
---
--- >>> runTP $ diffDiff @Integer
--- Inductive lemma: diffDiff
---   Step: Base                            Q.E.D.
---   Step: 1 (2 way case split)
---     Step: 1.1.1                         Q.E.D.
---     Step: 1.1.2                         Q.E.D.
---     Step: 1.1.3 (2 way case split)
---       Step: 1.1.3.1                     Q.E.D.
---       Step: 1.1.3.2.1                   Q.E.D.
---       Step: 1.1.3.2.2 (a ∉ cs)          Q.E.D.
---       Step: 1.1.3.Completeness          Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2 (2 way case split)
---       Step: 1.2.2.1.1                   Q.E.D.
---       Step: 1.2.2.1.2                   Q.E.D.
---       Step: 1.2.2.1.3 (a ∈ cs)          Q.E.D.
---       Step: 1.2.2.2.1                   Q.E.D.
---       Step: 1.2.2.2.2                   Q.E.D.
---       Step: 1.2.2.2.3 (a ∉ bs)          Q.E.D.
---       Step: 1.2.2.2.4 (a ∉ cs)          Q.E.D.
---       Step: 1.2.2.Completeness          Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] diffDiff :: Ɐas ∷ [Integer] → Ɐbs ∷ [Integer] → Ɐcs ∷ [Integer] → Bool
-diffDiff :: forall a. (Eq a, SymVal a) => TP (Proof (Forall "as" [a] -> Forall "bs" [a] -> Forall "cs" [a] -> SBool))
-diffDiff = induct "diffDiff"
-                  (\(Forall as) (Forall bs) (Forall cs) -> (as \\ bs) \\ cs .== (as \\ cs) \\ bs) $
-                  \ih (a, as) bs cs ->
-                      [] |- ((a .: as) \\ bs) \\ cs
-                         =: cases [ a `elem`    bs ==> (as \\ bs) \\ cs
-                                                    ?? ih
-                                                    =: (as \\ cs) \\ bs
-                                                    =: cases [ a `elem`    cs ==> ((a .: as) \\ cs) \\ bs
-                                                                               =: qed
-                                                             , a `notElem` cs ==> (a .: (as \\ cs)) \\ bs
-                                                                               ?? "a ∉ cs"
-                                                                               =: ((a .: as) \\ cs) \\ bs
-                                                                               =: qed
-                                                             ]
-                                  , a `notElem` bs ==> (a .: (as \\ bs)) \\ cs
-                                                    =: cases [ a `elem`    cs ==> (as \\ bs) \\ cs
-                                                                               ?? ih
-                                                                               =: (as \\ cs) \\ bs
-                                                                               ?? "a ∈ cs"
-                                                                               =: ((a .: as) \\ cs) \\ bs
-                                                                               =: qed
-                                                             , a `notElem` cs ==> a .: ((as \\ bs) \\ cs)
-                                                                               ?? ih
-                                                                               =: a .: ((as \\ cs) \\ bs)
-                                                                               ?? "a ∉ bs"
-                                                                               =: (a .: (as \\ cs)) \\ bs
-                                                                               ?? "a ∉ cs"
-                                                                               =: ((a .: as) \\ cs) \\ bs
-                                                                               =: qed
-                                                             ]
-                                  ]
-
--- | Are the two lists disjoint?
-disjoint :: (Eq a, SymVal a) => SList a -> SList a -> SBool
-disjoint = smtFunction "disjoint" $ \xs ys -> null xs .|| head xs `notElem` ys .&& disjoint (tail xs) ys
-
--- | @disjoint as bs .=> as \\ bs == as@
---
--- >>> runTP $ disjointDiff @Integer
--- Inductive lemma: disjointDiff
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] disjointDiff :: Ɐas ∷ [Integer] → Ɐbs ∷ [Integer] → Bool
-disjointDiff :: forall a. (Eq a, SymVal a) => TP (Proof (Forall "as" [a] -> Forall "bs" [a] -> SBool))
-disjointDiff = induct "disjointDiff"
-                      (\(Forall as) (Forall bs) -> disjoint as bs .=> as \\ bs .== as) $
-                      \ih (a, as) bs -> [disjoint (a .: as) bs]
-                                     |- (a .: as) \\ bs
-                                     =: a .: (as \\ bs)
-                                     ?? ih
-                                     =: a .: as
-                                     =: qed
-
--- | @fst (partition f xs) == filter f xs@
---
--- >>> runTP $ partition1 @Integer (uninterpret "f")
--- Inductive lemma: partition1
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] partition1 :: Ɐxs ∷ [Integer] → Bool
-partition1 :: forall a. SymVal a => (SBV a -> SBool) -> TP (Proof (Forall "xs" [a] -> SBool))
-partition1 f =
-   induct "partition1"
-          (\(Forall xs) -> fst (partition f xs) .== filter f xs) $
-          \ih (x, xs) -> [] |- fst (partition f (x .: xs))
-                            =: fst (let res = partition f xs
-                                    in ite (f x)
-                                           (tuple (x .: fst res, snd res))
-                                           (tuple (fst res, x .: snd res)))
-                            =: ite (f x) (x .: fst (partition f xs)) (fst (partition f xs))
-                            ?? ih
-                            =: ite (f x) (x .: filter f xs) (filter f xs)
-                            =: filter f (x .: xs)
-                            =: qed
-
--- | @snd (partition f xs) == filter (not . f) xs@
---
--- >>> runTP $ partition2 @Integer (uninterpret "f")
--- Inductive lemma: partition2
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] partition2 :: Ɐxs ∷ [Integer] → Bool
-partition2 :: forall a. SymVal a => (SBV a -> SBool) -> TP (Proof (Forall "xs" [a] -> SBool))
-partition2 f =
-   induct "partition2"
-          (\(Forall xs) -> snd (partition f xs) .== filter (sNot . f) xs) $
-          \ih (x, xs) -> [] |- snd (partition f (x .: xs))
-                            =: snd (let res = partition f xs
-                                    in ite (f x)
-                                           (tuple (x .: fst res, snd res))
-                                           (tuple (fst res, x .: snd res)))
-                            =: ite (f x) (snd (partition f xs)) (x .: snd (partition f xs))
-                            ?? ih
-                            =: ite (f x) (filter (sNot . f) xs) (x .: filter (sNot . f) xs)
-                            =: filter (sNot . f) (x .: xs)
-                            =: qed
-
--- | @take n (take m xs) == take (n `smin` m) xs@
---
--- >>> runTP $ take_take @Integer
--- Lemma: take_take                        Q.E.D.
--- [Proven] take_take :: Ɐm ∷ Integer → Ɐn ∷ Integer → Ɐxs ∷ [Integer] → Bool
-take_take :: forall a. SymVal a => TP (Proof (Forall "m" Integer -> Forall "n" Integer -> Forall "xs" [a] -> SBool))
-take_take = lemma "take_take"
-                  (\(Forall m) (Forall n) (Forall xs) -> take n (take m xs) .== take (n `smin` m) xs)
-                  []
-
--- | @n >= 0 && m >= 0 ==> drop n (drop m xs) == drop (n + m) xs@
---
--- >>> runTP $ drop_drop @Integer
--- Lemma: drop_drop                        Q.E.D.
--- [Proven] drop_drop :: Ɐm ∷ Integer → Ɐn ∷ Integer → Ɐxs ∷ [Integer] → Bool
-drop_drop :: forall a. SymVal a => TP (Proof (Forall "m" Integer -> Forall "n" Integer -> Forall "xs" [a] -> SBool))
-drop_drop = lemma "drop_drop"
-                  (\(Forall m) (Forall n) (Forall xs) -> n .>= 0 .&& m .>= 0 .=> drop n (drop m xs) .== drop (n + m) xs)
-                  []
-
--- | @take n xs ++ drop n xs == xs@
---
--- >>> runTP $ take_drop @Integer
--- Lemma: take_drop                        Q.E.D.
--- [Proven] take_drop :: Ɐn ∷ Integer → Ɐxs ∷ [Integer] → Bool
-take_drop :: forall a. SymVal a => TP (Proof (Forall "n" Integer -> Forall "xs" [a] -> SBool))
-take_drop = lemma "take_drop"
-                  (\(Forall n) (Forall xs) -> take n xs ++ drop n xs .== xs)
-                  []
-
--- | @n .> 0 ==> take n (x .: xs) == x .: take (n - 1) xs@
---
--- >>> runTP $ take_cons @Integer
--- Lemma: take_cons                        Q.E.D.
--- [Proven] take_cons :: Ɐn ∷ Integer → Ɐx ∷ Integer → Ɐxs ∷ [Integer] → Bool
-take_cons :: forall a. SymVal a => TP (Proof (Forall "n" Integer -> Forall "x" a -> Forall "xs" [a] -> SBool))
-take_cons = lemma "take_cons"
-                  (\(Forall n) (Forall x) (Forall xs) -> n .> 0 .=> take n (x .: xs) .== x .: take (n - 1) xs)
-                  []
-
--- | @take n (map f xs) == map f (take n xs)@
---
--- >>> runTP $ take_map @Integer @Integer (uninterpret "f")
--- Lemma: take_cons                        Q.E.D.
--- Lemma: map1                             Q.E.D.
--- Lemma: take_map.n <= 0                  Q.E.D.
--- Inductive lemma: take_map.n > 0
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: take_map
---   Step: 1                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] take_map :: Ɐn ∷ Integer → Ɐxs ∷ [Integer] → Bool
-take_map :: forall a b. (SymVal a, SymVal b) => (SBV a -> SBV b) -> TP (Proof (Forall "n" Integer -> Forall "xs" [a] -> SBool))
-take_map f = do
-    tc   <- take_cons @a
-
-    map1 <- lemma "map1"
-                  (\(Forall x) (Forall xs) -> map f (x .: xs) .== f x .: map f xs)
-                  []
-
-    h1 <- lemma "take_map.n <= 0"
-                 (\(Forall @"xs" xs) (Forall @"n" n) -> n .<= 0 .=> take n (map f xs) .== map f (take n xs))
-                 []
-
-    h2 <- induct "take_map.n > 0"
-                 (\(Forall @"xs" xs) (Forall @"n" n) -> n .> 0 .=> take n (map f xs) .== map f (take n xs)) $
-                 \ih (x, xs) n -> [n .> 0] |- take n (map f (x .: xs))
-                                           =: take n (f x .: map f xs)
-                                           =: f x .: take (n - 1) (map f xs)
-                                           ?? ih `at` Inst @"n" (n-1)
-                                           =: f x .: map f (take (n - 1) xs)
-                                           ?? map1 `at` (Inst @"x" x, Inst @"xs" (take (n - 1) xs))
-                                           =: map f (x .: take (n - 1) xs)
-                                           ?? tc
-                                           =: map f (take n (x .: xs))
-                                           =: qed
-
-    calc "take_map"
-         (\(Forall n) (Forall xs) -> take n (map f xs) .== map f (take n xs)) $
-         \n xs -> [] |- take n (map f xs)
-                     ?? h1
-                     ?? h2
-                     =: map f (take n xs)
-                     =: qed
-
--- | @n .> 0 ==> drop n (x .: xs) == drop (n - 1) xs@
---
--- >>> runTP $ drop_cons @Integer
--- Lemma: drop_cons                        Q.E.D.
--- [Proven] drop_cons :: Ɐn ∷ Integer → Ɐx ∷ Integer → Ɐxs ∷ [Integer] → Bool
-drop_cons :: forall a. SymVal a => TP (Proof (Forall "n" Integer -> Forall "x" a -> Forall "xs" [a] -> SBool))
-drop_cons = lemma "drop_cons"
-                  (\(Forall n) (Forall x) (Forall xs) -> n .> 0 .=> drop n (x .: xs) .== drop (n - 1) xs)
-                  []
-
--- | @drop n (map f xs) == map f (drop n xs)@
---
--- >>> runTP $ drop_map @Integer @String (uninterpret "f")
--- Lemma: drop_cons                        Q.E.D.
--- Lemma: drop_cons                        Q.E.D.
--- Lemma: drop_map.n <= 0                  Q.E.D.
--- Inductive lemma: drop_map.n > 0
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: drop_map
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] drop_map :: Ɐn ∷ Integer → Ɐxs ∷ [Integer] → Bool
-drop_map :: forall a b. (SymVal a, SymVal b) => (SBV a -> SBV b) -> TP (Proof (Forall "n" Integer -> Forall "xs" [a] -> SBool))
-drop_map f = do
-   dcA <- drop_cons @a
-   dcB <- drop_cons @b
-
-   h1 <- lemma "drop_map.n <= 0"
-               (\(Forall @"xs" xs) (Forall @"n" n) -> n .<= 0 .=> drop n (map f xs) .== map f (drop n xs))
-               []
-
-   h2 <- induct "drop_map.n > 0"
-                (\(Forall @"xs" xs) (Forall @"n" n) -> n .> 0 .=> drop n (map f xs) .== map f (drop n xs)) $
-                \ih (x, xs) n -> [n .> 0] |- drop n (map f (x .: xs))
-                                          =: drop n (f x .: map f xs)
-                                          ?? dcB `at` (Inst @"n" n, Inst @"x" (f x), Inst @"xs" (map f xs))
-                                          =: drop (n - 1) (map f xs)
-                                          ?? ih `at` Inst @"n" (n-1)
-                                          =: map f (drop (n - 1) xs)
-                                          ?? dcA `at` (Inst @"n" n, Inst @"x" x, Inst @"xs" xs)
-                                          =: map f (drop n (x .: xs))
-                                          =: qed
-
-   -- I'm a bit surprised that z3 can't deduce the following with a simple-lemma, which is essentially a simple case-split.
-   -- But the good thing about calc is that it lets us direct the tool in precise ways that we'd like.
-   calc "drop_map"
-        (\(Forall n) (Forall xs) -> drop n (map f xs) .== map f (drop n xs)) $
-        \n xs -> [] |- let result = drop n (map f xs) .== map f (drop n xs)
-                       in result
-                       =: ite (n .<= 0) (n .<= 0 .=> result) (n .> 0 .=> result)
-                       ?? h1
-                       =: ite (n .<= 0) sTrue (n .> 0 .=> result)
-                       ?? h2
-                       =: ite (n .<= 0) sTrue sTrue
-                       =: sTrue
-                       =: qed
-
--- | @n >= 0 ==> length (take n xs) == length xs \`min\` n@
---
--- >>> runTP $ length_take @Integer
--- Lemma: length_take                      Q.E.D.
--- [Proven] length_take :: Ɐn ∷ Integer → Ɐxs ∷ [Integer] → Bool
-length_take :: forall a. SymVal a => TP (Proof (Forall "n" Integer -> Forall "xs" [a] -> SBool))
-length_take = lemma "length_take"
-                    (\(Forall n) (Forall xs) -> n .>= 0 .=> length (take n xs) .== length xs `smin` n)
-                    []
-
--- | @n >= 0 ==> length (drop n xs) == (length xs - n) \`max\` 0@
---
--- >>> runTP $ length_drop @Integer
--- Lemma: length_drop                      Q.E.D.
--- [Proven] length_drop :: Ɐn ∷ Integer → Ɐxs ∷ [Integer] → Bool
-length_drop :: forall a. SymVal a => TP (Proof (Forall "n" Integer -> Forall "xs" [a] -> SBool))
-length_drop = lemma "length_drop"
-                    (\(Forall n) (Forall xs) -> n .>= 0 .=> length (drop n xs) .== (length xs - n) `smax` 0)
-                    []
-
--- | @length xs \<= n ==\> take n xs == xs@
---
--- >>> runTP $ take_all @Integer
--- Lemma: take_all                         Q.E.D.
--- [Proven] take_all :: Ɐn ∷ Integer → Ɐxs ∷ [Integer] → Bool
-take_all :: forall a. SymVal a => TP (Proof (Forall "n" Integer -> Forall "xs" [a] -> SBool))
-take_all = lemma "take_all"
-                 (\(Forall n) (Forall xs) -> length xs .<= n .=> take n xs .== xs)
-                 []
-
--- | @length xs \<= n ==\> drop n xs == nil@
---
--- >>> runTP $ drop_all @Integer
--- Lemma: drop_all                         Q.E.D.
--- [Proven] drop_all :: Ɐn ∷ Integer → Ɐxs ∷ [Integer] → Bool
-drop_all :: forall a. SymVal a => TP (Proof (Forall "n" Integer -> Forall "xs" [a] -> SBool))
-drop_all = lemma "drop_all"
-                 (\(Forall n) (Forall xs) -> length xs .<= n .=> drop n xs .== nil)
-                 []
-
--- | @take n (xs ++ ys) == (take n xs ++ take (n - length xs) ys)@
---
--- >>> runTP $ take_append @Integer
--- Lemma: take_append                      Q.E.D.
--- [Proven] take_append :: Ɐn ∷ Integer → Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool
-take_append :: forall a. SymVal a => TP (Proof (Forall "n" Integer -> Forall "xs" [a] -> Forall "ys" [a] -> SBool))
-take_append = lemmaWith cvc5 "take_append"
-                        (\(Forall n) (Forall xs) (Forall ys) -> take n (xs ++ ys) .== take n xs ++ take (n - length xs) ys)
-                        []
-
--- | @drop n (xs ++ ys) == drop n xs ++ drop (n - length xs) ys@
---
--- NB. As of Feb 2025, z3 struggles to prove this, but cvc5 gets it out-of-the-box.
---
--- >>> runTP $ drop_append @Integer
--- Lemma: drop_append                      Q.E.D.
--- [Proven] drop_append :: Ɐn ∷ Integer → Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool
-drop_append :: forall a. SymVal a => TP (Proof (Forall "n" Integer -> Forall "xs" [a] -> Forall "ys" [a] -> SBool))
-drop_append = lemmaWith cvc5 "drop_append"
-                        (\(Forall n) (Forall xs) (Forall ys) -> drop n (xs ++ ys) .== drop n xs ++ drop (n - length xs) ys)
-                        []
-
--- | @length xs == length ys ==> map fst (zip xs ys) = xs@
---
--- >>> runTP $ map_fst_zip @Integer @Integer
--- Inductive lemma: map_fst_zip
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] map_fst_zip :: (Ɐxs ∷ [Integer], Ɐys ∷ [Integer]) → Bool
-map_fst_zip :: forall a b. (SymVal a, SymVal b) => TP (Proof ((Forall "xs" [a], Forall "ys" [b]) -> SBool))
-map_fst_zip = induct "map_fst_zip"
-                     (\(Forall xs, Forall ys) -> length xs .== length ys .=> map fst (zip xs ys) .== xs) $
-                     \ih (x, xs, y, ys) -> [length (x .: xs) .== length (y .: ys)]
-                                        |- map fst (zip (x .: xs) (y .: ys))
-                                        =: map fst (tuple (x, y) .: zip xs ys)
-                                        =: fst (tuple (x, y)) .: map fst (zip xs ys)
-                                        =: x .: map fst (zip xs ys)
-                                        ?? ih
-                                        =: x .: xs
-                                        =: qed
-
--- | @length xs == length ys ==> map snd (zip xs ys) = xs@
---
--- >>> runTP $ map_snd_zip @Integer @Integer
--- Inductive lemma: map_snd_zip
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] map_snd_zip :: (Ɐxs ∷ [Integer], Ɐys ∷ [Integer]) → Bool
-map_snd_zip :: forall a b. (SymVal a, SymVal b) => TP (Proof ((Forall "xs" [a], Forall "ys" [b]) -> SBool))
-map_snd_zip = induct "map_snd_zip"
-                     (\(Forall xs, Forall ys) -> length xs .== length ys .=> map snd (zip xs ys) .== ys) $
-                     \ih (x, xs, y, ys) -> [length (x .: xs) .== length (y .: ys)]
-                                        |- map snd (zip (x .: xs) (y .: ys))
-                                        =: map snd (tuple (x, y) .: zip xs ys)
-                                        =: snd (tuple (x, y)) .: map snd (zip xs ys)
-                                        =: y .: map snd (zip xs ys)
-                                        ?? ih
-                                        =: y .: ys
-                                        =: qed
-
--- | @map fst (zip xs ys) == take (min (length xs) (length ys)) xs@
---
--- >>> runTP $ map_fst_zip_take @Integer @Integer
--- Lemma: take_cons                        Q.E.D.
--- Inductive lemma: map_fst_zip_take
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] map_fst_zip_take :: (Ɐxs ∷ [Integer], Ɐys ∷ [Integer]) → Bool
-map_fst_zip_take :: forall a b. (SymVal a, SymVal b) => TP (Proof ((Forall "xs" [a], Forall "ys" [b]) -> SBool))
-map_fst_zip_take = do
-   tc <- take_cons @a
-
-   induct "map_fst_zip_take"
-          (\(Forall xs, Forall ys) -> map fst (zip xs ys) .== take (length xs `smin` length ys) xs) $
-          \ih (x, xs, y, ys) -> [] |- map fst (zip (x .: xs) (y .: ys))
-                                   =: map fst (tuple (x, y) .: zip xs ys)
-                                   =: x .: map fst (zip xs ys)
-                                   ?? ih
-                                   =: x .: take (length xs `smin` length ys) xs
-                                   ?? tc
-                                   =: take (1 + (length xs `smin` length ys)) (x .: xs)
-                                   =: take (length (x .: xs) `smin` length (y .: ys)) (x .: xs)
-                                   =: qed
-
--- | @map snd (zip xs ys) == take (min (length xs) (length ys)) xs@
---
--- >>> runTP $ map_snd_zip_take @Integer @Integer
--- Lemma: take_cons                        Q.E.D.
--- Inductive lemma: map_snd_zip_take
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] map_snd_zip_take :: (Ɐxs ∷ [Integer], Ɐys ∷ [Integer]) → Bool
-map_snd_zip_take :: forall a b. (SymVal a, SymVal b) => TP (Proof ((Forall "xs" [a], Forall "ys" [b]) -> SBool))
-map_snd_zip_take = do
-   tc <- take_cons @a
-
-   induct "map_snd_zip_take"
-          (\(Forall xs, Forall ys) -> map snd (zip xs ys) .== take (length xs `smin` length ys) ys) $
-          \ih (x, xs, y, ys) -> [] |- map snd (zip (x .: xs) (y .: ys))
-                                   =: map snd (tuple (x, y) .: zip xs ys)
-                                   =: y .: map snd (zip xs ys)
-                                   ?? ih
-                                   =: y .: take (length xs `smin` length ys) ys
-                                   ?? tc
-                                   =: take (1 + (length xs `smin` length ys)) (y .: ys)
-                                   =: take (length (x .: xs) `smin` length (y .: ys)) (y .: ys)
-                                   =: qed
-
--- | Count the number of occurrences of an element in a list
-count :: SymVal a => SBV a -> SList a -> SInteger
-count = smtFunction "count" $ \e l -> ite (null l)
-                                          0
-                                          (let (x, xs) = uncons l
-                                               cxs     = count e xs
-                                           in ite (e .== x) (1 + cxs) cxs)
-
--- | Interleave the elements of two lists. If one ends, we take the rest from the other.
-interleave :: SymVal a => SList a -> SList a -> SList a
-interleave = smtFunction "interleave" (\xs ys -> ite (null  xs) ys (head xs .: interleave ys (tail xs)))
-
--- | Prove that interleave preserves total length.
---
--- The induction here is on the total length of the lists, and hence
--- we use the generalized induction principle. We have:
---
--- >>> runTP $ interleaveLen @Integer
--- Inductive lemma (strong): interleaveLen
---   Step: Measure is non-negative         Q.E.D.
---   Step: 1 (2 way full case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.2.3                         Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] interleaveLen :: Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool
-interleaveLen :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> Forall "ys" [a] -> SBool))
-interleaveLen = sInduct "interleaveLen"
-                        (\(Forall xs) (Forall ys) -> length xs + length ys .== length (interleave xs ys))
-                        (\xs ys -> length xs + length ys) $
-                        \ih xs ys -> [] |- length xs + length ys .== length (interleave xs ys)
-                                        =: split xs
-                                                 trivial
-                                                 (\a as -> length (a .: as) + length ys .== length (interleave (a .: as) ys)
-                                                        =: 1 + length as + length ys .== 1 + length (interleave ys as)
-                                                        ?? ih `at` (Inst @"xs" ys, Inst @"ys" as)
-                                                        =: sTrue
-                                                        =: qed)
-
--- | Uninterleave the elements of two lists. We roughly split it into two, of alternating elements.
-uninterleave :: SymVal a => SList a -> STuple [a] [a]
-uninterleave lst = uninterleaveGen lst (tuple (nil, nil))
-
--- | Generalized form of uninterleave with the auxilary lists made explicit.
-uninterleaveGen :: SymVal a => SList a -> STuple [a] [a] -> STuple [a] [a]
-uninterleaveGen = smtFunction "uninterleave" (\xs alts -> let (es, os) = untuple alts
-                                                          in ite (null xs)
-                                                                 (tuple (reverse es, reverse os))
-                                                                 (uninterleaveGen (tail xs) (tuple (os, head xs .: es))))
-
--- | The functions 'uninterleave' and 'interleave' are inverses so long as the inputs are of the same length. (The equality
--- would even hold if the first argument has one extra element, but we keep things simple here.)
---
--- We have:
---
--- >>> runTP $ interleaveRoundTrip @Integer
--- Lemma: revCons                          Q.E.D.
--- Inductive lemma (strong): roundTripGen
---   Step: Measure is non-negative         Q.E.D.
---   Step: 1 (4 way full case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2                           Q.E.D.
---     Step: 1.3                           Q.E.D.
---     Step: 1.4.1                         Q.E.D.
---     Step: 1.4.2                         Q.E.D.
---     Step: 1.4.3                         Q.E.D.
---     Step: 1.4.4                         Q.E.D.
---     Step: 1.4.5                         Q.E.D.
---     Step: 1.4.6                         Q.E.D.
---     Step: 1.4.7                         Q.E.D.
---     Step: 1.4.8                         Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: interleaveRoundTrip
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] interleaveRoundTrip :: Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool
-interleaveRoundTrip :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> Forall "ys" [a] -> SBool))
-interleaveRoundTrip = do
-
-   revHelper <- lemma "revCons" (\(Forall a) (Forall as) (Forall bs) -> reverse @a (a .: as) ++ bs .== reverse as ++ (a .: bs)) []
-
-   -- Generalize the theorem first to take the helper lists explicitly
-   roundTripGen <- sInductWith cvc5
-         "roundTripGen"
-         (\(Forall @"xs" xs) (Forall @"ys" ys) (Forall @"alts" alts) ->
-               length xs .== length ys .=> let (es, os) = untuple alts
-                                           in uninterleaveGen (interleave xs ys) alts .== tuple (reverse es ++ xs, reverse os ++ ys))
-         (\xs ys _alts -> length xs + length ys) $
-         \ih xs ys alts -> [length xs .== length ys]
-                        |- let (es, os) = untuple alts
-                        in uninterleaveGen (interleave xs ys) alts
-                        =: split2 (xs, ys)
-                                  trivial
-                                  trivial
-                                  trivial
-                                  (\(a, as) (b, bs) -> uninterleaveGen (interleave (a .: as) (b .: bs)) alts
-                                                    =: uninterleaveGen (a .: interleave (b .: bs) as) alts
-                                                    =: uninterleaveGen (a .: b .: interleave as bs) alts
-                                                    =: uninterleaveGen (interleave as bs) (tuple (a .: es, b .: os))
-                                                    ?? ih `at` (Inst @"xs" as, Inst @"ys" bs, Inst @"alts" (tuple (a .: es, b .: os)))
-                                                    =: tuple (reverse (a .: es) ++ as, reverse (b .: os) ++ bs)
-                                                    ?? revHelper `at` (Inst @"a" a, Inst @"as" es, Inst @"bs" as)
-                                                    =: tuple (reverse es ++ (a .: as), reverse (b .: os) ++ bs)
-                                                    ?? revHelper `at` (Inst @"a" b, Inst @"as" os, Inst @"bs" bs)
-                                                    =: tuple (reverse es ++ (a .: as), reverse os ++ (b .: bs))
-                                                    =: tuple (reverse es ++ xs, reverse os ++ ys)
-                                                    =: qed)
-
-   -- Round-trip theorem:
-   calc "interleaveRoundTrip"
-           (\(Forall xs) (Forall ys) -> length xs .== length ys .=> uninterleave (interleave xs ys) .== tuple (xs, ys)) $
-           \xs ys -> [length xs .== length ys]
-                  |- uninterleave (interleave xs ys)
-                  =: uninterleaveGen (interleave xs ys) (tuple (nil, nil))
-                  ?? roundTripGen `at` (Inst @"xs" xs, Inst @"ys" ys, Inst @"alts" (tuple (nil, nil)))
-                  =: tuple (reverse nil ++ xs, reverse nil ++ ys)
-                  =: qed
-
--- | @count e (xs ++ ys) == count e xs + count e ys@
---
--- >>> runTP $ countAppend @Integer
--- Inductive lemma: countAppend
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2 (unfold count)                Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4 (simplify)                    Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] countAppend :: Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Ɐe ∷ Integer → Bool
-countAppend :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> Forall "ys" [a] -> Forall "e" a -> SBool))
-countAppend =
-   induct "countAppend"
-          (\(Forall xs) (Forall ys) (Forall e) -> count e (xs ++ ys) .== count e xs + count e ys) $
-          \ih (x, xs) ys e -> [] |- count e ((x .: xs) ++ ys)
-                                 =: count e (x .: (xs ++ ys))
-                                 ?? "unfold count"
-                                 =: (let r = count e (xs ++ ys) in ite (e .== x) (1+r) r)
-                                 ?? ih `at` (Inst @"ys" ys, Inst @"e" e)
-                                 =: (let r = count e xs + count e ys in ite (e .== x) (1+r) r)
-                                 ?? "simplify"
-                                 =: count e (x .: xs) + count e ys
-                                 =: qed
-
--- | @count e (take n xs) + count e (drop n xs) == count e xs@
---
--- >>> runTP $ takeDropCount @Integer
--- Inductive lemma: countAppend
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2 (unfold count)                Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4 (simplify)                    Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: take_drop                        Q.E.D.
--- Lemma: takeDropCount
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] takeDropCount :: Ɐxs ∷ [Integer] → Ɐn ∷ Integer → Ɐe ∷ Integer → Bool
-takeDropCount :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> Forall "n" Integer -> Forall "e" a -> SBool))
-takeDropCount = do
-       capp     <- countAppend @a
-       takeDrop <- take_drop   @a
-
-       calc "takeDropCount"
-            (\(Forall xs) (Forall n) (Forall e) -> count e (take n xs) + count e (drop n xs) .== count e xs) $
-            \xs n e -> [] |- count e (take n xs) + count e (drop n xs)
-                          ?? capp `at` (Inst @"xs" (take n xs), Inst @"ys" (drop n xs), Inst @"e" e)
-                          =: count e (take n xs ++ drop n xs)
-                          ?? takeDrop
-                          =: count e xs
-                          =: qed
-
--- | @count e xs >= 0@
---
--- >>> runTP $ countNonNeg @Integer
--- Inductive lemma: countNonNeg
---   Step: Base                            Q.E.D.
---   Step: 1 (2 way case split)
---     Step: 1.1.1                         Q.E.D.
---     Step: 1.1.2                         Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] countNonNeg :: Ɐxs ∷ [Integer] → Ɐe ∷ Integer → Bool
-countNonNeg :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> Forall "e" a -> SBool))
-countNonNeg =
-   induct "countNonNeg"
-          (\(Forall xs) (Forall e) -> count e xs .>= 0) $
-          \ih (x, xs) e -> [] |- count e (x .: xs) .>= 0
-                              =: cases [ e .== x ==> 1 + count e xs .>= 0
-                                                  ?? ih
-                                                  =: sTrue
-                                                  =: qed
-                                       , e ./= x ==> count e xs .>= 0
-                                                  ?? ih
-                                                  =: sTrue
-                                                  =: qed
-                                       ]
-
--- | @e \`elem\` xs ==> count e xs .> 0@
---
--- >>> runTP $ countElem @Integer
--- Inductive lemma: countNonNeg
---   Step: Base                            Q.E.D.
---   Step: 1 (2 way case split)
---     Step: 1.1.1                         Q.E.D.
---     Step: 1.1.2                         Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
--- Inductive lemma: countElem
---   Step: Base                            Q.E.D.
---   Step: 1 (2 way case split)
---     Step: 1.1.1                         Q.E.D.
---     Step: 1.1.2                         Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] countElem :: Ɐxs ∷ [Integer] → Ɐe ∷ Integer → Bool
-countElem :: forall a. (Eq a, SymVal a) => TP (Proof (Forall "xs" [a] -> Forall "e" a -> SBool))
-countElem = do
-
-    cnn <- countNonNeg @a
-
-    induct "countElem"
-           (\(Forall xs) (Forall e) -> e `elem` xs .=> count e xs .> 0) $
-           \ih (x, xs) e -> [e `elem` (x .: xs)]
-                         |- count e (x .: xs) .> 0
-                         =: cases [ e .== x ==> 1 + count e xs .> 0
-                                             ?? cnn
-                                             =: sTrue
-                                             =: qed
-                                  , e ./= x ==> count e xs .> 0
-                                             ?? ih
-                                             =: sTrue
-                                             =: qed
-                                  ]
-
--- | @count e xs .> 0 .=> e \`elem\` xs@
---
--- >>> runTP $ elemCount @Integer
--- Inductive lemma: elemCount
---   Step: Base                            Q.E.D.
---   Step: 1 (2 way case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] elemCount :: Ɐxs ∷ [Integer] → Ɐe ∷ Integer → Bool
-elemCount :: forall a. (Eq a, SymVal a) => TP (Proof (Forall "xs" [a] -> Forall "e" a -> SBool))
-elemCount =
-    induct "elemCount"
-           (\(Forall xs) (Forall e) -> count e xs .> 0 .=> e `elem` xs) $
-           \ih (x, xs) e -> [count e xs .> 0]
-                         |- e `elem` (x .: xs)
-                         =: cases [ e .== x ==> trivial
-                                  , e ./= x ==> e `elem` xs
-                                             ?? ih
-                                             =: sTrue
-                                             =: qed
-                                  ]
-
-{- HLint ignore revRev         "Redundant reverse" -}
-{- HLint ignore allAny         "Use and"           -}
-{- HLint ignore bookKeeping    "Fuse foldr/map"    -}
-{- HLint ignore foldrMapFusion "Fuse foldr/map"    -}
-{- HLint ignore filterConcat   "Move filter"       -}
-{- HLint ignore module         "Use camelCase"     -}
-{- HLint ignore module         "Use first"         -}
-{- HLint ignore module         "Use second"        -}
-{- HLint ignore module         "Use zipWith"       -}
-{- HLint ignore mapCompose     "Use map once"      -}
-{- HLint ignore tailsAppend    "Avoid lambda"      -}
-{- HLint ignore tailsAppend    "Use :"             -}
-{- HLint ignore mapReverse     "Evaluate"          -}
-{- HLint ignore takeDropWhile  "Evaluate"          -}
diff --git a/Data/SBV/TP/TP.hs b/Data/SBV/TP/TP.hs
--- a/Data/SBV/TP/TP.hs
+++ b/Data/SBV/TP/TP.hs
@@ -7,19 +7,18 @@
 -- Stability : experimental
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE ConstraintKinds            #-}
-{-# LANGUAGE DataKinds                  #-}
-{-# LANGUAGE DerivingStrategies         #-}
-{-# LANGUAGE FlexibleContexts           #-}
-{-# LANGUAGE FlexibleInstances          #-}
-{-# LANGUAGE MultiParamTypeClasses      #-}
-{-# LANGUAGE NamedFieldPuns             #-}
-{-# LANGUAGE ScopedTypeVariables        #-}
-{-# LANGUAGE TupleSections              #-}
-{-# LANGUAGE TypeAbstractions           #-}
-{-# LANGUAGE TypeApplications           #-}
-{-# LANGUAGE TypeFamilyDependencies     #-}
-{-# LANGUAGE TypeOperators              #-}
+{-# LANGUAGE DataKinds              #-}
+{-# LANGUAGE FlexibleContexts       #-}
+{-# LANGUAGE FlexibleInstances      #-}
+{-# LANGUAGE MultiParamTypeClasses  #-}
+{-# LANGUAGE NamedFieldPuns         #-}
+{-# LANGUAGE OverloadedLists        #-}
+{-# LANGUAGE OverloadedStrings      #-}
+{-# LANGUAGE ScopedTypeVariables    #-}
+{-# LANGUAGE TupleSections          #-}
+{-# LANGUAGE TypeApplications       #-}
+{-# LANGUAGE TypeFamilyDependencies #-}
+{-# LANGUAGE TypeOperators          #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -27,16 +26,19 @@
          Proposition, Proof, proofOf, assumptionFromProof, Instantiatable(..), Inst(..)
        , rootOfTrust, RootOfTrust(..), ProofTree(..), showProofTree, showProofTreeHTML
        ,   axiom
-       ,   lemma,   lemmaWith
-       ,    calc,    calcWith
-       ,  induct,  inductWith
-       , sInduct, sInductWith
+       ,            lemma,          lemmaWith
+       ,   inductiveLemma, inductiveLemmaWith
+       ,             calc,           calcWith
+       ,           induct,         inductWith
+       ,          sInduct,        sInductWith
        , sorry
-       , TP, runTP, runTPWith, tpQuiet, tpRibbon, tpStats, tpAsms, tpCache
+       , TP, runTP, runTPWith, tpQuiet, tpStats, tpAsms
+       , whenDryRun, unlessDryRun
+       , measureLemma, measureLemmaWith
        , (|-), (|->), (⊢), (=:), (≡), (??), (∵), split, split2, cases, (==>), (⟹), qed, trivial, contradiction
        , qc, qcWith
        , disp
-       , recall
+       , recall, recallWith
        ) where
 
 import Data.SBV
@@ -44,6 +46,9 @@
 import Data.SBV.Core.Data  (SBV(..), SVal(..))
 import qualified Data.SBV.Core.Symbolic as S (sObserve)
 
+import qualified Data.Text as T
+
+import Data.SBV.Core.Symbolic (rSkipMeasureChecks, rNoTermCheckFunctions)
 import Data.SBV.Core.Operations (svEqual)
 import Data.SBV.Control hiding (getProof, (|->))
 
@@ -52,9 +57,13 @@
 
 import qualified Data.SBV.List as SL
 
+import Control.Exception (SomeException)
 import Control.Monad (when)
 import Control.Monad.Trans (liftIO)
+import Data.IORef (readIORef, writeIORef, modifyIORef')
 
+import qualified Data.Set as Set
+
 import Data.Char  (isSpace)
 import Data.List  (intercalate, isPrefixOf, isSuffixOf)
 import Data.Maybe (catMaybes, maybeToList)
@@ -70,7 +79,7 @@
 import qualified Test.QuickCheck as QC
 import Test.QuickCheck (quickCheckWithResult)
 
--- | Captures the steps for a calculationa proof
+-- | Captures the steps for a calculational proof
 data CalcStrategy = CalcStrategy { calcIntros     :: SBool
                                  , calcProofTree  :: TPProof
                                  , calcQCInstance :: [Int] -> Symbolic SBool
@@ -93,11 +102,6 @@
 getCalcStrategySaturatables :: CalcStrategy -> [SBool]
 getCalcStrategySaturatables (CalcStrategy calcIntros calcProofTree _calcQCInstance) = calcIntros : proofTreeSaturatables calcProofTree
 
--- | Propagate the settings for ribbon/timing from top to current. Because in any subsequent configuration
--- in a lemmaWith, inductWith etc., we just want to change the solver, not the actual settings for TP.
-tpMergeCfg :: SMTConfig -> SMTConfig -> SMTConfig
-tpMergeCfg cur top = cur{tpOptions = tpOptions top}
-
 -- | Use an injective type family to allow for curried use of calc and strong induction steps.
 type family StepArgs a t = result | result -> t where
   StepArgs                                                                             SBool  t =                                               (SBool, TPProofRaw (SBV t))
@@ -162,29 +166,44 @@
   {-# MINIMAL calcSteps #-}
   calcSteps :: (SymVal t, EqSymbolic (SBV t)) => a -> StepArgs a t -> Symbolic (SBool, CalcStrategy)
 
-  calc         nm p steps = getTPConfig >>= \cfg  -> calcWith          cfg                   nm p steps
-  calcWith cfg nm p steps = getTPConfig >>= \cfg' -> calcGeneric False (tpMergeCfg cfg cfg') nm p steps
+  calc         nm p steps = getTPConfig >>= \cfg  -> calcWith    cfg                   nm p steps
+  calcWith cfg nm p steps = getTPConfig >>= \cfg' -> calcGeneric (tpMergeCfg cfg cfg') nm p steps
 
-  calcGeneric :: (SymVal t, EqSymbolic (SBV t), Proposition a) => Bool -> SMTConfig -> String -> a -> StepArgs a t -> TP (Proof a)
-  calcGeneric tagTheorem cfg nm result steps = withProofCache nm $ do
-      tpSt <- getTPState
-      u    <- tpGetNextUnique
+  calcGeneric :: (SymVal t, EqSymbolic (SBV t), Proposition a) => SMTConfig -> String -> a -> StepArgs a t -> TP (Proof a)
+  calcGeneric cfg nm result steps = do
+      cached <- lookupProofCache result
+      case cached of
+        Just prf -> returnCachedProof cfg nm prf
+        Nothing  -> do
+          tpSt <- getTPState
+          u    <- tpGetNextUnique
 
-      (_, CalcStrategy {calcQCInstance}) <- liftIO $ runSMTWith cfg (calcSteps result steps)
+          (_, CalcStrategy {calcQCInstance}) <- liftIO $ runSMTWith cfg (calcSteps result steps)
 
-      liftIO $ runSMTWith cfg $ do
+          proof <- liftIO $ runSMTWith cfg $ do
 
-         qSaturateSavingObservables result -- make sure we saturate the result, i.e., get all it's UI's, types etc. pop out
+             qSaturateSavingObservables result -- make sure we saturate the result, i.e., get all it's UI's, types etc. pop out
 
-         message cfg $ (if tagTheorem then "Theorem" else "Lemma") ++ ": " ++ nm ++ "\n"
+             let header = "Lemma: " ++ nm
+             message cfg $ header ++ "\n"
+             liftIO $ do isDry <- readIORef (dryRun tpSt)
+                         when isDry $ modifyIORef' (maxRibbon tpSt) (max (length header))
 
-         (calcGoal, strategy@CalcStrategy {calcIntros, calcProofTree}) <- calcSteps result steps
+             (calcGoal, strategy@CalcStrategy {calcIntros, calcProofTree}) <- calcSteps result steps
 
-         -- Collect all subterms and saturate them
-         mapM_ qSaturateSavingObservables $ getCalcStrategySaturatables strategy
+             -- Collect all subterms and saturate them
+             mapM_ qSaturateSavingObservables $ getCalcStrategySaturatables strategy
 
-         query $ proveProofTree cfg tpSt nm (result, calcGoal) calcIntros calcProofTree u calcQCInstance
+             -- Run measure checks for any newly encountered recursive functions
+             st <- symbolicEnv
+             liftIO $ do writeIORef (rSkipMeasureChecks st) True
+                         checkNewMeasures cfg st tpSt
 
+             query $ proveProofTree cfg tpSt nm (result, calcGoal) calcIntros calcProofTree u calcQCInstance
+
+          addToProofCache result (proofOf proof)
+          pure proof
+
 -- | In the proof tree, what's the next node label?
 nextProofStep :: [Int] -> [Int]
 nextProofStep bs = case reverse bs of
@@ -223,24 +242,29 @@
 proveProofTree cfg tpSt nm (result, resultBool) initialHypotheses calcProofTree uniq quickCheckInstance = do
     results <- walk initialHypotheses 1 ([1], calcProofTree)
 
-    queryDebug [nm ++ ": Proof end: proving the result:"]
+    queryDebug [T.pack nm <> ": Proof end: proving the result:"]
 
     mbStartTime <- getTimeStampIf printStats
+    st <- symbolicEnv
+    noTermFns <- liftIO $ readIORef (rNoTermCheckFunctions st)
+    let ntcDeps = map noTermCheckProof (Set.toList noTermFns)
     smtProofStep cfg tpSt "Result" 1
                  (TPProofStep False nm [] [""])
                  (Just (initialHypotheses .=> sAnd results))
                  resultBool [] $ \d ->
                    do mbElapsed <- getElapsedTime mbStartTime
-                      let modulo = concludeModulo (concatMap getHelperProofs (getAllHelpers calcProofTree))
+                      let allDeps  = getDependencies calcProofTree ++ ntcDeps
+                          modulo   = concludeModulo (concatMap getHelperProofs (getAllHelpers calcProofTree) ++ ntcDeps)
                       finishTP cfg ("Q.E.D." ++ modulo) d (catMaybes [mbElapsed])
 
-                      pure $ Proof $ ProofObj { dependencies = getDependencies calcProofTree
+                      pure $ Proof $ ProofObj { dependencies = allDeps
                                               , isUserAxiom  = False
                                               , getObjProof  = label nm (quantifiedBool result)
                                               , getProp      = toDyn result
                                               , proofName    = nm
                                               , uniqId       = uniq
-                                              , isCached     = False
+                                              , aliases      = []
+                                              , wasCached    = False
                                               }
 
   where SMTConfig{tpOptions = TPOptions{printStats, printAsms}} = cfg
@@ -354,6 +378,8 @@
                         liftIO $ do
 
                            tab <- startTP cfg (verbose cfg) "Step" level (TPProofStep False nm (getHelperText hs') stepName)
+                           isDry <- readIORef (dryRun tpSt)
+                           when isDry $ modifyIORef' (maxRibbon tpSt) (max tab)
 
                            (mbT, r) <- timeIf printStats $ quickCheckWithResult qcArg{QC.chatty = verbose cfg} $ quickCheckInstance bn
 
@@ -501,7 +527,7 @@
 
 -- | Captures the schema for an inductive proof. Base case might be nothing, to cover strong induction.
 data InductionStrategy = InductionStrategy { inductionIntros     :: SBool
-                                           , inductionMeasure    :: Maybe SBool
+                                           , inductionMeasure    :: Maybe (SBool, [ProofObj])
                                            , inductionBaseCase   :: Maybe SBool
                                            , inductionProofTree  :: TPProof
                                            , inductiveStep       :: SBool
@@ -518,7 +544,15 @@
                                                     inductionProofSteps
                                                     inductiveStep
                                                     _inductiveQCInstance)
-  = inductionIntros : inductiveStep : proofTreeSaturatables inductionProofSteps ++ maybeToList inductionBaseCase ++ maybeToList inductionMeasure
+  = inductionIntros
+  : inductiveStep
+  : proofTreeSaturatables inductionProofSteps
+  ++ measureDs
+  ++ maybeToList inductionBaseCase
+  where objDeps p = getObjProof p : concatMap objDeps (dependencies p)
+        measureDs = case inductionMeasure of
+                      Nothing      -> []
+                      Just (a, ps) -> a : concatMap objDeps ps
 
 -- | A class for doing regular inductive proofs.
 class Inductive a where
@@ -535,106 +569,98 @@
    -- partial correctness is guaranteed if non-terminating functions are involved.
    inductWith :: (Proposition a, SymVal t, EqSymbolic (SBV t)) => SMTConfig -> String -> a -> (Proof (IHType a) -> IHArg a -> IStepArgs a t) -> TP (Proof a)
 
-   induct         nm p steps = getTPConfig >>= \cfg  -> inductWith                             cfg                   nm p steps
-   inductWith cfg nm p steps = getTPConfig >>= \cfg' -> inductionEngine RegularInduction False (tpMergeCfg cfg cfg') nm p (inductionStrategy p steps)
+   induct         nm p steps = getTPConfig >>= \cfg  -> inductWith                       cfg                   nm p steps
+   inductWith cfg nm p steps = getTPConfig >>= \cfg' -> inductionEngine RegularInduction (tpMergeCfg cfg cfg') nm p (inductionStrategy p steps)
 
    -- | Internal, shouldn't be needed outside the library
    {-# MINIMAL inductionStrategy #-}
    inductionStrategy :: (Proposition a, SymVal t, EqSymbolic (SBV t)) => a -> (Proof (IHType a) -> IHArg a -> IStepArgs a t) -> Symbolic InductionStrategy
 
--- | A class of values, capturing the zero of a measure value
-class OrdSymbolic (SBV a) => Zero a where
-  zero :: SBV a
-
--- | An integer as a measure
-instance Zero Integer where
-   zero = literal 0
-
--- | A tuple of integers as a measure
-instance Zero (Integer, Integer) where
-  zero = literal (0, 0)
-
--- | A triple of integers as a measure
-instance Zero (Integer, Integer, Integer) where
-  zero = literal (0, 0, 0)
-
--- | A quadruple of integers as a measure
-instance Zero (Integer, Integer, Integer, Integer) where
-  zero = literal (0, 0, 0, 0)
-
-instance Zero (Integer, Integer, Integer, Integer, Integer) where
-  zero = literal (0, 0, 0, 0, 0)
-
 -- | A class for doing generalized measure based strong inductive proofs.
 class SInductive a where
    -- | Inductively prove a lemma, using measure based induction, using the default config.
    -- Inductive proofs over lists only hold for finite lists. We also assume that all functions involved are terminating. SBV does not prove termination, so only
    -- partial correctness is guaranteed if non-terminating functions are involved.
-   sInduct :: (Proposition a, Zero m, SymVal t, EqSymbolic (SBV t)) => String -> a -> MeasureArgs a m -> (Proof a -> StepArgs a t) -> TP (Proof a)
+   sInduct :: (Proposition a, Zero m, SymVal t, EqSymbolic (SBV t)) => String -> a -> (MeasureArgs a m, [ProofObj]) -> (Proof a -> StepArgs a t) -> TP (Proof a)
 
    -- | Same as 'sInduct', but with the given solver configuration.
    -- Inductive proofs over lists only hold for finite lists. We also assume that all functions involved are terminating. SBV does not prove termination, so only
    -- partial correctness is guaranteed if non-terminating functions are involved.
-   sInductWith :: (Proposition a, Zero m, SymVal t, EqSymbolic (SBV t)) => SMTConfig -> String -> a -> MeasureArgs a m -> (Proof a -> StepArgs a t) -> TP (Proof a)
+   sInductWith :: (Proposition a, Zero m, SymVal t, EqSymbolic (SBV t)) => SMTConfig -> String -> a -> (MeasureArgs a m, [ProofObj]) -> (Proof a -> StepArgs a t) -> TP (Proof a)
 
-   sInduct         nm p m steps = getTPConfig >>= \cfg  -> sInductWith                            cfg                   nm p m steps
-   sInductWith cfg nm p m steps = getTPConfig >>= \cfg' -> inductionEngine GeneralInduction False (tpMergeCfg cfg cfg') nm p (sInductionStrategy p m steps)
+   sInduct         nm p mhs steps = getTPConfig >>= \cfg  -> sInductWith                      cfg                   nm p mhs steps
+   sInductWith cfg nm p mhs steps = getTPConfig >>= \cfg' -> inductionEngine GeneralInduction (tpMergeCfg cfg cfg') nm p (sInductionStrategy p mhs steps)
 
    -- | Internal, shouldn't be needed outside the library
    {-# MINIMAL sInductionStrategy #-}
-   sInductionStrategy :: (Proposition a, Zero m, SymVal t, EqSymbolic (SBV t)) => a -> MeasureArgs a m -> (Proof a -> StepArgs a t) -> Symbolic InductionStrategy
+   sInductionStrategy :: (Proposition a, Zero m, SymVal t, EqSymbolic (SBV t)) => a -> (MeasureArgs a m, [ProofObj]) -> (Proof a -> StepArgs a t) -> Symbolic InductionStrategy
 
 -- | Do an inductive proof, based on the given strategy
-inductionEngine :: Proposition a => InductionStyle -> Bool -> SMTConfig -> String -> a -> Symbolic InductionStrategy -> TP (Proof a)
-inductionEngine style tagTheorem cfg nm result getStrategy = withProofCache nm $ do
-   tpSt <- getTPState
-   u    <- tpGetNextUnique
+inductionEngine :: Proposition a => InductionStyle -> SMTConfig -> String -> a -> Symbolic InductionStrategy -> TP (Proof a)
+inductionEngine style cfg nm result getStrategy = do
+   cached <- lookupProofCache result
+   case cached of
+     Just prf -> returnCachedProof cfg nm prf
+     Nothing -> do
+       tpSt <- getTPState
+       u    <- tpGetNextUnique
 
-   liftIO $ runSMTWith cfg $ do
+       proof <- liftIO $ runSMTWith cfg $ do
 
-      qSaturateSavingObservables result -- make sure we saturate the result, i.e., get all it's UI's, types etc. pop out
+          qSaturateSavingObservables result -- make sure we saturate the result, i.e., get all it's UI's, types etc. pop out
 
-      let qual = case style of
-                   RegularInduction -> ""
-                   GeneralInduction  -> " (strong)"
+          let qual = case style of
+                       RegularInduction -> ""
+                       GeneralInduction  -> " (strong)"
 
-      message cfg $ "Inductive " ++ (if tagTheorem then "theorem" else "lemma") ++ qual ++ ": " ++ nm ++ "\n"
+          let header = "Inductive lemma" ++ qual ++ ": " ++ nm
+          message cfg $ header ++ "\n"
+          liftIO $ do isDry <- readIORef (dryRun tpSt)
+                      when isDry $ modifyIORef' (maxRibbon tpSt) (max (length header))
 
-      strategy@InductionStrategy { inductionIntros
-                                 , inductionMeasure
-                                 , inductionBaseCase
-                                 , inductionProofTree
-                                 , inductiveStep
-                                 , inductiveQCInstance
-                                 } <- getStrategy
+          strategy@InductionStrategy { inductionIntros
+                                     , inductionMeasure
+                                     , inductionBaseCase
+                                     , inductionProofTree
+                                     , inductiveStep
+                                     , inductiveQCInstance
+                                     } <- getStrategy
 
-      mapM_ qSaturateSavingObservables $ getInductionStrategySaturatables strategy
+          mapM_ qSaturateSavingObservables $ getInductionStrategySaturatables strategy
 
-      query $ do
+          -- Run measure checks for any newly encountered recursive functions
+          st <- symbolicEnv
+          liftIO $ do writeIORef (rSkipMeasureChecks st) True
+                      checkNewMeasures cfg st tpSt
 
-       case inductionMeasure of
-          Nothing -> queryDebug [nm ++ ": Induction" ++ qual ++ ", there is no custom measure to show non-negativeness."]
-          Just ms -> do queryDebug [nm ++ ": Induction, proving measure is always non-negative:"]
-                        smtProofStep cfg tpSt "Step" 1
-                                              (TPProofStep False nm [] ["Measure is non-negative"])
-                                              (Just inductionIntros)
-                                              ms
-                                              []
-                                              (\d -> finishTP cfg "Q.E.D." d [])
-       case inductionBaseCase of
-          Nothing -> queryDebug [nm ++ ": Induction" ++ qual ++ ", there is no base case to prove."]
-          Just bc -> do queryDebug [nm ++ ": Induction, proving base case:"]
-                        smtProofStep cfg tpSt "Step" 1
-                                              (TPProofStep False nm [] ["Base"])
-                                              (Just inductionIntros)
-                                              bc
-                                              []
-                                              (\d -> finishTP cfg "Q.E.D." d [])
+          query $ do
 
-       proveProofTree cfg tpSt nm (result, inductiveStep) inductionIntros inductionProofTree u inductiveQCInstance
+           case inductionMeasure of
+              Nothing      -> queryDebug [T.pack nm <> ": Induction" <> T.pack qual <> ", there is no custom measure to show non-negativeness."]
+              Just (m, hs) -> do queryDebug [T.pack nm <> ": Induction, proving measure is always non-negative:"]
+                                 smtProofStep cfg tpSt "Step" 1
+                                                       (TPProofStep False nm [] ["Measure is non-negative"])
+                                                       (Just (sAnd (inductionIntros : map getObjProof hs)))
+                                                       m
+                                                       []
+                                                       (\d -> finishTP cfg "Q.E.D." d [])
+           case inductionBaseCase of
+              Nothing -> queryDebug [T.pack nm <> ": Induction" <> T.pack qual <> ", there is no base case to prove."]
+              Just bc -> do queryDebug [T.pack nm <> ": Induction, proving base case:"]
+                            smtProofStep cfg tpSt "Step" 1
+                                                  (TPProofStep False nm [] ["Base"])
+                                                  (Just inductionIntros)
+                                                  bc
+                                                  []
+                                                  (\d -> finishTP cfg "Q.E.D." d [])
 
+           proveProofTree cfg tpSt nm (result, inductiveStep) inductionIntros inductionProofTree u inductiveQCInstance
+
+       addToProofCache result (proofOf proof)
+       pure proof
+
 -- Induction strategy helper
-mkIndStrategy :: (SymVal a, EqSymbolic (SBV a)) => Maybe SBool -> Maybe SBool -> (SBool, TPProofRaw (SBV a)) -> SBool -> ([Int] -> Symbolic SBool) -> Symbolic InductionStrategy
+mkIndStrategy :: (SymVal a, EqSymbolic (SBV a)) => Maybe (SBool, [ProofObj]) -> Maybe SBool -> (SBool, TPProofRaw (SBV a)) -> SBool -> ([Int] -> Symbolic SBool) -> Symbolic InductionStrategy
 mkIndStrategy mbMeasure mbBaseCase indSteps step indQCInstance = do
         CalcStrategy { calcIntros, calcProofTree, calcQCInstance } <- mkCalcSteps indSteps indQCInstance
         pure $ InductionStrategy { inductionIntros     = calcIntros
@@ -797,7 +823,7 @@
   inductionStrategy result steps = do
        (x, xs, nx, nxs, nxxs) <- mkLVar (Proxy @nxs)
 
-       let bc = result (Forall SL.nil)
+       let bc = result (Forall [])
            ih = internalAxiom "IH" (result (Forall xs))
 
        mkIndStrategy Nothing
@@ -815,7 +841,7 @@
        (x, xs, nx, nxs, nxxs) <- mkLVar (Proxy @nxs)
        (a, na)                <- mkVar  (Proxy @na)
 
-       let bc = result (Forall SL.nil) (Forall a)
+       let bc = result (Forall []) (Forall a)
            ih = internalAxiom "IH" (\(Forall a' :: Forall na a) -> result (Forall xs) (Forall a'))
 
        mkIndStrategy Nothing
@@ -834,7 +860,7 @@
        (a, na)                <- mkVar  (Proxy @na)
        (b, nb)                <- mkVar  (Proxy @nb)
 
-       let bc = result (Forall SL.nil) (Forall a) (Forall b)
+       let bc = result (Forall []) (Forall a) (Forall b)
            ih = internalAxiom "IH" (\(Forall a' :: Forall na a) (Forall b' :: Forall nb b) -> result (Forall xs) (Forall a') (Forall b'))
 
        mkIndStrategy Nothing
@@ -854,7 +880,7 @@
        (b, nb)                <- mkVar  (Proxy @nb)
        (c, nc)                <- mkVar  (Proxy @nc)
 
-       let bc = result (Forall SL.nil) (Forall a) (Forall b) (Forall c)
+       let bc = result (Forall []) (Forall a) (Forall b) (Forall c)
            ih = internalAxiom "IH" (\(Forall a' :: Forall na a) (Forall b' :: Forall nb b) (Forall c' :: Forall nc c) -> result (Forall xs) (Forall a') (Forall b') (Forall c'))
 
        mkIndStrategy Nothing
@@ -875,7 +901,7 @@
        (c, nc)                <- mkVar  (Proxy @nc)
        (d, nd)                <- mkVar  (Proxy @nd)
 
-       let bc = result (Forall SL.nil) (Forall a) (Forall b) (Forall c) (Forall d)
+       let bc = result (Forall []) (Forall a) (Forall b) (Forall c) (Forall d)
            ih = internalAxiom "IH" (\(Forall a' :: Forall na a) (Forall b' :: Forall nb b) (Forall c' :: Forall nc c) (Forall d' :: Forall nd d) -> result (Forall xs) (Forall a') (Forall b') (Forall c') (Forall d'))
 
        mkIndStrategy Nothing
@@ -897,7 +923,7 @@
        (d, nd)                <- mkVar  (Proxy @nd)
        (e, ne)                <- mkVar  (Proxy @ne)
 
-       let bc = result (Forall SL.nil) (Forall a) (Forall b) (Forall c) (Forall d) (Forall e)
+       let bc = result (Forall []) (Forall a) (Forall b) (Forall c) (Forall d) (Forall e)
            ih = internalAxiom "IH" (\(Forall a' :: Forall na a) (Forall b' :: Forall nb b) (Forall c' :: Forall nc c) (Forall d' :: Forall nd d) (Forall e' :: Forall ne e) -> result (Forall xs) (Forall a') (Forall b') (Forall c') (Forall d') (Forall e'))
 
        mkIndStrategy Nothing
@@ -915,7 +941,7 @@
        (x, xs, nx, nxs, nxxs) <- mkLVar (Proxy @nxs)
        (y, ys, ny, nys, nyys) <- mkLVar (Proxy @nys)
 
-       let bc = result (Forall SL.nil, Forall SL.nil) .&& result (Forall SL.nil, Forall (y SL..: ys)) .&& result (Forall (x SL..: xs), Forall SL.nil)
+       let bc = result (Forall [], Forall []) .&& result (Forall [], Forall (y SL..: ys)) .&& result (Forall (x SL..: xs), Forall [])
            ih = internalAxiom "IH" (result (Forall xs, Forall ys))
 
        mkIndStrategy Nothing
@@ -934,7 +960,7 @@
        (y, ys, ny, nys, nyys) <- mkLVar (Proxy @nys)
        (a, na)                <- mkVar  (Proxy @na)
 
-       let bc = result (Forall SL.nil, Forall SL.nil) (Forall a) .&& result (Forall SL.nil, Forall (y SL..: ys)) (Forall a) .&& result (Forall (x SL..: xs), Forall SL.nil) (Forall a)
+       let bc = result (Forall [], Forall []) (Forall a) .&& result (Forall [], Forall (y SL..: ys)) (Forall a) .&& result (Forall (x SL..: xs), Forall []) (Forall a)
            ih = internalAxiom "IH" (\(Forall a' :: Forall na a) -> result (Forall xs, Forall ys) (Forall a'))
 
        mkIndStrategy Nothing
@@ -954,7 +980,7 @@
        (a, na)                <- mkVar  (Proxy @na)
        (b, nb)                <- mkVar  (Proxy @nb)
 
-       let bc = result (Forall SL.nil, Forall SL.nil) (Forall a) (Forall b) .&& result (Forall SL.nil, Forall (y SL..: ys)) (Forall a) (Forall b) .&& result (Forall (x SL..: xs), Forall SL.nil) (Forall a) (Forall b)
+       let bc = result (Forall [], Forall []) (Forall a) (Forall b) .&& result (Forall [], Forall (y SL..: ys)) (Forall a) (Forall b) .&& result (Forall (x SL..: xs), Forall []) (Forall a) (Forall b)
            ih = internalAxiom "IH" (\(Forall a' :: Forall na a) (Forall b' :: Forall nb b) -> result (Forall xs, Forall ys) (Forall a') (Forall b'))
 
        mkIndStrategy Nothing
@@ -975,7 +1001,7 @@
        (b, nb)                <- mkVar  (Proxy @nb)
        (c, nc)                <- mkVar  (Proxy @nc)
 
-       let bc = result (Forall SL.nil, Forall SL.nil) (Forall a) (Forall b) (Forall c) .&& result (Forall SL.nil, Forall (y SL..: ys)) (Forall a) (Forall b) (Forall c) .&& result (Forall (x SL..: xs), Forall SL.nil) (Forall a) (Forall b) (Forall c)
+       let bc = result (Forall [], Forall []) (Forall a) (Forall b) (Forall c) .&& result (Forall [], Forall (y SL..: ys)) (Forall a) (Forall b) (Forall c) .&& result (Forall (x SL..: xs), Forall []) (Forall a) (Forall b) (Forall c)
            ih = internalAxiom "IH" (\(Forall a' :: Forall na a) (Forall b' :: Forall nb b) (Forall c' :: Forall nc c) -> result (Forall xs, Forall ys) (Forall a') (Forall b') (Forall c'))
 
        mkIndStrategy Nothing
@@ -997,7 +1023,7 @@
        (c, nc)                <- mkVar  (Proxy @nc)
        (d, nd)                <- mkVar  (Proxy @nd)
 
-       let bc = result (Forall SL.nil, Forall SL.nil) (Forall a) (Forall b) (Forall c) (Forall d) .&& result (Forall SL.nil, Forall (y SL..: ys)) (Forall a) (Forall b) (Forall c) (Forall d) .&& result (Forall (x SL..: xs), Forall SL.nil) (Forall a) (Forall b) (Forall c) (Forall d)
+       let bc = result (Forall [], Forall []) (Forall a) (Forall b) (Forall c) (Forall d) .&& result (Forall [], Forall (y SL..: ys)) (Forall a) (Forall b) (Forall c) (Forall d) .&& result (Forall (x SL..: xs), Forall []) (Forall a) (Forall b) (Forall c) (Forall d)
            ih = internalAxiom "IH" (\(Forall a' :: Forall na a) (Forall b' :: Forall nb b) (Forall c' :: Forall nc c) (Forall d' :: Forall nd d) -> result (Forall xs, Forall ys) (Forall a') (Forall b') (Forall c') (Forall d'))
 
        mkIndStrategy Nothing
@@ -1020,7 +1046,7 @@
        (d, nd)                <- mkVar  (Proxy @nd)
        (e, ne)                <- mkVar  (Proxy @ne)
 
-       let bc = result (Forall SL.nil, Forall SL.nil) (Forall a) (Forall b) (Forall c) (Forall d) (Forall e) .&& result (Forall SL.nil, Forall (y SL..: ys)) (Forall a) (Forall b) (Forall c) (Forall d) (Forall e) .&& result (Forall (x SL..: xs), Forall SL.nil) (Forall a) (Forall b) (Forall c) (Forall d) (Forall e)
+       let bc = result (Forall [], Forall []) (Forall a) (Forall b) (Forall c) (Forall d) (Forall e) .&& result (Forall [], Forall (y SL..: ys)) (Forall a) (Forall b) (Forall c) (Forall d) (Forall e) .&& result (Forall (x SL..: xs), Forall []) (Forall a) (Forall b) (Forall c) (Forall d) (Forall e)
            ih = internalAxiom "IH" (\(Forall a' :: Forall na a) (Forall b' :: Forall nb b) (Forall c' :: Forall nc c) (Forall d' :: Forall nd d) (Forall e' :: Forall ne e) -> result (Forall xs, Forall ys) (Forall a') (Forall b') (Forall c') (Forall d') (Forall e'))
 
        mkIndStrategy Nothing
@@ -1031,13 +1057,13 @@
 
 -- | Generalized induction with one parameter
 instance (KnownSymbol na, SymVal a) => SInductive (Forall na a -> SBool) where
-  sInductionStrategy result measure steps = do
+  sInductionStrategy result (measure, helpers) steps = do
       (a, na) <- mkVar (Proxy @na)
 
       let ih   = internalAxiom "IH" (\(Forall a' :: Forall na a) -> measure a' .< measure a .=> result (Forall a'))
           conc = result (Forall a)
 
-      mkIndStrategy (Just (measure a .>= zero))
+      mkIndStrategy (Just (nonNeg (measure a), helpers))
                     Nothing
                     (steps ih a)
                     (indResult [na] conc)
@@ -1045,14 +1071,14 @@
 
 -- | Generalized induction with two parameters
 instance (KnownSymbol na, SymVal a, KnownSymbol nb, SymVal b) => SInductive (Forall na a -> Forall nb b -> SBool) where
-  sInductionStrategy result measure steps = do
+  sInductionStrategy result (measure, helpers) steps = do
       (a, na) <- mkVar (Proxy @na)
       (b, nb) <- mkVar (Proxy @nb)
 
       let ih   = internalAxiom "IH" (\(Forall a' :: Forall na a) (Forall b' :: Forall nb b) -> measure a' b' .< measure a b .=> result (Forall a') (Forall b'))
           conc = result (Forall a) (Forall b)
 
-      mkIndStrategy (Just (measure a b .>= zero))
+      mkIndStrategy (Just (nonNeg (measure a b), helpers))
                     Nothing
                     (steps ih a b)
                     (indResult [na, nb] conc)
@@ -1060,7 +1086,7 @@
 
 -- | Generalized induction with three parameters
 instance (KnownSymbol na, SymVal a, KnownSymbol nb, SymVal b, KnownSymbol nc, SymVal c) => SInductive (Forall na a -> Forall nb b -> Forall nc c -> SBool) where
-  sInductionStrategy result measure steps = do
+  sInductionStrategy result (measure, helpers) steps = do
       (a, na) <- mkVar (Proxy @na)
       (b, nb) <- mkVar (Proxy @nb)
       (c, nc) <- mkVar (Proxy @nc)
@@ -1068,7 +1094,7 @@
       let ih   = internalAxiom "IH" (\(Forall a' :: Forall na a) (Forall b' :: Forall nb b) (Forall c' :: Forall nc c) -> measure a' b' c' .< measure a b c .=> result (Forall a') (Forall b') (Forall c'))
           conc = result (Forall a) (Forall b) (Forall c)
 
-      mkIndStrategy (Just (measure a b c .>= zero))
+      mkIndStrategy (Just (nonNeg (measure a b c), helpers))
                     Nothing
                     (steps ih a b c)
                     (indResult [na, nb, nc] conc)
@@ -1076,7 +1102,7 @@
 
 -- | Generalized induction with four parameters
 instance (KnownSymbol na, SymVal a, KnownSymbol nb, SymVal b, KnownSymbol nc, SymVal c, KnownSymbol nd, SymVal d) => SInductive (Forall na a -> Forall nb b -> Forall nc c -> Forall nd d -> SBool) where
-  sInductionStrategy result measure steps = do
+  sInductionStrategy result (measure, helpers) steps = do
       (a, na) <- mkVar (Proxy @na)
       (b, nb) <- mkVar (Proxy @nb)
       (c, nc) <- mkVar (Proxy @nc)
@@ -1085,7 +1111,7 @@
       let ih   = internalAxiom "IH" (\(Forall a' :: Forall na a) (Forall b' :: Forall nb b) (Forall c' :: Forall nc c) (Forall d' :: Forall nd d) -> measure a' b' c' d' .< measure a b c d .=> result (Forall a') (Forall b') (Forall c') (Forall d'))
           conc = result (Forall a) (Forall b) (Forall c) (Forall d)
 
-      mkIndStrategy (Just (measure a b c d .>= zero))
+      mkIndStrategy (Just (nonNeg (measure a b c d), helpers))
                     Nothing
                     (steps ih a b c d)
                     (indResult [na, nb, nc, nd] conc)
@@ -1093,7 +1119,7 @@
 
 -- | Generalized induction with five parameters
 instance (KnownSymbol na, SymVal a, KnownSymbol nb, SymVal b, KnownSymbol nc, SymVal c, KnownSymbol nd, SymVal d, KnownSymbol ne, SymVal e) => SInductive (Forall na a -> Forall nb b -> Forall nc c -> Forall nd d -> Forall ne e -> SBool) where
-  sInductionStrategy result measure steps = do
+  sInductionStrategy result (measure, helpers) steps = do
       (a, na) <- mkVar (Proxy @na)
       (b, nb) <- mkVar (Proxy @nb)
       (c, nc) <- mkVar (Proxy @nc)
@@ -1103,7 +1129,7 @@
       let ih   = internalAxiom "IH" (\(Forall a' :: Forall na a) (Forall b' :: Forall nb b) (Forall c' :: Forall nc c) (Forall d' :: Forall nd d) (Forall e' :: Forall ne e) -> measure a' b' c' d' e' .< measure a b c d e .=> result (Forall a') (Forall b') (Forall c') (Forall d') (Forall e'))
           conc = result (Forall a) (Forall b) (Forall c) (Forall d) (Forall e)
 
-      mkIndStrategy (Just (measure a b c d e .>= zero))
+      mkIndStrategy (Just (nonNeg (measure a b c d e), helpers))
                     Nothing
                     (steps ih a b c d e)
                     (indResult [na, nb, nc, nd, ne] conc)
@@ -1516,18 +1542,42 @@
 (⟹) = (==>)
 infix 0 ⟹
 
--- | Recalling a proof. This essentially sets the verbose output off during this proof. Note that
--- if we're doing stats, we ignore this as the whole point of doing stats is to see steps in detail.
-recall :: String -> TP (Proof a) -> TP (Proof a)
-recall nm prf = do
-  cfg <- getTPConfig
-  if printStats (tpOptions cfg)
-     then prf
-     else do tab <- liftIO $ startTP cfg (verbose cfg) "Lemma" 0 (TPProofOneShot nm [])
-             setTPConfig cfg{tpOptions = (tpOptions cfg) {quiet = True}}
-             r@Proof{proofOf = ProofObj{dependencies}} <- prf
-             setTPConfig cfg
-             liftIO $ finishTP cfg ("Q.E.D." ++ concludeModulo dependencies) (tab, Nothing) []
-             pure r
+-- | Recalling a proof. If the proposition was previously proved and cached, the cached result
+-- is returned without re-proving. The output is kept brief: a single "Q.E.D." line.
+-- If stats mode is on, we show the full proof steps as the point of stats is to see detail.
+recall :: TP (Proof a) -> TP (Proof a)
+recall prf = getTPConfig >>= \cfg -> recallWith cfg prf
 
-{- HLint ignore module "Eta reduce" -}
+-- | Recalling a proof, using a given config. Sets the recall context flag so that
+-- proof engines check the cache before proving.
+recallWith :: SMTConfig -> TP (Proof a) -> TP (Proof a)
+recallWith cfgIn prf = do
+  topCfg <- getTPConfig
+  tpSt   <- getTPState
+  let cfg@SMTConfig{tpOptions = TPOptions{printStats}} = cfgIn `tpMergeCfg` topCfg
+  -- Set recall context so proof engines check the cache
+  liftIO $ modifyIORef' (inRecallContext tpSt) (+1)
+  let cleanup = liftIO $ modifyIORef' (inRecallContext tpSt) (subtract 1)
+  if printStats
+     then restoring cfg topCfg $ do r <- prf
+                                    cleanup
+                                    pure r
+     else do let new = cfg{tpOptions = (tpOptions cfg) {quiet = True}}
+             restoring new topCfg $ do
+                 res <- tryTP prf
+                 cleanup
+                 case res of
+                   Left (_ :: SomeException) ->
+                     -- Re-run with original config so failure details are visible
+                     restoring cfg topCfg prf >> pure (error "unreachable")
+                   Right r@Proof{proofOf = po@ProofObj{dependencies, aliases = aka, wasCached = cached}} -> do
+                     let nm = proofName po
+                     liftIO $ printLemmaResult cfg (verbose cfg) nm dependencies cached aka
+                     pure r
+ where restoring new old act = do setTPConfig new
+                                  res <- act
+                                  setTPConfig old
+                                  pure res
+
+{- HLint ignore module "Eta reduce"         -}
+{- HLint ignore module "Reduce duplication" -}
diff --git a/Data/SBV/TP/Utils.hs b/Data/SBV/TP/Utils.hs
--- a/Data/SBV/TP/Utils.hs
+++ b/Data/SBV/TP/Utils.hs
@@ -23,17 +23,22 @@
 {-# OPTIONS_GHC -Wall -Werror #-}
 
 module Data.SBV.TP.Utils (
-         TP, runTP, runTPWith, Proof(..), ProofObj(..), assumptionFromProof, sorry, quickCheckProof
+         TP, runTP, runTPWith, tryTP, whenDryRun, unlessDryRun, Proof(..), ProofObj(..), assumptionFromProof, sorry, quickCheckProof, noTermCheckProof
        , startTP, finishTP, getTPState, getTPConfig, setTPConfig, tpGetNextUnique, TPState(..), TPStats(..), RootOfTrust(..)
-       , TPProofContext(..), message, updStats, rootOfTrust, concludeModulo
-       , ProofTree(..), TPUnique(..), showProofTree, showProofTreeHTML, shortProofName
-       , withProofCache
-       , tpQuiet, tpRibbon, tpAsms, tpStats, tpCache
+       , TPProofContext(..), message, updStats, rootOfTrust, concludeModulo, printLemmaResult
+       , ProofTree(..), TPUnique(..), showProofTree, showProofTreeHTML
+       , addToProofCache, lookupProofCache, returnCachedProof
+       , tpQuiet, tpAsms, tpStats
+       , measureLemma, measureLemmaWith
        ) where
 
-import Control.Monad.Reader (ReaderT, runReaderT, MonadReader, ask, liftIO)
+import Control.Exception    (Exception, try)
+import Control.Monad        (unless, when)
+import Control.Monad.Reader (ReaderT(..), runReaderT, MonadReader, ask, liftIO)
 import Control.Monad.Trans  (MonadIO)
 
+import Data.Generics (everywhere, mkT)
+
 import Data.Time (NominalDiffTime)
 
 import Data.Tree
@@ -43,7 +48,7 @@
 import Data.Typeable (typeOf, TypeRep)
 
 import Data.Char (isSpace)
-import Data.List (intercalate, isPrefixOf, isSuffixOf, isInfixOf, nubBy, partition, sort)
+import Data.List (intercalate, isPrefixOf, isSuffixOf, isInfixOf, nub, sort, dropWhileEnd)
 import Data.Int  (Int64)
 
 import Data.SBV.Utils.Lib (unQuote)
@@ -51,57 +56,137 @@
 import System.IO     (hFlush, stdout)
 import System.Random (randomIO)
 
-import Data.SBV.Core.Data      (SBool, Forall(..), quantifiedBool)
-import Data.SBV.Core.Model     (label)
-import Data.SBV.Core.Symbolic  (SMTConfig, TPOptions(..))
+import Data.SBV.Core.Data      (SBool, sTrue, Forall(..), QuantifiedBool, quantifiedBool, SBV(..), SV(..), NodeId(..), SBVExpr(..), SBVPgm(..), Op(..), CV(..))
+import Data.SBV.Core.Model     (label, MeasureHelper(..))
+import Data.SBV.Core.Symbolic  (SMTConfig, TPOptions(..), State(..), mkNewState, svToSV, SBVRunMode(..), globalSBVContext)
 import Data.SBV.Provers.Prover (defaultSMTCfg, SMTConfig(..))
 
 import Data.SBV.Utils.TDiff (showTDiff, timeIf)
 import Control.DeepSeq (NFData(rnf))
 
+import Data.Foldable (toList)
 import Data.IORef
 
 import GHC.Generics
 import Data.Dynamic
 
-import qualified Data.Map as Map
-import Data.Map (Map)
+import qualified Data.Map.Strict as Map
 
+import qualified Data.Set as Set
+import Data.Set (Set)
+
 -- | Various statistics we collect
-data TPStats = TPStats { noOfCheckSats :: Int
-                       , solverElapsed :: NominalDiffTime
-                       , qcElapsed     :: NominalDiffTime
+data TPStats = TPStats { noOfCheckSats :: !Int
+                       , solverElapsed :: !NominalDiffTime
+                       , qcElapsed     :: !NominalDiffTime
                        }
 
 -- | Extra state we carry in a TP context
-data TPState = TPState { stats      :: IORef TPStats
-                       , proofCache :: IORef (Map (String, TypeRep) ProofObj)
-                       , config     :: IORef SMTConfig
+data TPState = TPState { stats               :: IORef TPStats
+                       , proofCache          :: IORef (Map.Map (PropFingerprint, TypeRep) [ProofObj])
+                       , config              :: IORef SMTConfig
+                       , inRecallContext     :: IORef Int
+                       , measuresVerified    :: IORef (Set String)
+                       , productiveVerified  :: IORef (Set String)
+                       , measuresEncountered :: IORef (Set String)
+                       , dryRun              :: IORef Bool    -- ^ If True, collecting ribbon widths (no proving)
+                       , maxRibbon           :: IORef Int     -- ^ Session-wide maximum ribbon length
                        }
 
 -- | Monad for running TP proofs in.
 newtype TP a = TP (ReaderT TPState IO a)
             deriving newtype (Applicative, Functor, Monad, MonadIO, MonadReader TPState, MonadFail)
 
--- | If caches are enabled, see if we cached this proof and return it; otherwise generate it, cache it, and return it
-withProofCache :: forall a. Typeable a => String -> TP (Proof a) -> TP (Proof a)
-withProofCache nm genProof = do
-  TPState{proofCache, config} <- getTPState
-  cfg@SMTConfig {tpOptions = TPOptions {cacheProofs}} <- liftIO $ readIORef config
+-- | Run a TP action, catching exceptions.
+tryTP :: Exception e => TP a -> TP (Either e a)
+tryTP (TP act) = TP $ ReaderT $ \st -> try (runReaderT act st)
 
-  let key = (nm, typeOf (Proxy @a))
+-- | Run an action only during the dry-run pass.
+whenDryRun :: TP () -> TP ()
+whenDryRun act = do st <- ask
+                    isDry <- liftIO $ readIORef (dryRun st)
+                    when isDry act
 
-  if not cacheProofs
-     then genProof
-     else do cache <- liftIO $ readIORef proofCache
-             case key `Map.lookup` cache of
-               Just prf -> do liftIO $ do tab <- startTP cfg False "Cached" 0 (TPProofOneShot nm [])
-                                          finishTP cfg "Q.E.D." (tab, Nothing) []
-                              pure $ Proof prf{isCached = True}
-               Nothing  -> do p <- genProof
-                              liftIO $ modifyIORef' proofCache (Map.insert key (proofOf p))
-                              pure p
+-- | Run an action only during the real (non-dry-run) pass. Useful for guarding user-facing output
+-- (e.g., proof tree printing) that should be suppressed during ribbon calculation.
+unlessDryRun :: TP () -> TP ()
+unlessDryRun act = do st <- ask
+                      isDry <- liftIO $ readIORef (dryRun st)
+                      unless isDry act
 
+-- | Extract the integer node ID from an SV.
+svIntId :: SV -> Int
+svIntId (SV _ (NodeId (_, _, i))) = i
+
+-- | Zero out the SBVContext in an SV, keeping only the kind and integer node ID.
+-- Used to normalize 'Op' values for fingerprinting.
+zeroSV :: SV -> SV
+zeroSV (SV k (NodeId (_, mb, i))) = SV k (NodeId (globalSBVContext, mb, i))
+
+-- | Zero out all embedded SBVContext values inside an 'Op' using SYB generic traversal.
+-- This automatically handles all current and future Op constructors that embed SV's.
+zeroContextInOp :: Op -> Op
+zeroContextInOp = everywhere (mkT zeroSV)
+
+-- | Fingerprint of a proposition's symbolic expression DAG.
+-- Computed by evaluating 'quantifiedBool' in a fresh State and extracting
+-- the expression program (with embedded SV contexts zeroed out via SYB),
+-- the constant map (mapping constant values to their SV int IDs), and the final result SV.
+-- Two identical propositions evaluated in identically-initialized States produce
+-- identical fingerprints. Different propositions diverge somewhere in variable creation,
+-- expression construction, or hash-consing, producing different fingerprints.
+newtype PropFingerprint = PropFingerprint ([(CV, Int)], [(Int, Op, [Int])], Int)
+  deriving (Eq, Ord)
+
+-- | Compute the fingerprint of a proposition by evaluating it in a fresh
+-- lightweight State (no solver connection needed). The State is created via
+-- 'mkNewState' with 'LambdaGen' mode, which initializes all counters identically
+-- without starting a solver process.
+propFingerprint :: QuantifiedBool a => a -> IO PropFingerprint
+propFingerprint prop = do
+  st  <- mkNewState defaultSMTCfg (LambdaGen Nothing)
+  sv  <- svToSV st (unSBV (quantifiedBool prop))
+  pgm <- readIORef (spgm st)
+  cm  <- readIORef (rconstMap st)
+  let entries = [ (svIntId target, zeroContextInOp op, map svIntId args)
+                | (target, SBVApp op args) <- toList (pgmAssignments pgm)
+                ]
+      consts  = [(c, svIntId s) | (c, s) <- Map.toAscList cm]
+  pure $ PropFingerprint (consts, entries, svIntId sv)
+
+-- | After proving a proposition, add the proof to the cache for future recall lookups.
+addToProofCache :: forall a. (Typeable a, QuantifiedBool a) => a -> ProofObj -> TP ()
+addToProofCache prop prf = do
+  TPState{proofCache} <- getTPState
+  fp <- liftIO $ propFingerprint prop
+  let key = (fp, typeOf (Proxy @a))
+  liftIO $ modifyIORef' proofCache $ Map.insertWith (\_ old -> prf : old) key [prf]
+
+-- | Look up a cached proof for the given proposition. Only succeeds when in recall context
+-- (i.e., called from within a recall wrapper). On cache hit, the returned ProofObj has
+-- its 'aliases' field populated with the names of other proofs of the same proposition.
+lookupProofCache :: forall a. (Typeable a, QuantifiedBool a) => a -> TP (Maybe ProofObj)
+lookupProofCache prop = do
+  TPState{proofCache, inRecallContext} <- getTPState
+  inRecall <- liftIO $ readIORef inRecallContext
+  if inRecall == 0
+     then pure Nothing
+     else do fp <- liftIO $ propFingerprint prop
+             let key = (fp, typeOf (Proxy @a))
+             cache <- liftIO $ readIORef proofCache
+             pure $ case reverse <$> Map.lookup key cache of
+               Nothing     -> Nothing
+               Just []     -> Nothing
+               Just (p:ps) -> Just p { aliases = [proofName q | q <- ps] }
+
+-- | Return a cached proof, printing a brief "Q.E.D." line with optional "a.k.a." annotation.
+returnCachedProof :: SMTConfig -> String -> ProofObj -> TP (Proof a)
+returnCachedProof cfg nm prf = do
+   let aka  = filter (/= nm) $ nub $ proofName prf : aliases prf
+       prf' = prf { proofName = nm, wasCached = True, aliases = aka }
+   liftIO $ printLemmaResult cfg False nm (dependencies prf) True aka
+   pure $ Proof prf'
+
 -- | The context in which we make a check-sat call
 data TPProofContext = TPProofOneShot String      -- ^ A one shot proof, with string containing its name
                                      [ProofObj]  -- ^ Helpers used (latter only used for cex generation)
@@ -117,10 +202,59 @@
 -- | Run a TP proof, using the given configuration.
 runTPWith :: SMTConfig -> TP a -> IO a
 runTPWith cfg@SMTConfig{tpOptions = TPOptions{printStats}} (TP f) = do
-   rStats <- newIORef $ TPStats { noOfCheckSats = 0, solverElapsed = 0, qcElapsed = 0 }
-   rCache <- newIORef Map.empty
-   rCfg   <- newIORef cfg
-   (mbT, r) <- timeIf printStats $ runReaderT f TPState {config = rCfg, stats = rStats, proofCache = rCache}
+   rDryRun    <- newIORef True
+   rMaxRibbon <- newIORef 0
+
+   let runPass c = do
+         rStats       <- newIORef $ TPStats { noOfCheckSats = 0, solverElapsed = 0, qcElapsed = 0 }
+         rCache       <- newIORef Map.empty
+         rCfg         <- newIORef c
+         rRecall      <- newIORef (0 :: Int)
+         rMeasures    <- newIORef Set.empty
+         rProductive  <- newIORef Set.empty
+         rEncountered <- newIORef Set.empty
+         let st = TPState { config               = rCfg
+                           , stats               = rStats
+                           , proofCache          = rCache
+                           , inRecallContext     = rRecall
+                           , measuresVerified    = rMeasures
+                           , productiveVerified  = rProductive
+                           , measuresEncountered = rEncountered
+                           , dryRun              = rDryRun
+                           , maxRibbon           = rMaxRibbon
+                           }
+         a <- runReaderT f st
+         pure (a, st)
+
+   -- Pass 1: Dry run to collect ribbon widths
+   _ <- runPass ((tpQuiet True cfg){verbose = False})
+
+   -- Pass 2: Real run with computed ribbon
+   writeIORef rDryRun False
+   ribbon <- readIORef rMaxRibbon
+   let cfg' = cfg{tpOptions = (tpOptions cfg) { ribbonLength = max 20 (ribbon + 4) }}
+
+   (mbT, (r, TPState{stats = rStats, measuresVerified = rMeasures, productiveVerified = rProductive, measuresEncountered = rEncountered}))
+       <- timeIf printStats $ runPass cfg'
+
+   -- Print verified measures and productive functions
+   verified    <- readIORef rMeasures
+   productive  <- readIORef rProductive
+   encountered <- readIORef rEncountered
+
+   unless (Set.null verified)   $ printMeasures   cfg' (Set.toAscList verified)
+   unless (Set.null productive) $ printProductive cfg' (Set.toAscList productive)
+
+   -- Belt-and-suspenders: make sure all encountered measures have been verified.
+   -- Exclude functions in measuresBeingVerified: those are being verified by an outer caller
+   -- (e.g., when a measureLemma proof uses the function whose measure is being checked).
+   let beingVerified = measuresBeingVerified (tpOptions cfg)
+       missed = encountered `Set.difference` verified `Set.difference` productive `Set.difference` beingVerified
+
+   unless (Set.null missed) $
+     error $ "SBV.runTP: Internal error: The following functions have termination measures that were encountered but not verified: "
+           ++ intercalate ", " (Set.toAscList missed)
+
    case mbT of
      Nothing -> pure ()
      Just t  -> do TPStats noOfCheckSats solverTime qcElapsed <- readIORef rStats
@@ -132,7 +266,7 @@
                                , ("Decisions", show noOfCheckSats)
                                ]
 
-                   message cfg $ '[' : intercalate ", " [k ++ ": " ++ v | (k, v) <- stats] ++ "]\n"
+                   message cfg' $ '[' : intercalate ", " [k ++ ": " ++ v | (k, v) <- stats] ++ "]\n"
    pure r
 
 -- | get the state
@@ -159,15 +293,52 @@
 
 -- | Display the message if not quiet. Note that we don't print a newline; so the message must have it if needed.
 message :: MonadIO m => SMTConfig -> String -> m ()
-message SMTConfig{tpOptions = TPOptions{quiet}} s
-  | quiet = pure ()
-  | True  = liftIO $ putStr s
+message SMTConfig{tpOptions = TPOptions{quiet}, redirectVerbose} s
+  | quiet
+  = pure ()
+  | Just f <- redirectVerbose
+  = liftIO $ appendFile f s
+  | True
+  = liftIO $ putStr s >> hFlush stdout
 
+-- | Print the list of functions whose termination measures have been verified.
+printMeasures :: SMTConfig -> [String] -> IO ()
+printMeasures = printFunctions "Functions proven terminating"
+
+-- | Print the list of functions whose productivity (guardedness) has been verified.
+printProductive :: SMTConfig -> [String] -> IO ()
+printProductive = printFunctions "Functions proven productive"
+
+-- | Print a list of function names under a header, wrapping lines to avoid excessively long output.
+-- If the list fits on one line, it follows the header directly. Otherwise, it starts on a new line.
+printFunctions :: String -> SMTConfig -> [String] -> IO ()
+printFunctions header cfg names
+  | length oneLine <= limit = message cfg $ header ++ ": " ++ oneLine ++ "\n"
+  | True                    = message cfg $ header ++ ":\n  " ++ wrapped ++ "\n"
+  where cleaned = nub (sort (map strip names))
+        strip   = dropWhileEnd (== ' ') . takeWhile (/= '@')
+
+        limit = 90
+
+        oneLine = intercalate ", " cleaned
+
+        wrapped = go limit cleaned
+
+        go _ []     = ""
+        go _ [n]    = n
+        go r (n:ns) = let len  = length n + 2  -- account for ", "
+                          rest = go (r - len) ns
+                      in if r - len < 0 && r /= limit
+                         then "\n  " ++ go limit (n:ns)
+                         else case rest of
+                                '\n':_ -> n ++ "," ++ rest
+                                _      -> n ++ ", " ++ rest
+
 -- | Start a proof. We return the number of characters we printed, so the finisher can align the result.
 startTP :: SMTConfig -> Bool -> String -> Int -> TPProofContext -> IO Int
 startTP cfg newLine what level ctx = do message cfg $ line ++ if newLine then "\n" else ""
                                         hFlush stdout
-                                        return (length line)
+                                        pure (length line)
   where nm = case ctx of
                TPProofOneShot n _       -> n
                TPProofStep    _ _ hs ss -> intercalate "." ss ++ userHints hs
@@ -189,11 +360,12 @@
        mkTiming t = '[' : showTDiff t ++ "]"
 
 -- | Unique identifier for each proof.
-data TPUnique = TPInternal    -- IH's
-              | TPSorry       -- sorry
-              | TPQC          -- qc (quick-check)
-              | TPUser Int64  -- user given
-              deriving (NFData, Generic, Eq)
+data TPUnique = TPInternal        -- IH's
+              | TPSorry           -- sorry
+              | TPQC              -- qc (quick-check)
+              | TPNoTermCheck     -- no termination check (smtFunctionNoTermination)
+              | TPUser Int64      -- user given
+              deriving (NFData, Generic, Eq, Ord)
 
 -- | Proof for a property. This type is left abstract, i.e., the only way to create on is via a
 -- call to lemma/theorem etc., ensuring soundness. (Note that the trusted-code base here
@@ -214,7 +386,8 @@
                          , getProp      :: Dynamic        -- ^ The actual proposition
                          , proofName    :: String         -- ^ User given name
                          , uniqId       :: TPUnique       -- ^ Unique identifier
-                         , isCached     :: Bool           -- ^ Was this a cached proof?
+                         , aliases      :: [String]       -- ^ Other names for proofs of the same proposition (populated on cache hit)
+                         , wasCached    :: Bool           -- ^ Was this proof retrieved from the cache?
                          }
 
 -- | Drop the instantiation part
@@ -223,6 +396,26 @@
                  | True                = s
    where s = proofName p
 
+-- | Deduplicate proof objects by their unique id, keeping the first occurrence.
+-- Same result as @nubBy ((==) \`on\` uniqId)@, but O(n log n) instead of O(n^2).
+nubByUniqId :: [ProofObj] -> [ProofObj]
+nubByUniqId = go Set.empty
+  where go _    []     = []
+        go seen (p:ps)
+          | u `Set.member` seen =     go seen ps
+          | True                = p : go (Set.insert u seen) ps
+          where u = uniqId p
+
+-- | Nicely format a bunch of proof-names, shortened and uniquified. Note that if we get a dependency
+-- via multiple routes, they can get different uniqid's; so we do a bit of compression here.
+shortProofNames :: [ProofObj] -> String
+shortProofNames = intercalate ", " . map merge . compress . sort . map shortProofName . nubByUniqId
+ where compress []     = []
+       compress (a:as) = case span (a ==) as of
+                           (same, other) -> (a, length same + 1) : compress other
+       merge (n, 1) = n
+       merge (n, x) = n ++ " (x" ++ show x ++ ")"
+
 -- | Keeping track of where the sorry originates from. Used in displaying dependencies.
 newtype RootOfTrust = RootOfTrust (Maybe [ProofObj])
 
@@ -230,11 +423,11 @@
 instance Show RootOfTrust where
   show (RootOfTrust mbp) = case mbp of
                              Nothing -> "Nothing"
-                             Just ps -> "Just [" ++ intercalate ", " (map shortProofName ps) ++ "]"
+                             Just ps -> "Just [" ++ shortProofNames ps ++ "]"
 
 -- | Trust forms a semigroup
 instance Semigroup RootOfTrust where
-   RootOfTrust as <> RootOfTrust bs = RootOfTrust $ nubBy (\a b -> uniqId a == uniqId b) <$> (as <> bs)
+   RootOfTrust as <> RootOfTrust bs = RootOfTrust $ nubByUniqId <$> (as <> bs)
 
 -- | Trust forms a monoid
 instance Monoid RootOfTrust where
@@ -242,12 +435,13 @@
 
 -- | NFData ignores the getProp field
 instance NFData ProofObj where
-  rnf (ProofObj dependencies isUserAxiom getObjProof _getProp proofName uniqId isCached) =     rnf dependencies
-                                                                                         `seq` rnf isUserAxiom
-                                                                                         `seq` rnf getObjProof
-                                                                                         `seq` rnf proofName
-                                                                                         `seq` rnf uniqId
-                                                                                         `seq` rnf isCached
+  rnf (ProofObj dependencies isUserAxiom getObjProof _getProp proofName uniqId aliases wasCached) =     rnf dependencies
+                                                                                                 `seq` rnf isUserAxiom
+                                                                                                 `seq` rnf getObjProof
+                                                                                                 `seq` rnf proofName
+                                                                                                 `seq` rnf uniqId
+                                                                                                 `seq` rnf aliases
+                                                                                                 `seq` rnf wasCached
 
 -- | Dependencies of a proof, in a tree format.
 data ProofTree = ProofTree ProofObj [ProofTree]
@@ -274,10 +468,11 @@
 
         -- Don't show internal axioms, not interesting
         interesting (ProofTree p _) = case uniqId p of
-                                        TPInternal -> False
-                                        TPSorry    -> True
-                                        TPQC       -> True
-                                        TPUser{}   -> True
+                                        TPInternal    -> False
+                                        TPSorry       -> True
+                                        TPQC          -> True
+                                        TPNoTermCheck -> True
+                                        TPUser{}      -> True
 
         -- If a proof is used twice in the same proof, compress it
         compress :: [ProofTree] -> [(Int, ProofTree)]
@@ -316,25 +511,26 @@
 
 -- | Show instance for t'Proof'
 instance Typeable a => Show (Proof a) where
-  show p@(Proof po@ProofObj{proofName = nm}) = '[' : sh (rootOfTrust p) ++ "] " ++ nm ++ " :: " ++ pretty (show (typeOf p))
-    where sh (RootOfTrust Nothing)   = "Proven" ++ cacheInfo
-          sh (RootOfTrust (Just ps)) = "Modulo: " ++ join ps ++ cacheInfo
-
-          join = intercalate ", " . sort . map shortProofName
-
-          cacheInfo = case cachedProofs po of
-                        [] -> ""
-                        cs -> ". Cached: " ++ join (nubBy (\p1 p2 -> uniqId p1 == uniqId p2) cs)
-
-          cachedProofs prf@ProofObj{isCached} = if isCached then prf : rest else rest
-            where rest = concatMap cachedProofs (dependencies prf)
+  show p@(Proof ProofObj{proofName = nm}) = '[' : sh (rootOfTrust p) ++ "] " ++ nm ++ " :: " ++ pretty (show (typeOf p))
+    where sh (RootOfTrust Nothing)   = "Proven"
+          sh (RootOfTrust (Just ps)) = "Modulo: " ++ shortProofNames ps
 
           -- More mathematical notation for types.
           pretty :: String -> String
-          pretty = unwords . walk . words . concatMap (\c -> if c == ',' then " , " else [c]) . clean
+          pretty = charToString . compress . unwords . walk . words . concatMap (\c -> if c == ',' then " , " else [c]) . clean
             where fa v = ['Ɐ' : unQuote v, "∷"]
                   ex v = ['∃' : unQuote v, "∷"]
 
+                  -- Remove spaces before commas: "foo , bar" -> "foo, bar"
+                  compress (' ' : ',' : rest) = compress (',' : rest)
+                  compress (c : rest)         = c : compress rest
+                  compress []                 = []
+
+                  -- Replace [Char] with String everywhere
+                  charToString ('[':'C':'h':'a':'r':']':rest) = "String" ++ charToString rest
+                  charToString (c:rest)                       = c : charToString rest
+                  charToString []                             = []
+
                   walk ("SBV"    : "Bool" : rest) = walk $ "Bool" :  rest
                   walk ("Forall" : xs     : rest) = walk $ fa xs  ++ rest
                   walk ("Exists" : xs     : rest) = walk $ ex xs  ++ rest
@@ -373,7 +569,8 @@
                  , getProp      = toDyn p
                  , proofName    = "sorry"
                  , uniqId       = TPSorry
-                 , isCached     = False
+                 , aliases      = []
+                 , wasCached    = False
                  }
   where -- ideally, I'd rather just use
         --   p = sFalse
@@ -391,7 +588,8 @@
                            , getProp      = toDyn p
                            , proofName    = "quickCheck"
                            , uniqId       = TPQC
-                           , isCached     = False
+                           , aliases      = []
+                           , wasCached    = False
                            }
   where -- ideally, I'd rather just use
         --   p = sFalse
@@ -401,16 +599,32 @@
         -- solver to determine as false, we avoid the constant folding.
         p (Forall @"__sbvTP_quickCheck" (x :: SBool)) = label "QUICKCHECK: TP, proof uses \"qc\"" x
 
+-- | A proof object representing a function whose termination was not checked.
+-- When a function is defined with 'Data.SBV.smtFunctionNoTermination', its termination
+-- is assumed but not proven. Any proof that depends on such a function will be
+-- marked as modulo this assumption in its root of trust.
+noTermCheckProof :: String -> ProofObj
+noTermCheckProof nm = ProofObj { dependencies = []
+                               , isUserAxiom  = False
+                               , getObjProof  = sTrue
+                               , getProp      = toDyn True
+                               , proofName    = nm ++ " termination"
+                               , uniqId       = TPNoTermCheck
+                               , aliases      = []
+                               , wasCached    = False
+                               }
+
 -- | Calculate the root of trust. The returned list of proofs, if any, will need to be sorry and quickcheck free to
 -- have the given proof to be sorry-free.
 rootOfTrust :: Proof a -> RootOfTrust
 rootOfTrust = rot True . proofOf
   where rot atTop p@ProofObj{uniqId = curUniq, dependencies} = compress res
           where res = case curUniq of
-                        TPInternal -> RootOfTrust Nothing
-                        TPQC       -> RootOfTrust $ Just [quickCheckProof]
-                        TPSorry    -> RootOfTrust $ Just [sorry]
-                        TPUser {}  -> self <> foldMap (rot False) dependencies
+                        TPInternal    -> RootOfTrust Nothing
+                        TPQC          -> RootOfTrust $ Just [quickCheckProof]
+                        TPSorry       -> RootOfTrust $ Just [sorry]
+                        TPNoTermCheck -> RootOfTrust $ Just [p]
+                        TPUser {}     -> self <> foldMap (rot False) dependencies
 
                 -- if sorry or quickcheck is one of our direct dependencies, then we trust this proof.
                 -- Note that we skip this at the top. Why? at that level, we want to see the direct
@@ -421,20 +635,27 @@
 
                 isUnsafe ProofObj{uniqId = u} = u `elem` [TPSorry, TPQC]
 
-                -- If we have any dependency that is not sorry itself, then we can skip all the sorries.
-                -- Why? Because "sorry" will implicitly be coming from one of these anyhow. (In other
-                -- words, we do not need to (or want to) distinguish between different uses of sorry.
+                -- If sorry is present, it dominates everything else. Otherwise keep all.
                 compress (RootOfTrust mbps) = RootOfTrust $ reduce <$> mbps
-                  where reduce ps = case partition isUnsafe ps of
-                                      (l, []) | TPSorry `elem` map uniqId l -> [sorry]
-                                              | True                        -> [quickCheckProof]
-                                      (_, os) -> os
+                  where reduce ps
+                          | any (\o -> uniqId o == TPSorry) ps = [sorry]
+                          | True                               = ps
 
+-- | Print a one-line lemma result: @Lemma: name  Q.E.D. [Modulo: ...] [Cached] (a.k.a. ...)@
+printLemmaResult :: SMTConfig -> Bool -> String -> [ProofObj] -> Bool -> [String] -> IO ()
+printLemmaResult cfg verboseFlag nm deps cached aka = do
+   tab <- startTP cfg verboseFlag "Lemma" 0 (TPProofOneShot nm [])
+   finishTP cfg ("Q.E.D." ++ concludeModulo deps ++ cacheStr ++ akaStr) (tab, Nothing) []
+ where cacheStr | cached = " [Cached]"
+                | True   = ""
+       akaStr   | null aka = ""
+                | True     = " (a.k.a. " ++ intercalate ", " aka ++ ")"
+
 -- | Calculate the modulo string for dependencies
 concludeModulo :: [ProofObj] -> String
 concludeModulo by = case foldMap (rootOfTrust . Proof) by of
                       RootOfTrust Nothing   -> ""
-                      RootOfTrust (Just ps) -> " [Modulo: " ++ intercalate ", " (map shortProofName ps) ++ "]"
+                      RootOfTrust (Just ps) -> " [Modulo: " ++ shortProofNames ps ++ "]"
 
 -- | Make TP proofs quiet. Note that this setting will be effective with the
 -- call to 'runTP'\/'runTPWith', i.e., if you change the solver in a call to 'Data.SBV.TP.lemmaWith'\/'Data.SBV.TP.theoremWith', we
@@ -442,30 +663,45 @@
 tpQuiet :: Bool -> SMTConfig -> SMTConfig
 tpQuiet b cfg = cfg{tpOptions = (tpOptions cfg) { quiet = b }}
 
--- | Change the size of the ribbon for TP proofs. Note that this setting will be effective with the
--- call to 'runTP'\/'runTPWith', i.e., if you change the solver in a call to 'Data.SBV.TP.lemmaWith'\/'Data.SBV.TP.theoremWith', we
--- will inherit the ribbon settings from the surrounding environment.
-tpRibbon :: Int -> SMTConfig -> SMTConfig
-tpRibbon i cfg = cfg{tpOptions = (tpOptions cfg) { ribbonLength = i }}
-
 -- | Make TP proofs produce statistics. Note that this setting will be effective with the
 -- call to 'runTP'\/'runTPWith', i.e., if you change the solver in a call to 'Data.SBV.TP.lemmaWith'\/'Data.SBV.TP.theoremWith', we
 -- will inherit the statistics settings from the surrounding environment.
 tpStats :: SMTConfig -> SMTConfig
 tpStats cfg = cfg{tpOptions = (tpOptions cfg) { printStats = True }}
 
--- | Make TP proofs use proof-cache. Note that if you use this option then you are obligated to ensure all
--- lemma\/theorem names\/type pairs you use are unique for the whole run. (That is, we will reuse proofs if they have the
--- same name and type; hence if you prove two theorems that share name and type will be considered the same.)
--- If you don't ensure this uniqueness,  the results are not guaranteed to be sound. A good tip is to run the proof at
--- least once to completion, and use cache for regression purposes to avoid re-runs. Also, this setting will be effective
--- with the call to 'runTP'\/'runTPWith', i.e., if you -- the solver in a call to 'Data.SBV.TP.lemmaWith'\/'Data.SBV.TP.theoremWith', we will
--- inherit the caching behavior settings from the surrounding environment.
-tpCache :: SMTConfig -> SMTConfig
-tpCache cfg = cfg{tpOptions = (tpOptions cfg) { cacheProofs = True }}
 
 -- | When proving assumptions for each step, print them as well. Normally, SBV doesn't
 -- print assumptions in each proof step, though it does prove them as they are typically trivial.
 -- But in certain cases seeing them would be helpful.
 tpAsms :: SMTConfig -> SMTConfig
 tpAsms cfg = cfg{tpOptions = (tpOptions cfg) { printAsms = True }}
+
+-- | Create a t'MeasureHelper' from a TP proof action. During measure verification,
+-- the proof is run to confirm the property holds, and the proven property is extracted
+-- and asserted as an axiom in the measure verification session. The solver configuration
+-- is inherited from the measure verification context, with output suppressed.
+--
+-- Example usage with 'Data.SBV.smtFunctionWithMeasure':
+--
+-- @
+-- normalize = smtFunctionWithMeasure "normalize"
+--               (\\f -> tuple (ifComplexity f, ifDepth f)
+--               , [measureLemma ifDepthNonNeg, measureLemma ifComplexityPos]
+--               )
+--             $ \\f -> ...
+-- @
+measureLemma :: forall a. (QuantifiedBool a, Typeable a) => TP (Proof a) -> MeasureHelper
+measureLemma tp = MeasureHelper $ \cfg -> do
+  proof <- runTPWith (tpQuiet True cfg) tp
+  case fromDynamic @a (getProp (proofOf proof)) of
+    Just prop -> pure (quantifiedBool prop)
+    Nothing   -> error "Data.SBV.measureLemma: impossible type mismatch in measure helper"
+
+-- | Like 'measureLemma', but using the given solver configuration, ignoring the
+-- one from the measure verification context.
+measureLemmaWith :: forall a. (QuantifiedBool a, Typeable a) => SMTConfig -> TP (Proof a) -> MeasureHelper
+measureLemmaWith userCfg tp = MeasureHelper $ \_cfg -> do
+  proof <- runTPWith (tpQuiet True userCfg) tp
+  case fromDynamic @a (getProp (proofOf proof)) of
+    Just prop -> pure (quantifiedBool prop)
+    Nothing   -> error "Data.SBV.measureLemmaWith: impossible type mismatch in measure helper"
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,7 +11,6 @@
 -----------------------------------------------------------------------------
 
 {-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE TypeFamilies     #-}
 {-# LANGUAGE TypeOperators    #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
@@ -35,7 +34,7 @@
 bmcRefute :: (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.)
+    -> Symbolic ()                          -- ^ Setup code, if necessary. (Typically used for 'Data.SBV.setOption' calls. Pass @pure ()@ if not needed.)
     -> (st -> SBool)                        -- ^ Initial condition
     -> (st -> st -> SBool)                  -- ^ Transition relation
     -> (st -> SBool)                        -- ^ Goal to cover, i.e., we find a set of transitions that satisfy this predicate.
@@ -47,7 +46,7 @@
     => SMTConfig                            -- ^ Solver to use
     -> 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.)
+    -> Symbolic ()                          -- ^ Setup code, if necessary. (Typically used for 'Data.SBV.setOption' calls. Pass @pure ()@ if not needed.)
     -> (st -> SBool)                        -- ^ Initial condition
     -> (st -> st -> SBool)                  -- ^ Transition relation
     -> (st -> SBool)                        -- ^ Goal to cover, i.e., we find a set of transitions that satisfy this predicate.
@@ -60,7 +59,7 @@
 bmcCover :: (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.)
+    -> Symbolic ()                          -- ^ Setup code, if necessary. (Typically used for 'Data.SBV.setOption' calls. Pass @pure ()@ if not needed.)
     -> (st -> SBool)                        -- ^ Initial condition
     -> (st -> st -> SBool)                  -- ^ Transition relation
     -> (st -> SBool)                        -- ^ Goal to cover, i.e., we find a set of transitions that satisfy this predicate.
@@ -72,7 +71,7 @@
     => SMTConfig                            -- ^ Solver to use
     -> 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.)
+    -> Symbolic ()                          -- ^ Setup code, if necessary. (Typically used for 'Data.SBV.setOption' calls. Pass @pure ()@ if not needed.)
     -> (st -> SBool)                        -- ^ Initial condition
     -> (st -> st -> SBool)                  -- ^ Transition relation
     -> (st -> SBool)                        -- ^ Goal to cover, i.e., we find a set of transitions that satisfy this predicate.
@@ -94,7 +93,7 @@
 
          go i _ _
           | Just l <- mbLimit, i >= l
-          = return $ Left $ what ++ " limit of " ++ show l ++ " reached. " ++ badResult
+          = pure $ Left $ what ++ " limit of " ++ show l ++ " reached. " ++ badResult
 
          go i curState sofar = do when chatty $ io $ putStrLn $ what ++ ": Iteration: " ++ show i
 
@@ -111,9 +110,9 @@
                                     DSat{} -> error $ what ++ ": Solver returned an unexpected delta-sat result."
                                     Sat    -> do when chatty $ io $ putStrLn $ what ++ ": " ++ goodResult ++ " state found at iteration " ++ show i
                                                  ms <- mapM project (curState : sofar)
-                                                 return $ Right (i, reverse ms)
+                                                 pure $ Right (i, reverse ms)
                                     Unk    -> do when chatty $ io $ putStrLn $ what ++ ": Backend solver said unknown at iteration " ++ show  i
-                                                 return $ Left $ what ++ ": Solver said unknown in iteration " ++ show i
+                                                 pure $ Left $ what ++ ": Solver said unknown in iteration " ++ show i
                                     Unsat  -> do pop 1
                                                  nextState <- create
                                                  constrain $ curState `trans` nextState
diff --git a/Data/SBV/Tools/BVOptimize.hs b/Data/SBV/Tools/BVOptimize.hs
--- a/Data/SBV/Tools/BVOptimize.hs
+++ b/Data/SBV/Tools/BVOptimize.hs
@@ -97,7 +97,7 @@
 minMaxBV :: SFiniteBits a => Bool -> SMTConfig -> Bool -> SBV a -> Symbolic SatResult
 minMaxBV isMax cfg getUC v
  | hasSign v
- = error $ "minMaxBV works on unsigned bitvectors, received: " ++ show (kindOf v)
+ = error $ "minMaxBV works on unsigned bit-vectors, received: " ++ show (kindOf v)
  | True
  = do when getUC $ setOption $ ProduceUnsatCores True
       query $ go (blastBE v)
@@ -120,7 +120,7 @@
                                else constrain $ sNot b
                       r <- checkSat
                       case r of
-                        Sat    -> go bs >>= \res -> pop 1 >> return res
+                        Sat    -> go bs >>= \res -> pop 1 >> pure res
                         Unsat  ->                   pop 1 >> go bs
                         Unk    ->                   pop 1 >> rUnk
                         DSat{} -> error "minMaxBV: Unexpected DSat result"
diff --git a/Data/SBV/Tools/CodeGen.hs b/Data/SBV/Tools/CodeGen.hs
--- a/Data/SBV/Tools/CodeGen.hs
+++ b/Data/SBV/Tools/CodeGen.hs
@@ -6,7 +6,9 @@
 -- Maintainer: erkokl@gmail.com
 -- Stability : experimental
 --
--- Code-generation from SBV programs.
+-- Code-generation from SBV programs. This module selects the current C
+-- backend. Import "Data.SBV.Tools.CodeGen.Legacy" instead to use the original
+-- compatibility backend.
 -----------------------------------------------------------------------------
 
 {-# OPTIONS_GHC -Wall -Werror #-}
@@ -18,7 +20,8 @@
           SBVCodeGen, cgSym
 
         -- ** Setting code-generation options
-        , cgPerformRTCs, cgSetDriverValues, cgGenerateDriver, cgGenerateMakefile, cgOverwriteFiles, cgShowU8UsingHex
+        , cgPerformRTCs, cgSetDriverValues, cgArrayEqualityLimit, cgRegexLimits, cgGenerateDriver, cgGenerateMakefile, cgOverwriteFiles, cgShowU8UsingHex
+        , CgRegexLimits(..), defaultCgRegexLimits, cgSetRegexLimits
 
         -- ** Designating inputs
         , cgInput, cgInputArr
@@ -44,21 +47,432 @@
 import Data.SBV.Compilers.CodeGen
 
 {- $cCodeGeneration
-The SBV library can generate straight-line executable code in C. (While other target languages are
-certainly possible, currently only C is supported.) The generated code will perform no run-time memory-allocations,
-(no calls to @malloc@), so its memory usage can be predicted ahead of time. Also, the functions will execute precisely the
-same instructions in all calls, so they have predictable timing properties as well. The generated code
-has no loops or jumps, and is typically quite fast. While the generated code can be large due to complete unrolling,
-these characteristics make them suitable for use in hard real-time systems, as well as in traditional computing.
+The SBV library can generate executable C code from symbolic programs. Total
+native bit-vector arithmetic retains compact straight-line code. Programs
+using arbitrary-width bit-vectors, arbitrary floating-point values, or exact
+numbers can additionally contain generated runtime helpers, loops, and managed
+temporary storage appropriate to those representations.
+
+The original, native-scalar-only implementation remains available from
+"Data.SBV.Tools.CodeGen.Legacy" for compatibility during the transition to the
+new backend.
+
+Migration changes: without an explicit mapping, 'Data.SBV.SInteger' and
+rational-valued 'Data.SBV.SReal' now use exact GMP storage and require GMP at
+C build time. Legacy rejects these types without 'cgIntegerSize' or
+'cgSRealType'. Retain those settings if native, precision-losing mappings are
+intentional, or use the Legacy import to retain the original backend.
+
+== Building generated code
+
+'compileToC' writes a function source and header, plus an example driver and
+Makefile by default. 'compileToCLib' writes component sources, a shared header,
+and a Makefile building @name.a@ (not @libname.a@), with an optional combined
+driver. Generated C does not need the Haskell runtime or an SMT solver.
+
+For a standalone function named @example@, a typical build is:
+
+@
+make CC=clang CCFLAGS='-std=c11 -Wall -O2'
+./example_driver
+@
+
+Use 'cgGenerateDriver' to omit the example driver, and 'cgGenerateMakefile' to
+integrate sources into an existing build. With the driver disabled, build
+@example.o@ for a standalone function or @name.a@ for a library. Example drivers
+illustrate the generated calling convention; they are not exhaustive tests.
+
+Dependencies are selected from the operations and representations actually
+used, including those inside private functions and array lambdas:
+
+* Native and arbitrary-width bit-vectors, text, collections, arrays, and regex
+  matching do not themselves require an external runtime library. Their element
+  types or computations can still require one.
+* Exact integers, rational reals, and rationals require the C GMP headers and
+  library. Generated Makefiles obtain @GMP_CFLAGS@ and @GMP_LIBS@ from
+  @pkg-config@; set both variables explicitly if GMP is installed elsewhere.
+* LibBF-backed floating-point operations require @libbf.h@ and a compatible C
+  LibBF library. The default link flags are @-lbf -lm@. Installing the Haskell
+  @libBF@ package does not necessarily install a standalone library named
+  @libbf@ on the C linker's search path.
+* Native mathematical operations can require @-lm@ without GMP or LibBF.
+
+Generated Makefiles use @CCFLAGS@, not @CFLAGS@, and include local @*.mk@ files
+for overrides. Supply nonstandard include paths through @CCFLAGS@ and library
+paths through @LDFLAGS@. Required dependencies and 'cgAddLDFlags' are retained
+separately in @SBV_LIBS@, so inherited @LDFLAGS@ cannot discard them. Override
+@SBV_LIBS@ only to replace dependency discovery; retain every required library.
+For example, a LibBF-only program can use:
+
+@
+make CC=clang CCFLAGS='-std=c11 -Wall -O2 -I\/path\/to\/libbf' \\
+     SBV_LIBS='\/path\/to\/libbf.a -lm'
+@
+
+An external C caller should include the generated header and link the generated
+object or archive, followed by its required libraries. Static archives do not
+embed their GMP or LibBF dependencies. For a dependency-free library named
+@example@, for instance:
+
+@
+clang -std=c11 -O2 -ffp-contract=off caller.c example.a -o caller
+@
+
+Use the generated Makefile's link flags for libraries that need dependencies.
+Custom builds must also follow the floating-point and ownership contracts below.
+
+== Public C names
+
+Function, library, input, and output names must be portable ASCII C identifiers.
+Invalid names and C keywords are rejected, not silently renamed. Leading
+underscores, @sbv_@ and @SBV@ prefixes, generated type names, and names reserved
+for the runtime's C, GMP, and LibBF headers are unavailable for public names.
+For example, @my-function@, @switch@, and @sbv_bv_s16_mul@ are rejected.
+Ordinary library function names such as @remainder@ are allowed as parameter
+names, but not as generated entry points.
+
+Accepted names are preserved in public headers. Implementations and example
+drivers use private parameter bindings, so an input named @s0@ cannot collide
+with a symbolic temporary, and @values_data@ cannot collide with storage for
+an input named @values@. Driver output labels retain the requested names.
+Library component files must also have distinct names ignoring ASCII case,
+so a bundle is safe to render on case-insensitive filesystems.
+
+User-supplied C prototypes, declarations, and external implementations remain
+the caller's responsibility; their identifiers must not conflict with the
+generated runtime or entry points.
+
+Generated ADT constructor tags and structural declaration guards preserve
+case. Structural type names encode component boundaries explicitly; array
+names length-prefix both the key and value tags. Use the names in the generated
+header rather than deriving them from Haskell type spellings.
+
+== Representations and execution
+
+Generated code evaluates the symbolic computation without an SMT solver.
+Standalone programs and multi-function static libraries share these mappings:
+
+* Booleans use C @bool@. Native-width bit-vectors use fixed-width C integers;
+  other widths use generated limb structures. Arithmetic, shifts, joins, and
+  extractions preserve the declared bit width; 673 bits is only one example.
+* 'Data.SBV.SInteger', rational-valued 'Data.SBV.SReal', and
+  'Data.SBV.SRational' use GMP unless an applicable native mapping is selected.
+* 'Data.SBV.SFloat' and 'Data.SBV.SDouble' use native C values. Arbitrary
+  floating-point formats and explicitly directed native arithmetic rounding
+  use LibBF. Numeric casts between IEEE formats, bit-vectors, and exact GMP
+  numbers use LibBF too, except when a native conversion is provably exact.
+  Casts honor even the default round-to-nearest mode independently of the
+  caller's hardware rounding mode.
+  Floating-to-bit-vector casts round first, then retain the destination's low
+  bits; non-finite inputs produce zero. The latter choices give deterministic
+  results where SMT leaves an out-of-range or non-finite conversion unspecified.
+  Arbitrary formats are subject to LibBF's exponent-range limits: the backend
+  accepts at most 61 exponent bits and checks the selected C LibBF build too.
+* Strings and lists use length-aware descriptors. Sets use finite/cofinite
+  descriptors. Tuples and concrete ADTs use generated structures, including
+  tagged constructors and managed storage for recursive ADTs.
+* Symbolic arrays use persistent descriptors supporting constant arrays,
+  writes, retained lambdas, and caller-provided lookup callbacks. They are
+  distinct from finite lookup tables and 'cgInputArr'/'cgOutputArr' groups.
+  Reads walk the stored writes, taking time linear in their number in the
+  worst case. Embedding a function-scoped array in an aggregate copies its
+  stored-write chain, not its logical domain; already-owned storage can be shared.
+
+Generated headers supply ownership helpers for managed values. Inputs borrow
+their storage for the call; owned outputs must be released with the appropriate
+generated helper. Escaping callback contexts additionally require retain and
+release callbacks. See each generated header for its representation contract.
+
+Entry points, defined functions, and array lambdas preserve the guards of
+conditionals and short-circuit Boolean operations. An inactive branch does not
+evaluate its partial ADT selectors or function calls. Total bit-vector work may
+be shared outside branches; dependencies needed by both alternatives are also
+shared. Explicit assertions and hard constraints remain executable checks even
+when the generated function has no outputs.
+
+Finite table selection likewise protects unselected entries and unused defaults.
+Already available entries use direct C-array lookup; entries that require guarded
+evaluation use a switch. Enable 'cgPerformRTCs' to select the default for an
+out-of-range index. With checks disabled (the default), callers must guarantee
+in-range indices; invalid unchecked indices have no defined result and may
+terminate the process. Wide and exact indices are always checked before
+narrowing, independently of this option, to avoid aliasing an in-range entry.
+
+=== Floating-point calling convention
+
+Callers must enter generated code with the hardware rounding mode set to
+round-to-nearest, ties-to-even: @FE_TONEAREST@ from @<fenv.h>@. This requirement
+applies to standalone generated functions and library entry points. Callbacks
+and supplied C implementations must preserve this mode, or restore it before
+returning to or re-entering generated code.
+
+Generated code does not check, save, change, or restore the hardware rounding
+mode. Violating this precondition is unsupported and need not produce a
+diagnostic. Ordinary 'Data.SBV.SFloat' and 'Data.SBV.SDouble' RNE arithmetic
+therefore stays native, without a rounding-mode guard or a LibBF fallback.
+Explicit non-RNE and symbolic SBV rounding modes still use the rounding-aware
+adapters; they do not require the caller to change the hardware mode. The
+conversion bridges' independence from hardware rounding does not relax the
+entry-point precondition.
+
+Compile generated code with settings that preserve IEEE floating-point
+semantics; this precondition does not permit fast-math transformations that
+discard NaNs, signed zeros, or required rounding steps.
+Generated headers reject detectable fast-math and finite-math-only compiler
+modes, and floating-point programs require @FLT_EVAL_METHOD == 0@ so native
+expressions do not acquire excess evaluation precision. Generated Makefiles
+append @-ffp-contract=off@ after user compiler flags
+when compiling and linking, so separate SBV operations cannot be silently fused.
+Custom build systems must disable implicit contraction as well, including at
+LTO link time; source pragmas alone are insufficient with some compiler options.
+Explicit 'Data.SBV.fpFMA' remains a fused, single-rounding operation. Other
+unsafe floating-point options and caller-enabled flush-to-zero modes remain
+unsupported even when the compiler does not provide a detectable macro.
+
+=== Calling and owning generated values
+
+Input storage, including reachable aggregate fields and callback contexts, must
+remain valid and unchanged throughout the call. Pointer parameters must address
+valid objects; fixed-size groups require the declared number of elements.
+Outputs must not overlap other outputs or storage reachable through an input.
+In-place calls are not part of the supported ABI.
+
+Fixed-size input groups follow the same per-element borrowing rules as scalar
+inputs. In particular, a group of symbolic arrays accepts a C array of the
+generated @SBVArrayInput_...@ callback descriptors, not private array-node
+pointers. The example driver initializes and releases managed group elements
+individually, including their nested exact values and callback contexts.
+
+Scalar GMP output parameters, including each element of a GMP output group,
+must be initialized with @mpz_init@ or @mpq_init@ before the call. They can be
+reused across calls and must eventually be cleared by the caller. This also
+applies to the extra output parameter used for a single exact-number return.
+
+In contrast, managed string, list, set, tuple, ADT, and array output slots receive
+fresh owned values. They need no initialization, even when an aggregate contains
+GMP fields. Release an old owned value before reusing its slot; the generated
+entry point does not release the previous contents. Each output and return is
+an independent owner. Plain C assignment does not create another owner: use the
+generated clone or retain helper when both copies must survive independently.
+Never release borrowed input storage with an ownership helper.
+
+Reading an owned array can return a borrowed managed value. Clone that value
+before releasing the array if it must survive. Likewise, the generated
+@sbv_array_output_as_input_...@ helper borrows its array owner; it does not retain
+it. A callback's returned storage must remain valid while its context is alive.
+Callbacks must implement a stable, immutable lookup. When a non-null context
+escapes in a result, both retain and release hooks are required; retaining must
+preserve the lookup's meaning and give the result an independent lifetime.
+
+'Data.SBV.smtFunction' definitions and firstified higher-order specializations
+can compile to private C functions, including recursive definitions. Explicit
+closure environments remain SBV values; this is not an ABI for runtime Haskell
+function values. Hard constraints become executable preconditions.
+
+Array lambdas must be closed: their bodies may use their index, literal
+constants, and local computations, but may not capture outer symbolic values.
+The C backend checks every retained callback before generation, including
+nested lambdas, table entries/defaults, and rounding-mode operands. Unsupported
+captures are rejected explicitly, never replaced with default values or ignored.
+This check is conservative even when a retained capture would not be evaluated.
+Capturing array environments are deferred; SBV's existing frontend restrictions
+on nested and higher-order captures remain unchanged.
+
+== Runtime failures
+
+Generated programs and libraries use a fail-fast contract: a detected runtime
+failure terminates the calling process, using @abort@ or an unsuccessful exit.
+This includes failed executable preconditions and enabled assertions, detected
+invalid descriptors or missing required callback hooks, and allocation or
+resource-limit failures. There is no recoverable status-returning API.
+
+Callers must still satisfy the generated header's ABI and ownership requirements;
+runtime checks cannot validate arbitrary pointers or detect every malformed
+value. Outputs and cleanup are not guaranteed after failure. Intercepting
+termination or using @longjmp@ is not a supported recovery mechanism.
+
+Ordinary numerical results, including floating-point NaNs and infinities and
+SBV-defined totalized operations, are not themselves runtime failures.
+
+== Array equality
+
+Array equality enumerates a supported finite key domain and compares values
+using SMT object equality: NaNs are equal and signed floating-point zeros are
+distinct. It works for constant, updated, lambda-backed, and caller-provided
+arrays, stopping at the first mismatch. No backing array is materialized.
+Use 'Data.SBV..===' for arrays involving floating-point types; ordinary
+'Data.SBV..==' on such arrays is rejected by SBV before C generation.
+Lookup callbacks must respect SMT key equality, including returning the same
+value for all NaN encodings of a floating-point key.
+
+'cgArrayEqualityLimit' controls the maximum domain size, defaulting to 256
+keys per comparison. For example, setting it to 65536 permits 'Data.SBV.SWord16' keys,
+at the cost of up to 65,536 lookups in each array. The setting also applies
+inside defined functions and array lambdas, independently for each library
+component. A zero limit disables exhaustive comparison. This is a generation
+setting, not a runtime timeout; lookup and value-comparison costs are additional.
+Exceeding the limit reports the required domain size and suggests raising it.
+Infinite or unsupported domains and nested array equality remain unsupported
+regardless of the limit. These are generation-time diagnostics, not internal
+compiler errors, and library preflight rejects the whole bundle before writing
+any component files.
+
+Supported key domains are Booleans, bit-vectors, characters, rounding modes,
+floating-point formats, and non-recursive tuples and ADTs built from these.
+Floating-point enumeration visits bit encodings but compares only one NaN
+representative. Large domains require explicit opt-in even when the generated
+loop itself is compact.
+
+For example, admit the full 16-bit domain when generating a comparator:
+
+>>> import Data.SBV
+>>> import Data.SBV.Internals (compileToC')
+>>> :{
+let compareArrays = do
+      cgArrayEqualityLimit 65536
+      left  <- cgInput "left"  :: SBVCodeGen (SArray Word16 Word8)
+      right <- cgInput "right" :: SBVCodeGen (SArray Word16 Word8)
+      cgReturn (left .== right)
+:}
+
+>>> (_, _, generated) <- compileToC' "compareArrays" compareArrays
+>>> length (show generated) `seq` pure ()
+
+== Regular expressions
+
+Regex membership compiles to a bounded deterministic automaton: function-local
+static tables and an allocation-free C loop. All 'Data.SBV.RegExp.RegExp'
+constructors are supported, including complement, intersection, difference,
+and nullable repetitions. Matching consumes the entire string, preserves
+embedded NULs, and uses SBV's character domain @0..0x2ffff@, including numeric
+surrogate values. The normal canonical string-encoding ABI still applies.
+Regex language equality and inequality are decided during generation and
+produce Boolean constants, not runtime comparisons.
+
+There are no additional packages, generation tools, headers, or linker flags.
+Non-regex programs acquire no regex runtime code. Tables are private to each
+generated function and work inside defined functions and closed array lambdas.
+
+'cgRegexLimits' bounds compilation independently per regex operation: maximum
+explored automaton states (default 1024), expression nodes (4096), and charged
+generation work (16000000). Language comparison counts pairs of residual states.
+Expression limits also bound literal/list lengths and repetition expansion;
+work accounts for traversals, construction, normalization, and state comparisons.
+These are conservative implementation budgets, not time or memory guarantees.
+They can reject even a regex whose minimal automaton would be small; this
+initial implementation does not minimize automata or optimize large repetitions.
+
+Exceeding a budget fails during generation with a diagnostic naming the limit.
+No language approximation or fallback matcher is used. Zero in any limit
+disables regex compilation; negative limits are invalid. Successful generation
+supports inputs of any length, independently of these limits. Each library
+component can choose its own limits. Already folded or dead operations need
+no regex compilation.
+
+For example, permit a larger automaton when generating a suffix matcher:
+
+>>> import qualified Data.SBV.RegExp as RE
+>>> :{
+let suffixMatcher = do
+      cgRegexLimits 4096 8192 64000000
+      input <- cgInput "input" :: SBVCodeGen SString
+      cgReturn (input `RE.match` RE.Conc [RE.All, RE.Literal "done"])
+:}
+
+>>> (_, _, regexCode) <- compileToC' "suffixMatcher" suffixMatcher
+>>> length (show regexCode) `seq` pure ()
+
+== Boundaries
+
+=== Support policy
+
+The following distinctions apply equally to standalone functions and libraries:
+
+* /Supported representations/: arbitrary-width bit-vectors, native and
+  arbitrary-format floats, GMP integers and rational-valued reals, text,
+  lists, finite\/cofinite sets, tuples, concrete ADTs, and persistent arrays.
+  Dependencies and ownership follow the representation descriptions above.
+* /Supported with generation budgets/: exhaustive finite-domain array equality
+  ('cgArrayEqualityLimit') and regex compilation ('cgRegexLimits'). Exceeding
+  a budget reports the relevant setting; raising it does not enable a different
+  feature or change semantics. Regex matching has no approximate fallback.
+* /Unsupported types/: uninterpreted sorts, including uses nested in supported
+  containers. Uninterpreted /functions/ with caller-supplied C implementations
+  are a separate, supported mechanism.
+* /Unsupported recursive layouts/: recursive ADT references nested inside
+  composite constructor fields, such as tuples. Put recursive references in
+  direct constructor fields instead; those use the supported pointer layout.
+* /Unsupported equality/: nested arrays and general infinite-domain array
+  equality, even for sparse constant-plus-write arrays. The same restriction
+  applies to implicit element comparisons in collection operations.
+* /Unsupported solver requests/: finite or infinite quantifiers, special
+  relations, soft constraints, solver options, optimization objectives, and SMT-only constraint
+  attributes. Ordinary hard constraints become executable checks, not searches
+  for satisfying inputs.
+* /Unsupported closures/: array lambdas capturing outer symbolic values.
+  Closed array lambdas and firstified higher-order operations with explicit
+  'Data.SBV.Closure' environments remain supported. Unsupported implicit
+  higher-order captures are rejected by SBV's frontend or by C preflight when
+  retained in a defined function; the backend does not add first-class runtime
+  functions or general function equality.
+* /Unsupported exact real values/: algebraic roots, transcendental operations
+  in exact-rational mode, and inexact or interval literals that do not specify
+  a single exact value. A native real mapping explicitly opts into approximate
+  arithmetic; it does not choose an approximation for an algebraic literal.
+
+These unsupported cases report an explicit diagnostic during generation,
+including retained private-function and array-lambda bodies. Validation of an
+entire library precedes file output: a rejected component does not leave earlier
+components partially written. This is not a filesystem transaction; an I\/O
+failure while writing otherwise valid output can still leave files behind.
+Already constant-folded or eliminated operations do not require a lowering.
+Runtime failures and caller preconditions are separate contracts, described
+above; in particular, violating the RNE entry requirement is not diagnosed.
+
+Array comparisons with infinite or unsupported key domains, or values that
+themselves contain arrays, are rejected during generation. Comparing arrays
+nested inside collections or aggregates is also not implemented. Quantifiers,
+special solver relations, uninterpreted sorts, and soft constraints are rejected.
+The comparison restriction includes list searches, prefix/suffix checks, and
+replacement: these operations compare elements even when their result is not
+a Boolean. Arrays may still be transported inside lists and aggregates without
+comparing them. Array-containing set elements and array keys are rejected, since
+their representations require element or key equality.
+
+Exact GMP reals represent rational values, not arbitrary algebraic or
+transcendental values. Select 'cgSRealType' for native approximations and
+@libm@ transcendental operations when rounding is acceptable. The fixed-size
+input/output/return group APIs require at least one element; symbolic lists
+can be empty.
+
+Numeric conversions honor 'cgIntegerSize' and the @CgFloat@/@CgDouble@ real
+mappings. Converting a mapped real to an integer still floors; explicitly
+rounded floating casts retain their requested rounding mode. @CgLongDouble@
+retains native arithmetic and uses representation-aware LibBF bridges to exact
+integers, bit-vectors, and native or arbitrary floating-point formats. These
+bridges import the full significand and round directly to the destination,
+without narrowing through binary64. The target C compiler must provide binary64,
+x87 extended, or binary128 @long double@; other formats (including double-double)
+receive a compile-time diagnostic when a bridge is needed. Merely selecting
+@CgLongDouble@ does not itself require LibBF. Explicit native mappings remain
+approximations: compound expressions, including integer numerator\/denominator
+conversions in 'Data.SBV.Rational.sRationalToSReal', retain their separate rounding
+steps instead of becoming a single exact-rational conversion.
 -}
 
 {- $unboundedCGen
-The types 'Data.SBV.SInteger' and 'Data.SBV.SReal' are unbounded quantities that have no direct counterparts in the C language. Therefore,
-it is not possible to generate standard C code for SBV programs using these types, unless custom libraries are available. To
-overcome this, SBV allows the user to explicitly set what the corresponding types should be for these two cases, using
-the functions below. Note that while these mappings will produce valid C code, the resulting code will be subject to
-overflow/underflows for 'Data.SBV.SInteger', and rounding for 'Data.SBV.SReal', so there is an implicit loss of precision.
+The types 'Data.SBV.SInteger' and 'Data.SBV.SReal' are represented exactly by
+GMP when no alternative mapping is selected. The functions below retain the
+option of mapping them to native C types when a smaller ABI or compatibility
+with historical generated code is more important than exactness. Such native
+mappings are subject to overflow for 'Data.SBV.SInteger' and rounding for
+'Data.SBV.SReal'.
 
-If the user does /not/ specify these mappings, then SBV will
-refuse to compile programs that involve these types.
+Real-to-integer flooring preserves the mathematical floor of the represented
+native real, then retains the low bits selected by 'cgIntegerSize'. This applies
+to @CgFloat@, @CgDouble@, and @CgLongDouble@ without an out-of-range C integer
+cast. Flooring a non-finite mapped real terminates the process with a diagnostic.
+
+The compatibility backend in "Data.SBV.Tools.CodeGen.Legacy" retains the
+original requirement that these mappings be supplied explicitly.
 -}
diff --git a/Data/SBV/Tools/CodeGen/Legacy.hs b/Data/SBV/Tools/CodeGen/Legacy.hs
new file mode 100644
--- /dev/null
+++ b/Data/SBV/Tools/CodeGen/Legacy.hs
@@ -0,0 +1,36 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Data.SBV.Tools.CodeGen.Legacy
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Opt-in access to the original SBV-to-C compiler. This module exports the
+-- same code-generation interface as "Data.SBV.Tools.CodeGen"; changing the
+-- import is sufficient to select the compatibility backend.
+--
+-- @
+-- import Data.SBV.Tools.CodeGen.Legacy
+-- @
+--
+-- New code should normally import "Data.SBV.Tools.CodeGen" instead.
+-- Unlike the current backend, Legacy requires explicit 'cgIntegerSize' and
+-- 'cgSRealType' mappings; it never supplies the GMP fallback. Array-equality
+-- and regex generation limits are not exported: Legacy cannot use them.
+-- Native real-to-integer flooring uses the same overflow-safe, low-bit mapping
+-- as the current backend; flooring a non-finite mapped real fails explicitly.
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Data.SBV.Tools.CodeGen.Legacy
+  ( module Data.SBV.Tools.CodeGen
+  , compileToC
+  , compileToCLib
+  , compileToC'
+  , compileToCLib'
+  ) where
+
+import Data.SBV.Compilers.C.Legacy (compileToC, compileToCLib, compileToC', compileToCLib')
+import Data.SBV.Tools.CodeGen hiding (compileToC, compileToCLib, cgArrayEqualityLimit, cgRegexLimits, CgRegexLimits(..), defaultCgRegexLimits, cgSetRegexLimits)
diff --git a/Data/SBV/Tools/GenTest.hs b/Data/SBV/Tools/GenTest.hs
--- a/Data/SBV/Tools/GenTest.hs
+++ b/Data/SBV/Tools/GenTest.hs
@@ -9,7 +9,7 @@
 -- Test generation from symbolic programs
 -----------------------------------------------------------------------------
 
-{-# OPTIONS_GHC -Wall -Werror -Wno-incomplete-uni-patterns #-}
+{-# OPTIONS_GHC -Wall -Werror #-}
 
 module Data.SBV.Tools.GenTest (
         -- * Test case generation
@@ -23,6 +23,7 @@
 import Data.Function (on)
 import Data.List     (intercalate, groupBy)
 import Data.Maybe    (fromMaybe)
+import qualified Data.Text as T
 
 import Data.SBV.Core.AlgReals
 import Data.SBV.Core.Data
@@ -48,15 +49,15 @@
 genTest :: Outputtable a => Int -> Symbolic a -> IO TestVectors
 genTest n m = gen 0 []
   where gen i sofar
-         | i == n = return $ TV $ reverse sofar
+         | i == n = pure $ TV $ reverse sofar
          | True   = do t <- tc
                        gen (i+1) (t:sofar)
         tc = do (_, Result {resTraces=tvals, resConsts=(_, cs), resDefinitions=definitions, resConstraints=cstrs, resOutputs=os}) <- runSymbolic defaultSMTCfg (Concrete Nothing) (m >>= output)
-                let cval = fromMaybe (error "Cannot generate tests in the presence of uninterpeted constants!") . (`lookup` cs)
+                let cval = fromMaybe (error "Cannot generate tests in the presence of uninterpreted constants!") . (`lookup` cs)
                     cond = and [cvToBool (cval v) | (False, _, v) <- F.toList cstrs] -- Only pick-up "hard" constraints, as indicated by False in the fist component
                 unless (null definitions) $ error "Cannot generate tests in the presence of 'smtFunction' calls!"
                 if cond
-                   then return (map snd tvals, map cval os)
+                   then pure (map snd tvals, map cval os)
                    else tc   -- try again, with the same set of constraints
 
 -- | Test output style
@@ -94,8 +95,7 @@
           | needsWord             = ["import Data.Word", ""]
           | needsRatio            = ["import Data.Ratio"]
           | True                  = []
-          where ((is, os):_) = vs
-                params       = is ++ os
+          where params       = case vs of { (is, os):_ -> is ++ os; _ -> error "SBV.renderTest: impossible, empty test vectors" }
                 needsInt     = any isSW params
                 needsWord    = any isUW params
                 needsRatio   = any isR params
@@ -108,7 +108,9 @@
                 isUW cv      = case kindOf cv of
                                  KBounded False sz -> sz > 1
                                  _                 -> False
-        modName = let (f:r) = n in toUpper f : r
+        modName = case n of
+                    f:r -> toUpper f : r
+                    _   -> error "SBV.renderTest: impossible, empty module name"
         pad = replicate (length n + 3) ' '
         getType []         = "[a]"
         getType ((i, o):_) = "[(" ++ mapType typeOf i ++ ", " ++ mapType typeOf o ++ ")]"
@@ -141,27 +143,27 @@
                  KReal             -> error $ "SBV.renderTest: Unsupported real valued test value: " ++ show cv
                  KList es          -> error $ "SBV.renderTest: Unsupported list valued test: [" ++ show es ++ "]"
                  KSet  es          -> error $ "SBV.renderTest: Unsupported set valued test: {" ++ show es ++ "}"
-                 KUserSort us _    -> error $ "SBV.renderTest: Unsupported uninterpreted sort: " ++ us
                  _                 -> error $ "SBV.renderTest: Unexpected CV: " ++ show cv
 
         s cv = case kindOf cv of
+                  KVar{}            -> error $ "SBV.renderTest: Unexpected: " ++ show (kindOf cv)
                   KBool             -> take 5 (show (cvToBool cv) ++ repeat ' ')
-                  KBounded sgn   sz -> let CInteger w = cvVal cv in shex  False True (sgn, sz) w
-                  KUnbounded        -> let CInteger w = cvVal cv in shexI False True           w
-                  KFloat            -> let CFloat   w = cvVal cv in showHFloat w
-                  KDouble           -> let CDouble  w = cvVal cv in showHDouble w
+                  KBounded sgn   sz -> case cvVal cv of { CInteger w -> T.unpack $ shex  False True (sgn, sz) w; r -> bad r }
+                  KUnbounded        -> case cvVal cv of { CInteger w -> T.unpack $ shexI False True           w; r -> bad r }
+                  KFloat            -> case cvVal cv of { CFloat   w -> showHFloat w;                            r -> bad r }
+                  KDouble           -> case cvVal cv of { CDouble  w -> showHDouble w;                           r -> bad r }
                   KRational         -> error "SBV.renderTest: Unsupported rational number"
                   KFP{}             -> error "SBV.renderTest: Unsupported arbitrary float"
                   KChar             -> error "SBV.renderTest: Unsupported char"
                   KString           -> error "SBV.renderTest: Unsupported string"
-                  KReal             -> let CAlgReal w = cvVal cv in algRealToHaskell w
+                  KReal             -> case cvVal cv of { CAlgReal w -> algRealToHaskell w; r -> bad r }
                   KList es          -> error $ "SBV.renderTest: Unsupported list valued sort: [" ++ show es ++ "]"
                   KSet  es          -> error $ "SBV.renderTest: Unsupported set valued sort: {" ++ show es ++ "}"
-                  KUserSort us _    -> error $ "SBV.renderTest: Unsupported uninterpreted sort: " ++ us
-                  k@KTuple{}        -> error $ "SBV.renderTest: Unsupported tuple: " ++ show k
-                  k@KMaybe{}        -> error $ "SBV.renderTest: Unsupported maybe: " ++ show k
-                  k@KEither{}       -> error $ "SBV.renderTest: Unsupported sum: "   ++ show k
-                  k@KArray{}        -> error $ "SBV.renderTest: Unsupported array: " ++ show k
+                  k@KApp{}          -> error $ "SBV.renderTest: Unsupported adt app: " ++ show k
+                  k@KADT{}          -> error $ "SBV.renderTest: Unsupported adt: "     ++ show k
+                  k@KTuple{}        -> error $ "SBV.renderTest: Unsupported tuple: "   ++ show k
+                  k@KArray{}        -> error $ "SBV.renderTest: Unsupported array: "   ++ show k
+               where bad _ = error $ "SBV.renderTest: Unexpected CVal for kind: " ++ show (kindOf cv)
 
 c :: String -> [([CV], [CV])] -> String
 c n vs = intercalate "\n" $
@@ -231,6 +233,7 @@
               ]
   where mkField p cv i = "    " ++ t ++ " " ++ p ++ show i ++ ";"
             where t = case kindOf cv of
+                        KVar{}            -> error $ "SBV.renderTest: Unexpected: " ++ show (kindOf cv)
                         KBool             -> "SBool"
                         KBounded False 8  -> "SWord8"
                         KBounded False 16 -> "SWord16"
@@ -249,35 +252,34 @@
                         KString           -> error "SBV.renderTest: Unsupported string"
                         KUnbounded        -> error "SBV.renderTest: Unbounded integers are not supported when generating C test-cases."
                         KReal             -> error "SBV.renderTest: Real values are not supported when generating C test-cases."
-                        KUserSort us _    -> error $ "SBV.renderTest: Unsupported uninterpreted sort: " ++ us
+                        k@KApp{}          -> error $ "SBV.renderTest: Unsupported adt app: "     ++ show k
+                        k@KADT{}          -> error $ "SBV.renderTest: Unsupported adt: "         ++ show k
                         k@KList{}         -> error $ "SBV.renderTest: Unsupported list sort: "   ++ show k
                         k@KSet{}          -> error $ "SBV.renderTest: Unsupported set sort: "    ++ show k
                         k@KTuple{}        -> error $ "SBV.renderTest: Unsupported tuple sort: "  ++ show k
-                        k@KMaybe{}        -> error $ "SBV.renderTest: Unsupported maybe sort: "  ++ show k
-                        k@KEither{}       -> error $ "SBV.renderTest: Unsupported either sort: " ++ show k
                         k@KArray{}        -> error $ "SBV.renderTest: Unsupported array sort: "  ++ show k
 
-
         mkLine (is, os) = "{{" ++ intercalate ", " (map v is) ++ "}, {" ++ intercalate ", " (map v os) ++ "}}"
 
         v cv = case kindOf cv of
-                  KBool            -> if cvToBool cv then "true " else "false"
-                  KBounded sgn sz  -> let CInteger w = cvVal cv in chex  False True (sgn, sz) w
-                  KUnbounded       -> let CInteger w = cvVal cv in shexI False True           w
-                  KFloat           -> let CFloat w   = cvVal cv in showCFloat w
-                  KDouble          -> let CDouble w  = cvVal cv in showCDouble w
-                  KRational        -> error "SBV.renderTest: Unsupported rational number"
-                  KFP{}            -> error "SBV.renderTest: Unsupported arbitrary float"
-                  KChar            -> error "SBV.renderTest: Unsupported char"
-                  KString          -> error "SBV.renderTest: Unsupported string"
-                  k@KList{}        -> error $ "SBV.renderTest: Unsupported list sort!" ++ show k
-                  k@KSet{}         -> error $ "SBV.renderTest: Unsupported set sort!" ++ show k
-                  KUserSort us _   -> error $ "SBV.renderTest: Unsupported uninterpreted sort: " ++ us
-                  KReal            -> error "SBV.renderTest: Real values are not supported when generating C test-cases."
-                  k@KTuple{}       -> error $ "SBV.renderTest: Unsupported tuple sort: " ++ show k
-                  k@KMaybe{}       -> error $ "SBV.renderTest: Unsupported maybe sort: " ++ show k
-                  k@KEither{}      -> error $ "SBV.renderTest: Unsupported sum sort: "   ++ show k
-                  k@KArray{}       -> error $ "SBV.renderTest: Unsupported sum sort: "   ++ show k
+                  KVar{}          -> error $ "SBV.renderTest: Unexpected: " ++ show (kindOf cv)
+                  KBool           -> if cvToBool cv then "true " else "false"
+                  KBounded sgn sz -> case cvVal cv of { CInteger w -> T.unpack $ chex  False True (sgn, sz) w; r -> bad r }
+                  KUnbounded      -> case cvVal cv of { CInteger w -> T.unpack $ shexI False True           w; r -> bad r }
+                  KFloat          -> case cvVal cv of { CFloat w   -> showCFloat w;                            r -> bad r }
+                  KDouble         -> case cvVal cv of { CDouble w  -> showCDouble w;                           r -> bad r }
+                  KRational       -> error "SBV.renderTest: Unsupported rational number"
+                  KFP{}           -> error "SBV.renderTest: Unsupported arbitrary float"
+                  KChar           -> error "SBV.renderTest: Unsupported char"
+                  KString         -> error "SBV.renderTest: Unsupported string"
+                  KReal           -> error "SBV.renderTest: Real values are not supported when generating C test-cases."
+                  k@KList{}       -> error $ "SBV.renderTest: Unsupported list sort!"           ++ show k
+                  k@KSet{}        -> error $ "SBV.renderTest: Unsupported set sort!"            ++ show k
+                  k@KApp{}        -> error $ "SBV.renderTest: Unsupported adt app: "            ++ show k
+                  k@KADT{}        -> error $ "SBV.renderTest: Unsupported adt: "                ++ show k
+                  k@KTuple{}      -> error $ "SBV.renderTest: Unsupported tuple sort: "         ++ show k
+                  k@KArray{}      -> error $ "SBV.renderTest: Unsupported sum sort: "           ++ show k
+               where bad _ = error $ "SBV.renderTest: Unexpected CVal for kind: " ++ show (kindOf cv)
 
         outLine
           | null vs = "printf(\"\");"
@@ -352,7 +354,6 @@
                         KList ek          -> noForte $ "List of " ++ show ek
                         KSet  ek          -> noForte $ "Set of " ++ show ek
                         KUnbounded        -> noForte "Unbounded integers"
-                        KUserSort s _     -> noForte $ "Uninterpreted kind " ++ show s
                         _                 -> error $ "SBV.renderTest: Unexpected CV: " ++ show cv
 
         xlt s (CInteger  v)  = [toF (testBit v i) | i <- [s-1, s-2 .. 0]]
@@ -363,13 +364,11 @@
         xlt _ (CChar     r)  = error $ "SBV.renderTest.Forte: Unexpected char value: "             ++ show r
         xlt _ (CString   r)  = error $ "SBV.renderTest.Forte: Unexpected string value: "           ++ show r
         xlt _ (CAlgReal  r)  = error $ "SBV.renderTest.Forte: Unexpected real value: "             ++ show r
-        xlt _ (CUserSort r)  = error $ "SBV.renderTest.Forte: Unexpected uninterpreted value: "    ++ show r
+        xlt _ (CADT (k, _))  = error $ "SBV.renderTest.Forte: Unexpected ADT value: "              ++ show k
         xlt _ CList{}        = error   "SBV.renderTest.Forte: Unexpected list value!"
         xlt _ CSet{}         = error   "SBV.renderTest.Forte: Unexpected set value!"
         xlt _ CTuple{}       = error   "SBV.renderTest.Forte: Unexpected list value!"
-        xlt _ CMaybe{}       = error   "SBV.renderTest.Forte: Unexpected maybe value!"
-        xlt _ CEither{}      = error   "SBV.renderTest.Forte: Unexpected sum value!"
-        xlt _  CArray{}      = error   "SBV.renderTest.Forte: Unexpected array value!"
+        xlt _ CArray{}       = error   "SBV.renderTest.Forte: Unexpected array value!"
 
         mkLine  (i, o) = "("  ++ mkTuple (form (fst ss) (concatMap blast i)) ++ ", " ++ mkTuple (form (snd ss) (concatMap blast o)) ++ ")"
         mkTuple []  = "()"
@@ -379,9 +378,9 @@
         form []     bs = error $ "SBV.renderTest: Mismatched index in stream, extra " ++ show (length bs) ++ " bit(s) remain."
         form (i:is) bs
           | length bs < i = error $ "SBV.renderTest: Mismatched index in stream, was looking for " ++ show i ++ " bit(s), but only " ++ show bs ++ " remains."
-          | i == 1        = let b:r = bs
-                                v   = if b == '1' then "T" else "F"
-                            in v : form is r
+          | i == 1        = case bs of
+                              b:r -> (if b == '1' then "T" else "F") : form is r
+                              _   -> error "SBV.renderTest: impossible, empty bit stream"
           | True          = let (f, r) = splitAt i bs
                                 v      = "c \"" ++ show i ++ "'b" ++ f ++ "\""
                             in v : form is r
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
@@ -84,7 +84,7 @@
 -- and "Documentation.SBV.Examples.ProofTools.Sum" for examples.
 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.)
+       -> Symbolic ()                      -- ^ Setup code, if necessary. (Typically used for 'Data.SBV.setOption' calls. Pass @pure ()@ if not needed.)
        -> (st -> SBool)                    -- ^ Initial condition
        -> (st -> st -> SBool)              -- ^ Transition relation
        -> [(String, st -> SBool)]          -- ^ Strengthenings, if any. The @String@ is a simple tag.
@@ -115,14 +115,14 @@
                $ try "Proving partial correctness"
                      (\s _ -> let (term, result) = goal s in inv s .&& term .=> result)
                      (Failed PartialCorrectness)
-                     (msg "Done" >> return Proven)
+                     (msg "Done" >> pure Proven)
 
   where msg = when chatty . putStrLn
 
         try m p wrap cont = do msg m
                                res <- check p
                                case res of
-                                 Just ex -> return $ wrap ex
+                                 Just ex -> pure $ wrap ex
                                  Nothing -> cont
 
         check p = runSMTWith cfg $ do
@@ -135,14 +135,14 @@
                                    case cs of
                                      Unk    -> error "Solver said unknown"
                                      DSat{} -> error "Solver returned a delta-sat result"
-                                     Unsat  -> return Nothing
+                                     Unsat  -> pure Nothing
                                      Sat    -> do io $ msg "Failed in state:"
                                                   exS  <- project s
                                                   io $ msg $ show exS
                                                   io $ msg "Transitioning to:"
                                                   exS' <- project s'
                                                   io $ msg $ show exS'
-                                                  return $ Just (exS, exS')
+                                                  pure $ Just (exS, exS')
 
         strengthen []             cont = cont
         strengthen ((nm, st):sts) cont = try ("Proving strengthening initiation  : " ++ nm)
diff --git a/Data/SBV/Tools/Overflow.hs b/Data/SBV/Tools/Overflow.hs
--- a/Data/SBV/Tools/Overflow.hs
+++ b/Data/SBV/Tools/Overflow.hs
@@ -15,7 +15,6 @@
 {-# LANGUAGE FlexibleContexts     #-}
 {-# LANGUAGE FlexibleInstances    #-}
 {-# LANGUAGE ImplicitParams       #-}
-{-# LANGUAGE Rank2Types           #-}
 {-# LANGUAGE ScopedTypeVariables  #-}
 {-# LANGUAGE TypeApplications     #-}
 {-# LANGUAGE TypeOperators        #-}
@@ -24,7 +23,6 @@
 {-# OPTIONS_GHC -Wall -Werror #-}
 
 module Data.SBV.Tools.Overflow (
-
          -- * Arithmetic overflows
          ArithOverflow(..), CheckedArithmetic(..)
 
@@ -32,8 +30,7 @@
          , signedMulOverflow
 
          -- * Cast overflows
-       , sFromIntegralO, sFromIntegralChecked
-
+         , sFromIntegralO, sFromIntegralChecked
     ) where
 
 import Data.SBV.Core.Data
@@ -101,11 +98,11 @@
 instance (KnownNat n, BVIsNonZero n) => ArithOverflow (SInt  n) where {bvAddO = l2 bvAddO; bvSubO = l2 bvSubO; bvMulO = l2 bvMulO; bvDivO = l2 bvDivO; bvNegO = l1 bvNegO}
 
 instance ArithOverflow SVal where
-  bvAddO     = signPick2 (svMkOverflow2 (PlusOv False)) (svMkOverflow2 (PlusOv True))
-  bvSubO     = signPick2 (svMkOverflow2 (SubOv  False)) (svMkOverflow2 (SubOv  True))
-  bvMulO     = signPick2 (svMkOverflow2 (MulOv  False)) (svMkOverflow2 (MulOv  True))
-  bvDivO     = signPick2 (const (const svFalse))        (svMkOverflow2 DivOv)           -- unsigned division doesn't overflow
-  bvNegO     = signPick1 (const svFalse)                (svMkOverflow1 NegOv)           -- unsigned unary negation doesn't overflow
+  bvAddO = signPick2 (svMkOverflow2 (PlusOv False)) (svMkOverflow2 (PlusOv True))
+  bvSubO = signPick2 (svMkOverflow2 (SubOv  False)) (svMkOverflow2 (SubOv  True))
+  bvMulO = signPick2 (svMkOverflow2 (MulOv  False)) (svMkOverflow2 (MulOv  True))
+  bvDivO = signPick2 (const (const svFalse))        (svMkOverflow2 DivOv)           -- unsigned division doesn't overflow
+  bvNegO = signPick1 (const svFalse)                (svMkOverflow1 NegOv)           -- unsigned unary negation doesn't overflow
 
 -- | A class of checked-arithmetic operations. These follow the usual arithmetic,
 -- except make calls to 'Data.SBV.sAssert' to ensure no overflow/underflow can occur.
@@ -328,7 +325,7 @@
         --
         -- The result is at most N-2 for an N-bit word. Later we add two of these, so the maximum
         -- value we need to represent is 2N-4. This will require 1 + lg(2N-4) = 2 + log(N-1) bits.
-        -- To suppor the case N=0, we return a (2 + log N) bit word.
+        -- To support the case N=0, we return a (2 + log N) bit word.
         --
         -- Example for 3 bits:
         --
diff --git a/Data/SBV/Tools/Polynomial.hs b/Data/SBV/Tools/Polynomial.hs
--- a/Data/SBV/Tools/Polynomial.hs
+++ b/Data/SBV/Tools/Polynomial.hs
@@ -9,11 +9,8 @@
 -- Implementation of polynomial arithmetic
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DataKinds            #-}
-{-# LANGUAGE FlexibleContexts     #-}
+{-# LANGUAGE CPP                  #-}
 {-# LANGUAGE FlexibleInstances    #-}
-{-# LANGUAGE PatternGuards        #-}
-{-# LANGUAGE TypeFamilies         #-}
 {-# LANGUAGE UndecidableInstances #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
@@ -24,7 +21,11 @@
         ) where
 
 import Data.Bits  (Bits(..))
-import Data.List  (genericTake)
+import Data.List  (genericTake
+#if !MIN_VERSION_base(4,20,0)
+                  , foldl'
+#endif
+                  )
 import Data.Maybe (fromJust, fromMaybe)
 import Data.Word  (Word8, Word16, Word32, Word64)
 
@@ -149,7 +150,7 @@
   = fromBitsLE $ genericTake sz $ r ++ repeat sFalse
   where (_, r) = mdp ms rs
         ms = genericTake (2*sz) $ mul (blastLE x) (blastLE y) [] ++ repeat sFalse
-        rs = genericTake (2*sz) $ [fromBool (i `elem` red) |  i <- [0 .. foldr max 0 red] ] ++ repeat sFalse
+        rs = genericTake (2*sz) $ [fromBool (i `elem` red) |  i <- [0 .. foldl' max 0 red] ] ++ repeat sFalse
         sz = intSizeOf x
         mul _  []     ps = ps
         mul as (b:bs) ps = mul (sFalse:as) bs (ites b (as `addPoly` ps) ps)
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
@@ -108,7 +108,7 @@
 rangesWith :: forall a. (OrdSymbolic (SBV a), Num a, SymVal a,  SatModel a, Metric a, SymVal (MetricSpace a), SatModel (MetricSpace a)) => SMTConfig -> (SBV a -> SBool) -> IO [Range a]
 rangesWith cfg prop = do mbBounds <- getInitialBounds
                          case mbBounds of
-                           Nothing -> return []
+                           Nothing -> pure []
                            Just r  -> search [r] []
 
   where getInitialBounds :: IO (Maybe (Range a))
@@ -155,16 +155,16 @@
                                                                                                       constrain $ prop x
                                                                                                       cstr objName x
                                    case m of
-                                     Unsatisfiable{} -> return Nothing
+                                     Unsatisfiable{} -> pure Nothing
                                      Unknown{}       -> error "Solver said Unknown!"
                                      ProofError{}    -> error (show res)
-                                     _               -> return $ getModelObjectiveValue (annotateForMS (Proxy @a) objName) m
+                                     _               -> pure $ getModelObjectiveValue (annotateForMS (Proxy @a) objName) m
 
             mi <- getBound minimize
             ma <- getBound maximize
             case (mi, ma) of
-              (Just minV, Just maxV) -> return $ Just $ Range (getGenVal minV) (getGenVal maxV)
-              _                      -> return Nothing
+              (Just minV, Just maxV) -> pure $ Just $ Range (getGenVal minV) (getGenVal maxV)
+              _                      -> pure Nothing
 
         -- Is this range satisfiable? Returns a witness to it.
         witness :: Range a -> Symbolic (SBV a)
@@ -180,17 +180,17 @@
 
                                    constrain $ lower .&& upper
 
-                                   return x
+                                   pure x
 
         isFeasible :: Range a -> IO Bool
         isFeasible r = runSMTWith cfg $ do _ <- witness r
 
                                            query $ do cs <- checkSat
                                                       case cs of
-                                                        Unsat  -> return False
+                                                        Unsat  -> pure False
                                                         DSat{} -> error "Data.SBV.interval.isFeasible: Solver returned a delta-satisfiable result!"
                                                         Unk    -> error "Data.SBV.interval.isFeasible: Solver said unknown!"
-                                                        Sat    -> return True
+                                                        Sat    -> pure True
 
         bisect :: Range a -> IO (Maybe [Range a])
         bisect r@(Range lo hi) = runSMTWith cfg $ do x <- witness r
@@ -199,14 +199,14 @@
 
                                                      query $ do cs <- checkSat
                                                                 case cs of
-                                                                  Unsat  -> return Nothing
+                                                                  Unsat  -> pure Nothing
                                                                   DSat{} -> error "Data.SBV.interval.bisect: Solver returned a delta-satisfiable result!"
                                                                   Unk    -> error "Data.SBV.interval.bisect: Solver said unknown!"
                                                                   Sat    -> do midV <- Open <$> getValue x
-                                                                               return $ Just [Range lo midV, Range midV hi]
+                                                                               pure $ Just [Range lo midV, Range midV hi]
 
         search :: [Range a] -> [Range a] -> IO [Range a]
-        search []     sofar = return $ reverse sofar
+        search []     sofar = pure $ reverse sofar
         search (c:cs) sofar = do feasible <- isFeasible c
                                  if feasible
                                     then do mbCS <- bisect c
diff --git a/Data/SBV/Tools/STree.hs b/Data/SBV/Tools/STree.hs
--- a/Data/SBV/Tools/STree.hs
+++ b/Data/SBV/Tools/STree.hs
@@ -57,7 +57,7 @@
 writeSTree s i j = walk (blastBE i) s
   where walk []     _          = SLeaf j
         walk (b:bs) (SBin l r) = SBin (ite b l (walk bs l)) (ite b (walk bs r) r)
-        walk _      _          = error $ "SBV.STree.writeSTree: Impossible happened while reading: " ++ show i
+        walk _      _          = error $ "SBV.STree.writeSTree: Impossible happened while writing: " ++ show i
 
 -- | Construct the fully balanced initial tree using the given values.
 mkSTree :: forall i e. HasKind i => [SBV e] -> STree i e
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
@@ -13,12 +13,10 @@
 -- several example proofs.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE FlexibleContexts       #-}
-{-# LANGUAGE MultiParamTypeClasses  #-}
-{-# LANGUAGE NamedFieldPuns         #-}
-{-# LANGUAGE ScopedTypeVariables    #-}
-{-# LANGUAGE TypeFamilies           #-}
-{-# LANGUAGE TypeOperators          #-}
+{-# LANGUAGE FlexibleContexts    #-}
+{-# LANGUAGE NamedFieldPuns      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeOperators       #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -27,7 +25,7 @@
           Program(..), Stmt(..), assert, stable
 
         -- * Invariants, measures, and stability
-        , Invariant, Measure, Stable
+        , Invariant, WPMeasure, Stable
 
         -- * Verification conditions
         , VC(..)
@@ -75,7 +73,7 @@
 --
 -- The 'setup' field is reserved for any symbolic code you might
 -- want to run before the proof takes place, typically for calls
--- to 'Data.SBV.setOption'. If not needed, simply pass @return ()@.
+-- to 'Data.SBV.setOption'. If not needed, simply pass @pure ()@.
 -- For an interesting use case where we use setup to axiomatize
 -- the spec, see "Documentation.SBV.Examples.WeakestPreconditions.Fib"
 -- and "Documentation.SBV.Examples.WeakestPreconditions.GCD".
@@ -95,18 +93,18 @@
 
 -- | A measure takes the state and returns a sequence of integers. The ordering
 -- will be done lexicographically over the elements.
-type Measure st = st -> [SInteger]
+type WPMeasure st = st -> [SInteger]
 
 -- | A statement in our imperative program, parameterized over the state.
-data Stmt st = Skip                                                                     -- ^ Skip, do nothing.
-             | Abort String                                                             -- ^ Abort execution. The name is for diagnostic purposes.
-             | Assign (st -> st)                                                        -- ^ Assignment: Transform the state by a function.
-             | If (st -> SBool) (Stmt st) (Stmt st)                                     -- ^ Conditional: @If condition thenBranch elseBranch@.
-             | While String (Invariant st) (Maybe (Measure st)) (st -> SBool) (Stmt st) -- ^ A while loop: @While name invariant measure condition body@.
-                                                                                        -- The string @name@ is merely for diagnostic purposes.
-                                                                                        -- If the measure is 'Nothing', then only partial correctness
-                                                                                        -- of this loop will be proven.
-             | Seq [Stmt st]                                                            -- ^ A sequence of statements.
+data Stmt st = Skip                                                                       -- ^ Skip, do nothing.
+             | Abort String                                                               -- ^ Abort execution. The name is for diagnostic purposes.
+             | Assign (st -> st)                                                          -- ^ Assignment: Transform the state by a function.
+             | If (st -> SBool) (Stmt st) (Stmt st)                                       -- ^ Conditional: @If condition thenBranch elseBranch@.
+             | While String (Invariant st) (Maybe (WPMeasure st)) (st -> SBool) (Stmt st) -- ^ A while loop: @While name invariant measure condition body@.
+                                                                                          -- The string @name@ is merely for diagnostic purposes.
+                                                                                          -- If the measure is 'Nothing', then only partial correctness
+                                                                                          -- of this loop will be proven.
+             | Seq [Stmt st]                                                              -- ^ A sequence of statements.
 
 -- | An 'assert' is a quick way of ensuring some condition holds. If it does,
 -- then it's equivalent to 'Skip'. Otherwise, it is equivalent to 'Abort'.
@@ -236,7 +234,7 @@
                  Sat    -> do let checkVC :: (SBool, VC st SInteger) -> Query [VC res Integer]
                                   checkVC (cond, vc) = do c <- getValue cond
                                                           if c
-                                                             then return []   -- The VC was OK
+                                                             then pure []   -- The VC was OK
                                                              else do vc' <- case vc of
                                                                               BadPrecondition     s                 -> BadPrecondition     <$> project s
                                                                               BadPostcondition    s1 s2             -> BadPostcondition    <$> project s1 <*> project s2
@@ -246,13 +244,13 @@
                                                                               InvariantMaintain l s1 s2             -> InvariantMaintain l <$> project s1 <*> project s2
                                                                               MeasureBound      l (s, m)            -> do r <- project s
                                                                                                                           v <- mapM getValue m
-                                                                                                                          return $ MeasureBound l (r, v)
+                                                                                                                          pure $ MeasureBound l (r, v)
                                                                               MeasureDecrease   l (s1, i1) (s2, i2) -> do r1 <- project s1
                                                                                                                           v1 <- mapM getValue i1
                                                                                                                           r2 <- project s2
                                                                                                                           v2 <- mapM getValue i2
-                                                                                                                          return $ MeasureDecrease l (r1, v1) (r2, v2)
-                                                                     return [vc']
+                                                                                                                          pure $ MeasureDecrease l (r1, v1) (r2, v2)
+                                                                     pure [vc']
 
                               badVCs <- concat <$> mapM checkVC vcs
 
@@ -269,7 +267,7 @@
                               let disp c = mapM_ msg ["  " ++ l | l <- lines (show c)]
                               mapM_ disp badVCs
 
-                              return $ Failed badVCs
+                              pure $ Failed badVCs
 
         msg = io . when wpVerbose . putStrLn
 
@@ -277,28 +275,28 @@
         wp :: st -> Stmt st -> (st -> [(SBool, VC st SInteger)]) -> Query (st -> [(SBool, VC st SInteger)])
 
         -- Skip simply keeps the conditions
-        wp _ Skip post = return post
+        wp _ Skip post = pure post
 
         -- Abort is never satisfiable. The only way to have Abort's VC to pass is
         -- to run it in a precondition (either via program or in an if branch) that
         -- evaluates to false, i.e., it must not be reachable.
-        wp start (Abort nm) _ = return $ \st -> [(sFalse, AbortReachable nm start st)]
+        wp start (Abort nm) _ = pure $ \st -> [(sFalse, AbortReachable nm start st)]
 
         -- Assign simply transforms the state and passes on. It also checks that the
         -- stability constraints are not violated.
-        wp _ (Assign f) post = return $ \st -> let st'       = f st
-                                                   vcs       = map (\s -> let (nm, b) = s st st' in (b, Unstable nm st st')) stability
-                                               in vcs ++ post st'
+        wp _ (Assign f) post = pure $ \st -> let st'       = f st
+                                                 vcs       = map (\s -> let (nm, b) = s st st' in (b, Unstable nm st st')) stability
+                                             in vcs ++ post st'
 
         -- Conditional: We separately collect the VCs, and predicate with the proper branch condition
         wp start (If c tb fb) post = do tWP <- wp start tb post
                                         fWP <- wp start fb post
-                                        return $ \st -> let cond = c st
-                                                        in   [(     cond .=> b, v) | (b, v) <- tWP st]
-                                                          ++ [(sNot cond .=> b, v) | (b, v) <- fWP st]
+                                        pure $ \st -> let cond = c st
+                                                      in   [(     cond .=> b, v) | (b, v) <- tWP st]
+                                                        ++ [(sNot cond .=> b, v) | (b, v) <- fWP st]
 
         -- Sequencing: Simply run through the statements
-        wp _     (Seq [])              post = return post
+        wp _     (Seq [])              post = pure post
         wp start (Seq (s:ss))          post = wp start s =<< wp start (Seq ss) post
 
         -- While loop, where all the WP magic happens!
@@ -308,7 +306,7 @@
                 let noMeasure = isNothing mm
                     m         = fromJust mm
                     curM      = m st'
-                    zero      = map (const 0) curM
+                    zeroM     = map (const 0) curM
 
                     iterates   = inv st' .&&       cond st'
                     terminates = inv st' .&& sNot (cond st')
@@ -317,7 +315,7 @@
                 -- Condition 1: Invariant must hold prior to loop entry
                 invHoldsPrior <- wp start Skip (\st -> [(inv st, InvariantPre nm st)])
 
-                -- Condition 2: If we iterate, invariant must be maitained by the body
+                -- Condition 2: If we iterate, invariant must be maintained by the body
                 invMaintained <- wp st' body (\st -> [(iterates .=> inv st, InvariantMaintain nm st' st)])
 
                 -- Condition 3: If we terminate, invariant must be strong enough to establish the post condition
@@ -325,20 +323,20 @@
 
                 -- Condition 4: If we iterate, measure must always be non-negative
                 measureNonNegative <- if noMeasure
-                                      then return  (const [])
-                                      else wp st' Skip (const [(iterates .=> curM .>= zero, MeasureBound nm (st', curM))])
+                                      then pure  (const [])
+                                      else wp st' Skip (const [(iterates .=> curM .>= zeroM, MeasureBound nm (st', curM))])
 
                 -- Condition 5: If we iterate, the measure must decrease
                 measureDecreases <- if noMeasure
-                                    then return  (const [])
+                                    then pure  (const [])
                                     else wp st' body (\st -> let prevM = m st in [(iterates .=> prevM .< curM, MeasureDecrease nm (st', curM) (st, prevM))])
 
                 -- Simply concatenate the VCs from all our conditions:
-                return $ \st ->    invHoldsPrior      st
-                                ++ invMaintained      st'
-                                ++ invEstablish       st'
-                                ++ measureNonNegative st'
-                                ++ measureDecreases   st'
+                pure $ \st ->    invHoldsPrior      st
+                              ++ invMaintained      st'
+                              ++ invEstablish       st'
+                              ++ measureNonNegative st'
+                              ++ measureDecreases   st'
 
 -- | Check correctness using the default solver. Equivalent to @'wpProveWith' 'defaultWPCfg'@.
 wpProve :: (Show res, Mergeable st, Queriable IO st, res ~ QueryResult st) => Program st -> IO (ProofResult res)
@@ -390,7 +388,7 @@
                           else giveUp start (BadPrecondition start) "*** Initial state does not satisfy the precondition:"
 
                 case status of
-                  s@Stuck{} -> return s
+                  s@Stuck{} -> pure s
                   Good end  -> if unwrap [] "checking postcondition" (postcondition end)
                                then step [] end "*** Program successfully terminated, post condition holds of the final state:"
                                else giveUp end (BadPostcondition start end) "*** Failed, final state does not satisfy the postcondition:"
@@ -405,16 +403,16 @@
         step :: Loc -> st -> String -> IO (Status st)
         step l st m = do putStrLn $ sLoc l m
                          printST st
-                         return $ Good st
+                         pure $ Good st
 
         stop :: Loc -> VC st Integer -> String -> IO (Status st)
         stop l vc m = do putStrLn $ sLoc l m
-                         return $ Stuck vc
+                         pure $ Stuck vc
 
         giveUp :: st -> VC st Integer -> String -> IO (Status st)
         giveUp st vc m = do r <- stop [] vc m
                             printST st
-                            return r
+                            pure r
 
         dispST :: st -> String
         dispST st = intercalate "\n" ["  " ++ l | l <- lines (show st)]
@@ -436,7 +434,7 @@
                                                     ]
 
         go :: Loc -> Stmt st -> Status st -> IO (Status st)
-        go _   _ s@Stuck{}  = return s
+        go _   _ s@Stuck{}  = pure s
         go loc p (Good  st) = analyze p
           where analyze Skip = step loc st "Skip"
 
@@ -455,7 +453,7 @@
                   where branchTrue = unwrap loc "evaluating the test condition" (c st)
 
                 analyze (Seq stmts)  = walk stmts 1 (Good st)
-                  where walk []     _ is = return is
+                  where walk []     _ is = pure is
                         walk (s:ss) c is = walk ss (c+1) =<< go (Line c : loc) s is
 
                 analyze (While loopName invariant mbMeasure condition body)
@@ -472,20 +470,20 @@
                          currentMeasure   = map (unwrap loc (tag  "evaluating the measure"))   . measure
                          currentInvariant = unwrap loc (tag  "evaluating the invariant")       . invariant
 
-                         while _ _      _      s@Stuck{}  = return s
+                         while _ _      _      s@Stuck{}  = pure s
                          while c prevST mbPrev (Good  is)
                            | not (currentCondition is)
                            = step loc is $ tag "condition fails, terminating"
                            | not (currentInvariant is)
                            = stop loc (InvariantMaintain loopName prevST is) $ tag "invariant fails to hold in iteration " ++ show c
-                           | hasMeasure && mCur < zero
+                           | hasMeasure && mCur < zeroM
                            = stop loc (MeasureBound loopName (is, mCur)) $ tag "measure must be non-negative, evaluated to: " ++ show mCur
                            | hasMeasure, Just mPrev <- mbPrev, mCur >= mPrev
                            = stop loc (MeasureDecrease loopName (prevST, mPrev) (is, mCur)) $ tag $ "measure failed to decrease, prev = " ++ show mPrev ++ ", current = " ++ show mCur
                            | True
                            = do nextState <- go (Iteration c : loc) body =<< step loc is (tag "condition holds, executing the body")
                                 while (c+1) is (Just mCur) nextState
-                           where mCur = currentMeasure is
-                                 zero = map (const 0) mCur
+                           where mCur  = currentMeasure is
+                                 zeroM = map (const 0) mCur
 
 {- HLint ignore traceExecution "Use fromMaybe" -}
diff --git a/Data/SBV/Trans.hs b/Data/SBV/Trans.hs
--- a/Data/SBV/Trans.hs
+++ b/Data/SBV/Trans.hs
@@ -26,14 +26,16 @@
   , SWord8, SWord16, SWord32, SWord64, SWord, WordN
   -- *** Signed bit-vectors
   , SInt8, SInt16, SInt32, SInt64, SInt, IntN
-  -- *** Converting between fixed-size and arbitrary bitvectors
+  -- *** Converting between fixed-size and arbitrary bit-vectors
   , BVIsNonZero, FromSized, ToSized, fromSized, toSized
   -- ** Unbounded integers
   , SInteger
   -- ** Floating point numbers
   , SFloat, SDouble, SFloatingPoint
   -- ** Algebraic reals
-  , SReal, AlgReal, sRealToSInteger
+  , SReal, AlgReal
+  , sRealToSIntegerFloor, sRealToSIntegerCeiling, sRealToSIntegerTruncate
+  , sRealToSIntegerRoundAway, sRealToSIntegerRoundToEven, sRealToSIntegerRM
   -- ** Characters, Strings and Regular Expressions
   , SChar, SString
   -- ** Symbolic lists
@@ -49,7 +51,7 @@
   , sBools, sWord8s, sWord16s, sWord32s, sWord64s, sWords, sInt8s, sInt16s, sInt32s, sInt64s, sInts, sIntegers, sReals, sFloats, sDoubles, sChars, sStrings, sLists, sArrays
 
   -- * Symbolic Equality and Comparisons
-  , EqSymbolic(..), OrdSymbolic(..), Equality(..)
+  , EqSymbolic(..), OrdSymbolic(..), Zero(..), MeasureOf, Equality(..)
   -- * Conditionals: Mergeable values
   , Mergeable(..), ite, iteLazy
 
@@ -67,11 +69,11 @@
   -- ** Splitting, joining, and extending bit-vectors
   , bvExtract, (#), zeroExtend, signExtend, bvDrop, bvTake
   -- ** Exponentiation
-  , (.^)
+  , (.^), (.**)
   -- * IEEE-floating point numbers
   , IEEEFloating(..), RoundingMode(..), SRoundingMode, nan, infinity, sNaN, sInfinity
   -- ** Rounding modes
-  , sRoundNearestTiesToEven, sRoundNearestTiesToAway, sRoundTowardPositive, sRoundTowardNegative, sRoundTowardZero, sRNE, sRNA, sRTP, sRTN, sRTZ
+  , sRoundNearestTiesToEven, sRoundNearestTiesToAway, sRoundTowardPositive, sRoundTowardNegative, sRoundTowardZero, sRNE, sRNA, sRTP, sRTN, sRTZ, sCaseRoundingMode
   -- ** Conversion to/from floats
   , IEEEFloatConvertible(..)
 
@@ -85,11 +87,8 @@
   , blastSDouble
   , blastSFloatingPoint
 
-  -- * Enumerations
-  , mkSymbolicEnumeration
-
-  -- * Uninterpreted sorts, axioms, constants, and functions
-  , mkUninterpretedSort, SMTDefinable(..)
+  -- * Symbolic types
+  , mkSymbolic, SMTDefinable(..), smtFunction, smtFunctionWithMeasure
 
   -- * Properties, proofs, and satisfiability
   , Predicate, ConstraintSet, ProvableM(..), Provable, SatisfiableM(..), Satisfiable
@@ -137,7 +136,7 @@
 
   -- ** Programmable model extraction
   , SatModel(..), Modelable(..), displayModels, extractModels
-  , getModelDictionaries, getModelValues, getModelUninterpretedValues
+  , getModelDictionaries, getModelValues
 
   -- * SMT Interface
   , SMTConfig(..), Timing(..), SMTLibVersion(..), Solver(..), SMTSolver(..)
diff --git a/Data/SBV/Trans/Control.hs b/Data/SBV/Trans/Control.hs
--- a/Data/SBV/Trans/Control.hs
+++ b/Data/SBV/Trans/Control.hs
@@ -22,7 +22,7 @@
 
      -- * Querying the solver
      -- ** Extracting values
-     , getValue, getFunction, getUninterpretedValue, getModel, getAssignment, getSMTResult, getUnknownReason, getObservables
+     , getValue, getFunction, getModel, getAssignment, getSMTResult, getUnknownReason, getObservables
 
      -- ** Extracting the unsat core
      , getUnsatCore
diff --git a/Data/SBV/Tuple.hs b/Data/SBV/Tuple.hs
--- a/Data/SBV/Tuple.hs
+++ b/Data/SBV/Tuple.hs
@@ -16,11 +16,9 @@
 {-# LANGUAGE FlexibleInstances      #-}
 {-# LANGUAGE FunctionalDependencies #-}
 {-# LANGUAGE KindSignatures         #-}
-{-# LANGUAGE Rank2Types             #-}
-{-# LANGUAGE ScopedTypeVariables    #-}
 {-# LANGUAGE TypeApplications       #-}
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
 module Data.SBV.Tuple (
   -- * Symbolic field access
@@ -29,6 +27,8 @@
   , tuple, untuple
   -- * Swapping, only for 2-tuples
   , swap
+  -- * Currying and uncurrying
+  , curry, uncurry, curry3, uncurry3
   -- * Extractors for 2-tuple
   , fst, snd
   -- * Extractors for 3-tuple
@@ -41,7 +41,7 @@
 import Data.SBV.Core.Symbolic
 import Data.SBV.Core.Model
 
-import Prelude hiding (fst, snd)
+import Prelude hiding (fst, snd, curry, uncurry)
 
 #ifdef DOCTEST
 -- $setup
@@ -63,6 +63,29 @@
 swap t = tuple (b, a)
   where (a, b) = untuple t
 
+-- | Symbolic currying: turn a function that takes a symbolic 2-tuple into one
+-- that takes its two components separately. The inverse of 'uncurry'.
+curry :: (SymVal a, SymVal b) => (STuple a b -> r) -> SBV a -> SBV b -> r
+curry f a b = f (tuple (a, b))
+
+-- | Symbolic uncurrying: turn a function of two arguments into one that takes a
+-- symbolic 2-tuple. The inverse of 'curry'.
+uncurry :: (SymVal a, SymVal b) => (SBV a -> SBV b -> r) -> STuple a b -> r
+uncurry f t = f a b
+  where (a, b) = untuple t
+
+-- | Symbolic currying for 3-tuples: turn a function that takes a symbolic
+-- 3-tuple into one that takes its three components separately. The inverse of
+-- 'uncurry3'.
+curry3 :: (SymVal a, SymVal b, SymVal c) => (STuple3 a b c -> r) -> SBV a -> SBV b -> SBV c -> r
+curry3 f a b c = f (tuple (a, b, c))
+
+-- | Symbolic uncurrying for 3-tuples: turn a function of three arguments into
+-- one that takes a symbolic 3-tuple. The inverse of 'curry3'.
+uncurry3 :: (SymVal a, SymVal b, SymVal c) => (SBV a -> SBV b -> SBV c -> r) -> STuple3 a b c -> r
+uncurry3 f t = f a b c
+  where (a, b, c) = untuple t
+
 -- | First of a tuple
 fst :: (SymVal a, SymVal b) => STuple a b -> SBV a
 fst t = a where (a, _) = untuple t
@@ -79,7 +102,7 @@
 snd3 :: (SymVal a, SymVal b, SymVal c) => STuple3 a b c -> SBV b
 snd3 t = b where (_, b, _) = untuple t
 
--- | Thirdd of a 3-tuple
+-- | Third of a 3-tuple
 thd3 :: (SymVal a, SymVal b, SymVal c) => STuple3 a b c -> SBV c
 thd3 t = c where (_, _, c) = untuple t
 
diff --git a/Data/SBV/Utils/CrackNum.hs b/Data/SBV/Utils/CrackNum.hs
--- a/Data/SBV/Utils/CrackNum.hs
+++ b/Data/SBV/Utils/CrackNum.hs
@@ -11,7 +11,7 @@
 
 {-# LANGUAGE NamedFieldPuns #-}
 
-{-# OPTIONS_GHC -Wall -Werror -Wno-incomplete-uni-patterns #-}
+{-# OPTIONS_GHC -Wall -Werror #-}
 
 module Data.SBV.Utils.CrackNum (
         crackNum
@@ -42,26 +42,33 @@
   crackNum cv verbose mbIV = case kindOf cv of
                                -- Maybe one day we'll have a use for these, currently cracking them
                                -- any further seems overkill
+                               KVar       {}  -> Nothing
                                KBool      {}  -> Nothing
                                KUnbounded {}  -> Nothing
                                KReal      {}  -> Nothing
-                               KUserSort  {}  -> Nothing
+                               KApp       {}  -> Nothing
+                               KADT       {}  -> Nothing
                                KChar      {}  -> Nothing
                                KString    {}  -> Nothing
                                KList      {}  -> Nothing
                                KSet       {}  -> Nothing
                                KTuple     {}  -> Nothing
-                               KMaybe     {}  -> Nothing
-                               KEither    {}  -> Nothing
                                KRational  {}  -> Nothing
                                KArray     {}  -> Nothing
 
                                -- Actual crackables
-                               KFloat{}       -> Just $ let CFloat   f = cvVal cv in float verbose mbIV f
-                               KDouble{}      -> Just $ let CDouble  d = cvVal cv in float verbose mbIV d
-                               KFP{}          -> Just $ let CFP      f = cvVal cv in float verbose mbIV f
-                               KBounded sg sz -> Just $ let CInteger i = cvVal cv in int   sg sz i
+                               KFloat{}       | CFloat   f <- cvVal cv -> Just $ float verbose mbIV f
+                                              | True                   -> Nothing   -- Can't really happen; but don't die
 
+                               KDouble{}      | CDouble  d <- cvVal cv -> Just $ float verbose mbIV d
+                                              | True                   -> Nothing   -- Can't really happen; but don't die
+
+                               KFP{}          | CFP      f <- cvVal cv -> Just $ float verbose mbIV f
+                                              | True                   -> Nothing   -- Can't really happen; but don't die
+
+                               KBounded sg sz | CInteger i <- cvVal cv -> Just $ int   sg sz i
+                                              | True                   -> Nothing   -- Can't really happen; but don't die
+
 -- How far off the screen we want displayed? Somewhat experimentally found.
 tab :: String
 tab = replicate 18 ' '
@@ -76,7 +83,7 @@
 
 -- Convert bits to the corresponding integer.
 getVal :: [Bool] -> Integer
-getVal = foldl (\s b -> 2 * s + if b then 1 else 0) 0
+getVal = foldl' (\s b -> 2 * s + if b then 1 else 0) 0
 
 -- Show in hex, but pay attention to how wide a field it should be in
 mkHex :: [Bool] -> String
diff --git a/Data/SBV/Utils/Lib.hs b/Data/SBV/Utils/Lib.hs
--- a/Data/SBV/Utils/Lib.hs
+++ b/Data/SBV/Utils/Lib.hs
@@ -9,7 +9,6 @@
 -- Misc helpers
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE RankNTypes          #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeApplications    #-}
 
@@ -18,22 +17,30 @@
 module Data.SBV.Utils.Lib ( mlift2, mlift3, mlift4, mlift5, mlift6, mlift7, mlift8
                           , joinArgs, splitArgs
                           , stringToQFS, qfsToString
+                          , showText
                           , isKString
                           , checkObservableName
-                          , needsBars, barify, isEnclosedInBars
-                          , noSurrounding, unQuote, unBar, nameSupply
+                          , needsBars, barify
+                          , unQuote, unBar, nameSupply
                           , atProxy
+                          , mapToSortedList
                           ,   curry2,   curry3,   curry4,   curry5,   curry6,   curry7,   curry8,   curry9,   curry10,   curry11,   curry12
                           , uncurry2, uncurry3, uncurry4, uncurry5, uncurry6, uncurry7, uncurry8, uncurry9, uncurry10, uncurry11, uncurry12
                           )
                           where
 
 import Data.Char    (isSpace, chr, ord, isDigit, isAscii, isAlphaNum)
-import Data.List    (isPrefixOf, isSuffixOf)
+import Data.List    (isPrefixOf, isSuffixOf, sortBy)
+import Data.Ord     (comparing)
 import Data.Dynamic (fromDynamic, toDyn, Typeable)
 import Data.Maybe   (fromJust, isJust, isNothing)
 import Data.Proxy
+import Data.Text    (Text)
 
+import qualified Data.Text as T
+
+import qualified Data.Map.Strict as Map
+
 import Type.Reflection (typeRep)
 
 import Numeric (readHex, showHex)
@@ -47,31 +54,31 @@
 
 -- | Monadic lift over 2-tuples
 mlift2 :: Monad m => (a' -> b' -> r) -> (a -> m a') -> (b -> m b') -> (a, b) -> m r
-mlift2 k f g (a, b) = f a >>= \a' -> g b >>= \b' -> return $ k a' b'
+mlift2 k f g (a, b) = f a >>= \a' -> g b >>= \b' -> pure $ k a' b'
 
 -- | Monadic lift over 3-tuples
 mlift3 :: Monad m => (a' -> b' -> c' -> r) -> (a -> m a') -> (b -> m b') -> (c -> m c') -> (a, b, c) -> m r
-mlift3 k f g h (a, b, c) = f a >>= \a' -> g b >>= \b' -> h c >>= \c' -> return $ k a' b' c'
+mlift3 k f g h (a, b, c) = f a >>= \a' -> g b >>= \b' -> h c >>= \c' -> pure $ k a' b' c'
 
 -- | Monadic lift over 4-tuples
 mlift4 :: Monad m => (a' -> b' -> c' -> d' -> r) -> (a -> m a') -> (b -> m b') -> (c -> m c') -> (d -> m d') -> (a, b, c, d) -> m r
-mlift4 k f g h i (a, b, c, d) = f a >>= \a' -> g b >>= \b' -> h c >>= \c' -> i d >>= \d' -> return $ k a' b' c' d'
+mlift4 k f g h i (a, b, c, d) = f a >>= \a' -> g b >>= \b' -> h c >>= \c' -> i d >>= \d' -> pure $ k a' b' c' d'
 
 -- | Monadic lift over 5-tuples
 mlift5 :: Monad m => (a' -> b' -> c' -> d' -> e' -> r) -> (a -> m a') -> (b -> m b') -> (c -> m c') -> (d -> m d') -> (e -> m e') -> (a, b, c, d, e) -> m r
-mlift5 k f g h i j (a, b, c, d, e) = f a >>= \a' -> g b >>= \b' -> h c >>= \c' -> i d >>= \d' -> j e >>= \e' -> return $ k a' b' c' d' e'
+mlift5 k f g h i j (a, b, c, d, e) = f a >>= \a' -> g b >>= \b' -> h c >>= \c' -> i d >>= \d' -> j e >>= \e' -> pure $ k a' b' c' d' e'
 
 -- | Monadic lift over 6-tuples
 mlift6 :: Monad m => (a' -> b' -> c' -> d' -> e' -> f' -> r) -> (a -> m a') -> (b -> m b') -> (c -> m c') -> (d -> m d') -> (e -> m e') -> (f -> m f') -> (a, b, c, d, e, f) -> m r
-mlift6 k f g h i j l (a, b, c, d, e, y) = f a >>= \a' -> g b >>= \b' -> h c >>= \c' -> i d >>= \d' -> j e >>= \e' -> l y >>= \y' -> return $ k a' b' c' d' e' y'
+mlift6 k f g h i j l (a, b, c, d, e, y) = f a >>= \a' -> g b >>= \b' -> h c >>= \c' -> i d >>= \d' -> j e >>= \e' -> l y >>= \y' -> pure $ k a' b' c' d' e' y'
 
 -- | Monadic lift over 7-tuples
 mlift7 :: Monad m => (a' -> b' -> c' -> d' -> e' -> f' -> g' -> r) -> (a -> m a') -> (b -> m b') -> (c -> m c') -> (d -> m d') -> (e -> m e') -> (f -> m f') -> (g -> m g') -> (a, b, c, d, e, f, g) -> m r
-mlift7 k f g h i j l m (a, b, c, d, e, y, z) = f a >>= \a' -> g b >>= \b' -> h c >>= \c' -> i d >>= \d' -> j e >>= \e' -> l y >>= \y' -> m z >>= \z' -> return $ k a' b' c' d' e' y' z'
+mlift7 k f g h i j l m (a, b, c, d, e, y, z) = f a >>= \a' -> g b >>= \b' -> h c >>= \c' -> i d >>= \d' -> j e >>= \e' -> l y >>= \y' -> m z >>= \z' -> pure $ k a' b' c' d' e' y' z'
 
 -- | Monadic lift over 8-tuples
 mlift8 :: Monad m => (a' -> b' -> c' -> d' -> e' -> f' -> g' -> h' -> r) -> (a -> m a') -> (b -> m b') -> (c -> m c') -> (d -> m d') -> (e -> m e') -> (f -> m f') -> (g -> m g') -> (h -> m h') -> (a, b, c, d, e, f, g, h) -> m r
-mlift8 k f g h i j l m n (a, b, c, d, e, y, z, w) = f a >>= \a' -> g b >>= \b' -> h c >>= \c' -> i d >>= \d' -> j e >>= \e' -> l y >>= \y' -> m z >>= \z' -> n w >>= \w' -> return $ k a' b' c' d' e' y' z' w'
+mlift8 k f g h i j l m n (a, b, c, d, e, y, z, w) = f a >>= \a' -> g b >>= \b' -> h c >>= \c' -> i d >>= \d' -> j e >>= \e' -> l y >>= \y' -> m z >>= \z' -> n w >>= \w' -> pure $ k a' b' c' d' e' y' z' w'
 
 -- Command line argument parsing code courtesy of Neil Mitchell's cmdargs package: see
 -- <http://github.com/ndmitchell/cmdargs/blob/master/System/Console/CmdArgs/Explicit/SplitJoin.hs>
@@ -135,6 +142,10 @@
         -- Otherwise, just proceed; hopefully we covered everything above
         go (c : rest) = c : go rest
 
+-- | Show a value as 'Text'.
+showText :: Show a => a -> Text
+showText = T.pack . show
+
 -- | Given a Haskell string, convert it to SMTLib. if ord is 0x00020 to 0x0007E, then we print it as is
 -- to cover the printable ASCII range.
 stringToQFS :: String -> String
@@ -273,3 +284,9 @@
 
 uncurry12 :: (a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k -> l -> z) -> (a, b, c, d, e, f, g, h, i, j, k, l) -> z
 uncurry12 fn (a, b, c, d, e, f, g, h, i, j, k, l) = fn a b c d e f g h i j k l
+
+-- | Convert a map to a list of @(value, key)@ pairs, sorted by value.
+-- Useful when the map is keyed by a descriptor but indexed by an integer
+-- that determines output order.
+mapToSortedList :: Ord v => Map.Map k v -> [(v, k)]
+mapToSortedList = sortBy (comparing fst) . map (\(a, b) -> (b, a)) . Map.toList
diff --git a/Data/SBV/Utils/Numeric.hs b/Data/SBV/Utils/Numeric.hs
--- a/Data/SBV/Utils/Numeric.hs
+++ b/Data/SBV/Utils/Numeric.hs
@@ -9,24 +9,29 @@
 -- Various number related utilities
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleContexts  #-}
+{-# LANGUAGE OverloadedStrings #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
 module Data.SBV.Utils.Numeric (
            fpMaxH, fpMinH, fp2fp, fpRemH, fpRoundToIntegralH, fpIsEqualObjectH, fpCompareObjectH, fpIsNormalizedH
+         , roundAway
+         , divEucl, modEucl
          , floatToWord, wordToFloat, doubleToWord, wordToDouble
+         , RoundingMode(..), smtRoundingMode
          ) where
 
 import Data.Word
+import Data.Text         (Text)
 import Data.Array.ST     (newArray, readArray, MArray, STUArray)
 import Data.Array.Unsafe (castSTUArray)
 import GHC.ST            (runST, ST)
 
+import Test.QuickCheck  (Arbitrary(..), elements)
+
 -- | The SMT-Lib (in particular Z3) implementation for min/max for floats does not agree with
--- Haskell's; and also it does not agree with what the hardware does. Sigh.. See:
---      <https://gitlab.haskell.org/ghc/ghc/-/issues/10378>
---      <http://github.com/Z3Prover/z3/issues/68>
+-- Haskell's; and also it does not agree with what the hardware does. Sigh..
 -- So, we codify here what the Z3 (SMTLib) is implementing for fpMax.
 -- The discrepancy with Haskell is that the NaN propagation doesn't work in Haskell
 -- The discrepancy with x86 is that given +0/-0, x86 returns the second argument; SMTLib is non-deterministic
@@ -69,7 +74,7 @@
   | isInfinite x || isNaN x = 0 / 0
   | y == 0       || isNaN y = 0 / 0
   | isInfinite y            = x
-  | True                    = pSign (x - fromRational (fromInteger d * ry))
+  | True                    = pSign (fromRational (rx - fromInteger d * ry))
   where rx, ry, rd :: Rational
         rx = toRational x
         ry = toRational y
@@ -87,7 +92,7 @@
   | isNaN x      = x
   | x == 0       = x
   | isInfinite x = x
-  | i == 0       = if x < 0 || isNegativeZero x then -0.0 else 0.0
+  | i == 0       = if x < 0 then -0.0 else 0.0
   | True         = fromInteger i
   where i :: Integer
         i = round x
@@ -120,6 +125,33 @@
 fpIsNormalizedH :: RealFloat a => a -> Bool
 fpIsNormalizedH x = not (isDenormalized x || isInfinite x || isNaN x || x == 0)
 
+-- | @'roundAway' x@ returns the nearest integer to @x@; the integer furthest
+-- away from @0@ if @x@ is equidistant between two integers.
+
+-- This implementation is taken directly from the @fp-ieee@ library. Somewhat
+-- surprisingly, 'roundAway' is not a method of the 'RealFrac' class!
+roundAway :: (RealFrac a, Integral b) => a -> b
+roundAway x = case properFraction x of
+                -- x == n + f, signum x == signum f, 0 <= abs f < 1
+                (n,r) -> if abs r < 0.5 then
+                           n
+                         else
+                           if r < 0 then
+                             n - 1
+                           else
+                             n + 1
+
+-- | Euclidean division. @'divEucl' a b@ returns the integer @q@ satisfying the
+-- equations @a = (b * q) + r@ and @0 <= r < abs b@, where @'modEucl' a b = r@.
+divEucl :: Integral a => a -> a -> a
+divEucl a b = div a (abs b) * signum b
+
+-- | Euclidean modular division. @'modEucl' a b@ returns the integer @r@
+-- satisfying the equations @a = (b * q) + r@ and @0 <= r < abs b@, where
+-- @'divEucl' a b = q@.
+modEucl :: Integral a => a -> a -> a
+modEucl a b = mod a (abs b)
+
 -------------------------------------------------------------------------
 -- Reinterpreting float/double as word32/64 and back. Here, we use the
 -- definitions from the reinterpret-cast package:
@@ -152,3 +184,30 @@
 {-# INLINE cast #-}
 cast :: (MArray (STUArray s) a (ST s), MArray (STUArray s) b (ST s)) => a -> ST s b
 cast x = newArray (0 :: Int, 0) x >>= castSTUArray >>= flip readArray 0
+
+-- | Rounding mode to be used for the IEEE floating-point operations.
+-- Note that Haskell's default is 'RoundNearestTiesToEven'. If you use
+-- a different rounding mode, then the counter-examples you get may not
+-- match what you observe in Haskell.
+data RoundingMode = RoundNearestTiesToEven  -- ^ Round to nearest representable floating point value.
+                                            -- If precisely at half-way, pick the even number.
+                                            -- (In this context, /even/ means the lowest-order bit is zero.)
+                  | RoundNearestTiesToAway  -- ^ Round to nearest representable floating point value.
+                                            -- If precisely at half-way, pick the number further away from 0.
+                                            -- (That is, for positive values, pick the greater; for negative values, pick the smaller.)
+                  | RoundTowardPositive     -- ^ Round towards positive infinity. (Also known as rounding-up or ceiling.)
+                  | RoundTowardNegative     -- ^ Round towards negative infinity. (Also known as rounding-down or floor.)
+                  | RoundTowardZero         -- ^ Round towards zero. (Also known as truncation.)
+                  deriving (Show, Enum, Bounded)
+
+-- | Arbitrary instance for 'RoundingMode'
+instance Arbitrary RoundingMode where
+  arbitrary = elements [minBound .. maxBound]
+
+-- | Convert a rounding mode to the format SMT-Lib2 understands.
+smtRoundingMode :: RoundingMode -> Text
+smtRoundingMode RoundNearestTiesToEven = "roundNearestTiesToEven"
+smtRoundingMode RoundNearestTiesToAway = "roundNearestTiesToAway"
+smtRoundingMode RoundTowardPositive    = "roundTowardPositive"
+smtRoundingMode RoundTowardNegative    = "roundTowardNegative"
+smtRoundingMode RoundTowardZero        = "roundTowardZero"
diff --git a/Data/SBV/Utils/PrettyNum.hs b/Data/SBV/Utils/PrettyNum.hs
--- a/Data/SBV/Utils/PrettyNum.hs
+++ b/Data/SBV/Utils/PrettyNum.hs
@@ -10,9 +10,10 @@
 -----------------------------------------------------------------------------
 
 {-# LANGUAGE FlexibleInstances   #-}
+{-# LANGUAGE OverloadedStrings   #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
-{-# OPTIONS_GHC -Wall -Werror -Wno-incomplete-uni-patterns #-}
+{-# OPTIONS_GHC -Wall -Werror #-}
 
 module Data.SBV.Utils.PrettyNum (
         PrettyNum(..), readBin, shex, chex, shexI, sbin, sbinI
@@ -21,13 +22,15 @@
       , showNegativeNumber
       ) where
 
-import Data.Bits  ((.&.), countTrailingZeros)
+import Data.Bits  ((.&.), countTrailingZeros, testBit)
 import Data.Char  (intToDigit, ord, chr)
 import Data.Int   (Int8, Int16, Int32, Int64)
 import Data.List  (isPrefixOf)
-import Data.Maybe (fromJust, fromMaybe, listToMaybe)
+import Data.Maybe (fromMaybe, listToMaybe)
 import Data.Ratio (numerator, denominator)
 import Data.Word  (Word8, Word16, Word32, Word64)
+import Data.Text  (Text)
+import qualified Data.Text as T
 
 import qualified Data.Set as Set
 
@@ -35,44 +38,45 @@
 import qualified Numeric as N (showHFloat)
 
 import Data.SBV.Core.Data
-import Data.SBV.Core.Kind (smtType, smtRoundingMode, showBaseKind)
+import Data.SBV.Core.Kind (smtType, showBaseKind)
 
 import Data.SBV.Core.AlgReals    (algRealToSMTLib2)
 import Data.SBV.Core.SizedFloats (fprToSMTLib2, bfToString)
 
-import Data.SBV.Utils.Lib (stringToQFS)
+import Data.SBV.Utils.Lib     (stringToQFS, showText)
+import Data.SBV.Utils.Numeric (smtRoundingMode, floatToWord, doubleToWord)
 
 -- | PrettyNum class captures printing of numbers in hex and binary formats; also supporting negative numbers.
 class PrettyNum a where
   -- | Show a number in hexadecimal, starting with @0x@ and type.
-  hexS :: a -> String
+  hexS :: a -> Text
   -- | Show a number in binary, starting with @0b@ and type.
-  binS :: a -> String
+  binS :: a -> Text
   -- | Show a number in hexadecimal, starting with @0x@ but no type.
-  hexP :: a -> String
+  hexP :: a -> Text
   -- | Show a number in binary, starting with @0b@ but no type.
-  binP :: a -> String
+  binP :: a -> Text
   -- | Show a number in hex, without prefix, or types.
-  hex :: a -> String
+  hex :: a -> Text
   -- | Show a number in bin, without prefix, or types.
-  bin :: a -> String
+  bin :: a -> Text
 
 -- Why not default methods? Because defaults need "Integral a" but Bool is not..
 instance PrettyNum Bool where
-  hexS = show
-  binS = show
-  hexP = show
-  binP = show
-  hex  = show
-  bin  = show
+  hexS = showText
+  binS = showText
+  hexP = showText
+  binP = showText
+  hex  = showText
+  bin  = showText
 
 instance PrettyNum String where
-  hexS = show
-  binS = show
-  hexP = show
-  binP = show
-  hex  = show
-  bin  = show
+  hexS = showText
+  binS = showText
+  hexP = showText
+  binP = showText
+  hex  = showText
+  bin  = showText
 
 instance PrettyNum Word8 where
   hexS = shex True  True  (False, 8)
@@ -164,106 +168,77 @@
   hex  = shexI False False
   bin  = sbinI False False
 
-shBKind :: HasKind a => a -> String
-shBKind a = " :: " ++ showBaseKind (kindOf a)
+shBKind :: HasKind a => a -> Text
+shBKind a = " :: " <> showBaseKind (kindOf a)
 
 instance PrettyNum CV where
-  hexS cv | isUserSort      cv = shows cv                                               $  shBKind cv
-          | isBoolean       cv = hexS (cvToBool cv)                                     ++ shBKind cv
-          | isFloat         cv = let CFloat   f = cvVal cv in N.showHFloat f            $  shBKind cv
-          | isDouble        cv = let CDouble  d = cvVal cv in N.showHFloat d            $  shBKind cv
-          | isFP            cv = let CFP      f = cvVal cv in bfToString 16 True True f ++ shBKind cv
-          | isReal          cv = let CAlgReal r = cvVal cv in show r                    ++ shBKind cv
-          | isString        cv = let CString  s = cvVal cv in show s                    ++ shBKind cv
-          | not (isBounded cv) = let CInteger i = cvVal cv in shexI True True i
-          | True               = let CInteger i = cvVal cv in shex  True True (hasSign cv, intSizeOf cv) i
-
-  binS cv | isUserSort      cv = shows cv                                              $  shBKind cv
-          | isBoolean       cv = binS (cvToBool cv)                                    ++ shBKind cv
-          | isFloat         cv = let CFloat   f = cvVal cv in showBFloat f             $  shBKind cv
-          | isDouble        cv = let CDouble  d = cvVal cv in showBFloat d             $  shBKind cv
-          | isFP            cv = let CFP      f = cvVal cv in bfToString 2 True True f ++ shBKind cv
-          | isReal          cv = let CAlgReal r = cvVal cv in shows r                  $  shBKind cv
-          | isString        cv = let CString  s = cvVal cv in shows s                  $  shBKind cv
-          | not (isBounded cv) = let CInteger i = cvVal cv in sbinI True True i
-          | True               = let CInteger i = cvVal cv in sbin  True True (hasSign cv, intSizeOf cv) i
-
-  hexP cv | isUserSort      cv = show cv
-          | isBoolean       cv = hexS (cvToBool cv)
-          | isFloat         cv = let CFloat   f = cvVal cv in show f
-          | isDouble        cv = let CDouble  d = cvVal cv in show d
-          | isFP            cv = let CFP      f = cvVal cv in bfToString 16 True True f
-          | isReal          cv = let CAlgReal r = cvVal cv in show r
-          | isString        cv = let CString  s = cvVal cv in show s
-          | not (isBounded cv) = let CInteger i = cvVal cv in shexI False True i
-          | True               = let CInteger i = cvVal cv in shex  False True (hasSign cv, intSizeOf cv) i
-
-  binP cv | isUserSort      cv = show cv
-          | isBoolean       cv = binS (cvToBool cv)
-          | isFloat         cv = let CFloat   f = cvVal cv in show f
-          | isDouble        cv = let CDouble  d = cvVal cv in show d
-          | isFP            cv = let CFP      f = cvVal cv in bfToString 2 True True f
-          | isReal          cv = let CAlgReal r = cvVal cv in show r
-          | isString        cv = let CString  s = cvVal cv in show s
-          | not (isBounded cv) = let CInteger i = cvVal cv in sbinI False True i
-          | True               = let CInteger i = cvVal cv in sbin  False True (hasSign cv, intSizeOf cv) i
-
-  hex cv  | isUserSort      cv = show cv
-          | isBoolean       cv = hexS (cvToBool cv)
-          | isFloat         cv = let CFloat   f = cvVal cv in show f
-          | isDouble        cv = let CDouble  d = cvVal cv in show d
-          | isFP            cv = let CFP      f = cvVal cv in bfToString 16 False True f
-          | isReal          cv = let CAlgReal r = cvVal cv in show r
-          | isString        cv = let CString  s = cvVal cv in show s
-          | not (isBounded cv) = let CInteger i = cvVal cv in shexI False False i
-          | True               = let CInteger i = cvVal cv in shex  False False (hasSign cv, intSizeOf cv) i
+  hexS = cvPretty True  True  True  True  (\f -> T.pack (N.showHFloat f "")) (\d -> T.pack (N.showHFloat d ""))
+  binS = cvPretty False True  True  True  (\f -> T.pack (showBFloat f ""))   (\d -> T.pack (showBFloat d ""))
+  hexP = cvPretty True  False True  False showText                           showText
+  binP = cvPretty False False True  False showText                           showText
+  hex  = cvPretty True  False False False showText                           showText
+  bin  = cvPretty False False False False showText                           showText
 
-  bin cv  | isUserSort      cv = show cv
-          | isBoolean       cv = binS (cvToBool cv)
-          | isFloat         cv = let CFloat   f = cvVal cv in show f
-          | isDouble        cv = let CDouble  d = cvVal cv in show d
-          | isFP            cv = let CFP      f = cvVal cv in bfToString 2 False True f
-          | isReal          cv = let CAlgReal r = cvVal cv in show r
-          | isString        cv = let CString  s = cvVal cv in show s
-          | not (isBounded cv) = let CInteger i = cvVal cv in sbinI False False i
-          | True               = let CInteger i = cvVal cv in sbin  False False (hasSign cv, intSizeOf cv) i
+-- | Factor out the common structure of PrettyNum CV methods
+cvPretty :: Bool              -- ^ isHex (True) or isBin (False)
+         -> Bool              -- ^ Show type suffix on integers
+         -> Bool              -- ^ Show prefix (0x/0b) on integers
+         -> Bool              -- ^ Show kind suffix on non-integer cases
+         -> (Float -> Text)   -- ^ Float formatter
+         -> (Double -> Text)  -- ^ Double formatter
+         -> CV -> Text
+cvPretty isHex shType shPre shKind fmtF fmtD cv
+  | isADT           cv                         = showText cv <> knd
+  | isBoolean       cv                         = (if isHex then hexS else binS) (cvToBool cv) <> knd
+  | isFloat         cv, CFloat   f <- cvVal cv = fmtF f <> knd
+  | isDouble        cv, CDouble  d <- cvVal cv = fmtD d <> knd
+  | isFP            cv, CFP      f <- cvVal cv = T.pack (bfToString base shPre True f) <> knd
+  | isReal          cv, CAlgReal r <- cvVal cv = showText r <> knd
+  | isString        cv, CString  s <- cvVal cv = showText s <> knd
+  | not (isBounded cv), CInteger i <- cvVal cv = intI i
+  | CInteger i <- cvVal cv                     = intB (hasSign cv, intSizeOf cv) i
+  | True                                       = error $ "PrettyNum: Received CV that can't be displayed: " ++ show cv
+  where knd  = if shKind then shBKind cv else ""
+        base = if isHex then 16 else 2
+        intI = (if isHex then shexI else sbinI) shType shPre
+        intB = (if isHex then shex  else sbin)  shType shPre
 
 instance (SymVal a, PrettyNum a) => PrettyNum (SBV a) where
-  hexS s = maybe (show s) (hexS :: a -> String) $ unliteral s
-  binS s = maybe (show s) (binS :: a -> String) $ unliteral s
+  hexS s = maybe (showText s) (hexS :: a -> Text) $ unliteral s
+  binS s = maybe (showText s) (binS :: a -> Text) $ unliteral s
 
-  hexP s = maybe (show s) (hexP :: a -> String) $ unliteral s
-  binP s = maybe (show s) (binP :: a -> String) $ unliteral s
+  hexP s = maybe (showText s) (hexP :: a -> Text) $ unliteral s
+  binP s = maybe (showText s) (binP :: a -> Text) $ unliteral s
 
-  hex  s = maybe (show s) (hex  :: a -> String) $ unliteral s
-  bin  s = maybe (show s) (bin  :: a -> String) $ unliteral s
+  hex  s = maybe (showText s) (hex  :: a -> Text) $ unliteral s
+  bin  s = maybe (showText s) (bin  :: a -> Text) $ unliteral s
 
 -- | Show as a hexadecimal value. First bool controls whether type info is printed
 -- while the second boolean controls whether 0x prefix is printed. The tuple is
 -- the signedness and the bit-length of the input. The length of the string
 -- will /not/ depend on the value, but rather the bit-length.
-shex :: (Show a, Integral a) => Bool -> Bool -> (Bool, Int) -> a -> String
+shex :: (Show a, Integral a) => Bool -> Bool -> (Bool, Int) -> a -> Text
 shex shType shPre (signed, size) a
  | a < 0
- = "-" ++ pre ++ pad l (s16 (abs (fromIntegral a :: Integer)))  ++ t
+ = "-" <> pre <> T.pack (pad l (s16 (abs (fromIntegral a :: Integer)))) <> t
  | True
- = pre ++ pad l (s16 a) ++ t
- where t | shType = " :: " ++ (if signed then "Int" else "Word") ++ show size
-         | True   = ""
+ = pre <> T.pack (pad l (s16 a)) <> t
+ where t | shType = " :: " <> (if signed then "Int" else "Word") <> showText size
+         | True   = T.empty
        pre | shPre = "0x"
-           | True  = ""
+           | True  = T.empty
        l = (size + 3) `div` 4
 
 -- | Show as hexadecimal, but for C programs. We have to be careful about
 -- printing min-bounds, since C does some funky casting, possibly losing
 -- the sign bit. In those cases, we use the defined constants in <stdint.h>.
 -- We also properly append the necessary suffixes as needed.
-chex :: (Show a, Integral a) => Bool -> Bool -> (Bool, Int) -> a -> String
+chex :: (Show a, Integral a) => Bool -> Bool -> (Bool, Int) -> a -> Text
 chex shType shPre (signed, size) a
    | Just s <- (signed, size, fromIntegral a) `lookup` specials
-   = s
+   = T.pack s
    | True
-   = shex shType shPre (signed, size) a ++ suffix
+   = shex shType shPre (signed, size) a <> T.pack suffix
   where specials :: [((Bool, Int, Integer), String)]
         specials = [ ((True,  8, fromIntegral (minBound :: Int8)),  "INT8_MIN" )
                    , ((True, 16, fromIntegral (minBound :: Int16)), "INT16_MIN")
@@ -284,40 +259,40 @@
 -- | Show as a hexadecimal value, integer version. Almost the same as shex above
 -- except we don't have a bit-length so the length of the string will depend
 -- on the actual value.
-shexI :: Bool -> Bool -> Integer -> String
+shexI :: Bool -> Bool -> Integer -> Text
 shexI shType shPre a
  | a < 0
- = "-" ++ pre ++ s16 (abs a)  ++ t
+ = "-" <> pre <> T.pack (s16 (abs a)) <> t
  | True
- = pre ++ s16 a ++ t
+ = pre <> T.pack (s16 a) <> t
  where t | shType = " :: Integer"
-         | True   = ""
+         | True   = T.empty
        pre | shPre = "0x"
-           | True  = ""
+           | True  = T.empty
 
 -- | Similar to 'shex'; except in binary.
-sbin :: (Show a, Integral a) => Bool -> Bool -> (Bool, Int) -> a -> String
+sbin :: (Show a, Integral a) => Bool -> Bool -> (Bool, Int) -> a -> Text
 sbin shType shPre (signed,size) a
  | a < 0
- = "-" ++ pre ++ pad size (s2 (abs (fromIntegral a :: Integer)))  ++ t
+ = "-" <> pre <> T.pack (pad size (s2 (abs (fromIntegral a :: Integer)))) <> t
  | True
- = pre ++ pad size (s2 a) ++ t
- where t | shType = " :: " ++ (if signed then "Int" else "Word") ++ show size
-         | True   = ""
+ = pre <> T.pack (pad size (s2 a)) <> t
+ where t | shType = " :: " <> (if signed then "Int" else "Word") <> showText size
+         | True   = T.empty
        pre | shPre = "0b"
-           | True  = ""
+           | True  = T.empty
 
 -- | Similar to 'shexI'; except in binary.
-sbinI :: Bool -> Bool -> Integer -> String
+sbinI :: Bool -> Bool -> Integer -> Text
 sbinI shType shPre a
  | a < 0
- = "-" ++ pre ++ s2 (abs a) ++ t
+ = "-" <> pre <> T.pack (s2 (abs a)) <> t
  | True
- =  pre ++ s2 a ++ t
+ = pre <> T.pack (s2 a) <> t
  where t | shType = " :: Integer"
-         | True   = ""
+         | True   = T.empty
        pre | shPre = "0b"
-           | True  = ""
+           | True  = T.empty
 
 -- | Pad a string to a given length. If the string is longer, then we don't drop anything.
 pad :: Int -> String -> String
@@ -325,7 +300,7 @@
 
 -- | Binary printer
 s2 :: (Show a, Integral a) => a -> String
-s2  v = showIntAtBase 2 dig v "" where dig = fromJust . flip lookup [(0, '0'), (1, '1')]
+s2  v = showIntAtBase 2 intToDigit v ""
 
 -- | Hex printer
 s16 :: (Show a, Integral a) => a -> String
@@ -338,7 +313,7 @@
               [(a, "")] -> a
               _         -> error $ "SBV.readBin: Cannot read a binary number from: " ++ show s
   where cvt c = ord c - ord '0'
-        isDigit = (`elem` "01")
+        isDigit = (`elem` ("01" :: String))
         s' | "0b" `isPrefixOf` s = drop 2 s
            | True                = s
 
@@ -375,53 +350,52 @@
    | True                = show d
 
 -- | A version of show for floats that generates correct SMTLib literals using the rounding mode
-showSMTFloat :: RoundingMode -> Float -> String
-showSMTFloat rm f
+showSMTFloat :: Float -> Text
+showSMTFloat f
    | isNaN f             = as "NaN"
    | isInfinite f, f < 0 = as "-oo"
    | isInfinite f        = as "+oo"
    | isNegativeZero f    = as "-zero"
    | f == 0              = as "+zero"
-   | True                = "((_ to_fp 8 24) " ++ smtRoundingMode rm ++ " " ++ toSMTLibRational (toRational f) ++ ")"
-   where as s = "(_ " ++ s ++ " 8 24)"
-
+   | True                = let w   = floatToWord f
+                               b i = if w `testBit` i then '1' else '0'
+                               s   = T.pack [b 31]
+                               e   = T.pack [b i | i <- [30, 29 .. 23]]
+                               m   = T.pack [b i | i <- [22, 21 ..  0]]
+                           in "(fp #b" <> s <> " #b" <> e <> " #b" <> m <> ")"
+   where as s = "(_ " <> s <> " 8 24)"
 
 -- | A version of show for doubles that generates correct SMTLib literals using the rounding mode
-showSMTDouble :: RoundingMode -> Double -> String
-showSMTDouble rm d
+showSMTDouble :: Double -> Text
+showSMTDouble d
    | isNaN d             = as "NaN"
    | isInfinite d, d < 0 = as "-oo"
    | isInfinite d        = as "+oo"
    | isNegativeZero d    = as "-zero"
    | d == 0              = as "+zero"
-   | True                = "((_ to_fp 11 53) " ++ smtRoundingMode rm ++ " " ++ toSMTLibRational (toRational d) ++ ")"
-   where as s = "(_ " ++ s ++ " 11 53)"
+   | True                = let w   = doubleToWord d
+                               b i = if w `testBit` i then '1' else '0'
+                               s   = T.pack [b 63]
+                               e   = T.pack [b i | i <- [62, 61 .. 52]]
+                               m   = T.pack [b i | i <- [51, 50 ..  0]]
+                           in "(fp #b" <> s <> " #b" <> e <> " #b" <> m <> ")"
+   where as s = "(_ " <> s <> " 11 53)"
 
 -- | Show an SBV rational as an SMTLib value. This is used for faithful rationals.
-showSMTRational :: Rational -> String
-showSMTRational r = "(SBV.Rational " ++ showNegativeNumber (numerator r) ++ " " ++ showNegativeNumber (denominator r) ++ ")"
-
--- | Show a rational in SMTLib format. This is used for conversions from regular rationals.
-toSMTLibRational :: Rational -> String
-toSMTLibRational r
-   | n < 0
-   = "(- (/ "  ++ show (abs n) ++ ".0 " ++ show d ++ ".0))"
-   | True
-   = "(/ " ++ show n ++ ".0 " ++ show d ++ ".0)"
-  where n = numerator r
-        d = denominator r
+showSMTRational :: Rational -> Text
+showSMTRational r = "(SBV.Rational " <> showNegativeNumber (numerator r) <> " " <> showNegativeNumber (denominator r) <> ")"
 
 -- | Convert a CV to an SMTLib2 compliant value
-cvToSMTLib :: RoundingMode -> CV -> String
-cvToSMTLib rm x
+cvToSMTLib :: CV -> Text
+cvToSMTLib x
   | isBoolean       x, CInteger  w      <- cvVal x = if w == 0 then "false" else "true"
-  | isUserSort      x, CUserSort (_, s) <- cvVal x = roundModeConvert s
-  | isReal          x, CAlgReal  r      <- cvVal x = algRealToSMTLib2 r
-  | isFloat         x, CFloat    f      <- cvVal x = showSMTFloat  rm f
-  | isDouble        x, CDouble   d      <- cvVal x = showSMTDouble rm d
+  | isRoundingMode  x, CADT (s, [])     <- cvVal x = roundModeConvert s
+  | isReal          x, CAlgReal  r      <- cvVal x = T.pack (algRealToSMTLib2 r)
   | isRational      x, CRational r      <- cvVal x = showSMTRational r
-  | isFP            x, CFP       f      <- cvVal x = fprToSMTLib2 f
-  | not (isBounded x), CInteger  w      <- cvVal x = if w >= 0 then show w else "(- " ++ show (abs w) ++ ")"
+  | isFloat         x, CFloat    f      <- cvVal x = showSMTFloat  f
+  | isDouble        x, CDouble   d      <- cvVal x = showSMTDouble d
+  | isFP            x, CFP       f      <- cvVal x = T.pack (fprToSMTLib2 f)
+  | not (isBounded x), CInteger  w      <- cvVal x = if w >= 0 then showText w else "(- " <> showText (abs w) <> ")"
   | not (hasSign x)  , CInteger  w      <- cvVal x = smtLibHex (intSizeOf x) w
   -- signed numbers (with 2's complement representation) is problematic
   -- since there's no way to put a bvneg over a positive number to get minBound..
@@ -429,41 +403,42 @@
   | hasSign x        , CInteger  w      <- cvVal x = if w == negate (2 ^ intSizeOf x)
                                                      then mkMinBound (intSizeOf x)
                                                      else negIf (w < 0) $ smtLibHex (intSizeOf x) (abs w)
-  | isChar x         , CChar c          <- cvVal x = "(_ char " ++ smtLibHex 8 (fromIntegral (ord c)) ++ ")"
-  | isString x       , CString s        <- cvVal x = '\"' : stringToQFS s ++ "\""
+  | isChar x         , CChar c          <- cvVal x = "(_ char " <> smtLibHex 8 (fromIntegral (ord c)) <> ")"
+  | isString x       , CString s        <- cvVal x = "\"" <> T.pack (stringToQFS s) <> "\""
   | isList x         , CList xs         <- cvVal x = smtLibSeq (kindOf x) xs
   | isSet x          , CSet s           <- cvVal x = smtLibSet (kindOf x) s
   | isTuple x        , CTuple xs        <- cvVal x = smtLibTup (kindOf x) xs
-  | isMaybe x        , CMaybe mc        <- cvVal x = smtLibMaybe  (kindOf x) mc
-  | isEither x       , CEither ec       <- cvVal x = smtLibEither (kindOf x) ec
 
   -- Arrays become sequence of stores
-  | isArray x        , CArray ac       <- cvVal x = smtLibArray (kindOf x) ac
+  | isArray x        , CArray ac       <- cvVal x  = smtLibArray (kindOf x) ac
 
+  -- ADTs
+  | isADT x          , CADT c          <- cvVal x = smtLibADT (cvKind x) c
+
   | True = error $ "SBV.cvtCV: Impossible happened: Kind/Value disagreement on: " ++ show (kindOf x, x)
-  where roundModeConvert s = fromMaybe s (listToMaybe [smtRoundingMode m | m <- [minBound .. maxBound] :: [RoundingMode], show m == s])
+  where roundModeConvert s = fromMaybe (T.pack s) (listToMaybe [smtRoundingMode m | m <- [minBound .. maxBound] :: [RoundingMode], show m == s])
         -- Carefully code hex numbers, SMTLib is picky about lengths of hex constants. For the time
         -- being, SBV only supports sizes that are multiples of 4, but the below code is more robust
         -- in case of future extensions to support arbitrary sizes.
-        smtLibHex :: Int -> Integer -> String
-        smtLibHex 1  v = "#b" ++ show v
+        smtLibHex :: Int -> Integer -> Text
+        smtLibHex 1  v = "#b" <> showText v
         smtLibHex sz v
-          | sz `mod` 4 == 0 = "#x" ++ pad (sz `div` 4) (showHex v "")
-          | True            = "#b" ++ pad sz (showBin v "")
+          | sz `mod` 4 == 0 = "#x" <> T.pack (pad (sz `div` 4) (showHex v ""))
+          | True            = "#b" <> T.pack (pad sz (showBin v ""))
            where showBin = showIntAtBase 2 intToDigit
-        negIf :: Bool -> String -> String
-        negIf True  a = "(bvneg " ++ a ++ ")"
+        negIf :: Bool -> Text -> Text
+        negIf True  a = "(bvneg " <> a <> ")"
         negIf False a = a
 
-        smtLibSeq :: Kind -> [CVal] -> String
-        smtLibSeq k          [] = "(as seq.empty " ++ smtType k ++ ")"
+        smtLibSeq :: Kind -> [CVal] -> Text
+        smtLibSeq k          [] = "(as seq.empty " <> smtType k <> ")"
         smtLibSeq (KList ek) xs = let mkSeq  [e]   = e
-                                      mkSeq  es    = "(seq.++ " ++ unwords es ++ ")"
-                                      mkUnit inner = "(seq.unit " ++ inner ++ ")"
-                                  in mkSeq (mkUnit . cvToSMTLib rm . CV ek <$> xs)
-        smtLibSeq k _ = error "SBV.cvToSMTLib: Impossible case (smtLibSeq), received kind: " ++ show k
+                                      mkSeq  es    = "(seq.++ " <> T.unwords es <> ")"
+                                      mkUnit inner = "(seq.unit " <> inner <> ")"
+                                  in mkSeq (mkUnit . cvToSMTLib . CV ek <$> xs)
+        smtLibSeq k _ = error $ "SBV.cvToSMTLib: Impossible case (smtLibSeq), received kind: " ++ show k
 
-        smtLibSet :: Kind -> RCSet CVal -> String
+        smtLibSet :: Kind -> RCSet CVal -> Text
         smtLibSet k set = case set of
                             RegularSet    rs -> Set.foldr' (modify "true")  (start "false") rs
                             ComplementSet rs -> Set.foldr' (modify "false") (start "true")  rs
@@ -471,46 +446,39 @@
                        KSet ek -> ek
                        _       -> error $ "SBV.cvToSMTLib: Impossible case (smtLibSet), received kind: " ++ show k
 
-                start def = "((as const " ++ smtType k ++ ") " ++ def ++ ")"
+                start def = "((as const " <> smtType k <> ") " <> def <> ")"
 
-                modify how e s = "(store " ++ s ++ " " ++ cvToSMTLib rm (CV ke e) ++ " " ++ how ++ ")"
+                modify how e s = "(store " <> s <> " " <> cvToSMTLib (CV ke e) <> " " <> how <> ")"
 
-        smtLibTup :: Kind -> [CVal] -> String
+        smtLibTup :: Kind -> [CVal] -> Text
         smtLibTup (KTuple []) _  = "mkSBVTuple0"
-        smtLibTup (KTuple ks) xs = "(mkSBVTuple" ++ show (length ks) ++ " " ++ unwords (zipWith (\ek e -> cvToSMTLib rm (CV ek e)) ks xs) ++ ")"
+        smtLibTup (KTuple ks) xs = "(mkSBVTuple" <> showText (length ks) <> " " <> T.unwords (zipWith (\ek e -> cvToSMTLib (CV ek e)) ks xs) <> ")"
         smtLibTup k           _  = error $ "SBV.cvToSMTLib: Impossible case (smtLibTup), received kind: " ++ show k
 
-        dtConstructor fld []   res =  "(as " ++ fld ++ " " ++ smtType res ++ ")"
-        dtConstructor fld args res = "((as " ++ fld ++ " " ++ smtType res ++ ") " ++ unwords args ++ ")"
-
-        smtLibMaybe :: Kind -> Maybe CVal -> String
-        smtLibMaybe km@KMaybe{}   Nothing   = dtConstructor "nothing_SBVMaybe" []                       km
-        smtLibMaybe km@(KMaybe k) (Just  c) = dtConstructor "just_SBVMaybe"    [cvToSMTLib rm (CV k c)] km
-        smtLibMaybe k             _         = error $ "SBV.cvToSMTLib: Impossible case (smtLibMaybe), received kind: " ++ show k
-
-        smtLibEither :: Kind -> Either CVal CVal -> String
-        smtLibEither ke@(KEither  k _) (Left c)  = dtConstructor "left_SBVEither"  [cvToSMTLib rm (CV k c)] ke
-        smtLibEither ke@(KEither  _ k) (Right c) = dtConstructor "right_SBVEither" [cvToSMTLib rm (CV k c)] ke
-        smtLibEither k                 _         = error $ "SBV.cvToSMTLib: Impossible case (smtLibEither), received kind: " ++ show k
-
         -- Remember that in an ArrayModel we keep a history; i.e., the earlier elements are written later. So, we reverse the assocs
-        smtLibArray :: Kind -> ArrayModel CVal CVal -> String
+        smtLibArray :: Kind -> ArrayModel CVal CVal -> Text
         smtLibArray k@(KArray k1 k2) (ArrayModel assocs def) = mkStoreChain k k1 k2 (reverse assocs) def
         smtLibArray k              _                         = error $ "SBV.cvToSMTLib: Impossible case (smtLibArray), received non-matching kind: " ++ show k
 
         mkStoreChain k k1 k2 writes def = walk writes base
-          where base = "((as const " ++ smtType k ++ ") " ++ cvToSMTLib rm (CV k2 def) ++ ")"
+          where base = "((as const " <> smtType k <> ") " <> cvToSMTLib (CV k2 def) <> ")"
 
                 walk []                  sofar = sofar
                 walk ((key, val) : rest) sofar = walk rest (store key val sofar)
 
-                store key val sofar = "(store " ++ sofar ++ " " ++ cvToSMTLib rm (CV k1 key) ++ " " ++ cvToSMTLib rm (CV k2 val) ++ ")"
+                store key val sofar = "(store " <> sofar <> " " <> cvToSMTLib (CV k1 key) <> " " <> cvToSMTLib (CV k2 val) <> ")"
 
         -- anomaly at the 2's complement min value! Have to use binary notation here
         -- as there is no positive value we can provide to make the bvneg work.. (see above)
-        mkMinBound :: Int -> String
-        mkMinBound i = "#b1" ++ replicate (i-1) '0'
+        mkMinBound :: Int -> Text
+        mkMinBound i = "#b1" <> T.replicate (i-1) "0"
 
+        -- ADTs
+        smtLibADT :: Kind -> (String,  [(Kind, CVal)]) -> Text
+        smtLibADT knd (c, [])  = ascribe c knd
+        smtLibADT knd (c, kvs) = "(" <> ascribe c knd <> " " <> T.unwords (map (\(k, v) -> cvToSMTLib (CV  k v)) kvs) <> ")"
+        ascribe nm k = "(as " <> T.pack nm <> " " <> smtType k <> ")"
+
 -- | Show a float as a binary
 showBFloat :: (Show a, RealFloat a) => a -> ShowS
 showBFloat = showFloatAtBase 2
@@ -573,7 +541,7 @@
                   | True    = '<' : show v ++ ">"
 
 -- | When we show a negative number in SMTLib, we must properly parenthesize.
-showNegativeNumber :: (Show a, Num a, Ord a) => a -> String
+showNegativeNumber :: (Show a, Num a, Ord a) => a -> Text
 showNegativeNumber i
-  | i < 0 = "(- " ++ show (-i) ++ ")"
-  | True  = show i
+  | i < 0 = "(- " <> showText (-i) <> ")"
+  | True  = showText i
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
@@ -14,7 +14,7 @@
 {-# OPTIONS_GHC -Wall -Werror #-}
 
 module Data.SBV.Utils.SExpr ( SExpr(..), parenDeficit, parseSExpr
-                            , parseSExprFunction, makeHaskellFunction
+                            , parseSExprFunction, makeHaskellFunction, formatFunctionResponse
                             , unQuote, simplifyECon
                             , nameSupply
                             ) where
@@ -40,7 +40,8 @@
 
 -- | ADT S-Expression format, suitable for representing get-model output of SMT-Lib
 data SExpr = ECon           String
-           | ENum           (Integer, Maybe Int)  -- Second argument is how wide the field was in bits, if known. Useful in FP parsing.
+           | ENum           (Integer, Maybe Int, Bool)  -- Second argument is how wide the field was in bits, if known. Useful in FP parsing.
+                                                        -- Third argument is true, if this was a boolean constant
            | EReal          AlgReal
            | EFloat         Float
            | EFloatingPoint FP
@@ -50,30 +51,36 @@
 
 -- | Extremely simple minded tokenizer, good for our use model.
 tokenize :: String -> [String]
-tokenize inp = go inp []
+tokenize = tokenizeWith (\tok _ _ -> tok)
+
+-- The callback receives the decoded token and the original input suffixes at
+-- its start and end. Retaining these boundaries lets display code take exact
+-- source slices without changing the tokens used for parsing.
+tokenizeWith :: (String -> String -> String -> a) -> String -> [a]
+tokenizeWith retain inp = go inp []
  where go "" sofar = reverse sofar
 
        go (c:cs) sofar
           | isSpace c = go (dropWhile isSpace cs) sofar
 
-       go ('(':cs) sofar = go cs ("(" : sofar)
-       go (')':cs) sofar = go cs (")" : sofar)
+       go src@('(':cs) sofar = go cs (retain "(" src cs : sofar)
+       go src@(')':cs) sofar = go cs (retain ")" src cs : sofar)
 
-       go (':':':':cs) sofar = go cs ("::" : sofar)
+       go src@(':':':':cs) sofar = go cs (retain "::" src cs : sofar)
 
-       go (':':cs) sofar = case break (`elem` stopper) cs of
-                            (pre, rest) -> go rest ((':':pre) : sofar)
+       go src@(':':cs) sofar = case break (`elem` stopper) cs of
+                                (pre, rest) -> go rest (retain (':':pre) src rest : sofar)
 
-       go ('|':r) sofar = let wrap s = '|' : s ++ "|"
-                          in case span (/= '|') r of
-                               (pre, '|':rest) -> go rest (wrap pre : sofar)
-                               (pre, rest)     -> go rest (wrap pre : sofar)
+       go src@('|':r) sofar = let wrap s = '|' : s ++ "|"
+                              in case span (/= '|') r of
+                                   (pre, '|':rest) -> go rest (retain (wrap pre) src rest : sofar)
+                                   (pre, rest)     -> go rest (retain (wrap pre) src rest : sofar)
 
        go (';':r) sofar = go (drop 1 (dropWhile (/= '\n') r)) sofar
 
-       go ('"':r) sofar = go rest (finalStr : sofar)
+       go src@('"':r) sofar = go rest (retain finalStr src rest : sofar)
            where grabString []             acc = (reverse acc, [])         -- Strictly speaking, this is the unterminated string case; but let's ignore
-                 grabString ('"' :'"':cs)  acc = grabString cs ('"' :acc)
+                 grabString ('"' :'"':cs)  acc = grabString cs ('"' : acc)
                  grabString ('"':cs)       acc = (reverse acc, cs)
                  grabString (c:cs)         acc = grabString cs (c:acc)
 
@@ -81,7 +88,7 @@
                  finalStr    = '"' : str ++ "\""
 
        go cs sofar = case span (`notElem` stopper) cs of
-                       (pre, post) -> go post (pre : sofar)
+                            (pre, post) -> go post (retain pre cs post : sofar)
 
        -- characters that can stop the current token
        -- it is *crucial* that this list contains every character
@@ -103,7 +110,7 @@
                     if null extras
                        then case sexp of
                               EApp [ECon "error", ECon er] -> Left $ "Solver returned an error: " ++ er
-                              _                            -> return sexp
+                              _                            -> pure sexp
 
                        else die "Extra tokens after valid input"
   where inpToks = tokenize inp
@@ -114,21 +121,21 @@
         parse []         = die "ran out of tokens"
         parse ("(":toks) = do (f, r) <- parseApp toks []
                               f' <- cvt (EApp f)
-                              return (f', r)
+                              pure (f', r)
         parse (")":_)    = die "extra tokens after close paren"
         parse [tok]      = do t <- pTok tok
-                              return (t, [])
+                              pure (t, [])
         parse _          = die "ill-formed s-expr"
 
         parseApp []         _     = die "failed to grab s-expr application"
-        parseApp (")":toks) sofar = return (reverse sofar, toks)
+        parseApp (")":toks) sofar = pure (reverse sofar, toks)
         parseApp ("(":toks) sofar = do (f, r) <- parse ("(":toks)
                                        parseApp r (f : sofar)
         parseApp (tok:toks) sofar = do t <- pTok tok
                                        parseApp toks (t : sofar)
 
-        pTok "false" = return $ ENum (0, Nothing)
-        pTok "true"  = return $ ENum (1, Nothing)
+        pTok "false" = pure $ ENum (0, Nothing, True)
+        pTok "true"  = pure $ ENum (1, Nothing, True)
 
         pTok ('0':'b':r)                                 = mkNum (Just (length r))     $ readInt 2 (`elem` "01") (\c -> ord c - ord '0') r
         pTok ('b':'v':r) | not (null r) && all isDigit r = mkNum Nothing               $ readDec (takeWhile (/= '[') r)
@@ -136,7 +143,7 @@
         pTok ('#':'x':r)                                 = mkNum (Just (4 * length r)) $ readHex r
 
         pTok n | possiblyNum n = if all intChar n then mkNum Nothing $ readSigned readDec n else getReal n
-        pTok n                 = return $ ECon (constantMap n)
+        pTok n                 = pure $ ECon (constantMap n)
 
         -- crude, but effective!
         possiblyNum s = case s of
@@ -146,126 +153,130 @@
 
         intChar c = c == '-' || isDigit c
 
-        mkNum l [(n, "")] = return $ ENum (n, l)
+        mkNum l [(n, "")] = pure $ ENum (n, l, False)
         mkNum _ _         = die "cannot read number"
 
-        getReal n = return $ EReal $ mkPolyReal (Left (exact, n'))
+        getReal n = pure $ EReal $ mkPolyReal (Left (exact, n'))
           where exact = not ("?" `isPrefixOf` reverse n)
                 n' | exact = n
                    | True  = init n
 
+        fst3 (a, _, _) = a
+        snd3 (_, b, _) = b
+        thd3 (_, _, c) = c
+
         -- simplify numbers and root-obj values
-        cvt (EApp [ECon "to_int",  EReal a])                       = return $ EReal a   -- ignore the "casting"
-        cvt (EApp [ECon "to_real", EReal a])                       = return $ EReal a   -- ignore the "casting"
-        cvt (EApp [ECon "/", EReal a, EReal b])                    = return $ EReal (a / b)
-        cvt (EApp [ECon "/", EReal a, ENum  b])                    = return $ EReal (a                   / fromInteger (fst b))
-        cvt (EApp [ECon "/", ENum  a, EReal b])                    = return $ EReal (fromInteger (fst a) /             b      )
-        cvt (EApp [ECon "/", ENum  a, ENum  b])                    = return $ EReal (fromInteger (fst a) / fromInteger (fst b))
-        cvt (EApp [ECon "-", EReal a])                             = return $ EReal (-a)
-        cvt (EApp [ECon "-", ENum a])                              = return $ ENum  (-(fst a), snd a)
+        cvt (EApp [ECon "to_int",  EReal a])                       = pure $ EReal a   -- ignore the "casting"
+        cvt (EApp [ECon "to_real", EReal a])                       = pure $ EReal a   -- ignore the "casting"
+        cvt (EApp [ECon "/", EReal a, EReal b])                    = pure $ EReal (a / b)
+        cvt (EApp [ECon "/", EReal a, ENum  b])                    = pure $ EReal (a                    / fromInteger (fst3 b))
+        cvt (EApp [ECon "/", ENum  a, EReal b])                    = pure $ EReal (fromInteger (fst3 a) /             b      )
+        cvt (EApp [ECon "/", ENum  a, ENum  b])                    = pure $ EReal (fromInteger (fst3 a) / fromInteger (fst3 b))
+        cvt (EApp [ECon "-", EReal a])                             = pure $ EReal (-a)
+        cvt (EApp [ECon "-", ENum a])                              = pure $ ENum  (-(fst3 a), snd3 a, thd3 a)
 
         -- bit-vector value as CVC4 prints: (_ bv0 16) for instance
-        cvt (EApp [ECon "_", ENum a, ENum _b])                     = return $ ENum a
+        cvt (EApp [ECon "_", ENum a, ENum _b])                     = pure $ ENum a
         cvt (EApp [ECon "root-obj", EApp (ECon "+":trms), ENum k]) = do ts <- mapM getCoeff trms
-                                                                        return $ EReal $ mkPolyReal (Right (fst k, ts))
-        cvt (EApp [ECon "as", n, EApp [ECon "_", ECon "FloatingPoint", ENum (11, _), ENum (53, _)]]) = getDouble n
-        cvt (EApp [ECon "as", n, EApp [ECon "_", ECon "FloatingPoint", ENum ( 8, _), ENum (24, _)]]) = getFloat  n
-        cvt (EApp [ECon "as", n, ECon "Float64"])                                                    = getDouble n
-        cvt (EApp [ECon "as", n, ECon "Float32"])                                                    = getFloat  n
+                                                                        pure $ EReal $ mkPolyReal (Right (fst3 k, ts))
+        cvt (EApp [ECon "as", n, EApp [ECon "_", ECon "FloatingPoint", ENum (11, _, _), ENum (53, _, _)]]) = getDouble n
+        cvt (EApp [ECon "as", n, EApp [ECon "_", ECon "FloatingPoint", ENum ( 8, _, _), ENum (24, _, _)]]) = getFloat  n
+        cvt (EApp [ECon "as", n, ECon "Float64"])                                                          = getDouble n
+        cvt (EApp [ECon "as", n, ECon "Float32"])                                                          = getFloat  n
 
         -- Deal with CVC4's approximate reals
         cvt x@(EApp [ECon "witness", EApp [EApp [ECon v, ECon "Real"]]
                                    , EApp [ECon "or", EApp [ECon "=", ECon v', val], _]]) | v == v'   = do
                                                 approx <- cvt val
                                                 case approx of
-                                                  ENum (s, _) -> return $ EReal $ mkPolyReal (Left (False, show s))
-                                                  EReal aval  -> case aval of
-                                                                   AlgRational _ r -> return $ EReal $ AlgRational False r
-                                                                   _               -> return $ EReal aval
-                                                  _           -> die $ "Cannot parse a CVC4 approximate value from: " ++ show x
+                                                  ENum (s, _, _) -> pure $ EReal $ mkPolyReal (Left (False, show s))
+                                                  EReal aval     -> case aval of
+                                                                      AlgRational _ r -> pure $ EReal $ AlgRational False r
+                                                                      _               -> pure $ EReal aval
+                                                  _              -> die $ "Cannot parse a CVC4 approximate value from: " ++ show x
 
         -- Deal with CVC5's algebraic reals. This is very crude!
         cvt x@(EApp (ECon "_" : ECon "real_algebraic_number" : rest)) =
             let isComma (ECon ",") = True
                 isComma _          = False
 
-                get (ENum    (n, _))               = return $ fromIntegral n
-                get (EReal   (AlgRational True r)) = return r
-                get (EFloat  f)                    = return $ toRational f
-                get (EDouble d)                    = return $ toRational d
+                get (ENum    (n, _, _))            = pure $ fromIntegral n
+                get (EReal   (AlgRational True r)) = pure r
+                get (EFloat  f)                    = pure $ toRational f
+                get (EDouble d)                    = pure $ toRational d
                 get t                              = die $ "Cannot get a CVC5 real-algebraic bound from: " ++ show t
 
             in case drop 1 (dropWhile (not . isComma) rest) of
                 [EApp [n1, n2], _] -> do low  <- get n1
                                          high <- get n2
-                                         return $ EReal $ AlgInterval (OpenPoint low) (OpenPoint high)
+                                         pure $ EReal $ AlgInterval (OpenPoint low) (OpenPoint high)
                 _                  -> die $ "Cannot parse a CVC5 real-algebraic number from: " ++ show x
 
         -- NB. Note the lengths on the mantissa for the following two are 23/52; not 24/53!
-        cvt (EApp [ECon "fp",    ENum (s, Just 1), ENum ( e, Just 8),  ENum (m, Just 23)])           = return $ EFloat         $ getTripleFloat  s e m
-        cvt (EApp [ECon "fp",    ENum (s, Just 1), ENum ( e, Just 11), ENum (m, Just 52)])           = return $ EDouble        $ getTripleDouble s e m
-        cvt (EApp [ECon "fp",    ENum (s, Just 1), ENum ( e, Just eb), ENum (m, Just sb)])           = return $ EFloatingPoint $ fpFromRawRep (s == 1) (e, eb) (m, sb+1)
+        cvt (EApp [ECon "fp",    ENum (s, Just 1, _), ENum ( e, Just  8, _), ENum (m, Just 23, _)]) = pure $ EFloat         $ getTripleFloat  s e m
+        cvt (EApp [ECon "fp",    ENum (s, Just 1, _), ENum ( e, Just 11, _), ENum (m, Just 52, _)]) = pure $ EDouble        $ getTripleDouble s e m
+        cvt (EApp [ECon "fp",    ENum (s, Just 1, _), ENum ( e, Just eb, _), ENum (m, Just sb, _)]) = pure $ EFloatingPoint $ fpFromRawRep (s == 1) (e, eb) (m, sb+1)
 
-        cvt (EApp [ECon "_",     ECon "NaN",       ENum ( 8, _),       ENum (24,      _)])           = return $ EFloat           nan
-        cvt (EApp [ECon "_",     ECon "NaN",       ENum (11, _),       ENum (53,      _)])           = return $ EDouble          nan
-        cvt (EApp [ECon "_",     ECon "NaN",       ENum (eb, _),       ENum (sb,      _)])           = return $ EFloatingPoint $ fpNaN (fromIntegral eb) (fromIntegral sb)
+        cvt (EApp [ECon "_",     ECon "NaN",       ENum ( 8, _, _),       ENum (24, _, _)])         = pure $ EFloat           nan
+        cvt (EApp [ECon "_",     ECon "NaN",       ENum (11, _, _),       ENum (53, _, _)])         = pure $ EDouble          nan
+        cvt (EApp [ECon "_",     ECon "NaN",       ENum (eb, _, _),       ENum (sb, _, _)])         = pure $ EFloatingPoint $ fpNaN (fromIntegral eb) (fromIntegral sb)
 
-        cvt (EApp [ECon "_",     ECon "+oo",       ENum ( 8, _),       ENum (24,      _)])           = return $ EFloat           infinity
-        cvt (EApp [ECon "_",     ECon "+oo",       ENum (11, _),       ENum (53,      _)])           = return $ EDouble          infinity
-        cvt (EApp [ECon "_",     ECon "+oo",       ENum (eb, _),       ENum (sb,      _)])           = return $ EFloatingPoint $ fpInf False (fromIntegral eb) (fromIntegral sb)
+        cvt (EApp [ECon "_",     ECon "+oo",       ENum ( 8, _, _),       ENum (24, _, _)])         = pure $ EFloat           infinity
+        cvt (EApp [ECon "_",     ECon "+oo",       ENum (11, _, _),       ENum (53, _, _)])         = pure $ EDouble          infinity
+        cvt (EApp [ECon "_",     ECon "+oo",       ENum (eb, _, _),       ENum (sb, _, _)])         = pure $ EFloatingPoint $ fpInf False (fromIntegral eb) (fromIntegral sb)
 
-        cvt (EApp [ECon "_",     ECon "-oo",       ENum ( 8, _),       ENum (24,      _)])           = return $ EFloat         $ -infinity
-        cvt (EApp [ECon "_",     ECon "-oo",       ENum (11, _),       ENum (53,      _)])           = return $ EDouble        $ -infinity
-        cvt (EApp [ECon "_",     ECon "-oo",       ENum (eb, _),       ENum (sb,      _)])           = return $ EFloatingPoint $ fpInf True (fromIntegral eb) (fromIntegral sb)
+        cvt (EApp [ECon "_",     ECon "-oo",       ENum ( 8, _, _),       ENum (24, _, _)])         = pure $ EFloat         $ -infinity
+        cvt (EApp [ECon "_",     ECon "-oo",       ENum (11, _, _),       ENum (53, _, _)])         = pure $ EDouble        $ -infinity
+        cvt (EApp [ECon "_",     ECon "-oo",       ENum (eb, _, _),       ENum (sb, _, _)])         = pure $ EFloatingPoint $ fpInf True (fromIntegral eb) (fromIntegral sb)
 
-        cvt (EApp [ECon "_",     ECon "+zero",     ENum ( 8, _),       ENum (24,      _)])           = return $ EFloat  0
-        cvt (EApp [ECon "_",     ECon "+zero",     ENum (11, _),       ENum (53,      _)])           = return $ EDouble 0
-        cvt (EApp [ECon "_",     ECon "+zero",     ENum (eb, _),       ENum (sb,      _)])           = return $ EFloatingPoint $ fpZero False (fromIntegral eb) (fromIntegral sb)
+        cvt (EApp [ECon "_",     ECon "+zero",     ENum ( 8, _, _),       ENum (24, _, _)])         = pure $ EFloat  0
+        cvt (EApp [ECon "_",     ECon "+zero",     ENum (11, _, _),       ENum (53, _, _)])         = pure $ EDouble 0
+        cvt (EApp [ECon "_",     ECon "+zero",     ENum (eb, _, _),       ENum (sb, _, _)])         = pure $ EFloatingPoint $ fpZero False (fromIntegral eb) (fromIntegral sb)
 
-        cvt (EApp [ECon "_",     ECon "-zero",     ENum ( 8, _),       ENum (24,      _)])           = return $ EFloat         $ -0
-        cvt (EApp [ECon "_",     ECon "-zero",     ENum (11, _),       ENum (53,      _)])           = return $ EDouble        $ -0
-        cvt (EApp [ECon "_",     ECon "-zero",     ENum (eb, _),       ENum (sb,      _)])           = return $ EFloatingPoint $ fpZero True (fromIntegral eb) (fromIntegral sb)
+        cvt (EApp [ECon "_",     ECon "-zero",     ENum ( 8, _, _),       ENum (24, _, _)])         = pure $ EFloat         $ -0
+        cvt (EApp [ECon "_",     ECon "-zero",     ENum (11, _, _),       ENum (53, _, _)])         = pure $ EDouble        $ -0
+        cvt (EApp [ECon "_",     ECon "-zero",     ENum (eb, _, _),       ENum (sb, _, _)])         = pure $ EFloatingPoint $ fpZero True (fromIntegral eb) (fromIntegral sb)
 
-        cvt x                                                                                        = return x
+        cvt x                                                                                       = pure x
 
-        getCoeff (EApp [ECon "*", ENum k, EApp [ECon "^", ECon "x", ENum p]]) = return (fst k, fst p)  -- kx^p
-        getCoeff (EApp [ECon "*", ENum k,                 ECon "x"        ] ) = return (fst k,     1)  -- kx
-        getCoeff (                        EApp [ECon "^", ECon "x", ENum p] ) = return (    1, fst p)  --  x^p
-        getCoeff (                                        ECon "x"          ) = return (    1,     1)  --  x
-        getCoeff (                ENum k                                    ) = return (fst k,     0)  -- k
+        getCoeff (EApp [ECon "*", ENum k, EApp [ECon "^", ECon "x", ENum p]]) = pure (fst3 k, fst3 p)  -- kx^p
+        getCoeff (EApp [ECon "*", ENum k,                 ECon "x"        ] ) = pure (fst3 k,      1)  -- kx
+        getCoeff (                        EApp [ECon "^", ECon "x", ENum p] ) = pure (     1, fst3 p)  --  x^p
+        getCoeff (                                        ECon "x"          ) = pure (     1,      1)  --  x
+        getCoeff (                ENum k                                    ) = pure (fst3 k,      0)  -- k
         getCoeff x = die $ "Cannot parse a root-obj,\nProcessing term: " ++ show x
         getDouble (ECon s)  = case (s, rdFP (dropWhile (== '+') s)) of
-                                ("plusInfinity",  _     ) -> return $ EDouble infinity
-                                ("minusInfinity", _     ) -> return $ EDouble (-infinity)
-                                ("oo",            _     ) -> return $ EDouble infinity
-                                ("-oo",           _     ) -> return $ EDouble (-infinity)
-                                ("zero",          _     ) -> return $ EDouble 0
-                                ("-zero",         _     ) -> return $ EDouble (-0)
-                                ("NaN",           _     ) -> return $ EDouble nan
-                                (_,               Just v) -> return $ EDouble v
+                                ("plusInfinity",  _     ) -> pure $ EDouble infinity
+                                ("minusInfinity", _     ) -> pure $ EDouble (-infinity)
+                                ("oo",            _     ) -> pure $ EDouble infinity
+                                ("-oo",           _     ) -> pure $ EDouble (-infinity)
+                                ("zero",          _     ) -> pure $ EDouble 0
+                                ("-zero",         _     ) -> pure $ EDouble (-0)
+                                ("NaN",           _     ) -> pure $ EDouble nan
+                                (_,               Just v) -> pure $ EDouble v
                                 _               -> die $ "Cannot parse a double value from: " ++ s
         getDouble (EApp [_, s, _, _]) = getDouble s
-        getDouble (EReal r) = return $ EDouble $ fromRat $ toRational r
+        getDouble (EReal r) = pure $ EDouble $ fromRat $ toRational r
         getDouble x         = die $ "Cannot parse a double value from: " ++ show x
         getFloat (ECon s)   = case (s, rdFP (dropWhile (== '+') s)) of
-                                ("plusInfinity",  _     ) -> return $ EFloat infinity
-                                ("minusInfinity", _     ) -> return $ EFloat (-infinity)
-                                ("oo",            _     ) -> return $ EFloat infinity
-                                ("-oo",           _     ) -> return $ EFloat (-infinity)
-                                ("zero",          _     ) -> return $ EFloat 0
-                                ("-zero",         _     ) -> return $ EFloat (-0)
-                                ("NaN",           _     ) -> return $ EFloat nan
-                                (_,               Just v) -> return $ EFloat v
+                                ("plusInfinity",  _     ) -> pure $ EFloat infinity
+                                ("minusInfinity", _     ) -> pure $ EFloat (-infinity)
+                                ("oo",            _     ) -> pure $ EFloat infinity
+                                ("-oo",           _     ) -> pure $ EFloat (-infinity)
+                                ("zero",          _     ) -> pure $ EFloat 0
+                                ("-zero",         _     ) -> pure $ EFloat (-0)
+                                ("NaN",           _     ) -> pure $ EFloat nan
+                                (_,               Just v) -> pure $ EFloat v
                                 _               -> die $ "Cannot parse a float value from: " ++ s
-        getFloat (EReal r)  = return $ EFloat $ fromRat $ toRational r
+        getFloat (EReal r)  = pure $ EFloat $ fromRat $ toRational r
         getFloat (EApp [_, s, _, _]) = getFloat s
         getFloat x          = die $ "Cannot parse a float value from: " ++ show x
 
 -- | Parses the Z3 floating point formatted numbers like so: 1.321p5/1.2123e9 etc.
 rdFP :: (Read a, RealFloat a) => String -> Maybe a
 rdFP s = case break (`elem` "pe") s of
-           (m, 'p':e) -> rd m >>= \m' -> rd e >>= \e' -> return $ m' * ( 2 ** e')
-           (m, 'e':e) -> rd m >>= \m' -> rd e >>= \e' -> return $ m' * (10 ** e')
+           (m, 'p':e) -> rd m >>= \m' -> rd e >>= \e' -> pure $ m' * ( 2 ** e')
+           (m, 'e':e) -> rd m >>= \m' -> rd e >>= \e' -> pure $ m' * (10 ** e')
            (m, "")    -> rd m
            _          -> Nothing
  where rd v = case reads v of
@@ -317,7 +328,7 @@
 --              (= x!1 "l")
 --              (= x!1 "e")
 --              (= x!1 "h")))
---   For this, we do a little bit of an interpretative dance to see if we can "construct" the necesary expression.
+--   For this, we do a little bit of an interpretative dance to see if we can "construct" the necessary expression.
 --
 --   In parsed form:
 --      EApp [ECon "lambda",EApp [EApp [ECon "x!1",ECon "String"]],EApp [ECon "not",EApp [ECon "or",EApp [ECon "=",ECon "x!1",ECon "\"e\""],EApp [ECon "=",ECon "x!1",ECon "\"l\""]]]]
@@ -337,20 +348,20 @@
         foldM1 _ []     = error "Data.SBV.parseSetLambda: Impossible happened; empty arg to foldM1"
         foldM1 f (x:xs) = foldM f x xs
 
-        checkBool (ENum (1, Nothing)) = True
-        checkBool (ENum (0, Nothing)) = True
-        checkBool _                   = False
+        checkBool (ENum (1, Nothing, True)) = True
+        checkBool (ENum (0, Nothing, True)) = True
+        checkBool _                         = False
 
-        negBool (ENum (1, Nothing)) = ENum (0, Nothing)
-        negBool _                   = ENum (1, Nothing)
+        negBool (ENum (1, Nothing, _)) = ENum (0, Nothing, True)
+        negBool _                      = ENum (1, Nothing, True)
 
-        orBool t@(ENum (1, Nothing)) _                      = t
-        orBool _                     t@(ENum (1, Nothing))  = t
-        orBool _ _                                          = ENum (0, Nothing)
+        orBool t@(ENum (1, Nothing, _)) _                        = t
+        orBool _                        t@(ENum (1, Nothing, _)) = t
+        orBool _ _                                               = ENum (0, Nothing, True)
 
-        andBool f@(ENum (0, Nothing)) _                     = f
-        andBool _                     f@(ENum (0, Nothing)) = f
-        andBool _ _                                         = ENum (1, Nothing)
+        andBool f@(ENum (0, Nothing, _)) _                        = f
+        andBool _                        f@(ENum (0, Nothing, _)) = f
+        andBool _ _                                               = ENum (1, Nothing, True)
 
         neg :: ([([SExpr], SExpr)], SExpr) -> Maybe ([([SExpr], SExpr)], SExpr)
         neg (rows, dflt)
@@ -405,8 +416,8 @@
         lambda :: [(String, Bool)]  -- Bool is True if this is a boolean variable. Otherwise we don't keep track of the type
                -> SExpr -> Maybe [Either ([SExpr], SExpr) SExpr]
         lambda params body = reverse <$> go [] body
-          where true  = ENum (1, Nothing)
-                false = ENum (0, Nothing)
+          where true  = ENum (1, Nothing, True)
+                false = ENum (0, Nothing, True)
 
                 go :: [Either ([SExpr], SExpr) SExpr] -> SExpr -> Maybe [Either ([SExpr], SExpr) SExpr]
                 go sofar (EApp [ECon "ite", selector, thenBranch, elseBranch])
@@ -499,10 +510,10 @@
 parseStoreAssociations (EApp [ECon "_", ECon "as-array", ECon nm]) = Just $ Left nm
 parseStoreAssociations e                                           = Right <$> (chainAssigns =<< vals e)
     where vals :: SExpr -> Maybe [Either ([SExpr], SExpr) SExpr]
-          vals (EApp [EApp [ECon "as", ECon "const", ECon "Array"],            defVal]) = return [Right defVal]
-          vals (EApp [EApp [ECon "as", ECon "const", EApp (ECon "Array" : _)], defVal]) = return [Right defVal]
+          vals (EApp [EApp [ECon "as", ECon "const", ECon "Array"],            defVal]) = pure [Right defVal]
+          vals (EApp [EApp [ECon "as", ECon "const", EApp (ECon "Array" : _)], defVal]) = pure [Right defVal]
           vals (EApp (ECon "store" : prev : argsVal)) | length argsVal >= 2             = do rest <- vals prev
-                                                                                             return $ Left (init argsVal, last argsVal) : rest
+                                                                                             pure $ Left (init argsVal, last argsVal) : rest
           vals _                                                                        = Nothing
 
 -- | Turn a sequence of left-right chain assignments (condition + free) into a single chain
@@ -534,7 +545,7 @@
         same :: SExpr -> SExpr -> Bool
         same x y = case (x, y) of
                      (ECon a,            ECon b)            -> a == b
-                     (ENum (i, _),       ENum (j, _))       -> i == j
+                     (ENum (i, _, _),    ENum (j, _, _))    -> i == j
                      (EReal a,           EReal b)           -> algRealStructuralEqual a b
                      (EFloat  f1,        EFloat  f2)        -> fpIsEqualObjectH f1 f2
                      (EDouble d1,        EDouble d2)        -> fpIsEqualObjectH d1 d2
@@ -556,8 +567,8 @@
         eRank EDouble{}        = 5
         eRank EApp{}           = 6
 
--- Turn
---  "((F (lambda ((x!1 Int)) (+ 3 (* 2 x!1)))))"
+-- Turn a parsed function value
+--  "(lambda ((x!1 Int)) (+ 3 (* 2 x!1)))"
 ---  into
 --  "F x = 3 + 2 * x"
 -- if we can. We try but don't push too hard! This is only used for display purposes.
@@ -565,14 +576,12 @@
 -- This isn't very fool-proof; can be confused if there are binding constructs etc.
 -- Also, the generated text isn't necessarily fully Haskell acceptable.
 -- But it seems to do an OK job for most common use cases.
-makeHaskellFunction :: String -> String -> Bool -> Maybe [String] -> Maybe String
-makeHaskellFunction resp nm isCurried mbArgs
-   = case parseSExpr resp of
-       Right (EApp [EApp [ECon o, e]]) | o == nm -> do (args, bd) <- lambda e
-                                                       let params | isCurried = unwords args
-                                                                  | True      = '(' : intercalate ", " args ++ ")"
-                                                       return $ unBar nm ++ " " ++ params ++ " = " ++ bd
-       _                                         -> Nothing
+makeHaskellFunction :: SExpr -> String -> Bool -> Maybe [String] -> Maybe String
+makeHaskellFunction value nm isCurried mbArgs = do
+  (args, bd) <- lambda value
+  let params | isCurried = unwords args
+             | True      = '(' : intercalate ", " args ++ ")"
+  pure $ unBar nm ++ " " ++ params ++ " = " ++ bd
 
   where -- infinite supply of names; starting with the ones we're given
         preSupply = fromMaybe [] mbArgs
@@ -586,6 +595,23 @@
         getArg (EApp [ECon argName, _]) = Just argName
         getArg _                        = Nothing
 
+-- | Format an already parsed function value. The caller validates the response
+-- name. If lambda formatting fails, slice the original SMT-Lib value at token
+-- boundaries. This preserves its exact spelling, whitespace, and comments;
+-- rebuilding it from the normalized SExpr or decoded tokens would lose details.
+formatFunctionResponse :: SExpr -> String -> String -> Bool -> Maybe [String] -> String
+formatFunctionResponse value response nm isCurried mbArgs
+  | Just formatted <- makeHaskellFunction value nm isCurried mbArgs
+  = formatted
+  | ("(", _, _) : ("(", _, _) : (actual, _, _) : rest <- tokenizeWith (,,) response
+  , unBar actual == unBar nm
+  , (")", _, _) : (")", _, _) : body@((_, _, end) : _) <- reverse rest
+  , (_, start, _) : _ <- reverse body
+  = raw $ take (length start - length end) start
+  | True
+  = raw response
+  where raw s = nm ++ " = fromSMTLib " ++ s
+
 -- | z3 prints uninterpreted values like this: T!val!4 or T_val_4. Turn that into T_4
 simplifyECon :: String -> String
 simplifyECon "" = ""
@@ -600,7 +626,9 @@
   where go p e = case e of
                    ECon n | Just a <- n `lookup` env -> a
                           | True                     -> simplifyECon n
-                   ENum (i, _)       -> cnst i
+                   ENum (1, _, True) -> "True"
+                   ENum (0, _, True) -> "False"
+                   ENum (i, _, _)    -> cnst i
                    EReal  a          -> cnst a
                    EFloat f          -> cnst f
                    EFloatingPoint f  -> cnst f
@@ -621,13 +649,13 @@
                    EApp [ECon "not", EApp [ECon ">",  a, b]] -> go p $ EApp [ECon "<=", a, b]
 
                    -- Handle x + -y that z3 is fond of producing
-                   EApp [ECon a, x, EApp [ECon m, ENum (-1, _), y]] | isPlus a && isTimes m -> go p $ EApp [ECon "-", x, y]
+                   EApp [ECon a, x, EApp [ECon m, ENum (-1, _, _), y]] | isPlus a && isTimes m -> go p $ EApp [ECon "-", x, y]
 
                    -- Handle x + -NUM that z3 is also fond of producing
-                   EApp [ECon a, x, ENum (i, mw)] | isPlus a && i < 0 -> go p $ EApp [ECon "-", x, ENum (-i, mw)]
+                   EApp [ECon a, x, ENum (i, mw, bool)] | isPlus a && i < 0 -> go p $ EApp [ECon "-", x, ENum (-i, mw, bool)]
 
                    -- Handle -1 * x
-                   EApp [ECon o, ENum (-1, _), b] | isTimes o -> parenIf (p >= 8) (neg (go 8 b))
+                   EApp [ECon o, ENum (-1, _, _), b] | isTimes o -> parenIf (p >= 8) (neg (go 8 b))
 
                    -- Move additive constants to the right, multiplicative constants to the left
                    EApp [ECon o, x, y] | isPlus  o && isConst x && not (isConst y) -> go p $ EApp [ECon o, y, x]
diff --git a/Data/SBV/Utils/TDiff.hs b/Data/SBV/Utils/TDiff.hs
--- a/Data/SBV/Utils/TDiff.hs
+++ b/Data/SBV/Utils/TDiff.hs
@@ -77,7 +77,7 @@
                             r `seq` do mbElapsed <- getElapsedTime mbStart
                                        pure (mbElapsed, r)
 
--- | Same as 'timeIf', except we fully evaluate the result, via its the NFData instance.
+-- | Same as 'timeIf', except we fully evaluate the result, via its NFData instance.
 timeIfRNF :: (NFData a, MonadIO m) => Bool -> m a -> m (Maybe NominalDiffTime, a)
 timeIfRNF measureTime act = timeIf measureTime (act >>= \r -> rnf r `seq` pure r)
 
diff --git a/Documentation/SBV/Examples/ADT/Expr.hs b/Documentation/SBV/Examples/ADT/Expr.hs
new file mode 100644
--- /dev/null
+++ b/Documentation/SBV/Examples/ADT/Expr.hs
@@ -0,0 +1,172 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Documentation.SBV.Examples.ADT.Expr
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- A basic expression ADT example.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE FlexibleInstances   #-}
+{-# LANGUAGE OverloadedLists     #-}
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Documentation.SBV.Examples.ADT.Expr where
+
+import Data.SBV
+import Data.SBV.Control
+import Data.SBV.RegExp
+import Data.SBV.Tuple
+import qualified Data.SBV.List as SL
+
+-- | A basic arithmetic expression type.
+data Expr = Val Integer
+          | Var String
+          | Add Expr Expr
+          | Mul Expr Expr
+          | Let String Expr Expr
+
+-- | Create a symbolic version of expressions.
+mkSymbolic [''Expr]
+
+-- | Show instance for 'Expr'.
+instance Show Expr where
+  show (Val i)     = show i
+  show (Var a)     = a
+  show (Add l r)   = "(" ++ show l ++ " + " ++ show r ++ ")"
+  show (Mul l r)   = "(" ++ show l ++ " * " ++ show r ++ ")"
+  show (Let s a b) = "(let " ++ s ++ " = " ++ show a ++ " in " ++ show b ++ ")"
+
+-- | Num instance, simplifies construction of values
+instance Num Expr where
+  fromInteger = Val
+  (+)         = Add
+  (*)         = Mul
+  abs         = error "Num Expr: undefined abs"
+  signum      = error "Num Expr: undefined signum"
+  negate      = error "Num Expr: undefined negate"
+
+-- | Num instance for the symbolic version
+instance Num SExpr where
+  fromInteger = sVal . literal
+  (+)         = sAdd
+  (*)         = sMul
+  abs         = error "Num SExpr: undefined abs"
+  signum      = error "Num SExpr: undefined signum"
+  negate      = error "Num SExpr: undefined negate"
+
+-- | Validity: We require each variable appearing to be an identifier (lowercase letter followed by
+-- any number of upper-lower case letters and digits), and all expressions are closed; i.e., any
+-- variable referenced is introduced by an enclosing let expression.
+isValid :: SExpr -> SBool
+isValid = go []
+  where isId s = s `match` (asciiLower * KStar (asciiLetter + digit))
+        go :: SList String -> SExpr -> SBool
+        go = smtFunction "valid"
+           $ \env expr -> [sCase| expr of
+                              Var s     -> isId s .&& s `SL.elem` env
+                              Val _     -> sTrue
+                              Add l r   -> go env l .&& go env r
+                              Mul l r   -> go env l .&& go env r
+                              Let s a b -> isId s .&& go env a .&& go (s SL..: env) b
+                           |]
+
+-- | Evaluate an expression.
+eval :: SExpr -> SInteger
+eval = go []
+ where go :: SList (String, Integer) -> SExpr -> SInteger
+       go = smtFunction "eval"
+          $ \env expr -> [sCase| expr of
+                            Val i     -> i
+                            Var s     -> get env s
+                            Add l r   -> go env l + go env r
+                            Mul l r   -> go env l * go env r
+                            Let s e r -> go (tuple (s, go env e) SL..: env) r
+                         |]
+
+       get :: SList (String, Integer) -> SString -> SInteger
+       get = smtFunction "get"
+           $ \env s -> [sCase| env of
+                          []                    -> 0
+                          (k, v) : es | s .== k -> v
+                                      | True    -> get es s
+                       |]
+
+-- | A basic theorem about 'eval'.
+-- >>> evalPlus5
+-- Q.E.D.
+evalPlus5 :: IO ThmResult
+evalPlus5 = prove $ do e :: SExpr <- free "e"
+                       pure $ eval (e + 5) .== 5 + eval e
+
+-- | A simple sat result example.
+--
+-- >>> evalSat
+-- Satisfiable. Model:
+--   e = Let "a" (Val 1313) (Add (Val (-1312)) (Var "a")) :: Expr
+--   a =                                                9 :: Integer
+--   b =                                               10 :: Integer
+evalSat :: IO SatResult
+evalSat = sat $ do e :: SExpr    <- free "e"
+                   constrain $ isValid e
+                   constrain $ isLet   e
+
+                   a :: SInteger <- free "a"
+                   b :: SInteger <- free "b"
+                   constrain $ a .>= 4
+                   constrain $ b .>= 10
+
+                   pure $ eval (e + sVal a) .== b * eval e
+
+-- | Another test, generating some (mildly) interesting examples.
+--
+-- >>> genE
+-- Satisfiable. Model:
+--   e1 = Let "t" (Val 5) (Val 3) :: Expr
+--   e2 =                Val (-2) :: Expr
+genE :: IO SatResult
+genE = sat $ do e1 :: SExpr <- free "e1"
+                e2 :: SExpr <- free "e2"
+
+                constrain $ isValid e1
+                constrain $ isValid e2
+
+                constrain $ e1 ./== e2
+                constrain $ isLet e1
+                constrain $ eval e1 .== 3
+                constrain $ eval e1 .== eval e2 + 5
+
+-- | Query mode example.
+--
+-- >>> queryE
+-- e1: (let t = 5 in 3)
+-- e2: -2
+queryE :: IO ()
+queryE = runSMT $ do
+           e1 :: SExpr <- free "e1"
+           e2 :: SExpr <- free "e2"
+
+           constrain $ isValid e1
+           constrain $ isValid e2
+
+           constrain $ e1 ./== e2
+           constrain $ isLet e1
+           constrain $ eval e1 .== 3
+           constrain $ eval e1 .== eval e2 + 5
+
+           query $ do cs <- checkSat
+                      case cs of
+                        Sat -> do e1v <- getValue e1
+                                  e2v <- getValue e2
+                                  io $ putStrLn $ "e1: " ++ show e1v
+                                  io $ putStrLn $ "e2: " ++ show e2v
+                        _   -> error $ "Unexpected result: " ++ show cs
+
+{- HLint ignore module "Reduce duplication" -}
diff --git a/Documentation/SBV/Examples/ADT/Param.hs b/Documentation/SBV/Examples/ADT/Param.hs
new file mode 100644
--- /dev/null
+++ b/Documentation/SBV/Examples/ADT/Param.hs
@@ -0,0 +1,191 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Documentation.SBV.Examples.ADT.Param
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- A basic parameterized expression ADT example.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE FlexibleContexts    #-}
+{-# LANGUAGE FlexibleInstances   #-}
+{-# LANGUAGE OverloadedLists     #-}
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Documentation.SBV.Examples.ADT.Param where
+
+import Data.SBV
+import Data.SBV.Control
+import Data.SBV.RegExp
+import Data.SBV.Tuple
+import qualified Data.SBV.List as SL
+
+-- | A basic arithmetic expression type.
+data Expr nm val = Val val
+                 | Var nm
+                 | Add (Expr nm val) (Expr nm val)
+                 | Mul (Expr nm val) (Expr nm val)
+                 | Let nm (Expr nm val) (Expr nm val)
+
+-- | Create a symbolic version of expressions.
+mkSymbolic [''Expr]
+
+-- | Show instance for 'Expr'.
+instance (Show nm, Show val) => Show (Expr nm val) where
+  show (Val i)     = show i
+  show (Var a)     = show a
+  show (Add l r)   = "(" ++ show l ++ " + " ++ show r ++ ")"
+  show (Mul l r)   = "(" ++ show l ++ " * " ++ show r ++ ")"
+  show (Let s a b) = "(let " ++ show s ++ " = " ++ show a ++ " in " ++ show b ++ ")"
+
+-- | Show instance for 'Expr', specialized when name is string.
+instance {-# OVERLAPPING #-} Show val => Show (Expr String val) where
+  show (Val i)     = show i
+  show (Var a)     = a
+  show (Add l r)   = "(" ++ show l ++ " + " ++ show r ++ ")"
+  show (Mul l r)   = "(" ++ show l ++ " * " ++ show r ++ ")"
+  show (Let s a b) = "(let " ++ s ++ " = " ++ show a ++ " in " ++ show b ++ ")"
+
+-- | Num instance, simplifies construction of values
+instance Integral val => Num (Expr nm val) where
+  fromInteger = Val . fromIntegral
+  (+)         = Add
+  (*)         = Mul
+  abs         = error "Num Expr: undefined abs"
+  signum      = error "Num Expr: undefined signum"
+  negate      = error "Num Expr: undefined negate"
+
+-- | Num instance for the symbolic version
+instance (SymVal nm, SymVal val, Integral val) => Num (SExpr nm val) where
+  fromInteger = sVal . literal . fromIntegral
+  (+)         = sAdd
+  (*)         = sMul
+  abs         = error "Num SExpr: undefined abs"
+  signum      = error "Num SExpr: undefined signum"
+  negate      = error "Num SExpr: undefined negate"
+
+-- | Validity: We require each variable appearing to be an identifier to satisfy the predicate given.
+-- any number of upper-lower case letters and digits), and all expressions are closed; i.e., any
+-- variable referenced is introduced by an enclosing let expression.
+isValid :: (SymVal nm, Eq nm, SymVal val) => (SBV nm -> SBool) -> SExpr nm val -> SBool
+isValid nmChk = go []
+  where go = smtFunction "valid"
+           $ \env expr -> [sCase| expr of
+                              Var s     -> nmChk s  .&& s `SL.elem` env
+                              Val _     -> sTrue
+                              Add l r   -> go env l .&& go env r
+                              Mul l r   -> go env l .&& go env r
+                              Let s a b -> nmChk s  .&& go env a .&& go (s SL..: env) b
+                           |]
+
+-- | Evaluate an expression.
+eval :: (SymVal nm, SymVal val, Num (SBV val)) => SExpr nm val -> SBV val
+eval = go []
+ where go = smtFunction "eval"
+          $ \env expr -> [sCase| expr of
+                            Val i     -> i
+                            Var s     -> get env s
+                            Add l r   -> go env l + go env r
+                            Mul l r   -> go env l * go env r
+                            Let s e r -> go (tuple (s, go env e) SL..: env) r
+                         |]
+
+       get = smtFunction "get"
+           $ \env s -> [sCase| env of
+                           []                    -> 0
+                           (k, v) : es | s .== k -> v
+                                       | True    -> get es s
+                        |]
+
+-- | A basic theorem about 'eval'.
+-- >>> evalPlus5
+-- Q.E.D.
+evalPlus5 :: IO ThmResult
+evalPlus5 = prove $ do e :: SExpr String Integer <- free "e"
+                       pure $ eval (e + 5) .== 5 + eval e
+
+-- | Is this a string identifier? Lowercase letter followed by any number of upper-lower case letters and digits.
+isId :: SString -> SBool
+isId s = s `match` (asciiLower * KStar (asciiLetter + digit))
+
+-- | A simple sat result example.
+--
+-- >>> evalSat
+-- Satisfiable. Model:
+--   e = Let "a" (Val 1313) (Add (Val (-1312)) (Var "a")) :: Expr String Integer
+--   a =                                                9 :: Integer
+--   b =                                               10 :: Integer
+evalSat :: IO SatResult
+evalSat = sat $ do e :: SExpr String Integer  <- free "e"
+                   constrain $ isValid isId e
+                   constrain $ isLet   e
+
+                   a :: SInteger <- free "a"
+                   b :: SInteger <- free "b"
+                   constrain $ a .>= 4
+                   constrain $ b .>= 10
+
+                   pure $ eval (e + sVal a) .== b * eval e
+
+-- | Another test, generating some (mildly) interesting examples.
+--
+-- >>> genE
+-- Satisfiable. Model:
+--   e1 = Let "s" (Val 5) (Val 3) :: Expr String Integer
+--   e2 =                Val (-2) :: Expr String Integer
+genE :: IO SatResult
+genE = sat $ do e1 :: SExpr String Integer <- free "e1"
+                e2 :: SExpr String Integer <- free "e2"
+
+                constrain $ isValid isId e1
+                constrain $ isValid isId e2
+
+                constrain $ e1 ./== e2
+                constrain $ isLet e1
+                constrain $ eval e1 .== 3
+                constrain $ eval e1 .== eval e2 + 5
+
+-- | Query mode example.
+--
+-- >>> queryE
+-- e1: (let a = (-1 * -3) in (a * 1))
+-- e2: -2
+-- e3: (let h = 77 % 78 in h)
+queryE :: IO ()
+queryE = runSMT $ do
+           e1 :: SExpr String Integer <- free "e1"
+           e2 :: SExpr String Integer <- free "e2"
+
+           e3 :: SExpr String Rational <- free "e3"
+
+           constrain $ isValid isId e1
+           constrain $ isValid isId e2
+           constrain $ isValid isId e3
+
+           constrain $ e1 ./== e2
+           constrain $ isLet e1
+           constrain $ eval e1 .== 3
+           constrain $ eval e1 .== eval e2 + 5
+
+           constrain $ isLet e3
+           constrain $ isMul (getLet_2 e1)
+           constrain $ isMul (getLet_3 e1)
+
+           query $ do cs <- checkSat
+                      case cs of
+                        Sat -> do e1v <- getValue e1
+                                  e2v <- getValue e2
+                                  e3v <- getValue e3
+                                  io $ putStrLn $ "e1: " ++ show e1v
+                                  io $ putStrLn $ "e2: " ++ show e2v
+                                  io $ putStrLn $ "e3: " ++ show e3v
+                        _   -> error $ "Unexpected result: " ++ show cs
+
+{- HLint ignore module "Reduce duplication" -}
diff --git a/Documentation/SBV/Examples/ADT/Shapes.hs b/Documentation/SBV/Examples/ADT/Shapes.hs
new file mode 100644
--- /dev/null
+++ b/Documentation/SBV/Examples/ADT/Shapes.hs
@@ -0,0 +1,110 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Documentation.SBV.Examples.ADT.Shapes
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Generate shapes satisfying constraints on their dimensions and area. This
+-- example demonstrates symbolic pattern matching on an algebraic datatype,
+-- enumerating models with 'allSatWith', and extracting concrete Haskell values
+-- in query mode.
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE QuasiQuotes       #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE TypeApplications  #-}
+
+module Documentation.SBV.Examples.ADT.Shapes where
+
+import Data.SBV
+import Data.SBV.Control
+
+-- | Shapes with signed 32-bit dimensions. We reserve 'Rectangle' for shapes
+-- with unequal sides, so squares have their own constructor.
+data Shape = Dot                                        -- ^ A point, with zero area.
+           | Square    { side  :: Int32 }                -- ^ A square.
+           | Rectangle { sideA :: Int32, sideB :: Int32 } -- ^ A rectangle.
+           deriving Show
+
+-- | Generate 'SShape', symbolic constructors such as 'sSquare', and the
+-- support needed to pass shapes to and from the solver.
+mkSymbolic [''Shape]
+
+-- | Compute the area using 'sCase' to match a symbolic shape. Ordinary Haskell
+-- pattern matching cannot inspect a shape whose constructor is not yet known.
+area :: SShape -> SInt32
+area s = [sCase| s of
+            Dot           -> 0
+            Square a      -> a * a
+            Rectangle a b -> a * b
+         |]
+
+-- | Require positive dimensions below 100, and unequal sides for rectangles.
+-- The bounds also ensure that area calculations cannot overflow 'Int32'.
+-- A dot has no dimensions to constrain.
+goodShape :: SShape -> SBool
+goodShape s = [sCase| s of
+                 Dot           -> sTrue
+                 Square a      -> a .> 0 .&& a .< 100
+                 Rectangle a b -> a .> 0 .&& a .< 100 .&& b .> 0 .&& b .< 100 .&& a ./= b
+              |]
+
+-- | Create a symbolic shape and constrain its dimensions. Creating the value
+-- automatically declares the datatype to the solver.
+newShape :: Symbolic SShape
+newShape = do x <- free "shape"
+              constrain $ goodShape x
+              pure x
+
+-- | Select non-dot shapes with area between 10 and 30, inclusive.
+-- The explicit exclusion of 'Dot' is redundant with the area bound, but
+-- illustrates a symbolic comparison with a datatype constructor.
+interesting :: SShape -> SBool
+interesting x = area x .>= 10 .&& area x .<= 30 .&& x ./= sDot
+
+-- | Ask for five distinct models using SBV's built-in enumeration.
+--
+-- >>> examples
+-- Solution #1:
+--   shape = Rectangle 24 1 :: Shape
+-- Solution #2:
+--   shape = Rectangle 1 25 :: Shape
+-- Solution #3:
+--   shape = Rectangle 25 1 :: Shape
+-- Solution #4:
+--   shape = Square 5 :: Shape
+-- Solution #5:
+--   shape = Square 4 :: Shape
+-- Found 5 different solutions.
+examples :: IO AllSatResult
+examples = allSatWith z3{allSatMaxModelCount = Just 5} (interesting <$> newShape)
+
+-- | Enumerate shapes manually in query mode. After each satisfiability check,
+-- 'getValue' returns a concrete 'Shape'. We exclude that value using 'literal'
+-- before asking for the next model. Stop after five shapes, or earlier if
+-- there are no more solutions, and return them in discovery order.
+--
+-- >>> extracted
+-- [Square {side = 4},Rectangle {sideA = 15, sideB = 1},Square {side = 5},Rectangle {sideA = 4, sideB = 6},Rectangle {sideA = 12, sideB = 2}]
+extracted :: IO [Shape]
+extracted = runSMT $ do
+        x <- newShape
+        constrain $ interesting x
+
+        let loop :: Int -> [Shape] -> Query [Shape]
+            loop 5 sofar = pure $ reverse sofar
+            loop i sofar = do cs <- checkSat
+                              case cs of
+                                Sat   -> do xv <- getValue x
+                                            -- Exclude the entire shape, including its fields.
+                                            constrain $ x ./= literal xv
+                                            loop (i+1) (xv : sofar)
+                                Unsat -> pure $ reverse sofar
+                                _     -> error $ "Solver said: " ++ show cs
+
+        query $ loop 0 []
diff --git a/Documentation/SBV/Examples/ADT/Types.hs b/Documentation/SBV/Examples/ADT/Types.hs
new file mode 100644
--- /dev/null
+++ b/Documentation/SBV/Examples/ADT/Types.hs
@@ -0,0 +1,131 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Documentation.SBV.Examples.ADT.Types
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- An encoding of the simple type-checking via constraints, following
+-- <https://microsoft.github.io/z3guide/docs/theories/Datatypes/#using-datatypes-for-solving-type-constraints>
+-----------------------------------------------------------------------------
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE QuasiQuotes       #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE TypeApplications  #-}
+
+module Documentation.SBV.Examples.ADT.Types where
+
+import Data.SBV
+
+-- | Simple encoding of untyped lambda terms
+data M = Var { var   :: String }     -- ^ Variables: @x@
+       | Lam { bound :: String       -- ^ Abstraction: @\x. M@
+             , body :: M
+             }
+       | App { fn  :: M              -- ^ Application: @M M@
+             , arg :: M
+             }
+
+-- | Types.
+data T = TInt                        -- ^ Integers
+       | TStr                        -- ^ Strings
+       | TArr { dom :: T, rng :: T } -- ^ Functions: @t -> t@
+
+-- | Make terms and types symbolic
+mkSymbolic [''M]
+mkSymbolic [''T]
+
+-- | Instead of modeling environments for mapping variables to their
+-- types, we'll simply use an uninterpreted function. Note that
+-- this also implies we consider all terms to be given so that variables
+-- do not shadow each other; i.e., all variables are unique. This is
+-- a simplification, but it is not without justification: One can
+-- always alpha-rename bound variables so all bound variables are unique.
+env :: SString -> ST
+env = uninterpret "env"
+
+-- | Use an uninterpreted function to also magically find the type of a term.
+typeOf :: SM -> ST
+typeOf = uninterpret "typeOf"
+
+-- | Given a term and a type, check that the term has that type.
+tc :: SM -> ST -> SBool
+tc = smtFunction "constraints" $ \m t ->
+        [sCase| m of
+
+          -- Var case. The environment must match the type we expect.
+          Var s -> env s .== t
+
+          -- Abstraction case. Type must be a function, whose domain matches the variable.
+          -- And body must match the range.
+          Lam v b
+            | isTArr t .&& env v .== sdom t
+            -> tc b (srng t)
+
+          -- Application case. In this case, we ask the solver to give us the type of the
+          -- function, and then ensure the whole thing is well-formed
+          App f a -> let tf = typeOf f
+                     in   isTArr tf      -- f must have an arrow type
+                      .&& tc f tf        -- The function must type-check with that type
+                      .&& tc a (sdom tf) -- Argument must have the type of this function
+                      .&& t .== srng tf  -- Final result must match the type we're looking for
+
+          -- Otherwise, ill-typed.
+          _ -> sFalse
+        |]
+
+-- | Well typedness: If what the 'typeOf' function returns type-checks the term,
+-- then a term is well-typed.
+wellTyped :: SM -> SBool
+wellTyped m = tc m (typeOf m)
+
+-- | Make sure the identity function can be typed.
+--
+-- >>> idWF
+-- Satisfiable. Model:
+--   env :: String -> T
+--   env _ = TInt
+-- <BLANKLINE>
+--   typeOf :: M -> T
+--   typeOf _ = TArr TInt TInt
+--
+-- The model is rather uninteresting, but it shows that identity can have the type Integer to Integer, where
+-- all variables are mapped to Integers.
+idWF :: IO SatResult
+idWF = sat $ wellTyped $ sLam x vx
+  where x  = literal "x"
+        vx = sVar x
+
+-- | Check that if we apply a function that takes n integer to a string is not well-typed.
+--
+-- >>> intFuncAppString
+-- Unsatisfiable
+--
+-- As expected, the solver says that there's no way to type-check such an expression.
+intFuncAppString :: IO SatResult
+intFuncAppString = sat $ do
+        -- Introduce the constant @plus1 :: Int -> Int@
+        plus1 <- free "plus1"
+        constrain $ tc plus1 (literal (TInt `TArr` TInt))
+
+        -- Introduce the constant @str :: String@
+        str <- free "str"
+        constrain $ tc str sTStr
+
+        -- Check if the application of plus1 to str can be well-typed
+        pure $ wellTyped $ sApp plus1 str
+
+-- | Make sure self-application cannot be typed.
+--
+-- >>> selfAppNotWellTyped
+-- Unsatisfiable
+--
+-- We get unsatisfiable, indicating there's no way to come up with an environment that will
+-- successfully assign a type to the term @\x -> x x@.
+selfAppNotWellTyped :: IO SatResult
+selfAppNotWellTyped = sat $ wellTyped $ sLam x (sApp vx vx)
+  where x  = literal "x"
+        vx = sVar x
diff --git a/Documentation/SBV/Examples/BitPrecise/Adders.hs b/Documentation/SBV/Examples/BitPrecise/Adders.hs
new file mode 100644
--- /dev/null
+++ b/Documentation/SBV/Examples/BitPrecise/Adders.hs
@@ -0,0 +1,185 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Documentation.SBV.Examples.BitPrecise.Adders
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Build two textbook binary adders out of logic gates and prove them correct,
+-- fully automatically, by bit-blasting.
+--
+-- We model each adder as a Haskell function over a statically-known list of
+-- symbolic bits, producing a fixed Boolean circuit. We then prove---for a
+-- chosen word size---that the circuit computes the same result as SBV's native
+-- bit-vector addition @(+)@:
+--
+--   * A /ripple-carry/ adder, which threads a carry sequentially through a
+--     chain of full adders.
+--
+--   * A /carry-lookahead/ adder, which computes every carry directly from the
+--     generate\/propagate signals of all lower bits, with no sequential
+--     dependency.
+--
+-- Besides proving each adder equal to @(+)@, we also prove the two adders equal
+-- to /each other/: the fast, parallel carry-lookahead circuit computes exactly
+-- the same result as the simple ripple-carry reference.
+--
+-- All proofs here are discharged by a single decidable bit-vector query at a
+-- fixed width. See "Documentation.SBV.Examples.TP.Adder" for the companion
+-- development that instead proves a ripple-carry adder correct for /all/ widths
+-- at once, by induction.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE CPP                 #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Documentation.SBV.Examples.BitPrecise.Adders where
+
+import Data.SBV hiding (fullAdder)
+import GHC.TypeLits (KnownNat)
+
+#ifdef DOCTEST
+-- $setup
+-- >>> import Data.SBV
+-- >>> :set -XDataKinds -XTypeApplications -XScopedTypeVariables
+#endif
+
+-- | A symbolic bit is just a symbolic boolean.
+type Bit = SBool
+
+-- * Logic gates
+
+-- | A half adder takes two bits and produces their sum bit and carry bit:
+-- @sum = a xor b@, @carry = a and b@.
+halfAdder :: Bit -> Bit -> (Bit, Bit)
+halfAdder a b = (a .<+> b, a .&& b)
+
+-- | A full adder takes two bits and an incoming carry, and produces the sum bit
+-- together with the outgoing carry. We build it out of two half adders, in the
+-- usual way.
+fullAdder :: Bit -> Bit -> Bit -> (Bit, Bit)
+fullAdder a b cin = (s, c0 .|| c1)
+  where (s0, c0) = halfAdder a b
+        (s,  c1) = halfAdder s0 cin
+
+-- * Ripple-carry adder
+
+-- | The ripple-carry adder. Given an incoming carry and a little-endian list of
+-- bit pairs (one pair per bit position, least-significant first), it threads the
+-- carry through a chain of full adders, returning the list of sum bits together
+-- with the final carry-out.
+rippleAdd :: Bit -> [(Bit, Bit)] -> ([Bit], Bit)
+rippleAdd cin []            = ([], cin)
+rippleAdd cin ((a, b) : ps) = (s : ss, cout)
+  where (s,  c)    = fullAdder a b cin
+        (ss, cout) = rippleAdd c ps
+
+-- * Carry-lookahead adder
+
+-- | Generate and propagate signals for a bit position: a position /generates/ a
+-- carry when both inputs are set, and /propagates/ an incoming carry when
+-- exactly one input is set.
+generatePropagate :: Bit -> Bit -> (Bit, Bit)
+generatePropagate a b = (a .&& b, a .<+> b)
+
+-- | The carry-lookahead adder. Rather than rippling the carry through the chain,
+-- it computes the carry /into/ each position directly from the
+-- generate\/propagate signals of all lower positions, using the textbook
+-- expansion
+--
+-- @
+--   c(i) = g(i-1) + p(i-1).g(i-2) + ... + p(i-1)...p(1).g(0) + p(i-1)...p(0).cin
+-- @
+--
+-- so that every carry is an independent flat formula with no sequential
+-- dependency. The sum bit at position @i@ is then @p(i) xor c(i)@, and the
+-- carry-out is the carry into the (nonexistent) position just past the top.
+lookaheadAdd :: Bit -> [(Bit, Bit)] -> ([Bit], Bit)
+lookaheadAdd cin ps = (sums, carryInto n)
+  where n   = length ps
+        gps = [ generatePropagate a b | (a, b) <- ps ]
+
+        g k = fst (gps !! k)
+        p k = snd (gps !! k)
+
+        -- product of the propagate signals over positions [lo .. hi-1]
+        prodP lo hi = sAnd [ p k | k <- [lo .. hi - 1] ]
+
+        -- carry into position i, expanded over all lower positions
+        carryInto i = sOr $ (cin .&& prodP 0 i)
+                          : [ g j .&& prodP (j + 1) i | j <- [0 .. i - 1] ]
+
+        sums = [ p i .<+> carryInto i | i <- [0 .. n - 1] ]
+
+-- * Lifting to words
+
+-- | Run an adder over the bits of two words. We blast both operands into
+-- little-endian bit lists, feed them to the adder with no incoming carry, and
+-- reassemble the sum bits into a word. The carry-out is dropped, matching the
+-- wrap-around semantics of bit-vector @(+)@.
+addWith :: forall n. (KnownNat n, BVIsNonZero n) => (Bit -> [(Bit, Bit)] -> ([Bit], Bit)) -> SWord n -> SWord n -> SWord n
+addWith adder x y = fromBitsLE ss
+  where (ss, _) = adder sFalse (zip (blastLE x) (blastLE y))
+
+-- | The ripple-carry adder, lifted to words.
+rippleAddWord :: (KnownNat n, BVIsNonZero n) => SWord n -> SWord n -> SWord n
+rippleAddWord = addWith rippleAdd
+
+-- | The carry-lookahead adder, lifted to words.
+lookaheadAddWord :: (KnownNat n, BVIsNonZero n) => SWord n -> SWord n -> SWord n
+lookaheadAddWord = addWith lookaheadAdd
+
+-- * Correctness
+
+-- | The ripple-carry adder computes bit-vector addition. We prove it here at
+-- width 8, but the same call proves it at any width you instantiate:
+--
+-- >>> rippleCorrect @8
+-- Q.E.D.
+--
+-- Adder-versus-@(+)@ equivalence is one of the easy cases for bit-blasting (the
+-- carry chain is linear), so this stays fast even at large widths---it is the
+-- cheap baseline to compare the lookahead proofs against.
+rippleCorrect :: forall n. (KnownNat n, BVIsNonZero n) => IO ThmResult
+rippleCorrect = prove $ \(x :: SWord n) (y :: SWord n) -> rippleAddWord x y .== x + y
+
+-- | The carry-lookahead adder computes bit-vector addition:
+--
+-- >>> lookaheadCorrect @8
+-- Q.E.D.
+--
+-- Note that, unlike 'rippleCorrect', this proof slows down noticeably as the
+-- width grows. The lookahead carry is the flat \(O(n^2)\) generate\/propagate
+-- expansion, so the formula handed to the solver grows quadratically in the
+-- width---try @lookaheadCorrect \@64@, @\@128@, @\@256@ to watch it climb.
+lookaheadCorrect :: forall n. (KnownNat n, BVIsNonZero n) => IO ThmResult
+lookaheadCorrect = prove $ \(x :: SWord n) (y :: SWord n) -> lookaheadAddWord x y .== x + y
+
+-- | The fast carry-lookahead adder agrees with the simple ripple-carry adder on
+-- every input---the parallel carry computation refines the sequential one:
+--
+-- >>> rippleEqLookahead @8
+-- Q.E.D.
+--
+-- This proof drags in the same \(O(n^2)\) lookahead carry expansion as
+-- 'lookaheadCorrect', so it scales the same way: comfortable at small widths,
+-- visibly slower as the width grows.
+rippleEqLookahead :: forall n. (KnownNat n, BVIsNonZero n) => IO ThmResult
+rippleEqLookahead = prove $ \(x :: SWord n) (y :: SWord n) -> rippleAddWord x y .== lookaheadAddWord x y
+
+-- | The carry-out of the ripple-carry adder is exactly the unsigned overflow
+-- flag: it is set precisely when the true sum does not fit in @n@ bits, which
+-- for an addition with no incoming carry is detectable as the result wrapping
+-- below either operand:
+--
+-- >>> rippleOverflow @8
+-- Q.E.D.
+rippleOverflow :: forall n. (KnownNat n, BVIsNonZero n) => IO ThmResult
+rippleOverflow = prove $ \(x :: SWord n) (y :: SWord n) ->
+                   let (_, cout) = rippleAdd sFalse (zip (blastLE x) (blastLE y))
+                   in cout .== ((x + y) .< x)
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
@@ -110,6 +110,6 @@
 
                                         mid   = f low high
 
-                                    return $ sFromIntegral mid .== mid'
+                                    pure $ sFromIntegral mid .== mid'
 
 {- 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
@@ -294,7 +294,7 @@
         flagC <- sBool "flagC"
         flagZ <- sBool "flagZ"
 
-        return $ legatoIsCorrect (x, y, lo, regX, regA, flagC, flagZ)
+        pure $ legatoIsCorrect (x, y, lo, regX, regA, flagC, flagZ)
 
 ------------------------------------------------------------------
 -- * C Code generation
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
@@ -53,7 +53,7 @@
 There are two main parts to proving that a sorting algorithm is correct:
 
        * Prove that the output is non-decreasing
- 
+
        * Prove that the output is a permutation of the input
 -}
 
@@ -88,7 +88,7 @@
 correctness :: Int -> IO ThmResult
 correctness n = prove $ do xs <- mkFreeVars n
                            let ys = mergeSort xs
-                           return $ nonDecreasing ys .&& isPermutationOf xs ys
+                           pure $ nonDecreasing ys .&& isPermutationOf xs ys
 
 -----------------------------------------------------------------------------
 -- * Generating C code
diff --git a/Documentation/SBV/Examples/BitPrecise/PEXT_PDEP.hs b/Documentation/SBV/Examples/BitPrecise/PEXT_PDEP.hs
--- a/Documentation/SBV/Examples/BitPrecise/PEXT_PDEP.hs
+++ b/Documentation/SBV/Examples/BitPrecise/PEXT_PDEP.hs
@@ -25,7 +25,7 @@
 --    OD
 -- @
 --
--- PDEP (parallel deposit) is similar, except the assigment is:
+-- PDEP (parallel deposit) is similar, except the assignment is:
 --
 -- @
 --    DEST[m] := TEMP[k]
@@ -37,7 +37,6 @@
 
 {-# LANGUAGE CPP                 #-}
 {-# LANGUAGE DataKinds           #-}
-{-# LANGUAGE Rank2Types          #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeApplications    #-}
 
diff --git a/Documentation/SBV/Examples/BitPrecise/PrefixSum.hs b/Documentation/SBV/Examples/BitPrecise/PrefixSum.hs
--- a/Documentation/SBV/Examples/BitPrecise/PrefixSum.hs
+++ b/Documentation/SBV/Examples/BitPrecise/PrefixSum.hs
@@ -13,7 +13,7 @@
 -----------------------------------------------------------------------------
 
 {-# LANGUAGE CPP                 #-}
-{-# LANGUAGE Rank2Types          #-}
+{-# LANGUAGE RankNTypes          #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
@@ -68,13 +68,13 @@
 
 -- | The Ladner-Fischer (@lf@) implementation of prefix-sum.
 lf :: (a, a -> a -> a) -> PowerList a -> PowerList a
-lf _ []         = error "lf: malformed (empty) powerlist"
-lf _ [x]        = [x]
-lf (zero, f) pl = zipPL (zipWith f (rsh lfpq) p) lfpq
+lf _            []  = error "lf: malformed (empty) powerlist"
+lf _            [x] = [x]
+lf (zeroE, f)   pl  = zipPL (zipWith f (rsh lfpq) p) lfpq
    where (p, q) = unzipPL pl
          pq     = zipWith f p q
-         lfpq   = lf (zero, f) pq
-         rsh xs = zero : init xs
+         lfpq   = lf (zeroE, f) pq
+         rsh xs = zeroE : init xs
 
 
 ----------------------------------------------------------------------
@@ -85,7 +85,7 @@
 flIsCorrect :: Int -> (forall a. (OrdSymbolic a, Num a, Bits a) => (a, a -> a -> a)) -> Symbolic SBool
 flIsCorrect n zf = do
         args :: PowerList SWord32 <- mkFreeVars n
-        return $ ps zf args .== lf zf args
+        pure $ ps zf args .== lf zf args
 
 -- | Proves Ladner-Fischer is equivalent to reference specification for addition.
 -- @0@ is the left-unit element, and we use a power-list of size @8@. We have:
diff --git a/Documentation/SBV/Examples/CodeGeneration/AddSub.hs b/Documentation/SBV/Examples/CodeGeneration/AddSub.hs
--- a/Documentation/SBV/Examples/CodeGeneration/AddSub.hs
+++ b/Documentation/SBV/Examples/CodeGeneration/AddSub.hs
@@ -16,7 +16,7 @@
 import Data.SBV
 import Data.SBV.Tools.CodeGen
 
--- | Simple function that returns add/sum of args
+-- | Return the sum and difference of two unsigned 8-bit values, wrapping modulo 256.
 addSub :: SWord8 -> SWord8 -> (SWord8, SWord8)
 addSub x y = (x+y, x-y)
 
@@ -37,11 +37,11 @@
 -- addSub.o: addSub.c addSub.h
 -- 	${CC} ${CCFLAGS} -c $< -o $@
 -- <BLANKLINE>
--- addSub_driver.o: addSub_driver.c
+-- addSub_driver.o: addSub_driver.c addSub.h
 -- 	${CC} ${CCFLAGS} -c $< -o $@
 -- <BLANKLINE>
 -- addSub_driver: addSub.o addSub_driver.o
--- 	${CC} ${CCFLAGS} $^ -o $@
+-- 	${CC} ${CCFLAGS} $^ -o $@ ${LDFLAGS}
 -- <BLANKLINE>
 -- clean:
 -- 	rm -f *.o
@@ -52,9 +52,10 @@
 -- == BEGIN: "addSub.h" ================
 -- /* Header file for addSub. Automatically generated by SBV. Do not edit! */
 -- <BLANKLINE>
--- #ifndef __addSub__HEADER_INCLUDED__
--- #define __addSub__HEADER_INCLUDED__
+-- #ifndef SBV_GENERATED_addSub_HEADER_INCLUDED
+-- #define SBV_GENERATED_addSub_HEADER_INCLUDED
 -- <BLANKLINE>
+-- <BLANKLINE>
 -- #include <stdio.h>
 -- #include <stdlib.h>
 -- #include <inttypes.h>
@@ -63,6 +64,13 @@
 -- #include <string.h>
 -- #include <math.h>
 -- <BLANKLINE>
+-- /* Floating-point calling convention:
+--  * Enter generated code in FE_TONEAREST (round-to-nearest, ties-to-even).
+--  * Callbacks must preserve this mode before returning or re-entering.
+--  * Generated code does not check or change the hardware rounding mode.
+--  * Custom builds must disable implicit FP contraction, including at LTO link time.
+--  */
+-- <BLANKLINE>
 -- /* The boolean type */
 -- typedef bool SBool;
 -- <BLANKLINE>
@@ -88,7 +96,7 @@
 -- void addSub(const SWord8 x, const SWord8 y, SWord8 *sum,
 --             SWord8 *dif);
 -- <BLANKLINE>
--- #endif /* __addSub__HEADER_INCLUDED__ */
+-- #endif /* SBV_GENERATED_addSub_HEADER_INCLUDED */
 -- == END: "addSub.h" ==================
 -- == BEGIN: "addSub_driver.c" ================
 -- /* Example driver program for addSub. */
@@ -99,14 +107,14 @@
 -- <BLANKLINE>
 -- int main(void)
 -- {
---   SWord8 sum;
---   SWord8 dif;
+--   SWord8 sbv_driver_output_0;
+--   SWord8 sbv_driver_output_1;
 -- <BLANKLINE>
---   addSub(132, 241, &sum, &dif);
+--   addSub(132, 241, &sbv_driver_output_0, &sbv_driver_output_1);
 -- <BLANKLINE>
 --   printf("addSub(132, 241, &sum, &dif) ->\n");
---   printf("  sum = %"PRIu8"\n", sum);
---   printf("  dif = %"PRIu8"\n", dif);
+--   printf("  sum = %"PRIu8"\n", sbv_driver_output_0);
+--   printf("  dif = %"PRIu8"\n", sbv_driver_output_1);
 -- <BLANKLINE>
 --   return 0;
 -- }
@@ -116,24 +124,46 @@
 -- <BLANKLINE>
 -- #include "addSub.h"
 -- <BLANKLINE>
--- void addSub(const SWord8 x, const SWord8 y, SWord8 *sum,
---             SWord8 *dif)
+-- /* Exact bit-vector runtime. All arithmetic is modulo the declared width. */
+-- #ifndef SBV_CGEN_UNUSED
+-- #if defined(__GNUC__) || defined(__clang__)
+-- #define SBV_CGEN_UNUSED __attribute__((unused))
+-- #else
+-- #define SBV_CGEN_UNUSED
+-- #endif
+-- #endif
+-- <BLANKLINE>
+-- static inline SBV_CGEN_UNUSED SWord8 sbv_bv_u8_add(SWord8 a, SWord8 b)
 -- {
---   const SWord8 s0 = x;
---   const SWord8 s1 = y;
---   const SWord8 s2 = s0 + s1;
---   const SWord8 s3 = s0 - s1;
+--   const SWord8 bits = (SWord8) ((((uint64_t) (SWord8) a) + ((uint64_t) (SWord8) b)) & UINT64_C(0x00000000000000ff));
+--   return (SWord8) bits;
+-- }
 -- <BLANKLINE>
---   *sum = s2;
---   *dif = s3;
+-- static inline SBV_CGEN_UNUSED SWord8 sbv_bv_u8_sub(SWord8 a, SWord8 b)
+-- {
+--   const SWord8 bits = (SWord8) ((((uint64_t) (SWord8) a) - ((uint64_t) (SWord8) b)) & UINT64_C(0x00000000000000ff));
+--   return (SWord8) bits;
 -- }
+-- <BLANKLINE>
+-- <BLANKLINE>
+-- void addSub(const SWord8 sbv_input_0, const SWord8 sbv_input_1,
+--             SWord8 *sbv_output_0, SWord8 *sbv_output_1)
+-- {
+--   const SWord8 s0 = sbv_input_0;
+--   const SWord8 s1 = sbv_input_1;
+--   const SWord8 s2 = sbv_bv_u8_add(s0, s1);
+--   const SWord8 s3 = sbv_bv_u8_sub(s0, s1);
+-- <BLANKLINE>
+--   *sbv_output_0 = s2;
+--   *sbv_output_1 = s3;
+-- }
 -- == END: "addSub.c" ==================
 --
 genAddSub :: IO ()
 genAddSub = compileToC outDir "addSub" $ do
         x <- cgInput "x"
         y <- cgInput "y"
-        -- leave the cgDriverVals call out for generating a driver with random values
+        -- leave the cgSetDriverValues call out for generating a driver with random values
         cgSetDriverValues [132, 241]
         let (s, d) = addSub x y
         cgOutput "sum" s
diff --git a/Documentation/SBV/Examples/CodeGeneration/Fibonacci.hs b/Documentation/SBV/Examples/CodeGeneration/Fibonacci.hs
--- a/Documentation/SBV/Examples/CodeGeneration/Fibonacci.hs
+++ b/Documentation/SBV/Examples/CodeGeneration/Fibonacci.hs
@@ -107,7 +107,7 @@
 -- >   const SWord64 s32 = s6 ? 0x0000000000000001ULL : s31;
 -- >   const SWord64 s33 = s4 ? 0x0000000000000001ULL : s32;
 -- >   const SWord64 s34 = s2 ? 0x0000000000000000ULL : s33;
--- >   
+-- >
 -- >   return s34;
 -- > }
 genFib1 :: SWord64 -> IO ()
@@ -176,7 +176,7 @@
 -- >       0x000003af9a19bbd9ULL, 0x000005f6c7b064e2ULL, 0x000009a661ca20bbULL
 -- >   };
 -- >   const SWord64 s65 = s0 >= 65 ? 0x0000000000000000ULL : table0[s0];
--- >   
+-- >
 -- >   return s65;
 -- > }
 genFib2 :: Word64 -> IO ()
diff --git a/Documentation/SBV/Examples/CodeGeneration/GCD.hs b/Documentation/SBV/Examples/CodeGeneration/GCD.hs
--- a/Documentation/SBV/Examples/CodeGeneration/GCD.hs
+++ b/Documentation/SBV/Examples/CodeGeneration/GCD.hs
@@ -88,14 +88,14 @@
 -- precisely the same amount of time for all values of @x@ and @y@.
 --
 -- > /* File: "sgcd.c". Automatically generated by SBV. Do not edit! */
--- > 
+-- >
 -- > #include <stdio.h>
 -- > #include <stdlib.h>
 -- > #include <inttypes.h>
 -- > #include <stdint.h>
 -- > #include <stdbool.h>
 -- > #include "sgcd.h"
--- > 
+-- >
 -- > SWord8 sgcd(const SWord8 x, const SWord8 y)
 -- > {
 -- >   const SWord8 s0 = x;
@@ -146,7 +146,7 @@
 -- >   const SWord8 s46 = s9 ? s5 : s45;
 -- >   const SWord8 s47 = s6 ? s1 : s46;
 -- >   const SWord8 s48 = s3 ? s0 : s47;
--- >   
+-- >
 -- >   return s48;
 -- > }
 genGCDInC :: IO ()
diff --git a/Documentation/SBV/Examples/CodeGeneration/PopulationCount.hs b/Documentation/SBV/Examples/CodeGeneration/PopulationCount.hs
--- a/Documentation/SBV/Examples/CodeGeneration/PopulationCount.hs
+++ b/Documentation/SBV/Examples/CodeGeneration/PopulationCount.hs
@@ -91,7 +91,7 @@
 -- generate C code to compute population-counts for us. This action will generate all the
 -- C files that you will need, including a driver program for test purposes.
 --
--- Below is the generated header file for `popCountFast`:
+-- Below are the generated files for `popCountFast`:
 --
 -- >>> genPopCountInC
 -- == BEGIN: "Makefile" ================
@@ -108,11 +108,11 @@
 -- popCount.o: popCount.c popCount.h
 -- 	${CC} ${CCFLAGS} -c $< -o $@
 -- <BLANKLINE>
--- popCount_driver.o: popCount_driver.c
+-- popCount_driver.o: popCount_driver.c popCount.h
 -- 	${CC} ${CCFLAGS} -c $< -o $@
 -- <BLANKLINE>
 -- popCount_driver: popCount.o popCount_driver.o
--- 	${CC} ${CCFLAGS} $^ -o $@
+-- 	${CC} ${CCFLAGS} $^ -o $@ ${LDFLAGS}
 -- <BLANKLINE>
 -- clean:
 -- 	rm -f *.o
@@ -123,9 +123,10 @@
 -- == BEGIN: "popCount.h" ================
 -- /* Header file for popCount. Automatically generated by SBV. Do not edit! */
 -- <BLANKLINE>
--- #ifndef __popCount__HEADER_INCLUDED__
--- #define __popCount__HEADER_INCLUDED__
+-- #ifndef SBV_GENERATED_popCount_HEADER_INCLUDED
+-- #define SBV_GENERATED_popCount_HEADER_INCLUDED
 -- <BLANKLINE>
+-- <BLANKLINE>
 -- #include <stdio.h>
 -- #include <stdlib.h>
 -- #include <inttypes.h>
@@ -134,6 +135,13 @@
 -- #include <string.h>
 -- #include <math.h>
 -- <BLANKLINE>
+-- /* Floating-point calling convention:
+--  * Enter generated code in FE_TONEAREST (round-to-nearest, ties-to-even).
+--  * Callbacks must preserve this mode before returning or re-entering.
+--  * Generated code does not check or change the hardware rounding mode.
+--  * Custom builds must disable implicit FP contraction, including at LTO link time.
+--  */
+-- <BLANKLINE>
 -- /* The boolean type */
 -- typedef bool SBool;
 -- <BLANKLINE>
@@ -158,7 +166,7 @@
 -- /* Entry point prototype: */
 -- SWord8 popCount(const SWord64 x);
 -- <BLANKLINE>
--- #endif /* __popCount__HEADER_INCLUDED__ */
+-- #endif /* SBV_GENERATED_popCount_HEADER_INCLUDED */
 -- == END: "popCount.h" ==================
 -- == BEGIN: "popCount_driver.c" ================
 -- /* Example driver program for popCount. */
@@ -169,9 +177,9 @@
 -- <BLANKLINE>
 -- int main(void)
 -- {
---   const SWord8 __result = popCount(0x1b02e143e4f0e0e5ULL);
+--   const SWord8 sbv_result = popCount(0x1b02e143e4f0e0e5ULL);
 -- <BLANKLINE>
---   printf("popCount(0x1b02e143e4f0e0e5ULL) = %"PRIu8"\n", __result);
+--   printf("popCount(0x1b02e143e4f0e0e5ULL) = %"PRIu8"\n", sbv_result);
 -- <BLANKLINE>
 --   return 0;
 -- }
@@ -181,9 +189,68 @@
 -- <BLANKLINE>
 -- #include "popCount.h"
 -- <BLANKLINE>
--- SWord8 popCount(const SWord64 x)
+-- /* Exact bit-vector runtime. All arithmetic is modulo the declared width. */
+-- #ifndef SBV_CGEN_UNUSED
+-- #if defined(__GNUC__) || defined(__clang__)
+-- #define SBV_CGEN_UNUSED __attribute__((unused))
+-- #else
+-- #define SBV_CGEN_UNUSED
+-- #endif
+-- #endif
+-- <BLANKLINE>
+-- static inline SBV_CGEN_UNUSED SWord64 sbv_bv_u64_shl(SWord64 a, SWord64 amount)
 -- {
---   const SWord64 s0 = x;
+--   const uint64_t n = (uint64_t) (SWord64) amount;
+--   const SWord64 result = n >= 64 ? (SWord64) 0 : (SWord64) ((uint64_t) (SWord64) a << n);
+--   return result;
+-- }
+-- <BLANKLINE>
+-- static inline SBV_CGEN_UNUSED SWord64 sbv_bv_u64_lshr(SWord64 a, SWord64 amount)
+-- {
+--   const uint64_t n = (uint64_t) (SWord64) amount;
+--   return n >= 64 ? (SWord64) 0 : (SWord64) ((uint64_t) (SWord64) a >> n);
+-- }
+-- <BLANKLINE>
+-- static inline SBV_CGEN_UNUSED SWord8 sbv_bv_u8_add(SWord8 a, SWord8 b)
+-- {
+--   const SWord8 bits = (SWord8) ((((uint64_t) (SWord8) a) + ((uint64_t) (SWord8) b)) & UINT64_C(0x00000000000000ff));
+--   return (SWord8) bits;
+-- }
+-- <BLANKLINE>
+-- <BLANKLINE>
+-- SWord8 popCount(const SWord64 sbv_input_0)
+-- {
+--   const SWord64 s0 = sbv_input_0;
+--   const SWord64 s11 = s0 & 0x00000000000000ffULL;
+--   const SWord64 s14 = sbv_bv_u64_lshr(s0, 0x0000000000000008ULL);
+--   const SWord64 s15 = 0x00000000000000ffULL & s14;
+--   const SWord64 s18 = sbv_bv_u64_lshr(s14, 0x0000000000000008ULL);
+--   const SWord64 s19 = 0x00000000000000ffULL & s18;
+--   const SWord64 s22 = sbv_bv_u64_lshr(s18, 0x0000000000000008ULL);
+--   const SWord64 s23 = 0x00000000000000ffULL & s22;
+--   const SWord64 s26 = sbv_bv_u64_lshr(s22, 0x0000000000000008ULL);
+--   const SWord64 s27 = 0x00000000000000ffULL & s26;
+--   const SWord64 s30 = sbv_bv_u64_lshr(s26, 0x0000000000000008ULL);
+--   const SWord64 s31 = 0x00000000000000ffULL & s30;
+--   const SWord64 s34 = sbv_bv_u64_lshr(s30, 0x0000000000000008ULL);
+--   const SWord64 s35 = 0x00000000000000ffULL & s34;
+--   const SWord64 s38 = sbv_bv_u64_lshr(s34, 0x0000000000000008ULL);
+--   const SWord64 s39 = 0x00000000000000ffULL & s38;
+--         SWord8  s12;
+--         SWord8  s16;
+--         SWord8  s17;
+--         SWord8  s20;
+--         SWord8  s21;
+--         SWord8  s24;
+--         SWord8  s25;
+--         SWord8  s28;
+--         SWord8  s29;
+--         SWord8  s32;
+--         SWord8  s33;
+--         SWord8  s36;
+--         SWord8  s37;
+--         SWord8  s40;
+--         SWord8  s41;
 --   static const SWord8 table0[] = {
 --       0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3,
 --       3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4,
@@ -198,36 +265,21 @@
 --       5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5,
 --       5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
 --   };
---   const SWord64 s11 = s0 & 0x00000000000000ffULL;
---   const SWord8  s12 = table0[s11];
---   const SWord64 s14 = s0 >> 8;
---   const SWord64 s15 = 0x00000000000000ffULL & s14;
---   const SWord8  s16 = table0[s15];
---   const SWord8  s17 = s12 + s16;
---   const SWord64 s18 = s14 >> 8;
---   const SWord64 s19 = 0x00000000000000ffULL & s18;
---   const SWord8  s20 = table0[s19];
---   const SWord8  s21 = s17 + s20;
---   const SWord64 s22 = s18 >> 8;
---   const SWord64 s23 = 0x00000000000000ffULL & s22;
---   const SWord8  s24 = table0[s23];
---   const SWord8  s25 = s21 + s24;
---   const SWord64 s26 = s22 >> 8;
---   const SWord64 s27 = 0x00000000000000ffULL & s26;
---   const SWord8  s28 = table0[s27];
---   const SWord8  s29 = s25 + s28;
---   const SWord64 s30 = s26 >> 8;
---   const SWord64 s31 = 0x00000000000000ffULL & s30;
---   const SWord8  s32 = table0[s31];
---   const SWord8  s33 = s29 + s32;
---   const SWord64 s34 = s30 >> 8;
---   const SWord64 s35 = 0x00000000000000ffULL & s34;
---   const SWord8  s36 = table0[s35];
---   const SWord8  s37 = s33 + s36;
---   const SWord64 s38 = s34 >> 8;
---   const SWord64 s39 = 0x00000000000000ffULL & s38;
---   const SWord8  s40 = table0[s39];
---   const SWord8  s41 = s37 + s40;
+--   s12 = table0[s11];
+--   s16 = table0[s15];
+--   s17 = sbv_bv_u8_add(s12, s16);
+--   s20 = table0[s19];
+--   s21 = sbv_bv_u8_add(s17, s20);
+--   s24 = table0[s23];
+--   s25 = sbv_bv_u8_add(s21, s24);
+--   s28 = table0[s27];
+--   s29 = sbv_bv_u8_add(s25, s28);
+--   s32 = table0[s31];
+--   s33 = sbv_bv_u8_add(s29, s32);
+--   s36 = table0[s35];
+--   s37 = sbv_bv_u8_add(s33, s36);
+--   s40 = table0[s39];
+--   s41 = sbv_bv_u8_add(s37, s40);
 -- <BLANKLINE>
 --   return s41;
 -- }
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
@@ -9,16 +9,13 @@
 -- An implementation of AES (Advanced Encryption Standard), using SBV.
 -- For details on AES, see <http://en.wikipedia.org/wiki/Advanced_Encryption_Standard>.
 --
--- We do a T-box implementation, which leads to good C code as we can take
--- advantage of look-up tables. Note that we make virtually no attempt to
--- optimize our Haskell code. The concern here is not with getting Haskell running
--- fast at all. The idea is to program the T-Box implementation as naturally and clearly
--- as possible in Haskell, and have SBV's code-generator generate fast C code automatically.
--- Therefore, we merely use ordinary Haskell lists as our data-structures, and do not
--- bother with any unboxing or strictness annotations. Thus, we achieve the separation
--- of concerns: Correctness via clarity and simplicity and proofs on the Haskell side,
--- performance by relying on SBV's code generator. If necessary, the generated code
--- can be FFI'd back into Haskell to complete the loop.
+-- We choose a T-box implementation because it maps AES round operations to
+-- table lookups and word-sized XORs in generated C. The Haskell code can use
+-- ordinary lists and describe the tables mathematically: SBV computes their
+-- entries during code generation and emits constant C arrays. This keeps
+-- the algorithm readable without recomputing field arithmetic at run time.
+-- The examples below generate either a standalone block encryptor or a library
+-- with separate key-expansion, encryption, and decryption functions.
 --
 -- All 3 valid key sizes (128, 192, and 256) as required by the FIPS-197 standard
 -- are supported.
@@ -29,11 +26,7 @@
 {-# LANGUAGE ParallelListComp #-}
 {-# LANGUAGE TypeApplications #-}
 
-#if MIN_VERSION_base(4,19,0)
 {-# OPTIONS_GHC -Wall -Werror -Wno-incomplete-uni-patterns -Wno-x-partial #-}
-#else
-{-# OPTIONS_GHC -Wall -Werror -Wno-incomplete-uni-patterns #-}
-#endif
 
 module Documentation.SBV.Examples.Crypto.AES where
 
@@ -744,48 +737,40 @@
 -- ${codeGenIntro}
 -----------------------------------------------------------------------------
 {- $codeGenIntro
-   We have emphasized that our T-Box implementation in Haskell was guided by clarity and correctness, not
-   performance. Indeed, our implementation is hardly the fastest AES implementation in Haskell. However,
-   we can use it to automatically generate straight-line C-code that can run fairly fast.
-
-   For the purposes of illustration, we only show here how to generate code for a 128-bit AES block-encrypt
-   function, that takes 8 32-bit words as an argument. The first 4 are the 128-bit input, and the final
-   four are the 128-bit key. The impact of this is that the generated function would expand the key for
-   each block of encryption, a needless task unless we change the key in every block. In a more serious application,
-   we would instead generate code for both the 'aesKeySchedule' and the 'aesEncrypt' functions, thus reusing the
-   key-schedule over many applications of the encryption call. (Unfortunately doing this is rather cumbersome right
-   now, since Haskell does not support fixed-size lists.)
+   The C generator emits lookup tables and an unrolled sequence of AES rounds.
+   The generated block encryptor takes two input arrays of four 32-bit words
+   (plaintext and key), and writes four ciphertext words to an output array.
+   It expands the key on every call. To reuse an expanded key across blocks,
+   use the separate key-schedule and block functions generated by 'cgAESLibrary'.
 -}
 
--- | Code generation for 128-bit AES encryption.
---
--- The following sample from the generated code-lines show how T-Boxes are rendered as C arrays:
+-- | Generate and print the source, header, example driver, and Makefile for
+-- 128-bit AES encryption. The driver uses the test vector from Appendix C.1
+-- of the AES standard.
 --
--- @
---   static const SWord32 table1[] = {
---       0xc66363a5UL, 0xf87c7c84UL, 0xee777799UL, 0xf67b7b8dUL,
---       0xfff2f20dUL, 0xd66b6bbdUL, 0xde6f6fb1UL, 0x91c5c554UL,
---       0x60303050UL, 0x02010103UL, 0xce6767a9UL, 0x562b2b7dUL,
---       0xe7fefe19UL, 0xb5d7d762UL, 0x4dababe6UL, 0xec76769aUL,
---       ...
---       }
--- @
+-- We can inspect the same program without writing files:
 --
--- The generated program has 5 tables (one sbox table, and 4-Tboxes), all converted to fast C arrays. Here
--- is a sample of the generated straightline C-code:
+-- >>> import Data.SBV.Internals (compileToC')
+-- >>> import Data.List (isPrefixOf)
+-- >>> (_, _, generated) <- compileToC' "aes128BlockEncrypt" aes128BlockEncrypt
+-- >>> let generatedLines = lines (show generated)
 --
--- @
---   const SWord8  s1915 = (SWord8) s1912;
---   const SWord8  s1916 = table0[s1915];
---   const SWord16 s1917 = (((SWord16) s1914) << 8) | ((SWord16) s1916);
---   const SWord32 s1918 = (((SWord32) s1911) << 16) | ((SWord32) s1917);
---   const SWord32 s1919 = s1844 ^ s1918;
---   const SWord32 s1920 = s1903 ^ s1919;
--- @
+-- The generated program has four T-box tables and one S-box table:
 --
--- The GNU C-compiler does a fine job of optimizing this straightline code to generate a fairly efficient C implementation.
+-- >>> putStr $ unlines $ filter (isPrefixOf "  static const ") generatedLines
+--   static const SWord32 table1[] = {
+--   static const SWord32 table2[] = {
+--   static const SWord32 table3[] = {
+--   static const SWord32 table4[] = {
+--   static const SWord8 table0[] = {
 cgAES128BlockEncrypt :: IO ()
-cgAES128BlockEncrypt = compileToC Nothing "aes128BlockEncrypt" $ do
+cgAES128BlockEncrypt = compileToC Nothing "aes128BlockEncrypt" aes128BlockEncrypt
+
+-- | Code-generation action shared by the standalone encryptor and the
+-- generated-code examples above. Pass it to 'compileToC' with a destination
+-- directory to write the files instead of printing them.
+aes128BlockEncrypt :: SBVCodeGen ()
+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
 
@@ -806,6 +791,10 @@
    the same expanded key (potentially using some crypto-mode), until we decide to change the key. In this
    section, we show how to use SBV to instead generate a library of functions that can be used in such a scenario.
    The generated library is a typical @.a@ archive, that can be linked using the C-compiler as usual.
+
+   For example, @cgAESLibrary 128 (Just "aes128")@ writes the library sources,
+   header, example driver, and Makefile to @aes128@. Run @make -C aes128@ to
+   build the archive and driver.
 -}
 
 -- | Components of the AES implementation that the library is generated from. For each case, we provide
@@ -889,11 +878,8 @@
         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
--- reports 8.2 million block encryptions per second. So, the generated code is about 25% slower
--- as compared to the highly optimized OpenSSL implementation. (Note that the speed test was done
--- somewhat simplistically, so these numbers should be considered very rough estimates.)
+-- The generated library includes a header, a Makefile, and an example driver.
+-- Build the archive and driver with @make@ in the destination directory.
 cgAES128Library :: IO ()
 cgAES128Library = cgAESLibrary 128 Nothing
 
@@ -908,6 +894,7 @@
 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" -}
+{- HLint ignore aesRound             "Use head"           -}
+{- HLint ignore aesInvRound          "Use head"           -}
+{- HLint ignore aesDecryptUnwoundKey "Use head"           -}
+{- HLint ignore module               "Reduce duplication" -}
diff --git a/Documentation/SBV/Examples/Crypto/Prince.hs b/Documentation/SBV/Examples/Crypto/Prince.hs
--- a/Documentation/SBV/Examples/Crypto/Prince.hs
+++ b/Documentation/SBV/Examples/Crypto/Prince.hs
@@ -6,15 +6,14 @@
 -- Maintainer: erkokl@gmail.com
 -- Stability : experimental
 --
--- Implementation of Prince encryption and decrytion, following the spec
--- <https://eprint.iacr.org/2012/529.pdf>
+-- Implementation of Prince encryption and decryption.
 -----------------------------------------------------------------------------
 
 {-# LANGUAGE CPP              #-}
 {-# LANGUAGE DataKinds        #-}
 {-# LANGUAGE ParallelListComp #-}
 
-{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-incomplete-uni-patterns #-}
 
 module Documentation.SBV.Examples.Crypto.Prince where
 
@@ -131,8 +130,8 @@
 -- Q.E.D.
 prop_sr :: Predicate
 prop_sr = do b <- free "block"
-             return $   b .== sr (srInv b)
-                    .&& b .== srInv (sr b)
+             pure $   b .== sr (srInv b)
+                  .&& b .== srInv (sr b)
 
 -- | M' transformation
 m' :: Block -> Block
@@ -189,8 +188,8 @@
 -- Q.E.D.
 prop_SBox :: Predicate
 prop_SBox = do b <- free "block"
-               return $   b .== sBoxInv (sBox b)
-                      .&& b .== sBox (sBoxInv b)
+               pure $   b .== sBoxInv (sBox b)
+                    .&& b .== sBox (sBoxInv b)
 
 -- * Round constants
 
diff --git a/Documentation/SBV/Examples/Crypto/RC4.hs b/Documentation/SBV/Examples/Crypto/RC4.hs
--- a/Documentation/SBV/Examples/Crypto/RC4.hs
+++ b/Documentation/SBV/Examples/Crypto/RC4.hs
@@ -15,8 +15,6 @@
 -- functional implementation.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE ScopedTypeVariables #-}
-
 {-# OPTIONS_GHC -Wall -Werror #-}
 
 module Documentation.SBV.Examples.Crypto.RC4 where
@@ -146,7 +144,7 @@
         let ks  = keySchedule key
             ct  = zipWith xor ks pt
             pt' = zipWith xor ks ct
-        return $ pt .== pt'
+        pure $ pt .== pt'
 
 --------------------------------------------------------------------------------------------
 -- | For doctest purposes only
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
@@ -17,7 +17,6 @@
 
 {-# LANGUAGE DataKinds           #-}
 {-# LANGUAGE NamedFieldPuns      #-}
-{-# LANGUAGE Rank2Types          #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeApplications    #-}
 
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
@@ -70,10 +70,10 @@
 ldn :: forall proxy n. KnownNat n => proxy n -> Maybe Int -> [([Integer], Integer)] -> IO Solution
 ldn pn mbLim problem = do solution <- basis pn mbLim (map (map literal) m)
                           if homogeneous
-                              then return $ Homogeneous solution
+                              then pure $ Homogeneous solution
                               else do let ones  = [xs | (1:xs) <- solution]
                                           zeros = [xs | (0:xs) <- solution]
-                                      return $ NonHomogeneous ones zeros
+                                      pure $ NonHomogeneous ones zeros
   where rhs = map snd problem
         lhs = map fst problem
         homogeneous = all (== 0) rhs
@@ -114,7 +114,7 @@
 -- (1+k, k', 2k+k')
 --
 -- 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.
+-- You can verify these solutions by substituting the values for @x@, @y@ and @z@ in the above, for each choice.
 -- It's harder to see that they cover all possibilities, but a moments thought reveals that is indeed the case.
 test :: IO Solution
 test = ldn (Proxy @4) Nothing [([2,1,-1], 2)]
@@ -170,5 +170,5 @@
                                   , ([0,  0,  0,  0,  0,  4, -5], 1)
                                   ]
                       case soln of
-                        NonHomogeneous (xs:_) _ -> return xs
+                        NonHomogeneous (xs:_) _ -> pure xs
                         _                       -> search (i+1)
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
@@ -9,14 +9,10 @@
 -- Proves a simple mutex algorithm correct up to a given bound.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DeriveAnyClass      #-}
-{-# LANGUAGE DeriveDataTypeable  #-}
-{-# LANGUAGE FlexibleContexts    #-}
 {-# LANGUAGE FlexibleInstances   #-}
-{-# LANGUAGE OverloadedLists     #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE StandaloneDeriving  #-}
 {-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE TypeApplications    #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -29,10 +25,10 @@
 data State = Idle     -- ^ Regular work
            | Ready    -- ^ Intention to enter critical state
            | Critical -- ^ In the critical state
-           deriving (Enum, Bounded)
+           deriving Show
 
 -- | Make 'State' a symbolic enumeration
-mkSymbolicEnumeration ''State
+mkSymbolic [''State]
 
 -- | The mutex property holds for two sequences of state transitions, if they are not in
 -- their critical section at the same time.
@@ -114,7 +110,7 @@
 --
 -- >>> notFair 10
 -- Fairness is violated at bound: 10
--- P1: [Idle,Idle,Ready,Critical,Idle,Ready,Critical,Critical,Idle,Ready]
+-- P1: [Idle,Idle,Idle,Idle,Ready,Critical,Idle,Ready,Critical,Critical]
 -- P2: [Idle,Ready,Ready,Ready,Ready,Ready,Ready,Ready,Ready,Ready]
 -- Ts: [1,1,1,1,1,1,1,1,1,1]
 --
diff --git a/Documentation/SBV/Examples/Lists/CountOutAndTransfer.hs b/Documentation/SBV/Examples/Lists/CountOutAndTransfer.hs
--- a/Documentation/SBV/Examples/Lists/CountOutAndTransfer.hs
+++ b/Documentation/SBV/Examples/Lists/CountOutAndTransfer.hs
@@ -7,7 +7,7 @@
 -- Stability : experimental
 --
 -- Shows that COAT (Count-out-and-transfer) trick preserves order of cards.
--- From pg. 35 of <http://graphics8.nytimes.com/packages/pdf/crossword/Mulcahy_Mathematical_Card_Magic-Sample2.pdf>:
+-- Quoting Colm Mulcahy's /Mathematical Card Magic: Fifty-Two New Effects/ (CRC Press, 2013):
 --
 -- /Given a packet of n cards, COATing k cards refers to counting out that many from the top into a pile, thus reversing their order, and transferring those as a unit to the bottom./
 --
diff --git a/Documentation/SBV/Examples/Misc/Auxiliary.hs b/Documentation/SBV/Examples/Misc/Auxiliary.hs
--- a/Documentation/SBV/Examples/Misc/Auxiliary.hs
+++ b/Documentation/SBV/Examples/Misc/Auxiliary.hs
@@ -15,8 +15,6 @@
 -- considering them explicitly in model construction.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE OverloadedStrings #-}
-
 {-# OPTIONS_GHC -Wall -Werror #-}
 
 module Documentation.SBV.Examples.Misc.Auxiliary where
@@ -30,7 +28,7 @@
              y <- free "y"
              constrain $ x .>= 0
              constrain $ x .<= 1
-             return $ x - abs y .== (0 :: SInteger)
+             pure $ x - abs y .== (0 :: SInteger)
 
 -- | Generate all satisfying assignments for our problem. We have:
 --
diff --git a/Documentation/SBV/Examples/Misc/Definitions.hs b/Documentation/SBV/Examples/Misc/Definitions.hs
--- a/Documentation/SBV/Examples/Misc/Definitions.hs
+++ b/Documentation/SBV/Examples/Misc/Definitions.hs
@@ -11,7 +11,8 @@
 -- for recursive definitions.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE OverloadedLists  #-}
+{-# LANGUAGE OverloadedLists #-}
+{-# LANGUAGE QuasiQuotes     #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -19,7 +20,6 @@
 
 import Data.SBV
 import Data.SBV.Tuple
-import qualified Data.SBV.List as L
 
 -------------------------------------------------------------------------
 -- * Simple functions
@@ -46,11 +46,13 @@
 
 -- | Sum of numbers from 0 to the given number. Since this is a recursive
 -- definition, we cannot simply symbolically simulate it as it wouldn't
--- terminat. So, we use the function generation facilities to define it
--- directly in SMTLib. Note how the function itself takes a "recursive version"
--- of itself, and all recursive calls are made with this name.
+-- terminate. So, we use the function generation facilities to define it
+-- directly in SMTLib.
 sumToN :: SInteger -> SInteger
-sumToN = smtFunction "sumToN" $ \x -> ite (x .<= 0) 0 (x + sumToN (x - 1))
+sumToN = smtFunction "sumToN" $ \x -> [sCase| x of
+                                         _ | x .<= 0 -> 0
+                                         _           -> x + sumToN (x - 1)
+                                      |]
 
 -- | Prove that sumToN works as expected.
 --
@@ -65,7 +67,10 @@
 
 -- | Coding list-length recursively. Again, we map directly to an SMTLib function.
 len :: SList Integer -> SInteger
-len = smtFunction "list_length" $ \xs -> ite (L.null xs) 0 (1 + len (L.tail xs))
+len = smtFunction "list_length" $ \xs -> [sCase| xs of
+                                            []   -> 0
+                                            _:ts -> 1 + len ts
+                                         |]
 
 -- | Calculate the length of a list, using recursive functions.
 --
@@ -90,26 +95,56 @@
 pingPong :: IO SatResult
 pingPong = sat $ \x -> x .> 0 .&& ping x sTrue .> x
   where ping :: SInteger -> SBool -> SInteger
-        ping = smtFunction "ping" $ \x y -> ite y (pong (x+1) (sNot y)) (x - 1)
+        ping = smtFunctionWithMeasure "ping" (\_ y -> ite y 1 (0 :: SInteger), [])
+             $ \x y -> [sCase| y of
+                           True  -> pong (x+1) (sNot y)
+                           False -> x - 1
+                        |]
 
         pong :: SInteger -> SBool -> SInteger
-        pong = smtFunction "pong" $ \a b -> ite b (ping (a-1) (sNot b)) a
+        pong = smtFunctionWithMeasure "pong" (\_ b -> ite b 1 (0 :: SInteger), [])
+             $ \a b -> [sCase| b of
+                           True  -> ping (a-1) (sNot b)
+                           False -> a
+                        |]
 
--- | Usual way to define even-odd mutually recursively. Unfortunately, while this goes through,
--- the backend solver does not terminate on this example. See 'evenOdd2' for an alternative
--- technique to handle such definitions, which seems to be more solver friendly.
+-- | Usual way to define even-odd mutually recursively. While the termination measure
+-- is verified, current SMT solvers do not terminate when evaluating mutually recursive
+-- @define-funs-rec@ definitions. See 'isEvenOdd' for a single-function alternative
+-- that is more solver-friendly.
+--
+-- >>> evenOdd
+-- Unknown.
+--   Reason: timeout
 evenOdd :: IO SatResult
-evenOdd = satWith z3{verbose=True} $ \a r -> a .== 20 .&& r .== isE a
+evenOdd = sat $ do setTimeOut 5000
+                   a <- sInteger "a"
+                   r <- sBool "r"
+                   constrain $ a .== 20 .&& r .== isE a
   where isE, isO :: SInteger -> SBool
-        isE = smtFunction "isE" $ \x -> ite (x .< 0) (isE (-x)) (x .== 0 .|| isO (x - 1))
-        isO = smtFunction "isO" $ \x -> ite (x .< 0) (isO (-x)) (x .== 0 .|| isE (x - 1))
+        isE = smtFunctionWithMeasure "isE" (\x -> tuple (abs x, ite (x .< 0) (1 :: SInteger) 0), [])
+            $ \x -> [sCase| x of
+                       _ | x .< 0 -> isE (-x)
+                       _          -> x .== 0 .|| isO (x - 1)
+                    |]
+        isO = smtFunctionWithMeasure "isO" (\x -> tuple (abs x, ite (x .< 0) (1 :: SInteger) 0), [])
+            $ \x -> [sCase| x of
+                       _ | x .< 0 -> isO (-x)
+                       _          -> x .== 0 .|| isE (x - 1)
+                    |]
 
 -- | Another technique to handle mutually definitions is to define the functions together, and pull the results out individually.
--- This usually works better than defining the functions separately, from a solver perspective.
+--
+-- The measure @(abs x, ite (x < 0) 1 0)@ ensures termination: when @x < 0@, the call @isEvenOdd(-x)@
+-- keeps @abs x@ the same but drops the second component from 1 to 0. When @x > 0@, the call
+-- @isEvenOdd(x-1)@ decreases @abs x@.
 isEvenOdd :: SInteger -> STuple Bool Bool
-isEvenOdd = smtFunction "isEvenOdd" $ \x -> ite (x .<  0) (isEvenOdd (-x))
-                                          $ ite (x .== 0) (tuple (sTrue, sFalse))
-                                                          (swap (isEvenOdd (x - 1)))
+isEvenOdd = smtFunctionWithMeasure "isEvenOdd" (\x -> tuple (abs x, ite (x .< 0) (1 :: SInteger) 0), [])
+          $ \x -> [sCase| x of
+                     _ | x .<  0 -> isEvenOdd (-x)
+                     _ | x .== 0 -> tuple (sTrue, sFalse)
+                     _           -> swap (isEvenOdd (x - 1))
+                  |]
 
 -- | Extract the isEven function for easier use.
 isEven :: SInteger -> SBool
@@ -135,9 +170,12 @@
 
 -- | Ackermann function, demonstrating nested recursion.
 ack :: SInteger -> SInteger -> SInteger
-ack = smtFunction "ack" $ \x y -> ite (x .== 0) (y + 1)
-                                $ ite (y .== 0) (ack (x - 1) 1)
-                                                (ack (x - 1) (ack x (y - 1)))
+ack = smtFunction "ack"
+    $ \x y -> [sCase| x of
+                 _ | x .<= 0 -> y + 1
+                 _ | y .<= 0 -> ack (x - 1) 1
+                 _           -> ack (x - 1) (ack x (y - 1))
+              |]
 
 -- | We can prove constant-folding instances of the equality @ack 1 y == y + 2@:
 --
diff --git a/Documentation/SBV/Examples/Misc/Enumerate.hs b/Documentation/SBV/Examples/Misc/Enumerate.hs
--- a/Documentation/SBV/Examples/Misc/Enumerate.hs
+++ b/Documentation/SBV/Examples/Misc/Enumerate.hs
@@ -12,12 +12,10 @@
 -- example involving enumerations.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DeriveAnyClass      #-}
-{-# LANGUAGE DeriveDataTypeable  #-}
 {-# LANGUAGE FlexibleInstances   #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE StandaloneDeriving  #-}
 {-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE TypeApplications    #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -28,25 +26,20 @@
 -- | A simple enumerated type, that we'd like to translate to SMT-Lib intact;
 -- i.e., this type will not be uninterpreted but rather preserved and will
 -- be just like any other symbolic type SBV provides.
---
--- Also note that we need to have the following @LANGUAGE@ options defined:
--- @TemplateHaskell@, @StandaloneDeriving@, @DeriveDataTypeable@, @DeriveAnyClass@ for
--- this to work.
 data E = A | B | C
-       deriving (Enum, Bounded, Eq, Ord)
 
 -- | Make 'E' a symbolic value.
-mkSymbolicEnumeration ''E
+mkSymbolic [''E]
 
 -- | Have the SMT solver enumerate the elements of the domain. We have:
 --
 -- >>> elts
 -- Solution #1:
---   s0 = C :: E
+--   s0 = B :: E
 -- Solution #2:
 --   s0 = A :: E
 -- Solution #3:
---   s0 = B :: E
+--   s0 = C :: E
 -- Found 3 different solutions.
 elts :: IO AllSatResult
 elts = allSat $ \(x::SE) -> x .== x
diff --git a/Documentation/SBV/Examples/Misc/FirstOrderLogic.hs b/Documentation/SBV/Examples/Misc/FirstOrderLogic.hs
--- a/Documentation/SBV/Examples/Misc/FirstOrderLogic.hs
+++ b/Documentation/SBV/Examples/Misc/FirstOrderLogic.hs
@@ -12,17 +12,11 @@
 
 {-# LANGUAGE CPP                 #-}
 {-# LANGUAGE DataKinds           #-}
-{-# LANGUAGE DeriveAnyClass      #-}
-{-# LANGUAGE DeriveDataTypeable  #-}
 {-# LANGUAGE FlexibleInstances   #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE StandaloneDeriving  #-}
 {-# LANGUAGE TemplateHaskell     #-}
-{-# LANGUAGE TypeApplications    #-}
-
-#if MIN_VERSION_base(4,19,0)
 {-# LANGUAGE TypeAbstractions    #-}
-#endif
+{-# LANGUAGE TypeApplications    #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -38,17 +32,16 @@
 
 -- | An uninterpreted sort for demo purposes, named 'U'
 data U
-mkUninterpretedSort ''U
+mkSymbolic [''U]
 
 -- | An uninterpreted sort for demo purposes, named 'V'
 data V
-mkUninterpretedSort ''V
+mkSymbolic [''V]
 
 -- | An enumerated type for demo purposes, named 'E'
 data E = A | B | C
-       deriving (Enum, Bounded, Ord, Eq)
 
-mkSymbolicEnumeration ''E
+mkSymbolic [''E]
 
 -- | Helper to turn quantified formula to a regular boolean. We
 -- can think of this as quantifier elimination, hence the name 'qe'.
@@ -134,26 +127,25 @@
 >>> prove $ (qe (\(Forall x) -> p x) .|| qe (\(Forall x) -> q x)) .<=> qe (\(Forall x) -> p x .|| q x)
 Falsifiable. Counter-example:
   P :: U -> Bool
+  P U_1 = False
   P U_2 = True
-  P U_0 = True
-  P _   = False
+  P _   = True
 <BLANKLINE>
   Q :: U -> Bool
+  Q U_1 = True
   Q U_2 = False
-  Q U_0 = False
   Q _   = True
 
 The solver found us a falsifying instance: Pick a domain with at least three elements. We'll call
-the first element @U_2@, and the second element @U_0@, without naming the others. (Unfortunately the solver picks nonintuitive names, but you can substitute better names if you like. They're just names of two distinct
-objects that belong to the domain \(U\) with no other meaning.)
+the first element @U_1@, and the second element @U_2@, without naming the others. 
 
-Arrange so that \(P\) is true on @U_2@ and @U_0@, but false for everything else.
-Also arrange so that \(Q\) is false on these two elements, but true for everything else.
+Arrange so that \(P\) is false on @U_1@ true everywhere else.
+Also arrange so that \(Q\) is false for @U_2@ but true for everything else.
 
 With this
 assignment, the right hand side of our conjecture
 is true no matter which element you pick, because either \(P\) or \(Q\) is true on any
-given element. (Actually, only one will be true on any element, but that is tangential.)
+given element, or both.
 But left-hand-side is not a tautology: Clearly neither \(P\) nor \(Q\) are true for all elements, and
 hence both disjuncts are false. Thus, the alleged conjecture is not an equivalence in first order logic.
 -}
@@ -185,7 +177,7 @@
 -- >>> sat skolemEx1
 -- Satisfiable
 --
--- But this isn't really illimunating. We can first skolemize, and then ask to satisfy:
+-- But this isn't really illuminating. We can first skolemize, and then ask to satisfy:
 --
 -- >>> sat $ skolemize skolemEx1
 -- Satisfiable. Model:
@@ -209,18 +201,18 @@
 --   b _ = 0
 -- <BLANKLINE>
 --   d :: Word8 -> Word8 -> Word8
---   d a c = a + 255 * c
+--   d a c = 255 * c + a
 --
 -- Let's see what the solver said. It suggested we should use the value of @0@ for @b@, regardless of the
 -- choice of @a@. (Note how @b@ is a function of one variable, i.e., of @a@)
--- And it suggested using @a + (255 * c)@ for @d@,
+-- And it suggested using @255 * c + a@ for @d@,
 -- for whatever we choose for @a@ and @c@. Why does this work? Well, given
 -- arbitrary @a@ and @c@, we end up with:
 --
 -- @
 --     a + b >= c + d
---     --> substitute b = 0 and d = a + 255c as suggested by the solver
---     a + 0 >= c + a + 255c
+--     --> substitute b = 0 and d = 255c + a as suggested by the solver
+--     a + 0 >= c + 255c + a
 --     a >= 256c + a
 --     a >= a
 -- @
diff --git a/Documentation/SBV/Examples/Misc/Floating.hs b/Documentation/SBV/Examples/Misc/Floating.hs
--- a/Documentation/SBV/Examples/Misc/Floating.hs
+++ b/Documentation/SBV/Examples/Misc/Floating.hs
@@ -68,21 +68,21 @@
 --
 -- >>> assocPlusRegular
 -- Falsifiable. Counter-example:
---   x =  1.9258643e-34 :: Float
---   y =  -1.925931e-34 :: Float
---   z = -3.8518585e-34 :: Float
+--   x = -0.3383789 :: Float
+--   y = -27907.219 :: Float
+--   z = -515389.94 :: Float
 --
 -- Indeed, we have:
 --
--- >>> let x =  1.9258643e-34 :: Float
--- >>> let y =  -1.925931e-34 :: Float
--- >>> let z = -3.8518585e-34 :: Float
+-- >>> let x = -0.3383789 :: Float
+-- >>> let y = -27907.219 :: Float
+-- >>> let z = -515389.94 :: Float
 -- >>> x + (y + z)
--- -3.8519256e-34
+-- -543297.44
 -- >>> (x + y) + z
--- -3.851925e-34
+-- -543297.5
 --
--- Note the significant difference in the results!
+-- Note the precision difference in the results!
 assocPlusRegular :: IO ThmResult
 assocPlusRegular = prove $ do [x, y, z] <- sFloats ["x", "y", "z"]
                               let lhs = x+(y+z)
@@ -90,7 +90,7 @@
                               -- make sure we do not overflow at the intermediate points
                               constrain $ fpIsPoint lhs
                               constrain $ fpIsPoint rhs
-                              return $ lhs .== rhs
+                              pure $ lhs .== rhs
 
 -----------------------------------------------------------------------------
 -- * FP addition by non-zero can result in no change
@@ -102,13 +102,13 @@
 --
 -- >>> nonZeroAddition
 -- Falsifiable. Counter-example:
---   a = 2.9670994e34 :: Float
---   b = -7.208359e-5 :: Float
+--   a = -3.6509563e26 :: Float
+--   b =   1.6777216e7 :: Float
 --
 -- Indeed, we have:
 --
--- >>> let a = 2.9670994e34 :: Float
--- >>> let b = -7.208359e-5 :: Float
+-- >>> let a = -3.6509563e26 :: Float
+-- >>> let b =   1.6777216e7 :: Float
 -- >>> a + b == a
 -- True
 -- >>> b == 0
@@ -118,7 +118,7 @@
                              constrain $ fpIsPoint a
                              constrain $ fpIsPoint b
                              constrain $ a + b .== a
-                             return $ b .== 0
+                             pure $ b .== 0
 
 -----------------------------------------------------------------------------
 -- * FP multiplicative inverses may not exist
@@ -131,18 +131,18 @@
 --
 -- >>> multInverse
 -- Falsifiable. Counter-example:
---   a = -1.0669042e-38 :: Float
+--   a = 5.2268255e-34 :: Float
 --
 -- Indeed, we have:
 --
--- >>> let a = -1.0669042e-38 :: Float
+-- >>> let a = 5.2268255e-34 :: Float
 -- >>> a * (1/a)
 -- 0.99999994
 multInverse :: IO ThmResult
 multInverse = prove $ do a <- sFloat "a"
                          constrain $ fpIsPoint a
                          constrain $ fpIsPoint (1/a)
-                         return $ a * (1/a) .== 1
+                         pure $ a * (1/a) .== 1
 
 -----------------------------------------------------------------------------
 -- * Effect of rounding modes
@@ -158,24 +158,25 @@
 -- >>> roundingAdd
 -- Satisfiable. Model:
 --   rm = RoundTowardPositive :: RoundingMode
---   x  =          -4.0039067 :: Float
---   y  =            131076.0 :: Float
+--   x  =       -2.341805e-38 :: Float
+--   y  =        -1.83671e-40 :: Float
 --
 -- (Note that depending on your version of Z3, you might get a different result.)
 -- Unfortunately Haskell floats do not allow computation with arbitrary rounding modes, but SBV's
 -- 'SFloatingPoint' type does. We have:
 --
--- >>> sat $ \x -> x .== (fpAdd sRoundTowardPositive (-4.0039067) 131076.0 :: SFloat)
+-- >>> sat $ \x -> x .== (fpAdd sRoundTowardPositive (-2.341805e-38) (-1.83671e-40) :: SFloat)
 -- Satisfiable. Model:
---   s0 = 131072.0 :: Float
--- >>> (-4.0039067) + 131076.0 :: Float
--- 131071.99
+--   s0 = -2.360172e-38 :: Float
+-- >>> (-2.360172e-38) + (-1.83671e-40 :: Float)
+-- -2.378539e-38
 --
 -- We can see why these two results are indeed different: The 'RoundTowardPositive
--- (which rounds towards positive infinity) produces a larger result.
+-- (which rounds towards positive infinity) produces a larger result. If we do the computation
+-- using double precision, we get:
 --
--- >>> (-4.0039067) + 131076.0 :: Double
--- 131071.9960933
+-- >>> (-2.360172e-38) + (-1.83671e-40 :: Double)
+-- -2.3785390999999997e-38
 --
 -- we see that the "more precise" result is larger than what the 'Float' value is, justifying the
 -- larger value with 'RoundTowardPositive. A more detailed study is beyond our current scope, so we'll
@@ -189,7 +190,7 @@
                        let rhs = x + y
                        constrain $ fpIsPoint lhs
                        constrain $ fpIsPoint rhs
-                       return $ lhs ./= rhs
+                       pure $ lhs ./= rhs
 
 -- | Arbitrary precision floating-point numbers. SBV can talk about floating point numbers with arbitrary
 -- exponent and significand sizes as well. Here is a simple example demonstrating the minimum non-zero positive
diff --git a/Documentation/SBV/Examples/Misc/LambdaArray.hs b/Documentation/SBV/Examples/Misc/LambdaArray.hs
--- a/Documentation/SBV/Examples/Misc/LambdaArray.hs
+++ b/Documentation/SBV/Examples/Misc/LambdaArray.hs
@@ -29,17 +29,17 @@
 -- Q.E.D.
 memsetExample :: IO ThmResult
 memsetExample = prove $ do
-   mem  <- sArray   "mem"
-   lo   <- sInteger "lo"
-   hi   <- sInteger "hi"
-   zero <- sInteger "zero"
+   mem   <- sArray   "mem"
+   lo    <- sInteger "lo"
+   hi    <- sInteger "hi"
+   zeroV <- sInteger "zero"
 
    -- Get an index within lo/hi
    idx  <- sInteger "idx"
    constrain $ idx .>= lo .&& idx .<= hi
 
    -- It must be the case that we get zero back after mem-setting
-   pure $ readArray (memset mem lo hi zero) idx .== zero
+   pure $ readArray (memset mem lo hi zeroV) idx .== zeroV
 
 -- | Get an example of reading a value out of range. The value returned should be out-of-range for lo/hi
 --
@@ -53,10 +53,10 @@
 --   Read =       1 :: Integer
 outOfInit :: IO SatResult
 outOfInit = sat $ do
-   mem  <- sArray "mem"
-   lo   <- sInteger "lo"
-   hi   <- sInteger "hi"
-   zero <- sInteger "zero"
+   mem   <- sArray "mem"
+   lo    <- sInteger "lo"
+   hi    <- sInteger "hi"
+   zeroV <- sInteger "zero"
 
    -- Get a meaningful range:
    constrain $ lo .<= hi
@@ -65,4 +65,6 @@
    idx  <- sInteger "idx"
 
    -- Let read produce non-zero
-   constrain $ observe "Read" (readArray (memset mem lo hi zero) idx) ./= zero
+   constrain $ observe "Read" (readArray (memset mem lo hi zeroV) idx) ./= zeroV
+
+{- HLint ignore module "Reduce duplication" -}
diff --git a/Documentation/SBV/Examples/Misc/ModelExtract.hs b/Documentation/SBV/Examples/Misc/ModelExtract.hs
--- a/Documentation/SBV/Examples/Misc/ModelExtract.hs
+++ b/Documentation/SBV/Examples/Misc/ModelExtract.hs
@@ -25,7 +25,7 @@
 outside disallow = sat $ do x <- sInteger "x"
                             let notEq i = constrain $ x ./= literal i
                             mapM_ notEq disallow
-                            return $ x .>= 0
+                            pure $ x .>= 0
 
 -- | We now use "outside" repeatedly to generate 10 integers, such that we not only disallow
 -- previously generated elements, but also any value that differs from previous solutions
@@ -37,7 +37,7 @@
 genVals :: IO [Integer]
 genVals = go [] []
   where go _ model
-         | length model >= 10 = return model
+         | length model >= 10 = pure model
         go disallow model
           = do res <- outside disallow
                -- Look up the value of "x" in the generated model
@@ -45,4 +45,4 @@
                -- SBV known type would be OK as well.
                case "x" `getModelValue` res of
                  Just c -> go ([c-4 .. c+4] ++ disallow) (c : model)
-                 _      -> return model
+                 _      -> pure model
diff --git a/Documentation/SBV/Examples/Misc/Newtypes.hs b/Documentation/SBV/Examples/Misc/Newtypes.hs
--- a/Documentation/SBV/Examples/Misc/Newtypes.hs
+++ b/Documentation/SBV/Examples/Misc/Newtypes.hs
@@ -94,4 +94,4 @@
     humanHeight :: SHumanHeightInCm <- free "humanheight"
     constrain $ humanHeight .== tallestHumanEver
 
-    return $ ceilingHighEnoughForHuman ceiling humanHeight
+    pure $ ceilingHighEnoughForHuman ceiling humanHeight
diff --git a/Documentation/SBV/Examples/Misc/ProgramPaths.hs b/Documentation/SBV/Examples/Misc/ProgramPaths.hs
--- a/Documentation/SBV/Examples/Misc/ProgramPaths.hs
+++ b/Documentation/SBV/Examples/Misc/ProgramPaths.hs
@@ -30,7 +30,7 @@
 d1 :: SInteger -> SInteger -> SInteger
 d1 x y = ite (y .< x - 2) 7 2
 
--- | Symbolic version of @d2 x y = if y > 3 then  10 else  50@
+-- | Symbolic version of @d2 y = if y > 3 then  10 else  50@
 d2 :: SInteger -> SInteger
 d2 y = ite (y .> 3) 10 50
 
diff --git a/Documentation/SBV/Examples/Misc/SetAlgebra.hs b/Documentation/SBV/Examples/Misc/SetAlgebra.hs
--- a/Documentation/SBV/Examples/Misc/SetAlgebra.hs
+++ b/Documentation/SBV/Examples/Misc/SetAlgebra.hs
@@ -359,6 +359,6 @@
 >>> prove $ \(a :: SI) b c -> (b `intersection` c) `isSubsetOf` a .=> b `isSubsetOf` a .&& c `isSubsetOf` a
 Falsifiable. Counter-example:
   s0 = U - {2} :: {Integer}
-  s1 =      {} :: {Integer}
+  s1 = U - {2} :: {Integer}
   s2 =     {2} :: {Integer}
 -}
diff --git a/Documentation/SBV/Examples/Misc/SoftConstrain.hs b/Documentation/SBV/Examples/Misc/SoftConstrain.hs
--- a/Documentation/SBV/Examples/Misc/SoftConstrain.hs
+++ b/Documentation/SBV/Examples/Misc/SoftConstrain.hs
@@ -44,4 +44,4 @@
                    softConstrain $ x .== "default-x-value"
                    softConstrain $ y .== "default-y-value"
 
-                   return sTrue
+                   pure sTrue
diff --git a/Documentation/SBV/Examples/Optimization/Enumerate.hs b/Documentation/SBV/Examples/Optimization/Enumerate.hs
--- a/Documentation/SBV/Examples/Optimization/Enumerate.hs
+++ b/Documentation/SBV/Examples/Optimization/Enumerate.hs
@@ -10,13 +10,10 @@
 -- by properly defining your metric values.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DeriveAnyClass      #-}
-{-# LANGUAGE DeriveDataTypeable  #-}
-{-# LANGUAGE FlexibleInstances   #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE StandaloneDeriving  #-}
-{-# LANGUAGE TemplateHaskell     #-}
-{-# LANGUAGE TypeFamilies        #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE TypeApplications  #-}
+{-# LANGUAGE TypeFamilies      #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -26,10 +23,9 @@
 
 -- | A simple enumeration
 data Day = Mon | Tue | Wed | Thu | Fri | Sat | Sun
-         deriving (Enum, Bounded)
 
 -- | Make 'Day' a symbolic value.
-mkSymbolicEnumeration ''Day
+mkSymbolic [''Day]
 
 -- | Make day an optimizable value, by mapping it to 'Word8' in the most
 -- obvious way. We can map it to any value the underlying solver can optimize,
diff --git a/Documentation/SBV/Examples/Optimization/ExtField.hs b/Documentation/SBV/Examples/Optimization/ExtField.hs
--- a/Documentation/SBV/Examples/Optimization/ExtField.hs
+++ b/Documentation/SBV/Examples/Optimization/ExtField.hs
@@ -10,6 +10,7 @@
 -----------------------------------------------------------------------------
 
 {-# LANGUAGE CPP #-}
+
 {-# OPTIONS_GHC -Wall -Werror #-}
 
 module Documentation.SBV.Examples.Optimization.ExtField where
diff --git a/Documentation/SBV/Examples/ProofTools/BMC.hs b/Documentation/SBV/Examples/ProofTools/BMC.hs
--- a/Documentation/SBV/Examples/ProofTools/BMC.hs
+++ b/Documentation/SBV/Examples/ProofTools/BMC.hs
@@ -59,7 +59,7 @@
         -- calls to 'Data.SBV.setOption'. We do not need any for this problem,
         -- so we simply do nothing.
         setup :: Symbolic ()
-        setup = return ()
+        setup = pure ()
 
         -- Transition relation: At each step we either
         -- get to increase @x@ by 2, or decrement @y@ by 4:
diff --git a/Documentation/SBV/Examples/ProofTools/Strengthen.hs b/Documentation/SBV/Examples/ProofTools/Strengthen.hs
--- a/Documentation/SBV/Examples/ProofTools/Strengthen.hs
+++ b/Documentation/SBV/Examples/ProofTools/Strengthen.hs
@@ -22,7 +22,7 @@
 -- Where @*@ stands for non-deterministic choice. For each program we try to prove that @y >= 1@ is an invariant.
 --
 -- It turns out that the property @y >= 1@ is indeed an invariant, but is
--- not inductive for either program. We proceed to strengten the invariant
+-- not inductive for either program. We proceed to strengthen the invariant
 -- and establish it for the first case. We then note that the same strengthening
 -- doesn't work for the second program, and find a further strengthening to
 -- establish that case as well. This example follows the introductory example
@@ -68,7 +68,7 @@
         -- calls to 'Data.SBV.setOption'. We do not need any for this problem,
         -- so we simply do nothing.
         setup :: Symbolic ()
-        setup = return ()
+        setup = pure ()
 
         -- Initially, @x@ and @y@ are both @1@
         initial :: S SInteger -> SBool
diff --git a/Documentation/SBV/Examples/ProofTools/Sum.hs b/Documentation/SBV/Examples/ProofTools/Sum.hs
--- a/Documentation/SBV/Examples/ProofTools/Sum.hs
+++ b/Documentation/SBV/Examples/ProofTools/Sum.hs
@@ -60,7 +60,7 @@
         -- calls to 'Data.SBV.setOption'. We do not need any for this problem,
         -- so we simply do nothing.
         setup :: Symbolic ()
-        setup = return ()
+        setup = pure ()
 
         -- Initially, @s@ and @i@ are both @0@. We also require @n@ to be at least @0@.
         initial :: S SInteger -> SBool
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
@@ -12,7 +12,7 @@
 -- computer with 4 integer registers (w, x, y, z), and 6 instructions (inp, add, mul, div, mod, eql).
 -- You are given a program (hilariously called "monad"), and your goal is to figure out what
 -- the maximum and minimum inputs you can provide to this program such that when it runs
--- register z ends up with the value 1. Please refer to the above link for the full description.
+-- register z ends up with the value 0. Please refer to the above link for the full description.
 --
 -- While there are multiple ways to solve this problem in SBV, the solution here demonstrates
 -- how to turn programs in this fictional language into actual Haskell/SBV programs, i.e.,
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
@@ -35,11 +35,9 @@
 -- NB. Thanks to Amit Goel for suggesting the formalization strategy used in here.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DeriveAnyClass      #-}
-{-# LANGUAGE DeriveDataTypeable  #-}
-{-# LANGUAGE FlexibleInstances   #-}
-{-# LANGUAGE StandaloneDeriving  #-}
-{-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE TypeApplications  #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -53,14 +51,12 @@
 
 -- | Months. We only put in the months involved in the puzzle for simplicity
 data Month = May | Jun | Jul | Aug
-           deriving (Enum, Bounded)
 
 -- | Days. Again, only the ones mentioned in the puzzle.
 data Day = D14 | D15 | D16 | D17 | D18 | D19
-         deriving (Enum, Bounded)
 
-mkSymbolicEnumeration ''Month
-mkSymbolicEnumeration ''Day
+mkSymbolic [''Month]
+mkSymbolic [''Day]
 
 -- | Represent the birthday as a record
 data Birthday = BD SMonth SDay
diff --git a/Documentation/SBV/Examples/Puzzles/Coins.hs b/Documentation/SBV/Examples/Puzzles/Coins.hs
--- a/Documentation/SBV/Examples/Puzzles/Coins.hs
+++ b/Documentation/SBV/Examples/Puzzles/Coins.hs
@@ -44,7 +44,7 @@
 mkCoin :: Int -> Symbolic Coin
 mkCoin i = do c <- free $ 'c' : show i
               constrain $ sAny (.== c) [1, 5, 10, 25, 50, 100]
-              return c
+              pure c
 
 -- | Return all combinations of a sequence of values.
 combinations :: [a] -> [[a]]
@@ -105,4 +105,4 @@
         constrain $ sAnd $ zipWith (.>=) cs (drop 1 cs)
 
         -- assert that the sum must be 115 cents.
-        return $ sum cs .== 115
+        pure $ sum cs .== 115
diff --git a/Documentation/SBV/Examples/Puzzles/DieHard.hs b/Documentation/SBV/Examples/Puzzles/DieHard.hs
--- a/Documentation/SBV/Examples/Puzzles/DieHard.hs
+++ b/Documentation/SBV/Examples/Puzzles/DieHard.hs
@@ -11,14 +11,12 @@
 -- We use a bounded-model-checking style search to find a solution.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DeriveAnyClass        #-}
-{-# LANGUAGE DeriveDataTypeable    #-}
 {-# LANGUAGE FlexibleInstances     #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE NamedFieldPuns        #-}
-{-# LANGUAGE StandaloneDeriving    #-}
 {-# LANGUAGE OverloadedRecordDot   #-}
 {-# LANGUAGE TemplateHaskell       #-}
+{-# LANGUAGE TypeApplications      #-}
 {-# LANGUAGE TypeFamilies          #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
@@ -30,9 +28,9 @@
 
 -- | Possible actions
 data Action = Initial | FillBig | FillSmall | EmptyBig | EmptySmall | BigToSmall | SmallToBig
-            deriving (Enum, Bounded)
+             deriving Show
 
-mkSymbolicEnumeration ''Action
+mkSymbolic [''Action]
 
 -- | We represent the state with two quantities, the amount of water in each jug. The
 -- action is how we got into this state.
diff --git a/Documentation/SBV/Examples/Puzzles/Drinker.hs b/Documentation/SBV/Examples/Puzzles/Drinker.hs
--- a/Documentation/SBV/Examples/Puzzles/Drinker.hs
+++ b/Documentation/SBV/Examples/Puzzles/Drinker.hs
@@ -16,10 +16,7 @@
 -- @
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DeriveAnyClass     #-}
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE StandaloneDeriving #-}
-{-# LANGUAGE TemplateHaskell    #-}
+{-# LANGUAGE TemplateHaskell #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -31,7 +28,7 @@
 data P
 
 -- | Make 'P' an uninterpreted sort, introducing the type 'SP' for its symbolic version
-mkUninterpretedSort ''P
+mkSymbolic [''P]
 
 -- | Declare the uninterpret function 'd', standing for drinking. For each person, this function
 -- assigns whether they are drinking; but is otherwise completely uninterpreted. (i.e., our theorem
diff --git a/Documentation/SBV/Examples/Puzzles/Euler185.hs b/Documentation/SBV/Examples/Puzzles/Euler185.hs
--- a/Documentation/SBV/Examples/Puzzles/Euler185.hs
+++ b/Documentation/SBV/Examples/Puzzles/Euler185.hs
@@ -34,7 +34,7 @@
 -- number of matching digits match what's given in the problem statement.
 euler185 :: Symbolic SBool
 euler185 = do soln <- mkFreeVars 16
-              return $ sAll digit soln .&& sAnd (map (genConstr soln) guesses)
+              pure $ sAll digit soln .&& sAnd (map (genConstr soln) guesses)
   where genConstr a (b, c) = sum (zipWith eq a b) .== (c :: SWord8)
         digit x = (x :: SWord8) .>= 0 .&& x .<= 9
         eq x y =  ite (x .== fromIntegral (ord y - ord '0')) 1 0
diff --git a/Documentation/SBV/Examples/Puzzles/Fish.hs b/Documentation/SBV/Examples/Puzzles/Fish.hs
--- a/Documentation/SBV/Examples/Puzzles/Fish.hs
+++ b/Documentation/SBV/Examples/Puzzles/Fish.hs
@@ -27,53 +27,47 @@
 -- Who owns the fish?
 ------------------------------------------------------------------------------
 
-{-# OPTIONS_GHC -Wall -Werror #-}
-
-{-# LANGUAGE DeriveAnyClass      #-}
-{-# LANGUAGE DeriveDataTypeable  #-}
 {-# LANGUAGE FlexibleInstances   #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE StandaloneDeriving  #-}
 {-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE TypeApplications    #-}
 
+{-# OPTIONS_GHC -Wall -Werror #-}
+
 module Documentation.SBV.Examples.Puzzles.Fish where
 
 import Data.SBV
 
 -- | Colors of houses
 data Color = Red | Green | White | Yellow | Blue
-           deriving (Enum, Bounded)
 
 -- | Make 'Color' a symbolic value.
-mkSymbolicEnumeration ''Color
+mkSymbolic [''Color]
 
 -- | Nationalities of the occupants
 data Nationality = Briton | Dane | Swede | Norwegian | German
-                 deriving (Enum, Bounded)
+                 deriving Show
 
 -- | Make 'Nationality' a symbolic value.
-mkSymbolicEnumeration ''Nationality
+mkSymbolic [''Nationality]
 
 -- | Beverage choices
 data Beverage = Tea | Coffee | Milk | Beer | Water
-              deriving (Enum, Bounded)
 
 -- | Make 'Beverage' a symbolic value.
-mkSymbolicEnumeration ''Beverage
+mkSymbolic [''Beverage]
 
 -- | Pets they keep
 data Pet = Dog | Horse | Cat | Bird | Fish
-         deriving (Enum, Bounded)
 
 -- | Make 'Pet' a symbolic value.
-mkSymbolicEnumeration ''Pet
+mkSymbolic [''Pet]
 
 -- | Sports they engage in
 data Sport = Football | Baseball | Volleyball | Hockey | Tennis
-           deriving (Enum, Bounded)
 
 -- | Make 'Sport' a symbolic value.
-mkSymbolicEnumeration ''Sport
+mkSymbolic [''Sport]
 
 -- | We have:
 --
diff --git a/Documentation/SBV/Examples/Puzzles/Garden.hs b/Documentation/SBV/Examples/Puzzles/Garden.hs
--- a/Documentation/SBV/Examples/Puzzles/Garden.hs
+++ b/Documentation/SBV/Examples/Puzzles/Garden.hs
@@ -28,12 +28,9 @@
 -- case, the second student would be right.
 ------------------------------------------------------------------------------
 
-{-# LANGUAGE DeriveAnyClass      #-}
-{-# LANGUAGE DeriveDataTypeable  #-}
-{-# LANGUAGE FlexibleInstances   #-}
-{-# LANGUAGE OverloadedStrings   #-}
-{-# LANGUAGE StandaloneDeriving  #-}
-{-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE FlexibleInstances  #-}
+{-# LANGUAGE TemplateHaskell    #-}
+{-# LANGUAGE TypeApplications   #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -43,10 +40,9 @@
 
 -- | Colors of the flowers
 data Color = Red | Yellow | Blue
-          deriving (Enum, Bounded)
 
 -- | Make 'Color' a symbolic value.
-mkSymbolicEnumeration ''Color
+mkSymbolic [''Color]
 
 -- | Represent flowers by symbolic integers
 type Flower = SInteger
diff --git a/Documentation/SBV/Examples/Puzzles/HexPuzzle.hs b/Documentation/SBV/Examples/Puzzles/HexPuzzle.hs
--- a/Documentation/SBV/Examples/Puzzles/HexPuzzle.hs
+++ b/Documentation/SBV/Examples/Puzzles/HexPuzzle.hs
@@ -36,13 +36,9 @@
 -- to the final one.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DeriveAnyClass      #-}
-{-# LANGUAGE DeriveDataTypeable  #-}
-{-# LANGUAGE FlexibleInstances   #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE StandaloneDeriving  #-}
-{-# LANGUAGE TemplateHaskell     #-}
-{-# LANGUAGE TypeApplications    #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE TypeApplications  #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -51,14 +47,11 @@
 import Data.SBV
 import Data.SBV.Control
 
-import Data.Proxy
-
 -- | Colors we're allowed
 data Color = Black | Blue | Green | Red
-          deriving (Enum, Bounded)
 
 -- | Make 'Color' a symbolic value.
-mkSymbolicEnumeration ''Color
+mkSymbolic [''Color]
 
 -- | Use 8-bit words for button numbers, even though we only have 1 to 19.
 type Button  = Word8
@@ -88,8 +81,7 @@
 -- | Iteratively search at increasing depths of button-presses to see if we can
 -- transform from the initial board position to a final board position.
 search :: [Color] -> [Color] -> IO ()
-search initial final = runSMT $ do registerType (Proxy @SColor)
-                                   let emptyGrid = lambdaArray (const sBlack)
+search initial final = runSMT $ do let emptyGrid = constArray sBlack
                                        initGrid  = foldr (\(i, c) a -> writeArray a (literal i) (literal c)) emptyGrid (zip [1..] initial)
                                    query $ loop (0 :: Int) initGrid []
 
@@ -136,8 +128,8 @@
 -- Searching at depth: 4
 -- Searching at depth: 5
 -- Searching at depth: 6
--- Found: [10,10,9,11,14,6]
 -- Found: [10,10,11,9,14,6]
+-- Found: [10,10,9,11,14,6]
 -- There are no more solutions.
 example :: IO ()
 example = search initBoard finalBoard
diff --git a/Documentation/SBV/Examples/Puzzles/KnightsAndKnaves.hs b/Documentation/SBV/Examples/Puzzles/KnightsAndKnaves.hs
--- a/Documentation/SBV/Examples/Puzzles/KnightsAndKnaves.hs
+++ b/Documentation/SBV/Examples/Puzzles/KnightsAndKnaves.hs
@@ -12,11 +12,9 @@
 -- Determine which one is a knave or a knight, depending on their answers.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DeriveAnyClass     #-}
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE FlexibleInstances  #-}
-{-# LANGUAGE StandaloneDeriving #-}
-{-# LANGUAGE TemplateHaskell    #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE TypeApplications  #-}
 
 module Documentation.SBV.Examples.Puzzles.KnightsAndKnaves where
 
@@ -27,19 +25,17 @@
 
 -- | Inhabitants of the island, as an uninterpreted sort
 data Inhabitant
-mkUninterpretedSort ''Inhabitant
+mkSymbolic [''Inhabitant]
 
 -- | Each inhabitant is either a knave or a knight
 data Identity = Knave | Knight
-              deriving (Enum, Bounded)
 
-mkSymbolicEnumeration ''Identity
+mkSymbolic [''Identity]
 
 -- | Statements are utterances which are either true or false
 data Statement = Truth | Falsity
-               deriving (Enum, Bounded)
 
-mkSymbolicEnumeration ''Statement
+mkSymbolic [''Statement]
 
 -- | John is an inhabitant of the island.
 john :: SInhabitant
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
@@ -20,12 +20,10 @@
 -- @
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DeriveAnyClass     #-}
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE FlexibleInstances  #-}
-{-# LANGUAGE NamedFieldPuns     #-}
-{-# LANGUAGE StandaloneDeriving #-}
-{-# LANGUAGE TemplateHaskell    #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE NamedFieldPuns    #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE TypeApplications  #-}
 
 {-# OPTIONS_GHC -Wall -Werror   #-}
 
@@ -39,19 +37,19 @@
 
 -- | Locations
 data Location = Bar | Beach | Alone
-              deriving (Enum, Bounded)
+              deriving Show
 
 -- | Sexes
-data Sex  = Male | Female
-          deriving (Enum, Bounded)
+data Sex = Male | Female
+         deriving Show
 
 -- | Roles
 data Role = Victim | Killer | Bystander
-          deriving (Enum, Bounded)
+          deriving Show
 
-mkSymbolicEnumeration ''Location
-mkSymbolicEnumeration ''Sex
-mkSymbolicEnumeration ''Role
+mkSymbolic [''Location]
+mkSymbolic [''Sex]
+mkSymbolic [''Role]
 
 -- | A person has a name, age, together with location and sex.
 -- We parameterize over a function so we can use this struct
@@ -89,10 +87,10 @@
 -- | Solve the puzzle. We have:
 --
 -- >>> killer
--- Alice     47  Bar    Female  Bystander
--- Husband   46  Beach  Male    Killer
--- Brother   47  Beach  Male    Victim
--- Daughter  20  Alone  Female  Bystander
+-- Alice     48  Bar    Female  Bystander
+-- Husband   47  Beach  Male    Killer
+-- Brother   48  Beach  Male    Victim
+-- 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.
diff --git a/Documentation/SBV/Examples/Puzzles/Newspaper.hs b/Documentation/SBV/Examples/Puzzles/Newspaper.hs
--- a/Documentation/SBV/Examples/Puzzles/Newspaper.hs
+++ b/Documentation/SBV/Examples/Puzzles/Newspaper.hs
@@ -6,7 +6,7 @@
 -- Maintainer: erkokl@gmail.com
 -- Stability : experimental
 --
--- Solution to the following puzzle (found at <http://hugopeters.me/posts/15>)
+-- Solution to the following puzzle (found at <https://hugopeters.me/posts/15>)
 -- which contains 10 questions:
 --
 -- @
diff --git a/Documentation/SBV/Examples/Puzzles/Orangutans.hs b/Documentation/SBV/Examples/Puzzles/Orangutans.hs
--- a/Documentation/SBV/Examples/Puzzles/Orangutans.hs
+++ b/Documentation/SBV/Examples/Puzzles/Orangutans.hs
@@ -11,12 +11,11 @@
 
 {-# LANGUAGE CPP                 #-}
 {-# LANGUAGE DeriveAnyClass      #-}
-{-# LANGUAGE DeriveDataTypeable  #-}
 {-# LANGUAGE DeriveGeneric       #-}
 {-# LANGUAGE FlexibleContexts    #-}
 {-# LANGUAGE FlexibleInstances   #-}
 {-# LANGUAGE TemplateHaskell     #-}
-{-# LANGUAGE StandaloneDeriving  #-}
+{-# LANGUAGE TypeApplications    #-}
 {-# LANGUAGE OverloadedRecordDot #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
@@ -33,19 +32,17 @@
 
 -- | Orangutans in the puzzle.
 data Orangutan = Merah | Ofallo | Quirrel | Shamir
-               deriving (Enum, Bounded)
+               deriving (Show, Enum, Bounded)
 
 -- | Handlers for each orangutan.
 data Handler = Dolly | Eva | Francine | Gracie
-             deriving (Enum, Bounded)
 
 -- | Location for each orangutan.
 data Location = Ambalat | Basahan | Kendisi | Tarakan
-             deriving (Enum, Bounded)
 
-mkSymbolicEnumeration ''Orangutan
-mkSymbolicEnumeration ''Handler
-mkSymbolicEnumeration ''Location
+mkSymbolic [''Orangutan]
+mkSymbolic [''Handler]
+mkSymbolic [''Location]
 
 -- | An assignment is solution to the puzzle
 data Assignment = MkAssignment { orangutan :: SOrangutan
diff --git a/Documentation/SBV/Examples/Puzzles/Rabbits.hs b/Documentation/SBV/Examples/Puzzles/Rabbits.hs
--- a/Documentation/SBV/Examples/Puzzles/Rabbits.hs
+++ b/Documentation/SBV/Examples/Puzzles/Rabbits.hs
@@ -15,11 +15,9 @@
 -- What's implicit here is that there is a rabbit that must be not-greedy;
 -- which we add to our constraints.
 -----------------------------------------------------------------------------
-{-# LANGUAGE DeriveAnyClass     #-}
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE StandaloneDeriving #-}
-{-# LANGUAGE TemplateHaskell    #-}
 
+{-# LANGUAGE TemplateHaskell #-}
+
 {-# OPTIONS_GHC -Wall -Werror #-}
 
 module Documentation.SBV.Examples.Puzzles.Rabbits where
@@ -30,7 +28,7 @@
 data Rabbit
 
 -- | Make rabbits symbolically available.
-mkUninterpretedSort ''Rabbit
+mkSymbolic [''Rabbit]
 
 -- | Identify those rabbits that are greedy. Note that we leave the predicate uninterpreted.
 greedy :: SRabbit -> SBool
diff --git a/Documentation/SBV/Examples/Puzzles/SquareBirthday.hs b/Documentation/SBV/Examples/Puzzles/SquareBirthday.hs
new file mode 100644
--- /dev/null
+++ b/Documentation/SBV/Examples/Puzzles/SquareBirthday.hs
@@ -0,0 +1,199 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Documentation.SBV.Examples.Puzzles.SquareBirthday
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- @
+-- Suppose that today is June 1, 2025. We call a date "square" if all of its components (day, month, and year) are
+-- perfect squares. I was born in the last millennium, and my next birthday (relative to that date) will be the last
+-- square date in my life. If you sum the square roots of the components of that upcoming square birthday
+-- (day, month, year), you obtain my age on June 1, 2025. My mother would have been born on a square date if the month
+-- were a square number; in reality it is not a square date, but both the month and day are perfect cubes. When was
+-- I born, and when was my mother born?
+-- @
+--
+-- So, let's solve it using SBV.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE FlexibleInstances   #-}
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE TypeApplications    #-}
+{-# LANGUAGE TypeFamilies        #-}
+{-# LANGUAGE OverloadedRecordDot #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Documentation.SBV.Examples.Puzzles.SquareBirthday where
+
+import Prelude hiding (fromEnum, toEnum)
+
+import Data.SBV
+import Data.SBV.Control
+
+import qualified Data.SBV.List  as SL
+import qualified Data.SBV.Tuple as ST
+
+-- | Months in a year.
+data Month = Jan | Feb | Mar | Apr | May | Jun
+           | Jul | Aug | Sep | Oct | Nov | Dec
+           deriving Show
+
+-- | A date. We use unbounded integers for day and year, which simplifies coding,
+-- though one can also enumerate the possible values from the problem itself.
+data Date = MkDate { day   :: Integer
+                   , month :: Month
+                   , year  :: Integer
+                   }
+
+-- | Make 'Month' and 'Date' usable in symbolic contexts.
+mkSymbolic [''Month, ''Date]
+
+-- | Show instance for date, for pretty-printing.
+instance Show Date where
+  show (MkDate d m y) = show m ++ " " ++ pad ++ show d ++ ", " ++ show y
+   where pad | d < 10 = " "
+             | True   = ""
+
+-- | Get a symbolic date with the given name. Since we used
+-- integers for the day and year fields, we constrain them
+-- appropriately. Note that one can further constrain days
+-- based on the year and month; but that level detail isn't
+-- necessary for the current problem.
+symDate :: String -> Symbolic SDate
+symDate nm = do dt <- free nm
+
+                constrain [sCase| dt of
+                              MkDate d _ y -> sAnd [ 1 .<= d, d .<= 31
+                                                   , 0 .<= y
+                                                   ]
+                          |]
+
+                pure dt
+
+-- | Encode today as a symbolic value. The puzzle says today is June 1st, 2025.
+today :: SDate
+today = literal $ MkDate { day   =    1
+                         , month =  Jun
+                         , year  = 2025
+                         }
+
+-- | A date is on or after another, if the month-day combo is
+-- lexicographically later. Note that we ignore the year for this
+-- comparison, as we're interested if the anniversary of a date is after or not.
+onOrAfter :: SDate -> SDate -> SBool
+d1 `onOrAfter` d2 = (smonth d1, sday d1) .>= (smonth d2, sday d2)
+
+-- | Similar to 'onOrAfter', except we require strictly later.
+after :: SDate -> SDate -> SBool
+d1 `after` d2 = (smonth d1, sday d1) .>  (smonth d2, sday d2)
+
+-- | The age based on a given date is the difference between years less than one.
+-- We have to adjust by 1 if today happens to be after the given date.
+age :: SDate -> SInteger
+age d = syear today - syear d - 1 + oneIf (today `after` d)
+
+-- | We can let years to range over arbitrary integers. But that complicates the
+-- job of the solver. So, based on what we know from the problem, we restrict
+-- our attention to years between 1900 and 2100. Note that there are only
+-- two years that satisfy this in that range: 1936 and 2025. (Any other square
+-- year makes no sense for the setting of the problem.) To simplify the square-root
+-- computation, we also store the square root in this list as the second component:
+--
+-- >>> squareYears
+-- [(1936,44),(2025,45)]
+squareYears :: [(Integer, Integer)]
+squareYears = takeWhile (\(y, _) -> y < 2100)
+            $ dropWhile (\(y, _) -> y < 1900)
+            $ [(i * i, i) | i <- [1::Integer ..]]
+
+-- | A date is square if all its components are.
+squareDate :: SDate -> SBool
+squareDate dt = [sCase| dt of
+                   MkDate d m y -> squareDay d .&& squareMonth m .&& squareYear y
+                |]
+  where squareDay   d = d `sElem` [1, 4, 9, 16, 25]
+        squareMonth m = m `sElem` [sJan, sApr, sSep]
+        squareYear  y = y `sElem` map (literal . fst) squareYears
+
+
+-- | Summing the square-roots of the components of a date.
+sqrSum :: SDate -> SInteger
+sqrSum dt = [sCase| dt of
+               MkDate d m y -> r d + mr m + r y
+            |]
+ where r v  = v `SL.lookup` literal ([(i * i, i) | i <- [1, 2, 3, 4, 5]] ++ squareYears)
+
+       mr :: SMonth -> SInteger
+       mr m = [sCase| m of
+                  Jan -> 1
+                  Apr -> 2
+                  Sep -> 3
+                  _   -> some "Non-Square Month" (const sTrue)
+              |]
+
+-- | Formalizing the puzzle. We literally write down the description in
+-- SBV notation. As with any formalization, this step is subjective; there
+-- could be many different ways to express the same problem. The description
+-- below is quite faithful to the problem description given. We have:
+--
+-- >>> puzzle
+-- Me : Sep 25, 1971
+-- Mom: Aug  1, 1936
+puzzle :: IO ()
+puzzle = runSMT $ do
+
+    -----------------------------------
+    -- Constraints about my birthday
+    -----------------------------------
+    myBirthday <- symDate "My Birthday"
+
+    -- I was born in the last millennium
+    constrain $ syear myBirthday .< 2000 .&& syear myBirthday .>= 1900
+
+    -- My next birthday will be a square
+    let next = [sCase| myBirthday of
+                  MkDate d m _ -> sMkDate d m (syear today + oneIf (today `onOrAfter` myBirthday))
+               |]
+
+    constrain $ squareDate next
+
+    -- And it'll be the last square day of my life, so we maximize the metric corresponding to the
+    -- date. We turn it into a 3-tuple of year, month, date over integers, which preserves the
+    -- order of the dates.
+    maximize "Next Birthday Latest" $ ST.tuple (syear next, fromEnum (smonth next), sday next)
+
+    -- If you square the components of my next birthday, it gives me my current age on Jun 1, 2025
+    constrain $ sqrSum next .== age myBirthday
+
+    -----------------------------------
+    -- Constraints about mom's birthday
+    -----------------------------------
+    momBirthday <- symDate "Mom's Birthday"
+
+    -- Mom has a square birth-date, except for the month:
+    constrain [sCase| momBirthday of
+                 MkDate d _ y -> squareDate (sMkDate d sJan y)
+              |]
+
+    -- Mom's day and month are perfect cubes
+    constrain [sCase| momBirthday of
+                 MkDate d m _ -> sAnd [ d `sElem` [1, 8, 27]
+                                      , m `sElem` [sJan, sAug]
+                                      ]
+              |]
+
+    -- Extract the results:
+    query $ do cs <- checkSat
+               case cs of
+                 Sat -> do me  <- getValue myBirthday
+                           mom <- getValue momBirthday
+
+                           io $ do putStrLn $ "Me : " ++ show me
+                                   putStrLn $ "Mom: " ++ show mom
+
+                 _   -> error $ "Unexpected result: " ++ show cs
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
@@ -9,16 +9,13 @@
 -- The Sudoku solver, quintessential SMT solver example!
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE CPP              #-}
 {-# LANGUAGE FlexibleContexts #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
 module Documentation.SBV.Examples.Puzzles.Sudoku where
 
-#if MIN_VERSION_base(4,18,0)
 import Control.Monad (when, zipWithM_)
-#endif
 
 import Control.Monad.State.Lazy
 
diff --git a/Documentation/SBV/Examples/Puzzles/Tower.hs b/Documentation/SBV/Examples/Puzzles/Tower.hs
--- a/Documentation/SBV/Examples/Puzzles/Tower.hs
+++ b/Documentation/SBV/Examples/Puzzles/Tower.hs
@@ -110,7 +110,7 @@
 -- * Example run
 -------------------------------------------------------------------
 
--- | Solve the puzzle descibed above. We get:
+-- | Solve the puzzle described above. We get:
 --
 -- >>> example
 --   1 2 3 2 2 4
diff --git a/Documentation/SBV/Examples/Puzzles/U2Bridge.hs b/Documentation/SBV/Examples/Puzzles/U2Bridge.hs
--- a/Documentation/SBV/Examples/Puzzles/U2Bridge.hs
+++ b/Documentation/SBV/Examples/Puzzles/U2Bridge.hs
@@ -9,14 +9,13 @@
 -- The famous U2 bridge crossing puzzle: <http://www.braingle.com/brainteasers/515/u2.html>
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DeriveAnyClass       #-}
-{-# LANGUAGE DeriveDataTypeable   #-}
-{-# LANGUAGE DeriveGeneric        #-}
-{-# LANGUAGE FlexibleInstances    #-}
-{-# LANGUAGE StandaloneDeriving   #-}
-{-# LANGUAGE TemplateHaskell      #-}
+{-# LANGUAGE DeriveAnyClass    #-}
+{-# LANGUAGE DeriveGeneric     #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE TypeApplications  #-}
 
-{-# OPTIONS_GHC -Wall -Werror -Wno-incomplete-uni-patterns #-}
+{-# OPTIONS_GHC -Wall -Werror #-}
 
 module Documentation.SBV.Examples.Puzzles.U2Bridge where
 
@@ -33,13 +32,12 @@
 -- * Modeling the puzzle
 -------------------------------------------------------------
 
--- | U2 band members. We want to translate this to SMT-Lib as a data-type, and hence the
--- call to mkSymbolicEnumeration.
+-- | U2 band members.
 data U2Member = Bono | Edge | Adam | Larry
-              deriving (Enum, Bounded, Eq, Ord)
+              deriving Show
 
 -- | Make 'U2Member' a symbolic value.
-mkSymbolicEnumeration ''U2Member
+mkSymbolic [''U2Member]
 
 -- | Model time using 32 bits
 type Time  = Word32
@@ -63,10 +61,10 @@
 
 -- | Location of the flash
 data Location = Here | There
-              deriving (Enum, Bounded)
+              deriving (Eq, Show, Enum, Bounded)
 
 -- | Make 'Location' a symbolic value.
-mkSymbolicEnumeration ''Location
+mkSymbolic [''Location]
 
 -- | The status of the puzzle after each move
 --
@@ -116,7 +114,7 @@
          let (ar, s1) = runState a s
              (br, s2) = runState b s
          put $ symbolicMerge f t s1 s2
-         return $ symbolicMerge f t ar br
+         pure $ symbolicMerge f t ar br
 
 -- | Read the state via an accessor function
 peek :: (Status -> a) -> Move a
@@ -135,7 +133,10 @@
 
 -- | Transferring a person to the other side
 xferPerson :: SU2Member -> Move ()
-xferPerson p =  do ~[lb, le, la, ll] <- mapM peek [lBono, lEdge, lAdam, lLarry]
+xferPerson p =  do lb <- peek lBono
+                   le <- peek lEdge
+                   la <- peek lAdam
+                   ll <- peek lLarry
                    let move l = ite (l .== sHere) sThere sHere
                        lb' = ite (p .== sBono)  (move lb) lb
                        le' = ite (p .== sEdge)  (move le) le
@@ -153,7 +154,7 @@
 
 -- | Symbolic version of 'Control.Monad.when'
 whenS :: SBool -> Move () -> Move ()
-whenS t a = ite t a (return ())
+whenS t a = ite t a (pure ())
 
 -- | Move one member, remembering to take the flash
 move1 :: SU2Member -> Move ()
@@ -197,9 +198,12 @@
 -- | Check if a given sequence of actions is valid, i.e., they must all
 -- cross the bridge according to the rules and in less than 17 seconds
 isValid :: Actions -> SBool
-isValid as = time end .<= 17 .&& sAll check as .&& zigZag (cycle [sThere, sHere]) (map flash states) .&& sAll (.== sThere) [lBono end, lEdge end, lAdam end, lLarry end]
-  where check (s, p1, p2) =   (sNot s .=> p1 .> p2)       -- for two person moves, ensure first person is "larger"
-                          .&& (s      .=> p2 .== sBono)   -- for one person moves, ensure second person is always "bono"
+isValid as =   time end .<= 17
+           .&& sAll check as
+           .&& zigZag (cycle [sThere, sHere]) (map flash states)
+           .&& sAll (.== sThere) [lBono end, lEdge end, lAdam end, lLarry end]
+  where check (s, p1, p2) =   (sNot s .=> p1 .>  p2)    -- for two person moves, ensure first person is "larger"
+                          .&& (s      .=> p2 .== sBono) -- for one person moves, ensure second person is always "bono"
         states = evalState (run as) start
         end = last states
         zigZag reqs locs = sAnd $ zipWith (.==) locs reqs
@@ -214,19 +218,19 @@
               let genAct = do b  <- free_
                               p1 <- free_
                               p2 <- free_
-                              return (b, p1, p2)
+                              pure (b, p1, p2)
               res <- allSat $ isValid `fmap` mapM (const genAct) [1..n]
               cnt <- displayModels (sortOn show) disp res
-              if cnt == 0 then return False
+              if cnt == 0 then pure False
                           else do putStrLn $ "Found: " ++ show cnt ++ " solution" ++ plu cnt ++ " with " ++ show n ++ " move" ++ plu n ++ "."
-                                  return True
+                                  pure True
   where plu v = if v == 1 then "" else "s"
         disp :: Int -> (Bool, [(Bool, U2Member, U2Member)]) -> IO ()
         disp i (_, ss)
          | lss /= n = error $ "Expected " ++ show n ++ " results; got: " ++ show lss
          | True     = do putStrLn $ "Solution #" ++ show i ++ ":"
                          go False 0 ss
-                         return ()
+                         pure ()
          where lss  = length ss
                go _ t []                   = putStrLn $ "Total time: " ++ show t
                go l t ((True,  a, _):rest) = do putStrLn $ sh2 t ++ shL l ++ show a
diff --git a/Documentation/SBV/Examples/Queries/Abducts.hs b/Documentation/SBV/Examples/Queries/Abducts.hs
--- a/Documentation/SBV/Examples/Queries/Abducts.hs
+++ b/Documentation/SBV/Examples/Queries/Abducts.hs
@@ -23,9 +23,9 @@
 --
 -- >>> example
 -- Got: (define-fun abd () Bool (= s1 2))
--- Got: (define-fun abd () Bool (and (= s1 1) (<= s1 s0)))
--- Got: (define-fun abd () Bool (and (<= 1 s0) (= s1 s0)))
--- Got: (define-fun abd () Bool (and (<= s1 (+ s0 s0)) (<= 1 s1)))
+-- Got: (define-fun abd () Bool (and (= s1 1) (= s1 s0)))
+-- Got: (define-fun abd () Bool (and (= s0 2) (= s1 1)))
+-- Got: (define-fun abd () Bool (and (<= 1 s0) (= s1 1)))
 --
 -- Note that @s0@ refers to @x@ and @s1@ refers to @y@ above. You can verify
 -- that adding any of these will ensure @x + y >= 2@.
diff --git a/Documentation/SBV/Examples/Queries/AllSat.hs b/Documentation/SBV/Examples/Queries/AllSat.hs
--- a/Documentation/SBV/Examples/Queries/AllSat.hs
+++ b/Documentation/SBV/Examples/Queries/AllSat.hs
@@ -45,7 +45,7 @@
                       Unk    -> error "Too bad, solver said unknown.." -- Won't happen
                       DSat{} -> error "Unexpected dsat result.."       -- Won't happen
                       Unsat  -> do io $ putStrLn "No other solution!"
-                                   return $ reverse sofar
+                                   pure $ reverse sofar
 
                       Sat    -> do xv <- getValue x
                                    yv <- getValue y
diff --git a/Documentation/SBV/Examples/Queries/CaseSplit.hs b/Documentation/SBV/Examples/Queries/CaseSplit.hs
--- a/Documentation/SBV/Examples/Queries/CaseSplit.hs
+++ b/Documentation/SBV/Examples/Queries/CaseSplit.hs
@@ -54,7 +54,7 @@
                   case mbR of
                     Nothing     -> error "Cannot find a FP number x such that x /= x"  -- Won't happen!
                     Just (s, _) -> do xv <- getValue x
-                                      return (s, xv)
+                                      pure (s, xv)
 
 -- | Demonstrates the "coverage" case.
 --
@@ -82,4 +82,4 @@
                   case mbR of
                     Nothing     -> error "Cannot find a solution!" -- Won't happen!
                     Just (s, _) -> do xv <- getValue x
-                                      return (s, xv)
+                                      pure (s, xv)
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
@@ -61,12 +61,12 @@
     Unk    -> error "Too bad, solver said unknown.." -- Won't happen
     DSat{} -> error "Unexpected dsat result.."       -- Won't happen
     Unsat  -> do io $ putStrLn "No other solution!"
-                 return Nothing
+                 pure Nothing
 
     Sat    -> do xv <- getValue x
                  yv <- getValue y
                  io $ putStrLn $ "[One]: Current solution is: " ++ show (xv, yv)
-                 return $ Just (xv + yv)
+                 pure $ Just (xv + yv)
 
 -- | In the second query we constrain for an answer where y is smaller than x,
 -- and then return the product of the found values.
@@ -81,12 +81,12 @@
     Unk    -> error "Too bad, solver said unknown.." -- Won't happen
     DSat{} -> error "Unexpected dsat result.."       -- Won't happen
     Unsat  -> do io $ putStrLn "No other solution!"
-                 return Nothing
+                 pure Nothing
 
     Sat    -> do yv <- getValue y
                  xv <- getValue x
                  io $ putStrLn $ "[Two]: Current solution is: " ++ show (xv, yv)
-                 return $ Just (xv * yv)
+                 pure $ Just (xv * yv)
 
 -- | Run the demo several times to see that the children threads will change ordering.
 demo :: IO ()
@@ -125,14 +125,14 @@
     Unk    -> error "Too bad, solver said unknown.." -- Won't happen
     DSat{} -> error "Unexpected dsat result.."       -- Won't happen
     Unsat  -> do io $ putStrLn "No other solution!"
-                 return Nothing
+                 pure Nothing
 
     Sat    -> do xv <- getValue x
                  yv <- getValue y
                  io $ putStrLn $ "[One]: Current solution is: " ++ show (xv, yv)
                  io $ putStrLn   "[One]: Place vars for [Two]"
                  liftIO $ putMVar v2 (literal (xv + yv), literal (xv * yv))
-                 return $ Just (xv + yv)
+                 pure $ Just (xv + yv)
 
 -- | In the second query we create a new variable z, and then a symbolic query
 -- using information from the first query and return a solution that uses the
@@ -153,13 +153,13 @@
     Unk    -> error "Too bad, solver said unknown.." -- Won't happen
     DSat{} -> error "Unexpected dsat result.."       -- Won't happen
     Unsat  -> do io $ putStrLn "No other solution!"
-                 return Nothing
+                 pure Nothing
 
     Sat    -> do yv <- getValue y
                  xv <- getValue x
                  zv <- getValue z
                  io $ putStrLn $ "[Two]: My solution is: " ++ show (zv + xv, zv + yv)
-                 return $ Just (zv * xv * yv)
+                 pure $ Just (zv * xv * yv)
 
 -- | In our second demonstration we show how through the use of concurrency
 -- constructs the user can have children queries communicate with one another.
diff --git a/Documentation/SBV/Examples/Queries/Enums.hs b/Documentation/SBV/Examples/Queries/Enums.hs
--- a/Documentation/SBV/Examples/Queries/Enums.hs
+++ b/Documentation/SBV/Examples/Queries/Enums.hs
@@ -9,12 +9,10 @@
 -- Demonstrates the use of enumeration values during queries.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DeriveAnyClass      #-}
-{-# LANGUAGE DeriveDataTypeable  #-}
 {-# LANGUAGE FlexibleInstances   #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE StandaloneDeriving  #-}
 {-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE TypeApplications    #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -23,12 +21,12 @@
 import Data.SBV
 import Data.SBV.Control
 
--- | Days of the week. We make it symbolic using the 'mkSymbolicEnumeration' splice.
+-- | Days of the week. We make it symbolic using the 'mkSymbolic' splice.
 data Day = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday
-         deriving (Eq, Ord, Bounded, Enum)
+         deriving Show
 
 -- | Make 'Day' a symbolic value.
-mkSymbolicEnumeration ''Day
+mkSymbolic [''Day]
 
 -- | A trivial query to find three consecutive days that's all before 'Thursday'. The point
 -- here is that we can perform queries on such enumerated values and use 'getValue' on them
@@ -62,6 +60,6 @@
                                     Sat -> do a <- getValue d1
                                               b <- getValue d2
                                               c <- getValue d3
-                                              return [a, b, c]
+                                              pure [a, b, c]
 
                                     _   -> error "Impossible, can't find days!"
diff --git a/Documentation/SBV/Examples/Queries/FourFours.hs b/Documentation/SBV/Examples/Queries/FourFours.hs
--- a/Documentation/SBV/Examples/Queries/FourFours.hs
+++ b/Documentation/SBV/Examples/Queries/FourFours.hs
@@ -19,12 +19,9 @@
 -- and ask the SMT solver to find the appropriate fillings.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DeriveAnyClass      #-}
-{-# LANGUAGE DeriveDataTypeable  #-}
-{-# LANGUAGE FlexibleInstances  #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE StandaloneDeriving  #-}
-{-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE TypeApplications  #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -40,20 +37,20 @@
 -- and exponentiation will only be to the power @0@. This does restrict the search space, but is sufficient to
 -- solve all the instances.
 data BinOp = Plus | Minus | Times | Divide | Expt
-           deriving (Eq, Enum, Bounded)
+           deriving (Eq, Show)
 
 -- | Make 'BinOp' a symbolic value.
-mkSymbolicEnumeration ''BinOp
+mkSymbolic [''BinOp]
 
 -- | Supported unary operators. Similar to 'BinOp' case, we will restrict square-root and factorial to
 -- be only applied to the value @4.
 data UnOp  = Negate | Sqrt | Factorial
-           deriving (Eq, Enum, Bounded)
+           deriving Eq
 
 -- | Make 'UnOp' a symbolic value.
-mkSymbolicEnumeration ''UnOp
+mkSymbolic [''UnOp]
 
--- | The shape of a tree, either a binary node, or a unary node, or the number @4@, represented hear by
+-- | The shape of a tree, either a binary node, or a unary node, or the number @4@, represented here by
 -- the constructor @F@. We parameterize by the operator type: When doing symbolic computations, we'll fill
 -- those with 'SBinOp' and 'SUnOp'. When finding the shapes, we will simply put unit values, i.e., holes.
 data T b u = B b (T b u) (T b u)
@@ -94,13 +91,13 @@
 fill :: T () () -> Symbolic (T SBinOp SUnOp)
 fill (B _ l r) = B <$> free_ <*> fill l <*> fill r
 fill (U _ t)   = U <$> free_ <*> fill t
-fill F         = return F
+fill F         = pure F
 
 -- | Minor helper for writing "symbolic" case statements. Simply walks down a list
 -- of values to match against a symbolic version of the key.
-sCase :: (Eq a, SymVal a, Mergeable v) => SBV a -> [(a, v)] -> v
-sCase k = walk
-  where walk []              = error "sCase: Expected a non-empty list of cases!"
+cases :: (Eq a, SymVal a, Mergeable v) => SBV a -> [(a, v)] -> v
+cases k = walk
+  where walk []              = error "cases: Expected a non-empty list of cases!"
         walk [(_, v)]        = v
         walk ((k1, v1):rest) = ite (k .== literal k1) v1 (walk rest)
 
@@ -112,27 +109,27 @@
 eval tree = case tree of
               B b l r -> eval l >>= \l' -> eval r >>= \r' -> binOp b l' r'
               U u t   -> eval t >>= uOp u
-              F       -> return 4
+              F       -> pure 4
 
   where binOp :: SBinOp -> SInteger -> SInteger -> Symbolic SInteger
         binOp o l r = do constrain $ o .== sDivide .=> r .== 4 .|| r .== 2
                          constrain $ o .== sExpt   .=> r .== 0
-                         return $ sCase o
-                                    [ (Plus,    l+r)
-                                    , (Minus,   l-r)
-                                    , (Times,   l*r)
-                                    , (Divide,  l `sDiv` r)
-                                    , (Expt,    1)   -- exponent is restricted to 0, so the value is 1
-                                    ]
+                         pure $ cases o
+                                  [ (Plus,    l+r)
+                                  , (Minus,   l-r)
+                                  , (Times,   l*r)
+                                  , (Divide,  l `sDiv` r)
+                                  , (Expt,    1)   -- exponent is restricted to 0, so the value is 1
+                                  ]
 
         uOp :: SUnOp -> SInteger -> Symbolic SInteger
         uOp o v = do constrain $ o .== sSqrt      .=> v .== 4
                      constrain $ o .== sFactorial .=> v .== 4
-                     return $ sCase o
-                                [ (Negate,    -v)
-                                , (Sqrt,       2)  -- argument is restricted to 4, so the value is 2
-                                , (Factorial, 24)  -- argument is restricted to 4, so the value is 24
-                                ]
+                     pure $ cases o
+                              [ (Negate,    -v)
+                              , (Sqrt,       2)  -- argument is restricted to 4, so the value is 2
+                              , (Factorial, 24)  -- argument is restricted to 4, so the value is 24
+                              ]
 
 -- | In the query mode, find a filling of a given tree shape /t/, such that it evaluates to the
 -- requested number /i/. Note that we return back a concrete tree.
@@ -143,10 +140,10 @@
                            query $ do cs <- checkSat
                                       case cs of
                                         Sat -> Just <$> construct symT
-                                        _   -> return Nothing
+                                        _   -> pure Nothing
     where -- Walk through the tree, ask the solver for
           -- the assignment to symbolic operators and fill back.
-          construct F           = return F
+          construct F           = pure F
           construct (U o s')    = do uo <- getValue o
                                      U uo <$> construct s'
           construct (B b l' r') = do bo <- getValue b
diff --git a/Documentation/SBV/Examples/Queries/GuessNumber.hs b/Documentation/SBV/Examples/Queries/GuessNumber.hs
--- a/Documentation/SBV/Examples/Queries/GuessNumber.hs
+++ b/Documentation/SBV/Examples/Queries/GuessNumber.hs
@@ -42,7 +42,7 @@
                             DSat{} -> error "Unexpected delta-sat result.."  -- Won't really happen
                             Unsat  ->
                                    -- This cannot happen! If it does, the input was
-                                   -- not properly constrainted. Note that we found this
+                                   -- not properly constrained. Note that we found this
                                    -- by getting an Unsat, not by checking the value!
                                    error $ unlines [ "There's no solution!"
                                                    , "Guess sequence: " ++ show (reverse sofar)
@@ -50,7 +50,7 @@
                             Sat    -> do gv <- getValue g
                                          case gv `compare` input of
                                            EQ -> -- Got it, return:
-                                                 return (reverse (gv : sofar))
+                                                 pure (reverse (gv : sofar))
                                            LT -> -- Solver guess is too small, increase the lower bound:
                                                  loop ((lb+1) `max` (lb + (input - lb) `div` 2)) ub (gv : sofar)
                                            GT -> -- Solver guess is too big, decrease the upper bound:
diff --git a/Documentation/SBV/Examples/Queries/UnsatCore.hs b/Documentation/SBV/Examples/Queries/UnsatCore.hs
--- a/Documentation/SBV/Examples/Queries/UnsatCore.hs
+++ b/Documentation/SBV/Examples/Queries/UnsatCore.hs
@@ -36,7 +36,7 @@
        query $ do cs <- checkSat
                   case cs of
                     Unsat -> Just <$> getUnsatCore
-                    _     -> return Nothing
+                    _     -> pure Nothing
 
 
 -- | Extract the unsat-core of 'p'. We have:
@@ -44,7 +44,7 @@
 -- >>> ucCore
 -- Unsat core is: ["less than 5","more than 10"]
 --
--- Demonstrating that the constraint @a .> b@ is /not/ needed for unsatisfiablity in this case.
+-- Demonstrating that the constraint @a .> b@ is /not/ needed for unsatisfiability in this case.
 ucCore :: IO ()
 ucCore = do mbCore <- runSMT p
             case mbCore of
diff --git a/Documentation/SBV/Examples/Strings/RegexCrossword.hs b/Documentation/SBV/Examples/Strings/RegexCrossword.hs
--- a/Documentation/SBV/Examples/Strings/RegexCrossword.hs
+++ b/Documentation/SBV/Examples/Strings/RegexCrossword.hs
@@ -26,7 +26,7 @@
 
 -- | Solve a given crossword, returning the corresponding rows
 solveCrossword :: [R.RegExp] -> [R.RegExp] -> IO [String]
-solveCrossword rowRegExps colRegExps = runSMT $ do
+solveCrossword rowRegExps colRegExps = runSMTWith cvc5 $ do
         let numRows = genericLength rowRegExps
             numCols = genericLength colRegExps
 
@@ -34,7 +34,7 @@
         let mkRow rowRegExp = do row :: SString <- free_
                                  constrain $ row `R.match` rowRegExp
                                  constrain $ L.length row .== literal numCols
-                                 return row
+                                 pure row
 
         rows <- mapM mkRow rowRegExps
 
@@ -42,7 +42,7 @@
         let mkCol colRegExp = do col :: SString <- free_
                                  constrain $ col `R.match` colRegExp
                                  constrain $ L.length col .== literal numRows
-                                 return col
+                                 pure col
 
         cols <- mapM mkCol colRegExps
 
diff --git a/Documentation/SBV/Examples/Strings/SQLInjection.hs b/Documentation/SBV/Examples/Strings/SQLInjection.hs
--- a/Documentation/SBV/Examples/Strings/SQLInjection.hs
+++ b/Documentation/SBV/Examples/Strings/SQLInjection.hs
@@ -49,11 +49,11 @@
 eval (Query q)         = do q' <- eval q
                             tell [q']
                             lift $ lift free_
-eval (Const str)       = return $ literal str
+eval (Const str)       = pure $ literal str
 eval (Concat e1 e2)    = (++) <$> eval e1 <*> eval e2
 eval (ReadVar nm)      = do n   <- eval nm
                             arr <- get
-                            return $ readArray arr n
+                            pure $ readArray arr n
 
 -- | A simple program to query all messages with a given topic id. In SQL like notation:
 --
diff --git a/Documentation/SBV/Examples/TP/Ackermann.hs b/Documentation/SBV/Examples/TP/Ackermann.hs
new file mode 100644
--- /dev/null
+++ b/Documentation/SBV/Examples/TP/Ackermann.hs
@@ -0,0 +1,279 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Documentation.SBV.Examples.TP.Ackermann
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Proving the relationship between Ackermann's original 3-argument function (1928)
+-- and the Ackermann-Péter function (1935).
+--
+-- Ackermann's original function was a 3-argument function designed to demonstrate
+-- a total computable function that is not primitive recursive. The third argument
+-- generalizes the operation: @ack 0 n a = n + a@ (addition), and higher levels
+-- correspond to multiplication, exponentiation, etc.
+--
+-- Rózsa Péter simplified this to a 2-argument function in 1935, which is what
+-- most people today call "the Ackermann function."
+--
+-- This example is inspired by: <https://github.com/imandra-ai/imandrax-examples/blob/main/src/ackermann.iml>
+--
+-- Note: This proof was developed by Claude (Anthropic's AI assistant) with
+-- minimal user prompting and guidance.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE CPP               #-}
+{-# LANGUAGE DataKinds         #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE QuasiQuotes       #-}
+{-# LANGUAGE TypeApplications  #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Documentation.SBV.Examples.TP.Ackermann where
+
+import Data.SBV
+import Data.SBV.Tuple
+import Data.SBV.TP
+
+#ifdef DOCTEST
+-- $setup
+-- >>> import Data.SBV
+-- >>> import Data.SBV.TP
+#endif
+
+-- * Ackermann's original 3-argument function (1928)
+
+-- | Ackermann's original 3-argument function (1928). This is the lesser-known
+-- original version, not the commonly referenced Ackermann-Péter function.
+-- The third argument @a@ generalizes the operation at each level.
+ack :: SInteger -> SInteger -> SInteger -> SInteger
+ack = smtFunction "ack"
+  $ \m n a -> [sCase| m of
+                 _ | m .<= 0 -> n + a
+                 _ | n .<= 0 -> 0
+                 _ | n .== 1 -> a
+                 _           -> ack (m - 1) (ack m (n - 1) a) a
+              |]
+
+-- * Ackermann-Péter function (1935)
+
+-- | The Ackermann-Péter function (1935), commonly known as "the Ackermann function."
+-- This is Rózsa Péter's simplified 2-argument version of Ackermann's original function.
+pet :: SInteger -> SInteger -> SInteger
+pet = smtFunction "pet"
+  $ \m n -> [sCase| m of
+               _ | m .<= 0 -> n + 1
+               _ | n .<= 0 -> pet (m - 1) 1
+               _           -> pet (m - 1) (pet m (n - 1))
+            |]
+
+-- * Correctness
+
+-- | Prove that @ack m 2 2 = 4@ for all m >= 0.
+--
+-- >>> runTP ack_2_2_4
+-- Inductive lemma (strong): ack_2_2_4
+--   Step: Measure is non-negative        Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1                          Q.E.D.
+--     Step: 1.2.1                        Q.E.D.
+--     Step: 1.2.2                        Q.E.D.
+--     Step: 1.2.3                        Q.E.D.
+--     Step: 1.2.4                        Q.E.D.
+--     Step: 1.Completeness               Q.E.D.
+--   Result:                              Q.E.D.
+-- Functions proven terminating: ack
+-- [Proven] ack_2_2_4 :: Ɐm ∷ Integer → Bool
+ack_2_2_4 :: TP (Proof (Forall "m" Integer -> SBool))
+ack_2_2_4 = sInduct "ack_2_2_4"
+                    (\(Forall m) -> m .>= 0 .=> ack m 2 2 .== 4)
+                    (id, []) $
+                    \ih m -> [m .>= 0]
+                          |- ack m 2 2
+                          =: cases [ m .== 0 ==> trivial
+                                   , m .> 0  ==> ack m 2 2
+                                              =: ack (m - 1) (ack m 1 2) 2
+                                              =: ack (m - 1) 2 2
+                                              ?? ih `at` Inst @"m" (m - 1)
+                                              =: (4 :: SInteger)
+                                              =: qed
+                                   ]
+
+-- | Prove that @ack@ is non-negative when all arguments are non-negative.
+-- We use strong induction on the lexicographic measure (m, n).
+--
+-- >>> runTP ack_psd
+-- Inductive lemma (strong): ack_psd
+--   Step: Measure is non-negative      Q.E.D.
+--   Step: 1 (4 way case split)
+--     Step: 1.1                        Q.E.D.
+--     Step: 1.2                        Q.E.D.
+--     Step: 1.3                        Q.E.D.
+--     Step: 1.4.1                      Q.E.D.
+--     Step: 1.4.2                      Q.E.D.
+--     Step: 1.4.3                      Q.E.D.
+--     Step: 1.Completeness             Q.E.D.
+--   Result:                            Q.E.D.
+-- Functions proven terminating: ack
+-- [Proven] ack_psd :: Ɐm ∷ Integer → Ɐn ∷ Integer → Ɐa ∷ Integer → Bool
+ack_psd :: TP (Proof (Forall "m" Integer -> Forall "n" Integer -> Forall "a" Integer -> SBool))
+ack_psd = sInduct "ack_psd"
+                  (\(Forall m) (Forall n) (Forall a) ->
+                      m .>= 0 .&& n .>= 0 .&& a .>= 0 .=> ack m n a .>= 0)
+                  (\m n _a -> tuple (m, n), []) $
+                  \ih m n a -> [m .>= 0, n .>= 0, a .>= 0]
+                            |- ack m n a .>= 0
+                            =: cases [ m .<= 0 ==> trivial   -- n + a >= 0
+                                     , n .<= 0 ==> trivial   -- 0 >= 0
+                                     , n .== 1 ==> trivial   -- a >= 0
+                                     , m .> 0 .&& n .> 1
+                                         ==> ack m n a .>= 0
+                                          =: ack (m - 1) (ack m (n - 1) a) a .>= 0
+                                          ?? ih `at` (Inst @"m" m, Inst @"n" (n - 1), Inst @"a" a)
+                                          ?? ih `at` (Inst @"m" (m - 1), Inst @"n" (ack m (n - 1) a), Inst @"a" a)
+                                          =: sTrue
+                                          =: qed
+                                     ]
+
+-- | Prove that @pet@ is non-negative when both arguments are non-negative.
+-- We use strong induction on the lexicographic measure (m, n).
+--
+-- >>> runTPWith cvc5 pet_psd
+-- Inductive lemma (strong): pet_psd
+--   Step: Measure is non-negative      Q.E.D.
+--   Step: 1 (3 way case split)
+--     Step: 1.1                        Q.E.D.
+--     Step: 1.2.1                      Q.E.D.
+--     Step: 1.2.2                      Q.E.D.
+--     Step: 1.2.3                      Q.E.D.
+--     Step: 1.3.1                      Q.E.D.
+--     Step: 1.3.2                      Q.E.D.
+--     Step: 1.3.3                      Q.E.D.
+--     Step: 1.Completeness             Q.E.D.
+--   Result:                            Q.E.D.
+-- Functions proven terminating: pet
+-- [Proven] pet_psd :: Ɐm ∷ Integer → Ɐn ∷ Integer → Bool
+pet_psd :: TP (Proof (Forall "m" Integer -> Forall "n" Integer -> SBool))
+pet_psd = do
+    sInduct "pet_psd"
+                  (\(Forall m) (Forall n) -> m .>= 0 .&& n .>= 0 .=> pet m n .>= 0)
+                  (\m n -> tuple (m, n), []) $
+                  \ih m n -> [m .>= 0, n .>= 0]
+                          |- pet m n .>= 0
+                          =: cases [ m .<= 0 ==> trivial   -- n + 1 >= 0
+                                   , m .> 0 .&& n .<= 0
+                                       ==> pet m n .>= 0
+                                        =: pet (m - 1) 1 .>= 0
+                                        ?? ih `at` (Inst @"m" (m - 1), Inst @"n" (1 :: SInteger))
+                                        =: sTrue
+                                        =: qed
+                                   , m .> 0 .&& n .> 0
+                                       ==> pet m n .>= 0
+                                        =: pet (m - 1) (pet m (n - 1)) .>= 0
+                                        ?? ih `at` (Inst @"m" m, Inst @"n" (n - 1))
+                                        ?? ih `at` (Inst @"m" (m - 1), Inst @"n" (pet m (n - 1)))
+                                        =: sTrue
+                                        =: qed
+                                   ]
+
+-- | The main theorem, relating @pet@ and @ack@: @pet m n + 3 = ack (m-1) (n+3) 2@ for @m > 0@ and @n >= 0@.
+--
+-- >>> runTPWith cvc5 petAck
+-- Inductive lemma (strong): ack_2_2_4
+--   Step: Measure is non-negative        Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1                          Q.E.D.
+--     Step: 1.2.1                        Q.E.D.
+--     Step: 1.2.2                        Q.E.D.
+--     Step: 1.2.3                        Q.E.D.
+--     Step: 1.2.4                        Q.E.D.
+--     Step: 1.Completeness               Q.E.D.
+--   Result:                              Q.E.D.
+-- Inductive lemma (strong): pet_psd
+--   Step: Measure is non-negative        Q.E.D.
+--   Step: 1 (3 way case split)
+--     Step: 1.1                          Q.E.D.
+--     Step: 1.2.1                        Q.E.D.
+--     Step: 1.2.2                        Q.E.D.
+--     Step: 1.2.3                        Q.E.D.
+--     Step: 1.3.1                        Q.E.D.
+--     Step: 1.3.2                        Q.E.D.
+--     Step: 1.3.3                        Q.E.D.
+--     Step: 1.Completeness               Q.E.D.
+--   Result:                              Q.E.D.
+-- Inductive lemma (strong): petAck
+--   Step: Measure is non-negative        Q.E.D.
+--   Step: 1 (4 way case split)
+--     Step: 1.1                          Q.E.D.
+--     Step: 1.2.1                        Q.E.D.
+--     Step: 1.2.2                        Q.E.D.
+--     Step: 1.2.3                        Q.E.D.
+--     Step: 1.3.1                        Q.E.D.
+--     Step: 1.3.2                        Q.E.D.
+--     Step: 1.3.3                        Q.E.D.
+--     Step: 1.3.4                        Q.E.D.
+--     Step: 1.3.5                        Q.E.D.
+--     Step: 1.4.1                        Q.E.D.
+--     Step: 1.4.2                        Q.E.D.
+--     Step: 1.4.3                        Q.E.D.
+--     Step: 1.4.4                        Q.E.D.
+--     Step: 1.4.5                        Q.E.D.
+--     Step: 1.Completeness               Q.E.D.
+--   Result:                              Q.E.D.
+-- Functions proven terminating: ack, pet
+-- [Proven] petAck :: Ɐm ∷ Integer → Ɐn ∷ Integer → Bool
+petAck :: TP (Proof (Forall "m" Integer -> Forall "n" Integer -> SBool))
+petAck = do
+    ack224 <- ack_2_2_4
+    psd    <- pet_psd
+    sInduct "petAck"
+               (\(Forall m) (Forall n) ->
+                   m .> 0 .&& n .>= 0 .=> pet m n + 3 .== ack (m - 1) (n + 3) 2)
+               (\m n -> tuple (m, n), []) $
+               \ih m n -> [m .> 0, n .>= 0]
+                       |- pet m n + 3 .== ack (m - 1) (n + 3) 2
+                       =: cases [ m .== 1 .&& n .== 0
+                                    ==> trivial
+                                , m .== 1 .&& n .> 0
+                                    ==> pet 1 n + 3 .== ack 0 (n + 3) 2
+                                     =: pet 0 (pet 1 (n - 1)) + 3 .== (n + 3) + 2
+                                     ?? ih `at` (Inst @"m" (1 :: SInteger), Inst @"n" (n - 1))
+                                     =: sTrue
+                                     =: qed
+                                , m .> 1 .&& n .<= 0
+                                    -- n <= 0 with n >= 0 means n == 0
+                                    ==> pet m n + 3 .== ack (m - 1) (n + 3) 2
+                                     -- First unfold pet: since n <= 0, pet m n = pet (m-1) 1
+                                     =: pet (m - 1) 1 + 3 .== ack (m - 1) (n + 3) 2
+                                     -- Unfold ack: ack (m-1) (n+3) 2 = ack (m-2) (ack (m-1) (n+2) 2) 2
+                                     =: pet (m - 1) 1 + 3 .== ack (m - 2) (ack (m - 1) (n + 2) 2) 2
+                                     -- Apply IH at (m-1, 1): pet (m-1) 1 + 3 = ack (m-2) 4 2
+                                     ?? ih `at` (Inst @"m" (m - 1), Inst @"n" (1 :: SInteger))
+                                     =: ack (m - 2) 4 2 .== ack (m - 2) (ack (m - 1) (n + 2) 2) 2
+                                     -- Since n = 0, n+2 = 2, and ack (m-1) 2 2 = 4 by ack_2_2_4
+                                     ?? ack224 `at` Inst @"m" (m - 1)
+                                     =: sTrue
+                                     =: qed
+                                , m .> 1 .&& n .> 0
+                                    ==> pet m n + 3 .== ack (m - 1) (n + 3) 2
+                                     -- Unfold pet: pet m n = pet (m-1) (pet m (n-1))
+                                     =: pet (m - 1) (pet m (n - 1)) + 3 .== ack (m - 1) (n + 3) 2
+                                     -- Unfold ack on RHS: ack (m-1) (n+3) 2 = ack (m-2) (ack (m-1) (n+2) 2) 2
+                                     =: pet (m - 1) (pet m (n - 1)) + 3 .== ack (m - 2) (ack (m - 1) (n + 2) 2) 2
+                                     -- Use pet_psd to establish pet m (n-1) >= 0
+                                     ?? psd `at` (Inst @"m" m, Inst @"n" (n - 1))
+                                     -- Apply IH at (m-1, pet m (n-1)) to transform LHS
+                                     ?? ih `at` (Inst @"m" (m - 1), Inst @"n" (pet m (n - 1)))
+                                     =: ack (m - 2) (pet m (n - 1) + 3) 2 .== ack (m - 2) (ack (m - 1) (n + 2) 2) 2
+                                     -- Apply IH at (m, n-1): pet m (n-1) + 3 = ack (m-1) (n+2) 2
+                                     ?? ih `at` (Inst @"m" m, Inst @"n" (n - 1))
+                                     =: sTrue
+                                     =: qed
+                                ]
+
+{- HLint ignore module    "Use curry"     -}
+{- HLint ignore ack_psd   "Use camelCase" -}
+{- HLint ignore pet_psd   "Use camelCase" -}
+{- HLint ignore ack_2_2_4 "Use camelCase" -}
diff --git a/Documentation/SBV/Examples/TP/Adder.hs b/Documentation/SBV/Examples/TP/Adder.hs
new file mode 100644
--- /dev/null
+++ b/Documentation/SBV/Examples/TP/Adder.hs
@@ -0,0 +1,395 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Documentation.SBV.Examples.TP.Adder
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Prove binary adders correct by induction, for /all/ widths at once.
+--
+-- This is the inductive companion to
+-- "Documentation.SBV.Examples.BitPrecise.Adders", which proves fixed-width
+-- adders correct automatically by bit-blasting. Here, instead, we model the
+-- operands as arbitrary-length, little-endian symbolic bit lists and prove---by
+-- induction on the list---properties that hold with no bound on the width:
+--
+--   * a ripple-carry adder agrees with the mathematical value of the bits
+--     (@correctness@);
+--
+--   * a parallel-prefix (carry-lookahead) tree computes the same carry as the
+--     ripple, because the generate\/propagate carry operator is associative
+--     (@lookaheadCorrect@); and
+--
+--   * that lookahead carry is exactly the carry the ripple adder threads
+--     (@lookaheadMatchesAdder@).
+--
+-- A number is represented by a little-endian list of bit pairs: one
+-- @(a, b)@ per position, least-significant first, where @a@ is a bit of the
+-- first operand and @b@ the corresponding bit of the second. The integer value
+-- of such a list is @sum_i bit_i * 2^i@.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE CPP                 #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE OverloadedLists     #-}
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Documentation.SBV.Examples.TP.Adder where
+
+import Prelude hiding (fst, snd, foldl, map, curry, uncurry, (++))
+
+import Data.SBV hiding (fullAdder)
+import Data.SBV.List (foldl, map, (++))
+import Data.SBV.Tuple
+import Data.SBV.TP
+
+import Documentation.SBV.Examples.TP.Lists (foldlOverAppend)
+
+-- We reuse the very same combinational gates that the fixed-width, bit-blasted
+-- companion proves correct---only the adder driver differs (a symbolic,
+-- inductive recursion here versus a metalevel one there). The 'Data.SBV.fullAdder'
+-- word-level operation is hidden above so 'fullAdder' refers to that gate.
+import Documentation.SBV.Examples.BitPrecise.Adders (Bit, fullAdder, generatePropagate)
+
+#ifdef DOCTEST
+-- $setup
+-- >>> :set -XOverloadedLists
+-- >>> import Data.SBV
+-- >>> import Data.SBV.TP
+#endif
+
+-- * Bits, values, and the adder
+
+-- | The integer value of a single bit: @1@ if set, @0@ otherwise.
+bitVal :: Bit -> SInteger
+bitVal b = ite b 1 0
+
+-- | The integer value of a little-endian bit list: @sum_i bit_i * 2^i@.
+val :: SList Bool -> SInteger
+val = smtFunction "val"
+    $ \bs -> [sCase| bs of
+                []     -> 0
+                x : xs -> bitVal x + 2 * val xs
+             |]
+
+-- | The value of the first operand, read off the first components of the pairs.
+valA :: SList (Bool, Bool) -> SInteger
+valA = smtFunction "valA"
+     $ \ps -> [sCase| ps of
+                 []          -> 0
+                 (a, _) : qs -> bitVal a + 2 * valA qs
+              |]
+
+-- | The value of the second operand, read off the second components of the pairs.
+valB :: SList (Bool, Bool) -> SInteger
+valB = smtFunction "valB"
+     $ \ps -> [sCase| ps of
+                 []          -> 0
+                 (_, b) : qs -> bitVal b + 2 * valB qs
+              |]
+
+-- | The ripple-carry adder. Given an incoming carry and a little-endian list of
+-- bit pairs, thread the carry through a chain of full adders (the same
+-- 'fullAdder' gate the bit-blasted companion verifies), emitting each sum bit
+-- and, at the end, the final carry-out as the most-significant bit. The result
+-- is therefore one bit longer than the input, so its value is exactly the full
+-- sum---no truncation.
+rca :: Bit -> SList (Bool, Bool) -> SList Bool
+rca = smtFunction "rca"
+    $ \c ps -> [sCase| ps of
+                  []     -> [c]
+                  p : qs -> let (s, co) = uncurry fullAdder p c
+                            in s .: rca co qs
+               |]
+
+-- * Correctness
+
+-- | The ripple-carry adder computes the sum of its operands, for any width:
+--
+-- @val (rca 0 ps) == valA ps + valB ps@
+--
+-- We prove it via a more general lemma that tracks the incoming carry, since the
+-- recursive calls feed each stage's carry-out into the next.
+--
+-- >>> runTP correctness
+-- Lemma: fullAdderCorrect        Q.E.D.
+-- Inductive lemma: rcaCorrect
+--   Step: Base                   Q.E.D.
+--   Step: 1                      Q.E.D.
+--   Step: 2                      Q.E.D.
+--   Step: 3                      Q.E.D.
+--   Step: 4                      Q.E.D.
+--   Step: 5                      Q.E.D.
+--   Result:                      Q.E.D.
+-- Lemma: adderCorrect            Q.E.D.
+-- Functions proven terminating: rca, val, valA, valB
+-- [Proven] adderCorrect :: Ɐps ∷ [(Bool, Bool)] → Bool
+correctness :: TP (Proof (Forall "ps" [(Bool, Bool)] -> SBool))
+correctness = do
+
+  -- A single full adder is arithmetically correct: the sum bit plus twice the
+  -- carry-out equals the sum of the three input bits. This is a finite boolean
+  -- fact, discharged directly.
+  faC <- lemma "fullAdderCorrect"
+               (\(Forall @"a" a) (Forall @"b" b) (Forall @"c" c) ->
+                    let (s, co) = fullAdder a b c
+                    in bitVal s + 2 * bitVal co .== bitVal a + bitVal b + bitVal c)
+               []
+
+  -- The general statement, tracking the incoming carry. Induct on the list of
+  -- bit pairs; the carry is universally quantified so the induction hypothesis
+  -- applies at the carry-out fed to the recursive call.
+  rcaC <- induct "rcaCorrect"
+                 (\(Forall @"ps" ps) (Forall @"c" c) ->
+                      val (rca c ps) .== valA ps + valB ps + bitVal c) $
+                 \ih (p, ps) c ->
+                     let a       = fst p
+                         b       = snd p
+                         (s, co) = fullAdder a b c
+                     in [] |- val (rca c (p .: ps))
+                           =: val (s .: rca co ps)
+                           =: bitVal s + 2 * val (rca co ps)
+                           ?? ih `at` Inst @"c" co
+                           =: bitVal s + 2 * (valA ps + valB ps + bitVal co)
+                           ?? faC `at` (Inst @"a" a, Inst @"b" b, Inst @"c" c)
+                           =: (bitVal a + 2 * valA ps) + (bitVal b + 2 * valB ps) + bitVal c
+                           =: valA (p .: ps) + valB (p .: ps) + bitVal c
+                           =: qed
+
+  -- The headline corollary: with no incoming carry, the adder computes the sum.
+  lemma "adderCorrect"
+        (\(Forall ps) -> val (rca sFalse ps) .== valA ps + valB ps)
+        [proofOf rcaC]
+
+-- * Carry-lookahead, via a parallel-prefix tree
+--
+-- $lookahead
+-- A ripple-carry adder is slow because each stage waits for the carry from the
+-- one below it. A /carry-lookahead/ adder breaks that chain by computing the
+-- carries in parallel. The key is to summarize a contiguous block of positions
+-- by a @(generate, propagate)@ /section/: whether the block produces a carry on
+-- its own (@generate@), and whether it would pass an incoming carry straight
+-- through (@propagate@). Adjacent sections combine with the associative operator
+-- 'dot', so the carries can be gathered by a balanced /tree/ of 'dot's rather
+-- than a linear ripple.
+--
+-- We prove that tree correct against the ripple as follows. 'dot' is an
+-- associative monoid with identity 'idSec', and applying a section to an
+-- incoming carry ('applyC') is its action. The ripple carry is the /linear/
+-- fold of 'dot' over the sections (@carryIsFold@), and a balanced tree of 'dot's
+-- computes that /same/ fold by associativity (@treeIsFold@). Hence the parallel
+-- tree and the sequential ripple agree.
+
+-- | Combine two adjacent @(generate, propagate)@ sections, lower-order first.
+-- The combined block generates a carry if the high part does, or if it
+-- propagates one generated by the low part; it propagates only if both do.
+dot :: SBV (Bool, Bool) -> SBV (Bool, Bool) -> SBV (Bool, Bool)
+dot lo hi = tuple (fst hi .|| (snd hi .&& fst lo), snd hi .&& snd lo)
+
+-- | The identity section: generates nothing, propagates everything.
+idSec :: SBV (Bool, Bool)
+idSec = tuple (sFalse, sTrue)
+
+-- | Apply a section to an incoming carry, giving the carry out of that section.
+applyC :: SBV (Bool, Bool) -> Bit -> Bit
+applyC sec c = fst sec .|| (snd sec .&& c)
+
+-- | The sequential ripple carry-out: thread the incoming carry through the
+-- sections, left to right.
+carry :: Bit -> SList (Bool, Bool) -> Bit
+carry = smtFunction "carry"
+      $ \c gps -> [sCase| gps of
+                     []       -> c
+                     b : rest -> carry (applyC b c) rest
+                  |]
+
+-- | The @(generate, propagate)@ section of a single operand bit-pair @(a, b)@,
+-- using the very same 'generatePropagate' gate as the bit-blasted companion.
+gpOf :: SBV (Bool, Bool) -> SBV (Bool, Bool)
+gpOf p = tuple (uncurry generatePropagate p)
+
+-- | The carry-out actually threaded by the ripple adder 'rca': fold the
+-- incoming carry through the full-adder carry of each position. (This is 'rca'
+-- with the sum bits dropped---it threads the identical carry, via the same
+-- 'fullAdder'.)
+rcaCarry :: Bit -> SList (Bool, Bool) -> Bit
+rcaCarry = smtFunction "rcaCarry"
+         $ \c ps -> [sCase| ps of
+                       []     -> c
+                       p : qs -> let (_, co) = uncurry fullAdder p c
+                                 in rcaCarry co qs
+                    |]
+
+-- | The headline lookahead result, in textbook parallel-prefix form: the ripple
+-- carry over a concatenation equals combining the two halves' sections
+-- /independently/ and then applying the result to the incoming carry. Since
+-- 'dot' is associative, the halves can be split the same way recursively---so
+-- the carries can be gathered by a balanced /tree/ of 'dot's instead of a linear
+-- ripple, and this says every such tree computes the same carry.
+--
+-- The proof rests on two pieces: @carryIsFold@ (the ripple carry /is/ the linear
+-- fold of 'dot'), kept as its own reusable lemma, and @foldlDotSplit@ (the fold
+-- distributes over append---the associativity law that licenses any tree).
+--
+-- >>> runTP lookaheadCorrect
+-- Lemma: dotAssoc                     Q.E.D.
+-- Lemma: dotLeftUnit                  Q.E.D.
+-- Lemma: applyCDot                    Q.E.D.
+-- Inductive lemma: foldlDotShift
+--   Step: Base                        Q.E.D.
+--   Step: 1                           Q.E.D.
+--   Step: 2                           Q.E.D.
+--   Step: 3                           Q.E.D.
+--   Step: 4                           Q.E.D.
+--   Step: 5                           Q.E.D.
+--   Step: 6                           Q.E.D.
+--   Result:                           Q.E.D.
+-- Inductive lemma: carryIsFold
+--   Step: Base                        Q.E.D.
+--   Step: 1                           Q.E.D.
+--   Step: 2                           Q.E.D.
+--   Step: 3                           Q.E.D.
+--   Step: 4                           Q.E.D.
+--   Step: 5                           Q.E.D.
+--   Step: 6                           Q.E.D.
+--   Result:                           Q.E.D.
+-- Inductive lemma: foldlOverAppend
+--   Step: Base                        Q.E.D.
+--   Step: 1                           Q.E.D.
+--   Step: 2                           Q.E.D.
+--   Step: 3                           Q.E.D.
+--   Result:                           Q.E.D.
+-- Lemma: foldlDotSplit
+--   Step: 1                           Q.E.D.
+--   Step: 2                           Q.E.D.
+--   Result:                           Q.E.D.
+-- Lemma: treeCarry
+--   Step: 1                           Q.E.D.
+--   Step: 2                           Q.E.D.
+--   Result:                           Q.E.D.
+-- Functions proven terminating: carry, sbv.foldl
+-- [Proven] treeCarry :: Ɐc ∷ Bool → Ɐxs ∷ [(Bool, Bool)] → Ɐys ∷ [(Bool, Bool)] → Bool
+lookaheadCorrect :: TP (Proof (Forall "c" Bool -> Forall "xs" [(Bool, Bool)] -> Forall "ys" [(Bool, Bool)] -> SBool))
+lookaheadCorrect = do
+
+  -- 'dot' is an associative monoid with identity 'idSec'; 'applyC' is its
+  -- action. All finite boolean facts.
+  assoc <- lemma "dotAssoc"    (\(Forall @"x" x) (Forall @"y" y) (Forall @"z" z) -> dot x (dot y z) .== dot (dot x y) z)                  []
+  lunit <- lemma "dotLeftUnit" (\(Forall @"x" x) -> dot idSec x .== x)                                                                    []
+  act   <- lemma "applyCDot"   (\(Forall @"lo" lo) (Forall @"hi" hi) (Forall @"c" c) -> applyC (dot lo hi) c .== applyC hi (applyC lo c)) []
+
+  -- Folding with an initial section @s@ equals @s@ combined with the fold from
+  -- the identity. (Accumulator reassociation, à la Lists.foldrFoldl.)
+  fldShift <- induct "foldlDotShift"
+                  (\(Forall @"xs" xs) (Forall @"s" s) ->
+                       foldl dot s xs .== dot s (foldl dot idSec xs)) $
+                  \ih (x, xs) s -> [] |- foldl dot s (x .: xs)
+                                      =: foldl dot (dot s x) xs
+                                      ?? ih `at` Inst @"s" (dot s x)
+                                      =: dot (dot s x) (foldl dot idSec xs)
+                                      ?? assoc
+                                      =: dot s (dot x (foldl dot idSec xs))
+                                      ?? ih `at` Inst @"s" x
+                                      =: dot s (foldl dot x xs)
+                                      ?? lunit
+                                      =: dot s (foldl dot (dot idSec x) xs)
+                                      =: dot s (foldl dot idSec (x .: xs))
+                                      =: qed
+
+  -- The reusable link: the sequential ripple carry is the left fold of 'dot'
+  -- over the sections, applied to the incoming carry. Induct on the sections;
+  -- the carry is the threaded argument, so the hypothesis applies at the next
+  -- carry-in.
+  cif <- induct "carryIsFold"
+                (\(Forall @"gps" gps) (Forall @"c" c) ->
+                     carry c gps .== applyC (foldl dot idSec gps) c) $
+                \ih (b, gps) c -> [] |- carry c (b .: gps)
+                                     =: carry (applyC b c) gps
+                                     ?? ih `at` Inst @"c" (applyC b c)
+                                     =: applyC (foldl dot idSec gps) (applyC b c)
+                                     ?? act `at` (Inst @"lo" b, Inst @"hi" (foldl dot idSec gps), Inst @"c" c)
+                                     =: applyC (dot b (foldl dot idSec gps)) c
+                                     ?? fldShift `at` (Inst @"xs" gps, Inst @"s" b)
+                                     =: applyC (foldl dot b gps) c
+                                     ?? lunit
+                                     =: applyC (foldl dot (dot idSec b) gps) c
+                                     =: applyC (foldl dot idSec (b .: gps)) c
+                                     =: qed
+
+  -- foldl of 'dot' distributes over append (imported from the Lists examples).
+  foa <- foldlOverAppend dot
+
+  -- The split/homomorphism law: reducing a concatenation equals reducing the
+  -- halves independently and combining them with 'dot'. This is what licenses
+  -- any balanced (tree) grouping of the sections.
+  splitLaw <- calc "foldlDotSplit"
+                (\(Forall @"xs" xs) (Forall @"ys" ys) ->
+                     foldl dot idSec (xs ++ ys) .== dot (foldl dot idSec xs) (foldl dot idSec ys)) $
+                \xs ys -> [] |- foldl dot idSec (xs ++ ys)
+                             ?? foa `at` (Inst @"xs" xs, Inst @"ys" ys, Inst @"e" idSec)
+                             =: foldl dot (foldl dot idSec xs) ys
+                             ?? fldShift `at` (Inst @"xs" ys, Inst @"s" (foldl dot idSec xs))
+                             =: dot (foldl dot idSec xs) (foldl dot idSec ys)
+                             =: qed
+
+  -- Headline: the ripple carry of a concatenation equals applying the
+  -- independently-combined half-sections to the incoming carry.
+  calc "treeCarry"
+       (\(Forall @"c" c) (Forall @"xs" xs) (Forall @"ys" ys) ->
+            carry c (xs ++ ys) .== applyC (dot (foldl dot idSec xs) (foldl dot idSec ys)) c) $
+       \c xs ys -> [] |- carry c (xs ++ ys)
+                    ?? cif `at` (Inst @"gps" (xs ++ ys), Inst @"c" c)
+                    =: applyC (foldl dot idSec (xs ++ ys)) c
+                    ?? splitLaw `at` (Inst @"xs" xs, Inst @"ys" ys)
+                    =: applyC (dot (foldl dot idSec xs) (foldl dot idSec ys)) c
+                    =: qed
+
+-- | The capstone, tying the lookahead machinery back to the actual adder:
+-- running the (foldable, tree-groupable) section 'carry' over the operands'
+-- generate\/propagate signals reproduces exactly the carry that the ripple adder
+-- 'rca' threads. Combined with @treeCarry@, this says the adder's own carry can
+-- be computed by any balanced prefix tree.
+--
+-- >>> runTP lookaheadMatchesAdder
+-- Lemma: applyCgpOf                         Q.E.D.
+-- Inductive lemma: lookaheadMatchesAdder
+--   Step: Base                              Q.E.D.
+--   Step: 1                                 Q.E.D.
+--   Step: 2                                 Q.E.D.
+--   Step: 3                                 Q.E.D.
+--   Step: 4                                 Q.E.D.
+--   Step: 5                                 Q.E.D.
+--   Result:                                 Q.E.D.
+-- Functions proven terminating: carry, rcaCarry, sbv.map
+-- [Proven] lookaheadMatchesAdder :: Ɐps ∷ [(Bool, Bool)] → Ɐc ∷ Bool → Bool
+lookaheadMatchesAdder :: TP (Proof (Forall "ps" [(Bool, Bool)] -> Forall "c" Bool -> SBool))
+lookaheadMatchesAdder = do
+
+  -- Applying a position's generate/propagate section to a carry is exactly the
+  -- full-adder carry-out. A finite boolean fact.
+  applyGP <- lemma "applyCgpOf"
+                   (\(Forall @"p" p) (Forall @"c" c) ->
+                        let (_, co) = uncurry fullAdder p c
+                        in applyC (gpOf p) c .== co)
+                   []
+
+  -- Induct on the operands; the carry is threaded, so the hypothesis applies at
+  -- the next carry-in.
+  induct "lookaheadMatchesAdder"
+         (\(Forall @"ps" ps) (Forall @"c" c) -> carry c (map gpOf ps) .== rcaCarry c ps) $
+         \ih (p, ps) c -> let (_, co) = uncurry fullAdder p c
+                          in [] |- carry c (map gpOf (p .: ps))
+                                =: carry c (gpOf p .: map gpOf ps)
+                                =: carry (applyC (gpOf p) c) (map gpOf ps)
+                                ?? applyGP `at` (Inst @"p" p, Inst @"c" c)
+                                =: carry co (map gpOf ps)
+                                ?? ih `at` Inst @"c" co
+                                =: rcaCarry co ps
+                                =: rcaCarry c (p .: ps)
+                                =: qed
diff --git a/Documentation/SBV/Examples/TP/Basics.hs b/Documentation/SBV/Examples/TP/Basics.hs
--- a/Documentation/SBV/Examples/TP/Basics.hs
+++ b/Documentation/SBV/Examples/TP/Basics.hs
@@ -11,9 +11,10 @@
 
 {-# LANGUAGE CPP                 #-}
 {-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeAbstractions    #-}
 {-# LANGUAGE TypeApplications    #-}
-{-# LANGUAGE ScopedTypeVariables #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -43,7 +44,7 @@
 -- We have:
 --
 -- >>> trueIsProvable
--- Lemma: true                             Q.E.D.
+-- Lemma: true         Q.E.D.
 -- [Proven] true :: Bool
 trueIsProvable :: IO (Proof SBool)
 trueIsProvable = runTP $ lemma "true" sTrue []
@@ -67,7 +68,7 @@
 --
 -- We have:
 -- >>> largerIntegerExists
--- Lemma: largerIntegerExists              Q.E.D.
+-- Lemma: largerIntegerExists    Q.E.D.
 -- [Proven] largerIntegerExists :: Ɐx ∷ Integer → ∃y ∷ Integer → Bool
 largerIntegerExists :: IO (Proof (Forall "x" Integer -> Exists "y" Integer -> SBool))
 largerIntegerExists = runTP $ lemma "largerIntegerExists"
@@ -79,7 +80,7 @@
 -- | Pushing a universal through conjunction. We have:
 --
 -- >>> forallConjunction @Integer (uninterpret "p") (uninterpret "q")
--- Lemma: forallConjunction                Q.E.D.
+-- Lemma: forallConjunction    Q.E.D.
 -- [Proven] forallConjunction :: Bool
 forallConjunction :: forall a. SymVal a => (SBV a -> SBool) -> (SBV a -> SBool) -> IO (Proof SBool)
 forallConjunction p q = runTP $ do
@@ -95,7 +96,7 @@
 -- | Pushing an existential through disjunction. We have:
 --
 -- >>> existsDisjunction @Integer (uninterpret "p") (uninterpret "q")
--- Lemma: existsDisjunction                Q.E.D.
+-- Lemma: existsDisjunction    Q.E.D.
 -- [Proven] existsDisjunction :: Bool
 existsDisjunction :: forall a. SymVal a => (SBV a -> SBool) -> (SBV a -> SBool) -> IO (Proof SBool)
 existsDisjunction p q = runTP $ do
@@ -115,18 +116,18 @@
 -- *** Failed to prove forallConjunctionNot.
 -- Falsifiable. Counter-example:
 --   p :: Integer -> Bool
---   p 2 = True
---   p 1 = False
+--   p 4 = True
+--   p 3 = False
 --   p _ = True
 -- <BLANKLINE>
 --   q :: Integer -> Bool
---   q 2 = False
---   q 1 = True
+--   q 4 = False
+--   q 3 = True
 --   q _ = True
 --
--- Note how @p@ assigns two selected values to @True@ and everything else to @False@, while @q@ does the exact opposite.
--- So, there is no common value that satisfies both, providing a counter-example. (It's not clear why the solver finds
--- a model with two distinct values, as one would have sufficed. But it is still a valud model.)
+-- Note how @p@ and @q@ differ in their treatment of the inputs 3 and 4, but agree everywhere else. So, for each
+-- input, at least one of @p@ or @q@ is @True@, making the disjunction @True@ for all inputs. But the predicates
+-- @p@ and @q@ are not universally true themselves, constituting a counter-example.
 forallDisjunctionNot :: forall a. SymVal a => (SBV a -> SBool) -> (SBV a -> SBool) -> IO ()
 forallDisjunctionNot p q = runTP $ do
     let qb = quantifiedBool
@@ -148,14 +149,15 @@
 -- *** Failed to prove existsConjunctionNot.
 -- Falsifiable. Counter-example:
 --   p :: Integer -> Bool
---   p 1 = False
+--   p 3 = False
 --   p _ = True
 -- <BLANKLINE>
 --   q :: Integer -> Bool
---   q 1 = True
+--   q 3 = True
 --   q _ = False
 --
--- In this case, we again have a predicate That disagree at every point, providing a counter-example.
+-- In this case, both @p@ and @q@ have a satisfying input (for @p@ everything but 3, for @q@, only 3), but
+-- there is no single value that satisfies both, thus giving us our counter-example.
 existsConjunctionNot :: forall a. SymVal a => (SBV a -> SBool) -> (SBV a -> SBool) -> IO ()
 existsConjunctionNot p q = runTP $ do
     let qb = quantifiedBool
@@ -178,7 +180,7 @@
 -- Lemma: qcExample
 --   Step: 1 (passed 1000 tests)           Q.E.D. [Modulo: quickCheck]
 --   Step: 2 (Failed during quickTest)
--- 
+--
 -- *** QuickCheck failed for qcExample.2
 -- *** Failed! Assertion failed (after 1 test):
 --   n   = 175 :: Word8
@@ -205,8 +207,8 @@
 --
 -- >>> runTP (qcFermat 3)
 -- Lemma: qcFermat 3
---   Step: 1 (qc: Running 1000 tests)      QC OK
---   Result:                               Q.E.D. [Modulo: quickCheck]
+--   Step: 1 (qc: Running 1000 tests)    QC OK
+--   Result:                             Q.E.D. [Modulo: quickCheck]
 -- [Modulo: quickCheck] qcFermat 3 :: Ɐx ∷ Integer → Ɐy ∷ Integer → Ɐz ∷ Integer → Bool
 qcFermat :: Integer -> TP (Proof (Forall "x" Integer -> Forall "y" Integer -> Forall "z" Integer -> SBool))
 qcFermat e = calc ("qcFermat " <> show e)
@@ -218,32 +220,137 @@
                          =: qed
   where n = literal e
 
--- * No termination checks
+-- * Termination checking
 
--- | It's important to realize that TP proofs in SBV neither check nor guarantee that the
--- functions we use are terminating. This is beyond the scope (and current capabilities) of what SBV can handle.
--- That is, the proof is up-to-termination, i.e., any proof implicitly assumes all functions defined (or axiomatized)
--- terminate for all possible inputs. If non-termination is possible, then the logic becomes inconsistent, i.e.,
+-- | When a recursive function is defined via 'smtFunction', SBV automatically checks that it terminates
+-- by guessing and verifying a termination measure. Here we define a simple recursive @sumToN@ and prove
+-- a property about it. Note the @Functions proven terminating@ line in the output, confirming that SBV
+-- verified the termination of @sumToN@ before proceeding with the proof.
+--
+-- >>> terminationDemo
+-- Lemma: sumToN_at_5    Q.E.D.
+-- Functions proven terminating: sumToN
+-- [Proven] sumToN_at_5 :: Ɐn ∷ Integer → Bool
+terminationDemo :: IO (Proof (Forall "n" Integer -> SBool))
+terminationDemo = runTP $ do
+    let sumToN :: SInteger -> SInteger
+        sumToN = smtFunction "sumToN" $ \x -> [sCase| x of
+                                                 _ | x .<= 0 -> 0
+                                                 _           -> x + sumToN (x - 1)
+                                              |]
+
+    lemma "sumToN_at_5"
+          (\(Forall n) -> n .== 5 .=> sumToN n .== 15)
+          []
+
+-- | If SBV cannot determine a termination measure, it will report an error. Here, we define
+-- a function that recurses without decreasing any argument, and SBV rightfully rejects it:
+--
+-- >>> badTermination `catch` (\(e :: SomeException) -> mapM_ putStrLn . filter (\l -> take 3 l == "***") . lines $ show e)
+-- *** Data.SBV: Cannot determine a termination measure.
+-- ***
+-- ***   Function: bad :: SBV Integer -> SBV Integer
+-- ***
+-- ***   Measures tried:
+-- ***     abs arg1
+-- ***     smax 0 arg1
+-- ***     abs arg1 + smax 0 arg1
+-- ***     (abs arg1, smax 0 arg1)
+-- ***     (smax 0 arg1, abs arg1)
+-- ***
+-- *** Please use 'smtFunctionWithMeasure' to provide an explicit measure.
+badTermination :: IO ()
+badTermination = do
+    let bad :: SInteger -> SInteger
+        bad = smtFunction "bad" $ \x -> [sCase| x of
+                                           _ | x .== 0 -> 0
+                                           _           -> bad x
+                                        |]
+    r <- prove $ \x -> bad x .== bad x
+    print r
+
+-- | If the user provides an explicit but incorrect termination measure via 'smtFunctionWithMeasure',
+-- SBV will detect this and report an error. Here, we use @const 0@ as a measure, which clearly
+-- does not decrease at recursive calls:
+--
+-- >>> badMeasure `catch` (\(e :: SomeException) -> mapM_ putStrLn . filter (\l -> take 3 l == "***") . lines $ show e)
+-- *** Data.SBV: Termination measure does not strictly decrease at a recursive call site.
+-- ***
+-- ***   Function: badM :: SBV Integer -> SBV Integer
+-- ***
+-- ***   Falsifiable. Counter-example:
+-- ***     arg    = 1 :: Integer
+-- ***     before = 0 :: Integer
+-- ***     then   = 0 :: Integer
+-- ***
+-- *** The measure must strictly decrease at every recursive call.
+badMeasure :: IO ()
+badMeasure = do
+    let badM :: SInteger -> SInteger
+        badM = smtFunctionWithMeasure "badM" (const (0 :: SInteger), [])
+             $ \x -> [sCase| x of
+                        _ | x .<= 0 -> 0
+                        _           -> x + badM (x - 1)
+                     |]
+    r <- prove $ \x -> badM x .== badM x
+    print r
+
+-- | A termination measure is only a valid argument for termination if it takes values in a
+-- /well-founded/ order: one with no infinite descending chains. Being non-negative and strictly
+-- decreasing then forces the recursion to stop. The integers (bounded below by @0@) are well-founded,
+-- but the reals are /not/: the chain @1, 1\/2, 1\/4, ...@ descends forever without ever reaching a
+-- minimum. So a real-valued measure proves nothing.
+--
+-- Consider this Zeno-style non-terminating recursion: for any @x > 0@, the argument @x \/ 2@ is
+-- again positive, so it never reaches the base case. Yet the measure @0 `smax` x@ is non-negative
+-- and strictly decreases at the recursive call (@x \/ 2 < x@). Accepting it would mean certifying a
+-- non-terminating function as terminating, which can be used to derive falsehoods.
+--
+-- @
+-- zeno :: SReal -> SReal
+-- zeno = smtFunctionWithMeasure \"zeno\" (\\x -> 0 \`smax\` x, [])
+--      $ \\x -> ite (x .<= 0) 0 (zeno (x \/ 2))
+-- @
+--
+-- SBV rules this out /at compile time/: the 'Data.SBV.Zero' class gates which types may be used as
+-- measures, and there is deliberately no instance for algebraic reals. So the definition above does
+-- not type-check, reporting:
+--
+-- @
+--     • A termination measure may not have a real-valued result.
+--
+--       The reals are not well-ordered: an infinite descending chain such as
+--       1, 1\/2, 1\/4, ... has no least element, so a non-negative and strictly
+--       decreasing real measure does not imply termination.
+--
+--       Use an integer-valued measure instead (e.g. a count of remaining steps).
+-- @
+
+-- * Axioms and consistency
+
+-- | SBV checks that recursive functions defined via 'smtFunction' terminate, verifying a termination measure, which
+-- can be auto-guessed or specified by the user. However, axioms are taken on faith: they are not checked for consistency.
+-- If an axiom introduces a non-terminating or contradictory definition, the logic becomes inconsistent, i.e.,
 -- we can prove arbitrary results.
 --
--- Here is a simple example where we tell SBV that there is a function @f@ with non terminating behavior. Using this,
--- we can deduce @False@:
+-- Here is a simple example where we assert an axiom equivalent to a non-terminating definition @f n == 1 + f n@.
+-- Using this, we can deduce @False@:
 --
--- >>> noTerminationChecks
+-- >>> axiomsAreDangerous
 -- Axiom: bad
--- Lemma: noTerminationImpliesFalse
---   Step: 1 (bad @ (n |-> 0 :: SInteger)) Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] noTerminationImpliesFalse :: Bool
-noTerminationChecks :: IO (Proof SBool)
-noTerminationChecks = runTP $ do
+-- Lemma: axiomsCanBeInconsistent
+--   Step: 1 (bad @ (n |-> 0 :: SInteger))    Q.E.D.
+--   Result:                                  Q.E.D.
+-- [Proven] axiomsCanBeInconsistent :: Bool
+axiomsAreDangerous :: IO (Proof SBool)
+axiomsAreDangerous = runTP $ do
 
    let f :: SInteger -> SInteger
        f = uninterpret "f"
 
    badAxiom <- axiom "bad" (\(Forall n) -> f n .== 1 + f n)
 
-   calc "noTerminationImpliesFalse"
+   calc "axiomsCanBeInconsistent"
         sFalse
         ([] |- f 0
             ?? badAxiom `at` Inst @"n" (0 :: SInteger)
@@ -261,7 +368,7 @@
 -- Lemma: badRevLen
 -- *** Failed to prove badRevLen.
 -- Falsifiable. Counter-example:
---   xs = [17,17,17] :: [Integer]
+--   xs = [20,20,20] :: [Integer]
 badRevLen :: IO ()
 badRevLen = runTP $
    void $ lemma "badRevLen"
@@ -277,7 +384,7 @@
 -- Lemma: badLengthProof
 -- *** Failed to prove badLengthProof.
 -- Falsifiable. Counter-example:
---   xs   = [12,15,20,24,33,42] :: [Integer]
+--   xs   = [13,16,19,24,34,42] :: [Integer]
 --   imp  =                  42 :: Integer
 --   spec =                   6 :: Integer
 badLengthProof :: IO ()
@@ -292,48 +399,29 @@
 -- | It is not unusual that TP proofs rely on other proofs. Typically, all the helpers are used together and proven in
 -- one go. It is, however, useful to be able to write these proofs as top-level entries, and reuse them multiple times
 -- in several proofs. (See "Documentation/SBV/Examples/TP/PowerMod.hs" for an example.) To avoid re-proving such
--- lemmas, you can turn on proof caching. The idea behind caching is simple: If we see a lemma with the same name being
--- proven again, then we simply reuse the last result. The catch here is that lemmas are identified by their names: Hence,
--- for caching to be sound, you need to make sure all names used in your proof are unique. Otherwise you can
--- conclude wrong results!
---
--- A good trick is to pay the price and run your entire proof without caching (which is the default) once, and if it is
--- all good, turn on caching to save time in regressions. (And rerun without caching after code changes.)
+-- lemmas, SBV caches proof results keyed by symbolic fingerprint. Use 'recall' to invoke a proof action that
+-- benefits from the cache: if the proposition has already been proved, the cached result is returned immediately.
+-- Note that 'lemma', 'calc', and 'induct' always prove from scratch and then store the result in the cache;
+-- only 'recall' performs a cache lookup.
 --
--- To demonstrate why caching can be unsound, simply consider a proof where we first prove true, and then prove false
--- but we /trick/ TP by reusing the name. If you run this, you'll see:
+-- Lemma names do not need to be unique. If you prove the same proposition under different names, 'recall' will
+-- show the aliases. If you prove different propositions under the same name, each is proved independently.
+-- To demonstrate, note that reusing the name @"evil"@ does not cause any confusion: the second call to
+-- 'lemma' proves from scratch and correctly fails:
 --
--- >>> runTP badCaching `catch` (\(_ :: SomeException) -> pure ())
--- Lemma: evil                             Q.E.D.
+-- >>> runTP duplicateNames `catch` (\(_ :: SomeException) -> pure ())
+-- Lemma: evil         Q.E.D.
 -- Lemma: evil
 -- *** Failed to prove evil.
 -- Falsifiable
 --
--- This is good, the proof failed since it's just not true. (Except for the confusing naming printed in the trace
--- due to our own choice.)
---
--- Let's see what happens if we turn caching on:
---
--- >>> runTPWith (tpCache z3) badCaching
--- Lemma: evil                             Q.E.D.
--- Cached: evil                            Q.E.D.
---
--- In this case we were able to ostensibly prove False, i.e., this result is unsound. But at least SBV warned us
--- that we used a cached proof (@evil@), reminding us that using unique names is a proof of obligation for the user
--- if caching is turned on. Clearly, we failed to uniquely name our proofs in this case.
---
--- Note that a bad proof obtained this way is unsound in the way that it is misleading: That is, it will lead you
--- to believe you proved something while you actually proved something else. (More technically, you cannot take the evil
--- lemma and use it to prove arbitrary things, since it's still just the proof of truth.) In this sense it is just
--- useless as opposed to soundness, but it is alarming as one can be led astray.
---
 -- (Incidentally, if you really want to be evil, you can just use 'axiom' and assert false, but that's another story.)
-badCaching :: TP ()
-badCaching = do
-   -- Prove true, giving it a bad name
+duplicateNames :: TP ()
+duplicateNames = do
+   -- Prove true
    _ <- lemma "evil" sTrue []
 
-   -- Attempt to prove false, using evil:
+   -- Attempt to prove false, reusing the same name. Will be caught!
    _ <- lemma "evil" sFalse []
 
    pure ()
diff --git a/Documentation/SBV/Examples/TP/BinarySearch.hs b/Documentation/SBV/Examples/TP/BinarySearch.hs
--- a/Documentation/SBV/Examples/TP/BinarySearch.hs
+++ b/Documentation/SBV/Examples/TP/BinarySearch.hs
@@ -9,10 +9,9 @@
 -- Proving binary search correct.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DataKinds           #-}
-{-# LANGUAGE TypeAbstractions    #-}
-{-# LANGUAGE TypeApplications    #-}
-{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE DataKinds        #-}
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE TypeApplications #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -37,16 +36,16 @@
 -- | Encode binary search in a functional style.
 bsearch :: Arr -> Idx -> SInteger -> SMaybe Integer
 bsearch array (low, high) = f array low high
-  where f = smtFunction "bsearch" $ \arr lo hi x ->
+  where f = smtFunctionWithMeasure "bsearch" (\_arr lo hi _x -> (hi - lo + 1) `smax` 0, [])
+          $ \arr lo hi x ->
                let mid  = (lo + hi) `sEDiv` 2
                    xmid = arr `readArray` mid
-               in ite (lo .> hi)
-                      sNothing
-                      (ite (xmid .== x)
-                           (sJust mid)
-                           (ite (xmid .< x)
-                                (bsearch arr (mid+1, hi)    x)
-                                (bsearch arr (lo,    mid-1) x)))
+               in [sCase| lo of
+                     _ | lo .> hi   -> sNothing
+                     _ | xmid .== x -> sJust mid
+                     _ | xmid .< x  -> bsearch arr (mid+1, hi)    x
+                     _              -> bsearch arr (lo,    mid-1) x
+                  |]
 
 -- * Correctness proof
 
@@ -64,51 +63,52 @@
 -- We have:
 --
 -- >>> correctness
--- Lemma: notInRange                                 Q.E.D.
--- Lemma: inRangeHigh                                Q.E.D.
--- Lemma: inRangeLow                                 Q.E.D.
--- Lemma: nonDecreasing                              Q.E.D.
+-- Lemma: notInRange                            Q.E.D.
+-- Lemma: inRangeHigh                           Q.E.D.
+-- Lemma: inRangeLow                            Q.E.D.
+-- Lemma: nonDecreasing                         Q.E.D.
 -- Inductive lemma (strong): bsearchAbsent
---   Step: Measure is non-negative                   Q.E.D.
---   Step: 1 (unfold bsearch)                        Q.E.D.
---   Step: 2 (push isNothing down, simplify)         Q.E.D.
+--   Step: Measure is non-negative              Q.E.D.
+--   Step: 1 (unfold bsearch)                   Q.E.D.
+--   Step: 2 (push isNothing down, simplify)    Q.E.D.
 --   Step: 3 (2 way case split)
---     Step: 3.1                                     Q.E.D.
---     Step: 3.2.1                                   Q.E.D.
---     Step: 3.2.2                                   Q.E.D.
---     Step: 3.2.3                                   Q.E.D.
---     Step: 3.2.4                                   Q.E.D.
---     Step: 3.2.5 (simplify)                        Q.E.D.
---     Step: 3.Completeness                          Q.E.D.
---   Result:                                         Q.E.D.
+--     Step: 3.1                                Q.E.D.
+--     Step: 3.2.1                              Q.E.D.
+--     Step: 3.2.2                              Q.E.D.
+--     Step: 3.2.3                              Q.E.D.
+--     Step: 3.2.4                              Q.E.D.
+--     Step: 3.2.5 (simplify)                   Q.E.D.
+--     Step: 3.Completeness                     Q.E.D.
+--   Result:                                    Q.E.D.
 -- Inductive lemma (strong): bsearchPresent
---   Step: Measure is non-negative                   Q.E.D.
---   Step: 1 (unfold bsearch)                        Q.E.D.
---   Step: 2 (simplify)                              Q.E.D.
+--   Step: Measure is non-negative              Q.E.D.
+--   Step: 1 (unfold bsearch)                   Q.E.D.
+--   Step: 2 (simplify)                         Q.E.D.
 --   Step: 3 (3 way case split)
---     Step: 3.1                                     Q.E.D.
---     Step: 3.2                                     Q.E.D.
---     Step: 3.3.1                                   Q.E.D.
+--     Step: 3.1                                Q.E.D.
+--     Step: 3.2                                Q.E.D.
+--     Step: 3.3.1                              Q.E.D.
 --     Step: 3.3.2 (3 way case split)
---       Step: 3.3.2.1                               Q.E.D.
---       Step: 3.3.2.2.1                             Q.E.D.
---       Step: 3.3.2.2.2                             Q.E.D.
---       Step: 3.3.2.3.1                             Q.E.D.
---       Step: 3.3.2.3.2                             Q.E.D.
---       Step: 3.3.2.Completeness                    Q.E.D.
---     Step: 3.Completeness                          Q.E.D.
---   Result:                                         Q.E.D.
+--       Step: 3.3.2.1                          Q.E.D.
+--       Step: 3.3.2.2.1                        Q.E.D.
+--       Step: 3.3.2.2.2                        Q.E.D.
+--       Step: 3.3.2.3.1                        Q.E.D.
+--       Step: 3.3.2.3.2                        Q.E.D.
+--       Step: 3.3.2.Completeness               Q.E.D.
+--     Step: 3.Completeness                     Q.E.D.
+--   Result:                                    Q.E.D.
 -- Lemma: bsearchCorrect
 --   Step: 1 (2 way case split)
---     Step: 1.1.1                                   Q.E.D.
---     Step: 1.1.2                                   Q.E.D.
---     Step: 1.2.1                                   Q.E.D.
---     Step: 1.2.2                                   Q.E.D.
---     Step: 1.Completeness                          Q.E.D.
---   Result:                                         Q.E.D.
+--     Step: 1.1.1                              Q.E.D.
+--     Step: 1.1.2                              Q.E.D.
+--     Step: 1.2.1                              Q.E.D.
+--     Step: 1.2.2                              Q.E.D.
+--     Step: 1.Completeness                     Q.E.D.
+--   Result:                                    Q.E.D.
+-- Functions proven terminating: bsearch
 -- [Proven] bsearchCorrect :: Ɐarr ∷ (ArrayModel Integer Integer) → Ɐlo ∷ Integer → Ɐhi ∷ Integer → Ɐx ∷ Integer → Bool
 correctness :: IO (Proof (Forall "arr" (ArrayModel Integer Integer) -> Forall "lo" Integer -> Forall "hi" Integer -> Forall "x" Integer -> SBool))
-correctness = runTPWith (tpRibbon 50 cvc5) $ do
+correctness = runTPWith cvc5 $ do
 
   -- Helper: if a value is not in a range, then it isn't in any subrange of it:
   notInRange <- lemma "notInRange"
@@ -142,7 +142,7 @@
   bsearchAbsent <- sInduct "bsearchAbsent"
         (\(Forall arr) (Forall lo) (Forall hi) (Forall x) ->
             nonDecreasing arr (lo, hi) .&& sNot (inArray arr (lo, hi) x) .=> isNothing (bsearch arr (lo, hi) x))
-        (\_arr lo hi _x -> abs (hi - lo + 1)) $
+        (\_arr lo hi _x -> abs (hi - lo + 1), []) $
         \ih arr lo hi x ->
               [nonDecreasing arr (lo, hi), sNot (inArray arr (lo, hi) x)]
            |- isNothing (bsearch arr (lo, hi) x)
@@ -195,7 +195,7 @@
   bsearchPresent <- sInduct "bsearchPresent"
         (\(Forall arr) (Forall lo) (Forall hi) (Forall x) ->
             nonDecreasing arr (lo, hi) .&& inArray arr (lo, hi) x .=> arr `readArray` fromJust (bsearch arr (lo, hi) x) .== x)
-        (\_arr lo hi _x -> abs (hi - lo + 1)) $
+        (\_arr lo hi _x -> abs (hi - lo + 1), []) $
         \ih arr lo hi x ->
              [nonDecreasing arr (lo, hi), inArray arr (lo, hi) x]
           |- x .== arr `readArray` fromJust (bsearch arr (lo, hi) x)
@@ -265,3 +265,5 @@
                                    =: sTrue
                                    =: qed
                               ]
+
+{- HLint ignore module "Reduce duplication" -}
diff --git a/Documentation/SBV/Examples/TP/CaseSplit.hs b/Documentation/SBV/Examples/TP/CaseSplit.hs
--- a/Documentation/SBV/Examples/TP/CaseSplit.hs
+++ b/Documentation/SBV/Examples/TP/CaseSplit.hs
@@ -9,8 +9,7 @@
 -- Use TP to prove @2n^2 + n + 1@ is never divisible by @3@.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DataKinds        #-}
-{-# LANGUAGE TypeAbstractions #-}
+{-# LANGUAGE DataKinds #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -26,11 +25,11 @@
 -- >>> notDiv3
 -- Lemma: notDiv3
 --   Step: 1 (3 way case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2                           Q.E.D.
---     Step: 1.3                           Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
+--     Step: 1.1               Q.E.D.
+--     Step: 1.2               Q.E.D.
+--     Step: 1.3               Q.E.D.
+--     Step: 1.Completeness    Q.E.D.
+--   Result:                   Q.E.D.
 -- [Proven] notDiv3 :: Ɐn ∷ Integer → Bool
 notDiv3 :: IO (Proof (Forall "n" Integer -> SBool))
 notDiv3 = runTP $ do
diff --git a/Documentation/SBV/Examples/TP/Coins.hs b/Documentation/SBV/Examples/TP/Coins.hs
new file mode 100644
--- /dev/null
+++ b/Documentation/SBV/Examples/TP/Coins.hs
@@ -0,0 +1,114 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Documentation.SBV.Examples.TP.Coins
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Proving the classic coin change theorem: For any amount @n >= 8@, you can make
+-- exact change using only 3-cent and 5-cent coins.
+--
+-- This example is inspired by: <https://github.com/imandra-ai/imandrax-examples/blob/main/src/coins.iml>
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE CPP               #-}
+{-# LANGUAGE DataKinds         #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE QuasiQuotes       #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE TypeApplications  #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Documentation.SBV.Examples.TP.Coins where
+
+import Data.SBV
+import Data.SBV.Maybe hiding (maybe)
+import Data.SBV.TP
+
+#ifdef DOCTEST
+-- $setup
+-- >>> import Data.SBV.TP
+#endif
+
+-- * Types
+
+-- | A pocket contains a count of 3-cent and 5-cent coins.
+data Pocket = Pocket { num3s :: Integer
+                     , num5s :: Integer
+                     }
+
+-- | Create a symbolic version of Pocket.
+mkSymbolic [''Pocket]
+
+-- * Making change
+
+-- | Make change for a given amount. Returns 'Nothing' if the amount is less than 8.
+-- Base cases:
+--
+--   *  8 = 3 + 5
+--   *  9 = 3 + 3 + 3
+--   * 10 = 5 + 5
+--
+-- For @n > 10@, we use change for @n-3@ and add one more 3-cent coin.
+mkChange :: SInteger -> SMaybe Pocket
+mkChange = smtFunction "mkChange" $ \n ->
+    [sCase| n of
+       _ | n .<   8 -> sNothing
+       _ | n .==  8 -> sJust (sPocket 1 1)
+       _ | n .==  9 -> sJust (sPocket 3 0)
+       _ | n .== 10 -> sJust (sPocket 0 2)
+       _            -> case mkChange (n - 3) of
+                         Nothing             -> sNothing
+                         Just (Pocket n3 n5) -> sJust (sPocket (n3 + 1) n5)
+   |]
+
+-- | Evaluate the value of a pocket (total cents).
+evalPocket :: SMaybe Pocket -> SInteger
+evalPocket mp = [sCase| mp of
+                   Nothing             -> 0
+                   Just (Pocket n3 n5) -> 3 * n3 + 5 * n5
+                |]
+
+-- * Correctness
+
+-- | Prove that for any @n >= 8@, @mkChange@ produces a pocket that evaluates to @n@.
+--
+-- We have:
+--
+-- >>> runTP correctness
+-- Inductive lemma (strong): mkChangeCorrect
+--   Step: Measure is non-negative              Q.E.D.
+--   Step: 1 (5 way case split)
+--     Step: 1.1                                Q.E.D.
+--     Step: 1.2                                Q.E.D.
+--     Step: 1.3                                Q.E.D.
+--     Step: 1.4                                Q.E.D.
+--     Step: 1.5.1                              Q.E.D.
+--     Step: 1.5.2                              Q.E.D.
+--     Step: 1.5.3                              Q.E.D.
+--     Step: 1.Completeness                     Q.E.D.
+--   Result:                                    Q.E.D.
+-- Functions proven terminating: mkChange
+-- [Proven] mkChangeCorrect :: Ɐn ∷ Integer → Bool
+correctness :: TP (Proof (Forall "n" Integer -> SBool))
+correctness =
+    sInduct "mkChangeCorrect"
+            (\(Forall n) -> n .>= 8 .=> evalPocket (mkChange n) .== n)
+            (id, []) $
+            \ih n -> [n .>= 8]
+                  |- evalPocket (mkChange n) .== n
+                  =: cases [ n .== 8  ==> trivial
+                           , n .== 9  ==> trivial
+                           , n .== 10 ==> trivial
+                           , n .< 8   ==> trivial   -- Vacuously true: contradicts n >= 8
+                           , n .> 10  ==> evalPocket (mkChange n) .== n
+                                       =: [sCase| mkChange (n - 3) of
+                                            Nothing             -> evalPocket sNothing .== n
+                                            Just (Pocket n3 n5) -> evalPocket (sJust (sPocket (n3 + 1) n5)) .== n
+                                         |]
+                                       ?? ih `at` Inst @"n" (n - 3)
+                                       =: sTrue
+                                       =: qed
+                           ]
diff --git a/Documentation/SBV/Examples/TP/Collatz.hs b/Documentation/SBV/Examples/TP/Collatz.hs
new file mode 100644
--- /dev/null
+++ b/Documentation/SBV/Examples/TP/Collatz.hs
@@ -0,0 +1,119 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Documentation.SBV.Examples.TP.Collatz
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- The Collatz function: starting from a positive integer, if it is 1 we stop;
+-- if it is even we halve it; if it is odd we triple and add one.  Whether this
+-- process terminates for every positive integer is the famous Collatz conjecture,
+-- an open problem in mathematics. Because no termination measure is known, we
+-- define 'collatz' with 'smtFunctionNoTermination', which emits the recursive
+-- definition without any termination check.
+--
+-- We then prove that 'collatz' reaches 1 for every power of two.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE CPP                 #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Documentation.SBV.Examples.TP.Collatz where
+
+import Data.SBV
+import Data.SBV.TP
+
+#ifdef DOCTEST
+-- $setup
+-- >>> import Data.SBV.TP
+#endif
+
+-- * Definitions
+
+-- | The Collatz function. Termination for all positive integers is the famous
+-- Collatz conjecture, an open problem in mathematics. We use 'smtFunctionNoTermination'
+-- since no termination measure is known.
+collatz :: SInteger -> SInteger
+collatz = smtFunctionNoTermination "collatz"
+        $ \n -> [sCase| n of
+                   1                  -> 1
+                   _ | 2 `sDivides` n -> collatz (n `sDiv` 2)
+                     | True           -> collatz (3 * n + 1)
+                |]
+
+-- | Power of two: @pow2 k = 2^k@ for @k >= 0@.
+pow2 :: SInteger -> SInteger
+pow2 = smtFunction "pow2"
+     $ \k -> [sCase| k of
+                _ | k .<= 0 -> 1
+                  | True    -> 2 * pow2 (k - 1)
+             |]
+
+-- * Helper lemmas
+
+-- | Doubling doesn't change the Collatz result.
+--
+-- >>> runTP doubling
+-- Lemma: doubling     Q.E.D. [Modulo: collatz termination]
+-- [Modulo: collatz termination] doubling :: Ɐn ∷ Integer → Bool
+doubling :: TP (Proof (Forall "n" Integer -> SBool))
+doubling = lemma "doubling" (\(Forall @"n" n) -> n .>= 1 .=> collatz (2 * n) .== collatz n) []
+
+-- | Powers of two are positive.
+--
+-- >>> runTP pow2pos
+-- Inductive lemma: pow2pos
+--   Step: Base                Q.E.D.
+--   Step: 1                   Q.E.D.
+--   Step: 2                   Q.E.D.
+--   Result:                   Q.E.D.
+-- Functions proven terminating: pow2
+-- [Proven] pow2pos :: Ɐk ∷ Integer → Bool
+pow2pos :: TP (Proof (Forall "k" Integer -> SBool))
+pow2pos = induct "pow2pos"
+                 (\(Forall @"k" k) -> pow2 k .>= 1) $
+                 \ih k -> []
+                       |- pow2 (k + 1) .>= 1
+                       =: 2 * pow2 k .>= 1
+                       ?? ih
+                       =: sTrue
+                       =: qed
+
+-- * Correctness
+
+-- | All powers of two reach 1 under the Collatz function.
+--
+-- >>> runTP collatzPow2
+-- Lemma: doubling                 Q.E.D. [Modulo: collatz termination]
+-- Lemma: pow2pos                  Q.E.D.
+-- Inductive lemma: collatzPow2
+--   Step: Base                    Q.E.D.
+--   Step: 1                       Q.E.D.
+--   Step: 2                       Q.E.D. [Modulo: collatz termination]
+--   Step: 3                       Q.E.D.
+--   Result:                       Q.E.D. [Modulo: collatz termination]
+-- Functions proven terminating: pow2
+-- [Modulo: collatz termination] collatzPow2 :: Ɐk ∷ Integer → Bool
+collatzPow2 :: TP (Proof (Forall "k" Integer -> SBool))
+collatzPow2 = do
+   dbl <- recall doubling
+   p2p <- recall pow2pos
+
+   induct "collatzPow2"
+          (\(Forall @"k" k) -> k .>= 0 .=> collatz (pow2 k) .== 1) $
+          \ih k -> [k .>= 0]
+                |- collatz (pow2 (k + 1))
+                =: collatz (2 * pow2 k)
+                ?? dbl
+                ?? p2p
+                =: collatz (pow2 k)
+                ?? ih
+                =: (1 :: SInteger)
+                =: qed
diff --git a/Documentation/SBV/Examples/TP/ConstFold.hs b/Documentation/SBV/Examples/TP/ConstFold.hs
new file mode 100644
--- /dev/null
+++ b/Documentation/SBV/Examples/TP/ConstFold.hs
@@ -0,0 +1,1523 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Documentation.SBV.Examples.TP.ConstFold
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Correctness of constant folding for a simple expression language.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE CPP                 #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Documentation.SBV.Examples.TP.ConstFold where
+
+import Prelude hiding ((++), snd)
+
+import Data.SBV
+import Data.SBV.List  as SL
+import Data.SBV.Tuple as ST
+import Data.SBV.TP
+
+-- Get the expression language definitions
+import Documentation.SBV.Examples.TP.VM
+
+#ifdef DOCTEST
+-- $setup
+-- >>> import Data.SBV
+-- >>> import Data.SBV.TP
+-- >>> :set -XTypeApplications
+#endif
+
+-- | Base expression type (used in quantifiers).
+type Exp = Expr String Integer
+
+-- | Base environment-list type (used in quantifiers).
+type EL = [(String, Integer)]
+
+-- | Symbolic expression over strings and integers.
+type SE = SExpr String Integer
+
+-- | Symbolic environment over strings and integers.
+type E = Env String Integer
+
+-- * Simplification
+
+-- | Simplify an expression at the top level, assuming sub-expressions are already folded.
+-- The rules are:
+--
+--   * @Sqr (Con v)         → Con (v*v)@
+--   * @Inc (Con v)         → Con (v+1)@
+--   * @Add (Con 0) x       → x@
+--   * @Add x (Con 0)       → x@
+--   * @Add (Con a) (Con b) → Con (a+b)@
+--   * @Mul (Con 0) x       → Con 0@
+--   * @Mul x (Con 0)       → Con 0@
+--   * @Mul (Con 1) x       → x@
+--   * @Mul x (Con 1)       → x@
+--   * @Mul (Con a) (Con b) → Con (a*b)@
+--   * @Let nm (Con v) b    → subst nm v b@
+simplify :: SE -> SE
+simplify = smtFunction "simplify" $ \expr ->
+  [sCase| expr of
+    Sqr (Con v)         -> sCon (v * v)
+
+    Inc (Con v)         -> sCon (v + 1)
+
+    Add (Con 0) r       -> r
+    Add l       (Con 0) -> l
+    Add (Con a) (Con b) -> sCon (a + b)
+
+    Mul (Con 0) _       -> sCon 0
+    Mul _       (Con 0) -> sCon 0
+    Mul (Con 1) r       -> r
+    Mul l       (Con 1) -> l
+    Mul (Con a) (Con b) -> sCon (a * b)
+
+    Let nm (Con v) b    -> subst nm v b
+
+    -- fall-thru
+    _                   -> expr
+  |]
+
+-- * Substitution
+
+-- | Substitute a variable with a value in an expression. Capture-avoiding:
+-- if a @Let@-bound variable shadows the target, we do not substitute in the body.
+--
+--   * @Var x         → if x == nm then Con v else Var x@
+--   * @Con c         → Con c@
+--   * @Sqr a         → Sqr (subst nm v a)@
+--   * @Inc a         → Inc (subst nm v a)@
+--   * @Add a b       → Add (subst nm v a) (subst nm v b)@
+--   * @Mul a b       → Mul (subst nm v a) (subst nm v b)@
+--   * @Let x a b     → Let x (subst nm v a) (if x == nm then b else subst nm v b)@
+subst :: SString -> SInteger -> SE -> SE
+subst = smtFunction "subst" $ \nm v expr ->
+  [sCase| expr of
+
+    -- Substitute for vars if name matches
+    Var x | x .== nm -> sCon v
+          | True     -> sVar x
+
+    -- pass thru
+    Con c   -> sCon c
+    Sqr a   -> sSqr (subst nm v a)
+    Inc a   -> sInc (subst nm v a)
+    Add a b -> sAdd (subst nm v a) (subst nm v b)
+    Mul a b -> sMul (subst nm v a) (subst nm v b)
+
+    -- substitute in the definition, but only substitute in the body if the name is not shadowing
+    Let x a b | x .== nm -> sLet x (subst nm v a) b
+              | True     -> sLet x (subst nm v a) (subst nm v b)
+  |]
+
+-- * Constant folding
+
+-- | Constant fold an expression bottom-up: first fold sub-expressions, then simplify.
+cfold :: SE -> SE
+cfold = smtFunction "cfold" $ \expr ->
+  [sCase| expr of
+    Var nm     -> sVar nm
+    Con v      -> sCon v
+    Sqr a      -> simplify (sSqr (cfold a))
+    Inc a      -> simplify (sInc (cfold a))
+    Add a b    -> simplify (sAdd (cfold a) (cfold b))
+    Mul a b    -> simplify (sMul (cfold a) (cfold b))
+    Let nm a b -> simplify (sLet nm (cfold a) (cfold b))
+  |]
+
+-- * Correctness
+
+-- | The size measure is always non-negative.
+--
+-- >>> runTP measureNonNeg
+-- Lemma: measureNonNeg    Q.E.D.
+-- Functions proven terminating: exprSize
+-- [Proven] measureNonNeg :: Ɐe ∷ (Expr String Integer) → Bool
+measureNonNeg :: TP (Proof (Forall "e" Exp -> SBool))
+measureNonNeg = inductiveLemma "measureNonNeg"
+                               (\(Forall @"e" (e :: SE)) -> size e .>= 0)
+                               []
+
+-- | Congruence for squaring: if @a == b@ then @a*a == b*b@.
+--
+-- >>> runTP sqrCong
+-- Lemma: sqrCong      Q.E.D.
+-- [Proven] sqrCong :: Ɐa ∷ Integer → Ɐb ∷ Integer → Bool
+sqrCong :: TP (Proof (Forall "a" Integer -> Forall "b" Integer -> SBool))
+sqrCong = lemma "sqrCong"
+                (\(Forall @"a" (a :: SInteger)) (Forall @"b" b) ->
+                      a .== b .=> a * a .== b * b) []
+
+-- | Congruence for addition on the left: if @a == b@ then @a+c == b+c@.
+--
+-- >>> runTP addCongL
+-- Lemma: addCongL     Q.E.D.
+-- [Proven] addCongL :: Ɐa ∷ Integer → Ɐb ∷ Integer → Ɐc ∷ Integer → Bool
+addCongL :: TP (Proof (Forall "a" Integer -> Forall "b" Integer -> Forall "c" Integer -> SBool))
+addCongL = lemma "addCongL"
+                 (\(Forall @"a" (a :: SInteger)) (Forall @"b" b) (Forall @"c" c) ->
+                       a .== b .=> a + c .== b + c) []
+
+-- | Congruence for addition on the right: if @b == c@ then @a+b == a+c@.
+--
+-- >>> runTP addCongR
+-- Lemma: addCongR     Q.E.D.
+-- [Proven] addCongR :: Ɐa ∷ Integer → Ɐb ∷ Integer → Ɐc ∷ Integer → Bool
+addCongR :: TP (Proof (Forall "a" Integer -> Forall "b" Integer -> Forall "c" Integer -> SBool))
+addCongR = lemma "addCongR"
+                 (\(Forall @"a" (a :: SInteger)) (Forall @"b" b) (Forall @"c" c) ->
+                       b .== c .=> a + b .== a + c) []
+
+-- | Congruence for multiplication on the left: if @a == b@ then @a*c == b*c@.
+--
+-- >>> runTP mulCongL
+-- Lemma: mulCongL     Q.E.D.
+-- [Proven] mulCongL :: Ɐa ∷ Integer → Ɐb ∷ Integer → Ɐc ∷ Integer → Bool
+mulCongL :: TP (Proof (Forall "a" Integer -> Forall "b" Integer -> Forall "c" Integer -> SBool))
+mulCongL = lemma "mulCongL"
+                 (\(Forall @"a" (a :: SInteger)) (Forall @"b" b) (Forall @"c" c) ->
+                       a .== b .=> a * c .== b * c) []
+
+-- | Congruence for multiplication on the right: if @b == c@ then @a*b == a*c@.
+--
+-- >>> runTP mulCongR
+-- Lemma: mulCongR     Q.E.D.
+-- [Proven] mulCongR :: Ɐa ∷ Integer → Ɐb ∷ Integer → Ɐc ∷ Integer → Bool
+mulCongR :: TP (Proof (Forall "a" Integer -> Forall "b" Integer -> Forall "c" Integer -> SBool))
+mulCongR = lemma "mulCongR"
+                 (\(Forall @"a" (a :: SInteger)) (Forall @"b" b) (Forall @"c" c) ->
+                       b .== c .=> a * b .== a * c) []
+
+-- | Unfolding @interpInEnv@ over @Sqr@.
+--
+-- >>> runTP sqrHelper
+-- Lemma: sqrHelper    Q.E.D.
+-- Functions proven terminating: interpInEnv, sbv.lookup
+-- [Proven] sqrHelper :: Ɐenv ∷ [(String, Integer)] → Ɐa ∷ (Expr String Integer) → Bool
+sqrHelper :: TP (Proof (Forall "env" EL -> Forall "a" Exp -> SBool))
+sqrHelper = lemma "sqrHelper"
+                  (\(Forall @"env" (env :: E)) (Forall @"a" a) ->
+                        interpInEnv env (sSqr a) .== interpInEnv env a * interpInEnv env a) []
+
+-- | Unfolding @interpInEnv@ over @Add@.
+--
+-- >>> runTP addHelper
+-- Lemma: addHelper    Q.E.D.
+-- Functions proven terminating: interpInEnv, sbv.lookup
+-- [Proven] addHelper :: Ɐenv ∷ [(String, Integer)] → Ɐa ∷ (Expr String Integer) → Ɐb ∷ (Expr String Integer) → Bool
+addHelper :: TP (Proof (Forall "env" EL -> Forall "a" Exp -> Forall "b" Exp -> SBool))
+addHelper = lemma "addHelper"
+                  (\(Forall @"env" (env :: E)) (Forall @"a" a) (Forall @"b" b) ->
+                        interpInEnv env (sAdd a b) .== interpInEnv env a + interpInEnv env b) []
+
+-- | Unfolding @interpInEnv@ over @Mul@.
+--
+-- >>> runTP mulHelper
+-- Lemma: mulHelper    Q.E.D.
+-- Functions proven terminating: interpInEnv, sbv.lookup
+-- [Proven] mulHelper :: Ɐenv ∷ [(String, Integer)] → Ɐa ∷ (Expr String Integer) → Ɐb ∷ (Expr String Integer) → Bool
+mulHelper :: TP (Proof (Forall "env" EL -> Forall "a" Exp -> Forall "b" Exp -> SBool))
+mulHelper = lemma "mulHelper"
+                  (\(Forall @"env" (env :: E)) (Forall @"a" a) (Forall @"b" b) ->
+                        interpInEnv env (sMul a b) .== interpInEnv env a * interpInEnv env b) []
+
+-- | Unfolding @interpInEnv@ over @Let@.
+--
+-- >>> runTP letHelper
+-- Lemma: letHelper    Q.E.D.
+-- Functions proven terminating: interpInEnv, sbv.lookup
+-- [Proven] letHelper :: Ɐenv ∷ [(String, Integer)] → Ɐnm ∷ String → Ɐa ∷ (Expr String Integer) → Ɐb ∷ (Expr String Integer) → Bool
+letHelper :: TP (Proof (Forall "env" EL -> Forall "nm" String -> Forall "a" Exp -> Forall "b" Exp -> SBool))
+letHelper = lemma "letHelper"
+                  (\(Forall @"env" (env :: E)) (Forall @"nm" nm) (Forall @"a" a) (Forall @"b" b) ->
+                        interpInEnv env (sLet nm a b) .== interpInEnv (ST.tuple (nm, interpInEnv env a) .: env) b) []
+
+-- * Environment lemmas
+
+-- | Swapping two adjacent bindings with distinct keys does not affect lookup.
+--
+-- >>> runTP lookupSwap
+-- Lemma: lookupSwap
+--   Step: 1 (2 way case split)
+--     Step: 1.1               Q.E.D.
+--     Step: 1.2.1             Q.E.D.
+--     Step: 1.2.2             Q.E.D.
+--     Step: 1.Completeness    Q.E.D.
+--   Result:                   Q.E.D.
+-- Functions proven terminating: sbv.lookup
+-- [Proven] lookupSwap :: Ɐk ∷ String → Ɐb1 ∷ (String, Integer) → Ɐb2 ∷ (String, Integer) → Ɐenv ∷ [(String, Integer)] → Bool
+lookupSwap :: TP (Proof (Forall "k" String -> Forall "b1" (String, Integer)
+                      -> Forall "b2" (String, Integer) -> Forall "env" EL -> SBool))
+lookupSwap = calc "lookupSwap"
+                  (\(Forall @"k" (k :: SString)) (Forall @"b1" (b1 :: STuple String Integer))
+                    (Forall @"b2" (b2 :: STuple String Integer)) (Forall @"env" (env :: E)) ->
+                      let (x, _) = ST.untuple b1
+                          (y, _) = ST.untuple b2
+                      in  x ./= y .=> SL.lookup k (b1 .: b2 .: env) .== SL.lookup k (b2 .: b1 .: env)) $
+                  \k b1 b2 env ->
+                      let (x, _) = ST.untuple b1
+                          (y, _) = ST.untuple b2
+                      in [x ./= y]
+                      |- cases [ k .== x
+                                 ==> SL.lookup k (b1 .: b2 .: env)
+                                  =: SL.lookup k (b2 .: b1 .: env)
+                                  =: qed
+                               , k ./= x
+                                 ==> SL.lookup k (b1 .: b2 .: env)
+                                  =: SL.lookup k (b2 .: env)
+                                  =: SL.lookup k (b2 .: b1 .: env)
+                                  =: qed
+                               ]
+
+-- | One-step unfolding of 'SL.lookup' on a cons cell. The solver can expand the
+-- @define-fun-rec@ but struggles to fold it back, so we provide this as a reusable hint.
+--
+-- >>> runTP lookupCons
+-- Lemma: lookupCons    Q.E.D.
+-- Functions proven terminating: sbv.lookup
+-- [Proven] lookupCons :: Ɐk ∷ String → Ɐb ∷ (String, Integer) → Ɐrest ∷ [(String, Integer)] → Bool
+lookupCons :: TP (Proof (Forall "k" String -> Forall "b" (String, Integer) -> Forall "rest" EL -> SBool))
+lookupCons = lemma "lookupCons"
+   (\(Forall @"k" (k :: SString)) (Forall @"b" (b :: STuple String Integer)) (Forall @"rest" (rest :: E)) ->
+      let (bk, bv) = ST.untuple b
+      in SL.lookup k (b .: rest) .== ite (k .== bk) bv (SL.lookup k rest))
+   []
+
+-- | Generalized swap: swapping two adjacent distinct-keyed bindings behind
+-- a prefix does not affect lookup.
+--
+-- >>> runTP lookupSwapPfx
+-- Lemma: lookupSwap                          Q.E.D.
+-- Lemma: lookupCons                          Q.E.D.
+-- Inductive lemma (strong): lookupSwapPfx
+--   Step: Measure is non-negative            Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1 (base)                       Q.E.D.
+--     Step: 1.2.1 (cons)                     Q.E.D.
+--     Step: 1.2.2                            Q.E.D.
+--     Step: 1.2.3                            Q.E.D.
+--     Step: 1.2.4                            Q.E.D.
+--     Step: 1.2.5                            Q.E.D.
+--     Step: 1.Completeness                   Q.E.D.
+--   Result:                                  Q.E.D.
+-- Functions proven terminating: sbv.lookup
+-- [Proven] lookupSwapPfx :: Ɐpfx ∷ [(String, Integer)] → Ɐk ∷ String → Ɐb1 ∷ (String, Integer) → Ɐb2 ∷ (String, Integer) → Ɐenv ∷ [(String, Integer)] → Bool
+lookupSwapPfx :: TP (Proof (Forall "pfx" EL -> Forall "k" String -> Forall "b1" (String, Integer)
+                         -> Forall "b2" (String, Integer) -> Forall "env" EL -> SBool))
+lookupSwapPfx = do
+   lkS <- recall lookupSwap
+   lkC <- recall lookupCons
+
+   sInduct "lookupSwapPfx"
+     (\(Forall @"pfx" (pfx :: E)) (Forall @"k" (k :: SString)) (Forall @"b1" (b1 :: STuple String Integer))
+       (Forall @"b2" (b2 :: STuple String Integer)) (Forall @"env" (env :: E)) ->
+         let (x, _) = ST.untuple b1
+             (y, _) = ST.untuple b2
+         in  x ./= y .=>    SL.lookup k (pfx ++ b1 .: b2 .: env)
+                         .== SL.lookup k (pfx ++ b2 .: b1 .: env))
+     (\pfx _ _ _ _ -> SL.length pfx :: SInteger, []) $
+     \ih pfx k b1 b2 env ->
+       let (x, _) = ST.untuple b1
+           (y, _) = ST.untuple b2
+       in [x ./= y]
+       |- cases [ SL.null pfx
+                  ==> SL.lookup k (pfx ++ b1 .: b2 .: env)
+                   ?? "base"
+                   ?? lkS `at` (Inst @"k" k, Inst @"b1" b1, Inst @"b2" b2, Inst @"env" env)
+                   =: SL.lookup k (pfx ++ b2 .: b1 .: env)
+                   =: qed
+                , sNot (SL.null pfx)
+                  ==> let h      = SL.head pfx
+                          t      = SL.tail pfx
+                          (hk, hv) = ST.untuple h
+                       in SL.lookup k (pfx ++ b1 .: b2 .: env)
+                       ?? "cons"
+                       ?? pfx .== h .: t
+                       =: SL.lookup k (h .: (t ++ b1 .: b2 .: env))
+                       =: ite (k .== hk) hv (SL.lookup k (t ++ b1 .: b2 .: env))
+                       ?? ih `at` (Inst @"pfx" t, Inst @"k" k, Inst @"b1" b1, Inst @"b2" b2, Inst @"env" env)
+                       =: ite (k .== hk) hv (SL.lookup k (t ++ b2 .: b1 .: env))
+                       ?? lkC `at` (Inst @"k" k, Inst @"b" h, Inst @"rest" (t ++ b2 .: b1 .: env))
+                       =: SL.lookup k (h .: (t ++ b2 .: b1 .: env))
+                       =: SL.lookup k (pfx ++ b2 .: b1 .: env)
+                       =: qed
+                ]
+
+-- | A shadowed binding does not affect lookup: if the same key appears first, the second is irrelevant.
+--
+-- >>> runTP lookupShadow
+-- Lemma: lookupShadow    Q.E.D.
+-- Functions proven terminating: sbv.lookup
+-- [Proven] lookupShadow :: Ɐk ∷ String → Ɐb1 ∷ (String, Integer) → Ɐb2 ∷ (String, Integer) → Ɐenv ∷ [(String, Integer)] → Bool
+lookupShadow :: TP (Proof (Forall "k" String -> Forall "b1" (String, Integer)
+                        -> Forall "b2" (String, Integer) -> Forall "env" EL -> SBool))
+lookupShadow = lemma "lookupShadow"
+                     (\(Forall @"k" (k :: SString)) (Forall @"b1" (b1 :: STuple String Integer))
+                       (Forall @"b2" (b2 :: STuple String Integer)) (Forall @"env" (env :: E)) ->
+                         let (x, _) = ST.untuple b1
+                             (y, _) = ST.untuple b2
+                         in  x .== y .=>    SL.lookup k (b1 .: b2 .: env)
+                                        .== SL.lookup k (b1 .: env))
+                     []
+
+-- | Generalized shadow: a shadowed binding behind a prefix does not affect lookup.
+--
+-- >>> runTP lookupShadowPfx
+-- Lemma: lookupShadow                          Q.E.D.
+-- Lemma: lookupCons                            Q.E.D.
+-- Inductive lemma (strong): lookupShadowPfx
+--   Step: Measure is non-negative              Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1 (base)                         Q.E.D.
+--     Step: 1.2.1 (cons)                       Q.E.D.
+--     Step: 1.2.2                              Q.E.D.
+--     Step: 1.2.3                              Q.E.D.
+--     Step: 1.2.4                              Q.E.D.
+--     Step: 1.2.5                              Q.E.D.
+--     Step: 1.Completeness                     Q.E.D.
+--   Result:                                    Q.E.D.
+-- Functions proven terminating: sbv.lookup
+-- [Proven] lookupShadowPfx :: Ɐpfx ∷ [(String, Integer)] → Ɐk ∷ String → Ɐb1 ∷ (String, Integer) → Ɐb2 ∷ (String, Integer) → Ɐenv ∷ [(String, Integer)] → Bool
+lookupShadowPfx :: TP (Proof (Forall "pfx" EL -> Forall "k" String -> Forall "b1" (String, Integer)
+                           -> Forall "b2" (String, Integer) -> Forall "env" EL -> SBool))
+lookupShadowPfx = do
+   lkSh <- recall lookupShadow
+   lkC  <- recall lookupCons
+   sInduct "lookupShadowPfx"
+     (\(Forall @"pfx" (pfx :: E)) (Forall @"k" (k :: SString)) (Forall @"b1" (b1 :: STuple String Integer))
+       (Forall @"b2" (b2 :: STuple String Integer)) (Forall @"env" (env :: E)) ->
+         let (x, _) = ST.untuple b1
+             (y, _) = ST.untuple b2
+         in  x .== y .=>    SL.lookup k (pfx ++ b1 .: b2 .: env)
+                         .== SL.lookup k (pfx ++ b1 .: env))
+     (\pfx _ _ _ _ -> SL.length pfx :: SInteger, []) $
+     \ih pfx k b1 b2 env ->
+       let (x, _) = ST.untuple b1
+           (y, _) = ST.untuple b2
+       in [x .== y]
+       |- cases [ SL.null pfx
+                  ==> SL.lookup k (pfx ++ b1 .: b2 .: env)
+                   ?? "base"
+                   ?? lkSh `at` (Inst @"k" k, Inst @"b1" b1, Inst @"b2" b2, Inst @"env" env)
+                   =: SL.lookup k (pfx ++ b1 .: env)
+                   =: qed
+                , sNot (SL.null pfx)
+                  ==> let h  = SL.head pfx
+                          t  = SL.tail pfx
+                          (hk, hv) = ST.untuple h
+                       in SL.lookup k (pfx ++ b1 .: b2 .: env)
+                       ?? "cons"
+                       ?? pfx .== h .: t
+                       =: SL.lookup k (h .: (t ++ b1 .: b2 .: env))
+                       =: ite (k .== hk) hv (SL.lookup k (t ++ b1 .: b2 .: env))
+                       ?? ih `at` (Inst @"pfx" t, Inst @"k" k, Inst @"b1" b1, Inst @"b2" b2, Inst @"env" env)
+                       =: ite (k .== hk) hv (SL.lookup k (t ++ b1 .: env))
+                       ?? lkC `at` (Inst @"k" k, Inst @"b" h, Inst @"rest" (t ++ b1 .: env))
+                       =: SL.lookup k (h .: (t ++ b1 .: env))
+                       =: SL.lookup k (pfx ++ b1 .: env)
+                       =: qed
+                ]
+
+-- | Swapping two adjacent distinct-keyed bindings in the environment
+-- does not affect interpretation. The @pfx@ parameter allows the swap
+-- to happen at any depth in the environment.
+--
+-- >>> runTPWith cvc5 envSwap
+-- Lemma: measureNonNeg                       Q.E.D.
+-- Lemma: lookupSwapPfx                       Q.E.D.
+-- Lemma: sqrCong                             Q.E.D.
+-- Lemma: sqrHelper                           Q.E.D.
+-- Lemma: addCongL                            Q.E.D.
+-- Lemma: addCongR                            Q.E.D.
+-- Lemma: addHelper                           Q.E.D.
+-- Lemma: mulCongL                            Q.E.D.
+-- Lemma: mulCongR                            Q.E.D.
+-- Lemma: mulHelper                           Q.E.D.
+-- Lemma: letHelper                           Q.E.D.
+-- Inductive lemma (strong): envSwap
+--   Step: Measure is non-negative            Q.E.D.
+--   Step: 1 (7 way case split)
+--     Step: 1.1 (Var)                        Q.E.D.
+--     Step: 1.2 (Con)                        Q.E.D.
+--     Step: 1.3.1 (Sqr)                      Q.E.D.
+--     Step: 1.3.2                            Q.E.D.
+--     Step: 1.3.3                            Q.E.D.
+--     Step: 1.4 (Inc)                        Q.E.D.
+--     Step: 1.5.1 (Add)                      Q.E.D.
+--     Step: 1.5.2                            Q.E.D.
+--     Step: 1.5.3                            Q.E.D.
+--     Step: 1.5.4                            Q.E.D.
+--     Step: 1.6.1 (Mul)                      Q.E.D.
+--     Step: 1.6.2                            Q.E.D.
+--     Step: 1.6.3                            Q.E.D.
+--     Step: 1.6.4                            Q.E.D.
+--     Step: 1.7.1 (Let)                      Q.E.D.
+--     Step: 1.7.2                            Q.E.D.
+--     Step: 1.7.3                            Q.E.D.
+--     Step: 1.7.4                            Q.E.D.
+--     Step: 1.Completeness                   Q.E.D.
+--   Result:                                  Q.E.D.
+-- Functions proven terminating: exprSize, interpInEnv, sbv.lookup
+-- [Proven] envSwap :: Ɐe ∷ (Expr String Integer) → Ɐpfx ∷ [(String, Integer)] → Ɐenv ∷ [(String, Integer)] → Ɐb1 ∷ (String, Integer) → Ɐb2 ∷ (String, Integer) → Bool
+envSwap :: TP (Proof (Forall "e" Exp -> Forall "pfx" EL -> Forall "env" EL
+                   -> Forall "b1" (String, Integer) -> Forall "b2" (String, Integer) -> SBool))
+envSwap = do
+   mnn   <- recall measureNonNeg
+   lkSP  <- recall lookupSwapPfx
+   sqrC  <- recall sqrCong
+   sqrH  <- recall sqrHelper
+   addCL <- recall addCongL
+   addCR <- recall addCongR
+   addH  <- recall addHelper
+   mulCL <- recall mulCongL
+   mulCR <- recall mulCongR
+   mulH  <- recall mulHelper
+   letH  <- recall letHelper
+
+   sInduct "envSwap"
+     (\(Forall @"e" (e :: SE)) (Forall @"pfx" (pfx :: E)) (Forall @"env" (env :: E))
+       (Forall @"b1" (b1 :: STuple String Integer)) (Forall @"b2" (b2 :: STuple String Integer)) ->
+       let (x, _)  = ST.untuple b1
+           (y, _)  = ST.untuple b2
+       in x ./= y .=> interpInEnv (pfx ++ b1 .: b2 .: env) e .== interpInEnv (pfx ++ b2 .: b1 .: env) e)
+     (\e _ _ _ _ -> size e :: SInteger, [proofOf mnn]) $
+     \ih e pfx env b1 b2 ->
+       let (x, _) = ST.untuple b1
+           (y, _) = ST.untuple b2
+           env1 = pfx ++ b1 .: b2 .: env
+           env2 = pfx ++ b2 .: b1 .: env
+       in [x ./= y]
+       |- cases [ isVar e
+                  ==> let nm = svar e
+                    in interpInEnv env1 (sVar nm)
+                    ?? "Var"
+                    ?? lkSP `at` (Inst @"pfx" pfx, Inst @"k" nm, Inst @"b1" b1, Inst @"b2" b2, Inst @"env" env)
+                    =: interpInEnv env2 (sVar nm)
+                    =: qed
+
+                , isCon e
+                  ==> let v = scon e
+                    in interpInEnv env1 (sCon v)
+                    ?? "Con"
+                    =: interpInEnv env2 (sCon v)
+                    =: qed
+
+                , isSqr e
+                  ==> let a = ssqrVal e
+                    in interpInEnv env1 (sSqr a)
+                    ?? "Sqr"
+                    ?? sqrH `at` (Inst @"env" env1, Inst @"a" a)
+                    =: interpInEnv env1 a * interpInEnv env1 a
+                    ?? ih `at` (Inst @"e" a, Inst @"pfx" pfx, Inst @"env" env, Inst @"b1" b1, Inst @"b2" b2)
+                    ?? sqrC `at` (Inst @"a" (interpInEnv env1 a), Inst @"b" (interpInEnv env2 a))
+                    =: interpInEnv env2 a * interpInEnv env2 a
+                    ?? sqrH `at` (Inst @"env" env2, Inst @"a" a)
+                    =: interpInEnv env2 (sSqr a)
+                    =: qed
+
+                , isInc e
+                  ==> let a = sincVal e
+                    in interpInEnv env1 (sInc a)
+                    ?? "Inc"
+                    ?? ih `at` (Inst @"e" a, Inst @"pfx" pfx, Inst @"env" env, Inst @"b1" b1, Inst @"b2" b2)
+                    =: interpInEnv env2 (sInc a)
+                    =: qed
+
+                , isAdd e
+                  ==> let a = sadd1 e
+                          b = sadd2 e
+                    in interpInEnv env1 (sAdd a b)
+                    ?? "Add"
+                    ?? addH `at` (Inst @"env" env1, Inst @"a" a, Inst @"b" b)
+                    =: interpInEnv env1 a + interpInEnv env1 b
+                    ?? ih `at` (Inst @"e" a, Inst @"pfx" pfx, Inst @"env" env, Inst @"b1" b1, Inst @"b2" b2)
+                    ?? addCL `at` (Inst @"a" (interpInEnv env1 a), Inst @"b" (interpInEnv env2 a), Inst @"c" (interpInEnv env1 b))
+                    =: interpInEnv env2 a + interpInEnv env1 b
+                    ?? ih `at` (Inst @"e" b, Inst @"pfx" pfx, Inst @"env" env, Inst @"b1" b1, Inst @"b2" b2)
+                    ?? addCR `at` (Inst @"a" (interpInEnv env2 a), Inst @"b" (interpInEnv env1 b), Inst @"c" (interpInEnv env2 b))
+                    =: interpInEnv env2 a + interpInEnv env2 b
+                    ?? addH `at` (Inst @"env" env2, Inst @"a" a, Inst @"b" b)
+                    =: interpInEnv env2 (sAdd a b)
+                    =: qed
+
+                , isMul e
+                  ==> let a = smul1 e
+                          b = smul2 e
+                    in interpInEnv env1 (sMul a b)
+                    ?? "Mul"
+                    ?? mulH `at` (Inst @"env" env1, Inst @"a" a, Inst @"b" b)
+                    =: interpInEnv env1 a * interpInEnv env1 b
+                    ?? ih `at` (Inst @"e" a, Inst @"pfx" pfx, Inst @"env" env, Inst @"b1" b1, Inst @"b2" b2)
+                    ?? mulCL `at` (Inst @"a" (interpInEnv env1 a), Inst @"b" (interpInEnv env2 a), Inst @"c" (interpInEnv env1 b))
+                    =: interpInEnv env2 a * interpInEnv env1 b
+                    ?? ih `at` (Inst @"e" b, Inst @"pfx" pfx, Inst @"env" env, Inst @"b1" b1, Inst @"b2" b2)
+                    ?? mulCR `at` (Inst @"a" (interpInEnv env2 a), Inst @"b" (interpInEnv env1 b), Inst @"c" (interpInEnv env2 b))
+                    =: interpInEnv env2 a * interpInEnv env2 b
+                    ?? mulH `at` (Inst @"env" env2, Inst @"a" a, Inst @"b" b)
+                    =: interpInEnv env2 (sMul a b)
+                    =: qed
+
+                , isLet e
+                  ==> let nm = slvar  e
+                          a  = slval  e
+                          b  = slbody e
+                          val1 = interpInEnv env1 a
+                          val2 = interpInEnv env2 a
+                    in interpInEnv env1 (sLet nm a b)
+                    ?? "Let"
+                    ?? letH `at` (Inst @"env" env1, Inst @"nm" nm, Inst @"a" a, Inst @"b" b)
+                    =: interpInEnv (ST.tuple (nm, val1) .: env1) b
+                    ?? ih `at` (Inst @"e" a, Inst @"pfx" pfx, Inst @"env" env, Inst @"b1" b1, Inst @"b2" b2)
+                    =: interpInEnv (ST.tuple (nm, val2) .: env1) b
+                    ?? ih `at` (Inst @"e" b, Inst @"pfx" (ST.tuple (nm, val2) .: pfx), Inst @"env" env, Inst @"b1" b1, Inst @"b2" b2)
+                    =: interpInEnv (ST.tuple (nm, val2) .: env2) b
+                    ?? letH `at` (Inst @"env" env2, Inst @"nm" nm, Inst @"a" a, Inst @"b" b)
+                    =: interpInEnv env2 (sLet nm a b)
+                    =: qed
+                ]
+
+-- | A shadowed binding in the environment does not affect interpretation.
+-- The @pfx@ parameter allows the shadow to occur at any depth.
+--
+-- >>> runTPWith cvc5 envShadow
+-- Lemma: measureNonNeg                         Q.E.D.
+-- Lemma: lookupShadowPfx                       Q.E.D.
+-- Lemma: sqrCong                               Q.E.D.
+-- Lemma: sqrHelper                             Q.E.D.
+-- Lemma: addCongL                              Q.E.D.
+-- Lemma: addCongR                              Q.E.D.
+-- Lemma: addHelper                             Q.E.D.
+-- Lemma: mulCongL                              Q.E.D.
+-- Lemma: mulCongR                              Q.E.D.
+-- Lemma: mulHelper                             Q.E.D.
+-- Lemma: letHelper                             Q.E.D.
+-- Inductive lemma (strong): envShadow
+--   Step: Measure is non-negative              Q.E.D.
+--   Step: 1 (7 way case split)
+--     Step: 1.1 (Var)                          Q.E.D.
+--     Step: 1.2 (Con)                          Q.E.D.
+--     Step: 1.3.1 (Sqr)                        Q.E.D.
+--     Step: 1.3.2                              Q.E.D.
+--     Step: 1.3.3                              Q.E.D.
+--     Step: 1.4 (Inc)                          Q.E.D.
+--     Step: 1.5.1 (Add)                        Q.E.D.
+--     Step: 1.5.2                              Q.E.D.
+--     Step: 1.5.3                              Q.E.D.
+--     Step: 1.5.4                              Q.E.D.
+--     Step: 1.6.1 (Mul)                        Q.E.D.
+--     Step: 1.6.2                              Q.E.D.
+--     Step: 1.6.3                              Q.E.D.
+--     Step: 1.6.4                              Q.E.D.
+--     Step: 1.7.1 (Let)                        Q.E.D.
+--     Step: 1.7.2                              Q.E.D.
+--     Step: 1.7.3                              Q.E.D.
+--     Step: 1.7.4                              Q.E.D.
+--     Step: 1.Completeness                     Q.E.D.
+--   Result:                                    Q.E.D.
+-- Functions proven terminating: exprSize, interpInEnv, sbv.lookup
+-- [Proven] envShadow :: Ɐe ∷ (Expr String Integer) → Ɐpfx ∷ [(String, Integer)] → Ɐenv ∷ [(String, Integer)] → Ɐb1 ∷ (String, Integer) → Ɐb2 ∷ (String, Integer) → Bool
+envShadow :: TP (Proof (Forall "e" Exp -> Forall "pfx" EL -> Forall "env" EL
+                     -> Forall "b1" (String, Integer) -> Forall "b2" (String, Integer) -> SBool))
+envShadow = do
+   mnn   <- recall measureNonNeg
+   lkShP <- recall lookupShadowPfx
+   sqrC  <- recall sqrCong
+   sqrH  <- recall sqrHelper
+   addCL <- recall addCongL
+   addCR <- recall addCongR
+   addH  <- recall addHelper
+   mulCL <- recall mulCongL
+   mulCR <- recall mulCongR
+   mulH  <- recall mulHelper
+   letH  <- recall letHelper
+
+   sInduct "envShadow"
+     (\(Forall @"e" (e :: SE)) (Forall @"pfx" (pfx :: E)) (Forall @"env" (env :: E))
+       (Forall @"b1" (b1 :: STuple String Integer)) (Forall @"b2" (b2 :: STuple String Integer)) ->
+       let (x, _)  = ST.untuple b1
+           (y, _)  = ST.untuple b2
+       in x .== y .=> interpInEnv (pfx ++ b1 .: b2 .: env) e .== interpInEnv (pfx ++ b1 .: env) e)
+     (\e _ _ _ _ -> size e :: SInteger, [proofOf mnn]) $
+     \ih e pfx env b1 b2 ->
+       let (x, _) = ST.untuple b1
+           (y, _) = ST.untuple b2
+           env1 = pfx ++ b1 .: b2 .: env
+           env2 = pfx ++ b1 .: env
+       in [x .== y]
+       |- cases [ isVar e
+                  ==> let nm = svar e
+                    in interpInEnv env1 (sVar nm)
+                    ?? "Var"
+                    ?? lkShP `at` (Inst @"pfx" pfx, Inst @"k" nm, Inst @"b1" b1, Inst @"b2" b2, Inst @"env" env)
+                    =: interpInEnv env2 (sVar nm)
+                    =: qed
+
+                , isCon e
+                  ==> let v = scon e
+                    in interpInEnv env1 (sCon v)
+                    ?? "Con"
+                    =: interpInEnv env2 (sCon v)
+                    =: qed
+
+                , isSqr e
+                  ==> let a = ssqrVal e
+                    in interpInEnv env1 (sSqr a)
+                    ?? "Sqr"
+                    ?? sqrH `at` (Inst @"env" env1, Inst @"a" a)
+                    =: interpInEnv env1 a * interpInEnv env1 a
+                    ?? ih `at` (Inst @"e" a, Inst @"pfx" pfx, Inst @"env" env, Inst @"b1" b1, Inst @"b2" b2)
+                    ?? sqrC `at` (Inst @"a" (interpInEnv env1 a), Inst @"b" (interpInEnv env2 a))
+                    =: interpInEnv env2 a * interpInEnv env2 a
+                    ?? sqrH `at` (Inst @"env" env2, Inst @"a" a)
+                    =: interpInEnv env2 (sSqr a)
+                    =: qed
+
+                , isInc e
+                  ==> let a = sincVal e
+                    in interpInEnv env1 (sInc a)
+                    ?? "Inc"
+                    ?? ih `at` (Inst @"e" a, Inst @"pfx" pfx, Inst @"env" env, Inst @"b1" b1, Inst @"b2" b2)
+                    =: interpInEnv env2 (sInc a)
+                    =: qed
+
+                , isAdd e
+                  ==> let a = sadd1 e
+                          b = sadd2 e
+                    in interpInEnv env1 (sAdd a b)
+                    ?? "Add"
+                    ?? addH `at` (Inst @"env" env1, Inst @"a" a, Inst @"b" b)
+                    =: interpInEnv env1 a + interpInEnv env1 b
+                    ?? ih `at` (Inst @"e" a, Inst @"pfx" pfx, Inst @"env" env, Inst @"b1" b1, Inst @"b2" b2)
+                    ?? addCL `at` (Inst @"a" (interpInEnv env1 a), Inst @"b" (interpInEnv env2 a), Inst @"c" (interpInEnv env1 b))
+                    =: interpInEnv env2 a + interpInEnv env1 b
+                    ?? ih `at` (Inst @"e" b, Inst @"pfx" pfx, Inst @"env" env, Inst @"b1" b1, Inst @"b2" b2)
+                    ?? addCR `at` (Inst @"a" (interpInEnv env2 a), Inst @"b" (interpInEnv env1 b), Inst @"c" (interpInEnv env2 b))
+                    =: interpInEnv env2 a + interpInEnv env2 b
+                    ?? addH `at` (Inst @"env" env2, Inst @"a" a, Inst @"b" b)
+                    =: interpInEnv env2 (sAdd a b)
+                    =: qed
+
+                , isMul e
+                  ==> let a = smul1 e
+                          b = smul2 e
+                    in interpInEnv env1 (sMul a b)
+                    ?? "Mul"
+                    ?? mulH `at` (Inst @"env" env1, Inst @"a" a, Inst @"b" b)
+                    =: interpInEnv env1 a * interpInEnv env1 b
+                    ?? ih `at` (Inst @"e" a, Inst @"pfx" pfx, Inst @"env" env, Inst @"b1" b1, Inst @"b2" b2)
+                    ?? mulCL `at` (Inst @"a" (interpInEnv env1 a), Inst @"b" (interpInEnv env2 a), Inst @"c" (interpInEnv env1 b))
+                    =: interpInEnv env2 a * interpInEnv env1 b
+                    ?? ih `at` (Inst @"e" b, Inst @"pfx" pfx, Inst @"env" env, Inst @"b1" b1, Inst @"b2" b2)
+                    ?? mulCR `at` (Inst @"a" (interpInEnv env2 a), Inst @"b" (interpInEnv env1 b), Inst @"c" (interpInEnv env2 b))
+                    =: interpInEnv env2 a * interpInEnv env2 b
+                    ?? mulH `at` (Inst @"env" env2, Inst @"a" a, Inst @"b" b)
+                    =: interpInEnv env2 (sMul a b)
+                    =: qed
+
+                , isLet e
+                  ==> let nm = slvar  e
+                          a  = slval  e
+                          b  = slbody e
+                          val1 = interpInEnv env1 a
+                          val2 = interpInEnv env2 a
+                    in interpInEnv env1 (sLet nm a b)
+                    ?? "Let"
+                    ?? letH `at` (Inst @"env" env1, Inst @"nm" nm, Inst @"a" a, Inst @"b" b)
+                    =: interpInEnv (ST.tuple (nm, val1) .: env1) b
+                    ?? ih `at` (Inst @"e" a, Inst @"pfx" pfx, Inst @"env" env, Inst @"b1" b1, Inst @"b2" b2)
+                    =: interpInEnv (ST.tuple (nm, val2) .: env1) b
+                    ?? ih `at` (Inst @"e" b, Inst @"pfx" (ST.tuple (nm, val2) .: pfx), Inst @"env" env, Inst @"b1" b1, Inst @"b2" b2)
+                    =: interpInEnv (ST.tuple (nm, val2) .: env2) b
+                    ?? letH `at` (Inst @"env" env2, Inst @"nm" nm, Inst @"a" a, Inst @"b" b)
+                    =: interpInEnv env2 (sLet nm a b)
+                    =: qed
+                ]
+
+-- * Substitution correctness
+
+-- | Unfolding @interpInEnv@ over @Var@.
+--
+-- >>> runTP varHelper
+-- Lemma: varHelper    Q.E.D.
+-- Functions proven terminating: interpInEnv, sbv.lookup
+-- [Proven] varHelper :: Ɐenv ∷ [(String, Integer)] → Ɐnm ∷ String → Bool
+varHelper :: TP (Proof (Forall "env" EL -> Forall "nm" String -> SBool))
+varHelper = lemma "varHelper"
+                  (\(Forall @"env" (env :: E)) (Forall @"nm" nm) ->
+                        interpInEnv env (sVar nm) .== SL.lookup nm env) []
+
+-- | Substitution preserves semantics: interpreting in an extended environment
+-- is the same as substituting and interpreting in the original environment.
+--
+-- >>> runTPWith cvc5 substCorrect
+-- Lemma: measureNonNeg                         Q.E.D.
+-- Lemma: sqrCong                               Q.E.D.
+-- Lemma: sqrHelper                             Q.E.D.
+-- Lemma: addHelper                             Q.E.D.
+-- Lemma: mulCongL                              Q.E.D.
+-- Lemma: mulCongR                              Q.E.D.
+-- Lemma: mulHelper                             Q.E.D.
+-- Lemma: letHelper                             Q.E.D.
+-- Lemma: varHelper                             Q.E.D.
+-- Lemma: envSwap                               Q.E.D.
+-- Lemma: envShadow                             Q.E.D.
+-- Inductive lemma (strong): substCorrect
+--   Step: Measure is non-negative              Q.E.D.
+--   Step: 1 (7 way case split)
+--     Step: 1.1 (2 way case split)
+--       Step: 1.1.1.1 (Var)                    Q.E.D.
+--       Step: 1.1.1.2                          Q.E.D.
+--       Step: 1.1.1.3                          Q.E.D.
+--       Step: 1.1.1.4                          Q.E.D.
+--       Step: 1.1.1.5                          Q.E.D.
+--       Step: 1.1.2.1 (Var)                    Q.E.D.
+--       Step: 1.1.2.2                          Q.E.D.
+--       Step: 1.1.2.3                          Q.E.D.
+--       Step: 1.1.2.4                          Q.E.D.
+--       Step: 1.1.2.5                          Q.E.D.
+--       Step: 1.1.Completeness                 Q.E.D.
+--     Step: 1.2 (Con)                          Q.E.D.
+--     Step: 1.3.1 (Sqr)                        Q.E.D.
+--     Step: 1.3.2                              Q.E.D.
+--     Step: 1.3.3                              Q.E.D.
+--     Step: 1.3.4                              Q.E.D.
+--     Step: 1.4 (Inc)                          Q.E.D.
+--     Step: 1.5.1 (Add)                        Q.E.D.
+--     Step: 1.5.2                              Q.E.D.
+--     Step: 1.5.3                              Q.E.D.
+--     Step: 1.5.4                              Q.E.D.
+--     Step: 1.6.1 (Mul)                        Q.E.D.
+--     Step: 1.6.2                              Q.E.D.
+--     Step: 1.6.3                              Q.E.D.
+--     Step: 1.6.4                              Q.E.D.
+--     Step: 1.6.5                              Q.E.D.
+--     Step: 1.7.1 (Let)                        Q.E.D.
+--     Step: 1.7.2 (2 way case split)
+--       Step: 1.7.2.1.1                        Q.E.D.
+--       Step: 1.7.2.1.2 (shadow)               Q.E.D.
+--       Step: 1.7.2.1.3                        Q.E.D.
+--       Step: 1.7.2.1.4                        Q.E.D.
+--       Step: 1.7.2.1.5                        Q.E.D.
+--       Step: 1.7.2.2.1                        Q.E.D.
+--       Step: 1.7.2.2.2 (swap)                 Q.E.D.
+--       Step: 1.7.2.2.3                        Q.E.D.
+--       Step: 1.7.2.2.4                        Q.E.D.
+--       Step: 1.7.2.2.5                        Q.E.D.
+--       Step: 1.7.2.2.6                        Q.E.D.
+--       Step: 1.7.2.Completeness               Q.E.D.
+--     Step: 1.Completeness                     Q.E.D.
+--   Result:                                    Q.E.D.
+-- Functions proven terminating: exprSize, interpInEnv, sbv.lookup, subst
+-- [Proven] substCorrect :: Ɐe ∷ (Expr String Integer) → Ɐnm ∷ String → Ɐv ∷ Integer → Ɐenv ∷ [(String, Integer)] → Bool
+substCorrect :: TP (Proof (Forall "e" Exp -> Forall "nm" String -> Forall "v" Integer -> Forall "env" EL -> SBool))
+substCorrect = do
+   mnn   <- recall measureNonNeg
+   sqrC  <- recall sqrCong
+   sqrH  <- recall sqrHelper
+   addH  <- recall addHelper
+   mulCL <- recall mulCongL
+   mulCR <- recall mulCongR
+   mulH  <- recall mulHelper
+   letH  <- recall letHelper
+   varH  <- recall varHelper
+   eSwp  <- recall envSwap
+   eShd  <- recall envShadow
+
+   sInduct "substCorrect"
+     (\(Forall @"e" (e :: SE)) (Forall @"nm" (nm :: SString)) (Forall @"v" (v :: SInteger)) (Forall @"env" (env :: E)) ->
+         interpInEnv (ST.tuple (nm, v) .: env) e .== interpInEnv env (subst nm v e))
+     (\e _ _ _ -> size e :: SInteger, [proofOf mnn]) $
+     \ih e nm v env ->
+       let nmv  = ST.tuple (nm, v)
+           env1 = nmv .: env
+       in []
+       |- cases [ isVar e
+                  ==> let x = svar e
+                    in interpInEnv env1 (sVar x)
+                    ?? "Var"
+                    =: cases [ x .== nm
+                               ==> interpInEnv env1 (sVar nm)
+                                ?? varH `at` (Inst @"env" env1, Inst @"nm" nm)
+                                =: SL.lookup nm env1
+                                =: v
+                                =: interpInEnv env (sCon v)
+                                =: interpInEnv env (subst nm v (sVar nm))
+                                =: qed
+                             , x ./= nm
+                               ==> interpInEnv env1 (sVar x)
+                                ?? varH `at` (Inst @"env" env1, Inst @"nm" x)
+                                =: SL.lookup x env1
+                                =: SL.lookup x env
+                                ?? varH `at` (Inst @"env" env, Inst @"nm" x)
+                                =: interpInEnv env (sVar x)
+                                =: interpInEnv env (subst nm v (sVar x))
+                                =: qed
+                             ]
+
+                , isCon e
+                  ==> let c = scon e
+                    in interpInEnv env1 (sCon c)
+                    ?? "Con"
+                    =: interpInEnv env (subst nm v (sCon c))
+                    =: qed
+
+                , isSqr e
+                  ==> let a = ssqrVal e
+                    in interpInEnv env1 (sSqr a)
+                    ?? "Sqr"
+                    ?? sqrH `at` (Inst @"env" env1, Inst @"a" a)
+                    =: interpInEnv env1 a * interpInEnv env1 a
+                    ?? ih `at` (Inst @"e" a, Inst @"nm" nm, Inst @"v" v, Inst @"env" env)
+                    ?? sqrC `at` (Inst @"a" (interpInEnv env1 a), Inst @"b" (interpInEnv env (subst nm v a)))
+                    =: interpInEnv env (subst nm v a) * interpInEnv env (subst nm v a)
+                    ?? sqrH `at` (Inst @"env" env, Inst @"a" (subst nm v a))
+                    =: interpInEnv env (sSqr (subst nm v a))
+                    =: interpInEnv env (subst nm v (sSqr a))
+                    =: qed
+
+                , isInc e
+                  ==> let a = sincVal e
+                    in interpInEnv env1 (sInc a)
+                    ?? "Inc"
+                    ?? ih `at` (Inst @"e" a, Inst @"nm" nm, Inst @"v" v, Inst @"env" env)
+                    =: interpInEnv env (subst nm v (sInc a))
+                    =: qed
+
+                , isAdd e
+                  ==> let a = sadd1 e
+                          b = sadd2 e
+                    in interpInEnv env1 (sAdd a b)
+                    ?? "Add"
+                    ?? addH `at` (Inst @"env" env1, Inst @"a" a, Inst @"b" b)
+                    =: interpInEnv env1 a + interpInEnv env1 b
+                    ?? ih `at` (Inst @"e" a, Inst @"nm" nm, Inst @"v" v, Inst @"env" env)
+                    ?? ih `at` (Inst @"e" b, Inst @"nm" nm, Inst @"v" v, Inst @"env" env)
+                    =: interpInEnv env (subst nm v a) + interpInEnv env (subst nm v b)
+                    ?? addH `at` (Inst @"env" env, Inst @"a" (subst nm v a), Inst @"b" (subst nm v b))
+                    =: interpInEnv env (sAdd (subst nm v a) (subst nm v b))
+                    =: interpInEnv env (subst nm v (sAdd a b))
+                    =: qed
+
+                , isMul e
+                  ==> let a = smul1 e
+                          b = smul2 e
+                    in interpInEnv env1 (sMul a b)
+                    ?? "Mul"
+                    ?? mulH `at` (Inst @"env" env1, Inst @"a" a, Inst @"b" b)
+                    =: interpInEnv env1 a * interpInEnv env1 b
+                    ?? ih `at` (Inst @"e" a, Inst @"nm" nm, Inst @"v" v, Inst @"env" env)
+                    ?? mulCL `at` (Inst @"a" (interpInEnv env1 a), Inst @"b" (interpInEnv env (subst nm v a)), Inst @"c" (interpInEnv env1 b))
+                    =: interpInEnv env (subst nm v a) * interpInEnv env1 b
+                    ?? ih `at` (Inst @"e" b, Inst @"nm" nm, Inst @"v" v, Inst @"env" env)
+                    ?? mulCR `at` (Inst @"a" (interpInEnv env (subst nm v a)), Inst @"b" (interpInEnv env1 b), Inst @"c" (interpInEnv env (subst nm v b)))
+                    =: interpInEnv env (subst nm v a) * interpInEnv env (subst nm v b)
+                    ?? mulH `at` (Inst @"env" env, Inst @"a" (subst nm v a), Inst @"b" (subst nm v b))
+                    =: interpInEnv env (sMul (subst nm v a) (subst nm v b))
+                    =: interpInEnv env (subst nm v (sMul a b))
+                    =: qed
+
+                , isLet e
+                  ==> let x   = slvar  e
+                          a   = slval  e
+                          b   = slbody e
+                          val = interpInEnv env1 a
+                    in interpInEnv env1 (sLet x a b)
+                    ?? "Let"
+                    ?? letH `at` (Inst @"env" env1, Inst @"nm" x, Inst @"a" a, Inst @"b" b)
+                    =: interpInEnv (ST.tuple (x, val) .: env1) b
+                    =: cases [ x .== nm
+                               ==> let xv = ST.tuple (x, val)
+                                 in interpInEnv (xv .: nmv .: env) b
+                                 ?? "shadow"
+                                 ?? eShd `at` (Inst @"e" b, Inst @"pfx" (SL.nil :: E), Inst @"env" env, Inst @"b1" xv, Inst @"b2" nmv)
+                                 =: interpInEnv (xv .: env) b
+                                 ?? ih `at` (Inst @"e" a, Inst @"nm" nm, Inst @"v" v, Inst @"env" env)
+                                 =: interpInEnv (ST.tuple (x, interpInEnv env (subst nm v a)) .: env) b
+                                 ?? letH `at` (Inst @"env" env, Inst @"nm" x, Inst @"a" (subst nm v a), Inst @"b" b)
+                                 =: interpInEnv env (sLet x (subst nm v a) b)
+                                 =: interpInEnv env (subst nm v (sLet x a b))
+                                 =: qed
+                             , x ./= nm
+                               ==> let xv = ST.tuple (x, val)
+                                 in interpInEnv (xv .: nmv .: env) b
+                                 ?? "swap"
+                                 ?? eSwp `at` (Inst @"e" b, Inst @"pfx" (SL.nil :: E), Inst @"env" env, Inst @"b1" xv, Inst @"b2" nmv)
+                                 =: interpInEnv (nmv .: xv .: env) b
+                                 ?? ih `at` (Inst @"e" b, Inst @"nm" nm, Inst @"v" v, Inst @"env" (xv .: env))
+                                 =: interpInEnv (xv .: env) (subst nm v b)
+                                 ?? ih `at` (Inst @"e" a, Inst @"nm" nm, Inst @"v" v, Inst @"env" env)
+                                 =: interpInEnv (ST.tuple (x, interpInEnv env (subst nm v a)) .: env) (subst nm v b)
+                                 ?? letH `at` (Inst @"env" env, Inst @"nm" x, Inst @"a" (subst nm v a), Inst @"b" (subst nm v b))
+                                 =: interpInEnv env (sLet x (subst nm v a) (subst nm v b))
+                                 =: interpInEnv env (subst nm v (sLet x a b))
+                                 =: qed
+                             ]
+                ]
+
+-- | Simplification preserves semantics.
+--
+-- >>> runTPWith cvc5 simpCorrect
+-- Lemma: sqrCong                               Q.E.D.
+-- Lemma: sqrHelper                             Q.E.D.
+-- Lemma: addHelper                             Q.E.D.
+-- Lemma: mulCongL                              Q.E.D.
+-- Lemma: mulCongR                              Q.E.D.
+-- Lemma: mulHelper                             Q.E.D.
+-- Lemma: letHelper                             Q.E.D.
+-- Lemma: substCorrect                          Q.E.D.
+-- Lemma: simpCorrect
+--   Step: 1 (7 way case split)
+--     Step: 1.1.1 (Var)                        Q.E.D.
+--     Step: 1.1.2                              Q.E.D.
+--     Step: 1.1.3                              Q.E.D.
+--     Step: 1.2.1 (Con)                        Q.E.D.
+--     Step: 1.2.2                              Q.E.D.
+--     Step: 1.2.3                              Q.E.D.
+--     Step: 1.3.1 (Sqr)                        Q.E.D.
+--     Step: 1.3.2 (2 way case split)
+--       Step: 1.3.2.1.1                        Q.E.D.
+--       Step: 1.3.2.1.2 (Sqr Con)              Q.E.D.
+--       Step: 1.3.2.1.3                        Q.E.D.
+--       Step: 1.3.2.1.4                        Q.E.D.
+--       Step: 1.3.2.1.5                        Q.E.D.
+--       Step: 1.3.2.2.1                        Q.E.D.
+--       Step: 1.3.2.2.2 (Sqr _)                Q.E.D.
+--       Step: 1.3.2.Completeness               Q.E.D.
+--     Step: 1.4.1 (Inc)                        Q.E.D.
+--     Step: 1.4.2 (2 way case split)
+--       Step: 1.4.2.1.1                        Q.E.D.
+--       Step: 1.4.2.1.2 (Inc Con)              Q.E.D.
+--       Step: 1.4.2.1.3                        Q.E.D.
+--       Step: 1.4.2.2.1                        Q.E.D.
+--       Step: 1.4.2.2.2 (Inc _)                Q.E.D.
+--       Step: 1.4.2.Completeness               Q.E.D.
+--     Step: 1.5.1 (Add)                        Q.E.D.
+--     Step: 1.5.2 (6 way case split)
+--       Step: 1.5.2.1.1                        Q.E.D.
+--       Step: 1.5.2.1.2 (Add 0+b)              Q.E.D.
+--       Step: 1.5.2.1.3                        Q.E.D.
+--       Step: 1.5.2.2.1                        Q.E.D.
+--       Step: 1.5.2.2.2 (Add a+0)              Q.E.D.
+--       Step: 1.5.2.2.3                        Q.E.D.
+--       Step: 1.5.2.3.1                        Q.E.D.
+--       Step: 1.5.2.3.2 (Add Con)              Q.E.D.
+--       Step: 1.5.2.3.3                        Q.E.D.
+--       Step: 1.5.2.4 (2 way case split)
+--         Step: 1.5.2.4.1.1                    Q.E.D.
+--         Step: 1.5.2.4.1.2 (Add 0,_)          Q.E.D.
+--         Step: 1.5.2.4.1.3                    Q.E.D.
+--         Step: 1.5.2.4.2.1                    Q.E.D.
+--         Step: 1.5.2.4.2.2 (Add C,_)          Q.E.D.
+--         Step: 1.5.2.4.Completeness           Q.E.D.
+--       Step: 1.5.2.5 (2 way case split)
+--         Step: 1.5.2.5.1.1                    Q.E.D.
+--         Step: 1.5.2.5.1.2 (Add _,0)          Q.E.D.
+--         Step: 1.5.2.5.1.3                    Q.E.D.
+--         Step: 1.5.2.5.2.1                    Q.E.D.
+--         Step: 1.5.2.5.2.2 (Add _,C)          Q.E.D.
+--         Step: 1.5.2.5.Completeness           Q.E.D.
+--       Step: 1.5.2.6.1                        Q.E.D.
+--       Step: 1.5.2.6.2 (Add _,_)              Q.E.D.
+--       Step: 1.5.2.Completeness               Q.E.D.
+--     Step: 1.6.1 (Mul)                        Q.E.D.
+--     Step: 1.6.2 (8 way case split)
+--       Step: 1.6.2.1.1                        Q.E.D.
+--       Step: 1.6.2.1.2 (Mul 0*b)              Q.E.D.
+--       Step: 1.6.2.1.3                        Q.E.D.
+--       Step: 1.6.2.2.1                        Q.E.D.
+--       Step: 1.6.2.2.2 (Mul a*0)              Q.E.D.
+--       Step: 1.6.2.2.3                        Q.E.D.
+--       Step: 1.6.2.3.1                        Q.E.D.
+--       Step: 1.6.2.3.2 (Mul 1*b)              Q.E.D.
+--       Step: 1.6.2.3.3                        Q.E.D.
+--       Step: 1.6.2.3.4                        Q.E.D.
+--       Step: 1.6.2.3.5                        Q.E.D.
+--       Step: 1.6.2.4.1                        Q.E.D.
+--       Step: 1.6.2.4.2 (Mul a*1)              Q.E.D.
+--       Step: 1.6.2.4.3                        Q.E.D.
+--       Step: 1.6.2.4.4                        Q.E.D.
+--       Step: 1.6.2.4.5                        Q.E.D.
+--       Step: 1.6.2.5.1                        Q.E.D.
+--       Step: 1.6.2.5.2 (Mul Con)              Q.E.D.
+--       Step: 1.6.2.5.3                        Q.E.D.
+--       Step: 1.6.2.5.4                        Q.E.D.
+--       Step: 1.6.2.5.5                        Q.E.D.
+--       Step: 1.6.2.5.6                        Q.E.D.
+--       Step: 1.6.2.6 (3 way case split)
+--         Step: 1.6.2.6.1.1                    Q.E.D.
+--         Step: 1.6.2.6.1.2 (Mul 0,_)          Q.E.D.
+--         Step: 1.6.2.6.1.3                    Q.E.D.
+--         Step: 1.6.2.6.2.1                    Q.E.D.
+--         Step: 1.6.2.6.2.2 (Mul 1,_)          Q.E.D.
+--         Step: 1.6.2.6.2.3                    Q.E.D.
+--         Step: 1.6.2.6.2.4                    Q.E.D.
+--         Step: 1.6.2.6.2.5                    Q.E.D.
+--         Step: 1.6.2.6.3.1                    Q.E.D.
+--         Step: 1.6.2.6.3.2 (Mul C,_)          Q.E.D.
+--         Step: 1.6.2.6.Completeness           Q.E.D.
+--       Step: 1.6.2.7 (3 way case split)
+--         Step: 1.6.2.7.1.1                    Q.E.D.
+--         Step: 1.6.2.7.1.2 (Mul _,0)          Q.E.D.
+--         Step: 1.6.2.7.1.3                    Q.E.D.
+--         Step: 1.6.2.7.2.1                    Q.E.D.
+--         Step: 1.6.2.7.2.2 (Mul _,1)          Q.E.D.
+--         Step: 1.6.2.7.2.3                    Q.E.D.
+--         Step: 1.6.2.7.2.4                    Q.E.D.
+--         Step: 1.6.2.7.2.5                    Q.E.D.
+--         Step: 1.6.2.7.3.1                    Q.E.D.
+--         Step: 1.6.2.7.3.2 (Mul _,C)          Q.E.D.
+--         Step: 1.6.2.7.Completeness           Q.E.D.
+--       Step: 1.6.2.8.1                        Q.E.D.
+--       Step: 1.6.2.8.2 (Mul _,_)              Q.E.D.
+--       Step: 1.6.2.Completeness               Q.E.D.
+--     Step: 1.7.1 (Let)                        Q.E.D.
+--     Step: 1.7.2 (2 way case split)
+--       Step: 1.7.2.1.1                        Q.E.D.
+--       Step: 1.7.2.1.2 (Let Con)              Q.E.D.
+--       Step: 1.7.2.1.3                        Q.E.D.
+--       Step: 1.7.2.1.4                        Q.E.D.
+--       Step: 1.7.2.2.1                        Q.E.D.
+--       Step: 1.7.2.2.2 (Let _)                Q.E.D.
+--       Step: 1.7.2.Completeness               Q.E.D.
+--     Step: 1.Completeness                     Q.E.D.
+--   Result:                                    Q.E.D.
+-- Functions proven terminating: exprSize, interpInEnv, sbv.lookup, simplify, subst
+-- [Proven] simpCorrect :: Ɐe ∷ (Expr String Integer) → Ɐenv ∷ [(String, Integer)] → Bool
+simpCorrect :: TP (Proof (Forall "e" Exp -> Forall "env" EL -> SBool))
+simpCorrect = do
+   sqrC  <- recall sqrCong
+   sqrH  <- recall sqrHelper
+   addH  <- recall addHelper
+   mulCL <- recall mulCongL
+   mulCR <- recall mulCongR
+   mulH  <- recall mulHelper
+   letH  <- recall letHelper
+   subC  <- recall substCorrect
+
+   calc "simpCorrect"
+     (\(Forall @"e" (e :: SE)) (Forall @"env" (env :: E)) -> interpInEnv env (simplify e) .== interpInEnv env e) $
+     \e env -> []
+     |- [pCase| e of
+          Var nm     -> interpInEnv env (simplify e)
+                     ?? "Var"
+                     =: interpInEnv env (simplify (sVar nm))
+                     =: interpInEnv env (sVar nm)
+                     =: interpInEnv env e
+                     =: qed
+
+          Con c      -> interpInEnv env (simplify e)
+                     ?? "Con"
+                     =: interpInEnv env (simplify (sCon c))
+                     =: interpInEnv env (sCon c)
+                     =: interpInEnv env e
+                     =: qed
+
+          Sqr a      -> interpInEnv env (simplify e)
+                     ?? "Sqr"
+                     =: interpInEnv env (simplify (sSqr a))
+                     =: cases [ isCon a
+                                 ==> let v = scon a
+                                   in interpInEnv env (simplify (sSqr (sCon v)))
+                                   ?? "Sqr Con"
+                                   =: interpInEnv env (sCon (v * v))
+                                   ?? interpInEnv env (sCon (v * v)) .== v * v
+                                   =: v * v
+                                   ?? sqrC `at` (Inst @"a" (interpInEnv env (sCon v)), Inst @"b" v)
+                                   =: interpInEnv env (sCon v) * interpInEnv env (sCon v)
+                                   ?? sqrH `at` (Inst @"env" env, Inst @"a" (sCon v))
+                                   =: interpInEnv env (sSqr (sCon v))
+                                   =: qed
+                               , sNot (isCon a)
+                                 ==> interpInEnv env (simplify (sSqr a))
+                                   ?? "Sqr _"
+                                   =: interpInEnv env (sSqr a)
+                                   =: qed
+                               ]
+
+          Inc a      -> interpInEnv env (simplify e)
+                     ?? "Inc"
+                     =: interpInEnv env (simplify (sInc a))
+                     =: cases [ isCon a
+                                 ==> let v = scon a
+                                   in interpInEnv env (simplify (sInc (sCon v)))
+                                   ?? "Inc Con"
+                                   =: interpInEnv env (sCon (v + 1))
+                                   =: interpInEnv env (sInc (sCon v))
+                                   =: qed
+                               , sNot (isCon a)
+                                 ==> interpInEnv env (simplify (sInc a))
+                                   ?? "Inc _"
+                                   =: interpInEnv env (sInc a)
+                                   =: qed
+                               ]
+
+          Add a b    -> interpInEnv env (simplify e)
+                     ?? "Add"
+                     =: interpInEnv env (simplify (sAdd a b))
+                     =: cases [ isCon a .&& scon a .== 0
+                                 ==> interpInEnv env (simplify (sAdd (sCon 0) b))
+                                   ?? "Add 0+b"
+                                   =: interpInEnv env b
+                                   ?? addH `at` (Inst @"env" env, Inst @"a" (sCon 0), Inst @"b" b)
+                                   =: interpInEnv env (sAdd (sCon 0) b)
+                                   =: qed
+
+                               , isCon b .&& scon b .== 0
+                                 ==> interpInEnv env (simplify (sAdd a (sCon 0)))
+                                   ?? "Add a+0"
+                                   =: interpInEnv env a
+                                   ?? addH `at` (Inst @"env" env, Inst @"a" a, Inst @"b" (sCon 0))
+                                   =: interpInEnv env (sAdd a (sCon 0))
+                                   =: qed
+
+                               , isCon a .&& isCon b
+                                 ==> let va = scon a; vb = scon b
+                                   in interpInEnv env (simplify (sAdd (sCon va) (sCon vb)))
+                                   ?? "Add Con"
+                                   =: interpInEnv env (sCon (va + vb))
+                                   ?? addH `at` (Inst @"env" env, Inst @"a" (sCon va), Inst @"b" (sCon vb))
+                                   =: interpInEnv env (sAdd (sCon va) (sCon vb))
+                                   =: qed
+
+                               , isCon a .&& sNot (isCon b)
+                                 ==> let va = scon a
+                                   in cases [ va .== 0
+                                              ==> interpInEnv env (simplify (sAdd (sCon 0) b))
+                                                ?? "Add 0,_"
+                                                =: interpInEnv env b
+                                                ?? addH `at` (Inst @"env" env, Inst @"a" (sCon 0), Inst @"b" b)
+                                                =: interpInEnv env (sAdd (sCon 0) b)
+                                                =: qed
+                                            , va ./= 0
+                                              ==> interpInEnv env (simplify (sAdd (sCon va) b))
+                                                ?? "Add C,_"
+                                                =: interpInEnv env (sAdd (sCon va) b)
+                                                =: qed
+                                            ]
+
+                               , sNot (isCon a) .&& isCon b
+                                 ==> let vb = scon b
+                                   in cases [ vb .== 0
+                                              ==> interpInEnv env (simplify (sAdd a (sCon 0)))
+                                                ?? "Add _,0"
+                                                =: interpInEnv env a
+                                                ?? addH `at` (Inst @"env" env, Inst @"a" a, Inst @"b" (sCon 0))
+                                                =: interpInEnv env (sAdd a (sCon 0))
+                                                =: qed
+                                            , vb ./= 0
+                                              ==> interpInEnv env (simplify (sAdd a (sCon vb)))
+                                                ?? "Add _,C"
+                                                =: interpInEnv env (sAdd a (sCon vb))
+                                                =: qed
+                                            ]
+
+                               , sNot (isCon a) .&& sNot (isCon b)
+                                 ==> interpInEnv env (simplify (sAdd a b))
+                                   ?? "Add _,_"
+                                   =: interpInEnv env (sAdd a b)
+                                   =: qed
+                               ]
+
+          Mul a b    -> interpInEnv env (simplify e)
+                     ?? "Mul"
+                     =: interpInEnv env (simplify (sMul a b))
+                     =: cases [ isCon a .&& scon a .== 0
+                                 ==> interpInEnv env (simplify (sMul (sCon 0) b))
+                                   ?? "Mul 0*b"
+                                   =: interpInEnv env (sCon 0)
+                                   ?? mulH `at` (Inst @"env" env, Inst @"a" (sCon 0), Inst @"b" b)
+                                   =: interpInEnv env (sMul (sCon 0) b)
+                                   =: qed
+
+                               , isCon b .&& scon b .== 0
+                                 ==> interpInEnv env (simplify (sMul a (sCon 0)))
+                                   ?? "Mul a*0"
+                                   =: interpInEnv env (sCon 0)
+                                   ?? mulH `at` (Inst @"env" env, Inst @"a" a, Inst @"b" (sCon 0))
+                                   =: interpInEnv env (sMul a (sCon 0))
+                                   =: qed
+
+                               , isCon a .&& scon a .== 1
+                                 ==> interpInEnv env (simplify (sMul (sCon 1) b))
+                                   ?? "Mul 1*b"
+                                   =: interpInEnv env b
+                                   =: 1 * interpInEnv env b
+                                   ?? interpInEnv env (sCon 1) .== 1
+                                   =: interpInEnv env (sCon 1) * interpInEnv env b
+                                   ?? mulH `at` (Inst @"env" env, Inst @"a" (sCon 1), Inst @"b" b)
+                                   =: interpInEnv env (sMul (sCon 1) b)
+                                   =: qed
+
+                               , isCon b .&& scon b .== 1
+                                 ==> interpInEnv env (simplify (sMul a (sCon 1)))
+                                   ?? "Mul a*1"
+                                   =: interpInEnv env a
+                                   =: interpInEnv env a * 1
+                                   ?? interpInEnv env (sCon 1) .== 1
+                                   =: interpInEnv env a * interpInEnv env (sCon 1)
+                                   ?? mulH `at` (Inst @"env" env, Inst @"a" a, Inst @"b" (sCon 1))
+                                   =: interpInEnv env (sMul a (sCon 1))
+                                   =: qed
+
+                               , isCon a .&& isCon b
+                                 ==> let va = scon a; vb = scon b
+                                   in interpInEnv env (simplify (sMul (sCon va) (sCon vb)))
+                                   ?? "Mul Con"
+                                   ?? simplify (sMul (sCon va) (sCon vb)) .== sCon (va * vb)
+                                   =: interpInEnv env (sCon (va * vb))
+                                   ?? interpInEnv env (sCon (va * vb)) .== va * vb
+                                   =: va * vb
+                                   ?? mulCL `at` (Inst @"a" (interpInEnv env (sCon va)), Inst @"b" va, Inst @"c" vb)
+                                   =: interpInEnv env (sCon va) * vb
+                                   ?? mulCR `at` (Inst @"a" (interpInEnv env (sCon va)), Inst @"b" (interpInEnv env (sCon vb)), Inst @"c" vb)
+                                   =: interpInEnv env (sCon va) * interpInEnv env (sCon vb)
+                                   ?? mulH `at` (Inst @"env" env, Inst @"a" (sCon va), Inst @"b" (sCon vb))
+                                   =: interpInEnv env (sMul (sCon va) (sCon vb))
+                                   =: qed
+
+                               , isCon a .&& sNot (isCon b)
+                                 ==> let va = scon a
+                                   in cases [ va .== 0
+                                              ==> interpInEnv env (simplify (sMul (sCon 0) b))
+                                                ?? "Mul 0,_"
+                                                =: interpInEnv env (sCon 0)
+                                                ?? mulH `at` (Inst @"env" env, Inst @"a" (sCon 0), Inst @"b" b)
+                                                =: interpInEnv env (sMul (sCon 0) b)
+                                                =: qed
+                                            , va .== 1
+                                              ==> interpInEnv env (simplify (sMul (sCon 1) b))
+                                                ?? "Mul 1,_"
+                                                =: interpInEnv env b
+                                                =: 1 * interpInEnv env b
+                                                ?? interpInEnv env (sCon 1) .== 1
+                                                =: interpInEnv env (sCon 1) * interpInEnv env b
+                                                ?? mulH `at` (Inst @"env" env, Inst @"a" (sCon 1), Inst @"b" b)
+                                                =: interpInEnv env (sMul (sCon 1) b)
+                                                =: qed
+                                            , va ./= 0 .&& va ./= 1
+                                              ==> interpInEnv env (simplify (sMul (sCon va) b))
+                                                ?? "Mul C,_"
+                                                =: interpInEnv env (sMul (sCon va) b)
+                                                =: qed
+                                            ]
+
+                               , sNot (isCon a) .&& isCon b
+                                 ==> let vb = scon b
+                                   in cases [ vb .== 0
+                                              ==> interpInEnv env (simplify (sMul a (sCon 0)))
+                                                ?? "Mul _,0"
+                                                =: interpInEnv env (sCon 0)
+                                                ?? mulH `at` (Inst @"env" env, Inst @"a" a, Inst @"b" (sCon 0))
+                                                =: interpInEnv env (sMul a (sCon 0))
+                                                =: qed
+                                            , vb .== 1
+                                              ==> interpInEnv env (simplify (sMul a (sCon 1)))
+                                                ?? "Mul _,1"
+                                                =: interpInEnv env a
+                                                =: interpInEnv env a * 1
+                                                ?? interpInEnv env (sCon 1) .== 1
+                                                =: interpInEnv env a * interpInEnv env (sCon 1)
+                                                ?? mulH `at` (Inst @"env" env, Inst @"a" a, Inst @"b" (sCon 1))
+                                                =: interpInEnv env (sMul a (sCon 1))
+                                                =: qed
+                                            , vb ./= 0 .&& vb ./= 1
+                                              ==> interpInEnv env (simplify (sMul a (sCon vb)))
+                                                ?? "Mul _,C"
+                                                =: interpInEnv env (sMul a (sCon vb))
+                                                =: qed
+                                            ]
+
+                               , sNot (isCon a) .&& sNot (isCon b)
+                                 ==> interpInEnv env (simplify (sMul a b))
+                                   ?? "Mul _,_"
+                                   =: interpInEnv env (sMul a b)
+                                   =: qed
+                               ]
+
+          Let nm a b -> interpInEnv env (simplify e)
+                     ?? "Let"
+                     =: interpInEnv env (simplify (sLet nm a b))
+                     =: cases [ isCon a
+                                 ==> let v = scon a
+                                   in interpInEnv env (simplify (sLet nm (sCon v) b))
+                                   ?? "Let Con"
+                                   =: interpInEnv env (subst nm v b)
+                                   ?? subC `at` (Inst @"e" b, Inst @"nm" nm, Inst @"v" v, Inst @"env" env)
+                                   =: interpInEnv (ST.tuple (nm, v) .: env) b
+                                   ?? letH `at` (Inst @"env" env, Inst @"nm" nm, Inst @"a" (sCon v), Inst @"b" b)
+                                   =: interpInEnv env (sLet nm (sCon v) b)
+                                   =: qed
+                               , sNot (isCon a)
+                                 ==> interpInEnv env (simplify (sLet nm a b))
+                                   ?? "Let _"
+                                   =: interpInEnv env (sLet nm a b)
+                                   =: qed
+                               ]
+        |]
+
+-- | Constant folding preserves the semantics: interpreting an expression
+-- is the same as constant-folding it first and then interpreting the result.
+--
+-- >>> runTPWith cvc5 cfoldCorrect
+-- Lemma: measureNonNeg                         Q.E.D.
+-- Lemma: simpCorrect                           Q.E.D.
+-- Lemma: sqrCong                               Q.E.D. [Cached]
+-- Lemma: sqrHelper                             Q.E.D. [Cached]
+-- Lemma: mulCongL                              Q.E.D. [Cached]
+-- Lemma: mulCongR                              Q.E.D. [Cached]
+-- Lemma: mulHelper                             Q.E.D. [Cached]
+-- Inductive lemma (strong): cfoldCorrect
+--   Step: Measure is non-negative              Q.E.D.
+--   Step: 1 (7 way case split)
+--     Step: 1.1.1 (case Var)                   Q.E.D.
+--     Step: 1.1.2                              Q.E.D.
+--     Step: 1.1.3                              Q.E.D.
+--     Step: 1.2.1 (case Con)                   Q.E.D.
+--     Step: 1.2.2                              Q.E.D.
+--     Step: 1.2.3                              Q.E.D.
+--     Step: 1.3.1 (case Sqr)                   Q.E.D.
+--     Step: 1.3.2                              Q.E.D.
+--     Step: 1.3.3                              Q.E.D.
+--     Step: 1.3.4                              Q.E.D.
+--     Step: 1.3.5                              Q.E.D.
+--     Step: 1.3.6                              Q.E.D.
+--     Step: 1.3.7                              Q.E.D.
+--     Step: 1.4.1 (case Inc)                   Q.E.D.
+--     Step: 1.4.2                              Q.E.D.
+--     Step: 1.4.3                              Q.E.D.
+--     Step: 1.4.4                              Q.E.D.
+--     Step: 1.4.5                              Q.E.D.
+--     Step: 1.5.1 (case Add)                   Q.E.D.
+--     Step: 1.5.2                              Q.E.D.
+--     Step: 1.5.3                              Q.E.D.
+--     Step: 1.5.4                              Q.E.D.
+--     Step: 1.5.5                              Q.E.D.
+--     Step: 1.6.1 (case Mul)                   Q.E.D.
+--     Step: 1.6.2                              Q.E.D.
+--     Step: 1.6.3                              Q.E.D.
+--     Step: 1.6.4                              Q.E.D.
+--     Step: 1.6.5                              Q.E.D.
+--     Step: 1.6.6                              Q.E.D.
+--     Step: 1.6.7                              Q.E.D.
+--     Step: 1.6.8                              Q.E.D.
+--     Step: 1.7.1 (case Let)                   Q.E.D.
+--     Step: 1.7.2                              Q.E.D.
+--     Step: 1.7.3                              Q.E.D.
+--     Step: 1.7.4                              Q.E.D.
+--     Step: 1.7.5                              Q.E.D.
+--     Step: 1.Completeness                     Q.E.D.
+--   Result:                                    Q.E.D.
+-- Functions proven terminating: cfold, exprSize, interpInEnv, sbv.lookup, simplify, subst
+-- [Proven] cfoldCorrect :: Ɐe ∷ (Expr String Integer) → Ɐenv ∷ [(String, Integer)] → Bool
+cfoldCorrect :: TP (Proof (Forall "e" Exp -> Forall "env" EL -> SBool))
+cfoldCorrect = do
+   mnn   <- recall measureNonNeg
+   sc    <- recall simpCorrect
+   sqrC  <- recall sqrCong
+   sqrH  <- recall sqrHelper
+   mulCL <- recall mulCongL
+   mulCR <- recall mulCongR
+   mulH  <- recall mulHelper
+
+   sInduct "cfoldCorrect"
+     (\(Forall @"e" (e :: SE)) (Forall @"env" (env :: E)) -> interpInEnv env (cfold e) .== interpInEnv env e)
+     (\e _ -> size e, [proofOf mnn]) $
+     \ih e env -> []
+       |- [pCase| e of
+            Var nm     -> interpInEnv env (cfold e)
+                       ?? "case Var"
+                       =: interpInEnv env (cfold (sVar nm))
+                       =: interpInEnv env (sVar nm)
+                       =: interpInEnv env e
+                       =: qed
+
+            Con v      -> interpInEnv env (cfold e)
+                       ?? "case Con"
+                       =: interpInEnv env (cfold (sCon v))
+                       =: interpInEnv env (sCon v)
+                       =: interpInEnv env e
+                       =: qed
+
+            Sqr a      -> interpInEnv env (cfold e)
+                       ?? "case Sqr"
+                       =: interpInEnv env (cfold (sSqr a))
+                       =: interpInEnv env (simplify (sSqr (cfold a)))
+                       ?? sc `at` (Inst @"e" (sSqr (cfold a)), Inst @"env" env)
+                       =: interpInEnv env (sSqr (cfold a))
+                       ?? sqrH `at` (Inst @"env" env, Inst @"a" (cfold a))
+                       =: interpInEnv env (cfold a) * interpInEnv env (cfold a)
+                       ?? ih `at` (Inst @"e" a, Inst @"env" env)
+                       ?? sqrC `at` (Inst @"a" (interpInEnv env (cfold a)), Inst @"b" (interpInEnv env a))
+                       =: interpInEnv env a * interpInEnv env a
+                       ?? sqrH `at` (Inst @"env" env, Inst @"a" a)
+                       =: interpInEnv env (sSqr a)
+                       =: interpInEnv env e
+                       =: qed
+
+            Inc a      -> interpInEnv env (cfold e)
+                       ?? "case Inc"
+                       =: interpInEnv env (cfold (sInc a))
+                       =: interpInEnv env (simplify (sInc (cfold a)))
+                       ?? sc `at` (Inst @"e" (sInc (cfold a)), Inst @"env" env)
+                       =: interpInEnv env (sInc (cfold a))
+                       ?? ih `at` (Inst @"e" a, Inst @"env" env)
+                       =: interpInEnv env (sInc a)
+                       =: interpInEnv env e
+                       =: qed
+
+            Add a b    -> interpInEnv env (cfold e)
+                       ?? "case Add"
+                       =: interpInEnv env (cfold (sAdd a b))
+                       =: interpInEnv env (simplify (sAdd (cfold a) (cfold b)))
+                       ?? sc `at` (Inst @"e" (sAdd (cfold a) (cfold b)), Inst @"env" env)
+                       =: interpInEnv env (sAdd (cfold a) (cfold b))
+                       ?? ih `at` (Inst @"e" a, Inst @"env" env)
+                       ?? ih `at` (Inst @"e" b, Inst @"env" env)
+                       =: interpInEnv env (sAdd a b)
+                       =: interpInEnv env e
+                       =: qed
+
+            Mul a b    -> interpInEnv env (cfold e)
+                       ?? "case Mul"
+                       =: interpInEnv env (cfold (sMul a b))
+                       =: interpInEnv env (simplify (sMul (cfold a) (cfold b)))
+                       ?? sc `at` (Inst @"e" (sMul (cfold a) (cfold b)), Inst @"env" env)
+                       =: interpInEnv env (sMul (cfold a) (cfold b))
+                       ?? mulH `at` (Inst @"env" env, Inst @"a" (cfold a), Inst @"b" (cfold b))
+                       =: interpInEnv env (cfold a) * interpInEnv env (cfold b)
+                       ?? ih `at` (Inst @"e" a, Inst @"env" env)
+                       ?? mulCL `at` (Inst @"a" (interpInEnv env (cfold a)), Inst @"b" (interpInEnv env a), Inst @"c" (interpInEnv env (cfold b)))
+                       =: interpInEnv env a * interpInEnv env (cfold b)
+                       ?? ih `at` (Inst @"e" b, Inst @"env" env)
+                       ?? mulCR `at` (Inst @"a" (interpInEnv env a), Inst @"b" (interpInEnv env (cfold b)), Inst @"c" (interpInEnv env b))
+                       =: interpInEnv env a * interpInEnv env b
+                       ?? mulH `at` (Inst @"env" env, Inst @"a" a, Inst @"b" b)
+                       =: interpInEnv env (sMul a b)
+                       =: interpInEnv env e
+                       =: qed
+
+            Let nm a b -> interpInEnv env (cfold e)
+                       ?? "case Let"
+                       =: interpInEnv env (cfold (sLet nm a b))
+                       =: interpInEnv env (simplify (sLet nm (cfold a) (cfold b)))
+                       ?? sc `at` (Inst @"e" (sLet nm (cfold a) (cfold b)), Inst @"env" env)
+                       =: interpInEnv env (sLet nm (cfold a) (cfold b))
+                       ?? ih `at` (Inst @"e" a, Inst @"env" env)
+                       ?? ih `at` (Inst @"e" b, Inst @"env" (ST.tuple (nm, interpInEnv env a) .: env))
+                       =: interpInEnv env (sLet nm a b)
+                       =: interpInEnv env e
+                       =: qed
+          |]
+
+{-# ANN simpCorrect  ("HLint: ignore Evaluate" :: String) #-}
+{-# ANN cfoldCorrect ("HLint: ignore Evaluate" :: String) #-}
diff --git a/Documentation/SBV/Examples/TP/Countdown.hs b/Documentation/SBV/Examples/TP/Countdown.hs
new file mode 100644
--- /dev/null
+++ b/Documentation/SBV/Examples/TP/Countdown.hs
@@ -0,0 +1,135 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Documentation.SBV.Examples.TP.Countdown
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Proving properties of a countdown function that builds a list
+-- from @n@ down to @0@.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE CPP                 #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Documentation.SBV.Examples.TP.Countdown where
+
+import Prelude hiding (head, length, (!!))
+
+import Data.SBV
+import Data.SBV.List
+import Data.SBV.TP
+
+#ifdef DOCTEST
+-- $setup
+-- >>> import Data.SBV.TP
+#endif
+
+-- * Definitions
+
+-- | A function that counts down from @n@ to @0@, building a list.
+countdown :: SInteger -> SList Integer
+countdown = smtFunction "countdown"
+          $ \n -> [sCase| n of
+                     v | v .<= 0 -> singleton 0
+                       | True    -> v .: countdown (v - 1)
+                  |]
+
+-- * Correctness
+
+-- | Prove that @countdown n@ always starts with @n@, for positive @n@.
+--
+-- >>> runTP countdownHead
+-- Lemma: countdownHead    Q.E.D.
+-- Functions proven terminating: countdown
+-- [Proven] countdownHead :: Ɐn ∷ Integer → Bool
+countdownHead :: TP (Proof (Forall "n" Integer -> SBool))
+countdownHead = lemma "countdownHead" (\(Forall @"n" n) -> n .> 0 .=> head (countdown n) .== n) []
+
+-- | Prove by induction that @countdown n@ is never empty.
+--
+-- >>> runTP countdownNonEmpty
+-- Inductive lemma: countdownNonEmpty
+--   Step: Base                          Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Result:                             Q.E.D.
+-- Functions proven terminating: countdown
+-- [Proven] countdownNonEmpty :: Ɐn ∷ Integer → Bool
+countdownNonEmpty :: TP (Proof (Forall "n" Integer -> SBool))
+countdownNonEmpty =
+   induct "countdownNonEmpty"
+          (\(Forall @"n" n) -> n .>= 0 .=> length (countdown n) .> 0) $
+          \ih n -> [n .>= 0] |- length (countdown (n + 1))
+                             =: length ((n + 1) .: countdown n)
+                             ?? ih
+                             =: 1 + length (countdown n)
+                             =: qed
+
+-- | Prove by induction that @countdown n@ has length @n + 1@.
+--
+-- >>> runTP countdownLen
+-- Inductive lemma: countdownLen
+--   Step: Base                     Q.E.D.
+--   Step: 1                        Q.E.D.
+--   Step: 2                        Q.E.D.
+--   Step: 3                        Q.E.D.
+--   Result:                        Q.E.D.
+-- Functions proven terminating: countdown
+-- [Proven] countdownLen :: Ɐn ∷ Integer → Bool
+countdownLen :: TP (Proof (Forall "n" Integer -> SBool))
+countdownLen =
+   induct "countdownLen"
+          (\(Forall @"n" n) -> n .>= 0 .=> length (countdown n) .== n + 1) $
+          \ih n -> [n .>= 0] |- length (countdown (n + 1))
+                             =: length ((n + 1) .: countdown n)
+                             =: 1 + length (countdown n)
+                             ?? ih
+                             =: n + 2
+                             =: qed
+
+-- | Prove by induction that the @k@-th element of @countdown n@ is @n - k@.
+--
+-- The key subtlety is that the 'induct' Result step only has access to the calc chain
+-- equalities, not to the helper proofs (which live inside each step's assertion stack).
+-- The Result step must prove @P(n+1, k)@ for all valid @k@, i.e., @0 <= k <= n+1@.
+-- If the intros only cover @k <= n@, the Result step has no information for @k = n+1@
+-- and hangs. The fix is to use intros @[n >= 0, 0 <= k, k <= n+1]@ so the calc chain
+-- covers the entire domain of the goal.
+--
+-- >>> runTP countdownElem
+-- Lemma: countdownLen               Q.E.D.
+-- Lemma: elemOne                    Q.E.D.
+-- Inductive lemma: countdownElem
+--   Step: Base                      Q.E.D.
+--   Step: 1                         Q.E.D.
+--   Step: 2                         Q.E.D.
+--   Result:                         Q.E.D.
+-- Functions proven terminating: countdown
+-- [Proven] countdownElem :: Ɐn ∷ Integer → Ɐk ∷ Integer → Bool
+countdownElem :: TP (Proof (Forall "n" Integer -> Forall "k" Integer -> SBool))
+countdownElem = do
+   cLen <- recall countdownLen
+
+   -- NB. The precondition uses (<=) not (<): this is important so the lemma covers
+   -- k = length y (the last valid index of x .: y), not just k < length y.
+   elemOne <- lemma "elemOne" (\(Forall @"x" (x :: SInteger)) (Forall @"y" y) (Forall @"k" k) ->
+                                   k .> 0 .&& k .<= length y .=> (x .: y) !! k .== y !! (k - 1)) []
+
+   induct "countdownElem"
+          (\(Forall @"n" n) (Forall @"k" k) -> 0 .<= k .&& k .<= n .=> countdown n !! k .== n - k) $
+          \ih n k -> [n .>= 0, 0 .<= k, k .<= n + 1]
+                  |- countdown (n + 1) !! k
+                  =: ((n + 1) .: countdown n) !! k
+                  ?? elemOne
+                  ?? cLen
+                  ?? ih `at` Inst @"k" (k - 1)
+                  =: n + 1 - k
+                  =: qed
diff --git a/Documentation/SBV/Examples/TP/Fibonacci.hs b/Documentation/SBV/Examples/TP/Fibonacci.hs
--- a/Documentation/SBV/Examples/TP/Fibonacci.hs
+++ b/Documentation/SBV/Examples/TP/Fibonacci.hs
@@ -10,10 +10,9 @@
 -- version are equivalent.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DataKinds           #-}
-{-# LANGUAGE TypeAbstractions    #-}
-{-# LANGUAGE TypeApplications    #-}
-{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE DataKinds        #-}
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE TypeApplications #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -26,13 +25,19 @@
 
 -- | Calculate fibonacci using the textbook definition.
 fibonacci :: SInteger -> SInteger
-fibonacci = smtFunction "fibonacci" $ \n -> ite (n .<= 1) 1 (fibonacci (n-1) + fibonacci (n-2))
+fibonacci = smtFunction "fibonacci" $ \n -> [sCase| n of
+                                               _ | n .<= 1 -> 1
+                                               _           -> fibonacci (n-1) + fibonacci (n-2)
+                                            |]
 
 -- * Tail recursive version
 
 -- | Tail recursive version
 fib :: SInteger -> SInteger -> SInteger -> SInteger
-fib = smtFunction "fib" $ \a b n -> ite (n .<= 0) a (fib b (a+b) (n-1))
+fib = smtFunction "fib" $ \a b n -> [sCase| n of
+                                       _ | n .<= 0 -> a
+                                       _           -> fib b (a+b) (n-1)
+                                    |]
 
 -- | Faster version of fibonacci, using the tail-recursive version.
 fibTail :: SInteger -> SInteger
@@ -40,21 +45,22 @@
 
 -- * Correctness
 
--- | Proving the the tail version of fibonacci is equivalent to the textbook version.
+-- | Proving the tail recursive version of fibonacci is equivalent to the textbook version.
 --
 -- We have:
 --
 -- >>> correctness
 -- Inductive lemma: helper
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2 (unfold fibonacci)            Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: Base                    Q.E.D.
+--   Step: 1                       Q.E.D.
+--   Step: 2 (unfold fibonacci)    Q.E.D.
+--   Step: 3                       Q.E.D.
+--   Result:                       Q.E.D.
 -- Lemma: fibCorrect
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: 1                       Q.E.D.
+--   Step: 2                       Q.E.D.
+--   Result:                       Q.E.D.
+-- Functions proven terminating: fib, fibonacci
 -- [Proven] fibCorrect :: Ɐn ∷ Integer → Bool
 correctness :: IO (Proof (Forall "n" Integer -> SBool))
 correctness = runTP $ do
diff --git a/Documentation/SBV/Examples/TP/GCD.hs b/Documentation/SBV/Examples/TP/GCD.hs
--- a/Documentation/SBV/Examples/TP/GCD.hs
+++ b/Documentation/SBV/Examples/TP/GCD.hs
@@ -16,6 +16,7 @@
 
 {-# LANGUAGE CPP              #-}
 {-# LANGUAGE DataKinds        #-}
+{-# LANGUAGE QuasiQuotes      #-}
 {-# LANGUAGE TypeAbstractions #-}
 {-# LANGUAGE TypeApplications #-}
 
@@ -31,6 +32,7 @@
 
 #ifdef DOCTEST
 -- $setup
+-- >>> import Data.SBV
 -- >>> import Data.SBV.TP
 #endif
 
@@ -44,7 +46,10 @@
 -- there is no greatest common divisor for the pair @(0, 0)@. So, maximality here is meant
 -- to be in terms of divisibility. That is, any divisor of @a@ and @b@ will also divide their @gcd@.
 nGCD :: SInteger -> SInteger -> SInteger
-nGCD = smtFunction "nGCD" $ \a b -> ite (b .== 0) a (nGCD b (a `sEMod` b))
+nGCD = smtFunction "nGCD" $ \a b -> [sCase| b of
+                                       _ | b .== 0 -> a
+                                       _           -> nGCD b (a `sEMod` b)
+                                    |]
 
 -- | Generalized GCD, working for all integers. We simply call @nGCD@ with the absolute value of the arguments.
 gcd :: SInteger -> SInteger -> SInteger
@@ -57,21 +62,22 @@
 -- ==== __Proof__
 -- >>> runTP gcdNonNegative
 -- Inductive lemma (strong): nonNegativeNGCD
---   Step: Measure is non-negative         Q.E.D.
+--   Step: Measure is non-negative              Q.E.D.
 --   Step: 1 (2 way case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: nonNegative                      Q.E.D.
+--     Step: 1.1                                Q.E.D.
+--     Step: 1.2.1                              Q.E.D.
+--     Step: 1.2.2                              Q.E.D.
+--     Step: 1.Completeness                     Q.E.D.
+--   Result:                                    Q.E.D.
+-- Lemma: nonNegative                           Q.E.D.
+-- Functions proven terminating: nGCD
 -- [Proven] nonNegative :: Ɐa ∷ Integer → Ɐb ∷ Integer → Bool
 gcdNonNegative :: TP (Proof (Forall "a" Integer -> Forall "b" Integer -> SBool))
 gcdNonNegative = do
      -- We first prove over nGCD, using strong induction with the measure @a+b@.
      nn <- sInduct "nonNegativeNGCD"
                    (\(Forall a) (Forall b) -> a .>= 0 .&& b .>= 0 .=> nGCD a b .>= 0)
-                   (\_a b -> b) $
+                   (\_a b -> b, []) $
                    \ih a b -> [a .>= 0, b .>= 0]
                            |- cases [ b .== 0 ==> trivial
                                     , b ./= 0 ==> nGCD a b .>= 0
@@ -90,14 +96,15 @@
 -- ==== __Proof__
 -- >>> runTP gcdZero
 -- Inductive lemma (strong): nGCDZero
---   Step: Measure is non-negative         Q.E.D.
+--   Step: Measure is non-negative       Q.E.D.
 --   Step: 1 (2 way case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: gcdZero                          Q.E.D.
+--     Step: 1.1                         Q.E.D.
+--     Step: 1.2.1                       Q.E.D.
+--     Step: 1.2.2                       Q.E.D.
+--     Step: 1.Completeness              Q.E.D.
+--   Result:                             Q.E.D.
+-- Lemma: gcdZero                        Q.E.D.
+-- Functions proven terminating: nGCD
 -- [Proven] gcdZero :: Ɐa ∷ Integer → Ɐb ∷ Integer → Bool
 gcdZero :: TP (Proof (Forall "a" Integer -> Forall "b" Integer -> SBool))
 gcdZero = do
@@ -106,7 +113,7 @@
   nGCDZero <-
     sInduct "nGCDZero"
             (\(Forall @"a" a) (Forall @"b" b) -> a .>= 0 .&& b .>= 0 .&& nGCD a b .== 0 .=> a .== 0 .&& b .== 0)
-            (\_a b -> b) $
+            (\_a b -> b, []) $
             \ih a b -> [a .>= 0, b .>= 0]
                     |- (nGCD a b .== 0 .=> a .== 0 .&& b .== 0)
                     =: cases [ b .== 0 ==> trivial
@@ -117,7 +124,7 @@
                              ]
 
   lemma "gcdZero"
-        (\(Forall @"a" a) (Forall @"b" b) -> gcd a b .== 0 .=> a .== 0 .&& b .== 0) 
+        (\(Forall @"a" a) (Forall @"b" b) -> gcd a b .== 0 .=> a .== 0 .&& b .== 0)
         [proofOf nGCDZero]
 
 -- | \(\gcd\, a\ b=\gcd\, b\ a\)
@@ -125,11 +132,13 @@
 -- ==== __Proof__
 -- >>> runTP commutative
 -- Lemma: nGCDCommutative
---   Step: 1                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: 1                 Q.E.D.
+--   Result:                 Q.E.D.
 -- Lemma: commutative
---   Step: 1                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: 1                 Q.E.D.
+--   Step: 2                 Q.E.D.
+--   Result:                 Q.E.D.
+-- Functions proven terminating: nGCD
 -- [Proven] commutative :: Ɐa ∷ Integer → Ɐb ∷ Integer → Bool
 commutative :: TP (Proof (Forall "a" Integer -> Forall "b" Integer -> SBool))
 commutative = do
@@ -148,7 +157,8 @@
     calc "commutative"
           (\(Forall a) (Forall b) -> gcd a b .== gcd b a) $
           \a b -> [] |- gcd a b
-                     ?? nGCDComm
+                     =: nGCD (abs a) (abs b)
+                     ?? nGCDComm `at` (Inst @"a" (abs a), Inst @"b" (abs b))
                      =: gcd b a
                      =: qed
 
@@ -156,7 +166,8 @@
 --
 -- ==== __Proof__
 -- >>> runTP negGCD
--- Lemma: negGCD                           Q.E.D.
+-- Lemma: negGCD       Q.E.D.
+-- Functions proven terminating: nGCD
 -- [Proven] negGCD :: Ɐa ∷ Integer → Ɐb ∷ Integer → Bool
 negGCD :: TP (Proof (Forall "a" Integer -> Forall "b" Integer -> SBool))
 negGCD = lemma "negGCD" (\(Forall a) (Forall b) -> let g = gcd a b in gcd (-a) b .== g .&& g .== gcd a (-b)) []
@@ -165,10 +176,11 @@
 --
 -- ==== __Proof__
 -- >>> runTP zeroGCD
--- Lemma: negGCD                           Q.E.D.
--- [Proven] negGCD :: Ɐa ∷ Integer → Bool
+-- Lemma: zeroGCD      Q.E.D.
+-- Functions proven terminating: nGCD
+-- [Proven] zeroGCD :: Ɐa ∷ Integer → Bool
 zeroGCD :: TP (Proof (Forall "a" Integer -> SBool))
-zeroGCD = lemma "negGCD" (\(Forall a) -> gcd a 0 .== gcd 0 a .&& gcd 0 a .== abs a .&& gcd 0 0 .== 0) []
+zeroGCD = lemma "zeroGCD" (\(Forall a) -> gcd a 0 .== gcd 0 a .&& gcd 0 a .== abs a .&& gcd 0 0 .== 0) []
 
 -- * Even and odd
 
@@ -182,88 +194,116 @@
 
 -- * Divisibility
 
--- | Divides relation. By definition we @0@ only divides @0@. (But every number divides @0@).
+-- | Divides relation. By definition @0@ only divides @0@. (But every number divides @0@).
 dvd :: SInteger -> SInteger -> SBool
 a `dvd` b = ite (a .== 0) (b .== 0) (b `sEMod` a .== 0)
 
+-- | \(d \mid a \implies d \mid ka\)
+--
+-- ==== __Proof__
+-- >>> runTP dvdMul
+-- Lemma: mulMod0              Q.E.D.
+-- Lemma: dvdMul
+--   Step: 1 (2 way case split)
+--     Step: 1.1               Q.E.D.
+--     Step: 1.2.1             Q.E.D.
+--     Step: 1.2.2             Q.E.D.
+--     Step: 1.Completeness    Q.E.D.
+--   Result:                   Q.E.D.
+-- [Proven] dvdMul :: Ɐd ∷ Integer → Ɐa ∷ Integer → Ɐk ∷ Integer → Bool
+dvdMul :: TP (Proof (Forall "d" Integer -> Forall "a" Integer -> Forall "k" Integer -> SBool))
+dvdMul = do
+   -- The only genuinely nonlinear fact we need: any multiple of a nonzero @d@ leaves no
+   -- remainder modulo @d@. We prove it once, in isolation, so z3 sees the smallest possible
+   -- nonlinear goal. With this in hand, the divisibility argument below is pure substitution.
+   mulMod0 <- lemma "mulMod0"
+                    (\(Forall @"d" d) (Forall @"y" y) -> d ./= 0 .=> (d * y) `sEMod` d .== 0)
+                    []
+
+   calc "dvdMul"
+        (\(Forall d) (Forall a) (Forall k) -> d `dvd` a .=> d `dvd` (k*a)) $
+        \d a k -> [d `dvd` a]
+               |- cases [ d .== 0 ==> d `dvd` (k*a)
+                                   ?? a .== 0
+                                   =: sTrue
+                                   =: qed
+                        , d ./= 0 ==> let q = a `sEDiv` d
+                                   in d `dvd` (k*a)
+                                      =: (k*a) `sEMod` d .== 0
+                                      -- @d@ divides @a@ exactly, so @a = d*q@, hence @k*a = d*(k*q)@
+                                      ?? a     .== d * q
+                                      ?? k * a .== d * (k * q)
+                                      -- and @d*(k*q)@ is a multiple of @d@, so its remainder is @0@
+                                      ?? mulMod0 `at` (Inst @"d" d, Inst @"y" (k * q))
+                                      =: sTrue
+                                      =: qed
+                        ]
+
 -- | \(a \mid |b| \iff a \mid b\)
 --
--- A number divides another exactly when it also divides its absolute value. While this property
--- seems obvious, I was unable to get z3 to prove it. Even CVC5 needs a bit of help to guide it through
--- the case split on @b@.
+-- A number divides another exactly when it also divides its absolute value. This follows
+-- from 'dvdMul', as both directions are an instance of multiplying by @-1@.
 --
 -- ==== __Proof__
 -- >>> runTP dvdAbs
+-- Lemma: dvdMul               Q.E.D.
 -- Lemma: dvdAbs_l2r
 --   Step: 1 (2 way case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2                           Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
+--     Step: 1.1               Q.E.D.
+--     Step: 1.2               Q.E.D.
+--     Step: 1.Completeness    Q.E.D.
+--   Result:                   Q.E.D.
 -- Lemma: dvdAbs_r2l
 --   Step: 1 (2 way case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2                           Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: dvdAbs                           Q.E.D.
+--     Step: 1.1               Q.E.D.
+--     Step: 1.2               Q.E.D.
+--     Step: 1.Completeness    Q.E.D.
+--   Result:                   Q.E.D.
+-- Lemma: dvdAbs               Q.E.D.
 -- [Proven] dvdAbs :: Ɐa ∷ Integer → Ɐb ∷ Integer → Bool
 dvdAbs :: TP (Proof (Forall "a" Integer -> Forall "b" Integer -> SBool))
 dvdAbs = do
-   l2r <- calcWith cvc5 "dvdAbs_l2r"
-                   (\(Forall @"a" a) (Forall @"b" b) -> a `dvd` abs b .=> a `dvd` b) $
-                   \a b -> [a `dvd` abs b]
-                        |- cases [ b .<  0 ==> sTrue =: qed
-                                 , b .>= 0 ==> sTrue =: qed
-                                 ]
+   dM <- recall dvdMul
 
-   r2l <- calcWith cvc5 "dvdAbs_r2l"
-                   (\(Forall @"a" a) (Forall @"b" b) -> a `dvd` b .=> a `dvd` abs b) $
-                   \a b -> [a `dvd` b]
-                        |- cases [ b .<  0 ==> sTrue =: qed
-                                 , b .>= 0 ==> sTrue =: qed
-                                 ]
+   l2r <- calc "dvdAbs_l2r"
+               (\(Forall @"a" a) (Forall @"b" b) -> a `dvd` abs b .=> a `dvd` b) $
+               \a b -> [a `dvd` abs b]
+                    |- cases [ b .>= 0 ==> a `dvd` b
+                                        =: sTrue
+                                        =: qed
+                             , b .<  0 ==> a `dvd` b
+                                        ?? dM `at` (Inst @"d" a, Inst @"a" (abs b), Inst @"k" (-1))
+                                        =: sTrue
+                                        =: qed
+                             ]
 
+   r2l <- calc "dvdAbs_r2l"
+               (\(Forall @"a" a) (Forall @"b" b) -> a `dvd` b .=> a `dvd` abs b) $
+               \a b -> [a `dvd` b]
+                    |- cases [ b .>= 0 ==> a `dvd` abs b
+                                        =: sTrue
+                                        =: qed
+                             , b .<  0 ==> a `dvd` abs b
+                                        ?? dM `at` (Inst @"d" a, Inst @"a" b, Inst @"k" (-1))
+                                        =: sTrue
+                                        =: qed
+                             ]
+
    lemma "dvdAbs"
          (\(Forall @"a" a) (Forall @"b" b) -> a `dvd` b .== a `dvd` abs b)
          [proofOf l2r, proofOf r2l]
 
--- | \(d \mid a \implies d \mid ka\)
---
--- ==== __Proof__
--- >>> runTP dvdMul
--- Lemma: dvdMul
---   Step: 1 (2 way case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2                           Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
--- [Proven] dvdMul :: Ɐd ∷ Integer → Ɐa ∷ Integer → Ɐk ∷ Integer → Bool
-dvdMul :: TP (Proof (Forall "d" Integer -> Forall "a" Integer -> Forall "k" Integer -> SBool))
-dvdMul = calc "dvdMul"
-              (\(Forall d) (Forall a) (Forall k) -> d `dvd` a .=> d `dvd` (k*a)) $
-              \d a k -> [d `dvd` a]
-                     |- cases [ d .== 0 ==> d `dvd` (k*a)
-                                         ?? a .== 0
-                                         =: sTrue
-                                         =: qed
-                              , d ./= 0 ==> d `dvd` (k*a)
-                                         ?? a .== d * a `sEDiv` d
-                                         =: d `dvd` (k * d * a `sEDiv` d)
-                                         =: qed
-                              ]
-
 -- | \(d \mid (2a + 1) \implies \mathrm{isOdd}(d)\)
 --
 -- ==== __Proof__
 -- >>> runTP dvdOddThenOdd
 -- Lemma: dvdOddThenOdd
 --   Step: 1 (2 way case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
+--     Step: 1.1               Q.E.D.
+--     Step: 1.2.1             Q.E.D.
+--     Step: 1.2.2             Q.E.D.
+--     Step: 1.Completeness    Q.E.D.
+--   Result:                   Q.E.D.
 -- [Proven] dvdOddThenOdd :: Ɐd ∷ Integer → Ɐa ∷ Integer → Bool
 dvdOddThenOdd :: TP (Proof (Forall "d" Integer -> Forall "a" Integer -> SBool))
 dvdOddThenOdd = calc "dvdOddThenOdd"
@@ -279,63 +319,88 @@
 --
 -- ==== __Proof__
 -- >>> runTP dvdEvenWhenOdd
+-- Lemma: dvdMul               Q.E.D.
+-- Lemma: dvdSelf
+--   Step: 1 (2 way case split)
+--     Step: 1.1               Q.E.D.
+--     Step: 1.2.1             Q.E.D.
+--     Step: 1.2.2             Q.E.D.
+--     Step: 1.Completeness    Q.E.D.
+--   Result:                   Q.E.D.
 -- Lemma: dvdEvenWhenOdd
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Step: 6                               Q.E.D.
---   Step: 7                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: 1                   Q.E.D.
+--   Step: 2                   Q.E.D.
+--   Step: 3                   Q.E.D.
+--   Step: 4                   Q.E.D.
+--   Step: 5                   Q.E.D.
+--   Step: 6                   Q.E.D.
+--   Step: 7                   Q.E.D.
+--   Result:                   Q.E.D.
 -- [Proven] dvdEvenWhenOdd :: Ɐd ∷ Integer → Ɐa ∷ Integer → Bool
 dvdEvenWhenOdd :: TP (Proof (Forall "d" Integer -> Forall "a" Integer -> SBool))
-dvdEvenWhenOdd = calc "dvdEvenWhenOdd"
-                      (\(Forall d) (Forall a) -> isOdd d .&& d `dvd` (2*a) .=> d `dvd` a) $
-                      \d a ->  [isOdd d, d `dvd` (2*a)]
-                           |-> let t = (d - 1) `sEDiv` 2
-                                   m = (2*a)   `sEDiv` d
-                            in sTrue
+dvdEvenWhenOdd = do
+   dMul <- recall dvdMul
 
-                            -- Observe that d = 2t+1 and 2a = dm
-                            =: d .== 2*t + 1 .&& 2*a .== d*m
+   -- Every number divides itself. We could hand this to z3 directly, but as a raw fact it
+   -- forces it to reason about @d `sEMod` d@ with a symbolic divisor, which it is fickle at.
+   -- Spelling out the reduction keeps it robust.
+   dSelf <- calc "dvdSelf"
+                 (\(Forall @"d" d) -> d `dvd` d) $
+                 \d -> [] |- cases [ d .== 0 ==> trivial
+                                   , d ./= 0 ==> d `dvd` d
+                                              =: d `sEMod` d .== 0
+                                              =: sTrue
+                                              =: qed
+                                   ]
 
-                            -- So, 2a == (2t+1)m holds
-                            =: 2*a .== (2*t+1) * m
+   calc "dvdEvenWhenOdd"
+        (\(Forall d) (Forall a) -> isOdd d .&& d `dvd` (2*a) .=> d `dvd` a) $
+        \d a ->  [isOdd d, d `dvd` (2*a)]
+             |-  let t = (d - 1) `sEDiv` 2
+                     m = (2*a)   `sEDiv` d
+              in sTrue
 
-                            -- Arithmetic gives us
-                            =: 2*a .== 2*t*m + m .&& 2*(a-t*m) .== m
+              -- Observe that d = 2t+1 and 2a = dm
+              =: d .== 2*t + 1 .&& 2*a .== d*m
 
-                            -- So, we now now m is even
-                            =: 2 `sDivides` m
+              -- So, 2a == (2t+1)m holds
+              =: 2*a .== (2*t+1) * m
 
-                            -- Give that divisor a name:
-                            =: let n = m `sEDiv` 2
+              -- Arithmetic gives us
+              =: 2*a .== 2*t*m + m .&& 2*(a-t*m) .== m
 
-                            -- It follows that 2a = d(2n) = 2(dn)
-                            in 2*a .== d * (2 * n) .&& 2 * a .== 2 * (d * n)
+              -- So m = 2*(a-t*m), i.e., m is even
+              =: m .== 2 * (a - t*m)
 
-                            -- From which we can conclude a = dn
-                            =: a .== d * n
+              -- Let n = a - t*m, so m = 2n. It follows that 2a = d(2n) = 2(dn)
+              =: let n = a - t*m
+              in 2*a .== d * (2 * n) .&& 2 * a .== 2 * (d * n)
 
-                            -- Thus we can deduce d must divide a
-                            =: d `dvd` a
+              -- From which we can conclude a = dn
+              =: a .== d * n
 
-                            -- Done!
-                            =: qed
+              -- Since d divides d (dSelf), it also divides any multiple of itself, in
+              -- particular d*n (dMul). As a == d*n, d divides a. We hand z3 these as
+              -- proven facts, so it doesn't have to rediscover the divisibility itself.
+              ?? dSelf `at` Inst @"d" d
+              ?? dMul  `at` (Inst @"d" d, Inst @"a" d, Inst @"k" n)
+              =: d `dvd` a
 
+              -- Done!
+              =: qed
+
 -- | \(d \mid a \land d \mid b \implies d \mid (a + b)\)
 --
 -- ==== __Proof__
 -- >>> runTP dvdSum1
 -- Lemma: dvdSum1
 --   Step: 1 (2 way case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.2.3                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
+--     Step: 1.1               Q.E.D.
+--     Step: 1.2.1             Q.E.D.
+--     Step: 1.2.2             Q.E.D.
+--     Step: 1.2.3             Q.E.D.
+--     Step: 1.Completeness    Q.E.D.
+--   Result:                   Q.E.D.
 -- [Proven] dvdSum1 :: Ɐd ∷ Integer → Ɐa ∷ Integer → Ɐb ∷ Integer → Bool
 dvdSum1 :: TP (Proof (Forall "d" Integer -> Forall "a" Integer -> Forall "b" Integer -> SBool))
 dvdSum1 =
@@ -356,12 +421,12 @@
 -- >>> runTP dvdSum2
 -- Lemma: dvdSum2
 --   Step: 1 (2 way case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.2.3                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
+--     Step: 1.1               Q.E.D.
+--     Step: 1.2.1             Q.E.D.
+--     Step: 1.2.2             Q.E.D.
+--     Step: 1.2.3             Q.E.D.
+--     Step: 1.Completeness    Q.E.D.
+--   Result:                   Q.E.D.
 -- [Proven] dvdSum2 :: Ɐd ∷ Integer → Ɐa ∷ Integer → Ɐb ∷ Integer → Bool
 dvdSum2 :: TP (Proof (Forall "d" Integer -> Forall "a" Integer -> Forall "b" Integer -> SBool))
 dvdSum2 =
@@ -387,24 +452,25 @@
 --
 -- ==== __Proof__
 -- >>> runTP gcdDivides
--- Lemma: dvdAbs                           Q.E.D.
+-- Lemma: dvdAbs                        Q.E.D.
 -- Lemma: helper
---   Step: 1                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: 1                            Q.E.D.
+--   Result:                            Q.E.D.
 -- Inductive lemma (strong): dvdNGCD
---   Step: Measure is non-negative         Q.E.D.
+--   Step: Measure is non-negative      Q.E.D.
 --   Step: 1 (2 way case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: gcdDivides                       Q.E.D.
+--     Step: 1.1                        Q.E.D.
+--     Step: 1.2.1                      Q.E.D.
+--     Step: 1.2.2                      Q.E.D.
+--     Step: 1.Completeness             Q.E.D.
+--   Result:                            Q.E.D.
+-- Lemma: gcdDivides                    Q.E.D.
+-- Functions proven terminating: nGCD
 -- [Proven] gcdDivides :: Ɐa ∷ Integer → Ɐb ∷ Integer → Bool
 gcdDivides :: TP (Proof (Forall "a" Integer -> Forall "b" Integer -> SBool))
 gcdDivides = do
 
-   dAbs <- recall "dvdAbs" dvdAbs
+   dAbs <- recall dvdAbs
 
    -- Helper about divisibility. If x|b and x| a%b, then x|a.
    helper <- calc "helper"
@@ -422,7 +488,7 @@
    -- Use strong induction to prove divisibility over non-negative numbers.
    dNGCD <- sInduct "dvdNGCD"
                      (\(Forall @"a" a) (Forall @"b" b) -> a .>= 0 .&& b .>= 0 .=> nGCD a b `dvd` a .&& nGCD a b `dvd` b)
-                     (\_a b -> b) $
+                     (\_a b -> b, []) $
                      \ih a b -> [a .>= 0, b .>= 0]
                              |- let g = nGCD a b
                              in g `dvd` a .&& g `dvd` b
@@ -446,34 +512,39 @@
 --
 -- ==== __Proof__
 -- >>> runTP gcdMaximal
--- Lemma: dvdAbs                           Q.E.D.
--- Lemma: eDiv                             Q.E.D.
+-- Lemma: dvdAbs                         Q.E.D.
+-- Lemma: commutative                    Q.E.D.
+-- Lemma: eDiv                           Q.E.D.
 -- Lemma: helper
---   Step: 1 (x `dvd` a && x `dvd` b)      Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: 1 (x `dvd` a && x `dvd` b)    Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Step: 3                             Q.E.D.
+--   Result:                             Q.E.D.
 -- Inductive lemma (strong): mNGCD
---   Step: Measure is non-negative         Q.E.D.
+--   Step: Measure is non-negative       Q.E.D.
 --   Step: 1 (2 way case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
+--     Step: 1.1                         Q.E.D.
+--     Step: 1.2.1                       Q.E.D.
+--     Step: 1.2.2                       Q.E.D.
+--     Step: 1.Completeness              Q.E.D.
+--   Result:                             Q.E.D.
 -- Lemma: gcdMaximal
 --   Step: 1 (2 way case split)
---     Step: 1.1.1                         Q.E.D.
---     Step: 1.1.2                         Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
+--     Step: 1.1.1                       Q.E.D.
+--     Step: 1.1.2                       Q.E.D.
+--     Step: 1.2.1                       Q.E.D.
+--     Step: 1.2.2                       Q.E.D.
+--     Step: 1.2.3                       Q.E.D.
+--     Step: 1.2.4                       Q.E.D.
+--     Step: 1.Completeness              Q.E.D.
+--   Result:                             Q.E.D.
+-- Functions proven terminating: nGCD
 -- [Proven] gcdMaximal :: Ɐa ∷ Integer → Ɐb ∷ Integer → Ɐx ∷ Integer → Bool
 gcdMaximal :: TP (Proof (Forall "a" Integer -> Forall "b" Integer -> Forall "x" Integer -> SBool))
 gcdMaximal = do
 
-   dAbs  <- recall "dvdAbs" dvdAbs
+   dAbs <- recall dvdAbs
+   comm <- recall commutative
 
    eDiv <- lemma "eDiv"
                  (\(Forall @"x" x) (Forall @"y" y) -> y ./= 0 .=> x .== (x `sEDiv` y) * y + x `sEMod` y)
@@ -501,7 +572,7 @@
    mNGCD <- sInduct "mNGCD"
                     (\(Forall @"a" a) (Forall @"b" b) (Forall @"x" x) ->
                           a .>= 0 .&& b .>= 0 .&& x `dvd` a .&& x `dvd` b .=> x `dvd` nGCD a b)
-                    (\_a b _x -> b) $
+                    (\_a b _x -> b, []) $
                     \ih a b x -> let g = nGCD a b
                               in [a .>= 0, b .>= 0, x `dvd` a .&& x `dvd` b]
                               |- x `dvd` g
@@ -524,7 +595,10 @@
                                            ?? dAbs     `at` (Inst @"a" x, Inst @"b" b)
                                            =: sTrue
                                            =: qed
-                        , abs a .<  abs b ==> x `dvd` nGCD (abs b) (abs a)
+                        , abs a .<  abs b ==> x `dvd` gcd a b
+                                           ?? comm `at` (Inst @"a" a, Inst @"b" b)
+                                           =: x `dvd` gcd b a
+                                           =: x `dvd` nGCD (abs b) (abs a)
                                            ?? mNGCD    `at` (Inst @"a" (abs b), Inst @"b" (abs a), Inst @"x" x)
                                            ?? dAbs     `at` (Inst @"a" x, Inst @"b" a)
                                            ?? dAbs     `at` (Inst @"a" x, Inst @"b" b)
@@ -538,17 +612,18 @@
 --
 -- ==== __Proof__
 -- >>> runTP gcdCorrect
--- Lemma: gcdDivides                       Q.E.D.
--- Lemma: gcdMaximal                       Q.E.D.
+-- Lemma: gcdDivides                     Q.E.D.
+-- Lemma: gcdMaximal                     Q.E.D.
 -- Lemma: gcdCorrect
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Result:                             Q.E.D.
+-- Functions proven terminating: nGCD
 -- [Proven] gcdCorrect :: Ɐa ∷ Integer → Ɐb ∷ Integer → Bool
 gcdCorrect :: TP (Proof (Forall "a" Integer -> Forall "b" Integer -> SBool))
 gcdCorrect = do
-  divides <- recall "gcdDivides" gcdDivides
-  maximal <- recall "gcdMaximal" gcdMaximal
+  divides <- recall gcdDivides
+  maximal <- recall gcdMaximal
 
   calc "gcdCorrect"
        (\(Forall a) (Forall b) ->
@@ -576,19 +651,20 @@
 --
 -- ==== __Proof__
 -- >>> runTP gcdLargest
--- Lemma: gcdMaximal                       Q.E.D.
--- Lemma: gcdZero                          Q.E.D.
--- Lemma: gcdNonNegative                   Q.E.D.
+-- Lemma: gcdMaximal                            Q.E.D.
+-- Lemma: gcdZero                               Q.E.D.
+-- Lemma: nonNegative                           Q.E.D.
 -- Lemma: gcdLargest
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: 1                                    Q.E.D.
+--   Step: 2                                    Q.E.D.
+--   Result:                                    Q.E.D.
+-- Functions proven terminating: nGCD
 -- [Proven] gcdLargest :: Ɐa ∷ Integer → Ɐb ∷ Integer → Ɐx ∷ Integer → Bool
 gcdLargest :: TP (Proof (Forall "a" Integer -> Forall "b" Integer -> Forall "x" Integer -> SBool))
 gcdLargest = do
-   maximal <- recall "gcdMaximal"     gcdMaximal
-   zero    <- recall "gcdZero"        gcdZero
-   nn      <- recall "gcdNonNegative" gcdNonNegative
+   maximal <- recall gcdMaximal
+   gcdZ    <- recall gcdZero
+   nn      <- recall gcdNonNegative
 
    calc "gcdLargest"
         (\(Forall a) (Forall b) (Forall x) -> (a ./= 0 .|| b ./= 0) .&& x `dvd` a .&& x `dvd` b .=> x .<= gcd a b) $
@@ -596,7 +672,7 @@
                |- x .<= gcd a b
                ?? maximal `at` (Inst @"a" a, Inst @"b" b, Inst @"x" x)
                =: (x `dvd` gcd a b .=> x .<= gcd a b)
-               ?? zero  `at` (Inst @"a" a, Inst @"b" b)
+               ?? gcdZ  `at` (Inst @"a" a, Inst @"b" b)
                ?? nn    `at` (Inst @"a" a, Inst @"b" b)
                =: sTrue
                =: qed
@@ -607,27 +683,28 @@
 --
 -- ==== __Proof__
 -- >>> runTP gcdAdd
--- Lemma: dvdSum1                          Q.E.D.
--- Lemma: dvdSum2                          Q.E.D.
--- Lemma: gcdDivides                       Q.E.D.
--- Lemma: gcdLargest                       Q.E.D.
+-- Lemma: dvdSum1                               Q.E.D.
+-- Lemma: dvdSum2                               Q.E.D.
+-- Lemma: gcdDivides                            Q.E.D.
+-- Lemma: gcdLargest                            Q.E.D.
 -- Lemma: gcdAdd
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Step: 6                               Q.E.D.
---   Step: 7                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: 1                                    Q.E.D.
+--   Step: 2                                    Q.E.D.
+--   Step: 3                                    Q.E.D.
+--   Step: 4                                    Q.E.D.
+--   Step: 5                                    Q.E.D.
+--   Step: 6                                    Q.E.D.
+--   Step: 7                                    Q.E.D.
+--   Result:                                    Q.E.D.
+-- Functions proven terminating: nGCD
 -- [Proven] gcdAdd :: Ɐa ∷ Integer → Ɐb ∷ Integer → Bool
 gcdAdd :: TP (Proof (Forall "a" Integer -> Forall "b" Integer -> SBool))
 gcdAdd = do
 
-   dSum1   <- recall "dvdSum1"    dvdSum1
-   dSum2   <- recall "dvdSum2"    dvdSum2
-   divides <- recall "gcdDivides" gcdDivides
-   largest <- recall "gcdLargest" gcdLargest
+   dSum1   <- recall dvdSum1
+   dSum2   <- recall dvdSum2
+   divides <- recall gcdDivides
+   largest <- recall gcdLargest
 
    calc "gcdAdd"
         (\(Forall @"a" a) (Forall @"b" b) -> gcd a b .== gcd (a + b) b) $
@@ -667,34 +744,50 @@
 --
 -- ==== __Proof__
 -- >>> runTP gcdEvenEven
--- Lemma: modEE                            Q.E.D.
+-- Lemma: red2                               Q.E.D.
+-- Lemma: modEE
+--   Step: 1                                 Q.E.D.
+--   Step: 2                                 Q.E.D.
+--   Step: 3                                 Q.E.D.
+--   Result:                                 Q.E.D.
 -- Inductive lemma (strong): nGCDEvenEven
---   Step: Measure is non-negative         Q.E.D.
+--   Step: Measure is non-negative           Q.E.D.
 --   Step: 1 (2 way case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.2.3                         Q.E.D.
---     Step: 1.2.4                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
+--     Step: 1.1                             Q.E.D.
+--     Step: 1.2.1                           Q.E.D.
+--     Step: 1.2.2                           Q.E.D.
+--     Step: 1.2.3                           Q.E.D.
+--     Step: 1.2.4                           Q.E.D.
+--     Step: 1.Completeness                  Q.E.D.
+--   Result:                                 Q.E.D.
 -- Lemma: gcdEvenEven
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: 1                                 Q.E.D.
+--   Step: 2                                 Q.E.D.
+--   Step: 3                                 Q.E.D.
+--   Step: 4                                 Q.E.D.
+--   Result:                                 Q.E.D.
+-- Functions proven terminating: nGCD
 -- [Proven] gcdEvenEven :: Ɐa ∷ Integer → Ɐb ∷ Integer → Bool
 gcdEvenEven :: TP (Proof (Forall "a" Integer -> Forall "b" Integer -> SBool))
 gcdEvenEven = do
 
-   modEE <- lemma "modEE"
-                  (\(Forall @"a" a) (Forall @"b" b) -> b ./= 0 .=> (2 * a) `sEMod` (2 * b) .== 2 * (a `sEMod` b))
+   red2  <- lemmaWith z3 "red2"
+                  (\(Forall @"a" a) (Forall @"b" b) -> b ./= 0 .=> (2*a) `sEDiv` (2*b) .== a `sEDiv` b)
                   []
 
+   modEE <- calcWith cvc5 "modEE"
+                 (\(Forall @"a" a) (Forall @"b" b) -> b ./= 0 .=> (2*a) `sEMod` (2*b) .== 2 * (a `sEMod` b)) $
+                 \a b -> [b ./= 0]
+                      |- (2*a) `sEMod` (2*b)
+                      ?? red2 `at` (Inst @"a" a, Inst @"b" b)
+                      =: 2*a - 2*b * (a `sEDiv` b)
+                      =: 2 * (a - b * (a `sEDiv` b))
+                      =: 2 * (a `sEMod` b)
+                      =: qed
+
    nGCDEvenEven <- sInduct "nGCDEvenEven"
                            (\(Forall @"a" a) (Forall @"b" b) -> a .>= 0 .&& b .>= 0 .=> nGCD (2*a) (2*b) .== 2 * nGCD a b)
-                           (\_a b -> b) $
+                           (\_a b -> b, []) $
                            \ih a b -> [a .>= 0, b .>= 0]
                                    |- nGCD (2*a) (2*b)
                                    =: cases [ b .== 0 ==> trivial
@@ -721,30 +814,31 @@
 --
 -- ==== __Proof__
 -- >>> runTP gcdOddEven
--- Lemma: gcdDivides                       Q.E.D.
--- Lemma: gcdLargest                       Q.E.D.
--- Lemma: dvdMul                           Q.E.D.
--- Lemma: dvdOddThenOdd                    Q.E.D.
--- Lemma: dvdEvenWhenOdd                   Q.E.D.
+-- Lemma: gcdDivides                            Q.E.D.
+-- Lemma: gcdLargest                            Q.E.D.
+-- Lemma: dvdMul                                Q.E.D. [Cached]
+-- Lemma: dvdOddThenOdd                         Q.E.D.
+-- Lemma: dvdEvenWhenOdd                        Q.E.D.
 -- Lemma: gcdOddEven
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Step: 6                               Q.E.D.
---   Step: 7                               Q.E.D.
---   Step: 8                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: 1                                    Q.E.D.
+--   Step: 2                                    Q.E.D.
+--   Step: 3                                    Q.E.D.
+--   Step: 4                                    Q.E.D.
+--   Step: 5                                    Q.E.D.
+--   Step: 6                                    Q.E.D.
+--   Step: 7                                    Q.E.D.
+--   Step: 8                                    Q.E.D.
+--   Result:                                    Q.E.D.
+-- Functions proven terminating: nGCD
 -- [Proven] gcdOddEven :: Ɐa ∷ Integer → Ɐb ∷ Integer → Bool
 gcdOddEven :: TP (Proof (Forall "a" Integer -> Forall "b" Integer -> SBool))
 gcdOddEven = do
 
-   divides      <- recall "gcdDivides"     gcdDivides
-   largest      <- recall "gcdLargest"     gcdLargest
-   dMul         <- recall "dvdMul"         dvdMul
-   dOddThenOdd  <- recall "dvdOddThenOdd"  dvdOddThenOdd
-   dEvenWhenOdd <- recall "dvdEvenWhenOdd" dvdEvenWhenOdd
+   divides      <- recall gcdDivides
+   largest      <- recall gcdLargest
+   dMul         <- recall dvdMul
+   dOddThenOdd  <- recall dvdOddThenOdd
+   dEvenWhenOdd <- recall dvdEvenWhenOdd
 
    calc "gcdOddEven"
         (\(Forall a) (Forall b) -> gcd (2*a+1) (2*b) .== gcd (2*a+1) b) $
@@ -786,15 +880,18 @@
 
 -- * GCD via subtraction
 
--- | @nGCDSub@ is the original verision of Euclid, which uses subtraction instead of modulus. This is the version that
+-- | @nGCDSub@ is the original version of Euclid, which uses subtraction instead of modulus. This is the version that
 -- works on non-negative numbers. It has the precondition that @a >= b >= 0@, and maintains this invariant in each
 -- recursive call.
 nGCDSub :: SInteger -> SInteger -> SInteger
-nGCDSub = smtFunction "nGCDSub" $ \a b -> ite (a .== b) a
-                                        $ ite (a .== 0) b
-                                        $ ite (b .== 0) a
-                                        $ ite (a .> b)  (nGCDSub (a - b) b)
-                                                        (nGCDSub a (b - a))
+nGCDSub = smtFunction "nGCDSub"
+        $ \a b -> [sCase| a of
+                     _ | a .== b -> a
+                     _ | a .<= 0 -> b
+                     _ | b .<= 0 -> a
+                     _ | a .> b  -> nGCDSub (a - b) b
+                     _           -> nGCDSub a (b - a)
+                  |]
 
 -- | Generalized version of subtraction based GCD, working over all integers.
 gcdSub :: SInteger -> SInteger -> SInteger
@@ -807,41 +904,59 @@
 --
 -- ==== __Proof__
 -- >>> runTP gcdSubEquiv
--- Lemma: commutative                      Q.E.D.
--- Lemma: gcdAdd                           Q.E.D.
+-- Lemma: commutative                           Q.E.D.
+-- Lemma: gcdAdd                                Q.E.D.
+-- Lemma: gcdNonNeg
+--   Step: 1                                    Q.E.D.
+--   Result:                                    Q.E.D.
 -- Inductive lemma (strong): nGCDSubEquiv
---   Step: Measure is non-negative         Q.E.D.
+--   Step: Measure is non-negative              Q.E.D.
 --   Step: 1 (5 way case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2                           Q.E.D.
---     Step: 1.3                           Q.E.D.
---     Step: 1.4.1                         Q.E.D.
---     Step: 1.4.2                         Q.E.D.
---     Step: 1.4.3                         Q.E.D.
---     Step: 1.5.1                         Q.E.D.
---     Step: 1.5.2                         Q.E.D.
---     Step: 1.5.3                         Q.E.D.
---     Step: 1.5.4                         Q.E.D.
---     Step: 1.5.5                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
+--     Step: 1.1                                Q.E.D.
+--     Step: 1.2                                Q.E.D.
+--     Step: 1.3                                Q.E.D.
+--     Step: 1.4.1                              Q.E.D.
+--     Step: 1.4.2                              Q.E.D.
+--     Step: 1.4.3                              Q.E.D.
+--     Step: 1.5.1                              Q.E.D.
+--     Step: 1.5.2                              Q.E.D.
+--     Step: 1.5.3                              Q.E.D.
+--     Step: 1.5.4                              Q.E.D.
+--     Step: 1.5.5                              Q.E.D.
+--     Step: 1.Completeness                     Q.E.D.
+--   Result:                                    Q.E.D.
 -- Lemma: gcdSubEquiv
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: 1                                    Q.E.D.
+--   Step: 2                                    Q.E.D.
+--   Step: 3                                    Q.E.D.
+--   Result:                                    Q.E.D.
+-- Functions proven terminating: nGCD, nGCDSub
 -- [Proven] gcdSubEquiv :: Ɐa ∷ Integer → Ɐb ∷ Integer → Bool
 gcdSubEquiv :: TP (Proof (Forall "a" Integer -> Forall "b" Integer -> SBool))
 gcdSubEquiv = do
 
    -- We'll be using the commutativity of GCD and the gcdAdd property
-   comm <- recall "commutative" commutative
-   addG <- recall "gcdAdd"      gcdAdd
+   comm <- recall commutative
+   addG <- recall gcdAdd
 
+   -- Bridge from the general @gcd@ (used by @comm@/@addG@) to @nGCD@ on non-negative inputs.
+   -- Since @gcd x y = nGCD (abs x) (abs y)@, this is just @abs@ elimination -- but proving it
+   -- here, in isolation, lets z3 close it by congruence (equal args => equal @nGCD@) instead of
+   -- unfolding the recursive @nGCD@. Handed to the induction below as an opaque equality, it
+   -- keeps z3 from diverging when relating @gcd@-facts to @nGCD@.
+   nnB <- calc "gcdNonNeg"
+               (\(Forall @"x" x) (Forall @"y" y) -> x .>= 0 .&& y .>= 0 .=> gcd x y .== nGCD x y) $
+               \x y -> [x .>= 0, y .>= 0]
+                    |- gcd x y
+                    ?? abs x .== x
+                    ?? abs y .== y
+                    =: nGCD x y
+                    =: qed
+
    -- First prove over the non-negative numbers:
    nEq <- sInduct "nGCDSubEquiv"
                   (\(Forall @"a" a) (Forall @"b" b) -> a .>= 0 .&& b .>= 0 .=> nGCDSub a b .== nGCD a b)
-                  (\a b -> a + b) $
+                  (\a b -> a + b, []) $
                   \ih a b -> [a .>= 0, b .>= 0]
                           |- nGCDSub a b
                           =: cases [ a .== b             ==> nGCD a b =: qed
@@ -851,16 +966,28 @@
                                                           ?? ih
                                                           =: nGCD (a - b) b
                                                           ?? addG `at` (Inst @"a" (a - b), Inst @"b" b)
+                                                          ?? nnB  `at` (Inst @"x" (a - b), Inst @"y" b)
+                                                          ?? nnB  `at` (Inst @"x" a,       Inst @"y" b)
                                                           =: nGCD a b
                                                           =: qed
                                    , a .< b  .&& a ./= 0 ==> nGCDSub a (b - a)
                                                           ?? ih
                                                           =: nGCD a (b - a)
                                                           ?? comm
+                                                          ?? nnB `at` (Inst @"x" a,       Inst @"y" (b - a))
+                                                          ?? nnB `at` (Inst @"x" (b - a), Inst @"y" a)
                                                           =: nGCD (b - a) a
+                                                          -- @addG@ is stated over @gcd@; hand z3 the
+                                                          -- @gcd = nGCD@ bridge (via @nnB@) as proven
+                                                          -- equalities so it closes this by chaining
+                                                          -- rather than unfolding the recursive @nGCD@.
                                                           ?? addG `at` (Inst @"a" (b - a), Inst @"b" a)
+                                                          ?? nnB  `at` (Inst @"x" (b - a), Inst @"y" a)
+                                                          ?? nnB  `at` (Inst @"x" b,       Inst @"y" a)
                                                           =: nGCD b a
                                                           ?? comm
+                                                          ?? nnB `at` (Inst @"x" b, Inst @"y" a)
+                                                          ?? nnB `at` (Inst @"x" a, Inst @"y" b)
                                                           =: nGCD a b
                                                           =: qed
                                    ]
@@ -879,12 +1006,15 @@
 
 -- | @nGCDBin@ is the binary GCD algorithm that works on non-negative numbers.
 nGCDBin :: SInteger -> SInteger -> SInteger
-nGCDBin = smtFunction "nGCDBin" $ \a b -> ite (a .== 0)               b
-                                        $ ite (b .== 0)               a
-                                        $ ite (isEven a .&& isEven b) (2 * nGCDBin (a `sEDiv` 2) (b `sEDiv` 2))
-                                        $ ite (isOdd  a .&& isEven b) (    nGCDBin a             (b `sEDiv` 2))
-                                        $ ite (a .<= b)               (    nGCDBin a             (b - a))
-                                                                      (    nGCDBin (a - b)       b)
+nGCDBin = smtFunction "nGCDBin"
+        $ \a b -> [sCase| a of
+                     _ | a .<= 0               -> b
+                     _ | b .<= 0               -> a
+                     _ | isEven a .&& isEven b -> 2 * nGCDBin (a `sEDiv` 2) (b `sEDiv` 2)
+                     _ | isOdd  a .&& isEven b -> nGCDBin a (b `sEDiv` 2)
+                     _ | a .<= b               -> nGCDBin a (b - a)
+                     _                         -> nGCDBin (a - b) b
+                  |]
 -- | Generalized version that works on arbitrary integers.
 gcdBin :: SInteger -> SInteger -> SInteger
 gcdBin a b = nGCDBin (abs a) (abs b)
@@ -896,53 +1026,54 @@
 --
 -- ==== __Proof__
 -- >>> runTP gcdBinEquiv
--- Lemma: gcdEvenEven                      Q.E.D.
--- Lemma: gcdOddEven                       Q.E.D.
--- Lemma: gcdAdd                           Q.E.D.
--- Lemma: commutative                      Q.E.D.
+-- Lemma: gcdEvenEven                           Q.E.D.
+-- Lemma: gcdOddEven                            Q.E.D.
+-- Lemma: gcdAdd                                Q.E.D.
+-- Lemma: commutative                           Q.E.D. [Cached]
 -- Inductive lemma (strong): nGCDBinEquiv
---   Step: Measure is non-negative         Q.E.D.
+--   Step: Measure is non-negative              Q.E.D.
 --   Step: 1 (5 way case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2                           Q.E.D.
---     Step: 1.3.1                         Q.E.D.
---     Step: 1.3.2                         Q.E.D.
---     Step: 1.3.3                         Q.E.D.
---     Step: 1.4.1                         Q.E.D.
---     Step: 1.4.2                         Q.E.D.
---     Step: 1.4.3                         Q.E.D.
+--     Step: 1.1                                Q.E.D.
+--     Step: 1.2                                Q.E.D.
+--     Step: 1.3.1                              Q.E.D.
+--     Step: 1.3.2                              Q.E.D.
+--     Step: 1.3.3                              Q.E.D.
+--     Step: 1.4.1                              Q.E.D.
+--     Step: 1.4.2                              Q.E.D.
+--     Step: 1.4.3                              Q.E.D.
 --     Step: 1.5 (3 way case split)
---       Step: 1.5.1                       Q.E.D.
---       Step: 1.5.2.1                     Q.E.D.
---       Step: 1.5.2.2                     Q.E.D.
---       Step: 1.5.2.3                     Q.E.D.
---       Step: 1.5.2.4                     Q.E.D.
---       Step: 1.5.2.5                     Q.E.D.
---       Step: 1.5.2.6                     Q.E.D.
---       Step: 1.5.3.1                     Q.E.D.
---       Step: 1.5.3.2                     Q.E.D.
---       Step: 1.5.3.3                     Q.E.D.
---       Step: 1.5.3.4                     Q.E.D.
---       Step: 1.5.Completeness            Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
+--       Step: 1.5.1                            Q.E.D.
+--       Step: 1.5.2.1                          Q.E.D.
+--       Step: 1.5.2.2                          Q.E.D.
+--       Step: 1.5.2.3                          Q.E.D.
+--       Step: 1.5.2.4                          Q.E.D.
+--       Step: 1.5.2.5                          Q.E.D.
+--       Step: 1.5.2.6                          Q.E.D.
+--       Step: 1.5.3.1                          Q.E.D.
+--       Step: 1.5.3.2                          Q.E.D.
+--       Step: 1.5.3.3                          Q.E.D.
+--       Step: 1.5.3.4                          Q.E.D.
+--       Step: 1.5.Completeness                 Q.E.D.
+--     Step: 1.Completeness                     Q.E.D.
+--   Result:                                    Q.E.D.
 -- Lemma: gcdBinEquiv
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: 1                                    Q.E.D.
+--   Step: 2                                    Q.E.D.
+--   Step: 3                                    Q.E.D.
+--   Result:                                    Q.E.D.
+-- Functions proven terminating: nGCD, nGCDBin
 -- [Proven] gcdBinEquiv :: Ɐa ∷ Integer → Ɐb ∷ Integer → Bool
 gcdBinEquiv :: TP (Proof (Forall "a" Integer -> Forall "b" Integer -> SBool))
 gcdBinEquiv = do
-   gEvenEven <- recall "gcdEvenEven" gcdEvenEven
-   gOddEven  <- recall "gcdOddEven"  gcdOddEven
-   gAdd      <- recall "gcdAdd"      gcdAdd
-   comm      <- recall "commutative" commutative
+   gEvenEven <- recallWith cvc5 gcdEvenEven
+   gOddEven  <- recall gcdOddEven
+   gAdd      <- recall gcdAdd
+   comm      <- recall commutative
 
    -- First prove over the non-negative numbers:
    nEq <- sInduct "nGCDBinEquiv"
                   (\(Forall @"a" a) (Forall @"b" b) -> a .>= 0 .&& b .>= 0 .=> nGCDBin a b .== nGCD a b)
-                  (\a b -> tuple (a, b)) $
+                  (\a b -> tuple (a, b), []) $
                   \ih a b -> [a .>= 0, b .>= 0]
                           |- nGCDBin a b
                           =: cases [ a .== 0               ==> trivial
diff --git a/Documentation/SBV/Examples/TP/InsertionSort.hs b/Documentation/SBV/Examples/TP/InsertionSort.hs
--- a/Documentation/SBV/Examples/TP/InsertionSort.hs
+++ b/Documentation/SBV/Examples/TP/InsertionSort.hs
@@ -13,9 +13,10 @@
 {-# LANGUAGE DataKinds           #-}
 {-# LANGUAGE FlexibleContexts    #-}
 {-# LANGUAGE OverloadedLists     #-}
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeAbstractions    #-}
 {-# LANGUAGE TypeApplications    #-}
-{-# LANGUAGE ScopedTypeVariables #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -38,31 +39,39 @@
 
 -- | Insert an element into an already sorted list in the correct place.
 insert :: (OrdSymbolic (SBV a), SymVal a) => SBV a -> SList a -> SList a
-insert = smtFunction "insert" $ \e l -> ite (null l) [e]
-                                      $ let (x, xs) = uncons l
-                                        in ite (e .<= x) (e .: x .: xs) (x .: insert e xs)
+insert = smtFunction "insert"
+       $ \e l -> [sCase| l of
+                     []               -> [e]
+                     x : xs | e .<= x -> e .: x .: xs
+                            | True    -> x .: insert e xs
+                 |]
 
 -- | Insertion sort, using 'insert' above to successively insert the elements.
 insertionSort :: (OrdSymbolic (SBV a), SymVal a) => SList a -> SList a
-insertionSort = smtFunction "insertionSort" $ \l -> ite (null l) nil
-                                                  $ let (x, xs) = uncons l
-                                                    in insert x (insertionSort xs)
+insertionSort = smtFunction "insertionSort"
+              $ \l -> [sCase| l of
+                          []     -> []
+                          x : xs -> insert x (insertionSort xs)
+                      |]
 
 
 -- | Remove the first occurrence of an number from a list, if any.
 removeFirst :: (Eq a, SymVal a) => SBV a -> SList a -> SList a
-removeFirst = smtFunction "removeFirst" $ \e l -> ite (null l)
-                                                      nil
-                                                      (let (x, xs) = uncons l
-                                                       in ite (e .== x) xs (x .: removeFirst e xs))
+removeFirst = smtFunction "removeFirst"
+            $ \e l -> [sCase| l of
+                          []               -> []
+                          x : xs | e .== x -> xs
+                                 | True    -> x .: removeFirst e xs
+                      |]
 
 -- | Are two lists permutations of each other? Note that we diverge from the counting
 -- based definition of permutation here, since this variant works better with insertion sort.
 isPermutation :: (Eq a, SymVal a) => SList a -> SList a -> SBool
-isPermutation = smtFunction "isPermutation" $ \l r -> ite (null l)
-                                                          (null r)
-                                                          (let (x, xs) = uncons l
-                                                           in x `elem` r .&& isPermutation xs (removeFirst x r))
+isPermutation = smtFunction "isPermutation"
+              $ \l r -> [sCase| l of
+                            []     -> null r
+                            x : xs -> x `elem` r .&& isPermutation xs (removeFirst x r)
+                        |]
 
 -- * Correctness proof
 
@@ -71,48 +80,49 @@
 -- We have:
 --
 -- >>> correctness @Integer
--- Lemma: nonDecrTail                           Q.E.D.
+-- Lemma: nonDecrTail                          Q.E.D.
 -- Inductive lemma: insertNonDecreasing
---   Step: Base                                 Q.E.D.
---   Step: 1 (unfold insert)                    Q.E.D.
---   Step: 2 (push nonDecreasing down)          Q.E.D.
---   Step: 3 (unfold simplify)                  Q.E.D.
---   Step: 4                                    Q.E.D.
---   Step: 5                                    Q.E.D.
---   Result:                                    Q.E.D.
+--   Step: Base                                Q.E.D.
+--   Step: 1 (unfold insert)                   Q.E.D.
+--   Step: 2 (push nonDecreasing down)         Q.E.D.
+--   Step: 3 (unfold simplify)                 Q.E.D.
+--   Step: 4                                   Q.E.D.
+--   Step: 5                                   Q.E.D.
+--   Result:                                   Q.E.D.
 -- Inductive lemma: sortNonDecreasing
---   Step: Base                                 Q.E.D.
---   Step: 1 (unfold insertionSort)             Q.E.D.
---   Step: 2                                    Q.E.D.
---   Result:                                    Q.E.D.
+--   Step: Base                                Q.E.D.
+--   Step: 1 (unfold insertionSort)            Q.E.D.
+--   Step: 2                                   Q.E.D.
+--   Result:                                   Q.E.D.
 -- Inductive lemma: insertIsElem
---   Step: Base                                 Q.E.D.
---   Step: 1                                    Q.E.D.
---   Step: 2                                    Q.E.D.
---   Step: 3                                    Q.E.D.
---   Step: 4                                    Q.E.D.
---   Result:                                    Q.E.D.
+--   Step: Base                                Q.E.D.
+--   Step: 1                                   Q.E.D.
+--   Step: 2                                   Q.E.D.
+--   Step: 3                                   Q.E.D.
+--   Step: 4                                   Q.E.D.
+--   Result:                                   Q.E.D.
 -- Inductive lemma: removeAfterInsert
---   Step: Base                                 Q.E.D.
---   Step: 1 (expand insert)                    Q.E.D.
---   Step: 2 (push removeFirst down ite)        Q.E.D.
---   Step: 3 (unfold removeFirst on 'then')     Q.E.D.
---   Step: 4 (unfold removeFirst on 'else')     Q.E.D.
---   Step: 5                                    Q.E.D.
---   Step: 6 (simplify)                         Q.E.D.
---   Result:                                    Q.E.D.
+--   Step: Base                                Q.E.D.
+--   Step: 1 (expand insert)                   Q.E.D.
+--   Step: 2 (push removeFirst down ite)       Q.E.D.
+--   Step: 3 (unfold removeFirst on 'then')    Q.E.D.
+--   Step: 4 (unfold removeFirst on 'else')    Q.E.D.
+--   Step: 5                                   Q.E.D.
+--   Step: 6 (simplify)                        Q.E.D.
+--   Result:                                   Q.E.D.
 -- Inductive lemma: sortIsPermutation
---   Step: Base                                 Q.E.D.
---   Step: 1                                    Q.E.D.
---   Step: 2                                    Q.E.D.
---   Step: 3                                    Q.E.D.
---   Step: 4                                    Q.E.D.
---   Step: 5                                    Q.E.D.
---   Result:                                    Q.E.D.
--- Lemma: insertionSortIsCorrect                Q.E.D.
+--   Step: Base                                Q.E.D.
+--   Step: 1                                   Q.E.D.
+--   Step: 2                                   Q.E.D.
+--   Step: 3                                   Q.E.D.
+--   Step: 4                                   Q.E.D.
+--   Step: 5                                   Q.E.D.
+--   Result:                                   Q.E.D.
+-- Lemma: insertionSortIsCorrect               Q.E.D.
+-- Functions proven terminating: insert, insertionSort, isPermutation, nonDecreasing, removeFirst
 -- [Proven] insertionSortIsCorrect :: Ɐxs ∷ [Integer] → Bool
 correctness :: forall a. (OrdSymbolic (SBV a), Eq a, SymVal a) => IO (Proof (Forall "xs" [a] -> SBool))
-correctness = runTPWith (tpRibbon 45 cvc5) $ do
+correctness = runTPWith cvc5 $ do
 
     --------------------------------------------------------------------------------------------
     -- Part I. Import helper lemmas, definitions
@@ -158,7 +168,7 @@
                                  =: qed
 
     --------------------------------------------------------------------------------------------
-    -- Part III. Prove that the output of insertion sort is a permuation of its input
+    -- Part III. Prove that the output of insertion sort is a permutation of its input
     --------------------------------------------------------------------------------------------
 
     insertIsElem <-
diff --git a/Documentation/SBV/Examples/TP/Kadane.hs b/Documentation/SBV/Examples/TP/Kadane.hs
new file mode 100644
--- /dev/null
+++ b/Documentation/SBV/Examples/TP/Kadane.hs
@@ -0,0 +1,175 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Documentation.SBV.Examples.TP.Kadane
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Proving the correctness of Kadane's algorithm for computing the maximum
+-- sum of any contiguous list (maximum segment sum problem).
+--
+-- Kadane's algorithm is a classic dynamic programming algorithm that solves
+-- the maximum segment sum problem in O(n) time. Given a list of integers,
+-- it finds the maximum sum of any contiguous list, where the empty
+-- list has sum 0.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE CPP                 #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE OverloadedLists     #-}
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Documentation.SBV.Examples.TP.Kadane where
+
+import Prelude hiding (length, maximum, null, head, tail, (++))
+
+import Data.SBV
+import Data.SBV.TP
+
+#ifdef DOCTEST
+-- $setup
+-- >>> import Data.SBV
+-- >>> import Data.SBV.TP
+-- >>> :set -XOverloadedLists
+#endif
+
+-- * Problem specification
+
+-- | The maximum segment sum problem: Find the maximum sum of any contiguous
+-- subarray. We include the empty subarray (with sum 0) as a valid segment.
+-- This is the obvious definition: Empty list maps to 0. Otherwise, we take the
+-- value of the segment starting at the current position, and take the maximum
+-- of that value with the recursive result of the tail. This is obviously
+-- correct, but has the runtime of O(n^2).
+--
+-- We have:
+--
+-- >>> mss [1, -2, 3, 4, -1, 2]  -- the segment: [3, 4, -1, 2]
+-- 8 :: SInteger
+-- >>> mss [-2, -3, -1]          -- empty segment
+-- 0 :: SInteger
+-- >>> mss [1, 2, 3]             -- the whole list
+-- 6 :: SInteger
+mss :: SList Integer -> SInteger
+mss = smtFunction "mss"
+    $ \xs -> [sCase| xs of
+                 []    -> 0
+                 _ : t -> mssBegin xs `smax` mss t
+             |]
+
+-- | Maximum sum of segments starting at the beginning of the given list.
+-- This is 0 if the empty segment is best, or positive if a non-empty prefix exists.
+--
+-- We have:
+--
+-- >>> mssBegin [1, -2, 3, 4, -1, 2]  -- the segment: [1, -2, 3, 4, -1, 2]
+-- 7 :: SInteger
+-- >>> mssBegin [-2, -3, -1]          -- empty segment
+-- 0 :: SInteger
+-- >>> mssBegin [1, 2, 3]             -- the whole list
+-- 6 :: SInteger
+mssBegin :: SList Integer -> SInteger
+mssBegin = smtFunction "mssBegin"
+         $ \xs -> [sCase| xs of
+                      []    -> 0
+                      h : t -> 0 `smax` (h `smax` (h + mssBegin t))
+                  |]
+
+-- * Kadane's algorithm implementation
+
+-- | Kadane algorithm: We call the helper with the values of maximum value ending
+-- at the beginning and the list, and recurse.
+--
+-- >>> kadane [1, -2, 3, 4, -1, 2]  -- the segment: [3, 4, -1, 2]
+-- 8 :: SInteger
+-- >>> kadane [-2, -3, -1]          -- empty segment
+-- 0 :: SInteger
+-- >>> kadane [1, 2, 3]             -- the whole list
+-- 6 :: SInteger
+kadane :: SList Integer -> SInteger
+kadane xs = kadaneHelper xs 0 0
+
+-- | Helper for Kadane's algorithm. Along with the list, we keep track of the maximum-value
+-- ending at the beginning of the list argument, and the maximum value sofar.
+kadaneHelper :: SList Integer -> SInteger -> SInteger -> SInteger
+kadaneHelper = smtFunction "kadaneHelper"
+             $ \xs maxEndingHere maxSoFar ->
+                  [sCase| xs of
+                      []    -> maxSoFar
+                      h : t -> let newMaxEndingHere = 0 `smax` (h + maxEndingHere)
+                                   newMaxSofar      = maxSoFar `smax` newMaxEndingHere
+                               in kadaneHelper t newMaxEndingHere newMaxSofar
+                  |]
+
+-- * Correctness proof
+
+-- | The key insight is that we need a generalized invariant that characterizes
+-- @kadaneHelper@ for arbitrary accumulator values, not just the initial @(0, 0)@.
+--
+-- The invariant states: for @kadaneHelper xs meh msf@ where:
+--
+--   * @meh@ (max-ending-here) is the maximum sum of a segment ending at the boundary
+--   * @msf@ (max-so-far) is the best segment sum seen in the already-processed prefix
+--   * Preconditions: @meh >= 0@ and @msf >= meh@
+--
+-- @
+--   kadaneHelper xs meh msf == msf `smax` mss xs `smax` (meh + mssBegin xs)
+-- @
+--
+-- This captures that the result is the maximum of:
+--
+--   * @msf@ - the best segment entirely in the already-processed prefix
+--   * @mss xs@ - the best segment entirely in the remaining suffix
+--   * @meh + mssBegin xs@ - the best segment crossing the boundary
+--
+-- >>> runTPWith cvc5 correctness
+-- Inductive lemma: kadaneHelperInvariant
+--   Step: Base                              Q.E.D.
+--   Step: 1                                 Q.E.D.
+--   Step: 2                                 Q.E.D.
+--   Result:                                 Q.E.D.
+-- Lemma: correctness
+--   Step: 1                                 Q.E.D.
+--   Step: 2                                 Q.E.D.
+--   Step: 3                                 Q.E.D.
+--   Step: 4                                 Q.E.D.
+--   Result:                                 Q.E.D.
+-- Functions proven terminating: kadaneHelper, mss, mssBegin
+-- [Proven] correctness :: Ɐxs ∷ [Integer] → Bool
+correctness :: TP (Proof (Forall "xs" [Integer] -> SBool))
+correctness = do
+
+  -- First, prove the generalized invariant. This is the heart of the proof: it relates kadaneHelper with arbitrary
+  -- accumulators to the specification functions mss and mssBegin.
+  invariant <- induct "kadaneHelperInvariant"
+      (\(Forall xs) (Forall meh) (Forall msf) ->
+         (meh .>= 0 .&& msf .>= meh) .=> kadaneHelper xs meh msf .== (msf `smax` mss xs `smax` (meh + mssBegin xs))) $
+      \ih (a, as) meh msf ->
+         [meh .>= 0, msf .>= meh] |- let newMeh = 0 `smax` (a + meh)
+                                         newMsf = msf `smax` newMeh
+                                     in kadaneHelper (a .: as) meh msf
+                                     =: kadaneHelper as newMeh newMsf
+                                     ?? ih `at` (Inst @"meh" newMeh, Inst @"msf" newMsf)
+                                     =: newMsf `smax` mss as `smax` (newMeh + mssBegin as)
+                                     =: qed
+
+  -- Now the main theorem follows easily: kadane xs = kadaneHelper xs 0 0
+  -- and with meh=0, msf=0, the invariant gives us:
+  --   kadaneHelper xs 0 0 = 0 `smax` mss xs `smax` (0 + mssBegin xs)
+  --                       = mss xs `smax` mssBegin xs
+  --                       = mss xs  (since mss xs >= mssBegin xs by definition)
+  calc "correctness"
+       (\(Forall xs) -> mss xs .== kadane xs) $
+       \xs -> [] |- kadane xs
+                 =: kadaneHelper xs 0 0
+                 ?? invariant `at` (Inst @"xs" xs, Inst @"meh" (0 :: SInteger), Inst @"msf" (0 :: SInteger))
+                 =: 0 `smax` mss xs `smax` (0 + mssBegin xs)
+                 =: mss xs `smax` mssBegin xs
+                 -- mss xs >= mssBegin xs by definition (mss considers all segments)
+                 =: mss xs
+                 =: qed
diff --git a/Documentation/SBV/Examples/TP/Kleene.hs b/Documentation/SBV/Examples/TP/Kleene.hs
--- a/Documentation/SBV/Examples/TP/Kleene.hs
+++ b/Documentation/SBV/Examples/TP/Kleene.hs
@@ -11,14 +11,11 @@
 -- Based on <http://www.philipzucker.com/bryzzowski_kat/>
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DataKinds            #-}
-{-# LANGUAGE DeriveAnyClass       #-}
-{-# LANGUAGE DeriveDataTypeable   #-}
-{-# LANGUAGE FlexibleInstances    #-}
-{-# LANGUAGE ScopedTypeVariables  #-}
-{-# LANGUAGE StandaloneDeriving   #-}
-{-# LANGUAGE TemplateHaskell      #-}
-{-# LANGUAGE TypeAbstractions     #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE FlexibleInstances   #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE TypeAbstractions    #-}
 
 {-# OPTIONS_GHC -Wall -Werror -Wno-unused-matches #-}
 
@@ -31,7 +28,7 @@
 
 -- | An uninterpreted sort, corresponding to the type of Kleene algebra strings.
 data Kleene
-mkUninterpretedSort ''Kleene
+mkSymbolic [''Kleene]
 
 -- | Star operator over kleene algebras. We're leaving this uninterpreted.
 star :: SKleene -> SKleene
@@ -72,20 +69,20 @@
 -- Axiom: ldistrib
 -- Axiom: unfold
 -- Axiom: least_fix
--- Lemma: par_lzero                        Q.E.D.
--- Lemma: par_monotone                     Q.E.D.
--- Lemma: seq_monotone                     Q.E.D.
+-- Lemma: par_lzero                     Q.E.D.
+-- Lemma: par_monotone                  Q.E.D.
+-- Lemma: seq_monotone                  Q.E.D.
 -- Lemma: star_star_1
---   Step: 1 (unfold)                      Q.E.D.
---   Step: 2 (factor out x * star x)       Q.E.D.
---   Step: 3 (par_idem)                    Q.E.D.
---   Step: 4 (unfold)                      Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: subset_eq                        Q.E.D.
--- Lemma: star_star_2_2                    Q.E.D.
--- Lemma: star_star_2_3                    Q.E.D.
--- Lemma: star_star_2_1                    Q.E.D.
--- Lemma: star_star_2                      Q.E.D.
+--   Step: 1 (unfold)                   Q.E.D.
+--   Step: 2 (factor out x * star x)    Q.E.D.
+--   Step: 3 (par_idem)                 Q.E.D.
+--   Step: 4 (unfold)                   Q.E.D.
+--   Result:                            Q.E.D.
+-- Lemma: subset_eq                     Q.E.D.
+-- Lemma: star_star_2_2                 Q.E.D.
+-- Lemma: star_star_2_3                 Q.E.D.
+-- Lemma: star_star_2_1                 Q.E.D.
+-- Lemma: star_star_2                   Q.E.D.
 kleeneProofs :: IO ()
 kleeneProofs = runTP $ do
 
diff --git a/Documentation/SBV/Examples/TP/Lists.hs b/Documentation/SBV/Examples/TP/Lists.hs
new file mode 100644
--- /dev/null
+++ b/Documentation/SBV/Examples/TP/Lists.hs
@@ -0,0 +1,2096 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Documentation.SBV.Examples.TP.Lists
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- A variety of TP proofs on list processing functions. Note that
+-- these proofs only hold for finite lists. SMT-solvers do not model infinite
+-- lists, and hence all claims are for finite (but arbitrary-length) lists.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE CPP                 #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE OverloadedLists     #-}
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Documentation.SBV.Examples.TP.Lists (
+     -- * Append
+     appendNull, consApp, appendAssoc, initsLength, tailsLength, tailsAppend
+
+     -- * Reverse
+   , revLen, revApp, revCons, revSnoc, revRev, enumLen, revNM
+
+     -- * Length
+   , lengthTail, lenAppend, lenAppend2
+
+     -- * Replicate
+   , replicateLength
+
+     -- * All and any
+   , allAny
+
+     -- * Map
+   , mapEquiv, mapAppend, mapReverse, mapCompose, mapConcat
+
+     -- * Foldr and foldl
+   , foldrMapFusion, foldrFusion, foldrOverAppend, foldlOverAppend, foldrFoldlDuality, foldrFoldlDualityGeneralized, foldrFoldl
+   , bookKeeping
+
+     -- * Filter
+   , filterAppend, filterConcat, takeDropWhile
+
+     -- * Stutter removal
+   , destutter, destutterIdempotent
+
+     -- * Difference
+   , appendDiff, diffAppend, diffDiff
+
+     -- * Partition
+   , partition1, partition2
+
+    -- * Take and drop
+   , take_take, drop_drop, take_drop, take_cons, take_map, drop_cons, drop_map, length_take, length_drop, take_all, drop_all
+   , take_append, drop_append
+
+   -- * Zip
+   , map_fst_zip
+   , map_snd_zip
+   , map_fst_zip_take
+   , map_snd_zip_take
+
+   -- * Counting elements
+   , count, countOneStep, countAppend, takeDropCount, countNonNeg, countElem, elemCount
+
+   -- * Disjointness
+   , disjoint, disjointDiff
+
+   -- * Interleaving
+   , interleave, uninterleave, interleaveLen, interleaveRoundTrip
+ ) where
+
+import Prelude (Integer, Bool, Eq, ($), Num(..), id, (.), flip)
+
+import Data.Proxy (Proxy(..))
+
+import Data.SBV
+import Data.SBV.List
+import Data.SBV.Tuple
+import Data.SBV.TP
+
+#ifdef DOCTEST
+-- $setup
+-- >>> :set -XScopedTypeVariables
+-- >>> :set -XTypeApplications
+-- >>> import Data.SBV
+-- >>> import Data.SBV.TP
+-- >>> import Control.Exception
+#endif
+
+-- | @xs ++ [] == xs@
+--
+-- >>> runTP $ appendNull @Integer
+-- Lemma: appendNull    Q.E.D.
+-- [Proven] appendNull :: Ɐxs ∷ [Integer] → Bool
+appendNull :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> SBool))
+appendNull = lemma "appendNull"
+                   (\(Forall xs) -> xs ++ [] .== xs)
+                   []
+
+-- | @(x : xs) ++ ys == x : (xs ++ ys)@
+--
+-- >>> runTP $ consApp @Integer
+-- Lemma: consApp      Q.E.D.
+-- [Proven] consApp :: Ɐx ∷ Integer → Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool
+consApp :: forall a. SymVal a => TP (Proof (Forall "x" a -> Forall "xs" [a] -> Forall "ys" [a] -> SBool))
+consApp = lemma "consApp"
+                (\(Forall x) (Forall xs) (Forall ys) -> (x .: xs) ++ ys .== x .: (xs ++ ys))
+                []
+
+-- | @(xs ++ ys) ++ zs == xs ++ (ys ++ zs)@
+--
+-- >>> runTP $ appendAssoc @Integer
+-- Lemma: appendAssoc    Q.E.D.
+-- [Proven] appendAssoc :: Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Ɐzs ∷ [Integer] → Bool
+--
+-- Surprisingly, z3 can prove this without any induction. (Since SBV's append translates directly to
+-- the concatenation of sequences in SMTLib, it must trigger an internal heuristic in z3
+-- that proves it right out-of-the-box!)
+appendAssoc :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> Forall "ys" [a] -> Forall "zs" [a] -> SBool))
+appendAssoc =
+   lemma "appendAssoc"
+         (\(Forall xs) (Forall ys) (Forall zs) -> xs ++ (ys ++ zs) .== (xs ++ ys) ++ zs)
+         []
+
+-- | @length (inits xs) == 1 + length xs@
+--
+-- >>> runTP $ initsLength @Integer
+-- Lemma: initLength                        Q.E.D.
+-- Inductive lemma (strong): initsLength
+--   Step: Measure is non-negative          Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1                            Q.E.D.
+--     Step: 1.2.1                          Q.E.D.
+--     Step: 1.2.2                          Q.E.D.
+--     Step: 1.2.3                          Q.E.D.
+--     Step: 1.2.4                          Q.E.D.
+--     Step: 1.Completeness                 Q.E.D.
+--   Result:                                Q.E.D.
+-- Functions proven terminating: sbv.inits
+-- [Proven] initsLength :: Ɐxs ∷ [Integer] → Bool
+initsLength :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> SBool))
+initsLength = do
+
+   initLength <- lemma "initLength"
+                       (\(Forall @"xs" (xs :: SList a)) -> sNot (null xs) .=> length (init xs) .== length xs - 1)
+                       []
+
+   sInduct "initsLength"
+           (\(Forall xs) -> length (inits xs) .== 1 + length xs)
+           (length @a, []) $
+           \ih xs -> [] |- length (inits xs) .== 1 + length xs
+                        =: [pCase| xs of
+                              []            -> trivial
+                              whole@(_ : _) ->
+                                   length (inits whole) .== 1 + length whole
+                                =: length (inits (init whole) ++ [whole]) .== 1 + length whole
+                                =: 1 + length (inits (init whole)) .== 1 + length whole
+                                ?? ih         `at` Inst @"xs" (init whole)
+                                ?? initLength `at` Inst @"xs" whole
+                                =: sTrue
+                                =: qed
+                           |]
+
+-- | @length (tails xs) == 1 + length xs@
+--
+-- >>> runTP $ tailsLength @Integer
+-- Inductive lemma: tailsLength
+--   Step: Base                    Q.E.D.
+--   Step: 1                       Q.E.D.
+--   Step: 2                       Q.E.D.
+--   Step: 3                       Q.E.D.
+--   Step: 4                       Q.E.D.
+--   Result:                       Q.E.D.
+-- Functions proven terminating: sbv.tails
+-- [Proven] tailsLength :: Ɐxs ∷ [Integer] → Bool
+tailsLength :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> SBool))
+tailsLength =
+   induct "tailsLength"
+          (\(Forall xs) -> length (tails xs) .== 1 + length xs) $
+          \ih (x, xs) -> [] |- length (tails (x .: xs))
+                            =: length (tails xs ++ [x .: xs])
+                            =: length (tails xs) + 1
+                            ?? ih
+                            =: 1 + length xs + 1
+                            =: 1 + length (x .: xs)
+                            =: qed
+
+-- | @tails (xs ++ ys) == map (++ ys) (tails xs) ++ tail (tails ys)@
+--
+-- This property comes from Richard Bird's "Pearls of functional Algorithm Design" book, chapter 2.
+-- Note that it is not exactly as stated there, as the definition of @tails@ Bird uses is different
+-- than the standard Haskell function @tails@: Bird's version does not return the empty list as the
+-- tail. So, we slightly modify it to fit the standard definition. (NB. z3 is finicky on this
+-- problem, while cvc5 works much better.)
+--
+-- >>> runTPWith cvc5 $ tailsAppend @Integer
+-- Inductive lemma: base case
+--   Step: Base                    Q.E.D.
+--   Step: 1                       Q.E.D.
+--   Step: 2                       Q.E.D.
+--   Step: 3                       Q.E.D.
+--   Result:                       Q.E.D.
+-- Lemma: helper
+--   Step: 1                       Q.E.D.
+--   Step: 2                       Q.E.D.
+--   Result:                       Q.E.D.
+-- Inductive lemma: tailsAppend
+--   Step: Base                    Q.E.D.
+--   Step: 1                       Q.E.D.
+--   Step: 2                       Q.E.D.
+--   Step: 3                       Q.E.D.
+--   Step: 4                       Q.E.D.
+--   Result:                       Q.E.D.
+-- Functions proven terminating: sbv.closureMap, sbv.tails
+-- [Proven] tailsAppend :: Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool
+tailsAppend :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> Forall "ys" [a] -> SBool))
+tailsAppend = do
+
+   let -- Ideally, we would like to define appendEach like this:
+       --
+       --       appendEach xs ys = map (++ ys) xs
+       --
+       -- But capture of ys is not allowed when we use the higher-order
+       -- function map in SBV. So, we create a closure instead.
+       appendEach :: SList a -> SList [a] -> SList [a]
+       appendEach ys = map $ Closure { closureEnv = ys
+                                     , closureFun = \env xs -> xs ++ env
+                                     }
+
+   -- Even proving the base case of induction is hard due to recursive definition. So we first prove the base case by induction.
+   bc <- induct "base case"
+                (\(Forall @"ys" (ys :: SList a)) -> tails ys .== [ys] ++ tail (tails ys)) $
+                \ih (y, ys) -> [] |- tails (y .: ys)
+                                  =: [y .: ys] ++ tails ys
+                                  ?? ih
+                                  =: [y .: ys] ++ [ys] ++ tail (tails ys)
+                                  =: [y .: ys] ++ tail (tails (y .: ys))
+                                  =: qed
+
+   -- Also need a helper to relate how appendEach and tails work together
+   helper <- calc "helper"
+                   (\(Forall @"xs" xs) (Forall @"ys" ys) (Forall @"x" x) ->
+                        appendEach ys (tails (x .: xs)) .== [(x .: xs) ++ ys] ++ appendEach ys (tails xs)) $
+                   \xs ys x -> [] |- appendEach ys (tails (x .: xs))
+                                  =: appendEach ys ([x .: xs] ++ tails xs)
+                                  =: [(x .: xs) ++ ys] ++ appendEach ys (tails xs)
+                                  =: qed
+
+   induct "tailsAppend"
+          (\(Forall xs) (Forall ys) -> tails (xs ++ ys) .== appendEach ys (tails xs) ++ tail (tails ys)) $
+          \ih (x, xs) ys -> [assumptionFromProof bc]
+                         |- tails ((x .: xs) ++ ys)
+                         =: tails (x .: (xs ++ ys))
+                         =: [x .: (xs ++ ys)] ++ tails (xs ++ ys)
+                         ?? ih
+                         =: [(x .: xs) ++ ys] ++ appendEach ys (tails xs) ++ tail (tails ys)
+                         ?? helper
+                         =: appendEach ys (tails (x .: xs)) ++ tail (tails ys)
+                         =: qed
+
+-- | @length xs == length (reverse xs)@
+--
+-- >>> runTP $ revLen @Integer
+-- Inductive lemma: revLen
+--   Step: Base               Q.E.D.
+--   Step: 1                  Q.E.D.
+--   Step: 2                  Q.E.D.
+--   Step: 3                  Q.E.D.
+--   Step: 4                  Q.E.D.
+--   Result:                  Q.E.D.
+-- Functions proven terminating: sbv.reverse
+-- [Proven] revLen :: Ɐxs ∷ [Integer] → Bool
+revLen :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> SBool))
+revLen = induct "revLen"
+                (\(Forall xs) -> length (reverse xs) .== length xs) $
+                \ih (x, xs) -> [] |- length (reverse (x .: xs))
+                                  =: length (reverse xs ++ [x])
+                                  =: length (reverse xs) + length [x]
+                                  ?? ih
+                                  =: length xs + 1
+                                  =: length (x .: xs)
+                                  =: qed
+
+-- | @reverse (xs ++ ys) .== reverse ys ++ reverse xs@
+--
+-- >>> runTP $ revApp @Integer
+-- Inductive lemma: revApp
+--   Step: Base               Q.E.D.
+--   Step: 1                  Q.E.D.
+--   Step: 2                  Q.E.D.
+--   Step: 3                  Q.E.D.
+--   Step: 4                  Q.E.D.
+--   Step: 5                  Q.E.D.
+--   Result:                  Q.E.D.
+-- Functions proven terminating: sbv.reverse
+-- [Proven] revApp :: Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool
+revApp :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> Forall "ys" [a] -> SBool))
+revApp = induct "revApp"
+                 (\(Forall xs) (Forall ys) -> reverse (xs ++ ys) .== reverse ys ++ reverse xs) $
+                 \ih (x, xs) ys -> [] |- reverse ((x .: xs) ++ ys)
+                                      =: reverse (x .: (xs ++ ys))
+                                      =: reverse (xs ++ ys) ++ [x]
+                                      ?? ih
+                                      =: (reverse ys ++ reverse xs) ++ [x]
+                                      =: reverse ys ++ (reverse xs ++ [x])
+                                      =: reverse ys ++ reverse (x .: xs)
+                                      =: qed
+
+-- | @reverse (x:xs) == reverse xs ++ [x]@
+--
+-- >>> runTP $ revCons @Integer
+-- Lemma: revCons      Q.E.D.
+-- Functions proven terminating: sbv.reverse
+-- [Proven] revCons :: Ɐx ∷ Integer → Ɐxs ∷ [Integer] → Bool
+revCons :: forall a. SymVal a => TP (Proof (Forall "x" a -> Forall "xs" [a] -> SBool))
+revCons = lemma "revCons"
+                (\(Forall x) (Forall xs) -> reverse (x .: xs) .== reverse xs ++ [x])
+                []
+
+-- | @reverse (xs ++ [x]) == x : reverse xs@
+--
+-- >>> runTP $ revSnoc @Integer
+-- Inductive lemma: revApp
+--   Step: Base               Q.E.D.
+--   Step: 1                  Q.E.D.
+--   Step: 2                  Q.E.D.
+--   Step: 3                  Q.E.D.
+--   Step: 4                  Q.E.D.
+--   Step: 5                  Q.E.D.
+--   Result:                  Q.E.D.
+-- Lemma: revSnoc             Q.E.D.
+-- Functions proven terminating: sbv.reverse
+-- [Proven] revSnoc :: Ɐx ∷ Integer → Ɐxs ∷ [Integer] → Bool
+revSnoc :: forall a. SymVal a => TP (Proof (Forall "x" a -> Forall "xs" [a] -> SBool))
+revSnoc = do
+   ra <- revApp @a
+
+   lemma "revSnoc"
+         (\(Forall x) (Forall xs) -> reverse (xs ++ [x]) .== x .: reverse xs)
+         [proofOf ra]
+
+-- | @reverse (reverse xs) == xs@
+--
+-- >>> runTP $ revRev @Integer
+-- Inductive lemma: revApp
+--   Step: Base               Q.E.D.
+--   Step: 1                  Q.E.D.
+--   Step: 2                  Q.E.D.
+--   Step: 3                  Q.E.D.
+--   Step: 4                  Q.E.D.
+--   Step: 5                  Q.E.D.
+--   Result:                  Q.E.D.
+-- Inductive lemma: revRev
+--   Step: Base               Q.E.D.
+--   Step: 1                  Q.E.D.
+--   Step: 2                  Q.E.D.
+--   Step: 3                  Q.E.D.
+--   Step: 4                  Q.E.D.
+--   Result:                  Q.E.D.
+-- Functions proven terminating: sbv.reverse
+-- [Proven] revRev :: Ɐxs ∷ [Integer] → Bool
+revRev :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> SBool))
+revRev = do
+
+   ra <- revApp @a
+
+   induct "revRev"
+          (\(Forall xs) -> reverse (reverse xs) .== xs) $
+          \ih (x, xs) -> [] |- reverse (reverse (x .: xs))
+                            =: reverse (reverse xs ++ [x])
+                            ?? ra
+                            =: reverse [x] ++ reverse (reverse xs)
+                            ?? ih
+                            =: [x] ++ xs
+                            =: x .: xs
+                            =: qed
+
+-- | \(\mathit{length } [n \dots m] = \max(0,\; m - n + 1)\)
+--
+-- The proof uses the metric @|m-n|@.
+--
+-- >>> runTP enumLen
+-- Inductive lemma (strong): enumLen
+--   Step: Measure is non-negative      Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1                        Q.E.D.
+--     Step: 1.2.1                      Q.E.D.
+--     Step: 1.2.2                      Q.E.D.
+--     Step: 1.2.3                      Q.E.D.
+--     Step: 1.2.4                      Q.E.D.
+--     Step: 1.Completeness             Q.E.D.
+--   Result:                            Q.E.D.
+-- Functions proven terminating: EnumSymbolic.Integer.enumFromThenTo.up
+-- [Proven] enumLen :: Ɐn ∷ Integer → Ɐm ∷ Integer → Bool
+enumLen :: TP (Proof (Forall "n" Integer -> Forall "m" Integer -> SBool))
+enumLen =
+  sInduct "enumLen"
+          (\(Forall n) (Forall m) -> length [sEnum|n .. m|] .== 0 `smax` (m - n + 1))
+          (\n m -> abs (m - n), []) $
+          \ih n m -> [] |- length [sEnum|n+1 .. m|]
+                        =: cases [ n+1 .>  m ==> trivial
+                                 , n+1 .<= m ==> length (n+1 .: [sEnum|n+2 .. m|])
+                                              =: 1 + length [sEnum|n+2 .. m|]
+                                              ?? ih
+                                              =: 1 + (0 `smax` (m - (n+2) + 1))
+                                              =: 0 `smax` (m - (n+1) + 1)
+                                              =: qed
+                                 ]
+
+-- | @reverse [n .. m] == [m, m-1 .. n]@
+--
+-- The proof uses the metric @|m-n|@.
+--
+-- >>> runTP revNM
+-- Inductive lemma (strong): helper
+--   Step: Measure is non-negative     Q.E.D.
+--   Step: 1                           Q.E.D.
+--   Step: 2                           Q.E.D.
+--   Step: 3                           Q.E.D.
+--   Result:                           Q.E.D.
+-- Inductive lemma (strong): revNM
+--   Step: Measure is non-negative     Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1                       Q.E.D.
+--     Step: 1.2.1                     Q.E.D.
+--     Step: 1.2.2                     Q.E.D.
+--     Step: 1.2.3                     Q.E.D.
+--     Step: 1.2.4                     Q.E.D.
+--     Step: 1.Completeness            Q.E.D.
+--   Result:                           Q.E.D.
+-- Functions proven terminating:
+--   EnumSymbolic.Integer.enumFromThenTo.down, EnumSymbolic.Integer.enumFromThenTo.up, sbv.reverse
+-- [Proven] revNM :: Ɐn ∷ Integer → Ɐm ∷ Integer → Bool
+revNM :: TP (Proof (Forall "n" Integer -> Forall "m" Integer -> SBool))
+revNM = do
+
+  helper <- sInduct "helper"
+                    (\(Forall @"m" (m :: SInteger)) (Forall @"n" n) ->
+                          n .< m .=> [sEnum|m, m-1 .. n+1|] ++ [n] .== [sEnum|m, m-1 .. n|])
+                    (\m n -> abs (m - n), []) $
+                    \ih m n -> [n .< m] |- [sEnum|m, m-1 .. n+1|] ++ [n]
+                                        =: m .: [sEnum|m-1, m-2 .. n+1|] ++ [n]
+                                        ?? ih
+                                        =: m .: [sEnum|m-1, m-2 .. n|]
+                                        =: [sEnum|m, m-1 .. n|]
+                                        =: qed
+
+  sInduct "revNM"
+          (\(Forall n) (Forall m) -> reverse [sEnum|n .. m|] .== [sEnum|m, m-1 .. n|])
+          (\n m -> abs (m - n), []) $
+          \ih n m -> [] |- reverse [sEnum|n .. m|]
+                        =: cases [ n .>  m ==> trivial
+                                 , n .<= m ==> reverse (n .: [sEnum|(n+1) .. m|])
+                                            =: reverse [sEnum|(n+1) .. m|] ++ [n]
+                                            ?? ih
+                                            =: [sEnum|m, m-1 .. n+1|] ++ [n]
+                                            ?? helper
+                                            =: [sEnum|m, m-1 .. n|]
+                                            =: qed
+                                 ]
+
+-- | @length (x : xs) == 1 + length xs@
+--
+-- >>> runTP $ lengthTail @Integer
+-- Lemma: lengthTail    Q.E.D.
+-- [Proven] lengthTail :: Ɐx ∷ Integer → Ɐxs ∷ [Integer] → Bool
+lengthTail :: forall a. SymVal a => TP (Proof (Forall "x" a -> Forall "xs" [a] -> SBool))
+lengthTail = lemma "lengthTail"
+                   (\(Forall x) (Forall xs) -> length (x .: xs) .== 1 + length xs)
+                   []
+
+-- | @length (xs ++ ys) == length xs + length ys@
+--
+-- >>> runTP $ lenAppend @Integer
+-- Lemma: lenAppend    Q.E.D.
+-- [Proven] lenAppend :: Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool
+lenAppend :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> Forall "ys" [a] -> SBool))
+lenAppend = lemma "lenAppend"
+                  (\(Forall xs) (Forall ys) -> length (xs ++ ys) .== length xs + length ys)
+                  []
+
+-- | @length xs == length ys -> length (xs ++ ys) == 2 * length xs@
+--
+-- >>> runTP $ lenAppend2 @Integer
+-- Lemma: lenAppend2    Q.E.D.
+-- [Proven] lenAppend2 :: Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool
+lenAppend2 :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> Forall "ys" [a] -> SBool))
+lenAppend2 = lemma "lenAppend2"
+                   (\(Forall xs) (Forall ys) -> length xs .== length ys .=> length (xs ++ ys) .== 2 * length xs)
+                   []
+
+-- | @length (replicate k x) == max (0, k)@
+--
+-- >>> runTP $ replicateLength @Integer
+-- Inductive lemma: replicateLength
+--   Step: Base                        Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1                       Q.E.D.
+--     Step: 1.2.1                     Q.E.D.
+--     Step: 1.2.2                     Q.E.D.
+--     Step: 1.2.3                     Q.E.D.
+--     Step: 1.2.4                     Q.E.D.
+--     Step: 1.Completeness            Q.E.D.
+--   Result:                           Q.E.D.
+-- Functions proven terminating: sbv.replicate
+-- [Proven] replicateLength :: Ɐk ∷ Integer → Ɐx ∷ Integer → Bool
+replicateLength :: forall a. SymVal a => TP (Proof (Forall "k" Integer -> Forall "x" a -> SBool))
+replicateLength = induct "replicateLength"
+                         (\(Forall k) (Forall x) -> length (replicate k x) .== 0 `smax` k) $
+                         \ih k x -> [] |- length (replicate (k+1) x)
+                                       =: cases [ k .< 0  ==> trivial
+                                                , k .>= 0 ==> length (x .: replicate k x)
+                                                           =: 1 + length (replicate k x)
+                                                           ?? ih
+                                                           =: 1 + 0 `smax` k
+                                                           =: 0 `smax` (k+1)
+                                                           =: qed
+                                                ]
+
+-- | @not (all id xs) == any not xs@
+--
+-- A list of booleans is not all true, if any of them is false.
+--
+-- >>> runTP allAny
+-- Inductive lemma: allAny
+--   Step: Base               Q.E.D.
+--   Step: 1                  Q.E.D.
+--   Step: 2                  Q.E.D.
+--   Step: 3                  Q.E.D.
+--   Step: 4                  Q.E.D.
+--   Result:                  Q.E.D.
+-- Functions proven terminating: sbv.foldr
+-- [Proven] allAny :: Ɐxs ∷ [Bool] → Bool
+allAny :: TP (Proof (Forall "xs" [Bool] -> SBool))
+allAny = induct "allAny"
+                (\(Forall xs) -> sNot (all id xs) .== any sNot xs) $
+                \ih (x, xs) -> [] |- sNot (all id (x .: xs))
+                                  =: sNot (x .&& all id xs)
+                                  =: (sNot x .|| sNot (all id xs))
+                                  ?? ih
+                                  =: sNot x .|| any sNot xs
+                                  =: any sNot (x .: xs)
+                                  =: qed
+
+-- | @f == g ==> map f xs == map g xs@
+--
+-- >>> runTP $ mapEquiv @Integer @Integer (uninterpret "f") (uninterpret "g")
+-- Inductive lemma: mapEquiv
+--   Step: Base                 Q.E.D.
+--   Step: 1                    Q.E.D.
+--   Step: 2                    Q.E.D.
+--   Step: 3                    Q.E.D.
+--   Step: 4                    Q.E.D.
+--   Result:                    Q.E.D.
+-- Functions proven terminating: sbv.map
+-- [Proven] mapEquiv :: Ɐxs ∷ [Integer] → Bool
+mapEquiv :: forall a b. (SymVal a, SymVal b) => (SBV a -> SBV b) -> (SBV a -> SBV b) -> TP (Proof (Forall "xs" [a] -> SBool))
+mapEquiv f g = do
+   let f'eq'g :: SBool
+       f'eq'g = quantifiedBool $ \(Forall x) -> f x .== g x
+
+   induct "mapEquiv"
+          (\(Forall xs) -> f'eq'g .=> map f xs .== map g xs) $
+          \ih (x, xs) -> [f'eq'g] |- map f (x .: xs) .== map g (x .: xs)
+                                  =: f x .: map f xs .== g x .: map g xs
+                                  =: f x .: map f xs .== f x .: map g xs
+                                  ?? ih
+                                  =: f x .: map f xs .== f x .: map f xs
+                                  =: map f (x .: xs) .== map f (x .: xs)
+                                  =: qed
+
+-- | @map f (xs ++ ys) == map f xs ++ map f ys@
+--
+-- >>> runTP $ mapAppend @Integer @Integer (uninterpret "f")
+-- Inductive lemma: mapAppend
+--   Step: Base                  Q.E.D.
+--   Step: 1                     Q.E.D.
+--   Step: 2                     Q.E.D.
+--   Step: 3                     Q.E.D.
+--   Step: 4                     Q.E.D.
+--   Step: 5                     Q.E.D.
+--   Result:                     Q.E.D.
+-- Functions proven terminating: sbv.map
+-- [Proven] mapAppend :: Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool
+mapAppend :: forall a b. (SymVal a, SymVal b) => (SBV a -> SBV b) -> TP (Proof (Forall "xs" [a] -> Forall "ys" [a] -> SBool))
+mapAppend f =
+   induct "mapAppend"
+          (\(Forall xs) (Forall ys) -> map f (xs ++ ys) .== map f xs ++ map f ys) $
+          \ih (x, xs) ys -> [] |- map f ((x .: xs) ++ ys)
+                               =: map f (x .: (xs ++ ys))
+                             =: f x .: map f (xs ++ ys)
+                             ?? ih
+                             =: f x .: (map f xs  ++ map f ys)
+                             =: (f x .: map f xs) ++ map f ys
+                             =: map f (x .: xs) ++ map f ys
+                             =: qed
+
+-- | @map f . reverse == reverse . map f@
+--
+-- >>> runTP $ mapReverse @Integer @String (uninterpret "f")
+-- Inductive lemma: mapAppend
+--   Step: Base                   Q.E.D.
+--   Step: 1                      Q.E.D.
+--   Step: 2                      Q.E.D.
+--   Step: 3                      Q.E.D.
+--   Step: 4                      Q.E.D.
+--   Step: 5                      Q.E.D.
+--   Result:                      Q.E.D.
+-- Inductive lemma: mapReverse
+--   Step: Base                   Q.E.D.
+--   Step: 1                      Q.E.D.
+--   Step: 2                      Q.E.D.
+--   Step: 3                      Q.E.D.
+--   Step: 4                      Q.E.D.
+--   Step: 5                      Q.E.D.
+--   Step: 6                      Q.E.D.
+--   Result:                      Q.E.D.
+-- Functions proven terminating: sbv.map, sbv.reverse
+-- [Proven] mapReverse :: Ɐxs ∷ [Integer] → Bool
+mapReverse :: forall a b. (SymVal a, SymVal b) => (SBV a -> SBV b) -> TP (Proof (Forall "xs" [a] -> SBool))
+mapReverse f = do
+     mApp <- mapAppend f
+
+     induct "mapReverse"
+            (\(Forall xs) -> reverse (map f xs) .== map f (reverse xs)) $
+            \ih (x, xs) -> [] |- reverse (map f (x .: xs))
+                              =: reverse (f x .: map f xs)
+                              =: reverse (map f xs) ++ [f x]
+                              ?? ih
+                              =: map f (reverse xs) ++ [f x]
+                              =: map f (reverse xs) ++ map f [x]
+                              ?? mApp
+                              =: map f (reverse xs ++ [x])
+                              =: map f (reverse (x .: xs))
+                              =: qed
+
+-- | @map f . map g == map (f . g)@
+--
+-- >>> runTP $ mapCompose @Integer @Bool @String (uninterpret "f") (uninterpret "g")
+-- Inductive lemma: mapCompose
+--   Step: Base                   Q.E.D.
+--   Step: 1                      Q.E.D.
+--   Step: 2                      Q.E.D.
+--   Step: 3                      Q.E.D.
+--   Step: 4                      Q.E.D.
+--   Step: 5                      Q.E.D.
+--   Result:                      Q.E.D.
+-- Functions proven terminating: sbv.map
+-- [Proven] mapCompose :: Ɐxs ∷ [Integer] → Bool
+mapCompose :: forall a b c. (SymVal a, SymVal b, SymVal c) => (SBV a -> SBV b) -> (SBV b -> SBV c) -> TP (Proof (Forall "xs" [a] -> SBool))
+mapCompose f g =
+  induct "mapCompose"
+         (\(Forall xs) -> map g (map f xs) .== map (g . f) xs) $
+         \ih (x, xs) -> [] |- map g (map f (x .: xs))
+                           =: map g (f x .: map f xs)
+                           =: g (f x) .: map g (map f xs)
+                           ?? ih
+                           =: g (f x) .: map (g . f) xs
+                           =: (g . f) x .: map (g . f) xs
+                           =: map (g . f) (x .: xs)
+                           =: qed
+
+-- | @map f . concat = concat . map (map f)@
+--
+-- >>> runTP $ mapConcat @Integer @Bool (uninterpret "f")
+-- Lemma: mapAppend              Q.E.D.
+-- Inductive lemma: mapConcat
+--   Step: Base                  Q.E.D.
+--   Step: 1                     Q.E.D.
+--   Step: 2                     Q.E.D.
+--   Step: 3                     Q.E.D.
+--   Step: 4                     Q.E.D.
+--   Step: 5                     Q.E.D.
+--   Result:                     Q.E.D.
+-- Functions proven terminating: sbv.foldr, sbv.map
+-- [Proven] mapConcat :: Ɐxs ∷ [[Integer]] → Bool
+mapConcat :: (SymVal a, SymVal b) => (SBV a -> SBV b) -> TP (Proof (Forall "xs" [[a]] -> SBool))
+mapConcat f = do
+   ma <- recall (mapAppend f)
+
+   induct "mapConcat"
+          (\(Forall xs) -> map f (concat xs) .== concat (map (map f) xs)) $
+          \ih (x, xs) -> [] |- map f (concat (x .: xs))
+                            =: map f (x ++ concat xs)
+                            ?? ma
+                            =: map f x ++ map f (concat xs)
+                            ?? ih
+                            =: map f x ++ concat (map (map f) xs)
+                            =: concat (map f x .: map (map f) xs)
+                            =: concat (map (map f) (x .: xs))
+                            =: qed
+
+-- | @foldr f a . map g == foldr (f . g) a@
+--
+-- >>> runTP $ foldrMapFusion @String @Bool @Integer (uninterpret "a") (uninterpret "b") (uninterpret "c")
+-- Inductive lemma: foldrMapFusion
+--   Step: Base                       Q.E.D.
+--   Step: 1                          Q.E.D.
+--   Step: 2                          Q.E.D.
+--   Step: 3                          Q.E.D.
+--   Step: 4                          Q.E.D.
+--   Result:                          Q.E.D.
+-- Functions proven terminating: sbv.foldr, sbv.map
+-- [Proven] foldrMapFusion :: Ɐxs ∷ [String] → Bool
+foldrMapFusion :: forall a b c. (SymVal a, SymVal b, SymVal c) => SBV c -> (SBV a -> SBV b) -> (SBV b -> SBV c -> SBV c) -> TP (Proof (Forall "xs" [a] -> SBool))
+foldrMapFusion a g f =
+  induct "foldrMapFusion"
+         (\(Forall xs) -> foldr f a (map g xs) .== foldr (f . g) a xs) $
+         \ih (x, xs) -> [] |- foldr f a (map g (x .: xs))
+                           =: foldr f a (g x .: map g xs)
+                           =: g x `f` foldr f a (map g xs)
+                           ?? ih
+                           =: g x `f` foldr (f . g) a xs
+                           =: foldr (f . g) a (x .: xs)
+                           =: qed
+
+-- |
+--
+-- @
+--   f . foldr g a == foldr h b
+--   provided, f a = b and for all x and y, f (g x y) == h x (f y).
+-- @
+--
+-- >>> runTP $ foldrFusion @String @Bool @Integer (uninterpret "a") (uninterpret "b") (uninterpret "f") (uninterpret "g") (uninterpret "h")
+-- Inductive lemma: foldrFusion
+--   Step: Base                    Q.E.D.
+--   Step: 1                       Q.E.D.
+--   Step: 2                       Q.E.D.
+--   Step: 3                       Q.E.D.
+--   Step: 4                       Q.E.D.
+--   Result:                       Q.E.D.
+-- Functions proven terminating: sbv.foldr
+-- [Proven] foldrFusion :: Ɐxs ∷ [String] → Bool
+foldrFusion :: forall a b c. (SymVal a, SymVal b, SymVal c) => SBV c -> SBV b -> (SBV c -> SBV b) -> (SBV a -> SBV c -> SBV c) -> (SBV a -> SBV b -> SBV b) -> TP (Proof (Forall "xs" [a] -> SBool))
+foldrFusion a b f g h = do
+   let -- Assumptions under which the equality holds
+       h1 = f a .== b
+       h2 = quantifiedBool $ \(Forall x) (Forall y) -> f (g x y) .== h x (f y)
+
+   induct "foldrFusion"
+          (\(Forall xs) -> h1 .&& h2 .=> f (foldr g a xs) .== foldr h b xs) $
+          \ih (x, xs) -> [h1, h2] |- f (foldr g a (x .: xs))
+                                  =: f (g x (foldr g a xs))
+                                  =: h x (f (foldr g a xs))
+                                  ?? ih
+                                  =: h x (foldr h b xs)
+                                  =: foldr h b (x .: xs)
+                                  =: qed
+
+-- | @foldr f a (xs ++ ys) == foldr f (foldr f a ys) xs@
+--
+-- >>> runTP $ foldrOverAppend @Integer (uninterpret "a") (uninterpret "f")
+-- Inductive lemma: foldrOverAppend
+--   Step: Base                        Q.E.D.
+--   Step: 1                           Q.E.D.
+--   Step: 2                           Q.E.D.
+--   Step: 3                           Q.E.D.
+--   Step: 4                           Q.E.D.
+--   Result:                           Q.E.D.
+-- Functions proven terminating: sbv.foldr
+-- [Proven] foldrOverAppend :: Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool
+foldrOverAppend :: forall a. SymVal a => SBV a -> (SBV a -> SBV a -> SBV a) -> TP (Proof (Forall "xs" [a] -> Forall "ys" [a] -> SBool))
+foldrOverAppend a f =
+   induct "foldrOverAppend"
+          (\(Forall xs) (Forall ys) -> foldr f a (xs ++ ys) .== foldr f (foldr f a ys) xs) $
+          \ih (x, xs) ys -> [] |- foldr f a ((x .: xs) ++ ys)
+                               =: foldr f a (x .: (xs ++ ys))
+                               =: x `f` foldr f a (xs ++ ys)
+                               ?? ih
+                               =: x `f` foldr f (foldr f a ys) xs
+                               =: foldr f (foldr f a ys) (x .: xs)
+                               =: qed
+
+-- | @foldl f e (xs ++ ys) == foldl f (foldl f e xs) ys@
+--
+-- >>> runTP $ foldlOverAppend @Integer @Bool (uninterpret "f")
+-- Inductive lemma: foldlOverAppend
+--   Step: Base                        Q.E.D.
+--   Step: 1                           Q.E.D.
+--   Step: 2                           Q.E.D.
+--   Step: 3                           Q.E.D.
+--   Result:                           Q.E.D.
+-- Functions proven terminating: sbv.foldl
+-- [Proven] foldlOverAppend :: Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Ɐe ∷ Bool → Bool
+foldlOverAppend :: forall a b. (SymVal a, SymVal b) => (SBV b -> SBV a -> SBV b) -> TP (Proof (Forall "xs" [a] -> Forall "ys" [a] -> Forall "e" b -> SBool))
+foldlOverAppend f =
+   induct "foldlOverAppend"
+          (\(Forall xs) (Forall ys) (Forall a) -> foldl f a (xs ++ ys) .== foldl f (foldl f a xs) ys) $
+          \ih (x, xs) ys a -> [] |- foldl f a ((x .: xs) ++ ys)
+                                 =: foldl f a (x .: (xs ++ ys))
+                                 =: foldl f (a `f` x) (xs ++ ys)
+                                 -- z3 is smart enough to instantiate the IH correctly below, but we're
+                                 -- using an explicit instantiation to be clear about the use of @a@ at a different value
+                                 ?? ih `at` (Inst @"ys" ys, Inst @"e" (a `f` x))
+                                 =: foldl f (foldl f (a `f` x) xs) ys
+                                 =: qed
+
+-- | @foldr f e xs == foldl (flip f) e (reverse xs)@
+--
+-- >>> runTP $ foldrFoldlDuality @Integer @String (uninterpret "f")
+-- Inductive lemma: foldlOverAppend
+--   Step: Base                          Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Step: 3                             Q.E.D.
+--   Result:                             Q.E.D.
+-- Inductive lemma: foldrFoldlDuality
+--   Step: Base                          Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Step: 3                             Q.E.D.
+--   Step: 4                             Q.E.D.
+--   Step: 5                             Q.E.D.
+--   Step: 6                             Q.E.D.
+--   Result:                             Q.E.D.
+-- Functions proven terminating: sbv.foldl, sbv.foldr, sbv.reverse
+-- [Proven] foldrFoldlDuality :: Ɐxs ∷ [Integer] → Ɐe ∷ String → Bool
+foldrFoldlDuality :: forall a b. (SymVal a, SymVal b) => (SBV a -> SBV b -> SBV b) -> TP (Proof (Forall "xs" [a] -> Forall "e" b -> SBool))
+foldrFoldlDuality f = do
+   foa <- foldlOverAppend (flip f)
+
+   induct "foldrFoldlDuality"
+          (\(Forall xs) (Forall e) -> foldr f e xs .== foldl (flip f) e (reverse xs)) $
+          \ih (x, xs) e -> [] |- let ff  = flip f
+                                     rxs = reverse xs
+                                 in foldr f e (x .: xs)
+                                 =: x `f` foldr f e xs
+                                 ?? ih
+                                 =: x `f` foldl ff e rxs
+                                 =: foldl ff e rxs `ff` x
+                                 =: foldl ff (foldl ff e rxs) [x]
+                                 ?? foa
+                                 =: foldl ff e (rxs ++ [x])
+                                 =: foldl ff e (reverse (x .: xs))
+                                 =: qed
+
+-- | Given:
+--
+-- @
+--     x \@ (y \@ z) = (x \@ y) \@ z     (associativity of @)
+-- and e \@ x = x                     (left unit)
+-- and x \@ e = x                     (right unit)
+-- @
+--
+-- Proves:
+--
+-- @
+--     foldr (\@) e xs == foldl (\@) e xs
+-- @
+--
+-- >>> runTP $ foldrFoldlDualityGeneralized @Integer (uninterpret "e") (uninterpret "|@|")
+-- Inductive lemma: helper
+--   Step: Base                          Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Step: 3                             Q.E.D.
+--   Step: 4                             Q.E.D.
+--   Result:                             Q.E.D.
+-- Inductive lemma: foldrFoldlDuality
+--   Step: Base                          Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Step: 3                             Q.E.D.
+--   Step: 4                             Q.E.D.
+--   Step: 5                             Q.E.D.
+--   Step: 6                             Q.E.D.
+--   Result:                             Q.E.D.
+-- Functions proven terminating: sbv.foldl, sbv.foldr
+-- [Proven] foldrFoldlDuality :: Ɐxs ∷ [Integer] → Bool
+foldrFoldlDualityGeneralized :: forall a. SymVal a => SBV a -> (SBV a -> SBV a -> SBV a) -> TP (Proof (Forall "xs" [a] -> SBool))
+foldrFoldlDualityGeneralized e (@) = do
+   -- Assumptions under which the equality holds
+   let assoc = quantifiedBool $ \(Forall x) (Forall y) (Forall z) -> x @ (y @ z) .== (x @ y) @ z
+       lunit = quantifiedBool $ \(Forall x) -> e @ x .== x
+       runit = quantifiedBool $ \(Forall x) -> x @ e .== x
+
+   -- Helper: foldl (@) (y @ z) xs = y @ foldl (@) z xs
+   -- Note the instantiation of the IH at a different value for z. It turns out
+   -- we don't have to actually specify this since z3 can figure it out by itself, but we're being explicit.
+   helper <- induct "helper"
+                    (\(Forall @"xs" xs) (Forall @"y" y) (Forall @"z" z) -> assoc .=> foldl (@) (y @ z) xs .== y @ foldl (@) z xs) $
+                    \ih (x, xs) y z -> [assoc] |- foldl (@) (y @ z) (x .: xs)
+                                               =: foldl (@) ((y @ z) @ x) xs
+                                               ?? assoc
+                                               =: foldl (@) (y @ (z @ x)) xs
+                                               ?? ih `at` (Inst @"y" y, Inst @"z" (z @ x))
+                                               =: y @ foldl (@) (z @ x) xs
+                                               =: y @ foldl (@) z (x .: xs)
+                                               =: qed
+
+   induct "foldrFoldlDuality"
+          (\(Forall xs) -> assoc .&& lunit .&& runit .=> foldr (@) e xs .== foldl (@) e xs) $
+          \ih (x, xs) -> [assoc, lunit, runit] |- foldr (@) e (x .: xs)
+                                               =: x @ foldr (@) e xs
+                                               ?? ih
+                                               =: x @ foldl (@) e xs
+                                               ?? helper
+                                               =: foldl (@) (x @ e) xs
+                                               ?? runit
+                                               =: foldl (@) x xs
+                                               ?? lunit
+                                               =: foldl (@) (e @ x) xs
+                                               =: foldl (@) e (x .: xs)
+                                               =: qed
+
+-- | Given:
+--
+-- @
+--        (x \<+> y) \<*> z = x \<+> (y \<*> z)
+--   and  x \<+> e = e \<*> x
+-- @
+--
+-- Proves:
+--
+-- @
+--    foldr (\<+>) e xs = foldl (\<*>) e xs
+-- @
+--
+-- In Bird's Introduction to Functional Programming book (2nd edition) this is called the second duality theorem:
+--
+-- >>> runTP $ foldrFoldl @Integer @String (uninterpret "<+>") (uninterpret "<*>") (uninterpret "e")
+-- Inductive lemma: foldl over <*>/<+>
+--   Step: Base                           Q.E.D.
+--   Step: 1                              Q.E.D.
+--   Step: 2                              Q.E.D.
+--   Step: 3                              Q.E.D.
+--   Step: 4                              Q.E.D.
+--   Result:                              Q.E.D.
+-- Inductive lemma: foldrFoldl
+--   Step: Base                           Q.E.D.
+--   Step: 1                              Q.E.D.
+--   Step: 2                              Q.E.D.
+--   Step: 3                              Q.E.D.
+--   Step: 4                              Q.E.D.
+--   Step: 5                              Q.E.D.
+--   Result:                              Q.E.D.
+-- Functions proven terminating: sbv.foldl, sbv.foldr
+-- [Proven] foldrFoldl :: Ɐxs ∷ [Integer] → Bool
+foldrFoldl :: forall a b. (SymVal a, SymVal b) => (SBV a -> SBV b -> SBV b) -> (SBV b -> SBV a -> SBV b) -> SBV b -> TP (Proof (Forall "xs" [a] -> SBool))
+foldrFoldl (<+>) (<*>) e = do
+   -- Assumptions about the operators
+   let -- (x <+> y) <*> z == x <+> (y <*> z)
+       assoc = quantifiedBool $ \(Forall x) (Forall y) (Forall z) -> (x <+> y) <*> z .== x <+> (y <*> z)
+
+       -- x <+> e == e <*> x
+       unit  = quantifiedBool $ \(Forall x) -> x <+> e .== e <*> x
+
+   -- Helper: x <+> foldl (<*>) y xs == foldl (<*>) (x <+> y) xs
+   helper <-
+      induct "foldl over <*>/<+>"
+             (\(Forall @"xs" xs) (Forall @"x" x) (Forall @"y" y) -> assoc .=> x <+> foldl (<*>) y xs .== foldl (<*>) (x <+> y) xs) $
+
+             -- Using z to avoid confusion with the variable x already present, following Bird.
+             -- z3 can figure out the proper instantiation of ih so the at call is unnecessary, but being explicit is helpful.
+             \ih (z, xs) x y -> [assoc] |- x <+> foldl (<*>) y (z .: xs)
+                                        =: x <+> foldl (<*>) (y <*> z) xs
+                                        ?? ih `at` (Inst @"x" x, Inst @"y" (y <*> z))
+                                        =: foldl (<*>) (x <+> (y <*> z)) xs
+                                        ?? assoc
+                                        =: foldl (<*>) ((x <+> y) <*> z) xs
+                                        =: foldl (<*>) (x <+> y) (z .: xs)
+                                        =: qed
+
+   -- Final proof:
+   induct "foldrFoldl"
+          (\(Forall xs) -> assoc .&& unit .=> foldr (<+>) e xs .== foldl (<*>) e xs) $
+          \ih (x, xs) -> [assoc, unit] |- foldr (<+>) e (x .: xs)
+                                       =: x <+> foldr (<+>) e xs
+                                       ?? ih
+                                       =: x <+> foldl (<*>) e xs
+                                       ?? helper
+                                       =: foldl (<*>) (x <+> e) xs
+                                       =: foldl (<*>) (e <*> x) xs
+                                       =: foldl (<*>) e (x .: xs)
+                                       =: qed
+
+-- | Provided @f@ is associative and @a@ is its both left and right-unit:
+--
+-- @foldr f a . concat == foldr f a . map (foldr f a)@
+--
+-- >>> runTP $ bookKeeping @Integer (uninterpret "a") (uninterpret "f")
+-- Inductive lemma: foldBase
+--   Step: Base                        Q.E.D.
+--   Step: 1                           Q.E.D.
+--   Step: 2                           Q.E.D.
+--   Step: 3                           Q.E.D.
+--   Step: 4                           Q.E.D.
+--   Result:                           Q.E.D.
+-- Inductive lemma: foldrOverAppend
+--   Step: Base                        Q.E.D.
+--   Step: 1                           Q.E.D.
+--   Step: 2                           Q.E.D.
+--   Step: 3                           Q.E.D.
+--   Step: 4                           Q.E.D.
+--   Result:                           Q.E.D.
+-- Inductive lemma: bookKeeping
+--   Step: Base                        Q.E.D.
+--   Step: 1                           Q.E.D.
+--   Step: 2                           Q.E.D.
+--   Step: 3                           Q.E.D.
+--   Step: 4                           Q.E.D.
+--   Step: 5                           Q.E.D.
+--   Step: 6                           Q.E.D.
+--   Result:                           Q.E.D.
+-- Functions proven terminating: sbv.foldr, sbv.map
+-- [Proven] bookKeeping :: Ɐxss ∷ [[Integer]] → Bool
+--
+-- NB. This theorem does not hold if @f@ does not have a left-unit! Consider the input @[[], [x]]@. Left hand side reduces to
+-- @x@, while the right hand side reduces to: @f a x@. And unless @f@ is commutative or @a@ is not also a left-unit,
+-- then one can find a counter-example. (Aside: if both left and right units exist for a binary operator, then they
+-- are necessarily the same element, since @l = f l r = r@. So, an equivalent statement could simply say @f@ has
+-- both left and right units.) A concrete counter-example is:
+--
+-- @
+--   data T = A | B | C
+--
+--   f :: T -> T -> T
+--   f C A = A
+--   f C B = A
+--   f x _ = x
+-- @
+--
+-- You can verify @f@ is associative. Also note that @C@ is the right-unit for @f@, but it isn't the left-unit.
+-- In fact, @f@ has no-left unit by the above argument. In this case, the bookkeeping law produces @B@ for
+-- the left-hand-side, and @A@ for the right-hand-side for the input @[[], [B]]@.
+bookKeeping :: forall a. SymVal a => SBV a -> (SBV a -> SBV a -> SBV a) -> TP (Proof (Forall "xss" [[a]] -> SBool))
+bookKeeping a f = do
+
+   -- Assumptions about f
+   let assoc = quantifiedBool $ \(Forall x) (Forall y) (Forall z) -> x `f` (y `f` z) .== (x `f` y) `f` z
+       rUnit = quantifiedBool $ \(Forall x) -> x `f` a .== x
+       lUnit = quantifiedBool $ \(Forall x) -> a `f` x .== x
+
+   -- Helper: @foldr f y xs = foldr f a xs `f` y@
+   helper <- induct "foldBase"
+                    (\(Forall xs) (Forall y) -> lUnit .&& assoc .=> foldr f y xs .== foldr f a xs `f` y) $
+                    \ih (x, xs) y -> [lUnit, assoc] |- foldr f y (x .: xs)
+                                                    =: x `f` foldr f y xs
+                                                    ?? ih
+                                                    =: x `f` (foldr f a xs `f` y)
+                                                    =: (x `f` foldr f a xs) `f` y
+                                                    =: foldr f a (x .: xs) `f` y
+                                                    =: qed
+
+   foa <- foldrOverAppend a f
+
+   induct "bookKeeping"
+          (\(Forall xss) -> assoc .&& rUnit .&& lUnit .=> foldr f a (concat xss) .== foldr f a (map (foldr f a) xss)) $
+          \ih (xs, xss) -> [assoc, rUnit, lUnit] |- foldr f a (concat (xs .: xss))
+                                                 =: foldr f a (xs ++ concat xss)
+                                                 ?? foa
+                                                 =: foldr f (foldr f a (concat xss)) xs
+                                                 ?? ih
+                                                 =: foldr f (foldr f a (map (foldr f a) xss)) xs
+                                                 ?? helper `at` (Inst @"xs" xs, Inst @"y" (foldr f a (map (foldr f a) xss)))
+                                                 =: foldr f a xs `f` foldr f a (map (foldr f a) xss)
+                                                 =: foldr f a (foldr f a xs .: map (foldr f a) xss)
+                                                 =: foldr f a (map (foldr f a) (xs .: xss))
+                                                 =: qed
+
+-- | @filter p (xs ++ ys) == filter p xs ++ filter p ys@
+--
+-- >>> runTP $ filterAppend @Integer (uninterpret "p")
+-- Inductive lemma: filterAppend
+--   Step: Base                     Q.E.D.
+--   Step: 1                        Q.E.D.
+--   Step: 2                        Q.E.D.
+--   Step: 3                        Q.E.D.
+--   Step: 4                        Q.E.D.
+--   Step: 5                        Q.E.D.
+--   Result:                        Q.E.D.
+-- Functions proven terminating: sbv.filter
+-- [Proven] filterAppend :: Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool
+filterAppend :: forall a. SymVal a => (SBV a -> SBool) -> TP (Proof (Forall "xs" [a] -> Forall "ys" [a] -> SBool))
+filterAppend p =
+   induct "filterAppend"
+          (\(Forall xs) (Forall ys) -> filter p xs ++ filter p ys .== filter p (xs ++ ys)) $
+          \ih (x, xs) ys -> [] |- filter p (x .: xs) ++ filter p ys
+                               =: ite (p x) (x .: filter p xs) (filter p xs) ++ filter p ys
+                               =: ite (p x) (x .: filter p xs ++ filter p ys) (filter p xs ++ filter p ys)
+                               ?? ih
+                               =: ite (p x) (x .: filter p (xs ++ ys)) (filter p (xs ++ ys))
+                               =: filter p (x .: (xs ++ ys))
+                               =: filter p ((x .: xs) ++ ys)
+                               =: qed
+
+-- | @filter p (concat xss) == concatMap (filter p xss)@
+--
+-- >>> runTP $ filterConcat @Integer (uninterpret "f")
+-- Inductive lemma: filterAppend
+--   Step: Base                     Q.E.D.
+--   Step: 1                        Q.E.D.
+--   Step: 2                        Q.E.D.
+--   Step: 3                        Q.E.D.
+--   Step: 4                        Q.E.D.
+--   Step: 5                        Q.E.D.
+--   Result:                        Q.E.D.
+-- Inductive lemma: filterConcat
+--   Step: Base                     Q.E.D.
+--   Step: 1                        Q.E.D.
+--   Step: 2                        Q.E.D.
+--   Step: 3                        Q.E.D.
+--   Result:                        Q.E.D.
+-- Functions proven terminating: sbv.filter, sbv.foldr, sbv.map
+-- [Proven] filterConcat :: Ɐxss ∷ [[Integer]] → Bool
+filterConcat :: forall a. SymVal a => (SBV a -> SBool) -> TP (Proof (Forall "xss" [[a]] -> SBool))
+filterConcat p = do
+  fa <- filterAppend p
+
+  inductWith cvc5 "filterConcat"
+         (\(Forall xss) -> filter p (concat xss) .== concatMap (filter p) xss) $
+         \ih (xs, xss) -> [] |- filter p (concat (xs .: xss))
+                             =: filter p (xs ++ concat xss)
+                             ?? fa
+                             =: filter p xs ++ filter p (concat xss)
+                             ?? ih
+                             =: concatMap (filter p) (xs .: xss)
+                             =: qed
+
+-- | @takeWhile f xs ++ dropWhile f xs == xs@
+--
+-- >>> runTP $ takeDropWhile @Integer (uninterpret "f")
+-- Inductive lemma: takeDropWhile
+--   Step: Base                      Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1.1                   Q.E.D.
+--     Step: 1.1.2                   Q.E.D.
+--     Step: 1.2.1                   Q.E.D.
+--     Step: 1.2.2                   Q.E.D.
+--     Step: 1.Completeness          Q.E.D.
+--   Result:                         Q.E.D.
+-- Functions proven terminating: sbv.dropWhile, sbv.takeWhile
+-- [Proven] takeDropWhile :: Ɐxs ∷ [Integer] → Bool
+takeDropWhile :: forall a. SymVal a => (SBV a -> SBool) -> TP (Proof (Forall "xs" [a] -> SBool))
+takeDropWhile f =
+   induct "takeDropWhile"
+          (\(Forall xs) -> takeWhile f xs ++ dropWhile f xs .== xs) $
+          \ih (x, xs) -> [] |- takeWhile f (x .: xs) ++ dropWhile f (x .: xs)
+                            =: cases [ f x        ==> x .: takeWhile f xs ++ dropWhile f xs
+                                                   ?? ih
+                                                   =: x .: xs
+                                                   =: qed
+                                     , sNot (f x) ==> [] ++ x .: xs
+                                                   =: x .: xs
+                                                   =: qed
+                                     ]
+-- | Remove adjacent duplicates.
+destutter :: SymVal a => SList a -> SList a
+destutter = smtFunction "destutter"
+          $ \xs -> [sCase| xs of
+                      []   -> xs
+                      [_]  -> xs
+                      a : rest@(b : _) | a .== b ->      destutter rest
+                                       | True    -> a .: destutter rest
+                   |]
+
+-- | @destutter (destutter xs) == destutter xs@
+--
+-- >>> runTP $ destutterIdempotent @Integer
+-- Inductive lemma: helper1
+--   Step: Base                         Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1                        Q.E.D.
+--     Step: 1.2.1                      Q.E.D.
+--     Step: 1.2.2                      Q.E.D.
+--     Step: 1.Completeness             Q.E.D.
+--   Result:                            Q.E.D.
+-- Inductive lemma: helper2
+--   Step: Base                         Q.E.D.
+--   Step: 1                            Q.E.D.
+--   Result:                            Q.E.D.
+-- Inductive lemma (strong): helper3
+--   Step: Measure is non-negative      Q.E.D.
+--   Step: 1 (3 way case split)
+--     Step: 1.1                        Q.E.D.
+--     Step: 1.2                        Q.E.D.
+--     Step: 1.3.1                      Q.E.D.
+--     Step: 1.3.2 (2 way case split)
+--       Step: 1.3.2.1.1                Q.E.D.
+--       Step: 1.3.2.1.2                Q.E.D.
+--       Step: 1.3.2.2.1                Q.E.D.
+--       Step: 1.3.2.2.2                Q.E.D.
+--       Step: 1.3.2.Completeness       Q.E.D.
+--     Step: 1.Completeness             Q.E.D.
+--   Result:                            Q.E.D.
+-- Lemma: destutterIdempotent           Q.E.D.
+-- Functions proven terminating: destutter, noAdd
+-- [Proven] destutterIdempotent :: Ɐxs ∷ [Integer] → Bool
+destutterIdempotent :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> SBool))
+destutterIdempotent = do
+
+   -- No adjacent duplicates
+   let noAdd = smtFunction "noAdd"
+             $ \xs -> [sCase| xs of
+                         []  -> sTrue
+                         [_] -> sTrue
+                         a : rest@(b : _) | a .== b -> sFalse
+                                          | True    -> noAdd rest
+                      |]
+
+   -- Helper: The head of a destuttered non-empty list does not change
+   helper1 <- induct "helper1"
+                     (\(Forall @"xs" (xs :: SList a)) (Forall @"h" h) -> head (destutter (h .: xs)) .== h) $
+                     \ih (x, xs) h -> []
+                                   |- head (destutter (h .: x .: xs))
+                                   =: cases [ h ./= x ==> trivial
+                                            , h .== x ==> head (destutter (x .: xs))
+                                                       ?? ih
+                                                       =: x
+                                                       =: qed
+                                            ]
+
+   -- Helper: show that if a list has no adjacent duplicates, then destutter leaves it unchanged:
+   helper2 <- induct "helper2"
+                     (\(Forall @"xs" (xs :: SList a)) -> noAdd xs .=> destutter xs .== xs) $
+                     \ih (x, xs) -> [noAdd (x .: xs)]
+                                 |- destutter (x .: xs)
+                                 ?? ih
+                                 =: x .: xs
+                                 =: qed
+
+   -- Helper: prove that noAdd is true for the result of destutter
+   helper3 <- sInductWith cvc5 "helper3"
+                  (\(Forall @"xs" (xs :: SList a)) -> noAdd (destutter xs))
+                  (length, []) $
+                  \ih xs -> []
+                         |- noAdd (destutter xs)
+                         =: [pCase| xs of
+                              []  -> trivial
+                              [_] -> trivial
+                              whole@(a : rest@(b : bs))
+                                 -> noAdd (destutter whole)
+                                 =: cases [a .== b  ==> noAdd (destutter rest)
+                                                     ?? ih
+                                                     =: sTrue
+                                                     =: qed
+                                          , a ./= b ==> noAdd (a .: destutter rest)
+                                                     ?? helper1 `at` (Inst @"xs" bs, Inst @"h" b)
+                                                     ?? ih
+                                                     =: sTrue
+                                                     =: qed
+                                          ]
+                            |]
+
+   -- Now we can prove idempotency easily:
+   lemma "destutterIdempotent"
+          (\(Forall xs) -> destutter (destutter xs) .== destutter xs)
+          [proofOf helper2, proofOf helper3]
+
+-- | @(as ++ bs) \\ cs == (as \\ cs) ++ (bs \\ cs)@
+--
+-- >>> runTP $ appendDiff @Integer
+-- Inductive lemma: appendDiff
+--   Step: Base                   Q.E.D.
+--   Step: 1                      Q.E.D.
+--   Step: 2                      Q.E.D.
+--   Step: 3                      Q.E.D.
+--   Result:                      Q.E.D.
+-- Functions proven terminating: sbv.diff
+-- [Proven] appendDiff :: Ɐas ∷ [Integer] → Ɐbs ∷ [Integer] → Ɐcs ∷ [Integer] → Bool
+appendDiff :: forall a. (Eq a, SymVal a) => TP (Proof (Forall "as" [a] -> Forall "bs" [a] -> Forall "cs" [a] -> SBool))
+appendDiff = induct "appendDiff"
+                    (\(Forall as) (Forall bs) (Forall cs) -> (as ++ bs) \\ cs .== (as \\ cs) ++ (bs \\ cs)) $
+                    \ih (a, as) bs cs -> [] |- (a .: as ++ bs) \\ cs
+                                            =: (a .: (as ++ bs)) \\ cs
+                                            =: ite (a `elem` cs) ((as ++ bs) \\ cs) (a .: ((as ++ bs) \\ cs))
+                                            ?? ih
+                                            =: ((a .: as) \\ cs) ++ (bs \\ cs)
+                                            =: qed
+
+-- | @as \\ (bs ++ cs) == (as \\ bs) \\ cs@
+--
+-- >>> runTP $ diffAppend @Integer
+-- Inductive lemma: diffAppend
+--   Step: Base                   Q.E.D.
+--   Step: 1                      Q.E.D.
+--   Step: 2                      Q.E.D.
+--   Step: 3                      Q.E.D.
+--   Step: 4                      Q.E.D.
+--   Result:                      Q.E.D.
+-- Functions proven terminating: sbv.diff
+-- [Proven] diffAppend :: Ɐas ∷ [Integer] → Ɐbs ∷ [Integer] → Ɐcs ∷ [Integer] → Bool
+diffAppend :: forall a. (Eq a, SymVal a) => TP (Proof (Forall "as" [a] -> Forall "bs" [a] -> Forall "cs" [a] -> SBool))
+diffAppend = induct "diffAppend"
+                    (\(Forall as) (Forall bs) (Forall cs) -> as \\ (bs ++ cs) .== (as \\ bs) \\ cs) $
+                    \ih (a, as) bs cs -> [] |- (a .: as) \\ (bs ++ cs)
+                                            =: ite (a `elem` (bs ++ cs)) (as \\ (bs ++ cs)) (a .: (as \\ (bs ++ cs)))
+                                            ?? ih `at` (Inst @"bs" bs, Inst @"cs" cs)
+                                            =: ite (a `elem` (bs ++ cs)) ((as \\ bs) \\ cs) (a .: (as \\ (bs ++ cs)))
+                                            ?? ih `at` (Inst @"bs" bs, Inst @"cs" cs)
+                                            =: ite (a `elem` (bs ++ cs)) ((as \\ bs) \\ cs) (a .: ((as \\ bs) \\ cs))
+                                            =: ((a .: as) \\ bs) \\ cs
+                                            =: qed
+
+-- | @(as \\ bs) \\ cs == (as \\ cs) \\ bs@
+--
+-- >>> runTP $ diffDiff @Integer
+-- Inductive lemma: diffDiff
+--   Step: Base                      Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1.1                   Q.E.D.
+--     Step: 1.1.2                   Q.E.D.
+--     Step: 1.1.3 (2 way case split)
+--       Step: 1.1.3.1               Q.E.D.
+--       Step: 1.1.3.2.1             Q.E.D.
+--       Step: 1.1.3.2.2 (a ∉ cs)    Q.E.D.
+--       Step: 1.1.3.Completeness    Q.E.D.
+--     Step: 1.2.1                   Q.E.D.
+--     Step: 1.2.2 (2 way case split)
+--       Step: 1.2.2.1.1             Q.E.D.
+--       Step: 1.2.2.1.2             Q.E.D.
+--       Step: 1.2.2.1.3 (a ∈ cs)    Q.E.D.
+--       Step: 1.2.2.2.1             Q.E.D.
+--       Step: 1.2.2.2.2             Q.E.D.
+--       Step: 1.2.2.2.3 (a ∉ bs)    Q.E.D.
+--       Step: 1.2.2.2.4 (a ∉ cs)    Q.E.D.
+--       Step: 1.2.2.Completeness    Q.E.D.
+--     Step: 1.Completeness          Q.E.D.
+--   Result:                         Q.E.D.
+-- Functions proven terminating: sbv.diff
+-- [Proven] diffDiff :: Ɐas ∷ [Integer] → Ɐbs ∷ [Integer] → Ɐcs ∷ [Integer] → Bool
+diffDiff :: forall a. (Eq a, SymVal a) => TP (Proof (Forall "as" [a] -> Forall "bs" [a] -> Forall "cs" [a] -> SBool))
+diffDiff = induct "diffDiff"
+                  (\(Forall as) (Forall bs) (Forall cs) -> (as \\ bs) \\ cs .== (as \\ cs) \\ bs) $
+                  \ih (a, as) bs cs ->
+                      [] |- ((a .: as) \\ bs) \\ cs
+                         =: cases [ a `elem`    bs ==> (as \\ bs) \\ cs
+                                                    ?? ih
+                                                    =: (as \\ cs) \\ bs
+                                                    =: cases [ a `elem`    cs ==> ((a .: as) \\ cs) \\ bs
+                                                                               =: qed
+                                                             , a `notElem` cs ==> (a .: (as \\ cs)) \\ bs
+                                                                               ?? "a ∉ cs"
+                                                                               =: ((a .: as) \\ cs) \\ bs
+                                                                               =: qed
+                                                             ]
+                                  , a `notElem` bs ==> (a .: (as \\ bs)) \\ cs
+                                                    =: cases [ a `elem`    cs ==> (as \\ bs) \\ cs
+                                                                               ?? ih
+                                                                               =: (as \\ cs) \\ bs
+                                                                               ?? "a ∈ cs"
+                                                                               =: ((a .: as) \\ cs) \\ bs
+                                                                               =: qed
+                                                             , a `notElem` cs ==> a .: ((as \\ bs) \\ cs)
+                                                                               ?? ih
+                                                                               =: a .: ((as \\ cs) \\ bs)
+                                                                               ?? "a ∉ bs"
+                                                                               =: (a .: (as \\ cs)) \\ bs
+                                                                               ?? "a ∉ cs"
+                                                                               =: ((a .: as) \\ cs) \\ bs
+                                                                               =: qed
+                                                             ]
+                                  ]
+
+-- | Are the two lists disjoint?
+disjoint :: (Eq a, SymVal a) => SList a -> SList a -> SBool
+disjoint = smtFunction "disjoint"
+         $ \xs ys -> [sCase| xs of
+                        []     -> sTrue
+                        a : as -> a `notElem` ys .&& disjoint as ys
+                     |]
+
+-- | @disjoint as bs .=> as \\ bs == as@
+--
+-- >>> runTP $ disjointDiff @Integer
+-- Inductive lemma: disjointDiff
+--   Step: Base                     Q.E.D.
+--   Step: 1                        Q.E.D.
+--   Step: 2                        Q.E.D.
+--   Result:                        Q.E.D.
+-- Functions proven terminating: disjoint, sbv.diff
+-- [Proven] disjointDiff :: Ɐas ∷ [Integer] → Ɐbs ∷ [Integer] → Bool
+disjointDiff :: forall a. (Eq a, SymVal a) => TP (Proof (Forall "as" [a] -> Forall "bs" [a] -> SBool))
+disjointDiff = induct "disjointDiff"
+                      (\(Forall as) (Forall bs) -> disjoint as bs .=> as \\ bs .== as) $
+                      \ih (a, as) bs -> [disjoint (a .: as) bs]
+                                     |- (a .: as) \\ bs
+                                     =: a .: (as \\ bs)
+                                     ?? ih
+                                     =: a .: as
+                                     =: qed
+
+-- | @fst (partition f xs) == filter f xs@
+--
+-- >>> runTP $ partition1 @Integer (uninterpret "f")
+-- Inductive lemma: partition1
+--   Step: Base                   Q.E.D.
+--   Step: 1                      Q.E.D.
+--   Step: 2                      Q.E.D.
+--   Step: 3                      Q.E.D.
+--   Step: 4                      Q.E.D.
+--   Result:                      Q.E.D.
+-- Functions proven terminating: sbv.filter, sbv.partition
+-- [Proven] partition1 :: Ɐxs ∷ [Integer] → Bool
+partition1 :: forall a. SymVal a => (SBV a -> SBool) -> TP (Proof (Forall "xs" [a] -> SBool))
+partition1 f =
+   induct "partition1"
+          (\(Forall xs) -> fst (partition f xs) .== filter f xs) $
+          \ih (x, xs) -> [] |- fst (partition f (x .: xs))
+                            =: fst (let res = partition f xs
+                                    in ite (f x)
+                                           (tuple (x .: fst res, snd res))
+                                           (tuple (fst res, x .: snd res)))
+                            =: ite (f x) (x .: fst (partition f xs)) (fst (partition f xs))
+                            ?? ih
+                            =: ite (f x) (x .: filter f xs) (filter f xs)
+                            =: filter f (x .: xs)
+                            =: qed
+
+-- | @snd (partition f xs) == filter (not . f) xs@
+--
+-- >>> runTP $ partition2 @Integer (uninterpret "f")
+-- Inductive lemma: partition2
+--   Step: Base                   Q.E.D.
+--   Step: 1                      Q.E.D.
+--   Step: 2                      Q.E.D.
+--   Step: 3                      Q.E.D.
+--   Step: 4                      Q.E.D.
+--   Result:                      Q.E.D.
+-- Functions proven terminating: sbv.filter, sbv.partition
+-- [Proven] partition2 :: Ɐxs ∷ [Integer] → Bool
+partition2 :: forall a. SymVal a => (SBV a -> SBool) -> TP (Proof (Forall "xs" [a] -> SBool))
+partition2 f =
+   induct "partition2"
+          (\(Forall xs) -> snd (partition f xs) .== filter (sNot . f) xs) $
+          \ih (x, xs) -> [] |- snd (partition f (x .: xs))
+                            =: snd (let res = partition f xs
+                                    in ite (f x)
+                                           (tuple (x .: fst res, snd res))
+                                           (tuple (fst res, x .: snd res)))
+                            =: ite (f x) (snd (partition f xs)) (x .: snd (partition f xs))
+                            ?? ih
+                            =: ite (f x) (filter (sNot . f) xs) (x .: filter (sNot . f) xs)
+                            =: filter (sNot . f) (x .: xs)
+                            =: qed
+
+-- | @take n (take m xs) == take (n `smin` m) xs@
+--
+-- >>> runTP $ take_take @Integer
+-- Lemma: take_take    Q.E.D.
+-- [Proven] take_take :: Ɐm ∷ Integer → Ɐn ∷ Integer → Ɐxs ∷ [Integer] → Bool
+take_take :: forall a. SymVal a => TP (Proof (Forall "m" Integer -> Forall "n" Integer -> Forall "xs" [a] -> SBool))
+take_take = lemma "take_take"
+                  (\(Forall m) (Forall n) (Forall xs) -> take n (take m xs) .== take (n `smin` m) xs)
+                  []
+
+-- | @n >= 0 && m >= 0 ==> drop n (drop m xs) == drop (n + m) xs@
+--
+-- >>> runTP $ drop_drop @Integer
+-- Lemma: drop_drop    Q.E.D.
+-- [Proven] drop_drop :: Ɐm ∷ Integer → Ɐn ∷ Integer → Ɐxs ∷ [Integer] → Bool
+drop_drop :: forall a. SymVal a => TP (Proof (Forall "m" Integer -> Forall "n" Integer -> Forall "xs" [a] -> SBool))
+drop_drop = lemma "drop_drop"
+                  (\(Forall m) (Forall n) (Forall xs) -> n .>= 0 .&& m .>= 0 .=> drop n (drop m xs) .== drop (n + m) xs)
+                  []
+
+-- | @take n xs ++ drop n xs == xs@
+--
+-- >>> runTP $ take_drop @Integer
+-- Lemma: take_drop    Q.E.D.
+-- [Proven] take_drop :: Ɐn ∷ Integer → Ɐxs ∷ [Integer] → Bool
+take_drop :: forall a. SymVal a => TP (Proof (Forall "n" Integer -> Forall "xs" [a] -> SBool))
+take_drop = lemma "take_drop"
+                  (\(Forall n) (Forall xs) -> take n xs ++ drop n xs .== xs)
+                  []
+
+-- | @n .> 0 ==> take n (x .: xs) == x .: take (n - 1) xs@
+--
+-- >>> runTP $ take_cons @Integer
+-- Lemma: take_cons    Q.E.D.
+-- [Proven] take_cons :: Ɐn ∷ Integer → Ɐx ∷ Integer → Ɐxs ∷ [Integer] → Bool
+take_cons :: forall a. SymVal a => TP (Proof (Forall "n" Integer -> Forall "x" a -> Forall "xs" [a] -> SBool))
+take_cons = lemma "take_cons"
+                  (\(Forall n) (Forall x) (Forall xs) -> n .> 0 .=> take n (x .: xs) .== x .: take (n - 1) xs)
+                  []
+
+-- | @take n (map f xs) == map f (take n xs)@
+--
+-- >>> runTP $ take_map @Integer @Integer (uninterpret "f")
+-- Lemma: take_cons                   Q.E.D.
+-- Lemma: map1                        Q.E.D.
+-- Lemma: take_map.n <= 0             Q.E.D.
+-- Inductive lemma: take_map.n > 0
+--   Step: Base                       Q.E.D.
+--   Step: 1                          Q.E.D.
+--   Step: 2                          Q.E.D.
+--   Step: 3                          Q.E.D.
+--   Step: 4                          Q.E.D.
+--   Step: 5                          Q.E.D.
+--   Result:                          Q.E.D.
+-- Lemma: take_map
+--   Step: 1                          Q.E.D.
+--   Result:                          Q.E.D.
+-- Functions proven terminating: sbv.map
+-- [Proven] take_map :: Ɐn ∷ Integer → Ɐxs ∷ [Integer] → Bool
+take_map :: forall a b. (SymVal a, SymVal b) => (SBV a -> SBV b) -> TP (Proof (Forall "n" Integer -> Forall "xs" [a] -> SBool))
+take_map f = do
+    tc   <- take_cons @a
+
+    map1 <- lemma "map1"
+                  (\(Forall x) (Forall xs) -> map f (x .: xs) .== f x .: map f xs)
+                  []
+
+    h1 <- lemma "take_map.n <= 0"
+                 (\(Forall @"xs" xs) (Forall @"n" n) -> n .<= 0 .=> take n (map f xs) .== map f (take n xs))
+                 []
+
+    h2 <- inductWith cvc5 "take_map.n > 0"
+                 (\(Forall @"xs" xs) (Forall @"n" n) -> n .> 0 .=> take n (map f xs) .== map f (take n xs)) $
+                 \ih (x, xs) n -> [n .> 0] |- take n (map f (x .: xs))
+                                           =: take n (f x .: map f xs)
+                                           =: f x .: take (n - 1) (map f xs)
+                                           ?? ih `at` Inst @"n" (n-1)
+                                           =: f x .: map f (take (n - 1) xs)
+                                           ?? map1 `at` (Inst @"x" x, Inst @"xs" (take (n - 1) xs))
+                                           =: map f (x .: take (n - 1) xs)
+                                           ?? tc
+                                           =: map f (take n (x .: xs))
+                                           =: qed
+
+    calc "take_map"
+         (\(Forall n) (Forall xs) -> take n (map f xs) .== map f (take n xs)) $
+         \n xs -> [] |- take n (map f xs)
+                     ?? h1
+                     ?? h2
+                     =: map f (take n xs)
+                     =: qed
+
+-- | @n .> 0 ==> drop n (x .: xs) == drop (n - 1) xs@
+--
+-- Note that we name the lemma with the type it is proven at, using 'atProxy'. This way, a
+-- proof that needs this lemma at several different types (as 'drop_map' does) gets a distinct
+-- name for each instance.
+--
+-- >>> runTP $ drop_cons @Integer
+-- Lemma: drop_cons @Integer    Q.E.D.
+-- [Proven] drop_cons @Integer :: Ɐn ∷ Integer → Ɐx ∷ Integer → Ɐxs ∷ [Integer] → Bool
+drop_cons :: forall a. SymVal a => TP (Proof (Forall "n" Integer -> Forall "x" a -> Forall "xs" [a] -> SBool))
+drop_cons = lemma (atProxy (Proxy @a) "drop_cons")
+                  (\(Forall n) (Forall x) (Forall xs) -> n .> 0 .=> drop n (x .: xs) .== drop (n - 1) xs)
+                  []
+
+-- | @drop n (map f xs) == map f (drop n xs)@
+--
+-- >>> runTP $ drop_map @Integer @String (uninterpret "f")
+-- Lemma: drop_cons @Integer          Q.E.D.
+-- Lemma: drop_cons @[Char]           Q.E.D.
+-- Lemma: drop_map.n <= 0             Q.E.D.
+-- Inductive lemma: drop_map.n > 0
+--   Step: Base                       Q.E.D.
+--   Step: 1                          Q.E.D.
+--   Step: 2                          Q.E.D.
+--   Step: 3                          Q.E.D.
+--   Step: 4                          Q.E.D.
+--   Result:                          Q.E.D.
+-- Lemma: drop_map
+--   Step: 1                          Q.E.D.
+--   Step: 2                          Q.E.D.
+--   Step: 3                          Q.E.D.
+--   Step: 4                          Q.E.D.
+--   Result:                          Q.E.D.
+-- Functions proven terminating: sbv.map
+-- [Proven] drop_map :: Ɐn ∷ Integer → Ɐxs ∷ [Integer] → Bool
+drop_map :: forall a b. (SymVal a, SymVal b) => (SBV a -> SBV b) -> TP (Proof (Forall "n" Integer -> Forall "xs" [a] -> SBool))
+drop_map f = do
+   dcA <- drop_cons @a
+
+   -- We need 'drop_cons' at the result type as well. We can't simply use @drop_cons \@b@ here: if @b@ is
+   -- itself a sequence (as it is in the doctest above, where it is 'String'), then z3 gives up on the
+   -- resulting nested-sequence goal with an incompleteness report. So, we prove this instance with cvc5.
+   dcB <- lemmaWith cvc5 (atProxy (Proxy @b) "drop_cons")
+                    (\(Forall @"n" n) (Forall @"x" (x :: SBV b)) (Forall @"xs" xs) -> n .> 0 .=> drop n (x .: xs) .== drop (n - 1) xs)
+                    []
+
+   h1 <- lemma "drop_map.n <= 0"
+               (\(Forall @"xs" xs) (Forall @"n" n) -> n .<= 0 .=> drop n (map f xs) .== map f (drop n xs))
+               []
+
+   h2 <- induct "drop_map.n > 0"
+                (\(Forall @"xs" xs) (Forall @"n" n) -> n .> 0 .=> drop n (map f xs) .== map f (drop n xs)) $
+                \ih (x, xs) n -> [n .> 0] |- drop n (map f (x .: xs))
+                                          =: drop n (f x .: map f xs)
+                                          ?? dcB `at` (Inst @"n" n, Inst @"x" (f x), Inst @"xs" (map f xs))
+                                          =: drop (n - 1) (map f xs)
+                                          ?? ih `at` Inst @"n" (n-1)
+                                          =: map f (drop (n - 1) xs)
+                                          ?? dcA `at` (Inst @"n" n, Inst @"x" x, Inst @"xs" xs)
+                                          =: map f (drop n (x .: xs))
+                                          =: qed
+
+   -- I'm a bit surprised that z3 can't deduce the following with a simple-lemma, which is essentially a simple case-split.
+   -- But the good thing about calc is that it lets us direct the tool in precise ways that we'd like.
+   calc "drop_map"
+        (\(Forall n) (Forall xs) -> drop n (map f xs) .== map f (drop n xs)) $
+        \n xs -> [] |- let result = drop n (map f xs) .== map f (drop n xs)
+                       in result
+                       =: ite (n .<= 0) (n .<= 0 .=> result) (n .> 0 .=> result)
+                       ?? h1
+                       =: ite (n .<= 0) sTrue (n .> 0 .=> result)
+                       ?? h2
+                       =: ite (n .<= 0) sTrue sTrue
+                       =: sTrue
+                       =: qed
+
+-- | @n >= 0 ==> length (take n xs) == length xs \`min\` n@
+--
+-- >>> runTP $ length_take @Integer
+-- Lemma: length_take    Q.E.D.
+-- [Proven] length_take :: Ɐn ∷ Integer → Ɐxs ∷ [Integer] → Bool
+length_take :: forall a. SymVal a => TP (Proof (Forall "n" Integer -> Forall "xs" [a] -> SBool))
+length_take = lemma "length_take"
+                    (\(Forall n) (Forall xs) -> n .>= 0 .=> length (take n xs) .== length xs `smin` n)
+                    []
+
+-- | @n >= 0 ==> length (drop n xs) == (length xs - n) \`max\` 0@
+--
+-- >>> runTP $ length_drop @Integer
+-- Lemma: length_drop    Q.E.D.
+-- [Proven] length_drop :: Ɐn ∷ Integer → Ɐxs ∷ [Integer] → Bool
+length_drop :: forall a. SymVal a => TP (Proof (Forall "n" Integer -> Forall "xs" [a] -> SBool))
+length_drop = lemma "length_drop"
+                    (\(Forall n) (Forall xs) -> n .>= 0 .=> length (drop n xs) .== (length xs - n) `smax` 0)
+                    []
+
+-- | @length xs \<= n ==\> take n xs == xs@
+--
+-- >>> runTP $ take_all @Integer
+-- Lemma: take_all     Q.E.D.
+-- [Proven] take_all :: Ɐn ∷ Integer → Ɐxs ∷ [Integer] → Bool
+take_all :: forall a. SymVal a => TP (Proof (Forall "n" Integer -> Forall "xs" [a] -> SBool))
+take_all = lemma "take_all"
+                 (\(Forall n) (Forall xs) -> length xs .<= n .=> take n xs .== xs)
+                 []
+
+-- | @length xs \<= n ==\> drop n xs == []@
+--
+-- >>> runTP $ drop_all @Integer
+-- Lemma: drop_all     Q.E.D.
+-- [Proven] drop_all :: Ɐn ∷ Integer → Ɐxs ∷ [Integer] → Bool
+drop_all :: forall a. SymVal a => TP (Proof (Forall "n" Integer -> Forall "xs" [a] -> SBool))
+drop_all = lemma "drop_all"
+                 (\(Forall n) (Forall xs) -> length xs .<= n .=> drop n xs .== [])
+                 []
+
+-- | @take n (xs ++ ys) == (take n xs ++ take (n - length xs) ys)@
+--
+-- >>> runTP $ take_append @Integer
+-- Lemma: take_append    Q.E.D.
+-- [Proven] take_append :: Ɐn ∷ Integer → Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool
+take_append :: forall a. SymVal a => TP (Proof (Forall "n" Integer -> Forall "xs" [a] -> Forall "ys" [a] -> SBool))
+take_append = lemmaWith cvc5 "take_append"
+                        (\(Forall n) (Forall xs) (Forall ys) -> take n (xs ++ ys) .== take n xs ++ take (n - length xs) ys)
+                        []
+
+-- | @drop n (xs ++ ys) == drop n xs ++ drop (n - length xs) ys@
+--
+-- NB. As of Feb 2025, z3 struggles to prove this, but cvc5 gets it out-of-the-box.
+--
+-- >>> runTP $ drop_append @Integer
+-- Lemma: drop_append    Q.E.D.
+-- [Proven] drop_append :: Ɐn ∷ Integer → Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool
+drop_append :: forall a. SymVal a => TP (Proof (Forall "n" Integer -> Forall "xs" [a] -> Forall "ys" [a] -> SBool))
+drop_append = lemmaWith cvc5 "drop_append"
+                        (\(Forall n) (Forall xs) (Forall ys) -> drop n (xs ++ ys) .== drop n xs ++ drop (n - length xs) ys)
+                        []
+
+-- | @length xs == length ys ==> map fst (zip xs ys) = xs@
+--
+-- >>> runTP $ map_fst_zip @Integer @Integer
+-- Inductive lemma: map_fst_zip
+--   Step: Base                    Q.E.D.
+--   Step: 1                       Q.E.D.
+--   Step: 2                       Q.E.D.
+--   Step: 3                       Q.E.D.
+--   Step: 4                       Q.E.D.
+--   Result:                       Q.E.D.
+-- Functions proven terminating: sbv.map, sbv.zip
+-- [Proven] map_fst_zip :: (Ɐxs ∷ [Integer], Ɐys ∷ [Integer]) → Bool
+map_fst_zip :: forall a b. (SymVal a, SymVal b) => TP (Proof ((Forall "xs" [a], Forall "ys" [b]) -> SBool))
+map_fst_zip = induct "map_fst_zip"
+                     (\(Forall xs, Forall ys) -> length xs .== length ys .=> map fst (zip xs ys) .== xs) $
+                     \ih (x, xs, y, ys) -> [length (x .: xs) .== length (y .: ys)]
+                                        |- map fst (zip (x .: xs) (y .: ys))
+                                        =: map fst (tuple (x, y) .: zip xs ys)
+                                        =: fst (tuple (x, y)) .: map fst (zip xs ys)
+                                        =: x .: map fst (zip xs ys)
+                                        ?? ih
+                                        =: x .: xs
+                                        =: qed
+
+-- | @length xs == length ys ==> map snd (zip xs ys) = xs@
+--
+-- >>> runTP $ map_snd_zip @Integer @Integer
+-- Inductive lemma: map_snd_zip
+--   Step: Base                    Q.E.D.
+--   Step: 1                       Q.E.D.
+--   Step: 2                       Q.E.D.
+--   Step: 3                       Q.E.D.
+--   Step: 4                       Q.E.D.
+--   Result:                       Q.E.D.
+-- Functions proven terminating: sbv.map, sbv.zip
+-- [Proven] map_snd_zip :: (Ɐxs ∷ [Integer], Ɐys ∷ [Integer]) → Bool
+map_snd_zip :: forall a b. (SymVal a, SymVal b) => TP (Proof ((Forall "xs" [a], Forall "ys" [b]) -> SBool))
+map_snd_zip = induct "map_snd_zip"
+                     (\(Forall xs, Forall ys) -> length xs .== length ys .=> map snd (zip xs ys) .== ys) $
+                     \ih (x, xs, y, ys) -> [length (x .: xs) .== length (y .: ys)]
+                                        |- map snd (zip (x .: xs) (y .: ys))
+                                        =: map snd (tuple (x, y) .: zip xs ys)
+                                        =: snd (tuple (x, y)) .: map snd (zip xs ys)
+                                        =: y .: map snd (zip xs ys)
+                                        ?? ih
+                                        =: y .: ys
+                                        =: qed
+
+-- | @map fst (zip xs ys) == take (min (length xs) (length ys)) xs@
+--
+-- >>> runTP $ map_fst_zip_take @Integer @Integer
+-- Lemma: take_cons                     Q.E.D.
+-- Inductive lemma: map_fst_zip_take
+--   Step: Base                         Q.E.D.
+--   Step: 1                            Q.E.D.
+--   Step: 2                            Q.E.D.
+--   Step: 3                            Q.E.D.
+--   Step: 4                            Q.E.D.
+--   Step: 5                            Q.E.D.
+--   Result:                            Q.E.D.
+-- Functions proven terminating: sbv.map, sbv.zip
+-- [Proven] map_fst_zip_take :: (Ɐxs ∷ [Integer], Ɐys ∷ [Integer]) → Bool
+map_fst_zip_take :: forall a b. (SymVal a, SymVal b) => TP (Proof ((Forall "xs" [a], Forall "ys" [b]) -> SBool))
+map_fst_zip_take = do
+   tc <- take_cons @a
+
+   induct "map_fst_zip_take"
+          (\(Forall xs, Forall ys) -> map fst (zip xs ys) .== take (length xs `smin` length ys) xs) $
+          \ih (x, xs, y, ys) -> [] |- map fst (zip (x .: xs) (y .: ys))
+                                   =: map fst (tuple (x, y) .: zip xs ys)
+                                   =: x .: map fst (zip xs ys)
+                                   ?? ih
+                                   =: x .: take (length xs `smin` length ys) xs
+                                   ?? tc
+                                   =: take (1 + (length xs `smin` length ys)) (x .: xs)
+                                   =: take (length (x .: xs) `smin` length (y .: ys)) (x .: xs)
+                                   =: qed
+
+-- | @map snd (zip xs ys) == take (min (length xs) (length ys)) xs@
+--
+-- >>> runTP $ map_snd_zip_take @Integer @Integer
+-- Lemma: take_cons                     Q.E.D.
+-- Inductive lemma: map_snd_zip_take
+--   Step: Base                         Q.E.D.
+--   Step: 1                            Q.E.D.
+--   Step: 2                            Q.E.D.
+--   Step: 3                            Q.E.D.
+--   Step: 4                            Q.E.D.
+--   Step: 5                            Q.E.D.
+--   Result:                            Q.E.D.
+-- Functions proven terminating: sbv.map, sbv.zip
+-- [Proven] map_snd_zip_take :: (Ɐxs ∷ [Integer], Ɐys ∷ [Integer]) → Bool
+map_snd_zip_take :: forall a b. (SymVal a, SymVal b) => TP (Proof ((Forall "xs" [a], Forall "ys" [b]) -> SBool))
+map_snd_zip_take = do
+   tc <- take_cons @a
+
+   induct "map_snd_zip_take"
+          (\(Forall xs, Forall ys) -> map snd (zip xs ys) .== take (length xs `smin` length ys) ys) $
+          \ih (x, xs, y, ys) -> [] |- map snd (zip (x .: xs) (y .: ys))
+                                   =: map snd (tuple (x, y) .: zip xs ys)
+                                   =: y .: map snd (zip xs ys)
+                                   ?? ih
+                                   =: y .: take (length xs `smin` length ys) ys
+                                   ?? tc
+                                   =: take (1 + (length xs `smin` length ys)) (y .: ys)
+                                   =: take (length (x .: xs) `smin` length (y .: ys)) (y .: ys)
+                                   =: qed
+
+-- | Count the number of occurrences of an element in a list
+count :: SymVal a => SBV a -> SList a -> SInteger
+count = smtFunction "count"
+      $ \e l -> [sCase| l of
+                   []               -> 0
+                   x : xs | e .== x -> 1 + count e xs
+                          | True    -> count e xs
+                |]
+
+-- | One-step unfolding of 'count' on a cons cell. The solver can expand the
+-- @define-fun-rec@ but struggles to fold it back, so we provide this as a reusable hint.
+--
+-- >>> runTP $ countOneStep @Integer
+-- Lemma: countOneStep    Q.E.D.
+-- Functions proven terminating: count
+-- [Proven] countOneStep :: Ɐe ∷ Integer → Ɐx ∷ Integer → Ɐxs ∷ [Integer] → Bool
+countOneStep :: forall a. SymVal a => TP (Proof (Forall "e" a -> Forall "x" a -> Forall "xs" [a] -> SBool))
+countOneStep = lemma "countOneStep"
+   (\(Forall @"e" e) (Forall @"x" x) (Forall @"xs" (xs :: SList a)) ->
+      count e (x .: xs) .== ite (e .== x) (1 + count e xs) (count e xs))
+   []
+
+-- | Interleave the elements of two lists. If one ends, we take the rest from the other.
+interleave :: SymVal a => SList a -> SList a -> SList a
+interleave = smtFunction "interleave"
+           $ \xs ys -> [sCase| xs of
+                           []     -> ys
+                           a : as -> a .: interleave ys as
+                        |]
+
+-- | Prove that interleave preserves total length.
+--
+-- The induction here is on the total length of the lists, and hence
+-- we use the generalized induction principle. We have:
+--
+-- >>> runTP $ interleaveLen @Integer
+-- Inductive lemma (strong): interleaveLen
+--   Step: Measure is non-negative            Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1                              Q.E.D.
+--     Step: 1.2.1                            Q.E.D.
+--     Step: 1.2.2                            Q.E.D.
+--     Step: 1.2.3                            Q.E.D.
+--     Step: 1.Completeness                   Q.E.D.
+--   Result:                                  Q.E.D.
+-- Functions proven terminating: interleave
+-- [Proven] interleaveLen :: Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool
+interleaveLen :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> Forall "ys" [a] -> SBool))
+interleaveLen = sInduct "interleaveLen"
+                        (\(Forall xs) (Forall ys) -> length xs + length ys .== length (interleave xs ys))
+                        (\xs ys -> length xs + length ys, []) $
+                        \ih xs ys -> [] |- length xs + length ys .== length (interleave xs ys)
+                                        =: [pCase| xs of
+                                              []             -> trivial
+                                              whole@(_ : as) ->
+                                                   length whole + length ys .== length (interleave whole ys)
+                                                =: 1 + length as + length ys .== 1 + length (interleave ys as)
+                                                ?? ih `at` (Inst @"xs" ys, Inst @"ys" as)
+                                                =: sTrue
+                                                =: qed
+                                           |]
+
+-- | Uninterleave the elements of two lists. We roughly split it into two, of alternating elements.
+uninterleave :: SymVal a => SList a -> STuple [a] [a]
+uninterleave lst = uninterleaveGen lst (tuple ([], []))
+
+-- | Generalized form of uninterleave with the auxiliary lists made explicit.
+uninterleaveGen :: SymVal a => SList a -> STuple [a] [a] -> STuple [a] [a]
+uninterleaveGen = smtFunction "uninterleave"
+                $ \xs alts -> let (es, os) = untuple alts
+                              in [sCase| xs of
+                                    []     -> tuple (reverse es, reverse os)
+                                    x : ys -> uninterleaveGen ys (tuple (os, x .: es))
+                                 |]
+
+-- | The functions 'uninterleave' and 'interleave' are inverses so long as the inputs are of the same length. (The equality
+-- would even hold if the first argument has one extra element, but we keep things simple here.)
+--
+-- We have:
+--
+-- >>> runTP $ interleaveRoundTrip @Integer
+-- Lemma: revCons                            Q.E.D.
+-- Inductive lemma (strong): roundTripGen
+--   Step: Measure is non-negative           Q.E.D.
+--   Step: 1 (3 way case split)
+--     Step: 1.1                             Q.E.D.
+--     Step: 1.2                             Q.E.D.
+--     Step: 1.3.1                           Q.E.D.
+--     Step: 1.3.2                           Q.E.D.
+--     Step: 1.3.3                           Q.E.D.
+--     Step: 1.3.4                           Q.E.D.
+--     Step: 1.3.5                           Q.E.D.
+--     Step: 1.3.6                           Q.E.D.
+--     Step: 1.3.7                           Q.E.D.
+--     Step: 1.3.8                           Q.E.D.
+--     Step: 1.Completeness                  Q.E.D.
+--   Result:                                 Q.E.D.
+-- Lemma: interleaveRoundTrip
+--   Step: 1                                 Q.E.D.
+--   Step: 2                                 Q.E.D.
+--   Result:                                 Q.E.D.
+-- Functions proven terminating: interleave, sbv.reverse, uninterleave
+-- [Proven] interleaveRoundTrip :: Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool
+interleaveRoundTrip :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> Forall "ys" [a] -> SBool))
+interleaveRoundTrip = do
+
+   revHelper <- lemma "revCons" (\(Forall a) (Forall as) (Forall bs) -> reverse @a (a .: as) ++ bs .== reverse as ++ (a .: bs)) []
+
+   -- Generalize the theorem first to take the helper lists explicitly
+   roundTripGen <- sInductWith cvc5
+         "roundTripGen"
+         (\(Forall @"xs" xs) (Forall @"ys" ys) (Forall @"alts" alts) ->
+               length xs .== length ys .=> let (es, os) = untuple alts
+                                           in uninterleaveGen (interleave xs ys) alts .== tuple (reverse es ++ xs, reverse os ++ ys))
+         (\xs ys _alts -> length xs + length ys, []) $
+         \ih xs ys alts -> [length xs .== length ys]
+                        |- let (es, os) = untuple alts
+                        in uninterleaveGen (interleave xs ys) alts
+                        =: [pCase| tuple (xs, ys) of
+                              ([], _) -> trivial
+                              (_, []) -> trivial
+                              (ll@(a : as), rr@(b : bs)) ->
+                                   uninterleaveGen (interleave ll rr) alts
+                                =: uninterleaveGen (a .: interleave rr as) alts
+                                =: uninterleaveGen (a .: b .: interleave as bs) alts
+                                =: uninterleaveGen (interleave as bs) (tuple (a .: es, b .: os))
+                                ?? ih `at` (Inst @"xs" as, Inst @"ys" bs, Inst @"alts" (tuple (a .: es, b .: os)))
+                                =: tuple (reverse (a .: es) ++ as, reverse (b .: os) ++ bs)
+                                ?? revHelper `at` (Inst @"a" a, Inst @"as" es, Inst @"bs" as)
+                                =: tuple (reverse es ++ ll, reverse (b .: os) ++ bs)
+                                ?? revHelper `at` (Inst @"a" b, Inst @"as" os, Inst @"bs" bs)
+                                =: tuple (reverse es ++ ll, reverse os ++ rr)
+                                =: tuple (reverse es ++ xs, reverse os ++ ys)
+                                =: qed
+                           |]
+
+   -- Round-trip theorem:
+   calc "interleaveRoundTrip"
+           (\(Forall xs) (Forall ys) -> length xs .== length ys .=> uninterleave (interleave xs ys) .== tuple (xs, ys)) $
+           \xs ys -> [length xs .== length ys]
+                  |- uninterleave (interleave xs ys)
+                  =: uninterleaveGen (interleave xs ys) (tuple ([], []))
+                  ?? roundTripGen `at` (Inst @"xs" xs, Inst @"ys" ys, Inst @"alts" (tuple ([], [])))
+                  =: tuple (reverse [] ++ xs, reverse [] ++ ys)
+                  =: qed
+
+-- | @count e (xs ++ ys) == count e xs + count e ys@
+--
+-- >>> runTP $ countAppend @Integer
+-- Inductive lemma: countAppend
+--   Step: Base                    Q.E.D.
+--   Step: 1                       Q.E.D.
+--   Step: 2 (unfold count)        Q.E.D.
+--   Step: 3                       Q.E.D.
+--   Step: 4 (simplify)            Q.E.D.
+--   Result:                       Q.E.D.
+-- Functions proven terminating: count
+-- [Proven] countAppend :: Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Ɐe ∷ Integer → Bool
+countAppend :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> Forall "ys" [a] -> Forall "e" a -> SBool))
+countAppend =
+   induct "countAppend"
+          (\(Forall xs) (Forall ys) (Forall e) -> count e (xs ++ ys) .== count e xs + count e ys) $
+          \ih (x, xs) ys e -> [] |- count e ((x .: xs) ++ ys)
+                                 =: count e (x .: (xs ++ ys))
+                                 ?? "unfold count"
+                                 =: (let r = count e (xs ++ ys) in ite (e .== x) (1+r) r)
+                                 ?? ih `at` (Inst @"ys" ys, Inst @"e" e)
+                                 =: (let r = count e xs + count e ys in ite (e .== x) (1+r) r)
+                                 ?? "simplify"
+                                 =: count e (x .: xs) + count e ys
+                                 =: qed
+
+-- | @count e (take n xs) + count e (drop n xs) == count e xs@
+--
+-- >>> runTP $ takeDropCount @Integer
+-- Inductive lemma: countAppend
+--   Step: Base                    Q.E.D.
+--   Step: 1                       Q.E.D.
+--   Step: 2 (unfold count)        Q.E.D.
+--   Step: 3                       Q.E.D.
+--   Step: 4 (simplify)            Q.E.D.
+--   Result:                       Q.E.D.
+-- Lemma: take_drop                Q.E.D.
+-- Lemma: takeDropCount
+--   Step: 1                       Q.E.D.
+--   Step: 2                       Q.E.D.
+--   Result:                       Q.E.D.
+-- Functions proven terminating: count
+-- [Proven] takeDropCount :: Ɐxs ∷ [Integer] → Ɐn ∷ Integer → Ɐe ∷ Integer → Bool
+takeDropCount :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> Forall "n" Integer -> Forall "e" a -> SBool))
+takeDropCount = do
+       capp     <- countAppend @a
+       takeDrop <- take_drop   @a
+
+       calc "takeDropCount"
+            (\(Forall xs) (Forall n) (Forall e) -> count e (take n xs) + count e (drop n xs) .== count e xs) $
+            \xs n e -> [] |- count e (take n xs) + count e (drop n xs)
+                          ?? capp `at` (Inst @"xs" (take n xs), Inst @"ys" (drop n xs), Inst @"e" e)
+                          =: count e (take n xs ++ drop n xs)
+                          ?? takeDrop
+                          =: count e xs
+                          =: qed
+
+-- | @count e xs >= 0@
+--
+-- >>> runTP $ countNonNeg @Integer
+-- Inductive lemma: countNonNeg
+--   Step: Base                    Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1.1                 Q.E.D.
+--     Step: 1.1.2                 Q.E.D.
+--     Step: 1.2.1                 Q.E.D.
+--     Step: 1.2.2                 Q.E.D.
+--     Step: 1.Completeness        Q.E.D.
+--   Result:                       Q.E.D.
+-- Functions proven terminating: count
+-- [Proven] countNonNeg :: Ɐxs ∷ [Integer] → Ɐe ∷ Integer → Bool
+countNonNeg :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> Forall "e" a -> SBool))
+countNonNeg =
+   induct "countNonNeg"
+          (\(Forall xs) (Forall e) -> count e xs .>= 0) $
+          \ih (x, xs) e -> [] |- count e (x .: xs) .>= 0
+                              =: cases [ e .== x ==> 1 + count e xs .>= 0
+                                                  ?? ih
+                                                  =: sTrue
+                                                  =: qed
+                                       , e ./= x ==> count e xs .>= 0
+                                                  ?? ih
+                                                  =: sTrue
+                                                  =: qed
+                                       ]
+
+-- | @e \`elem\` xs ==> count e xs .> 0@
+--
+-- >>> runTP $ countElem @Integer
+-- Inductive lemma: countNonNeg
+--   Step: Base                    Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1.1                 Q.E.D.
+--     Step: 1.1.2                 Q.E.D.
+--     Step: 1.2.1                 Q.E.D.
+--     Step: 1.2.2                 Q.E.D.
+--     Step: 1.Completeness        Q.E.D.
+--   Result:                       Q.E.D.
+-- Inductive lemma: countElem
+--   Step: Base                    Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1.1                 Q.E.D.
+--     Step: 1.1.2                 Q.E.D.
+--     Step: 1.2.1                 Q.E.D.
+--     Step: 1.2.2                 Q.E.D.
+--     Step: 1.Completeness        Q.E.D.
+--   Result:                       Q.E.D.
+-- Functions proven terminating: count
+-- [Proven] countElem :: Ɐxs ∷ [Integer] → Ɐe ∷ Integer → Bool
+countElem :: forall a. (Eq a, SymVal a) => TP (Proof (Forall "xs" [a] -> Forall "e" a -> SBool))
+countElem = do
+
+    cnn <- countNonNeg @a
+
+    induct "countElem"
+           (\(Forall xs) (Forall e) -> e `elem` xs .=> count e xs .> 0) $
+           \ih (x, xs) e -> [e `elem` (x .: xs)]
+                         |- count e (x .: xs) .> 0
+                         =: cases [ e .== x ==> 1 + count e xs .> 0
+                                             ?? cnn
+                                             =: sTrue
+                                             =: qed
+                                  , e ./= x ==> count e xs .> 0
+                                             ?? ih
+                                             =: sTrue
+                                             =: qed
+                                  ]
+
+-- | @count e xs .> 0 .=> e \`elem\` xs@
+--
+-- >>> runTP $ elemCount @Integer
+-- Inductive lemma: elemCount
+--   Step: Base                  Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1                 Q.E.D.
+--     Step: 1.2.1               Q.E.D.
+--     Step: 1.2.2               Q.E.D.
+--     Step: 1.Completeness      Q.E.D.
+--   Result:                     Q.E.D.
+-- Functions proven terminating: count
+-- [Proven] elemCount :: Ɐxs ∷ [Integer] → Ɐe ∷ Integer → Bool
+elemCount :: forall a. (Eq a, SymVal a) => TP (Proof (Forall "xs" [a] -> Forall "e" a -> SBool))
+elemCount =
+    induct "elemCount"
+           (\(Forall xs) (Forall e) -> count e xs .> 0 .=> e `elem` xs) $
+           \ih (x, xs) e -> [count e xs .> 0]
+                         |- e `elem` (x .: xs)
+                         =: cases [ e .== x ==> trivial
+                                  , e ./= x ==> e `elem` xs
+                                             ?? ih
+                                             =: sTrue
+                                             =: qed
+                                  ]
+
+{- HLint ignore revRev         "Redundant reverse" -}
+{- HLint ignore allAny         "Use and"           -}
+{- HLint ignore bookKeeping    "Fuse foldr/map"    -}
+{- HLint ignore foldrMapFusion "Fuse foldr/map"    -}
+{- HLint ignore filterConcat   "Move filter"       -}
+{- HLint ignore module         "Use camelCase"     -}
+{- HLint ignore module         "Use first"         -}
+{- HLint ignore module         "Use second"        -}
+{- HLint ignore module         "Use zipWith"       -}
+{- HLint ignore mapCompose     "Use map once"      -}
+{- HLint ignore tailsAppend    "Avoid lambda"      -}
+{- HLint ignore tailsAppend    "Use :"             -}
+{- HLint ignore mapReverse     "Evaluate"          -}
+{- HLint ignore mapConcat      "Use concatMap"     -}
+{- HLint ignore takeDropWhile  "Evaluate"          -}
diff --git a/Documentation/SBV/Examples/TP/Majority.hs b/Documentation/SBV/Examples/TP/Majority.hs
--- a/Documentation/SBV/Examples/TP/Majority.hs
+++ b/Documentation/SBV/Examples/TP/Majority.hs
@@ -10,8 +10,8 @@
 -- closely, which you can find at <https://github.com/acl2/acl2/blob/master/books/demos/majority-vote.lisp>.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE CPP                 #-}
 {-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE QuasiQuotes         #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeAbstractions    #-}
 {-# LANGUAGE TypeApplications    #-}
@@ -26,7 +26,7 @@
 import Data.SBV.List
 
 import Data.SBV.TP
-import qualified Data.SBV.TP.List as TP
+import qualified Documentation.SBV.Examples.TP.Lists as TP
 
 -- * Calculating majority
 
@@ -35,11 +35,11 @@
 -- majority element, then the result is irrelevant.
 majority :: SymVal a => SBV a -> SInteger -> SList a -> SBV a
 majority = smtFunction "majority"
-                    $ \c i lst ->  ite (null lst) c
-                                       (let (x, xs) = uncons lst
-                                        in ite (i .== 0)
-                                                (majority x 1 xs)
-                                                (majority c (i + ite (c .== x) 1 (-1)) xs))
+                    $ \c i lst -> [sCase| lst of
+                                     []               -> c
+                                     x : xs | i .== 0 -> majority x 1 xs
+                                            | True    -> majority c (i + ite (c .== x) 1 (-1)) xs
+                                  |]
 
 -- | We can now define mjrty, which simply feeds the majority function with an arbitrary element of the domain.
 -- By the definition of 'majority' above, this arbitrary element will be returned if the given list is empty.
@@ -72,25 +72,26 @@
 --
 -- >>> correctness @Integer
 -- Inductive lemma: majorityGeneral
---   Step: Base                            Q.E.D.
+--   Step: Base                        Q.E.D.
 --   Step: 1 (2 way case split)
---     Step: 1.1.1                         Q.E.D.
---     Step: 1.1.2                         Q.E.D.
---     Step: 1.2.1                         Q.E.D.
+--     Step: 1.1.1                     Q.E.D.
+--     Step: 1.1.2                     Q.E.D.
+--     Step: 1.2.1                     Q.E.D.
 --     Step: 1.2.2 (2 way case split)
---       Step: 1.2.2.1.1                   Q.E.D.
---       Step: 1.2.2.1.2                   Q.E.D.
---       Step: 1.2.2.2.1                   Q.E.D.
---       Step: 1.2.2.2.2                   Q.E.D.
---       Step: 1.2.2.Completeness          Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: majority                         Q.E.D.
--- Lemma: ifExistsFound                    Q.E.D.
--- Lemma: ifNoMajority                     Q.E.D.
+--       Step: 1.2.2.1.1               Q.E.D.
+--       Step: 1.2.2.1.2               Q.E.D.
+--       Step: 1.2.2.2.1               Q.E.D.
+--       Step: 1.2.2.2.2               Q.E.D.
+--       Step: 1.2.2.Completeness      Q.E.D.
+--     Step: 1.Completeness            Q.E.D.
+--   Result:                           Q.E.D.
+-- Lemma: majority                     Q.E.D.
+-- Lemma: ifExistsFound                Q.E.D.
+-- Lemma: ifNoMajority                 Q.E.D.
 -- Lemma: uniqueness
---   Step: 1                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: 1                           Q.E.D.
+--   Result:                           Q.E.D.
+-- Functions proven terminating: count, majority
 -- ([Proven] majority :: Ɐc ∷ Integer → Ɐxs ∷ [Integer] → Bool,[Proven] ifExistsFound :: Ɐc ∷ Integer → Ɐxs ∷ [Integer] → Bool,[Proven] ifNoMajority :: Ɐc ∷ Integer → Ɐxs ∷ [Integer] → Bool,[Proven] uniqueness :: Ɐm1 ∷ Integer → Ɐm2 ∷ Integer → Ɐxs ∷ [Integer] → Bool)
 correctness :: forall a. SymVal a
             => IO ( Proof (Forall "c" a -> Forall "xs" [a] -> SBool)                    -- If majority exists, the calculated value is majority
diff --git a/Documentation/SBV/Examples/TP/McCarthy91.hs b/Documentation/SBV/Examples/TP/McCarthy91.hs
--- a/Documentation/SBV/Examples/TP/McCarthy91.hs
+++ b/Documentation/SBV/Examples/TP/McCarthy91.hs
@@ -9,10 +9,10 @@
 -- Proving McCarthy's 91 function correct.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DataKinds           #-}
-{-# LANGUAGE TypeAbstractions    #-}
-{-# LANGUAGE TypeApplications    #-}
-{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE DataKinds        #-}
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE TypeAbstractions #-}
+{-# LANGUAGE TypeApplications #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -23,11 +23,22 @@
 
 -- * Definitions
 
--- | Nested recursive definition of McCarthy's function.
+-- | Nested recursive definition of McCarthy's function. We use 'smtFunctionWithContract' because
+-- the nested recursion @mcCarthy91 (mcCarthy91 (n + 11))@ requires knowing what the inner call returns
+-- in order to verify that the outer call's measure decreases. The contract states that for inputs @≤ 100@,
+-- the result is @91@. Note that the contract itself is verified as part of the measure check: SBV proves
+-- both measure decrease and the contract simultaneously via well-founded induction.
 mcCarthy91 :: SInteger -> SInteger
-mcCarthy91 = smtFunction "mcCarthy91" $ \n -> ite (n .> 100)
-                                                  (n - 10)
-                                                  (mcCarthy91 (mcCarthy91 (n + 11)))
+mcCarthy91 = smtFunctionWithContract "mcCarthy91"
+               ( \n -> 0 `smax` (101 - n)
+               , \n r -> n .<= 100 .=> r .== 91
+               , []
+               )
+           $ \n -> [sCase| n of
+                      _ | n .> 100 -> n - 10
+                      _            -> mcCarthy91 (mcCarthy91 (n + 11))
+                   |]
+
 -- | Specification for McCarthy's function.
 spec91 :: SInteger -> SInteger
 spec91 n = ite (n .> 100) (n - 10) 91
@@ -38,20 +49,21 @@
 -- and strong induction. We have:
 --
 -- >>> correctness
--- Lemma: case1                            Q.E.D.
--- Lemma: case2                            Q.E.D.
+-- Lemma: case1                       Q.E.D.
+-- Lemma: case2                       Q.E.D.
 -- Inductive lemma (strong): case3
---   Step: Measure is non-negative         Q.E.D.
---   Step: 1 (unfold)                      Q.E.D.
---   Step: 2                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: Measure is non-negative    Q.E.D.
+--   Step: 1 (unfold)                 Q.E.D.
+--   Step: 2                          Q.E.D.
+--   Result:                          Q.E.D.
 -- Lemma: mcCarthy91
 --   Step: 1 (3 way case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2                           Q.E.D.
---     Step: 1.3                           Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
+--     Step: 1.1                      Q.E.D.
+--     Step: 1.2                      Q.E.D.
+--     Step: 1.3                      Q.E.D.
+--     Step: 1.Completeness           Q.E.D.
+--   Result:                          Q.E.D.
+-- Functions proven terminating: mcCarthy91
 -- [Proven] mcCarthy91 :: Ɐn ∷ Integer → Bool
 correctness :: IO (Proof (Forall "n" Integer -> SBool))
 correctness = runTP $ do
@@ -65,7 +77,7 @@
    -- Case 3. When @n < 90@. The crucial point here is the measure, which makes sure 101 < 100 < 99 < ...
    case3 <- sInduct "case3"
                     (\(Forall n) -> n .< 90 .=> mcCarthy91 n .== spec91 n)
-                    (\n -> abs (101 - n)) $
+                    (\n -> abs (101 - n), []) $
                     \ih n -> [n .< 90] |- mcCarthy91 n
                                        ?? "unfold"
                                        =: mcCarthy91 (mcCarthy91 (n + 11))
diff --git a/Documentation/SBV/Examples/TP/MergeSort.hs b/Documentation/SBV/Examples/TP/MergeSort.hs
--- a/Documentation/SBV/Examples/TP/MergeSort.hs
+++ b/Documentation/SBV/Examples/TP/MergeSort.hs
@@ -13,9 +13,9 @@
 {-# LANGUAGE DataKinds           #-}
 {-# LANGUAGE FlexibleContexts    #-}
 {-# LANGUAGE OverloadedLists     #-}
-{-# LANGUAGE TypeAbstractions    #-}
-{-# LANGUAGE TypeApplications    #-}
+{-# LANGUAGE QuasiQuotes         #-}
 {-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications    #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -27,8 +27,8 @@
 import Data.SBV.List
 import Data.SBV.Tuple
 import Data.SBV.TP
-import qualified Data.SBV.TP.List as TP
 
+import qualified Documentation.SBV.Examples.TP.Lists       as TP
 import qualified Documentation.SBV.Examples.TP.SortHelpers as SH
 
 #ifdef DOCTEST
@@ -40,17 +40,24 @@
 
 -- | Merge two already sorted lists into another
 merge :: (OrdSymbolic (SBV a), SymVal a) => SList a -> SList a -> SList a
-merge = smtFunction "merge" $ \l r -> ite (null l) r
-                                    $ ite (null r) l
-                                    $ let (a, as) = uncons l
-                                          (b, bs) = uncons r
-                                      in ite (a .<= b) (a .: merge as r) (b .: merge l bs)
+merge = smtFunction "merge"
+      $ \l r -> [sCase| tuple (l, r) of
+                   ([], _) -> r
+                   (_, []) -> l
 
+                   (ll@(a : as), rr@(b : bs)) | a .<= b -> a .: merge as rr
+                                              | True    -> b .: merge ll bs
+                |]
+
 -- | Merge sort, using 'merge' above to successively sort halved input
 mergeSort :: (OrdSymbolic (SBV a), SymVal a) => SList a -> SList a
-mergeSort = smtFunction "mergeSort" $ \l -> ite (length l .<= 1) l
-                                              $ let (h1, h2) = splitAt (length l `sEDiv` 2) l
-                                                in merge (mergeSort h1) (mergeSort h2)
+mergeSort = smtFunction "mergeSort"
+          $ \l -> [sCase| l of
+                     []  -> l
+                     [_] -> l
+                     _   -> let (h1, h2) = splitAt (length l `sEDiv` 2) l
+                            in merge (mergeSort h1) (mergeSort h2)
+                  |]
 
 -- * Correctness proof
 
@@ -59,71 +66,78 @@
 -- We have:
 --
 -- >>> correctness @Integer
--- Lemma: nonDecrInsert                                        Q.E.D.
+-- Lemma: nonDecrInsert                                      Q.E.D.
 -- Inductive lemma: countAppend
---   Step: Base                                                Q.E.D.
---   Step: 1                                                   Q.E.D.
---   Step: 2 (unfold count)                                    Q.E.D.
---   Step: 3                                                   Q.E.D.
---   Step: 4 (simplify)                                        Q.E.D.
---   Result:                                                   Q.E.D.
--- Lemma: take_drop                                            Q.E.D.
+--   Step: Base                                              Q.E.D.
+--   Step: 1                                                 Q.E.D.
+--   Step: 2 (unfold count)                                  Q.E.D.
+--   Step: 3                                                 Q.E.D.
+--   Step: 4 (simplify)                                      Q.E.D.
+--   Result:                                                 Q.E.D.
+-- Lemma: take_drop                                          Q.E.D.
 -- Lemma: takeDropCount
---   Step: 1                                                   Q.E.D.
---   Step: 2                                                   Q.E.D.
---   Result:                                                   Q.E.D.
+--   Step: 1                                                 Q.E.D.
+--   Step: 2                                                 Q.E.D.
+--   Result:                                                 Q.E.D.
+-- Lemma: countOneStep                                       Q.E.D.
+-- Lemma: mergeHead                                          Q.E.D.
+-- Lemma: mergeUnfold                                        Q.E.D.
 -- Inductive lemma (strong): mergeKeepsSort
---   Step: Measure is non-negative                             Q.E.D.
---   Step: 1 (4 way full case split)
---     Step: 1.1                                               Q.E.D.
---     Step: 1.2                                               Q.E.D.
---     Step: 1.3                                               Q.E.D.
---     Step: 1.4.1 (unfold merge)                              Q.E.D.
---     Step: 1.4.2 (2 way case split)
---       Step: 1.4.2.1.1 (case split)                          Q.E.D.
---       Step: 1.4.2.1.2                                       Q.E.D.
---       Step: 1.4.2.2.1 (case split)                          Q.E.D.
---       Step: 1.4.2.2.2                                       Q.E.D.
---       Step: 1.4.2.Completeness                              Q.E.D.
---   Result:                                                   Q.E.D.
+--   Step: Measure is non-negative                           Q.E.D.
+--   Step: 1 (3 way case split)
+--     Step: 1.1                                             Q.E.D.
+--     Step: 1.2                                             Q.E.D.
+--     Step: 1.3 (2 way case split)
+--       Step: 1.3.1.1 (2 way case split)                    Q.E.D.
+--       Step: 1.3.1.2                                       Q.E.D.
+--       Step: 1.3.1.3                                       Q.E.D.
+--       Step: 1.3.2.1 (2 way case split)                    Q.E.D.
+--       Step: 1.3.2.2                                       Q.E.D.
+--       Step: 1.3.2.3                                       Q.E.D.
+--       Step: 1.3.Completeness                              Q.E.D.
+--     Step: 1.Completeness                                  Q.E.D.
+--   Result:                                                 Q.E.D.
 -- Inductive lemma (strong): sortNonDecreasing
---   Step: Measure is non-negative                             Q.E.D.
---   Step: 1 (2 way full case split)
---     Step: 1.1                                               Q.E.D.
---     Step: 1.2.1 (unfold)                                    Q.E.D.
---     Step: 1.2.2 (push nonDecreasing down)                   Q.E.D.
---     Step: 1.2.3                                             Q.E.D.
---     Step: 1.2.4                                             Q.E.D.
---   Result:                                                   Q.E.D.
+--   Step: Measure is non-negative                           Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1                                             Q.E.D.
+--     Step: 1.2.1 (unfold)                                  Q.E.D.
+--     Step: 1.2.2 (push nonDecreasing down)                 Q.E.D.
+--     Step: 1.2.3                                           Q.E.D.
+--     Step: 1.2.4                                           Q.E.D.
+--     Step: 1.Completeness                                  Q.E.D.
+--   Result:                                                 Q.E.D.
 -- Inductive lemma (strong): mergeCount
---   Step: Measure is non-negative                             Q.E.D.
---   Step: 1 (4 way full case split)
---     Step: 1.1                                               Q.E.D.
---     Step: 1.2                                               Q.E.D.
---     Step: 1.3                                               Q.E.D.
---     Step: 1.4.1 (unfold merge)                              Q.E.D.
---     Step: 1.4.2 (push count inside)                         Q.E.D.
---     Step: 1.4.3 (unfold count, twice)                       Q.E.D.
---     Step: 1.4.4                                             Q.E.D.
---     Step: 1.4.5                                             Q.E.D.
---     Step: 1.4.6 (unfold count in reverse, twice)            Q.E.D.
---     Step: 1.4.7 (simplify)                                  Q.E.D.
---   Result:                                                   Q.E.D.
+--   Step: Measure is non-negative                           Q.E.D.
+--   Step: 1 (3 way case split)
+--     Step: 1.1                                             Q.E.D.
+--     Step: 1.2                                             Q.E.D.
+--     Step: 1.3.1 (unfold merge)                            Q.E.D.
+--     Step: 1.3.2 (push count inside)                       Q.E.D.
+--     Step: 1.3.3 (unfold count, twice)                     Q.E.D.
+--     Step: 1.3.4                                           Q.E.D.
+--     Step: 1.3.5                                           Q.E.D.
+--     Step: 1.3.6 (unfold count in reverse, twice)          Q.E.D.
+--     Step: 1.3.7 (simplify)                                Q.E.D.
+--     Step: 1.Completeness                                  Q.E.D.
+--   Result:                                                 Q.E.D.
 -- Inductive lemma (strong): sortIsPermutation
---   Step: Measure is non-negative                             Q.E.D.
---   Step: 1 (2 way full case split)
---     Step: 1.1                                               Q.E.D.
---     Step: 1.2.1 (unfold mergeSort)                          Q.E.D.
---     Step: 1.2.2 (push count down, simplify, rearrange)      Q.E.D.
---     Step: 1.2.3                                             Q.E.D.
---     Step: 1.2.4                                             Q.E.D.
---     Step: 1.2.5                                             Q.E.D.
---     Step: 1.2.6                                             Q.E.D.
---   Result:                                                   Q.E.D.
--- Lemma: mergeSortIsCorrect                                   Q.E.D.
+--   Step: Measure is non-negative                           Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1                                             Q.E.D.
+--     Step: 1.2.1 (unfold mergeSort)                        Q.E.D.
+--     Step: 1.2.2 (push count down, simplify, rearrange)    Q.E.D.
+--     Step: 1.2.3                                           Q.E.D.
+--     Step: 1.2.4                                           Q.E.D.
+--     Step: 1.2.5                                           Q.E.D.
+--     Step: 1.2.6                                           Q.E.D.
+--     Step: 1.Completeness                                  Q.E.D.
+--   Result:                                                 Q.E.D.
+-- Lemma: mergeSortIsCorrect                                 Q.E.D.
+-- Functions proven terminating: count, merge, mergeSort, nonDecreasing
 -- [Proven] mergeSortIsCorrect :: Ɐxs ∷ [Integer] → Bool
 correctness :: forall a. (OrdSymbolic (SBV a), SymVal a) => IO (Proof (Forall "xs" [a] -> SBool))
-correctness = runTPWith (tpRibbon 60 z3) $ do
+correctness = runTP $ do
 
     --------------------------------------------------------------------------------------------
     -- Part I. Import helper lemmas, definitions
@@ -134,7 +148,20 @@
 
     nonDecrIns    <- SH.nonDecrIns    @a
     takeDropCount <- TP.takeDropCount @a
+    cntStep       <- TP.countOneStep  @a
 
+    -- Head of merge: one unfold of merge suffices for the solver
+    mergeHead <- lemma "mergeHead"
+                    (\(Forall xs) (Forall ys) -> sNot (null ys) .=>
+                        head (merge xs ys) .== ite (null xs) (head ys) (ite (head xs .<= head ys) (head xs) (head ys)))
+                    []
+
+    -- Unfold lemma for merge's recursive case
+    mergeUnfold <- lemma "mergeUnfold"
+                    (\(Forall x) (Forall xs) (Forall y) (Forall ys) ->
+                        merge (x .: xs) (y .: ys) .== ite (x .<= y) (x .: merge xs (y .: ys)) (y .: merge (x .: xs) ys))
+                    []
+
     --------------------------------------------------------------------------------------------
     -- Part II. Prove that the output of merge sort is non-decreasing.
     --------------------------------------------------------------------------------------------
@@ -142,131 +169,142 @@
     mergeKeepsSort <-
         sInductWith cvc5 "mergeKeepsSort"
            (\(Forall xs) (Forall ys) -> nonDecreasing xs .&& nonDecreasing ys .=> nonDecreasing (merge xs ys))
-           (\xs ys -> tuple (length xs, length ys)) $
+           (\xs ys -> tuple (length xs, length ys), []) $
            \ih xs ys -> [nonDecreasing xs, nonDecreasing ys]
-                     |- split2 (xs, ys)
-                               trivial           -- when both xs and ys are empty.  Trivial.
-                               trivial           -- when xs is empty, but ys isn't. Trivial.
-                               trivial           -- when ys is empty, but xs isn't. Trivial.
-                               (\(a, as) (b, bs) ->
-                                     nonDecreasing (merge (a .: as) (b .: bs))
-                                  ?? "unfold merge"
-                                  =: nonDecreasing (ite (a .<= b)
-                                                        (a .: merge as (b .: bs))
-                                                        (b .: merge (a .: as) bs))
-                                  ?? "case split"
-                                  =: cases [ a .<= b ==> nonDecreasing (a .: merge as (b .: bs))
-                                                      ?? ih         `at` (Inst @"xs" as, Inst @"ys" (b .: bs))
-                                                      ?? nonDecrIns `at` (Inst @"x" a, Inst @"xs" (merge as (b .: bs)))
-                                                      =: sTrue
-                                                      =: qed
-                                           , a .> b  ==> nonDecreasing (b .: merge (a .: as) bs)
-                                                      ?? ih         `at` (Inst @"xs" (a .: as), Inst @"ys" bs)
-                                                      ?? nonDecrIns `at` (Inst @"x" b, Inst @"xs" (merge (a .: as) bs))
-                                                      =: sTrue
-                                                      =: qed
-                                           ])
+                     |- [pCase| tuple (xs, ys) of
+                          ([], _)          -> trivial
+                          (_, [])          -> trivial
+                          (ll@(a : as), rr@(b : bs)) ->
+                                nonDecreasing (merge ll rr)
+                             ?? "2 way case split"
+                             =: cases [ a .<= b ==> nonDecreasing (merge ll rr)
+                                                 ?? mergeUnfold `at` (Inst @"x" a, Inst @"xs" as, Inst @"y" b, Inst @"ys" bs)
+                                                 =: nonDecreasing (a .: merge as rr)
+                                                 ?? ih         `at` (Inst @"xs" as, Inst @"ys" rr)
+                                                 ?? nonDecrIns `at` (Inst @"x" a, Inst @"xs" (merge as rr))
+                                                 ?? mergeHead  `at` (Inst @"xs" as, Inst @"ys" rr)
+                                                 =: sTrue
+                                                 =: qed
+                                      , a .> b  ==> nonDecreasing (merge ll rr)
+                                                 ?? mergeUnfold `at` (Inst @"x" a, Inst @"xs" as, Inst @"y" b, Inst @"ys" bs)
+                                                 =: nonDecreasing (b .: merge ll bs)
+                                                 ?? ih         `at` (Inst @"xs" ll, Inst @"ys" bs)
+                                                 ?? nonDecrIns `at` (Inst @"x" b, Inst @"xs" (merge ll bs))
+                                                 ?? mergeHead  `at` (Inst @"xs" ll, Inst @"ys" bs)
+                                                 =: sTrue
+                                                 =: qed
+                                      ]
+                        |]
 
     sortNonDecreasing <-
         sInduct "sortNonDecreasing"
                 (\(Forall xs) -> nonDecreasing (mergeSort xs))
-                length $
-                \ih xs -> [] |- split xs
-                                      qed
-                                      (\e es -> nonDecreasing (mergeSort (e .: es))
-                                             ?? "unfold"
-                                             =: let (h1, h2) = splitAt (length (e .: es) `sEDiv` 2) (e .: es)
-                                                in nonDecreasing (ite (length (e .: es) .<= 1)
-                                                                      (e .: es)
-                                                                      (merge (mergeSort h1) (mergeSort h2)))
-                                             ?? "push nonDecreasing down"
-                                             =: ite (length (e .: es) .<= 1)
-                                                    (nonDecreasing (e .: es))
-                                                    (nonDecreasing (merge (mergeSort h1) (mergeSort h2)))
-                                             ?? ih `at` Inst @"xs" es
-                                             =: ite (length (e .: es) .<= 1)
-                                                    sTrue
-                                                    (nonDecreasing (merge (mergeSort h1) (mergeSort h2)))
-                                             ?? ih `at` Inst @"xs" h1
-                                             ?? ih `at` Inst @"xs" h2
-                                             ?? mergeKeepsSort `at` (Inst @"xs" (mergeSort h1), Inst @"ys" (mergeSort h2))
-                                             =: sTrue
-                                             =: qed)
+                (length, []) $
+                \ih xs -> [] |- [pCase| xs of
+                                  []             -> qed
+                                  whole@(_ : es) ->
+                                        nonDecreasing (mergeSort whole)
+                                     ?? "unfold"
+                                     =: let (h1, h2) = splitAt (length whole `sEDiv` 2) whole
+                                        in nonDecreasing (ite (length whole .<= 1)
+                                                              whole
+                                                              (merge (mergeSort h1) (mergeSort h2)))
+                                     ?? "push nonDecreasing down"
+                                     =: ite (length whole .<= 1)
+                                            (nonDecreasing whole)
+                                            (nonDecreasing (merge (mergeSort h1) (mergeSort h2)))
+                                     ?? ih `at` Inst @"xs" es
+                                     =: ite (length whole .<= 1)
+                                            sTrue
+                                            (nonDecreasing (merge (mergeSort h1) (mergeSort h2)))
+                                     ?? ih `at` Inst @"xs" h1
+                                     ?? ih `at` Inst @"xs" h2
+                                     ?? mergeKeepsSort `at` (Inst @"xs" (mergeSort h1), Inst @"ys" (mergeSort h2))
+                                     =: sTrue
+                                     =: qed
+                                |]
 
     --------------------------------------------------------------------------------------------
-    -- Part III. Prove that the output of merge sort is a permuation of its input
+    -- Part III. Prove that the output of merge sort is a permutation of its input
     --------------------------------------------------------------------------------------------
     mergeCount <-
         sInduct "mergeCount"
                 (\(Forall xs) (Forall ys) (Forall e) -> count e (merge xs ys) .== count e xs + count e ys)
-                (\xs ys _e -> tuple (length xs, length ys)) $
-                \ih as bs e -> [] |- split2 (as, bs)
-                                            trivial
-                                            trivial
-                                            trivial
-                                            (\(x, xs) (y, ys) -> count e (merge (x .: xs) (y .: ys))
-                                                              ?? "unfold merge"
-                                                              =: count e (ite (x .<= y)
-                                                                              (x .: merge xs (y .: ys))
-                                                                              (y .: merge (x .: xs) ys))
-                                                              ?? "push count inside"
-                                                              =: ite (x .<= y)
-                                                                     (count e (x .: merge xs (y .: ys)))
-                                                                     (count e (y .: merge (x .: xs) ys))
-                                                              ?? "unfold count, twice"
-                                                              =: ite (x .<= y)
-                                                                     (let r = count e (merge xs (y .: ys)) in ite (e .== x) (1+r) r)
-                                                                     (let r = count e (merge (x .: xs) ys) in ite (e .== y) (1+r) r)
-                                                              ?? ih `at` (Inst @"xs" xs, Inst @"ys" (y .: ys), Inst @"e" e)
-                                                              =: ite (x .<= y)
-                                                                     (let r = count e xs + count e (y .: ys) in ite (e .== x) (1+r) r)
-                                                                     (let r = count e (merge (x .: xs) ys) in ite (e .== y) (1+r) r)
-                                                              ?? ih `at` (Inst @"xs" (x .: xs), Inst @"ys" ys, Inst @"e" e)
-                                                              =: ite (x .<= y)
-                                                                     (let r = count e xs + count e (y .: ys) in ite (e .== x) (1+r) r)
-                                                                     (let r = count e (x .: xs) + count e ys in ite (e .== y) (1+r) r)
-                                                              ?? "unfold count in reverse, twice"
-                                                              =: ite (x .<= y)
-                                                                     (count e (x .: xs) + count e (y .: ys))
-                                                                     (count e (x .: xs) + count e (y .: ys))
-                                                              ?? "simplify"
-                                                              =: count e (x .: xs) + count e (y .: ys)
-                                                              =: qed)
+                (\xs ys _e -> tuple (length xs, length ys), []) $
+                \ih as bs e -> [] |- [pCase| tuple (as, bs) of
+                                      ([], _) -> trivial
+                                      (_, []) -> trivial
 
+                                      (ll@(x : xs), rr@(y : ys)) ->
+                                              count e (merge ll rr)
+                                           ?? "unfold merge"
+                                           =: count e (ite (x .<= y)
+                                                           (x .: merge xs rr)
+                                                           (y .: merge ll ys))
+                                           ?? "push count inside"
+                                           =: ite (x .<= y)
+                                                  (count e (x .: merge xs rr))
+                                                  (count e (y .: merge ll ys))
+                                           ?? "unfold count, twice"
+                                           ?? cntStep `at` (Inst @"e" e, Inst @"x" x, Inst @"xs" (merge xs rr))
+                                           ?? cntStep `at` (Inst @"e" e, Inst @"x" y, Inst @"xs" (merge ll ys))
+                                           =: ite (x .<= y)
+                                                  (let r = count e (merge xs rr) in ite (e .== x) (1+r) r)
+                                                  (let r = count e (merge ll ys) in ite (e .== y) (1+r) r)
+                                           ?? ih `at` (Inst @"xs" xs, Inst @"ys" rr, Inst @"e" e)
+                                           =: ite (x .<= y)
+                                                  (let r = count e xs + count e rr in ite (e .== x) (1+r) r)
+                                                  (let r = count e (merge ll ys) in ite (e .== y) (1+r) r)
+                                           ?? ih `at` (Inst @"xs" ll, Inst @"ys" ys, Inst @"e" e)
+                                           =: ite (x .<= y)
+                                                  (let r = count e xs + count e rr in ite (e .== x) (1+r) r)
+                                                  (let r = count e ll + count e ys in ite (e .== y) (1+r) r)
+                                           ?? "unfold count in reverse, twice"
+                                           ?? cntStep `at` (Inst @"e" e, Inst @"x" x, Inst @"xs" xs)
+                                           ?? cntStep `at` (Inst @"e" e, Inst @"x" y, Inst @"xs" ys)
+                                           =: ite (x .<= y)
+                                                  (count e ll + count e rr)
+                                                  (count e ll + count e rr)
+                                           ?? "simplify"
+                                           =: count e ll + count e rr
+                                           =: qed
+                                    |]
+
     sortIsPermutation <-
         sInductWith cvc5 "sortIsPermutation"
                 (\(Forall xs) (Forall e) -> count e xs .== count e (mergeSort xs))
-                (\xs _e -> length xs) $
-                \ih as e -> [] |- split as
-                                        trivial
-                                        (\x xs -> count e (mergeSort (x .: xs))
-                                               ?? "unfold mergeSort"
-                                               =: count e (ite (length (x .: xs) .<= 1)
-                                                               (x .: xs)
-                                                               (let (h1, h2) = splitAt (length (x .: xs) `sEDiv` 2) (x .: xs)
-                                                                in merge (mergeSort h1) (mergeSort h2)))
-                                               ?? "push count down, simplify, rearrange"
-                                               =: let (h1, h2) = splitAt (length (x .: xs) `sEDiv` 2) (x .: xs)
-                                               in ite (null xs)
-                                                      (count e [x])
-                                                      (count e (merge (mergeSort h1) (mergeSort h2)))
-                                               ?? mergeCount `at` (Inst @"xs" (mergeSort h1), Inst @"ys" (mergeSort h2), Inst @"e" e)
-                                               =: ite (null xs)
-                                                      (count e [x])
-                                                      (count e (mergeSort h1) + count e (mergeSort h2))
-                                               ?? ih `at` (Inst @"xs" h1, Inst @"e" e)
-                                               =: ite (null xs)
-                                                      (count e [x])
-                                                      (count e h1 + count e (mergeSort h2))
-                                               ?? ih `at` (Inst @"xs" h2, Inst @"e" e)
-                                               =: ite (null xs)
-                                                      (count e [x])
-                                                      (count e h1 + count e h2)
-                                               ?? takeDropCount `at` (Inst @"xs" (x .: xs), Inst @"n" (length (x .: xs) `sEDiv` 2), Inst @"e" e)
-                                               =: ite (null xs)
-                                                      (count e [x])
-                                                      (count e (x .: xs))
-                                               =: qed)
+                (\xs _e -> length xs, []) $
+                \ih as e -> [] |- [pCase| as of
+                                    []     -> trivial
+                                    whole@(x : xs) -> count e (mergeSort whole)
+                                           ?? "unfold mergeSort"
+                                           =: count e (ite (length whole .<= 1)
+                                                           whole
+                                                           (let (h1, h2) = splitAt (length whole `sEDiv` 2) whole
+                                                            in merge (mergeSort h1) (mergeSort h2)))
+                                           ?? "push count down, simplify, rearrange"
+                                           =: let (h1, h2) = splitAt (length whole `sEDiv` 2) whole
+                                           in ite (null xs)
+                                                  (count e [x])
+                                                  (count e (merge (mergeSort h1) (mergeSort h2)))
+                                           ?? mergeCount `at` (Inst @"xs" (mergeSort h1), Inst @"ys" (mergeSort h2), Inst @"e" e)
+                                           =: ite (null xs)
+                                                  (count e [x])
+                                                  (count e (mergeSort h1) + count e (mergeSort h2))
+                                           ?? ih `at` (Inst @"xs" h1, Inst @"e" e)
+                                           =: ite (null xs)
+                                                  (count e [x])
+                                                  (count e h1 + count e (mergeSort h2))
+                                           ?? ih `at` (Inst @"xs" h2, Inst @"e" e)
+                                           =: ite (null xs)
+                                                  (count e [x])
+                                                  (count e h1 + count e h2)
+                                           ?? takeDropCount `at` (Inst @"xs" whole, Inst @"n" (length whole `sEDiv` 2), Inst @"e" e)
+                                           =: ite (null xs)
+                                                  (count e [x])
+                                                  (count e whole)
+                                           =: qed
+                                  |]
 
     --------------------------------------------------------------------------------------------
     -- Put the two parts together for the final proof
diff --git a/Documentation/SBV/Examples/TP/MutualCorecursion.hs b/Documentation/SBV/Examples/TP/MutualCorecursion.hs
new file mode 100644
--- /dev/null
+++ b/Documentation/SBV/Examples/TP/MutualCorecursion.hs
@@ -0,0 +1,187 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Documentation.SBV.Examples.TP.MutualCorecursion
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Demonstrating mutually corecursive (productive) functions. Two functions
+-- @ping@ and @pong@ take turns producing elements of a stream: each emits
+-- its argument and then calls the other with the next value:
+--
+-- @
+--   ping n = n .: pong (n + 1)
+--   pong n = n .: ping (n + 1)
+-- @
+--
+-- Together they produce the natural number stream starting from @n@:
+-- @ping 0 = [0, 1, 2, 3, ...]@. We prove that the @k@-th element
+-- of @ping n@ is @n + k@.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE CPP                 #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Documentation.SBV.Examples.TP.MutualCorecursion where
+
+import Prelude hiding (head, length, (!!))
+
+import Data.SBV
+import Data.SBV.List
+import Data.SBV.TP
+
+#ifdef DOCTEST
+-- $setup
+-- >>> import Data.SBV.TP
+#endif
+
+-- * Definitions
+
+-- | @ping n@ emits @n@ and hands off to 'pong'. Note the use of 'smtProductiveFunction':
+-- since @ping@ and @pong@ are corecursive (no base case, always producing output), we
+-- declare them productive instead of terminating.
+ping :: SInteger -> SList Integer
+ping = smtProductiveFunction "ping"
+     $ \n -> n .: pong (n + 1)
+
+-- | @pong n@ emits @n@ and hands off to 'ping'. See 'ping' for why we use 'smtProductiveFunction'.
+pong :: SInteger -> SList Integer
+pong = smtProductiveFunction "pong"
+     $ \n -> n .: ping (n + 1)
+
+-- * Helper lemmas
+
+-- | @ping@ produces unboundedly long lists.
+--
+-- >>> runTP pingLen
+-- Inductive lemma: pingLen
+--   Step: Base                Q.E.D.
+--   Step: 1                   Q.E.D.
+--   Step: 2                   Q.E.D.
+--   Result:                   Q.E.D.
+-- Functions proven productive: ping, pong
+-- [Proven] pingLen :: Ɐm ∷ Integer → Ɐn ∷ Integer → Bool
+pingLen :: TP (Proof (Forall "m" Integer -> Forall "n" Integer -> SBool))
+pingLen = inductWith cvc5 "pingLen"
+                     (\(Forall @"m" (m :: SInteger)) (Forall @"n" n) -> length (ping n) .>= m) $
+                     \ih m n -> []
+                             |- length (ping n) .>= m + 1
+                             =: length (n .: pong (n + 1)) .>= m + 1
+                             ?? ih `at` Inst @"n" (n + 2)
+                             =: sTrue
+                             =: qed
+
+-- | @pong@ produces unboundedly long lists.
+--
+-- >>> runTP pongLen
+-- Inductive lemma: pongLen
+--   Step: Base                Q.E.D.
+--   Step: 1                   Q.E.D.
+--   Step: 2                   Q.E.D.
+--   Result:                   Q.E.D.
+-- Functions proven productive: ping, pong
+-- [Proven] pongLen :: Ɐm ∷ Integer → Ɐn ∷ Integer → Bool
+pongLen :: TP (Proof (Forall "m" Integer -> Forall "n" Integer -> SBool))
+pongLen = inductWith cvc5 "pongLen"
+                     (\(Forall @"m" (m :: SInteger)) (Forall @"n" n) -> length (pong n) .>= m) $
+                     \ih m n -> []
+                             |- length (pong n) .>= m + 1
+                             =: length (n .: ping (n + 1)) .>= m + 1
+                             ?? ih `at` Inst @"n" (n + 2)
+                             =: sTrue
+                             =: qed
+
+-- | Indexing past a cons: @(x .: y) !! k == y !! (k - 1)@ when @k > 0@ and in bounds.
+--
+-- >>> runTP consIndex
+-- Lemma: consIndex    Q.E.D.
+-- [Proven] consIndex :: Ɐx ∷ Integer → Ɐy ∷ [Integer] → Ɐk ∷ Integer → Bool
+consIndex :: TP (Proof (Forall "x" Integer -> Forall "y" [Integer] -> Forall "k" Integer -> SBool))
+consIndex = lemma "consIndex"
+                  (\(Forall @"x" (x :: SInteger)) (Forall @"y" y) (Forall @"k" k) ->
+                        k .> 0 .&& k .<= length y .=> (x .: y) !! k .== y !! (k - 1))
+                  []
+
+-- * Correctness
+
+-- | Proving @ping n@ and @pong n@ produce the same elements. We prove that the @k@-th
+-- elements are the same, by induction on @k@.
+--
+-- >>> runTP pingEqPong
+-- Lemma: pingLen                 Q.E.D.
+-- Lemma: pongLen                 Q.E.D.
+-- Lemma: consIndex               Q.E.D.
+-- Inductive lemma: pingEqPong
+--   Step: Base                   Q.E.D.
+--   Step: 1                      Q.E.D.
+--   Step: 2                      Q.E.D.
+--   Step: 3                      Q.E.D.
+--   Step: 4                      Q.E.D.
+--   Step: 5                      Q.E.D.
+--   Result:                      Q.E.D.
+-- Functions proven productive: ping, pong
+-- [Proven] pingEqPong :: Ɐk ∷ Integer → Ɐn ∷ Integer → Bool
+pingEqPong :: TP (Proof (Forall "k" Integer -> Forall "n" Integer -> SBool))
+pingEqPong = do
+   piLen <- recall pingLen
+   poLen <- recall pongLen
+   ci    <- recall consIndex
+
+   inductWith cvc5 "pingEqPong"
+          (\(Forall @"k" k) (Forall @"n" n) -> k .>= 0 .=> ping n !! k .== pong n !! k) $
+          \ih k n -> [k .>= 0]
+                  |- ping n !! (k + 1)
+                  =: (n .: pong (n + 1)) !! (k + 1)
+                  ?? ci `at` (Inst @"x" n, Inst @"y" (pong (n + 1)), Inst @"k" (k + 1))
+                  ?? poLen
+                  =: pong (n + 1) !! k
+                  ?? ih `at` Inst @"n" (n + 1)
+                  =: ping (n + 1) !! k
+                  ?? ci `at` (Inst @"x" n, Inst @"y" (ping (n + 1)), Inst @"k" (k + 1))
+                  ?? piLen
+                  =: (n .: ping (n + 1)) !! (k + 1)
+                  =: pong n !! (k + 1)
+                  =: qed
+
+-- | The @k@-th element of @ping n@ is @n + k@.
+--
+-- >>> runTP pingElem
+-- Lemma: pingEqPong              Q.E.D.
+-- Lemma: consIndex               Q.E.D. [Cached]
+-- Lemma: pongLen                 Q.E.D. [Cached]
+-- Inductive lemma: pingElem
+--   Step: Base                   Q.E.D.
+--   Step: 1                      Q.E.D.
+--   Step: 2                      Q.E.D.
+--   Step: 3                      Q.E.D.
+--   Step: 4                      Q.E.D.
+--   Step: 5                      Q.E.D.
+--   Result:                      Q.E.D.
+-- Functions proven productive: ping, pong
+-- [Proven] pingElem :: Ɐk ∷ Integer → Ɐn ∷ Integer → Bool
+pingElem :: TP (Proof (Forall "k" Integer -> Forall "n" Integer -> SBool))
+pingElem = do
+   eq    <- recall pingEqPong
+   ci    <- recall consIndex
+   poLen <- recall pongLen
+
+   inductWith cvc5 "pingElem"
+          (\(Forall @"k" k) (Forall @"n" n) -> k .>= 0 .=> ping n !! k .== n + k) $
+          \ih k n -> [k .>= 0]
+                  |- ping n !! (k + 1)
+                  =: (n .: pong (n + 1)) !! (k + 1)
+                  ?? ci `at` (Inst @"x" n, Inst @"y" (pong (n + 1)), Inst @"k" (k + 1))
+                  ?? poLen
+                  =: pong (n + 1) !! k
+                  ?? eq `at` (Inst @"k" k, Inst @"n" (n + 1))
+                  =: ping (n + 1) !! k
+                  ?? ih `at` Inst @"n" (n + 1)
+                  =: (n + 1) + k
+                  =: n + (k + 1)
+                  =: qed
diff --git a/Documentation/SBV/Examples/TP/NatStream.hs b/Documentation/SBV/Examples/TP/NatStream.hs
new file mode 100644
--- /dev/null
+++ b/Documentation/SBV/Examples/TP/NatStream.hs
@@ -0,0 +1,121 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Documentation.SBV.Examples.TP.NatStream
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Demonstrating productive (corecursive) functions. A productive function
+-- is one where every recursive call is guarded by a data constructor, so
+-- the function always makes progress by producing output. Unlike terminating
+-- functions, productive functions need not have a base case and may produce
+-- infinite output.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE CPP                 #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Documentation.SBV.Examples.TP.NatStream where
+
+import Prelude hiding (head, length, (!!))
+
+import Data.SBV
+import Data.SBV.List
+import Data.SBV.TP
+
+#ifdef DOCTEST
+-- $setup
+-- >>> import Data.SBV.TP
+#endif
+
+-- * Definitions
+
+-- | The infinite stream of integers starting from @n@: @[n, n+1, n+2, ...]@.
+-- There is no base case; every recursive call is guarded by the list
+-- constructor @.:@, making this a productive (corecursive) definition.
+nats :: SInteger -> SList Integer
+nats = smtProductiveFunction "nats"
+     $ \n -> n .: nats (n + 1)
+
+-- * Correctness
+
+-- | Prove that @nats n@ always starts with @n@.
+--
+-- NB. As of Mar 2026, z3 can't handle this but cvc5 can.
+--
+-- >>> runTP natsHead
+-- Lemma: natsHead     Q.E.D.
+-- Functions proven productive: nats
+-- [Proven] natsHead :: Ɐn ∷ Integer → Bool
+natsHead :: TP (Proof (Forall "n" Integer -> SBool))
+natsHead = lemmaWith cvc5 "natsHead"
+                 (\(Forall @"n" n) -> head (nats n) .== n)
+                 []
+
+-- | Prove by induction that @nats n@ has at least @m@ elements, for any @m@.
+-- This captures the idea that @nats@ produces an unboundedly long list.
+--
+-- NB. As of Mar 2026, z3 can't handle this but cvc5 can.
+--
+-- >>> runTP natsLen
+-- Inductive lemma: natsLen
+--   Step: Base                Q.E.D.
+--   Step: 1                   Q.E.D.
+--   Step: 2                   Q.E.D.
+--   Result:                   Q.E.D.
+-- Functions proven productive: nats
+-- [Proven] natsLen :: Ɐm ∷ Integer → Ɐn ∷ Integer → Bool
+natsLen :: TP (Proof (Forall "m" Integer -> Forall "n" Integer -> SBool))
+natsLen =
+   inductWith cvc5 "natsLen"
+          (\(Forall @"m" m) (Forall @"n" n) -> length (nats n) .>= m) $
+          \ih m n -> []
+                  |- length (nats n) .>= m + 1
+                  =: length (n .: nats (n + 1)) .>= m + 1
+                  ?? ih `at` Inst @"n" (n + 1)
+                  =: sTrue
+                  =: qed
+
+-- | Prove by induction that the @k@-th element of @nats n@ is @n + k@.
+--
+-- NB. As of Mar 2026, z3 can't handle this but cvc5 can.
+--
+-- >>> runTP natsElem
+-- Lemma: natsLen               Q.E.D.
+-- Lemma: elemOne               Q.E.D.
+-- Inductive lemma: natsElem
+--   Step: Base                 Q.E.D.
+--   Step: 1                    Q.E.D.
+--   Step: 2                    Q.E.D.
+--   Step: 3                    Q.E.D.
+--   Step: 4                    Q.E.D.
+--   Result:                    Q.E.D.
+-- Functions proven productive: nats
+-- [Proven] natsElem :: Ɐk ∷ Integer → Ɐn ∷ Integer → Bool
+natsElem :: TP (Proof (Forall "k" Integer -> Forall "n" Integer -> SBool))
+natsElem = do
+   nLen <- recall natsLen
+
+   elemOne <- lemma "elemOne"
+                    (\(Forall @"x" (x :: SInteger)) (Forall @"y" y) (Forall @"k" k) ->
+                          k .> 0 .&& k .<= length y .=> (x .: y) !! k .== y !! (k - 1))
+                    []
+
+   inductWith cvc5 "natsElem"
+          (\(Forall @"k" k) (Forall @"n" n) -> k .>= 0 .=> nats n !! k .== n + k) $
+          \ih k n -> [k .>= 0]
+                  |- nats n !! (k + 1)
+                  =: (n .: nats (n + 1)) !! (k + 1)
+                  ?? elemOne
+                  ?? nLen
+                  =: nats (n + 1) !! k
+                  ?? ih `at` Inst @"n" (n + 1)
+                  =: (n + 1) + k
+                  =: n + (k + 1)
+                  =: qed
diff --git a/Documentation/SBV/Examples/TP/Numeric.hs b/Documentation/SBV/Examples/TP/Numeric.hs
--- a/Documentation/SBV/Examples/TP/Numeric.hs
+++ b/Documentation/SBV/Examples/TP/Numeric.hs
@@ -40,12 +40,13 @@
 --
 -- >>> runTP $ sumConstProof (uninterpret "c")
 -- Inductive lemma: sumConst_correct
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: Base                         Q.E.D.
+--   Step: 1                            Q.E.D.
+--   Step: 2                            Q.E.D.
+--   Step: 3                            Q.E.D.
+--   Step: 4                            Q.E.D.
+--   Result:                            Q.E.D.
+-- Functions proven terminating: sbv.foldr, sbv.replicate
 -- [Proven] sumConst_correct :: Ɐn ∷ Integer → Bool
 sumConstProof :: SInteger -> TP (Proof (Forall "n" Integer -> SBool))
 sumConstProof c = induct "sumConst_correct"
@@ -70,11 +71,12 @@
 --
 -- >>> runTP sumProof
 -- Inductive lemma: sum_correct
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: Base                    Q.E.D.
+--   Step: 1                       Q.E.D.
+--   Step: 2                       Q.E.D.
+--   Step: 3                       Q.E.D.
+--   Result:                       Q.E.D.
+-- Functions proven terminating: EnumSymbolic.Integer.enumFromThenTo.down, sbv.foldr
 -- [Proven] sum_correct :: Ɐn ∷ Integer → Bool
 sumProof :: TP (Proof (Forall "n" Integer -> SBool))
 sumProof = induct "sum_correct"
@@ -92,14 +94,15 @@
 --
 -- >>> runTP sumSquareProof
 -- Inductive lemma: sumSquare_correct
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Step: 6                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: Base                          Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Step: 3                             Q.E.D.
+--   Step: 4                             Q.E.D.
+--   Step: 5                             Q.E.D.
+--   Step: 6                             Q.E.D.
+--   Result:                             Q.E.D.
+-- Functions proven terminating: EnumSymbolic.Integer.enumFromThenTo.down, sbv.foldr, sbv.map
 -- [Proven] sumSquare_correct :: Ɐn ∷ Integer → Bool
 sumSquareProof :: TP (Proof (Forall "n" Integer -> SBool))
 sumSquareProof = do
@@ -128,27 +131,28 @@
 --
 -- >>> runTP nicomachus
 -- Inductive lemma: sum_correct
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: evenHalfSquared                  Q.E.D.
+--   Step: Base                    Q.E.D.
+--   Step: 1                       Q.E.D.
+--   Step: 2                       Q.E.D.
+--   Step: 3                       Q.E.D.
+--   Result:                       Q.E.D.
+-- Lemma: evenHalfSquared          Q.E.D.
 -- Inductive lemma: nn1IsEven
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: Base                    Q.E.D.
+--   Step: 1                       Q.E.D.
+--   Step: 2                       Q.E.D.
+--   Step: 3                       Q.E.D.
+--   Result:                       Q.E.D.
 -- Lemma: sum_squared
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: 1                       Q.E.D.
+--   Step: 2                       Q.E.D.
+--   Result:                       Q.E.D.
 -- Inductive lemma: nicomachus
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: Base                    Q.E.D.
+--   Step: 1                       Q.E.D.
+--   Step: 2                       Q.E.D.
+--   Result:                       Q.E.D.
+-- Functions proven terminating: EnumSymbolic.Integer.enumFromThenTo.down, sbv.foldr, sumCubed
 -- [Proven] nicomachus :: Ɐn ∷ Integer → Bool
 nicomachus :: TP (Proof (Forall "n" Integer -> SBool))
 nicomachus = do
@@ -158,7 +162,10 @@
        infixr 8 ^
 
        sumCubed :: SInteger -> SInteger
-       sumCubed = smtFunction "sumCubed" $ \n -> ite (n .<= 0) 0 (n^3 + sumCubed (n - 1))
+       sumCubed = smtFunction "sumCubed" $ \n -> [sCase| n of
+                                                    _ | n .<= 0 -> 0
+                                                    _           -> n^3 + sumCubed (n - 1)
+                                                 |]
 
    -- Grab the proof of regular summation formula
    sp <- sumProof
@@ -212,23 +219,27 @@
 -- NB. As of Feb 2025, z3 struggles with the inductive step in this proof, but cvc5 performs just fine.
 --
 -- >>> runTP elevenMinusFour
--- Lemma: powN                             Q.E.D.
+-- Lemma: powN                         Q.E.D.
 -- Inductive lemma: elevenMinusFour
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Step: 6                               Q.E.D.
---   Step: 7                               Q.E.D.
---   Step: 8                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: Base                        Q.E.D.
+--   Step: 1                           Q.E.D.
+--   Step: 2                           Q.E.D.
+--   Step: 3                           Q.E.D.
+--   Step: 4                           Q.E.D.
+--   Step: 5                           Q.E.D.
+--   Step: 6                           Q.E.D.
+--   Step: 7                           Q.E.D.
+--   Step: 8                           Q.E.D.
+--   Result:                           Q.E.D.
+-- Functions proven terminating: pow
 -- [Proven] elevenMinusFour :: Ɐn ∷ Integer → Bool
 elevenMinusFour :: TP (Proof (Forall "n" Integer -> SBool))
 elevenMinusFour = do
    let pow :: SInteger -> SInteger -> SInteger
-       pow = smtFunction "pow" $ \x y -> ite (y .== 0) 1 (x * pow x (y - 1))
+       pow = smtFunction "pow" $ \x y -> [sCase| y of
+                                            _ | y .<= 0 -> 1
+                                            _           -> x * pow x (y - 1)
+                                         |]
 
        emf :: SInteger -> SBool
        emf n = 7 `sDivides` (11 `pow` n - 4 `pow` n)
@@ -260,21 +271,22 @@
 --
 -- >>> runTP sumMulFactorial
 -- Lemma: fact (n+1)
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: 1                           Q.E.D.
+--   Step: 2                           Q.E.D.
+--   Step: 3                           Q.E.D.
+--   Step: 4                           Q.E.D.
+--   Result:                           Q.E.D.
 -- Inductive lemma: sumMulFactorial
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Step: 6                               Q.E.D.
---   Step: 7                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: Base                        Q.E.D.
+--   Step: 1                           Q.E.D.
+--   Step: 2                           Q.E.D.
+--   Step: 3                           Q.E.D.
+--   Step: 4                           Q.E.D.
+--   Step: 5                           Q.E.D.
+--   Step: 6                           Q.E.D.
+--   Step: 7                           Q.E.D.
+--   Result:                           Q.E.D.
+-- Functions proven terminating: EnumSymbolic.Integer.enumFromThenTo.down, sbv.foldr, sbv.map
 -- [Proven] sumMulFactorial :: Ɐn ∷ Integer → Bool
 sumMulFactorial :: TP (Proof (Forall "n" Integer -> SBool))
 sumMulFactorial = do
@@ -311,14 +323,15 @@
 --
 -- >>> runTP product0
 -- Inductive lemma: product0
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
+--   Step: Base                 Q.E.D.
+--   Step: 1                    Q.E.D.
 --   Step: 2 (2 way case split)
---     Step: 2.1                           Q.E.D.
---     Step: 2.2.1                         Q.E.D.
---     Step: 2.2.2                         Q.E.D.
---     Step: 2.Completeness                Q.E.D.
---   Result:                               Q.E.D.
+--     Step: 2.1                Q.E.D.
+--     Step: 2.2.1              Q.E.D.
+--     Step: 2.2.2              Q.E.D.
+--     Step: 2.Completeness     Q.E.D.
+--   Result:                    Q.E.D.
+-- Functions proven terminating: sbv.foldr
 -- [Proven] product0 :: Ɐxs ∷ [Integer] → Bool
 product0 :: TP (Proof (Forall "xs" [Integer] -> SBool))
 product0 =
@@ -341,7 +354,7 @@
 --
 -- >>> badNonNegative `catch` (\(_ :: SomeException) -> pure ())
 -- Inductive lemma: badNonNegative
---   Step: Base                            Q.E.D.
+--   Step: Base                       Q.E.D.
 --   Step: 1
 -- *** Failed to prove badNonNegative.1.
 -- Falsifiable. Counter-example:
diff --git a/Documentation/SBV/Examples/TP/Peano.hs b/Documentation/SBV/Examples/TP/Peano.hs
new file mode 100644
--- /dev/null
+++ b/Documentation/SBV/Examples/TP/Peano.hs
@@ -0,0 +1,926 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Documentation.SBV.Examples.TP.Peano
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Modeling Peano arithmetic in SBV and proving various properties using TP.
+-- Most of the properties we prove come from <https://en.wikipedia.org/wiki/Peano_axioms>.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE CPP                 #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE FlexibleInstances   #-}
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Documentation.SBV.Examples.TP.Peano where
+
+import Data.SBV
+import Data.SBV.TP
+
+#ifdef DOCTEST
+-- $setup
+-- >>> import Data.SBV
+-- >>> import Data.SBV.TP
+#endif
+
+-- | Natural numbers. (If you are looking at the haddock documents, note the plethora of definitions
+-- the call to 'mkSymbolic' generates. You can mostly ignore these, except for the case analyzer,
+-- the testers and accessors.)
+data Nat = Zero
+         | Succ { prev :: Nat }
+
+-- | Create a symbolic version of naturals.
+mkSymbolic [''Nat]
+
+-- | Numeric instance. Choices: We clamp everything at Zero. Negation is identity.
+instance Num Nat where
+  fromInteger i | i <= 0 = Zero
+                | True   = Succ (fromInteger (i - 1))
+
+  a + Zero   = a
+  a + Succ b = Succ (a + b)
+
+  (-) = error "Nat: No support for subtraction"
+
+  _ * Zero   = Zero
+  a * Succ b = a + a * b
+
+  abs = id
+
+  signum Zero = 0
+  signum _    = 1
+
+  negate = id
+
+-- Symbolic numeric instance, mirroring the above
+instance Num SNat where
+  fromInteger = literal . fromInteger
+
+  (+) = plus
+      where plus = smtFunction "sNatPlus" $
+                     \m n -> [sCase| m of
+                               Zero   -> n
+                               Succ p -> sSucc (p + n)
+                             |]
+
+  (-) = error "SNat: No support for subtraction"
+
+  (*) = times
+      where times = smtFunction "sNatTimes" $
+                      \m n -> [sCase| m of
+                                Zero   -> 0
+                                Succ p -> n + p * n
+                              |]
+
+  abs = id
+
+  signum m = [sCase| m of
+               Zero -> 0
+               _    -> 1
+             |]
+
+-- | Symbolic ordering. We only define less-than, other methods use the defaults.
+instance OrdSymbolic SNat where
+   m .< n = quantifiedBool (\(Exists k) -> n .== m + sSucc k)
+
+-- * Conversion to and from integers
+
+-- | Convert from 'Nat' to 'Integer'.
+--
+-- NB. When writing the properties below, we use the notation \(\overline{n}\) to mean @n2i n@.
+n2i :: SNat -> SInteger
+n2i = smtFunction "n2i" $ \n -> [sCase| n of
+                                   Zero   -> 0
+                                   Succ p -> 1 + n2i p
+                                |]
+
+-- | Convert Non-negative integers to 'Nat'. Negative numbers become Zero.
+--
+-- NB. When writing the properties below, we use the notation \(\underline{i}\) to mean @i2n i@.
+i2n :: SInteger -> SNat
+i2n = smtFunction "i2n" $ \i -> [sCase| i of
+                                   _ | i .<= 0 -> 0
+                                   _           -> sSucc (i2n (i - 1))
+                                |]
+
+-- | \(\overline{n} \geq 0\)
+--
+-- >>> runTP n2iNonNeg
+-- Lemma: n2iNonNeg    Q.E.D.
+-- Functions proven terminating: n2i
+-- [Proven] n2iNonNeg :: Ɐn ∷ Nat → Bool
+n2iNonNeg  :: TP (Proof (Forall "n" Nat -> SBool))
+n2iNonNeg = inductiveLemma "n2iNonNeg" (\(Forall n) -> n2i n .>= 0) []
+
+-- | \(\overline{\underline{i}} = \max(i, 0)\).
+--
+-- >>> runTP i2n2i
+-- Lemma: i2n2i        Q.E.D.
+-- Functions proven terminating: i2n, n2i
+-- [Proven] i2n2i :: Ɐi ∷ Integer → Bool
+i2n2i :: TP (Proof (Forall "i" Integer -> SBool))
+i2n2i = inductiveLemma "i2n2i" (\(Forall i) -> n2i (i2n i) .== i `smax` 0) []
+
+-- | \(\underline{\overline{n}} = n\)
+--
+-- >>> runTP n2i2n
+-- Lemma: n2i2n        Q.E.D.
+-- Functions proven terminating: i2n, n2i
+-- [Proven] n2i2n :: Ɐn ∷ Nat → Bool
+n2i2n :: TP (Proof (Forall "n" Nat -> SBool))
+n2i2n = inductiveLemma "n2i2n" (\(Forall n) -> i2n (n2i n) .== n) []
+
+-- | \(\overline{m + n} = \overline{m} + \overline{n}\)
+--
+-- >>> runTP n2iAdd
+-- Lemma: n2iAdd       Q.E.D.
+-- Functions proven terminating: n2i, sNatPlus
+-- [Proven] n2iAdd :: Ɐm ∷ Nat → Ɐn ∷ Nat → Bool
+n2iAdd :: TP (Proof (Forall "m" Nat -> Forall "n" Nat -> SBool))
+n2iAdd = inductiveLemma "n2iAdd" (\(Forall m) (Forall n) -> n2i (m + n) .== n2i m + n2i n) []
+
+-- * Addition
+
+-- ** Correctness
+
+-- | \(\overline{m + n} = \overline{m} + \overline{n}\)
+--
+-- >>> runTP addCorrect
+-- Lemma: addCorrect    Q.E.D.
+-- Functions proven terminating: n2i, sNatPlus
+-- [Proven] addCorrect :: Ɐm ∷ Nat → Ɐn ∷ Nat → Bool
+addCorrect :: TP (Proof (Forall "m" Nat -> Forall "n" Nat -> SBool))
+addCorrect = inductiveLemma
+               "addCorrect"
+               (\(Forall m) (Forall n) -> n2i (m + n) .== n2i m + n2i n)
+               []
+
+-- ** Left and right unit
+
+-- | \(0 + m = m\)
+--
+-- >>> runTP addLeftUnit
+-- Lemma: addLeftUnit    Q.E.D.
+-- Functions proven terminating: sNatPlus
+-- [Proven] addLeftUnit :: Ɐm ∷ Nat → Bool
+addLeftUnit :: TP (Proof (Forall "m" Nat -> SBool))
+addLeftUnit = lemma "addLeftUnit" (\(Forall m) -> 0 + m .== m) []
+
+-- | \(m + 0 = m\)
+--
+-- >>> runTP addRightUnit
+-- Lemma: addRightUnit    Q.E.D.
+-- Functions proven terminating: sNatPlus
+-- [Proven] addRightUnit :: Ɐm ∷ Nat → Bool
+addRightUnit :: TP (Proof (Forall "m" Nat -> SBool))
+addRightUnit = inductiveLemma "addRightUnit" (\(Forall m) -> m + 0 .== m) []
+
+-- ** Addition with non-zero values
+
+-- | \(m + \mathrm{Succ}\,n = \mathrm{Succ}\,(m + n)\)
+--
+-- >>> runTP addSucc
+-- Lemma: caseZero     Q.E.D.
+-- Lemma: caseSucc
+--   Step: 1           Q.E.D.
+--   Step: 2           Q.E.D.
+--   Step: 3           Q.E.D.
+--   Result:           Q.E.D.
+-- Lemma: addSucc      Q.E.D.
+-- Functions proven terminating: sNatPlus
+-- [Proven] addSucc :: Ɐm ∷ Nat → Ɐn ∷ Nat → Bool
+addSucc :: TP (Proof (Forall "m" Nat -> Forall "n" Nat -> SBool))
+addSucc = do
+   caseZero <- lemma "caseZero"
+                      (\(Forall @"n" n) -> 0 + sSucc n .== sSucc (0 + n))
+                      []
+
+   caseSucc <- calc "caseSucc"
+                    (\(Forall @"m" m) (Forall @"n" n) ->
+                        m + sSucc n .== sSucc (m + n) .=> sSucc m + sSucc n .== sSucc (sSucc m + n)) $
+                    \m n -> let ih = m + sSucc n .== sSucc (m + n)
+                         in [ih] |- sSucc m + sSucc n
+                                 =: sSucc (m + sSucc n)
+                                 ?? ih
+                                 =: sSucc (sSucc (m + n))
+                                 =: sSucc (sSucc m + n)
+                                 =: qed
+
+   inductiveLemma
+      "addSucc"
+      (\(Forall @"m" m) (Forall @"n" n) -> m + sSucc n .== sSucc (m + n))
+      [proofOf caseZero, proofOf caseSucc]
+
+-- ** Associativity
+
+-- | \(m + (n + o) = (m + n) + o\)
+--
+-- >>> runTP addAssoc
+-- Lemma: addAssoc     Q.E.D.
+-- Functions proven terminating: sNatPlus
+-- [Proven] addAssoc :: Ɐm ∷ Nat → Ɐn ∷ Nat → Ɐo ∷ Nat → Bool
+addAssoc :: TP (Proof (Forall "m" Nat -> Forall "n" Nat -> Forall "o" Nat -> SBool))
+addAssoc = inductiveLemma
+             "addAssoc"
+             (\(Forall m) (Forall n) (Forall o) -> m + (n + o) .== (m + n) + o)
+             []
+
+-- ** Commutativity
+
+-- | \(m + n = n + m\)
+--
+-- >>> runTP addComm
+-- Lemma: addLeftUnit     Q.E.D.
+-- Lemma: addRightUnit    Q.E.D.
+-- Lemma: caseZero        Q.E.D.
+-- Lemma: addSucc         Q.E.D.
+-- Lemma: caseSucc
+--   Step: 1              Q.E.D.
+--   Step: 2              Q.E.D.
+--   Step: 3              Q.E.D.
+--   Result:              Q.E.D.
+-- Lemma: addComm         Q.E.D.
+-- Functions proven terminating: sNatPlus
+-- [Proven] addComm :: Ɐm ∷ Nat → Ɐn ∷ Nat → Bool
+addComm :: TP (Proof (Forall "m" Nat -> Forall "n" Nat -> SBool))
+addComm = do
+    alu <- recall addLeftUnit
+    aru <- recall addRightUnit
+
+    caseZero <- lemma "caseZero"
+                      (\(Forall @"n" (n :: SNat)) -> 0 + n .== n + 0)
+                      [proofOf alu, proofOf aru]
+
+    as <- recall addSucc
+
+    caseSucc <- calc "caseSucc"
+                     (\(Forall @"m" m) (Forall @"n" n) -> m + n .== n + m .=> sSucc m + n .== n + sSucc m) $
+                     \m n -> let ih = m + n .== n + m
+                          in [ih] |- sSucc m + n
+                                  =: sSucc (m + n)
+                                  ?? ih
+                                  =: sSucc (n + m)
+                                  ?? as `at` (Inst @"m" n, Inst @"n" m)
+                                  =: n + sSucc m
+                                  =: qed
+
+    inductiveLemma "addComm"
+                   (\(Forall m) (Forall n) -> m + n .== n + m)
+                   [proofOf caseZero, proofOf caseSucc]
+
+-- * Multiplication
+
+-- ** Correctness
+
+-- | \(\overline{m * n} = \overline{m} * \overline{n}\)
+--
+-- >>> runTP mulCorrect
+-- Lemma: caseZero       Q.E.D.
+-- Lemma: addCorrect     Q.E.D.
+-- Lemma: caseSucc
+--   Step: 1             Q.E.D.
+--   Step: 2             Q.E.D.
+--   Step: 3             Q.E.D.
+--   Step: 4             Q.E.D.
+--   Step: 5             Q.E.D.
+--   Result:             Q.E.D.
+-- Lemma: mullCorrect    Q.E.D.
+-- Functions proven terminating: n2i, sNatPlus, sNatTimes
+-- [Proven] mullCorrect :: Ɐm ∷ Nat → Ɐn ∷ Nat → Bool
+mulCorrect :: TP (Proof (Forall "m" Nat -> Forall "n" Nat -> SBool))
+mulCorrect = do
+   caseZero <- lemma "caseZero"
+                     (\(Forall @"n" n) -> n2i (0 * n) .== n2i 0 * n2i n)
+                     []
+
+   addC <- recall addCorrect
+
+   caseSucc <- calc "caseSucc"
+                    (\(Forall @"m" m) (Forall @"n" n) ->
+                          n2i (m * n) .== n2i m * n2i n .=> n2i (sSucc m * n) .== n2i (sSucc m) * n2i n) $
+                    \m n -> let ih = n2i (m * n) .== n2i m * n2i n
+                         in [ih] |- n2i (sSucc m * n)
+                                 =: n2i (n + m * n)
+                                 ?? addC `at` (Inst @"m" n, Inst @"n" (m * n))
+                                 =: n2i n + n2i (m * n)
+                                 ?? ih
+                                 =: n2i n + n2i m * n2i n
+                                 =: n2i n * (1 + n2i m)
+                                 =: n2i n * n2i (sSucc m)
+                                 =: qed
+
+   inductiveLemma
+       "mullCorrect"
+       (\(Forall @"m" m) (Forall @"n" n) -> n2i (m * n) .== n2i m * n2i n)
+       [proofOf caseZero, proofOf caseSucc]
+
+-- ** Left and right absorption
+
+-- | \(0 * m = 0\)
+--
+-- >>> runTP mulLeftAbsorb
+-- Lemma: mulLeftAbsorb    Q.E.D.
+-- Functions proven terminating: sNatPlus, sNatTimes
+-- [Proven] mulLeftAbsorb :: Ɐm ∷ Nat → Bool
+mulLeftAbsorb :: TP (Proof (Forall "m" Nat -> SBool))
+mulLeftAbsorb = lemma "mulLeftAbsorb" (\(Forall m) -> 0 * m .== 0) []
+
+-- | \(m * 0 = 0\)
+--
+-- >>> runTP mulRightAbsorb
+-- Lemma: mulRightAbsorb    Q.E.D.
+-- Functions proven terminating: sNatPlus, sNatTimes
+-- [Proven] mulRightAbsorb :: Ɐm ∷ Nat → Bool
+mulRightAbsorb :: TP (Proof (Forall "m" Nat -> SBool))
+mulRightAbsorb = inductiveLemma "mulRightAbsorb" (\(Forall m) -> m * 0 .== 0) []
+
+-- ** Left and right unit
+
+-- | \(\mathrm{Succ\,0} * m = m\)
+--
+-- >>> runTP mulLeftUnit
+-- Lemma: mulLeftUnit    Q.E.D.
+-- Functions proven terminating: sNatPlus, sNatTimes
+-- [Proven] mulLeftUnit :: Ɐm ∷ Nat → Bool
+mulLeftUnit :: TP (Proof (Forall "m" Nat -> SBool))
+mulLeftUnit = inductiveLemma "mulLeftUnit" (\(Forall m) -> sSucc 0 * m .== m) []
+
+-- | \(m * \mathrm{Succ\,0} = m\)
+--
+-- >>> runTP mulRightUnit
+-- Lemma: mulRightUnit    Q.E.D.
+-- Functions proven terminating: sNatPlus, sNatTimes
+-- [Proven] mulRightUnit :: Ɐm ∷ Nat → Bool
+mulRightUnit :: TP (Proof (Forall "m" Nat -> SBool))
+mulRightUnit = inductiveLemma "mulRightUnit" (\(Forall m) -> m * sSucc 0 .== m) []
+
+-- ** Distribution over addition
+
+-- | \(m * (n + o) = m * n + m * o\)
+--
+-- >>> runTP distribLeft
+-- Lemma: caseZero        Q.E.D.
+-- Lemma: addAssoc        Q.E.D.
+-- Lemma: addComm         Q.E.D.
+-- Lemma: caseSucc
+--   Step: 1              Q.E.D.
+--   Step: 2              Q.E.D.
+--   Step: 3              Q.E.D.
+--   Step: 4              Q.E.D.
+--   Step: 5              Q.E.D.
+--   Step: 6              Q.E.D.
+--   Step: 7              Q.E.D.
+--   Step: 8              Q.E.D.
+--   Step: 9              Q.E.D.
+--   Result:              Q.E.D.
+-- Lemma: distribLeft     Q.E.D.
+-- Functions proven terminating: sNatPlus, sNatTimes
+-- [Proven] distribLeft :: Ɐm ∷ Nat → Ɐn ∷ Nat → Ɐo ∷ Nat → Bool
+distribLeft :: TP (Proof (Forall "m" Nat -> Forall "n" Nat -> Forall "o" Nat -> SBool))
+distribLeft = do
+   caseZero <- lemma "caseZero" (\(Forall @"n" n) (Forall @"o" (o :: SNat)) -> 0 * (n + o) .== 0 * n + 0 * o) []
+
+   addAsc <- recall addAssoc
+   addCom <- recall addComm
+
+   caseSucc <- calc "caseSucc"
+                    (\(Forall @"m" m) (Forall @"n" n) (Forall @"o" o) ->
+                        m * (n + o) .== m * n + m * o .=> sSucc m * (n + o) .== sSucc m * n + sSucc m * o) $
+               \m n o -> let ih = m * (n + o) .== m * n + m * o
+                      in [ih] |- sSucc m * (n + o)
+                              =: (n + o) + m * (n + o)
+                              ?? ih
+                              =: (n + o) + (m * n + m * o)
+                              ?? addAsc `at` (Inst @"m" n, Inst @"n" o, Inst @"o" (m * n + m * o))
+                              =: n + (o + (m * n + m * o))
+                              ?? addCom `at` (Inst @"m" (m * n), Inst @"n" (m * o))
+                              =: n + (o + (m * o + m * n))
+                              ?? addAsc `at` (Inst @"m" o, Inst @"n" (m * o), Inst @"o" (m * n))
+                              =: n + ((o + m * o) + m * n)
+                              =: n + (sSucc m * o + m * n)
+                              ?? addCom `at` (Inst @"m" (sSucc m * o), Inst @"n" (m * n))
+                              =: n + (m * n + sSucc m * o)
+                              ?? addAsc `at` (Inst @"m" n, Inst @"n" (m * n), Inst @"o" (sSucc m * o))
+                              =: (n + m * n) + sSucc m * o
+                              =: sSucc m * n + sSucc m * o
+                              =: qed
+
+   inductiveLemma
+     "distribLeft"
+     (\(Forall m) (Forall n) (Forall o) -> m * (n + o) .== m * n + m * o)
+     [proofOf caseZero, proofOf caseSucc]
+
+-- | \((m + n) * o = m * o + n * o\)
+--
+-- >>> runTP distribRight
+-- Lemma: caseZero        Q.E.D.
+-- Lemma: addAssoc        Q.E.D.
+-- Lemma: addComm         Q.E.D.
+-- Lemma: addSucc         Q.E.D. [Cached]
+-- Lemma: caseSucc
+--   Step: 1              Q.E.D.
+--   Step: 2              Q.E.D.
+--   Step: 3              Q.E.D.
+--   Step: 4              Q.E.D.
+--   Step: 5              Q.E.D.
+--   Step: 6              Q.E.D.
+--   Step: 7              Q.E.D.
+--   Result:              Q.E.D.
+-- Lemma: distribRight    Q.E.D.
+-- Functions proven terminating: sNatPlus, sNatTimes
+-- [Proven] distribRight :: Ɐm ∷ Nat → Ɐn ∷ Nat → Ɐo ∷ Nat → Bool
+distribRight :: TP (Proof (Forall "m" Nat -> Forall "n" Nat -> Forall "o" Nat -> SBool))
+distribRight = do
+   caseZero <- lemma "caseZero" (\(Forall @"n" n) (Forall @"o" (o :: SNat)) -> (0 + n) * o .== 0 * o + n * o) []
+
+   pAddAssoc <- recall addAssoc
+   pAddCom   <- recall addComm
+   pAddSucc  <- recall addSucc
+
+   caseSucc <- calc "caseSucc"
+                    (\(Forall @"m" m) (Forall @"n" n) (Forall @"o" o) ->
+                        (m + n) * o .== m * o + n * o .=> (sSucc m + n) * o .== sSucc m * o + n * o) $
+               \m n o -> let ih = (m + n) * o .== m * o + n * o
+                      in [ih] |- (sSucc m + n) * o
+                              ?? pAddCom `at` (Inst @"m" (sSucc m), Inst @"n" n)
+                              =: (n + sSucc m) * o
+                              ?? pAddSucc `at` (Inst @"m" n, Inst @"n" m)
+                              =: sSucc (n + m) * o
+                              ?? pAddCom `at` (Inst @"m" n, Inst @"n" m)
+                              =: sSucc (m + n) * o
+                              =: o + (m + n) * o
+                              ?? ih
+                              =: o + (m * o + n *o)
+                              ?? pAddAssoc `at` (Inst @"m" o, Inst @"n" (m * o), Inst @"o" (n * o))
+                              =: (o + m * o) + n * o
+                              =: sSucc m * o + n * o
+                              =: qed
+
+   inductiveLemma
+     "distribRight"
+     (\(Forall m) (Forall n) (Forall o) -> (m + n) * o .== m * o + n * o)
+     [proofOf caseZero, proofOf caseSucc]
+
+-- ** Multiplication with non-zero values
+
+-- | \(m * \mathrm{Succ}\,n = m * n + m\)
+--
+-- >>> runTP mulSucc
+-- Lemma: addLeftUnit       Q.E.D.
+-- Lemma: distribLeft       Q.E.D.
+-- Lemma: mulRightUnit      Q.E.D.
+-- Lemma: addComm           Q.E.D. [Cached]
+-- Lemma: mulSucc
+--   Step: 1                Q.E.D.
+--   Step: 2 (defn of +)    Q.E.D.
+--   Step: 3                Q.E.D.
+--   Step: 4                Q.E.D.
+--   Step: 5                Q.E.D.
+--   Result:                Q.E.D.
+-- Functions proven terminating: sNatPlus, sNatTimes
+-- [Proven] mulSucc :: Ɐm ∷ Nat → Ɐn ∷ Nat → Bool
+mulSucc :: TP (Proof (Forall "m" Nat -> Forall "n" Nat -> SBool))
+mulSucc = do
+   alu <- recall addLeftUnit
+   dL  <- recall distribLeft
+   mru <- recall mulRightUnit
+   ac  <- recall addComm
+
+   calc "mulSucc"
+        (\(Forall @"m" m) (Forall @"n" n) -> m * sSucc n .== m * n + m) $
+        \m n -> [] |- m * sSucc n
+                   ?? alu
+                   =: m * sSucc (0 + n)
+                   ?? "defn of +"
+                   =: m * (sSucc 0 + n)
+                   ?? dL `at` (Inst @"m" m, Inst @"n" (sSucc 0), Inst @"o" n)
+                   =: m * sSucc 0 + m * n
+                   ?? mru
+                   =: m + m * n
+                   ?? ac `at` (Inst @"m" m, Inst @"n" (m * n))
+                   =: m * n + m
+                   =: qed
+
+-- ** Associativity
+
+-- | \(m * (n * o) = (m * n) * o\)
+--
+-- >>> runTP mulAssoc
+-- Lemma: caseZero        Q.E.D.
+-- Lemma: distribRight    Q.E.D.
+-- Lemma: caseSucc
+--   Step: 1              Q.E.D.
+--   Step: 2              Q.E.D.
+--   Step: 3              Q.E.D.
+--   Step: 4              Q.E.D.
+--   Result:              Q.E.D.
+-- Lemma: mulAssoc        Q.E.D.
+-- Functions proven terminating: sNatPlus, sNatTimes
+-- [Proven] mulAssoc :: Ɐm ∷ Nat → Ɐn ∷ Nat → Ɐo ∷ Nat → Bool
+mulAssoc :: TP (Proof (Forall "m" Nat -> Forall "n" Nat -> Forall "o" Nat -> SBool))
+mulAssoc = do
+   caseZero <- lemma "caseZero"
+                     (\(Forall @"n" n) (Forall @"o" (o :: SNat)) -> 0 * (n * o) .== (0 * n) * o)
+                     []
+
+   distR <- recall distribRight
+
+   caseSucc <- calc "caseSucc"
+                    (\(Forall @"m" m) (Forall @"n" n) (Forall @"o" o) ->
+                       m * (n * o) .== (m * n) * o .=> sSucc m * (n * o) .== (sSucc m * n) * o) $
+                    \m n o -> let ih = m * (n * o) .== (m * n) * o
+                              in [ih] |- sSucc m * (n * o)
+                                      =: (n * o) + m * (n * o)
+                                      ?? ih
+                                      =: (n * o) + (m * n) * o
+                                      ?? distR `at` (Inst @"m" n, Inst @"n" (m * n), Inst @"o" o)
+                                      =: (n + m * n) * o
+                                      =: (sSucc m * n) * o
+                                      =: qed
+
+   inductiveLemma
+     "mulAssoc"
+     (\(Forall m) (Forall n) (Forall o) -> m * (n * o) .== (m * n) * o)
+     [proofOf caseZero, proofOf caseSucc]
+
+-- ** Commutativity
+
+-- | \(m * n = n * m\)
+--
+-- >>> runTP mulComm
+-- Lemma: mulRightAbsorb    Q.E.D.
+-- Lemma: caseZero          Q.E.D.
+-- Lemma: mulRightUnit      Q.E.D.
+-- Lemma: distribLeft       Q.E.D.
+-- Lemma: caseSucc
+--   Step: 1                Q.E.D.
+--   Step: 2                Q.E.D.
+--   Step: 3                Q.E.D.
+--   Step: 4                Q.E.D.
+--   Step: 5                Q.E.D.
+--   Step: 6                Q.E.D.
+--   Result:                Q.E.D.
+-- Lemma: mulComm           Q.E.D.
+-- Functions proven terminating: sNatPlus, sNatTimes
+-- [Proven] mulComm :: Ɐm ∷ Nat → Ɐn ∷ Nat → Bool
+mulComm :: TP (Proof (Forall "m" Nat -> Forall "n" Nat -> SBool))
+mulComm = do
+  mra <- recall mulRightAbsorb
+
+  caseZero <- lemma "caseZero"
+                    (\(Forall @"m" (m :: SNat)) -> 0 * m .== m * 0)
+                    [proofOf mra]
+
+  mru <- recall mulRightUnit
+  dL  <- recall distribLeft
+
+  caseSucc <- calc "caseSucc"
+                   (\(Forall @"m" m) (Forall @"n" n) -> m * n .== n * m .=> sSucc m * n .== n * sSucc m) $
+                   \m n -> let ih = m * n .== n * m
+                        in [ih] |- sSucc m * n
+                                =: n + m * n
+                                ?? ih
+                                =: n + n * m
+                                ?? mru
+                                =: n * sSucc 0 + n * m
+                                ?? dL `at` (Inst @"m" n, Inst @"n" (sSucc 0), Inst @"o" m)
+                                =: n * (sSucc 0 + m)
+                                =: n * sSucc (0 + m)
+                                =: n * sSucc m
+                                =: qed
+
+  inductiveLemma
+    "mulComm"
+    (\(Forall @"m" m) (Forall @"n" n) -> m * n .== n * m)
+    [proofOf caseZero, proofOf caseSucc]
+
+-- * Ordering
+
+-- ** Transitivity of @<@
+
+-- | \(m < n \;\wedge\; n < o \;\rightarrow\; m < o\)
+--
+-- >>> runTP ltTrans
+-- Lemma: addAssoc     Q.E.D.
+-- Lemma: ltTrans
+--   Step: 1           Q.E.D.
+--   Step: 2           Q.E.D.
+--   Step: 3           Q.E.D.
+--   Step: 4           Q.E.D.
+--   Step: 5           Q.E.D.
+--   Step: 6           Q.E.D.
+--   Result:           Q.E.D.
+-- Functions proven terminating: sNatPlus
+-- [Proven] ltTrans :: Ɐm ∷ Nat → Ɐn ∷ Nat → Ɐo ∷ Nat → Bool
+ltTrans :: TP (Proof (Forall "m" Nat -> Forall "n" Nat -> Forall "o" Nat -> SBool))
+ltTrans = do
+  aa <- recall addAssoc
+
+  calc "ltTrans"
+       (\(Forall @"m" m) (Forall @"n" n) (Forall @"o" o) -> m .< n .&& n .< o .=> m .< o) $
+       \m n o ->  [m .< n, n .< o]
+              |-> let k1 = some "k1" (\k -> n .== m + sSucc k)
+                      k2 = some "k2" (\k -> o .== n + sSucc k)
+               in n .== m + sSucc k1
+               =: o .== n + sSucc k2
+               =: o .== (m + sSucc k1) + sSucc k2
+               ?? aa `at` (Inst @"m" m, Inst @"n" (sSucc k1), Inst @"o" (sSucc k2))
+               =: o .== m + (sSucc k1 + sSucc k2)
+               =: o .== m + sSucc (k1 + sSucc k2)
+               =: m .< o
+               =: sTrue
+               =: qed
+
+-- ** Irreflexivity of @<@
+
+-- | \(\neg(m < m)\)
+--
+-- >>> runTP ltIrreflexive
+-- Lemma: cancel           Q.E.D.
+-- Lemma: ltIrreflexive
+--   Step: 1               Q.E.D.
+--   Step: 2               Q.E.D.
+--   Result:               Q.E.D.
+-- Functions proven terminating: sNatPlus
+-- [Proven] ltIrreflexive :: Ɐm ∷ Nat → Bool
+ltIrreflexive :: TP (Proof (Forall "m" Nat -> SBool))
+ltIrreflexive = do
+  cancel <- inductiveLemma
+              "cancel"
+              (\(Forall @"m" m) (Forall @"n" n) -> m + n .== m .=> n .== 0)
+              []
+
+  calc "ltIrreflexive"
+       (\(Forall @"m" m) -> sNot (m .< m)) $
+       \m -> [m .< m] |-> let k = some "k" (\d -> m .== m + sSucc d)
+                      in m .== m + sSucc k
+                      ?? cancel `at` (Inst @"m" m, Inst @"n" (sSucc k))
+                      =: sSucc k .== 0
+                      =: contradiction
+
+-- ** Trichotomy
+
+-- | \(m \geq n = \overline{m} \geq \overline{n}\)
+--
+-- >>> runTP lteEquiv
+-- Lemma: n2iAdd               Q.E.D.
+-- Lemma: n2iNonNeg            Q.E.D.
+-- Lemma: n2i2n                Q.E.D.
+-- Lemma: i2n2i                Q.E.D.
+-- Lemma: addRightUnit         Q.E.D.
+-- Lemma: lteEquiv_ltr
+--   Step: 1 (2 way case split)
+--     Step: 1.1               Q.E.D.
+--     Step: 1.2.1             Q.E.D.
+--     Step: 1.2.2             Q.E.D.
+--     Step: 1.2.3             Q.E.D.
+--     Step: 1.2.4             Q.E.D.
+--     Step: 1.Completeness    Q.E.D.
+--   Result:                   Q.E.D.
+-- Lemma: lteEquiv_rtl
+--   Step: 1                   Q.E.D.
+--   Step: 2                   Q.E.D.
+--   Step: 3                   Q.E.D.
+--   Step: 4                   Q.E.D.
+--   Step: 5                   Q.E.D.
+--   Step: 6                   Q.E.D.
+--   Step: 7 (2 way case split)
+--     Step: 7.1               Q.E.D.
+--     Step: 7.2.1             Q.E.D.
+--     Step: 7.2.2             Q.E.D.
+--     Step: 7.2.3             Q.E.D.
+--     Step: 7.2.4             Q.E.D.
+--     Step: 7.2.5             Q.E.D.
+--     Step: 7.Completeness    Q.E.D.
+--   Result:                   Q.E.D.
+-- Lemma: lteEquiv             Q.E.D.
+-- Functions proven terminating: i2n, n2i, sNatPlus
+-- [Proven] lteEquiv :: Ɐm ∷ Nat → Ɐn ∷ Nat → Bool
+lteEquiv :: TP (Proof (Forall "m" Nat -> Forall "n" Nat -> SBool))
+lteEquiv = do
+    n2ia    <- recall n2iAdd
+    nn      <- recall n2iNonNeg
+    n2i2nId <- recall n2i2n
+    i2n2iId <- recall i2n2i
+    aru     <- recall addRightUnit
+
+    ltr <- calcWith cvc5 "lteEquiv_ltr"
+              (\(Forall @"m" m) (Forall @"n" n) -> (m .>= n) .=> (n2i m .>= n2i n)) $
+              \m n -> [m .>= n]
+                   |- n2i m .>= n2i n
+                    =: cases [ m .== n ==> trivial
+                             , m .>  n ==> let k = some "k" (\d -> m .== n + sSucc d)
+                                        in n2i m .>= n2i n
+                                        ?? m .> n
+                                        =: n2i (n + sSucc k) .>= n2i n
+                                        ?? n2ia `at` (Inst @"m" n, Inst @"n" (sSucc k))
+                                        =: n2i n + n2i (sSucc k) .>= n2i n
+                                        ?? nn `at` Inst @"n" (sSucc k)
+                                        =: sTrue
+                                        =: qed
+                             ]
+
+    rtl <- calc "lteEquiv_rtl"
+                (\(Forall @"m" m) (Forall @"n" n) -> (n2i m .>= n2i n) .=> (m .>= n)) $
+                \m n -> [n2i m .>= n2i n]
+                     |-> let k = n2i m - n2i n
+                     in k .>= 0
+                     =: n2i m .== n2i n + k
+                     ?? i2n2iId `at` Inst @"i" k
+                     =: n2i m .== n2i n + n2i (i2n k)
+                     ?? n2ia `at` (Inst @"m" n, Inst @"n" (i2n k))
+                     =: n2i m .== n2i (n + i2n k)
+                     =: i2n (n2i m) .== i2n (n2i (n + i2n k))
+                     ?? n2i2nId `at` Inst @"n" m
+                     =: m .== i2n (n2i (n + i2n k))
+                     ?? n2i2nId `at` Inst @"n" (n + i2n k)
+                     =: m .== n + i2n k
+                     =: cases [ k .>  0 ==> trivial
+                              , k .<= 0 ==> m .== n + i2n k
+                                         ?? i2n k .== 0
+                                         =: m .== n + 0
+                                         ?? aru
+                                         =: m .== n
+                                         =: m .== n .|| m .> n
+                                         =: m .>= n
+                                         =: qed
+                              ]
+
+    lemma "lteEquiv"
+          (\(Forall m) (Forall n) -> (n2i m .>= n2i n) .== (m .>= n))
+          [proofOf ltr, proofOf rtl]
+
+-- | \(m \geq n \;\lor\; n \geq m\)
+--
+-- >>> runTP ordered
+-- Lemma: lteEquiv             Q.E.D.
+-- Lemma: ordered
+--   Step: 1                   Q.E.D.
+--   Step: 2                   Q.E.D.
+--   Result:                   Q.E.D.
+-- Functions proven terminating: i2n, n2i, sNatPlus
+-- [Proven] ordered :: Ɐm ∷ Nat → Ɐn ∷ Nat → Bool
+ordered :: TP (Proof (Forall "m" Nat -> Forall "n" Nat -> SBool))
+ordered = do
+   lteEq <- recall lteEquiv
+
+   calcWith cvc5 "ordered"
+        (\(Forall m) (Forall n) -> m .>= n .|| n .>= m) $
+        \m n -> [] |- (m .>= n .|| n .>= m)
+                   ?? lteEq `at` (Inst @"m" m, Inst @"n" n)
+                   =: (n2i m .>= n2i n .|| n .>= m)
+                   ?? lteEq `at` (Inst @"m" n, Inst @"n" m)
+                   =: (n2i m .>= n2i n .|| n2i n .>= n2i m)
+                   =: qed
+
+-- | \(m < n \;\lor\; m = n \;\lor\; n < m\)
+--
+-- >>> runTP trichotomy
+-- Lemma: ordered              Q.E.D.
+-- Lemma: trichotomy           Q.E.D.
+-- Functions proven terminating: i2n, n2i, sNatPlus
+-- [Proven] trichotomy :: Ɐm ∷ Nat → Ɐn ∷ Nat → Bool
+trichotomy :: TP (Proof (Forall "m" Nat -> Forall "n" Nat -> SBool))
+trichotomy = do
+   pOrdered <- recall ordered
+
+   lemma "trichotomy"
+         (\(Forall m) (Forall n) -> m .< n .|| m .== n .|| n .< m)
+         [proofOf pOrdered]
+
+-- ** Addition and ordering
+
+-- | \(m < n \;\rightarrow\; m + o < n + o\)
+--
+-- >>> runTP addOrder
+-- Lemma: addAssoc        Q.E.D.
+-- Lemma: addComm         Q.E.D.
+-- Lemma: addOrder
+--   Step: 1              Q.E.D.
+--   Step: 2              Q.E.D.
+--   Step: 3              Q.E.D.
+--   Step: 4              Q.E.D.
+--   Step: 5              Q.E.D.
+--   Result:              Q.E.D.
+-- Functions proven terminating: sNatPlus
+-- [Proven] addOrder :: Ɐm ∷ Nat → Ɐn ∷ Nat → Ɐo ∷ Nat → Bool
+addOrder :: TP (Proof (Forall "m" Nat -> Forall "n" Nat -> Forall "o" Nat -> SBool))
+addOrder = do
+  pAddAssoc <- recall addAssoc
+  pAddComm  <- recall addComm
+
+  calc "addOrder"
+       (\(Forall m) (Forall n) (Forall o) -> m .< n .=> m + o .< n + o) $
+       \m n o -> [m .< n]
+              |-> let k = some "k" (\d -> n .== m + sSucc d)
+               in n .== m + sSucc k
+               =: n + o .== (m + sSucc k) + o
+               ?? pAddAssoc `at` (Inst @"m" m, Inst @"n" (sSucc k), Inst @"o" o)
+               =: n + o .== m + (sSucc k + o)
+               ?? pAddComm `at` (Inst @"m" (sSucc k), Inst @"n" o)
+               =: n + o .== m + (o + sSucc k)
+               ?? pAddAssoc `at` (Inst @"m" m, Inst @"n" o, Inst @"o" (sSucc k))
+               =: n + o .== (m + o) + sSucc k
+               =: m + o .<= n + o
+               =: qed
+
+-- ** Multiplication and ordering
+
+-- | \(o > 0 \;\wedge\; m < n \;\rightarrow\; m * o < n * o\)
+--
+-- >>> runTP mulOrder
+-- Lemma: distribRight    Q.E.D.
+-- Lemma: mulOrder
+--   Step: 1              Q.E.D.
+--   Step: 2              Q.E.D.
+--   Step: 3              Q.E.D.
+--   Step: 4              Q.E.D.
+--   Step: 5              Q.E.D.
+--   Step: 6              Q.E.D.
+--   Result:              Q.E.D.
+-- Functions proven terminating: sNatPlus, sNatTimes
+-- [Proven] mulOrder :: Ɐm ∷ Nat → Ɐn ∷ Nat → Ɐo ∷ Nat → Bool
+mulOrder :: TP (Proof (Forall "m" Nat -> Forall "n" Nat -> Forall "o" Nat -> SBool))
+mulOrder = do
+  pDistribRight <- recall distribRight
+
+  calc "mulOrder"
+       (\(Forall m) (Forall n) (Forall o) -> 0 .< o .&& m .< n .=> m * o .< n * o) $
+       \m n o -> [0 .< o, m .< n]
+              |-> let k = some "k" (\d -> n .== m + sSucc d)
+               in n .== m + sSucc k
+               =: n * o .== (m + sSucc k) * o
+               ?? pDistribRight `at` (Inst @"m" m, Inst @"n" (sSucc k), Inst @"o" o)
+               =: n * o .== m * o + sSucc k * o
+               ?? 0 .< o
+               =: n * o .== m * o + sSucc k * sSucc (sprev o)
+               =: n * o .== m * o + (sSucc (sprev o) + k * sSucc (sprev o))
+               =: n * o .== m * o + sSucc (sprev o + k * sSucc (sprev o))
+               =: m * o .< n * o
+               =: qed
+
+-- ** Order and sum
+
+-- | \(m < n \;\rightarrow\; \exists o.\; m + o = n\)
+--
+-- >>> runTP orderSum
+-- Lemma: orderSum     Q.E.D.
+-- Functions proven terminating: sNatPlus
+-- [Proven] orderSum :: Ɐm ∷ Nat → Ɐn ∷ Nat → Bool
+orderSum :: TP (Proof (Forall "m" Nat -> Forall "n" Nat -> SBool))
+orderSum = lemma "orderSum"
+                 (\(Forall m) (Forall n) -> m .< n .=> quantifiedBool (\(Exists o) -> m + o .== n))
+                 []
+
+-- ** 0 and 1 relationship
+
+-- | \(0 < 1\)
+--
+-- >>> runTP zeroLtOne
+-- Lemma: zeroLtOne    Q.E.D.
+-- Functions proven terminating: sNatPlus
+-- [Proven] zeroLtOne :: Bool
+zeroLtOne :: TP (Proof SBool)
+zeroLtOne = lemma "zeroLtOne" (0 .< (1 :: SNat)) []
+
+-- | \(m > 0 \;\rightarrow\; m \geq 1\)
+--
+-- >>> runTP nothingBetweenZeroAndOne
+-- Lemma: nothingBetweenZeroAndOne    Q.E.D.
+-- Functions proven terminating: sNatPlus
+-- [Proven] nothingBetweenZeroAndOne :: Ɐm ∷ Nat → Bool
+nothingBetweenZeroAndOne :: TP (Proof (Forall "m" Nat -> SBool))
+nothingBetweenZeroAndOne = lemma "nothingBetweenZeroAndOne"
+                                 (\(Forall m) -> m .> 0 .=> m .>= 1)
+                                 []
+
+-- ** 0 is the minimum
+
+-- | \(m \geq 0\)
+--
+-- >>> runTP minimumElt
+-- Lemma: minimumElt    Q.E.D.
+-- Functions proven terminating: sNatPlus
+-- [Proven] minimumElt :: Ɐm ∷ Nat → Bool
+minimumElt :: TP (Proof (Forall "m" Nat -> SBool))
+minimumElt = lemma "minimumElt" (\(Forall m) -> m .>= 0) []
+
+-- ** There is no maximum element
+
+-- | \(\forall m \;\exists n \;.\; m < n\)
+--
+-- >>> runTP noMaximumElt
+-- Lemma: noMaximumElt    Q.E.D.
+-- Functions proven terminating: sNatPlus
+-- [Proven] noMaximumElt :: Ɐm ∷ Nat → ∃n ∷ Nat → Bool
+noMaximumElt :: TP (Proof (Forall "m" Nat -> Exists "n" Nat -> SBool))
+noMaximumElt = lemma "noMaximumElt" (\(Forall m) (Exists n) -> m .< n) []
diff --git a/Documentation/SBV/Examples/TP/PigeonHole.hs b/Documentation/SBV/Examples/TP/PigeonHole.hs
new file mode 100644
--- /dev/null
+++ b/Documentation/SBV/Examples/TP/PigeonHole.hs
@@ -0,0 +1,53 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Documentation.SBV.Examples.TP.PigeonHole
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Proves the pigeon-hole principle. If a list of integers sum to more than the length
+-- of the list itself, then some cell must contain a value larger than @1@.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE CPP       #-}
+{-# LANGUAGE DataKinds #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Documentation.SBV.Examples.TP.PigeonHole where
+
+import Prelude hiding (sum, length, elem, null, any)
+
+import Data.SBV
+import Data.SBV.List
+import Data.SBV.TP
+
+#ifdef DOCTEST
+-- $setup
+-- >>> import Data.SBV.TP
+#endif
+
+-- | Overflow: Some value is greater than 1.
+overflow :: SList Integer -> SBool
+overflow = any (.> 1)
+
+-- | \(\sum xs > \lvert xs \rvert \Rightarrow \textrm{overflow}\, xs\)
+--
+-- >>> runTP pigeonHole
+-- Inductive lemma: pigeonHole
+--   Step: Base                   Q.E.D.
+--   Step: 1                      Q.E.D.
+--   Step: 2                      Q.E.D.
+--   Result:                      Q.E.D.
+-- Functions proven terminating: sbv.foldr
+--[Proven] pigeonHole :: Ɐxs ∷ [Integer] → Bool
+pigeonHole :: TP (Proof (Forall "xs" [Integer] -> SBool))
+pigeonHole = induct "pigeonHole"
+                   (\(Forall xs) -> sum xs .> length xs .=> overflow xs) $
+                   \ih (x, xs) -> [sum xs .> length xs]
+                               |- overflow (x .: xs)
+                               =: (x .> 1 .|| overflow xs)
+                               ?? ih
+                               =: sTrue
+                               =: qed
diff --git a/Documentation/SBV/Examples/TP/PowerMod.hs b/Documentation/SBV/Examples/TP/PowerMod.hs
--- a/Documentation/SBV/Examples/TP/PowerMod.hs
+++ b/Documentation/SBV/Examples/TP/PowerMod.hs
@@ -9,13 +9,14 @@
 -- Proofs about power and modulus. Adapted from an example by amigalemming,
 -- see <http://github.com/LeventErkok/sbv/issues/744>.
 --
--- We also demonstrate the proof-caching features of TP.
+-- We also demonstrate the use of recall for reusing previously established proofs.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DataKinds           #-}
-{-# LANGUAGE TypeAbstractions    #-}
-{-# LANGUAGE TypeApplications    #-}
-{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE CPP              #-}
+{-# LANGUAGE DataKinds        #-}
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE TypeAbstractions #-}
+{-# LANGUAGE TypeApplications #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -24,54 +25,85 @@
 import Data.SBV
 import Data.SBV.TP
 
--- | The proofs in this module are structured so they are presented at the top-level and reused.
--- This results in re-running the proofs over and over, as each proof has to run all its dependents.
--- To avoid re-running proofs, we tell TP to use a proof-cache. Note that use of a proof-cache comes
--- with the user obligation that all proofs used are uniquely named. Otherwise the results can be
--- unsound, and SBV will indicate this possibility in its output.
-runCached :: TP a -> IO a
-runCached = runTPWith (tpCache z3)
+#ifdef DOCTEST
+-- $setup
+-- >>> import Data.SBV.TP
+#endif
 
 -- | Power function over integers.
 power :: SInteger -> SInteger -> SInteger
-power = smtFunction "power" $ \b n -> ite (n .<= 0) 1 (b * power b (n-1))
+power = smtFunction "power" $ \b n -> [sCase| n of
+                                         _ | n .<= 0 -> 1
+                                         _           -> b * power b (n-1)
+                                      |]
 
 -- | \(m > 1 \Rightarrow n + mk \equiv n \pmod{m}\)
 --
 -- ==== __Proof__
--- >>> runCached modAddMultiple
--- Inductive lemma: modAddMultiple
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
+-- >>> runTP modAddMultiple
+-- Inductive lemma: modAddMultiplePos
+--   Step: Base                          Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Step: 3                             Q.E.D.
+--   Result:                             Q.E.D.
+-- Lemma: modAddMultiple
+--   Step: 1 (2 way case split)
+--     Step: 1.1                         Q.E.D.
+--     Step: 1.2                         Q.E.D.
+--     Step: 1.Completeness              Q.E.D.
+--   Result:                             Q.E.D.
 -- [Proven] modAddMultiple :: Ɐk ∷ Integer → Ɐn ∷ Integer → Ɐm ∷ Integer → Bool
 modAddMultiple :: TP (Proof (Forall "k" Integer -> Forall "n" Integer -> Forall "m" Integer -> SBool))
 modAddMultiple = do
-   inductWith (tpCache cvc5) "modAddMultiple"
+   -- First prove for k >= 0 by induction. We need this restriction since
+   -- the inductive hypothesis for integers is guarded by k >= 0.
+   pos <- induct "modAddMultiplePos"
+             (\(Forall k) (Forall n) (Forall m) -> k .>= 0 .&& m .> 1 .=> (n + m*k) `sEMod` m .== n `sEMod` m) $
+             \ih k n m -> [k .>= 0, m .> 1] |- (n + m*(k+1)) `sEMod` m
+                                             =: (n + m*k + m) `sEMod` m
+                                             ?? m `sEMod` m .== 0
+                                             ?? (n + m*k + m) `sEDiv` m .== (n + m*k) `sEDiv` m + 1
+                                             =: (n + m*k) `sEMod` m
+                                             ?? ih `at` (Inst @"n" n, Inst @"m" m)
+                                             =: n `sEMod` m
+                                             =: qed
+
+   -- Extend to all k by case-splitting. For k < 0, use the positive case with
+   -- k' = -k > 0 and n' = n+m*k: pos gives (n'+m*k') mod m = n' mod m,
+   -- i.e., n mod m = (n+m*k) mod m.
+   calc "modAddMultiple"
       (\(Forall k) (Forall n) (Forall m) -> m .> 1 .=> (n + m*k) `sEMod` m .== n `sEMod` m) $
-      \ih k n m -> [m .> 1] |- (n + m*(k+1)) `sEMod` m
-                              =: (n + m*k + m) `sEMod` m
-                              =: (n + m*k) `sEMod` m
-                              ?? ih `at` (Inst @"n" n, Inst @"m" m)
-                              =: n `sEMod` m
-                              =: qed
+      \k n m -> [m .> 1] |- cases [ k .>= 0 ==> (n + m*k) `sEMod` m
+                                             ?? pos `at` (Inst @"k" k, Inst @"n" n, Inst @"m" m)
+                                             =: n `sEMod` m
+                                             =: qed
+                                  , k .< 0  ==> (n + m*k) `sEMod` m
+                                             ?? pos `at` (Inst @"k" (-k), Inst @"n" (n + m*k), Inst @"m" m)
+                                             =: n `sEMod` m
+                                             =: qed
+                                  ]
 
 -- | \(m > 0 \Rightarrow a + b \equiv a + (b \bmod m) \pmod{m}\)
 --
 -- ==== __Proof__
--- >>> runCached modAddRight
--- Inductive lemma: modAddMultiple
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
+-- >>> runTP modAddRight
+-- Inductive lemma: modAddMultiplePos
+--   Step: Base                          Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Step: 3                             Q.E.D.
+--   Result:                             Q.E.D.
+-- Lemma: modAddMultiple
+--   Step: 1 (2 way case split)
+--     Step: 1.1                         Q.E.D.
+--     Step: 1.2                         Q.E.D.
+--     Step: 1.Completeness              Q.E.D.
+--   Result:                             Q.E.D.
 -- Lemma: modAddRight
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Result:                             Q.E.D.
 -- [Proven] modAddRight :: Ɐa ∷ Integer → Ɐb ∷ Integer → Ɐm ∷ Integer → Bool
 modAddRight :: TP (Proof (Forall "a" Integer -> Forall "b" Integer -> Forall "m" Integer -> SBool))
 modAddRight = do
@@ -87,22 +119,28 @@
 -- | \(m > 0 \Rightarrow a + b \equiv (a \bmod m) + b \pmod{m}\)
 --
 -- ==== __Proof__
--- >>> runCached modAddLeft
--- Inductive lemma: modAddMultiple
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
+-- >>> runTP modAddLeft
+-- Inductive lemma: modAddMultiplePos
+--   Step: Base                          Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Step: 3                             Q.E.D.
+--   Result:                             Q.E.D.
+-- Lemma: modAddMultiple
+--   Step: 1 (2 way case split)
+--     Step: 1.1                         Q.E.D.
+--     Step: 1.2                         Q.E.D.
+--     Step: 1.Completeness              Q.E.D.
+--   Result:                             Q.E.D.
 -- Lemma: modAddRight
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Result:                             Q.E.D.
 -- Lemma: modAddLeft
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Step: 3                             Q.E.D.
+--   Result:                             Q.E.D.
 -- [Proven] modAddLeft :: Ɐa ∷ Integer → Ɐb ∷ Integer → Ɐm ∷ Integer → Bool
 modAddLeft :: TP (Proof (Forall "a" Integer -> Forall "b" Integer -> Forall "m" Integer -> SBool))
 modAddLeft = do
@@ -119,27 +157,34 @@
 -- | \(m > 0 \Rightarrow a - b \equiv a - (b \bmod m) \pmod{m}\)
 --
 -- ==== __Proof__
--- >>> runCached modSubRight
--- Inductive lemma: modAddMultiple
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
+-- >>> runTP modSubRight
+-- Inductive lemma: modAddMultiplePos
+--   Step: Base                          Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Step: 3                             Q.E.D.
+--   Result:                             Q.E.D.
+-- Lemma: modAddMultiple
+--   Step: 1 (2 way case split)
+--     Step: 1.1                         Q.E.D.
+--     Step: 1.2                         Q.E.D.
+--     Step: 1.Completeness              Q.E.D.
+--   Result:                             Q.E.D.
 -- Lemma: modSubRight
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Step: 3                             Q.E.D.
+--   Result:                             Q.E.D.
 -- [Proven] modSubRight :: Ɐa ∷ Integer → Ɐb ∷ Integer → Ɐm ∷ Integer → Bool
 modSubRight :: TP (Proof (Forall "a" Integer -> Forall "b" Integer -> Forall "m" Integer -> SBool))
 modSubRight = do
    mAddMul <- modAddMultiple
    calc "modSubRight"
       (\(Forall a) (Forall b) (Forall m) -> m .> 0 .=>  (a-b) `sEMod` m .== (a - b `sEMod` m) `sEMod` m) $
-      \a b m -> [m .> 0] |- (a-b) `sEMod` m
+      \a b m -> [m .> 0] |- (a - b) `sEMod` m
+                         ?? b .== b `sEMod` m + m * b `sEDiv` m
                          =: (a - (b `sEMod` m + m * b `sEDiv` m)) `sEMod` m
-                         =: ((a - b `sEMod` m) + m*(- (b `sEDiv` m))) `sEMod` m
+                         =: ((a - b `sEMod` m) + m * (- (b `sEDiv` m))) `sEMod` m
                          ?? mAddMul `at` (Inst @"k" (- (b `sEDiv` m)), Inst @"n" (a - b `sEMod` m), Inst @"m" m)
                          =: (a - b `sEMod` m) `sEMod` m
                          =: qed
@@ -147,38 +192,43 @@
 -- | \(a \geq 0 \land m > 0 \Rightarrow ab \equiv a \cdot (b \bmod m) \pmod{m}\)
 --
 -- ==== __Proof__
--- >>> runCached modMulRightNonneg
--- Inductive lemma: modAddMultiple
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
+-- >>> runTP modMulRightNonneg
+-- Inductive lemma: modAddMultiplePos
+--   Step: Base                          Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Step: 3                             Q.E.D.
+--   Result:                             Q.E.D.
+-- Lemma: modAddMultiple
+--   Step: 1 (2 way case split)
+--     Step: 1.1                         Q.E.D.
+--     Step: 1.2                         Q.E.D.
+--     Step: 1.Completeness              Q.E.D.
+--   Result:                             Q.E.D.
 -- Lemma: modAddRight
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Result:                             Q.E.D.
 -- Lemma: modAddLeft
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Cached: modAddRight                     Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Step: 3                             Q.E.D.
+--   Result:                             Q.E.D.
+-- Lemma: modAddRight                    Q.E.D. [Cached]
 -- Inductive lemma: modMulRightNonneg
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Step: 6                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven. Cached: modAddRight] modMulRightNonneg :: Ɐa ∷ Integer → Ɐb ∷ Integer → Ɐm ∷ Integer → Bool
+--   Step: Base                          Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Step: 3                             Q.E.D.
+--   Step: 4                             Q.E.D.
+--   Step: 5                             Q.E.D.
+--   Step: 6                             Q.E.D.
+--   Result:                             Q.E.D.
+-- [Proven] modMulRightNonneg :: Ɐa ∷ Integer → Ɐb ∷ Integer → Ɐm ∷ Integer → Bool
 modMulRightNonneg :: TP (Proof (Forall "a" Integer -> Forall "b" Integer -> Forall "m" Integer -> SBool))
 modMulRightNonneg = do
    mAddL <- modAddLeft
-   mAddR <- modAddRight
+   mAddR <- recall modAddRight
 
    induct "modMulRightNonneg"
       (\(Forall a) (Forall b) (Forall m) -> a .>= 0 .&& m .> 0 .=> (a*b) `sEMod` m .== (a * b `sEMod` m) `sEMod` m) $
@@ -198,42 +248,43 @@
 -- | \(a \geq 0 \land m > 0 \Rightarrow -ab \equiv -\left(a \cdot (b \bmod m)\right) \pmod{m}\)
 --
 -- ==== __Proof__
--- >>> runCached modMulRightNeg
--- Inductive lemma: modAddMultiple
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
+-- >>> runTP modMulRightNeg
+-- Inductive lemma: modAddMultiplePos
+--   Step: Base                          Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Step: 3                             Q.E.D.
+--   Result:                             Q.E.D.
+-- Lemma: modAddMultiple
+--   Step: 1 (2 way case split)
+--     Step: 1.1                         Q.E.D.
+--     Step: 1.2                         Q.E.D.
+--     Step: 1.Completeness              Q.E.D.
+--   Result:                             Q.E.D.
 -- Lemma: modAddRight
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Result:                             Q.E.D.
 -- Lemma: modAddLeft
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Lemma: modSubRight
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Step: 3                             Q.E.D.
+--   Result:                             Q.E.D.
+-- Lemma: modSubRight                    Q.E.D.
 -- Inductive lemma: modMulRightNeg
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Step: 6                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven. Cached: modAddMultiple] modMulRightNeg :: Ɐa ∷ Integer → Ɐb ∷ Integer → Ɐm ∷ Integer → Bool
+--   Step: Base                          Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Step: 3                             Q.E.D.
+--   Step: 4                             Q.E.D.
+--   Step: 5                             Q.E.D.
+--   Step: 6                             Q.E.D.
+--   Result:                             Q.E.D.
+-- [Proven] modMulRightNeg :: Ɐa ∷ Integer → Ɐb ∷ Integer → Ɐm ∷ Integer → Bool
 modMulRightNeg :: TP (Proof (Forall "a" Integer -> Forall "b" Integer -> Forall "m" Integer -> SBool))
 modMulRightNeg = do
    mAddL <- modAddLeft
-   mSubR <- modSubRight
+   mSubR <- recall modSubRight
 
    induct "modMulRightNeg"
       (\(Forall a) (Forall b) (Forall m) -> a .>= 0 .&& m .> 0 .=> (-(a*b)) `sEMod` m .== (-(a * b `sEMod` m)) `sEMod` m) $
@@ -253,64 +304,52 @@
 -- | \(m > 0 \Rightarrow ab \equiv a \cdot (b \bmod m) \pmod{m}\)
 --
 -- ==== __Proof__
--- >>> runCached modMulRight
--- Inductive lemma: modAddMultiple
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
+-- >>> runTP modMulRight
+-- Inductive lemma: modAddMultiplePos
+--   Step: Base                          Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Step: 3                             Q.E.D.
+--   Result:                             Q.E.D.
+-- Lemma: modAddMultiple
+--   Step: 1 (2 way case split)
+--     Step: 1.1                         Q.E.D.
+--     Step: 1.2                         Q.E.D.
+--     Step: 1.Completeness              Q.E.D.
+--   Result:                             Q.E.D.
 -- Lemma: modAddRight
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Result:                             Q.E.D.
 -- Lemma: modAddLeft
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Cached: modAddRight                     Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Step: 3                             Q.E.D.
+--   Result:                             Q.E.D.
+-- Lemma: modAddRight                    Q.E.D. [Cached]
 -- Inductive lemma: modMulRightNonneg
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Step: 6                               Q.E.D.
---   Result:                               Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Cached: modAddRight                     Q.E.D.
--- Cached: modAddLeft                      Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Lemma: modSubRight
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
--- Inductive lemma: modMulRightNeg
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Step: 6                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: Base                          Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Step: 3                             Q.E.D.
+--   Step: 4                             Q.E.D.
+--   Step: 5                             Q.E.D.
+--   Step: 6                             Q.E.D.
+--   Result:                             Q.E.D.
+-- Lemma: modMulRightNeg                 Q.E.D.
 -- Lemma: modMulRight
 --   Step: 1 (2 way case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.2.3                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
--- [Proven. Cached: modAddLeft, modAddMultiple, modAddRight] modMulRight :: Ɐa ∷ Integer → Ɐb ∷ Integer → Ɐm ∷ Integer → Bool
+--     Step: 1.1                         Q.E.D.
+--     Step: 1.2.1                       Q.E.D.
+--     Step: 1.2.2                       Q.E.D.
+--     Step: 1.2.3                       Q.E.D.
+--     Step: 1.Completeness              Q.E.D.
+--   Result:                             Q.E.D.
+-- [Proven] modMulRight :: Ɐa ∷ Integer → Ɐb ∷ Integer → Ɐm ∷ Integer → Bool
 modMulRight :: TP (Proof (Forall "a" Integer -> Forall "b" Integer -> Forall "m" Integer -> SBool))
 modMulRight = do
    mMulNonneg <- modMulRightNonneg
-   mMulNeg    <- modMulRightNeg
+   mMulNeg    <- recall modMulRightNeg
 
    calc "modMulRight"
         (\(Forall a) (Forall b) (Forall m) -> m .> 0 .=> (a*b) `sEMod` m .== (a * b `sEMod` m) `sEMod` m) $
@@ -329,68 +368,17 @@
 -- | \(m > 0 \Rightarrow ab \equiv (a \bmod m) \cdot b \pmod{m}\)
 --
 -- ==== __Proof__
--- >>> runCached modMulLeft
--- Inductive lemma: modAddMultiple
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: modAddRight
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: modAddLeft
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Cached: modAddRight                     Q.E.D.
--- Inductive lemma: modMulRightNonneg
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Step: 6                               Q.E.D.
---   Result:                               Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Cached: modAddRight                     Q.E.D.
--- Cached: modAddLeft                      Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Lemma: modSubRight
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
--- Inductive lemma: modMulRightNeg
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Step: 6                               Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: modMulRight
---   Step: 1 (2 way case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.2.3                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
+-- >>> runTP modMulLeft
+-- Lemma: modMulRight                    Q.E.D.
 -- Lemma: modMulLeft
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven. Cached: modAddLeft, modAddMultiple, modAddRight] modMulLeft :: Ɐa ∷ Integer → Ɐb ∷ Integer → Ɐm ∷ Integer → Bool
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Step: 3                             Q.E.D.
+--   Result:                             Q.E.D.
+-- [Proven] modMulLeft :: Ɐa ∷ Integer → Ɐb ∷ Integer → Ɐm ∷ Integer → Bool
 modMulLeft :: TP (Proof (Forall "a" Integer -> Forall "b" Integer -> Forall "m" Integer -> SBool))
 modMulLeft = do
-   mMulR <- modMulRight
+   mMulR <- recall modMulRight
 
    calc "modMulLeft"
         (\(Forall a) (Forall b) (Forall m) -> m .> 0 .=> (a*b) `sEMod` m .== (a `sEMod` m * b) `sEMod` m) $
@@ -404,92 +392,25 @@
 -- | \(n \geq 0 \land m > 0 \Rightarrow b^n \equiv (b \bmod m)^n \pmod{m}\)
 --
 -- ==== __Proof__
--- >>> runCached powerMod
--- Inductive lemma: modAddMultiple
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: modAddRight
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: modAddLeft
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Cached: modAddRight                     Q.E.D.
--- Inductive lemma: modMulRightNonneg
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Step: 6                               Q.E.D.
---   Result:                               Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Cached: modAddRight                     Q.E.D.
--- Cached: modAddLeft                      Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Lemma: modSubRight
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
--- Inductive lemma: modMulRightNeg
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Step: 6                               Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: modMulRight
---   Step: 1 (2 way case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.2.3                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: modMulLeft
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Cached: modAddRight                     Q.E.D.
--- Cached: modAddLeft                      Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Cached: modAddRight                     Q.E.D.
--- Cached: modMulRightNonneg               Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Cached: modAddRight                     Q.E.D.
--- Cached: modAddLeft                      Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Cached: modSubRight                     Q.E.D.
--- Cached: modMulRightNeg                  Q.E.D.
--- Cached: modMulRight                     Q.E.D.
+-- >>> runTP powerMod
+-- Lemma: modMulLeft                     Q.E.D.
+-- Lemma: modMulRight                    Q.E.D. [Cached]
 -- Inductive lemma: powerModInduct
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Step: 6                               Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: powerMod                         Q.E.D.
--- [Proven. Cached: modAddLeft, modAddMultiple, modAddRight, modMulRight] powerMod :: Ɐb ∷ Integer → Ɐn ∷ Integer → Ɐm ∷ Integer → Bool
+--   Step: Base                          Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Step: 3                             Q.E.D.
+--   Step: 4                             Q.E.D.
+--   Step: 5                             Q.E.D.
+--   Step: 6                             Q.E.D.
+--   Result:                             Q.E.D.
+-- Lemma: powerMod                       Q.E.D.
+-- Functions proven terminating: power
+-- [Proven] powerMod :: Ɐb ∷ Integer → Ɐn ∷ Integer → Ɐm ∷ Integer → Bool
 powerMod :: TP (Proof (Forall "b" Integer -> Forall "n" Integer -> Forall "m" Integer -> SBool))
 powerMod = do
-   mMulL <- modMulLeft
-   mMulR <- modMulRight
+   mMulL <- recall modMulLeft
+   mMulR <- recall modMulRight
 
    -- We want to write the b parameter first, but need to induct on n. So, this helper rearranges the parameters only.
    pMod <- induct "powerModInduct"
@@ -515,12 +436,13 @@
 -- | \(n \geq 0 \Rightarrow 1^n = 1\)
 --
 -- ==== __Proof__
--- >>> runCached onePower
+-- >>> runTP onePower
 -- Inductive lemma: onePower
---   Step: Base                            Q.E.D.
---   Step: 1 (unfold power)                Q.E.D.
---   Step: 2                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: Base                 Q.E.D.
+--   Step: 1 (unfold power)     Q.E.D.
+--   Step: 2                    Q.E.D.
+--   Result:                    Q.E.D.
+-- Functions proven terminating: power
 -- [Proven] onePower :: Ɐn ∷ Integer → Bool
 onePower :: TP (Proof (Forall "n" Integer -> SBool))
 onePower = induct "onePower"
@@ -535,103 +457,21 @@
 -- | \(n \geq 0 \Rightarrow (27^n \bmod 13) = 1\)
 --
 -- ==== __Proof__
--- >>> runCached powerOf27
--- Inductive lemma: onePower
---   Step: Base                            Q.E.D.
---   Step: 1 (unfold power)                Q.E.D.
---   Step: 2                               Q.E.D.
---   Result:                               Q.E.D.
--- Inductive lemma: modAddMultiple
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: modAddRight
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: modAddLeft
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Cached: modAddRight                     Q.E.D.
--- Inductive lemma: modMulRightNonneg
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Step: 6                               Q.E.D.
---   Result:                               Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Cached: modAddRight                     Q.E.D.
--- Cached: modAddLeft                      Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Lemma: modSubRight
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
--- Inductive lemma: modMulRightNeg
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Step: 6                               Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: modMulRight
---   Step: 1 (2 way case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.2.3                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: modMulLeft
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Cached: modAddRight                     Q.E.D.
--- Cached: modAddLeft                      Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Cached: modAddRight                     Q.E.D.
--- Cached: modMulRightNonneg               Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Cached: modAddRight                     Q.E.D.
--- Cached: modAddLeft                      Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Cached: modSubRight                     Q.E.D.
--- Cached: modMulRightNeg                  Q.E.D.
--- Cached: modMulRight                     Q.E.D.
--- Inductive lemma: powerModInduct
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Step: 6                               Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: powerMod                         Q.E.D.
+-- >>> runTP powerOf27
+-- Lemma: onePower                       Q.E.D.
+-- Lemma: powerMod                       Q.E.D.
 -- Lemma: powerOf27
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven. Cached: modAddLeft, modAddMultiple, modAddRight, modMulRight] powerOf27 :: Ɐn ∷ Integer → Bool
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Step: 3                             Q.E.D.
+--   Step: 4                             Q.E.D.
+--   Result:                             Q.E.D.
+-- Functions proven terminating: power
+-- [Proven] powerOf27 :: Ɐn ∷ Integer → Bool
 powerOf27 :: TP (Proof (Forall "n" Integer -> SBool))
 powerOf27 = do
-   pOne <- onePower
-   pMod <- powerMod
+   pOne <- recall onePower
+   pMod <- recall powerMod
    calc "powerOf27" (\(Forall n) -> n .>= 0 .=> power 27 n `sEMod` 13 .== 1) $
                     \n -> [n .>= 0]
                        |- power 27 n `sEMod` 13
@@ -646,105 +486,16 @@
 -- | \(n \geq 0 \wedge m > 0 \implies (27^{\frac{n}{3}} \bmod 13) \cdot 3^{n \bmod 3} \equiv 3^{n \bmod 3} \pmod{m}\)
 --
 -- ==== __Proof__
--- >>> runCached powerOfThreeMod13VarDivisor
--- Inductive lemma: onePower
---   Step: Base                            Q.E.D.
---   Step: 1 (unfold power)                Q.E.D.
---   Step: 2                               Q.E.D.
---   Result:                               Q.E.D.
--- Inductive lemma: modAddMultiple
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: modAddRight
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: modAddLeft
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Cached: modAddRight                     Q.E.D.
--- Inductive lemma: modMulRightNonneg
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Step: 6                               Q.E.D.
---   Result:                               Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Cached: modAddRight                     Q.E.D.
--- Cached: modAddLeft                      Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Lemma: modSubRight
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
--- Inductive lemma: modMulRightNeg
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Step: 6                               Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: modMulRight
---   Step: 1 (2 way case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.2.3                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: modMulLeft
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Cached: modAddRight                     Q.E.D.
--- Cached: modAddLeft                      Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Cached: modAddRight                     Q.E.D.
--- Cached: modMulRightNonneg               Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Cached: modAddRight                     Q.E.D.
--- Cached: modAddLeft                      Q.E.D.
--- Cached: modAddMultiple                  Q.E.D.
--- Cached: modSubRight                     Q.E.D.
--- Cached: modMulRightNeg                  Q.E.D.
--- Cached: modMulRight                     Q.E.D.
--- Inductive lemma: powerModInduct
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Step: 5                               Q.E.D.
---   Step: 6                               Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: powerMod                         Q.E.D.
--- Lemma: powerOf27
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Result:                               Q.E.D.
+-- >>> runTP powerOfThreeMod13VarDivisor
+-- Lemma: powerOf27                      Q.E.D.
 -- Lemma: powerOfThreeMod13VarDivisor
---   Step: 1                               Q.E.D.
---   Result:                               Q.E.D.
--- [Proven. Cached: modAddLeft, modAddMultiple, modAddRight, modMulRight] powerOfThreeMod13VarDivisor :: Ɐn ∷ Integer → Ɐm ∷ Integer → Bool
+--   Step: 1                             Q.E.D.
+--   Result:                             Q.E.D.
+-- Functions proven terminating: power
+-- [Proven] powerOfThreeMod13VarDivisor :: Ɐn ∷ Integer → Ɐm ∷ Integer → Bool
 powerOfThreeMod13VarDivisor :: TP (Proof (Forall "n" Integer -> Forall "m" Integer -> SBool))
 powerOfThreeMod13VarDivisor = do
-   p27 <- powerOf27
+   p27 <- recall powerOf27
    calc "powerOfThreeMod13VarDivisor"
         (\(Forall n) (Forall m) ->
             n .>= 0 .&& m .> 0 .=>     power 27 (n `sEDiv` 3) `sEMod` 13 * power 3 (n `sEMod` 3) `sEMod` m
diff --git a/Documentation/SBV/Examples/TP/Primes.hs b/Documentation/SBV/Examples/TP/Primes.hs
new file mode 100644
--- /dev/null
+++ b/Documentation/SBV/Examples/TP/Primes.hs
@@ -0,0 +1,549 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Documentation.SBV.Examples.TP.Primes
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Prove that there are an infinite number of primes. Along the way we formalize
+-- and prove a number of properties about divisibility as well. Our proof is inspired by
+-- the ACL2 proof in <https://github.com/acl2/acl2/blob/master/books/projects/numbers/euclid.lisp>.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE CPP              #-}
+{-# LANGUAGE DataKinds        #-}
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE TypeAbstractions #-}
+{-# LANGUAGE TypeApplications #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Documentation.SBV.Examples.TP.Primes where
+
+import Data.SBV
+import Data.SBV.TP
+
+#ifdef DOCTEST
+-- $setup
+-- >>> import Data.SBV.TP
+#endif
+
+-- * Divisibility
+
+-- | Divides relation. By definition @0@ only divides @0@. (But every number divides @0@).
+dvd :: SInteger -> SInteger -> SBool
+x `dvd` y = ite (x .== 0) (y .== 0) (y `sEMod` x .== 0)
+
+-- | \(x \mid y \implies x \mid y * z\)
+--
+-- === __Proof__
+-- >>> runTP dividesProduct
+-- Lemma: dividesProduct
+--   Step: 1 (2 way case split)
+--     Step: 1.1               Q.E.D.
+--     Step: 1.2.1             Q.E.D.
+--     Step: 1.2.2             Q.E.D.
+--     Step: 1.2.3             Q.E.D.
+--     Step: 1.Completeness    Q.E.D.
+--   Result:                   Q.E.D.
+-- [Proven] dividesProduct :: Ɐx ∷ Integer → Ɐy ∷ Integer → Ɐz ∷ Integer → Bool
+dividesProduct :: TP (Proof (Forall "x" Integer -> Forall "y" Integer -> Forall "z" Integer -> SBool))
+dividesProduct = calc "dividesProduct"
+                      (\(Forall x) (Forall y) (Forall z) -> x `dvd` y .=> x `dvd` (y*z)) $
+                      \x y z -> [x `dvd` y]
+                             |- cases [ x .== 0 ==> x `dvd` (y*z)
+                                                 ?? y .== 0
+                                                 =: sTrue
+                                                 =: qed
+                                      , x ./= 0 ==> x `dvd` (y*z)
+                                                 ?? y .== x * y `sEDiv` x
+                                                 =: x `dvd` ((x * y `sEDiv` x) * z)
+                                                 =: x `dvd` (x * ((y `sEDiv` x) * z))
+                                                 =: sTrue
+                                                 =: qed
+                                      ]
+-- | \(x \mid y \land y \mid z \implies x \mid z\)
+--
+-- === __Proof__
+-- >>> runTP dividesTransitive
+-- Lemma: dividesProduct       Q.E.D.
+-- Lemma: dividesTransitive
+--   Step: 1 (2 way case split)
+--     Step: 1.1               Q.E.D.
+--     Step: 1.2.1             Q.E.D.
+--     Step: 1.2.2             Q.E.D.
+--     Step: 1.2.3             Q.E.D.
+--     Step: 1.2.4             Q.E.D.
+--     Step: 1.Completeness    Q.E.D.
+--   Result:                   Q.E.D.
+-- [Proven] dividesTransitive :: Ɐx ∷ Integer → Ɐy ∷ Integer → Ɐz ∷ Integer → Bool
+dividesTransitive :: TP (Proof (Forall "x" Integer -> Forall "y" Integer -> Forall "z" Integer -> SBool))
+dividesTransitive = do
+    dp <- recall dividesProduct
+
+    calc "dividesTransitive"
+         (\(Forall x) (Forall y) (Forall z) -> x `dvd` y .&& y `dvd` z .=> x `dvd` z) $
+         \x y z -> [x `dvd` y, y `dvd` z]
+                |- cases [ x .== 0 .|| y .== 0 .|| z .== 0 ==> trivial
+                         , x ./= 0 .&& y ./= 0 .&& z ./= 0
+                            ==> x `dvd` z
+                             ?? z .== z `sEDiv` y * y
+                             =: x `dvd` (z `sEDiv` y * y)
+                             ?? y .== y `sEDiv` x * x
+                             ?? x `dvd` y
+                             =: x `dvd` ((z `sEDiv` y) * (y `sEDiv` x * x))
+                             =: x `dvd` (x * ((z `sEDiv` y) * (y `sEDiv` x)))
+                             ?? dp `at` (Inst @"x" x, Inst @"y" x, Inst @"z" ((z `sEDiv` y) * (y `sEDiv` x)))
+                             =: sTrue
+                             =: qed
+                         ]
+
+-- * The least divisor
+
+-- | The definition of primality will depend on the notion of least divisor. Given @k@ and @n@, the least-divisor of
+-- @n@ that is at least @k@ is the number that is at least @k@ and divides @n@ evenly. The idea is that a number is
+-- prime if the least divisor starting from @2@ is itself.
+ld :: SInteger -> SInteger -> SInteger
+ld = smtFunctionWithMeasure "ld" (\k n -> (n - k) `smax` 0, [])
+   $ \k n -> [sCase| tuple (k .<= 0 .|| k .> n, n `sEMod` k) of
+                (True, _) -> 0
+                (_,    0) -> k
+                _         -> ld (k+1) n
+             |]
+
+-- | \(1 < k \leq n \implies \mathit{ld}\,k\,n \mid n \land k \leq \mathit{ld}\,k\,n \leq n\)
+--
+-- === __Proof__
+-- >>> runTP leastDivisorDivides
+-- Inductive lemma (strong): leastDivisorDivides
+--   Step: Measure is non-negative                  Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1                                    Q.E.D.
+--     Step: 1.2                                    Q.E.D.
+--     Step: 1.Completeness                         Q.E.D.
+--   Result:                                        Q.E.D.
+-- Functions proven terminating: ld
+-- [Proven] leastDivisorDivides :: Ɐk ∷ Integer → Ɐn ∷ Integer → Bool
+leastDivisorDivides :: TP (Proof (Forall "k" Integer -> Forall "n" Integer -> SBool))
+leastDivisorDivides =
+   sInduct "leastDivisorDivides"
+           (\(Forall k) (Forall n) -> 1 .< k .&& k .<= n .=> let d = ld k n in d `dvd` n .&& k .<= d .&& d .<= n)
+           (\k n -> n - k, []) $
+           \ih k n -> [1 .< k, k .<= n]
+                  |- let d = ld k n
+                  in cases [ n `sEMod` k .== 0 ==> d `dvd` n .&& k .<= d .&& d .<= n
+                                                ?? d .== k
+                                                =: sTrue
+                                                =: qed
+                           , n `sEMod` k ./= 0 ==> d `dvd` n .&& k .<= d .&& d .<= n
+                                                ?? d .== ld (k+1) n
+                                                ?? ih `at` (Inst @"k" (k+1), Inst @"n" n)
+                                                =: sTrue
+                                                =: qed
+                           ]
+
+-- | \(1 < k \leq n \land d \mid n \land k \leq d \implies \mathit{ld}\,k\,n \leq d\)
+--
+-- === __Proof__
+-- >>> runTP leastDivisorIsLeast
+-- Inductive lemma (strong): leastDivisorisLeast
+--   Step: Measure is non-negative                  Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1                                    Q.E.D.
+--     Step: 1.2                                    Q.E.D.
+--     Step: 1.Completeness                         Q.E.D.
+--   Result:                                        Q.E.D.
+-- Functions proven terminating: ld
+-- [Proven] leastDivisorisLeast :: Ɐk ∷ Integer → Ɐn ∷ Integer → Ɐd ∷ Integer → Bool
+leastDivisorIsLeast :: TP (Proof (Forall "k" Integer -> Forall "n" Integer -> Forall "d" Integer -> SBool))
+leastDivisorIsLeast =
+  sInduct "leastDivisorisLeast"
+          (\(Forall k) (Forall n) (Forall d) -> 1 .< k .&& k .<= n .&& d `dvd` n .&& k .<= d .=> ld k n .<= d)
+          (\k n _d -> n - k, []) $
+          \ih k n d -> [1 .< k, k .<= n, d `dvd` n, k .<= d]
+                    |- cases [ n `sEMod` k .== 0 ==> ld k n .<= d
+                                                  =: k .<= d
+                                                  =: qed
+                             , n `sEMod` k ./= 0 ==> ld k n .<= d
+                                                  ?? ih
+                                                  =: sTrue
+                                                  =: qed
+                             ]
+
+-- | \(n \geq k \geq 2 \implies \mathit{ld}\,k\,(\mathit{ld}\,k\,n) = \mathit{ld}\,k\,n\)
+--
+-- === __Proof__
+-- >>> runTP leastDivisorTwice
+-- Lemma: dividesTransitive                         Q.E.D.
+-- Lemma: leastDivisorDivides                       Q.E.D.
+-- Lemma: leastDivisorisLeast                       Q.E.D.
+-- Lemma: helper1                                   Q.E.D.
+-- Lemma: helper2                                   Q.E.D.
+-- Lemma: helper3
+--   Step: 1                                        Q.E.D.
+--   Result:                                        Q.E.D.
+-- Lemma: helper4                                   Q.E.D.
+-- Lemma: helper5
+--   Step: 1                                        Q.E.D.
+--   Result:                                        Q.E.D.
+-- Lemma: leastDivisorTwice                         Q.E.D.
+-- Functions proven terminating: ld
+-- [Proven] leastDivisorTwice :: Ɐk ∷ Integer → Ɐn ∷ Integer → Bool
+leastDivisorTwice :: TP (Proof (Forall "k" Integer -> Forall "n" Integer -> SBool))
+leastDivisorTwice = do
+  dt  <- recall dividesTransitive
+  ldd <- recall leastDivisorDivides
+  ldl <- recall leastDivisorIsLeast
+
+  h1 <- lemmaWith cvc5
+              "helper1"
+              (\(Forall @"k" k) (Forall @"n" n) -> n .>= k .&& k .>= 2 .=> ld k (ld k n) `dvd` ld k n .&& ld k (ld k n) .<= ld k n)
+              [proofOf ldd]
+
+  h2 <- lemma "helper2"
+              (\(Forall @"k" k) (Forall @"n" n) -> n .>= k .&& k .>= 2 .=> ld k n `dvd` n)
+              [proofOf ldd]
+
+  h3 <- calc "helper3"
+             (\(Forall @"k" k) (Forall @"n" n) -> n .>= k .&& k .>= 2 .=> ld k (ld k n) `dvd` n) $
+             \k n -> [n .>= k, k .>= 2]
+                  |- ld k (ld k n) `dvd` n
+                  ?? h1
+                  ?? h2
+                  ?? dt `at` (Inst @"x" (ld k (ld k n)), Inst @"y" (ld k n), Inst @"z" n)
+                  =: sTrue
+                  =: qed
+
+  h4 <- lemma "helper4"
+              (\(Forall @"k" k) (Forall @"n" n) -> n .>= k .&& k .>= 2 .=> k .<= ld k (ld k n))
+              [proofOf ldd]
+
+  h5 <- calc "helper5"
+              (\(Forall @"k" k) (Forall @"n" n) -> n .>= k .&& k .>= 2 .=> ld k n .<= ld k (ld k n)) $
+              \k n -> [n .>= k, k .>= 2]
+                   |- ld k n .<= ld k (ld k n)
+                   ?? h3  `at` (Inst @"k" k, Inst @"n" n)
+                   ?? h4  `at` (Inst @"k" k, Inst @"n" n)
+                   ?? ldl `at` (Inst @"k" k, Inst @"n" n, Inst @"d" (ld k (ld k n)))
+                   =: sTrue
+                   =: qed
+
+  lemma "leastDivisorTwice"
+        (\(Forall k) (Forall n) -> n .>= k .&& k .>= 2 .=> ld k (ld k n) .== ld k n)
+        [proofOf h1, proofOf h5]
+
+-- * Primality
+
+-- | A number is prime if its least divisor greater than or equal to @2@ is itself.
+isPrime :: SInteger -> SBool
+isPrime n = n .>= 2 .&& ld 2 n .== n
+
+-- | \(\mathit{isPrime}\,p \implies p \geq 2\)
+--
+-- === __Proof__
+-- >>> runTP primeAtLeast2
+-- Lemma: primeAtLeast2    Q.E.D.
+-- Functions proven terminating: ld
+-- [Proven] primeAtLeast2 :: Ɐp ∷ Integer → Bool
+primeAtLeast2 :: TP (Proof (Forall "p" Integer -> SBool))
+primeAtLeast2 = lemma "primeAtLeast2" (\(Forall p) -> isPrime p .=> p .>= 2) []
+
+-- | \(n \geq 2 \implies \mathit{isPrime}\,(\mathit{ld}\,2\,n)\)
+--
+-- === __Proof__
+-- >>> runTP leastDivisorIsPrime
+-- Lemma: leastDivisorTwice                         Q.E.D.
+-- Lemma: leastDivisorDivides                       Q.E.D. [Cached]
+-- Lemma: leastDivisorIsPrime
+--   Step: 1                                        Q.E.D.
+--   Result:                                        Q.E.D.
+-- Functions proven terminating: ld
+-- [Proven] leastDivisorIsPrime :: Ɐn ∷ Integer → Bool
+leastDivisorIsPrime :: TP (Proof (Forall "n" Integer -> SBool))
+leastDivisorIsPrime = do
+   ldt <- recall leastDivisorTwice
+   ldd <- recall leastDivisorDivides
+
+   calc "leastDivisorIsPrime"
+        (\(Forall n) -> n .>= 2 .=> isPrime (ld 2 n)) $
+        \n -> [n .>= 2] |- isPrime (ld 2 n)
+                        ?? ldt `at` (Inst @"k" 2, Inst @"n" n)
+                        ?? ldd `at` (Inst @"k" 2, Inst @"n" n)
+                        =: sTrue
+                        =: qed
+
+-- | The least prime divisor is the least divisor of it starting from @2@. By 'leastDivisorIsPrime', this number
+-- is guaranteed to be prime.
+leastPrimeDivisor :: SInteger -> SInteger
+leastPrimeDivisor n = ld 2 n
+
+-- * Formalizing factorial
+
+-- | The factorial function.
+fact :: SInteger -> SInteger
+fact = smtFunction "fact" $ \n -> [sCase| n of
+                                     _ | n .<= 0 -> 1
+                                     _           -> n * fact (n - 1)
+                                  |]
+
+-- | \(n! \geq 1\)
+--
+-- === __Proof__
+-- >>> runTP factAtLeast1
+-- Inductive lemma: factAtLeast1
+--   Step: Base                     Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1                    Q.E.D.
+--     Step: 1.2.1                  Q.E.D.
+--     Step: 1.2.2                  Q.E.D.
+--     Step: 1.Completeness         Q.E.D.
+--   Result:                        Q.E.D.
+-- Functions proven terminating: fact
+-- [Proven] factAtLeast1 :: Ɐn ∷ Integer → Bool
+factAtLeast1 :: TP (Proof (Forall "n" Integer -> SBool))
+factAtLeast1 = inductWith cvc5 "factAtLeast1"
+                      (\(Forall n) -> fact n .>= 1) $
+                      \ih n -> [] |- fact (n+1) .>= 1
+                                  =: cases [ n+1 .<= 0 ==> trivial
+                                           , n+1 .>  0 ==> (n+1) * fact n .>= 1
+                                                        ?? ih
+                                                        =: sTrue
+                                                        =: qed
+                                           ]
+
+-- | \(1 \leq k \land k \leq n \implies k \mid n!\)
+--
+-- === __Proof__
+-- >>> runTP dividesFact
+-- Lemma: dividesProduct           Q.E.D.
+-- Lemma: factUnfold               Q.E.D.
+-- Lemma: dvdCong                  Q.E.D.
+-- Lemma: dvdRefl                  Q.E.D.
+-- Inductive lemma: dividesFact
+--   Step: Base                    Q.E.D.
+--   Step: 1                       Q.E.D.
+--   Step: 2 (2 way case split)
+--     Step: 2.1.1                 Q.E.D.
+--     Step: 2.1.2                 Q.E.D.
+--     Step: 2.2.1                 Q.E.D.
+--     Step: 2.2.2                 Q.E.D.
+--     Step: 2.2.3                 Q.E.D.
+--     Step: 2.Completeness        Q.E.D.
+--   Result:                       Q.E.D.
+-- Functions proven terminating: fact
+-- [Proven] dividesFact :: Ɐn ∷ Integer → Ɐk ∷ Integer → Bool
+dividesFact :: TP (Proof (Forall "n" Integer -> Forall "k" Integer -> SBool))
+dividesFact = do
+   dvp <- recall dividesProduct
+
+   -- Unfolding 'fact' underneath the mod that 'dvd' introduces is something no solver comes back
+   -- from. So, we split that step into two obligations, neither of which mentions both: 'factUnfold'
+   -- is the defining equation of 'fact' (no mod in sight), and 'dvdCong' is congruence of 'dvd'
+   -- over equal arguments (no recursion in sight). The step itself is then propositional.
+   --
+   -- Note that we phrase 'factUnfold' at @n+1@, matching the shape it is used at below exactly.
+   fu <- lemmaWith cvc5 "factUnfold"
+                   (\(Forall @"n" n) -> n .>= 0 .=> fact (n+1) .== (n+1) * fact n)
+                   []
+
+   dc <- lemma "dvdCong"
+               (\(Forall @"k" k) (Forall @"x" x) (Forall @"y" y) -> x .== y .=> (k `dvd` x .== k `dvd` y))
+               []
+
+   -- Every number divides itself. Isolated like this it is a one-liner for z3; buried inside the
+   -- case below (where 'fact' is also in scope) it is not.
+   dr <- lemma "dvdRefl" (\(Forall @"x" x) -> x `dvd` x) []
+
+   inductWith cvc5 "dividesFact"
+                   (\(Forall n) (Forall k) -> 1 .<= k .&& k .<= n .=> k `dvd` fact n) $
+                   \ih n k -> [1 .<= k, k .<= n + 1]
+                           |- k `dvd` fact (n + 1)
+                           ?? fu `at` Inst @"n" n
+                           ?? dc `at` (Inst @"k" k, Inst @"x" (fact (n+1)), Inst @"y" ((n + 1) * fact n))
+                           =: k `dvd` ((n + 1) * fact n)
+                           =: cases [ k .== n + 1 ==> k `dvd` ((n + 1) * fact n)
+                                                   ?? dr `at` Inst @"x" k
+                                                   ?? dvp `at` (Inst @"x" k, Inst @"y" (n+1), Inst @"z" (fact n))
+                                                   =: sTrue
+                                                   =: qed
+                                    , k ./= n + 1 ==> k `dvd` ((n + 1) * fact n)
+                                                   ?? dc `at` (Inst @"k" k, Inst @"x" ((n + 1) * fact n), Inst @"y" (fact n * (n + 1)))
+                                                   =: k `dvd` (fact n * (n + 1))
+                                                   ?? ih `at` Inst @"k" k
+                                                   ?? dvp `at` (Inst @"x" k, Inst @"y" (fact n), Inst @"z" (n+1))
+                                                   =: sTrue
+                                                   =: qed
+                                    ]
+
+-- | \(1 \leq k \land k \leq n \implies \neg (k \mid n! + 1)\)
+--
+-- === __Proof__
+-- >>> runTP notDividesFactP1
+-- Lemma: dividesFact              Q.E.D.
+-- Lemma: notDividesFactP1
+--   Step: 1                       Q.E.D.
+--   Step: 2                       Q.E.D.
+--   Step: 3                       Q.E.D.
+--   Result:                       Q.E.D.
+-- Functions proven terminating: fact
+-- [Proven] notDividesFactP1 :: Ɐn ∷ Integer → Ɐk ∷ Integer → Bool
+notDividesFactP1 :: TP (Proof (Forall "n" Integer -> Forall "k" Integer -> SBool))
+notDividesFactP1 = do
+   df    <- recall dividesFact
+
+   calc "notDividesFactP1"
+         (\(Forall n) (Forall k) -> 1 .< k .&& k .<= n .=> sNot (k `dvd` (fact n + 1))) $
+         \n k -> [1 .< k, k .<= n]
+              |- k `dvd` (fact n + 1)
+              ?? df `at` (Inst @"n" n, Inst @"k" k)
+              =: k `dvd` (k * fact n `sEDiv` k + 1)
+              =: k `dvd` 1
+              =: contradiction
+
+-- * Finding a greater prime
+
+-- | Given a number, return another number which is both prime and is larger than the input. Note that
+-- we don't claim to return the closest prime to the input. Just some prime that is larger, as we shall prove.
+greaterPrime :: SInteger -> SInteger
+greaterPrime n = leastPrimeDivisor (1 + fact n)
+
+-- | \(\mathit{greaterPrime}\, n \mid n! + 1\)
+--
+-- === __Proof__
+-- >>> runTP greaterPrimeDivides
+-- Lemma: leastDivisorDivides                       Q.E.D.
+-- Lemma: factAtLeast1                              Q.E.D.
+-- Lemma: greaterPrimeDivides
+--   Step: 1                                        Q.E.D.
+--   Step: 2                                        Q.E.D.
+--   Step: 3                                        Q.E.D.
+--   Result:                                        Q.E.D.
+-- Functions proven terminating: fact, ld
+-- [Proven] greaterPrimeDivides :: Ɐn ∷ Integer → Bool
+greaterPrimeDivides :: TP (Proof (Forall "n" Integer -> SBool))
+greaterPrimeDivides = do
+   ldd  <- recall leastDivisorDivides
+   fal1 <- recall factAtLeast1
+
+   calc "greaterPrimeDivides"
+        (\(Forall n) -> greaterPrime n `dvd` (1 + fact n)) $
+        \n -> [] |- greaterPrime n `dvd` (1 + fact n)
+                 =: leastPrimeDivisor (1 + fact n) `dvd` (1 + fact n)
+                 =: ld 2 (1 + fact n) `dvd` (1 + fact n)
+                 ?? ldd  `at` (Inst @"k" 2, Inst @"n" (1 + fact n))
+                 ?? fal1 `at` Inst @"n" n
+                 =: sTrue
+                 =: qed
+
+-- | \(\mathit{greaterPrime}\, n > n\)
+--
+-- === __Proof__
+-- >>> runTP greaterPrimeGreater
+-- Lemma: notDividesFactP1                          Q.E.D.
+-- Lemma: greaterPrimeDivides                       Q.E.D.
+-- Lemma: leastDivisorIsPrime                       Q.E.D.
+-- Lemma: factAtLeast1                              Q.E.D. [Cached]
+-- Lemma: primeAtLeast2                             Q.E.D.
+-- Lemma: greaterPrimeGreater
+--   Step: 1                                        Q.E.D.
+--   Step: 2                                        Q.E.D.
+--   Step: 3                                        Q.E.D.
+--   Step: 4                                        Q.E.D.
+--   Step: 5                                        Q.E.D.
+--   Step: 6                                        Q.E.D.
+--   Result:                                        Q.E.D.
+-- Functions proven terminating: fact, ld
+-- [Proven] greaterPrimeGreater :: Ɐn ∷ Integer → Bool
+greaterPrimeGreater :: TP (Proof (Forall "n" Integer -> SBool))
+greaterPrimeGreater = do
+   ndfp1 <- recall notDividesFactP1
+   gpd   <- recall greaterPrimeDivides
+   ldp   <- recall leastDivisorIsPrime
+   fal1  <- recall factAtLeast1
+   pal2  <- recall primeAtLeast2
+
+   calc "greaterPrimeGreater"
+         (\(Forall n) -> greaterPrime n .> n) $
+         \n -> [] |-> sTrue
+                   ?? ndfp1 `at` (Inst @"n" n, Inst @"k" (greaterPrime n))
+                   ?? gpd   `at` Inst @"n" n
+                   =: sNot (1 .< greaterPrime n .&& greaterPrime n .<= n)
+                   =: (1 .>= greaterPrime n .|| greaterPrime n .> n)
+                   =: (1 .>= leastPrimeDivisor (1 + fact n) .|| greaterPrime n .> n)
+                   =: (1 .>= leastPrimeDivisor (1 + fact n) .|| greaterPrime n .> n)
+                   =: (1 .>= ld 2 (1 + fact n) .|| greaterPrime n .> n)
+                   ?? ldp  `at` Inst @"n" (1 + fact n)
+                   ?? pal2 `at` Inst @"p" (ld 2 (1 + fact n))
+                   ?? fal1 `at` Inst @"n" n
+                   =: greaterPrime n .> n
+                   =: qed
+
+-- * Infinitude of primes
+
+-- | \(\mathit{isPrime}\,(\mathit{greaterPrime}\,n) \land \mathit{greaterPrime}\,n > n\)
+--
+-- We can finally prove our goal: For each given number, there is a larger number that is prime. This
+-- establishes that we have an infinite number of primes.
+--
+-- === __Proof__
+-- >>> runTP infinitudeOfPrimes
+-- Lemma: leastDivisorIsPrime                       Q.E.D.
+-- Lemma: factAtLeast1                              Q.E.D.
+-- Lemma: greaterPrimeGreater                       Q.E.D.
+-- Lemma: infinitudeOfPrimes
+--   Step: 1                                        Q.E.D.
+--   Step: 2                                        Q.E.D.
+--   Step: 3                                        Q.E.D.
+--   Result:                                        Q.E.D.
+-- Functions proven terminating: fact, ld
+-- [Proven] infinitudeOfPrimes :: Ɐn ∷ Integer → Bool
+infinitudeOfPrimes :: TP (Proof (Forall "n" Integer -> SBool))
+infinitudeOfPrimes = do
+   ldp <- recall leastDivisorIsPrime
+   fa1 <- recall factAtLeast1
+   gpg <- recall greaterPrimeGreater
+
+   calc "infinitudeOfPrimes"
+         (\(Forall n) -> let p = greaterPrime n in p .> n .&& isPrime p) $
+         \n -> [] |- let p = greaterPrime n
+                  in p .> n .&& isPrime (greaterPrime n)
+                  =: p .> n .&& isPrime (leastPrimeDivisor (1 + fact n))
+                  =: p .> n .&& isPrime (ld 2 (1 + fact n))
+                  ?? ldp `at` Inst @"n" (1 + fact n)
+                  ?? fa1 `at` Inst @"n" n
+                  ?? gpg `at` Inst @"n" n
+                  =: sTrue
+                  =: qed
+
+-- | \(\forall n. \exists p. \mathit{isPrime}\,p \land p > n\)
+--
+-- Another expression of the fact that there are infinitely many primes. One might prefer this
+-- version as it only refers to the 'isPrime' predicate only.
+--
+-- === __Proof__
+-- >>> runTP noLargestPrime
+-- Lemma: infinitudeOfPrimes                        Q.E.D.
+-- Lemma: helper
+--   Step: 1                                        Q.E.D.
+--   Result:                                        Q.E.D.
+-- Lemma: noLargestPrime                            Q.E.D.
+-- Functions proven terminating: fact, ld
+-- [Proven] noLargestPrime :: Ɐn ∷ Integer → ∃p ∷ Integer → Bool
+noLargestPrime :: TP (Proof (Forall "n" Integer -> Exists "p" Integer -> SBool))
+noLargestPrime = do
+   iop <- recall infinitudeOfPrimes
+
+   h <- calc "helper"
+             (\(Forall @"n" n) -> quantifiedBool (\(Exists p) -> isPrime p .&& p .> n)) $
+             \n -> [] |- quantifiedBool (\(Exists p) -> isPrime p .&& p .> n)
+                      ?? iop `at` Inst @"n" n
+                      =: sTrue
+                      =: qed
+
+   lemmaWith cvc5 "noLargestPrime"
+       (\(Forall n) (Exists p) -> isPrime p .&& p .> n)
+       [proofOf h]
+
+{- HLint ignore module "Avoid lambda" -}
+{- HLint ignore module "Eta reduce"   -}
diff --git a/Documentation/SBV/Examples/TP/Queue.hs b/Documentation/SBV/Examples/TP/Queue.hs
new file mode 100644
--- /dev/null
+++ b/Documentation/SBV/Examples/TP/Queue.hs
@@ -0,0 +1,197 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Documentation.SBV.Examples.TP.Queue
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- A classic functional queue implemented with two stacks (lists). The front
+-- list holds elements ready for dequeue; the back list accumulates new
+-- elements in reverse. We prove that this representation faithfully
+-- implements a FIFO queue by showing:
+--
+--   (1) Enqueue appends to the abstract queue.
+--   (2) Enqueuing a sequence of elements and reading out the abstraction
+--       gives back the original sequence.
+--   (3) Dequeue retrieves the front of the abstract queue.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE CPP                 #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE OverloadedLists     #-}
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Documentation.SBV.Examples.TP.Queue where
+
+import Prelude hiding (length, head, tail, null, reverse, (++), fst, snd)
+
+import Data.SBV
+import Data.SBV.List
+import Data.SBV.Tuple
+import Data.SBV.TP
+
+#ifdef DOCTEST
+-- $setup
+-- >>> :set -XOverloadedLists
+-- >>> :set -XTypeApplications
+-- >>> import Data.SBV
+-- >>> import Data.SBV.Tuple
+-- >>> import Data.SBV.TP
+#endif
+
+-- * Queue representation
+
+-- | A queue is a pair @(front, back)@ representing the abstract list
+-- @front ++ reverse back@.
+type Queue a = STuple [a] [a]
+
+-- | Abstraction function: the list a queue represents.
+--
+-- >>> toList (tuple ([1,2,3], [6,5,4])) :: SList Integer
+-- [1,2,3,4,5,6] :: [SInteger]
+toList :: SymVal a => Queue a -> SList a
+toList q = [sCase| q of
+               (f, b) -> f ++ reverse b
+           |]
+
+-- | The empty queue.
+--
+-- >>> toList (emptyQ @Integer)
+-- [] :: [SInteger]
+emptyQ :: SymVal a => Queue a
+emptyQ = tuple ([], [])
+
+-- | Enqueue: add an element to the back.
+--
+-- >>> toList (enqueue (tuple ([1,2], [4,3])) 5) :: SList Integer
+-- [1,2,3,4,5] :: [SInteger]
+enqueue :: SymVal a => Queue a -> SBV a -> Queue a
+enqueue q x = [sCase| q of
+                  (f, b) -> tuple (f, x .: b)
+              |]
+
+-- | Enqueue all elements of a list, left to right.
+--
+-- >>> toList (enqueueAll (emptyQ @Integer) [1,2,3])
+-- [1,2,3] :: [SInteger]
+enqueueAll :: SymVal a => Queue a -> SList a -> Queue a
+enqueueAll = smtFunction "enqueueAll"
+           $ \q xs -> [sCase| xs of
+                         []       -> q
+                         x : rest -> enqueueAll (enqueue q x) rest
+                      |]
+
+-- | Dequeue: remove and return the front element. When the front list
+-- is empty, we reverse the back list into the front first.
+-- Precondition: the queue is non-empty.
+--
+-- >>> let (v, q') = untuple (dequeue (tuple ([1,2,3], [6,5,4]) :: Queue Integer)) in (v, toList q')
+-- (1 :: SInteger,[2,3,4,5,6] :: [SInteger])
+-- >>> let (v, q') = untuple (dequeue (tuple ([], [3,2,1]) :: Queue Integer)) in (v, toList q')
+-- (1 :: SInteger,[2,3] :: [SInteger])
+dequeue :: forall a. SymVal a => Queue a -> STuple a ([a], [a])
+dequeue q = [sCase| q of
+               (x : xs, t) -> tuple (x, tuple (xs, t))
+               ([],     t) -> case reverse t of
+                                y : ys -> tuple (y, tuple (ys, []))
+                                -- unreachable: both front and back are empty
+                                _      -> tuple (some "dead" (const sTrue), tuple ([], []))
+            |]
+
+-- * Correctness
+
+-- | @toList (enqueue q x) == toList q ++ [x]@
+--
+-- Enqueue appends to the abstract list.
+--
+-- >>> runTP $ enqueueCorrect @Integer
+-- Lemma: enqueueCorrect    Q.E.D.
+-- Functions proven terminating: sbv.reverse
+-- [Proven] enqueueCorrect :: Ɐf ∷ [Integer] → Ɐb ∷ [Integer] → Ɐx ∷ Integer → Bool
+enqueueCorrect :: forall a. SymVal a => TP (Proof (Forall "f" [a] -> Forall "b" [a] -> Forall "x" a -> SBool))
+enqueueCorrect =
+   lemma "enqueueCorrect"
+         (\(Forall @"f" f) (Forall @"b" b) (Forall @"x" x) ->
+              toList (enqueue (tuple (f, b)) x) .== toList (tuple (f, b)) ++ [x])
+         []
+
+-- | @toList (enqueueAll q xs) == toList q ++ xs@
+--
+-- Enqueuing a sequence of elements appends the whole sequence to the
+-- abstract list. This is the key invariant of the two-stack representation.
+--
+-- >>> runTP $ enqueueAllCorrect @Integer
+-- Lemma: enqueueCorrect                 Q.E.D.
+-- Inductive lemma: enqueueAllCorrect
+--   Step: Base                          Q.E.D.
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Step: 3                             Q.E.D.
+--   Result:                             Q.E.D.
+-- Functions proven terminating: enqueueAll, sbv.reverse
+-- [Proven] enqueueAllCorrect :: Ɐxs ∷ [Integer] → Ɐf ∷ [Integer] → Ɐb ∷ [Integer] → Bool
+enqueueAllCorrect :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> Forall "f" [a] -> Forall "b" [a] -> SBool))
+enqueueAllCorrect = do
+
+   eqC <- enqueueCorrect @a
+
+   induct "enqueueAllCorrect"
+          (\(Forall @"xs" xs) (Forall @"f" f) (Forall @"b" b) ->
+               toList (enqueueAll (tuple (f, b)) xs) .== (f ++ reverse b) ++ xs) $
+          \ih (x, xs) f b -> []
+                          |- toList (enqueueAll (tuple (f, b)) (x .: xs))
+                          =: toList (enqueueAll (tuple (f, x .: b)) xs)
+                          ?? ih `at` (Inst @"f" f, Inst @"b" (x .: b))
+                          =: (f ++ reverse (x .: b)) ++ xs
+                          ?? eqC
+                          =: (f ++ reverse b) ++ (x .: xs)
+                          =: qed
+
+-- | @toList (enqueueAll emptyQ xs) == xs@
+--
+-- Starting from an empty queue, enqueuing a list of elements produces
+-- a queue whose abstract contents is that same list. This demonstrates
+-- the fundamental FIFO property: elements come out in the order they went in.
+--
+-- >>> runTP $ fifo @Integer
+-- Lemma: enqueueAllCorrect              Q.E.D.
+-- Lemma: fifo
+--   Step: 1                             Q.E.D.
+--   Step: 2                             Q.E.D.
+--   Result:                             Q.E.D.
+-- Functions proven terminating: enqueueAll, sbv.reverse
+-- [Proven] fifo :: Ɐxs ∷ [Integer] → Bool
+fifo :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> SBool))
+fifo = do
+   eaC <- recall (enqueueAllCorrect @a)
+
+   calc "fifo"
+        (\(Forall xs) -> toList (enqueueAll emptyQ xs) .== xs) $
+        \xs -> [] |- toList (enqueueAll emptyQ xs)
+                  ?? eaC `at` (Inst @"xs" xs, Inst @"f" ([] :: SList a), Inst @"b" ([] :: SList a))
+                  =: reverse [] ++ xs
+                  =: xs
+                  =: qed
+
+-- | Dequeue from a non-empty queue gives the head of the abstract list,
+-- and the remaining queue represents the tail.
+--
+-- >>> runTP $ dequeueCorrect @Integer
+-- Lemma: dequeueCorrect    Q.E.D.
+-- Functions proven terminating: sbv.reverse
+-- [Proven] dequeueCorrect :: Ɐf ∷ [Integer] → Ɐb ∷ [Integer] → Bool
+dequeueCorrect :: forall a. SymVal a => TP (Proof (Forall "f" [a] -> Forall "b" [a] -> SBool))
+dequeueCorrect =
+   lemma "dequeueCorrect"
+         (\(Forall @"f" f) (Forall @"b" b) ->
+              sNot (null (toList (tuple (f, b))))
+              .=> let (v, q) = untuple (dequeue (tuple (f, b)))
+                      l      = toList (tuple (f, b))
+                  in v .== head l .&& toList q .== tail l)
+         []
diff --git a/Documentation/SBV/Examples/TP/QuickSort.hs b/Documentation/SBV/Examples/TP/QuickSort.hs
--- a/Documentation/SBV/Examples/TP/QuickSort.hs
+++ b/Documentation/SBV/Examples/TP/QuickSort.hs
@@ -16,6 +16,7 @@
 {-# LANGUAGE DataKinds           #-}
 {-# LANGUAGE FlexibleContexts    #-}
 {-# LANGUAGE OverloadedLists     #-}
+{-# LANGUAGE QuasiQuotes         #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeAbstractions    #-}
 {-# LANGUAGE TypeApplications    #-}
@@ -31,37 +32,113 @@
 import Data.SBV.List hiding (partition)
 import Data.SBV.Tuple
 import Data.SBV.TP
-import qualified Data.SBV.TP.List as TP
+import qualified Documentation.SBV.Examples.TP.Lists as TP
 
 import qualified Documentation.SBV.Examples.TP.SortHelpers as SH
 
 #ifdef DOCTEST
 -- $setup
 -- >>> :set -XTypeApplications
+-- >>> import Data.SBV.TP
 #endif
 
 -- * Quick sort
 
 -- | Quick-sort, using the first element as pivot.
-quickSort :: (OrdSymbolic (SBV a), SymVal a) => SList a -> SList a
-quickSort = smtFunction "quickSort" $ \l -> ite (null l)
-                                                nil
-                                                (let (x,  xs) = uncons l
-                                                     (lo, hi) = untuple (partition x xs)
-                                                 in  quickSort lo ++ [x] ++ quickSort hi)
+quickSort :: forall a. (OrdSymbolic (SBV a), SymVal a) => SList a -> SList a
+quickSort = smtFunctionWithMeasure "quickSort"
+              ( length @a
+              , [ measureLemma (partitionFstBound @a)
+                , measureLemma (partitionSndBound @a)
+                ]
+              )
+          $ \l -> [sCase| l of
+                     []     -> []
+                     x : xs -> case partition x xs of
+                                 (lo, hi) -> quickSort lo ++ [x] ++ quickSort hi
+                  |]
 
 -- | We define @partition@ as an explicit function. Unfortunately, we can't just replace this
 -- with @\pivot xs -> Data.List.SBV.partition (.< pivot) xs@ because that would create a firstified version of partition
 -- with a free-variable captured, which isn't supported due to higher-order limitations in SMTLib.
 partition :: (OrdSymbolic (SBV a), SymVal a) => SBV a -> SList a -> STuple [a] [a]
-partition = smtFunction "partition" $ \pivot xs -> ite (null xs)
-                                                       (tuple (nil, nil))
-                                                       (let (a,  as) = uncons xs
-                                                            (lo, hi) = untuple (partition pivot as)
-                                                        in ite (a .< pivot)
-                                                               (tuple (a .: lo, hi))
-                                                               (tuple (lo, a .: hi)))
+partition = smtFunction "partition"
+          $ \pivot xs -> [sCase| xs of
+                            []     -> tuple ([], [])
+                            a : as -> case partition pivot as of
+                                        (lo, hi) | a .< pivot -> tuple (a .: lo, hi)
+                                                 | True       -> tuple (lo, a .: hi)
+                         |]
 
+-- | The first component of partition is no longer than the input.
+--
+-- >>> runTP $ partitionFstBound @Integer
+-- Inductive lemma (strong): partitionNotLongerFst
+--   Step: Measure is non-negative                    Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1                                      Q.E.D.
+--     Step: 1.2.1                                    Q.E.D.
+--     Step: 1.2.2 (simplify)                         Q.E.D.
+--     Step: 1.2.3                                    Q.E.D.
+--     Step: 1.Completeness                           Q.E.D.
+--   Result:                                          Q.E.D.
+-- Functions proven terminating: partition
+-- [Proven] partitionNotLongerFst :: Ɐl ∷ [Integer] → Ɐpivot ∷ Integer → Bool
+partitionFstBound :: forall a. (OrdSymbolic (SBV a), SymVal a) => TP (Proof (Forall "l" [a] -> Forall "pivot" a -> SBool))
+partitionFstBound = sInduct "partitionNotLongerFst"
+   (\(Forall l) (Forall pivot) -> length (fst (partition @a pivot l)) .<= length l)
+   (\l _ -> length l, []) $
+   \ih l pivot -> [] |- length (fst (partition @a pivot l)) .<= length l
+                     =: [pCase| l of
+                          []             -> trivial
+                          whole@(a : as) ->
+                             let lo = fst (partition pivot as)
+                             in ite (a .< pivot)
+                                    (length (a .: lo) .<= length whole)
+                                    (length       lo  .<= length whole)
+                             ?? "simplify"
+                             =: ite (a .< pivot)
+                                    (length lo .<=     length as)
+                                    (length lo .<= 1 + length as)
+                             ?? ih `at` (Inst @"l" as, Inst @"pivot" pivot)
+                             =: sTrue
+                             =: qed
+                        |]
+
+-- | The second component of partition is no longer than the input.
+--
+-- >>> runTP $ partitionSndBound @Integer
+-- Inductive lemma (strong): partitionNotLongerSnd
+--   Step: Measure is non-negative                    Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1                                      Q.E.D.
+--     Step: 1.2.1                                    Q.E.D.
+--     Step: 1.2.2 (simplify)                         Q.E.D.
+--     Step: 1.2.3                                    Q.E.D.
+--     Step: 1.Completeness                           Q.E.D.
+--   Result:                                          Q.E.D.
+-- Functions proven terminating: partition
+-- [Proven] partitionNotLongerSnd :: Ɐl ∷ [Integer] → Ɐpivot ∷ Integer → Bool
+partitionSndBound :: forall a. (OrdSymbolic (SBV a), SymVal a) => TP (Proof (Forall "l" [a] -> Forall "pivot" a -> SBool))
+partitionSndBound = sInduct "partitionNotLongerSnd"
+   (\(Forall l) (Forall pivot) -> length (snd (partition @a pivot l)) .<= length l)
+   (\l _ -> length l, []) $
+   \ih l pivot -> [] |- length (snd (partition @a pivot l)) .<= length l
+                     =: [pCase| l of
+                          []     -> trivial
+                          whole@(a : as) -> let hi = snd (partition pivot as)
+                                 in ite (a .< pivot)
+                                        (length       hi  .<= length whole)
+                                        (length (a .: hi) .<= length whole)
+                                 ?? "simplify"
+                                 =: ite (a .< pivot)
+                                        (length hi .<= 1 + length as)
+                                        (length hi .<=     length as)
+                                 ?? ih `at` (Inst @"l" as, Inst @"pivot" pivot)
+                                 =: sTrue
+                                 =: qed
+                        |]
+
 -- * Correctness proof
 
 -- | Correctness of quick-sort.
@@ -70,166 +147,154 @@
 --
 -- >>> correctness @Integer
 -- Inductive lemma: countAppend
---   Step: Base                                                Q.E.D.
---   Step: 1                                                   Q.E.D.
---   Step: 2 (unfold count)                                    Q.E.D.
---   Step: 3                                                   Q.E.D.
---   Step: 4 (simplify)                                        Q.E.D.
---   Result:                                                   Q.E.D.
+--   Step: Base                                       Q.E.D.
+--   Step: 1                                          Q.E.D.
+--   Step: 2 (unfold count)                           Q.E.D.
+--   Step: 3                                          Q.E.D.
+--   Step: 4 (simplify)                               Q.E.D.
+--   Result:                                          Q.E.D.
 -- Inductive lemma: countNonNeg
---   Step: Base                                                Q.E.D.
+--   Step: Base                                       Q.E.D.
 --   Step: 1 (2 way case split)
---     Step: 1.1.1                                             Q.E.D.
---     Step: 1.1.2                                             Q.E.D.
---     Step: 1.2.1                                             Q.E.D.
---     Step: 1.2.2                                             Q.E.D.
---     Step: 1.Completeness                                    Q.E.D.
---   Result:                                                   Q.E.D.
+--     Step: 1.1.1                                    Q.E.D.
+--     Step: 1.1.2                                    Q.E.D.
+--     Step: 1.2.1                                    Q.E.D.
+--     Step: 1.2.2                                    Q.E.D.
+--     Step: 1.Completeness                           Q.E.D.
+--   Result:                                          Q.E.D.
 -- Inductive lemma: countElem
---   Step: Base                                                Q.E.D.
+--   Step: Base                                       Q.E.D.
 --   Step: 1 (2 way case split)
---     Step: 1.1.1                                             Q.E.D.
---     Step: 1.1.2                                             Q.E.D.
---     Step: 1.2.1                                             Q.E.D.
---     Step: 1.2.2                                             Q.E.D.
---     Step: 1.Completeness                                    Q.E.D.
---   Result:                                                   Q.E.D.
+--     Step: 1.1.1                                    Q.E.D.
+--     Step: 1.1.2                                    Q.E.D.
+--     Step: 1.2.1                                    Q.E.D.
+--     Step: 1.2.2                                    Q.E.D.
+--     Step: 1.Completeness                           Q.E.D.
+--   Result:                                          Q.E.D.
 -- Inductive lemma: elemCount
---   Step: Base                                                Q.E.D.
+--   Step: Base                                       Q.E.D.
 --   Step: 1 (2 way case split)
---     Step: 1.1                                               Q.E.D.
---     Step: 1.2.1                                             Q.E.D.
---     Step: 1.2.2                                             Q.E.D.
---     Step: 1.Completeness                                    Q.E.D.
---   Result:                                                   Q.E.D.
+--     Step: 1.1                                      Q.E.D.
+--     Step: 1.2.1                                    Q.E.D.
+--     Step: 1.2.2                                    Q.E.D.
+--     Step: 1.Completeness                           Q.E.D.
+--   Result:                                          Q.E.D.
 -- Lemma: sublistCorrect
---   Step: 1                                                   Q.E.D.
---   Result:                                                   Q.E.D.
+--   Step: 1                                          Q.E.D.
+--   Result:                                          Q.E.D.
 -- Lemma: sublistElem
---   Step: 1                                                   Q.E.D.
---   Result:                                                   Q.E.D.
--- Lemma: sublistTail                                          Q.E.D.
--- Lemma: sublistIfPerm                                        Q.E.D.
+--   Step: 1                                          Q.E.D.
+--   Result:                                          Q.E.D.
+-- Lemma: sublistTail                                 Q.E.D.
+-- Lemma: sublistIfPerm                               Q.E.D.
 -- Inductive lemma: lltCorrect
---   Step: Base                                                Q.E.D.
---   Step: 1                                                   Q.E.D.
---   Result:                                                   Q.E.D.
+--   Step: Base                                       Q.E.D.
+--   Step: 1                                          Q.E.D.
+--   Result:                                          Q.E.D.
 -- Inductive lemma: lgeCorrect
---   Step: Base                                                Q.E.D.
---   Step: 1                                                   Q.E.D.
---   Result:                                                   Q.E.D.
+--   Step: Base                                       Q.E.D.
+--   Step: 1                                          Q.E.D.
+--   Result:                                          Q.E.D.
 -- Inductive lemma: lltSublist
---   Step: Base                                                Q.E.D.
---   Step: 1                                                   Q.E.D.
---   Step: 2                                                   Q.E.D.
---   Result:                                                   Q.E.D.
+--   Step: Base                                       Q.E.D.
+--   Step: 1                                          Q.E.D.
+--   Step: 2                                          Q.E.D.
+--   Result:                                          Q.E.D.
 -- Lemma: lltPermutation
---   Step: 1                                                   Q.E.D.
---   Result:                                                   Q.E.D.
+--   Step: 1                                          Q.E.D.
+--   Result:                                          Q.E.D.
 -- Inductive lemma: lgeSublist
---   Step: Base                                                Q.E.D.
---   Step: 1                                                   Q.E.D.
---   Step: 2                                                   Q.E.D.
---   Result:                                                   Q.E.D.
+--   Step: Base                                       Q.E.D.
+--   Step: 1                                          Q.E.D.
+--   Step: 2                                          Q.E.D.
+--   Result:                                          Q.E.D.
 -- Lemma: lgePermutation
---   Step: 1                                                   Q.E.D.
---   Result:                                                   Q.E.D.
+--   Step: 1                                          Q.E.D.
+--   Result:                                          Q.E.D.
 -- Inductive lemma: partitionFstLT
---   Step: Base                                                Q.E.D.
---   Step: 1 (unroll partition)                                Q.E.D.
---   Step: 2 (push fst down, simplify)                         Q.E.D.
---   Step: 3 (push llt down)                                   Q.E.D.
---   Step: 4                                                   Q.E.D.
---   Result:                                                   Q.E.D.
+--   Step: Base                                       Q.E.D.
+--   Step: 1 (unroll partition)                       Q.E.D.
+--   Step: 2 (push fst down, simplify)                Q.E.D.
+--   Step: 3 (push llt down)                          Q.E.D.
+--   Step: 4                                          Q.E.D.
+--   Result:                                          Q.E.D.
 -- Inductive lemma: partitionSndGE
---   Step: Base                                                Q.E.D.
---   Step: 1                                                   Q.E.D.
---   Step: 2 (push lge down)                                   Q.E.D.
---   Step: 3                                                   Q.E.D.
---   Result:                                                   Q.E.D.
--- Inductive lemma (strong): partitionNotLongerFst
---   Step: Measure is non-negative                             Q.E.D.
---   Step: 1 (2 way full case split)
---     Step: 1.1                                               Q.E.D.
---     Step: 1.2.1                                             Q.E.D.
---     Step: 1.2.2 (simplify)                                  Q.E.D.
---     Step: 1.2.3                                             Q.E.D.
---   Result:                                                   Q.E.D.
--- Inductive lemma (strong): partitionNotLongerSnd
---   Step: Measure is non-negative                             Q.E.D.
---   Step: 1 (2 way full case split)
---     Step: 1.1                                               Q.E.D.
---     Step: 1.2.1                                             Q.E.D.
---     Step: 1.2.2 (simplify)                                  Q.E.D.
---     Step: 1.2.3                                             Q.E.D.
---   Result:                                                   Q.E.D.
+--   Step: Base                                       Q.E.D.
+--   Step: 1                                          Q.E.D.
+--   Step: 2 (push lge down)                          Q.E.D.
+--   Step: 3                                          Q.E.D.
+--   Result:                                          Q.E.D.
+-- Lemma: partitionNotLongerFst                       Q.E.D.
+-- Lemma: partitionNotLongerSnd                       Q.E.D.
 -- Inductive lemma: countPartition
---   Step: Base                                                Q.E.D.
---   Step: 1 (expand partition)                                Q.E.D.
---   Step: 2 (push countTuple down)                            Q.E.D.
+--   Step: Base                                       Q.E.D.
+--   Step: 1 (expand partition)                       Q.E.D.
+--   Step: 2 (push countTuple down)                   Q.E.D.
 --   Step: 3 (2 way case split)
---     Step: 3.1.1                                             Q.E.D.
---     Step: 3.1.2 (simplify)                                  Q.E.D.
---     Step: 3.1.3                                             Q.E.D.
---     Step: 3.2.1                                             Q.E.D.
---     Step: 3.2.2 (simplify)                                  Q.E.D.
---     Step: 3.2.3                                             Q.E.D.
---     Step: 3.Completeness                                    Q.E.D.
---   Result:                                                   Q.E.D.
+--     Step: 3.1.1                                    Q.E.D.
+--     Step: 3.1.2 (simplify)                         Q.E.D.
+--     Step: 3.1.3                                    Q.E.D.
+--     Step: 3.2.1                                    Q.E.D.
+--     Step: 3.2.2 (simplify)                         Q.E.D.
+--     Step: 3.2.3                                    Q.E.D.
+--     Step: 3.Completeness                           Q.E.D.
+--   Result:                                          Q.E.D.
 -- Inductive lemma (strong): sortCountsMatch
---   Step: Measure is non-negative                             Q.E.D.
---   Step: 1 (2 way full case split)
---     Step: 1.1                                               Q.E.D.
---     Step: 1.2.1                                             Q.E.D.
---     Step: 1.2.2 (expand quickSort)                          Q.E.D.
---     Step: 1.2.3 (push count down)                           Q.E.D.
---     Step: 1.2.4                                             Q.E.D.
---     Step: 1.2.5                                             Q.E.D.
---     Step: 1.2.6 (IH on lo)                                  Q.E.D.
---     Step: 1.2.7 (IH on hi)                                  Q.E.D.
---     Step: 1.2.8                                             Q.E.D.
---   Result:                                                   Q.E.D.
--- Lemma: sortIsPermutation                                    Q.E.D.
+--   Step: Measure is non-negative                    Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1                                      Q.E.D.
+--     Step: 1.2.1                                    Q.E.D.
+--     Step: 1.2.2 (expand quickSort)                 Q.E.D.
+--     Step: 1.2.3 (push count down)                  Q.E.D.
+--     Step: 1.2.4                                    Q.E.D.
+--     Step: 1.2.5                                    Q.E.D.
+--     Step: 1.2.6 (IH on lo)                         Q.E.D.
+--     Step: 1.2.7 (IH on hi)                         Q.E.D.
+--     Step: 1.2.8                                    Q.E.D.
+--     Step: 1.Completeness                           Q.E.D.
+--   Result:                                          Q.E.D.
+-- Lemma: sortIsPermutation                           Q.E.D.
 -- Inductive lemma: nonDecreasingMerge
---   Step: Base                                                Q.E.D.
---   Step: 1 (2 way full case split)
---     Step: 1.1                                               Q.E.D.
---     Step: 1.2.1                                             Q.E.D.
---     Step: 1.2.2                                             Q.E.D.
---     Step: 1.2.3                                             Q.E.D.
---     Step: 1.2.4                                             Q.E.D.
---     Step: 1.2.5                                             Q.E.D.
---     Step: 1.2.6                                             Q.E.D.
---     Step: 1.2.7                                             Q.E.D.
---   Result:                                                   Q.E.D.
+--   Step: Base                                       Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1                                      Q.E.D.
+--     Step: 1.2.1                                    Q.E.D.
+--     Step: 1.2.2                                    Q.E.D.
+--     Step: 1.2.3                                    Q.E.D.
+--     Step: 1.2.4                                    Q.E.D.
+--     Step: 1.2.5                                    Q.E.D.
+--     Step: 1.2.6                                    Q.E.D.
+--     Step: 1.2.7                                    Q.E.D.
+--     Step: 1.Completeness                           Q.E.D.
+--   Result:                                          Q.E.D.
 -- Inductive lemma (strong): sortIsNonDecreasing
---   Step: Measure is non-negative                             Q.E.D.
---   Step: 1 (2 way full case split)
---     Step: 1.1                                               Q.E.D.
---     Step: 1.2.1                                             Q.E.D.
---     Step: 1.2.2 (expand quickSort)                          Q.E.D.
---     Step: 1.2.3 (push nonDecreasing down)                   Q.E.D.
---     Step: 1.2.4                                             Q.E.D.
---   Result:                                                   Q.E.D.
--- Lemma: quickSortIsCorrect                                   Q.E.D.
+--   Step: Measure is non-negative                    Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1                                      Q.E.D.
+--     Step: 1.2.1                                    Q.E.D.
+--     Step: 1.2.2 (expand quickSort)                 Q.E.D.
+--     Step: 1.2.3                                    Q.E.D.
+--     Step: 1.Completeness                           Q.E.D.
+--   Result:                                          Q.E.D.
+-- Lemma: quickSortIsCorrect                          Q.E.D.
 -- Inductive lemma: partitionSortedLeft
---   Step: Base                                                Q.E.D.
---   Step: 1                                                   Q.E.D.
---   Step: 2                                                   Q.E.D.
---   Result:                                                   Q.E.D.
+--   Step: Base                                       Q.E.D.
+--   Step: 1                                          Q.E.D.
+--   Step: 2                                          Q.E.D.
+--   Result:                                          Q.E.D.
 -- Inductive lemma: partitionSortedRight
---   Step: Base                                                Q.E.D.
---   Step: 1                                                   Q.E.D.
---   Step: 2                                                   Q.E.D.
---   Result:                                                   Q.E.D.
+--   Step: Base                                       Q.E.D.
+--   Step: 1                                          Q.E.D.
+--   Step: 2                                          Q.E.D.
+--   Result:                                          Q.E.D.
 -- Inductive lemma: unchangedIfNondecreasing
---   Step: Base                                                Q.E.D.
---   Step: 1                                                   Q.E.D.
---   Step: 2                                                   Q.E.D.
---   Step: 3                                                   Q.E.D.
---   Step: 4                                                   Q.E.D.
---   Result:                                                   Q.E.D.
--- Lemma: ifChangedThenUnsorted                                Q.E.D.
+--   Step: Base                                       Q.E.D.
+--   Step: 1                                          Q.E.D.
+--   Step: 2                                          Q.E.D.
+--   Step: 3                                          Q.E.D.
+--   Step: 4                                          Q.E.D.
+--   Result:                                          Q.E.D.
+-- Lemma: ifChangedThenUnsorted                       Q.E.D.
 -- == Proof tree:
 -- quickSortIsCorrect
 --  ├╴sortIsPermutation
@@ -261,9 +326,10 @@
 --     │  │  └╴sublistTail
 --     │  └╴sublistIfPerm
 --     └╴nonDecreasingMerge
+-- Functions proven terminating: count, lge, llt, nonDecreasing, partition, quickSort
 -- [Proven] quickSortIsCorrect :: Ɐxs ∷ [Integer] → Bool
 correctness :: forall a. (Eq a, OrdSymbolic (SBV a), SymVal a) => IO (Proof (Forall "xs" [a] -> SBool))
-correctness = runTPWith (tpRibbon 60 z3) $ do
+correctness = runTP $ do
 
   --------------------------------------------------------------------------------------------
   -- Part I. Import helper lemmas, definitions
@@ -284,8 +350,16 @@
   -- llt: list less-than:     all the elements are <  pivot
   -- lge: list greater-equal: all the elements are >= pivot
   let llt, lge :: SBV a -> SList a -> SBool
-      llt = smtFunction "llt" $ \pivot l -> null l .|| let (x, xs) = uncons l in x .<  pivot .&& llt pivot xs
-      lge = smtFunction "lge" $ \pivot l -> null l .|| let (x, xs) = uncons l in x .>= pivot .&& lge pivot xs
+      llt = smtFunction "llt"
+          $ \pivot l -> [sCase| l of
+                           []     -> sTrue
+                           x : xs -> x .<  pivot .&& llt pivot xs
+                        |]
+      lge = smtFunction "lge"
+          $ \pivot l -> [sCase| l of
+                           []     -> sTrue
+                           x : xs -> x .>= pivot .&& lge pivot xs
+                        |]
 
   -- llt correctness
   lltCorrect <-
@@ -404,40 +478,10 @@
                              =: qed
 
   -- The first element of partition does not increase in size
-  partitionNotLongerFst <- sInduct "partitionNotLongerFst"
-     (\(Forall l) (Forall pivot) -> length (fst (partition @a pivot l)) .<= length l)
-     (\l _ -> length l) $
-     \ih l pivot -> [] |- length (fst (partition @a pivot l)) .<= length l
-                       =: split l trivial
-                                (\a as -> let lo = fst (partition pivot as)
-                                       in ite (a .< pivot)
-                                              (length (a .: lo) .<= length (a .: as))
-                                              (length       lo  .<= length (a .: as))
-                                       ?? "simplify"
-                                       =: ite (a .< pivot)
-                                              (length lo .<=     length as)
-                                              (length lo .<= 1 + length as)
-                                       ?? ih `at` (Inst @"l" as, Inst @"pivot" pivot)
-                                       =: sTrue
-                                       =: qed)
+  partitionNotLongerFst <- recall (partitionFstBound @a)
 
   -- The second element of partition does not increase in size
-  partitionNotLongerSnd <- sInduct "partitionNotLongerSnd"
-     (\(Forall l) (Forall pivot) -> length (snd (partition @a pivot l)) .<= length l)
-     (\l _ -> length l) $
-     \ih l pivot -> [] |- length (snd (partition @a pivot l)) .<= length l
-                       =: split l trivial
-                                (\a as -> let hi = snd (partition pivot as)
-                                       in ite (a .< pivot)
-                                              (length       hi  .<= length (a .: as))
-                                              (length (a .: hi) .<= length (a .: as))
-                                       ?? "simplify"
-                                       =: ite (a .< pivot)
-                                              (length hi .<= 1 + length as)
-                                              (length hi .<=     length as)
-                                       ?? ih `at` (Inst @"l" as, Inst @"pivot" pivot)
-                                       =: sTrue
-                                       =: qed)
+  partitionNotLongerSnd <- recall (partitionSndBound @a)
 
   --------------------------------------------------------------------------------------------
   -- Part IV. Helper lemmas for count
@@ -487,32 +531,34 @@
   sortCountsMatch <-
      sInduct "sortCountsMatch"
              (\(Forall xs) (Forall e) -> count e xs .== count e (quickSort xs))
-             (\xs _ -> length xs) $
+             (\xs _ -> length xs, []) $
              \ih xs e ->
                 [] |- count e (quickSort xs)
-                   =: split xs trivial
-                            (\a as -> count e (quickSort (a .: as))
-                                   ?? "expand quickSort"
-                                   =: count e (let (lo, hi) = untuple (partition a as)
-                                               in quickSort lo ++ [a] ++ quickSort hi)
-                                   ?? "push count down"
-                                   =: let (lo, hi) = untuple (partition a as)
-                                   in count e (quickSort lo ++ [a] ++ quickSort hi)
-                                   ?? countAppend `at` (Inst @"xs" (quickSort lo), Inst @"ys" ([a] ++ quickSort hi), Inst @"e" e)
-                                   =: count e (quickSort lo) + count e ([a] ++ quickSort hi)
-                                   ?? countAppend `at` (Inst @"xs" [a], Inst @"ys" (quickSort hi), Inst @"e" e)
-                                   =: count e (quickSort lo) + count e [a] + count e (quickSort hi)
-                                   ?? ih                    `at` (Inst @"xs" lo, Inst @"e" e)
-                                   ?? partitionNotLongerFst `at` (Inst @"l"  as, Inst @"pivot" a)
-                                   ?? "IH on lo"
-                                   =: count e lo + count e [a] + count e (quickSort hi)
-                                   ?? ih                    `at` (Inst @"xs" hi, Inst @"e" e)
-                                   ?? partitionNotLongerSnd `at` (Inst @"l"  as, Inst @"pivot" a)
-                                   ?? "IH on hi"
-                                   =: count e lo + count e [a] + count e hi
-                                   ?? countPartition `at` (Inst @"xs" as, Inst @"pivot" a, Inst @"e" e)
-                                   =: count e xs
-                                   =: qed)
+                   =: [pCase| xs of
+                        []             -> trivial
+                        whole@(a : as) ->
+                              let (lo, hi) = untuple (partition a as)
+                              in count e (quickSort whole)
+                              ?? "expand quickSort"
+                              =: count e (quickSort lo ++ [a] ++ quickSort hi)
+                              ?? "push count down"
+                              =: count e (quickSort lo ++ [a] ++ quickSort hi)
+                              ?? countAppend `at` (Inst @"xs" (quickSort lo), Inst @"ys" ([a] ++ quickSort hi), Inst @"e" e)
+                              =: count e (quickSort lo) + count e ([a] ++ quickSort hi)
+                              ?? countAppend `at` (Inst @"xs" [a], Inst @"ys" (quickSort hi), Inst @"e" e)
+                              =: count e (quickSort lo) + count e [a] + count e (quickSort hi)
+                              ?? ih                    `at` (Inst @"xs" lo, Inst @"e" e)
+                              ?? partitionNotLongerFst `at` (Inst @"l"  as, Inst @"pivot" a)
+                              ?? "IH on lo"
+                              =: count e lo + count e [a] + count e (quickSort hi)
+                              ?? ih                    `at` (Inst @"xs" hi, Inst @"e" e)
+                              ?? partitionNotLongerSnd `at` (Inst @"l"  as, Inst @"pivot" a)
+                              ?? "IH on hi"
+                              =: count e lo + count e [a] + count e hi
+                              ?? countPartition `at` (Inst @"xs" as, Inst @"pivot" a, Inst @"e" e)
+                              =: count e xs
+                              =: qed
+                      |]
 
   sortIsPermutation <- lemma "sortIsPermutation" (\(Forall xs) -> isPermutation xs (quickSort xs)) [proofOf sortCountsMatch]
 
@@ -527,18 +573,21 @@
           \ih (x, xs) pivot ys ->
                 [nonDecreasing (x .: xs), llt pivot xs, nonDecreasing ys, lge pivot ys]
              |- nonDecreasing (x .: xs ++ [pivot] ++ ys)
-             =: split xs trivial
-                      (\a as -> nonDecreasing (x .: (a .: as) ++ [pivot] ++ ys)
-                             =: nonDecreasing (x .: a .: (as ++ [pivot] ++ ys))
-                             =: x .<= a .&& nonDecreasing (a .: (as ++ [pivot] ++ ys))
-                             =: nonDecreasing (a .: (as ++ [pivot] ++ ys))
-                             =: nonDecreasing ((a .: as) ++ [pivot] ++ ys)
-                             =: nonDecreasing (xs ++ [pivot] ++ ys)
-                             -- This hint shouldn't be necessary, but it makes the proof go faster!
-                             ?? nonDecreasing xs
-                             ?? ih
-                             =: sTrue
-                             =: qed)
+             =: [pCase| xs of
+                  [] -> trivial
+                  whole@(a : as) ->
+                         nonDecreasing (x .: whole ++ [pivot] ++ ys)
+                      =: nonDecreasing (x .: a .: (as ++ [pivot] ++ ys))
+                      =: x .<= a .&& nonDecreasing (a .: (as ++ [pivot] ++ ys))
+                      =: nonDecreasing (a .: (as ++ [pivot] ++ ys))
+                      =: nonDecreasing (whole ++ [pivot] ++ ys)
+                      =: nonDecreasing (xs ++ [pivot] ++ ys)
+                      -- This hint shouldn't be necessary, but it makes the proof go faster!
+                      ?? nonDecreasing xs
+                      ?? ih
+                      =: sTrue
+                      =: qed
+                |]
 
   --------------------------------------------------------------------------------------------
   -- Part VII. Prove that the output of quick sort is non-decreasing
@@ -546,41 +595,41 @@
   sortIsNonDecreasing <-
      sInductWith cvc5 "sortIsNonDecreasing"
              (\(Forall xs) -> nonDecreasing (quickSort xs))
-             (length @a) $
+             (length @a, []) $
              \ih xs ->
                 [] |- nonDecreasing (quickSort xs)
-                   =: split xs trivial
-                            (\a as -> nonDecreasing (quickSort (a .: as))
-                                   ?? "expand quickSort"
-                                   =: nonDecreasing (let (lo, hi) = untuple (partition a as)
-                                                     in quickSort lo ++ [a] ++ quickSort hi)
-                                   ?? "push nonDecreasing down"
-                                   =: let (lo, hi) = untuple (partition a as)
-                                   in nonDecreasing (quickSort lo ++ [a] ++ quickSort hi)
-                                   -- Deduce that lo/hi is not longer than as, and hence, shorter than xs
-                                   ?? partitionNotLongerFst `at` (Inst @"l" as, Inst @"pivot" a)
-                                   ?? partitionNotLongerSnd `at` (Inst @"l" as, Inst @"pivot" a)
+                   =: [pCase| xs of
+                        [] -> trivial
+                        whole@(a : as) ->
+                             let (lo, hi) = untuple (partition a as)
+                             in nonDecreasing (quickSort whole)
+                          ?? "expand quickSort"
+                          =: nonDecreasing (quickSort lo ++ [a] ++ quickSort hi)
+                          -- Deduce that lo/hi is not longer than as, and hence, shorter than xs
+                          ?? partitionNotLongerFst `at` (Inst @"l" as, Inst @"pivot" a)
+                          ?? partitionNotLongerSnd `at` (Inst @"l" as, Inst @"pivot" a)
 
-                                   -- Use the inductive hypothesis twice to deduce quickSort of lo and hi are nonDecreasing
-                                   ?? ih `at` Inst @"xs" lo  -- nonDecreasing (quickSort lo)
-                                   ?? ih `at` Inst @"xs" hi  -- nonDecreasing (quickSort hi)
+                          -- Use the inductive hypothesis twice to deduce quickSort of lo and hi are nonDecreasing
+                          ?? ih `at` Inst @"xs" lo  -- nonDecreasing (quickSort lo)
+                          ?? ih `at` Inst @"xs" hi  -- nonDecreasing (quickSort hi)
 
-                                   -- Deduce that lo is all less than a, and hi is all greater than or equal to a
-                                   ?? partitionFstLT `at` (Inst @"l" as, Inst @"pivot" a)
-                                   ?? partitionSndGE `at` (Inst @"l" as, Inst @"pivot" a)
+                          -- Deduce that lo is all less than a, and hi is all greater than or equal to a
+                          ?? partitionFstLT `at` (Inst @"l" as, Inst @"pivot" a)
+                          ?? partitionSndGE `at` (Inst @"l" as, Inst @"pivot" a)
 
-                                   -- Deduce that quickSort lo is all less than a
-                                   ?? sortIsPermutation `at`  Inst @"xs" lo
-                                   ?? lltPermutation    `at` (Inst @"xs" (quickSort lo), Inst @"pivot" a, Inst @"ys" lo)
+                          -- Deduce that quickSort lo is all less than a
+                          ?? sortIsPermutation `at`  Inst @"xs" lo
+                          ?? lltPermutation    `at` (Inst @"xs" (quickSort lo), Inst @"pivot" a, Inst @"ys" lo)
 
-                                   -- Deduce that quickSort hi is all greater than or equal to a
-                                   ?? sortIsPermutation `at`  Inst @"xs" hi
-                                   ?? lgePermutation    `at` (Inst @"xs" (quickSort hi), Inst @"pivot" a, Inst @"ys" hi)
+                          -- Deduce that quickSort hi is all greater than or equal to a
+                          ?? sortIsPermutation `at`  Inst @"xs" hi
+                          ?? lgePermutation    `at` (Inst @"xs" (quickSort hi), Inst @"pivot" a, Inst @"ys" hi)
 
-                                   -- Finally conclude that the whole reconstruction is non-decreasing
-                                   ?? nonDecreasingMerge `at` (Inst @"xs" (quickSort lo), Inst @"pivot" a, Inst @"ys" (quickSort hi))
-                                   =: sTrue
-                                   =: qed)
+                          -- Finally conclude that the whole reconstruction is non-decreasing
+                          ?? nonDecreasingMerge `at` (Inst @"xs" (quickSort lo), Inst @"pivot" a, Inst @"ys" (quickSort hi))
+                          =: sTrue
+                          =: qed
+                      |]
 
   --------------------------------------------------------------------------------------------
   -- Part VIII. Putting it together
@@ -631,16 +680,18 @@
                           =: x .: xs
                           =: qed
 
-  -- A nice corrollary to the above is that if quicksort changes its input, that implies the input was not non-decreasing:
+  -- A nice corollary to the above is that if quicksort changes its input, that implies the input was not non-decreasing:
   _ <- lemma "ifChangedThenUnsorted"
              (\(Forall @"xs" xs) -> quickSort xs ./= xs .=> sNot (nonDecreasing xs))
              [proofOf unchangedIfNondecreasing]
 
   --------------------------------------------------------------------------------------------
-  -- | We can display the dependencies in a proof
+  -- We can display the dependencies in a proof.
+  -- Note that we do avoid doing this during the
+  -- dry-run of the proof to avoid duplicate output.
   --------------------------------------------------------------------------------------------
-  liftIO $ do putStrLn "== Proof tree:"
-              putStr $ showProofTree True qs
+  unlessDryRun $ liftIO $ do putStrLn "== Proof tree:"
+                             putStr $ showProofTree True qs
 
   pure qs
 
diff --git a/Documentation/SBV/Examples/TP/RevAcc.hs b/Documentation/SBV/Examples/TP/RevAcc.hs
--- a/Documentation/SBV/Examples/TP/RevAcc.hs
+++ b/Documentation/SBV/Examples/TP/RevAcc.hs
@@ -6,13 +6,14 @@
 -- Maintainer: erkokl@gmail.com
 -- Stability : experimental
 --
--- Proves that the accummulating version of reverse is equivalent to the
+-- Proves that the accumulating version of reverse is equivalent to the
 -- standard definition.
 -----------------------------------------------------------------------------
 
 {-# LANGUAGE CPP                 #-}
 {-# LANGUAGE DataKinds           #-}
 {-# LANGUAGE OverloadedLists     #-}
+{-# LANGUAGE QuasiQuotes         #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeAbstractions    #-}
 
@@ -31,11 +32,15 @@
 -- >>> :set -XTypeApplications
 #endif
 
--- * Reversing with an accummulator.
+-- * Reversing with an accumulator.
 
--- | Accummulating reverse.
+-- | Accumulating reverse.
 revAcc :: SymVal a => SList a -> SList a -> SList a
-revAcc = smtFunction "revAcc" $ \acc xs -> ite (null xs) acc (revAcc (head xs .: acc) (tail xs))
+revAcc = smtFunction "revAcc"
+       $ \acc xs -> [sCase| xs of
+                       []     -> acc
+                       a : as -> revAcc (a .: acc) as
+                    |]
 
 -- | Given 'revAcc', we can reverse a list by providing the empty list as the initial accumulator.
 rev :: SymVal a => SList a -> SList a
@@ -47,13 +52,14 @@
 --
 -- >>> correctness @Integer
 -- Inductive lemma: revAccCorrect
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4                               Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: revCorrect                       Q.E.D.
+--   Step: Base                      Q.E.D.
+--   Step: 1                         Q.E.D.
+--   Step: 2                         Q.E.D.
+--   Step: 3                         Q.E.D.
+--   Step: 4                         Q.E.D.
+--   Result:                         Q.E.D.
+-- Lemma: revCorrect                 Q.E.D.
+-- Functions proven terminating: revAcc, sbv.reverse
 -- [Proven] revCorrect :: Ɐxs ∷ [Integer] → Bool
 correctness :: forall a. SymVal a => IO (Proof (Forall "xs" [a] -> SBool))
 correctness = runTP $ do
diff --git a/Documentation/SBV/Examples/TP/Reverse.hs b/Documentation/SBV/Examples/TP/Reverse.hs
--- a/Documentation/SBV/Examples/TP/Reverse.hs
+++ b/Documentation/SBV/Examples/TP/Reverse.hs
@@ -17,8 +17,8 @@
 {-# LANGUAGE CPP                 #-}
 {-# LANGUAGE DataKinds           #-}
 {-# LANGUAGE OverloadedLists     #-}
+{-# LANGUAGE QuasiQuotes         #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeAbstractions    #-}
 {-# LANGUAGE TypeApplications    #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
@@ -31,7 +31,7 @@
 import Data.SBV.List hiding (partition)
 import Data.SBV.TP
 
-import qualified Data.SBV.TP.List as TP
+import qualified Documentation.SBV.Examples.TP.Lists as TP
 
 #ifdef DOCTEST
 -- $setup
@@ -42,14 +42,54 @@
 -- * Reversing with no auxiliaries
 
 -- | This definition of reverse uses no helper functions, other than the usual
--- head, tail, cons, and uncons to reverse a given list. Note that efficiency
+-- head, tail, and cons to reverse a given list. Note that efficiency
 -- is not our concern here, we call 'rev' itself three times in the body.
-rev :: SymVal a => SList a -> SList a
-rev = smtFunction "rev" $ \xs -> ite (null xs .|| null (tail xs)) xs
-                                     (let (x, as)     = uncons xs
-                                          (hras, tas) = uncons (rev as)
-                                      in hras .: rev (x .: rev tas))
+rev :: forall a. SymVal a => SList a -> SList a
+rev = smtFunctionWithMeasure "rev"
+        ( length @a
+        , [measureLemma (revPreservesLen @a)]
+        )
+    $ \xs -> [sCase| xs of
+                []     -> xs
+                x : as -> case rev as of
+                            []         -> [x]
+                            hras : tas -> hras .: rev (x .: rev tas)
+             |]
 
+-- | Reversing preserves length. Needed as a measure helper for 'rev'.
+--
+-- >>> runTP $ revPreservesLen @Integer
+-- Inductive lemma (strong): revPreservesLen
+--   Step: Measure is non-negative              Q.E.D.
+--   Step: 1 (3 way case split)
+--     Step: 1.1                                Q.E.D.
+--     Step: 1.2                                Q.E.D.
+--     Step: 1.3.1                              Q.E.D.
+--     Step: 1.3.2                              Q.E.D.
+--     Step: 1.3.3                              Q.E.D.
+--     Step: 1.Completeness                     Q.E.D.
+--   Result:                                    Q.E.D.
+-- Functions proven terminating: rev
+-- [Proven] revPreservesLen :: Ɐxs ∷ [Integer] → Bool
+revPreservesLen :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> SBool))
+revPreservesLen = sInductWith cvc5 "revPreservesLen"
+   (\(Forall xs) -> length (rev @a xs) .== length xs)
+   (length, []) $
+   \ih xs -> [] |- length (rev @a xs) .== length xs
+               =: [pCase| xs of
+                    []     -> trivial
+                    [_]    -> trivial
+                    whole@(a : as) -> length (head (rev as) .: rev (a .: rev (tail (rev as)))) .== length whole
+                           -- Simplify: length (h .: e) = 1 + length e
+                           =: (1 + length (rev (a .: rev (tail (rev as))))) .== (1 + length as)
+                           -- Now apply the IH instances in order: each precondition depends on previous conclusions
+                           ?? ih `at` Inst @"xs" as
+                           ?? ih `at` Inst @"xs" (tail (rev as))
+                           ?? ih `at` Inst @"xs" (a .: rev (tail (rev as)))
+                           =: sTrue
+                           =: qed
+                  |]
+
 -- * Correctness proof
 
 -- | Correctness the function 'rev'. We have:
@@ -61,73 +101,74 @@
 -- Lemma: revRev                           Q.E.D.
 -- Inductive lemma (strong): revCorrect
 --   Step: Measure is non-negative         Q.E.D.
---   Step: 1 (2 way full case split)
+--   Step: 1 (3 way case split)
 --     Step: 1.1                           Q.E.D.
---     Step: 1.2 (2 way full case split)
---       Step: 1.2.1                       Q.E.D.
---       Step: 1.2.2.1                     Q.E.D.
---       Step: 1.2.2.2                     Q.E.D.
---       Step: 1.2.2.3                     Q.E.D.
---       Step: 1.2.2.4                     Q.E.D.
---       Step: 1.2.2.5                     Q.E.D.
---       Step: 1.2.2.6 (simplify head)     Q.E.D.
---       Step: 1.2.2.7                     Q.E.D.
---       Step: 1.2.2.8 (simplify tail)     Q.E.D.
---       Step: 1.2.2.9                     Q.E.D.
---       Step: 1.2.2.10                    Q.E.D.
---       Step: 1.2.2.11                    Q.E.D.
---       Step: 1.2.2.12 (substitute)       Q.E.D.
---       Step: 1.2.2.13                    Q.E.D.
---       Step: 1.2.2.14                    Q.E.D.
---       Step: 1.2.2.15                    Q.E.D.
+--     Step: 1.2                           Q.E.D.
+--     Step: 1.3.1                         Q.E.D.
+--     Step: 1.3.2                         Q.E.D.
+--     Step: 1.3.3                         Q.E.D.
+--     Step: 1.3.4                         Q.E.D.
+--     Step: 1.3.5 (simplify head)         Q.E.D.
+--     Step: 1.3.6                         Q.E.D.
+--     Step: 1.3.7 (simplify tail)         Q.E.D.
+--     Step: 1.3.8                         Q.E.D.
+--     Step: 1.3.9                         Q.E.D.
+--     Step: 1.3.10                        Q.E.D.
+--     Step: 1.3.11 (substitute)           Q.E.D.
+--     Step: 1.3.12                        Q.E.D.
+--     Step: 1.3.13                        Q.E.D.
+--     Step: 1.3.14                        Q.E.D.
+--     Step: 1.Completeness                Q.E.D.
 --   Result:                               Q.E.D.
+-- Functions proven terminating: rev, sbv.reverse
 -- [Proven] revCorrect :: Ɐxs ∷ [Integer] → Bool
 correctness :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> SBool))
 correctness = do
 
   -- Quietly import a few helpers from "Data.SBV.TP.List"
-  revLen  <- recall "revLen"  $ TP.revLen  @a
-  revApp  <- recall "revApp"  $ TP.revApp  @a
-  revSnoc <- recall "revSnoc" $ TP.revSnoc @a
-  revRev  <- recall "revRev"  $ TP.revRev  @a
+  revLen  <- recall $ TP.revLen  @a
+  revApp  <- recall $ TP.revApp  @a
+  revSnoc <- recall $ TP.revSnoc @a
+  revRev  <- recall $ TP.revRev  @a
 
   sInductWith cvc5 "revCorrect"
     (\(Forall xs) -> rev xs .== reverse xs)
-    length $
+    (length, []) $
     \ih xs -> [] |- rev xs
-                 =: split xs trivial
-                          (\a as -> split as trivial
-                                          (\_ _ -> head (rev as) .: rev (a .: rev (tail (rev as)))
-                                                ?? ih `at` Inst @"xs" as
-                                                =: head (reverse as) .: rev (a .: rev (tail (rev as)))
-                                                ?? ih `at` Inst @"xs" as
-                                                =: head (reverse as) .: rev (a .: rev (tail (reverse as)))
-                                                ?? ih `at` Inst @"xs" (tail (rev as))
-                                                =: head (reverse as) .: rev (a .: rev (tail (reverse as)))
-                                                ?? revSnoc `at` (Inst @"x" (last as), Inst @"xs" (init as))
-                                                =: let w = init as
-                                                       b = last as
-                                                in head (b .: reverse w) .: rev (a .: rev (tail (reverse as)))
-                                                ?? "simplify head"
-                                                =: b .: rev (a .: rev (tail (reverse as)))
-                                                ?? revSnoc `at` (Inst @"x" (last xs), Inst @"xs" (init as))
-                                                =: b .: rev (a .: rev (tail (b .: reverse w)))
-                                                ?? "simplify tail"
-                                                =: b .: rev (a .: rev (reverse w))
-                                                ?? ih     `at` Inst @"xs" (reverse w)
-                                                ?? revLen `at` Inst @"xs" w
-                                                =: b .: rev (a .: reverse (reverse w))
-                                                ?? revRev `at` Inst @"xs" w
-                                                =: b .: rev (a .: w)
-                                                ?? ih
-                                                =: b .: reverse (a .: w)
-                                                ?? "substitute"
-                                                =: last as .: reverse (a .: init as)
-                                                ?? revApp `at` (Inst @"xs" (a .: init as), Inst @"ys" [last as])
-                                                =: reverse (a .: init as ++ [last as])
-                                                =: reverse (a .: as)
-                                                =: reverse xs
-                                                =: qed))
+                 =: [pCase| xs of
+                      []     -> trivial
+                      [_]    -> trivial
+                      a : as -> head (rev as) .: rev (a .: rev (tail (rev as)))
+                             -- Replace both occurrences of rev as together.
+                             ?? ih `at` Inst @"xs" as
+                             =: head (reverse as) .: rev (a .: rev (tail (reverse as)))
+                             ?? ih `at` Inst @"xs" (tail (rev as))
+                             =: head (reverse as) .: rev (a .: rev (tail (reverse as)))
+                             ?? revSnoc `at` (Inst @"x" (last as), Inst @"xs" (init as))
+                             =: let w = init as
+                                    b = last as
+                             in head (b .: reverse w) .: rev (a .: rev (tail (reverse as)))
+                             ?? "simplify head"
+                             =: b .: rev (a .: rev (tail (reverse as)))
+                             ?? revSnoc `at` (Inst @"x" (last xs), Inst @"xs" (init as))
+                             =: b .: rev (a .: rev (tail (b .: reverse w)))
+                             ?? "simplify tail"
+                             =: b .: rev (a .: rev (reverse w))
+                             ?? ih     `at` Inst @"xs" (reverse w)
+                             ?? revLen `at` Inst @"xs" w
+                             =: b .: rev (a .: reverse (reverse w))
+                             ?? revRev `at` Inst @"xs" w
+                             =: b .: rev (a .: w)
+                             ?? ih
+                             =: b .: reverse (a .: w)
+                             ?? "substitute"
+                             =: last as .: reverse (a .: init as)
+                             ?? revApp `at` (Inst @"xs" (a .: init as), Inst @"ys" [last as])
+                             =: reverse (a .: init as ++ [last as])
+                             =: reverse (a .: as)
+                             =: reverse xs
+                             =: qed
+                    |]
 
 {- HLint ignore correctness "Use last"          -}
 {- HLint ignore correctness "Redundant reverse" -}
diff --git a/Documentation/SBV/Examples/TP/RunLength.hs b/Documentation/SBV/Examples/TP/RunLength.hs
new file mode 100644
--- /dev/null
+++ b/Documentation/SBV/Examples/TP/RunLength.hs
@@ -0,0 +1,198 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Documentation.SBV.Examples.TP.RunLength
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Proving that run-length decoding inverts encoding. We define:
+--
+--   * @encode@: groups consecutive equal elements into (value, count) pairs
+--   * @decode@: expands each pair back into a run of elements
+--
+-- and prove @decode (encode xs) == xs@ for all finite lists @xs@.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE CPP                 #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE OverloadedLists     #-}
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Documentation.SBV.Examples.TP.RunLength where
+
+import Prelude hiding (length, head, tail, null, reverse, (++), replicate, fst, snd)
+
+import Data.SBV
+import Data.SBV.List
+import Data.SBV.Tuple
+import Data.SBV.TP
+
+#ifdef DOCTEST
+-- $setup
+-- >>> :set -XOverloadedLists
+-- >>> :set -XTypeApplications
+-- >>> import Data.SBV
+-- >>> import Data.SBV.Tuple
+-- >>> import Data.SBV.TP
+#endif
+
+-- * Definitions
+
+-- | Run-length decode: expand each (value, count) pair into a run of that element.
+--
+-- >>> decode (tuple (1,3) .: tuple (2,2) .: tuple (3,1) .: []) :: SList Integer
+-- [1,1,1,2,2,3] :: [SInteger]
+-- >>> decode ([] :: SList (Integer, Integer))
+-- [] :: [SInteger]
+decode :: forall a. SymVal a => SList (a, Integer) -> SList a
+decode = smtFunction "decode"
+       $ \ps -> [sCase| ps of
+                   []            -> []
+                   (e, c) : rest -> replicate c e ++ decode rest
+                |]
+
+-- | Prepend an element to a run-length encoded list. If the head run has the
+-- same value, we increment its count; otherwise we create a new singleton run.
+--
+-- >>> encodeCons 1 (encode [1,1,2,2]) :: SList (Integer, Integer)
+-- [(1,3),(2,2)] :: [(SInteger, SInteger)]
+-- >>> encodeCons 5 (encode [1,1,2,2]) :: SList (Integer, Integer)
+-- [(5,1),(1,2),(2,2)] :: [(SInteger, SInteger)]
+encodeCons :: forall a. SymVal a => SBV a -> SList (a, Integer) -> SList (a, Integer)
+encodeCons = smtFunction "encodeCons"
+           $ \x ps -> [sCase| ps of
+                         []                      -> [tuple (x, 1)]
+                         (e, c) : rest | x .== e -> tuple (x, c + 1) .: rest
+                                       | True    -> tuple (x,     1) .: ps
+                      |]
+
+-- | Run-length encode: fold from the right, using 'encodeCons' to merge
+-- each element into the growing encoding.
+--
+-- >>> encode [1,1,1,2,2,3] :: SList (Integer, Integer)
+-- [(1,3),(2,2),(3,1)] :: [(SInteger, SInteger)]
+-- >>> encode ([] :: SList Integer)
+-- [] :: [(SInteger, SInteger)]
+-- >>> encode [4] :: SList (Integer, Integer)
+-- [(4,1)] :: [(SInteger, SInteger)]
+encode :: forall a. SymVal a => SList a -> SList (a, Integer)
+encode = smtFunction "encode"
+       $ \xs -> [sCase| xs of
+                   []       -> []
+                   x : rest -> encodeCons x (encode rest)
+                |]
+
+-- * Correctness
+
+-- | @decode (encode xs) == xs@
+--
+-- The proof proceeds by induction on @xs@. The key helper shows that
+-- decoding after 'encodeCons' is the same as consing the element,
+-- provided the head count in the encoded list is positive (which
+-- 'encode' always guarantees).
+--
+-- >>> runTPWith cvc5 $ correctness @Integer
+-- Lemma: decodeEncodeCons
+--   Step: 1 (3 way case split)
+--     Step: 1.1.1                         Q.E.D.
+--     Step: 1.1.2                         Q.E.D.
+--     Step: 1.1.3                         Q.E.D.
+--     Step: 1.1.4                         Q.E.D.
+--     Step: 1.2.1                         Q.E.D.
+--     Step: 1.2.2                         Q.E.D.
+--     Step: 1.2.3                         Q.E.D.
+--     Step: 1.2.4                         Q.E.D.
+--     Step: 1.3.1                         Q.E.D.
+--     Step: 1.3.2                         Q.E.D.
+--     Step: 1.Completeness                Q.E.D.
+--   Result:                               Q.E.D.
+-- Inductive lemma: encodeHeadPos
+--   Step: Base                            Q.E.D.
+--   Step: 1 (3 way case split)
+--     Step: 1.1                           Q.E.D.
+--     Step: 1.2.1                         Q.E.D.
+--     Step: 1.2.2                         Q.E.D.
+--     Step: 1.2.3                         Q.E.D.
+--     Step: 1.3                           Q.E.D.
+--     Step: 1.Completeness                Q.E.D.
+--   Result:                               Q.E.D.
+-- Inductive lemma (strong): rleCorrect
+--   Step: Measure is non-negative         Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1                           Q.E.D.
+--     Step: 1.2.1                         Q.E.D.
+--     Step: 1.2.2                         Q.E.D.
+--     Step: 1.2.3                         Q.E.D.
+--     Step: 1.2.4                         Q.E.D.
+--     Step: 1.Completeness                Q.E.D.
+--   Result:                               Q.E.D.
+-- Functions proven terminating: decode, encode, sbv.replicate
+-- [Proven] rleCorrect :: Ɐxs ∷ [Integer] → Bool
+correctness :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> SBool))
+correctness = do
+
+  -- Key helper: encodeCons followed by decode is the same as consing.
+  -- The condition ensures the head count is positive so that
+  -- replicate (n+1) unfolds correctly.
+  helper <- calc "decodeEncodeCons"
+                 (\(Forall @"x" (x :: SBV a)) (Forall @"ps" ps) ->
+                      (null ps .|| snd (head ps) .>= 1)
+                      .=> decode (encodeCons x ps) .== x .: decode ps) $
+                 \x ps -> [null ps .|| snd (head ps) .>= 1]
+                       |- decode (encodeCons x ps)
+                       =: [pCase| ps of
+                             []                       -> decode [tuple (x, 1)]
+                                                      =: replicate 1 x ++ decode []
+                                                      =: [x] ++ decode []
+                                                      =: x .: decode []
+                                                      =: qed
+                             ((e, c) : ecs) | x .== e -> decode (tuple (x, c + 1) .: ecs)
+                                                      =: replicate (c + 1) x ++ decode ecs
+                                                      =: x .: replicate c x ++ decode ecs
+                                                      =: x .: decode (tuple (e, c) .: ecs)
+                                                      =: qed
+                                            | True    -> decode (tuple (x, 1) .: ps)
+                                                      =: x .: decode ps
+                                                      =: qed
+                          |]
+
+  -- encode always produces a list whose head (if any) has count >= 1
+  -- (This is needed as a precondition for helper above.)
+  encPos <- induct "encodeHeadPos"
+                   (\(Forall @"xs" (xs :: SList a)) ->
+                        null (encode xs) .|| snd (head (encode xs)) .>= 1) $
+                   \ih (x, xs) -> []
+                               |- (null (encodeCons x (encode xs)) .|| snd (head (encodeCons x (encode xs))) .>= 1)
+                               =: cases [ null (encode xs)        ==> trivial
+                                        , sNot (null (encode xs)) .&& x .== fst (head (encode xs))
+                                           ==> snd (head (encodeCons x (encode xs))) .>= 1
+                                            =: snd (head (encode xs)) + 1 .>= 1
+                                            ?? ih
+                                            =: sTrue
+                                            =: qed
+                                        , sNot (null (encode xs)) .&& x ./= fst (head (encode xs))
+                                           ==> trivial
+                                        ]
+
+  -- Main theorem: decode . encode == id
+  sInduct "rleCorrect"
+          (\(Forall xs) -> decode @a (encode xs) .== xs)
+          (length @a, []) $
+          \ih xs -> [] |- decode (encode xs)
+                      =: [pCase| xs of
+                            []             -> trivial
+                            whole@(x : ys) -> decode (encode whole)
+                                           =: decode (encodeCons x (encode ys))
+                                           ?? helper `at` (Inst @"x" x, Inst @"ps" (encode ys))
+                                           ?? encPos `at` Inst @"xs" ys
+                                           =: x .: decode (encode ys)
+                                           ?? ih `at` Inst @"xs" ys
+                                           =: x .: ys
+                                           =: qed
+                         |]
diff --git a/Documentation/SBV/Examples/TP/ShefferStroke.hs b/Documentation/SBV/Examples/TP/ShefferStroke.hs
--- a/Documentation/SBV/Examples/TP/ShefferStroke.hs
+++ b/Documentation/SBV/Examples/TP/ShefferStroke.hs
@@ -11,15 +11,12 @@
 -- logic), imply it is a boolean algebra.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DataKinds            #-}
-{-# LANGUAGE DeriveDataTypeable   #-}
-{-# LANGUAGE DeriveAnyClass       #-}
-{-# LANGUAGE FlexibleInstances    #-}
-{-# LANGUAGE NamedFieldPuns       #-}
-{-# LANGUAGE ScopedTypeVariables  #-}
-{-# LANGUAGE StandaloneDeriving   #-}
-{-# LANGUAGE TemplateHaskell      #-}
-{-# LANGUAGE TypeAbstractions     #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE FlexibleInstances   #-}
+{-# LANGUAGE NamedFieldPuns      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE TypeAbstractions    #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -101,7 +98,7 @@
 
 -- | The abstract type for the domain.
 data Stroke
-mkUninterpretedSort ''Stroke
+mkSymbolic [''Stroke]
 
 -- | The sheffer stroke operator.
 (⏐) :: SStroke -> SStroke -> SStroke
@@ -145,195 +142,195 @@
 -- Axiom: a ⏐ (b ⏐ ﬧb) == ﬧa
 -- Axiom: ﬧ(a ⏐ (b ⏐ c)) == (ﬧb ⏐ a) ⏐ (ﬧc ⏐ a)
 -- Lemma: a | b = b | a
---   Step: 1 (ﬧﬧa == a)                                        Q.E.D.
---   Step: 2 (ﬧﬧa == a)                                        Q.E.D.
---   Step: 3                                                   Q.E.D.
---   Step: 4 (ﬧ(a ⏐ (b ⏐ c)) == (ﬧb ⏐ a) ⏐ (ﬧc ⏐ a))           Q.E.D.
---   Step: 5                                                   Q.E.D.
---   Step: 6 (ﬧﬧa == a)                                        Q.E.D.
---   Step: 7 (ﬧﬧa == a)                                        Q.E.D.
---   Result:                                                   Q.E.D.
+--   Step: 1 (ﬧﬧa == a)                                 Q.E.D.
+--   Step: 2 (ﬧﬧa == a)                                 Q.E.D.
+--   Step: 3                                            Q.E.D.
+--   Step: 4 (ﬧ(a ⏐ (b ⏐ c)) == (ﬧb ⏐ a) ⏐ (ﬧc ⏐ a))    Q.E.D.
+--   Step: 5                                            Q.E.D.
+--   Step: 6 (ﬧﬧa == a)                                 Q.E.D.
+--   Step: 7 (ﬧﬧa == a)                                 Q.E.D.
+--   Result:                                            Q.E.D.
 -- Lemma: a | a′ = b | b′
---   Step: 1 (ﬧﬧa == a)                                        Q.E.D.
---   Step: 2 (a ⏐ (b ⏐ ﬧb) == ﬧa)                              Q.E.D.
---   Step: 3                                                   Q.E.D.
---   Step: 4 (a ⏐ (b ⏐ ﬧb) == ﬧa)                              Q.E.D.
---   Step: 5 (ﬧﬧa == a)                                        Q.E.D.
---   Result:                                                   Q.E.D.
--- Lemma: a ⊔ b = b ⊔ a                                        Q.E.D.
--- Lemma: a ⊓ b = b ⊓ a                                        Q.E.D.
--- Lemma: a ⊔ ⲳ = a                                            Q.E.D.
--- Lemma: a ⊓ т = a                                            Q.E.D.
--- Lemma: a ⊔ (b ⊓ c) = (a ⊔ b) ⊓ (a ⊔ c)                      Q.E.D.
--- Lemma: a ⊓ (b ⊔ c) = (a ⊓ b) ⊔ (a ⊓ c)                      Q.E.D.
--- Lemma: a ⊔ aᶜ = т                                           Q.E.D.
--- Lemma: a ⊓ aᶜ = ⲳ                                           Q.E.D.
+--   Step: 1 (ﬧﬧa == a)                                 Q.E.D.
+--   Step: 2 (a ⏐ (b ⏐ ﬧb) == ﬧa)                       Q.E.D.
+--   Step: 3                                            Q.E.D.
+--   Step: 4 (a ⏐ (b ⏐ ﬧb) == ﬧa)                       Q.E.D.
+--   Step: 5 (ﬧﬧa == a)                                 Q.E.D.
+--   Result:                                            Q.E.D.
+-- Lemma: a ⊔ b = b ⊔ a                                 Q.E.D.
+-- Lemma: a ⊓ b = b ⊓ a                                 Q.E.D.
+-- Lemma: a ⊔ ⲳ = a                                     Q.E.D.
+-- Lemma: a ⊓ т = a                                     Q.E.D.
+-- Lemma: a ⊔ (b ⊓ c) = (a ⊔ b) ⊓ (a ⊔ c)               Q.E.D.
+-- Lemma: a ⊓ (b ⊔ c) = (a ⊓ b) ⊔ (a ⊓ c)               Q.E.D.
+-- Lemma: a ⊔ aᶜ = т                                    Q.E.D.
+-- Lemma: a ⊓ aᶜ = ⲳ                                    Q.E.D.
 -- Lemma: a ⊔ т = т
---   Step: 1                                                   Q.E.D.
---   Step: 2                                                   Q.E.D.
---   Step: 3                                                   Q.E.D.
---   Step: 4                                                   Q.E.D.
---   Step: 5                                                   Q.E.D.
---   Step: 6                                                   Q.E.D.
---   Result:                                                   Q.E.D.
+--   Step: 1                                            Q.E.D.
+--   Step: 2                                            Q.E.D.
+--   Step: 3                                            Q.E.D.
+--   Step: 4                                            Q.E.D.
+--   Step: 5                                            Q.E.D.
+--   Step: 6                                            Q.E.D.
+--   Result:                                            Q.E.D.
 -- Lemma: a ⊓ ⲳ = ⲳ
---   Step: 1                                                   Q.E.D.
---   Step: 2                                                   Q.E.D.
---   Step: 3                                                   Q.E.D.
---   Step: 4                                                   Q.E.D.
---   Step: 5                                                   Q.E.D.
---   Step: 6                                                   Q.E.D.
---   Result:                                                   Q.E.D.
+--   Step: 1                                            Q.E.D.
+--   Step: 2                                            Q.E.D.
+--   Step: 3                                            Q.E.D.
+--   Step: 4                                            Q.E.D.
+--   Step: 5                                            Q.E.D.
+--   Step: 6                                            Q.E.D.
+--   Result:                                            Q.E.D.
 -- Lemma: a ⊔ (a ⊓ b) = a
---   Step: 1                                                   Q.E.D.
---   Step: 2                                                   Q.E.D.
---   Step: 3                                                   Q.E.D.
---   Step: 4                                                   Q.E.D.
---   Step: 5                                                   Q.E.D.
---   Result:                                                   Q.E.D.
+--   Step: 1                                            Q.E.D.
+--   Step: 2                                            Q.E.D.
+--   Step: 3                                            Q.E.D.
+--   Step: 4                                            Q.E.D.
+--   Step: 5                                            Q.E.D.
+--   Result:                                            Q.E.D.
 -- Lemma: a ⊓ (a ⊔ b) = a
---   Step: 1                                                   Q.E.D.
---   Step: 2                                                   Q.E.D.
---   Step: 3                                                   Q.E.D.
---   Step: 4                                                   Q.E.D.
---   Step: 5                                                   Q.E.D.
---   Result:                                                   Q.E.D.
+--   Step: 1                                            Q.E.D.
+--   Step: 2                                            Q.E.D.
+--   Step: 3                                            Q.E.D.
+--   Step: 4                                            Q.E.D.
+--   Step: 5                                            Q.E.D.
+--   Result:                                            Q.E.D.
 -- Lemma: a ⊓ a = a
---   Step: 1                                                   Q.E.D.
---   Step: 2                                                   Q.E.D.
---   Result:                                                   Q.E.D.
+--   Step: 1                                            Q.E.D.
+--   Step: 2                                            Q.E.D.
+--   Result:                                            Q.E.D.
 -- Lemma: a ⊔ a' = т → a ⊓ a' = ⲳ → a' = aᶜ
---   Step: 1                                                   Q.E.D.
---   Step: 2                                                   Q.E.D.
---   Step: 3                                                   Q.E.D.
---   Step: 4                                                   Q.E.D.
---   Step: 5                                                   Q.E.D.
---   Step: 6                                                   Q.E.D.
---   Step: 7                                                   Q.E.D.
---   Step: 8                                                   Q.E.D.
---   Step: 9                                                   Q.E.D.
---   Step: 10                                                  Q.E.D.
---   Step: 11                                                  Q.E.D.
---   Result:                                                   Q.E.D.
--- Lemma: aᶜᶜ = a                                              Q.E.D.
--- Lemma: aᶜ = bᶜ → a = b                                      Q.E.D.
--- Lemma: a ⊔ bᶜ = т → a ⊓ bᶜ = ⲳ → a = b                      Q.E.D.
+--   Step: 1                                            Q.E.D.
+--   Step: 2                                            Q.E.D.
+--   Step: 3                                            Q.E.D.
+--   Step: 4                                            Q.E.D.
+--   Step: 5                                            Q.E.D.
+--   Step: 6                                            Q.E.D.
+--   Step: 7                                            Q.E.D.
+--   Step: 8                                            Q.E.D.
+--   Step: 9                                            Q.E.D.
+--   Step: 10                                           Q.E.D.
+--   Step: 11                                           Q.E.D.
+--   Result:                                            Q.E.D.
+-- Lemma: aᶜᶜ = a                                       Q.E.D.
+-- Lemma: aᶜ = bᶜ → a = b                               Q.E.D.
+-- Lemma: a ⊔ bᶜ = т → a ⊓ bᶜ = ⲳ → a = b               Q.E.D.
 -- Lemma: a ⊔ (aᶜ ⊔ b) = т
---   Step: 1                                                   Q.E.D.
---   Step: 2                                                   Q.E.D.
---   Step: 3                                                   Q.E.D.
---   Step: 4                                                   Q.E.D.
---   Step: 5                                                   Q.E.D.
---   Step: 6                                                   Q.E.D.
---   Result:                                                   Q.E.D.
+--   Step: 1                                            Q.E.D.
+--   Step: 2                                            Q.E.D.
+--   Step: 3                                            Q.E.D.
+--   Step: 4                                            Q.E.D.
+--   Step: 5                                            Q.E.D.
+--   Step: 6                                            Q.E.D.
+--   Result:                                            Q.E.D.
 -- Lemma: a ⊓ (aᶜ ⊓ b) = ⲳ
---   Step: 1                                                   Q.E.D.
---   Step: 2                                                   Q.E.D.
---   Step: 3                                                   Q.E.D.
---   Step: 4                                                   Q.E.D.
---   Step: 5                                                   Q.E.D.
---   Step: 6                                                   Q.E.D.
---   Result:                                                   Q.E.D.
--- Lemma: (a ⊔ b)ᶜ = aᶜ ⊓ bᶜ                                   Q.E.D.
--- Lemma: (a ⨅ b)ᶜ = aᶜ ⨆ bᶜ                                   Q.E.D.
--- Lemma: (a ⊔ (b ⊔ c)) ⊔ aᶜ = т                               Q.E.D.
--- Lemma: b ⊓ (a ⊔ (b ⊔ c)) = b                                Q.E.D.
--- Lemma: b ⊔ (a ⊓ (b ⊓ c)) = b                                Q.E.D.
+--   Step: 1                                            Q.E.D.
+--   Step: 2                                            Q.E.D.
+--   Step: 3                                            Q.E.D.
+--   Step: 4                                            Q.E.D.
+--   Step: 5                                            Q.E.D.
+--   Step: 6                                            Q.E.D.
+--   Result:                                            Q.E.D.
+-- Lemma: (a ⊔ b)ᶜ = aᶜ ⊓ bᶜ                            Q.E.D.
+-- Lemma: (a ⨅ b)ᶜ = aᶜ ⨆ bᶜ                            Q.E.D.
+-- Lemma: (a ⊔ (b ⊔ c)) ⊔ aᶜ = т                        Q.E.D.
+-- Lemma: b ⊓ (a ⊔ (b ⊔ c)) = b                         Q.E.D.
+-- Lemma: b ⊔ (a ⊓ (b ⊓ c)) = b                         Q.E.D.
 -- Lemma: (a ⊔ (b ⊔ c)) ⊔ bᶜ = т
---   Step: 1                                                   Q.E.D.
---   Step: 2                                                   Q.E.D.
---   Step: 3                                                   Q.E.D.
---   Step: 4                                                   Q.E.D.
---   Step: 5                                                   Q.E.D.
---   Step: 6                                                   Q.E.D.
---   Step: 7                                                   Q.E.D.
---   Step: 8                                                   Q.E.D.
---   Step: 9                                                   Q.E.D.
---   Result:                                                   Q.E.D.
--- Lemma: (a ⊔ (b ⊔ c)) ⊔ cᶜ = т                               Q.E.D.
+--   Step: 1                                            Q.E.D.
+--   Step: 2                                            Q.E.D.
+--   Step: 3                                            Q.E.D.
+--   Step: 4                                            Q.E.D.
+--   Step: 5                                            Q.E.D.
+--   Step: 6                                            Q.E.D.
+--   Step: 7                                            Q.E.D.
+--   Step: 8                                            Q.E.D.
+--   Step: 9                                            Q.E.D.
+--   Result:                                            Q.E.D.
+-- Lemma: (a ⊔ (b ⊔ c)) ⊔ cᶜ = т                        Q.E.D.
 -- Lemma: (a ⊔ b ⊔ c)ᶜ ⊓ a = ⲳ
---   Step: 1                                                   Q.E.D.
---   Step: 2                                                   Q.E.D.
---   Step: 3                                                   Q.E.D.
---   Step: 4                                                   Q.E.D.
---   Step: 5                                                   Q.E.D.
---   Step: 6                                                   Q.E.D.
---   Step: 7                                                   Q.E.D.
---   Step: 8                                                   Q.E.D.
---   Step: 9                                                   Q.E.D.
---   Result:                                                   Q.E.D.
--- Lemma: (a ⊔ b ⊔ c)ᶜ ⊓ b = ⲳ                                 Q.E.D.
--- Lemma: (a ⊔ b ⊔ c)ᶜ ⊓ c = ⲳ                                 Q.E.D.
+--   Step: 1                                            Q.E.D.
+--   Step: 2                                            Q.E.D.
+--   Step: 3                                            Q.E.D.
+--   Step: 4                                            Q.E.D.
+--   Step: 5                                            Q.E.D.
+--   Step: 6                                            Q.E.D.
+--   Step: 7                                            Q.E.D.
+--   Step: 8                                            Q.E.D.
+--   Step: 9                                            Q.E.D.
+--   Result:                                            Q.E.D.
+-- Lemma: (a ⊔ b ⊔ c)ᶜ ⊓ b = ⲳ                          Q.E.D.
+-- Lemma: (a ⊔ b ⊔ c)ᶜ ⊓ c = ⲳ                          Q.E.D.
 -- Lemma: (a ⊔ (b ⊔ c)) ⊔ ((a ⊔ b) ⊔ c)ᶜ = т
---   Step: 1                                                   Q.E.D.
---   Step: 2                                                   Q.E.D.
---   Step: 3                                                   Q.E.D.
---   Step: 4                                                   Q.E.D.
---   Step: 5                                                   Q.E.D.
---   Step: 6                                                   Q.E.D.
---   Step: 7                                                   Q.E.D.
---   Step: 8                                                   Q.E.D.
---   Result:                                                   Q.E.D.
+--   Step: 1                                            Q.E.D.
+--   Step: 2                                            Q.E.D.
+--   Step: 3                                            Q.E.D.
+--   Step: 4                                            Q.E.D.
+--   Step: 5                                            Q.E.D.
+--   Step: 6                                            Q.E.D.
+--   Step: 7                                            Q.E.D.
+--   Step: 8                                            Q.E.D.
+--   Result:                                            Q.E.D.
 -- Lemma: (a ⊔ (b ⊔ c)) ⊓ ((a ⊔ b) ⊔ c)ᶜ = ⲳ
---   Step: 1                                                   Q.E.D.
---   Step: 2                                                   Q.E.D.
---   Step: 3                                                   Q.E.D.
---   Step: 4                                                   Q.E.D.
---   Step: 5                                                   Q.E.D.
---   Step: 6                                                   Q.E.D.
---   Step: 7                                                   Q.E.D.
---   Step: 8                                                   Q.E.D.
---   Step: 9                                                   Q.E.D.
---   Step: 10                                                  Q.E.D.
---   Step: 11                                                  Q.E.D.
---   Step: 12                                                  Q.E.D.
---   Result:                                                   Q.E.D.
--- Lemma: a ⊔ (b ⊔ c) = (a ⊔ b) ⊔ c                            Q.E.D.
+--   Step: 1                                            Q.E.D.
+--   Step: 2                                            Q.E.D.
+--   Step: 3                                            Q.E.D.
+--   Step: 4                                            Q.E.D.
+--   Step: 5                                            Q.E.D.
+--   Step: 6                                            Q.E.D.
+--   Step: 7                                            Q.E.D.
+--   Step: 8                                            Q.E.D.
+--   Step: 9                                            Q.E.D.
+--   Step: 10                                           Q.E.D.
+--   Step: 11                                           Q.E.D.
+--   Step: 12                                           Q.E.D.
+--   Result:                                            Q.E.D.
+-- Lemma: a ⊔ (b ⊔ c) = (a ⊔ b) ⊔ c                     Q.E.D.
 -- Lemma: a ⊓ (b ⊓ c) = (a ⊓ b) ⊓ c
---   Step: 1                                                   Q.E.D.
---   Step: 2                                                   Q.E.D.
---   Step: 3                                                   Q.E.D.
---   Result:                                                   Q.E.D.
+--   Step: 1                                            Q.E.D.
+--   Step: 2                                            Q.E.D.
+--   Step: 3                                            Q.E.D.
+--   Result:                                            Q.E.D.
 -- Lemma: a ≤ b → b ≤ a → a = b
---   Step: 1                                                   Q.E.D.
---   Step: 2                                                   Q.E.D.
---   Step: 3                                                   Q.E.D.
---   Result:                                                   Q.E.D.
--- Lemma: a ≤ a                                                Q.E.D.
+--   Step: 1                                            Q.E.D.
+--   Step: 2                                            Q.E.D.
+--   Step: 3                                            Q.E.D.
+--   Result:                                            Q.E.D.
+-- Lemma: a ≤ a                                         Q.E.D.
 -- Lemma: a ≤ b → b ≤ c → a ≤ c
---   Step: 1                                                   Q.E.D.
---   Step: 2                                                   Q.E.D.
---   Step: 3                                                   Q.E.D.
---   Step: 4                                                   Q.E.D.
---   Result:                                                   Q.E.D.
--- Lemma: a < b ↔ a ≤ b ∧ ¬b ≤ a                               Q.E.D.
--- Lemma: a ≤ a ⊔ b                                            Q.E.D.
--- Lemma: b ≤ a ⊔ b                                            Q.E.D.
+--   Step: 1                                            Q.E.D.
+--   Step: 2                                            Q.E.D.
+--   Step: 3                                            Q.E.D.
+--   Step: 4                                            Q.E.D.
+--   Result:                                            Q.E.D.
+-- Lemma: a < b ↔ a ≤ b ∧ ¬b ≤ a                        Q.E.D.
+-- Lemma: a ≤ a ⊔ b                                     Q.E.D.
+-- Lemma: b ≤ a ⊔ b                                     Q.E.D.
 -- Lemma: a ≤ c → b ≤ c → a ⊔ b ≤ c
---   Step: 1                                                   Q.E.D.
---   Step: 2                                                   Q.E.D.
---   Result:                                                   Q.E.D.
--- Lemma: a ⊓ b ≤ a                                            Q.E.D.
--- Lemma: a ⊓ b ≤ b                                            Q.E.D.
+--   Step: 1                                            Q.E.D.
+--   Step: 2                                            Q.E.D.
+--   Result:                                            Q.E.D.
+-- Lemma: a ⊓ b ≤ a                                     Q.E.D.
+-- Lemma: a ⊓ b ≤ b                                     Q.E.D.
 -- Lemma: a ≤ b → a ≤ c → a ≤ b ⊓ c
---   Step: 1                                                   Q.E.D.
---   Step: 2                                                   Q.E.D.
---   Step: 3                                                   Q.E.D.
---   Result:                                                   Q.E.D.
--- Lemma: (x ⊔ y) ⊓ (x ⊔ z) ≤ x ⊔ y ⊓ z                        Q.E.D.
--- Lemma: x ⊓ xᶜ ≤ ⊥                                           Q.E.D.
--- Lemma: ⊤ ≤ x ⊔ xᶜ                                           Q.E.D.
+--   Step: 1                                            Q.E.D.
+--   Step: 2                                            Q.E.D.
+--   Step: 3                                            Q.E.D.
+--   Result:                                            Q.E.D.
+-- Lemma: (x ⊔ y) ⊓ (x ⊔ z) ≤ x ⊔ y ⊓ z                 Q.E.D.
+-- Lemma: x ⊓ xᶜ ≤ ⊥                                    Q.E.D.
+-- Lemma: ⊤ ≤ x ⊔ xᶜ                                    Q.E.D.
 -- Lemma: a ≤ ⊤
---   Step: 1                                                   Q.E.D.
---   Step: 2                                                   Q.E.D.
---   Step: 3                                                   Q.E.D.
---   Result:                                                   Q.E.D.
+--   Step: 1                                            Q.E.D.
+--   Step: 2                                            Q.E.D.
+--   Step: 3                                            Q.E.D.
+--   Result:                                            Q.E.D.
 -- Lemma: ⊥ ≤ a
---   Step: 1                                                   Q.E.D.
---   Step: 2                                                   Q.E.D.
---   Result:                                                   Q.E.D.
--- Lemma: x \ y = x ⊓ yᶜ                                       Q.E.D.
--- Lemma: x ⇨ y = y ⊔ xᶜ                                       Q.E.D.
+--   Step: 1                                            Q.E.D.
+--   Step: 2                                            Q.E.D.
+--   Result:                                            Q.E.D.
+-- Lemma: x \ y = x ⊓ yᶜ                                Q.E.D.
+-- Lemma: x ⇨ y = y ⊔ xᶜ                                Q.E.D.
 -- BooleanAlgebraProof {
 --   le_refl         : [Proven] a ≤ a :: Ɐa ∷ Stroke → Bool
 --   le_trans        : [Proven] a ≤ b → b ≤ c → a ≤ c :: Ɐa ∷ Stroke → Ɐb ∷ Stroke → Ɐc ∷ Stroke → Bool
@@ -354,7 +351,7 @@
 --   himp_eq         : [Proven] x ⇨ y = y ⊔ xᶜ :: Ɐx ∷ Stroke → Ɐy ∷ Stroke → Bool
 -- }
 shefferBooleanAlgebra :: IO BooleanAlgebraProof
-shefferBooleanAlgebra = runTPWith (tpRibbon 60 z3) $ do
+shefferBooleanAlgebra = runTP $ do
 
   -- shorthand
   let p = proofOf
diff --git a/Documentation/SBV/Examples/TP/SortHelpers.hs b/Documentation/SBV/Examples/TP/SortHelpers.hs
--- a/Documentation/SBV/Examples/TP/SortHelpers.hs
+++ b/Documentation/SBV/Examples/TP/SortHelpers.hs
@@ -12,20 +12,21 @@
 {-# LANGUAGE CPP                 #-}
 {-# LANGUAGE DataKinds           #-}
 {-# LANGUAGE FlexibleContexts    #-}
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeAbstractions    #-}
 {-# LANGUAGE TypeApplications    #-}
-{-# LANGUAGE ScopedTypeVariables #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
 module Documentation.SBV.Examples.TP.SortHelpers where
 
-import Prelude hiding (null, tail, elem, head, (++), take, drop)
+import Prelude hiding (null, length, tail, elem, head, (++), take, drop)
 
 import Data.SBV
 import Data.SBV.List
 import Data.SBV.TP
-import Data.SBV.TP.List
+import Documentation.SBV.Examples.TP.Lists
 
 #ifdef DOCTEST
 -- $setup
@@ -35,10 +36,12 @@
 
 -- | A predicate testing whether a given list is non-decreasing.
 nonDecreasing :: (OrdSymbolic (SBV a), SymVal a) => SList a -> SBool
-nonDecreasing = smtFunction "nonDecreasing" $ \l ->  null l .|| null (tail l)
-                                                 .|| let (x, l') = uncons l
-                                                         (y, _)  = uncons l'
-                                                     in x .<= y .&& nonDecreasing l'
+nonDecreasing = smtFunction "nonDecreasing"
+              $ \l -> [sCase| l of
+                         []  -> sTrue
+                         [_] -> sTrue
+                         x : rest@(y : _) -> x .<= y .&& nonDecreasing rest
+                      |]
 
 -- | Are two lists permutations of each other?
 isPermutation :: SymVal a => SList a -> SList a -> SBool
@@ -47,7 +50,8 @@
 -- | The tail of a non-decreasing list is non-decreasing. We have:
 --
 -- >>> runTP $ nonDecrTail @Integer
--- Lemma: nonDecrTail                      Q.E.D.
+-- Lemma: nonDecrTail    Q.E.D.
+-- Functions proven terminating: nonDecreasing
 -- [Proven] nonDecrTail :: Ɐx ∷ Integer → Ɐxs ∷ [Integer] → Bool
 nonDecrTail :: forall a. (OrdSymbolic (SBV a), SymVal a) => TP (Proof (Forall "x" a -> Forall "xs" [a] -> SBool))
 nonDecrTail = lemma "nonDecrTail"
@@ -57,7 +61,8 @@
 -- | If we insert an element that is less than the head of a nonDecreasing list, it remains nondecreasing. We have:
 --
 -- >>> runTP $ nonDecrIns @Integer
--- Lemma: nonDecrInsert                    Q.E.D.
+-- Lemma: nonDecrInsert    Q.E.D.
+-- Functions proven terminating: nonDecreasing
 -- [Proven] nonDecrInsert :: Ɐx ∷ Integer → Ɐxs ∷ [Integer] → Bool
 nonDecrIns :: forall a. (OrdSymbolic (SBV a), SymVal a) => TP (Proof (Forall "x" a -> Forall "xs" [a] -> SBool))
 nonDecrIns = lemma "nonDecrInsert"
@@ -72,34 +77,35 @@
 --
 -- >>> runTP $ sublistCorrect @Integer
 -- Inductive lemma: countNonNeg
---   Step: Base                            Q.E.D.
+--   Step: Base                    Q.E.D.
 --   Step: 1 (2 way case split)
---     Step: 1.1.1                         Q.E.D.
---     Step: 1.1.2                         Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
+--     Step: 1.1.1                 Q.E.D.
+--     Step: 1.1.2                 Q.E.D.
+--     Step: 1.2.1                 Q.E.D.
+--     Step: 1.2.2                 Q.E.D.
+--     Step: 1.Completeness        Q.E.D.
+--   Result:                       Q.E.D.
 -- Inductive lemma: countElem
---   Step: Base                            Q.E.D.
+--   Step: Base                    Q.E.D.
 --   Step: 1 (2 way case split)
---     Step: 1.1.1                         Q.E.D.
---     Step: 1.1.2                         Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
+--     Step: 1.1.1                 Q.E.D.
+--     Step: 1.1.2                 Q.E.D.
+--     Step: 1.2.1                 Q.E.D.
+--     Step: 1.2.2                 Q.E.D.
+--     Step: 1.Completeness        Q.E.D.
+--   Result:                       Q.E.D.
 -- Inductive lemma: elemCount
---   Step: Base                            Q.E.D.
+--   Step: Base                    Q.E.D.
 --   Step: 1 (2 way case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
+--     Step: 1.1                   Q.E.D.
+--     Step: 1.2.1                 Q.E.D.
+--     Step: 1.2.2                 Q.E.D.
+--     Step: 1.Completeness        Q.E.D.
+--   Result:                       Q.E.D.
 -- Lemma: sublistCorrect
---   Step: 1                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: 1                       Q.E.D.
+--   Result:                       Q.E.D.
+-- Functions proven terminating: count
 -- [Proven] sublistCorrect :: Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Ɐx ∷ Integer → Bool
 sublistCorrect :: forall a. (Eq a, SymVal a) => TP (Proof (Forall "xs" [a] -> Forall "ys" [a] -> Forall "x" a -> SBool))
 sublistCorrect = do
@@ -120,37 +126,38 @@
 --
 -- >>> runTP $ sublistElem @Integer
 -- Inductive lemma: countNonNeg
---   Step: Base                            Q.E.D.
+--   Step: Base                    Q.E.D.
 --   Step: 1 (2 way case split)
---     Step: 1.1.1                         Q.E.D.
---     Step: 1.1.2                         Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
+--     Step: 1.1.1                 Q.E.D.
+--     Step: 1.1.2                 Q.E.D.
+--     Step: 1.2.1                 Q.E.D.
+--     Step: 1.2.2                 Q.E.D.
+--     Step: 1.Completeness        Q.E.D.
+--   Result:                       Q.E.D.
 -- Inductive lemma: countElem
---   Step: Base                            Q.E.D.
+--   Step: Base                    Q.E.D.
 --   Step: 1 (2 way case split)
---     Step: 1.1.1                         Q.E.D.
---     Step: 1.1.2                         Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
+--     Step: 1.1.1                 Q.E.D.
+--     Step: 1.1.2                 Q.E.D.
+--     Step: 1.2.1                 Q.E.D.
+--     Step: 1.2.2                 Q.E.D.
+--     Step: 1.Completeness        Q.E.D.
+--   Result:                       Q.E.D.
 -- Inductive lemma: elemCount
---   Step: Base                            Q.E.D.
+--   Step: Base                    Q.E.D.
 --   Step: 1 (2 way case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2.1                         Q.E.D.
---     Step: 1.2.2                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
+--     Step: 1.1                   Q.E.D.
+--     Step: 1.2.1                 Q.E.D.
+--     Step: 1.2.2                 Q.E.D.
+--     Step: 1.Completeness        Q.E.D.
+--   Result:                       Q.E.D.
 -- Lemma: sublistCorrect
---   Step: 1                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: 1                       Q.E.D.
+--   Result:                       Q.E.D.
 -- Lemma: sublistElem
---   Step: 1                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: 1                       Q.E.D.
+--   Result:                       Q.E.D.
+-- Functions proven terminating: count
 -- [Proven] sublistElem :: Ɐx ∷ Integer → Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool
 sublistElem :: forall a. (Eq a, SymVal a) => TP (Proof (Forall "x" a -> Forall "xs" [a] -> Forall "ys" [a] -> SBool))
 sublistElem = do
@@ -167,7 +174,8 @@
 -- | If one list is a sublist of another so is its tail. We have:
 --
 -- >>> runTP $ sublistTail @Integer
--- Lemma: sublistTail                      Q.E.D.
+-- Lemma: sublistTail    Q.E.D.
+-- Functions proven terminating: count
 -- [Proven] sublistTail :: Ɐx ∷ Integer → Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool
 sublistTail :: forall a. (Eq a, SymVal a) => TP (Proof (Forall "x" a -> Forall "xs" [a] -> Forall "ys" [a] -> SBool))
 sublistTail =
@@ -178,7 +186,8 @@
 -- | Permutation implies sublist. We have:
 --
 -- >>> runTP $ sublistIfPerm @Integer
--- Lemma: sublistIfPerm                    Q.E.D.
+-- Lemma: sublistIfPerm    Q.E.D.
+-- Functions proven terminating: count
 -- [Proven] sublistIfPerm :: Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool
 sublistIfPerm :: forall a. (Eq a, SymVal a) => TP (Proof (Forall "xs" [a] -> Forall "ys" [a] -> SBool))
 sublistIfPerm = lemma "sublistIfPerm"
diff --git a/Documentation/SBV/Examples/TP/Sqrt2IsIrrational.hs b/Documentation/SBV/Examples/TP/Sqrt2IsIrrational.hs
--- a/Documentation/SBV/Examples/TP/Sqrt2IsIrrational.hs
+++ b/Documentation/SBV/Examples/TP/Sqrt2IsIrrational.hs
@@ -9,9 +9,8 @@
 -- Prove that square-root of 2 is irrational.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DataKinds           #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE DataKinds        #-}
+{-# LANGUAGE TypeAbstractions #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -49,15 +48,15 @@
 --
 -- >>> sqrt2IsIrrational
 -- Lemma: oddSquaredIsOdd
---   Step: 1                               Q.E.D.
---   Step: 2 (expand square)               Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: squareEvenImpliesEven            Q.E.D.
+--   Step: 1                       Q.E.D.
+--   Step: 2 (expand square)       Q.E.D.
+--   Result:                       Q.E.D.
+-- Lemma: squareEvenImpliesEven    Q.E.D.
 -- Lemma: evenSquaredIsMult4
---   Step: 1                               Q.E.D.
---   Step: 2 (expand square)               Q.E.D.
---   Result:                               Q.E.D.
--- Lemma: sqrt2IsIrrational                Q.E.D.
+--   Step: 1                       Q.E.D.
+--   Step: 2 (expand square)       Q.E.D.
+--   Result:                       Q.E.D.
+-- Lemma: sqrt2IsIrrational        Q.E.D.
 -- [Proven] sqrt2IsIrrational :: Bool
 sqrt2IsIrrational :: IO (Proof SBool)
 sqrt2IsIrrational = runTP $ do
@@ -84,7 +83,7 @@
                                            =: 4*k*k + 4*k + 1
                                            =: qed
 
-    -- Prove that if a perfect square is even, then it be the square of an even number. For z3, the above proof
+    -- Prove that if a perfect square is even, then it has to be the square of an even number. For z3, the above proof
     -- is enough to establish this.
     squareEvenImpliesEven <- lemma "squareEvenImpliesEven"
                                    (\(Forall @"a" a) -> even (sq a) .=> even a)
diff --git a/Documentation/SBV/Examples/TP/StrongInduction.hs b/Documentation/SBV/Examples/TP/StrongInduction.hs
--- a/Documentation/SBV/Examples/TP/StrongInduction.hs
+++ b/Documentation/SBV/Examples/TP/StrongInduction.hs
@@ -11,6 +11,7 @@
 
 {-# LANGUAGE CPP                 #-}
 {-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE QuasiQuotes         #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeAbstractions    #-}
 {-# LANGUAGE TypeApplications    #-}
@@ -39,29 +40,33 @@
 --
 -- >>> oddSequence1
 -- Inductive lemma (strong): oddSequence1
---   Step: Measure is non-negative         Q.E.D.
+--   Step: Measure is non-negative           Q.E.D.
 --   Step: 1 (3 way case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2                           Q.E.D.
---     Step: 1.3.1                         Q.E.D.
---     Step: 1.3.2                         Q.E.D.
---     Step: 1.3.3                         Q.E.D.
---     Step: 1.Completeness                Q.E.D.
---   Result:                               Q.E.D.
+--     Step: 1.1                             Q.E.D.
+--     Step: 1.2                             Q.E.D.
+--     Step: 1.3.1                           Q.E.D.
+--     Step: 1.3.2                           Q.E.D.
+--     Step: 1.3.3                           Q.E.D.
+--     Step: 1.Completeness                  Q.E.D.
+--   Result:                                 Q.E.D.
+-- Functions proven terminating: seq
 -- [Proven] oddSequence1 :: Ɐn ∷ Integer → Bool
 oddSequence1 :: IO (Proof (Forall "n" Integer -> SBool))
 oddSequence1 = runTP $ do
   let s :: SInteger -> SInteger
-      s = smtFunction "seq" $ \n -> ite (n .<= 0) 1
-                                  $ ite (n .== 1) 3
-                                  $ s (n-2) + 2 * s (n-1)
+      s = smtFunction "seq"
+        $ \n -> [sCase| n of
+                   _ | n .<= 0 -> 1
+                   _ | n .== 1 -> 3
+                   _           -> s (n-2) + 2 * s (n-1)
+                |]
 
   -- z3 can't handle this, but CVC5 is proves it just fine.
   -- Note also that we do a "proof-by-contradiction," by deriving that
   -- the negation of the goal leads to falsehood.
   sInductWith cvc5 "oddSequence1"
           (\(Forall n) -> n .>= 0 .=> sNot (2 `sDivides` s n))
-          abs $
+          (abs, []) $
           \ih n -> [n .>= 0] |- 2 `sDivides` s n
                              =: cases [ n .== 0 ==> contradiction
                                       , n .== 1 ==> contradiction
@@ -76,39 +81,43 @@
 -- We have:
 --
 -- >>> oddSequence2
--- Lemma: oddSequence_0                              Q.E.D.
--- Lemma: oddSequence_1                              Q.E.D.
+-- Lemma: oddSequence_0                          Q.E.D.
+-- Lemma: oddSequence_1                          Q.E.D.
 -- Inductive lemma (strong): oddSequence_sNp2
---   Step: Measure is non-negative                   Q.E.D.
---   Step: 1                                         Q.E.D.
---   Step: 2                                         Q.E.D.
---   Step: 3 (simplify)                              Q.E.D.
---   Step: 4                                         Q.E.D.
---   Step: 5 (simplify)                              Q.E.D.
---   Step: 6                                         Q.E.D.
---   Result:                                         Q.E.D.
+--   Step: Measure is non-negative               Q.E.D.
+--   Step: 1                                     Q.E.D.
+--   Step: 2                                     Q.E.D.
+--   Step: 3 (simplify)                          Q.E.D.
+--   Step: 4                                     Q.E.D.
+--   Step: 5 (simplify)                          Q.E.D.
+--   Step: 6                                     Q.E.D.
+--   Result:                                     Q.E.D.
 -- Lemma: oddSequence2
 --   Step: 1 (3 way case split)
---     Step: 1.1                                     Q.E.D.
---     Step: 1.2                                     Q.E.D.
---     Step: 1.3.1                                   Q.E.D.
---     Step: 1.3.2                                   Q.E.D.
---     Step: 1.Completeness                          Q.E.D.
---   Result:                                         Q.E.D.
+--     Step: 1.1                                 Q.E.D.
+--     Step: 1.2                                 Q.E.D.
+--     Step: 1.3.1                               Q.E.D.
+--     Step: 1.3.2                               Q.E.D.
+--     Step: 1.Completeness                      Q.E.D.
+--   Result:                                     Q.E.D.
+-- Functions proven terminating: seq
 -- [Proven] oddSequence2 :: Ɐn ∷ Integer → Bool
 oddSequence2 :: IO (Proof (Forall "n" Integer -> SBool))
-oddSequence2 = runTPWith (tpRibbon 50 z3) $ do
+oddSequence2 = runTP $ do
   let s :: SInteger -> SInteger
-      s = smtFunction "seq" $ \n -> ite (n .<= 0) 1
-                                  $ ite (n .== 1) 3
-                                  $ 2 * s (n-1) - s (n-2)
+      s = smtFunction "seq"
+        $ \n -> [sCase| n of
+                   _ | n .<= 0 -> 1
+                   _ | n .== 1 -> 3
+                   _           -> 2 * s (n-1) - s (n-2)
+                |]
 
   s0 <- lemma "oddSequence_0" (s 0 .== 1) []
   s1 <- lemma "oddSequence_1" (s 1 .== 3) []
 
   sNp2 <- sInduct "oddSequence_sNp2"
                   (\(Forall n) -> n .>= 2 .=> s n .== 2 * n + 1)
-                  abs $
+                  (abs, []) $
                   \ih n -> [n .>= 2] |- s n
                                      =: 2 * s (n-1) - s (n-2)
                                      ?? ih `at` Inst @"n" (n-1)
@@ -149,12 +158,16 @@
 won'tProve1 :: IO ()
 won'tProve1 = runTP $ do
    let len :: SList Integer -> SInteger
-       len = smtFunction "len" $ \xs -> ite (null xs) 0 (1 + len (tail xs))
+       len = smtFunction "len"
+           $ \xs -> [sCase| xs of
+                       []     -> 0
+                       _ : as -> 1 + len as
+                    |]
 
    -- Run it for 5 seconds, as otherwise z3 will hang as it can't prove make the inductive step
    _ <- sInductWith z3{extraArgs = ["-t:5000"]} "lengthGood"
                 (\(Forall xs) -> len xs .== length xs)
-                length $
+                (length, []) $
                 \ih xs -> [] |- len xs
                              -- incorrectly instantiate the IH at xs!
                              ?? ih `at` Inst @"xs" xs
@@ -167,7 +180,7 @@
 --
 -- >>> won'tProve2 `catch` (\(_ :: SomeException) -> pure ())
 -- Inductive lemma (strong): badLength
---   Step: Measure is non-negative         Q.E.D.
+--   Step: Measure is non-negative        Q.E.D.
 --   Step: 1
 -- *** Failed to prove badLength.1.
 -- Falsifiable. Counter-example:
@@ -175,15 +188,15 @@
 won'tProve2 :: IO ()
 won'tProve2 = runTP $ do
    let len :: SList Integer -> SInteger
-       len = smtFunction "badLength" $ \xs -> ite (null xs)
-                                                  123
-                                                  (ite (null xs)
-                                                       0
-                                                       (1 + len (tail xs)))
+       len = smtFunction "badLength"
+           $ \xs -> [sCase| xs of
+                       []     -> 123
+                       _ : as -> 1 + len as
+                    |]
 
    _ <- sInduct "badLength"
                 (\(Forall xs) -> len xs .== length xs)
-                length $
+                (length, []) $
                 \ih xs -> [] |- len xs
                              ?? ih `at` Inst @"xs" xs
                              =: length xs
@@ -204,7 +217,7 @@
 won'tProve3 = runTP $ do
    _ <- sInduct "badMeasure"
                 (\(Forall @"x" (x :: SInteger)) -> x .== x)
-                id $
+                (id, []) $
                 \_ih x -> [] |- x
                              =: x
                              =: qed
@@ -229,13 +242,17 @@
 
    let -- a bizarre (but valid!) way to sum two integers
        weirdSum :: SInteger -> SInteger -> SInteger
-       weirdSum = smtFunction "weirdSum" (\x y -> ite (x .<= 0) y (weirdSum (x - 1) (y + 1)))
+       weirdSum = smtFunction "weirdSum"
+                $ \x y -> [sCase| x of
+                              _ | x .<= 0 -> y
+                              _           -> weirdSum (x - 1) (y + 1)
+                           |]
 
    _ <- sInductWith z3{extraArgs = ["-t:5000"]} "badMeasure"
                 (\(Forall x) (Forall y) -> x .>= 0 .=> weirdSum x y .== x + y)
                 -- This measure is not good, since it remains the same. Note that we do not get a
                 -- failure, but the proof will never converge either; so we put a time bound
-                (\x y -> abs x + abs y) $
+                (\x y -> abs x + abs y, []) $
                 \ih x y -> [x .>= 0] |- ite (x .<= 0) y (weirdSum (x - 1) (y + 1))
                                      =: cases [ x .<= 0 ==> trivial
                                               , x .>  0 ==> weirdSum (x - 1) (y + 1)
@@ -254,33 +271,37 @@
 --
 -- >>> sumHalves
 -- Inductive lemma: sumAppend
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: Base                           Q.E.D.
+--   Step: 1                              Q.E.D.
+--   Step: 2                              Q.E.D.
+--   Step: 3                              Q.E.D.
+--   Result:                              Q.E.D.
 -- Inductive lemma (strong): sumHalves
---   Step: Measure is non-negative         Q.E.D.
---   Step: 1 (2 way full case split)
---     Step: 1.1                           Q.E.D.
---     Step: 1.2 (2 way full case split)
---       Step: 1.2.1                       Q.E.D.
---       Step: 1.2.2.1                     Q.E.D.
---       Step: 1.2.2.2                     Q.E.D.
---       Step: 1.2.2.3                     Q.E.D.
---       Step: 1.2.2.4                     Q.E.D.
---       Step: 1.2.2.5                     Q.E.D.
---       Step: 1.2.2.6 (simplify)          Q.E.D.
---   Result:                               Q.E.D.
+--   Step: Measure is non-negative        Q.E.D.
+--   Step: 1 (3 way case split)
+--     Step: 1.1                          Q.E.D.
+--     Step: 1.2                          Q.E.D.
+--     Step: 1.3.1                        Q.E.D.
+--     Step: 1.3.2                        Q.E.D.
+--     Step: 1.3.3                        Q.E.D.
+--     Step: 1.3.4                        Q.E.D.
+--     Step: 1.3.5                        Q.E.D.
+--     Step: 1.3.6 (simplify)             Q.E.D.
+--     Step: 1.Completeness               Q.E.D.
+--   Result:                              Q.E.D.
+-- Functions proven terminating: halvingSum, sbv.foldr
 -- [Proven] sumHalves :: Ɐxs ∷ [Integer] → Bool
 sumHalves :: IO (Proof (Forall "xs" [Integer] -> SBool))
 sumHalves = runTP $ do
 
     let halvingSum :: SList Integer -> SInteger
-        halvingSum = smtFunction "halvingSum" $ \xs -> ite (null xs .|| null (tail xs))
-                                                           (sum xs)
-                                                           (let (f, s) = splitAt (length xs `sDiv` 2) xs
-                                                            in halvingSum f + halvingSum s)
+        halvingSum = smtFunction "halvingSum"
+                   $ \xs -> [sCase| xs of
+                                []  -> sum xs
+                                [_] -> sum xs
+                                _   -> let (f, s) = splitAt (length xs `sDiv` 2) xs
+                                       in halvingSum f + halvingSum s
+                            |]
 
     helper <- induct "sumAppend"
                      (\(Forall xs) (Forall ys) -> sum (xs ++ ys) .== sum xs + sum ys) $
@@ -294,19 +315,22 @@
     -- Use strong induction to prove the theorem. CVC5 solves this with ease, but z3 struggles.
     sInductWith cvc5 "sumHalves"
       (\(Forall xs) -> halvingSum xs .== sum xs)
-      length $
+      (length, []) $
       \ih xs -> [] |- halvingSum xs
-                   =: split xs qed
-                            (\a as -> split as qed
-                                            (\b bs -> halvingSum (a .: b .: bs)
-                                                   =: let (f, s) = splitAt (length (a .: b .: bs) `sDiv` 2) (a .: b .: bs)
-                                                   in halvingSum f + halvingSum s
-                                                   ?? ih `at` Inst @"xs" f
-                                                   =: sum f + halvingSum s
-                                                   ?? ih `at` Inst @"xs" s
-                                                   =: sum f + sum s
-                                                   ?? helper `at` (Inst @"xs" f, Inst @"ys" s)
-                                                   =: sum (f ++ s)
-                                                   ?? "simplify"
-                                                   =: sum (a .: b .: bs)
-                                                   =: qed))
+                   =: [pCase| xs of
+                        []                -> qed
+                        [_]               -> qed
+                        whole@(_ : _ : _) ->
+                             halvingSum whole
+                          =: let (f, s) = splitAt (length whole `sDiv` 2) whole
+                          in halvingSum f + halvingSum s
+                          ?? ih `at` Inst @"xs" f
+                          =: sum f + halvingSum s
+                          ?? ih `at` Inst @"xs" s
+                          =: sum f + sum s
+                          ?? helper `at` (Inst @"xs" f, Inst @"ys" s)
+                          =: sum (f ++ s)
+                          ?? "simplify"
+                          =: sum whole
+                          =: qed
+                      |]
diff --git a/Documentation/SBV/Examples/TP/SumReverse.hs b/Documentation/SBV/Examples/TP/SumReverse.hs
--- a/Documentation/SBV/Examples/TP/SumReverse.hs
+++ b/Documentation/SBV/Examples/TP/SumReverse.hs
@@ -13,7 +13,6 @@
 {-# LANGUAGE DataKinds           #-}
 {-# LANGUAGE FlexibleContexts    #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeAbstractions    #-}
 {-# LANGUAGE TypeApplications    #-}
 {-# LANGUAGE OverloadedLists     #-}
 
@@ -38,21 +37,22 @@
 --
 -- >>> revSum @Integer
 -- Inductive lemma: sumAppend
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4 (associativity)               Q.E.D.
---   Step: 5                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: Base                   Q.E.D.
+--   Step: 1                      Q.E.D.
+--   Step: 2                      Q.E.D.
+--   Step: 3                      Q.E.D.
+--   Step: 4 (associativity)      Q.E.D.
+--   Step: 5                      Q.E.D.
+--   Result:                      Q.E.D.
 -- Inductive lemma: sumReverse
---   Step: Base                            Q.E.D.
---   Step: 1                               Q.E.D.
---   Step: 2                               Q.E.D.
---   Step: 3                               Q.E.D.
---   Step: 4 (commutativity)               Q.E.D.
---   Step: 5                               Q.E.D.
---   Result:                               Q.E.D.
+--   Step: Base                   Q.E.D.
+--   Step: 1                      Q.E.D.
+--   Step: 2                      Q.E.D.
+--   Step: 3                      Q.E.D.
+--   Step: 4 (commutativity)      Q.E.D.
+--   Step: 5                      Q.E.D.
+--   Result:                      Q.E.D.
+-- Functions proven terminating: sbv.foldr, sbv.reverse
 -- [Proven] sumReverse :: Ɐxs ∷ [Integer] → Bool
 revSum :: forall a. (SymVal a, Num (SBV a)) => IO (Proof (Forall "xs" [a] -> SBool))
 revSum = runTP $ do
diff --git a/Documentation/SBV/Examples/TP/Tao.hs b/Documentation/SBV/Examples/TP/Tao.hs
--- a/Documentation/SBV/Examples/TP/Tao.hs
+++ b/Documentation/SBV/Examples/TP/Tao.hs
@@ -18,12 +18,7 @@
 
 
 {-# LANGUAGE CPP                 #-}
-{-# LANGUAGE DeriveAnyClass      #-}
-{-# LANGUAGE DeriveDataTypeable  #-}
-{-# LANGUAGE DataKinds           #-}
-{-# LANGUAGE TypeAbstractions    #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE StandaloneDeriving  #-}
 {-# LANGUAGE TemplateHaskell     #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
@@ -41,7 +36,7 @@
 
 -- | Create an uninterpreted type to do the proofs over.
 data T
-mkUninterpretedSort ''T
+mkSymbolic [''T]
 
 -- | Prove that:
 --
@@ -54,7 +49,7 @@
 -- We have:
 --
 -- >>> tao @T (uninterpret "op")
--- Lemma: tao                              Q.E.D.
+-- Lemma: tao          Q.E.D.
 -- [Proven] tao :: Bool
 tao :: forall a. SymVal a => (SBV a -> SBV a -> SBV a) -> IO (Proof SBool)
 tao op = runTP $
diff --git a/Documentation/SBV/Examples/TP/TautologyChecker.hs b/Documentation/SBV/Examples/TP/TautologyChecker.hs
new file mode 100644
--- /dev/null
+++ b/Documentation/SBV/Examples/TP/TautologyChecker.hs
@@ -0,0 +1,1124 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Documentation.SBV.Examples.TP.TautologyChecker
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- A verified tautology checker (unordered BDD-style SAT solver) in SBV.
+-- This is a port of the Imandra proof by Grant Passmore, originally
+-- inspired by Boyer-Moore '79.
+-- See <https://raw.githubusercontent.com/imandra-ai/imandrax-examples/refs/heads/main/src/tautology.iml>
+--
+-- We define a simple formula type with If-then-else, normalize formulas into a canonical form, and prove
+-- both soundness and completeness of the tautology checker. The canonical form is essentially an
+-- unordered-BDD, making it easy to evaluate it.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE CPP               #-}
+{-# LANGUAGE DataKinds         #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE OverloadedLists   #-}
+{-# LANGUAGE QuasiQuotes       #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE TypeAbstractions  #-}
+{-# LANGUAGE TypeApplications  #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Documentation.SBV.Examples.TP.TautologyChecker where
+
+import Prelude hiding (null, tail, head, (++))
+
+import Data.SBV
+import Data.SBV.List
+import Data.SBV.TP
+import Data.SBV.Tuple
+
+#ifdef DOCTEST
+-- $setup
+-- >>> import Data.SBV
+-- >>> import Data.SBV.TP
+#endif
+
+-- * Formula representation
+
+-- | A propositional formula with variables and if-then-else.
+data Formula = FTrue
+             | FFalse
+             | Var { fVar   :: Integer }
+             | If  { ifCond :: Formula
+                   , ifThen :: Formula
+                   , ifElse :: Formula
+                   }
+
+-- | Make formulas symbolic.
+mkSymbolic [''Formula]
+
+-- * Measuring formulas
+
+-- | Depth of nested If constructors in the condition position.
+ifDepth :: SFormula -> SInteger
+ifDepth = smtFunction "ifDepth"
+        $ \f -> [sCase| f of
+                   If c _ _ -> 1 + ifDepth c
+                   _        -> 0
+                |]
+
+-- | \(\mathit{ifDepth}(f) \geq 0\)
+--
+-- >>> runTP ifDepthNonNeg
+-- Lemma: ifDepthNonNeg    Q.E.D.
+-- Functions proven terminating: ifDepth
+-- [Proven] ifDepthNonNeg :: Ɐf ∷ Formula → Bool
+ifDepthNonNeg :: TP (Proof (Forall "f" Formula -> SBool))
+ifDepthNonNeg = inductiveLemma "ifDepthNonNeg" (\(Forall f) -> ifDepth f .>= 0) []
+
+-- | Complexity of a formula (for termination measure).
+ifComplexity :: SFormula -> SInteger
+ifComplexity = smtFunction "ifComplexity"
+             $ \f -> [sCase| f of
+                        If c l r -> ifComplexity c * (ifComplexity l + ifComplexity r)
+                        _        -> 1
+                     |]
+
+-- | \(\mathit{ifComplexity}(f) > 0\)
+--
+-- >>> runTP ifComplexityPos
+-- Lemma: ifComplexityPos    Q.E.D.
+-- Functions proven terminating: ifComplexity
+-- [Proven] ifComplexityPos :: Ɐf ∷ Formula → Bool
+ifComplexityPos :: TP (Proof (Forall "f" Formula -> SBool))
+ifComplexityPos = inductiveLemma "ifComplexityPos" (\(Forall f) -> ifComplexity f .> 0) []
+
+-- | The branches of an If have smaller complexity than the whole.
+--
+-- \(\mathit{ifComplexity}(c) < \mathit{ifComplexity}(\mathit{If}(c, l, r)) \land \mathit{ifComplexity}(l) < \mathit{ifComplexity}(\mathit{If}(c, l, r)) \land \mathit{ifComplexity}(r) < \mathit{ifComplexity}(\mathit{If}(c, l, r))\)
+--
+-- >>> runTP ifComplexitySmaller
+-- Lemma: ifComplexityPos        Q.E.D.
+-- Lemma: ifComplexitySmaller
+--   Step: 1                     Q.E.D.
+--   Result:                     Q.E.D.
+-- Functions proven terminating: ifComplexity
+-- [Proven] ifComplexitySmaller :: Ɐc ∷ Formula → Ɐl ∷ Formula → Ɐr ∷ Formula → Bool
+ifComplexitySmaller :: TP (Proof (Forall "c" Formula -> Forall "l" Formula -> Forall "r" Formula -> SBool))
+ifComplexitySmaller = do
+  icp <- recall ifComplexityPos
+
+  calc "ifComplexitySmaller"
+       (\(Forall c) (Forall l) (Forall r) ->
+          let ic = ifComplexity (sIf c l r)
+          in ifComplexity c .< ic .&& ifComplexity l .< ic .&& ifComplexity r .< ic) $
+       \c l r ->
+         let ic = ifComplexity (sIf c l r)
+             cc = ifComplexity c
+             cl = ifComplexity l
+             cr = ifComplexity r
+         in [] |- cc .< ic .&& cl .< ic .&& cr .< ic
+               ?? icp `at` Inst @"f" c
+               ?? icp `at` Inst @"f" l
+               ?? icp `at` Inst @"f" r
+               =: sTrue
+               =: qed
+
+-- * Normalization
+
+-- | Check if a formula is in normal form (no nested If in condition position).
+isNormal :: SFormula -> SBool
+isNormal = smtFunction "isNormal"
+         $ \f -> [sCase| f of
+                    If c p q  -> sNot (isIf c) .&& isNormal p .&& isNormal q
+                    _         -> sTrue
+                 |]
+
+-- | Normalize a formula by eliminating nested Ifs in condition position.
+--
+-- The key transformation is:
+--
+-- @
+--   If (If (p, q, r), left, right)
+--     =
+--   If (p, If (q, left, right), If (r, left, right))
+-- @
+--
+-- Note that this transformation increases the size of the formula, but reduces its complexity.
+normalize :: SFormula -> SFormula
+normalize = smtFunctionWithMeasure "normalize"
+                                   ( \f -> tuple (ifComplexity f, ifDepth f)
+                                   , [ measureLemma        ifDepthNonNeg
+                                     , measureLemma        ifComplexityPos
+                                     , measureLemmaWith z3 ifComplexitySmaller
+                                     , measureLemmaWith z3 normalizePreservesComplexity
+                                     ]
+                                   )
+          $ \f -> [sCase| f of
+                     If (If p q r) left right -> normalize (sIf p (sIf q left right) (sIf r left right))
+                     If c          left right -> sIf c (normalize left) (normalize right)
+                     _                        -> f
+                  |]
+
+-- | The normalization transformation preserves complexity.
+--
+-- \(\mathit{ifComplexity}(\mathit{If}(p, \mathit{If}(q, l, r), \mathit{If}(s, l, r))) = \mathit{ifComplexity}(\mathit{If}(\mathit{If}(p, q, s), l, r))\)
+--
+-- >>> runTP normalizePreservesComplexity
+-- Lemma: helper                          Q.E.D.
+-- Lemma: normalizePreservesComplexity
+--   Step: 1                              Q.E.D.
+--   Step: 2                              Q.E.D.
+--   Step: 3                              Q.E.D.
+--   Step: 4                              Q.E.D.
+--   Step: 5                              Q.E.D.
+--   Step: 6                              Q.E.D.
+--   Step: 7                              Q.E.D.
+--   Result:                              Q.E.D.
+-- Functions proven terminating: ifComplexity
+-- [Proven] normalizePreservesComplexity :: Ɐp ∷ Formula → Ɐq ∷ Formula → Ɐs ∷ Formula → Ɐl ∷ Formula → Ɐr ∷ Formula → Bool
+normalizePreservesComplexity :: TP (Proof (Forall "p" Formula -> Forall "q" Formula -> Forall "s" Formula -> Forall "l" Formula -> Forall "r" Formula -> SBool))
+normalizePreservesComplexity = do
+
+  -- The following is a trivial lemma, but without it the solver don't seem to be able to make progress since
+  -- it needs to instantiate it properly. So we help the solver out explicitly.
+  helper <- lemma "helper"
+                  (\(Forall @"a" a) (Forall @"b" b) (Forall @"c" c) -> a .== b .=> a * c .== b * (c :: SInteger))
+                  []
+
+  calc "normalizePreservesComplexity"
+       (\(Forall p) (Forall q) (Forall s) (Forall l) (Forall r) ->
+          ifComplexity (sIf p (sIf q l r) (sIf s l r)) .== ifComplexity (sIf (sIf p q s) l r)) $
+       \p q s l r ->
+         let cp = ifComplexity p
+             cq = ifComplexity q
+             cs = ifComplexity s
+             cl = ifComplexity l
+             cr = ifComplexity r
+         in [] |- ifComplexity (sIf p (sIf q l r) (sIf s l r))
+               =: cp * (ifComplexity (sIf q l r) + ifComplexity (sIf s l r))
+               =: cp * (cq * (cl + cr) + cs * (cl + cr))
+               =: cp * ((cq + cs) * (cl + cr))
+               =: (cp * (cq + cs)) * (cl + cr)
+               ?? helper `at` (Inst @"a" (ifComplexity (sIf p q s)), Inst @"b" (cp * (cq + cs)), Inst @"c" (cl + cr))
+               =: ifComplexity (sIf p q s) * (cl + cr)
+               =: ifComplexity (sIf p q s) * (ifComplexity l + ifComplexity r)
+               =: ifComplexity (sIf (sIf p q s) l r)
+               =: qed
+
+-- * Variable bindings
+
+-- | A binding associates a variable ID with a boolean value.
+data Binding = Binding { varId :: Integer
+                       , value :: Bool
+                       }
+
+-- | Make bindings symbolic.
+mkSymbolic [''Binding]
+
+-- | Look up a variable in the binding list. If it's not in the list, then it's false.
+lookUp :: SInteger -> SList Binding -> SBool
+lookUp = smtFunction "lookUp"
+       $ \vid bs -> [sCase| bs of
+                       []                                    -> sFalse
+                       Binding bId bVal : rest | vid .== bId -> bVal
+                                               | True        -> lookUp vid rest
+                    |]
+
+-- | Check if a variable is assigned in the bindings.
+isAssigned :: SInteger -> SList Binding -> SBool
+isAssigned = smtFunction "isAssigned"
+           $ \vid bs -> [sCase| bs of
+                           []                                -> sFalse
+                           Binding bId _ : rst | bId .== vid -> sTrue
+                                               | True        -> isAssigned vid rst
+                        |]
+
+-- | Add a binding assuming the variable is true.
+assumeTrue :: SInteger -> SList Binding -> SList Binding
+assumeTrue vid bs = sBinding vid sTrue .: bs
+
+-- | Add a binding assuming the variable is false.
+assumeFalse :: SInteger -> SList Binding -> SList Binding
+assumeFalse vid bs = sBinding vid sFalse .: bs
+
+-- | Adding a binding preserves existing assignments.
+--
+-- >>> runTP isAssignedExtends
+-- Lemma: isAssignedExtends    Q.E.D.
+-- Functions proven terminating: isAssigned
+-- [Proven] isAssignedExtends :: Ɐi ∷ Integer → Ɐn ∷ Integer → Ɐv ∷ Bool → Ɐbs ∷ [Binding] → Bool
+isAssignedExtends :: TP (Proof (Forall "i" Integer -> Forall "n" Integer -> Forall "v" Bool -> Forall "bs" [Binding] -> SBool))
+isAssignedExtends = lemma "isAssignedExtends"
+                          (\(Forall i) (Forall n) (Forall v) (Forall bs) -> isAssigned i bs .=> isAssigned i (sBinding n v .: bs))
+                          []
+
+-- | Looking up a variable in extended bindings: if already assigned, value is preserved.
+--
+-- >>> runTP lookUpExtends
+-- Lemma: lookUpExtends    Q.E.D.
+-- Functions proven terminating: isAssigned, lookUp
+-- [Proven] lookUpExtends :: Ɐi ∷ Integer → Ɐn ∷ Integer → Ɐv ∷ Bool → Ɐbs ∷ [Binding] → Bool
+lookUpExtends :: TP (Proof (Forall "i" Integer -> Forall "n" Integer -> Forall "v" Bool -> Forall "bs" [Binding] -> SBool))
+lookUpExtends = lemma "lookUpExtends"
+                      (\(Forall i) (Forall n) (Forall v) (Forall bs) ->
+                                isAssigned i bs .&& i ./= n .=> lookUp i (sBinding n v .: bs) .== lookUp i bs)
+                      []
+
+-- | Looking up a variable that was just added returns the added value.
+--
+-- >>> runTP lookUpSame
+-- Lemma: lookUpSame    Q.E.D.
+-- Functions proven terminating: lookUp
+-- [Proven] lookUpSame :: Ɐn ∷ Integer → Ɐv ∷ Bool → Ɐbs ∷ [Binding] → Bool
+lookUpSame :: TP (Proof (Forall "n" Integer -> Forall "v" Bool -> Forall "bs" [Binding] -> SBool))
+lookUpSame = lemma "lookUpSame" (\(Forall n) (Forall v) (Forall bs) -> lookUp n (sBinding n v .: bs) .== v) []
+
+-- | Adding a binding for a variable makes it assigned.
+--
+-- >>> runTP isAssignedSame
+-- Lemma: isAssignedSame    Q.E.D.
+-- Functions proven terminating: isAssigned
+-- [Proven] isAssignedSame :: Ɐn ∷ Integer → Ɐv ∷ Bool → Ɐbs ∷ [Binding] → Bool
+isAssignedSame :: TP (Proof (Forall "n" Integer -> Forall "v" Bool -> Forall "bs" [Binding] -> SBool))
+isAssignedSame = lemma "isAssignedSame" (\(Forall n) (Forall v) (Forall bs) -> isAssigned n (sBinding n v .: bs)) []
+
+-- * Formula evaluation
+
+-- | Evaluate a formula under a binding environment.
+eval :: SFormula -> SList Binding -> SBool
+eval = smtFunction "eval"
+     $ \f bs -> [sCase| f of
+                   Var n    -> lookUp n bs
+                   If c l r | eval c bs -> eval l bs
+                            | True      -> eval r bs
+                   FTrue    -> sTrue
+                   FFalse   -> sFalse
+                |]
+
+-- * Tautology checking
+
+-- | Check if a normalized formula is a tautology.
+isTautology' :: SFormula -> SList Binding -> SBool
+isTautology' = smtFunction "isTautology'" $ \f bs ->
+  [sCase| f of
+    -- Trivial cases
+    FTrue          -> sTrue
+    FFalse         -> sFalse
+
+    -- Variable
+    Var _          -> eval f bs
+
+    -- Constant branches
+    If FTrue  l _  -> isTautology' l bs
+    If FFalse _ r  -> isTautology' r bs
+
+    -- Branching on a variable
+    If (Var n) l r
+      -- We have already this variable, so evaluate based on the current choice
+      | isAssigned n bs, eval (sVar n) bs -> isTautology' l bs
+      | isAssigned n bs                   -> isTautology' r bs
+
+      -- We haven't yet assigned this variable. Both branches should work out:
+      | True             ->     isTautology' l (assumeTrue  n bs)
+                            .&& isTautology' r (assumeFalse n bs)
+
+    If _ _ _ -> sFalse  -- Contradicts isNormal assumption
+  |]
+
+-- | Main tautology checker.
+isTautology :: SFormula -> SBool
+isTautology f = isTautology' (normalize f) []
+
+-- * Soundness
+
+-- | \(\mathit{lookUp}(x, a \mathbin{+\!\!+} b) = \mathit{if } \mathit{isAssigned}(x, a) \mathit{ then } \mathit{lookUp}(x, a) \mathit{ else } \mathit{lookUp}(x, b)\)
+--
+-- If we look up a variable in a concatenated binding list, we first check
+-- the first list, and only if not found there, check the second.
+--
+-- >>> runTP lookUpStable
+-- Inductive lemma: lookUpStable
+--   Step: Base                     Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1.1                  Q.E.D.
+--     Step: 1.1.2                  Q.E.D.
+--     Step: 1.2.1                  Q.E.D.
+--     Step: 1.2.2                  Q.E.D.
+--     Step: 1.Completeness         Q.E.D.
+--   Result:                        Q.E.D.
+-- Functions proven terminating: isAssigned, lookUp
+-- [Proven] lookUpStable :: Ɐa ∷ [Binding] → Ɐx ∷ Integer → Ɐb ∷ [Binding] → Bool
+lookUpStable :: TP (Proof (Forall "a" [Binding] -> Forall "x" Integer -> Forall "b" [Binding] -> SBool))
+lookUpStable =
+  induct "lookUpStable"
+         (\(Forall a) (Forall x) (Forall b) -> lookUp x (a ++ b) .== ite (isAssigned x a) (lookUp x a) (lookUp x b)) $
+         \ih (binding, a) x b ->
+           let vid = svarId binding
+               val = svalue binding
+           in [] |- lookUp x ((binding .: a) ++ b)
+                 =: cases [ vid .== x ==> ite (isAssigned x (binding .: a)) (lookUp x (binding .: a)) (lookUp x b)
+                                       =: val
+                                       =: qed
+                          , vid ./= x ==> lookUp x (a ++ b)
+                                       ?? ih
+                                       =: ite (isAssigned x a) (lookUp x a) (lookUp x b)
+                                       =: qed
+                          ]
+
+-- | \(\mathit{lookUp}(x, a) \implies \mathit{isAssigned}(x, a)\)
+--
+-- >>> runTP trueIsAssigned
+-- Inductive lemma: trueIsAssigned
+--   Step: Base                       Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1                      Q.E.D.
+--     Step: 1.2.1                    Q.E.D.
+--     Step: 1.2.2                    Q.E.D.
+--     Step: 1.Completeness           Q.E.D.
+--   Result:                          Q.E.D.
+-- Functions proven terminating: isAssigned, lookUp
+-- [Proven] trueIsAssigned :: Ɐa ∷ [Binding] → Ɐx ∷ Integer → Bool
+trueIsAssigned :: TP (Proof (Forall "a" [Binding] -> Forall "x" Integer -> SBool))
+trueIsAssigned =
+  induct "trueIsAssigned"
+         (\(Forall a) (Forall x) -> lookUp x a .=> isAssigned x a) $
+         \ih (binding, a) x ->
+           let vid = [sCase| binding of Binding v _ -> v|]
+           in [lookUp x (binding .: a)]
+           |- isAssigned x (binding .: a)
+           =: cases [ vid .== x ==> trivial
+                    , vid ./= x ==> isAssigned x a
+                                 ?? ih
+                                 =: sTrue
+                                 =: qed
+                    ]
+
+-- | \(\mathit{value} = \mathit{lookUp}(x, bs) \implies \mathit{eval}(f, \{x \mapsto \mathit{value}\} :: bs) = \mathit{eval}(f, bs)\)
+--
+-- If we add a redundant binding (same id and value) to the front, evaluation doesn't change.
+--
+-- >>> runTPWith cvc5 evalStable
+-- Lemma: ifComplexityPos                  Q.E.D.
+-- Lemma: ifComplexitySmaller              Q.E.D.
+-- Inductive lemma (strong): evalStable
+--   Step: Measure is non-negative         Q.E.D.
+--   Step: 1 (4 way case split)
+--     Step: 1.1                           Q.E.D.
+--     Step: 1.2                           Q.E.D.
+--     Step: 1.3                           Q.E.D.
+--     Step: 1.4.1                         Q.E.D.
+--     Step: 1.4.2                         Q.E.D.
+--     Step: 1.4.3                         Q.E.D.
+--     Step: 1.4.4                         Q.E.D.
+--     Step: 1.4.5                         Q.E.D.
+--     Step: 1.4.6                         Q.E.D.
+--     Step: 1.Completeness                Q.E.D.
+--   Result:                               Q.E.D.
+-- Functions proven terminating: eval, ifComplexity, lookUp
+-- [Proven] evalStable :: Ɐf ∷ Formula → Ɐx ∷ Integer → Ɐv ∷ Bool → Ɐbs ∷ [Binding] → Bool
+evalStable :: TP (Proof (Forall "f" Formula -> Forall "x" Integer -> Forall "v" Bool -> Forall "bs" [Binding] -> SBool))
+evalStable = do
+  icp <- recall ifComplexityPos
+  ibs <- recall ifComplexitySmaller
+
+  sInduct "evalStable"
+          (\(Forall f) (Forall x) (Forall v) (Forall bs) -> v .== lookUp x bs .=> eval f (sBinding x v .: bs) .== eval f bs)
+          (\f _ _ _ -> ifComplexity f, [proofOf icp]) $
+          \ih f x v bs ->
+               let b = sBinding x v
+               in [v .== lookUp x bs]
+               |- cases [ isFTrue  f ==> trivial
+                        , isFFalse f ==> trivial
+                        , isVar    f ==> trivial
+                        , isIf     f ==>
+                            let c = sifCond f
+                                l = sifThen f
+                                r = sifElse f
+                            in eval f (b .: bs)
+                            =: eval (sIf c l r) (b .: bs)
+                            =: ite (eval c (b .: bs)) (eval l (b .: bs)) (eval r (b .: bs))
+                            ?? ih  `at` (Inst @"f" c, Inst @"x" x, Inst @"v" v, Inst @"bs" bs)
+                            ?? ibs `at` (Inst @"c" c, Inst @"l" l, Inst @"r" r)
+                            =: ite (eval c bs) (eval l (b .: bs)) (eval r (b .: bs))
+                            ?? ih  `at` (Inst @"f" l, Inst @"x" x, Inst @"v" v, Inst @"bs" bs)
+                            ?? ibs `at` (Inst @"c" c, Inst @"l" l, Inst @"r" r)
+                            =: ite (eval c bs) (eval l bs) (eval r (b .: bs))
+                            ?? ih  `at` (Inst @"f" r, Inst @"x" x, Inst @"v" v, Inst @"bs" bs)
+                            ?? ibs `at` (Inst @"c" c, Inst @"l" l, Inst @"r" r)
+                            =: ite (eval c bs) (eval l bs) (eval r bs)
+                            =: eval (sIf c l r) bs
+                            =: qed
+                        ]
+
+-- | Key soundness lemma: If a normalized formula is a tautology under bindings @b@,
+-- then it evaluates to true under @b ++ a@ for any @a@.
+--
+-- >>> runTPWith cvc5 tautologyImpliesEval
+-- Lemma: ifComplexityPos                            Q.E.D.
+-- Lemma: ifComplexitySmaller                        Q.E.D.
+-- Lemma: lookUpStable                               Q.E.D.
+-- Lemma: trueIsAssigned                             Q.E.D.
+-- Lemma: evalStable                                 Q.E.D.
+-- Inductive lemma (strong): tautologyImpliesEval
+--   Step: Measure is non-negative                   Q.E.D.
+--   Step: 1 (4 way case split)
+--     Step: 1.1                                     Q.E.D.
+--     Step: 1.2                                     Q.E.D.
+--     Step: 1.3.1                                   Q.E.D.
+--     Step: 1.3.2                                   Q.E.D.
+--     Step: 1.3.3                                   Q.E.D.
+--     Step: 1.3.4                                   Q.E.D.
+--     Step: 1.3.5                                   Q.E.D.
+--     Step: 1.4 (4 way case split)
+--       Step: 1.4.1.1                               Q.E.D.
+--       Step: 1.4.1.2                               Q.E.D.
+--       Step: 1.4.2.1                               Q.E.D.
+--       Step: 1.4.2.2                               Q.E.D.
+--       Step: 1.4.2.3                               Q.E.D.
+--       Step: 1.4.3 (2 way case split)
+--         Step: 1.4.3.1.1                           Q.E.D.
+--         Step: 1.4.3.1.2                           Q.E.D.
+--         Step: 1.4.3.1.3                           Q.E.D.
+--         Step: 1.4.3.1.4                           Q.E.D.
+--         Step: 1.4.3.2 (2 way case split)
+--           Step: 1.4.3.2.1.1                       Q.E.D.
+--           Step: 1.4.3.2.1.2                       Q.E.D.
+--           Step: 1.4.3.2.1.3                       Q.E.D.
+--           Step: 1.4.3.2.1.4                       Q.E.D.
+--           Step: 1.4.3.2.1.5                       Q.E.D.
+--           Step: 1.4.3.2.1.6                       Q.E.D.
+--           Step: 1.4.3.2.1.7                       Q.E.D.
+--           Step: 1.4.3.2.1.8                       Q.E.D.
+--           Step: 1.4.3.2.2.1                       Q.E.D.
+--           Step: 1.4.3.2.2.2                       Q.E.D.
+--           Step: 1.4.3.2.2.3                       Q.E.D.
+--           Step: 1.4.3.2.2.4                       Q.E.D.
+--           Step: 1.4.3.2.2.5                       Q.E.D.
+--           Step: 1.4.3.2.2.6                       Q.E.D.
+--           Step: 1.4.3.2.2.7                       Q.E.D.
+--           Step: 1.4.3.2.2.8                       Q.E.D.
+--           Step: 1.4.3.2.Completeness              Q.E.D.
+--         Step: 1.4.3.Completeness                  Q.E.D.
+--       Step: 1.4.4                                 Q.E.D.
+--       Step: 1.4.Completeness                      Q.E.D.
+--     Step: 1.Completeness                          Q.E.D.
+--   Result:                                         Q.E.D.
+-- Functions proven terminating: eval, ifComplexity, isAssigned, isNormal, isTautology', lookUp
+-- [Proven] tautologyImpliesEval :: Ɐf ∷ Formula → Ɐa ∷ [Binding] → Ɐb ∷ [Binding] → Bool
+tautologyImpliesEval :: TP (Proof (Forall "f" Formula -> Forall "a" [Binding] -> Forall "b" [Binding] -> SBool))
+tautologyImpliesEval = do
+
+  icp <- recall ifComplexityPos
+  ibs <- recall ifComplexitySmaller
+  lus <- recall lookUpStable
+  tia <- recall trueIsAssigned
+  evs <- recall evalStable
+
+  sInduct "tautologyImpliesEval"
+          (\(Forall f) (Forall a) (Forall b) -> isNormal f .&& isTautology' f b .=> eval f (b ++ a))
+          (\f _ _ -> ifComplexity f, [proofOf icp]) $
+          \ih f a b ->
+                [isNormal f, isTautology' f b]
+             |- cases [ isFTrue  f ==> trivial
+                      , isFFalse f ==> trivial
+                      , isVar    f ==> let n = sfVar f
+                                       in eval f (b ++ a)
+                                       =: eval (sVar n) (b ++ a)
+                                       =: lookUp n (b ++ a)
+                                       ?? lus `at` (Inst @"a" b, Inst @"x" n, Inst @"b" a)
+                                       =: ite (isAssigned n b) (lookUp n b) (lookUp n a)
+                                       ?? tia `at` (Inst @"a" b, Inst @"x" n)
+                                       =: lookUp n b
+                                       =: sTrue
+                                       =: qed
+                      , isIf f     ==>
+                          let c = sifCond f
+                              l = sifThen f
+                              r = sifElse f
+                          in cases [ isFTrue  c ==> eval (sIf c l r) (b ++ a)
+                                                 =: ite (eval c (b ++ a)) (eval l (b ++ a)) (eval r (b ++ a))
+                                                 ?? ibs `at` (Inst @"c" c, Inst @"l" l, Inst @"r" r)
+                                                 ?? ih  `at` (Inst @"f" l, Inst @"a" a, Inst @"b" b)
+                                                 =: sTrue
+                                                 =: qed
+                                   , isFFalse c ==> eval (sIf c l r) (b ++ a)
+                                                 =: ite (eval c (b ++ a)) (eval l (b ++ a)) (eval r (b ++ a))
+                                                 =: eval r (b ++ a)
+                                                 ?? ibs `at` (Inst @"c" c, Inst @"l" l, Inst @"r" r)
+                                                 ?? ih  `at` (Inst @"f" r, Inst @"a" a, Inst @"b" b)
+                                                 =: sTrue
+                                                 =: qed
+                                   , isVar    c ==> let n = sfVar c
+                                                    in cases [ isAssigned n b ==>
+                                                                    eval (sIf (sVar n) l r) (b ++ a)
+                                                                 =: ite (eval (sVar n) (b ++ a)) (eval l (b ++ a)) (eval r (b ++ a))
+                                                                 =: ite (lookUp n (b ++ a)) (eval l (b ++ a)) (eval r (b ++ a))
+                                                                 ?? lus `at` (Inst @"a" b, Inst @"x" n, Inst @"b" a)
+                                                                 =: ite (lookUp n b) (eval l (b ++ a)) (eval r (b ++ a))
+                                                                 ?? ibs `at` (Inst @"c" c, Inst @"l" l, Inst @"r" r)
+                                                                 ?? ih  `at` (Inst @"f" l, Inst @"a" a, Inst @"b" b)
+                                                                 ?? ih  `at` (Inst @"f" r, Inst @"a" a, Inst @"b" b)
+                                                                 =: sTrue
+                                                                 =: qed
+                                                             , sNot (isAssigned n b) ==>
+                                                                 cases [ lookUp n a ==>
+                                                                             eval (sIf (sVar n) l r) (b ++ a)
+                                                                          =: ite (eval (sVar n) (b ++ a)) (eval l (b ++ a)) (eval r (b ++ a))
+                                                                          =: ite (lookUp n (b ++ a)) (eval l (b ++ a)) (eval r (b ++ a))
+                                                                          ?? lus `at` (Inst @"a" b, Inst @"x" n, Inst @"b" a)
+                                                                          =: ite (lookUp n a) (eval l (b ++ a)) (eval r (b ++ a))
+                                                                          =: eval l (b ++ a)
+                                                                          ?? evs `at` (Inst @"f" l, Inst @"x" n, Inst @"v" (lookUp n a), Inst @"bs" (b ++ a))
+                                                                          ?? lus `at` (Inst @"a" b, Inst @"x" n, Inst @"b" a)
+                                                                          =: eval l (sBinding n (lookUp n a) .: (b ++ a))
+                                                                          =: eval l (sBinding n sTrue .: (b ++ a))
+                                                                          =: eval l (assumeTrue n b ++ a)
+                                                                          ?? ibs `at` (Inst @"c" c, Inst @"l" l, Inst @"r" r)
+                                                                          ?? ih  `at` (Inst @"f" l, Inst @"a" a, Inst @"b" (assumeTrue n b))
+                                                                          =: sTrue
+                                                                          =: qed
+                                                                       , sNot (lookUp n a) ==>
+                                                                             eval (sIf (sVar n) l r) (b ++ a)
+                                                                          =: ite (eval (sVar n) (b ++ a)) (eval l (b ++ a)) (eval r (b ++ a))
+                                                                          =: ite (lookUp n (b ++ a)) (eval l (b ++ a)) (eval r (b ++ a))
+                                                                          ?? lus `at` (Inst @"a" b, Inst @"x" n, Inst @"b" a)
+                                                                          =: ite (lookUp n a) (eval l (b ++ a)) (eval r (b ++ a))
+                                                                          =: eval r (b ++ a)
+                                                                          ?? evs `at` (Inst @"f" r, Inst @"x" n, Inst @"v" (lookUp n a), Inst @"bs" (b ++ a))
+                                                                          ?? lus `at` (Inst @"a" b, Inst @"x" n, Inst @"b" a)
+                                                                          =: eval r (sBinding n (lookUp n a) .: (b ++ a))
+                                                                          =: eval r (sBinding n sFalse .: (b ++ a))
+                                                                          =: eval r (assumeFalse n b ++ a)
+                                                                          ?? ibs `at` (Inst @"c" c, Inst @"l" l, Inst @"r" r)
+                                                                          ?? ih  `at` (Inst @"f" r, Inst @"a" a, Inst @"b" (assumeFalse n b))
+                                                                          =: sTrue
+                                                                          =: qed
+                                                                       ]
+                                                             ]
+                                   , isIf c     ==> trivial  -- Contradicts isNormal
+                                   ]
+                      ]
+
+-- * Normalization correctness
+
+-- | \(\mathit{isNormal}(\mathit{normalize}(f))\)
+--
+-- Normalization produces normalized formulas.
+--
+-- >>> runTP normalizeCorrect
+-- Lemma: ifComplexityPos                        Q.E.D.
+-- Lemma: ifComplexitySmaller                    Q.E.D.
+-- Lemma: normalizePreservesComplexity           Q.E.D.
+-- Lemma: ifDepthNonNeg                          Q.E.D.
+-- Inductive lemma (strong): normalizeCorrect
+--   Step: Measure is non-negative               Q.E.D.
+--   Step: 1 (4 way case split)
+--     Step: 1.1                                 Q.E.D.
+--     Step: 1.2                                 Q.E.D.
+--     Step: 1.3                                 Q.E.D.
+--     Step: 1.4 (2 way case split)
+--       Step: 1.4.1.1                           Q.E.D.
+--       Step: 1.4.1.2                           Q.E.D.
+--       Step: 1.4.2.1                           Q.E.D.
+--       Step: 1.4.2.2                           Q.E.D.
+--       Step: 1.4.2.3                           Q.E.D.
+--       Step: 1.4.2.4                           Q.E.D.
+--       Step: 1.4.2.5                           Q.E.D.
+--       Step: 1.4.Completeness                  Q.E.D.
+--     Step: 1.Completeness                      Q.E.D.
+--   Result:                                     Q.E.D.
+-- Functions proven terminating: ifComplexity, ifDepth, isNormal, normalize
+-- [Proven] normalizeCorrect :: Ɐf ∷ Formula → Bool
+normalizeCorrect :: TP (Proof (Forall "f" Formula -> SBool))
+normalizeCorrect = do
+  icp <- recall ifComplexityPos
+  ibs <- recall ifComplexitySmaller
+  npc <- recall normalizePreservesComplexity
+  idn <- recall ifDepthNonNeg
+
+  sInductWith cvc5 "normalizeCorrect"
+              (\(Forall f) -> isNormal (normalize f))
+              (\f -> tuple (ifComplexity f, ifDepth f), [proofOf icp, proofOf idn]) $
+              \ih f -> []
+                    |- isNormal (normalize f)
+                    =: cases [ isFTrue  f ==> trivial
+                             , isFFalse f ==> trivial
+                             , isVar    f ==> trivial
+                             , isIf     f ==> let c = sifCond f
+                                                  l = sifThen f
+                                                  r = sifElse f
+                                              in cases [ isIf c ==>
+                                                           let p  = sifCond c
+                                                               q  = sifThen c
+                                                               rc = sifElse c
+                                                               transformed = sIf p (sIf q l r) (sIf rc l r)
+                                                           in isNormal (normalize transformed)
+                                                           ?? npc `at` (Inst @"p" p, Inst @"q" q, Inst @"s" rc, Inst @"l" l, Inst @"r" r)
+                                                           ?? ih `at` Inst @"f" transformed
+                                                           =: sTrue
+                                                           =: qed
+                                                       , sNot (isIf c) ==>
+                                                              isNormal (sIf c (normalize l) (normalize r))
+                                                           =: sNot (isIf c) .&& isNormal (normalize l) .&& isNormal (normalize r)
+                                                           =: isNormal (normalize l) .&& isNormal (normalize r)
+                                                           ?? ibs `at` (Inst @"c" c, Inst @"l" l, Inst @"r" r)
+                                                           ?? ih  `at` Inst @"f" l
+                                                           =: isNormal (normalize r)
+                                                           ?? ibs `at` (Inst @"c" c, Inst @"l" l, Inst @"r" r)
+                                                           ?? ih  `at` Inst @"f" r
+                                                           =: sTrue
+                                                           =: qed
+                                                       ]
+                             ]
+
+-- | \(\mathit{isNormal}(f) \implies \mathit{normalize}(f) = f\)
+--
+-- Normalizing a normalized formula is the identity.
+--
+-- >>> runTP normalizeSame
+-- Lemma: ifComplexityPos                     Q.E.D.
+-- Lemma: ifComplexitySmaller                 Q.E.D.
+-- Inductive lemma (strong): normalizeSame
+--   Step: Measure is non-negative            Q.E.D.
+--   Step: 1 (4 way case split)
+--     Step: 1.1                              Q.E.D.
+--     Step: 1.2                              Q.E.D.
+--     Step: 1.3                              Q.E.D.
+--     Step: 1.4.1                            Q.E.D.
+--     Step: 1.4.2                            Q.E.D.
+--     Step: 1.Completeness                   Q.E.D.
+--   Result:                                  Q.E.D.
+-- Functions proven terminating: ifComplexity, isNormal, normalize
+-- [Proven] normalizeSame :: Ɐf ∷ Formula → Bool
+normalizeSame :: TP (Proof (Forall "f" Formula -> SBool))
+normalizeSame = do
+  icp <- recall ifComplexityPos
+  ibs <- recall ifComplexitySmaller
+
+  sInduct "normalizeSame"
+          (\(Forall f) -> isNormal f .=> normalize f .== f)
+          (ifComplexity, [proofOf icp]) $
+          \ih f -> [isNormal f]
+                |- cases [ isFTrue  f ==> trivial
+                         , isFFalse f ==> trivial
+                         , isVar    f ==> trivial
+                         , isIf     f ==> let c = sifCond f
+                                              l = sifThen f
+                                              r = sifElse f
+                                          in sIf c (normalize l) (normalize r)
+                                          ?? ibs `at` (Inst @"c" c, Inst @"l" l, Inst @"r" r)
+                                          ?? ih `at` Inst @"f" l
+                                          =: sIf c l (normalize r)
+                                          ?? ibs `at` (Inst @"c" c, Inst @"l" l, Inst @"r" r)
+                                          ?? ih `at` Inst @"f" r
+                                          =: sIf c l r
+                                          =: qed
+                         ]
+
+-- | \(\mathit{eval}(\mathit{normalize}(f), bs) = \mathit{eval}(f, bs)\)
+--
+-- Normalization preserves semantics.
+--
+-- >>> runTP normalizeRespectsTruth
+-- Lemma: ifComplexityPos                              Q.E.D.
+-- Lemma: ifComplexitySmaller                          Q.E.D.
+-- Lemma: normalizePreservesComplexity                 Q.E.D.
+-- Lemma: ifDepthNonNeg                                Q.E.D.
+-- Inductive lemma (strong): normalizeRespectsTruth
+--   Step: Measure is non-negative                     Q.E.D.
+--   Step: 1 (4 way case split)
+--     Step: 1.1                                       Q.E.D.
+--     Step: 1.2                                       Q.E.D.
+--     Step: 1.3                                       Q.E.D.
+--     Step: 1.4 (2 way case split)
+--       Step: 1.4.1                                   Q.E.D.
+--       Step: 1.4.2.1                                 Q.E.D.
+--       Step: 1.4.2.2                                 Q.E.D.
+--       Step: 1.4.2.3                                 Q.E.D.
+--       Step: 1.4.Completeness                        Q.E.D.
+--     Step: 1.Completeness                            Q.E.D.
+--   Result:                                           Q.E.D.
+-- Functions proven terminating: eval, ifComplexity, ifDepth, lookUp, normalize
+-- [Proven] normalizeRespectsTruth :: Ɐf ∷ Formula → Ɐbs ∷ [Binding] → Bool
+normalizeRespectsTruth :: TP (Proof (Forall "f" Formula -> Forall "bs" [Binding] -> SBool))
+normalizeRespectsTruth = do
+  icp <- recall ifComplexityPos
+  ibs <- recall ifComplexitySmaller
+  npc <- recall normalizePreservesComplexity
+  idn <- recall ifDepthNonNeg
+
+  sInductWith cvc5 "normalizeRespectsTruth"
+              (\(Forall f) (Forall bs) -> eval (normalize f) bs .== eval f bs)
+              (\f _ -> tuple (ifComplexity f, ifDepth f), [proofOf icp, proofOf idn]) $
+              \ih f bs -> []
+                       |- cases [ isFTrue  f ==> trivial
+                                , isFFalse f ==> trivial
+                                , isVar    f ==> trivial
+                                , isIf     f ==> let c = sifCond f
+                                                     l = sifThen f
+                                                     r = sifElse f
+                                                 in cases [ isIf c ==>
+                                                              let p  = sifCond c
+                                                                  q  = sifThen c
+                                                                  rc = sifElse c
+                                                                  transformed = sIf p (sIf q l r) (sIf rc l r)
+                                                              in eval (normalize (sIf c l r)) bs .== eval (sIf c l r) bs
+                                                              ?? npc `at` (Inst @"p" p, Inst @"q" q, Inst @"s" rc, Inst @"l" l, Inst @"r" r)
+                                                              ?? ih  `at` (Inst @"f" transformed, Inst @"bs" bs)
+                                                              =: sTrue
+                                                              =: qed
+                                                          , sNot (isIf c) ==>
+                                                                 eval (normalize (sIf c l r)) bs .== eval (sIf c l r) bs
+                                                              =: eval (sIf c (normalize l) (normalize r)) bs .== eval (sIf c l r) bs
+                                                              =: ite (eval c bs) (eval (normalize l) bs) (eval (normalize r) bs) .== ite (eval c bs) (eval l bs) (eval r bs)
+                                                              ?? ibs `at` (Inst @"c" c, Inst @"l" l, Inst @"r" r)
+                                                              ?? ih  `at` (Inst @"f" l, Inst @"bs" bs)
+                                                              ?? ih  `at` (Inst @"f" r, Inst @"bs" bs)
+                                                              =: sTrue
+                                                              =: qed
+                                                          ]
+                                ]
+
+-- * Main soundness theorem
+
+-- | \(\mathit{isTautology}(f) \implies \mathit{eval}(f, \mathit{bindings})\)
+--
+-- If the tautology checker says a formula is a tautology, then it evaluates
+-- to true under any binding environment. This is the soundness theorem.
+--
+-- >>> runTP soundness
+-- Lemma: tautologyImpliesEval                         Q.E.D.
+-- Lemma: normalizeRespectsTruth                       Q.E.D.
+-- Lemma: normalizeCorrect                             Q.E.D.
+-- Lemma: soundness
+--   Step: 1                                           Q.E.D.
+--   Step: 2                                           Q.E.D.
+--   Result:                                           Q.E.D.
+-- Functions proven terminating: eval, ifComplexity, ifDepth, isAssigned, isNormal, isTautology', lookUp, normalize
+-- [Proven] soundness :: Ɐf ∷ Formula → Ɐbindings ∷ [Binding] → Bool
+soundness :: TP (Proof (Forall "f" Formula -> Forall "bindings" [Binding] -> SBool))
+soundness = do
+  tie <- recallWith cvc5 tautologyImpliesEval
+  nrt <- recall normalizeRespectsTruth
+  nc  <- recall normalizeCorrect
+
+  calc "soundness"
+       (\(Forall f) (Forall bindings) -> isTautology f .=> eval f bindings) $
+       \f bindings -> [isTautology f]
+                   |- eval f bindings
+                   ?? nrt `at` (Inst @"f" f, Inst @"bs" bindings)
+                   =: eval (normalize f) bindings
+                   ?? nc  `at` Inst @"f" f
+                   ?? tie `at` (Inst @"f" (normalize f), Inst @"a" bindings, Inst @"b" [])
+                   =: sTrue
+                   =: qed
+
+-- * Completeness
+
+-- | Result of attempting to falsify a formula.
+data FalsifyResult = FalsifyResult { falsified :: Bool
+                                   , cex       :: [Binding]
+                                   }
+
+-- | Make FalsifyResult symbolic.
+mkSymbolic [''FalsifyResult]
+
+-- | Attempt to falsify a normalized formula under given bindings.
+-- Returns whether falsification succeeded and the counterexample bindings.
+falsify' :: SFormula -> SList Binding -> SFalsifyResult
+falsify' = smtFunction "falsify'" $ \f bs ->
+  [sCase| f of
+    FTrue  -> sFalsifyResult sFalse []
+    FFalse -> sFalsifyResult sTrue bs
+
+    Var i
+      | isAssigned i bs, eval (sVar i) bs -> sFalsifyResult sFalse []
+      | isAssigned i bs                   -> sFalsifyResult sTrue bs
+      | True                              -> sFalsifyResult sTrue (sBinding i sFalse .: bs)
+
+    If (Var i) l r
+      | isAssigned i bs, eval (sVar i) bs -> falsify' l bs
+      | isAssigned i bs                   -> falsify' r bs
+      | True                              -> let resL = falsify' l (assumeTrue i bs)
+                                             in ite (sNot (sfalsified resL))
+                                                    (falsify' r (assumeFalse i bs))
+                                                    resL
+    If FTrue  l _  -> falsify' l bs
+    If FFalse _ r  -> falsify' r bs
+    If _      _ _  -> sFalsifyResult sFalse []  -- Shouldn't happen for normal formulas
+  |]
+
+-- | Falsify a formula by first normalizing it.
+falsify :: SFormula -> SFalsifyResult
+falsify f = falsify' (normalize f) []
+
+-- * Completeness lemmas
+
+-- | If a normalized formula is not a tautology, then falsify' returns falsified = true.
+--
+-- >>> runTPWith cvc5 nonTautIsFalsified
+-- Lemma: ifComplexityPos                          Q.E.D.
+-- Lemma: ifComplexitySmaller                      Q.E.D.
+-- Inductive lemma (strong): nonTautIsFalsified
+--   Step: Measure is non-negative                 Q.E.D.
+--   Step: 1 (4 way case split)
+--     Step: 1.1                                   Q.E.D.
+--     Step: 1.2                                   Q.E.D.
+--     Step: 1.3                                   Q.E.D.
+--     Step: 1.4                                   Q.E.D.
+--     Step: 1.Completeness                        Q.E.D.
+--   Result:                                       Q.E.D.
+-- Functions proven terminating: eval, falsify', ifComplexity, isAssigned, isNormal, isTautology', lookUp
+-- [Proven] nonTautIsFalsified :: Ɐf ∷ Formula → Ɐbs ∷ [Binding] → Bool
+nonTautIsFalsified :: TP (Proof (Forall "f" Formula -> Forall "bs" [Binding] -> SBool))
+nonTautIsFalsified = do
+  icp <- recall ifComplexityPos
+  ibs <- recall ifComplexitySmaller
+
+  sInduct "nonTautIsFalsified"
+          (\(Forall f) (Forall bs) -> isNormal f .&& sNot (isTautology' f bs) .=> sfalsified (falsify' f bs))
+          (\f _ -> ifComplexity f, [proofOf icp]) $
+          \ih f bs -> [isNormal f, sNot (isTautology' f bs)]
+                   |- cases [ isFTrue  f ==> trivial
+                            , isFFalse f ==> trivial
+                            , isVar    f ==> trivial
+                            , isIf     f ==> let c = sifCond f
+                                                 l = sifThen f
+                                                 r = sifElse f
+                                             in sfalsified (falsify' f bs)
+                                             ?? ibs `at` (Inst @"c" c, Inst @"l" l, Inst @"r" r)
+                                             ?? ih  `at` (Inst @"f" l, Inst @"bs" bs)
+                                             ?? ih  `at` (Inst @"f" r, Inst @"bs" bs)
+                                             ?? ih  `at` (Inst @"f" l, Inst @"bs" (assumeTrue (sfVar c) bs))
+                                             ?? ih  `at` (Inst @"f" r, Inst @"bs" (assumeFalse (sfVar c) bs))
+                                             =: sTrue
+                                             =: qed
+                            ]
+
+-- | If a variable is assigned in the input bindings and falsify' succeeds,
+-- the lookup value is preserved in the output bindings.
+--
+-- >>> runTPWith cvc5 falsifyExtendsBindings
+-- Lemma: ifComplexityPos                              Q.E.D.
+-- Lemma: ifComplexitySmaller                          Q.E.D.
+-- Lemma: isAssignedExtends                            Q.E.D.
+-- Lemma: lookUpExtends                                Q.E.D.
+-- Inductive lemma (strong): falsifyExtendsBindings
+--   Step: Measure is non-negative                     Q.E.D.
+--   Step: 1 (4 way case split)
+--     Step: 1.1                                       Q.E.D.
+--     Step: 1.2                                       Q.E.D.
+--     Step: 1.3                                       Q.E.D.
+--     Step: 1.4                                       Q.E.D.
+--     Step: 1.Completeness                            Q.E.D.
+--   Result:                                           Q.E.D.
+-- Functions proven terminating: eval, falsify', ifComplexity, isAssigned, lookUp
+-- [Proven] falsifyExtendsBindings :: Ɐf ∷ Formula → Ɐbs ∷ [Binding] → Ɐi ∷ Integer → Bool
+falsifyExtendsBindings :: TP (Proof (Forall "f" Formula -> Forall "bs" [Binding] -> Forall "i" Integer -> SBool))
+falsifyExtendsBindings = do
+  icp <- recall ifComplexityPos
+  ibs <- recall ifComplexitySmaller
+  iae <- recall isAssignedExtends
+  lue <- recall lookUpExtends
+
+  sInduct "falsifyExtendsBindings"
+          (\(Forall f) (Forall bs) (Forall i) ->
+             isAssigned i bs .&& sfalsified (falsify' f bs) .=>
+             lookUp i (scex (falsify' f bs)) .== lookUp i bs)
+          (\f _ _ -> ifComplexity f, [proofOf icp]) $
+          \ih f bs i -> [isAssigned i bs, sfalsified (falsify' f bs)]
+                     |- cases [ isFTrue  f ==> trivial
+                              , isFFalse f ==> trivial
+                              , isVar    f ==> let n = sfVar f
+                                               in lookUp i (scex (falsify' f bs)) .== lookUp i bs
+                                               ?? lue `at` (Inst @"i" i, Inst @"n" n, Inst @"v" sFalse, Inst @"bs" bs)
+                                               =: sTrue
+                                               =: qed
+                              , isIf     f ==> let c = sifCond f
+                                                   l = sifThen f
+                                                   r = sifElse f
+                                                   n = sfVar c
+                                               in lookUp i (scex (falsify' f bs)) .== lookUp i bs
+                                               ?? ibs `at` (Inst @"c" c, Inst @"l" l, Inst @"r" r)
+                                               ?? iae `at` (Inst @"i" i, Inst @"n" n, Inst @"v" sTrue,  Inst @"bs" bs)
+                                               ?? iae `at` (Inst @"i" i, Inst @"n" n, Inst @"v" sFalse, Inst @"bs" bs)
+                                               ?? lue `at` (Inst @"i" i, Inst @"n" n, Inst @"v" sTrue,  Inst @"bs" bs)
+                                               ?? lue `at` (Inst @"i" i, Inst @"n" n, Inst @"v" sFalse, Inst @"bs" bs)
+                                               ?? ih  `at` (Inst @"f" l, Inst @"bs" bs, Inst @"i" i)
+                                               ?? ih  `at` (Inst @"f" r, Inst @"bs" bs, Inst @"i" i)
+                                               ?? ih  `at` (Inst @"f" l, Inst @"bs" (assumeTrue n bs), Inst @"i" i)
+                                               ?? ih  `at` (Inst @"f" r, Inst @"bs" (assumeFalse n bs), Inst @"i" i)
+                                               =: sTrue
+                                               =: qed
+                              ]
+
+-- | If falsify' returns falsified = true, then evaluating the formula
+-- with the returned bindings gives false.
+--
+-- >>> runTPWith cvc5 falsifyFalsifies
+-- Lemma: ifComplexityPos                              Q.E.D.
+-- Lemma: ifComplexitySmaller                          Q.E.D.
+-- Lemma: falsifyExtendsBindings                       Q.E.D.
+-- Lemma: lookUpSame                                   Q.E.D.
+-- Lemma: isAssignedSame                               Q.E.D.
+-- Inductive lemma (strong): falsifyFalsifies
+--   Step: Measure is non-negative                     Q.E.D.
+--   Step: 1 (4 way case split)
+--     Step: 1.1.1                                     Q.E.D.
+--     Step: 1.1.2                                     Q.E.D.
+--     Step: 1.1.3                                     Q.E.D.
+--     Step: 1.2.1                                     Q.E.D.
+--     Step: 1.2.2                                     Q.E.D.
+--     Step: 1.2.3                                     Q.E.D.
+--     Step: 1.3.1                                     Q.E.D.
+--     Step: 1.3.2                                     Q.E.D.
+--     Step: 1.3.3                                     Q.E.D.
+--     Step: 1.4 (4 way case split)
+--       Step: 1.4.1                                   Q.E.D.
+--       Step: 1.4.2                                   Q.E.D.
+--       Step: 1.4.3 (2 way case split)
+--         Step: 1.4.3.1 (2 way case split)
+--           Step: 1.4.3.1.1                           Q.E.D.
+--           Step: 1.4.3.1.2                           Q.E.D.
+--           Step: 1.4.3.1.Completeness                Q.E.D.
+--         Step: 1.4.3.2 (2 way case split)
+--           Step: 1.4.3.2.1                           Q.E.D.
+--           Step: 1.4.3.2.2                           Q.E.D.
+--           Step: 1.4.3.2.Completeness                Q.E.D.
+--         Step: 1.4.3.Completeness                    Q.E.D.
+--       Step: 1.4.4                                   Q.E.D.
+--       Step: 1.4.Completeness                        Q.E.D.
+--     Step: 1.Completeness                            Q.E.D.
+--   Result:                                           Q.E.D.
+-- Functions proven terminating: eval, falsify', ifComplexity, isAssigned, isNormal, lookUp
+-- [Proven] falsifyFalsifies :: Ɐf ∷ Formula → Ɐbs ∷ [Binding] → Bool
+falsifyFalsifies :: TP (Proof (Forall "f" Formula -> Forall "bs" [Binding] -> SBool))
+falsifyFalsifies = do
+  icp <- recall ifComplexityPos
+  ibs <- recall ifComplexitySmaller
+  feb <- recall falsifyExtendsBindings
+  lus <- recall lookUpSame
+  ias <- recall isAssignedSame
+
+  sInduct "falsifyFalsifies"
+          (\(Forall f) (Forall bs) -> isNormal f .&& sfalsified (falsify' f bs) .=> sNot (eval f (scex (falsify' f bs))))
+          (\f _ -> ifComplexity f, [proofOf icp]) $
+          \ih f bs -> [isNormal f, sfalsified (falsify' f bs)]
+                   |- cases [ isFTrue  f ==> sNot (eval f (scex (falsify' f bs)))
+                                          =: sNot (eval sFTrue (scex (falsify' sFTrue bs)))
+                                          =: sNot sTrue
+                                          =: sFalse
+                                          =: qed
+                            , isFFalse f ==> sNot (eval f (scex (falsify' f bs)))
+                                          =: sNot (eval sFFalse bs)
+                                          =: sNot sFalse
+                                          =: sTrue
+                                          =: qed
+                            , isVar    f ==> let n = sfVar f
+                                             in sNot (eval f (scex (falsify' f bs)))
+                                             =: sNot (eval (sVar n) (scex (falsify' (sVar n) bs)))
+                                             =: sNot (lookUp n (scex (falsify' (sVar n) bs)))
+                                             =: sTrue
+                                             =: qed
+                            , isIf     f ==> let c = sifCond f
+                                                 l = sifThen f
+                                                 r = sifElse f
+                                             in cases [ isFTrue  c ==> sNot (eval f (scex (falsify' f bs)))
+                                                                    ?? ibs `at` (Inst @"c" c, Inst @"l" l, Inst @"r" r)
+                                                                    ?? ih  `at` (Inst @"f" l, Inst @"bs" bs)
+                                                                    =: sTrue
+                                                                    =: qed
+                                                      , isFFalse c ==> sNot (eval f (scex (falsify' f bs)))
+                                                                    ?? ibs `at` (Inst @"c" c, Inst @"l" l, Inst @"r" r)
+                                                                    ?? ih  `at` (Inst @"f" r, Inst @"bs" bs)
+                                                                    =: sTrue
+                                                                    =: qed
+                                                      , isVar    c ==> let n = sfVar c
+                                                                       in cases [ isAssigned n bs ==>
+                                                                                      cases [ lookUp n bs ==>
+                                                                                                  sNot (eval f (scex (falsify' f bs)))
+                                                                                               ?? ibs `at` (Inst @"c" c, Inst @"l" l, Inst @"r" r)
+                                                                                               ?? feb `at` (Inst @"f" l, Inst @"bs" bs, Inst @"i" n)
+                                                                                               ?? ih  `at` (Inst @"f" l, Inst @"bs" bs)
+                                                                                               =: sTrue
+                                                                                               =: qed
+                                                                                            , sNot (lookUp n bs) ==>
+                                                                                                  sNot (eval f (scex (falsify' f bs)))
+                                                                                               ?? ibs `at` (Inst @"c" c, Inst @"l" l, Inst @"r" r)
+                                                                                               ?? feb `at` (Inst @"f" r, Inst @"bs" bs, Inst @"i" n)
+                                                                                               ?? ih  `at` (Inst @"f" r, Inst @"bs" bs)
+                                                                                               =: sTrue
+                                                                                               =: qed
+                                                                                            ]
+                                                                                , sNot (isAssigned n bs) ==>
+                                                                                      let resL = falsify' l (assumeTrue n bs)
+                                                                                      in cases [ sfalsified resL ==>
+                                                                                                     sNot (eval f (scex (falsify' f bs)))
+                                                                                                  ?? ibs `at` (Inst @"c" c, Inst @"l" l, Inst @"r" r)
+                                                                                                  ?? ias `at` (Inst @"n" n, Inst @"v" sTrue, Inst @"bs" bs)
+                                                                                                  ?? lus `at` (Inst @"n" n, Inst @"v" sTrue, Inst @"bs" bs)
+                                                                                                  ?? feb `at` (Inst @"f" l, Inst @"bs" (assumeTrue n bs), Inst @"i" n)
+                                                                                                  ?? ih  `at` (Inst @"f" l, Inst @"bs" (assumeTrue n bs))
+                                                                                                  =: sTrue
+                                                                                                  =: qed
+                                                                                               , sNot (sfalsified resL) ==>
+                                                                                                     sNot (eval f (scex (falsify' f bs)))
+                                                                                                  ?? ibs `at` (Inst @"c" c, Inst @"l" l, Inst @"r" r)
+                                                                                                  ?? ias `at` (Inst @"n" n, Inst @"v" sFalse, Inst @"bs" bs)
+                                                                                                  ?? lus `at` (Inst @"n" n, Inst @"v" sFalse, Inst @"bs" bs)
+                                                                                                  ?? feb `at` (Inst @"f" r, Inst @"bs" (assumeFalse n bs), Inst @"i" n)
+                                                                                                  ?? ih  `at` (Inst @"f" r, Inst @"bs" (assumeFalse n bs))
+                                                                                                  =: sTrue
+                                                                                                  =: qed
+                                                                                               ]
+                                                                                ]
+                                                      , isIf     c ==> sNot (eval f (scex (falsify' f bs)))
+                                                                    =: sTrue  -- Contradicts isNormal
+                                                                    =: qed
+                                                      ]
+                            ]
+
+-- | Helper lemma for completeness: If a formula is not a tautology,
+-- evaluating its normalization with falsify's bindings gives false.
+--
+-- >>> runTPWith cvc5 completenessHelper
+-- Lemma: falsifyFalsifies                             Q.E.D.
+-- Lemma: nonTautIsFalsified                           Q.E.D.
+-- Lemma: normalizeCorrect                             Q.E.D.
+-- Lemma: completenessHelper                           Q.E.D.
+-- Functions proven terminating:
+--   eval, falsify', ifComplexity, ifDepth, isAssigned, isNormal, isTautology', lookUp, normalize
+-- [Proven] completenessHelper :: Ɐf ∷ Formula → Bool
+completenessHelper :: TP (Proof (Forall "f" Formula -> SBool))
+completenessHelper = do
+  ff  <- recall falsifyFalsifies
+  nti <- recall nonTautIsFalsified
+  nc  <- recallWith z3 normalizeCorrect
+
+  lemma "completenessHelper"
+        (\(Forall f) -> sNot (isTautology f) .=> sNot (eval (normalize f) (scex (falsify f))))
+        [proofOf ff, proofOf nti, proofOf nc]
+
+-- * Main completeness theorem
+
+-- | \(\lnot\mathit{isTautology}(f) \implies \lnot\mathit{eval}(f, \mathit{falsify}(f).\mathit{bindings})\)
+--
+-- If the tautology checker says a formula is not a tautology, then there exists
+-- a binding environment (provided by falsify) under which it evaluates to false.
+-- This is the completeness theorem.
+--
+-- >>> runTPWith cvc5 completeness
+-- Lemma: completenessHelper                           Q.E.D.
+-- Lemma: normalizeRespectsTruth                       Q.E.D.
+-- Lemma: completeness                                 Q.E.D.
+-- Functions proven terminating:
+--   eval, falsify', ifComplexity, ifDepth, isAssigned, isNormal, isTautology', lookUp, normalize
+-- [Proven] completeness :: Ɐf ∷ Formula → Bool
+completeness :: TP (Proof (Forall "f" Formula -> SBool))
+completeness = do
+  ch  <- recall completenessHelper
+  nrt <- recallWith z3 normalizeRespectsTruth
+
+  lemma "completeness"
+        (\(Forall f) -> sNot (isTautology f) .=> sNot (eval f (scex (falsify f))))
+        [proofOf ch, proofOf nrt]
diff --git a/Documentation/SBV/Examples/TP/Tree.hs b/Documentation/SBV/Examples/TP/Tree.hs
new file mode 100644
--- /dev/null
+++ b/Documentation/SBV/Examples/TP/Tree.hs
@@ -0,0 +1,283 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Documentation.SBV.Examples.TP.Tree
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Proofs about binary tree mirroring, in-order traversal (flattening), and
+-- tree sizes.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE CPP                 #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE FlexibleInstances   #-}
+{-# LANGUAGE OverloadedLists     #-}
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Documentation.SBV.Examples.TP.Tree where
+
+import Prelude hiding (length, head, tail, null, reverse, (++))
+
+import Data.SBV
+import Data.SBV.List
+import Data.SBV.TP
+
+import qualified Documentation.SBV.Examples.TP.Lists as TP
+
+import Data.Proxy (Proxy(..))
+
+#ifdef DOCTEST
+-- $setup
+-- >>> :set -XTypeApplications
+-- >>> import Data.SBV
+-- >>> import Data.SBV.TP
+#endif
+
+-- * Binary tree definition
+
+-- | A classic parametric binary tree data type.
+data Tree a = Leaf
+            | Node (Tree a) a (Tree a)
+            deriving (Show, Eq)
+
+-- | Generate symbolic counterpart 'STree'.
+mkSymbolic [''Tree]
+
+-- * Tree operations
+
+-- | Mirror a tree by recursively swapping its left and right subtrees.
+--
+-- >>> mirror $ literal $ Node (Node Leaf (1::Integer) Leaf) 2 Leaf
+-- Node Leaf 2 (Node Leaf 1 Leaf) :: Tree Integer
+mirror :: SymVal a => STree a -> STree a
+mirror = smtFunction "mirror"
+       $ \t -> [sCase| t of
+                   Leaf       -> sLeaf
+                   Node l x r -> sNode (mirror r) x (mirror l)
+               |]
+
+-- | Flatten a tree into a list via in-order traversal.
+--
+-- >>> flatten (sNode (sNode sLeaf (1 :: SInteger) sLeaf) 2 (sNode sLeaf 3 sLeaf))
+-- [1,2,3] :: [SInteger]
+flatten :: SymVal a => STree a -> SList a
+flatten = smtFunction "flatten"
+        $ \t -> [sCase| t of
+                    Leaf       -> []
+                    Node l x r -> flatten l ++ [x] ++ flatten r
+                |]
+
+-- | Calculate the number of internal nodes in a tree.
+--
+-- >>> treeSize (sNode (sNode sLeaf (1 :: SInteger) sLeaf) 2 sLeaf)
+-- 2 :: SInteger
+treeSize :: SymVal a => STree a -> SInteger
+treeSize = smtFunction "treeSize"
+         $ \t -> [sCase| t of
+                     Leaf       -> 0
+                     Node l _ r -> 1 + treeSize l + treeSize r
+                 |]
+
+-- | The size is always non-negative.
+--
+-- >>> runTP $ treeSizePos @Integer
+-- Lemma: treeSizePos @Integer    Q.E.D.
+-- Functions proven terminating: treeSize
+-- [Proven] treeSizePos @Integer :: Ɐt ∷ (Tree Integer) → Bool
+treeSizePos :: forall a. SymVal a => TP (Proof (Forall "t" (Tree a) -> SBool))
+treeSizePos = inductiveLemma (atProxy (Proxy @a) "treeSizePos") (\(Forall t) -> treeSize t .>= 0) []
+
+-- | Both subtrees of a node are strictly smaller than the node itself. This is the
+-- lemma that lets us discharge the guard on the induction hypothesis in the strong
+-- induction proofs below.
+--
+-- @treeSize l < treeSize (Node l x r) && treeSize r < treeSize (Node l x r)@
+--
+-- >>> runTP $ treeSizeSmaller @Integer
+-- Lemma: treeSizePos @Integer        Q.E.D.
+-- Lemma: treeSizeSmaller @Integer
+--   Step: 1                          Q.E.D.
+--   Result:                          Q.E.D.
+-- Functions proven terminating: treeSize
+-- [Proven] treeSizeSmaller @Integer :: Ɐl ∷ (Tree Integer) → Ɐx ∷ Integer → Ɐr ∷ (Tree Integer) → Bool
+treeSizeSmaller :: forall a. SymVal a => TP (Proof (Forall "l" (Tree a) -> Forall "x" a -> Forall "r" (Tree a) -> SBool))
+treeSizeSmaller = do
+  tsp <- recall $ treeSizePos @a
+
+  calc (atProxy (Proxy @a) "treeSizeSmaller")
+       (\(Forall l) (Forall x) (Forall r) ->
+           let n = treeSize (sNode l x r)
+           in treeSize l .< n .&& treeSize r .< n) $
+       \l x r -> let n = treeSize (sNode l x r)
+                 in [] |- treeSize l .< n .&& treeSize r .< n
+                        ?? tsp `at` Inst @"t" l
+                        ?? tsp `at` Inst @"t" r
+                        =: sTrue
+                        =: qed
+
+-- * Correctness proofs
+
+-- | Proves that mirroring a tree twice yields the original tree:
+--
+-- @mirror (mirror t) == t@
+--
+-- >>> runTP $ mirrorInvolution @Integer
+-- Lemma: treeSizePos @Integer                            Q.E.D.
+-- Lemma: treeSizeSmaller @Integer                        Q.E.D.
+-- Inductive lemma (strong): mirrorInvolution @Integer
+--   Step: Measure is non-negative                        Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1.1                                        Q.E.D.
+--     Step: 1.1.2                                        Q.E.D.
+--     Step: 1.2.1                                        Q.E.D.
+--     Step: 1.2.2                                        Q.E.D.
+--     Step: 1.2.3                                        Q.E.D.
+--     Step: 1.2.4                                        Q.E.D.
+--     Step: 1.Completeness                               Q.E.D.
+--   Result:                                              Q.E.D.
+-- Functions proven terminating: mirror, treeSize
+-- [Proven] mirrorInvolution @Integer :: Ɐt ∷ (Tree Integer) → Bool
+mirrorInvolution :: forall a. SymVal a => TP (Proof (Forall "t" (Tree a) -> SBool))
+mirrorInvolution = do
+  tsp <- recall $ treeSizePos     @a
+  tss <- recall $ treeSizeSmaller @a
+
+  sInduct (atProxy (Proxy @a) "mirrorInvolution")
+          (\(Forall @"t" t) -> mirror (mirror t) .== t)
+          (treeSize, [proofOf tsp]) $
+          \ih t -> [] |- [pCase| t of
+                            Leaf       -> mirror (mirror sLeaf)
+                                       =: mirror sLeaf
+                                       =: sLeaf
+                                       =: qed
+                            Node l x r -> mirror (mirror (sNode l x r))
+                                       =: mirror (sNode (mirror r) x (mirror l))
+                                       =: sNode (mirror (mirror l)) x (mirror (mirror r))
+                                       ?? tss `at` (Inst @"l" l, Inst @"x" x, Inst @"r" r)
+                                       ?? ih  `at` Inst @"t" l
+                                       =: sNode l x (mirror (mirror r))
+                                       ?? tss `at` (Inst @"l" l, Inst @"x" x, Inst @"r" r)
+                                       ?? ih  `at` Inst @"t" r
+                                       =: sNode l x r
+                                       =: qed
+                         |]
+
+-- | Proves that mirroring a tree preserves its size:
+--
+-- @treeSize (mirror t) == treeSize t@
+--
+-- >>> runTP $ sizeMirror @Integer
+-- Lemma: treeSizePos @Integer                      Q.E.D.
+-- Lemma: treeSizeSmaller @Integer                  Q.E.D.
+-- Inductive lemma (strong): sizeMirror @Integer
+--   Step: Measure is non-negative                  Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1                                    Q.E.D.
+--     Step: 1.2.1                                  Q.E.D.
+--     Step: 1.2.2                                  Q.E.D.
+--     Step: 1.2.3                                  Q.E.D.
+--     Step: 1.2.4                                  Q.E.D.
+--     Step: 1.2.5                                  Q.E.D.
+--     Step: 1.Completeness                         Q.E.D.
+--   Result:                                        Q.E.D.
+-- Functions proven terminating: mirror, treeSize
+-- [Proven] sizeMirror @Integer :: Ɐt ∷ (Tree Integer) → Bool
+sizeMirror :: forall a. SymVal a => TP (Proof (Forall "t" (Tree a) -> SBool))
+sizeMirror = do
+  tsp <- recall $ treeSizePos     @a
+  tss <- recall $ treeSizeSmaller @a
+
+  sInduct (atProxy (Proxy @a) "sizeMirror")
+          (\(Forall @"t" t) -> treeSize (mirror t) .== treeSize t)
+          (treeSize, [proofOf tsp]) $
+          \ih t -> [] |- [pCase| t of
+                            Leaf       -> treeSize (mirror (sLeaf :: STree a))
+                                       =: treeSize (sLeaf :: STree a)
+                                       =: qed
+                            Node l x r -> treeSize (mirror (sNode l x r))
+                                       =: treeSize (sNode (mirror r) x (mirror l))
+                                       =: 1 + treeSize (mirror r) + treeSize (mirror l)
+                                       ?? tss `at` (Inst @"l" l, Inst @"x" x, Inst @"r" r)
+                                       ?? ih  `at` Inst @"t" r
+                                       =: 1 + treeSize r + treeSize (mirror l)
+                                       ?? tss `at` (Inst @"l" l, Inst @"x" x, Inst @"r" r)
+                                       ?? ih  `at` Inst @"t" l
+                                       =: 1 + treeSize r + treeSize l
+                                       =: treeSize (sNode l x r)
+                                       =: qed
+                         |]
+
+-- | Proves that in-order traversal of a mirrored tree is equal to the reverse
+-- of the in-order traversal of the original tree:
+--
+-- @flatten (mirror t) == reverse (flatten t)@
+--
+-- >>> runTP $ flattenMirror @Integer
+-- Lemma: treeSizePos @Integer                         Q.E.D.
+-- Lemma: treeSizeSmaller @Integer                     Q.E.D.
+-- Lemma: revApp                                       Q.E.D.
+-- Lemma: appendAssoc                                  Q.E.D.
+-- Inductive lemma (strong): flattenMirror @Integer
+--   Step: Measure is non-negative                     Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1.1                                     Q.E.D.
+--     Step: 1.1.2                                     Q.E.D.
+--     Step: 1.1.3                                     Q.E.D.
+--     Step: 1.1.4                                     Q.E.D.
+--     Step: 1.2.1                                     Q.E.D.
+--     Step: 1.2.2                                     Q.E.D.
+--     Step: 1.2.3                                     Q.E.D.
+--     Step: 1.2.4                                     Q.E.D.
+--     Step: 1.2.5                                     Q.E.D.
+--     Step: 1.2.6                                     Q.E.D.
+--     Step: 1.2.7                                     Q.E.D.
+--     Step: 1.2.8                                     Q.E.D.
+--     Step: 1.Completeness                            Q.E.D.
+--   Result:                                           Q.E.D.
+-- Functions proven terminating: flatten, mirror, sbv.reverse, treeSize
+-- [Proven] flattenMirror @Integer :: Ɐt ∷ (Tree Integer) → Bool
+flattenMirror :: forall a. SymVal a => TP (Proof (Forall "t" (Tree a) -> SBool))
+flattenMirror = do
+  tsp <- recall $ treeSizePos     @a
+  tss <- recall $ treeSizeSmaller @a
+
+  -- Quietly import a couple of list helpers from "Documentation.SBV.Examples.TP.Lists"
+  revApp <- recall $ TP.revApp      @a
+  aAssoc <- recall $ TP.appendAssoc @a
+
+  sInduct (atProxy (Proxy @a) "flattenMirror")
+          (\(Forall @"t" t) -> flatten (mirror t) .== reverse (flatten t))
+          (treeSize, [proofOf tsp]) $
+          \ih t -> [] |- [pCase| t of
+                            Leaf       -> flatten (mirror sLeaf)
+                                       =: flatten sLeaf
+                                       =: ([] :: SList a)
+                                       =: reverse []
+                                       =: reverse (flatten sLeaf)
+                                       =: qed
+                            Node l x r -> flatten (mirror (sNode l x r))
+                                       =: flatten (sNode (mirror r) x (mirror l))
+                                       =: flatten (mirror r) ++ [x] ++ flatten (mirror l)
+                                       ?? tss `at` (Inst @"l" l, Inst @"x" x, Inst @"r" r)
+                                       ?? ih  `at` Inst @"t" r
+                                       =: reverse (flatten r) ++ [x] ++ flatten (mirror l)
+                                       ?? tss `at` (Inst @"l" l, Inst @"x" x, Inst @"r" r)
+                                       ?? ih  `at` Inst @"t" l
+                                       =: reverse (flatten r) ++ [x] ++ reverse (flatten l)
+                                       ?? aAssoc `at` (Inst @"xs" (reverse (flatten r)), Inst @"ys" [x], Inst @"zs" (reverse (flatten l)))
+                                       =: (reverse (flatten r) ++ [x]) ++ reverse (flatten l)
+                                       ?? revApp `at` (Inst @"xs" [x], Inst @"ys" (flatten r))
+                                       =: reverse ([x] ++ flatten r) ++ reverse (flatten l)
+                                       ?? revApp `at` (Inst @"xs" (flatten l), Inst @"ys" ([x] ++ flatten r))
+                                       =: reverse (flatten l ++ [x] ++ flatten r)
+                                       =: reverse (flatten (sNode l x r))
+                                       =: qed
+                         |]
diff --git a/Documentation/SBV/Examples/TP/UpDown.hs b/Documentation/SBV/Examples/TP/UpDown.hs
new file mode 100644
--- /dev/null
+++ b/Documentation/SBV/Examples/TP/UpDown.hs
@@ -0,0 +1,114 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Documentation.SBV.Examples.TP.UpDown
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Proves @reverse (down n) = up n@.
+--
+-- This problem is motivated by an ACL2 midterm exam question, from Fall 2011.
+-- See: <https://www.cs.utexas.edu/~moore/classes/cs389r/midterm-answers.lisp>.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE CPP              #-}
+{-# LANGUAGE DataKinds        #-}
+{-# LANGUAGE OverloadedLists  #-}
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE TypeAbstractions #-}
+{-# LANGUAGE TypeApplications #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Documentation.SBV.Examples.TP.UpDown where
+
+import Prelude hiding (reverse, (++))
+
+import Data.SBV
+import Data.SBV.TP
+import Data.SBV.List
+
+import Documentation.SBV.Examples.TP.Lists
+import Documentation.SBV.Examples.TP.Peano
+
+#ifdef DOCTEST
+-- $setup
+-- >>> import Data.SBV.TP
+#endif
+
+-- | Construct a list of size @n@, containing numbers @1@ to @n@.
+--
+-- >>> up 0
+-- [] :: [SInteger]
+-- >>> up 5
+-- [1,2,3,4,5] :: [SInteger]
+up :: SNat -> SList Integer
+up n = upAcc n []
+
+-- | Keep consing the first argument on to the accumulator, until we hit zero. After that, return the second argument.
+-- Normally, we'd define this as a local function, but the definition needs to be visible for the proofs.
+upAcc :: SNat -> SList Integer -> SList Integer
+upAcc = smtFunction "up"
+      $ \n lst -> [sCase| n of
+                     Zero   -> lst
+                     Succ p -> upAcc p (n2i n .: lst)
+                  |]
+
+-- | Construct a list of size @n@, containing numbers @n-1@ down to @0@.
+--
+-- >>> down 0
+-- [] :: [SInteger]
+-- >>> down 5
+-- [5,4,3,2,1] :: [SInteger]
+down :: SNat -> SList Integer
+down = smtFunction "down"
+     $ \n -> [sCase| n of
+                Zero   -> []
+                Succ p -> n2i n .: down p
+             |]
+
+-- | Prove that @reverse (down n)@ is the same as @up n@
+--
+-- >>> runTP upDown
+-- Lemma: n2iNonNeg                       Q.E.D.
+-- Lemma: revCons                         Q.E.D.
+-- Inductive lemma (strong): upDownGen
+--   Step: Measure is non-negative        Q.E.D.
+--   Step: 1 (2 way case split)
+--     Step: 1.1                          Q.E.D.
+--     Step: 1.2.1                        Q.E.D.
+--     Step: 1.2.2                        Q.E.D.
+--     Step: 1.2.3                        Q.E.D.
+--     Step: 1.2.4                        Q.E.D.
+--     Step: 1.Completeness               Q.E.D.
+--   Result:                              Q.E.D.
+-- Lemma: upDown                          Q.E.D.
+-- Functions proven terminating: down, n2i, sbv.reverse, up
+-- [Proven] upDown :: Ɐn ∷ Nat → Bool
+upDown :: TP (Proof (Forall "n" Nat -> SBool))
+upDown = do
+   n2inn <- recall n2iNonNeg
+   rc    <- recall (revCons @Integer)
+
+   -- We first generalize the theorem, to make it inductive
+   upDownGen <- sInduct "upDownGen"
+           (\(Forall @"n" n) (Forall @"xs" xs) -> reverse (down n) ++ xs .== upAcc n xs)
+           (\n _ -> n2i n, [proofOf n2inn]) $
+           \ih n xs -> [] |- cases [ isZero n ==> trivial
+                                   , isSucc n ==> let p = getSucc_1 n
+                                               in reverse (down (sSucc p)) ++ xs
+                                               =: reverse (n2i n .: down p) ++ xs
+                                               ?? rc
+                                               =: reverse (down p) ++ (n2i n .: xs)
+                                               ?? ih `at` (Inst @"n" p, Inst @"xs" (n2i n .: xs))
+                                               =: upAcc p (n2i n .: xs)
+                                               =: upAcc n xs
+                                               =: qed
+                                   ]
+
+   -- The theorem we want to prove follows by instantiating the list at empty, and
+   -- the SMT solver can figure it out by itself
+   lemma "upDown"
+         (\(Forall n) -> reverse (down n) .== up n)
+         [proofOf upDownGen]
diff --git a/Documentation/SBV/Examples/TP/VM.hs b/Documentation/SBV/Examples/TP/VM.hs
new file mode 100644
--- /dev/null
+++ b/Documentation/SBV/Examples/TP/VM.hs
@@ -0,0 +1,448 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Documentation.SBV.Examples.TP.VM
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Correctness of a simple interpreter vs virtual-machine interpretation of a language.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE CPP                 #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE FlexibleContexts    #-}
+{-# LANGUAGE FlexibleInstances   #-}
+{-# LANGUAGE OverloadedLists     #-}
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Documentation.SBV.Examples.TP.VM
+#ifndef DOCTEST
+ (   -- * Language
+     Expr(..), SExpr, size
+
+
+     -- * Symbolic accessors
+   , sCaseExpr
+   , isVar, sVar, getVar_1,                     svar
+   , isCon, sCon, getCon_1,                     scon
+   , isSqr, sSqr, getSqr_1,                     ssqrVal
+   , isInc, sInc, getInc_1,                     sincVal
+   , isAdd, sAdd, getAdd_1, getAdd_2,           sadd1, sadd2
+   , isMul, sMul, getMul_1, getMul_2,           smul1, smul2
+   , isLet, sLet, getLet_1, getLet_2, getLet_3, slvar, slval, slbody
+
+     -- * Environment and the stack
+   , Env, Stack
+
+     -- * Interpretation
+   , interpInEnv, interp
+
+     -- * Virtual machine
+   , Instr(..), SInstr
+
+     -- * Compilation
+   , compile, compileAndRun
+
+     -- * Correctness of the compiler
+   , correctness)
+#endif
+where
+
+import Data.SBV
+import Data.SBV.Tuple as ST
+import Data.SBV.List  as SL
+
+import Data.SBV.TP
+
+#ifdef DOCTEST
+-- $setup
+-- >>> import Data.SBV.TP
+-- >>> :set -XTypeApplications
+#endif
+
+-- * Language
+
+-- | Basic expression language.
+data Expr nm val = Var {var    :: nm                                            } -- ^ Variables
+                 | Con {con    :: val                                           } -- ^ Constants
+                 | Sqr {sqrVal :: Expr nm val                                   } -- ^ Squaring
+                 | Inc {incVal :: Expr nm val                                   } -- ^ Increment
+                 | Add {add1   :: Expr nm val, add2 :: Expr nm val              } -- ^ Addition
+                 | Mul {mul1   :: Expr nm val, mul2 :: Expr nm val              } -- ^ Addition
+                 | Let {lvar   :: nm, lval ::  Expr nm val, lbody :: Expr nm val} -- ^ Let expression
+
+-- | Create symbolic version of expressions
+mkSymbolic [''Expr]
+
+-- | Size of an expression. Used in strong induction.
+size :: (SymVal nm, SymVal val) => SExpr nm val -> SInteger
+size = smtFunction "exprSize"
+     $ \expr -> [sCase| expr of
+                   Var _     -> 0
+                   Con _     -> 0
+                   Sqr a     -> 1 + size a
+                   Inc a     -> 1 + size a
+                   Add a b   -> 1 + size a `smax` size b
+                   Mul a b   -> 1 + size a `smax` size b
+                   Let _ a b -> 1 + size a `smax` size b
+                |]
+
+-- | Environment, binding names to values
+type Env nm val = SList (nm, val)
+
+-- * Functional interpretation
+
+-- | Interpreter, in the usual functional style, taking an arbitrary environment.
+interpInEnv :: (SymVal nm, SymVal val, Num (SBV val)) => Env nm val -> SExpr nm val -> SBV val
+interpInEnv = smtFunction "interpInEnv"
+            $ \env expr ->
+                 [sCase| expr of
+                    Var nm    -> nm `SL.lookup` env
+                    Con v     -> v
+                    Sqr a     -> let av = interpInEnv env a in av * av
+                    Inc a     -> let av = interpInEnv env a in av + 1
+                    Add a b   -> let av = interpInEnv env a; bv = interpInEnv env b in av + bv
+                    Mul a b   -> let av = interpInEnv env a; bv = interpInEnv env b in av * bv
+                    Let v a b -> let av = interpInEnv env a in interpInEnv (tuple (v, av) .: env) b
+                 |]
+
+-- | Interpret starting from empty environment.
+interp :: (SymVal nm, SymVal val, Num (SBV val)) => SExpr nm val -> SBV val
+interp = interpInEnv []
+
+-- * Virtual machine
+
+-- | Instructions
+data Instr nm val = IPushN { ivar :: nm  } -- ^ Push the value of nm from the environment on to the stack
+                  | IPushV { ival :: val } -- ^ Push a value on to the stack
+                  | IDup                   -- ^ Duplicate the top of the stack
+                  | IAdd                   -- ^ Add      the top two elements and push back
+                  | IMul                   -- ^ Multiply the top two elements and push back
+                  | IBind nm               -- ^ Bind the value on top of stack to name
+                  | IForget                -- ^ Pop and ignore the binding on the environment
+
+-- | Create symbolic version of instructions
+mkSymbolic [''Instr]
+
+-- | Stack of values.
+type Stack val = SList val
+
+-- | Pushing on to the stack.
+push :: SymVal val => SBV val -> Stack val  -> Stack val
+push = (SL..:)
+
+-- | Top of the stack. If the stack is empty, the result is underspecified.
+top :: SymVal val => Stack val  -> SBV val
+top = SL.head
+
+-- | Popping from the stack. If the stack is empty, the result is underspecified.
+pop :: SymVal val => Stack val  -> Stack val
+pop = SL.tail
+
+-- | A pair containing an environment and a stack
+type EnvStack nm val = SBV ([(nm, val)], [val])
+
+-- | Executing a single instruction in a given environment and the instruction stack.
+-- We produce the new environment, and the new stack.
+execute :: (SymVal nm, SymVal val, Num (SBV val)) => EnvStack nm val -> SInstr nm val -> EnvStack nm val
+execute envStk instr = let (env, stk) = untuple envStk
+                       in tuple [sCase| instr of
+                                   IPushN nm   -> (env, push (nm `SL.lookup` env) stk)
+                                   IPushV v    -> (env, push v stk)
+                                   IDup        -> (env, push (top stk) stk)
+                                   IAdd        -> (env, let a = top stk; b = top (pop stk) in push (a + b) (pop (pop stk)))
+                                   IMul        -> (env, let a = top stk; b = top (pop stk) in push (a * b) (pop (pop stk)))
+                                   IBind nm    -> (push (tuple (nm, top stk)) env, pop stk)
+                                   IForget     -> (pop env, stk)
+                                |]
+
+-- | Execute a sequence of instructions, in a given stack and env. Returnsg the final environment and the stack. This is a
+-- simple fold-left.
+run :: (SymVal nm, SymVal val, Num (SBV val)) => EnvStack nm val -> SList (Instr nm val) -> EnvStack nm val
+run = SL.foldl execute
+
+-- * Compiler
+
+-- | Convert an expression to a sequence of instructions for our virtual machine.
+compile :: (SymVal nm, SymVal val, Num (SBV val)) => SExpr nm val -> SList (Instr nm val)
+compile = smtFunction "compile"
+        $ \expr -> [sCase| expr of
+                      Var nm    -> [sIPushN nm]
+                      Con v     -> [sIPushV v]
+                      Sqr a     -> compile a SL.++ [sIDup,     sIMul]
+                      Inc a     -> compile a SL.++ [sIPushV 1, sIAdd]
+                      Add a b   -> compile a SL.++ compile b  SL.++ [sIAdd]
+                      Mul a b   -> compile a SL.++ compile b  SL.++ [sIMul]
+                      Let v a b -> compile a SL.++ [sIBind v] SL.++ compile b SL.++ [sIForget]
+                   |]
+
+-- | Compile and run an expression.
+compileAndRun :: (SymVal nm, SymVal val, Num (SBV val)) => SExpr nm val -> SBV val
+compileAndRun = top . ST.snd . run (tuple ([], [])) . compile
+
+-- * Correctness
+
+-- | The property we're after is that interpreting an expression is the same as
+-- first compiling it to virtual-machine instructions, and then running them.
+--
+-- >>> runTP (correctness @String @Integer)
+-- Inductive lemma: runSeq
+--   Step: Base                        Q.E.D.
+--   Step: 1                           Q.E.D.
+--   Step: 2                           Q.E.D.
+--   Step: 3                           Q.E.D.
+--   Result:                           Q.E.D.
+-- Lemma: runOne                       Q.E.D.
+-- Lemma: runTwo
+--   Step: 1                           Q.E.D.
+--   Step: 2                           Q.E.D.
+--   Result:                           Q.E.D.
+-- Lemma: runMul                       Q.E.D.
+-- Lemma: measureNonNeg                Q.E.D.
+-- Inductive lemma (strong): helper
+--   Step: Measure is non-negative     Q.E.D.
+--   Step: 1 (7 way case split)
+--     Step: 1.1.1 (case Var)          Q.E.D.
+--     Step: 1.1.2                     Q.E.D.
+--     Step: 1.2.1 (case Con)          Q.E.D.
+--     Step: 1.2.2                     Q.E.D.
+--     Step: 1.2.3                     Q.E.D.
+--     Step: 1.3.1 (case Sqr)          Q.E.D.
+--     Step: 1.3.2                     Q.E.D.
+--     Step: 1.3.3                     Q.E.D.
+--     Step: 1.3.4                     Q.E.D.
+--     Step: 1.3.5                     Q.E.D.
+--     Step: 1.3.6                     Q.E.D.
+--     Step: 1.3.7                     Q.E.D.
+--     Step: 1.4.1 (case Inc)          Q.E.D.
+--     Step: 1.4.2                     Q.E.D.
+--     Step: 1.4.3                     Q.E.D.
+--     Step: 1.4.4                     Q.E.D.
+--     Step: 1.4.5                     Q.E.D.
+--     Step: 1.4.6                     Q.E.D.
+--     Step: 1.4.7                     Q.E.D.
+--     Step: 1.5.1 (case sAdd)         Q.E.D.
+--     Step: 1.5.2                     Q.E.D.
+--     Step: 1.5.3                     Q.E.D.
+--     Step: 1.5.4                     Q.E.D.
+--     Step: 1.5.5                     Q.E.D.
+--     Step: 1.5.6                     Q.E.D.
+--     Step: 1.5.7                     Q.E.D.
+--     Step: 1.5.8                     Q.E.D.
+--     Step: 1.5.9                     Q.E.D.
+--     Step: 1.6.1 (case sMul)         Q.E.D.
+--     Step: 1.6.2                     Q.E.D.
+--     Step: 1.6.3                     Q.E.D.
+--     Step: 1.6.4                     Q.E.D.
+--     Step: 1.6.5                     Q.E.D.
+--     Step: 1.6.6                     Q.E.D.
+--     Step: 1.6.7                     Q.E.D.
+--     Step: 1.6.8                     Q.E.D.
+--     Step: 1.6.9                     Q.E.D.
+--     Step: 1.7.1 (case Let)          Q.E.D.
+--     Step: 1.7.2                     Q.E.D.
+--     Step: 1.7.3                     Q.E.D.
+--     Step: 1.7.4                     Q.E.D.
+--     Step: 1.7.5                     Q.E.D.
+--     Step: 1.7.6                     Q.E.D.
+--     Step: 1.7.7                     Q.E.D.
+--     Step: 1.7.8                     Q.E.D.
+--     Step: 1.7.9                     Q.E.D.
+--     Step: 1.7.10                    Q.E.D.
+--     Step: 1.7.11                    Q.E.D.
+--     Step: 1.Completeness            Q.E.D.
+--   Result:                           Q.E.D.
+-- Lemma: correctness
+--   Step: 1                           Q.E.D.
+--   Step: 2                           Q.E.D.
+--   Step: 3                           Q.E.D.
+--   Step: 4                           Q.E.D.
+--   Result:                           Q.E.D.
+-- Functions proven terminating: compile, exprSize, interpInEnv, sbv.foldl, sbv.lookup
+-- [Proven] correctness :: Ɐexpr ∷ (Expr String Integer) → Bool
+correctness :: forall nm val. (SymVal nm, SymVal val, Num (SBV val)) => TP (Proof (Forall "expr" (Expr nm val) -> SBool))
+correctness = do
+
+   -- Running a sequence of instructions that are appended is equivalent to running them in sequence:
+   runSeq <- induct "runSeq"
+                    (\(Forall @"xs" xs) (Forall @"ys" ys) (Forall @"es" (es :: EnvStack nm val))
+                         -> run es (xs SL.++ ys) .== run (run es xs) ys) $
+                    \ih (x, xs) ys es -> [] |- run es ((x .: xs) SL.++ ys)
+                                            =: run es (x .: (xs SL.++ ys))
+                                            =: run (execute es x) (xs SL.++ ys)
+                                            ?? ih `at` (Inst @"ys" ys, Inst @"es" (execute es x))
+                                            =: run (run es (x .: xs)) ys
+                                            =: qed
+
+   -- The following few lemmas make the proof go thru faster, even though they're really easy to prove themselves.
+
+   -- Running one instruction is equal to just executing it
+   runOne <- lemma "runOne"
+                   (\(Forall @"es" (es :: EnvStack nm val)) (Forall @"i" i) -> run es [i] .== execute es i)
+                   []
+
+   -- Same for two
+   runTwo <- calc "runTwo"
+                   (\(Forall @"es" (es :: EnvStack nm val)) (Forall @"i" i) (Forall @"j" j)
+                             -> run es [i, j] .== execute (execute es i) j) $
+                   \es i j -> [] |- run es [i, j]
+                                 =: run (execute es i) [j]
+                                 =: execute (execute es i) j
+                                 =: qed
+
+   -- Provers struggle with multiplication, so help them a bit here even though this is really
+   -- a trivial proof. What's hard is the correct instantiation of it, so abstracting it away helps
+   -- us speed up the solver.
+   runMul <- lemma "runMul"
+                    (\(Forall @"a" a) (Forall @"b" b) (Forall  @"env" (env :: Env nm val)) (Forall @"stk" stk)
+                                 ->   execute (tuple (env, push a (push b stk))) sIMul
+                                 .==  tuple (env, push (a * b) stk))
+                   []
+
+   -- We will use the size of the expression as the measure. We need to show that it is
+   -- always positive for the inductive proof to go thru.
+   measureNonNeg <- inductiveLemma "measureNonNeg"
+                                   (\(Forall @"e" (e :: SExpr nm val)) -> size e .>= 0)
+                                   []
+
+   -- A more general version of the theorem, starting with an arbitrary env and stack.
+   -- We prove this using the induction principle for expressions.
+   helper <- sInductWith cvc5 "helper"
+               (\(Forall @"e" e) (Forall @"env" (env :: Env nm val)) (Forall @"stk" stk) ->
+                             run (tuple (env, stk)) (compile e)
+                         .== tuple (env, push (interpInEnv env e) stk))
+               (\e _ _  -> size e, [proofOf measureNonNeg]) $
+               \ih e env stk -> []
+                 |- [pCase| e of
+                      Var nm     -> run (tuple (env, stk)) (compile (sVar nm))
+                                 ?? "case Var"
+                                 =: run (tuple (env, stk)) [sIPushN nm]
+                                 =: tuple (env, push (interpInEnv env (sVar nm)) stk)
+                                 =: qed
+
+                      Con v      -> run (tuple (env, stk)) (compile (sCon v))
+                                 ?? "case Con"
+                                 =: run (tuple (env, stk)) [sIPushV v]
+                                 =: tuple (env, push v stk)
+                                 =: tuple (env, push (interpInEnv env (sCon v)) stk)
+                                 =: qed
+
+                      Sqr a      -> run (tuple (env, stk)) (compile (sSqr a))
+                                 ?? "case Sqr"
+                                 =: run (tuple (env, stk)) (compile a SL.++ [sIDup, sIMul])
+                                 ?? runSeq
+                                 =: run (run (tuple (env, stk)) (compile a)) [sIDup, sIMul]
+                                 ?? ih `at` (Inst @"e" a, Inst @"env" env, Inst @"stk" stk)
+                                 =: let stk' = push (interpInEnv env a) stk
+                                 in run (tuple (env, stk')) [sIDup, sIMul]
+                                 ?? runTwo `at` (Inst @"es" (tuple (env, stk')), Inst @"i" sIDup, Inst @"j" sIMul)
+                                 =: execute (execute (tuple (env, stk')) sIDup) sIMul
+                                 =: let stk'' = push (interpInEnv env a) stk'
+                                 in execute (tuple (env, stk'')) sIMul
+                                 =: tuple (env, push (interpInEnv env a * interpInEnv env a) stk)
+                                 =: tuple (env, push (interpInEnv env (sSqr a)) stk)
+                                 =: qed
+
+                      Inc a      -> run (tuple (env, stk)) (compile (sInc a))
+                                 ?? "case Inc"
+                                 =: run (tuple (env, stk)) (compile a SL.++ [sIPushV 1, sIAdd])
+                                 ?? runSeq
+                                 =: run (run (tuple (env, stk)) (compile a)) [sIPushV 1, sIAdd]
+                                 ?? ih `at` (Inst @"e" a, Inst @"env" env, Inst @"stk" stk)
+                                 =: let stk' = push (interpInEnv env a) stk
+                                 in run (tuple (env, stk')) [sIPushV 1, sIAdd]
+                                 ?? runTwo `at` (Inst @"es" (tuple (env, stk')), Inst @"i" (sIPushV 1), Inst @"j" sIAdd)
+                                 =: execute (execute (tuple (env, stk')) (sIPushV 1)) sIAdd
+                                 =: let stk'' = push 1 stk'
+                                 in execute (tuple (env, stk'')) sIAdd
+                                 =: tuple (env, push (1 + interpInEnv env a) stk)
+                                 =: tuple (env, push (interpInEnv env (sInc a)) stk)
+                                 =: qed
+
+                      Add a b    -> run (tuple (env, stk)) (compile (sAdd a b))
+                                 ?? "case sAdd"
+                                 =: run (tuple (env, stk)) (compile a SL.++ compile b SL.++ [sIAdd])
+                                 ?? runSeq
+                                 =: run (run (tuple (env, stk)) (compile a)) (compile b SL.++ [sIAdd])
+                                 ?? ih `at` (Inst @"e" a, Inst @"env" env, Inst @"stk" stk)
+                                 =: let stk' = push (interpInEnv env a) stk
+                                 in run (tuple (env, stk')) (compile b SL.++ [sIAdd])
+                                 ?? runSeq
+                                 =: run (run (tuple (env, stk')) (compile b)) [sIAdd]
+                                 ?? ih `at` (Inst @"e" b, Inst @"env" env, Inst @"stk" stk')
+                                 =: let stk'' = push (interpInEnv env b) stk'
+                                 in run (tuple (env, stk'')) [sIAdd]
+                                 ?? runOne `at` (Inst @"es" (tuple (env, stk'')), Inst @"i" sIAdd)
+                                 =: execute (tuple (env, stk'')) sIAdd
+                                 =: tuple (env, push (interpInEnv env b + interpInEnv env a) stk)
+                                 =: tuple (env, push (interpInEnv env a + interpInEnv env b) stk)
+                                 =: tuple (env, push (interpInEnv env (sAdd a b)) stk)
+                                 =: qed
+
+                      Mul a b    -> run (tuple (env, stk)) (compile (sMul a b))
+                                 ?? "case sMul"
+                                 =: run (tuple (env, stk)) (compile a SL.++ compile b SL.++ [sIMul])
+                                 ?? runSeq
+                                 =: run (run (tuple (env, stk)) (compile a)) (compile b SL.++ [sIMul])
+                                 ?? ih `at` (Inst @"e" a, Inst @"env" env, Inst @"stk" stk)
+                                 =: let stk' = push (interpInEnv env a) stk
+                                 in run (tuple (env, stk')) (compile b SL.++ [sIMul])
+                                 ?? runSeq
+                                 =: run (run (tuple (env, stk')) (compile b)) [sIMul]
+                                 ?? ih `at` (Inst @"e" b, Inst @"env" env, Inst @"stk" stk')
+                                 =: let stk'' = push (interpInEnv env b) stk'
+                                 in run (tuple (env, stk'')) [sIMul]
+                                 ?? runOne `at` (Inst @"es" (tuple (env, stk'')), Inst @"i" sIMul)
+                                 =: execute (tuple (env, stk'')) sIMul
+                                 ?? runMul `at` ( Inst @"a"   (interpInEnv env b)
+                                                , Inst @"b"   (interpInEnv env a)
+                                                , Inst @"env" env
+                                                , Inst @"stk" stk)
+                                 =: tuple (env, push (interpInEnv env b * interpInEnv env a) stk)
+                                 =: tuple (env, push (interpInEnv env a * interpInEnv env b) stk)
+                                 =: tuple (env, push (interpInEnv env (sMul a b)) stk)
+                                 =: qed
+
+                      Let nm a b -> run (tuple (env, stk)) (compile (sLet nm a b))
+                                 ?? "case Let"
+                                 =: run (tuple (env, stk)) (compile a SL.++ [sIBind nm] SL.++ compile b SL.++ [sIForget])
+                                 ?? runSeq
+                                 =: run (run (tuple (env, stk)) (compile a)) ([sIBind nm] SL.++ compile b SL.++ [sIForget])
+                                 ?? ih `at` (Inst @"e" a, Inst @"env" env, Inst @"stk" stk)
+                                 =: let stk' = push (interpInEnv env a) stk
+                                 in run (tuple (env, stk')) ([sIBind nm] SL.++ compile b SL.++ [sIForget])
+                                 ?? runSeq
+                                 =: run (run (tuple (env, stk')) [sIBind nm]) (compile b SL.++ [sIForget])
+                                 ?? runOne
+                                 =: run (execute (tuple (env, stk')) (sIBind nm)) (compile b SL.++ [sIForget])
+                                 =: let env' = push (tuple (nm, interpInEnv env a)) env
+                                 in run (tuple (env', stk)) (compile b SL.++ [sIForget])
+                                 ?? runSeq
+                                 =: run (run (tuple (env', stk)) (compile b)) [sIForget]
+                                 ?? ih `at` (Inst @"e" b, Inst @"env" env', Inst @"stk" stk)
+                                 =: let stk'' = push (interpInEnv env' b) stk
+                                 in run (tuple (env', stk'')) [sIForget]
+                                 ?? runOne
+                                 =: execute (tuple (env', stk'')) sIForget
+                                 =: tuple (env, stk'')
+                                 =: tuple (env, push (interpInEnv env (sLet nm a b)) stk)
+                                 =: qed
+                    |]
+
+   -- We can now prove the final correctness theorem, based on the helper.
+   calc "correctness"
+        (\(Forall @"expr" (e :: SExpr nm val)) -> compileAndRun e .== interp e) $
+        \(e :: SExpr nm val) -> [] |- compileAndRun e
+                                   =: top (ST.snd (run (tuple ([], [])) (compile e)))
+                                   ?? helper `at` (Inst @"e" e, Inst @"env" [], Inst @"stk" [])
+                                   =: top (ST.snd (tuple ([] :: Env nm val, push (interpInEnv [] e) [])))
+                                   =: interpInEnv [] e
+                                   =: interp e
+                                   =: qed
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
@@ -20,7 +20,6 @@
 -- named @x@ and @y@.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE CPP                        #-}
 {-# LANGUAGE DeriveFunctor              #-}
 {-# LANGUAGE GADTs                      #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
@@ -41,12 +40,8 @@
 import Data.SBV.Internals (SBV(SBV), unSBV)
 import Data.SBV.Trans.Control
 
--- Starting with base 4.16; Data.Bits exports And, which conflicts with the definition here
-#if MIN_VERSION_base(4,16,0)
+-- Data.Bits exports And, which conflicts with the definition here
 import Data.SBV.Trans hiding(And)
-#else
-import Data.SBV.Trans
-#endif
 
 -- * Allocation of symbolic variables, so we can extract a model later.
 
diff --git a/Documentation/SBV/Examples/Uninterpreted/AUF.hs b/Documentation/SBV/Examples/Uninterpreted/AUF.hs
--- a/Documentation/SBV/Examples/Uninterpreted/AUF.hs
+++ b/Documentation/SBV/Examples/Uninterpreted/AUF.hs
@@ -27,8 +27,7 @@
 -- The function @read@ and @write@ are usual array operations.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE CPP                 #-}
-{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE CPP #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
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
@@ -9,10 +9,7 @@
 -- Demonstrates uninterpreted sorts and how they can be used for deduction.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DeriveAnyClass     #-}
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE StandaloneDeriving #-}
-{-# LANGUAGE TemplateHaskell    #-}
+{-# LANGUAGE TemplateHaskell #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -33,7 +30,7 @@
 
 -- | Make this sort uninterpreted. This splice will automatically introduce
 -- the type 'SB' into the environment, as a synonym for 'SBV' 'B'.
-mkUninterpretedSort ''B
+mkSymbolic [''B]
 
 -----------------------------------------------------------------------------
 -- * Uninterpreted connectives over 'B'
@@ -67,8 +64,8 @@
                   p <- free "p"
                   q <- free "q"
                   r <- free "r"
-                  return $   not (p `or` (q `and` r))
-                         .== (not p `and` not q) `or` (not p `and` not r)
+                  pure $   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/Uninterpreted/EUFLogic.hs b/Documentation/SBV/Examples/Uninterpreted/EUFLogic.hs
new file mode 100644
--- /dev/null
+++ b/Documentation/SBV/Examples/Uninterpreted/EUFLogic.hs
@@ -0,0 +1,340 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Documentation.SBV.Examples.Uninterpreted.EUFLogic
+-- License   : BSD3
+-- Stability : experimental
+--
+-- Demonstrates the ability to generate uninterpreted functions of arbitrarily
+-- many arguments, whose types are generated programmatically. The high-level
+-- idea of this module is to provide a strongly-typed representation, using a
+-- GADT, of a logic that includes uninterpreted functions. This module then
+-- defines an interpretation of this logic into SBV, which it uses to perform
+-- SMT queries in the logic.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE CPP                  #-}
+{-# LANGUAGE DataKinds            #-}
+{-# LANGUAGE FlexibleContexts     #-}
+{-# LANGUAGE FlexibleInstances    #-}
+{-# LANGUAGE GADTs                #-}
+{-# LANGUAGE RankNTypes           #-}
+{-# LANGUAGE TypeFamilies         #-}
+{-# LANGUAGE TypeOperators        #-}
+{-# LANGUAGE UndecidableInstances #-}
+
+module Documentation.SBV.Examples.Uninterpreted.EUFLogic where
+
+import Data.SBV
+
+import Control.Monad.State
+
+import Data.Kind
+import Data.Type.Equality
+import Data.Map (Map)
+import qualified Data.Map as Map
+
+import GHC.TypeLits
+
+#ifdef DOCTEST
+-- $setup
+-- >>> import Data.SBV
+#endif
+
+----------------------------------------------------------------------
+-- * Types of the EUF Logic
+----------------------------------------------------------------------
+
+-- | The datakind for the types in our EUF logic.
+data EUFType = Tp_Bool | Tp_BV Natural
+
+-- | A singleton type for natural numbers that can be used as the widths of bitvectors.
+data BVWidth w = (KnownNat w, BVIsNonZero w) => BVWidth (SNat w)
+
+-- | Create a t'BVWidth' object for a 'KnownNat' that is non-zero
+knownBVWidth :: (KnownNat w, BVIsNonZero w) => BVWidth w
+knownBVWidth = BVWidth natSing
+
+-- | TestEquality instance for BVWidth.
+instance TestEquality BVWidth where
+  testEquality (BVWidth w1) (BVWidth w2) | Just Refl <- testEquality w1 w2 = Just Refl
+                                         | True                            = Nothing
+
+-- | A singleton type that represents type-level 'EUFType's at the object level
+data TypeRepr (tp :: EUFType) where
+  Repr_Bool :: TypeRepr Tp_Bool
+  Repr_BV   :: BVWidth w -> TypeRepr (Tp_BV w)
+
+-- | TestEquality instance for Type representations
+instance TestEquality TypeRepr where
+  testEquality Repr_Bool    Repr_Bool                                      = Just Refl
+  testEquality (Repr_BV w1) (Repr_BV w2) | Just Refl <- testEquality w1 w2 = Just Refl
+  testEquality _            _                                              = Nothing
+
+-- | A list of 'TypeRepr's for each type in a type-level list
+data TypeReprs tps where
+  Repr_Nil  :: TypeReprs '[]
+  Repr_Cons :: TypeRepr tp -> TypeReprs tps -> TypeReprs (tp ': tps)
+
+instance TestEquality TypeReprs where
+  testEquality Repr_Nil             Repr_Nil                                                    = Just Refl
+  testEquality (Repr_Cons tps1 tp1) (Repr_Cons tps2 tp2) | Just Refl <- testEquality tps1 tps2
+                                                         , Just Refl <- testEquality tp1  tp2   = Just Refl
+  testEquality _                    _                                                           = Nothing
+
+-- | An 'EUFType' with a known 'TypeRepr' representation
+class KnownEUFType tp where
+  knownEUFType :: TypeRepr tp
+
+-- | Mapping from Tp_Bool
+instance KnownEUFType Tp_Bool where
+  knownEUFType = Repr_Bool
+
+-- | Mapping from Tp_BV
+instance (KnownNat w, BVIsNonZero w) => KnownEUFType (Tp_BV w) where
+  knownEUFType = Repr_BV (BVWidth natSing)
+
+-- | A sequence of types t'EUFType' with a known 'TypeReprs' representation
+class KnownEUFTypes tps where
+  knownEUFTypes :: TypeReprs tps
+
+instance KnownEUFTypes '[] where
+  knownEUFTypes = Repr_Nil
+
+instance (KnownEUFType tp, KnownEUFTypes tps) => KnownEUFTypes (tp ': tps) where
+  knownEUFTypes = Repr_Cons knownEUFType knownEUFTypes
+
+----------------------------------------------------------------------
+-- * Operations of the EUF Logic
+----------------------------------------------------------------------
+
+-- | An uninterpreted function in our EUF logic, which is a string name plus the input and output types.
+data UnintOp (ins :: [EUFType]) (out :: EUFType) = UnintOp { unintOpName :: String
+                                                           , unintOpIns :: TypeReprs ins
+                                                           , unintOpOut :: TypeRepr  out
+                                                           }
+
+-- | The operations of our EUF logic, which are indexed by a list of 0 or more
+-- input types and a single output type.
+data Op (ins :: [EUFType]) (out :: EUFType) where
+  -- Uninterpreted functions
+  Op_Unint :: UnintOp ins out -> Op ins out
+
+  -- Boolean operations
+  Op_And        :: Op (Tp_Bool ': Tp_Bool ': '[]) Tp_Bool
+  Op_Or         :: Op (Tp_Bool ': Tp_Bool ': '[]) Tp_Bool
+  Op_Not        :: Op (Tp_Bool ': '[])            Tp_Bool
+  Op_BoolLit    :: Bool -> Op '[] Tp_Bool
+  Op_IfThenElse :: TypeRepr a -> Op (Tp_Bool ': a ': a ': '[]) a
+
+  -- Bitvector operations
+  Op_Plus   :: BVWidth w -> Op (Tp_BV w ': Tp_BV w ': '[]) (Tp_BV w)
+  Op_Minus  :: BVWidth w -> Op (Tp_BV w ': Tp_BV w ': '[]) (Tp_BV w)
+  Op_Times  :: BVWidth w -> Op (Tp_BV w ': Tp_BV w ': '[]) (Tp_BV w)
+
+  Op_Abs    :: BVWidth w -> Op (Tp_BV w ': '[]) (Tp_BV w)
+  Op_Signum :: BVWidth w -> Op (Tp_BV w ': '[]) (Tp_BV w)
+
+  Op_BVLit  :: BVWidth w -> Integer -> Op '[] (Tp_BV w)
+
+  Op_BVEq   :: BVWidth w -> Op (Tp_BV w ': Tp_BV w ': '[]) Tp_Bool
+  Op_BVLt   :: BVWidth w -> Op (Tp_BV w ': Tp_BV w ': '[]) Tp_Bool
+
+-- | Create an uninterpreted 'Op' of known type
+mkUnintOp :: (KnownEUFTypes ins, KnownEUFType out) => String -> Op ins out
+mkUnintOp nm = Op_Unint $ UnintOp nm knownEUFTypes knownEUFType
+
+-- | Get the input types and output type of an 'Op'
+opInsOut :: Op ins out -> (TypeReprs ins, TypeRepr out)
+opInsOut (Op_Unint uop)                      = (unintOpIns uop, unintOpOut uop)
+opInsOut Op_And                              = (knownEUFTypes, knownEUFType)
+opInsOut Op_Or                               = (knownEUFTypes, knownEUFType)
+opInsOut Op_Not                              = (knownEUFTypes, knownEUFType)
+opInsOut (Op_BoolLit _)                      = (knownEUFTypes, knownEUFType)
+opInsOut (Op_IfThenElse Repr_Bool)           = (knownEUFTypes, knownEUFType)
+opInsOut (Op_IfThenElse (Repr_BV BVWidth{})) = (knownEUFTypes, knownEUFType)
+opInsOut (Op_Plus       BVWidth{})           = (knownEUFTypes, knownEUFType)
+opInsOut (Op_Minus      BVWidth{})           = (knownEUFTypes, knownEUFType)
+opInsOut (Op_Times      BVWidth{})           = (knownEUFTypes, knownEUFType)
+opInsOut (Op_Abs        BVWidth{})           = (knownEUFTypes, knownEUFType)
+opInsOut (Op_Signum     BVWidth{})           = (knownEUFTypes, knownEUFType)
+opInsOut (Op_BVLit      BVWidth{} _)         = (knownEUFTypes, knownEUFType)
+opInsOut (Op_BVEq       BVWidth{})           = (knownEUFTypes, knownEUFType)
+opInsOut (Op_BVLt       BVWidth{})           = (knownEUFTypes, knownEUFType)
+
+-- | Get the input types of an 'Op'
+opIns :: Op ins out -> TypeReprs ins
+opIns = fst . opInsOut
+
+----------------------------------------------------------------------
+-- * Expressions of the EUF Logic
+----------------------------------------------------------------------
+
+-- | The expressions of our EUF logic, which are just operations applied to argument expressions.
+data EUFExpr tp where
+  EUFExpr :: Op ins out -> EUFExprs ins -> EUFExpr out
+
+-- | A sequence of expressions for each type in a type-level list
+data EUFExprs tps where
+  EUFExprsNil  :: EUFExprs '[]
+  EUFExprsCons :: EUFExpr tp -> EUFExprs tps -> EUFExprs (tp ': tps)
+
+-- | Build the type @t'EUFExpr' in1 -> ... -> t'EUFExpr' inn -> out@
+type family EUFExprFun (ins :: [EUFType]) (out :: EUFType) :: Type where
+  EUFExprFun '[]         out = EUFExpr out
+  EUFExprFun (tp ': tps) out = EUFExpr tp -> EUFExprFun tps out
+
+-- | Build an t'EUFExprFun' from a function on t'EUFExprs'
+lambdaEUFExprFun :: TypeReprs ins -> (EUFExprs ins -> EUFExpr out) -> EUFExprFun ins out
+lambdaEUFExprFun Repr_Nil          f = f EUFExprsNil
+lambdaEUFExprFun (Repr_Cons _ tps) f = \e -> lambdaEUFExprFun tps (f . EUFExprsCons e)
+
+-- | Apply an 'Op' to t'EUFExprs' for its input types, returning an t'EUFExpr' for its output type
+applyOp :: Op ins out -> EUFExprFun ins out
+applyOp op = lambdaEUFExprFun (opIns op) (EUFExpr op)
+
+instance (KnownNat w, BVIsNonZero w) => Num (EUFExpr (Tp_BV w)) where
+  fromInteger i = applyOp (Op_BVLit knownBVWidth i)
+
+  e1 + e2 = applyOp (Op_Plus  knownBVWidth) e1 e2
+  e1 - e2 = applyOp (Op_Minus knownBVWidth) e1 e2
+  e1 * e2 = applyOp (Op_Times knownBVWidth) e1 e2
+
+  abs    e = applyOp (Op_Abs    knownBVWidth) e
+  signum e = applyOp (Op_Signum knownBVWidth) e
+
+-- | Build an expression from an uninterpreted operation of a known type
+mkUnintExpr :: KnownEUFType tp => String -> EUFExpr tp
+mkUnintExpr nm = EUFExpr (mkUnintOp nm) EUFExprsNil
+
+----------------------------------------------------------------------
+-- * Interpreting the EUF Logic into SBV
+----------------------------------------------------------------------
+
+-- | Convert an 'EUFType' to a type of SBV expressions
+type family Type2SBV (tp :: EUFType) :: Type where
+  Type2SBV Tp_Bool   = SBool
+  Type2SBV (Tp_BV w) = SBV (WordN w)
+
+-- | Convert the type inputs plus output of an 'Op' to a function over 'SBV' values
+type family OpTypes2SBV (ins :: [EUFType]) (out :: EUFType) :: Type where
+  OpTypes2SBV '[] out         = Type2SBV out
+  OpTypes2SBV (tp ': tps) out = Type2SBV tp -> OpTypes2SBV tps out
+
+-- | Create an 'SMTDefinable' instance for the type returned by 'OpTypes2SBV' and pass it to a local function
+withSMTDefOpTypes :: TypeReprs ins -> TypeRepr out -> (SMTDefinable (OpTypes2SBV ins out) => a) -> a
+withSMTDefOpTypes Repr_Nil                            Repr_Bool           f = f
+withSMTDefOpTypes Repr_Nil                            (Repr_BV BVWidth{}) f = f
+withSMTDefOpTypes (Repr_Cons Repr_Bool ins)           out                 f = withSMTDefOpTypes ins out f
+withSMTDefOpTypes (Repr_Cons (Repr_BV BVWidth{}) ins) out                 f = withSMTDefOpTypes ins out f
+
+-- | An uninterpreted function that has been resolved to an 'SBV' function
+data ResolvedUnintOp = forall ins out. ResolvedUnintOp (UnintOp ins out) (OpTypes2SBV ins out)
+
+-- | A 'Map' for resolving uninterpreted operations
+type UnintMap = Map String ResolvedUnintOp
+
+-- | Look up the uninterpreted op associated with a 'String' in an 'UnintMap' at
+-- a particular type, raising an error if that 'String' is associated with a
+-- different type. If the 'String' is not associated with any uninterpreted
+-- function, create one and return it, updating the 'UnintMap'.
+unintEnsure :: UnintOp ins out -> UnintMap -> (OpTypes2SBV ins out, UnintMap)
+unintEnsure uop m
+  | Just (ResolvedUnintOp uop' f) <- Map.lookup (unintOpName uop) m
+  , Just Refl <- testEquality (unintOpIns uop) (unintOpIns uop')
+  , Just Refl <- testEquality (unintOpOut uop) (unintOpOut uop')
+  = (f, m)
+unintEnsure uop m
+  | Just _ <- Map.lookup (unintOpName uop) m
+  = error $ "unintEnsure: uninterpreted op " ++ unintOpName uop ++ " used at incorrect type"
+unintEnsure uop m =
+  withSMTDefOpTypes (unintOpIns uop) (unintOpOut uop)
+     $ let f = uninterpret (unintOpName uop)
+       in (f, Map.insert (unintOpName uop) (ResolvedUnintOp uop f) m)
+
+-- | The monad for interpreting t'EUFExpr's into SBV, which is just a state monad
+-- over an 'UnintMap'
+type InterpM = State UnintMap
+
+-- | Run an 'InterpM' computation starting with the empty 'UnintMap'
+runInterpM :: InterpM a -> a
+runInterpM = flip evalState Map.empty
+
+-- | Interpret an 'Op' into a function over SBV values
+interpOp :: Op ins out -> InterpM (OpTypes2SBV ins out)
+interpOp (Op_Unint uop)                      = state (unintEnsure uop)
+interpOp Op_And                              = pure (.&&)
+interpOp Op_Or                               = pure (.||)
+interpOp Op_Not                              = pure sNot
+interpOp (Op_BoolLit    b)                   = pure $ fromBool b
+interpOp (Op_IfThenElse Repr_Bool)           = pure ite
+interpOp (Op_IfThenElse (Repr_BV BVWidth{})) = pure ite
+interpOp (Op_Plus       BVWidth{})           = pure (+)
+interpOp (Op_Minus      BVWidth{})           = pure (-)
+interpOp (Op_Times      BVWidth{})           = pure (*)
+interpOp (Op_Abs        BVWidth{})           = pure abs
+interpOp (Op_Signum     BVWidth{})           = pure signum
+interpOp (Op_BVLit      BVWidth{} i)         = pure $ fromInteger i
+interpOp (Op_BVEq       BVWidth{})           = pure (.==)
+interpOp (Op_BVLt       BVWidth{})           = pure (.<)
+
+-- | Interpret an t'EUFExpr' into an SBV value.
+interpEUFExpr :: EUFExpr tp -> InterpM (Type2SBV tp)
+interpEUFExpr (EUFExpr op args) = do f <- interpOp op
+                                     interpApplyEUFExprs op f args
+
+-- | Apply an interpretation of an operator to the interpretations of a sequence of arguments for it.
+interpApplyEUFExprs :: ghost out -> OpTypes2SBV ins out -> EUFExprs ins -> InterpM (Type2SBV out)
+interpApplyEUFExprs _   f EUFExprsNil         = pure f
+interpApplyEUFExprs out f (EUFExprsCons e es) = do f_app <- f <$> interpEUFExpr e
+                                                   interpApplyEUFExprs out f_app es
+
+-- | Top-level call to interpret an t'EUFExpr' to an 'SBV' value
+interpEUF :: EUFExpr a -> Type2SBV a
+interpEUF = runInterpM . interpEUFExpr
+
+----------------------------------------------------------------------
+-- * Examples
+----------------------------------------------------------------------
+
+-- | Example EUF problem
+--
+-- > f (f (a) - f (b)) /= f (c), b >= a, a >= b + c, c >= 0
+--
+-- from <https://goto.ucsd.edu/~rjhala/classes/sp13/cse291/slides/lec-smt.markdown.pdf>
+-- noting that @x >= y@ is the same as @not (x < y)@. We have:
+--
+-- >>> sat $ interpEUF example
+-- Satisfiable. Model:
+--   a =  996506182 :: Word32
+--   b = 3298461113 :: Word32
+--   c = 1445036292 :: Word32
+-- <BLANKLINE>
+--   f :: Word32 -> Word32
+--   f 0          = 4188219399
+--   f 3298461113 = 4054018119
+--   f 1445036292 = 285239361
+--   f 996506182  = 4054018119
+--   f _          = 0
+--
+--  Note that the original example is unsatisfiable over integers. It is however satisfiable
+--  over 32-bit words, hence the model above.
+example :: EUFExpr Tp_Bool
+example =
+  applyOp Op_And (applyOp Op_Not (applyOp (Op_BVEq knownBVWidth)
+                                          (applyOp f (applyOp f a - applyOp f b))
+                                          (applyOp f c)))
+                 (applyOp Op_And (applyOp Op_Not (applyOp (Op_BVLt knownBVWidth) b a))
+                                 (applyOp Op_And
+                                          (applyOp Op_Not (applyOp (Op_BVLt knownBVWidth) a (b + c)))
+                                          (applyOp Op_Not (applyOp (Op_BVLt knownBVWidth) c 0))))
+  where
+    f :: Op '[Tp_BV 32] (Tp_BV 32)
+    f = mkUnintOp "f"
+
+    a, b, c :: EUFExpr (Tp_BV 32)
+    a = mkUnintExpr "a"
+    b = mkUnintExpr "b"
+    c = mkUnintExpr "c"
+
+{- HLint ignore "Use camelCase" -}
+{- HLint ignore "Eta reduce"    -}
diff --git a/Documentation/SBV/Examples/Uninterpreted/Multiply.hs b/Documentation/SBV/Examples/Uninterpreted/Multiply.hs
--- a/Documentation/SBV/Examples/Uninterpreted/Multiply.hs
+++ b/Documentation/SBV/Examples/Uninterpreted/Multiply.hs
@@ -13,7 +13,7 @@
 {-# LANGUAGE CPP                 #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
-{-# OPTIONS_GHC -Wall -Werror -Wno-incomplete-uni-patterns #-}
+{-# OPTIONS_GHC -Wall -Werror #-}
 
 module Documentation.SBV.Examples.Uninterpreted.Multiply where
 
@@ -49,8 +49,8 @@
 -- >>> sat synthMul22
 -- Satisfiable. Model:
 --   mul22_hi :: Bool -> Bool -> Bool -> Bool -> Bool
---   mul22_hi False True  True  True  = True
 --   mul22_hi True  True  False True  = True
+--   mul22_hi False True  True  True  = True
 --   mul22_hi True  False True  True  = True
 --   mul22_hi True  False False True  = True
 --   mul22_hi False True  True  False = True
@@ -86,5 +86,6 @@
 -- and rest assured that we have a correctly synthesized circuit!
 synthMul22 :: ConstraintSet
 synthMul22 = constrain $ \(Forall (a :: SWord8)) (Forall b) -> mul22 (lsb2 a) (lsb2 b) .== lsb2 (a * b)
-  where lsb2 x = let [x1, x0] = reverse $ take 2 $ blastLE x
-                 in (x1, x0)
+  where lsb2 x = case blastLE x of
+                   (x0 : x1 : _) -> (x1, x0)
+                   _             -> error "synthMul22: Can't get enough bits from x!"
diff --git a/Documentation/SBV/Examples/Uninterpreted/Sort.hs b/Documentation/SBV/Examples/Uninterpreted/Sort.hs
--- a/Documentation/SBV/Examples/Uninterpreted/Sort.hs
+++ b/Documentation/SBV/Examples/Uninterpreted/Sort.hs
@@ -9,10 +9,7 @@
 -- Demonstrates uninterpreted sorts, together with axioms.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DeriveAnyClass     #-}
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE StandaloneDeriving #-}
-{-# LANGUAGE TemplateHaskell    #-}
+{-# LANGUAGE TemplateHaskell #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -24,10 +21,10 @@
 -- in the backend SMT solver.
 data Q
 
--- | Make 'Q' an uinterpreted sort. This will automatically introduce the
+-- | Make 'Q' an uninterpreted sort. This will automatically introduce the
 -- type 'SQ' into our environment, which is the symbolic version of the
 -- carrier type 'Q'.
-mkUninterpretedSort ''Q
+mkSymbolic [''Q]
 
 -- | Declare an uninterpreted function that works over Q's
 f :: SQ -> SQ
@@ -45,7 +42,7 @@
 --   f _ = Q_1
 t1 :: IO SatResult
 t1 = sat $ do x <- free "x"
-              return $ f x ./= x
+              pure $ f x ./= x
 
 -- | This is a variant on the first example, except we also add an axiom
 -- for the sort, stating that the domain 'Q' has only one element. In this case
@@ -56,4 +53,4 @@
 t2 :: IO SatResult
 t2 = sat $ do x <- free "x"
               constrain $ \(Forall a) (Forall b) -> a .== (b :: SQ)
-              return $ f x ./= x
+              pure $ f x ./= x
diff --git a/Documentation/SBV/Examples/Uninterpreted/UISortAllSat.hs b/Documentation/SBV/Examples/Uninterpreted/UISortAllSat.hs
--- a/Documentation/SBV/Examples/Uninterpreted/UISortAllSat.hs
+++ b/Documentation/SBV/Examples/Uninterpreted/UISortAllSat.hs
@@ -10,11 +10,8 @@
 -- Thanks to Eric Seidel for the idea.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE CPP                #-}
-{-# LANGUAGE DeriveAnyClass     #-}
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE StandaloneDeriving #-}
-{-# LANGUAGE TemplateHaskell    #-}
+{-# LANGUAGE CPP             #-}
+{-# LANGUAGE TemplateHaskell #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -33,7 +30,7 @@
 
 -- | Make 'L' into an uninterpreted sort, automatically introducing 'SL'
 -- as a synonym for 'SBV' 'L'.
-mkUninterpretedSort ''L
+mkSymbolic [''L]
 
 -- | An uninterpreted "classify" function. Really, we only care about
 -- the fact that such a function exists, not what it does.
@@ -88,4 +85,4 @@
            constrain $ classify l0 .== 0
            constrain $ classify l1 .== 1
            constrain $ classify l2 .== 2
-           return $ l .== l0 .|| l .== l1 .|| l .== l2
+           pure $ l .== l0 .|| l .== l1 .|| l .== l2
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
@@ -37,7 +37,7 @@
 
 -- * Program state
 
--- | The state of the length program, paramaterized over the element type @a@
+-- | The state of the length program, parameterized over the element type @a@
 data AppS a = AppS { xs :: a  -- ^ The first input list
                    , ys :: a  -- ^ The second input list
                    , ts :: a  -- ^ Temporary variable
@@ -89,7 +89,7 @@
 
 -- | A program is the algorithm, together with its pre- and post-conditions.
 imperativeAppend :: Program A
-imperativeAppend = Program { setup         = return ()
+imperativeAppend = Program { setup         = pure ()
                            , precondition  = const sTrue  -- no precondition
                            , program       = algorithm
                            , postcondition = postcondition
diff --git a/Documentation/SBV/Examples/WeakestPreconditions/Basics.hs b/Documentation/SBV/Examples/WeakestPreconditions/Basics.hs
--- a/Documentation/SBV/Examples/WeakestPreconditions/Basics.hs
+++ b/Documentation/SBV/Examples/WeakestPreconditions/Basics.hs
@@ -90,7 +90,7 @@
 
 -- | A program is the algorithm, together with its pre- and post-conditions.
 imperativeInc :: Stmt I -> Stmt I -> Program I
-imperativeInc before after = Program { setup         = return ()
+imperativeInc before after = Program { setup         = pure ()
                                      , precondition  = pre
                                      , program       = algorithm before after
                                      , postcondition = post
diff --git a/Documentation/SBV/Examples/WeakestPreconditions/Fib.hs b/Documentation/SBV/Examples/WeakestPreconditions/Fib.hs
--- a/Documentation/SBV/Examples/WeakestPreconditions/Fib.hs
+++ b/Documentation/SBV/Examples/WeakestPreconditions/Fib.hs
@@ -39,7 +39,7 @@
 
 -- * Program state
 
--- | The state for the sum program, parameterized over a base type @a@.
+-- | The state for the fibonacci program, parameterized over a base type @a@.
 data FibS a = FibS { n :: a    -- ^ The input value
                    , i :: a    -- ^ Loop counter
                    , k :: a    -- ^ tracks @fib (i+1)@
diff --git a/Documentation/SBV/Examples/WeakestPreconditions/GCD.hs b/Documentation/SBV/Examples/WeakestPreconditions/GCD.hs
--- a/Documentation/SBV/Examples/WeakestPreconditions/GCD.hs
+++ b/Documentation/SBV/Examples/WeakestPreconditions/GCD.hs
@@ -45,7 +45,7 @@
 
 -- * Program state
 
--- | The state for the sum program, parameterized over a base type @a@.
+-- | The state for the GCD program, parameterized over a base type @a@.
 data GCDS a = GCDS { x :: a    -- ^ First value
                    , y :: a    -- ^ Second value
                    , i :: a    -- ^ Copy of x to be modified
diff --git a/Documentation/SBV/Examples/WeakestPreconditions/IntDiv.hs b/Documentation/SBV/Examples/WeakestPreconditions/IntDiv.hs
--- a/Documentation/SBV/Examples/WeakestPreconditions/IntDiv.hs
+++ b/Documentation/SBV/Examples/WeakestPreconditions/IntDiv.hs
@@ -66,7 +66,7 @@
 --
 -- Note that we need to explicitly annotate each loop with its invariant and the termination
 -- measure. For convenience, we take those two as parameters for simplicity.
-algorithm :: Invariant D -> Maybe (Measure D) -> Stmt D
+algorithm :: Invariant D -> Maybe (WPMeasure D) -> Stmt D
 algorithm inv msr = Seq [ assert "x, y >= 0" $ \DivS{x, y} -> x .>= 0 .&& y .>= 0
                         , Assign $ \st@DivS{x} -> st{r = x, q = 0}
                         , While "y <= r"
@@ -92,8 +92,8 @@
 noChange = [stable "x" x, stable "y" y]
 
 -- | A program is the algorithm, together with its pre- and post-conditions.
-imperativeDiv :: Invariant D -> Maybe (Measure D) -> Program D
-imperativeDiv inv msr = Program { setup         = return ()
+imperativeDiv :: Invariant D -> Maybe (WPMeasure D) -> Program D
+imperativeDiv inv msr = Program { setup         = pure ()
                                 , precondition  = pre
                                 , program       = algorithm inv msr
                                 , postcondition = post
@@ -110,7 +110,7 @@
 
 -- | The measure. In each iteration @r@ decreases, but always remains positive.
 -- Since @y@ is strictly positive, @r@ can serve as a measure for the loop.
-measure :: Measure D
+measure :: WPMeasure D
 measure DivS{r} = [r]
 
 -- | Check that the program terminates and the post condition holds. We have:
diff --git a/Documentation/SBV/Examples/WeakestPreconditions/IntSqrt.hs b/Documentation/SBV/Examples/WeakestPreconditions/IntSqrt.hs
--- a/Documentation/SBV/Examples/WeakestPreconditions/IntSqrt.hs
+++ b/Documentation/SBV/Examples/WeakestPreconditions/IntSqrt.hs
@@ -72,7 +72,7 @@
 --
 -- Note that we need to explicitly annotate each loop with its invariant and the termination
 -- measure. For convenience, we take those two as parameters for simplicity.
-algorithm :: Invariant S -> Maybe (Measure S) -> Stmt S
+algorithm :: Invariant S -> Maybe (WPMeasure S) -> Stmt S
 algorithm inv msr = Seq [ assert "x >= 0" $ \SqrtS{x} -> x .>= 0
                         , Assign $ \st -> st{sqrt = 0, i = 1, j = 1}
                         , While "i <= x"
@@ -102,8 +102,8 @@
 noChange = [stable "x" x]
 
 -- | A program is the algorithm, together with its pre- and post-conditions.
-imperativeSqrt :: Invariant S -> Maybe (Measure S) -> Program S
-imperativeSqrt inv msr = Program { setup         = return ()
+imperativeSqrt :: Invariant S -> Maybe (WPMeasure S) -> Program S
+imperativeSqrt inv msr = Program { setup         = pure ()
                                  , precondition  = pre
                                  , program       = algorithm inv msr
                                  , postcondition = post
@@ -123,7 +123,7 @@
   where sq n = n * n
 
 -- | The measure. In each iteration @i@ strictly increases, thus reducing the differential @x - i@
-measure :: Measure S
+measure :: WPMeasure S
 measure SqrtS{x, i} = [x - i]
 
 -- | Check that the program terminates and the post condition holds. We have:
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
@@ -31,7 +31,7 @@
 
 -- * Program state
 
--- | The state of the length program, paramaterized over the element type @a@
+-- | The state of the length program, parameterized over the element type @a@
 data LenS a b = LenS { xs :: a  -- ^ The input list
                      , ys :: a  -- ^ Copy of input
                      , l  :: b  -- ^ Running length
@@ -67,7 +67,7 @@
 --
 -- Note that we need to explicitly annotate each loop with its invariant and the termination
 -- measure. For convenience, we take those two as parameters, so we can experiment later.
-algorithm :: Invariant S -> Maybe (Measure S) -> Stmt S
+algorithm :: Invariant S -> Maybe (WPMeasure S) -> Stmt S
 algorithm inv msr = Seq [ Assign $ \st@LenS{xs} -> st{ys = xs, l = 0}
                         , While "! (null ys)"
                                 inv
@@ -91,8 +91,8 @@
 noChange = [stable "xs" xs]
 
 -- | A program is the algorithm, together with its pre- and post-conditions.
-imperativeLength :: Invariant S -> Maybe (Measure S) -> Program S
-imperativeLength inv msr = Program { setup         = return ()
+imperativeLength :: Invariant S -> Maybe (WPMeasure S) -> Program S
+imperativeLength inv msr = Program { setup         = pure ()
                                    , precondition  = pre
                                    , program       = algorithm inv msr
                                    , postcondition = post
@@ -105,7 +105,7 @@
 invariant LenS{xs, ys, l} = L.length xs .== l + L.length ys
 
 -- | The measure is obviously the length of @ys@, as we peel elements off of it through the loop.
-measure :: Measure S
+measure :: WPMeasure S
 measure LenS{ys} = [L.length ys]
 
 -- * Correctness
diff --git a/Documentation/SBV/Examples/WeakestPreconditions/Sum.hs b/Documentation/SBV/Examples/WeakestPreconditions/Sum.hs
--- a/Documentation/SBV/Examples/WeakestPreconditions/Sum.hs
+++ b/Documentation/SBV/Examples/WeakestPreconditions/Sum.hs
@@ -71,7 +71,7 @@
 --
 -- Note that we need to explicitly annotate each loop with its invariant and the termination
 -- measure. For convenience, we take those two as parameters, so we can experiment later.
-algorithm :: Invariant S -> Maybe (Measure S) -> Stmt S
+algorithm :: Invariant S -> Maybe (WPMeasure S) -> Stmt S
 algorithm inv msr = Seq [ Assign $ \st -> st{i = 0, s = 0}
                         , assert "n >= 0" $ \SumS{n} -> n .>= 0
                         , While "i < n"
@@ -99,8 +99,8 @@
 noChange = [stable "n" n]
 
 -- | A program is the algorithm, together with its pre- and post-conditions.
-imperativeSum :: Invariant S -> Maybe (Measure S) -> Program S
-imperativeSum inv msr = Program { setup         = return ()
+imperativeSum :: Invariant S -> Maybe (WPMeasure S) -> Program S
+imperativeSum inv msr = Program { setup         = pure ()
                                 , precondition  = pre
                                 , program       = algorithm inv msr
                                 , postcondition = post
@@ -143,7 +143,7 @@
 -- >>> correctness invariant (Just measure)
 -- Total correctness is established.
 -- Q.E.D.
-correctness :: Invariant S -> Maybe (Measure S) -> IO (ProofResult (SumS Integer))
+correctness :: Invariant S -> Maybe (WPMeasure S) -> IO (ProofResult (SumS Integer))
 correctness inv msr = wpProveWith defaultWPCfg{wpVerbose=True} (imperativeSum inv msr)
 
 -- * Example proof attempts
@@ -207,8 +207,8 @@
 Following proof obligation failed:
 ==================================
   Invariant for loop "i < n" is not maintained by the body:
-    Before: SumS {n = 3, i = 1, s = 1}
-    After : SumS {n = 3, i = 2, s = 3}
+    Before: SumS {n = 2, i = 1, s = 1}
+    After : SumS {n = 2, i = 2, s = 3}
 
 Here, we posed the extra incorrect invariant that @s <= i@ must be maintained, and SBV found us a reachable state that violates the invariant. The
 /before/ state indeed satisfies @s <= i@, but the /after/ state does not. Note that the proof fails in this case not because the program
@@ -239,10 +239,10 @@
 Following proof obligation failed:
 ==================================
   Measure for loop "i < n" does not decrease:
-    Before : SumS {n = 2, i = -2, s = 1}
-    Measure: 0
-    After  : SumS {n = 2, i = -1, s = 0}
+    Before : SumS {n = 1, i = 0, s = 0}
     Measure: 1
+    After  : SumS {n = 1, i = 1, s = 1}
+    Measure: 2
 
 Clearly, as @i@ increases, so does our bogus measure @n+i@. (Note that in this case the counterexample might have @i@ and @n@ as negative values, as the SMT solver finds a counter-example to induction, not
 necessarily a reachable state. Obviously, all such failures need to be addressed for the full proof.)
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
 SBV: SMT Based Verification in Haskell
 
-Copyright (c) 2010-2025, Levent Erkok (erkokl@gmail.com)
+Copyright (c) 2010-2026, Levent Erkok (erkokl@gmail.com)
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,26 +1,82 @@
 # SBV: SMT Based Verification in Haskell
 
-[![Build Status](https://github.com/LeventErkok/sbv/actions/workflows/haskell-ci.yml/badge.svg)](https://github.com/LeventErkok/sbv/actions/workflows/haskell-ci.yml)
+[![Build Status](https://github.com/LeventErkok/sbv/actions/workflows/ci.yml/badge.svg)](https://github.com/LeventErkok/sbv/actions/workflows/ci.yml)
 
-On Hackage: http://hackage.haskell.org/package/sbv
+***Express properties about Haskell programs and automatically prove them using SMT solvers.***
 
-Express properties about Haskell programs and automatically prove them using SMT solvers.
+[Hackage](http://hackage.haskell.org/package/sbv) | [Release Notes](http://github.com/LeventErkok/sbv/tree/master/CHANGES.md) | [Documentation](http://hackage.haskell.org/package/sbv/docs/Data-SBV.html)
 
-On one end, SBV can be used as a push-button prover over many types:
+SBV provides symbolic versions of Haskell types. Programs written with these types can be automatically verified, checked for satisfiability, optimized, or compiled to C — all via SMT solvers.
 
+## SBV in 5 Minutes
+
+Fire up GHCi with SBV:
+
+```
+$ cabal repl --build-depends sbv
+```
+
+For unbounded integers, `x + 1 .> x` is always true:
+
 ```haskell
-$ ghci
 ghci> :m Data.SBV
-ghci> prove $ \x -> x `shiftL` 2 .== 4 * (x::SWord8)
+ghci> prove $ \x -> x + 1 .> (x :: SInteger)
 Q.E.D.
-ghci> prove $ \x -> x `shiftL` 2 .== 2 * (x::SWord8)
+```
+
+But with machine arithmetic, overflow lurks:
+
+```haskell
+ghci> prove $ \x -> x + 1 .> (x :: SInt8)
 Falsifiable. Counter-example:
-  s0 = 32 :: Word8
+  s0 = 127 :: Int8
 ```
 
-On the other extreme, SBV can be used as an SMT-based proof assistant to prove equational and inductive program properties:
+IEEE-754 floats break reflexivity of equality:
 
 ```haskell
+ghci> prove $ \x -> (x :: SFloat) .== x
+Falsifiable. Counter-example:
+  s0 = NaN :: Float
+```
+
+What's the multiplicative inverse of 3 modulo 256?
+
+```haskell
+ghci> sat $ \x -> x * 3 .== (1 :: SWord8)
+Satisfiable. Model:
+  s0 = 171 :: Word8
+```
+
+Use quantifiers for named results:
+
+```haskell
+ghci> sat $ skolemize $ \(Exists @"x" x) (Exists @"y" y) -> x * y .== (96::SInteger) .&& x + y .== 28
+Satisfiable. Model:
+  x = 24 :: Integer
+  y =  4 :: Integer
+```
+
+Optimize a cost function subject to constraints:
+
+```haskell
+ghci> :{
+optimize Lexicographic $ do x <- sInteger "x"
+                            y <- sInteger "y"
+                            constrain $ x + y .== 20
+                            constrain $ x .>= 5
+                            constrain $ y .>= 5
+                            minimize "cost" $ x * y
+:}
+Optimal in an extension field:
+  x    =  5 :: Integer
+  y    = 15 :: Integer
+  cost = 75 :: Integer
+```
+
+For inductive proofs and equational reasoning, SBV includes a theorem prover:
+
+```haskell
 revApp :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> Forall "ys" [a] -> SBool))
 revApp = induct "revApp"
                  (\(Forall xs) (Forall ys) -> reverse (xs ++ ys) .== reverse ys ++ reverse xs) $
@@ -34,9 +90,7 @@
                                       =: qed
 ```
 
-Running this proof produces:
-
-```haskell
+```
 ghci> runTP $ revApp @Integer
 Inductive lemma: revApp
   Step: Base                            Q.E.D.
@@ -46,111 +100,103 @@
   Step: 4                               Q.E.D.
   Step: 5                               Q.E.D.
   Result:                               Q.E.D.
+Functions proven terminating: sbv.reverse
 [Proven] revApp :: Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool
 ```
 
-Establishing how `reverse` distributes over `++` (at the monomorpic type of list of integers).
+## Features
 
-The function `prove` establishes theorem-hood, while `sat` finds a satisfying model if it exists. The `runTP` function
-runs a proof script, establishing theorems with user guidance.
+**Symbolic types** — Booleans, signed/unsigned integers (8/16/32/64-bit and arbitrary-width), unbounded integers, reals, rationals, IEEE-754 floats, characters, strings, lists, tuples, sums, optionals, sets, enumerations, algebraic data types, and uninterpreted sorts.
 
-All satisfying models can be computed using `allSat`.
-SBV can also perform static assertion checks, such as absence of division-by-0, and other user given properties.
-Furthermore, SBV can perform optimization, minimizing/maximizing arithmetic goals for their optimal values.
+**Verification** — `prove`/`sat`/`allSat` for property checking and model finding, `safe`/`sAssert` for assertion verification, `dsat`/`dprove` for delta-satisfiability, and QuickCheck integration.
 
-SBV also allows for an incremental mode: Users are given a handle to the SMT solver as their programs execute, and they can issue SMTLib commands programmatically, query values, and direct the interaction using a high-level typed API. The incremental mode also allows for creation of constraints based on the current model, and access to internals of SMT solvers for advanced users. See the `runSMT` and `query` commands for details.
+**Optimization** — Minimize/maximize cost functions subject to constraints via `optimize`/`maximize`/`minimize`, with support for lexicographic, independent, and Pareto objectives.
 
-## Overview
+**Quantifiers and functions** — Universal and existential quantifiers (including alternating), with skolemization for named bindings. Define SMT-level functions directly from Haskell via `smtFunction`, including recursive and mutually recursive definitions with automatic termination checking.
 
- - [Hackage](http://hackage.haskell.org/package/sbv)
- - [Release Notes](http://github.com/LeventErkok/sbv/tree/master/CHANGES.md)
-   
-SBV library provides support for dealing with symbolic values in Haskell. It introduces the types:
+**Theorem proving (TP)** — Semi-automated inductive proofs (including strong induction) with equational reasoning chains. Includes termination checking, recursive and mutually recursive definitions, productive (co-recursive) functions, and user-defined measures.
 
- - `SBool`: Symbolic Booleans (bits).
- - `SWord8`, `SWord16`, `SWord32`, `SWord64`: Symbolic Words (unsigned).
- - `SInt8`, `SInt16`, `SInt32`, `SInt64`: Symbolic Ints (signed).
- - `SWord N`, `SInt N`, for `N > 0`: Arbitrary sized unsigned/signed bit-vectors, parameterized by the bitsize. (Using DataKinds extension.)
- - `SInteger`: Symbolic unbounded integers (signed).
- - `SReal`: Symbolic infinite precision algebraic reals (signed).
- - `SRational`: Symbolic rationals, ratio of two symbolic integers. (`Rational`.)
- - `SFloat`: IEEE-754 single precision floating point number. (`Float`.)
- - `SDouble`: IEEE-754 double precision floating point number. (`Double`.)
- - `SFloatingPoint`: IEEE-754 floating point number with user specified exponent and significand sizes. (`FloatingPoint`)
- - `SChar`: Symbolic characters, supporting unicode.
- - `SString`: Symbolic strings.
- - `SList`: Symbolic lists. (Which can be nested, i.e., lists of lists.)
- - `STuple`: Symbolic tuples (upto 8-tuples, can be nested)
- - `SEither`: Symbolic sums
- - `SMaybe`: Symbolic optional values
- - `SSet`: Symbolic sets
- - Arrays of symbolic values.
- - Symbolic enumerations, for arbitrary user-defined enumerated types.
- - Symbolic polynomials over GF(2^n ), polynomial arithmetic, and CRCs.
- - Uninterpreted constants and functions over symbolic values, with user defined axioms.
- - Uninterpreted sorts, and proofs over such sorts, potentially with axioms.
- - Ability to define SMTLib functions, generated directly from Haskell versions, including support for recursive and mutually recursive functions.
- - Reasoning with universal and existential quantifiers, including alternating quantifiers.
-   
-The user can construct ordinary Haskell programs using these types, which behave like ordinary Haskell values when used concretely. However, when used with symbolic arguments, functions built out of these types can also be:
+**Code generation** — Compile symbolic programs to C functions or static libraries (`compileToC`, `compileToCLib`), including recursive functions, arbitrary-width arithmetic, structured values, and bounded regex compilation. The previous compiler remains available through `Data.SBV.Tools.CodeGen.Legacy`. Generate test vectors with `genTest`.
 
- - proven correct via an external SMT solver (the `prove` function),
- - checked for satisfiability (the `sat`, and `allSat` functions),
- - checked for assertion violations (the `safe` function with `sAssert` calls),
- - checked for delta-satisfiability (the `dsat` and `dprove` functions),
- - used in synthesis (the `sat`function with existentials),
- - checked for machine-arithmetic overflow/underflow conditions,
- - optimized with respect to cost functions (the `optimize`, `maximize`, and `minimize` functions),
- - quick-checked,
- - used for generating Haskell and C test vectors (the `genTest` function),
- - compiled down to C, rendered as straight-line programs or libraries (`compileToC` and `compileToCLib` functions).
-   
-## Picking the SMT solver to use
+**SMT interaction** — Incremental mode via `runSMT`/`query` for programmatic solver interaction with a high-level typed API. Run multiple solvers simultaneously with `proveWithAny`/`proveWithAll`.
 
-The SBV library uses third-party SMT solvers via the standard SMT-Lib interface. The following solvers are supported:
+## Algebraic Data Types
 
- - [ABC](http://www.eecs.berkeley.edu/~alanmi/abc) from University of Berkeley
- - [Boolector](http://boolector.github.io/) from Johannes Kepler University
- - [Bitwuzla](http://bitwuzla.github.io/) from Stanford University
- - [CVC4](http://cvc4.github.io/) from Stanford University and the University of Iowa
- - [CVC5](http://cvc5.github.io/) from Stanford University and the University of Iowa
- - [DReal](http://dreal.github.io/) from CMU
- - [MathSAT](http://mathsat.fbk.eu/) from FBK and DISI-University of Trento
- - [OpenSMT](http://verify.inf.usi.ch/opensmt) from Università della Svizzera italiana
- - [Yices](http://github.com/SRI-CSL/yices2) from SRI
- - [Z3](http://github.com/Z3Prover/z3/wiki) from Microsoft
-   
-Most functions have two variants: For instance `prove`/`proveWith`. The former uses the default solver, which is currently Z3. The latter expects you to pass it a configuration that picks the solver.
-The valid values are `abc`, `boolector`, `bitwuzla`, `cvc4`, `cvc5`, `dReal`, `mathSAT`, `openSMT`, `yices`, and `z3`.
+User-defined algebraic data types — including enumerations, recursive, and parametric types — are supported via `mkSymbolic`, with pattern matching via `sCase` (and its proof counterpart `pCase`):
 
-See [versions](http://github.com/LeventErkok/sbv/blob/master/SMTSolverVersions.md) for a listing of the versions of these tools SBV has been tested with. Please report if you see any discrepancies!
+```haskell
+{-# LANGUAGE QuasiQuotes     #-}
+{-# LANGUAGE TemplateHaskell #-}
 
-Other SMT solvers can be used with SBV as well, with a relatively easy hook-up mechanism. Please do get in touch if you plan to use SBV with any other solver.
+import Data.SBV
 
-## Using multiple solvers, simultaneously
+data Expr a = Val a
+            | Add (Expr a) (Expr a)
+            | Mul (Expr a) (Expr a)
+            deriving Show
 
-SBV also allows for running multiple solvers at the same time, either picking the result of the first to complete, or getting results from all.
-See `proveWithAny`/`proveWithAll` and `satWithAny`/`satWithAll` functions. The function `sbvAvailableSolvers` can be used to query the available solvers at run-time.
+-- Make Expr symbolically available, named SExpr
+mkSymbolic [''Expr]
 
-## TP: Semi-automated theorem proving
+eval :: SymVal a => (SBV a -> SBV a -> SBV a) -> (SBV a -> SBV a -> SBV a) -> SBV (Expr a) -> SBV a
+eval add mul = smtFunction "eval" $ \e ->
+    [sCase| e of
+       Val v   -> v
+       Add x y -> eval add mul x `add` eval add mul y
+       Mul x y -> eval add mul x `mul` eval add mul y
+    |]
+```
 
-While SMT solvers are quite powerful, there is a certain class of problems that they are just not well suited for. In particular, SMT
-solvers are not good at proofs that require induction, or those that require complex chains of reasoning. Induction is necessary to reason about
-any recursive algorithm, and most such proofs require carefully constructed equational steps.
+The `sCase` construct supports nested pattern matching, as-patterns, guards, and wildcards, making programming with algebraic data types natural. Plain `case` expressions inside `sCase` are automatically treated as symbolic case-splits. The `pCase` variant provides the same features for proof case-splits in the theorem proving context.
 
-SBV allows for a style of semi-automated theorem proving, called TP. which can be used to construct such proofs.
-The documentation includes example proofs for many list functions, and even inductive proofs for
-the familiar insertion, merge, quick-sort algorithms, along with a proof that the square-root of 2 is irrational.
-While a proper theorem prover (such as Lean, Isabelle etc.) is a more appropriate choice for such proofs, with some
-guidance (and acceptance of a much larger trusted code base!), SBV can be used to establish correctness of various mathematical
-claims and algorithms that are usually beyond the scope of SMT solvers alone. See the documentation under
-the `Documentation.SBV.Examples.TP` directory.
+## Supported SMT Solvers
 
-## Copyright, License
+SBV communicates with solvers via the standard SMT-Lib interface:
 
-The SBV library is distributed with the BSD3 license. See [COPYRIGHT](http://github.com/LeventErkok/sbv/tree/master/COPYRIGHT) for details.
-The [LICENSE](http://github.com/LeventErkok/sbv/tree/master/LICENSE) file contains the [BSD3](http://en.wikipedia.org/wiki/BSD_licenses) verbiage.
+| Solver | From | | Solver | From |
+|--------|------|-|--------|------|
+| [ABC](https://github.com/berkeley-abc/abc) | Berkeley | | [DReal](http://dreal.github.io/) | CMU |
+| [Bitwuzla](http://bitwuzla.github.io/) | Stanford | | [MathSAT](http://mathsat.fbk.eu/) | FBK / Trento |
+| [Boolector](http://boolector.github.io/) | JKU | | [OpenSMT](http://verify.inf.usi.ch/opensmt) | USI |
+| [CVC4](http://cvc4.github.io/) | Stanford / Iowa | | [Yices](http://github.com/SRI-CSL/yices2) | SRI |
+| [CVC5](http://cvc5.github.io/) | Stanford / Iowa | | [Z3](http://github.com/Z3Prover/z3/wiki) | Microsoft |
 
+**Z3** is the default solver. Use `proveWith`, `satWith`, etc. to select a different one (e.g., `proveWith cvc5`). See [tested versions](http://github.com/LeventErkok/sbv/blob/master/SMTSolverVersions.md) for details. Other SMT-Lib compatible solvers can be hooked up with minimal effort — get in touch if you'd like to use one not listed here.
+
+## A Selection of Examples
+
+SBV ships with many worked examples. Here are some highlights:
+
+| Example | Description |
+|---------|-------------|
+| [Sudoku](http://hackage.haskell.org/package/sbv/docs/Documentation-SBV-Examples-Puzzles-Sudoku.html) | Solve Sudoku puzzles using SMT constraints |
+| [N-Queens](http://hackage.haskell.org/package/sbv/docs/Documentation-SBV-Examples-Puzzles-NQueens.html) | Solve the N-Queens placement puzzle |
+| [SEND + MORE = MONEY](http://hackage.haskell.org/package/sbv/docs/Documentation-SBV-Examples-Puzzles-SendMoreMoney.html) | The classic cryptarithmetic puzzle |
+| [Fish/Zebra](http://hackage.haskell.org/package/sbv/docs/Documentation-SBV-Examples-Puzzles-Fish.html) | Einstein's logic puzzle |
+| [SQL Injection](http://hackage.haskell.org/package/sbv/docs/Documentation-SBV-Examples-Strings-SQLInjection.html) | Find inputs that cause SQL injection vulnerabilities |
+| [Regex Crossword](http://hackage.haskell.org/package/sbv/docs/Documentation-SBV-Examples-Strings-RegexCrossword.html) | Solve regex crossword puzzles |
+| [BitTricks](http://hackage.haskell.org/package/sbv/docs/Documentation-SBV-Examples-BitPrecise-BitTricks.html) | Verify bit-manipulation tricks from Stanford's bithacks collection |
+| [Legato multiplier](http://hackage.haskell.org/package/sbv/docs/Documentation-SBV-Examples-BitPrecise-Legato.html) | Correctness proof of Legato's 8-bit multiplier |
+| [Prefix sum](http://hackage.haskell.org/package/sbv/docs/Documentation-SBV-Examples-BitPrecise-PrefixSum.html) | Ladner-Fischer prefix-sum implementation proof |
+| [AES](http://hackage.haskell.org/package/sbv/docs/Documentation-SBV-Examples-Crypto-AES.html) | AES encryption with C code generation |
+| [CRC](http://hackage.haskell.org/package/sbv/docs/Documentation-SBV-Examples-CodeGeneration-CRC_USB5.html) | Symbolic CRC computation with C code generation |
+| [Sqrt2 irrational](http://hackage.haskell.org/package/sbv/docs/Documentation-SBV-Examples-TP-Sqrt2IsIrrational.html) | Prove that the square root of 2 is irrational |
+| [Sorting](http://hackage.haskell.org/package/sbv/docs/Documentation-SBV-Examples-TP-InsertionSort.html) | Prove [insertion sort](http://hackage.haskell.org/package/sbv/docs/Documentation-SBV-Examples-TP-InsertionSort.html), [merge sort](http://hackage.haskell.org/package/sbv/docs/Documentation-SBV-Examples-TP-MergeSort.html), and [quick sort](http://hackage.haskell.org/package/sbv/docs/Documentation-SBV-Examples-TP-QuickSort.html) correct |
+| [Kadane](http://hackage.haskell.org/package/sbv/docs/Documentation-SBV-Examples-TP-Kadane.html) | Prove Kadane's maximum segment-sum algorithm correct |
+| [McCarthy91](http://hackage.haskell.org/package/sbv/docs/Documentation-SBV-Examples-TP-McCarthy91.html) | Prove McCarthy's 91 function meets its specification |
+| [Binary search](http://hackage.haskell.org/package/sbv/docs/Documentation-SBV-Examples-TP-BinarySearch.html) | Prove binary search correct |
+| [Collatz](http://hackage.haskell.org/package/sbv/docs/Documentation-SBV-Examples-TP-Collatz.html) | Explore properties of the Collatz sequence |
+| [Infinitely many primes](http://hackage.haskell.org/package/sbv/docs/Documentation-SBV-Examples-TP-Primes.html) | Prove there are infinitely many primes |
+| [Tautology checker](http://hackage.haskell.org/package/sbv/docs/Documentation-SBV-Examples-TP-TautologyChecker.html) | A verified BDD-style tautology checker |
+
+Browse the full collection in `Documentation.SBV.Examples` [on Hackage](http://hackage.haskell.org/package/sbv).
+
+## License
+
+SBV is distributed under the [BSD3](http://en.wikipedia.org/wiki/BSD_licenses) license. See [COPYRIGHT](http://github.com/LeventErkok/sbv/tree/master/COPYRIGHT) and [LICENSE](http://github.com/LeventErkok/sbv/tree/master/LICENSE) for details.
+
+Please report bugs and feature requests at the [GitHub issue tracker](http://github.com/LeventErkok/sbv/issues).
+
 ## Thanks
 
 The following people made major contributions to SBV, by developing new features and contributing to the design in significant ways: Joel Burget, Brian Huffman, Brian Schroeder, and Jeffrey Young.
@@ -160,6 +206,7 @@
 Ara Adkins,
 Andrew Anderson,
 Kanishka Azimi,
+David van Balen,
 Markus Barenhoff,
 Reid Barton,
 Ben Blaxill,
@@ -230,6 +277,8 @@
 May Torrence,
 Daniel Wagner,
 Sean Weaver,
+Robin Webbers,
+Eddy Westbrook,
 Nis Wegmann,
 Jared Ziegler,
 and Marco Zocca.
diff --git a/SBVBenchSuite/BenchSuite/Bench/Bench.hs b/SBVBenchSuite/BenchSuite/Bench/Bench.hs
--- a/SBVBenchSuite/BenchSuite/Bench/Bench.hs
+++ b/SBVBenchSuite/BenchSuite/Bench/Bench.hs
@@ -10,7 +10,7 @@
 -- Assessing the overhead of calling solving examples via sbv vs individual solvers
 -----------------------------------------------------------------------------
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 {-# LANGUAGE CPP                       #-}
 {-# LANGUAGE ExistentialQuantification #-}
 {-# LANGUAGE FlexibleContexts          #-}
diff --git a/SBVBenchSuite/BenchSuite/CodeGeneration/Uninterpreted.hs b/SBVBenchSuite/BenchSuite/CodeGeneration/Uninterpreted.hs
--- a/SBVBenchSuite/BenchSuite/CodeGeneration/Uninterpreted.hs
+++ b/SBVBenchSuite/BenchSuite/CodeGeneration/Uninterpreted.hs
@@ -26,3 +26,5 @@
   , runIO "CodeGen" genCCode
   ]
   where testLeft = \x y -> tstShiftLeft x y 0 .== x + y
+
+{- HLint ignore module "Redundant lambda" -}
diff --git a/SBVBenchSuite/BenchSuite/Crypto/AES.hs b/SBVBenchSuite/BenchSuite/Crypto/AES.hs
--- a/SBVBenchSuite/BenchSuite/Crypto/AES.hs
+++ b/SBVBenchSuite/BenchSuite/Crypto/AES.hs
@@ -33,3 +33,5 @@
   , runIO   "CodeGen.AES128Lib" cgAES128Library
   ]
   where inverseGFPrf = \x -> x ./= 0 .=> x `gf28Mult` gf28Inverse x .== 1
+
+{- HLint ignore module "Redundant lambda" -}
diff --git a/SBVBenchSuite/BenchSuite/Existentials/Diophantine.hs b/SBVBenchSuite/BenchSuite/Existentials/Diophantine.hs
--- a/SBVBenchSuite/BenchSuite/Existentials/Diophantine.hs
+++ b/SBVBenchSuite/BenchSuite/Existentials/Diophantine.hs
@@ -10,7 +10,7 @@
 -- Bench suite for Documentation.SBV.Examples.Existentials.Diophantine
 -----------------------------------------------------------------------------
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
 module BenchSuite.Existentials.Diophantine(benchmarks) where
 
diff --git a/SBVBenchSuite/BenchSuite/Misc/Enumerate.hs b/SBVBenchSuite/BenchSuite/Misc/Enumerate.hs
--- a/SBVBenchSuite/BenchSuite/Misc/Enumerate.hs
+++ b/SBVBenchSuite/BenchSuite/Misc/Enumerate.hs
@@ -35,3 +35,5 @@
                    constrain $ \(Forall e) -> mx .>= (e::SE)
         _minE = do mx <- free "minE"
                    constrain $ \(Forall e) -> mx .<= (e::SE)
+
+{- HLint ignore module "Redundant lambda" -}
diff --git a/SBVBenchSuite/BenchSuite/Misc/NoDiv0.hs b/SBVBenchSuite/BenchSuite/Misc/NoDiv0.hs
--- a/SBVBenchSuite/BenchSuite/Misc/NoDiv0.hs
+++ b/SBVBenchSuite/BenchSuite/Misc/NoDiv0.hs
@@ -10,7 +10,7 @@
 -- Bench suite for Documentation.SBV.Examples.Misc.NoDiv0
 -----------------------------------------------------------------------------
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
 module BenchSuite.Misc.NoDiv0(benchmarks) where
 
diff --git a/SBVBenchSuite/BenchSuite/Misc/SetAlgebra.hs b/SBVBenchSuite/BenchSuite/Misc/SetAlgebra.hs
--- a/SBVBenchSuite/BenchSuite/Misc/SetAlgebra.hs
+++ b/SBVBenchSuite/BenchSuite/Misc/SetAlgebra.hs
@@ -129,3 +129,5 @@
         relCompFull    = \(a :: SI) -> a \\ full .== empty
         distSubset1    = \(a :: SI) b c -> a `isSubsetOf` (b `union` c) .=> a `isSubsetOf` b .&& a `isSubsetOf` c
         distSubset2    = \(a :: SI) b c -> (b `intersection` c) `isSubsetOf` a .=> b `isSubsetOf` a .&& c `isSubsetOf` a
+
+{- HLint ignore module "Redundant lambda" -}
diff --git a/SBVBenchSuite/BenchSuite/Optimization/Instances.hs b/SBVBenchSuite/BenchSuite/Optimization/Instances.hs
--- a/SBVBenchSuite/BenchSuite/Optimization/Instances.hs
+++ b/SBVBenchSuite/BenchSuite/Optimization/Instances.hs
@@ -10,7 +10,7 @@
 -- Helper file to provide common orphaned instances for Optimization benchmarks
 -----------------------------------------------------------------------------
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
 module BenchSuite.Optimization.Instances where
 
diff --git a/SBVBenchSuite/BenchSuite/ProofTools/BMC.hs b/SBVBenchSuite/BenchSuite/ProofTools/BMC.hs
--- a/SBVBenchSuite/BenchSuite/ProofTools/BMC.hs
+++ b/SBVBenchSuite/BenchSuite/ProofTools/BMC.hs
@@ -10,7 +10,7 @@
 -- Bench suite for Documentation.SBV.Examples.ProofTools.BMC
 -----------------------------------------------------------------------------
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
 module BenchSuite.ProofTools.BMC(benchmarks) where
 
diff --git a/SBVBenchSuite/BenchSuite/ProofTools/Fibonacci.hs b/SBVBenchSuite/BenchSuite/ProofTools/Fibonacci.hs
--- a/SBVBenchSuite/BenchSuite/ProofTools/Fibonacci.hs
+++ b/SBVBenchSuite/BenchSuite/ProofTools/Fibonacci.hs
@@ -10,7 +10,7 @@
 -- Bench suite for Documentation.SBV.Examples.ProofTools.Fibonacci
 -----------------------------------------------------------------------------
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
 module BenchSuite.ProofTools.Fibonacci(benchmarks) where
 
diff --git a/SBVBenchSuite/BenchSuite/ProofTools/Strengthen.hs b/SBVBenchSuite/BenchSuite/ProofTools/Strengthen.hs
--- a/SBVBenchSuite/BenchSuite/ProofTools/Strengthen.hs
+++ b/SBVBenchSuite/BenchSuite/ProofTools/Strengthen.hs
@@ -10,7 +10,7 @@
 -- Bench suite for Documentation.SBV.Examples.ProofTools.Strengthen
 -----------------------------------------------------------------------------
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
 module BenchSuite.ProofTools.Strengthen(benchmarks) where
 
diff --git a/SBVBenchSuite/BenchSuite/ProofTools/Sum.hs b/SBVBenchSuite/BenchSuite/ProofTools/Sum.hs
--- a/SBVBenchSuite/BenchSuite/ProofTools/Sum.hs
+++ b/SBVBenchSuite/BenchSuite/ProofTools/Sum.hs
@@ -10,7 +10,7 @@
 -- Bench suite for Documentation.SBV.Examples.ProofTools.Sum
 -----------------------------------------------------------------------------
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
 module BenchSuite.ProofTools.Sum(benchmarks) where
 
diff --git a/SBVBenchSuite/BenchSuite/Puzzles/Sudoku.hs b/SBVBenchSuite/BenchSuite/Puzzles/Sudoku.hs
--- a/SBVBenchSuite/BenchSuite/Puzzles/Sudoku.hs
+++ b/SBVBenchSuite/BenchSuite/Puzzles/Sudoku.hs
@@ -19,9 +19,6 @@
 import Utils.SBVBenchFramework
 import BenchSuite.Bench.Bench as S
 
-import Data.Maybe (fromMaybe)
-
-
 -- benchmark suite
 benchmarks :: Runner
 benchmarks = rGroup
@@ -32,4 +29,4 @@
 checkPuzzle :: Puzzle -> IO Bool
 checkPuzzle p = do final <- fillBoard p
                    let vld = valid (map (map literal) final)
-                   pure $ fromMaybe False (unliteral vld)
+                   pure $ Just True == unliteral vld
diff --git a/SBVBenchSuite/BenchSuite/Queries/Enums.hs b/SBVBenchSuite/BenchSuite/Queries/Enums.hs
--- a/SBVBenchSuite/BenchSuite/Queries/Enums.hs
+++ b/SBVBenchSuite/BenchSuite/Queries/Enums.hs
@@ -10,7 +10,7 @@
 -- Bench suite for Documentation.SBV.Examples.Queries.Enums
 -----------------------------------------------------------------------------
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
 module BenchSuite.Queries.Enums(benchmarks) where
 
diff --git a/SBVBenchSuite/BenchSuite/Queries/GuessNumber.hs b/SBVBenchSuite/BenchSuite/Queries/GuessNumber.hs
--- a/SBVBenchSuite/BenchSuite/Queries/GuessNumber.hs
+++ b/SBVBenchSuite/BenchSuite/Queries/GuessNumber.hs
@@ -10,7 +10,7 @@
 -- Bench suite for Documentation.SBV.Examples.Queries.GuessNumber
 -----------------------------------------------------------------------------
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
 module BenchSuite.Queries.GuessNumber(benchmarks) where
 
diff --git a/SBVBenchSuite/BenchSuite/Transformers/SymbolicEval.hs b/SBVBenchSuite/BenchSuite/Transformers/SymbolicEval.hs
--- a/SBVBenchSuite/BenchSuite/Transformers/SymbolicEval.hs
+++ b/SBVBenchSuite/BenchSuite/Transformers/SymbolicEval.hs
@@ -10,7 +10,7 @@
 -- Bench suite for Documentation.SBV.Examples.Transformers.SymbolicEval
 -----------------------------------------------------------------------------
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
 module BenchSuite.Transformers.SymbolicEval(benchmarks) where
 
diff --git a/SBVBenchSuite/BenchSuite/Uninterpreted/AUF.hs b/SBVBenchSuite/BenchSuite/Uninterpreted/AUF.hs
--- a/SBVBenchSuite/BenchSuite/Uninterpreted/AUF.hs
+++ b/SBVBenchSuite/BenchSuite/Uninterpreted/AUF.hs
@@ -10,7 +10,7 @@
 -- Bench suite for Documentation.SBV.Examples.Uninterpreted.AUF
 -----------------------------------------------------------------------------
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
 module BenchSuite.Uninterpreted.AUF(benchmarks) where
diff --git a/SBVBenchSuite/BenchSuite/Uninterpreted/Deduce.hs b/SBVBenchSuite/BenchSuite/Uninterpreted/Deduce.hs
--- a/SBVBenchSuite/BenchSuite/Uninterpreted/Deduce.hs
+++ b/SBVBenchSuite/BenchSuite/Uninterpreted/Deduce.hs
@@ -10,7 +10,7 @@
 -- Bench suite for Documentation.SBV.Examples.Uninterpreted.Deduce
 -----------------------------------------------------------------------------
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
 module BenchSuite.Uninterpreted.Deduce(benchmarks) where
@@ -33,3 +33,6 @@
                r <- free "r"
                return $ not (p `or` (q `and` r))
                  .== (not p `and` not q) `or` (not p `and` not r)
+
+{- HLint ignore module "Redundant lambda" -}
+{- HLint ignore module "Redundant not"    -}
diff --git a/SBVBenchSuite/BenchSuite/Uninterpreted/Multiply.hs b/SBVBenchSuite/BenchSuite/Uninterpreted/Multiply.hs
--- a/SBVBenchSuite/BenchSuite/Uninterpreted/Multiply.hs
+++ b/SBVBenchSuite/BenchSuite/Uninterpreted/Multiply.hs
@@ -36,3 +36,5 @@
                            sFalse
 
     correct = \a1 a0 b1 b0 -> mul22_hi a1 a0 b1 b0 .== (a1 .&& b0) .<+> (a0 .&& b1)
+
+{- HLint ignore module "Redundant lambda" -}
diff --git a/SBVBenchSuite/BenchSuite/Uninterpreted/Shannon.hs b/SBVBenchSuite/BenchSuite/Uninterpreted/Shannon.hs
--- a/SBVBenchSuite/BenchSuite/Uninterpreted/Shannon.hs
+++ b/SBVBenchSuite/BenchSuite/Uninterpreted/Shannon.hs
@@ -41,3 +41,5 @@
 f'   = derivative f
 f''  = universal f
 f''' = existential f
+
+{- HLint ignore module "Redundant lambda" -}
diff --git a/SBVBenchSuite/BenchSuite/WeakestPreconditions/Append.hs b/SBVBenchSuite/BenchSuite/WeakestPreconditions/Append.hs
--- a/SBVBenchSuite/BenchSuite/WeakestPreconditions/Append.hs
+++ b/SBVBenchSuite/BenchSuite/WeakestPreconditions/Append.hs
@@ -10,7 +10,7 @@
 -- Bench suite for Documentation.SBV.Examples.WeakestPreconditions.Append
 -----------------------------------------------------------------------------
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
 module BenchSuite.WeakestPreconditions.Append(benchmarks) where
 
diff --git a/SBVBenchSuite/BenchSuite/WeakestPreconditions/Basics.hs b/SBVBenchSuite/BenchSuite/WeakestPreconditions/Basics.hs
--- a/SBVBenchSuite/BenchSuite/WeakestPreconditions/Basics.hs
+++ b/SBVBenchSuite/BenchSuite/WeakestPreconditions/Basics.hs
@@ -10,7 +10,7 @@
 -- Bench suite for Documentation.SBV.Examples.WeakestPreconditions.Basics
 -----------------------------------------------------------------------------
 
-{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wno-orphans #-}
 {-# LANGUAGE NamedFieldPuns #-}
 
 module BenchSuite.WeakestPreconditions.Basics(benchmarks) where
diff --git a/SBVBenchSuite/BenchSuite/WeakestPreconditions/Fib.hs b/SBVBenchSuite/BenchSuite/WeakestPreconditions/Fib.hs
--- a/SBVBenchSuite/BenchSuite/WeakestPreconditions/Fib.hs
+++ b/SBVBenchSuite/BenchSuite/WeakestPreconditions/Fib.hs
@@ -10,7 +10,7 @@
 -- Bench suite for Documentation.SBV.Examples.WeakestPreconditions.Fig
 -----------------------------------------------------------------------------
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
 module BenchSuite.WeakestPreconditions.Fib(benchmarks) where
 
diff --git a/SBVBenchSuite/BenchSuite/WeakestPreconditions/GCD.hs b/SBVBenchSuite/BenchSuite/WeakestPreconditions/GCD.hs
--- a/SBVBenchSuite/BenchSuite/WeakestPreconditions/GCD.hs
+++ b/SBVBenchSuite/BenchSuite/WeakestPreconditions/GCD.hs
@@ -10,7 +10,7 @@
 -- Bench suite for Documentation.SBV.Examples.WeakestPreconditions.GCD
 -----------------------------------------------------------------------------
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
 module BenchSuite.WeakestPreconditions.GCD(benchmarks) where
 
diff --git a/SBVBenchSuite/BenchSuite/WeakestPreconditions/Instances.hs b/SBVBenchSuite/BenchSuite/WeakestPreconditions/Instances.hs
--- a/SBVBenchSuite/BenchSuite/WeakestPreconditions/Instances.hs
+++ b/SBVBenchSuite/BenchSuite/WeakestPreconditions/Instances.hs
@@ -10,7 +10,7 @@
 -- Helper file to provide common orphaned instances for WeakestPrecondition benchmarks
 -----------------------------------------------------------------------------
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
 module BenchSuite.WeakestPreconditions.Instances where
 
diff --git a/SBVBenchSuite/BenchSuite/WeakestPreconditions/IntDiv.hs b/SBVBenchSuite/BenchSuite/WeakestPreconditions/IntDiv.hs
--- a/SBVBenchSuite/BenchSuite/WeakestPreconditions/IntDiv.hs
+++ b/SBVBenchSuite/BenchSuite/WeakestPreconditions/IntDiv.hs
@@ -10,7 +10,7 @@
 -- Bench suite for Documentation.SBV.Examples.WeakestPreconditions.IntDiv
 -----------------------------------------------------------------------------
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
 module BenchSuite.WeakestPreconditions.IntDiv(benchmarks) where
 
diff --git a/SBVBenchSuite/BenchSuite/WeakestPreconditions/IntSqrt.hs b/SBVBenchSuite/BenchSuite/WeakestPreconditions/IntSqrt.hs
--- a/SBVBenchSuite/BenchSuite/WeakestPreconditions/IntSqrt.hs
+++ b/SBVBenchSuite/BenchSuite/WeakestPreconditions/IntSqrt.hs
@@ -10,7 +10,7 @@
 -- Bench suite for Documentation.SBV.Examples.WeakestPreconditions.IntSqrt
 -----------------------------------------------------------------------------
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
 module BenchSuite.WeakestPreconditions.IntSqrt(benchmarks) where
 
diff --git a/SBVBenchSuite/BenchSuite/WeakestPreconditions/Length.hs b/SBVBenchSuite/BenchSuite/WeakestPreconditions/Length.hs
--- a/SBVBenchSuite/BenchSuite/WeakestPreconditions/Length.hs
+++ b/SBVBenchSuite/BenchSuite/WeakestPreconditions/Length.hs
@@ -10,7 +10,7 @@
 -- Bench suite for Documentation.SBV.Examples.WeakestPreconditions.Length
 -----------------------------------------------------------------------------
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
 module BenchSuite.WeakestPreconditions.Length(benchmarks) where
 
diff --git a/SBVBenchSuite/BenchSuite/WeakestPreconditions/Sum.hs b/SBVBenchSuite/BenchSuite/WeakestPreconditions/Sum.hs
--- a/SBVBenchSuite/BenchSuite/WeakestPreconditions/Sum.hs
+++ b/SBVBenchSuite/BenchSuite/WeakestPreconditions/Sum.hs
@@ -10,7 +10,7 @@
 -- Bench suite for Documentation.SBV.Examples.WeakestPreconditions.Sum
 -----------------------------------------------------------------------------
 
-{-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 {-# LANGUAGE NamedFieldPuns #-}
 
 module BenchSuite.WeakestPreconditions.Sum(benchmarks) where
diff --git a/SBVBenchSuite/Utils/SBVBenchFramework.hs b/SBVBenchSuite/Utils/SBVBenchFramework.hs
--- a/SBVBenchSuite/Utils/SBVBenchFramework.hs
+++ b/SBVBenchSuite/Utils/SBVBenchFramework.hs
@@ -14,7 +14,7 @@
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
 
-{-# OPTIONS_GHC -fno-warn-orphans -fno-warn-missing-methods #-} -- for ProvableM orphan
+{-# OPTIONS_GHC -Wno-orphans -Wno-missing-methods #-} -- for ProvableM orphan
 
 module Utils.SBVBenchFramework
   ( mkExecString
@@ -73,7 +73,7 @@
 
 spaceTo :: Char -> Char -> Char
 spaceTo c x | isSpace x = c
-            | otherwise = x
+            | True      = x
 
 -- | Construct a benchmark file name. The input name should be a time stamp or
 -- whatever you want to name the benchmark
diff --git a/SBVTestSuite/GoldFiles/addSub.gold b/SBVTestSuite/GoldFiles/addSub.gold
--- a/SBVTestSuite/GoldFiles/addSub.gold
+++ b/SBVTestSuite/GoldFiles/addSub.gold
@@ -12,11 +12,11 @@
 addSub.o: addSub.c addSub.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
-addSub_driver.o: addSub_driver.c
+addSub_driver.o: addSub_driver.c addSub.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
 addSub_driver: addSub.o addSub_driver.o
-	${CC} ${CCFLAGS} $^ -o $@
+	${CC} ${CCFLAGS} $^ -o $@ ${LDFLAGS}
 
 clean:
 	rm -f *.o
@@ -27,9 +27,10 @@
 == BEGIN: "addSub.h" ================
 /* Header file for addSub. Automatically generated by SBV. Do not edit! */
 
-#ifndef __addSub__HEADER_INCLUDED__
-#define __addSub__HEADER_INCLUDED__
+#ifndef SBV_GENERATED_addSub_HEADER_INCLUDED
+#define SBV_GENERATED_addSub_HEADER_INCLUDED
 
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <inttypes.h>
@@ -38,6 +39,13 @@
 #include <string.h>
 #include <math.h>
 
+/* Floating-point calling convention:
+ * Enter generated code in FE_TONEAREST (round-to-nearest, ties-to-even).
+ * Callbacks must preserve this mode before returning or re-entering.
+ * Generated code does not check or change the hardware rounding mode.
+ * Custom builds must disable implicit FP contraction, including at LTO link time.
+ */
+
 /* The boolean type */
 typedef bool SBool;
 
@@ -63,7 +71,7 @@
 void addSub(const SWord8 x, const SWord8 y, SWord8 *sum,
             SWord8 *dif);
 
-#endif /* __addSub__HEADER_INCLUDED__ */
+#endif /* SBV_GENERATED_addSub_HEADER_INCLUDED */
 == END: "addSub.h" ==================
 == BEGIN: "addSub_driver.c" ================
 /* Example driver program for addSub. */
@@ -74,14 +82,14 @@
 
 int main(void)
 {
-  SWord8 sum;
-  SWord8 dif;
+  SWord8 sbv_driver_output_0;
+  SWord8 sbv_driver_output_1;
 
-  addSub(76, 92, &sum, &dif);
+  addSub(76, 92, &sbv_driver_output_0, &sbv_driver_output_1);
 
   printf("addSub(76, 92, &sum, &dif) ->\n");
-  printf("  sum = %"PRIu8"\n", sum);
-  printf("  dif = %"PRIu8"\n", dif);
+  printf("  sum = %"PRIu8"\n", sbv_driver_output_0);
+  printf("  dif = %"PRIu8"\n", sbv_driver_output_1);
 
   return 0;
 }
@@ -91,15 +99,37 @@
 
 #include "addSub.h"
 
-void addSub(const SWord8 x, const SWord8 y, SWord8 *sum,
-            SWord8 *dif)
+/* Exact bit-vector runtime. All arithmetic is modulo the declared width. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_u8_add(SWord8 a, SWord8 b)
 {
-  const SWord8 s0 = x;
-  const SWord8 s1 = y;
-  const SWord8 s2 = s0 + s1;
-  const SWord8 s3 = s0 - s1;
+  const SWord8 bits = (SWord8) ((((uint64_t) (SWord8) a) + ((uint64_t) (SWord8) b)) & UINT64_C(0x00000000000000ff));
+  return (SWord8) bits;
+}
 
-  *sum = s2;
-  *dif = s3;
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_u8_sub(SWord8 a, SWord8 b)
+{
+  const SWord8 bits = (SWord8) ((((uint64_t) (SWord8) a) - ((uint64_t) (SWord8) b)) & UINT64_C(0x00000000000000ff));
+  return (SWord8) bits;
+}
+
+
+void addSub(const SWord8 sbv_input_0, const SWord8 sbv_input_1,
+            SWord8 *sbv_output_0, SWord8 *sbv_output_1)
+{
+  const SWord8 s0 = sbv_input_0;
+  const SWord8 s1 = sbv_input_1;
+  const SWord8 s2 = sbv_bv_u8_add(s0, s1);
+  const SWord8 s3 = sbv_bv_u8_sub(s0, s1);
+
+  *sbv_output_0 = s2;
+  *sbv_output_1 = s3;
 }
 == END: "addSub.c" ==================
diff --git a/SBVTestSuite/GoldFiles/adt00.gold b/SBVTestSuite/GoldFiles/adt00.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt00.gold
@@ -0,0 +1,95 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] (declare-datatypes ((SBVTuple3 3)) ((par (T1 T2 T3)
+                                           ((mkSBVTuple3 (proj_1_SBVTuple3 T1)
+                                                         (proj_2_SBVTuple3 T2)
+                                                         (proj_3_SBVTuple3 T3))))))
+[GOOD] ; --- sums ---
+[GOOD] (declare-datatype SBVRational ((SBV.Rational (sbv.rat.numerator Int) (sbv.rat.denominator Int))))
+
+[GOOD] (define-fun sbv.rat.eq ((x SBVRational) (y SBVRational)) Bool
+          (= (* (sbv.rat.numerator   x) (sbv.rat.denominator y))
+             (* (sbv.rat.denominator x) (sbv.rat.numerator   y)))
+       )
+
+[GOOD] (define-fun sbv.rat.notEq ((x SBVRational) (y SBVRational)) Bool
+          (not (sbv.rat.eq x y))
+       )
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Maybe
+[GOOD] (declare-datatype Maybe (par (a) (
+           (Nothing)
+           (Just (getJust_1 a))
+       )))
+[GOOD] ; User defined ADT: Either
+[GOOD] (declare-datatype Either (par (a b) (
+           (Left (getLeft_1 a))
+           (Right (getRight_1 b))
+       )))
+[GOOD] ; User defined ADT: ADT
+[GOOD] (declare-datatype ADT (
+           (AEmpty)
+           (ABool (getABool_1 Bool))
+           (AInteger (getAInteger_1 Int))
+           (AWord8 (getAWord8_1 (_ BitVec 8)))
+           (AWord16 (getAWord16_1 (_ BitVec 16)))
+           (AWord32 (getAWord32_1 (_ BitVec 32)))
+           (AWord64 (getAWord64_1 (_ BitVec 64)))
+           (AInt8 (getAInt8_1 (_ BitVec 8)))
+           (AInt16 (getAInt16_1 (_ BitVec 16)))
+           (AInt32 (getAInt32_1 (_ BitVec 32)))
+           (AInt64 (getAInt64_1 (_ BitVec 64)))
+           (AWord1 (getAWord1_1 (_ BitVec 1)))
+           (AWord5 (getAWord5_1 (_ BitVec 5)))
+           (AWord30 (getAWord30_1 (_ BitVec 30)))
+           (AInt1 (getAInt1_1 (_ BitVec 1)))
+           (AInt5 (getAInt5_1 (_ BitVec 5)))
+           (AInt30 (getAInt30_1 (_ BitVec 30)))
+           (AReal (getAReal_1 Real))
+           (AFloat (getAFloat_1 (_ FloatingPoint  8 24)))
+           (ADouble (getADouble_1 (_ FloatingPoint 11 53)))
+           (AFP (getAFP_1 (_ FloatingPoint 5 12)))
+           (AString (getAString_1 String))
+           (AList (getAList_1 (Seq Int)))
+           (ATuple (getATuple_1 (SBVTuple2 (_ FloatingPoint 11 53) (Seq (SBVTuple2 (_ BitVec 5) (Seq (_ FloatingPoint  8 24)))))))
+           (AMaybe (getAMaybe_1 (Maybe (SBVTuple3 Real (_ FloatingPoint  8 24) (SBVTuple2 (Either Int (_ FloatingPoint  8 24)) (Seq Bool))))))
+           (AEither (getAEither_1 (Either (SBVTuple2 (Maybe Int) Bool) (Seq Int))))
+           (APair (getAPair_1 ADT) (getAPair_2 ADT))
+           (KChar (getKChar_1 String))
+           (KRational (getKRational_1 SBVRational))
+           (KArray (getKArray_1 (Array Int Bool)))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () ADT) ; tracks user variable "e"
+[GOOD] (assert (and (= 1 (str.len (getKChar_1 s0)))
+                    (< 0 (sbv.rat.denominator (getKRational_1 s0)))
+               ))
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool (= s0 s0))
+[GOOD] (define-fun s2 () Bool (not s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[SEND] (check-sat)
+[RECV] unsat
+
+UNSAT*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt01.gold b/SBVTestSuite/GoldFiles/adt01.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt01.gold
@@ -0,0 +1,103 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] (declare-datatypes ((SBVTuple3 3)) ((par (T1 T2 T3)
+                                           ((mkSBVTuple3 (proj_1_SBVTuple3 T1)
+                                                         (proj_2_SBVTuple3 T2)
+                                                         (proj_3_SBVTuple3 T3))))))
+[GOOD] ; --- sums ---
+[GOOD] (declare-datatype SBVRational ((SBV.Rational (sbv.rat.numerator Int) (sbv.rat.denominator Int))))
+
+[GOOD] (define-fun sbv.rat.eq ((x SBVRational) (y SBVRational)) Bool
+          (= (* (sbv.rat.numerator   x) (sbv.rat.denominator y))
+             (* (sbv.rat.denominator x) (sbv.rat.numerator   y)))
+       )
+
+[GOOD] (define-fun sbv.rat.notEq ((x SBVRational) (y SBVRational)) Bool
+          (not (sbv.rat.eq x y))
+       )
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Maybe
+[GOOD] (declare-datatype Maybe (par (a) (
+           (Nothing)
+           (Just (getJust_1 a))
+       )))
+[GOOD] ; User defined ADT: Either
+[GOOD] (declare-datatype Either (par (a b) (
+           (Left (getLeft_1 a))
+           (Right (getRight_1 b))
+       )))
+[GOOD] ; User defined ADT: ADT
+[GOOD] (declare-datatype ADT (
+           (AEmpty)
+           (ABool (getABool_1 Bool))
+           (AInteger (getAInteger_1 Int))
+           (AWord8 (getAWord8_1 (_ BitVec 8)))
+           (AWord16 (getAWord16_1 (_ BitVec 16)))
+           (AWord32 (getAWord32_1 (_ BitVec 32)))
+           (AWord64 (getAWord64_1 (_ BitVec 64)))
+           (AInt8 (getAInt8_1 (_ BitVec 8)))
+           (AInt16 (getAInt16_1 (_ BitVec 16)))
+           (AInt32 (getAInt32_1 (_ BitVec 32)))
+           (AInt64 (getAInt64_1 (_ BitVec 64)))
+           (AWord1 (getAWord1_1 (_ BitVec 1)))
+           (AWord5 (getAWord5_1 (_ BitVec 5)))
+           (AWord30 (getAWord30_1 (_ BitVec 30)))
+           (AInt1 (getAInt1_1 (_ BitVec 1)))
+           (AInt5 (getAInt5_1 (_ BitVec 5)))
+           (AInt30 (getAInt30_1 (_ BitVec 30)))
+           (AReal (getAReal_1 Real))
+           (AFloat (getAFloat_1 (_ FloatingPoint  8 24)))
+           (ADouble (getADouble_1 (_ FloatingPoint 11 53)))
+           (AFP (getAFP_1 (_ FloatingPoint 5 12)))
+           (AString (getAString_1 String))
+           (AList (getAList_1 (Seq Int)))
+           (ATuple (getATuple_1 (SBVTuple2 (_ FloatingPoint 11 53) (Seq (SBVTuple2 (_ BitVec 5) (Seq (_ FloatingPoint  8 24)))))))
+           (AMaybe (getAMaybe_1 (Maybe (SBVTuple3 Real (_ FloatingPoint  8 24) (SBVTuple2 (Either Int (_ FloatingPoint  8 24)) (Seq Bool))))))
+           (AEither (getAEither_1 (Either (SBVTuple2 (Maybe Int) Bool) (Seq Int))))
+           (APair (getAPair_1 ADT) (getAPair_2 ADT))
+           (KChar (getKChar_1 String))
+           (KRational (getKRational_1 SBVRational))
+           (KArray (getKArray_1 (Array Int Bool)))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () ADT ((as APair ADT) ((as AInt64 ADT) #x0000000000000004) ((as AMaybe ADT) ((as Just (Maybe (SBVTuple3 Real (_ FloatingPoint  8 24) (SBVTuple2 (Either Int (_ FloatingPoint  8 24)) (Seq Bool))))) (mkSBVTuple3 0.0 (fp #b0 #b10000010 #b10000000000000000000000) (mkSBVTuple2 ((as Left (Either Int (_ FloatingPoint  8 24))) 3) (seq.++ (seq.unit false) (seq.unit true))))))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () ADT) ; tracks user variable "e"
+[GOOD] (assert (and (= 1 (str.len (getKChar_1 s0)))
+                    (< 0 (sbv.rat.denominator (getKRational_1 s0)))
+               ))
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (APair (AInt64 #x0000000000000004)
+              (AMaybe (Just (mkSBVTuple3 0.0
+                                         (fp #b0 #x82 #b10000000000000000000000)
+                                         (mkSBVTuple2 (Left 3)
+                                                      (seq.++ (seq.unit false)
+                                                              (seq.unit true)))))))))
+
+MODEL: SMTModel {modelObjectives = [], modelBindings = Nothing, modelAssocs = [("e",APair (AInt64 4) (AMaybe (Just (0.0,12.0,(Left 3,[False,True])))) :: ADT)], modelUIFuns = []}
+DONE.*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt02.gold b/SBVTestSuite/GoldFiles/adt02.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt02.gold
@@ -0,0 +1,97 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] (declare-datatypes ((SBVTuple3 3)) ((par (T1 T2 T3)
+                                           ((mkSBVTuple3 (proj_1_SBVTuple3 T1)
+                                                         (proj_2_SBVTuple3 T2)
+                                                         (proj_3_SBVTuple3 T3))))))
+[GOOD] ; --- sums ---
+[GOOD] (declare-datatype SBVRational ((SBV.Rational (sbv.rat.numerator Int) (sbv.rat.denominator Int))))
+
+[GOOD] (define-fun sbv.rat.eq ((x SBVRational) (y SBVRational)) Bool
+          (= (* (sbv.rat.numerator   x) (sbv.rat.denominator y))
+             (* (sbv.rat.denominator x) (sbv.rat.numerator   y)))
+       )
+
+[GOOD] (define-fun sbv.rat.notEq ((x SBVRational) (y SBVRational)) Bool
+          (not (sbv.rat.eq x y))
+       )
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Maybe
+[GOOD] (declare-datatype Maybe (par (a) (
+           (Nothing)
+           (Just (getJust_1 a))
+       )))
+[GOOD] ; User defined ADT: Either
+[GOOD] (declare-datatype Either (par (a b) (
+           (Left (getLeft_1 a))
+           (Right (getRight_1 b))
+       )))
+[GOOD] ; User defined ADT: ADT
+[GOOD] (declare-datatype ADT (
+           (AEmpty)
+           (ABool (getABool_1 Bool))
+           (AInteger (getAInteger_1 Int))
+           (AWord8 (getAWord8_1 (_ BitVec 8)))
+           (AWord16 (getAWord16_1 (_ BitVec 16)))
+           (AWord32 (getAWord32_1 (_ BitVec 32)))
+           (AWord64 (getAWord64_1 (_ BitVec 64)))
+           (AInt8 (getAInt8_1 (_ BitVec 8)))
+           (AInt16 (getAInt16_1 (_ BitVec 16)))
+           (AInt32 (getAInt32_1 (_ BitVec 32)))
+           (AInt64 (getAInt64_1 (_ BitVec 64)))
+           (AWord1 (getAWord1_1 (_ BitVec 1)))
+           (AWord5 (getAWord5_1 (_ BitVec 5)))
+           (AWord30 (getAWord30_1 (_ BitVec 30)))
+           (AInt1 (getAInt1_1 (_ BitVec 1)))
+           (AInt5 (getAInt5_1 (_ BitVec 5)))
+           (AInt30 (getAInt30_1 (_ BitVec 30)))
+           (AReal (getAReal_1 Real))
+           (AFloat (getAFloat_1 (_ FloatingPoint  8 24)))
+           (ADouble (getADouble_1 (_ FloatingPoint 11 53)))
+           (AFP (getAFP_1 (_ FloatingPoint 5 12)))
+           (AString (getAString_1 String))
+           (AList (getAList_1 (Seq Int)))
+           (ATuple (getATuple_1 (SBVTuple2 (_ FloatingPoint 11 53) (Seq (SBVTuple2 (_ BitVec 5) (Seq (_ FloatingPoint  8 24)))))))
+           (AMaybe (getAMaybe_1 (Maybe (SBVTuple3 Real (_ FloatingPoint  8 24) (SBVTuple2 (Either Int (_ FloatingPoint  8 24)) (Seq Bool))))))
+           (AEither (getAEither_1 (Either (SBVTuple2 (Maybe Int) Bool) (Seq Int))))
+           (APair (getAPair_1 ADT) (getAPair_2 ADT))
+           (KChar (getKChar_1 String))
+           (KRational (getKRational_1 SBVRational))
+           (KArray (getKArray_1 (Array Int Bool)))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () ADT) ; tracks user variable "e"
+[GOOD] (assert (and (= 1 (str.len (getKChar_1 s0)))
+                    (< 0 (sbv.rat.denominator (getKRational_1 s0)))
+               ))
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-AList Bool) s0))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s1)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (AList (seq.unit 2))))
+
+MODEL: SMTModel {modelObjectives = [], modelBindings = Nothing, modelAssocs = [("e",AList [2] :: ADT)], modelUIFuns = []}
+DONE.*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt03.gold b/SBVTestSuite/GoldFiles/adt03.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt03.gold
@@ -0,0 +1,96 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] (declare-datatypes ((SBVTuple3 3)) ((par (T1 T2 T3)
+                                           ((mkSBVTuple3 (proj_1_SBVTuple3 T1)
+                                                         (proj_2_SBVTuple3 T2)
+                                                         (proj_3_SBVTuple3 T3))))))
+[GOOD] ; --- sums ---
+[GOOD] (declare-datatype SBVRational ((SBV.Rational (sbv.rat.numerator Int) (sbv.rat.denominator Int))))
+
+[GOOD] (define-fun sbv.rat.eq ((x SBVRational) (y SBVRational)) Bool
+          (= (* (sbv.rat.numerator   x) (sbv.rat.denominator y))
+             (* (sbv.rat.denominator x) (sbv.rat.numerator   y)))
+       )
+
+[GOOD] (define-fun sbv.rat.notEq ((x SBVRational) (y SBVRational)) Bool
+          (not (sbv.rat.eq x y))
+       )
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Maybe
+[GOOD] (declare-datatype Maybe (par (a) (
+           (Nothing)
+           (Just (getJust_1 a))
+       )))
+[GOOD] ; User defined ADT: Either
+[GOOD] (declare-datatype Either (par (a b) (
+           (Left (getLeft_1 a))
+           (Right (getRight_1 b))
+       )))
+[GOOD] ; User defined ADT: ADT
+[GOOD] (declare-datatype ADT (
+           (AEmpty)
+           (ABool (getABool_1 Bool))
+           (AInteger (getAInteger_1 Int))
+           (AWord8 (getAWord8_1 (_ BitVec 8)))
+           (AWord16 (getAWord16_1 (_ BitVec 16)))
+           (AWord32 (getAWord32_1 (_ BitVec 32)))
+           (AWord64 (getAWord64_1 (_ BitVec 64)))
+           (AInt8 (getAInt8_1 (_ BitVec 8)))
+           (AInt16 (getAInt16_1 (_ BitVec 16)))
+           (AInt32 (getAInt32_1 (_ BitVec 32)))
+           (AInt64 (getAInt64_1 (_ BitVec 64)))
+           (AWord1 (getAWord1_1 (_ BitVec 1)))
+           (AWord5 (getAWord5_1 (_ BitVec 5)))
+           (AWord30 (getAWord30_1 (_ BitVec 30)))
+           (AInt1 (getAInt1_1 (_ BitVec 1)))
+           (AInt5 (getAInt5_1 (_ BitVec 5)))
+           (AInt30 (getAInt30_1 (_ BitVec 30)))
+           (AReal (getAReal_1 Real))
+           (AFloat (getAFloat_1 (_ FloatingPoint  8 24)))
+           (ADouble (getADouble_1 (_ FloatingPoint 11 53)))
+           (AFP (getAFP_1 (_ FloatingPoint 5 12)))
+           (AString (getAString_1 String))
+           (AList (getAList_1 (Seq Int)))
+           (ATuple (getATuple_1 (SBVTuple2 (_ FloatingPoint 11 53) (Seq (SBVTuple2 (_ BitVec 5) (Seq (_ FloatingPoint  8 24)))))))
+           (AMaybe (getAMaybe_1 (Maybe (SBVTuple3 Real (_ FloatingPoint  8 24) (SBVTuple2 (Either Int (_ FloatingPoint  8 24)) (Seq Bool))))))
+           (AEither (getAEither_1 (Either (SBVTuple2 (Maybe Int) Bool) (Seq Int))))
+           (APair (getAPair_1 ADT) (getAPair_2 ADT))
+           (KChar (getKChar_1 String))
+           (KRational (getKRational_1 SBVRational))
+           (KArray (getKArray_1 (Array Int Bool)))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () ADT) ; tracks user variable "e"
+[GOOD] (assert (and (= 1 (str.len (getKChar_1 s0)))
+                    (< 0 (sbv.rat.denominator (getKRational_1 s0)))
+               ))
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-AList Bool) s0))
+[GOOD] (define-fun s2 () Bool ((as is-AFP Bool) s0))
+[GOOD] (define-fun s3 () Bool (and s1 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s3)
+[SEND] (check-sat)
+[RECV] unsat
+
+UNSAT*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt04.gold b/SBVTestSuite/GoldFiles/adt04.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt04.gold
@@ -0,0 +1,181 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] (declare-datatypes ((SBVTuple3 3)) ((par (T1 T2 T3)
+                                           ((mkSBVTuple3 (proj_1_SBVTuple3 T1)
+                                                         (proj_2_SBVTuple3 T2)
+                                                         (proj_3_SBVTuple3 T3))))))
+[GOOD] ; --- sums ---
+[GOOD] (declare-datatype SBVRational ((SBV.Rational (sbv.rat.numerator Int) (sbv.rat.denominator Int))))
+
+[GOOD] (define-fun sbv.rat.eq ((x SBVRational) (y SBVRational)) Bool
+          (= (* (sbv.rat.numerator   x) (sbv.rat.denominator y))
+             (* (sbv.rat.denominator x) (sbv.rat.numerator   y)))
+       )
+
+[GOOD] (define-fun sbv.rat.notEq ((x SBVRational) (y SBVRational)) Bool
+          (not (sbv.rat.eq x y))
+       )
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Maybe
+[GOOD] (declare-datatype Maybe (par (a) (
+           (Nothing)
+           (Just (getJust_1 a))
+       )))
+[GOOD] ; User defined ADT: Either
+[GOOD] (declare-datatype Either (par (a b) (
+           (Left (getLeft_1 a))
+           (Right (getRight_1 b))
+       )))
+[GOOD] ; User defined ADT: ADT
+[GOOD] (declare-datatype ADT (
+           (AEmpty)
+           (ABool (getABool_1 Bool))
+           (AInteger (getAInteger_1 Int))
+           (AWord8 (getAWord8_1 (_ BitVec 8)))
+           (AWord16 (getAWord16_1 (_ BitVec 16)))
+           (AWord32 (getAWord32_1 (_ BitVec 32)))
+           (AWord64 (getAWord64_1 (_ BitVec 64)))
+           (AInt8 (getAInt8_1 (_ BitVec 8)))
+           (AInt16 (getAInt16_1 (_ BitVec 16)))
+           (AInt32 (getAInt32_1 (_ BitVec 32)))
+           (AInt64 (getAInt64_1 (_ BitVec 64)))
+           (AWord1 (getAWord1_1 (_ BitVec 1)))
+           (AWord5 (getAWord5_1 (_ BitVec 5)))
+           (AWord30 (getAWord30_1 (_ BitVec 30)))
+           (AInt1 (getAInt1_1 (_ BitVec 1)))
+           (AInt5 (getAInt5_1 (_ BitVec 5)))
+           (AInt30 (getAInt30_1 (_ BitVec 30)))
+           (AReal (getAReal_1 Real))
+           (AFloat (getAFloat_1 (_ FloatingPoint  8 24)))
+           (ADouble (getADouble_1 (_ FloatingPoint 11 53)))
+           (AFP (getAFP_1 (_ FloatingPoint 5 12)))
+           (AString (getAString_1 String))
+           (AList (getAList_1 (Seq Int)))
+           (ATuple (getATuple_1 (SBVTuple2 (_ FloatingPoint 11 53) (Seq (SBVTuple2 (_ BitVec 5) (Seq (_ FloatingPoint  8 24)))))))
+           (AMaybe (getAMaybe_1 (Maybe (SBVTuple3 Real (_ FloatingPoint  8 24) (SBVTuple2 (Either Int (_ FloatingPoint  8 24)) (Seq Bool))))))
+           (AEither (getAEither_1 (Either (SBVTuple2 (Maybe Int) Bool) (Seq Int))))
+           (APair (getAPair_1 ADT) (getAPair_2 ADT))
+           (KChar (getKChar_1 String))
+           (KRational (getKRational_1 SBVRational))
+           (KArray (getKArray_1 (Array Int Bool)))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () Int 0)
+[GOOD] (define-fun s5 () Int 5)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () ADT) ; tracks user variable "a"
+[GOOD] (assert (and (= 1 (str.len (getKChar_1 s0)))
+                    (< 0 (sbv.rat.denominator (getKRational_1 s0)))
+               ))
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-AInteger Bool) s0))
+[GOOD] (define-fun s2 () Int (getAInteger_1 s0))
+[GOOD] (define-fun s4 () Bool (>= s2 s3))
+[GOOD] (define-fun s6 () Bool (<= s2 s5))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s1)
+[GOOD] (assert s4)
+[GOOD] (assert s6)
+*** Checking Satisfiability, all solutions..
+Fast allSat, Looking for solution 1
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (AInteger 4)))
+[GOOD] (push 1)
+[GOOD] (define-fun s7 () ADT ((as AInteger ADT) 4))
+[GOOD] (define-fun s8 () Bool (= s0 s7))
+[GOOD] (define-fun s9 () Bool (not s8))
+[GOOD] (assert s9)
+Fast allSat, Looking for solution 2
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (AInteger 0)))
+[GOOD] (push 1)
+[GOOD] (define-fun s10 () ADT ((as AInteger ADT) 0))
+[GOOD] (define-fun s11 () Bool (= s0 s10))
+[GOOD] (define-fun s12 () Bool (not s11))
+[GOOD] (assert s12)
+Fast allSat, Looking for solution 3
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (AInteger 3)))
+[GOOD] (push 1)
+[GOOD] (define-fun s13 () ADT ((as AInteger ADT) 3))
+[GOOD] (define-fun s14 () Bool (= s0 s13))
+[GOOD] (define-fun s15 () Bool (not s14))
+[GOOD] (assert s15)
+Fast allSat, Looking for solution 4
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (AInteger 5)))
+[GOOD] (push 1)
+[GOOD] (define-fun s16 () ADT ((as AInteger ADT) 5))
+[GOOD] (define-fun s17 () Bool (= s0 s16))
+[GOOD] (define-fun s18 () Bool (not s17))
+[GOOD] (assert s18)
+Fast allSat, Looking for solution 5
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (AInteger 2)))
+[GOOD] (push 1)
+[GOOD] (define-fun s19 () ADT ((as AInteger ADT) 2))
+[GOOD] (define-fun s20 () Bool (= s0 s19))
+[GOOD] (define-fun s21 () Bool (not s20))
+[GOOD] (assert s21)
+Fast allSat, Looking for solution 6
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (AInteger 1)))
+[GOOD] (push 1)
+[GOOD] (define-fun s22 () ADT ((as AInteger ADT) 1))
+[GOOD] (define-fun s23 () Bool (= s0 s22))
+[GOOD] (define-fun s24 () Bool (not s23))
+[GOOD] (assert s24)
+Fast allSat, Looking for solution 7
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+
+MODEL:Satisfiable. Model:
+  a = AInteger 1 :: ADT
+MODEL:Satisfiable. Model:
+  a = AInteger 2 :: ADT
+MODEL:Satisfiable. Model:
+  a = AInteger 5 :: ADT
+MODEL:Satisfiable. Model:
+  a = AInteger 3 :: ADT
+MODEL:Satisfiable. Model:
+  a = AInteger 0 :: ADT
+MODEL:Satisfiable. Model:
+  a = AInteger 4 :: ADT
diff --git a/SBVTestSuite/GoldFiles/adt05.gold b/SBVTestSuite/GoldFiles/adt05.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt05.gold
@@ -0,0 +1,131 @@
+** Calling: cvc5 --lang smt --incremental --nl-cov
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic HO_ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] (declare-datatypes ((SBVTuple3 3)) ((par (T1 T2 T3)
+                                           ((mkSBVTuple3 (proj_1_SBVTuple3 T1)
+                                                         (proj_2_SBVTuple3 T2)
+                                                         (proj_3_SBVTuple3 T3))))))
+[GOOD] ; --- sums ---
+[GOOD] (declare-datatype SBVRational ((SBV.Rational (sbv.rat.numerator Int) (sbv.rat.denominator Int))))
+
+[GOOD] (define-fun sbv.rat.eq ((x SBVRational) (y SBVRational)) Bool
+          (= (* (sbv.rat.numerator   x) (sbv.rat.denominator y))
+             (* (sbv.rat.denominator x) (sbv.rat.numerator   y)))
+       )
+
+[GOOD] (define-fun sbv.rat.notEq ((x SBVRational) (y SBVRational)) Bool
+          (not (sbv.rat.eq x y))
+       )
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Maybe
+[GOOD] (declare-datatype Maybe (par (a) (
+           (Nothing)
+           (Just (getJust_1 a))
+       )))
+[GOOD] ; User defined ADT: Either
+[GOOD] (declare-datatype Either (par (a b) (
+           (Left (getLeft_1 a))
+           (Right (getRight_1 b))
+       )))
+[GOOD] ; User defined ADT: ADT
+[GOOD] (declare-datatype ADT (
+           (AEmpty)
+           (ABool (getABool_1 Bool))
+           (AInteger (getAInteger_1 Int))
+           (AWord8 (getAWord8_1 (_ BitVec 8)))
+           (AWord16 (getAWord16_1 (_ BitVec 16)))
+           (AWord32 (getAWord32_1 (_ BitVec 32)))
+           (AWord64 (getAWord64_1 (_ BitVec 64)))
+           (AInt8 (getAInt8_1 (_ BitVec 8)))
+           (AInt16 (getAInt16_1 (_ BitVec 16)))
+           (AInt32 (getAInt32_1 (_ BitVec 32)))
+           (AInt64 (getAInt64_1 (_ BitVec 64)))
+           (AWord1 (getAWord1_1 (_ BitVec 1)))
+           (AWord5 (getAWord5_1 (_ BitVec 5)))
+           (AWord30 (getAWord30_1 (_ BitVec 30)))
+           (AInt1 (getAInt1_1 (_ BitVec 1)))
+           (AInt5 (getAInt5_1 (_ BitVec 5)))
+           (AInt30 (getAInt30_1 (_ BitVec 30)))
+           (AReal (getAReal_1 Real))
+           (AFloat (getAFloat_1 (_ FloatingPoint  8 24)))
+           (ADouble (getADouble_1 (_ FloatingPoint 11 53)))
+           (AFP (getAFP_1 (_ FloatingPoint 5 12)))
+           (AString (getAString_1 String))
+           (AList (getAList_1 (Seq Int)))
+           (ATuple (getATuple_1 (SBVTuple2 (_ FloatingPoint 11 53) (Seq (SBVTuple2 (_ BitVec 5) (Seq (_ FloatingPoint  8 24)))))))
+           (AMaybe (getAMaybe_1 (Maybe (SBVTuple3 Real (_ FloatingPoint  8 24) (SBVTuple2 (Either Int (_ FloatingPoint  8 24)) (Seq Bool))))))
+           (AEither (getAEither_1 (Either (SBVTuple2 (Maybe Int) Bool) (Seq Int))))
+           (APair (getAPair_1 ADT) (getAPair_2 ADT))
+           (KChar (getKChar_1 String))
+           (KRational (getKRational_1 SBVRational))
+           (KArray (getKArray_1 (Array Int Bool)))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s4 () (_ FloatingPoint  8 24) (fp #b0 #b10000001 #b00000000000000000000000))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () ADT) ; tracks user variable "a"
+[GOOD] (assert (and (= 1 (str.len (getKChar_1 s0)))
+                    (< 0 (sbv.rat.denominator (getKRational_1 s0)))
+               ))
+[GOOD] (declare-fun s1 () ADT) ; tracks user variable "b"
+[GOOD] (assert (and (= 1 (str.len (getKChar_1 s1)))
+                    (< 0 (sbv.rat.denominator (getKRational_1 s1)))
+               ))
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (is-AFloat s0))
+[GOOD] (define-fun s3 () (_ FloatingPoint  8 24) (getAFloat_1 s0))
+[GOOD] (define-fun s5 () Bool (fp.eq s3 s4))
+[GOOD] (define-fun s6 () Bool (and s2 s5))
+[GOOD] (define-fun s7 () Bool (is-AFloat s1))
+[GOOD] (define-fun s8 () (_ FloatingPoint  8 24) (getAFloat_1 s1))
+[GOOD] (define-fun s9 () Bool (fp.isNaN s8))
+[GOOD] (define-fun s10 () Bool (and s7 s9))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s6)
+[GOOD] (assert s10)
+*** Checking Satisfiability, all solutions..
+Fast allSat, Looking for solution 1
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (AFloat (fp #b0 #b10000001 #b00000000000000000000000))))
+[SEND] (get-value (s1))
+[RECV] ((s1 (AFloat (fp #b0 #b11111111 #b10000000000000000000000))))
+[GOOD] (push 1)
+[GOOD] (define-fun s11 () ADT ((as AFloat ADT) (fp #b0 #b10000001 #b00000000000000000000000)))
+[GOOD] (define-fun s12 () Bool (= s0 s11))
+[GOOD] (define-fun s13 () Bool (not s12))
+[GOOD] (assert s13)
+Fast allSat, Looking for solution 2
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (define-fun s14 () ADT ((as AFloat ADT) (_ NaN 8 24)))
+[GOOD] (define-fun s15 () Bool (= s1 s14))
+[GOOD] (define-fun s16 () Bool (not s15))
+[GOOD] (assert s16)
+[GOOD] (assert s12)
+Fast allSat, Looking for solution 2
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+*** Solver   : CVC5
+*** Exit code: ExitSuccess
+
+MODEL:Satisfiable. Model:
+  a = AFloat 4.0 :: ADT
+  b = AFloat NaN :: ADT
diff --git a/SBVTestSuite/GoldFiles/adt06.gold b/SBVTestSuite/GoldFiles/adt06.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt06.gold
@@ -0,0 +1,104 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] (declare-datatypes ((SBVTuple3 3)) ((par (T1 T2 T3)
+                                           ((mkSBVTuple3 (proj_1_SBVTuple3 T1)
+                                                         (proj_2_SBVTuple3 T2)
+                                                         (proj_3_SBVTuple3 T3))))))
+[GOOD] ; --- sums ---
+[GOOD] (declare-datatype SBVRational ((SBV.Rational (sbv.rat.numerator Int) (sbv.rat.denominator Int))))
+
+[GOOD] (define-fun sbv.rat.eq ((x SBVRational) (y SBVRational)) Bool
+          (= (* (sbv.rat.numerator   x) (sbv.rat.denominator y))
+             (* (sbv.rat.denominator x) (sbv.rat.numerator   y)))
+       )
+
+[GOOD] (define-fun sbv.rat.notEq ((x SBVRational) (y SBVRational)) Bool
+          (not (sbv.rat.eq x y))
+       )
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Maybe
+[GOOD] (declare-datatype Maybe (par (a) (
+           (Nothing)
+           (Just (getJust_1 a))
+       )))
+[GOOD] ; User defined ADT: Either
+[GOOD] (declare-datatype Either (par (a b) (
+           (Left (getLeft_1 a))
+           (Right (getRight_1 b))
+       )))
+[GOOD] ; User defined ADT: ADT
+[GOOD] (declare-datatype ADT (
+           (AEmpty)
+           (ABool (getABool_1 Bool))
+           (AInteger (getAInteger_1 Int))
+           (AWord8 (getAWord8_1 (_ BitVec 8)))
+           (AWord16 (getAWord16_1 (_ BitVec 16)))
+           (AWord32 (getAWord32_1 (_ BitVec 32)))
+           (AWord64 (getAWord64_1 (_ BitVec 64)))
+           (AInt8 (getAInt8_1 (_ BitVec 8)))
+           (AInt16 (getAInt16_1 (_ BitVec 16)))
+           (AInt32 (getAInt32_1 (_ BitVec 32)))
+           (AInt64 (getAInt64_1 (_ BitVec 64)))
+           (AWord1 (getAWord1_1 (_ BitVec 1)))
+           (AWord5 (getAWord5_1 (_ BitVec 5)))
+           (AWord30 (getAWord30_1 (_ BitVec 30)))
+           (AInt1 (getAInt1_1 (_ BitVec 1)))
+           (AInt5 (getAInt5_1 (_ BitVec 5)))
+           (AInt30 (getAInt30_1 (_ BitVec 30)))
+           (AReal (getAReal_1 Real))
+           (AFloat (getAFloat_1 (_ FloatingPoint  8 24)))
+           (ADouble (getADouble_1 (_ FloatingPoint 11 53)))
+           (AFP (getAFP_1 (_ FloatingPoint 5 12)))
+           (AString (getAString_1 String))
+           (AList (getAList_1 (Seq Int)))
+           (ATuple (getATuple_1 (SBVTuple2 (_ FloatingPoint 11 53) (Seq (SBVTuple2 (_ BitVec 5) (Seq (_ FloatingPoint  8 24)))))))
+           (AMaybe (getAMaybe_1 (Maybe (SBVTuple3 Real (_ FloatingPoint  8 24) (SBVTuple2 (Either Int (_ FloatingPoint  8 24)) (Seq Bool))))))
+           (AEither (getAEither_1 (Either (SBVTuple2 (Maybe Int) Bool) (Seq Int))))
+           (APair (getAPair_1 ADT) (getAPair_2 ADT))
+           (KChar (getKChar_1 String))
+           (KRational (getKRational_1 SBVRational))
+           (KArray (getKArray_1 (Array Int Bool)))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () ADT) ; tracks user variable "a"
+[GOOD] (assert (and (= 1 (str.len (getKChar_1 s0)))
+                    (< 0 (sbv.rat.denominator (getKRational_1 s0)))
+               ))
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-AMaybe Bool) s0))
+[GOOD] (define-fun s2 () (Maybe (SBVTuple3 Real (_ FloatingPoint  8 24) (SBVTuple2 (Either Int (_ FloatingPoint  8 24)) (Seq Bool)))) (getAMaybe_1 s0))
+[GOOD] (define-fun s3 () Bool ((as is-Just Bool) s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s1)
+[GOOD] (assert s3)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (AMaybe (Just (mkSBVTuple3 2.0
+                                  (fp #b0 #x00 #b00000000000000000000001)
+                                  (mkSBVTuple2 (Right (fp #b0 #x00 #b00000000000000000100000))
+                                               (seq.unit false)))))))
+
+getValue: AMaybe (Just (2.0,1.0e-45,(Right 4.5e-44,[False])))
+DONE
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt07.gold b/SBVTestSuite/GoldFiles/adt07.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt07.gold
@@ -0,0 +1,44 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Either
+[GOOD] (declare-datatype Either (par (a b) (
+           (Left (getLeft_1 a))
+           (Right (getRight_1 b))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (Either Int (SBVTuple2 Int (Array Int Bool))) ((as Right (Either Int (SBVTuple2 Int (Array Int Bool)))) (mkSBVTuple2 4 (store ((as const (Array Int Bool)) false) 2 true))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Either Int (SBVTuple2 Int (Array Int Bool)))) ; tracks user variable "a"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (Right (mkSBVTuple2 4 (store ((as const (Array Int Bool)) false) 2 true)))))
+
+getValue: Right (4,{2})
+DONE
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt08.gold b/SBVTestSuite/GoldFiles/adt08.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt08.gold
@@ -0,0 +1,55 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Probe
+[GOOD] (declare-datatype Probe (
+           (PSet (getPSet_1 (Array Int Bool)))
+           (PArr (getPArr_1 (Array Int Bool)))
+           (PInt (getPInt_1 Int))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s4 () (Array Int Bool) (store ((as const (Array Int Bool)) false) 2 true))
+[GOOD] (define-fun s9 () Int 3)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Probe) ; tracks user variable "a"
+[GOOD] (declare-fun s1 () Probe) ; tracks user variable "b"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool ((as is-PSet Bool) s0))
+[GOOD] (define-fun s3 () (Array Int Bool) (getPSet_1 s0))
+[GOOD] (define-fun s5 () Bool (= s3 s4))
+[GOOD] (define-fun s6 () Bool (and s2 s5))
+[GOOD] (define-fun s7 () Bool ((as is-PArr Bool) s1))
+[GOOD] (define-fun s8 () (Array Int Bool) (getPArr_1 s1))
+[GOOD] (define-fun s10 () Bool (select s8 s9))
+[GOOD] (define-fun s11 () Bool (and s7 s10))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s6)
+[GOOD] (assert s11)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (PSet (store ((as const (Array Int Bool)) false) 2 true))))
+[SEND] (get-value (s1))
+[RECV] ((s1 (PArr ((as const (Array Int Bool)) true))))
+
+getValue a: PSet {2}
+getValue b: PArr (ArrayModel [] True)
+DONE
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_chk01.gold b/SBVTestSuite/GoldFiles/adt_chk01.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_chk01.gold
@@ -0,0 +1,40 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: A
+[GOOD] (declare-datatype A (
+           (A (getA_1 Int))
+           (B (getB_1 (_ BitVec 8)))
+           (C (getC_1 A) (getC_2 A))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () A ((as A A) 13))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () A) ; tracks user variable "res"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (A 13)))
+Result: A 13
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr00.gold b/SBVTestSuite/GoldFiles/adt_expr00.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr00.gold
@@ -0,0 +1,219 @@
+[MEASURE] Verifying termination measures for: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): not in a multi-member cycle, skipping mutual check
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): barified = "|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|"
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2)]
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): recursive calls found = 6
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): trying sbv.dt.size.Expr arg2
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK (structural recursion)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): barified = "|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|"
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2)]
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): recursive calls found = 1
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): trying length arg1
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Bool (>= s4 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Int (seq.len s13))
+[GOOD] (define-fun s18 () Bool (not s10))
+[GOOD] (define-fun s19 () Bool (and s6 s18))
+[GOOD] (define-fun s20 () Bool (> s4 s17))
+[GOOD] (define-fun s21 () Bool (=> s19 s20))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): length arg1 -> OK
+[MEASURE] Passed (terminating): get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Val Expr) 3))
+[GOOD] (define-fun s3 () (Seq (SBVTuple2 String Int)) (as seq.empty (Seq (SBVTuple2 String Int))))
+[GOOD] (define-fun s5 () Int 3)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| :: [(SString, SInteger)] -> SString -> SInteger [Recursive]
+[GOOD] (define-fun-rec |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| ((l2_s0 (Seq (SBVTuple2 String Int))) (l2_s1 String)) Int
+                                                 (let ((l2_s3 0))
+                                                 (let ((l2_s11 1))
+                                                 (let ((l2_s2 (seq.len l2_s0)))
+                                                 (let ((l2_s4 (= l2_s2 l2_s3)))
+                                                 (let ((l2_s5 (not l2_s4)))
+                                                 (let ((l2_s6 (seq.nth l2_s0 l2_s3)))
+                                                 (let ((l2_s7 (proj_1_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s8 (= l2_s1 l2_s7)))
+                                                 (let ((l2_s9 (and l2_s5 l2_s8)))
+                                                 (let ((l2_s10 (proj_2_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s12 (- l2_s2 l2_s11)))
+                                                 (let ((l2_s13 (seq.extract l2_s0 l2_s11 l2_s12)))
+                                                 (let ((l2_s14 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l2_s13 l2_s1)))
+                                                 (let ((l2_s15 (ite l2_s9 l2_s10 l2_s14)))
+                                                 (let ((l2_s16 (ite l2_s4 l2_s3 l2_s15)))
+                                                 l2_s16))))))))))))))))
+[GOOD] ; |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| :: [(SString, SInteger)] -> Expr -> SInteger [Recursive] [Refers to: |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|]
+[GOOD] (define-fun-rec |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| ((l1_s0 (Seq (SBVTuple2 String Int))) (l1_s1 Expr)) Int
+                                 (let ((l1_s2 ((as is-Val Bool) l1_s1)))
+                                 (let ((l1_s3 (getVal_1 l1_s1)))
+                                 (let ((l1_s4 ((as is-Var Bool) l1_s1)))
+                                 (let ((l1_s5 (getVar_1 l1_s1)))
+                                 (let ((l1_s6 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l1_s0 l1_s5)))
+                                 (let ((l1_s7 ((as is-Add Bool) l1_s1)))
+                                 (let ((l1_s8 (getAdd_1 l1_s1)))
+                                 (let ((l1_s9 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s8)))
+                                 (let ((l1_s10 (getAdd_2 l1_s1)))
+                                 (let ((l1_s11 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s10)))
+                                 (let ((l1_s12 (+ l1_s9 l1_s11)))
+                                 (let ((l1_s13 ((as is-Mul Bool) l1_s1)))
+                                 (let ((l1_s14 (getMul_1 l1_s1)))
+                                 (let ((l1_s15 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s14)))
+                                 (let ((l1_s16 (getMul_2 l1_s1)))
+                                 (let ((l1_s17 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s16)))
+                                 (let ((l1_s18 (* l1_s15 l1_s17)))
+                                 (let ((l1_s19 (getLet_1 l1_s1)))
+                                 (let ((l1_s20 (getLet_2 l1_s1)))
+                                 (let ((l1_s21 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s20)))
+                                 (let ((l1_s22 ((as mkSBVTuple2 (SBVTuple2 String Int)) l1_s19 l1_s21)))
+                                 (let ((l1_s23 (seq.unit l1_s22)))
+                                 (let ((l1_s24 (seq.++ l1_s23 l1_s0)))
+                                 (let ((l1_s25 (getLet_3 l1_s1)))
+                                 (let ((l1_s26 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s24 l1_s25)))
+                                 (let ((l1_s27 (ite l1_s13 l1_s18 l1_s26)))
+                                 (let ((l1_s28 (ite l1_s7 l1_s12 l1_s27)))
+                                 (let ((l1_s29 (ite l1_s4 l1_s6 l1_s28)))
+                                 (let ((l1_s30 (ite l1_s2 l1_s3 l1_s29)))
+                                 l1_s30))))))))))))))))))))))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s4 () Int (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| s3 s0))
+[GOOD] (define-fun s6 () Bool (distinct s4 s5))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s6)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr00c.gold b/SBVTestSuite/GoldFiles/adt_expr00c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr00c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr01.gold b/SBVTestSuite/GoldFiles/adt_expr01.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr01.gold
@@ -0,0 +1,219 @@
+[MEASURE] Verifying termination measures for: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): not in a multi-member cycle, skipping mutual check
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): barified = "|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|"
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2)]
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): recursive calls found = 6
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): trying sbv.dt.size.Expr arg2
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK (structural recursion)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): barified = "|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|"
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2)]
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): recursive calls found = 1
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): trying length arg1
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Bool (>= s4 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Int (seq.len s13))
+[GOOD] (define-fun s18 () Bool (not s10))
+[GOOD] (define-fun s19 () Bool (and s6 s18))
+[GOOD] (define-fun s20 () Bool (> s4 s17))
+[GOOD] (define-fun s21 () Bool (=> s19 s20))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): length arg1 -> OK
+[MEASURE] Passed (terminating): get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Add Expr) ((as Val Expr) 3) ((as Val Expr) 4)))
+[GOOD] (define-fun s3 () (Seq (SBVTuple2 String Int)) (as seq.empty (Seq (SBVTuple2 String Int))))
+[GOOD] (define-fun s5 () Int 7)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| :: [(SString, SInteger)] -> SString -> SInteger [Recursive]
+[GOOD] (define-fun-rec |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| ((l2_s0 (Seq (SBVTuple2 String Int))) (l2_s1 String)) Int
+                                                 (let ((l2_s3 0))
+                                                 (let ((l2_s11 1))
+                                                 (let ((l2_s2 (seq.len l2_s0)))
+                                                 (let ((l2_s4 (= l2_s2 l2_s3)))
+                                                 (let ((l2_s5 (not l2_s4)))
+                                                 (let ((l2_s6 (seq.nth l2_s0 l2_s3)))
+                                                 (let ((l2_s7 (proj_1_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s8 (= l2_s1 l2_s7)))
+                                                 (let ((l2_s9 (and l2_s5 l2_s8)))
+                                                 (let ((l2_s10 (proj_2_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s12 (- l2_s2 l2_s11)))
+                                                 (let ((l2_s13 (seq.extract l2_s0 l2_s11 l2_s12)))
+                                                 (let ((l2_s14 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l2_s13 l2_s1)))
+                                                 (let ((l2_s15 (ite l2_s9 l2_s10 l2_s14)))
+                                                 (let ((l2_s16 (ite l2_s4 l2_s3 l2_s15)))
+                                                 l2_s16))))))))))))))))
+[GOOD] ; |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| :: [(SString, SInteger)] -> Expr -> SInteger [Recursive] [Refers to: |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|]
+[GOOD] (define-fun-rec |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| ((l1_s0 (Seq (SBVTuple2 String Int))) (l1_s1 Expr)) Int
+                                 (let ((l1_s2 ((as is-Val Bool) l1_s1)))
+                                 (let ((l1_s3 (getVal_1 l1_s1)))
+                                 (let ((l1_s4 ((as is-Var Bool) l1_s1)))
+                                 (let ((l1_s5 (getVar_1 l1_s1)))
+                                 (let ((l1_s6 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l1_s0 l1_s5)))
+                                 (let ((l1_s7 ((as is-Add Bool) l1_s1)))
+                                 (let ((l1_s8 (getAdd_1 l1_s1)))
+                                 (let ((l1_s9 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s8)))
+                                 (let ((l1_s10 (getAdd_2 l1_s1)))
+                                 (let ((l1_s11 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s10)))
+                                 (let ((l1_s12 (+ l1_s9 l1_s11)))
+                                 (let ((l1_s13 ((as is-Mul Bool) l1_s1)))
+                                 (let ((l1_s14 (getMul_1 l1_s1)))
+                                 (let ((l1_s15 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s14)))
+                                 (let ((l1_s16 (getMul_2 l1_s1)))
+                                 (let ((l1_s17 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s16)))
+                                 (let ((l1_s18 (* l1_s15 l1_s17)))
+                                 (let ((l1_s19 (getLet_1 l1_s1)))
+                                 (let ((l1_s20 (getLet_2 l1_s1)))
+                                 (let ((l1_s21 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s20)))
+                                 (let ((l1_s22 ((as mkSBVTuple2 (SBVTuple2 String Int)) l1_s19 l1_s21)))
+                                 (let ((l1_s23 (seq.unit l1_s22)))
+                                 (let ((l1_s24 (seq.++ l1_s23 l1_s0)))
+                                 (let ((l1_s25 (getLet_3 l1_s1)))
+                                 (let ((l1_s26 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s24 l1_s25)))
+                                 (let ((l1_s27 (ite l1_s13 l1_s18 l1_s26)))
+                                 (let ((l1_s28 (ite l1_s7 l1_s12 l1_s27)))
+                                 (let ((l1_s29 (ite l1_s4 l1_s6 l1_s28)))
+                                 (let ((l1_s30 (ite l1_s2 l1_s3 l1_s29)))
+                                 l1_s30))))))))))))))))))))))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s4 () Int (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| s3 s0))
+[GOOD] (define-fun s6 () Bool (distinct s4 s5))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s6)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr01c.gold b/SBVTestSuite/GoldFiles/adt_expr01c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr01c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr02.gold b/SBVTestSuite/GoldFiles/adt_expr02.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr02.gold
@@ -0,0 +1,219 @@
+[MEASURE] Verifying termination measures for: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): not in a multi-member cycle, skipping mutual check
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): barified = "|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|"
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2)]
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): recursive calls found = 6
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): trying sbv.dt.size.Expr arg2
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK (structural recursion)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): barified = "|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|"
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2)]
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): recursive calls found = 1
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): trying length arg1
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Bool (>= s4 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Int (seq.len s13))
+[GOOD] (define-fun s18 () Bool (not s10))
+[GOOD] (define-fun s19 () Bool (and s6 s18))
+[GOOD] (define-fun s20 () Bool (> s4 s17))
+[GOOD] (define-fun s21 () Bool (=> s19 s20))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): length arg1 -> OK
+[MEASURE] Passed (terminating): get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Mul Expr) ((as Val Expr) 3) ((as Add Expr) ((as Val Expr) 3) ((as Val Expr) 4))))
+[GOOD] (define-fun s3 () (Seq (SBVTuple2 String Int)) (as seq.empty (Seq (SBVTuple2 String Int))))
+[GOOD] (define-fun s5 () Int 21)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| :: [(SString, SInteger)] -> SString -> SInteger [Recursive]
+[GOOD] (define-fun-rec |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| ((l2_s0 (Seq (SBVTuple2 String Int))) (l2_s1 String)) Int
+                                                 (let ((l2_s3 0))
+                                                 (let ((l2_s11 1))
+                                                 (let ((l2_s2 (seq.len l2_s0)))
+                                                 (let ((l2_s4 (= l2_s2 l2_s3)))
+                                                 (let ((l2_s5 (not l2_s4)))
+                                                 (let ((l2_s6 (seq.nth l2_s0 l2_s3)))
+                                                 (let ((l2_s7 (proj_1_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s8 (= l2_s1 l2_s7)))
+                                                 (let ((l2_s9 (and l2_s5 l2_s8)))
+                                                 (let ((l2_s10 (proj_2_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s12 (- l2_s2 l2_s11)))
+                                                 (let ((l2_s13 (seq.extract l2_s0 l2_s11 l2_s12)))
+                                                 (let ((l2_s14 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l2_s13 l2_s1)))
+                                                 (let ((l2_s15 (ite l2_s9 l2_s10 l2_s14)))
+                                                 (let ((l2_s16 (ite l2_s4 l2_s3 l2_s15)))
+                                                 l2_s16))))))))))))))))
+[GOOD] ; |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| :: [(SString, SInteger)] -> Expr -> SInteger [Recursive] [Refers to: |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|]
+[GOOD] (define-fun-rec |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| ((l1_s0 (Seq (SBVTuple2 String Int))) (l1_s1 Expr)) Int
+                                 (let ((l1_s2 ((as is-Val Bool) l1_s1)))
+                                 (let ((l1_s3 (getVal_1 l1_s1)))
+                                 (let ((l1_s4 ((as is-Var Bool) l1_s1)))
+                                 (let ((l1_s5 (getVar_1 l1_s1)))
+                                 (let ((l1_s6 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l1_s0 l1_s5)))
+                                 (let ((l1_s7 ((as is-Add Bool) l1_s1)))
+                                 (let ((l1_s8 (getAdd_1 l1_s1)))
+                                 (let ((l1_s9 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s8)))
+                                 (let ((l1_s10 (getAdd_2 l1_s1)))
+                                 (let ((l1_s11 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s10)))
+                                 (let ((l1_s12 (+ l1_s9 l1_s11)))
+                                 (let ((l1_s13 ((as is-Mul Bool) l1_s1)))
+                                 (let ((l1_s14 (getMul_1 l1_s1)))
+                                 (let ((l1_s15 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s14)))
+                                 (let ((l1_s16 (getMul_2 l1_s1)))
+                                 (let ((l1_s17 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s16)))
+                                 (let ((l1_s18 (* l1_s15 l1_s17)))
+                                 (let ((l1_s19 (getLet_1 l1_s1)))
+                                 (let ((l1_s20 (getLet_2 l1_s1)))
+                                 (let ((l1_s21 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s20)))
+                                 (let ((l1_s22 ((as mkSBVTuple2 (SBVTuple2 String Int)) l1_s19 l1_s21)))
+                                 (let ((l1_s23 (seq.unit l1_s22)))
+                                 (let ((l1_s24 (seq.++ l1_s23 l1_s0)))
+                                 (let ((l1_s25 (getLet_3 l1_s1)))
+                                 (let ((l1_s26 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s24 l1_s25)))
+                                 (let ((l1_s27 (ite l1_s13 l1_s18 l1_s26)))
+                                 (let ((l1_s28 (ite l1_s7 l1_s12 l1_s27)))
+                                 (let ((l1_s29 (ite l1_s4 l1_s6 l1_s28)))
+                                 (let ((l1_s30 (ite l1_s2 l1_s3 l1_s29)))
+                                 l1_s30))))))))))))))))))))))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s4 () Int (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| s3 s0))
+[GOOD] (define-fun s6 () Bool (distinct s4 s5))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s6)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr02c.gold b/SBVTestSuite/GoldFiles/adt_expr02c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr02c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr03.gold b/SBVTestSuite/GoldFiles/adt_expr03.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr03.gold
@@ -0,0 +1,219 @@
+[MEASURE] Verifying termination measures for: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): not in a multi-member cycle, skipping mutual check
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): barified = "|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|"
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2)]
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): recursive calls found = 6
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): trying sbv.dt.size.Expr arg2
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK (structural recursion)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): barified = "|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|"
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2)]
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): recursive calls found = 1
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): trying length arg1
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Bool (>= s4 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Int (seq.len s13))
+[GOOD] (define-fun s18 () Bool (not s10))
+[GOOD] (define-fun s19 () Bool (and s6 s18))
+[GOOD] (define-fun s20 () Bool (> s4 s17))
+[GOOD] (define-fun s21 () Bool (=> s19 s20))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): length arg1 -> OK
+[MEASURE] Passed (terminating): get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Let Expr) "a" ((as Mul Expr) ((as Val Expr) 3) ((as Add Expr) ((as Val Expr) 3) ((as Val Expr) 4))) ((as Add Expr) ((as Var Expr) "a") ((as Add Expr) ((as Val Expr) 3) ((as Val Expr) 4)))))
+[GOOD] (define-fun s3 () (Seq (SBVTuple2 String Int)) (as seq.empty (Seq (SBVTuple2 String Int))))
+[GOOD] (define-fun s5 () Int 28)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| :: [(SString, SInteger)] -> SString -> SInteger [Recursive]
+[GOOD] (define-fun-rec |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| ((l2_s0 (Seq (SBVTuple2 String Int))) (l2_s1 String)) Int
+                                                 (let ((l2_s3 0))
+                                                 (let ((l2_s11 1))
+                                                 (let ((l2_s2 (seq.len l2_s0)))
+                                                 (let ((l2_s4 (= l2_s2 l2_s3)))
+                                                 (let ((l2_s5 (not l2_s4)))
+                                                 (let ((l2_s6 (seq.nth l2_s0 l2_s3)))
+                                                 (let ((l2_s7 (proj_1_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s8 (= l2_s1 l2_s7)))
+                                                 (let ((l2_s9 (and l2_s5 l2_s8)))
+                                                 (let ((l2_s10 (proj_2_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s12 (- l2_s2 l2_s11)))
+                                                 (let ((l2_s13 (seq.extract l2_s0 l2_s11 l2_s12)))
+                                                 (let ((l2_s14 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l2_s13 l2_s1)))
+                                                 (let ((l2_s15 (ite l2_s9 l2_s10 l2_s14)))
+                                                 (let ((l2_s16 (ite l2_s4 l2_s3 l2_s15)))
+                                                 l2_s16))))))))))))))))
+[GOOD] ; |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| :: [(SString, SInteger)] -> Expr -> SInteger [Recursive] [Refers to: |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|]
+[GOOD] (define-fun-rec |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| ((l1_s0 (Seq (SBVTuple2 String Int))) (l1_s1 Expr)) Int
+                                 (let ((l1_s2 ((as is-Val Bool) l1_s1)))
+                                 (let ((l1_s3 (getVal_1 l1_s1)))
+                                 (let ((l1_s4 ((as is-Var Bool) l1_s1)))
+                                 (let ((l1_s5 (getVar_1 l1_s1)))
+                                 (let ((l1_s6 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l1_s0 l1_s5)))
+                                 (let ((l1_s7 ((as is-Add Bool) l1_s1)))
+                                 (let ((l1_s8 (getAdd_1 l1_s1)))
+                                 (let ((l1_s9 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s8)))
+                                 (let ((l1_s10 (getAdd_2 l1_s1)))
+                                 (let ((l1_s11 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s10)))
+                                 (let ((l1_s12 (+ l1_s9 l1_s11)))
+                                 (let ((l1_s13 ((as is-Mul Bool) l1_s1)))
+                                 (let ((l1_s14 (getMul_1 l1_s1)))
+                                 (let ((l1_s15 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s14)))
+                                 (let ((l1_s16 (getMul_2 l1_s1)))
+                                 (let ((l1_s17 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s16)))
+                                 (let ((l1_s18 (* l1_s15 l1_s17)))
+                                 (let ((l1_s19 (getLet_1 l1_s1)))
+                                 (let ((l1_s20 (getLet_2 l1_s1)))
+                                 (let ((l1_s21 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s20)))
+                                 (let ((l1_s22 ((as mkSBVTuple2 (SBVTuple2 String Int)) l1_s19 l1_s21)))
+                                 (let ((l1_s23 (seq.unit l1_s22)))
+                                 (let ((l1_s24 (seq.++ l1_s23 l1_s0)))
+                                 (let ((l1_s25 (getLet_3 l1_s1)))
+                                 (let ((l1_s26 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s24 l1_s25)))
+                                 (let ((l1_s27 (ite l1_s13 l1_s18 l1_s26)))
+                                 (let ((l1_s28 (ite l1_s7 l1_s12 l1_s27)))
+                                 (let ((l1_s29 (ite l1_s4 l1_s6 l1_s28)))
+                                 (let ((l1_s30 (ite l1_s2 l1_s3 l1_s29)))
+                                 l1_s30))))))))))))))))))))))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s4 () Int (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| s3 s0))
+[GOOD] (define-fun s6 () Bool (distinct s4 s5))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s6)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr03c.gold b/SBVTestSuite/GoldFiles/adt_expr03c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr03c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr04.gold b/SBVTestSuite/GoldFiles/adt_expr04.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr04.gold
@@ -0,0 +1,30 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 63)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "res"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 63))
+Result: 63
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr05.gold b/SBVTestSuite/GoldFiles/adt_expr05.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr05.gold
@@ -0,0 +1,30 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 3969)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "res"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3969))
+Result: 3969
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr06.gold b/SBVTestSuite/GoldFiles/adt_expr06.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr06.gold
@@ -0,0 +1,75 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Var Expr) "a"))
+[GOOD] (define-fun s5 () String "a")
+[GOOD] (define-fun s8 () Int 0)
+[GOOD] (define-fun s9 () String "b")
+[GOOD] (define-fun s11 () String "c")
+[GOOD] (define-fun s15 () Int 1)
+[GOOD] (define-fun s16 () Int 2)
+[GOOD] (define-fun s19 () Int 10)
+[GOOD] (define-fun s22 () Int 3)
+[GOOD] (define-fun s25 () Int 4)
+[GOOD] (define-fun s28 () Int 5)
+[GOOD] (define-fun s29 () Int 6)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s4 () String (getVar_1 s0))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool (and s3 s6))
+[GOOD] (define-fun s10 () Bool (= s4 s9))
+[GOOD] (define-fun s12 () Bool (= s4 s11))
+[GOOD] (define-fun s13 () Bool (or s10 s12))
+[GOOD] (define-fun s14 () Bool (and s3 s13))
+[GOOD] (define-fun s17 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s18 () Int (getVal_1 s0))
+[GOOD] (define-fun s20 () Bool (< s18 s19))
+[GOOD] (define-fun s21 () Bool (and s17 s20))
+[GOOD] (define-fun s23 () Bool (= s18 s19))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s26 () Bool (> s18 s19))
+[GOOD] (define-fun s27 () Bool (and s17 s26))
+[GOOD] (define-fun s30 () Int (ite s27 s28 s29))
+[GOOD] (define-fun s31 () Int (ite s24 s25 s30))
+[GOOD] (define-fun s32 () Int (ite s21 s22 s31))
+[GOOD] (define-fun s33 () Int (ite s3 s16 s32))
+[GOOD] (define-fun s34 () Int (ite s14 s15 s33))
+[GOOD] (define-fun s35 () Int (ite s7 s8 s34))
+[GOOD] (define-fun s36 () Bool (distinct s8 s35))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s36)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr06c.gold b/SBVTestSuite/GoldFiles/adt_expr06c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr06c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr07.gold b/SBVTestSuite/GoldFiles/adt_expr07.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr07.gold
@@ -0,0 +1,75 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Var Expr) "b"))
+[GOOD] (define-fun s5 () String "a")
+[GOOD] (define-fun s8 () Int 0)
+[GOOD] (define-fun s9 () String "b")
+[GOOD] (define-fun s11 () String "c")
+[GOOD] (define-fun s15 () Int 1)
+[GOOD] (define-fun s16 () Int 2)
+[GOOD] (define-fun s19 () Int 10)
+[GOOD] (define-fun s22 () Int 3)
+[GOOD] (define-fun s25 () Int 4)
+[GOOD] (define-fun s28 () Int 5)
+[GOOD] (define-fun s29 () Int 6)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s4 () String (getVar_1 s0))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool (and s3 s6))
+[GOOD] (define-fun s10 () Bool (= s4 s9))
+[GOOD] (define-fun s12 () Bool (= s4 s11))
+[GOOD] (define-fun s13 () Bool (or s10 s12))
+[GOOD] (define-fun s14 () Bool (and s3 s13))
+[GOOD] (define-fun s17 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s18 () Int (getVal_1 s0))
+[GOOD] (define-fun s20 () Bool (< s18 s19))
+[GOOD] (define-fun s21 () Bool (and s17 s20))
+[GOOD] (define-fun s23 () Bool (= s18 s19))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s26 () Bool (> s18 s19))
+[GOOD] (define-fun s27 () Bool (and s17 s26))
+[GOOD] (define-fun s30 () Int (ite s27 s28 s29))
+[GOOD] (define-fun s31 () Int (ite s24 s25 s30))
+[GOOD] (define-fun s32 () Int (ite s21 s22 s31))
+[GOOD] (define-fun s33 () Int (ite s3 s16 s32))
+[GOOD] (define-fun s34 () Int (ite s14 s15 s33))
+[GOOD] (define-fun s35 () Int (ite s7 s8 s34))
+[GOOD] (define-fun s36 () Bool (distinct s15 s35))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s36)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr07c.gold b/SBVTestSuite/GoldFiles/adt_expr07c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr07c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr08.gold b/SBVTestSuite/GoldFiles/adt_expr08.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr08.gold
@@ -0,0 +1,75 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Var Expr) "c"))
+[GOOD] (define-fun s5 () String "a")
+[GOOD] (define-fun s8 () Int 0)
+[GOOD] (define-fun s9 () String "b")
+[GOOD] (define-fun s11 () String "c")
+[GOOD] (define-fun s15 () Int 1)
+[GOOD] (define-fun s16 () Int 2)
+[GOOD] (define-fun s19 () Int 10)
+[GOOD] (define-fun s22 () Int 3)
+[GOOD] (define-fun s25 () Int 4)
+[GOOD] (define-fun s28 () Int 5)
+[GOOD] (define-fun s29 () Int 6)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s4 () String (getVar_1 s0))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool (and s3 s6))
+[GOOD] (define-fun s10 () Bool (= s4 s9))
+[GOOD] (define-fun s12 () Bool (= s4 s11))
+[GOOD] (define-fun s13 () Bool (or s10 s12))
+[GOOD] (define-fun s14 () Bool (and s3 s13))
+[GOOD] (define-fun s17 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s18 () Int (getVal_1 s0))
+[GOOD] (define-fun s20 () Bool (< s18 s19))
+[GOOD] (define-fun s21 () Bool (and s17 s20))
+[GOOD] (define-fun s23 () Bool (= s18 s19))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s26 () Bool (> s18 s19))
+[GOOD] (define-fun s27 () Bool (and s17 s26))
+[GOOD] (define-fun s30 () Int (ite s27 s28 s29))
+[GOOD] (define-fun s31 () Int (ite s24 s25 s30))
+[GOOD] (define-fun s32 () Int (ite s21 s22 s31))
+[GOOD] (define-fun s33 () Int (ite s3 s16 s32))
+[GOOD] (define-fun s34 () Int (ite s14 s15 s33))
+[GOOD] (define-fun s35 () Int (ite s7 s8 s34))
+[GOOD] (define-fun s36 () Bool (distinct s15 s35))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s36)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr08c.gold b/SBVTestSuite/GoldFiles/adt_expr08c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr08c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr09.gold b/SBVTestSuite/GoldFiles/adt_expr09.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr09.gold
@@ -0,0 +1,75 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Var Expr) "d"))
+[GOOD] (define-fun s5 () String "a")
+[GOOD] (define-fun s8 () Int 0)
+[GOOD] (define-fun s9 () String "b")
+[GOOD] (define-fun s11 () String "c")
+[GOOD] (define-fun s15 () Int 1)
+[GOOD] (define-fun s16 () Int 2)
+[GOOD] (define-fun s19 () Int 10)
+[GOOD] (define-fun s22 () Int 3)
+[GOOD] (define-fun s25 () Int 4)
+[GOOD] (define-fun s28 () Int 5)
+[GOOD] (define-fun s29 () Int 6)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s4 () String (getVar_1 s0))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool (and s3 s6))
+[GOOD] (define-fun s10 () Bool (= s4 s9))
+[GOOD] (define-fun s12 () Bool (= s4 s11))
+[GOOD] (define-fun s13 () Bool (or s10 s12))
+[GOOD] (define-fun s14 () Bool (and s3 s13))
+[GOOD] (define-fun s17 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s18 () Int (getVal_1 s0))
+[GOOD] (define-fun s20 () Bool (< s18 s19))
+[GOOD] (define-fun s21 () Bool (and s17 s20))
+[GOOD] (define-fun s23 () Bool (= s18 s19))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s26 () Bool (> s18 s19))
+[GOOD] (define-fun s27 () Bool (and s17 s26))
+[GOOD] (define-fun s30 () Int (ite s27 s28 s29))
+[GOOD] (define-fun s31 () Int (ite s24 s25 s30))
+[GOOD] (define-fun s32 () Int (ite s21 s22 s31))
+[GOOD] (define-fun s33 () Int (ite s3 s16 s32))
+[GOOD] (define-fun s34 () Int (ite s14 s15 s33))
+[GOOD] (define-fun s35 () Int (ite s7 s8 s34))
+[GOOD] (define-fun s36 () Bool (distinct s16 s35))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s36)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr09c.gold b/SBVTestSuite/GoldFiles/adt_expr09c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr09c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr10.gold b/SBVTestSuite/GoldFiles/adt_expr10.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr10.gold
@@ -0,0 +1,454 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s15 () Expr ((as Val Expr) (- 5)))
+[GOOD] (define-fun s17 () Expr ((as Val Expr) (- 4)))
+[GOOD] (define-fun s19 () Expr ((as Val Expr) (- 3)))
+[GOOD] (define-fun s21 () Expr ((as Val Expr) (- 2)))
+[GOOD] (define-fun s23 () Expr ((as Val Expr) (- 1)))
+[GOOD] (define-fun s25 () Expr ((as Val Expr) 0))
+[GOOD] (define-fun s27 () Expr ((as Val Expr) 1))
+[GOOD] (define-fun s29 () Expr ((as Val Expr) 2))
+[GOOD] (define-fun s31 () Expr ((as Val Expr) 3))
+[GOOD] (define-fun s33 () Expr ((as Val Expr) 4))
+[GOOD] (define-fun s35 () Expr ((as Val Expr) 5))
+[GOOD] (define-fun s37 () Expr ((as Val Expr) 6))
+[GOOD] (define-fun s39 () Expr ((as Val Expr) 7))
+[GOOD] (define-fun s41 () Expr ((as Val Expr) 8))
+[GOOD] (define-fun s43 () Expr ((as Val Expr) 9))
+[GOOD] (define-fun s61 () String "a")
+[GOOD] (define-fun s64 () Int 0)
+[GOOD] (define-fun s65 () String "b")
+[GOOD] (define-fun s67 () String "c")
+[GOOD] (define-fun s71 () Int 1)
+[GOOD] (define-fun s72 () Int 2)
+[GOOD] (define-fun s75 () Int 10)
+[GOOD] (define-fun s78 () Int 3)
+[GOOD] (define-fun s81 () Int 4)
+[GOOD] (define-fun s84 () Int 5)
+[GOOD] (define-fun s85 () Int 6)
+[GOOD] (define-fun s414 () Int 45)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] (declare-fun s1 () Expr)
+[GOOD] (declare-fun s2 () Expr)
+[GOOD] (declare-fun s3 () Expr)
+[GOOD] (declare-fun s4 () Expr)
+[GOOD] (declare-fun s5 () Expr)
+[GOOD] (declare-fun s6 () Expr)
+[GOOD] (declare-fun s7 () Expr)
+[GOOD] (declare-fun s8 () Expr)
+[GOOD] (declare-fun s9 () Expr)
+[GOOD] (declare-fun s10 () Expr)
+[GOOD] (declare-fun s11 () Expr)
+[GOOD] (declare-fun s12 () Expr)
+[GOOD] (declare-fun s13 () Expr)
+[GOOD] (declare-fun s14 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s16 () Bool (= s0 s15))
+[GOOD] (define-fun s18 () Bool (= s1 s17))
+[GOOD] (define-fun s20 () Bool (= s2 s19))
+[GOOD] (define-fun s22 () Bool (= s3 s21))
+[GOOD] (define-fun s24 () Bool (= s4 s23))
+[GOOD] (define-fun s26 () Bool (= s5 s25))
+[GOOD] (define-fun s28 () Bool (= s6 s27))
+[GOOD] (define-fun s30 () Bool (= s7 s29))
+[GOOD] (define-fun s32 () Bool (= s8 s31))
+[GOOD] (define-fun s34 () Bool (= s9 s33))
+[GOOD] (define-fun s36 () Bool (= s10 s35))
+[GOOD] (define-fun s38 () Bool (= s11 s37))
+[GOOD] (define-fun s40 () Bool (= s12 s39))
+[GOOD] (define-fun s42 () Bool (= s13 s41))
+[GOOD] (define-fun s44 () Bool (= s14 s43))
+[GOOD] (define-fun s45 () Bool (and s42 s44))
+[GOOD] (define-fun s46 () Bool (and s40 s45))
+[GOOD] (define-fun s47 () Bool (and s38 s46))
+[GOOD] (define-fun s48 () Bool (and s36 s47))
+[GOOD] (define-fun s49 () Bool (and s34 s48))
+[GOOD] (define-fun s50 () Bool (and s32 s49))
+[GOOD] (define-fun s51 () Bool (and s30 s50))
+[GOOD] (define-fun s52 () Bool (and s28 s51))
+[GOOD] (define-fun s53 () Bool (and s26 s52))
+[GOOD] (define-fun s54 () Bool (and s24 s53))
+[GOOD] (define-fun s55 () Bool (and s22 s54))
+[GOOD] (define-fun s56 () Bool (and s20 s55))
+[GOOD] (define-fun s57 () Bool (and s18 s56))
+[GOOD] (define-fun s58 () Bool (and s16 s57))
+[GOOD] (define-fun s59 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s60 () String (getVar_1 s0))
+[GOOD] (define-fun s62 () Bool (= s60 s61))
+[GOOD] (define-fun s63 () Bool (and s59 s62))
+[GOOD] (define-fun s66 () Bool (= s60 s65))
+[GOOD] (define-fun s68 () Bool (= s60 s67))
+[GOOD] (define-fun s69 () Bool (or s66 s68))
+[GOOD] (define-fun s70 () Bool (and s59 s69))
+[GOOD] (define-fun s73 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s74 () Int (getVal_1 s0))
+[GOOD] (define-fun s76 () Bool (< s74 s75))
+[GOOD] (define-fun s77 () Bool (and s73 s76))
+[GOOD] (define-fun s79 () Bool (= s74 s75))
+[GOOD] (define-fun s80 () Bool (and s73 s79))
+[GOOD] (define-fun s82 () Bool (> s74 s75))
+[GOOD] (define-fun s83 () Bool (and s73 s82))
+[GOOD] (define-fun s86 () Int (ite s83 s84 s85))
+[GOOD] (define-fun s87 () Int (ite s80 s81 s86))
+[GOOD] (define-fun s88 () Int (ite s77 s78 s87))
+[GOOD] (define-fun s89 () Int (ite s59 s72 s88))
+[GOOD] (define-fun s90 () Int (ite s70 s71 s89))
+[GOOD] (define-fun s91 () Int (ite s63 s64 s90))
+[GOOD] (define-fun s92 () Bool ((as is-Var Bool) s1))
+[GOOD] (define-fun s93 () String (getVar_1 s1))
+[GOOD] (define-fun s94 () Bool (= s61 s93))
+[GOOD] (define-fun s95 () Bool (and s92 s94))
+[GOOD] (define-fun s96 () Bool (= s65 s93))
+[GOOD] (define-fun s97 () Bool (= s67 s93))
+[GOOD] (define-fun s98 () Bool (or s96 s97))
+[GOOD] (define-fun s99 () Bool (and s92 s98))
+[GOOD] (define-fun s100 () Bool ((as is-Val Bool) s1))
+[GOOD] (define-fun s101 () Int (getVal_1 s1))
+[GOOD] (define-fun s102 () Bool (< s101 s75))
+[GOOD] (define-fun s103 () Bool (and s100 s102))
+[GOOD] (define-fun s104 () Bool (= s75 s101))
+[GOOD] (define-fun s105 () Bool (and s100 s104))
+[GOOD] (define-fun s106 () Bool (> s101 s75))
+[GOOD] (define-fun s107 () Bool (and s100 s106))
+[GOOD] (define-fun s108 () Int (ite s107 s84 s85))
+[GOOD] (define-fun s109 () Int (ite s105 s81 s108))
+[GOOD] (define-fun s110 () Int (ite s103 s78 s109))
+[GOOD] (define-fun s111 () Int (ite s92 s72 s110))
+[GOOD] (define-fun s112 () Int (ite s99 s71 s111))
+[GOOD] (define-fun s113 () Int (ite s95 s64 s112))
+[GOOD] (define-fun s114 () Int (+ s91 s113))
+[GOOD] (define-fun s115 () Bool ((as is-Var Bool) s2))
+[GOOD] (define-fun s116 () String (getVar_1 s2))
+[GOOD] (define-fun s117 () Bool (= s61 s116))
+[GOOD] (define-fun s118 () Bool (and s115 s117))
+[GOOD] (define-fun s119 () Bool (= s65 s116))
+[GOOD] (define-fun s120 () Bool (= s67 s116))
+[GOOD] (define-fun s121 () Bool (or s119 s120))
+[GOOD] (define-fun s122 () Bool (and s115 s121))
+[GOOD] (define-fun s123 () Bool ((as is-Val Bool) s2))
+[GOOD] (define-fun s124 () Int (getVal_1 s2))
+[GOOD] (define-fun s125 () Bool (< s124 s75))
+[GOOD] (define-fun s126 () Bool (and s123 s125))
+[GOOD] (define-fun s127 () Bool (= s75 s124))
+[GOOD] (define-fun s128 () Bool (and s123 s127))
+[GOOD] (define-fun s129 () Bool (> s124 s75))
+[GOOD] (define-fun s130 () Bool (and s123 s129))
+[GOOD] (define-fun s131 () Int (ite s130 s84 s85))
+[GOOD] (define-fun s132 () Int (ite s128 s81 s131))
+[GOOD] (define-fun s133 () Int (ite s126 s78 s132))
+[GOOD] (define-fun s134 () Int (ite s115 s72 s133))
+[GOOD] (define-fun s135 () Int (ite s122 s71 s134))
+[GOOD] (define-fun s136 () Int (ite s118 s64 s135))
+[GOOD] (define-fun s137 () Int (+ s114 s136))
+[GOOD] (define-fun s138 () Bool ((as is-Var Bool) s3))
+[GOOD] (define-fun s139 () String (getVar_1 s3))
+[GOOD] (define-fun s140 () Bool (= s61 s139))
+[GOOD] (define-fun s141 () Bool (and s138 s140))
+[GOOD] (define-fun s142 () Bool (= s65 s139))
+[GOOD] (define-fun s143 () Bool (= s67 s139))
+[GOOD] (define-fun s144 () Bool (or s142 s143))
+[GOOD] (define-fun s145 () Bool (and s138 s144))
+[GOOD] (define-fun s146 () Bool ((as is-Val Bool) s3))
+[GOOD] (define-fun s147 () Int (getVal_1 s3))
+[GOOD] (define-fun s148 () Bool (< s147 s75))
+[GOOD] (define-fun s149 () Bool (and s146 s148))
+[GOOD] (define-fun s150 () Bool (= s75 s147))
+[GOOD] (define-fun s151 () Bool (and s146 s150))
+[GOOD] (define-fun s152 () Bool (> s147 s75))
+[GOOD] (define-fun s153 () Bool (and s146 s152))
+[GOOD] (define-fun s154 () Int (ite s153 s84 s85))
+[GOOD] (define-fun s155 () Int (ite s151 s81 s154))
+[GOOD] (define-fun s156 () Int (ite s149 s78 s155))
+[GOOD] (define-fun s157 () Int (ite s138 s72 s156))
+[GOOD] (define-fun s158 () Int (ite s145 s71 s157))
+[GOOD] (define-fun s159 () Int (ite s141 s64 s158))
+[GOOD] (define-fun s160 () Int (+ s137 s159))
+[GOOD] (define-fun s161 () Bool ((as is-Var Bool) s4))
+[GOOD] (define-fun s162 () String (getVar_1 s4))
+[GOOD] (define-fun s163 () Bool (= s61 s162))
+[GOOD] (define-fun s164 () Bool (and s161 s163))
+[GOOD] (define-fun s165 () Bool (= s65 s162))
+[GOOD] (define-fun s166 () Bool (= s67 s162))
+[GOOD] (define-fun s167 () Bool (or s165 s166))
+[GOOD] (define-fun s168 () Bool (and s161 s167))
+[GOOD] (define-fun s169 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s170 () Int (getVal_1 s4))
+[GOOD] (define-fun s171 () Bool (< s170 s75))
+[GOOD] (define-fun s172 () Bool (and s169 s171))
+[GOOD] (define-fun s173 () Bool (= s75 s170))
+[GOOD] (define-fun s174 () Bool (and s169 s173))
+[GOOD] (define-fun s175 () Bool (> s170 s75))
+[GOOD] (define-fun s176 () Bool (and s169 s175))
+[GOOD] (define-fun s177 () Int (ite s176 s84 s85))
+[GOOD] (define-fun s178 () Int (ite s174 s81 s177))
+[GOOD] (define-fun s179 () Int (ite s172 s78 s178))
+[GOOD] (define-fun s180 () Int (ite s161 s72 s179))
+[GOOD] (define-fun s181 () Int (ite s168 s71 s180))
+[GOOD] (define-fun s182 () Int (ite s164 s64 s181))
+[GOOD] (define-fun s183 () Int (+ s160 s182))
+[GOOD] (define-fun s184 () Bool ((as is-Var Bool) s5))
+[GOOD] (define-fun s185 () String (getVar_1 s5))
+[GOOD] (define-fun s186 () Bool (= s61 s185))
+[GOOD] (define-fun s187 () Bool (and s184 s186))
+[GOOD] (define-fun s188 () Bool (= s65 s185))
+[GOOD] (define-fun s189 () Bool (= s67 s185))
+[GOOD] (define-fun s190 () Bool (or s188 s189))
+[GOOD] (define-fun s191 () Bool (and s184 s190))
+[GOOD] (define-fun s192 () Bool ((as is-Val Bool) s5))
+[GOOD] (define-fun s193 () Int (getVal_1 s5))
+[GOOD] (define-fun s194 () Bool (< s193 s75))
+[GOOD] (define-fun s195 () Bool (and s192 s194))
+[GOOD] (define-fun s196 () Bool (= s75 s193))
+[GOOD] (define-fun s197 () Bool (and s192 s196))
+[GOOD] (define-fun s198 () Bool (> s193 s75))
+[GOOD] (define-fun s199 () Bool (and s192 s198))
+[GOOD] (define-fun s200 () Int (ite s199 s84 s85))
+[GOOD] (define-fun s201 () Int (ite s197 s81 s200))
+[GOOD] (define-fun s202 () Int (ite s195 s78 s201))
+[GOOD] (define-fun s203 () Int (ite s184 s72 s202))
+[GOOD] (define-fun s204 () Int (ite s191 s71 s203))
+[GOOD] (define-fun s205 () Int (ite s187 s64 s204))
+[GOOD] (define-fun s206 () Int (+ s183 s205))
+[GOOD] (define-fun s207 () Bool ((as is-Var Bool) s6))
+[GOOD] (define-fun s208 () String (getVar_1 s6))
+[GOOD] (define-fun s209 () Bool (= s61 s208))
+[GOOD] (define-fun s210 () Bool (and s207 s209))
+[GOOD] (define-fun s211 () Bool (= s65 s208))
+[GOOD] (define-fun s212 () Bool (= s67 s208))
+[GOOD] (define-fun s213 () Bool (or s211 s212))
+[GOOD] (define-fun s214 () Bool (and s207 s213))
+[GOOD] (define-fun s215 () Bool ((as is-Val Bool) s6))
+[GOOD] (define-fun s216 () Int (getVal_1 s6))
+[GOOD] (define-fun s217 () Bool (< s216 s75))
+[GOOD] (define-fun s218 () Bool (and s215 s217))
+[GOOD] (define-fun s219 () Bool (= s75 s216))
+[GOOD] (define-fun s220 () Bool (and s215 s219))
+[GOOD] (define-fun s221 () Bool (> s216 s75))
+[GOOD] (define-fun s222 () Bool (and s215 s221))
+[GOOD] (define-fun s223 () Int (ite s222 s84 s85))
+[GOOD] (define-fun s224 () Int (ite s220 s81 s223))
+[GOOD] (define-fun s225 () Int (ite s218 s78 s224))
+[GOOD] (define-fun s226 () Int (ite s207 s72 s225))
+[GOOD] (define-fun s227 () Int (ite s214 s71 s226))
+[GOOD] (define-fun s228 () Int (ite s210 s64 s227))
+[GOOD] (define-fun s229 () Int (+ s206 s228))
+[GOOD] (define-fun s230 () Bool ((as is-Var Bool) s7))
+[GOOD] (define-fun s231 () String (getVar_1 s7))
+[GOOD] (define-fun s232 () Bool (= s61 s231))
+[GOOD] (define-fun s233 () Bool (and s230 s232))
+[GOOD] (define-fun s234 () Bool (= s65 s231))
+[GOOD] (define-fun s235 () Bool (= s67 s231))
+[GOOD] (define-fun s236 () Bool (or s234 s235))
+[GOOD] (define-fun s237 () Bool (and s230 s236))
+[GOOD] (define-fun s238 () Bool ((as is-Val Bool) s7))
+[GOOD] (define-fun s239 () Int (getVal_1 s7))
+[GOOD] (define-fun s240 () Bool (< s239 s75))
+[GOOD] (define-fun s241 () Bool (and s238 s240))
+[GOOD] (define-fun s242 () Bool (= s75 s239))
+[GOOD] (define-fun s243 () Bool (and s238 s242))
+[GOOD] (define-fun s244 () Bool (> s239 s75))
+[GOOD] (define-fun s245 () Bool (and s238 s244))
+[GOOD] (define-fun s246 () Int (ite s245 s84 s85))
+[GOOD] (define-fun s247 () Int (ite s243 s81 s246))
+[GOOD] (define-fun s248 () Int (ite s241 s78 s247))
+[GOOD] (define-fun s249 () Int (ite s230 s72 s248))
+[GOOD] (define-fun s250 () Int (ite s237 s71 s249))
+[GOOD] (define-fun s251 () Int (ite s233 s64 s250))
+[GOOD] (define-fun s252 () Int (+ s229 s251))
+[GOOD] (define-fun s253 () Bool ((as is-Var Bool) s8))
+[GOOD] (define-fun s254 () String (getVar_1 s8))
+[GOOD] (define-fun s255 () Bool (= s61 s254))
+[GOOD] (define-fun s256 () Bool (and s253 s255))
+[GOOD] (define-fun s257 () Bool (= s65 s254))
+[GOOD] (define-fun s258 () Bool (= s67 s254))
+[GOOD] (define-fun s259 () Bool (or s257 s258))
+[GOOD] (define-fun s260 () Bool (and s253 s259))
+[GOOD] (define-fun s261 () Bool ((as is-Val Bool) s8))
+[GOOD] (define-fun s262 () Int (getVal_1 s8))
+[GOOD] (define-fun s263 () Bool (< s262 s75))
+[GOOD] (define-fun s264 () Bool (and s261 s263))
+[GOOD] (define-fun s265 () Bool (= s75 s262))
+[GOOD] (define-fun s266 () Bool (and s261 s265))
+[GOOD] (define-fun s267 () Bool (> s262 s75))
+[GOOD] (define-fun s268 () Bool (and s261 s267))
+[GOOD] (define-fun s269 () Int (ite s268 s84 s85))
+[GOOD] (define-fun s270 () Int (ite s266 s81 s269))
+[GOOD] (define-fun s271 () Int (ite s264 s78 s270))
+[GOOD] (define-fun s272 () Int (ite s253 s72 s271))
+[GOOD] (define-fun s273 () Int (ite s260 s71 s272))
+[GOOD] (define-fun s274 () Int (ite s256 s64 s273))
+[GOOD] (define-fun s275 () Int (+ s252 s274))
+[GOOD] (define-fun s276 () Bool ((as is-Var Bool) s9))
+[GOOD] (define-fun s277 () String (getVar_1 s9))
+[GOOD] (define-fun s278 () Bool (= s61 s277))
+[GOOD] (define-fun s279 () Bool (and s276 s278))
+[GOOD] (define-fun s280 () Bool (= s65 s277))
+[GOOD] (define-fun s281 () Bool (= s67 s277))
+[GOOD] (define-fun s282 () Bool (or s280 s281))
+[GOOD] (define-fun s283 () Bool (and s276 s282))
+[GOOD] (define-fun s284 () Bool ((as is-Val Bool) s9))
+[GOOD] (define-fun s285 () Int (getVal_1 s9))
+[GOOD] (define-fun s286 () Bool (< s285 s75))
+[GOOD] (define-fun s287 () Bool (and s284 s286))
+[GOOD] (define-fun s288 () Bool (= s75 s285))
+[GOOD] (define-fun s289 () Bool (and s284 s288))
+[GOOD] (define-fun s290 () Bool (> s285 s75))
+[GOOD] (define-fun s291 () Bool (and s284 s290))
+[GOOD] (define-fun s292 () Int (ite s291 s84 s85))
+[GOOD] (define-fun s293 () Int (ite s289 s81 s292))
+[GOOD] (define-fun s294 () Int (ite s287 s78 s293))
+[GOOD] (define-fun s295 () Int (ite s276 s72 s294))
+[GOOD] (define-fun s296 () Int (ite s283 s71 s295))
+[GOOD] (define-fun s297 () Int (ite s279 s64 s296))
+[GOOD] (define-fun s298 () Int (+ s275 s297))
+[GOOD] (define-fun s299 () Bool ((as is-Var Bool) s10))
+[GOOD] (define-fun s300 () String (getVar_1 s10))
+[GOOD] (define-fun s301 () Bool (= s61 s300))
+[GOOD] (define-fun s302 () Bool (and s299 s301))
+[GOOD] (define-fun s303 () Bool (= s65 s300))
+[GOOD] (define-fun s304 () Bool (= s67 s300))
+[GOOD] (define-fun s305 () Bool (or s303 s304))
+[GOOD] (define-fun s306 () Bool (and s299 s305))
+[GOOD] (define-fun s307 () Bool ((as is-Val Bool) s10))
+[GOOD] (define-fun s308 () Int (getVal_1 s10))
+[GOOD] (define-fun s309 () Bool (< s308 s75))
+[GOOD] (define-fun s310 () Bool (and s307 s309))
+[GOOD] (define-fun s311 () Bool (= s75 s308))
+[GOOD] (define-fun s312 () Bool (and s307 s311))
+[GOOD] (define-fun s313 () Bool (> s308 s75))
+[GOOD] (define-fun s314 () Bool (and s307 s313))
+[GOOD] (define-fun s315 () Int (ite s314 s84 s85))
+[GOOD] (define-fun s316 () Int (ite s312 s81 s315))
+[GOOD] (define-fun s317 () Int (ite s310 s78 s316))
+[GOOD] (define-fun s318 () Int (ite s299 s72 s317))
+[GOOD] (define-fun s319 () Int (ite s306 s71 s318))
+[GOOD] (define-fun s320 () Int (ite s302 s64 s319))
+[GOOD] (define-fun s321 () Int (+ s298 s320))
+[GOOD] (define-fun s322 () Bool ((as is-Var Bool) s11))
+[GOOD] (define-fun s323 () String (getVar_1 s11))
+[GOOD] (define-fun s324 () Bool (= s61 s323))
+[GOOD] (define-fun s325 () Bool (and s322 s324))
+[GOOD] (define-fun s326 () Bool (= s65 s323))
+[GOOD] (define-fun s327 () Bool (= s67 s323))
+[GOOD] (define-fun s328 () Bool (or s326 s327))
+[GOOD] (define-fun s329 () Bool (and s322 s328))
+[GOOD] (define-fun s330 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s331 () Int (getVal_1 s11))
+[GOOD] (define-fun s332 () Bool (< s331 s75))
+[GOOD] (define-fun s333 () Bool (and s330 s332))
+[GOOD] (define-fun s334 () Bool (= s75 s331))
+[GOOD] (define-fun s335 () Bool (and s330 s334))
+[GOOD] (define-fun s336 () Bool (> s331 s75))
+[GOOD] (define-fun s337 () Bool (and s330 s336))
+[GOOD] (define-fun s338 () Int (ite s337 s84 s85))
+[GOOD] (define-fun s339 () Int (ite s335 s81 s338))
+[GOOD] (define-fun s340 () Int (ite s333 s78 s339))
+[GOOD] (define-fun s341 () Int (ite s322 s72 s340))
+[GOOD] (define-fun s342 () Int (ite s329 s71 s341))
+[GOOD] (define-fun s343 () Int (ite s325 s64 s342))
+[GOOD] (define-fun s344 () Int (+ s321 s343))
+[GOOD] (define-fun s345 () Bool ((as is-Var Bool) s12))
+[GOOD] (define-fun s346 () String (getVar_1 s12))
+[GOOD] (define-fun s347 () Bool (= s61 s346))
+[GOOD] (define-fun s348 () Bool (and s345 s347))
+[GOOD] (define-fun s349 () Bool (= s65 s346))
+[GOOD] (define-fun s350 () Bool (= s67 s346))
+[GOOD] (define-fun s351 () Bool (or s349 s350))
+[GOOD] (define-fun s352 () Bool (and s345 s351))
+[GOOD] (define-fun s353 () Bool ((as is-Val Bool) s12))
+[GOOD] (define-fun s354 () Int (getVal_1 s12))
+[GOOD] (define-fun s355 () Bool (< s354 s75))
+[GOOD] (define-fun s356 () Bool (and s353 s355))
+[GOOD] (define-fun s357 () Bool (= s75 s354))
+[GOOD] (define-fun s358 () Bool (and s353 s357))
+[GOOD] (define-fun s359 () Bool (> s354 s75))
+[GOOD] (define-fun s360 () Bool (and s353 s359))
+[GOOD] (define-fun s361 () Int (ite s360 s84 s85))
+[GOOD] (define-fun s362 () Int (ite s358 s81 s361))
+[GOOD] (define-fun s363 () Int (ite s356 s78 s362))
+[GOOD] (define-fun s364 () Int (ite s345 s72 s363))
+[GOOD] (define-fun s365 () Int (ite s352 s71 s364))
+[GOOD] (define-fun s366 () Int (ite s348 s64 s365))
+[GOOD] (define-fun s367 () Int (+ s344 s366))
+[GOOD] (define-fun s368 () Bool ((as is-Var Bool) s13))
+[GOOD] (define-fun s369 () String (getVar_1 s13))
+[GOOD] (define-fun s370 () Bool (= s61 s369))
+[GOOD] (define-fun s371 () Bool (and s368 s370))
+[GOOD] (define-fun s372 () Bool (= s65 s369))
+[GOOD] (define-fun s373 () Bool (= s67 s369))
+[GOOD] (define-fun s374 () Bool (or s372 s373))
+[GOOD] (define-fun s375 () Bool (and s368 s374))
+[GOOD] (define-fun s376 () Bool ((as is-Val Bool) s13))
+[GOOD] (define-fun s377 () Int (getVal_1 s13))
+[GOOD] (define-fun s378 () Bool (< s377 s75))
+[GOOD] (define-fun s379 () Bool (and s376 s378))
+[GOOD] (define-fun s380 () Bool (= s75 s377))
+[GOOD] (define-fun s381 () Bool (and s376 s380))
+[GOOD] (define-fun s382 () Bool (> s377 s75))
+[GOOD] (define-fun s383 () Bool (and s376 s382))
+[GOOD] (define-fun s384 () Int (ite s383 s84 s85))
+[GOOD] (define-fun s385 () Int (ite s381 s81 s384))
+[GOOD] (define-fun s386 () Int (ite s379 s78 s385))
+[GOOD] (define-fun s387 () Int (ite s368 s72 s386))
+[GOOD] (define-fun s388 () Int (ite s375 s71 s387))
+[GOOD] (define-fun s389 () Int (ite s371 s64 s388))
+[GOOD] (define-fun s390 () Int (+ s367 s389))
+[GOOD] (define-fun s391 () Bool ((as is-Var Bool) s14))
+[GOOD] (define-fun s392 () String (getVar_1 s14))
+[GOOD] (define-fun s393 () Bool (= s61 s392))
+[GOOD] (define-fun s394 () Bool (and s391 s393))
+[GOOD] (define-fun s395 () Bool (= s65 s392))
+[GOOD] (define-fun s396 () Bool (= s67 s392))
+[GOOD] (define-fun s397 () Bool (or s395 s396))
+[GOOD] (define-fun s398 () Bool (and s391 s397))
+[GOOD] (define-fun s399 () Bool ((as is-Val Bool) s14))
+[GOOD] (define-fun s400 () Int (getVal_1 s14))
+[GOOD] (define-fun s401 () Bool (< s400 s75))
+[GOOD] (define-fun s402 () Bool (and s399 s401))
+[GOOD] (define-fun s403 () Bool (= s75 s400))
+[GOOD] (define-fun s404 () Bool (and s399 s403))
+[GOOD] (define-fun s405 () Bool (> s400 s75))
+[GOOD] (define-fun s406 () Bool (and s399 s405))
+[GOOD] (define-fun s407 () Int (ite s406 s84 s85))
+[GOOD] (define-fun s408 () Int (ite s404 s81 s407))
+[GOOD] (define-fun s409 () Int (ite s402 s78 s408))
+[GOOD] (define-fun s410 () Int (ite s391 s72 s409))
+[GOOD] (define-fun s411 () Int (ite s398 s71 s410))
+[GOOD] (define-fun s412 () Int (ite s394 s64 s411))
+[GOOD] (define-fun s413 () Int (+ s390 s412))
+[GOOD] (define-fun s415 () Bool (distinct s413 s414))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s58)
+[GOOD] (assert s415)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr10c.gold b/SBVTestSuite/GoldFiles/adt_expr10c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr10c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr11.gold b/SBVTestSuite/GoldFiles/adt_expr11.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr11.gold
@@ -0,0 +1,102 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Expr ((as Val Expr) 10))
+[GOOD] (define-fun s8 () String "a")
+[GOOD] (define-fun s11 () Int 0)
+[GOOD] (define-fun s12 () String "b")
+[GOOD] (define-fun s14 () String "c")
+[GOOD] (define-fun s18 () Int 1)
+[GOOD] (define-fun s19 () Int 2)
+[GOOD] (define-fun s22 () Int 10)
+[GOOD] (define-fun s25 () Int 3)
+[GOOD] (define-fun s28 () Int 4)
+[GOOD] (define-fun s31 () Int 5)
+[GOOD] (define-fun s32 () Int 6)
+[GOOD] (define-fun s62 () Int 8)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] (declare-fun s1 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (= s0 s2))
+[GOOD] (define-fun s4 () Bool (= s1 s2))
+[GOOD] (define-fun s5 () Bool (and s3 s4))
+[GOOD] (define-fun s6 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s7 () String (getVar_1 s0))
+[GOOD] (define-fun s9 () Bool (= s7 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s13 () Bool (= s7 s12))
+[GOOD] (define-fun s15 () Bool (= s7 s14))
+[GOOD] (define-fun s16 () Bool (or s13 s15))
+[GOOD] (define-fun s17 () Bool (and s6 s16))
+[GOOD] (define-fun s20 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s21 () Int (getVal_1 s0))
+[GOOD] (define-fun s23 () Bool (< s21 s22))
+[GOOD] (define-fun s24 () Bool (and s20 s23))
+[GOOD] (define-fun s26 () Bool (= s21 s22))
+[GOOD] (define-fun s27 () Bool (and s20 s26))
+[GOOD] (define-fun s29 () Bool (> s21 s22))
+[GOOD] (define-fun s30 () Bool (and s20 s29))
+[GOOD] (define-fun s33 () Int (ite s30 s31 s32))
+[GOOD] (define-fun s34 () Int (ite s27 s28 s33))
+[GOOD] (define-fun s35 () Int (ite s24 s25 s34))
+[GOOD] (define-fun s36 () Int (ite s6 s19 s35))
+[GOOD] (define-fun s37 () Int (ite s17 s18 s36))
+[GOOD] (define-fun s38 () Int (ite s10 s11 s37))
+[GOOD] (define-fun s39 () Bool ((as is-Var Bool) s1))
+[GOOD] (define-fun s40 () String (getVar_1 s1))
+[GOOD] (define-fun s41 () Bool (= s8 s40))
+[GOOD] (define-fun s42 () Bool (and s39 s41))
+[GOOD] (define-fun s43 () Bool (= s12 s40))
+[GOOD] (define-fun s44 () Bool (= s14 s40))
+[GOOD] (define-fun s45 () Bool (or s43 s44))
+[GOOD] (define-fun s46 () Bool (and s39 s45))
+[GOOD] (define-fun s47 () Bool ((as is-Val Bool) s1))
+[GOOD] (define-fun s48 () Int (getVal_1 s1))
+[GOOD] (define-fun s49 () Bool (< s48 s22))
+[GOOD] (define-fun s50 () Bool (and s47 s49))
+[GOOD] (define-fun s51 () Bool (= s22 s48))
+[GOOD] (define-fun s52 () Bool (and s47 s51))
+[GOOD] (define-fun s53 () Bool (> s48 s22))
+[GOOD] (define-fun s54 () Bool (and s47 s53))
+[GOOD] (define-fun s55 () Int (ite s54 s31 s32))
+[GOOD] (define-fun s56 () Int (ite s52 s28 s55))
+[GOOD] (define-fun s57 () Int (ite s50 s25 s56))
+[GOOD] (define-fun s58 () Int (ite s39 s19 s57))
+[GOOD] (define-fun s59 () Int (ite s46 s18 s58))
+[GOOD] (define-fun s60 () Int (ite s42 s11 s59))
+[GOOD] (define-fun s61 () Int (+ s38 s60))
+[GOOD] (define-fun s63 () Bool (distinct s61 s62))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s5)
+[GOOD] (assert s63)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr11c.gold b/SBVTestSuite/GoldFiles/adt_expr11c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr11c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr12.gold b/SBVTestSuite/GoldFiles/adt_expr12.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr12.gold
@@ -0,0 +1,319 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s10 () Expr ((as Val Expr) 11))
+[GOOD] (define-fun s12 () Expr ((as Val Expr) 12))
+[GOOD] (define-fun s14 () Expr ((as Val Expr) 13))
+[GOOD] (define-fun s16 () Expr ((as Val Expr) 14))
+[GOOD] (define-fun s18 () Expr ((as Val Expr) 15))
+[GOOD] (define-fun s20 () Expr ((as Val Expr) 16))
+[GOOD] (define-fun s22 () Expr ((as Val Expr) 17))
+[GOOD] (define-fun s24 () Expr ((as Val Expr) 18))
+[GOOD] (define-fun s26 () Expr ((as Val Expr) 19))
+[GOOD] (define-fun s28 () Expr ((as Val Expr) 20))
+[GOOD] (define-fun s41 () String "a")
+[GOOD] (define-fun s44 () Int 0)
+[GOOD] (define-fun s45 () String "b")
+[GOOD] (define-fun s47 () String "c")
+[GOOD] (define-fun s51 () Int 1)
+[GOOD] (define-fun s52 () Int 2)
+[GOOD] (define-fun s55 () Int 10)
+[GOOD] (define-fun s58 () Int 3)
+[GOOD] (define-fun s61 () Int 4)
+[GOOD] (define-fun s64 () Int 5)
+[GOOD] (define-fun s65 () Int 6)
+[GOOD] (define-fun s279 () Int 50)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] (declare-fun s1 () Expr)
+[GOOD] (declare-fun s2 () Expr)
+[GOOD] (declare-fun s3 () Expr)
+[GOOD] (declare-fun s4 () Expr)
+[GOOD] (declare-fun s5 () Expr)
+[GOOD] (declare-fun s6 () Expr)
+[GOOD] (declare-fun s7 () Expr)
+[GOOD] (declare-fun s8 () Expr)
+[GOOD] (declare-fun s9 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s11 () Bool (= s0 s10))
+[GOOD] (define-fun s13 () Bool (= s1 s12))
+[GOOD] (define-fun s15 () Bool (= s2 s14))
+[GOOD] (define-fun s17 () Bool (= s3 s16))
+[GOOD] (define-fun s19 () Bool (= s4 s18))
+[GOOD] (define-fun s21 () Bool (= s5 s20))
+[GOOD] (define-fun s23 () Bool (= s6 s22))
+[GOOD] (define-fun s25 () Bool (= s7 s24))
+[GOOD] (define-fun s27 () Bool (= s8 s26))
+[GOOD] (define-fun s29 () Bool (= s9 s28))
+[GOOD] (define-fun s30 () Bool (and s27 s29))
+[GOOD] (define-fun s31 () Bool (and s25 s30))
+[GOOD] (define-fun s32 () Bool (and s23 s31))
+[GOOD] (define-fun s33 () Bool (and s21 s32))
+[GOOD] (define-fun s34 () Bool (and s19 s33))
+[GOOD] (define-fun s35 () Bool (and s17 s34))
+[GOOD] (define-fun s36 () Bool (and s15 s35))
+[GOOD] (define-fun s37 () Bool (and s13 s36))
+[GOOD] (define-fun s38 () Bool (and s11 s37))
+[GOOD] (define-fun s39 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s40 () String (getVar_1 s0))
+[GOOD] (define-fun s42 () Bool (= s40 s41))
+[GOOD] (define-fun s43 () Bool (and s39 s42))
+[GOOD] (define-fun s46 () Bool (= s40 s45))
+[GOOD] (define-fun s48 () Bool (= s40 s47))
+[GOOD] (define-fun s49 () Bool (or s46 s48))
+[GOOD] (define-fun s50 () Bool (and s39 s49))
+[GOOD] (define-fun s53 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s54 () Int (getVal_1 s0))
+[GOOD] (define-fun s56 () Bool (< s54 s55))
+[GOOD] (define-fun s57 () Bool (and s53 s56))
+[GOOD] (define-fun s59 () Bool (= s54 s55))
+[GOOD] (define-fun s60 () Bool (and s53 s59))
+[GOOD] (define-fun s62 () Bool (> s54 s55))
+[GOOD] (define-fun s63 () Bool (and s53 s62))
+[GOOD] (define-fun s66 () Int (ite s63 s64 s65))
+[GOOD] (define-fun s67 () Int (ite s60 s61 s66))
+[GOOD] (define-fun s68 () Int (ite s57 s58 s67))
+[GOOD] (define-fun s69 () Int (ite s39 s52 s68))
+[GOOD] (define-fun s70 () Int (ite s50 s51 s69))
+[GOOD] (define-fun s71 () Int (ite s43 s44 s70))
+[GOOD] (define-fun s72 () Bool ((as is-Var Bool) s1))
+[GOOD] (define-fun s73 () String (getVar_1 s1))
+[GOOD] (define-fun s74 () Bool (= s41 s73))
+[GOOD] (define-fun s75 () Bool (and s72 s74))
+[GOOD] (define-fun s76 () Bool (= s45 s73))
+[GOOD] (define-fun s77 () Bool (= s47 s73))
+[GOOD] (define-fun s78 () Bool (or s76 s77))
+[GOOD] (define-fun s79 () Bool (and s72 s78))
+[GOOD] (define-fun s80 () Bool ((as is-Val Bool) s1))
+[GOOD] (define-fun s81 () Int (getVal_1 s1))
+[GOOD] (define-fun s82 () Bool (< s81 s55))
+[GOOD] (define-fun s83 () Bool (and s80 s82))
+[GOOD] (define-fun s84 () Bool (= s55 s81))
+[GOOD] (define-fun s85 () Bool (and s80 s84))
+[GOOD] (define-fun s86 () Bool (> s81 s55))
+[GOOD] (define-fun s87 () Bool (and s80 s86))
+[GOOD] (define-fun s88 () Int (ite s87 s64 s65))
+[GOOD] (define-fun s89 () Int (ite s85 s61 s88))
+[GOOD] (define-fun s90 () Int (ite s83 s58 s89))
+[GOOD] (define-fun s91 () Int (ite s72 s52 s90))
+[GOOD] (define-fun s92 () Int (ite s79 s51 s91))
+[GOOD] (define-fun s93 () Int (ite s75 s44 s92))
+[GOOD] (define-fun s94 () Int (+ s71 s93))
+[GOOD] (define-fun s95 () Bool ((as is-Var Bool) s2))
+[GOOD] (define-fun s96 () String (getVar_1 s2))
+[GOOD] (define-fun s97 () Bool (= s41 s96))
+[GOOD] (define-fun s98 () Bool (and s95 s97))
+[GOOD] (define-fun s99 () Bool (= s45 s96))
+[GOOD] (define-fun s100 () Bool (= s47 s96))
+[GOOD] (define-fun s101 () Bool (or s99 s100))
+[GOOD] (define-fun s102 () Bool (and s95 s101))
+[GOOD] (define-fun s103 () Bool ((as is-Val Bool) s2))
+[GOOD] (define-fun s104 () Int (getVal_1 s2))
+[GOOD] (define-fun s105 () Bool (< s104 s55))
+[GOOD] (define-fun s106 () Bool (and s103 s105))
+[GOOD] (define-fun s107 () Bool (= s55 s104))
+[GOOD] (define-fun s108 () Bool (and s103 s107))
+[GOOD] (define-fun s109 () Bool (> s104 s55))
+[GOOD] (define-fun s110 () Bool (and s103 s109))
+[GOOD] (define-fun s111 () Int (ite s110 s64 s65))
+[GOOD] (define-fun s112 () Int (ite s108 s61 s111))
+[GOOD] (define-fun s113 () Int (ite s106 s58 s112))
+[GOOD] (define-fun s114 () Int (ite s95 s52 s113))
+[GOOD] (define-fun s115 () Int (ite s102 s51 s114))
+[GOOD] (define-fun s116 () Int (ite s98 s44 s115))
+[GOOD] (define-fun s117 () Int (+ s94 s116))
+[GOOD] (define-fun s118 () Bool ((as is-Var Bool) s3))
+[GOOD] (define-fun s119 () String (getVar_1 s3))
+[GOOD] (define-fun s120 () Bool (= s41 s119))
+[GOOD] (define-fun s121 () Bool (and s118 s120))
+[GOOD] (define-fun s122 () Bool (= s45 s119))
+[GOOD] (define-fun s123 () Bool (= s47 s119))
+[GOOD] (define-fun s124 () Bool (or s122 s123))
+[GOOD] (define-fun s125 () Bool (and s118 s124))
+[GOOD] (define-fun s126 () Bool ((as is-Val Bool) s3))
+[GOOD] (define-fun s127 () Int (getVal_1 s3))
+[GOOD] (define-fun s128 () Bool (< s127 s55))
+[GOOD] (define-fun s129 () Bool (and s126 s128))
+[GOOD] (define-fun s130 () Bool (= s55 s127))
+[GOOD] (define-fun s131 () Bool (and s126 s130))
+[GOOD] (define-fun s132 () Bool (> s127 s55))
+[GOOD] (define-fun s133 () Bool (and s126 s132))
+[GOOD] (define-fun s134 () Int (ite s133 s64 s65))
+[GOOD] (define-fun s135 () Int (ite s131 s61 s134))
+[GOOD] (define-fun s136 () Int (ite s129 s58 s135))
+[GOOD] (define-fun s137 () Int (ite s118 s52 s136))
+[GOOD] (define-fun s138 () Int (ite s125 s51 s137))
+[GOOD] (define-fun s139 () Int (ite s121 s44 s138))
+[GOOD] (define-fun s140 () Int (+ s117 s139))
+[GOOD] (define-fun s141 () Bool ((as is-Var Bool) s4))
+[GOOD] (define-fun s142 () String (getVar_1 s4))
+[GOOD] (define-fun s143 () Bool (= s41 s142))
+[GOOD] (define-fun s144 () Bool (and s141 s143))
+[GOOD] (define-fun s145 () Bool (= s45 s142))
+[GOOD] (define-fun s146 () Bool (= s47 s142))
+[GOOD] (define-fun s147 () Bool (or s145 s146))
+[GOOD] (define-fun s148 () Bool (and s141 s147))
+[GOOD] (define-fun s149 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s150 () Int (getVal_1 s4))
+[GOOD] (define-fun s151 () Bool (< s150 s55))
+[GOOD] (define-fun s152 () Bool (and s149 s151))
+[GOOD] (define-fun s153 () Bool (= s55 s150))
+[GOOD] (define-fun s154 () Bool (and s149 s153))
+[GOOD] (define-fun s155 () Bool (> s150 s55))
+[GOOD] (define-fun s156 () Bool (and s149 s155))
+[GOOD] (define-fun s157 () Int (ite s156 s64 s65))
+[GOOD] (define-fun s158 () Int (ite s154 s61 s157))
+[GOOD] (define-fun s159 () Int (ite s152 s58 s158))
+[GOOD] (define-fun s160 () Int (ite s141 s52 s159))
+[GOOD] (define-fun s161 () Int (ite s148 s51 s160))
+[GOOD] (define-fun s162 () Int (ite s144 s44 s161))
+[GOOD] (define-fun s163 () Int (+ s140 s162))
+[GOOD] (define-fun s164 () Bool ((as is-Var Bool) s5))
+[GOOD] (define-fun s165 () String (getVar_1 s5))
+[GOOD] (define-fun s166 () Bool (= s41 s165))
+[GOOD] (define-fun s167 () Bool (and s164 s166))
+[GOOD] (define-fun s168 () Bool (= s45 s165))
+[GOOD] (define-fun s169 () Bool (= s47 s165))
+[GOOD] (define-fun s170 () Bool (or s168 s169))
+[GOOD] (define-fun s171 () Bool (and s164 s170))
+[GOOD] (define-fun s172 () Bool ((as is-Val Bool) s5))
+[GOOD] (define-fun s173 () Int (getVal_1 s5))
+[GOOD] (define-fun s174 () Bool (< s173 s55))
+[GOOD] (define-fun s175 () Bool (and s172 s174))
+[GOOD] (define-fun s176 () Bool (= s55 s173))
+[GOOD] (define-fun s177 () Bool (and s172 s176))
+[GOOD] (define-fun s178 () Bool (> s173 s55))
+[GOOD] (define-fun s179 () Bool (and s172 s178))
+[GOOD] (define-fun s180 () Int (ite s179 s64 s65))
+[GOOD] (define-fun s181 () Int (ite s177 s61 s180))
+[GOOD] (define-fun s182 () Int (ite s175 s58 s181))
+[GOOD] (define-fun s183 () Int (ite s164 s52 s182))
+[GOOD] (define-fun s184 () Int (ite s171 s51 s183))
+[GOOD] (define-fun s185 () Int (ite s167 s44 s184))
+[GOOD] (define-fun s186 () Int (+ s163 s185))
+[GOOD] (define-fun s187 () Bool ((as is-Var Bool) s6))
+[GOOD] (define-fun s188 () String (getVar_1 s6))
+[GOOD] (define-fun s189 () Bool (= s41 s188))
+[GOOD] (define-fun s190 () Bool (and s187 s189))
+[GOOD] (define-fun s191 () Bool (= s45 s188))
+[GOOD] (define-fun s192 () Bool (= s47 s188))
+[GOOD] (define-fun s193 () Bool (or s191 s192))
+[GOOD] (define-fun s194 () Bool (and s187 s193))
+[GOOD] (define-fun s195 () Bool ((as is-Val Bool) s6))
+[GOOD] (define-fun s196 () Int (getVal_1 s6))
+[GOOD] (define-fun s197 () Bool (< s196 s55))
+[GOOD] (define-fun s198 () Bool (and s195 s197))
+[GOOD] (define-fun s199 () Bool (= s55 s196))
+[GOOD] (define-fun s200 () Bool (and s195 s199))
+[GOOD] (define-fun s201 () Bool (> s196 s55))
+[GOOD] (define-fun s202 () Bool (and s195 s201))
+[GOOD] (define-fun s203 () Int (ite s202 s64 s65))
+[GOOD] (define-fun s204 () Int (ite s200 s61 s203))
+[GOOD] (define-fun s205 () Int (ite s198 s58 s204))
+[GOOD] (define-fun s206 () Int (ite s187 s52 s205))
+[GOOD] (define-fun s207 () Int (ite s194 s51 s206))
+[GOOD] (define-fun s208 () Int (ite s190 s44 s207))
+[GOOD] (define-fun s209 () Int (+ s186 s208))
+[GOOD] (define-fun s210 () Bool ((as is-Var Bool) s7))
+[GOOD] (define-fun s211 () String (getVar_1 s7))
+[GOOD] (define-fun s212 () Bool (= s41 s211))
+[GOOD] (define-fun s213 () Bool (and s210 s212))
+[GOOD] (define-fun s214 () Bool (= s45 s211))
+[GOOD] (define-fun s215 () Bool (= s47 s211))
+[GOOD] (define-fun s216 () Bool (or s214 s215))
+[GOOD] (define-fun s217 () Bool (and s210 s216))
+[GOOD] (define-fun s218 () Bool ((as is-Val Bool) s7))
+[GOOD] (define-fun s219 () Int (getVal_1 s7))
+[GOOD] (define-fun s220 () Bool (< s219 s55))
+[GOOD] (define-fun s221 () Bool (and s218 s220))
+[GOOD] (define-fun s222 () Bool (= s55 s219))
+[GOOD] (define-fun s223 () Bool (and s218 s222))
+[GOOD] (define-fun s224 () Bool (> s219 s55))
+[GOOD] (define-fun s225 () Bool (and s218 s224))
+[GOOD] (define-fun s226 () Int (ite s225 s64 s65))
+[GOOD] (define-fun s227 () Int (ite s223 s61 s226))
+[GOOD] (define-fun s228 () Int (ite s221 s58 s227))
+[GOOD] (define-fun s229 () Int (ite s210 s52 s228))
+[GOOD] (define-fun s230 () Int (ite s217 s51 s229))
+[GOOD] (define-fun s231 () Int (ite s213 s44 s230))
+[GOOD] (define-fun s232 () Int (+ s209 s231))
+[GOOD] (define-fun s233 () Bool ((as is-Var Bool) s8))
+[GOOD] (define-fun s234 () String (getVar_1 s8))
+[GOOD] (define-fun s235 () Bool (= s41 s234))
+[GOOD] (define-fun s236 () Bool (and s233 s235))
+[GOOD] (define-fun s237 () Bool (= s45 s234))
+[GOOD] (define-fun s238 () Bool (= s47 s234))
+[GOOD] (define-fun s239 () Bool (or s237 s238))
+[GOOD] (define-fun s240 () Bool (and s233 s239))
+[GOOD] (define-fun s241 () Bool ((as is-Val Bool) s8))
+[GOOD] (define-fun s242 () Int (getVal_1 s8))
+[GOOD] (define-fun s243 () Bool (< s242 s55))
+[GOOD] (define-fun s244 () Bool (and s241 s243))
+[GOOD] (define-fun s245 () Bool (= s55 s242))
+[GOOD] (define-fun s246 () Bool (and s241 s245))
+[GOOD] (define-fun s247 () Bool (> s242 s55))
+[GOOD] (define-fun s248 () Bool (and s241 s247))
+[GOOD] (define-fun s249 () Int (ite s248 s64 s65))
+[GOOD] (define-fun s250 () Int (ite s246 s61 s249))
+[GOOD] (define-fun s251 () Int (ite s244 s58 s250))
+[GOOD] (define-fun s252 () Int (ite s233 s52 s251))
+[GOOD] (define-fun s253 () Int (ite s240 s51 s252))
+[GOOD] (define-fun s254 () Int (ite s236 s44 s253))
+[GOOD] (define-fun s255 () Int (+ s232 s254))
+[GOOD] (define-fun s256 () Bool ((as is-Var Bool) s9))
+[GOOD] (define-fun s257 () String (getVar_1 s9))
+[GOOD] (define-fun s258 () Bool (= s41 s257))
+[GOOD] (define-fun s259 () Bool (and s256 s258))
+[GOOD] (define-fun s260 () Bool (= s45 s257))
+[GOOD] (define-fun s261 () Bool (= s47 s257))
+[GOOD] (define-fun s262 () Bool (or s260 s261))
+[GOOD] (define-fun s263 () Bool (and s256 s262))
+[GOOD] (define-fun s264 () Bool ((as is-Val Bool) s9))
+[GOOD] (define-fun s265 () Int (getVal_1 s9))
+[GOOD] (define-fun s266 () Bool (< s265 s55))
+[GOOD] (define-fun s267 () Bool (and s264 s266))
+[GOOD] (define-fun s268 () Bool (= s55 s265))
+[GOOD] (define-fun s269 () Bool (and s264 s268))
+[GOOD] (define-fun s270 () Bool (> s265 s55))
+[GOOD] (define-fun s271 () Bool (and s264 s270))
+[GOOD] (define-fun s272 () Int (ite s271 s64 s65))
+[GOOD] (define-fun s273 () Int (ite s269 s61 s272))
+[GOOD] (define-fun s274 () Int (ite s267 s58 s273))
+[GOOD] (define-fun s275 () Int (ite s256 s52 s274))
+[GOOD] (define-fun s276 () Int (ite s263 s51 s275))
+[GOOD] (define-fun s277 () Int (ite s259 s44 s276))
+[GOOD] (define-fun s278 () Int (+ s255 s277))
+[GOOD] (define-fun s280 () Bool (distinct s278 s279))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s38)
+[GOOD] (assert s280)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr12c.gold b/SBVTestSuite/GoldFiles/adt_expr12c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr12c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr13.gold b/SBVTestSuite/GoldFiles/adt_expr13.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr13.gold
@@ -0,0 +1,75 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Val Expr) 3))
+[GOOD] (define-fun s5 () String "a")
+[GOOD] (define-fun s8 () Int 0)
+[GOOD] (define-fun s9 () String "b")
+[GOOD] (define-fun s11 () String "c")
+[GOOD] (define-fun s15 () Int 1)
+[GOOD] (define-fun s16 () Int 2)
+[GOOD] (define-fun s19 () Int 10)
+[GOOD] (define-fun s22 () Int 3)
+[GOOD] (define-fun s25 () Int 4)
+[GOOD] (define-fun s28 () Int 5)
+[GOOD] (define-fun s29 () Int 6)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s4 () String (getVar_1 s0))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool (and s3 s6))
+[GOOD] (define-fun s10 () Bool (= s4 s9))
+[GOOD] (define-fun s12 () Bool (= s4 s11))
+[GOOD] (define-fun s13 () Bool (or s10 s12))
+[GOOD] (define-fun s14 () Bool (and s3 s13))
+[GOOD] (define-fun s17 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s18 () Int (getVal_1 s0))
+[GOOD] (define-fun s20 () Bool (< s18 s19))
+[GOOD] (define-fun s21 () Bool (and s17 s20))
+[GOOD] (define-fun s23 () Bool (= s18 s19))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s26 () Bool (> s18 s19))
+[GOOD] (define-fun s27 () Bool (and s17 s26))
+[GOOD] (define-fun s30 () Int (ite s27 s28 s29))
+[GOOD] (define-fun s31 () Int (ite s24 s25 s30))
+[GOOD] (define-fun s32 () Int (ite s21 s22 s31))
+[GOOD] (define-fun s33 () Int (ite s3 s16 s32))
+[GOOD] (define-fun s34 () Int (ite s14 s15 s33))
+[GOOD] (define-fun s35 () Int (ite s7 s8 s34))
+[GOOD] (define-fun s36 () Bool (distinct s22 s35))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s36)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr13c.gold b/SBVTestSuite/GoldFiles/adt_expr13c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr13c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr14.gold b/SBVTestSuite/GoldFiles/adt_expr14.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr14.gold
@@ -0,0 +1,75 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Add Expr) ((as Val Expr) 3) ((as Val Expr) 4)))
+[GOOD] (define-fun s5 () String "a")
+[GOOD] (define-fun s8 () Int 0)
+[GOOD] (define-fun s9 () String "b")
+[GOOD] (define-fun s11 () String "c")
+[GOOD] (define-fun s15 () Int 1)
+[GOOD] (define-fun s16 () Int 2)
+[GOOD] (define-fun s19 () Int 10)
+[GOOD] (define-fun s22 () Int 3)
+[GOOD] (define-fun s25 () Int 4)
+[GOOD] (define-fun s28 () Int 5)
+[GOOD] (define-fun s29 () Int 6)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s4 () String (getVar_1 s0))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool (and s3 s6))
+[GOOD] (define-fun s10 () Bool (= s4 s9))
+[GOOD] (define-fun s12 () Bool (= s4 s11))
+[GOOD] (define-fun s13 () Bool (or s10 s12))
+[GOOD] (define-fun s14 () Bool (and s3 s13))
+[GOOD] (define-fun s17 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s18 () Int (getVal_1 s0))
+[GOOD] (define-fun s20 () Bool (< s18 s19))
+[GOOD] (define-fun s21 () Bool (and s17 s20))
+[GOOD] (define-fun s23 () Bool (= s18 s19))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s26 () Bool (> s18 s19))
+[GOOD] (define-fun s27 () Bool (and s17 s26))
+[GOOD] (define-fun s30 () Int (ite s27 s28 s29))
+[GOOD] (define-fun s31 () Int (ite s24 s25 s30))
+[GOOD] (define-fun s32 () Int (ite s21 s22 s31))
+[GOOD] (define-fun s33 () Int (ite s3 s16 s32))
+[GOOD] (define-fun s34 () Int (ite s14 s15 s33))
+[GOOD] (define-fun s35 () Int (ite s7 s8 s34))
+[GOOD] (define-fun s36 () Bool (distinct s29 s35))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s36)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr14c.gold b/SBVTestSuite/GoldFiles/adt_expr14c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr14c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr15.gold b/SBVTestSuite/GoldFiles/adt_expr15.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr15.gold
@@ -0,0 +1,75 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Mul Expr) ((as Val Expr) 3) ((as Add Expr) ((as Val Expr) 3) ((as Val Expr) 4))))
+[GOOD] (define-fun s5 () String "a")
+[GOOD] (define-fun s8 () Int 0)
+[GOOD] (define-fun s9 () String "b")
+[GOOD] (define-fun s11 () String "c")
+[GOOD] (define-fun s15 () Int 1)
+[GOOD] (define-fun s16 () Int 2)
+[GOOD] (define-fun s19 () Int 10)
+[GOOD] (define-fun s22 () Int 3)
+[GOOD] (define-fun s25 () Int 4)
+[GOOD] (define-fun s28 () Int 5)
+[GOOD] (define-fun s29 () Int 6)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s4 () String (getVar_1 s0))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool (and s3 s6))
+[GOOD] (define-fun s10 () Bool (= s4 s9))
+[GOOD] (define-fun s12 () Bool (= s4 s11))
+[GOOD] (define-fun s13 () Bool (or s10 s12))
+[GOOD] (define-fun s14 () Bool (and s3 s13))
+[GOOD] (define-fun s17 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s18 () Int (getVal_1 s0))
+[GOOD] (define-fun s20 () Bool (< s18 s19))
+[GOOD] (define-fun s21 () Bool (and s17 s20))
+[GOOD] (define-fun s23 () Bool (= s18 s19))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s26 () Bool (> s18 s19))
+[GOOD] (define-fun s27 () Bool (and s17 s26))
+[GOOD] (define-fun s30 () Int (ite s27 s28 s29))
+[GOOD] (define-fun s31 () Int (ite s24 s25 s30))
+[GOOD] (define-fun s32 () Int (ite s21 s22 s31))
+[GOOD] (define-fun s33 () Int (ite s3 s16 s32))
+[GOOD] (define-fun s34 () Int (ite s14 s15 s33))
+[GOOD] (define-fun s35 () Int (ite s7 s8 s34))
+[GOOD] (define-fun s36 () Bool (distinct s29 s35))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s36)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr15c.gold b/SBVTestSuite/GoldFiles/adt_expr15c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr15c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr16.gold b/SBVTestSuite/GoldFiles/adt_expr16.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr16.gold
@@ -0,0 +1,75 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Let Expr) "a" ((as Mul Expr) ((as Val Expr) 3) ((as Add Expr) ((as Val Expr) 3) ((as Val Expr) 4))) ((as Add Expr) ((as Var Expr) "a") ((as Add Expr) ((as Val Expr) 3) ((as Val Expr) 4)))))
+[GOOD] (define-fun s5 () String "a")
+[GOOD] (define-fun s8 () Int 0)
+[GOOD] (define-fun s9 () String "b")
+[GOOD] (define-fun s11 () String "c")
+[GOOD] (define-fun s15 () Int 1)
+[GOOD] (define-fun s16 () Int 2)
+[GOOD] (define-fun s19 () Int 10)
+[GOOD] (define-fun s22 () Int 3)
+[GOOD] (define-fun s25 () Int 4)
+[GOOD] (define-fun s28 () Int 5)
+[GOOD] (define-fun s29 () Int 6)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s4 () String (getVar_1 s0))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool (and s3 s6))
+[GOOD] (define-fun s10 () Bool (= s4 s9))
+[GOOD] (define-fun s12 () Bool (= s4 s11))
+[GOOD] (define-fun s13 () Bool (or s10 s12))
+[GOOD] (define-fun s14 () Bool (and s3 s13))
+[GOOD] (define-fun s17 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s18 () Int (getVal_1 s0))
+[GOOD] (define-fun s20 () Bool (< s18 s19))
+[GOOD] (define-fun s21 () Bool (and s17 s20))
+[GOOD] (define-fun s23 () Bool (= s18 s19))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s26 () Bool (> s18 s19))
+[GOOD] (define-fun s27 () Bool (and s17 s26))
+[GOOD] (define-fun s30 () Int (ite s27 s28 s29))
+[GOOD] (define-fun s31 () Int (ite s24 s25 s30))
+[GOOD] (define-fun s32 () Int (ite s21 s22 s31))
+[GOOD] (define-fun s33 () Int (ite s3 s16 s32))
+[GOOD] (define-fun s34 () Int (ite s14 s15 s33))
+[GOOD] (define-fun s35 () Int (ite s7 s8 s34))
+[GOOD] (define-fun s36 () Bool (distinct s29 s35))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s36)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr16c.gold b/SBVTestSuite/GoldFiles/adt_expr16c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr16c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr17.gold b/SBVTestSuite/GoldFiles/adt_expr17.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr17.gold
@@ -0,0 +1,75 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Add Expr) ((as Let Expr) "a" ((as Mul Expr) ((as Val Expr) 3) ((as Add Expr) ((as Val Expr) 3) ((as Val Expr) 4))) ((as Add Expr) ((as Var Expr) "a") ((as Add Expr) ((as Val Expr) 3) ((as Val Expr) 4)))) ((as Let Expr) "a" ((as Let Expr) "a" ((as Mul Expr) ((as Val Expr) 3) ((as Add Expr) ((as Val Expr) 3) ((as Val Expr) 4))) ((as Add Expr) ((as Var Expr) "a") ((as Add Expr) ((as Val Expr) 3) ((as Val Expr) 4)))) ((as Add Expr) ((as Var Expr) "a") ((as Add Expr) ((as Val Expr) 3) ((as Val Expr) 4))))))
+[GOOD] (define-fun s5 () String "a")
+[GOOD] (define-fun s8 () Int 0)
+[GOOD] (define-fun s9 () String "b")
+[GOOD] (define-fun s11 () String "c")
+[GOOD] (define-fun s15 () Int 1)
+[GOOD] (define-fun s16 () Int 2)
+[GOOD] (define-fun s19 () Int 10)
+[GOOD] (define-fun s22 () Int 3)
+[GOOD] (define-fun s25 () Int 4)
+[GOOD] (define-fun s28 () Int 5)
+[GOOD] (define-fun s29 () Int 6)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s4 () String (getVar_1 s0))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool (and s3 s6))
+[GOOD] (define-fun s10 () Bool (= s4 s9))
+[GOOD] (define-fun s12 () Bool (= s4 s11))
+[GOOD] (define-fun s13 () Bool (or s10 s12))
+[GOOD] (define-fun s14 () Bool (and s3 s13))
+[GOOD] (define-fun s17 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s18 () Int (getVal_1 s0))
+[GOOD] (define-fun s20 () Bool (< s18 s19))
+[GOOD] (define-fun s21 () Bool (and s17 s20))
+[GOOD] (define-fun s23 () Bool (= s18 s19))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s26 () Bool (> s18 s19))
+[GOOD] (define-fun s27 () Bool (and s17 s26))
+[GOOD] (define-fun s30 () Int (ite s27 s28 s29))
+[GOOD] (define-fun s31 () Int (ite s24 s25 s30))
+[GOOD] (define-fun s32 () Int (ite s21 s22 s31))
+[GOOD] (define-fun s33 () Int (ite s3 s16 s32))
+[GOOD] (define-fun s34 () Int (ite s14 s15 s33))
+[GOOD] (define-fun s35 () Int (ite s7 s8 s34))
+[GOOD] (define-fun s36 () Bool (distinct s29 s35))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s36)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr17c.gold b/SBVTestSuite/GoldFiles/adt_expr17c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr17c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr18.gold b/SBVTestSuite/GoldFiles/adt_expr18.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr18.gold
@@ -0,0 +1,75 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Let Expr) "a" ((as Add Expr) ((as Let Expr) "a" ((as Mul Expr) ((as Val Expr) 3) ((as Add Expr) ((as Val Expr) 3) ((as Val Expr) 4))) ((as Add Expr) ((as Var Expr) "a") ((as Add Expr) ((as Val Expr) 3) ((as Val Expr) 4)))) ((as Let Expr) "a" ((as Let Expr) "a" ((as Mul Expr) ((as Val Expr) 3) ((as Add Expr) ((as Val Expr) 3) ((as Val Expr) 4))) ((as Add Expr) ((as Var Expr) "a") ((as Add Expr) ((as Val Expr) 3) ((as Val Expr) 4)))) ((as Add Expr) ((as Var Expr) "a") ((as Add Expr) ((as Val Expr) 3) ((as Val Expr) 4))))) ((as Mul Expr) ((as Var Expr) "a") ((as Var Expr) "a"))))
+[GOOD] (define-fun s5 () String "a")
+[GOOD] (define-fun s8 () Int 0)
+[GOOD] (define-fun s9 () String "b")
+[GOOD] (define-fun s11 () String "c")
+[GOOD] (define-fun s15 () Int 1)
+[GOOD] (define-fun s16 () Int 2)
+[GOOD] (define-fun s19 () Int 10)
+[GOOD] (define-fun s22 () Int 3)
+[GOOD] (define-fun s25 () Int 4)
+[GOOD] (define-fun s28 () Int 5)
+[GOOD] (define-fun s29 () Int 6)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s4 () String (getVar_1 s0))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool (and s3 s6))
+[GOOD] (define-fun s10 () Bool (= s4 s9))
+[GOOD] (define-fun s12 () Bool (= s4 s11))
+[GOOD] (define-fun s13 () Bool (or s10 s12))
+[GOOD] (define-fun s14 () Bool (and s3 s13))
+[GOOD] (define-fun s17 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s18 () Int (getVal_1 s0))
+[GOOD] (define-fun s20 () Bool (< s18 s19))
+[GOOD] (define-fun s21 () Bool (and s17 s20))
+[GOOD] (define-fun s23 () Bool (= s18 s19))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s26 () Bool (> s18 s19))
+[GOOD] (define-fun s27 () Bool (and s17 s26))
+[GOOD] (define-fun s30 () Int (ite s27 s28 s29))
+[GOOD] (define-fun s31 () Int (ite s24 s25 s30))
+[GOOD] (define-fun s32 () Int (ite s21 s22 s31))
+[GOOD] (define-fun s33 () Int (ite s3 s16 s32))
+[GOOD] (define-fun s34 () Int (ite s14 s15 s33))
+[GOOD] (define-fun s35 () Int (ite s7 s8 s34))
+[GOOD] (define-fun s36 () Bool (distinct s29 s35))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s36)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_expr18c.gold b/SBVTestSuite/GoldFiles/adt_expr18c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_expr18c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_gen00.gold b/SBVTestSuite/GoldFiles/adt_gen00.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_gen00.gold
@@ -0,0 +1,278 @@
+[MEASURE] Verifying termination measures for: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer), valid @(SBV [[Char]] -> SBV Expr -> SBV Bool)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): not in a multi-member cycle, skipping mutual check
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): barified = "|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|"
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2)]
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): recursive calls found = 6
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): trying sbv.dt.size.Expr arg2
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK (structural recursion)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): barified = "|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|"
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2)]
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): recursive calls found = 1
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): trying length arg1
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Bool (>= s4 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Int (seq.len s13))
+[GOOD] (define-fun s18 () Bool (not s10))
+[GOOD] (define-fun s19 () Bool (and s6 s18))
+[GOOD] (define-fun s20 () Bool (> s4 s17))
+[GOOD] (define-fun s21 () Bool (=> s19 s20))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): length arg1 -> OK
+[MEASURE] Passed (terminating): get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] Checking: valid @(SBV [[Char]] -> SBV Expr -> SBV Bool)
+[MEASURE] valid @(SBV [[Char]] -> SBV Expr -> SBV Bool): barified = "|valid @(SBV [[Char]] -> SBV Expr -> SBV Bool)|"
+[MEASURE] valid @(SBV [[Char]] -> SBV Expr -> SBV Bool): Uninterpreted ops in DAG: [("|valid @(SBV [[Char]] -> SBV Expr -> SBV Bool)|",2),("|valid @(SBV [[Char]] -> SBV Expr -> SBV Bool)|",2),("|valid @(SBV [[Char]] -> SBV Expr -> SBV Bool)|",2),("|valid @(SBV [[Char]] -> SBV Expr -> SBV Bool)|",2),("|valid @(SBV [[Char]] -> SBV Expr -> SBV Bool)|",2),("|valid @(SBV [[Char]] -> SBV Expr -> SBV Bool)|",2)]
+[MEASURE] valid @(SBV [[Char]] -> SBV Expr -> SBV Bool): recursive calls found = 6
+[MEASURE] valid @(SBV [[Char]] -> SBV Expr -> SBV Bool): trying sbv.dt.size.Expr arg2
+[MEASURE] valid @(SBV [[Char]] -> SBV Expr -> SBV Bool): sbv.dt.size.Expr arg2 -> OK (structural recursion)
+[MEASURE] valid @(SBV [[Char]] -> SBV Expr -> SBV Bool): sbv.dt.size.Expr arg2 -> OK
+[MEASURE] Passed (terminating): valid @(SBV [[Char]] -> SBV Expr -> SBV Bool)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (Seq String) (as seq.empty (Seq String)))
+[GOOD] (define-fun s3 () (Seq (SBVTuple2 String Int)) (as seq.empty (Seq (SBVTuple2 String Int))))
+[GOOD] (define-fun s5 () Int 12)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr) ; tracks user variable "a"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |valid @(SBV [[Char]] -> SBV Expr -> SBV Bool)| :: [SString] -> Expr -> SBool [Recursive]
+[GOOD] (define-fun-rec |valid @(SBV [[Char]] -> SBV Expr -> SBV Bool)| ((l1_s0 (Seq String)) (l1_s1 Expr)) Bool
+                                 (let ((l1_s2 ((as is-Val Bool) l1_s1)))
+                                 (let ((l1_s3 ((as is-Var Bool) l1_s1)))
+                                 (let ((l1_s4 (getVar_1 l1_s1)))
+                                 (let ((l1_s5 (str.in_re l1_s4 (re.++ (re.range "a" "z") (re.* (re.union (re.range "a" "z") (re.range "A" "Z") (re.range "0" "9")))))))
+                                 (let ((l1_s6 (seq.unit l1_s4)))
+                                 (let ((l1_s7 (seq.contains l1_s0 l1_s6)))
+                                 (let ((l1_s8 (and l1_s5 l1_s7)))
+                                 (let ((l1_s9 ((as is-Add Bool) l1_s1)))
+                                 (let ((l1_s10 (getAdd_1 l1_s1)))
+                                 (let ((l1_s11 (|valid @(SBV [[Char]] -> SBV Expr -> SBV Bool)| l1_s0 l1_s10)))
+                                 (let ((l1_s12 (getAdd_2 l1_s1)))
+                                 (let ((l1_s13 (|valid @(SBV [[Char]] -> SBV Expr -> SBV Bool)| l1_s0 l1_s12)))
+                                 (let ((l1_s14 (and l1_s11 l1_s13)))
+                                 (let ((l1_s15 ((as is-Mul Bool) l1_s1)))
+                                 (let ((l1_s16 (getMul_1 l1_s1)))
+                                 (let ((l1_s17 (|valid @(SBV [[Char]] -> SBV Expr -> SBV Bool)| l1_s0 l1_s16)))
+                                 (let ((l1_s18 (getMul_2 l1_s1)))
+                                 (let ((l1_s19 (|valid @(SBV [[Char]] -> SBV Expr -> SBV Bool)| l1_s0 l1_s18)))
+                                 (let ((l1_s20 (and l1_s17 l1_s19)))
+                                 (let ((l1_s21 (getLet_1 l1_s1)))
+                                 (let ((l1_s22 (str.in_re l1_s21 (re.++ (re.range "a" "z") (re.* (re.union (re.range "a" "z") (re.range "A" "Z") (re.range "0" "9")))))))
+                                 (let ((l1_s23 (getLet_2 l1_s1)))
+                                 (let ((l1_s24 (|valid @(SBV [[Char]] -> SBV Expr -> SBV Bool)| l1_s0 l1_s23)))
+                                 (let ((l1_s25 (seq.unit l1_s21)))
+                                 (let ((l1_s26 (seq.++ l1_s25 l1_s0)))
+                                 (let ((l1_s27 (getLet_3 l1_s1)))
+                                 (let ((l1_s28 (|valid @(SBV [[Char]] -> SBV Expr -> SBV Bool)| l1_s26 l1_s27)))
+                                 (let ((l1_s29 (and l1_s24 l1_s28)))
+                                 (let ((l1_s30 (and l1_s22 l1_s29)))
+                                 (let ((l1_s31 (ite l1_s15 l1_s20 l1_s30)))
+                                 (let ((l1_s32 (ite l1_s9 l1_s14 l1_s31)))
+                                 (let ((l1_s33 (ite l1_s3 l1_s8 l1_s32)))
+                                 (let ((l1_s34 (or l1_s2 l1_s33)))
+                                 l1_s34))))))))))))))))))))))))))))))))))
+[GOOD] ; |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| :: [(SString, SInteger)] -> SString -> SInteger [Recursive]
+[GOOD] (define-fun-rec |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| ((l2_s0 (Seq (SBVTuple2 String Int))) (l2_s1 String)) Int
+                                                 (let ((l2_s3 0))
+                                                 (let ((l2_s11 1))
+                                                 (let ((l2_s2 (seq.len l2_s0)))
+                                                 (let ((l2_s4 (= l2_s2 l2_s3)))
+                                                 (let ((l2_s5 (not l2_s4)))
+                                                 (let ((l2_s6 (seq.nth l2_s0 l2_s3)))
+                                                 (let ((l2_s7 (proj_1_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s8 (= l2_s1 l2_s7)))
+                                                 (let ((l2_s9 (and l2_s5 l2_s8)))
+                                                 (let ((l2_s10 (proj_2_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s12 (- l2_s2 l2_s11)))
+                                                 (let ((l2_s13 (seq.extract l2_s0 l2_s11 l2_s12)))
+                                                 (let ((l2_s14 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l2_s13 l2_s1)))
+                                                 (let ((l2_s15 (ite l2_s9 l2_s10 l2_s14)))
+                                                 (let ((l2_s16 (ite l2_s4 l2_s3 l2_s15)))
+                                                 l2_s16))))))))))))))))
+[GOOD] ; |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| :: [(SString, SInteger)] -> Expr -> SInteger [Recursive] [Refers to: |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|]
+[GOOD] (define-fun-rec |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| ((l1_s0 (Seq (SBVTuple2 String Int))) (l1_s1 Expr)) Int
+                                 (let ((l1_s2 ((as is-Val Bool) l1_s1)))
+                                 (let ((l1_s3 (getVal_1 l1_s1)))
+                                 (let ((l1_s4 ((as is-Var Bool) l1_s1)))
+                                 (let ((l1_s5 (getVar_1 l1_s1)))
+                                 (let ((l1_s6 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l1_s0 l1_s5)))
+                                 (let ((l1_s7 ((as is-Add Bool) l1_s1)))
+                                 (let ((l1_s8 (getAdd_1 l1_s1)))
+                                 (let ((l1_s9 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s8)))
+                                 (let ((l1_s10 (getAdd_2 l1_s1)))
+                                 (let ((l1_s11 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s10)))
+                                 (let ((l1_s12 (+ l1_s9 l1_s11)))
+                                 (let ((l1_s13 ((as is-Mul Bool) l1_s1)))
+                                 (let ((l1_s14 (getMul_1 l1_s1)))
+                                 (let ((l1_s15 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s14)))
+                                 (let ((l1_s16 (getMul_2 l1_s1)))
+                                 (let ((l1_s17 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s16)))
+                                 (let ((l1_s18 (* l1_s15 l1_s17)))
+                                 (let ((l1_s19 (getLet_1 l1_s1)))
+                                 (let ((l1_s20 (getLet_2 l1_s1)))
+                                 (let ((l1_s21 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s20)))
+                                 (let ((l1_s22 ((as mkSBVTuple2 (SBVTuple2 String Int)) l1_s19 l1_s21)))
+                                 (let ((l1_s23 (seq.unit l1_s22)))
+                                 (let ((l1_s24 (seq.++ l1_s23 l1_s0)))
+                                 (let ((l1_s25 (getLet_3 l1_s1)))
+                                 (let ((l1_s26 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s24 l1_s25)))
+                                 (let ((l1_s27 (ite l1_s13 l1_s18 l1_s26)))
+                                 (let ((l1_s28 (ite l1_s7 l1_s12 l1_s27)))
+                                 (let ((l1_s29 (ite l1_s4 l1_s6 l1_s28)))
+                                 (let ((l1_s30 (ite l1_s2 l1_s3 l1_s29)))
+                                 l1_s30))))))))))))))))))))))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (|valid @(SBV [[Char]] -> SBV Expr -> SBV Bool)| s1 s0))
+[GOOD] (define-fun s4 () Int (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| s3 s0))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool ((as is-Let Bool) s0))
+[GOOD] (define-fun s8 () Expr (getLet_3 s0))
+[GOOD] (define-fun s9 () Bool ((as is-Let Bool) s8))
+[GOOD] (define-fun s10 () Expr (getLet_3 s8))
+[GOOD] (define-fun s11 () Bool ((as is-Add Bool) s10))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s6)
+[GOOD] (assert s7)
+[GOOD] (assert s9)
+[GOOD] (assert s11)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (Let "p"
+            (Add (Mul (Val 4) (Mul (Val (- 5)) (Val (- 3))))
+                 (Let "d" (Val (- 58)) (Var "d")))
+            (Let "d" (Add (Val 8) (Val 1)) (Add (Var "d") (Val 3))))))
+
+Got: (let p = ((4 * (-5 * -3)) + (let d = -58 in d)) in (let d = (8 + 1) in (d + 3)))
+DONE
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_gen01.gold b/SBVTestSuite/GoldFiles/adt_gen01.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_gen01.gold
@@ -0,0 +1,83 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () String "a")
+[GOOD] (define-fun s6 () Int 0)
+[GOOD] (define-fun s7 () String "b")
+[GOOD] (define-fun s9 () String "c")
+[GOOD] (define-fun s13 () Int 1)
+[GOOD] (define-fun s14 () Int 2)
+[GOOD] (define-fun s17 () Int 10)
+[GOOD] (define-fun s20 () Int 3)
+[GOOD] (define-fun s23 () Int 4)
+[GOOD] (define-fun s26 () Int 5)
+[GOOD] (define-fun s28 () Int 6)
+[GOOD] (define-fun s30 () Int 7)
+[GOOD] (define-fun s32 () Int 8)
+[GOOD] (define-fun s33 () Int 100)
+[GOOD] (define-fun s43 () Int (- 1))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr) ; tracks user variable "a"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s2 () String (getVar_1 s0))
+[GOOD] (define-fun s4 () Bool (= s2 s3))
+[GOOD] (define-fun s5 () Bool (and s1 s4))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s10 () Bool (= s2 s9))
+[GOOD] (define-fun s11 () Bool (or s8 s10))
+[GOOD] (define-fun s12 () Bool (and s1 s11))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s16 () Int (getVal_1 s0))
+[GOOD] (define-fun s18 () Bool (< s16 s17))
+[GOOD] (define-fun s19 () Bool (and s15 s18))
+[GOOD] (define-fun s21 () Bool (= s16 s17))
+[GOOD] (define-fun s22 () Bool (and s15 s21))
+[GOOD] (define-fun s24 () Bool (> s16 s17))
+[GOOD] (define-fun s25 () Bool (and s15 s24))
+[GOOD] (define-fun s27 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s29 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s31 () Bool ((as is-Let Bool) s0))
+[GOOD] (define-fun s34 () Int (ite s31 s32 s33))
+[GOOD] (define-fun s35 () Int (ite s29 s30 s34))
+[GOOD] (define-fun s36 () Int (ite s27 s28 s35))
+[GOOD] (define-fun s37 () Int (ite s25 s26 s36))
+[GOOD] (define-fun s38 () Int (ite s22 s23 s37))
+[GOOD] (define-fun s39 () Int (ite s19 s20 s38))
+[GOOD] (define-fun s40 () Int (ite s1 s14 s39))
+[GOOD] (define-fun s41 () Int (ite s12 s13 s40))
+[GOOD] (define-fun s42 () Int (ite s5 s6 s41))
+[GOOD] (define-fun s44 () Bool (= s42 s43))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s44)
+[SEND] (check-sat)
+[RECV] unsat
+
+UNSAT
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_gen02.gold b/SBVTestSuite/GoldFiles/adt_gen02.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_gen02.gold
@@ -0,0 +1,85 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () String "a")
+[GOOD] (define-fun s6 () Int 0)
+[GOOD] (define-fun s7 () String "b")
+[GOOD] (define-fun s9 () String "c")
+[GOOD] (define-fun s13 () Int 1)
+[GOOD] (define-fun s14 () Int 2)
+[GOOD] (define-fun s17 () Int 10)
+[GOOD] (define-fun s20 () Int 3)
+[GOOD] (define-fun s23 () Int 4)
+[GOOD] (define-fun s26 () Int 5)
+[GOOD] (define-fun s28 () Int 6)
+[GOOD] (define-fun s30 () Int 7)
+[GOOD] (define-fun s32 () Int 8)
+[GOOD] (define-fun s33 () Int 100)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr) ; tracks user variable "a"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s2 () String (getVar_1 s0))
+[GOOD] (define-fun s4 () Bool (= s2 s3))
+[GOOD] (define-fun s5 () Bool (and s1 s4))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s10 () Bool (= s2 s9))
+[GOOD] (define-fun s11 () Bool (or s8 s10))
+[GOOD] (define-fun s12 () Bool (and s1 s11))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s16 () Int (getVal_1 s0))
+[GOOD] (define-fun s18 () Bool (< s16 s17))
+[GOOD] (define-fun s19 () Bool (and s15 s18))
+[GOOD] (define-fun s21 () Bool (= s16 s17))
+[GOOD] (define-fun s22 () Bool (and s15 s21))
+[GOOD] (define-fun s24 () Bool (> s16 s17))
+[GOOD] (define-fun s25 () Bool (and s15 s24))
+[GOOD] (define-fun s27 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s29 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s31 () Bool ((as is-Let Bool) s0))
+[GOOD] (define-fun s34 () Int (ite s31 s32 s33))
+[GOOD] (define-fun s35 () Int (ite s29 s30 s34))
+[GOOD] (define-fun s36 () Int (ite s27 s28 s35))
+[GOOD] (define-fun s37 () Int (ite s25 s26 s36))
+[GOOD] (define-fun s38 () Int (ite s22 s23 s37))
+[GOOD] (define-fun s39 () Int (ite s19 s20 s38))
+[GOOD] (define-fun s40 () Int (ite s1 s14 s39))
+[GOOD] (define-fun s41 () Int (ite s12 s13 s40))
+[GOOD] (define-fun s42 () Int (ite s5 s6 s41))
+[GOOD] (define-fun s43 () Bool (= s6 s42))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s43)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (Var "a")))
+
+Got: a
+DONE
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_gen03.gold b/SBVTestSuite/GoldFiles/adt_gen03.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_gen03.gold
@@ -0,0 +1,85 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () String "a")
+[GOOD] (define-fun s6 () Int 0)
+[GOOD] (define-fun s7 () String "b")
+[GOOD] (define-fun s9 () String "c")
+[GOOD] (define-fun s13 () Int 1)
+[GOOD] (define-fun s14 () Int 2)
+[GOOD] (define-fun s17 () Int 10)
+[GOOD] (define-fun s20 () Int 3)
+[GOOD] (define-fun s23 () Int 4)
+[GOOD] (define-fun s26 () Int 5)
+[GOOD] (define-fun s28 () Int 6)
+[GOOD] (define-fun s30 () Int 7)
+[GOOD] (define-fun s32 () Int 8)
+[GOOD] (define-fun s33 () Int 100)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr) ; tracks user variable "a"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s2 () String (getVar_1 s0))
+[GOOD] (define-fun s4 () Bool (= s2 s3))
+[GOOD] (define-fun s5 () Bool (and s1 s4))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s10 () Bool (= s2 s9))
+[GOOD] (define-fun s11 () Bool (or s8 s10))
+[GOOD] (define-fun s12 () Bool (and s1 s11))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s16 () Int (getVal_1 s0))
+[GOOD] (define-fun s18 () Bool (< s16 s17))
+[GOOD] (define-fun s19 () Bool (and s15 s18))
+[GOOD] (define-fun s21 () Bool (= s16 s17))
+[GOOD] (define-fun s22 () Bool (and s15 s21))
+[GOOD] (define-fun s24 () Bool (> s16 s17))
+[GOOD] (define-fun s25 () Bool (and s15 s24))
+[GOOD] (define-fun s27 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s29 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s31 () Bool ((as is-Let Bool) s0))
+[GOOD] (define-fun s34 () Int (ite s31 s32 s33))
+[GOOD] (define-fun s35 () Int (ite s29 s30 s34))
+[GOOD] (define-fun s36 () Int (ite s27 s28 s35))
+[GOOD] (define-fun s37 () Int (ite s25 s26 s36))
+[GOOD] (define-fun s38 () Int (ite s22 s23 s37))
+[GOOD] (define-fun s39 () Int (ite s19 s20 s38))
+[GOOD] (define-fun s40 () Int (ite s1 s14 s39))
+[GOOD] (define-fun s41 () Int (ite s12 s13 s40))
+[GOOD] (define-fun s42 () Int (ite s5 s6 s41))
+[GOOD] (define-fun s43 () Bool (= s13 s42))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s43)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (Var "b")))
+
+Got: b
+DONE
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_gen04.gold b/SBVTestSuite/GoldFiles/adt_gen04.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_gen04.gold
@@ -0,0 +1,85 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () String "a")
+[GOOD] (define-fun s6 () Int 0)
+[GOOD] (define-fun s7 () String "b")
+[GOOD] (define-fun s9 () String "c")
+[GOOD] (define-fun s13 () Int 1)
+[GOOD] (define-fun s14 () Int 2)
+[GOOD] (define-fun s17 () Int 10)
+[GOOD] (define-fun s20 () Int 3)
+[GOOD] (define-fun s23 () Int 4)
+[GOOD] (define-fun s26 () Int 5)
+[GOOD] (define-fun s28 () Int 6)
+[GOOD] (define-fun s30 () Int 7)
+[GOOD] (define-fun s32 () Int 8)
+[GOOD] (define-fun s33 () Int 100)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr) ; tracks user variable "a"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s2 () String (getVar_1 s0))
+[GOOD] (define-fun s4 () Bool (= s2 s3))
+[GOOD] (define-fun s5 () Bool (and s1 s4))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s10 () Bool (= s2 s9))
+[GOOD] (define-fun s11 () Bool (or s8 s10))
+[GOOD] (define-fun s12 () Bool (and s1 s11))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s16 () Int (getVal_1 s0))
+[GOOD] (define-fun s18 () Bool (< s16 s17))
+[GOOD] (define-fun s19 () Bool (and s15 s18))
+[GOOD] (define-fun s21 () Bool (= s16 s17))
+[GOOD] (define-fun s22 () Bool (and s15 s21))
+[GOOD] (define-fun s24 () Bool (> s16 s17))
+[GOOD] (define-fun s25 () Bool (and s15 s24))
+[GOOD] (define-fun s27 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s29 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s31 () Bool ((as is-Let Bool) s0))
+[GOOD] (define-fun s34 () Int (ite s31 s32 s33))
+[GOOD] (define-fun s35 () Int (ite s29 s30 s34))
+[GOOD] (define-fun s36 () Int (ite s27 s28 s35))
+[GOOD] (define-fun s37 () Int (ite s25 s26 s36))
+[GOOD] (define-fun s38 () Int (ite s22 s23 s37))
+[GOOD] (define-fun s39 () Int (ite s19 s20 s38))
+[GOOD] (define-fun s40 () Int (ite s1 s14 s39))
+[GOOD] (define-fun s41 () Int (ite s12 s13 s40))
+[GOOD] (define-fun s42 () Int (ite s5 s6 s41))
+[GOOD] (define-fun s43 () Bool (= s14 s42))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s43)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (Var "")))
+
+Got: 
+DONE
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_gen05.gold b/SBVTestSuite/GoldFiles/adt_gen05.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_gen05.gold
@@ -0,0 +1,85 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () String "a")
+[GOOD] (define-fun s6 () Int 0)
+[GOOD] (define-fun s7 () String "b")
+[GOOD] (define-fun s9 () String "c")
+[GOOD] (define-fun s13 () Int 1)
+[GOOD] (define-fun s14 () Int 2)
+[GOOD] (define-fun s17 () Int 10)
+[GOOD] (define-fun s20 () Int 3)
+[GOOD] (define-fun s23 () Int 4)
+[GOOD] (define-fun s26 () Int 5)
+[GOOD] (define-fun s28 () Int 6)
+[GOOD] (define-fun s30 () Int 7)
+[GOOD] (define-fun s32 () Int 8)
+[GOOD] (define-fun s33 () Int 100)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr) ; tracks user variable "a"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s2 () String (getVar_1 s0))
+[GOOD] (define-fun s4 () Bool (= s2 s3))
+[GOOD] (define-fun s5 () Bool (and s1 s4))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s10 () Bool (= s2 s9))
+[GOOD] (define-fun s11 () Bool (or s8 s10))
+[GOOD] (define-fun s12 () Bool (and s1 s11))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s16 () Int (getVal_1 s0))
+[GOOD] (define-fun s18 () Bool (< s16 s17))
+[GOOD] (define-fun s19 () Bool (and s15 s18))
+[GOOD] (define-fun s21 () Bool (= s16 s17))
+[GOOD] (define-fun s22 () Bool (and s15 s21))
+[GOOD] (define-fun s24 () Bool (> s16 s17))
+[GOOD] (define-fun s25 () Bool (and s15 s24))
+[GOOD] (define-fun s27 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s29 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s31 () Bool ((as is-Let Bool) s0))
+[GOOD] (define-fun s34 () Int (ite s31 s32 s33))
+[GOOD] (define-fun s35 () Int (ite s29 s30 s34))
+[GOOD] (define-fun s36 () Int (ite s27 s28 s35))
+[GOOD] (define-fun s37 () Int (ite s25 s26 s36))
+[GOOD] (define-fun s38 () Int (ite s22 s23 s37))
+[GOOD] (define-fun s39 () Int (ite s19 s20 s38))
+[GOOD] (define-fun s40 () Int (ite s1 s14 s39))
+[GOOD] (define-fun s41 () Int (ite s12 s13 s40))
+[GOOD] (define-fun s42 () Int (ite s5 s6 s41))
+[GOOD] (define-fun s43 () Bool (= s20 s42))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s43)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (Val 0)))
+
+Got: 0
+DONE
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_gen06.gold b/SBVTestSuite/GoldFiles/adt_gen06.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_gen06.gold
@@ -0,0 +1,85 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () String "a")
+[GOOD] (define-fun s6 () Int 0)
+[GOOD] (define-fun s7 () String "b")
+[GOOD] (define-fun s9 () String "c")
+[GOOD] (define-fun s13 () Int 1)
+[GOOD] (define-fun s14 () Int 2)
+[GOOD] (define-fun s17 () Int 10)
+[GOOD] (define-fun s20 () Int 3)
+[GOOD] (define-fun s23 () Int 4)
+[GOOD] (define-fun s26 () Int 5)
+[GOOD] (define-fun s28 () Int 6)
+[GOOD] (define-fun s30 () Int 7)
+[GOOD] (define-fun s32 () Int 8)
+[GOOD] (define-fun s33 () Int 100)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr) ; tracks user variable "a"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s2 () String (getVar_1 s0))
+[GOOD] (define-fun s4 () Bool (= s2 s3))
+[GOOD] (define-fun s5 () Bool (and s1 s4))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s10 () Bool (= s2 s9))
+[GOOD] (define-fun s11 () Bool (or s8 s10))
+[GOOD] (define-fun s12 () Bool (and s1 s11))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s16 () Int (getVal_1 s0))
+[GOOD] (define-fun s18 () Bool (< s16 s17))
+[GOOD] (define-fun s19 () Bool (and s15 s18))
+[GOOD] (define-fun s21 () Bool (= s16 s17))
+[GOOD] (define-fun s22 () Bool (and s15 s21))
+[GOOD] (define-fun s24 () Bool (> s16 s17))
+[GOOD] (define-fun s25 () Bool (and s15 s24))
+[GOOD] (define-fun s27 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s29 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s31 () Bool ((as is-Let Bool) s0))
+[GOOD] (define-fun s34 () Int (ite s31 s32 s33))
+[GOOD] (define-fun s35 () Int (ite s29 s30 s34))
+[GOOD] (define-fun s36 () Int (ite s27 s28 s35))
+[GOOD] (define-fun s37 () Int (ite s25 s26 s36))
+[GOOD] (define-fun s38 () Int (ite s22 s23 s37))
+[GOOD] (define-fun s39 () Int (ite s19 s20 s38))
+[GOOD] (define-fun s40 () Int (ite s1 s14 s39))
+[GOOD] (define-fun s41 () Int (ite s12 s13 s40))
+[GOOD] (define-fun s42 () Int (ite s5 s6 s41))
+[GOOD] (define-fun s43 () Bool (= s23 s42))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s43)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (Val 10)))
+
+Got: 10
+DONE
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_gen07.gold b/SBVTestSuite/GoldFiles/adt_gen07.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_gen07.gold
@@ -0,0 +1,85 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () String "a")
+[GOOD] (define-fun s6 () Int 0)
+[GOOD] (define-fun s7 () String "b")
+[GOOD] (define-fun s9 () String "c")
+[GOOD] (define-fun s13 () Int 1)
+[GOOD] (define-fun s14 () Int 2)
+[GOOD] (define-fun s17 () Int 10)
+[GOOD] (define-fun s20 () Int 3)
+[GOOD] (define-fun s23 () Int 4)
+[GOOD] (define-fun s26 () Int 5)
+[GOOD] (define-fun s28 () Int 6)
+[GOOD] (define-fun s30 () Int 7)
+[GOOD] (define-fun s32 () Int 8)
+[GOOD] (define-fun s33 () Int 100)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr) ; tracks user variable "a"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s2 () String (getVar_1 s0))
+[GOOD] (define-fun s4 () Bool (= s2 s3))
+[GOOD] (define-fun s5 () Bool (and s1 s4))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s10 () Bool (= s2 s9))
+[GOOD] (define-fun s11 () Bool (or s8 s10))
+[GOOD] (define-fun s12 () Bool (and s1 s11))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s16 () Int (getVal_1 s0))
+[GOOD] (define-fun s18 () Bool (< s16 s17))
+[GOOD] (define-fun s19 () Bool (and s15 s18))
+[GOOD] (define-fun s21 () Bool (= s16 s17))
+[GOOD] (define-fun s22 () Bool (and s15 s21))
+[GOOD] (define-fun s24 () Bool (> s16 s17))
+[GOOD] (define-fun s25 () Bool (and s15 s24))
+[GOOD] (define-fun s27 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s29 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s31 () Bool ((as is-Let Bool) s0))
+[GOOD] (define-fun s34 () Int (ite s31 s32 s33))
+[GOOD] (define-fun s35 () Int (ite s29 s30 s34))
+[GOOD] (define-fun s36 () Int (ite s27 s28 s35))
+[GOOD] (define-fun s37 () Int (ite s25 s26 s36))
+[GOOD] (define-fun s38 () Int (ite s22 s23 s37))
+[GOOD] (define-fun s39 () Int (ite s19 s20 s38))
+[GOOD] (define-fun s40 () Int (ite s1 s14 s39))
+[GOOD] (define-fun s41 () Int (ite s12 s13 s40))
+[GOOD] (define-fun s42 () Int (ite s5 s6 s41))
+[GOOD] (define-fun s43 () Bool (= s26 s42))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s43)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (Val 11)))
+
+Got: 11
+DONE
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_gen08.gold b/SBVTestSuite/GoldFiles/adt_gen08.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_gen08.gold
@@ -0,0 +1,85 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () String "a")
+[GOOD] (define-fun s6 () Int 0)
+[GOOD] (define-fun s7 () String "b")
+[GOOD] (define-fun s9 () String "c")
+[GOOD] (define-fun s13 () Int 1)
+[GOOD] (define-fun s14 () Int 2)
+[GOOD] (define-fun s17 () Int 10)
+[GOOD] (define-fun s20 () Int 3)
+[GOOD] (define-fun s23 () Int 4)
+[GOOD] (define-fun s26 () Int 5)
+[GOOD] (define-fun s28 () Int 6)
+[GOOD] (define-fun s30 () Int 7)
+[GOOD] (define-fun s32 () Int 8)
+[GOOD] (define-fun s33 () Int 100)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr) ; tracks user variable "a"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s2 () String (getVar_1 s0))
+[GOOD] (define-fun s4 () Bool (= s2 s3))
+[GOOD] (define-fun s5 () Bool (and s1 s4))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s10 () Bool (= s2 s9))
+[GOOD] (define-fun s11 () Bool (or s8 s10))
+[GOOD] (define-fun s12 () Bool (and s1 s11))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s16 () Int (getVal_1 s0))
+[GOOD] (define-fun s18 () Bool (< s16 s17))
+[GOOD] (define-fun s19 () Bool (and s15 s18))
+[GOOD] (define-fun s21 () Bool (= s16 s17))
+[GOOD] (define-fun s22 () Bool (and s15 s21))
+[GOOD] (define-fun s24 () Bool (> s16 s17))
+[GOOD] (define-fun s25 () Bool (and s15 s24))
+[GOOD] (define-fun s27 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s29 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s31 () Bool ((as is-Let Bool) s0))
+[GOOD] (define-fun s34 () Int (ite s31 s32 s33))
+[GOOD] (define-fun s35 () Int (ite s29 s30 s34))
+[GOOD] (define-fun s36 () Int (ite s27 s28 s35))
+[GOOD] (define-fun s37 () Int (ite s25 s26 s36))
+[GOOD] (define-fun s38 () Int (ite s22 s23 s37))
+[GOOD] (define-fun s39 () Int (ite s19 s20 s38))
+[GOOD] (define-fun s40 () Int (ite s1 s14 s39))
+[GOOD] (define-fun s41 () Int (ite s12 s13 s40))
+[GOOD] (define-fun s42 () Int (ite s5 s6 s41))
+[GOOD] (define-fun s43 () Bool (= s28 s42))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s43)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (Add (Var "!0!") (Var "!0!"))))
+
+Got: (!0! + !0!)
+DONE
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_gen09.gold b/SBVTestSuite/GoldFiles/adt_gen09.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_gen09.gold
@@ -0,0 +1,85 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () String "a")
+[GOOD] (define-fun s6 () Int 0)
+[GOOD] (define-fun s7 () String "b")
+[GOOD] (define-fun s9 () String "c")
+[GOOD] (define-fun s13 () Int 1)
+[GOOD] (define-fun s14 () Int 2)
+[GOOD] (define-fun s17 () Int 10)
+[GOOD] (define-fun s20 () Int 3)
+[GOOD] (define-fun s23 () Int 4)
+[GOOD] (define-fun s26 () Int 5)
+[GOOD] (define-fun s28 () Int 6)
+[GOOD] (define-fun s30 () Int 7)
+[GOOD] (define-fun s32 () Int 8)
+[GOOD] (define-fun s33 () Int 100)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr) ; tracks user variable "a"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s2 () String (getVar_1 s0))
+[GOOD] (define-fun s4 () Bool (= s2 s3))
+[GOOD] (define-fun s5 () Bool (and s1 s4))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s10 () Bool (= s2 s9))
+[GOOD] (define-fun s11 () Bool (or s8 s10))
+[GOOD] (define-fun s12 () Bool (and s1 s11))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s16 () Int (getVal_1 s0))
+[GOOD] (define-fun s18 () Bool (< s16 s17))
+[GOOD] (define-fun s19 () Bool (and s15 s18))
+[GOOD] (define-fun s21 () Bool (= s16 s17))
+[GOOD] (define-fun s22 () Bool (and s15 s21))
+[GOOD] (define-fun s24 () Bool (> s16 s17))
+[GOOD] (define-fun s25 () Bool (and s15 s24))
+[GOOD] (define-fun s27 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s29 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s31 () Bool ((as is-Let Bool) s0))
+[GOOD] (define-fun s34 () Int (ite s31 s32 s33))
+[GOOD] (define-fun s35 () Int (ite s29 s30 s34))
+[GOOD] (define-fun s36 () Int (ite s27 s28 s35))
+[GOOD] (define-fun s37 () Int (ite s25 s26 s36))
+[GOOD] (define-fun s38 () Int (ite s22 s23 s37))
+[GOOD] (define-fun s39 () Int (ite s19 s20 s38))
+[GOOD] (define-fun s40 () Int (ite s1 s14 s39))
+[GOOD] (define-fun s41 () Int (ite s12 s13 s40))
+[GOOD] (define-fun s42 () Int (ite s5 s6 s41))
+[GOOD] (define-fun s43 () Bool (= s30 s42))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s43)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (Mul (Var "!0!") (Var "!0!"))))
+
+Got: (!0! * !0!)
+DONE
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_gen10.gold b/SBVTestSuite/GoldFiles/adt_gen10.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_gen10.gold
@@ -0,0 +1,85 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () String "a")
+[GOOD] (define-fun s6 () Int 0)
+[GOOD] (define-fun s7 () String "b")
+[GOOD] (define-fun s9 () String "c")
+[GOOD] (define-fun s13 () Int 1)
+[GOOD] (define-fun s14 () Int 2)
+[GOOD] (define-fun s17 () Int 10)
+[GOOD] (define-fun s20 () Int 3)
+[GOOD] (define-fun s23 () Int 4)
+[GOOD] (define-fun s26 () Int 5)
+[GOOD] (define-fun s28 () Int 6)
+[GOOD] (define-fun s30 () Int 7)
+[GOOD] (define-fun s32 () Int 8)
+[GOOD] (define-fun s33 () Int 100)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr) ; tracks user variable "a"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s2 () String (getVar_1 s0))
+[GOOD] (define-fun s4 () Bool (= s2 s3))
+[GOOD] (define-fun s5 () Bool (and s1 s4))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s10 () Bool (= s2 s9))
+[GOOD] (define-fun s11 () Bool (or s8 s10))
+[GOOD] (define-fun s12 () Bool (and s1 s11))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s16 () Int (getVal_1 s0))
+[GOOD] (define-fun s18 () Bool (< s16 s17))
+[GOOD] (define-fun s19 () Bool (and s15 s18))
+[GOOD] (define-fun s21 () Bool (= s16 s17))
+[GOOD] (define-fun s22 () Bool (and s15 s21))
+[GOOD] (define-fun s24 () Bool (> s16 s17))
+[GOOD] (define-fun s25 () Bool (and s15 s24))
+[GOOD] (define-fun s27 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s29 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s31 () Bool ((as is-Let Bool) s0))
+[GOOD] (define-fun s34 () Int (ite s31 s32 s33))
+[GOOD] (define-fun s35 () Int (ite s29 s30 s34))
+[GOOD] (define-fun s36 () Int (ite s27 s28 s35))
+[GOOD] (define-fun s37 () Int (ite s25 s26 s36))
+[GOOD] (define-fun s38 () Int (ite s22 s23 s37))
+[GOOD] (define-fun s39 () Int (ite s19 s20 s38))
+[GOOD] (define-fun s40 () Int (ite s1 s14 s39))
+[GOOD] (define-fun s41 () Int (ite s12 s13 s40))
+[GOOD] (define-fun s42 () Int (ite s5 s6 s41))
+[GOOD] (define-fun s43 () Bool (= s32 s42))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s43)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (Let "!0!" (Var "!0!") (Var "!0!"))))
+
+Got: (let !0! = !0! in !0!)
+DONE
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_gen11.gold b/SBVTestSuite/GoldFiles/adt_gen11.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_gen11.gold
@@ -0,0 +1,83 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () String "a")
+[GOOD] (define-fun s6 () Int 0)
+[GOOD] (define-fun s7 () String "b")
+[GOOD] (define-fun s9 () String "c")
+[GOOD] (define-fun s13 () Int 1)
+[GOOD] (define-fun s14 () Int 2)
+[GOOD] (define-fun s17 () Int 10)
+[GOOD] (define-fun s20 () Int 3)
+[GOOD] (define-fun s23 () Int 4)
+[GOOD] (define-fun s26 () Int 5)
+[GOOD] (define-fun s28 () Int 6)
+[GOOD] (define-fun s30 () Int 7)
+[GOOD] (define-fun s32 () Int 8)
+[GOOD] (define-fun s33 () Int 100)
+[GOOD] (define-fun s43 () Int 9)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr) ; tracks user variable "a"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s2 () String (getVar_1 s0))
+[GOOD] (define-fun s4 () Bool (= s2 s3))
+[GOOD] (define-fun s5 () Bool (and s1 s4))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s10 () Bool (= s2 s9))
+[GOOD] (define-fun s11 () Bool (or s8 s10))
+[GOOD] (define-fun s12 () Bool (and s1 s11))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s16 () Int (getVal_1 s0))
+[GOOD] (define-fun s18 () Bool (< s16 s17))
+[GOOD] (define-fun s19 () Bool (and s15 s18))
+[GOOD] (define-fun s21 () Bool (= s16 s17))
+[GOOD] (define-fun s22 () Bool (and s15 s21))
+[GOOD] (define-fun s24 () Bool (> s16 s17))
+[GOOD] (define-fun s25 () Bool (and s15 s24))
+[GOOD] (define-fun s27 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s29 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s31 () Bool ((as is-Let Bool) s0))
+[GOOD] (define-fun s34 () Int (ite s31 s32 s33))
+[GOOD] (define-fun s35 () Int (ite s29 s30 s34))
+[GOOD] (define-fun s36 () Int (ite s27 s28 s35))
+[GOOD] (define-fun s37 () Int (ite s25 s26 s36))
+[GOOD] (define-fun s38 () Int (ite s22 s23 s37))
+[GOOD] (define-fun s39 () Int (ite s19 s20 s38))
+[GOOD] (define-fun s40 () Int (ite s1 s14 s39))
+[GOOD] (define-fun s41 () Int (ite s12 s13 s40))
+[GOOD] (define-fun s42 () Int (ite s5 s6 s41))
+[GOOD] (define-fun s44 () Bool (= s42 s43))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s44)
+[SEND] (check-sat)
+[RECV] unsat
+
+UNSAT
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_gen12.gold b/SBVTestSuite/GoldFiles/adt_gen12.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_gen12.gold
@@ -0,0 +1,82 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () String "a")
+[GOOD] (define-fun s6 () Int 0)
+[GOOD] (define-fun s7 () String "b")
+[GOOD] (define-fun s9 () String "c")
+[GOOD] (define-fun s13 () Int 1)
+[GOOD] (define-fun s14 () Int 2)
+[GOOD] (define-fun s17 () Int 10)
+[GOOD] (define-fun s20 () Int 3)
+[GOOD] (define-fun s23 () Int 4)
+[GOOD] (define-fun s26 () Int 5)
+[GOOD] (define-fun s28 () Int 6)
+[GOOD] (define-fun s30 () Int 7)
+[GOOD] (define-fun s32 () Int 8)
+[GOOD] (define-fun s33 () Int 100)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr) ; tracks user variable "a"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s2 () String (getVar_1 s0))
+[GOOD] (define-fun s4 () Bool (= s2 s3))
+[GOOD] (define-fun s5 () Bool (and s1 s4))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s10 () Bool (= s2 s9))
+[GOOD] (define-fun s11 () Bool (or s8 s10))
+[GOOD] (define-fun s12 () Bool (and s1 s11))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s16 () Int (getVal_1 s0))
+[GOOD] (define-fun s18 () Bool (< s16 s17))
+[GOOD] (define-fun s19 () Bool (and s15 s18))
+[GOOD] (define-fun s21 () Bool (= s16 s17))
+[GOOD] (define-fun s22 () Bool (and s15 s21))
+[GOOD] (define-fun s24 () Bool (> s16 s17))
+[GOOD] (define-fun s25 () Bool (and s15 s24))
+[GOOD] (define-fun s27 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s29 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s31 () Bool ((as is-Let Bool) s0))
+[GOOD] (define-fun s34 () Int (ite s31 s32 s33))
+[GOOD] (define-fun s35 () Int (ite s29 s30 s34))
+[GOOD] (define-fun s36 () Int (ite s27 s28 s35))
+[GOOD] (define-fun s37 () Int (ite s25 s26 s36))
+[GOOD] (define-fun s38 () Int (ite s22 s23 s37))
+[GOOD] (define-fun s39 () Int (ite s19 s20 s38))
+[GOOD] (define-fun s40 () Int (ite s1 s14 s39))
+[GOOD] (define-fun s41 () Int (ite s12 s13 s40))
+[GOOD] (define-fun s42 () Int (ite s5 s6 s41))
+[GOOD] (define-fun s43 () Bool (= s33 s42))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s43)
+[SEND] (check-sat)
+[RECV] unsat
+
+UNSAT
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_lit00.gold b/SBVTestSuite/GoldFiles/adt_lit00.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_lit00.gold
@@ -0,0 +1,240 @@
+[MEASURE] Verifying termination measures for: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): not in a multi-member cycle, skipping mutual check
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): barified = "|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|"
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2)]
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): recursive calls found = 6
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): trying sbv.dt.size.Expr arg2
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK (structural recursion)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): barified = "|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|"
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2)]
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): recursive calls found = 1
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): trying length arg1
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Bool (>= s4 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Int (seq.len s13))
+[GOOD] (define-fun s18 () Bool (not s10))
+[GOOD] (define-fun s19 () Bool (and s6 s18))
+[GOOD] (define-fun s20 () Bool (> s4 s17))
+[GOOD] (define-fun s21 () Bool (=> s19 s20))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): length arg1 -> OK
+[MEASURE] Passed (terminating): get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Val Expr) 0))
+[GOOD] (define-fun s5 () Int 0)
+[GOOD] (define-fun s8 () Int 100)
+[GOOD] (define-fun s9 () Int 1)
+[GOOD] (define-fun s12 () Int 200)
+[GOOD] (define-fun s20 () (Seq (SBVTuple2 String Int)) (as seq.empty (Seq (SBVTuple2 String Int))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| :: [(SString, SInteger)] -> SString -> SInteger [Recursive]
+[GOOD] (define-fun-rec |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| ((l2_s0 (Seq (SBVTuple2 String Int))) (l2_s1 String)) Int
+                                                 (let ((l2_s3 0))
+                                                 (let ((l2_s11 1))
+                                                 (let ((l2_s2 (seq.len l2_s0)))
+                                                 (let ((l2_s4 (= l2_s2 l2_s3)))
+                                                 (let ((l2_s5 (not l2_s4)))
+                                                 (let ((l2_s6 (seq.nth l2_s0 l2_s3)))
+                                                 (let ((l2_s7 (proj_1_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s8 (= l2_s1 l2_s7)))
+                                                 (let ((l2_s9 (and l2_s5 l2_s8)))
+                                                 (let ((l2_s10 (proj_2_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s12 (- l2_s2 l2_s11)))
+                                                 (let ((l2_s13 (seq.extract l2_s0 l2_s11 l2_s12)))
+                                                 (let ((l2_s14 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l2_s13 l2_s1)))
+                                                 (let ((l2_s15 (ite l2_s9 l2_s10 l2_s14)))
+                                                 (let ((l2_s16 (ite l2_s4 l2_s3 l2_s15)))
+                                                 l2_s16))))))))))))))))
+[GOOD] ; |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| :: [(SString, SInteger)] -> Expr -> SInteger [Recursive] [Refers to: |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|]
+[GOOD] (define-fun-rec |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| ((l1_s0 (Seq (SBVTuple2 String Int))) (l1_s1 Expr)) Int
+                                 (let ((l1_s2 ((as is-Val Bool) l1_s1)))
+                                 (let ((l1_s3 (getVal_1 l1_s1)))
+                                 (let ((l1_s4 ((as is-Var Bool) l1_s1)))
+                                 (let ((l1_s5 (getVar_1 l1_s1)))
+                                 (let ((l1_s6 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l1_s0 l1_s5)))
+                                 (let ((l1_s7 ((as is-Add Bool) l1_s1)))
+                                 (let ((l1_s8 (getAdd_1 l1_s1)))
+                                 (let ((l1_s9 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s8)))
+                                 (let ((l1_s10 (getAdd_2 l1_s1)))
+                                 (let ((l1_s11 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s10)))
+                                 (let ((l1_s12 (+ l1_s9 l1_s11)))
+                                 (let ((l1_s13 ((as is-Mul Bool) l1_s1)))
+                                 (let ((l1_s14 (getMul_1 l1_s1)))
+                                 (let ((l1_s15 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s14)))
+                                 (let ((l1_s16 (getMul_2 l1_s1)))
+                                 (let ((l1_s17 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s16)))
+                                 (let ((l1_s18 (* l1_s15 l1_s17)))
+                                 (let ((l1_s19 (getLet_1 l1_s1)))
+                                 (let ((l1_s20 (getLet_2 l1_s1)))
+                                 (let ((l1_s21 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s20)))
+                                 (let ((l1_s22 ((as mkSBVTuple2 (SBVTuple2 String Int)) l1_s19 l1_s21)))
+                                 (let ((l1_s23 (seq.unit l1_s22)))
+                                 (let ((l1_s24 (seq.++ l1_s23 l1_s0)))
+                                 (let ((l1_s25 (getLet_3 l1_s1)))
+                                 (let ((l1_s26 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s24 l1_s25)))
+                                 (let ((l1_s27 (ite l1_s13 l1_s18 l1_s26)))
+                                 (let ((l1_s28 (ite l1_s7 l1_s12 l1_s27)))
+                                 (let ((l1_s29 (ite l1_s4 l1_s6 l1_s28)))
+                                 (let ((l1_s30 (ite l1_s2 l1_s3 l1_s29)))
+                                 l1_s30))))))))))))))))))))))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s4 () Int (getVal_1 s0))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool (and s3 s6))
+[GOOD] (define-fun s10 () Bool (= s4 s9))
+[GOOD] (define-fun s11 () Bool (and s3 s10))
+[GOOD] (define-fun s13 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s14 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s14))
+[GOOD] (define-fun s16 () Int (getVal_1 s14))
+[GOOD] (define-fun s17 () Bool (= s5 s16))
+[GOOD] (define-fun s18 () Bool (and s15 s17))
+[GOOD] (define-fun s19 () Bool (and s13 s18))
+[GOOD] (define-fun s21 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s22 () Int (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| s20 s21))
+[GOOD] (define-fun s23 () Int (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| s20 s0))
+[GOOD] (define-fun s24 () Int (ite s19 s22 s23))
+[GOOD] (define-fun s25 () Int (ite s11 s12 s24))
+[GOOD] (define-fun s26 () Int (ite s7 s8 s25))
+[GOOD] (define-fun s27 () Bool (distinct s8 s26))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s27)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_lit00c.gold b/SBVTestSuite/GoldFiles/adt_lit00c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_lit00c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_lit01.gold b/SBVTestSuite/GoldFiles/adt_lit01.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_lit01.gold
@@ -0,0 +1,240 @@
+[MEASURE] Verifying termination measures for: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): not in a multi-member cycle, skipping mutual check
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): barified = "|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|"
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2)]
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): recursive calls found = 6
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): trying sbv.dt.size.Expr arg2
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK (structural recursion)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): barified = "|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|"
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2)]
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): recursive calls found = 1
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): trying length arg1
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Bool (>= s4 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Int (seq.len s13))
+[GOOD] (define-fun s18 () Bool (not s10))
+[GOOD] (define-fun s19 () Bool (and s6 s18))
+[GOOD] (define-fun s20 () Bool (> s4 s17))
+[GOOD] (define-fun s21 () Bool (=> s19 s20))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): length arg1 -> OK
+[MEASURE] Passed (terminating): get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Val Expr) 1))
+[GOOD] (define-fun s5 () Int 0)
+[GOOD] (define-fun s8 () Int 100)
+[GOOD] (define-fun s9 () Int 1)
+[GOOD] (define-fun s12 () Int 200)
+[GOOD] (define-fun s20 () (Seq (SBVTuple2 String Int)) (as seq.empty (Seq (SBVTuple2 String Int))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| :: [(SString, SInteger)] -> SString -> SInteger [Recursive]
+[GOOD] (define-fun-rec |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| ((l2_s0 (Seq (SBVTuple2 String Int))) (l2_s1 String)) Int
+                                                 (let ((l2_s3 0))
+                                                 (let ((l2_s11 1))
+                                                 (let ((l2_s2 (seq.len l2_s0)))
+                                                 (let ((l2_s4 (= l2_s2 l2_s3)))
+                                                 (let ((l2_s5 (not l2_s4)))
+                                                 (let ((l2_s6 (seq.nth l2_s0 l2_s3)))
+                                                 (let ((l2_s7 (proj_1_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s8 (= l2_s1 l2_s7)))
+                                                 (let ((l2_s9 (and l2_s5 l2_s8)))
+                                                 (let ((l2_s10 (proj_2_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s12 (- l2_s2 l2_s11)))
+                                                 (let ((l2_s13 (seq.extract l2_s0 l2_s11 l2_s12)))
+                                                 (let ((l2_s14 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l2_s13 l2_s1)))
+                                                 (let ((l2_s15 (ite l2_s9 l2_s10 l2_s14)))
+                                                 (let ((l2_s16 (ite l2_s4 l2_s3 l2_s15)))
+                                                 l2_s16))))))))))))))))
+[GOOD] ; |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| :: [(SString, SInteger)] -> Expr -> SInteger [Recursive] [Refers to: |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|]
+[GOOD] (define-fun-rec |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| ((l1_s0 (Seq (SBVTuple2 String Int))) (l1_s1 Expr)) Int
+                                 (let ((l1_s2 ((as is-Val Bool) l1_s1)))
+                                 (let ((l1_s3 (getVal_1 l1_s1)))
+                                 (let ((l1_s4 ((as is-Var Bool) l1_s1)))
+                                 (let ((l1_s5 (getVar_1 l1_s1)))
+                                 (let ((l1_s6 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l1_s0 l1_s5)))
+                                 (let ((l1_s7 ((as is-Add Bool) l1_s1)))
+                                 (let ((l1_s8 (getAdd_1 l1_s1)))
+                                 (let ((l1_s9 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s8)))
+                                 (let ((l1_s10 (getAdd_2 l1_s1)))
+                                 (let ((l1_s11 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s10)))
+                                 (let ((l1_s12 (+ l1_s9 l1_s11)))
+                                 (let ((l1_s13 ((as is-Mul Bool) l1_s1)))
+                                 (let ((l1_s14 (getMul_1 l1_s1)))
+                                 (let ((l1_s15 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s14)))
+                                 (let ((l1_s16 (getMul_2 l1_s1)))
+                                 (let ((l1_s17 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s16)))
+                                 (let ((l1_s18 (* l1_s15 l1_s17)))
+                                 (let ((l1_s19 (getLet_1 l1_s1)))
+                                 (let ((l1_s20 (getLet_2 l1_s1)))
+                                 (let ((l1_s21 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s20)))
+                                 (let ((l1_s22 ((as mkSBVTuple2 (SBVTuple2 String Int)) l1_s19 l1_s21)))
+                                 (let ((l1_s23 (seq.unit l1_s22)))
+                                 (let ((l1_s24 (seq.++ l1_s23 l1_s0)))
+                                 (let ((l1_s25 (getLet_3 l1_s1)))
+                                 (let ((l1_s26 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s24 l1_s25)))
+                                 (let ((l1_s27 (ite l1_s13 l1_s18 l1_s26)))
+                                 (let ((l1_s28 (ite l1_s7 l1_s12 l1_s27)))
+                                 (let ((l1_s29 (ite l1_s4 l1_s6 l1_s28)))
+                                 (let ((l1_s30 (ite l1_s2 l1_s3 l1_s29)))
+                                 l1_s30))))))))))))))))))))))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s4 () Int (getVal_1 s0))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool (and s3 s6))
+[GOOD] (define-fun s10 () Bool (= s4 s9))
+[GOOD] (define-fun s11 () Bool (and s3 s10))
+[GOOD] (define-fun s13 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s14 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s14))
+[GOOD] (define-fun s16 () Int (getVal_1 s14))
+[GOOD] (define-fun s17 () Bool (= s5 s16))
+[GOOD] (define-fun s18 () Bool (and s15 s17))
+[GOOD] (define-fun s19 () Bool (and s13 s18))
+[GOOD] (define-fun s21 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s22 () Int (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| s20 s21))
+[GOOD] (define-fun s23 () Int (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| s20 s0))
+[GOOD] (define-fun s24 () Int (ite s19 s22 s23))
+[GOOD] (define-fun s25 () Int (ite s11 s12 s24))
+[GOOD] (define-fun s26 () Int (ite s7 s8 s25))
+[GOOD] (define-fun s27 () Bool (distinct s12 s26))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s27)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_lit01c.gold b/SBVTestSuite/GoldFiles/adt_lit01c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_lit01c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_lit02.gold b/SBVTestSuite/GoldFiles/adt_lit02.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_lit02.gold
@@ -0,0 +1,241 @@
+[MEASURE] Verifying termination measures for: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): not in a multi-member cycle, skipping mutual check
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): barified = "|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|"
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2)]
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): recursive calls found = 6
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): trying sbv.dt.size.Expr arg2
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK (structural recursion)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): barified = "|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|"
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2)]
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): recursive calls found = 1
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): trying length arg1
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Bool (>= s4 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Int (seq.len s13))
+[GOOD] (define-fun s18 () Bool (not s10))
+[GOOD] (define-fun s19 () Bool (and s6 s18))
+[GOOD] (define-fun s20 () Bool (> s4 s17))
+[GOOD] (define-fun s21 () Bool (=> s19 s20))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): length arg1 -> OK
+[MEASURE] Passed (terminating): get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Val Expr) 2))
+[GOOD] (define-fun s5 () Int 0)
+[GOOD] (define-fun s8 () Int 100)
+[GOOD] (define-fun s9 () Int 1)
+[GOOD] (define-fun s12 () Int 200)
+[GOOD] (define-fun s20 () (Seq (SBVTuple2 String Int)) (as seq.empty (Seq (SBVTuple2 String Int))))
+[GOOD] (define-fun s27 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| :: [(SString, SInteger)] -> SString -> SInteger [Recursive]
+[GOOD] (define-fun-rec |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| ((l2_s0 (Seq (SBVTuple2 String Int))) (l2_s1 String)) Int
+                                                 (let ((l2_s3 0))
+                                                 (let ((l2_s11 1))
+                                                 (let ((l2_s2 (seq.len l2_s0)))
+                                                 (let ((l2_s4 (= l2_s2 l2_s3)))
+                                                 (let ((l2_s5 (not l2_s4)))
+                                                 (let ((l2_s6 (seq.nth l2_s0 l2_s3)))
+                                                 (let ((l2_s7 (proj_1_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s8 (= l2_s1 l2_s7)))
+                                                 (let ((l2_s9 (and l2_s5 l2_s8)))
+                                                 (let ((l2_s10 (proj_2_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s12 (- l2_s2 l2_s11)))
+                                                 (let ((l2_s13 (seq.extract l2_s0 l2_s11 l2_s12)))
+                                                 (let ((l2_s14 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l2_s13 l2_s1)))
+                                                 (let ((l2_s15 (ite l2_s9 l2_s10 l2_s14)))
+                                                 (let ((l2_s16 (ite l2_s4 l2_s3 l2_s15)))
+                                                 l2_s16))))))))))))))))
+[GOOD] ; |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| :: [(SString, SInteger)] -> Expr -> SInteger [Recursive] [Refers to: |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|]
+[GOOD] (define-fun-rec |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| ((l1_s0 (Seq (SBVTuple2 String Int))) (l1_s1 Expr)) Int
+                                 (let ((l1_s2 ((as is-Val Bool) l1_s1)))
+                                 (let ((l1_s3 (getVal_1 l1_s1)))
+                                 (let ((l1_s4 ((as is-Var Bool) l1_s1)))
+                                 (let ((l1_s5 (getVar_1 l1_s1)))
+                                 (let ((l1_s6 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l1_s0 l1_s5)))
+                                 (let ((l1_s7 ((as is-Add Bool) l1_s1)))
+                                 (let ((l1_s8 (getAdd_1 l1_s1)))
+                                 (let ((l1_s9 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s8)))
+                                 (let ((l1_s10 (getAdd_2 l1_s1)))
+                                 (let ((l1_s11 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s10)))
+                                 (let ((l1_s12 (+ l1_s9 l1_s11)))
+                                 (let ((l1_s13 ((as is-Mul Bool) l1_s1)))
+                                 (let ((l1_s14 (getMul_1 l1_s1)))
+                                 (let ((l1_s15 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s14)))
+                                 (let ((l1_s16 (getMul_2 l1_s1)))
+                                 (let ((l1_s17 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s16)))
+                                 (let ((l1_s18 (* l1_s15 l1_s17)))
+                                 (let ((l1_s19 (getLet_1 l1_s1)))
+                                 (let ((l1_s20 (getLet_2 l1_s1)))
+                                 (let ((l1_s21 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s20)))
+                                 (let ((l1_s22 ((as mkSBVTuple2 (SBVTuple2 String Int)) l1_s19 l1_s21)))
+                                 (let ((l1_s23 (seq.unit l1_s22)))
+                                 (let ((l1_s24 (seq.++ l1_s23 l1_s0)))
+                                 (let ((l1_s25 (getLet_3 l1_s1)))
+                                 (let ((l1_s26 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s24 l1_s25)))
+                                 (let ((l1_s27 (ite l1_s13 l1_s18 l1_s26)))
+                                 (let ((l1_s28 (ite l1_s7 l1_s12 l1_s27)))
+                                 (let ((l1_s29 (ite l1_s4 l1_s6 l1_s28)))
+                                 (let ((l1_s30 (ite l1_s2 l1_s3 l1_s29)))
+                                 l1_s30))))))))))))))))))))))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s4 () Int (getVal_1 s0))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool (and s3 s6))
+[GOOD] (define-fun s10 () Bool (= s4 s9))
+[GOOD] (define-fun s11 () Bool (and s3 s10))
+[GOOD] (define-fun s13 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s14 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s14))
+[GOOD] (define-fun s16 () Int (getVal_1 s14))
+[GOOD] (define-fun s17 () Bool (= s5 s16))
+[GOOD] (define-fun s18 () Bool (and s15 s17))
+[GOOD] (define-fun s19 () Bool (and s13 s18))
+[GOOD] (define-fun s21 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s22 () Int (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| s20 s21))
+[GOOD] (define-fun s23 () Int (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| s20 s0))
+[GOOD] (define-fun s24 () Int (ite s19 s22 s23))
+[GOOD] (define-fun s25 () Int (ite s11 s12 s24))
+[GOOD] (define-fun s26 () Int (ite s7 s8 s25))
+[GOOD] (define-fun s28 () Bool (distinct s26 s27))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s28)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_lit02c.gold b/SBVTestSuite/GoldFiles/adt_lit02c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_lit02c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_lit03.gold b/SBVTestSuite/GoldFiles/adt_lit03.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_lit03.gold
@@ -0,0 +1,241 @@
+[MEASURE] Verifying termination measures for: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): not in a multi-member cycle, skipping mutual check
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): barified = "|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|"
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2)]
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): recursive calls found = 6
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): trying sbv.dt.size.Expr arg2
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK (structural recursion)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): barified = "|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|"
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2)]
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): recursive calls found = 1
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): trying length arg1
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Bool (>= s4 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Int (seq.len s13))
+[GOOD] (define-fun s18 () Bool (not s10))
+[GOOD] (define-fun s19 () Bool (and s6 s18))
+[GOOD] (define-fun s20 () Bool (> s4 s17))
+[GOOD] (define-fun s21 () Bool (=> s19 s20))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): length arg1 -> OK
+[MEASURE] Passed (terminating): get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Add Expr) ((as Val Expr) 0) ((as Val Expr) 5)))
+[GOOD] (define-fun s5 () Int 0)
+[GOOD] (define-fun s8 () Int 100)
+[GOOD] (define-fun s9 () Int 1)
+[GOOD] (define-fun s12 () Int 200)
+[GOOD] (define-fun s20 () (Seq (SBVTuple2 String Int)) (as seq.empty (Seq (SBVTuple2 String Int))))
+[GOOD] (define-fun s27 () Int 5)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| :: [(SString, SInteger)] -> SString -> SInteger [Recursive]
+[GOOD] (define-fun-rec |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| ((l2_s0 (Seq (SBVTuple2 String Int))) (l2_s1 String)) Int
+                                                 (let ((l2_s3 0))
+                                                 (let ((l2_s11 1))
+                                                 (let ((l2_s2 (seq.len l2_s0)))
+                                                 (let ((l2_s4 (= l2_s2 l2_s3)))
+                                                 (let ((l2_s5 (not l2_s4)))
+                                                 (let ((l2_s6 (seq.nth l2_s0 l2_s3)))
+                                                 (let ((l2_s7 (proj_1_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s8 (= l2_s1 l2_s7)))
+                                                 (let ((l2_s9 (and l2_s5 l2_s8)))
+                                                 (let ((l2_s10 (proj_2_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s12 (- l2_s2 l2_s11)))
+                                                 (let ((l2_s13 (seq.extract l2_s0 l2_s11 l2_s12)))
+                                                 (let ((l2_s14 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l2_s13 l2_s1)))
+                                                 (let ((l2_s15 (ite l2_s9 l2_s10 l2_s14)))
+                                                 (let ((l2_s16 (ite l2_s4 l2_s3 l2_s15)))
+                                                 l2_s16))))))))))))))))
+[GOOD] ; |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| :: [(SString, SInteger)] -> Expr -> SInteger [Recursive] [Refers to: |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|]
+[GOOD] (define-fun-rec |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| ((l1_s0 (Seq (SBVTuple2 String Int))) (l1_s1 Expr)) Int
+                                 (let ((l1_s2 ((as is-Val Bool) l1_s1)))
+                                 (let ((l1_s3 (getVal_1 l1_s1)))
+                                 (let ((l1_s4 ((as is-Var Bool) l1_s1)))
+                                 (let ((l1_s5 (getVar_1 l1_s1)))
+                                 (let ((l1_s6 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l1_s0 l1_s5)))
+                                 (let ((l1_s7 ((as is-Add Bool) l1_s1)))
+                                 (let ((l1_s8 (getAdd_1 l1_s1)))
+                                 (let ((l1_s9 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s8)))
+                                 (let ((l1_s10 (getAdd_2 l1_s1)))
+                                 (let ((l1_s11 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s10)))
+                                 (let ((l1_s12 (+ l1_s9 l1_s11)))
+                                 (let ((l1_s13 ((as is-Mul Bool) l1_s1)))
+                                 (let ((l1_s14 (getMul_1 l1_s1)))
+                                 (let ((l1_s15 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s14)))
+                                 (let ((l1_s16 (getMul_2 l1_s1)))
+                                 (let ((l1_s17 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s16)))
+                                 (let ((l1_s18 (* l1_s15 l1_s17)))
+                                 (let ((l1_s19 (getLet_1 l1_s1)))
+                                 (let ((l1_s20 (getLet_2 l1_s1)))
+                                 (let ((l1_s21 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s20)))
+                                 (let ((l1_s22 ((as mkSBVTuple2 (SBVTuple2 String Int)) l1_s19 l1_s21)))
+                                 (let ((l1_s23 (seq.unit l1_s22)))
+                                 (let ((l1_s24 (seq.++ l1_s23 l1_s0)))
+                                 (let ((l1_s25 (getLet_3 l1_s1)))
+                                 (let ((l1_s26 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s24 l1_s25)))
+                                 (let ((l1_s27 (ite l1_s13 l1_s18 l1_s26)))
+                                 (let ((l1_s28 (ite l1_s7 l1_s12 l1_s27)))
+                                 (let ((l1_s29 (ite l1_s4 l1_s6 l1_s28)))
+                                 (let ((l1_s30 (ite l1_s2 l1_s3 l1_s29)))
+                                 l1_s30))))))))))))))))))))))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s4 () Int (getVal_1 s0))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool (and s3 s6))
+[GOOD] (define-fun s10 () Bool (= s4 s9))
+[GOOD] (define-fun s11 () Bool (and s3 s10))
+[GOOD] (define-fun s13 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s14 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s14))
+[GOOD] (define-fun s16 () Int (getVal_1 s14))
+[GOOD] (define-fun s17 () Bool (= s5 s16))
+[GOOD] (define-fun s18 () Bool (and s15 s17))
+[GOOD] (define-fun s19 () Bool (and s13 s18))
+[GOOD] (define-fun s21 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s22 () Int (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| s20 s21))
+[GOOD] (define-fun s23 () Int (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| s20 s0))
+[GOOD] (define-fun s24 () Int (ite s19 s22 s23))
+[GOOD] (define-fun s25 () Int (ite s11 s12 s24))
+[GOOD] (define-fun s26 () Int (ite s7 s8 s25))
+[GOOD] (define-fun s28 () Bool (distinct s26 s27))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s28)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_lit03c.gold b/SBVTestSuite/GoldFiles/adt_lit03c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_lit03c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_lit04.gold b/SBVTestSuite/GoldFiles/adt_lit04.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_lit04.gold
@@ -0,0 +1,241 @@
+[MEASURE] Verifying termination measures for: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): not in a multi-member cycle, skipping mutual check
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): barified = "|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|"
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2)]
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): recursive calls found = 6
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): trying sbv.dt.size.Expr arg2
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK (structural recursion)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): barified = "|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|"
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2)]
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): recursive calls found = 1
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): trying length arg1
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Bool (>= s4 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Int (seq.len s13))
+[GOOD] (define-fun s18 () Bool (not s10))
+[GOOD] (define-fun s19 () Bool (and s6 s18))
+[GOOD] (define-fun s20 () Bool (> s4 s17))
+[GOOD] (define-fun s21 () Bool (=> s19 s20))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): length arg1 -> OK
+[MEASURE] Passed (terminating): get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Add Expr) ((as Val Expr) 1) ((as Val Expr) 5)))
+[GOOD] (define-fun s5 () Int 0)
+[GOOD] (define-fun s8 () Int 100)
+[GOOD] (define-fun s9 () Int 1)
+[GOOD] (define-fun s12 () Int 200)
+[GOOD] (define-fun s20 () (Seq (SBVTuple2 String Int)) (as seq.empty (Seq (SBVTuple2 String Int))))
+[GOOD] (define-fun s27 () Int 6)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| :: [(SString, SInteger)] -> SString -> SInteger [Recursive]
+[GOOD] (define-fun-rec |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| ((l2_s0 (Seq (SBVTuple2 String Int))) (l2_s1 String)) Int
+                                                 (let ((l2_s3 0))
+                                                 (let ((l2_s11 1))
+                                                 (let ((l2_s2 (seq.len l2_s0)))
+                                                 (let ((l2_s4 (= l2_s2 l2_s3)))
+                                                 (let ((l2_s5 (not l2_s4)))
+                                                 (let ((l2_s6 (seq.nth l2_s0 l2_s3)))
+                                                 (let ((l2_s7 (proj_1_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s8 (= l2_s1 l2_s7)))
+                                                 (let ((l2_s9 (and l2_s5 l2_s8)))
+                                                 (let ((l2_s10 (proj_2_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s12 (- l2_s2 l2_s11)))
+                                                 (let ((l2_s13 (seq.extract l2_s0 l2_s11 l2_s12)))
+                                                 (let ((l2_s14 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l2_s13 l2_s1)))
+                                                 (let ((l2_s15 (ite l2_s9 l2_s10 l2_s14)))
+                                                 (let ((l2_s16 (ite l2_s4 l2_s3 l2_s15)))
+                                                 l2_s16))))))))))))))))
+[GOOD] ; |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| :: [(SString, SInteger)] -> Expr -> SInteger [Recursive] [Refers to: |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|]
+[GOOD] (define-fun-rec |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| ((l1_s0 (Seq (SBVTuple2 String Int))) (l1_s1 Expr)) Int
+                                 (let ((l1_s2 ((as is-Val Bool) l1_s1)))
+                                 (let ((l1_s3 (getVal_1 l1_s1)))
+                                 (let ((l1_s4 ((as is-Var Bool) l1_s1)))
+                                 (let ((l1_s5 (getVar_1 l1_s1)))
+                                 (let ((l1_s6 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l1_s0 l1_s5)))
+                                 (let ((l1_s7 ((as is-Add Bool) l1_s1)))
+                                 (let ((l1_s8 (getAdd_1 l1_s1)))
+                                 (let ((l1_s9 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s8)))
+                                 (let ((l1_s10 (getAdd_2 l1_s1)))
+                                 (let ((l1_s11 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s10)))
+                                 (let ((l1_s12 (+ l1_s9 l1_s11)))
+                                 (let ((l1_s13 ((as is-Mul Bool) l1_s1)))
+                                 (let ((l1_s14 (getMul_1 l1_s1)))
+                                 (let ((l1_s15 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s14)))
+                                 (let ((l1_s16 (getMul_2 l1_s1)))
+                                 (let ((l1_s17 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s16)))
+                                 (let ((l1_s18 (* l1_s15 l1_s17)))
+                                 (let ((l1_s19 (getLet_1 l1_s1)))
+                                 (let ((l1_s20 (getLet_2 l1_s1)))
+                                 (let ((l1_s21 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s20)))
+                                 (let ((l1_s22 ((as mkSBVTuple2 (SBVTuple2 String Int)) l1_s19 l1_s21)))
+                                 (let ((l1_s23 (seq.unit l1_s22)))
+                                 (let ((l1_s24 (seq.++ l1_s23 l1_s0)))
+                                 (let ((l1_s25 (getLet_3 l1_s1)))
+                                 (let ((l1_s26 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s24 l1_s25)))
+                                 (let ((l1_s27 (ite l1_s13 l1_s18 l1_s26)))
+                                 (let ((l1_s28 (ite l1_s7 l1_s12 l1_s27)))
+                                 (let ((l1_s29 (ite l1_s4 l1_s6 l1_s28)))
+                                 (let ((l1_s30 (ite l1_s2 l1_s3 l1_s29)))
+                                 l1_s30))))))))))))))))))))))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s4 () Int (getVal_1 s0))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool (and s3 s6))
+[GOOD] (define-fun s10 () Bool (= s4 s9))
+[GOOD] (define-fun s11 () Bool (and s3 s10))
+[GOOD] (define-fun s13 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s14 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s14))
+[GOOD] (define-fun s16 () Int (getVal_1 s14))
+[GOOD] (define-fun s17 () Bool (= s5 s16))
+[GOOD] (define-fun s18 () Bool (and s15 s17))
+[GOOD] (define-fun s19 () Bool (and s13 s18))
+[GOOD] (define-fun s21 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s22 () Int (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| s20 s21))
+[GOOD] (define-fun s23 () Int (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| s20 s0))
+[GOOD] (define-fun s24 () Int (ite s19 s22 s23))
+[GOOD] (define-fun s25 () Int (ite s11 s12 s24))
+[GOOD] (define-fun s26 () Int (ite s7 s8 s25))
+[GOOD] (define-fun s28 () Bool (distinct s26 s27))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s28)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_lit04c.gold b/SBVTestSuite/GoldFiles/adt_lit04c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_lit04c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_lit05.gold b/SBVTestSuite/GoldFiles/adt_lit05.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_lit05.gold
@@ -0,0 +1,240 @@
+[MEASURE] Verifying termination measures for: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): not in a multi-member cycle, skipping mutual check
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): barified = "|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|"
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2)]
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): recursive calls found = 6
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): trying sbv.dt.size.Expr arg2
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK (structural recursion)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): barified = "|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|"
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2)]
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): recursive calls found = 1
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): trying length arg1
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Bool (>= s4 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Int (seq.len s13))
+[GOOD] (define-fun s18 () Bool (not s10))
+[GOOD] (define-fun s19 () Bool (and s6 s18))
+[GOOD] (define-fun s20 () Bool (> s4 s17))
+[GOOD] (define-fun s21 () Bool (=> s19 s20))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): length arg1 -> OK
+[MEASURE] Passed (terminating): get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Var Expr) "x"))
+[GOOD] (define-fun s5 () Int 0)
+[GOOD] (define-fun s8 () Int 100)
+[GOOD] (define-fun s9 () Int 1)
+[GOOD] (define-fun s12 () Int 200)
+[GOOD] (define-fun s20 () (Seq (SBVTuple2 String Int)) (as seq.empty (Seq (SBVTuple2 String Int))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| :: [(SString, SInteger)] -> SString -> SInteger [Recursive]
+[GOOD] (define-fun-rec |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| ((l2_s0 (Seq (SBVTuple2 String Int))) (l2_s1 String)) Int
+                                                 (let ((l2_s3 0))
+                                                 (let ((l2_s11 1))
+                                                 (let ((l2_s2 (seq.len l2_s0)))
+                                                 (let ((l2_s4 (= l2_s2 l2_s3)))
+                                                 (let ((l2_s5 (not l2_s4)))
+                                                 (let ((l2_s6 (seq.nth l2_s0 l2_s3)))
+                                                 (let ((l2_s7 (proj_1_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s8 (= l2_s1 l2_s7)))
+                                                 (let ((l2_s9 (and l2_s5 l2_s8)))
+                                                 (let ((l2_s10 (proj_2_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s12 (- l2_s2 l2_s11)))
+                                                 (let ((l2_s13 (seq.extract l2_s0 l2_s11 l2_s12)))
+                                                 (let ((l2_s14 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l2_s13 l2_s1)))
+                                                 (let ((l2_s15 (ite l2_s9 l2_s10 l2_s14)))
+                                                 (let ((l2_s16 (ite l2_s4 l2_s3 l2_s15)))
+                                                 l2_s16))))))))))))))))
+[GOOD] ; |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| :: [(SString, SInteger)] -> Expr -> SInteger [Recursive] [Refers to: |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|]
+[GOOD] (define-fun-rec |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| ((l1_s0 (Seq (SBVTuple2 String Int))) (l1_s1 Expr)) Int
+                                 (let ((l1_s2 ((as is-Val Bool) l1_s1)))
+                                 (let ((l1_s3 (getVal_1 l1_s1)))
+                                 (let ((l1_s4 ((as is-Var Bool) l1_s1)))
+                                 (let ((l1_s5 (getVar_1 l1_s1)))
+                                 (let ((l1_s6 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l1_s0 l1_s5)))
+                                 (let ((l1_s7 ((as is-Add Bool) l1_s1)))
+                                 (let ((l1_s8 (getAdd_1 l1_s1)))
+                                 (let ((l1_s9 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s8)))
+                                 (let ((l1_s10 (getAdd_2 l1_s1)))
+                                 (let ((l1_s11 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s10)))
+                                 (let ((l1_s12 (+ l1_s9 l1_s11)))
+                                 (let ((l1_s13 ((as is-Mul Bool) l1_s1)))
+                                 (let ((l1_s14 (getMul_1 l1_s1)))
+                                 (let ((l1_s15 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s14)))
+                                 (let ((l1_s16 (getMul_2 l1_s1)))
+                                 (let ((l1_s17 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s16)))
+                                 (let ((l1_s18 (* l1_s15 l1_s17)))
+                                 (let ((l1_s19 (getLet_1 l1_s1)))
+                                 (let ((l1_s20 (getLet_2 l1_s1)))
+                                 (let ((l1_s21 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s20)))
+                                 (let ((l1_s22 ((as mkSBVTuple2 (SBVTuple2 String Int)) l1_s19 l1_s21)))
+                                 (let ((l1_s23 (seq.unit l1_s22)))
+                                 (let ((l1_s24 (seq.++ l1_s23 l1_s0)))
+                                 (let ((l1_s25 (getLet_3 l1_s1)))
+                                 (let ((l1_s26 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s24 l1_s25)))
+                                 (let ((l1_s27 (ite l1_s13 l1_s18 l1_s26)))
+                                 (let ((l1_s28 (ite l1_s7 l1_s12 l1_s27)))
+                                 (let ((l1_s29 (ite l1_s4 l1_s6 l1_s28)))
+                                 (let ((l1_s30 (ite l1_s2 l1_s3 l1_s29)))
+                                 l1_s30))))))))))))))))))))))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s4 () Int (getVal_1 s0))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool (and s3 s6))
+[GOOD] (define-fun s10 () Bool (= s4 s9))
+[GOOD] (define-fun s11 () Bool (and s3 s10))
+[GOOD] (define-fun s13 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s14 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s14))
+[GOOD] (define-fun s16 () Int (getVal_1 s14))
+[GOOD] (define-fun s17 () Bool (= s5 s16))
+[GOOD] (define-fun s18 () Bool (and s15 s17))
+[GOOD] (define-fun s19 () Bool (and s13 s18))
+[GOOD] (define-fun s21 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s22 () Int (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| s20 s21))
+[GOOD] (define-fun s23 () Int (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| s20 s0))
+[GOOD] (define-fun s24 () Int (ite s19 s22 s23))
+[GOOD] (define-fun s25 () Int (ite s11 s12 s24))
+[GOOD] (define-fun s26 () Int (ite s7 s8 s25))
+[GOOD] (define-fun s27 () Bool (distinct s5 s26))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s27)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_lit05c.gold b/SBVTestSuite/GoldFiles/adt_lit05c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_lit05c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_mr00.gold b/SBVTestSuite/GoldFiles/adt_mr00.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_mr00.gold
@@ -0,0 +1,69 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (var val) (
+           (Con (getCon_1 val))
+           (Var (getVar_1 var))
+           (Add (getAdd_1 (Expr var val)) (getAdd_2 (Expr var val)))
+           (Mul (getMul_1 (Expr var val)) (getMul_2 (Expr var val)))
+       )))
+[GOOD] ; User defined ADT: Stmt
+[GOOD] (declare-datatype Stmt (par (var val) (
+           (Assign (getAssign_1 var) (getAssign_2 (Expr var val)))
+           (Seq (getSeq_1 (Stmt var val)) (getSeq_2 (Stmt var val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Stmt String Int)) ; tracks user variable "p"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Seq Bool) s0))
+[GOOD] (define-fun s2 () (Stmt String Int) (getSeq_2 s0))
+[GOOD] (define-fun s3 () Bool ((as is-Seq Bool) s2))
+[GOOD] (define-fun s4 () (Stmt String Int) (getSeq_2 s2))
+[GOOD] (define-fun s5 () Bool ((as is-Seq Bool) s4))
+[GOOD] (define-fun s6 () (Stmt String Int) (getSeq_2 s4))
+[GOOD] (define-fun s7 () Bool ((as is-Assign Bool) s6))
+[GOOD] (define-fun s8 () (Expr String Int) (getAssign_2 s6))
+[GOOD] (define-fun s9 () Bool ((as is-Add Bool) s8))
+[GOOD] (define-fun s10 () (Expr String Int) (getAdd_1 s8))
+[GOOD] (define-fun s11 () Bool ((as is-Var Bool) s10))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s1)
+[GOOD] (assert s3)
+[GOOD] (assert s5)
+[GOOD] (assert s7)
+[GOOD] (assert s9)
+[GOOD] (assert s11)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (Seq (Assign "!3!" (Var "!6!"))
+            (Seq (Assign "!5!" (Var "!8!"))
+                 (Seq (Assign "!4!" (Var "!7!"))
+                      (Assign "!0!" (Add (Var "!1!") (Var "!2!"))))))))
+
+Got:
+!3! := !6!;
+!5! := !8!;
+!4! := !7!;
+!0! := (!1! + !2!)
+DONE
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_mr01.gold b/SBVTestSuite/GoldFiles/adt_mr01.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_mr01.gold
@@ -0,0 +1,73 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Maybe
+[GOOD] (declare-datatype Maybe (par (a) (
+           (Nothing)
+           (Just (getJust_1 a))
+       )))
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (var val) (
+           (Con (getCon_1 val))
+           (Var (getVar_1 var))
+           (Add (getAdd_1 (Expr var val)) (getAdd_2 (Expr var val)))
+           (Mul (getMul_1 (Expr var val)) (getMul_2 (Expr var val)))
+       )))
+[GOOD] ; User defined ADT: Stmt
+[GOOD] (declare-datatype Stmt (par (var val) (
+           (Assign (getAssign_1 var) (getAssign_2 (Expr var val)))
+           (Seq (getSeq_1 (Stmt var val)) (getSeq_2 (Stmt var val)))
+       )))
+[GOOD] ; User defined ADT: Either
+[GOOD] (declare-datatype Either (par (a b) (
+           (Left (getLeft_1 a))
+           (Right (getRight_1 b))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Stmt String (Maybe (Either Int Bool)))) ; tracks user variable "p"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Assign Bool) s0))
+[GOOD] (define-fun s2 () (Expr String (Maybe (Either Int Bool))) (getAssign_2 s0))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s2))
+[GOOD] (define-fun s4 () (Expr String (Maybe (Either Int Bool))) (getAdd_1 s2))
+[GOOD] (define-fun s5 () Bool ((as is-Con Bool) s4))
+[GOOD] (define-fun s6 () (Expr String (Maybe (Either Int Bool))) (getAdd_2 s2))
+[GOOD] (define-fun s7 () Bool ((as is-Con Bool) s6))
+[GOOD] (define-fun s8 () (Maybe (Either Int Bool)) (getCon_1 s4))
+[GOOD] (define-fun s9 () Bool ((as is-Nothing Bool) s8))
+[GOOD] (define-fun s10 () (Maybe (Either Int Bool)) (getCon_1 s6))
+[GOOD] (define-fun s11 () Bool ((as is-Just Bool) s10))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s1)
+[GOOD] (assert s3)
+[GOOD] (assert s5)
+[GOOD] (assert s7)
+[GOOD] (assert s9)
+[GOOD] (assert s11)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (Assign "!0!" (Add (Con Nothing) (Con (Just (Left 2)))))))
+
+Got:
+!0! := (Nothing + Just (Left 2))
+DONE
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_mr02.gold b/SBVTestSuite/GoldFiles/adt_mr02.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_mr02.gold
@@ -0,0 +1,50 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: A
+[GOOD] (declare-datatype A (par (a b) (
+           (Aa (getAa_1 a))
+           (Ab (getAb_1 b))
+           (Aab (getAab_1 a) (getAab_2 b))
+           (A2 (getA2_1 (A b String)))
+           (A3 (getA3_1 (A b a)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (A Int Bool)) ; tracks user variable "p"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-A2 Bool) s0))
+[GOOD] (define-fun s2 () (A Bool String) (getA2_1 s0))
+[GOOD] (define-fun s3 () Bool ((as is-A2 Bool) s2))
+[GOOD] (define-fun s4 () (A String String) (getA2_1 s2))
+[GOOD] (define-fun s5 () Bool ((as is-Aa Bool) s4))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s1)
+[GOOD] (assert s3)
+[GOOD] (assert s5)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (A2 ((as A2 (A Bool String)) (Aa "!0!")))))
+
+Got:
+A2 {a2 = A2 {a2 = Aa {aa = "!0!"}}}
+DONE
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_mr03.gold b/SBVTestSuite/GoldFiles/adt_mr03.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_mr03.gold
@@ -0,0 +1,47 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: A
+[GOOD] (declare-datatype A (par (a b) (
+           (Aa (getAa_1 a))
+           (Ab (getAb_1 b))
+           (Aab (getAab_1 a) (getAab_2 b))
+           (A2 (getA2_1 (A b String)))
+           (A3 (getA3_1 (A b a)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (A Int Bool)) ; tracks user variable "p"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-A3 Bool) s0))
+[GOOD] (define-fun s2 () (A Bool Int) (getA3_1 s0))
+[GOOD] (define-fun s3 () Bool ((as is-Ab Bool) s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s1)
+[GOOD] (assert s3)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (A3 (Ab 2))))
+
+Got:
+A3 {a3 = Ab {ab = 2}}
+DONE
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_mr04.gold b/SBVTestSuite/GoldFiles/adt_mr04.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_mr04.gold
@@ -0,0 +1,51 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: A
+[GOOD] (declare-datatype A (par (a b) (
+           (Aa (getAa_1 a))
+           (Ab (getAb_1 b))
+           (Aab (getAab_1 a) (getAab_2 b))
+           (A2 (getA2_1 (A b String)))
+           (A3 (getA3_1 (A b a)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (A Int (A (_ FloatingPoint  8 24) Bool))) ; tracks user variable "p"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-A2 Bool) s0))
+[GOOD] (define-fun s2 () (A (A (_ FloatingPoint  8 24) Bool) String) (getA2_1 s0))
+[GOOD] (define-fun s3 () Bool ((as is-A3 Bool) s2))
+[GOOD] (define-fun s4 () (A String (A (_ FloatingPoint  8 24) Bool)) (getA3_1 s2))
+[GOOD] (define-fun s5 () Bool ((as is-Aab Bool) s4))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s1)
+[GOOD] (assert s3)
+[GOOD] (assert s5)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 ((as A2 (A Int (A (_ FloatingPoint 8 24) Bool))) (A3 (Aab "!0!"
+                    (Aab (_ +zero 8 24) false))))))
+
+Got:
+A2 {a2 = A3 {a3 = Aab {aba = "!0!", abb = Aab {aba = 0.0, abb = False}}}}
+DONE
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested00.gold b/SBVTestSuite/GoldFiles/adt_nested00.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested00.gold
@@ -0,0 +1,80 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Add Expr) ((as Val Expr) 0) ((as Val Expr) 5)))
+[GOOD] (define-fun s7 () Int 0)
+[GOOD] (define-fun s21 () Int 1)
+[GOOD] (define-fun s34 () Expr ((as Val Expr) 0))
+[GOOD] (define-fun s40 () Expr ((as Val Expr) 5))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s6 () Int (getVal_1 s4))
+[GOOD] (define-fun s8 () Bool (= s6 s7))
+[GOOD] (define-fun s9 () Bool (and s5 s8))
+[GOOD] (define-fun s10 () Bool (and s3 s9))
+[GOOD] (define-fun s11 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s12 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s13 () Int (getVal_1 s11))
+[GOOD] (define-fun s14 () Bool (= s7 s13))
+[GOOD] (define-fun s15 () Bool (and s12 s14))
+[GOOD] (define-fun s16 () Bool (and s3 s15))
+[GOOD] (define-fun s17 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s18 () Expr (getMul_1 s0))
+[GOOD] (define-fun s19 () Bool ((as is-Val Bool) s18))
+[GOOD] (define-fun s20 () Int (getVal_1 s18))
+[GOOD] (define-fun s22 () Bool (= s20 s21))
+[GOOD] (define-fun s23 () Bool (and s19 s22))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s25 () Expr (getMul_2 s0))
+[GOOD] (define-fun s26 () Bool ((as is-Val Bool) s25))
+[GOOD] (define-fun s27 () Int (getVal_1 s25))
+[GOOD] (define-fun s28 () Bool (= s21 s27))
+[GOOD] (define-fun s29 () Bool (and s26 s28))
+[GOOD] (define-fun s30 () Bool (and s17 s29))
+[GOOD] (define-fun s31 () Bool (= s7 s20))
+[GOOD] (define-fun s32 () Bool (and s19 s31))
+[GOOD] (define-fun s33 () Bool (and s17 s32))
+[GOOD] (define-fun s35 () Expr (ite s33 s34 s0))
+[GOOD] (define-fun s36 () Expr (ite s30 s18 s35))
+[GOOD] (define-fun s37 () Expr (ite s24 s25 s36))
+[GOOD] (define-fun s38 () Expr (ite s16 s4 s37))
+[GOOD] (define-fun s39 () Expr (ite s10 s11 s38))
+[GOOD] (define-fun s41 () Bool (distinct s39 s40))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s41)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested00c.gold b/SBVTestSuite/GoldFiles/adt_nested00c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested00c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested01.gold b/SBVTestSuite/GoldFiles/adt_nested01.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested01.gold
@@ -0,0 +1,80 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Add Expr) ((as Val Expr) 7) ((as Val Expr) 0)))
+[GOOD] (define-fun s7 () Int 0)
+[GOOD] (define-fun s21 () Int 1)
+[GOOD] (define-fun s34 () Expr ((as Val Expr) 0))
+[GOOD] (define-fun s40 () Expr ((as Val Expr) 7))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s6 () Int (getVal_1 s4))
+[GOOD] (define-fun s8 () Bool (= s6 s7))
+[GOOD] (define-fun s9 () Bool (and s5 s8))
+[GOOD] (define-fun s10 () Bool (and s3 s9))
+[GOOD] (define-fun s11 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s12 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s13 () Int (getVal_1 s11))
+[GOOD] (define-fun s14 () Bool (= s7 s13))
+[GOOD] (define-fun s15 () Bool (and s12 s14))
+[GOOD] (define-fun s16 () Bool (and s3 s15))
+[GOOD] (define-fun s17 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s18 () Expr (getMul_1 s0))
+[GOOD] (define-fun s19 () Bool ((as is-Val Bool) s18))
+[GOOD] (define-fun s20 () Int (getVal_1 s18))
+[GOOD] (define-fun s22 () Bool (= s20 s21))
+[GOOD] (define-fun s23 () Bool (and s19 s22))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s25 () Expr (getMul_2 s0))
+[GOOD] (define-fun s26 () Bool ((as is-Val Bool) s25))
+[GOOD] (define-fun s27 () Int (getVal_1 s25))
+[GOOD] (define-fun s28 () Bool (= s21 s27))
+[GOOD] (define-fun s29 () Bool (and s26 s28))
+[GOOD] (define-fun s30 () Bool (and s17 s29))
+[GOOD] (define-fun s31 () Bool (= s7 s20))
+[GOOD] (define-fun s32 () Bool (and s19 s31))
+[GOOD] (define-fun s33 () Bool (and s17 s32))
+[GOOD] (define-fun s35 () Expr (ite s33 s34 s0))
+[GOOD] (define-fun s36 () Expr (ite s30 s18 s35))
+[GOOD] (define-fun s37 () Expr (ite s24 s25 s36))
+[GOOD] (define-fun s38 () Expr (ite s16 s4 s37))
+[GOOD] (define-fun s39 () Expr (ite s10 s11 s38))
+[GOOD] (define-fun s41 () Bool (distinct s39 s40))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s41)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested01c.gold b/SBVTestSuite/GoldFiles/adt_nested01c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested01c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested02.gold b/SBVTestSuite/GoldFiles/adt_nested02.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested02.gold
@@ -0,0 +1,80 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Mul Expr) ((as Val Expr) 1) ((as Val Expr) 9)))
+[GOOD] (define-fun s7 () Int 0)
+[GOOD] (define-fun s21 () Int 1)
+[GOOD] (define-fun s34 () Expr ((as Val Expr) 0))
+[GOOD] (define-fun s40 () Expr ((as Val Expr) 9))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s6 () Int (getVal_1 s4))
+[GOOD] (define-fun s8 () Bool (= s6 s7))
+[GOOD] (define-fun s9 () Bool (and s5 s8))
+[GOOD] (define-fun s10 () Bool (and s3 s9))
+[GOOD] (define-fun s11 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s12 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s13 () Int (getVal_1 s11))
+[GOOD] (define-fun s14 () Bool (= s7 s13))
+[GOOD] (define-fun s15 () Bool (and s12 s14))
+[GOOD] (define-fun s16 () Bool (and s3 s15))
+[GOOD] (define-fun s17 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s18 () Expr (getMul_1 s0))
+[GOOD] (define-fun s19 () Bool ((as is-Val Bool) s18))
+[GOOD] (define-fun s20 () Int (getVal_1 s18))
+[GOOD] (define-fun s22 () Bool (= s20 s21))
+[GOOD] (define-fun s23 () Bool (and s19 s22))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s25 () Expr (getMul_2 s0))
+[GOOD] (define-fun s26 () Bool ((as is-Val Bool) s25))
+[GOOD] (define-fun s27 () Int (getVal_1 s25))
+[GOOD] (define-fun s28 () Bool (= s21 s27))
+[GOOD] (define-fun s29 () Bool (and s26 s28))
+[GOOD] (define-fun s30 () Bool (and s17 s29))
+[GOOD] (define-fun s31 () Bool (= s7 s20))
+[GOOD] (define-fun s32 () Bool (and s19 s31))
+[GOOD] (define-fun s33 () Bool (and s17 s32))
+[GOOD] (define-fun s35 () Expr (ite s33 s34 s0))
+[GOOD] (define-fun s36 () Expr (ite s30 s18 s35))
+[GOOD] (define-fun s37 () Expr (ite s24 s25 s36))
+[GOOD] (define-fun s38 () Expr (ite s16 s4 s37))
+[GOOD] (define-fun s39 () Expr (ite s10 s11 s38))
+[GOOD] (define-fun s41 () Bool (distinct s39 s40))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s41)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested02c.gold b/SBVTestSuite/GoldFiles/adt_nested02c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested02c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested03.gold b/SBVTestSuite/GoldFiles/adt_nested03.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested03.gold
@@ -0,0 +1,80 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Mul Expr) ((as Val Expr) 4) ((as Val Expr) 1)))
+[GOOD] (define-fun s7 () Int 0)
+[GOOD] (define-fun s21 () Int 1)
+[GOOD] (define-fun s34 () Expr ((as Val Expr) 0))
+[GOOD] (define-fun s40 () Expr ((as Val Expr) 4))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s6 () Int (getVal_1 s4))
+[GOOD] (define-fun s8 () Bool (= s6 s7))
+[GOOD] (define-fun s9 () Bool (and s5 s8))
+[GOOD] (define-fun s10 () Bool (and s3 s9))
+[GOOD] (define-fun s11 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s12 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s13 () Int (getVal_1 s11))
+[GOOD] (define-fun s14 () Bool (= s7 s13))
+[GOOD] (define-fun s15 () Bool (and s12 s14))
+[GOOD] (define-fun s16 () Bool (and s3 s15))
+[GOOD] (define-fun s17 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s18 () Expr (getMul_1 s0))
+[GOOD] (define-fun s19 () Bool ((as is-Val Bool) s18))
+[GOOD] (define-fun s20 () Int (getVal_1 s18))
+[GOOD] (define-fun s22 () Bool (= s20 s21))
+[GOOD] (define-fun s23 () Bool (and s19 s22))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s25 () Expr (getMul_2 s0))
+[GOOD] (define-fun s26 () Bool ((as is-Val Bool) s25))
+[GOOD] (define-fun s27 () Int (getVal_1 s25))
+[GOOD] (define-fun s28 () Bool (= s21 s27))
+[GOOD] (define-fun s29 () Bool (and s26 s28))
+[GOOD] (define-fun s30 () Bool (and s17 s29))
+[GOOD] (define-fun s31 () Bool (= s7 s20))
+[GOOD] (define-fun s32 () Bool (and s19 s31))
+[GOOD] (define-fun s33 () Bool (and s17 s32))
+[GOOD] (define-fun s35 () Expr (ite s33 s34 s0))
+[GOOD] (define-fun s36 () Expr (ite s30 s18 s35))
+[GOOD] (define-fun s37 () Expr (ite s24 s25 s36))
+[GOOD] (define-fun s38 () Expr (ite s16 s4 s37))
+[GOOD] (define-fun s39 () Expr (ite s10 s11 s38))
+[GOOD] (define-fun s41 () Bool (distinct s39 s40))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s41)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested03c.gold b/SBVTestSuite/GoldFiles/adt_nested03c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested03c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested04.gold b/SBVTestSuite/GoldFiles/adt_nested04.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested04.gold
@@ -0,0 +1,79 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Mul Expr) ((as Val Expr) 0) ((as Val Expr) 99)))
+[GOOD] (define-fun s7 () Int 0)
+[GOOD] (define-fun s21 () Int 1)
+[GOOD] (define-fun s34 () Expr ((as Val Expr) 0))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s6 () Int (getVal_1 s4))
+[GOOD] (define-fun s8 () Bool (= s6 s7))
+[GOOD] (define-fun s9 () Bool (and s5 s8))
+[GOOD] (define-fun s10 () Bool (and s3 s9))
+[GOOD] (define-fun s11 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s12 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s13 () Int (getVal_1 s11))
+[GOOD] (define-fun s14 () Bool (= s7 s13))
+[GOOD] (define-fun s15 () Bool (and s12 s14))
+[GOOD] (define-fun s16 () Bool (and s3 s15))
+[GOOD] (define-fun s17 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s18 () Expr (getMul_1 s0))
+[GOOD] (define-fun s19 () Bool ((as is-Val Bool) s18))
+[GOOD] (define-fun s20 () Int (getVal_1 s18))
+[GOOD] (define-fun s22 () Bool (= s20 s21))
+[GOOD] (define-fun s23 () Bool (and s19 s22))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s25 () Expr (getMul_2 s0))
+[GOOD] (define-fun s26 () Bool ((as is-Val Bool) s25))
+[GOOD] (define-fun s27 () Int (getVal_1 s25))
+[GOOD] (define-fun s28 () Bool (= s21 s27))
+[GOOD] (define-fun s29 () Bool (and s26 s28))
+[GOOD] (define-fun s30 () Bool (and s17 s29))
+[GOOD] (define-fun s31 () Bool (= s7 s20))
+[GOOD] (define-fun s32 () Bool (and s19 s31))
+[GOOD] (define-fun s33 () Bool (and s17 s32))
+[GOOD] (define-fun s35 () Expr (ite s33 s34 s0))
+[GOOD] (define-fun s36 () Expr (ite s30 s18 s35))
+[GOOD] (define-fun s37 () Expr (ite s24 s25 s36))
+[GOOD] (define-fun s38 () Expr (ite s16 s4 s37))
+[GOOD] (define-fun s39 () Expr (ite s10 s11 s38))
+[GOOD] (define-fun s40 () Bool (distinct s34 s39))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s40)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested04c.gold b/SBVTestSuite/GoldFiles/adt_nested04c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested04c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested05.gold b/SBVTestSuite/GoldFiles/adt_nested05.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested05.gold
@@ -0,0 +1,79 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Add Expr) ((as Val Expr) 3) ((as Val Expr) 4)))
+[GOOD] (define-fun s7 () Int 0)
+[GOOD] (define-fun s21 () Int 1)
+[GOOD] (define-fun s34 () Expr ((as Val Expr) 0))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s6 () Int (getVal_1 s4))
+[GOOD] (define-fun s8 () Bool (= s6 s7))
+[GOOD] (define-fun s9 () Bool (and s5 s8))
+[GOOD] (define-fun s10 () Bool (and s3 s9))
+[GOOD] (define-fun s11 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s12 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s13 () Int (getVal_1 s11))
+[GOOD] (define-fun s14 () Bool (= s7 s13))
+[GOOD] (define-fun s15 () Bool (and s12 s14))
+[GOOD] (define-fun s16 () Bool (and s3 s15))
+[GOOD] (define-fun s17 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s18 () Expr (getMul_1 s0))
+[GOOD] (define-fun s19 () Bool ((as is-Val Bool) s18))
+[GOOD] (define-fun s20 () Int (getVal_1 s18))
+[GOOD] (define-fun s22 () Bool (= s20 s21))
+[GOOD] (define-fun s23 () Bool (and s19 s22))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s25 () Expr (getMul_2 s0))
+[GOOD] (define-fun s26 () Bool ((as is-Val Bool) s25))
+[GOOD] (define-fun s27 () Int (getVal_1 s25))
+[GOOD] (define-fun s28 () Bool (= s21 s27))
+[GOOD] (define-fun s29 () Bool (and s26 s28))
+[GOOD] (define-fun s30 () Bool (and s17 s29))
+[GOOD] (define-fun s31 () Bool (= s7 s20))
+[GOOD] (define-fun s32 () Bool (and s19 s31))
+[GOOD] (define-fun s33 () Bool (and s17 s32))
+[GOOD] (define-fun s35 () Expr (ite s33 s34 s0))
+[GOOD] (define-fun s36 () Expr (ite s30 s18 s35))
+[GOOD] (define-fun s37 () Expr (ite s24 s25 s36))
+[GOOD] (define-fun s38 () Expr (ite s16 s4 s37))
+[GOOD] (define-fun s39 () Expr (ite s10 s11 s38))
+[GOOD] (define-fun s40 () Bool (distinct s1 s39))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s40)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested05c.gold b/SBVTestSuite/GoldFiles/adt_nested05c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested05c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested06.gold b/SBVTestSuite/GoldFiles/adt_nested06.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested06.gold
@@ -0,0 +1,79 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Add Expr) ((as Val Expr) 1) ((as Val Expr) 5)))
+[GOOD] (define-fun s7 () Int 0)
+[GOOD] (define-fun s21 () Int 1)
+[GOOD] (define-fun s34 () Expr ((as Val Expr) 0))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s6 () Int (getVal_1 s4))
+[GOOD] (define-fun s8 () Bool (= s6 s7))
+[GOOD] (define-fun s9 () Bool (and s5 s8))
+[GOOD] (define-fun s10 () Bool (and s3 s9))
+[GOOD] (define-fun s11 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s12 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s13 () Int (getVal_1 s11))
+[GOOD] (define-fun s14 () Bool (= s7 s13))
+[GOOD] (define-fun s15 () Bool (and s12 s14))
+[GOOD] (define-fun s16 () Bool (and s3 s15))
+[GOOD] (define-fun s17 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s18 () Expr (getMul_1 s0))
+[GOOD] (define-fun s19 () Bool ((as is-Val Bool) s18))
+[GOOD] (define-fun s20 () Int (getVal_1 s18))
+[GOOD] (define-fun s22 () Bool (= s20 s21))
+[GOOD] (define-fun s23 () Bool (and s19 s22))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s25 () Expr (getMul_2 s0))
+[GOOD] (define-fun s26 () Bool ((as is-Val Bool) s25))
+[GOOD] (define-fun s27 () Int (getVal_1 s25))
+[GOOD] (define-fun s28 () Bool (= s21 s27))
+[GOOD] (define-fun s29 () Bool (and s26 s28))
+[GOOD] (define-fun s30 () Bool (and s17 s29))
+[GOOD] (define-fun s31 () Bool (= s7 s20))
+[GOOD] (define-fun s32 () Bool (and s19 s31))
+[GOOD] (define-fun s33 () Bool (and s17 s32))
+[GOOD] (define-fun s35 () Expr (ite s33 s34 s0))
+[GOOD] (define-fun s36 () Expr (ite s30 s18 s35))
+[GOOD] (define-fun s37 () Expr (ite s24 s25 s36))
+[GOOD] (define-fun s38 () Expr (ite s16 s4 s37))
+[GOOD] (define-fun s39 () Expr (ite s10 s11 s38))
+[GOOD] (define-fun s40 () Bool (distinct s1 s39))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s40)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested06c.gold b/SBVTestSuite/GoldFiles/adt_nested06c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested06c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested07.gold b/SBVTestSuite/GoldFiles/adt_nested07.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested07.gold
@@ -0,0 +1,79 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Add Expr) ((as Val Expr) 0) ((as Val Expr) 0)))
+[GOOD] (define-fun s7 () Int 0)
+[GOOD] (define-fun s21 () Int 1)
+[GOOD] (define-fun s34 () Expr ((as Val Expr) 0))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s6 () Int (getVal_1 s4))
+[GOOD] (define-fun s8 () Bool (= s6 s7))
+[GOOD] (define-fun s9 () Bool (and s5 s8))
+[GOOD] (define-fun s10 () Bool (and s3 s9))
+[GOOD] (define-fun s11 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s12 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s13 () Int (getVal_1 s11))
+[GOOD] (define-fun s14 () Bool (= s7 s13))
+[GOOD] (define-fun s15 () Bool (and s12 s14))
+[GOOD] (define-fun s16 () Bool (and s3 s15))
+[GOOD] (define-fun s17 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s18 () Expr (getMul_1 s0))
+[GOOD] (define-fun s19 () Bool ((as is-Val Bool) s18))
+[GOOD] (define-fun s20 () Int (getVal_1 s18))
+[GOOD] (define-fun s22 () Bool (= s20 s21))
+[GOOD] (define-fun s23 () Bool (and s19 s22))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s25 () Expr (getMul_2 s0))
+[GOOD] (define-fun s26 () Bool ((as is-Val Bool) s25))
+[GOOD] (define-fun s27 () Int (getVal_1 s25))
+[GOOD] (define-fun s28 () Bool (= s21 s27))
+[GOOD] (define-fun s29 () Bool (and s26 s28))
+[GOOD] (define-fun s30 () Bool (and s17 s29))
+[GOOD] (define-fun s31 () Bool (= s7 s20))
+[GOOD] (define-fun s32 () Bool (and s19 s31))
+[GOOD] (define-fun s33 () Bool (and s17 s32))
+[GOOD] (define-fun s35 () Expr (ite s33 s34 s0))
+[GOOD] (define-fun s36 () Expr (ite s30 s18 s35))
+[GOOD] (define-fun s37 () Expr (ite s24 s25 s36))
+[GOOD] (define-fun s38 () Expr (ite s16 s4 s37))
+[GOOD] (define-fun s39 () Expr (ite s10 s11 s38))
+[GOOD] (define-fun s40 () Bool (distinct s34 s39))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s40)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested07c.gold b/SBVTestSuite/GoldFiles/adt_nested07c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested07c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested08.gold b/SBVTestSuite/GoldFiles/adt_nested08.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested08.gold
@@ -0,0 +1,80 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Mul Expr) ((as Val Expr) 1) ((as Add Expr) ((as Val Expr) 3) ((as Val Expr) 4))))
+[GOOD] (define-fun s7 () Int 0)
+[GOOD] (define-fun s21 () Int 1)
+[GOOD] (define-fun s34 () Expr ((as Val Expr) 0))
+[GOOD] (define-fun s40 () Expr ((as Add Expr) ((as Val Expr) 3) ((as Val Expr) 4)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s6 () Int (getVal_1 s4))
+[GOOD] (define-fun s8 () Bool (= s6 s7))
+[GOOD] (define-fun s9 () Bool (and s5 s8))
+[GOOD] (define-fun s10 () Bool (and s3 s9))
+[GOOD] (define-fun s11 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s12 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s13 () Int (getVal_1 s11))
+[GOOD] (define-fun s14 () Bool (= s7 s13))
+[GOOD] (define-fun s15 () Bool (and s12 s14))
+[GOOD] (define-fun s16 () Bool (and s3 s15))
+[GOOD] (define-fun s17 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s18 () Expr (getMul_1 s0))
+[GOOD] (define-fun s19 () Bool ((as is-Val Bool) s18))
+[GOOD] (define-fun s20 () Int (getVal_1 s18))
+[GOOD] (define-fun s22 () Bool (= s20 s21))
+[GOOD] (define-fun s23 () Bool (and s19 s22))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s25 () Expr (getMul_2 s0))
+[GOOD] (define-fun s26 () Bool ((as is-Val Bool) s25))
+[GOOD] (define-fun s27 () Int (getVal_1 s25))
+[GOOD] (define-fun s28 () Bool (= s21 s27))
+[GOOD] (define-fun s29 () Bool (and s26 s28))
+[GOOD] (define-fun s30 () Bool (and s17 s29))
+[GOOD] (define-fun s31 () Bool (= s7 s20))
+[GOOD] (define-fun s32 () Bool (and s19 s31))
+[GOOD] (define-fun s33 () Bool (and s17 s32))
+[GOOD] (define-fun s35 () Expr (ite s33 s34 s0))
+[GOOD] (define-fun s36 () Expr (ite s30 s18 s35))
+[GOOD] (define-fun s37 () Expr (ite s24 s25 s36))
+[GOOD] (define-fun s38 () Expr (ite s16 s4 s37))
+[GOOD] (define-fun s39 () Expr (ite s10 s11 s38))
+[GOOD] (define-fun s41 () Bool (distinct s39 s40))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s41)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested08c.gold b/SBVTestSuite/GoldFiles/adt_nested08c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested08c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested09.gold b/SBVTestSuite/GoldFiles/adt_nested09.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested09.gold
@@ -0,0 +1,79 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Mul Expr) ((as Val Expr) 0) ((as Add Expr) ((as Val Expr) 3) ((as Val Expr) 4))))
+[GOOD] (define-fun s7 () Int 0)
+[GOOD] (define-fun s21 () Int 1)
+[GOOD] (define-fun s34 () Expr ((as Val Expr) 0))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s6 () Int (getVal_1 s4))
+[GOOD] (define-fun s8 () Bool (= s6 s7))
+[GOOD] (define-fun s9 () Bool (and s5 s8))
+[GOOD] (define-fun s10 () Bool (and s3 s9))
+[GOOD] (define-fun s11 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s12 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s13 () Int (getVal_1 s11))
+[GOOD] (define-fun s14 () Bool (= s7 s13))
+[GOOD] (define-fun s15 () Bool (and s12 s14))
+[GOOD] (define-fun s16 () Bool (and s3 s15))
+[GOOD] (define-fun s17 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s18 () Expr (getMul_1 s0))
+[GOOD] (define-fun s19 () Bool ((as is-Val Bool) s18))
+[GOOD] (define-fun s20 () Int (getVal_1 s18))
+[GOOD] (define-fun s22 () Bool (= s20 s21))
+[GOOD] (define-fun s23 () Bool (and s19 s22))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s25 () Expr (getMul_2 s0))
+[GOOD] (define-fun s26 () Bool ((as is-Val Bool) s25))
+[GOOD] (define-fun s27 () Int (getVal_1 s25))
+[GOOD] (define-fun s28 () Bool (= s21 s27))
+[GOOD] (define-fun s29 () Bool (and s26 s28))
+[GOOD] (define-fun s30 () Bool (and s17 s29))
+[GOOD] (define-fun s31 () Bool (= s7 s20))
+[GOOD] (define-fun s32 () Bool (and s19 s31))
+[GOOD] (define-fun s33 () Bool (and s17 s32))
+[GOOD] (define-fun s35 () Expr (ite s33 s34 s0))
+[GOOD] (define-fun s36 () Expr (ite s30 s18 s35))
+[GOOD] (define-fun s37 () Expr (ite s24 s25 s36))
+[GOOD] (define-fun s38 () Expr (ite s16 s4 s37))
+[GOOD] (define-fun s39 () Expr (ite s10 s11 s38))
+[GOOD] (define-fun s40 () Bool (distinct s34 s39))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s40)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested09c.gold b/SBVTestSuite/GoldFiles/adt_nested09c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested09c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested10.gold b/SBVTestSuite/GoldFiles/adt_nested10.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested10.gold
@@ -0,0 +1,79 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Var Expr) "x"))
+[GOOD] (define-fun s7 () Int 0)
+[GOOD] (define-fun s21 () Int 1)
+[GOOD] (define-fun s34 () Expr ((as Val Expr) 0))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s6 () Int (getVal_1 s4))
+[GOOD] (define-fun s8 () Bool (= s6 s7))
+[GOOD] (define-fun s9 () Bool (and s5 s8))
+[GOOD] (define-fun s10 () Bool (and s3 s9))
+[GOOD] (define-fun s11 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s12 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s13 () Int (getVal_1 s11))
+[GOOD] (define-fun s14 () Bool (= s7 s13))
+[GOOD] (define-fun s15 () Bool (and s12 s14))
+[GOOD] (define-fun s16 () Bool (and s3 s15))
+[GOOD] (define-fun s17 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s18 () Expr (getMul_1 s0))
+[GOOD] (define-fun s19 () Bool ((as is-Val Bool) s18))
+[GOOD] (define-fun s20 () Int (getVal_1 s18))
+[GOOD] (define-fun s22 () Bool (= s20 s21))
+[GOOD] (define-fun s23 () Bool (and s19 s22))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s25 () Expr (getMul_2 s0))
+[GOOD] (define-fun s26 () Bool ((as is-Val Bool) s25))
+[GOOD] (define-fun s27 () Int (getVal_1 s25))
+[GOOD] (define-fun s28 () Bool (= s21 s27))
+[GOOD] (define-fun s29 () Bool (and s26 s28))
+[GOOD] (define-fun s30 () Bool (and s17 s29))
+[GOOD] (define-fun s31 () Bool (= s7 s20))
+[GOOD] (define-fun s32 () Bool (and s19 s31))
+[GOOD] (define-fun s33 () Bool (and s17 s32))
+[GOOD] (define-fun s35 () Expr (ite s33 s34 s0))
+[GOOD] (define-fun s36 () Expr (ite s30 s18 s35))
+[GOOD] (define-fun s37 () Expr (ite s24 s25 s36))
+[GOOD] (define-fun s38 () Expr (ite s16 s4 s37))
+[GOOD] (define-fun s39 () Expr (ite s10 s11 s38))
+[GOOD] (define-fun s40 () Bool (distinct s1 s39))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s40)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested10c.gold b/SBVTestSuite/GoldFiles/adt_nested10c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested10c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested11.gold b/SBVTestSuite/GoldFiles/adt_nested11.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested11.gold
@@ -0,0 +1,79 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Val Expr) 42))
+[GOOD] (define-fun s7 () Int 0)
+[GOOD] (define-fun s21 () Int 1)
+[GOOD] (define-fun s34 () Expr ((as Val Expr) 0))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s6 () Int (getVal_1 s4))
+[GOOD] (define-fun s8 () Bool (= s6 s7))
+[GOOD] (define-fun s9 () Bool (and s5 s8))
+[GOOD] (define-fun s10 () Bool (and s3 s9))
+[GOOD] (define-fun s11 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s12 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s13 () Int (getVal_1 s11))
+[GOOD] (define-fun s14 () Bool (= s7 s13))
+[GOOD] (define-fun s15 () Bool (and s12 s14))
+[GOOD] (define-fun s16 () Bool (and s3 s15))
+[GOOD] (define-fun s17 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s18 () Expr (getMul_1 s0))
+[GOOD] (define-fun s19 () Bool ((as is-Val Bool) s18))
+[GOOD] (define-fun s20 () Int (getVal_1 s18))
+[GOOD] (define-fun s22 () Bool (= s20 s21))
+[GOOD] (define-fun s23 () Bool (and s19 s22))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s25 () Expr (getMul_2 s0))
+[GOOD] (define-fun s26 () Bool ((as is-Val Bool) s25))
+[GOOD] (define-fun s27 () Int (getVal_1 s25))
+[GOOD] (define-fun s28 () Bool (= s21 s27))
+[GOOD] (define-fun s29 () Bool (and s26 s28))
+[GOOD] (define-fun s30 () Bool (and s17 s29))
+[GOOD] (define-fun s31 () Bool (= s7 s20))
+[GOOD] (define-fun s32 () Bool (and s19 s31))
+[GOOD] (define-fun s33 () Bool (and s17 s32))
+[GOOD] (define-fun s35 () Expr (ite s33 s34 s0))
+[GOOD] (define-fun s36 () Expr (ite s30 s18 s35))
+[GOOD] (define-fun s37 () Expr (ite s24 s25 s36))
+[GOOD] (define-fun s38 () Expr (ite s16 s4 s37))
+[GOOD] (define-fun s39 () Expr (ite s10 s11 s38))
+[GOOD] (define-fun s40 () Bool (distinct s1 s39))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s40)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested11c.gold b/SBVTestSuite/GoldFiles/adt_nested11c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested11c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested12.gold b/SBVTestSuite/GoldFiles/adt_nested12.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested12.gold
@@ -0,0 +1,79 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Let Expr) "x" ((as Val Expr) 1) ((as Var Expr) "x")))
+[GOOD] (define-fun s7 () Int 0)
+[GOOD] (define-fun s21 () Int 1)
+[GOOD] (define-fun s34 () Expr ((as Val Expr) 0))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s6 () Int (getVal_1 s4))
+[GOOD] (define-fun s8 () Bool (= s6 s7))
+[GOOD] (define-fun s9 () Bool (and s5 s8))
+[GOOD] (define-fun s10 () Bool (and s3 s9))
+[GOOD] (define-fun s11 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s12 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s13 () Int (getVal_1 s11))
+[GOOD] (define-fun s14 () Bool (= s7 s13))
+[GOOD] (define-fun s15 () Bool (and s12 s14))
+[GOOD] (define-fun s16 () Bool (and s3 s15))
+[GOOD] (define-fun s17 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s18 () Expr (getMul_1 s0))
+[GOOD] (define-fun s19 () Bool ((as is-Val Bool) s18))
+[GOOD] (define-fun s20 () Int (getVal_1 s18))
+[GOOD] (define-fun s22 () Bool (= s20 s21))
+[GOOD] (define-fun s23 () Bool (and s19 s22))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s25 () Expr (getMul_2 s0))
+[GOOD] (define-fun s26 () Bool ((as is-Val Bool) s25))
+[GOOD] (define-fun s27 () Int (getVal_1 s25))
+[GOOD] (define-fun s28 () Bool (= s21 s27))
+[GOOD] (define-fun s29 () Bool (and s26 s28))
+[GOOD] (define-fun s30 () Bool (and s17 s29))
+[GOOD] (define-fun s31 () Bool (= s7 s20))
+[GOOD] (define-fun s32 () Bool (and s19 s31))
+[GOOD] (define-fun s33 () Bool (and s17 s32))
+[GOOD] (define-fun s35 () Expr (ite s33 s34 s0))
+[GOOD] (define-fun s36 () Expr (ite s30 s18 s35))
+[GOOD] (define-fun s37 () Expr (ite s24 s25 s36))
+[GOOD] (define-fun s38 () Expr (ite s16 s4 s37))
+[GOOD] (define-fun s39 () Expr (ite s10 s11 s38))
+[GOOD] (define-fun s40 () Bool (distinct s1 s39))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s40)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested12c.gold b/SBVTestSuite/GoldFiles/adt_nested12c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested12c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested13.gold b/SBVTestSuite/GoldFiles/adt_nested13.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested13.gold
@@ -0,0 +1,79 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Mul Expr) ((as Val Expr) 0) ((as Var Expr) "x")))
+[GOOD] (define-fun s7 () Int 0)
+[GOOD] (define-fun s21 () Int 1)
+[GOOD] (define-fun s34 () Expr ((as Val Expr) 0))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s6 () Int (getVal_1 s4))
+[GOOD] (define-fun s8 () Bool (= s6 s7))
+[GOOD] (define-fun s9 () Bool (and s5 s8))
+[GOOD] (define-fun s10 () Bool (and s3 s9))
+[GOOD] (define-fun s11 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s12 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s13 () Int (getVal_1 s11))
+[GOOD] (define-fun s14 () Bool (= s7 s13))
+[GOOD] (define-fun s15 () Bool (and s12 s14))
+[GOOD] (define-fun s16 () Bool (and s3 s15))
+[GOOD] (define-fun s17 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s18 () Expr (getMul_1 s0))
+[GOOD] (define-fun s19 () Bool ((as is-Val Bool) s18))
+[GOOD] (define-fun s20 () Int (getVal_1 s18))
+[GOOD] (define-fun s22 () Bool (= s20 s21))
+[GOOD] (define-fun s23 () Bool (and s19 s22))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s25 () Expr (getMul_2 s0))
+[GOOD] (define-fun s26 () Bool ((as is-Val Bool) s25))
+[GOOD] (define-fun s27 () Int (getVal_1 s25))
+[GOOD] (define-fun s28 () Bool (= s21 s27))
+[GOOD] (define-fun s29 () Bool (and s26 s28))
+[GOOD] (define-fun s30 () Bool (and s17 s29))
+[GOOD] (define-fun s31 () Bool (= s7 s20))
+[GOOD] (define-fun s32 () Bool (and s19 s31))
+[GOOD] (define-fun s33 () Bool (and s17 s32))
+[GOOD] (define-fun s35 () Expr (ite s33 s34 s0))
+[GOOD] (define-fun s36 () Expr (ite s30 s18 s35))
+[GOOD] (define-fun s37 () Expr (ite s24 s25 s36))
+[GOOD] (define-fun s38 () Expr (ite s16 s4 s37))
+[GOOD] (define-fun s39 () Expr (ite s10 s11 s38))
+[GOOD] (define-fun s40 () Bool (distinct s34 s39))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s40)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested13c.gold b/SBVTestSuite/GoldFiles/adt_nested13c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested13c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested14.gold b/SBVTestSuite/GoldFiles/adt_nested14.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested14.gold
@@ -0,0 +1,80 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Add Expr) ((as Val Expr) 0) ((as Mul Expr) ((as Val Expr) 2) ((as Val Expr) 3))))
+[GOOD] (define-fun s7 () Int 0)
+[GOOD] (define-fun s21 () Int 1)
+[GOOD] (define-fun s34 () Expr ((as Val Expr) 0))
+[GOOD] (define-fun s40 () Expr ((as Mul Expr) ((as Val Expr) 2) ((as Val Expr) 3)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s6 () Int (getVal_1 s4))
+[GOOD] (define-fun s8 () Bool (= s6 s7))
+[GOOD] (define-fun s9 () Bool (and s5 s8))
+[GOOD] (define-fun s10 () Bool (and s3 s9))
+[GOOD] (define-fun s11 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s12 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s13 () Int (getVal_1 s11))
+[GOOD] (define-fun s14 () Bool (= s7 s13))
+[GOOD] (define-fun s15 () Bool (and s12 s14))
+[GOOD] (define-fun s16 () Bool (and s3 s15))
+[GOOD] (define-fun s17 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s18 () Expr (getMul_1 s0))
+[GOOD] (define-fun s19 () Bool ((as is-Val Bool) s18))
+[GOOD] (define-fun s20 () Int (getVal_1 s18))
+[GOOD] (define-fun s22 () Bool (= s20 s21))
+[GOOD] (define-fun s23 () Bool (and s19 s22))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s25 () Expr (getMul_2 s0))
+[GOOD] (define-fun s26 () Bool ((as is-Val Bool) s25))
+[GOOD] (define-fun s27 () Int (getVal_1 s25))
+[GOOD] (define-fun s28 () Bool (= s21 s27))
+[GOOD] (define-fun s29 () Bool (and s26 s28))
+[GOOD] (define-fun s30 () Bool (and s17 s29))
+[GOOD] (define-fun s31 () Bool (= s7 s20))
+[GOOD] (define-fun s32 () Bool (and s19 s31))
+[GOOD] (define-fun s33 () Bool (and s17 s32))
+[GOOD] (define-fun s35 () Expr (ite s33 s34 s0))
+[GOOD] (define-fun s36 () Expr (ite s30 s18 s35))
+[GOOD] (define-fun s37 () Expr (ite s24 s25 s36))
+[GOOD] (define-fun s38 () Expr (ite s16 s4 s37))
+[GOOD] (define-fun s39 () Expr (ite s10 s11 s38))
+[GOOD] (define-fun s41 () Bool (distinct s39 s40))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s41)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested14c.gold b/SBVTestSuite/GoldFiles/adt_nested14c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested14c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested15.gold b/SBVTestSuite/GoldFiles/adt_nested15.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested15.gold
@@ -0,0 +1,114 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Add Expr) ((as Val Expr) 0) ((as Val Expr) 5)))
+[GOOD] (define-fun s7 () Int 0)
+[GOOD] (define-fun s21 () Int 1)
+[GOOD] (define-fun s34 () Expr ((as Val Expr) 0))
+[GOOD] (define-fun s74 () Expr ((as Val Expr) 5))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s6 () Int (getVal_1 s4))
+[GOOD] (define-fun s8 () Bool (= s6 s7))
+[GOOD] (define-fun s9 () Bool (and s5 s8))
+[GOOD] (define-fun s10 () Bool (and s3 s9))
+[GOOD] (define-fun s11 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s12 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s13 () Int (getVal_1 s11))
+[GOOD] (define-fun s14 () Bool (= s7 s13))
+[GOOD] (define-fun s15 () Bool (and s12 s14))
+[GOOD] (define-fun s16 () Bool (and s3 s15))
+[GOOD] (define-fun s17 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s18 () Expr (getMul_1 s0))
+[GOOD] (define-fun s19 () Bool ((as is-Val Bool) s18))
+[GOOD] (define-fun s20 () Int (getVal_1 s18))
+[GOOD] (define-fun s22 () Bool (= s20 s21))
+[GOOD] (define-fun s23 () Bool (and s19 s22))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s25 () Expr (getMul_2 s0))
+[GOOD] (define-fun s26 () Bool ((as is-Val Bool) s25))
+[GOOD] (define-fun s27 () Int (getVal_1 s25))
+[GOOD] (define-fun s28 () Bool (= s21 s27))
+[GOOD] (define-fun s29 () Bool (and s26 s28))
+[GOOD] (define-fun s30 () Bool (and s17 s29))
+[GOOD] (define-fun s31 () Bool (= s7 s20))
+[GOOD] (define-fun s32 () Bool (and s19 s31))
+[GOOD] (define-fun s33 () Bool (and s17 s32))
+[GOOD] (define-fun s35 () Expr (ite s33 s34 s0))
+[GOOD] (define-fun s36 () Expr (ite s30 s18 s35))
+[GOOD] (define-fun s37 () Expr (ite s24 s25 s36))
+[GOOD] (define-fun s38 () Expr (ite s16 s4 s37))
+[GOOD] (define-fun s39 () Expr (ite s10 s11 s38))
+[GOOD] (define-fun s40 () Bool ((as is-Add Bool) s39))
+[GOOD] (define-fun s41 () Expr (getAdd_1 s39))
+[GOOD] (define-fun s42 () Bool ((as is-Val Bool) s41))
+[GOOD] (define-fun s43 () Int (getVal_1 s41))
+[GOOD] (define-fun s44 () Bool (= s7 s43))
+[GOOD] (define-fun s45 () Bool (and s42 s44))
+[GOOD] (define-fun s46 () Bool (and s40 s45))
+[GOOD] (define-fun s47 () Expr (getAdd_2 s39))
+[GOOD] (define-fun s48 () Bool ((as is-Val Bool) s47))
+[GOOD] (define-fun s49 () Int (getVal_1 s47))
+[GOOD] (define-fun s50 () Bool (= s7 s49))
+[GOOD] (define-fun s51 () Bool (and s48 s50))
+[GOOD] (define-fun s52 () Bool (and s40 s51))
+[GOOD] (define-fun s53 () Bool ((as is-Mul Bool) s39))
+[GOOD] (define-fun s54 () Expr (getMul_1 s39))
+[GOOD] (define-fun s55 () Bool ((as is-Val Bool) s54))
+[GOOD] (define-fun s56 () Int (getVal_1 s54))
+[GOOD] (define-fun s57 () Bool (= s21 s56))
+[GOOD] (define-fun s58 () Bool (and s55 s57))
+[GOOD] (define-fun s59 () Bool (and s53 s58))
+[GOOD] (define-fun s60 () Expr (getMul_2 s39))
+[GOOD] (define-fun s61 () Bool ((as is-Val Bool) s60))
+[GOOD] (define-fun s62 () Int (getVal_1 s60))
+[GOOD] (define-fun s63 () Bool (= s21 s62))
+[GOOD] (define-fun s64 () Bool (and s61 s63))
+[GOOD] (define-fun s65 () Bool (and s53 s64))
+[GOOD] (define-fun s66 () Bool (= s7 s56))
+[GOOD] (define-fun s67 () Bool (and s55 s66))
+[GOOD] (define-fun s68 () Bool (and s53 s67))
+[GOOD] (define-fun s69 () Expr (ite s68 s34 s39))
+[GOOD] (define-fun s70 () Expr (ite s65 s54 s69))
+[GOOD] (define-fun s71 () Expr (ite s59 s60 s70))
+[GOOD] (define-fun s72 () Expr (ite s52 s41 s71))
+[GOOD] (define-fun s73 () Expr (ite s46 s47 s72))
+[GOOD] (define-fun s75 () Bool (distinct s73 s74))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s75)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested15c.gold b/SBVTestSuite/GoldFiles/adt_nested15c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested15c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested16.gold b/SBVTestSuite/GoldFiles/adt_nested16.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested16.gold
@@ -0,0 +1,113 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Add Expr) ((as Val Expr) 3) ((as Val Expr) 4)))
+[GOOD] (define-fun s7 () Int 0)
+[GOOD] (define-fun s21 () Int 1)
+[GOOD] (define-fun s34 () Expr ((as Val Expr) 0))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s6 () Int (getVal_1 s4))
+[GOOD] (define-fun s8 () Bool (= s6 s7))
+[GOOD] (define-fun s9 () Bool (and s5 s8))
+[GOOD] (define-fun s10 () Bool (and s3 s9))
+[GOOD] (define-fun s11 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s12 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s13 () Int (getVal_1 s11))
+[GOOD] (define-fun s14 () Bool (= s7 s13))
+[GOOD] (define-fun s15 () Bool (and s12 s14))
+[GOOD] (define-fun s16 () Bool (and s3 s15))
+[GOOD] (define-fun s17 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s18 () Expr (getMul_1 s0))
+[GOOD] (define-fun s19 () Bool ((as is-Val Bool) s18))
+[GOOD] (define-fun s20 () Int (getVal_1 s18))
+[GOOD] (define-fun s22 () Bool (= s20 s21))
+[GOOD] (define-fun s23 () Bool (and s19 s22))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s25 () Expr (getMul_2 s0))
+[GOOD] (define-fun s26 () Bool ((as is-Val Bool) s25))
+[GOOD] (define-fun s27 () Int (getVal_1 s25))
+[GOOD] (define-fun s28 () Bool (= s21 s27))
+[GOOD] (define-fun s29 () Bool (and s26 s28))
+[GOOD] (define-fun s30 () Bool (and s17 s29))
+[GOOD] (define-fun s31 () Bool (= s7 s20))
+[GOOD] (define-fun s32 () Bool (and s19 s31))
+[GOOD] (define-fun s33 () Bool (and s17 s32))
+[GOOD] (define-fun s35 () Expr (ite s33 s34 s0))
+[GOOD] (define-fun s36 () Expr (ite s30 s18 s35))
+[GOOD] (define-fun s37 () Expr (ite s24 s25 s36))
+[GOOD] (define-fun s38 () Expr (ite s16 s4 s37))
+[GOOD] (define-fun s39 () Expr (ite s10 s11 s38))
+[GOOD] (define-fun s40 () Bool ((as is-Add Bool) s39))
+[GOOD] (define-fun s41 () Expr (getAdd_1 s39))
+[GOOD] (define-fun s42 () Bool ((as is-Val Bool) s41))
+[GOOD] (define-fun s43 () Int (getVal_1 s41))
+[GOOD] (define-fun s44 () Bool (= s7 s43))
+[GOOD] (define-fun s45 () Bool (and s42 s44))
+[GOOD] (define-fun s46 () Bool (and s40 s45))
+[GOOD] (define-fun s47 () Expr (getAdd_2 s39))
+[GOOD] (define-fun s48 () Bool ((as is-Val Bool) s47))
+[GOOD] (define-fun s49 () Int (getVal_1 s47))
+[GOOD] (define-fun s50 () Bool (= s7 s49))
+[GOOD] (define-fun s51 () Bool (and s48 s50))
+[GOOD] (define-fun s52 () Bool (and s40 s51))
+[GOOD] (define-fun s53 () Bool ((as is-Mul Bool) s39))
+[GOOD] (define-fun s54 () Expr (getMul_1 s39))
+[GOOD] (define-fun s55 () Bool ((as is-Val Bool) s54))
+[GOOD] (define-fun s56 () Int (getVal_1 s54))
+[GOOD] (define-fun s57 () Bool (= s21 s56))
+[GOOD] (define-fun s58 () Bool (and s55 s57))
+[GOOD] (define-fun s59 () Bool (and s53 s58))
+[GOOD] (define-fun s60 () Expr (getMul_2 s39))
+[GOOD] (define-fun s61 () Bool ((as is-Val Bool) s60))
+[GOOD] (define-fun s62 () Int (getVal_1 s60))
+[GOOD] (define-fun s63 () Bool (= s21 s62))
+[GOOD] (define-fun s64 () Bool (and s61 s63))
+[GOOD] (define-fun s65 () Bool (and s53 s64))
+[GOOD] (define-fun s66 () Bool (= s7 s56))
+[GOOD] (define-fun s67 () Bool (and s55 s66))
+[GOOD] (define-fun s68 () Bool (and s53 s67))
+[GOOD] (define-fun s69 () Expr (ite s68 s34 s39))
+[GOOD] (define-fun s70 () Expr (ite s65 s54 s69))
+[GOOD] (define-fun s71 () Expr (ite s59 s60 s70))
+[GOOD] (define-fun s72 () Expr (ite s52 s41 s71))
+[GOOD] (define-fun s73 () Expr (ite s46 s47 s72))
+[GOOD] (define-fun s74 () Bool (distinct s1 s73))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s74)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested16c.gold b/SBVTestSuite/GoldFiles/adt_nested16c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested16c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested17.gold b/SBVTestSuite/GoldFiles/adt_nested17.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested17.gold
@@ -0,0 +1,114 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Mul Expr) ((as Val Expr) 1) ((as Add Expr) ((as Val Expr) 0) ((as Val Expr) 5))))
+[GOOD] (define-fun s7 () Int 0)
+[GOOD] (define-fun s21 () Int 1)
+[GOOD] (define-fun s34 () Expr ((as Val Expr) 0))
+[GOOD] (define-fun s74 () Expr ((as Val Expr) 5))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s6 () Int (getVal_1 s4))
+[GOOD] (define-fun s8 () Bool (= s6 s7))
+[GOOD] (define-fun s9 () Bool (and s5 s8))
+[GOOD] (define-fun s10 () Bool (and s3 s9))
+[GOOD] (define-fun s11 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s12 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s13 () Int (getVal_1 s11))
+[GOOD] (define-fun s14 () Bool (= s7 s13))
+[GOOD] (define-fun s15 () Bool (and s12 s14))
+[GOOD] (define-fun s16 () Bool (and s3 s15))
+[GOOD] (define-fun s17 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s18 () Expr (getMul_1 s0))
+[GOOD] (define-fun s19 () Bool ((as is-Val Bool) s18))
+[GOOD] (define-fun s20 () Int (getVal_1 s18))
+[GOOD] (define-fun s22 () Bool (= s20 s21))
+[GOOD] (define-fun s23 () Bool (and s19 s22))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s25 () Expr (getMul_2 s0))
+[GOOD] (define-fun s26 () Bool ((as is-Val Bool) s25))
+[GOOD] (define-fun s27 () Int (getVal_1 s25))
+[GOOD] (define-fun s28 () Bool (= s21 s27))
+[GOOD] (define-fun s29 () Bool (and s26 s28))
+[GOOD] (define-fun s30 () Bool (and s17 s29))
+[GOOD] (define-fun s31 () Bool (= s7 s20))
+[GOOD] (define-fun s32 () Bool (and s19 s31))
+[GOOD] (define-fun s33 () Bool (and s17 s32))
+[GOOD] (define-fun s35 () Expr (ite s33 s34 s0))
+[GOOD] (define-fun s36 () Expr (ite s30 s18 s35))
+[GOOD] (define-fun s37 () Expr (ite s24 s25 s36))
+[GOOD] (define-fun s38 () Expr (ite s16 s4 s37))
+[GOOD] (define-fun s39 () Expr (ite s10 s11 s38))
+[GOOD] (define-fun s40 () Bool ((as is-Add Bool) s39))
+[GOOD] (define-fun s41 () Expr (getAdd_1 s39))
+[GOOD] (define-fun s42 () Bool ((as is-Val Bool) s41))
+[GOOD] (define-fun s43 () Int (getVal_1 s41))
+[GOOD] (define-fun s44 () Bool (= s7 s43))
+[GOOD] (define-fun s45 () Bool (and s42 s44))
+[GOOD] (define-fun s46 () Bool (and s40 s45))
+[GOOD] (define-fun s47 () Expr (getAdd_2 s39))
+[GOOD] (define-fun s48 () Bool ((as is-Val Bool) s47))
+[GOOD] (define-fun s49 () Int (getVal_1 s47))
+[GOOD] (define-fun s50 () Bool (= s7 s49))
+[GOOD] (define-fun s51 () Bool (and s48 s50))
+[GOOD] (define-fun s52 () Bool (and s40 s51))
+[GOOD] (define-fun s53 () Bool ((as is-Mul Bool) s39))
+[GOOD] (define-fun s54 () Expr (getMul_1 s39))
+[GOOD] (define-fun s55 () Bool ((as is-Val Bool) s54))
+[GOOD] (define-fun s56 () Int (getVal_1 s54))
+[GOOD] (define-fun s57 () Bool (= s21 s56))
+[GOOD] (define-fun s58 () Bool (and s55 s57))
+[GOOD] (define-fun s59 () Bool (and s53 s58))
+[GOOD] (define-fun s60 () Expr (getMul_2 s39))
+[GOOD] (define-fun s61 () Bool ((as is-Val Bool) s60))
+[GOOD] (define-fun s62 () Int (getVal_1 s60))
+[GOOD] (define-fun s63 () Bool (= s21 s62))
+[GOOD] (define-fun s64 () Bool (and s61 s63))
+[GOOD] (define-fun s65 () Bool (and s53 s64))
+[GOOD] (define-fun s66 () Bool (= s7 s56))
+[GOOD] (define-fun s67 () Bool (and s55 s66))
+[GOOD] (define-fun s68 () Bool (and s53 s67))
+[GOOD] (define-fun s69 () Expr (ite s68 s34 s39))
+[GOOD] (define-fun s70 () Expr (ite s65 s54 s69))
+[GOOD] (define-fun s71 () Expr (ite s59 s60 s70))
+[GOOD] (define-fun s72 () Expr (ite s52 s41 s71))
+[GOOD] (define-fun s73 () Expr (ite s46 s47 s72))
+[GOOD] (define-fun s75 () Bool (distinct s73 s74))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s75)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested17c.gold b/SBVTestSuite/GoldFiles/adt_nested17c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested17c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested18.gold b/SBVTestSuite/GoldFiles/adt_nested18.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested18.gold
@@ -0,0 +1,252 @@
+[MEASURE] Verifying termination measures for: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): not in a multi-member cycle, skipping mutual check
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): barified = "|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|"
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2)]
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): recursive calls found = 6
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): trying sbv.dt.size.Expr arg2
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK (structural recursion)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): barified = "|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|"
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2)]
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): recursive calls found = 1
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): trying length arg1
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Bool (>= s4 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Int (seq.len s13))
+[GOOD] (define-fun s18 () Bool (not s10))
+[GOOD] (define-fun s19 () Bool (and s6 s18))
+[GOOD] (define-fun s20 () Bool (> s4 s17))
+[GOOD] (define-fun s21 () Bool (=> s19 s20))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): length arg1 -> OK
+[MEASURE] Passed (terminating): get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (Seq (SBVTuple2 String Int)) (as seq.empty (Seq (SBVTuple2 String Int))))
+[GOOD] (define-fun s6 () Int 0)
+[GOOD] (define-fun s20 () Int 1)
+[GOOD] (define-fun s33 () Expr ((as Val Expr) 0))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr) ; tracks user variable "e"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| :: [(SString, SInteger)] -> SString -> SInteger [Recursive]
+[GOOD] (define-fun-rec |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| ((l2_s0 (Seq (SBVTuple2 String Int))) (l2_s1 String)) Int
+                                                 (let ((l2_s3 0))
+                                                 (let ((l2_s11 1))
+                                                 (let ((l2_s2 (seq.len l2_s0)))
+                                                 (let ((l2_s4 (= l2_s2 l2_s3)))
+                                                 (let ((l2_s5 (not l2_s4)))
+                                                 (let ((l2_s6 (seq.nth l2_s0 l2_s3)))
+                                                 (let ((l2_s7 (proj_1_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s8 (= l2_s1 l2_s7)))
+                                                 (let ((l2_s9 (and l2_s5 l2_s8)))
+                                                 (let ((l2_s10 (proj_2_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s12 (- l2_s2 l2_s11)))
+                                                 (let ((l2_s13 (seq.extract l2_s0 l2_s11 l2_s12)))
+                                                 (let ((l2_s14 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l2_s13 l2_s1)))
+                                                 (let ((l2_s15 (ite l2_s9 l2_s10 l2_s14)))
+                                                 (let ((l2_s16 (ite l2_s4 l2_s3 l2_s15)))
+                                                 l2_s16))))))))))))))))
+[GOOD] ; |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| :: [(SString, SInteger)] -> Expr -> SInteger [Recursive] [Refers to: |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|]
+[GOOD] (define-fun-rec |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| ((l1_s0 (Seq (SBVTuple2 String Int))) (l1_s1 Expr)) Int
+                                 (let ((l1_s2 ((as is-Val Bool) l1_s1)))
+                                 (let ((l1_s3 (getVal_1 l1_s1)))
+                                 (let ((l1_s4 ((as is-Var Bool) l1_s1)))
+                                 (let ((l1_s5 (getVar_1 l1_s1)))
+                                 (let ((l1_s6 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l1_s0 l1_s5)))
+                                 (let ((l1_s7 ((as is-Add Bool) l1_s1)))
+                                 (let ((l1_s8 (getAdd_1 l1_s1)))
+                                 (let ((l1_s9 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s8)))
+                                 (let ((l1_s10 (getAdd_2 l1_s1)))
+                                 (let ((l1_s11 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s10)))
+                                 (let ((l1_s12 (+ l1_s9 l1_s11)))
+                                 (let ((l1_s13 ((as is-Mul Bool) l1_s1)))
+                                 (let ((l1_s14 (getMul_1 l1_s1)))
+                                 (let ((l1_s15 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s14)))
+                                 (let ((l1_s16 (getMul_2 l1_s1)))
+                                 (let ((l1_s17 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s16)))
+                                 (let ((l1_s18 (* l1_s15 l1_s17)))
+                                 (let ((l1_s19 (getLet_1 l1_s1)))
+                                 (let ((l1_s20 (getLet_2 l1_s1)))
+                                 (let ((l1_s21 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s20)))
+                                 (let ((l1_s22 ((as mkSBVTuple2 (SBVTuple2 String Int)) l1_s19 l1_s21)))
+                                 (let ((l1_s23 (seq.unit l1_s22)))
+                                 (let ((l1_s24 (seq.++ l1_s23 l1_s0)))
+                                 (let ((l1_s25 (getLet_3 l1_s1)))
+                                 (let ((l1_s26 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s24 l1_s25)))
+                                 (let ((l1_s27 (ite l1_s13 l1_s18 l1_s26)))
+                                 (let ((l1_s28 (ite l1_s7 l1_s12 l1_s27)))
+                                 (let ((l1_s29 (ite l1_s4 l1_s6 l1_s28)))
+                                 (let ((l1_s30 (ite l1_s2 l1_s3 l1_s29)))
+                                 l1_s30))))))))))))))))))))))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s3 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s4 () Bool ((as is-Val Bool) s3))
+[GOOD] (define-fun s5 () Int (getVal_1 s3))
+[GOOD] (define-fun s7 () Bool (= s5 s6))
+[GOOD] (define-fun s8 () Bool (and s4 s7))
+[GOOD] (define-fun s9 () Bool (and s2 s8))
+[GOOD] (define-fun s10 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s11 () Bool ((as is-Val Bool) s10))
+[GOOD] (define-fun s12 () Int (getVal_1 s10))
+[GOOD] (define-fun s13 () Bool (= s6 s12))
+[GOOD] (define-fun s14 () Bool (and s11 s13))
+[GOOD] (define-fun s15 () Bool (and s2 s14))
+[GOOD] (define-fun s16 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s17 () Expr (getMul_1 s0))
+[GOOD] (define-fun s18 () Bool ((as is-Val Bool) s17))
+[GOOD] (define-fun s19 () Int (getVal_1 s17))
+[GOOD] (define-fun s21 () Bool (= s19 s20))
+[GOOD] (define-fun s22 () Bool (and s18 s21))
+[GOOD] (define-fun s23 () Bool (and s16 s22))
+[GOOD] (define-fun s24 () Expr (getMul_2 s0))
+[GOOD] (define-fun s25 () Bool ((as is-Val Bool) s24))
+[GOOD] (define-fun s26 () Int (getVal_1 s24))
+[GOOD] (define-fun s27 () Bool (= s20 s26))
+[GOOD] (define-fun s28 () Bool (and s25 s27))
+[GOOD] (define-fun s29 () Bool (and s16 s28))
+[GOOD] (define-fun s30 () Bool (= s6 s19))
+[GOOD] (define-fun s31 () Bool (and s18 s30))
+[GOOD] (define-fun s32 () Bool (and s16 s31))
+[GOOD] (define-fun s34 () Expr (ite s32 s33 s0))
+[GOOD] (define-fun s35 () Expr (ite s29 s17 s34))
+[GOOD] (define-fun s36 () Expr (ite s23 s24 s35))
+[GOOD] (define-fun s37 () Expr (ite s15 s3 s36))
+[GOOD] (define-fun s38 () Expr (ite s9 s10 s37))
+[GOOD] (define-fun s39 () Int (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| s1 s38))
+[GOOD] (define-fun s40 () Int (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| s1 s0))
+[GOOD] (define-fun s41 () Bool (= s39 s40))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s41))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested19.gold b/SBVTestSuite/GoldFiles/adt_nested19.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested19.gold
@@ -0,0 +1,80 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Mul Expr) ((as Val Expr) 1) ((as Val Expr) 1)))
+[GOOD] (define-fun s7 () Int 0)
+[GOOD] (define-fun s21 () Int 1)
+[GOOD] (define-fun s34 () Expr ((as Val Expr) 0))
+[GOOD] (define-fun s40 () Expr ((as Val Expr) 1))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s6 () Int (getVal_1 s4))
+[GOOD] (define-fun s8 () Bool (= s6 s7))
+[GOOD] (define-fun s9 () Bool (and s5 s8))
+[GOOD] (define-fun s10 () Bool (and s3 s9))
+[GOOD] (define-fun s11 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s12 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s13 () Int (getVal_1 s11))
+[GOOD] (define-fun s14 () Bool (= s7 s13))
+[GOOD] (define-fun s15 () Bool (and s12 s14))
+[GOOD] (define-fun s16 () Bool (and s3 s15))
+[GOOD] (define-fun s17 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s18 () Expr (getMul_1 s0))
+[GOOD] (define-fun s19 () Bool ((as is-Val Bool) s18))
+[GOOD] (define-fun s20 () Int (getVal_1 s18))
+[GOOD] (define-fun s22 () Bool (= s20 s21))
+[GOOD] (define-fun s23 () Bool (and s19 s22))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s25 () Expr (getMul_2 s0))
+[GOOD] (define-fun s26 () Bool ((as is-Val Bool) s25))
+[GOOD] (define-fun s27 () Int (getVal_1 s25))
+[GOOD] (define-fun s28 () Bool (= s21 s27))
+[GOOD] (define-fun s29 () Bool (and s26 s28))
+[GOOD] (define-fun s30 () Bool (and s17 s29))
+[GOOD] (define-fun s31 () Bool (= s7 s20))
+[GOOD] (define-fun s32 () Bool (and s19 s31))
+[GOOD] (define-fun s33 () Bool (and s17 s32))
+[GOOD] (define-fun s35 () Expr (ite s33 s34 s0))
+[GOOD] (define-fun s36 () Expr (ite s30 s18 s35))
+[GOOD] (define-fun s37 () Expr (ite s24 s25 s36))
+[GOOD] (define-fun s38 () Expr (ite s16 s4 s37))
+[GOOD] (define-fun s39 () Expr (ite s10 s11 s38))
+[GOOD] (define-fun s41 () Bool (distinct s39 s40))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s41)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested19c.gold b/SBVTestSuite/GoldFiles/adt_nested19c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested19c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested20.gold b/SBVTestSuite/GoldFiles/adt_nested20.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested20.gold
@@ -0,0 +1,79 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Mul Expr) ((as Val Expr) 2) ((as Val Expr) 3)))
+[GOOD] (define-fun s7 () Int 0)
+[GOOD] (define-fun s21 () Int 1)
+[GOOD] (define-fun s34 () Expr ((as Val Expr) 0))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s6 () Int (getVal_1 s4))
+[GOOD] (define-fun s8 () Bool (= s6 s7))
+[GOOD] (define-fun s9 () Bool (and s5 s8))
+[GOOD] (define-fun s10 () Bool (and s3 s9))
+[GOOD] (define-fun s11 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s12 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s13 () Int (getVal_1 s11))
+[GOOD] (define-fun s14 () Bool (= s7 s13))
+[GOOD] (define-fun s15 () Bool (and s12 s14))
+[GOOD] (define-fun s16 () Bool (and s3 s15))
+[GOOD] (define-fun s17 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s18 () Expr (getMul_1 s0))
+[GOOD] (define-fun s19 () Bool ((as is-Val Bool) s18))
+[GOOD] (define-fun s20 () Int (getVal_1 s18))
+[GOOD] (define-fun s22 () Bool (= s20 s21))
+[GOOD] (define-fun s23 () Bool (and s19 s22))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s25 () Expr (getMul_2 s0))
+[GOOD] (define-fun s26 () Bool ((as is-Val Bool) s25))
+[GOOD] (define-fun s27 () Int (getVal_1 s25))
+[GOOD] (define-fun s28 () Bool (= s21 s27))
+[GOOD] (define-fun s29 () Bool (and s26 s28))
+[GOOD] (define-fun s30 () Bool (and s17 s29))
+[GOOD] (define-fun s31 () Bool (= s7 s20))
+[GOOD] (define-fun s32 () Bool (and s19 s31))
+[GOOD] (define-fun s33 () Bool (and s17 s32))
+[GOOD] (define-fun s35 () Expr (ite s33 s34 s0))
+[GOOD] (define-fun s36 () Expr (ite s30 s18 s35))
+[GOOD] (define-fun s37 () Expr (ite s24 s25 s36))
+[GOOD] (define-fun s38 () Expr (ite s16 s4 s37))
+[GOOD] (define-fun s39 () Expr (ite s10 s11 s38))
+[GOOD] (define-fun s40 () Bool (distinct s1 s39))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s40)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested20c.gold b/SBVTestSuite/GoldFiles/adt_nested20c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested20c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested21.gold b/SBVTestSuite/GoldFiles/adt_nested21.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested21.gold
@@ -0,0 +1,80 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Mul Expr) ((as Val Expr) 1) ((as Var Expr) "x")))
+[GOOD] (define-fun s7 () Int 0)
+[GOOD] (define-fun s21 () Int 1)
+[GOOD] (define-fun s34 () Expr ((as Val Expr) 0))
+[GOOD] (define-fun s40 () Expr ((as Var Expr) "x"))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s6 () Int (getVal_1 s4))
+[GOOD] (define-fun s8 () Bool (= s6 s7))
+[GOOD] (define-fun s9 () Bool (and s5 s8))
+[GOOD] (define-fun s10 () Bool (and s3 s9))
+[GOOD] (define-fun s11 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s12 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s13 () Int (getVal_1 s11))
+[GOOD] (define-fun s14 () Bool (= s7 s13))
+[GOOD] (define-fun s15 () Bool (and s12 s14))
+[GOOD] (define-fun s16 () Bool (and s3 s15))
+[GOOD] (define-fun s17 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s18 () Expr (getMul_1 s0))
+[GOOD] (define-fun s19 () Bool ((as is-Val Bool) s18))
+[GOOD] (define-fun s20 () Int (getVal_1 s18))
+[GOOD] (define-fun s22 () Bool (= s20 s21))
+[GOOD] (define-fun s23 () Bool (and s19 s22))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s25 () Expr (getMul_2 s0))
+[GOOD] (define-fun s26 () Bool ((as is-Val Bool) s25))
+[GOOD] (define-fun s27 () Int (getVal_1 s25))
+[GOOD] (define-fun s28 () Bool (= s21 s27))
+[GOOD] (define-fun s29 () Bool (and s26 s28))
+[GOOD] (define-fun s30 () Bool (and s17 s29))
+[GOOD] (define-fun s31 () Bool (= s7 s20))
+[GOOD] (define-fun s32 () Bool (and s19 s31))
+[GOOD] (define-fun s33 () Bool (and s17 s32))
+[GOOD] (define-fun s35 () Expr (ite s33 s34 s0))
+[GOOD] (define-fun s36 () Expr (ite s30 s18 s35))
+[GOOD] (define-fun s37 () Expr (ite s24 s25 s36))
+[GOOD] (define-fun s38 () Expr (ite s16 s4 s37))
+[GOOD] (define-fun s39 () Expr (ite s10 s11 s38))
+[GOOD] (define-fun s41 () Bool (distinct s39 s40))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s41)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested21c.gold b/SBVTestSuite/GoldFiles/adt_nested21c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested21c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested22.gold b/SBVTestSuite/GoldFiles/adt_nested22.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested22.gold
@@ -0,0 +1,80 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Add Expr) ((as Val Expr) 0) ((as Var Expr) "x")))
+[GOOD] (define-fun s7 () Int 0)
+[GOOD] (define-fun s21 () Int 1)
+[GOOD] (define-fun s34 () Expr ((as Val Expr) 0))
+[GOOD] (define-fun s40 () Expr ((as Var Expr) "x"))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s6 () Int (getVal_1 s4))
+[GOOD] (define-fun s8 () Bool (= s6 s7))
+[GOOD] (define-fun s9 () Bool (and s5 s8))
+[GOOD] (define-fun s10 () Bool (and s3 s9))
+[GOOD] (define-fun s11 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s12 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s13 () Int (getVal_1 s11))
+[GOOD] (define-fun s14 () Bool (= s7 s13))
+[GOOD] (define-fun s15 () Bool (and s12 s14))
+[GOOD] (define-fun s16 () Bool (and s3 s15))
+[GOOD] (define-fun s17 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s18 () Expr (getMul_1 s0))
+[GOOD] (define-fun s19 () Bool ((as is-Val Bool) s18))
+[GOOD] (define-fun s20 () Int (getVal_1 s18))
+[GOOD] (define-fun s22 () Bool (= s20 s21))
+[GOOD] (define-fun s23 () Bool (and s19 s22))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s25 () Expr (getMul_2 s0))
+[GOOD] (define-fun s26 () Bool ((as is-Val Bool) s25))
+[GOOD] (define-fun s27 () Int (getVal_1 s25))
+[GOOD] (define-fun s28 () Bool (= s21 s27))
+[GOOD] (define-fun s29 () Bool (and s26 s28))
+[GOOD] (define-fun s30 () Bool (and s17 s29))
+[GOOD] (define-fun s31 () Bool (= s7 s20))
+[GOOD] (define-fun s32 () Bool (and s19 s31))
+[GOOD] (define-fun s33 () Bool (and s17 s32))
+[GOOD] (define-fun s35 () Expr (ite s33 s34 s0))
+[GOOD] (define-fun s36 () Expr (ite s30 s18 s35))
+[GOOD] (define-fun s37 () Expr (ite s24 s25 s36))
+[GOOD] (define-fun s38 () Expr (ite s16 s4 s37))
+[GOOD] (define-fun s39 () Expr (ite s10 s11 s38))
+[GOOD] (define-fun s41 () Bool (distinct s39 s40))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s41)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested22c.gold b/SBVTestSuite/GoldFiles/adt_nested22c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested22c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested23.gold b/SBVTestSuite/GoldFiles/adt_nested23.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested23.gold
@@ -0,0 +1,253 @@
+[MEASURE] Verifying termination measures for: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): not in a multi-member cycle, skipping mutual check
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): barified = "|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|"
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2)]
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): recursive calls found = 6
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): trying sbv.dt.size.Expr arg2
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK (structural recursion)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): barified = "|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|"
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2)]
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): recursive calls found = 1
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): trying length arg1
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Bool (>= s4 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Int (seq.len s13))
+[GOOD] (define-fun s18 () Bool (not s10))
+[GOOD] (define-fun s19 () Bool (and s6 s18))
+[GOOD] (define-fun s20 () Bool (> s4 s17))
+[GOOD] (define-fun s21 () Bool (=> s19 s20))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): length arg1 -> OK
+[MEASURE] Passed (terminating): get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () (Seq (SBVTuple2 String Int)) (as seq.empty (Seq (SBVTuple2 String Int))))
+[GOOD] (define-fun s6 () Int 0)
+[GOOD] (define-fun s20 () Int 1)
+[GOOD] (define-fun s33 () Expr ((as Val Expr) 0))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr) ; tracks user variable "e"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| :: [(SString, SInteger)] -> SString -> SInteger [Recursive]
+[GOOD] (define-fun-rec |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| ((l2_s0 (Seq (SBVTuple2 String Int))) (l2_s1 String)) Int
+                                                 (let ((l2_s3 0))
+                                                 (let ((l2_s11 1))
+                                                 (let ((l2_s2 (seq.len l2_s0)))
+                                                 (let ((l2_s4 (= l2_s2 l2_s3)))
+                                                 (let ((l2_s5 (not l2_s4)))
+                                                 (let ((l2_s6 (seq.nth l2_s0 l2_s3)))
+                                                 (let ((l2_s7 (proj_1_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s8 (= l2_s1 l2_s7)))
+                                                 (let ((l2_s9 (and l2_s5 l2_s8)))
+                                                 (let ((l2_s10 (proj_2_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s12 (- l2_s2 l2_s11)))
+                                                 (let ((l2_s13 (seq.extract l2_s0 l2_s11 l2_s12)))
+                                                 (let ((l2_s14 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l2_s13 l2_s1)))
+                                                 (let ((l2_s15 (ite l2_s9 l2_s10 l2_s14)))
+                                                 (let ((l2_s16 (ite l2_s4 l2_s3 l2_s15)))
+                                                 l2_s16))))))))))))))))
+[GOOD] ; |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| :: [(SString, SInteger)] -> Expr -> SInteger [Recursive] [Refers to: |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|]
+[GOOD] (define-fun-rec |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| ((l1_s0 (Seq (SBVTuple2 String Int))) (l1_s1 Expr)) Int
+                                 (let ((l1_s2 ((as is-Val Bool) l1_s1)))
+                                 (let ((l1_s3 (getVal_1 l1_s1)))
+                                 (let ((l1_s4 ((as is-Var Bool) l1_s1)))
+                                 (let ((l1_s5 (getVar_1 l1_s1)))
+                                 (let ((l1_s6 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l1_s0 l1_s5)))
+                                 (let ((l1_s7 ((as is-Add Bool) l1_s1)))
+                                 (let ((l1_s8 (getAdd_1 l1_s1)))
+                                 (let ((l1_s9 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s8)))
+                                 (let ((l1_s10 (getAdd_2 l1_s1)))
+                                 (let ((l1_s11 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s10)))
+                                 (let ((l1_s12 (+ l1_s9 l1_s11)))
+                                 (let ((l1_s13 ((as is-Mul Bool) l1_s1)))
+                                 (let ((l1_s14 (getMul_1 l1_s1)))
+                                 (let ((l1_s15 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s14)))
+                                 (let ((l1_s16 (getMul_2 l1_s1)))
+                                 (let ((l1_s17 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s16)))
+                                 (let ((l1_s18 (* l1_s15 l1_s17)))
+                                 (let ((l1_s19 (getLet_1 l1_s1)))
+                                 (let ((l1_s20 (getLet_2 l1_s1)))
+                                 (let ((l1_s21 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s20)))
+                                 (let ((l1_s22 ((as mkSBVTuple2 (SBVTuple2 String Int)) l1_s19 l1_s21)))
+                                 (let ((l1_s23 (seq.unit l1_s22)))
+                                 (let ((l1_s24 (seq.++ l1_s23 l1_s0)))
+                                 (let ((l1_s25 (getLet_3 l1_s1)))
+                                 (let ((l1_s26 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s24 l1_s25)))
+                                 (let ((l1_s27 (ite l1_s13 l1_s18 l1_s26)))
+                                 (let ((l1_s28 (ite l1_s7 l1_s12 l1_s27)))
+                                 (let ((l1_s29 (ite l1_s4 l1_s6 l1_s28)))
+                                 (let ((l1_s30 (ite l1_s2 l1_s3 l1_s29)))
+                                 l1_s30))))))))))))))))))))))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s3 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s4 () Bool ((as is-Val Bool) s3))
+[GOOD] (define-fun s5 () Int (getVal_1 s3))
+[GOOD] (define-fun s7 () Bool (= s5 s6))
+[GOOD] (define-fun s8 () Bool (and s4 s7))
+[GOOD] (define-fun s9 () Bool (and s1 s8))
+[GOOD] (define-fun s10 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s11 () Bool ((as is-Val Bool) s10))
+[GOOD] (define-fun s12 () Int (getVal_1 s10))
+[GOOD] (define-fun s13 () Bool (= s6 s12))
+[GOOD] (define-fun s14 () Bool (and s11 s13))
+[GOOD] (define-fun s15 () Bool (and s1 s14))
+[GOOD] (define-fun s16 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s17 () Expr (getMul_1 s0))
+[GOOD] (define-fun s18 () Bool ((as is-Val Bool) s17))
+[GOOD] (define-fun s19 () Int (getVal_1 s17))
+[GOOD] (define-fun s21 () Bool (= s19 s20))
+[GOOD] (define-fun s22 () Bool (and s18 s21))
+[GOOD] (define-fun s23 () Bool (and s16 s22))
+[GOOD] (define-fun s24 () Expr (getMul_2 s0))
+[GOOD] (define-fun s25 () Bool ((as is-Val Bool) s24))
+[GOOD] (define-fun s26 () Int (getVal_1 s24))
+[GOOD] (define-fun s27 () Bool (= s20 s26))
+[GOOD] (define-fun s28 () Bool (and s25 s27))
+[GOOD] (define-fun s29 () Bool (and s16 s28))
+[GOOD] (define-fun s30 () Bool (= s6 s19))
+[GOOD] (define-fun s31 () Bool (and s18 s30))
+[GOOD] (define-fun s32 () Bool (and s16 s31))
+[GOOD] (define-fun s34 () Expr (ite s32 s33 s0))
+[GOOD] (define-fun s35 () Expr (ite s29 s17 s34))
+[GOOD] (define-fun s36 () Expr (ite s23 s24 s35))
+[GOOD] (define-fun s37 () Expr (ite s15 s3 s36))
+[GOOD] (define-fun s38 () Expr (ite s9 s10 s37))
+[GOOD] (define-fun s39 () Int (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| s2 s38))
+[GOOD] (define-fun s40 () Int (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| s2 s0))
+[GOOD] (define-fun s41 () Bool (= s39 s40))
+[GOOD] (define-fun s42 () Bool (=> s1 s41))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s42))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested24.gold b/SBVTestSuite/GoldFiles/adt_nested24.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested24.gold
@@ -0,0 +1,253 @@
+[MEASURE] Verifying termination measures for: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): not in a multi-member cycle, skipping mutual check
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): barified = "|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|"
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2)]
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): recursive calls found = 6
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): trying sbv.dt.size.Expr arg2
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK (structural recursion)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): barified = "|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|"
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2)]
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): recursive calls found = 1
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): trying length arg1
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Bool (>= s4 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Int (seq.len s13))
+[GOOD] (define-fun s18 () Bool (not s10))
+[GOOD] (define-fun s19 () Bool (and s6 s18))
+[GOOD] (define-fun s20 () Bool (> s4 s17))
+[GOOD] (define-fun s21 () Bool (=> s19 s20))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): length arg1 -> OK
+[MEASURE] Passed (terminating): get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () (Seq (SBVTuple2 String Int)) (as seq.empty (Seq (SBVTuple2 String Int))))
+[GOOD] (define-fun s7 () Int 0)
+[GOOD] (define-fun s20 () Int 1)
+[GOOD] (define-fun s33 () Expr ((as Val Expr) 0))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr) ; tracks user variable "e"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| :: [(SString, SInteger)] -> SString -> SInteger [Recursive]
+[GOOD] (define-fun-rec |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| ((l2_s0 (Seq (SBVTuple2 String Int))) (l2_s1 String)) Int
+                                                 (let ((l2_s3 0))
+                                                 (let ((l2_s11 1))
+                                                 (let ((l2_s2 (seq.len l2_s0)))
+                                                 (let ((l2_s4 (= l2_s2 l2_s3)))
+                                                 (let ((l2_s5 (not l2_s4)))
+                                                 (let ((l2_s6 (seq.nth l2_s0 l2_s3)))
+                                                 (let ((l2_s7 (proj_1_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s8 (= l2_s1 l2_s7)))
+                                                 (let ((l2_s9 (and l2_s5 l2_s8)))
+                                                 (let ((l2_s10 (proj_2_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s12 (- l2_s2 l2_s11)))
+                                                 (let ((l2_s13 (seq.extract l2_s0 l2_s11 l2_s12)))
+                                                 (let ((l2_s14 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l2_s13 l2_s1)))
+                                                 (let ((l2_s15 (ite l2_s9 l2_s10 l2_s14)))
+                                                 (let ((l2_s16 (ite l2_s4 l2_s3 l2_s15)))
+                                                 l2_s16))))))))))))))))
+[GOOD] ; |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| :: [(SString, SInteger)] -> Expr -> SInteger [Recursive] [Refers to: |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|]
+[GOOD] (define-fun-rec |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| ((l1_s0 (Seq (SBVTuple2 String Int))) (l1_s1 Expr)) Int
+                                 (let ((l1_s2 ((as is-Val Bool) l1_s1)))
+                                 (let ((l1_s3 (getVal_1 l1_s1)))
+                                 (let ((l1_s4 ((as is-Var Bool) l1_s1)))
+                                 (let ((l1_s5 (getVar_1 l1_s1)))
+                                 (let ((l1_s6 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l1_s0 l1_s5)))
+                                 (let ((l1_s7 ((as is-Add Bool) l1_s1)))
+                                 (let ((l1_s8 (getAdd_1 l1_s1)))
+                                 (let ((l1_s9 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s8)))
+                                 (let ((l1_s10 (getAdd_2 l1_s1)))
+                                 (let ((l1_s11 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s10)))
+                                 (let ((l1_s12 (+ l1_s9 l1_s11)))
+                                 (let ((l1_s13 ((as is-Mul Bool) l1_s1)))
+                                 (let ((l1_s14 (getMul_1 l1_s1)))
+                                 (let ((l1_s15 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s14)))
+                                 (let ((l1_s16 (getMul_2 l1_s1)))
+                                 (let ((l1_s17 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s16)))
+                                 (let ((l1_s18 (* l1_s15 l1_s17)))
+                                 (let ((l1_s19 (getLet_1 l1_s1)))
+                                 (let ((l1_s20 (getLet_2 l1_s1)))
+                                 (let ((l1_s21 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s20)))
+                                 (let ((l1_s22 ((as mkSBVTuple2 (SBVTuple2 String Int)) l1_s19 l1_s21)))
+                                 (let ((l1_s23 (seq.unit l1_s22)))
+                                 (let ((l1_s24 (seq.++ l1_s23 l1_s0)))
+                                 (let ((l1_s25 (getLet_3 l1_s1)))
+                                 (let ((l1_s26 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s24 l1_s25)))
+                                 (let ((l1_s27 (ite l1_s13 l1_s18 l1_s26)))
+                                 (let ((l1_s28 (ite l1_s7 l1_s12 l1_s27)))
+                                 (let ((l1_s29 (ite l1_s4 l1_s6 l1_s28)))
+                                 (let ((l1_s30 (ite l1_s2 l1_s3 l1_s29)))
+                                 l1_s30))))))))))))))))))))))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s6 () Int (getVal_1 s4))
+[GOOD] (define-fun s8 () Bool (= s6 s7))
+[GOOD] (define-fun s9 () Bool (and s5 s8))
+[GOOD] (define-fun s10 () Bool (and s3 s9))
+[GOOD] (define-fun s11 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s12 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s13 () Int (getVal_1 s11))
+[GOOD] (define-fun s14 () Bool (= s7 s13))
+[GOOD] (define-fun s15 () Bool (and s12 s14))
+[GOOD] (define-fun s16 () Bool (and s3 s15))
+[GOOD] (define-fun s17 () Expr (getMul_1 s0))
+[GOOD] (define-fun s18 () Bool ((as is-Val Bool) s17))
+[GOOD] (define-fun s19 () Int (getVal_1 s17))
+[GOOD] (define-fun s21 () Bool (= s19 s20))
+[GOOD] (define-fun s22 () Bool (and s18 s21))
+[GOOD] (define-fun s23 () Bool (and s1 s22))
+[GOOD] (define-fun s24 () Expr (getMul_2 s0))
+[GOOD] (define-fun s25 () Bool ((as is-Val Bool) s24))
+[GOOD] (define-fun s26 () Int (getVal_1 s24))
+[GOOD] (define-fun s27 () Bool (= s20 s26))
+[GOOD] (define-fun s28 () Bool (and s25 s27))
+[GOOD] (define-fun s29 () Bool (and s1 s28))
+[GOOD] (define-fun s30 () Bool (= s7 s19))
+[GOOD] (define-fun s31 () Bool (and s18 s30))
+[GOOD] (define-fun s32 () Bool (and s1 s31))
+[GOOD] (define-fun s34 () Expr (ite s32 s33 s0))
+[GOOD] (define-fun s35 () Expr (ite s29 s17 s34))
+[GOOD] (define-fun s36 () Expr (ite s23 s24 s35))
+[GOOD] (define-fun s37 () Expr (ite s16 s4 s36))
+[GOOD] (define-fun s38 () Expr (ite s10 s11 s37))
+[GOOD] (define-fun s39 () Int (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| s2 s38))
+[GOOD] (define-fun s40 () Int (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| s2 s0))
+[GOOD] (define-fun s41 () Bool (= s39 s40))
+[GOOD] (define-fun s42 () Bool (=> s1 s41))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s42))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested25.gold b/SBVTestSuite/GoldFiles/adt_nested25.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested25.gold
@@ -0,0 +1,71 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Add Expr) ((as Mul Expr) ((as Val Expr) 2) ((as Val Expr) 3)) ((as Mul Expr) ((as Val Expr) 4) ((as Val Expr) 5))))
+[GOOD] (define-fun s31 () Expr ((as Val Expr) 26))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Mul Bool) s4))
+[GOOD] (define-fun s6 () Expr (getMul_1 s4))
+[GOOD] (define-fun s7 () Bool ((as is-Val Bool) s6))
+[GOOD] (define-fun s8 () Expr (getMul_2 s4))
+[GOOD] (define-fun s9 () Bool ((as is-Val Bool) s8))
+[GOOD] (define-fun s10 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s11 () Bool ((as is-Mul Bool) s10))
+[GOOD] (define-fun s12 () Expr (getMul_1 s10))
+[GOOD] (define-fun s13 () Bool ((as is-Val Bool) s12))
+[GOOD] (define-fun s14 () Expr (getMul_2 s10))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s14))
+[GOOD] (define-fun s16 () Bool (and s13 s15))
+[GOOD] (define-fun s17 () Bool (and s11 s16))
+[GOOD] (define-fun s18 () Bool (and s9 s17))
+[GOOD] (define-fun s19 () Bool (and s7 s18))
+[GOOD] (define-fun s20 () Bool (and s5 s19))
+[GOOD] (define-fun s21 () Bool (and s3 s20))
+[GOOD] (define-fun s22 () Int (getVal_1 s6))
+[GOOD] (define-fun s23 () Int (getVal_1 s8))
+[GOOD] (define-fun s24 () Int (* s22 s23))
+[GOOD] (define-fun s25 () Int (getVal_1 s12))
+[GOOD] (define-fun s26 () Int (getVal_1 s14))
+[GOOD] (define-fun s27 () Int (* s25 s26))
+[GOOD] (define-fun s28 () Int (+ s24 s27))
+[GOOD] (define-fun s29 () Expr ((as Val Expr) s28))
+[GOOD] (define-fun s30 () Expr (ite s21 s29 s0))
+[GOOD] (define-fun s32 () Bool (distinct s30 s31))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s32)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested25c.gold b/SBVTestSuite/GoldFiles/adt_nested25c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested25c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested26.gold b/SBVTestSuite/GoldFiles/adt_nested26.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested26.gold
@@ -0,0 +1,71 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Add Expr) ((as Mul Expr) ((as Val Expr) 0) ((as Val Expr) 99)) ((as Mul Expr) ((as Val Expr) 1) ((as Val Expr) 1))))
+[GOOD] (define-fun s31 () Expr ((as Val Expr) 1))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Mul Bool) s4))
+[GOOD] (define-fun s6 () Expr (getMul_1 s4))
+[GOOD] (define-fun s7 () Bool ((as is-Val Bool) s6))
+[GOOD] (define-fun s8 () Expr (getMul_2 s4))
+[GOOD] (define-fun s9 () Bool ((as is-Val Bool) s8))
+[GOOD] (define-fun s10 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s11 () Bool ((as is-Mul Bool) s10))
+[GOOD] (define-fun s12 () Expr (getMul_1 s10))
+[GOOD] (define-fun s13 () Bool ((as is-Val Bool) s12))
+[GOOD] (define-fun s14 () Expr (getMul_2 s10))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s14))
+[GOOD] (define-fun s16 () Bool (and s13 s15))
+[GOOD] (define-fun s17 () Bool (and s11 s16))
+[GOOD] (define-fun s18 () Bool (and s9 s17))
+[GOOD] (define-fun s19 () Bool (and s7 s18))
+[GOOD] (define-fun s20 () Bool (and s5 s19))
+[GOOD] (define-fun s21 () Bool (and s3 s20))
+[GOOD] (define-fun s22 () Int (getVal_1 s6))
+[GOOD] (define-fun s23 () Int (getVal_1 s8))
+[GOOD] (define-fun s24 () Int (* s22 s23))
+[GOOD] (define-fun s25 () Int (getVal_1 s12))
+[GOOD] (define-fun s26 () Int (getVal_1 s14))
+[GOOD] (define-fun s27 () Int (* s25 s26))
+[GOOD] (define-fun s28 () Int (+ s24 s27))
+[GOOD] (define-fun s29 () Expr ((as Val Expr) s28))
+[GOOD] (define-fun s30 () Expr (ite s21 s29 s0))
+[GOOD] (define-fun s32 () Bool (distinct s30 s31))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s32)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested26c.gold b/SBVTestSuite/GoldFiles/adt_nested26c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested26c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested27.gold b/SBVTestSuite/GoldFiles/adt_nested27.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested27.gold
@@ -0,0 +1,70 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Add Expr) ((as Mul Expr) ((as Val Expr) 2) ((as Val Expr) 3)) ((as Var Expr) "x")))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Mul Bool) s4))
+[GOOD] (define-fun s6 () Expr (getMul_1 s4))
+[GOOD] (define-fun s7 () Bool ((as is-Val Bool) s6))
+[GOOD] (define-fun s8 () Expr (getMul_2 s4))
+[GOOD] (define-fun s9 () Bool ((as is-Val Bool) s8))
+[GOOD] (define-fun s10 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s11 () Bool ((as is-Mul Bool) s10))
+[GOOD] (define-fun s12 () Expr (getMul_1 s10))
+[GOOD] (define-fun s13 () Bool ((as is-Val Bool) s12))
+[GOOD] (define-fun s14 () Expr (getMul_2 s10))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s14))
+[GOOD] (define-fun s16 () Bool (and s13 s15))
+[GOOD] (define-fun s17 () Bool (and s11 s16))
+[GOOD] (define-fun s18 () Bool (and s9 s17))
+[GOOD] (define-fun s19 () Bool (and s7 s18))
+[GOOD] (define-fun s20 () Bool (and s5 s19))
+[GOOD] (define-fun s21 () Bool (and s3 s20))
+[GOOD] (define-fun s22 () Int (getVal_1 s6))
+[GOOD] (define-fun s23 () Int (getVal_1 s8))
+[GOOD] (define-fun s24 () Int (* s22 s23))
+[GOOD] (define-fun s25 () Int (getVal_1 s12))
+[GOOD] (define-fun s26 () Int (getVal_1 s14))
+[GOOD] (define-fun s27 () Int (* s25 s26))
+[GOOD] (define-fun s28 () Int (+ s24 s27))
+[GOOD] (define-fun s29 () Expr ((as Val Expr) s28))
+[GOOD] (define-fun s30 () Expr (ite s21 s29 s0))
+[GOOD] (define-fun s31 () Bool (distinct s1 s30))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s31)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested27c.gold b/SBVTestSuite/GoldFiles/adt_nested27c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested27c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested28.gold b/SBVTestSuite/GoldFiles/adt_nested28.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested28.gold
@@ -0,0 +1,70 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Mul Expr) ((as Val Expr) 2) ((as Val Expr) 3)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Mul Bool) s4))
+[GOOD] (define-fun s6 () Expr (getMul_1 s4))
+[GOOD] (define-fun s7 () Bool ((as is-Val Bool) s6))
+[GOOD] (define-fun s8 () Expr (getMul_2 s4))
+[GOOD] (define-fun s9 () Bool ((as is-Val Bool) s8))
+[GOOD] (define-fun s10 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s11 () Bool ((as is-Mul Bool) s10))
+[GOOD] (define-fun s12 () Expr (getMul_1 s10))
+[GOOD] (define-fun s13 () Bool ((as is-Val Bool) s12))
+[GOOD] (define-fun s14 () Expr (getMul_2 s10))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s14))
+[GOOD] (define-fun s16 () Bool (and s13 s15))
+[GOOD] (define-fun s17 () Bool (and s11 s16))
+[GOOD] (define-fun s18 () Bool (and s9 s17))
+[GOOD] (define-fun s19 () Bool (and s7 s18))
+[GOOD] (define-fun s20 () Bool (and s5 s19))
+[GOOD] (define-fun s21 () Bool (and s3 s20))
+[GOOD] (define-fun s22 () Int (getVal_1 s6))
+[GOOD] (define-fun s23 () Int (getVal_1 s8))
+[GOOD] (define-fun s24 () Int (* s22 s23))
+[GOOD] (define-fun s25 () Int (getVal_1 s12))
+[GOOD] (define-fun s26 () Int (getVal_1 s14))
+[GOOD] (define-fun s27 () Int (* s25 s26))
+[GOOD] (define-fun s28 () Int (+ s24 s27))
+[GOOD] (define-fun s29 () Expr ((as Val Expr) s28))
+[GOOD] (define-fun s30 () Expr (ite s21 s29 s0))
+[GOOD] (define-fun s31 () Bool (distinct s1 s30))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s31)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested28c.gold b/SBVTestSuite/GoldFiles/adt_nested28c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested28c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested29.gold b/SBVTestSuite/GoldFiles/adt_nested29.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested29.gold
@@ -0,0 +1,243 @@
+[MEASURE] Verifying termination measures for: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer), get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): not in a multi-member cycle, skipping mutual check
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): barified = "|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|"
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)|",2)]
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): recursive calls found = 6
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): trying sbv.dt.size.Expr arg2
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK (structural recursion)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer): sbv.dt.size.Expr arg2 -> OK
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)
+[MEASURE] Checking: get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): barified = "|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|"
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2)]
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): recursive calls found = 1
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): trying length arg1
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Bool (>= s4 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Int (seq.len s13))
+[GOOD] (define-fun s18 () Bool (not s10))
+[GOOD] (define-fun s19 () Bool (and s6 s18))
+[GOOD] (define-fun s20 () Bool (> s4 s17))
+[GOOD] (define-fun s21 () Bool (=> s19 s20))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): length arg1 -> OK
+[MEASURE] Passed (terminating): get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (Seq (SBVTuple2 String Int)) (as seq.empty (Seq (SBVTuple2 String Int))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr) ; tracks user variable "e"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| :: [(SString, SInteger)] -> SString -> SInteger [Recursive]
+[GOOD] (define-fun-rec |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| ((l2_s0 (Seq (SBVTuple2 String Int))) (l2_s1 String)) Int
+                                                 (let ((l2_s3 0))
+                                                 (let ((l2_s11 1))
+                                                 (let ((l2_s2 (seq.len l2_s0)))
+                                                 (let ((l2_s4 (= l2_s2 l2_s3)))
+                                                 (let ((l2_s5 (not l2_s4)))
+                                                 (let ((l2_s6 (seq.nth l2_s0 l2_s3)))
+                                                 (let ((l2_s7 (proj_1_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s8 (= l2_s1 l2_s7)))
+                                                 (let ((l2_s9 (and l2_s5 l2_s8)))
+                                                 (let ((l2_s10 (proj_2_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s12 (- l2_s2 l2_s11)))
+                                                 (let ((l2_s13 (seq.extract l2_s0 l2_s11 l2_s12)))
+                                                 (let ((l2_s14 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l2_s13 l2_s1)))
+                                                 (let ((l2_s15 (ite l2_s9 l2_s10 l2_s14)))
+                                                 (let ((l2_s16 (ite l2_s4 l2_s3 l2_s15)))
+                                                 l2_s16))))))))))))))))
+[GOOD] ; |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| :: [(SString, SInteger)] -> Expr -> SInteger [Recursive] [Refers to: |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|]
+[GOOD] (define-fun-rec |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| ((l1_s0 (Seq (SBVTuple2 String Int))) (l1_s1 Expr)) Int
+                                 (let ((l1_s2 ((as is-Val Bool) l1_s1)))
+                                 (let ((l1_s3 (getVal_1 l1_s1)))
+                                 (let ((l1_s4 ((as is-Var Bool) l1_s1)))
+                                 (let ((l1_s5 (getVar_1 l1_s1)))
+                                 (let ((l1_s6 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l1_s0 l1_s5)))
+                                 (let ((l1_s7 ((as is-Add Bool) l1_s1)))
+                                 (let ((l1_s8 (getAdd_1 l1_s1)))
+                                 (let ((l1_s9 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s8)))
+                                 (let ((l1_s10 (getAdd_2 l1_s1)))
+                                 (let ((l1_s11 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s10)))
+                                 (let ((l1_s12 (+ l1_s9 l1_s11)))
+                                 (let ((l1_s13 ((as is-Mul Bool) l1_s1)))
+                                 (let ((l1_s14 (getMul_1 l1_s1)))
+                                 (let ((l1_s15 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s14)))
+                                 (let ((l1_s16 (getMul_2 l1_s1)))
+                                 (let ((l1_s17 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s16)))
+                                 (let ((l1_s18 (* l1_s15 l1_s17)))
+                                 (let ((l1_s19 (getLet_1 l1_s1)))
+                                 (let ((l1_s20 (getLet_2 l1_s1)))
+                                 (let ((l1_s21 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s20)))
+                                 (let ((l1_s22 ((as mkSBVTuple2 (SBVTuple2 String Int)) l1_s19 l1_s21)))
+                                 (let ((l1_s23 (seq.unit l1_s22)))
+                                 (let ((l1_s24 (seq.++ l1_s23 l1_s0)))
+                                 (let ((l1_s25 (getLet_3 l1_s1)))
+                                 (let ((l1_s26 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s24 l1_s25)))
+                                 (let ((l1_s27 (ite l1_s13 l1_s18 l1_s26)))
+                                 (let ((l1_s28 (ite l1_s7 l1_s12 l1_s27)))
+                                 (let ((l1_s29 (ite l1_s4 l1_s6 l1_s28)))
+                                 (let ((l1_s30 (ite l1_s2 l1_s3 l1_s29)))
+                                 l1_s30))))))))))))))))))))))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s3 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s4 () Bool ((as is-Mul Bool) s3))
+[GOOD] (define-fun s5 () Expr (getMul_1 s3))
+[GOOD] (define-fun s6 () Bool ((as is-Val Bool) s5))
+[GOOD] (define-fun s7 () Expr (getMul_2 s3))
+[GOOD] (define-fun s8 () Bool ((as is-Val Bool) s7))
+[GOOD] (define-fun s9 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s10 () Bool ((as is-Mul Bool) s9))
+[GOOD] (define-fun s11 () Expr (getMul_1 s9))
+[GOOD] (define-fun s12 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s13 () Expr (getMul_2 s9))
+[GOOD] (define-fun s14 () Bool ((as is-Val Bool) s13))
+[GOOD] (define-fun s15 () Bool (and s12 s14))
+[GOOD] (define-fun s16 () Bool (and s10 s15))
+[GOOD] (define-fun s17 () Bool (and s8 s16))
+[GOOD] (define-fun s18 () Bool (and s6 s17))
+[GOOD] (define-fun s19 () Bool (and s4 s18))
+[GOOD] (define-fun s20 () Bool (and s2 s19))
+[GOOD] (define-fun s21 () Int (getVal_1 s5))
+[GOOD] (define-fun s22 () Int (getVal_1 s7))
+[GOOD] (define-fun s23 () Int (* s21 s22))
+[GOOD] (define-fun s24 () Int (getVal_1 s11))
+[GOOD] (define-fun s25 () Int (getVal_1 s13))
+[GOOD] (define-fun s26 () Int (* s24 s25))
+[GOOD] (define-fun s27 () Int (+ s23 s26))
+[GOOD] (define-fun s28 () Expr ((as Val Expr) s27))
+[GOOD] (define-fun s29 () Expr (ite s20 s28 s0))
+[GOOD] (define-fun s30 () Int (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| s1 s29))
+[GOOD] (define-fun s31 () Int (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| s1 s0))
+[GOOD] (define-fun s32 () Bool (= s30 s31))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s32))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested30.gold b/SBVTestSuite/GoldFiles/adt_nested30.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested30.gold
@@ -0,0 +1,108 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Add Expr) ((as Mul Expr) ((as Val Expr) 2) ((as Val Expr) 3)) ((as Mul Expr) ((as Val Expr) 4) ((as Val Expr) 5))))
+[GOOD] (define-fun s7 () Int 0)
+[GOOD] (define-fun s21 () Int 1)
+[GOOD] (define-fun s34 () Expr ((as Val Expr) 0))
+[GOOD] (define-fun s68 () Expr ((as Val Expr) 26))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s6 () Int (getVal_1 s4))
+[GOOD] (define-fun s8 () Bool (= s6 s7))
+[GOOD] (define-fun s9 () Bool (and s5 s8))
+[GOOD] (define-fun s10 () Bool (and s3 s9))
+[GOOD] (define-fun s11 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s12 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s13 () Int (getVal_1 s11))
+[GOOD] (define-fun s14 () Bool (= s7 s13))
+[GOOD] (define-fun s15 () Bool (and s12 s14))
+[GOOD] (define-fun s16 () Bool (and s3 s15))
+[GOOD] (define-fun s17 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s18 () Expr (getMul_1 s0))
+[GOOD] (define-fun s19 () Bool ((as is-Val Bool) s18))
+[GOOD] (define-fun s20 () Int (getVal_1 s18))
+[GOOD] (define-fun s22 () Bool (= s20 s21))
+[GOOD] (define-fun s23 () Bool (and s19 s22))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s25 () Expr (getMul_2 s0))
+[GOOD] (define-fun s26 () Bool ((as is-Val Bool) s25))
+[GOOD] (define-fun s27 () Int (getVal_1 s25))
+[GOOD] (define-fun s28 () Bool (= s21 s27))
+[GOOD] (define-fun s29 () Bool (and s26 s28))
+[GOOD] (define-fun s30 () Bool (and s17 s29))
+[GOOD] (define-fun s31 () Bool (= s7 s20))
+[GOOD] (define-fun s32 () Bool (and s19 s31))
+[GOOD] (define-fun s33 () Bool (and s17 s32))
+[GOOD] (define-fun s35 () Expr (ite s33 s34 s0))
+[GOOD] (define-fun s36 () Expr (ite s30 s18 s35))
+[GOOD] (define-fun s37 () Expr (ite s24 s25 s36))
+[GOOD] (define-fun s38 () Expr (ite s16 s4 s37))
+[GOOD] (define-fun s39 () Expr (ite s10 s11 s38))
+[GOOD] (define-fun s40 () Bool ((as is-Add Bool) s39))
+[GOOD] (define-fun s41 () Expr (getAdd_1 s39))
+[GOOD] (define-fun s42 () Bool ((as is-Mul Bool) s41))
+[GOOD] (define-fun s43 () Expr (getMul_1 s41))
+[GOOD] (define-fun s44 () Bool ((as is-Val Bool) s43))
+[GOOD] (define-fun s45 () Expr (getMul_2 s41))
+[GOOD] (define-fun s46 () Bool ((as is-Val Bool) s45))
+[GOOD] (define-fun s47 () Expr (getAdd_2 s39))
+[GOOD] (define-fun s48 () Bool ((as is-Mul Bool) s47))
+[GOOD] (define-fun s49 () Expr (getMul_1 s47))
+[GOOD] (define-fun s50 () Bool ((as is-Val Bool) s49))
+[GOOD] (define-fun s51 () Expr (getMul_2 s47))
+[GOOD] (define-fun s52 () Bool ((as is-Val Bool) s51))
+[GOOD] (define-fun s53 () Bool (and s50 s52))
+[GOOD] (define-fun s54 () Bool (and s48 s53))
+[GOOD] (define-fun s55 () Bool (and s46 s54))
+[GOOD] (define-fun s56 () Bool (and s44 s55))
+[GOOD] (define-fun s57 () Bool (and s42 s56))
+[GOOD] (define-fun s58 () Bool (and s40 s57))
+[GOOD] (define-fun s59 () Int (getVal_1 s43))
+[GOOD] (define-fun s60 () Int (getVal_1 s45))
+[GOOD] (define-fun s61 () Int (* s59 s60))
+[GOOD] (define-fun s62 () Int (getVal_1 s49))
+[GOOD] (define-fun s63 () Int (getVal_1 s51))
+[GOOD] (define-fun s64 () Int (* s62 s63))
+[GOOD] (define-fun s65 () Int (+ s61 s64))
+[GOOD] (define-fun s66 () Expr ((as Val Expr) s65))
+[GOOD] (define-fun s67 () Expr (ite s58 s66 s39))
+[GOOD] (define-fun s69 () Bool (distinct s67 s68))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s69)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested30c.gold b/SBVTestSuite/GoldFiles/adt_nested30c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested30c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested31.gold b/SBVTestSuite/GoldFiles/adt_nested31.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested31.gold
@@ -0,0 +1,108 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Add Expr) ((as Mul Expr) ((as Val Expr) 1) ((as Val Expr) 2)) ((as Mul Expr) ((as Val Expr) 0) ((as Val Expr) 4))))
+[GOOD] (define-fun s7 () Int 0)
+[GOOD] (define-fun s21 () Int 1)
+[GOOD] (define-fun s34 () Expr ((as Val Expr) 0))
+[GOOD] (define-fun s68 () Expr ((as Val Expr) 2))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s6 () Int (getVal_1 s4))
+[GOOD] (define-fun s8 () Bool (= s6 s7))
+[GOOD] (define-fun s9 () Bool (and s5 s8))
+[GOOD] (define-fun s10 () Bool (and s3 s9))
+[GOOD] (define-fun s11 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s12 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s13 () Int (getVal_1 s11))
+[GOOD] (define-fun s14 () Bool (= s7 s13))
+[GOOD] (define-fun s15 () Bool (and s12 s14))
+[GOOD] (define-fun s16 () Bool (and s3 s15))
+[GOOD] (define-fun s17 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s18 () Expr (getMul_1 s0))
+[GOOD] (define-fun s19 () Bool ((as is-Val Bool) s18))
+[GOOD] (define-fun s20 () Int (getVal_1 s18))
+[GOOD] (define-fun s22 () Bool (= s20 s21))
+[GOOD] (define-fun s23 () Bool (and s19 s22))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s25 () Expr (getMul_2 s0))
+[GOOD] (define-fun s26 () Bool ((as is-Val Bool) s25))
+[GOOD] (define-fun s27 () Int (getVal_1 s25))
+[GOOD] (define-fun s28 () Bool (= s21 s27))
+[GOOD] (define-fun s29 () Bool (and s26 s28))
+[GOOD] (define-fun s30 () Bool (and s17 s29))
+[GOOD] (define-fun s31 () Bool (= s7 s20))
+[GOOD] (define-fun s32 () Bool (and s19 s31))
+[GOOD] (define-fun s33 () Bool (and s17 s32))
+[GOOD] (define-fun s35 () Expr (ite s33 s34 s0))
+[GOOD] (define-fun s36 () Expr (ite s30 s18 s35))
+[GOOD] (define-fun s37 () Expr (ite s24 s25 s36))
+[GOOD] (define-fun s38 () Expr (ite s16 s4 s37))
+[GOOD] (define-fun s39 () Expr (ite s10 s11 s38))
+[GOOD] (define-fun s40 () Bool ((as is-Add Bool) s39))
+[GOOD] (define-fun s41 () Expr (getAdd_1 s39))
+[GOOD] (define-fun s42 () Bool ((as is-Mul Bool) s41))
+[GOOD] (define-fun s43 () Expr (getMul_1 s41))
+[GOOD] (define-fun s44 () Bool ((as is-Val Bool) s43))
+[GOOD] (define-fun s45 () Expr (getMul_2 s41))
+[GOOD] (define-fun s46 () Bool ((as is-Val Bool) s45))
+[GOOD] (define-fun s47 () Expr (getAdd_2 s39))
+[GOOD] (define-fun s48 () Bool ((as is-Mul Bool) s47))
+[GOOD] (define-fun s49 () Expr (getMul_1 s47))
+[GOOD] (define-fun s50 () Bool ((as is-Val Bool) s49))
+[GOOD] (define-fun s51 () Expr (getMul_2 s47))
+[GOOD] (define-fun s52 () Bool ((as is-Val Bool) s51))
+[GOOD] (define-fun s53 () Bool (and s50 s52))
+[GOOD] (define-fun s54 () Bool (and s48 s53))
+[GOOD] (define-fun s55 () Bool (and s46 s54))
+[GOOD] (define-fun s56 () Bool (and s44 s55))
+[GOOD] (define-fun s57 () Bool (and s42 s56))
+[GOOD] (define-fun s58 () Bool (and s40 s57))
+[GOOD] (define-fun s59 () Int (getVal_1 s43))
+[GOOD] (define-fun s60 () Int (getVal_1 s45))
+[GOOD] (define-fun s61 () Int (* s59 s60))
+[GOOD] (define-fun s62 () Int (getVal_1 s49))
+[GOOD] (define-fun s63 () Int (getVal_1 s51))
+[GOOD] (define-fun s64 () Int (* s62 s63))
+[GOOD] (define-fun s65 () Int (+ s61 s64))
+[GOOD] (define-fun s66 () Expr ((as Val Expr) s65))
+[GOOD] (define-fun s67 () Expr (ite s58 s66 s39))
+[GOOD] (define-fun s69 () Bool (distinct s67 s68))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s69)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested31c.gold b/SBVTestSuite/GoldFiles/adt_nested31c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested31c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested32.gold b/SBVTestSuite/GoldFiles/adt_nested32.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested32.gold
@@ -0,0 +1,108 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Mul Expr) ((as Val Expr) 1) ((as Add Expr) ((as Mul Expr) ((as Val Expr) 2) ((as Val Expr) 3)) ((as Mul Expr) ((as Val Expr) 4) ((as Val Expr) 5)))))
+[GOOD] (define-fun s7 () Int 0)
+[GOOD] (define-fun s21 () Int 1)
+[GOOD] (define-fun s34 () Expr ((as Val Expr) 0))
+[GOOD] (define-fun s68 () Expr ((as Val Expr) 26))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s6 () Int (getVal_1 s4))
+[GOOD] (define-fun s8 () Bool (= s6 s7))
+[GOOD] (define-fun s9 () Bool (and s5 s8))
+[GOOD] (define-fun s10 () Bool (and s3 s9))
+[GOOD] (define-fun s11 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s12 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s13 () Int (getVal_1 s11))
+[GOOD] (define-fun s14 () Bool (= s7 s13))
+[GOOD] (define-fun s15 () Bool (and s12 s14))
+[GOOD] (define-fun s16 () Bool (and s3 s15))
+[GOOD] (define-fun s17 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s18 () Expr (getMul_1 s0))
+[GOOD] (define-fun s19 () Bool ((as is-Val Bool) s18))
+[GOOD] (define-fun s20 () Int (getVal_1 s18))
+[GOOD] (define-fun s22 () Bool (= s20 s21))
+[GOOD] (define-fun s23 () Bool (and s19 s22))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s25 () Expr (getMul_2 s0))
+[GOOD] (define-fun s26 () Bool ((as is-Val Bool) s25))
+[GOOD] (define-fun s27 () Int (getVal_1 s25))
+[GOOD] (define-fun s28 () Bool (= s21 s27))
+[GOOD] (define-fun s29 () Bool (and s26 s28))
+[GOOD] (define-fun s30 () Bool (and s17 s29))
+[GOOD] (define-fun s31 () Bool (= s7 s20))
+[GOOD] (define-fun s32 () Bool (and s19 s31))
+[GOOD] (define-fun s33 () Bool (and s17 s32))
+[GOOD] (define-fun s35 () Expr (ite s33 s34 s0))
+[GOOD] (define-fun s36 () Expr (ite s30 s18 s35))
+[GOOD] (define-fun s37 () Expr (ite s24 s25 s36))
+[GOOD] (define-fun s38 () Expr (ite s16 s4 s37))
+[GOOD] (define-fun s39 () Expr (ite s10 s11 s38))
+[GOOD] (define-fun s40 () Bool ((as is-Add Bool) s39))
+[GOOD] (define-fun s41 () Expr (getAdd_1 s39))
+[GOOD] (define-fun s42 () Bool ((as is-Mul Bool) s41))
+[GOOD] (define-fun s43 () Expr (getMul_1 s41))
+[GOOD] (define-fun s44 () Bool ((as is-Val Bool) s43))
+[GOOD] (define-fun s45 () Expr (getMul_2 s41))
+[GOOD] (define-fun s46 () Bool ((as is-Val Bool) s45))
+[GOOD] (define-fun s47 () Expr (getAdd_2 s39))
+[GOOD] (define-fun s48 () Bool ((as is-Mul Bool) s47))
+[GOOD] (define-fun s49 () Expr (getMul_1 s47))
+[GOOD] (define-fun s50 () Bool ((as is-Val Bool) s49))
+[GOOD] (define-fun s51 () Expr (getMul_2 s47))
+[GOOD] (define-fun s52 () Bool ((as is-Val Bool) s51))
+[GOOD] (define-fun s53 () Bool (and s50 s52))
+[GOOD] (define-fun s54 () Bool (and s48 s53))
+[GOOD] (define-fun s55 () Bool (and s46 s54))
+[GOOD] (define-fun s56 () Bool (and s44 s55))
+[GOOD] (define-fun s57 () Bool (and s42 s56))
+[GOOD] (define-fun s58 () Bool (and s40 s57))
+[GOOD] (define-fun s59 () Int (getVal_1 s43))
+[GOOD] (define-fun s60 () Int (getVal_1 s45))
+[GOOD] (define-fun s61 () Int (* s59 s60))
+[GOOD] (define-fun s62 () Int (getVal_1 s49))
+[GOOD] (define-fun s63 () Int (getVal_1 s51))
+[GOOD] (define-fun s64 () Int (* s62 s63))
+[GOOD] (define-fun s65 () Int (+ s61 s64))
+[GOOD] (define-fun s66 () Expr ((as Val Expr) s65))
+[GOOD] (define-fun s67 () Expr (ite s58 s66 s39))
+[GOOD] (define-fun s69 () Bool (distinct s67 s68))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s69)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested32c.gold b/SBVTestSuite/GoldFiles/adt_nested32c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested32c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested33.gold b/SBVTestSuite/GoldFiles/adt_nested33.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested33.gold
@@ -0,0 +1,108 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Expr ((as Add Expr) ((as Val Expr) 0) ((as Add Expr) ((as Mul Expr) ((as Val Expr) 2) ((as Val Expr) 3)) ((as Mul Expr) ((as Val Expr) 4) ((as Val Expr) 5)))))
+[GOOD] (define-fun s7 () Int 0)
+[GOOD] (define-fun s21 () Int 1)
+[GOOD] (define-fun s34 () Expr ((as Val Expr) 0))
+[GOOD] (define-fun s68 () Expr ((as Val Expr) 26))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s4 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s5 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s6 () Int (getVal_1 s4))
+[GOOD] (define-fun s8 () Bool (= s6 s7))
+[GOOD] (define-fun s9 () Bool (and s5 s8))
+[GOOD] (define-fun s10 () Bool (and s3 s9))
+[GOOD] (define-fun s11 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s12 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s13 () Int (getVal_1 s11))
+[GOOD] (define-fun s14 () Bool (= s7 s13))
+[GOOD] (define-fun s15 () Bool (and s12 s14))
+[GOOD] (define-fun s16 () Bool (and s3 s15))
+[GOOD] (define-fun s17 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s18 () Expr (getMul_1 s0))
+[GOOD] (define-fun s19 () Bool ((as is-Val Bool) s18))
+[GOOD] (define-fun s20 () Int (getVal_1 s18))
+[GOOD] (define-fun s22 () Bool (= s20 s21))
+[GOOD] (define-fun s23 () Bool (and s19 s22))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s25 () Expr (getMul_2 s0))
+[GOOD] (define-fun s26 () Bool ((as is-Val Bool) s25))
+[GOOD] (define-fun s27 () Int (getVal_1 s25))
+[GOOD] (define-fun s28 () Bool (= s21 s27))
+[GOOD] (define-fun s29 () Bool (and s26 s28))
+[GOOD] (define-fun s30 () Bool (and s17 s29))
+[GOOD] (define-fun s31 () Bool (= s7 s20))
+[GOOD] (define-fun s32 () Bool (and s19 s31))
+[GOOD] (define-fun s33 () Bool (and s17 s32))
+[GOOD] (define-fun s35 () Expr (ite s33 s34 s0))
+[GOOD] (define-fun s36 () Expr (ite s30 s18 s35))
+[GOOD] (define-fun s37 () Expr (ite s24 s25 s36))
+[GOOD] (define-fun s38 () Expr (ite s16 s4 s37))
+[GOOD] (define-fun s39 () Expr (ite s10 s11 s38))
+[GOOD] (define-fun s40 () Bool ((as is-Add Bool) s39))
+[GOOD] (define-fun s41 () Expr (getAdd_1 s39))
+[GOOD] (define-fun s42 () Bool ((as is-Mul Bool) s41))
+[GOOD] (define-fun s43 () Expr (getMul_1 s41))
+[GOOD] (define-fun s44 () Bool ((as is-Val Bool) s43))
+[GOOD] (define-fun s45 () Expr (getMul_2 s41))
+[GOOD] (define-fun s46 () Bool ((as is-Val Bool) s45))
+[GOOD] (define-fun s47 () Expr (getAdd_2 s39))
+[GOOD] (define-fun s48 () Bool ((as is-Mul Bool) s47))
+[GOOD] (define-fun s49 () Expr (getMul_1 s47))
+[GOOD] (define-fun s50 () Bool ((as is-Val Bool) s49))
+[GOOD] (define-fun s51 () Expr (getMul_2 s47))
+[GOOD] (define-fun s52 () Bool ((as is-Val Bool) s51))
+[GOOD] (define-fun s53 () Bool (and s50 s52))
+[GOOD] (define-fun s54 () Bool (and s48 s53))
+[GOOD] (define-fun s55 () Bool (and s46 s54))
+[GOOD] (define-fun s56 () Bool (and s44 s55))
+[GOOD] (define-fun s57 () Bool (and s42 s56))
+[GOOD] (define-fun s58 () Bool (and s40 s57))
+[GOOD] (define-fun s59 () Int (getVal_1 s43))
+[GOOD] (define-fun s60 () Int (getVal_1 s45))
+[GOOD] (define-fun s61 () Int (* s59 s60))
+[GOOD] (define-fun s62 () Int (getVal_1 s49))
+[GOOD] (define-fun s63 () Int (getVal_1 s51))
+[GOOD] (define-fun s64 () Int (* s62 s63))
+[GOOD] (define-fun s65 () Int (+ s61 s64))
+[GOOD] (define-fun s66 () Expr ((as Val Expr) s65))
+[GOOD] (define-fun s67 () Expr (ite s58 s66 s39))
+[GOOD] (define-fun s69 () Bool (distinct s67 s68))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s69)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested33c.gold b/SBVTestSuite/GoldFiles/adt_nested33c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested33c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_nested34.gold b/SBVTestSuite/GoldFiles/adt_nested34.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_nested34.gold
@@ -0,0 +1,157 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (
+           (Val (getVal_1 Int))
+           (Var (getVar_1 String))
+           (Add (getAdd_1 Expr) (getAdd_2 Expr))
+           (Mul (getMul_1 Expr) (getMul_2 Expr))
+           (Let (getLet_1 String) (getLet_2 Expr) (getLet_3 Expr))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (Seq (SBVTuple2 String Int)) (as seq.empty (Seq (SBVTuple2 String Int))))
+[GOOD] (define-fun s6 () Int 0)
+[GOOD] (define-fun s20 () Int 1)
+[GOOD] (define-fun s33 () Expr ((as Val Expr) 0))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Expr) ; tracks user variable "e"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| :: [(SString, SInteger)] -> SString -> SInteger [Recursive]
+[GOOD] (define-fun-rec |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| ((l2_s0 (Seq (SBVTuple2 String Int))) (l2_s1 String)) Int
+                                                 (let ((l2_s3 0))
+                                                 (let ((l2_s9 1))
+                                                 (let ((l2_s2 (seq.len l2_s0)))
+                                                 (let ((l2_s4 (= l2_s2 l2_s3)))
+                                                 (let ((l2_s5 (seq.nth l2_s0 l2_s3)))
+                                                 (let ((l2_s6 (proj_1_SBVTuple2 l2_s5)))
+                                                 (let ((l2_s7 (= l2_s1 l2_s6)))
+                                                 (let ((l2_s8 (proj_2_SBVTuple2 l2_s5)))
+                                                 (let ((l2_s10 (- l2_s2 l2_s9)))
+                                                 (let ((l2_s11 (seq.extract l2_s0 l2_s9 l2_s10)))
+                                                 (let ((l2_s12 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l2_s11 l2_s1)))
+                                                 (let ((l2_s13 (ite l2_s7 l2_s8 l2_s12)))
+                                                 (let ((l2_s14 (ite l2_s4 l2_s3 l2_s13)))
+                                                 l2_s14))))))))))))))
+[GOOD] ; |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| :: [(SString, SInteger)] -> Expr -> SInteger [Recursive] [Refers to: |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|]
+[GOOD] (define-fun-rec |eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| ((l1_s0 (Seq (SBVTuple2 String Int))) (l1_s1 Expr)) Int
+                                 (let ((l1_s2 ((as is-Val Bool) l1_s1)))
+                                 (let ((l1_s3 (getVal_1 l1_s1)))
+                                 (let ((l1_s4 ((as is-Var Bool) l1_s1)))
+                                 (let ((l1_s5 (getVar_1 l1_s1)))
+                                 (let ((l1_s6 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l1_s0 l1_s5)))
+                                 (let ((l1_s7 ((as is-Add Bool) l1_s1)))
+                                 (let ((l1_s8 (getAdd_1 l1_s1)))
+                                 (let ((l1_s9 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s8)))
+                                 (let ((l1_s10 (getAdd_2 l1_s1)))
+                                 (let ((l1_s11 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s10)))
+                                 (let ((l1_s12 (+ l1_s9 l1_s11)))
+                                 (let ((l1_s13 ((as is-Mul Bool) l1_s1)))
+                                 (let ((l1_s14 (getMul_1 l1_s1)))
+                                 (let ((l1_s15 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s14)))
+                                 (let ((l1_s16 (getMul_2 l1_s1)))
+                                 (let ((l1_s17 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s16)))
+                                 (let ((l1_s18 (* l1_s15 l1_s17)))
+                                 (let ((l1_s19 (getLet_1 l1_s1)))
+                                 (let ((l1_s20 (getLet_2 l1_s1)))
+                                 (let ((l1_s21 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s0 l1_s20)))
+                                 (let ((l1_s22 ((as mkSBVTuple2 (SBVTuple2 String Int)) l1_s19 l1_s21)))
+                                 (let ((l1_s23 (seq.unit l1_s22)))
+                                 (let ((l1_s24 (seq.++ l1_s23 l1_s0)))
+                                 (let ((l1_s25 (getLet_3 l1_s1)))
+                                 (let ((l1_s26 (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| l1_s24 l1_s25)))
+                                 (let ((l1_s27 (ite l1_s13 l1_s18 l1_s26)))
+                                 (let ((l1_s28 (ite l1_s7 l1_s12 l1_s27)))
+                                 (let ((l1_s29 (ite l1_s4 l1_s6 l1_s28)))
+                                 (let ((l1_s30 (ite l1_s2 l1_s3 l1_s29)))
+                                 l1_s30))))))))))))))))))))))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s3 () Expr (getAdd_1 s0))
+[GOOD] (define-fun s4 () Bool ((as is-Val Bool) s3))
+[GOOD] (define-fun s5 () Int (getVal_1 s3))
+[GOOD] (define-fun s7 () Bool (= s5 s6))
+[GOOD] (define-fun s8 () Bool (and s4 s7))
+[GOOD] (define-fun s9 () Bool (and s2 s8))
+[GOOD] (define-fun s10 () Expr (getAdd_2 s0))
+[GOOD] (define-fun s11 () Bool ((as is-Val Bool) s10))
+[GOOD] (define-fun s12 () Int (getVal_1 s10))
+[GOOD] (define-fun s13 () Bool (= s6 s12))
+[GOOD] (define-fun s14 () Bool (and s11 s13))
+[GOOD] (define-fun s15 () Bool (and s2 s14))
+[GOOD] (define-fun s16 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s17 () Expr (getMul_1 s0))
+[GOOD] (define-fun s18 () Bool ((as is-Val Bool) s17))
+[GOOD] (define-fun s19 () Int (getVal_1 s17))
+[GOOD] (define-fun s21 () Bool (= s19 s20))
+[GOOD] (define-fun s22 () Bool (and s18 s21))
+[GOOD] (define-fun s23 () Bool (and s16 s22))
+[GOOD] (define-fun s24 () Expr (getMul_2 s0))
+[GOOD] (define-fun s25 () Bool ((as is-Val Bool) s24))
+[GOOD] (define-fun s26 () Int (getVal_1 s24))
+[GOOD] (define-fun s27 () Bool (= s20 s26))
+[GOOD] (define-fun s28 () Bool (and s25 s27))
+[GOOD] (define-fun s29 () Bool (and s16 s28))
+[GOOD] (define-fun s30 () Bool (= s6 s19))
+[GOOD] (define-fun s31 () Bool (and s18 s30))
+[GOOD] (define-fun s32 () Bool (and s16 s31))
+[GOOD] (define-fun s34 () Expr (ite s32 s33 s0))
+[GOOD] (define-fun s35 () Expr (ite s29 s17 s34))
+[GOOD] (define-fun s36 () Expr (ite s23 s24 s35))
+[GOOD] (define-fun s37 () Expr (ite s15 s3 s36))
+[GOOD] (define-fun s38 () Expr (ite s9 s10 s37))
+[GOOD] (define-fun s39 () Bool ((as is-Add Bool) s38))
+[GOOD] (define-fun s40 () Expr (getAdd_1 s38))
+[GOOD] (define-fun s41 () Bool ((as is-Mul Bool) s40))
+[GOOD] (define-fun s42 () Expr (getMul_1 s40))
+[GOOD] (define-fun s43 () Bool ((as is-Val Bool) s42))
+[GOOD] (define-fun s44 () Expr (getMul_2 s40))
+[GOOD] (define-fun s45 () Bool ((as is-Val Bool) s44))
+[GOOD] (define-fun s46 () Expr (getAdd_2 s38))
+[GOOD] (define-fun s47 () Bool ((as is-Mul Bool) s46))
+[GOOD] (define-fun s48 () Expr (getMul_1 s46))
+[GOOD] (define-fun s49 () Bool ((as is-Val Bool) s48))
+[GOOD] (define-fun s50 () Expr (getMul_2 s46))
+[GOOD] (define-fun s51 () Bool ((as is-Val Bool) s50))
+[GOOD] (define-fun s52 () Bool (and s49 s51))
+[GOOD] (define-fun s53 () Bool (and s47 s52))
+[GOOD] (define-fun s54 () Bool (and s45 s53))
+[GOOD] (define-fun s55 () Bool (and s43 s54))
+[GOOD] (define-fun s56 () Bool (and s41 s55))
+[GOOD] (define-fun s57 () Bool (and s39 s56))
+[GOOD] (define-fun s58 () Int (getVal_1 s42))
+[GOOD] (define-fun s59 () Int (getVal_1 s44))
+[GOOD] (define-fun s60 () Int (* s58 s59))
+[GOOD] (define-fun s61 () Int (getVal_1 s48))
+[GOOD] (define-fun s62 () Int (getVal_1 s50))
+[GOOD] (define-fun s63 () Int (* s61 s62))
+[GOOD] (define-fun s64 () Int (+ s60 s63))
+[GOOD] (define-fun s65 () Expr ((as Val Expr) s64))
+[GOOD] (define-fun s66 () Expr (ite s57 s65 s38))
+[GOOD] (define-fun s67 () Int (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| s1 s66))
+[GOOD] (define-fun s68 () Int (|eval @(SBV [([Char],Integer)] -> SBV Expr -> SBV Integer)| s1 s0))
+[GOOD] (define-fun s69 () Bool (= s67 s68))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s69))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pchk01.gold b/SBVTestSuite/GoldFiles/adt_pchk01.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pchk01.gold
@@ -0,0 +1,40 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: A
+[GOOD] (declare-datatype A (
+           (A (getA_1 Int))
+           (B (getB_1 (_ BitVec 8)))
+           (C (getC_1 A) (getC_2 A))
+       ))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () A ((as A A) 13))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () A) ; tracks user variable "res"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (A 13)))
+Result: A 13
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr00.gold b/SBVTestSuite/GoldFiles/adt_pexpr00.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr00.gold
@@ -0,0 +1,219 @@
+[MEASURE] Verifying termination measures for: eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer), eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer), get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): not in a multi-member cycle, skipping mutual check
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): barified = "|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|"
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2)]
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): recursive calls found = 6
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): trying sbv.dt.size.Expr arg2
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): sbv.dt.size.Expr arg2 -> OK (structural recursion)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): sbv.dt.size.Expr arg2 -> OK
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)
+[MEASURE] Checking: get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): barified = "|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|"
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2)]
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): recursive calls found = 1
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): trying length arg1
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Bool (>= s4 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Int (seq.len s13))
+[GOOD] (define-fun s18 () Bool (not s10))
+[GOOD] (define-fun s19 () Bool (and s6 s18))
+[GOOD] (define-fun s20 () Bool (> s4 s17))
+[GOOD] (define-fun s21 () Bool (=> s19 s20))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): length arg1 -> OK
+[MEASURE] Passed (terminating): get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (Expr String Int) ((as Val (Expr String Int)) 3))
+[GOOD] (define-fun s3 () (Seq (SBVTuple2 String Int)) (as seq.empty (Seq (SBVTuple2 String Int))))
+[GOOD] (define-fun s5 () Int 3)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int))
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| :: [(SString, SInteger)] -> SString -> SInteger [Recursive]
+[GOOD] (define-fun-rec |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| ((l2_s0 (Seq (SBVTuple2 String Int))) (l2_s1 String)) Int
+                                                 (let ((l2_s3 0))
+                                                 (let ((l2_s11 1))
+                                                 (let ((l2_s2 (seq.len l2_s0)))
+                                                 (let ((l2_s4 (= l2_s2 l2_s3)))
+                                                 (let ((l2_s5 (not l2_s4)))
+                                                 (let ((l2_s6 (seq.nth l2_s0 l2_s3)))
+                                                 (let ((l2_s7 (proj_1_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s8 (= l2_s1 l2_s7)))
+                                                 (let ((l2_s9 (and l2_s5 l2_s8)))
+                                                 (let ((l2_s10 (proj_2_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s12 (- l2_s2 l2_s11)))
+                                                 (let ((l2_s13 (seq.extract l2_s0 l2_s11 l2_s12)))
+                                                 (let ((l2_s14 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l2_s13 l2_s1)))
+                                                 (let ((l2_s15 (ite l2_s9 l2_s10 l2_s14)))
+                                                 (let ((l2_s16 (ite l2_s4 l2_s3 l2_s15)))
+                                                 l2_s16))))))))))))))))
+[GOOD] ; |eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| :: [(SString, SInteger)] -> Expr String Integer -> SInteger [Recursive] [Refers to: |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|]
+[GOOD] (define-fun-rec |eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| ((l1_s0 (Seq (SBVTuple2 String Int))) (l1_s1 (Expr String Int))) Int
+                                 (let ((l1_s2 ((as is-Val Bool) l1_s1)))
+                                 (let ((l1_s3 (getVal_1 l1_s1)))
+                                 (let ((l1_s4 ((as is-Var Bool) l1_s1)))
+                                 (let ((l1_s5 (getVar_1 l1_s1)))
+                                 (let ((l1_s6 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l1_s0 l1_s5)))
+                                 (let ((l1_s7 ((as is-Add Bool) l1_s1)))
+                                 (let ((l1_s8 (getAdd_1 l1_s1)))
+                                 (let ((l1_s9 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s0 l1_s8)))
+                                 (let ((l1_s10 (getAdd_2 l1_s1)))
+                                 (let ((l1_s11 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s0 l1_s10)))
+                                 (let ((l1_s12 (+ l1_s9 l1_s11)))
+                                 (let ((l1_s13 ((as is-Mul Bool) l1_s1)))
+                                 (let ((l1_s14 (getMul_1 l1_s1)))
+                                 (let ((l1_s15 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s0 l1_s14)))
+                                 (let ((l1_s16 (getMul_2 l1_s1)))
+                                 (let ((l1_s17 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s0 l1_s16)))
+                                 (let ((l1_s18 (* l1_s15 l1_s17)))
+                                 (let ((l1_s19 (getLet_1 l1_s1)))
+                                 (let ((l1_s20 (getLet_2 l1_s1)))
+                                 (let ((l1_s21 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s0 l1_s20)))
+                                 (let ((l1_s22 ((as mkSBVTuple2 (SBVTuple2 String Int)) l1_s19 l1_s21)))
+                                 (let ((l1_s23 (seq.unit l1_s22)))
+                                 (let ((l1_s24 (seq.++ l1_s23 l1_s0)))
+                                 (let ((l1_s25 (getLet_3 l1_s1)))
+                                 (let ((l1_s26 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s24 l1_s25)))
+                                 (let ((l1_s27 (ite l1_s13 l1_s18 l1_s26)))
+                                 (let ((l1_s28 (ite l1_s7 l1_s12 l1_s27)))
+                                 (let ((l1_s29 (ite l1_s4 l1_s6 l1_s28)))
+                                 (let ((l1_s30 (ite l1_s2 l1_s3 l1_s29)))
+                                 l1_s30))))))))))))))))))))))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s4 () Int (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| s3 s0))
+[GOOD] (define-fun s6 () Bool (distinct s4 s5))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s6)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr00c.gold b/SBVTestSuite/GoldFiles/adt_pexpr00c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr00c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr01.gold b/SBVTestSuite/GoldFiles/adt_pexpr01.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr01.gold
@@ -0,0 +1,219 @@
+[MEASURE] Verifying termination measures for: eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer), eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer), get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): not in a multi-member cycle, skipping mutual check
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): barified = "|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|"
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2)]
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): recursive calls found = 6
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): trying sbv.dt.size.Expr arg2
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): sbv.dt.size.Expr arg2 -> OK (structural recursion)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): sbv.dt.size.Expr arg2 -> OK
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)
+[MEASURE] Checking: get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): barified = "|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|"
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2)]
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): recursive calls found = 1
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): trying length arg1
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Bool (>= s4 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Int (seq.len s13))
+[GOOD] (define-fun s18 () Bool (not s10))
+[GOOD] (define-fun s19 () Bool (and s6 s18))
+[GOOD] (define-fun s20 () Bool (> s4 s17))
+[GOOD] (define-fun s21 () Bool (=> s19 s20))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): length arg1 -> OK
+[MEASURE] Passed (terminating): get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (Expr String Int) ((as Add (Expr String Int)) ((as Val (Expr String Int)) 3) ((as Val (Expr String Int)) 4)))
+[GOOD] (define-fun s3 () (Seq (SBVTuple2 String Int)) (as seq.empty (Seq (SBVTuple2 String Int))))
+[GOOD] (define-fun s5 () Int 7)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int))
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| :: [(SString, SInteger)] -> SString -> SInteger [Recursive]
+[GOOD] (define-fun-rec |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| ((l2_s0 (Seq (SBVTuple2 String Int))) (l2_s1 String)) Int
+                                                 (let ((l2_s3 0))
+                                                 (let ((l2_s11 1))
+                                                 (let ((l2_s2 (seq.len l2_s0)))
+                                                 (let ((l2_s4 (= l2_s2 l2_s3)))
+                                                 (let ((l2_s5 (not l2_s4)))
+                                                 (let ((l2_s6 (seq.nth l2_s0 l2_s3)))
+                                                 (let ((l2_s7 (proj_1_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s8 (= l2_s1 l2_s7)))
+                                                 (let ((l2_s9 (and l2_s5 l2_s8)))
+                                                 (let ((l2_s10 (proj_2_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s12 (- l2_s2 l2_s11)))
+                                                 (let ((l2_s13 (seq.extract l2_s0 l2_s11 l2_s12)))
+                                                 (let ((l2_s14 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l2_s13 l2_s1)))
+                                                 (let ((l2_s15 (ite l2_s9 l2_s10 l2_s14)))
+                                                 (let ((l2_s16 (ite l2_s4 l2_s3 l2_s15)))
+                                                 l2_s16))))))))))))))))
+[GOOD] ; |eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| :: [(SString, SInteger)] -> Expr String Integer -> SInteger [Recursive] [Refers to: |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|]
+[GOOD] (define-fun-rec |eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| ((l1_s0 (Seq (SBVTuple2 String Int))) (l1_s1 (Expr String Int))) Int
+                                 (let ((l1_s2 ((as is-Val Bool) l1_s1)))
+                                 (let ((l1_s3 (getVal_1 l1_s1)))
+                                 (let ((l1_s4 ((as is-Var Bool) l1_s1)))
+                                 (let ((l1_s5 (getVar_1 l1_s1)))
+                                 (let ((l1_s6 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l1_s0 l1_s5)))
+                                 (let ((l1_s7 ((as is-Add Bool) l1_s1)))
+                                 (let ((l1_s8 (getAdd_1 l1_s1)))
+                                 (let ((l1_s9 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s0 l1_s8)))
+                                 (let ((l1_s10 (getAdd_2 l1_s1)))
+                                 (let ((l1_s11 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s0 l1_s10)))
+                                 (let ((l1_s12 (+ l1_s9 l1_s11)))
+                                 (let ((l1_s13 ((as is-Mul Bool) l1_s1)))
+                                 (let ((l1_s14 (getMul_1 l1_s1)))
+                                 (let ((l1_s15 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s0 l1_s14)))
+                                 (let ((l1_s16 (getMul_2 l1_s1)))
+                                 (let ((l1_s17 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s0 l1_s16)))
+                                 (let ((l1_s18 (* l1_s15 l1_s17)))
+                                 (let ((l1_s19 (getLet_1 l1_s1)))
+                                 (let ((l1_s20 (getLet_2 l1_s1)))
+                                 (let ((l1_s21 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s0 l1_s20)))
+                                 (let ((l1_s22 ((as mkSBVTuple2 (SBVTuple2 String Int)) l1_s19 l1_s21)))
+                                 (let ((l1_s23 (seq.unit l1_s22)))
+                                 (let ((l1_s24 (seq.++ l1_s23 l1_s0)))
+                                 (let ((l1_s25 (getLet_3 l1_s1)))
+                                 (let ((l1_s26 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s24 l1_s25)))
+                                 (let ((l1_s27 (ite l1_s13 l1_s18 l1_s26)))
+                                 (let ((l1_s28 (ite l1_s7 l1_s12 l1_s27)))
+                                 (let ((l1_s29 (ite l1_s4 l1_s6 l1_s28)))
+                                 (let ((l1_s30 (ite l1_s2 l1_s3 l1_s29)))
+                                 l1_s30))))))))))))))))))))))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s4 () Int (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| s3 s0))
+[GOOD] (define-fun s6 () Bool (distinct s4 s5))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s6)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr01c.gold b/SBVTestSuite/GoldFiles/adt_pexpr01c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr01c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr02.gold b/SBVTestSuite/GoldFiles/adt_pexpr02.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr02.gold
@@ -0,0 +1,219 @@
+[MEASURE] Verifying termination measures for: eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer), eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer), get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): not in a multi-member cycle, skipping mutual check
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): barified = "|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|"
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2)]
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): recursive calls found = 6
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): trying sbv.dt.size.Expr arg2
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): sbv.dt.size.Expr arg2 -> OK (structural recursion)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): sbv.dt.size.Expr arg2 -> OK
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)
+[MEASURE] Checking: get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): barified = "|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|"
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2)]
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): recursive calls found = 1
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): trying length arg1
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Bool (>= s4 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Int (seq.len s13))
+[GOOD] (define-fun s18 () Bool (not s10))
+[GOOD] (define-fun s19 () Bool (and s6 s18))
+[GOOD] (define-fun s20 () Bool (> s4 s17))
+[GOOD] (define-fun s21 () Bool (=> s19 s20))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): length arg1 -> OK
+[MEASURE] Passed (terminating): get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (Expr String Int) ((as Mul (Expr String Int)) ((as Val (Expr String Int)) 3) ((as Add (Expr String Int)) ((as Val (Expr String Int)) 3) ((as Val (Expr String Int)) 4))))
+[GOOD] (define-fun s3 () (Seq (SBVTuple2 String Int)) (as seq.empty (Seq (SBVTuple2 String Int))))
+[GOOD] (define-fun s5 () Int 21)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int))
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| :: [(SString, SInteger)] -> SString -> SInteger [Recursive]
+[GOOD] (define-fun-rec |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| ((l2_s0 (Seq (SBVTuple2 String Int))) (l2_s1 String)) Int
+                                                 (let ((l2_s3 0))
+                                                 (let ((l2_s11 1))
+                                                 (let ((l2_s2 (seq.len l2_s0)))
+                                                 (let ((l2_s4 (= l2_s2 l2_s3)))
+                                                 (let ((l2_s5 (not l2_s4)))
+                                                 (let ((l2_s6 (seq.nth l2_s0 l2_s3)))
+                                                 (let ((l2_s7 (proj_1_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s8 (= l2_s1 l2_s7)))
+                                                 (let ((l2_s9 (and l2_s5 l2_s8)))
+                                                 (let ((l2_s10 (proj_2_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s12 (- l2_s2 l2_s11)))
+                                                 (let ((l2_s13 (seq.extract l2_s0 l2_s11 l2_s12)))
+                                                 (let ((l2_s14 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l2_s13 l2_s1)))
+                                                 (let ((l2_s15 (ite l2_s9 l2_s10 l2_s14)))
+                                                 (let ((l2_s16 (ite l2_s4 l2_s3 l2_s15)))
+                                                 l2_s16))))))))))))))))
+[GOOD] ; |eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| :: [(SString, SInteger)] -> Expr String Integer -> SInteger [Recursive] [Refers to: |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|]
+[GOOD] (define-fun-rec |eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| ((l1_s0 (Seq (SBVTuple2 String Int))) (l1_s1 (Expr String Int))) Int
+                                 (let ((l1_s2 ((as is-Val Bool) l1_s1)))
+                                 (let ((l1_s3 (getVal_1 l1_s1)))
+                                 (let ((l1_s4 ((as is-Var Bool) l1_s1)))
+                                 (let ((l1_s5 (getVar_1 l1_s1)))
+                                 (let ((l1_s6 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l1_s0 l1_s5)))
+                                 (let ((l1_s7 ((as is-Add Bool) l1_s1)))
+                                 (let ((l1_s8 (getAdd_1 l1_s1)))
+                                 (let ((l1_s9 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s0 l1_s8)))
+                                 (let ((l1_s10 (getAdd_2 l1_s1)))
+                                 (let ((l1_s11 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s0 l1_s10)))
+                                 (let ((l1_s12 (+ l1_s9 l1_s11)))
+                                 (let ((l1_s13 ((as is-Mul Bool) l1_s1)))
+                                 (let ((l1_s14 (getMul_1 l1_s1)))
+                                 (let ((l1_s15 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s0 l1_s14)))
+                                 (let ((l1_s16 (getMul_2 l1_s1)))
+                                 (let ((l1_s17 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s0 l1_s16)))
+                                 (let ((l1_s18 (* l1_s15 l1_s17)))
+                                 (let ((l1_s19 (getLet_1 l1_s1)))
+                                 (let ((l1_s20 (getLet_2 l1_s1)))
+                                 (let ((l1_s21 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s0 l1_s20)))
+                                 (let ((l1_s22 ((as mkSBVTuple2 (SBVTuple2 String Int)) l1_s19 l1_s21)))
+                                 (let ((l1_s23 (seq.unit l1_s22)))
+                                 (let ((l1_s24 (seq.++ l1_s23 l1_s0)))
+                                 (let ((l1_s25 (getLet_3 l1_s1)))
+                                 (let ((l1_s26 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s24 l1_s25)))
+                                 (let ((l1_s27 (ite l1_s13 l1_s18 l1_s26)))
+                                 (let ((l1_s28 (ite l1_s7 l1_s12 l1_s27)))
+                                 (let ((l1_s29 (ite l1_s4 l1_s6 l1_s28)))
+                                 (let ((l1_s30 (ite l1_s2 l1_s3 l1_s29)))
+                                 l1_s30))))))))))))))))))))))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s4 () Int (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| s3 s0))
+[GOOD] (define-fun s6 () Bool (distinct s4 s5))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s6)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr02c.gold b/SBVTestSuite/GoldFiles/adt_pexpr02c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr02c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr03.gold b/SBVTestSuite/GoldFiles/adt_pexpr03.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr03.gold
@@ -0,0 +1,219 @@
+[MEASURE] Verifying termination measures for: eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer), eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer), get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): not in a multi-member cycle, skipping mutual check
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): barified = "|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|"
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2)]
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): recursive calls found = 6
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): trying sbv.dt.size.Expr arg2
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): sbv.dt.size.Expr arg2 -> OK (structural recursion)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): sbv.dt.size.Expr arg2 -> OK
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)
+[MEASURE] Checking: get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): barified = "|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|"
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2)]
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): recursive calls found = 1
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): trying length arg1
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Bool (>= s4 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Int (seq.len s13))
+[GOOD] (define-fun s18 () Bool (not s10))
+[GOOD] (define-fun s19 () Bool (and s6 s18))
+[GOOD] (define-fun s20 () Bool (> s4 s17))
+[GOOD] (define-fun s21 () Bool (=> s19 s20))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): length arg1 -> OK
+[MEASURE] Passed (terminating): get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (Expr String Int) ((as Let (Expr String Int)) "a" ((as Mul (Expr String Int)) ((as Val (Expr String Int)) 3) ((as Add (Expr String Int)) ((as Val (Expr String Int)) 3) ((as Val (Expr String Int)) 4))) ((as Add (Expr String Int)) ((as Var (Expr String Int)) "a") ((as Add (Expr String Int)) ((as Val (Expr String Int)) 3) ((as Val (Expr String Int)) 4)))))
+[GOOD] (define-fun s3 () (Seq (SBVTuple2 String Int)) (as seq.empty (Seq (SBVTuple2 String Int))))
+[GOOD] (define-fun s5 () Int 28)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int))
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| :: [(SString, SInteger)] -> SString -> SInteger [Recursive]
+[GOOD] (define-fun-rec |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| ((l2_s0 (Seq (SBVTuple2 String Int))) (l2_s1 String)) Int
+                                                 (let ((l2_s3 0))
+                                                 (let ((l2_s11 1))
+                                                 (let ((l2_s2 (seq.len l2_s0)))
+                                                 (let ((l2_s4 (= l2_s2 l2_s3)))
+                                                 (let ((l2_s5 (not l2_s4)))
+                                                 (let ((l2_s6 (seq.nth l2_s0 l2_s3)))
+                                                 (let ((l2_s7 (proj_1_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s8 (= l2_s1 l2_s7)))
+                                                 (let ((l2_s9 (and l2_s5 l2_s8)))
+                                                 (let ((l2_s10 (proj_2_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s12 (- l2_s2 l2_s11)))
+                                                 (let ((l2_s13 (seq.extract l2_s0 l2_s11 l2_s12)))
+                                                 (let ((l2_s14 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l2_s13 l2_s1)))
+                                                 (let ((l2_s15 (ite l2_s9 l2_s10 l2_s14)))
+                                                 (let ((l2_s16 (ite l2_s4 l2_s3 l2_s15)))
+                                                 l2_s16))))))))))))))))
+[GOOD] ; |eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| :: [(SString, SInteger)] -> Expr String Integer -> SInteger [Recursive] [Refers to: |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|]
+[GOOD] (define-fun-rec |eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| ((l1_s0 (Seq (SBVTuple2 String Int))) (l1_s1 (Expr String Int))) Int
+                                 (let ((l1_s2 ((as is-Val Bool) l1_s1)))
+                                 (let ((l1_s3 (getVal_1 l1_s1)))
+                                 (let ((l1_s4 ((as is-Var Bool) l1_s1)))
+                                 (let ((l1_s5 (getVar_1 l1_s1)))
+                                 (let ((l1_s6 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l1_s0 l1_s5)))
+                                 (let ((l1_s7 ((as is-Add Bool) l1_s1)))
+                                 (let ((l1_s8 (getAdd_1 l1_s1)))
+                                 (let ((l1_s9 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s0 l1_s8)))
+                                 (let ((l1_s10 (getAdd_2 l1_s1)))
+                                 (let ((l1_s11 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s0 l1_s10)))
+                                 (let ((l1_s12 (+ l1_s9 l1_s11)))
+                                 (let ((l1_s13 ((as is-Mul Bool) l1_s1)))
+                                 (let ((l1_s14 (getMul_1 l1_s1)))
+                                 (let ((l1_s15 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s0 l1_s14)))
+                                 (let ((l1_s16 (getMul_2 l1_s1)))
+                                 (let ((l1_s17 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s0 l1_s16)))
+                                 (let ((l1_s18 (* l1_s15 l1_s17)))
+                                 (let ((l1_s19 (getLet_1 l1_s1)))
+                                 (let ((l1_s20 (getLet_2 l1_s1)))
+                                 (let ((l1_s21 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s0 l1_s20)))
+                                 (let ((l1_s22 ((as mkSBVTuple2 (SBVTuple2 String Int)) l1_s19 l1_s21)))
+                                 (let ((l1_s23 (seq.unit l1_s22)))
+                                 (let ((l1_s24 (seq.++ l1_s23 l1_s0)))
+                                 (let ((l1_s25 (getLet_3 l1_s1)))
+                                 (let ((l1_s26 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s24 l1_s25)))
+                                 (let ((l1_s27 (ite l1_s13 l1_s18 l1_s26)))
+                                 (let ((l1_s28 (ite l1_s7 l1_s12 l1_s27)))
+                                 (let ((l1_s29 (ite l1_s4 l1_s6 l1_s28)))
+                                 (let ((l1_s30 (ite l1_s2 l1_s3 l1_s29)))
+                                 l1_s30))))))))))))))))))))))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s4 () Int (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| s3 s0))
+[GOOD] (define-fun s6 () Bool (distinct s4 s5))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s6)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr03c.gold b/SBVTestSuite/GoldFiles/adt_pexpr03c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr03c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr04.gold b/SBVTestSuite/GoldFiles/adt_pexpr04.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr04.gold
@@ -0,0 +1,30 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 63)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "res"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 63))
+Result: 63
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr05.gold b/SBVTestSuite/GoldFiles/adt_pexpr05.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr05.gold
@@ -0,0 +1,30 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 3969)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "res"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3969))
+Result: 3969
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr06.gold b/SBVTestSuite/GoldFiles/adt_pexpr06.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr06.gold
@@ -0,0 +1,75 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (Expr String Int) ((as Var (Expr String Int)) "a"))
+[GOOD] (define-fun s5 () String "a")
+[GOOD] (define-fun s8 () Int 0)
+[GOOD] (define-fun s9 () String "b")
+[GOOD] (define-fun s11 () String "c")
+[GOOD] (define-fun s15 () Int 1)
+[GOOD] (define-fun s16 () Int 2)
+[GOOD] (define-fun s19 () Int 10)
+[GOOD] (define-fun s22 () Int 3)
+[GOOD] (define-fun s25 () Int 4)
+[GOOD] (define-fun s28 () Int 5)
+[GOOD] (define-fun s29 () Int 6)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int))
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s4 () String (getVar_1 s0))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool (and s3 s6))
+[GOOD] (define-fun s10 () Bool (= s4 s9))
+[GOOD] (define-fun s12 () Bool (= s4 s11))
+[GOOD] (define-fun s13 () Bool (or s10 s12))
+[GOOD] (define-fun s14 () Bool (and s3 s13))
+[GOOD] (define-fun s17 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s18 () Int (getVal_1 s0))
+[GOOD] (define-fun s20 () Bool (< s18 s19))
+[GOOD] (define-fun s21 () Bool (and s17 s20))
+[GOOD] (define-fun s23 () Bool (= s18 s19))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s26 () Bool (> s18 s19))
+[GOOD] (define-fun s27 () Bool (and s17 s26))
+[GOOD] (define-fun s30 () Int (ite s27 s28 s29))
+[GOOD] (define-fun s31 () Int (ite s24 s25 s30))
+[GOOD] (define-fun s32 () Int (ite s21 s22 s31))
+[GOOD] (define-fun s33 () Int (ite s3 s16 s32))
+[GOOD] (define-fun s34 () Int (ite s14 s15 s33))
+[GOOD] (define-fun s35 () Int (ite s7 s8 s34))
+[GOOD] (define-fun s36 () Bool (distinct s8 s35))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s36)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr06c.gold b/SBVTestSuite/GoldFiles/adt_pexpr06c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr06c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr07.gold b/SBVTestSuite/GoldFiles/adt_pexpr07.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr07.gold
@@ -0,0 +1,75 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (Expr String Int) ((as Var (Expr String Int)) "b"))
+[GOOD] (define-fun s5 () String "a")
+[GOOD] (define-fun s8 () Int 0)
+[GOOD] (define-fun s9 () String "b")
+[GOOD] (define-fun s11 () String "c")
+[GOOD] (define-fun s15 () Int 1)
+[GOOD] (define-fun s16 () Int 2)
+[GOOD] (define-fun s19 () Int 10)
+[GOOD] (define-fun s22 () Int 3)
+[GOOD] (define-fun s25 () Int 4)
+[GOOD] (define-fun s28 () Int 5)
+[GOOD] (define-fun s29 () Int 6)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int))
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s4 () String (getVar_1 s0))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool (and s3 s6))
+[GOOD] (define-fun s10 () Bool (= s4 s9))
+[GOOD] (define-fun s12 () Bool (= s4 s11))
+[GOOD] (define-fun s13 () Bool (or s10 s12))
+[GOOD] (define-fun s14 () Bool (and s3 s13))
+[GOOD] (define-fun s17 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s18 () Int (getVal_1 s0))
+[GOOD] (define-fun s20 () Bool (< s18 s19))
+[GOOD] (define-fun s21 () Bool (and s17 s20))
+[GOOD] (define-fun s23 () Bool (= s18 s19))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s26 () Bool (> s18 s19))
+[GOOD] (define-fun s27 () Bool (and s17 s26))
+[GOOD] (define-fun s30 () Int (ite s27 s28 s29))
+[GOOD] (define-fun s31 () Int (ite s24 s25 s30))
+[GOOD] (define-fun s32 () Int (ite s21 s22 s31))
+[GOOD] (define-fun s33 () Int (ite s3 s16 s32))
+[GOOD] (define-fun s34 () Int (ite s14 s15 s33))
+[GOOD] (define-fun s35 () Int (ite s7 s8 s34))
+[GOOD] (define-fun s36 () Bool (distinct s15 s35))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s36)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr07c.gold b/SBVTestSuite/GoldFiles/adt_pexpr07c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr07c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr08.gold b/SBVTestSuite/GoldFiles/adt_pexpr08.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr08.gold
@@ -0,0 +1,75 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (Expr String Int) ((as Var (Expr String Int)) "c"))
+[GOOD] (define-fun s5 () String "a")
+[GOOD] (define-fun s8 () Int 0)
+[GOOD] (define-fun s9 () String "b")
+[GOOD] (define-fun s11 () String "c")
+[GOOD] (define-fun s15 () Int 1)
+[GOOD] (define-fun s16 () Int 2)
+[GOOD] (define-fun s19 () Int 10)
+[GOOD] (define-fun s22 () Int 3)
+[GOOD] (define-fun s25 () Int 4)
+[GOOD] (define-fun s28 () Int 5)
+[GOOD] (define-fun s29 () Int 6)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int))
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s4 () String (getVar_1 s0))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool (and s3 s6))
+[GOOD] (define-fun s10 () Bool (= s4 s9))
+[GOOD] (define-fun s12 () Bool (= s4 s11))
+[GOOD] (define-fun s13 () Bool (or s10 s12))
+[GOOD] (define-fun s14 () Bool (and s3 s13))
+[GOOD] (define-fun s17 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s18 () Int (getVal_1 s0))
+[GOOD] (define-fun s20 () Bool (< s18 s19))
+[GOOD] (define-fun s21 () Bool (and s17 s20))
+[GOOD] (define-fun s23 () Bool (= s18 s19))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s26 () Bool (> s18 s19))
+[GOOD] (define-fun s27 () Bool (and s17 s26))
+[GOOD] (define-fun s30 () Int (ite s27 s28 s29))
+[GOOD] (define-fun s31 () Int (ite s24 s25 s30))
+[GOOD] (define-fun s32 () Int (ite s21 s22 s31))
+[GOOD] (define-fun s33 () Int (ite s3 s16 s32))
+[GOOD] (define-fun s34 () Int (ite s14 s15 s33))
+[GOOD] (define-fun s35 () Int (ite s7 s8 s34))
+[GOOD] (define-fun s36 () Bool (distinct s15 s35))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s36)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr08c.gold b/SBVTestSuite/GoldFiles/adt_pexpr08c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr08c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr09.gold b/SBVTestSuite/GoldFiles/adt_pexpr09.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr09.gold
@@ -0,0 +1,75 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (Expr String Int) ((as Var (Expr String Int)) "d"))
+[GOOD] (define-fun s5 () String "a")
+[GOOD] (define-fun s8 () Int 0)
+[GOOD] (define-fun s9 () String "b")
+[GOOD] (define-fun s11 () String "c")
+[GOOD] (define-fun s15 () Int 1)
+[GOOD] (define-fun s16 () Int 2)
+[GOOD] (define-fun s19 () Int 10)
+[GOOD] (define-fun s22 () Int 3)
+[GOOD] (define-fun s25 () Int 4)
+[GOOD] (define-fun s28 () Int 5)
+[GOOD] (define-fun s29 () Int 6)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int))
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s4 () String (getVar_1 s0))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool (and s3 s6))
+[GOOD] (define-fun s10 () Bool (= s4 s9))
+[GOOD] (define-fun s12 () Bool (= s4 s11))
+[GOOD] (define-fun s13 () Bool (or s10 s12))
+[GOOD] (define-fun s14 () Bool (and s3 s13))
+[GOOD] (define-fun s17 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s18 () Int (getVal_1 s0))
+[GOOD] (define-fun s20 () Bool (< s18 s19))
+[GOOD] (define-fun s21 () Bool (and s17 s20))
+[GOOD] (define-fun s23 () Bool (= s18 s19))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s26 () Bool (> s18 s19))
+[GOOD] (define-fun s27 () Bool (and s17 s26))
+[GOOD] (define-fun s30 () Int (ite s27 s28 s29))
+[GOOD] (define-fun s31 () Int (ite s24 s25 s30))
+[GOOD] (define-fun s32 () Int (ite s21 s22 s31))
+[GOOD] (define-fun s33 () Int (ite s3 s16 s32))
+[GOOD] (define-fun s34 () Int (ite s14 s15 s33))
+[GOOD] (define-fun s35 () Int (ite s7 s8 s34))
+[GOOD] (define-fun s36 () Bool (distinct s16 s35))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s36)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr09c.gold b/SBVTestSuite/GoldFiles/adt_pexpr09c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr09c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr10.gold b/SBVTestSuite/GoldFiles/adt_pexpr10.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr10.gold
@@ -0,0 +1,454 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s15 () (Expr String Int) ((as Val (Expr String Int)) (- 5)))
+[GOOD] (define-fun s17 () (Expr String Int) ((as Val (Expr String Int)) (- 4)))
+[GOOD] (define-fun s19 () (Expr String Int) ((as Val (Expr String Int)) (- 3)))
+[GOOD] (define-fun s21 () (Expr String Int) ((as Val (Expr String Int)) (- 2)))
+[GOOD] (define-fun s23 () (Expr String Int) ((as Val (Expr String Int)) (- 1)))
+[GOOD] (define-fun s25 () (Expr String Int) ((as Val (Expr String Int)) 0))
+[GOOD] (define-fun s27 () (Expr String Int) ((as Val (Expr String Int)) 1))
+[GOOD] (define-fun s29 () (Expr String Int) ((as Val (Expr String Int)) 2))
+[GOOD] (define-fun s31 () (Expr String Int) ((as Val (Expr String Int)) 3))
+[GOOD] (define-fun s33 () (Expr String Int) ((as Val (Expr String Int)) 4))
+[GOOD] (define-fun s35 () (Expr String Int) ((as Val (Expr String Int)) 5))
+[GOOD] (define-fun s37 () (Expr String Int) ((as Val (Expr String Int)) 6))
+[GOOD] (define-fun s39 () (Expr String Int) ((as Val (Expr String Int)) 7))
+[GOOD] (define-fun s41 () (Expr String Int) ((as Val (Expr String Int)) 8))
+[GOOD] (define-fun s43 () (Expr String Int) ((as Val (Expr String Int)) 9))
+[GOOD] (define-fun s61 () String "a")
+[GOOD] (define-fun s64 () Int 0)
+[GOOD] (define-fun s65 () String "b")
+[GOOD] (define-fun s67 () String "c")
+[GOOD] (define-fun s71 () Int 1)
+[GOOD] (define-fun s72 () Int 2)
+[GOOD] (define-fun s75 () Int 10)
+[GOOD] (define-fun s78 () Int 3)
+[GOOD] (define-fun s81 () Int 4)
+[GOOD] (define-fun s84 () Int 5)
+[GOOD] (define-fun s85 () Int 6)
+[GOOD] (define-fun s414 () Int 45)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int))
+[GOOD] (declare-fun s1 () (Expr String Int))
+[GOOD] (declare-fun s2 () (Expr String Int))
+[GOOD] (declare-fun s3 () (Expr String Int))
+[GOOD] (declare-fun s4 () (Expr String Int))
+[GOOD] (declare-fun s5 () (Expr String Int))
+[GOOD] (declare-fun s6 () (Expr String Int))
+[GOOD] (declare-fun s7 () (Expr String Int))
+[GOOD] (declare-fun s8 () (Expr String Int))
+[GOOD] (declare-fun s9 () (Expr String Int))
+[GOOD] (declare-fun s10 () (Expr String Int))
+[GOOD] (declare-fun s11 () (Expr String Int))
+[GOOD] (declare-fun s12 () (Expr String Int))
+[GOOD] (declare-fun s13 () (Expr String Int))
+[GOOD] (declare-fun s14 () (Expr String Int))
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s16 () Bool (= s0 s15))
+[GOOD] (define-fun s18 () Bool (= s1 s17))
+[GOOD] (define-fun s20 () Bool (= s2 s19))
+[GOOD] (define-fun s22 () Bool (= s3 s21))
+[GOOD] (define-fun s24 () Bool (= s4 s23))
+[GOOD] (define-fun s26 () Bool (= s5 s25))
+[GOOD] (define-fun s28 () Bool (= s6 s27))
+[GOOD] (define-fun s30 () Bool (= s7 s29))
+[GOOD] (define-fun s32 () Bool (= s8 s31))
+[GOOD] (define-fun s34 () Bool (= s9 s33))
+[GOOD] (define-fun s36 () Bool (= s10 s35))
+[GOOD] (define-fun s38 () Bool (= s11 s37))
+[GOOD] (define-fun s40 () Bool (= s12 s39))
+[GOOD] (define-fun s42 () Bool (= s13 s41))
+[GOOD] (define-fun s44 () Bool (= s14 s43))
+[GOOD] (define-fun s45 () Bool (and s42 s44))
+[GOOD] (define-fun s46 () Bool (and s40 s45))
+[GOOD] (define-fun s47 () Bool (and s38 s46))
+[GOOD] (define-fun s48 () Bool (and s36 s47))
+[GOOD] (define-fun s49 () Bool (and s34 s48))
+[GOOD] (define-fun s50 () Bool (and s32 s49))
+[GOOD] (define-fun s51 () Bool (and s30 s50))
+[GOOD] (define-fun s52 () Bool (and s28 s51))
+[GOOD] (define-fun s53 () Bool (and s26 s52))
+[GOOD] (define-fun s54 () Bool (and s24 s53))
+[GOOD] (define-fun s55 () Bool (and s22 s54))
+[GOOD] (define-fun s56 () Bool (and s20 s55))
+[GOOD] (define-fun s57 () Bool (and s18 s56))
+[GOOD] (define-fun s58 () Bool (and s16 s57))
+[GOOD] (define-fun s59 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s60 () String (getVar_1 s0))
+[GOOD] (define-fun s62 () Bool (= s60 s61))
+[GOOD] (define-fun s63 () Bool (and s59 s62))
+[GOOD] (define-fun s66 () Bool (= s60 s65))
+[GOOD] (define-fun s68 () Bool (= s60 s67))
+[GOOD] (define-fun s69 () Bool (or s66 s68))
+[GOOD] (define-fun s70 () Bool (and s59 s69))
+[GOOD] (define-fun s73 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s74 () Int (getVal_1 s0))
+[GOOD] (define-fun s76 () Bool (< s74 s75))
+[GOOD] (define-fun s77 () Bool (and s73 s76))
+[GOOD] (define-fun s79 () Bool (= s74 s75))
+[GOOD] (define-fun s80 () Bool (and s73 s79))
+[GOOD] (define-fun s82 () Bool (> s74 s75))
+[GOOD] (define-fun s83 () Bool (and s73 s82))
+[GOOD] (define-fun s86 () Int (ite s83 s84 s85))
+[GOOD] (define-fun s87 () Int (ite s80 s81 s86))
+[GOOD] (define-fun s88 () Int (ite s77 s78 s87))
+[GOOD] (define-fun s89 () Int (ite s59 s72 s88))
+[GOOD] (define-fun s90 () Int (ite s70 s71 s89))
+[GOOD] (define-fun s91 () Int (ite s63 s64 s90))
+[GOOD] (define-fun s92 () Bool ((as is-Var Bool) s1))
+[GOOD] (define-fun s93 () String (getVar_1 s1))
+[GOOD] (define-fun s94 () Bool (= s61 s93))
+[GOOD] (define-fun s95 () Bool (and s92 s94))
+[GOOD] (define-fun s96 () Bool (= s65 s93))
+[GOOD] (define-fun s97 () Bool (= s67 s93))
+[GOOD] (define-fun s98 () Bool (or s96 s97))
+[GOOD] (define-fun s99 () Bool (and s92 s98))
+[GOOD] (define-fun s100 () Bool ((as is-Val Bool) s1))
+[GOOD] (define-fun s101 () Int (getVal_1 s1))
+[GOOD] (define-fun s102 () Bool (< s101 s75))
+[GOOD] (define-fun s103 () Bool (and s100 s102))
+[GOOD] (define-fun s104 () Bool (= s75 s101))
+[GOOD] (define-fun s105 () Bool (and s100 s104))
+[GOOD] (define-fun s106 () Bool (> s101 s75))
+[GOOD] (define-fun s107 () Bool (and s100 s106))
+[GOOD] (define-fun s108 () Int (ite s107 s84 s85))
+[GOOD] (define-fun s109 () Int (ite s105 s81 s108))
+[GOOD] (define-fun s110 () Int (ite s103 s78 s109))
+[GOOD] (define-fun s111 () Int (ite s92 s72 s110))
+[GOOD] (define-fun s112 () Int (ite s99 s71 s111))
+[GOOD] (define-fun s113 () Int (ite s95 s64 s112))
+[GOOD] (define-fun s114 () Int (+ s91 s113))
+[GOOD] (define-fun s115 () Bool ((as is-Var Bool) s2))
+[GOOD] (define-fun s116 () String (getVar_1 s2))
+[GOOD] (define-fun s117 () Bool (= s61 s116))
+[GOOD] (define-fun s118 () Bool (and s115 s117))
+[GOOD] (define-fun s119 () Bool (= s65 s116))
+[GOOD] (define-fun s120 () Bool (= s67 s116))
+[GOOD] (define-fun s121 () Bool (or s119 s120))
+[GOOD] (define-fun s122 () Bool (and s115 s121))
+[GOOD] (define-fun s123 () Bool ((as is-Val Bool) s2))
+[GOOD] (define-fun s124 () Int (getVal_1 s2))
+[GOOD] (define-fun s125 () Bool (< s124 s75))
+[GOOD] (define-fun s126 () Bool (and s123 s125))
+[GOOD] (define-fun s127 () Bool (= s75 s124))
+[GOOD] (define-fun s128 () Bool (and s123 s127))
+[GOOD] (define-fun s129 () Bool (> s124 s75))
+[GOOD] (define-fun s130 () Bool (and s123 s129))
+[GOOD] (define-fun s131 () Int (ite s130 s84 s85))
+[GOOD] (define-fun s132 () Int (ite s128 s81 s131))
+[GOOD] (define-fun s133 () Int (ite s126 s78 s132))
+[GOOD] (define-fun s134 () Int (ite s115 s72 s133))
+[GOOD] (define-fun s135 () Int (ite s122 s71 s134))
+[GOOD] (define-fun s136 () Int (ite s118 s64 s135))
+[GOOD] (define-fun s137 () Int (+ s114 s136))
+[GOOD] (define-fun s138 () Bool ((as is-Var Bool) s3))
+[GOOD] (define-fun s139 () String (getVar_1 s3))
+[GOOD] (define-fun s140 () Bool (= s61 s139))
+[GOOD] (define-fun s141 () Bool (and s138 s140))
+[GOOD] (define-fun s142 () Bool (= s65 s139))
+[GOOD] (define-fun s143 () Bool (= s67 s139))
+[GOOD] (define-fun s144 () Bool (or s142 s143))
+[GOOD] (define-fun s145 () Bool (and s138 s144))
+[GOOD] (define-fun s146 () Bool ((as is-Val Bool) s3))
+[GOOD] (define-fun s147 () Int (getVal_1 s3))
+[GOOD] (define-fun s148 () Bool (< s147 s75))
+[GOOD] (define-fun s149 () Bool (and s146 s148))
+[GOOD] (define-fun s150 () Bool (= s75 s147))
+[GOOD] (define-fun s151 () Bool (and s146 s150))
+[GOOD] (define-fun s152 () Bool (> s147 s75))
+[GOOD] (define-fun s153 () Bool (and s146 s152))
+[GOOD] (define-fun s154 () Int (ite s153 s84 s85))
+[GOOD] (define-fun s155 () Int (ite s151 s81 s154))
+[GOOD] (define-fun s156 () Int (ite s149 s78 s155))
+[GOOD] (define-fun s157 () Int (ite s138 s72 s156))
+[GOOD] (define-fun s158 () Int (ite s145 s71 s157))
+[GOOD] (define-fun s159 () Int (ite s141 s64 s158))
+[GOOD] (define-fun s160 () Int (+ s137 s159))
+[GOOD] (define-fun s161 () Bool ((as is-Var Bool) s4))
+[GOOD] (define-fun s162 () String (getVar_1 s4))
+[GOOD] (define-fun s163 () Bool (= s61 s162))
+[GOOD] (define-fun s164 () Bool (and s161 s163))
+[GOOD] (define-fun s165 () Bool (= s65 s162))
+[GOOD] (define-fun s166 () Bool (= s67 s162))
+[GOOD] (define-fun s167 () Bool (or s165 s166))
+[GOOD] (define-fun s168 () Bool (and s161 s167))
+[GOOD] (define-fun s169 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s170 () Int (getVal_1 s4))
+[GOOD] (define-fun s171 () Bool (< s170 s75))
+[GOOD] (define-fun s172 () Bool (and s169 s171))
+[GOOD] (define-fun s173 () Bool (= s75 s170))
+[GOOD] (define-fun s174 () Bool (and s169 s173))
+[GOOD] (define-fun s175 () Bool (> s170 s75))
+[GOOD] (define-fun s176 () Bool (and s169 s175))
+[GOOD] (define-fun s177 () Int (ite s176 s84 s85))
+[GOOD] (define-fun s178 () Int (ite s174 s81 s177))
+[GOOD] (define-fun s179 () Int (ite s172 s78 s178))
+[GOOD] (define-fun s180 () Int (ite s161 s72 s179))
+[GOOD] (define-fun s181 () Int (ite s168 s71 s180))
+[GOOD] (define-fun s182 () Int (ite s164 s64 s181))
+[GOOD] (define-fun s183 () Int (+ s160 s182))
+[GOOD] (define-fun s184 () Bool ((as is-Var Bool) s5))
+[GOOD] (define-fun s185 () String (getVar_1 s5))
+[GOOD] (define-fun s186 () Bool (= s61 s185))
+[GOOD] (define-fun s187 () Bool (and s184 s186))
+[GOOD] (define-fun s188 () Bool (= s65 s185))
+[GOOD] (define-fun s189 () Bool (= s67 s185))
+[GOOD] (define-fun s190 () Bool (or s188 s189))
+[GOOD] (define-fun s191 () Bool (and s184 s190))
+[GOOD] (define-fun s192 () Bool ((as is-Val Bool) s5))
+[GOOD] (define-fun s193 () Int (getVal_1 s5))
+[GOOD] (define-fun s194 () Bool (< s193 s75))
+[GOOD] (define-fun s195 () Bool (and s192 s194))
+[GOOD] (define-fun s196 () Bool (= s75 s193))
+[GOOD] (define-fun s197 () Bool (and s192 s196))
+[GOOD] (define-fun s198 () Bool (> s193 s75))
+[GOOD] (define-fun s199 () Bool (and s192 s198))
+[GOOD] (define-fun s200 () Int (ite s199 s84 s85))
+[GOOD] (define-fun s201 () Int (ite s197 s81 s200))
+[GOOD] (define-fun s202 () Int (ite s195 s78 s201))
+[GOOD] (define-fun s203 () Int (ite s184 s72 s202))
+[GOOD] (define-fun s204 () Int (ite s191 s71 s203))
+[GOOD] (define-fun s205 () Int (ite s187 s64 s204))
+[GOOD] (define-fun s206 () Int (+ s183 s205))
+[GOOD] (define-fun s207 () Bool ((as is-Var Bool) s6))
+[GOOD] (define-fun s208 () String (getVar_1 s6))
+[GOOD] (define-fun s209 () Bool (= s61 s208))
+[GOOD] (define-fun s210 () Bool (and s207 s209))
+[GOOD] (define-fun s211 () Bool (= s65 s208))
+[GOOD] (define-fun s212 () Bool (= s67 s208))
+[GOOD] (define-fun s213 () Bool (or s211 s212))
+[GOOD] (define-fun s214 () Bool (and s207 s213))
+[GOOD] (define-fun s215 () Bool ((as is-Val Bool) s6))
+[GOOD] (define-fun s216 () Int (getVal_1 s6))
+[GOOD] (define-fun s217 () Bool (< s216 s75))
+[GOOD] (define-fun s218 () Bool (and s215 s217))
+[GOOD] (define-fun s219 () Bool (= s75 s216))
+[GOOD] (define-fun s220 () Bool (and s215 s219))
+[GOOD] (define-fun s221 () Bool (> s216 s75))
+[GOOD] (define-fun s222 () Bool (and s215 s221))
+[GOOD] (define-fun s223 () Int (ite s222 s84 s85))
+[GOOD] (define-fun s224 () Int (ite s220 s81 s223))
+[GOOD] (define-fun s225 () Int (ite s218 s78 s224))
+[GOOD] (define-fun s226 () Int (ite s207 s72 s225))
+[GOOD] (define-fun s227 () Int (ite s214 s71 s226))
+[GOOD] (define-fun s228 () Int (ite s210 s64 s227))
+[GOOD] (define-fun s229 () Int (+ s206 s228))
+[GOOD] (define-fun s230 () Bool ((as is-Var Bool) s7))
+[GOOD] (define-fun s231 () String (getVar_1 s7))
+[GOOD] (define-fun s232 () Bool (= s61 s231))
+[GOOD] (define-fun s233 () Bool (and s230 s232))
+[GOOD] (define-fun s234 () Bool (= s65 s231))
+[GOOD] (define-fun s235 () Bool (= s67 s231))
+[GOOD] (define-fun s236 () Bool (or s234 s235))
+[GOOD] (define-fun s237 () Bool (and s230 s236))
+[GOOD] (define-fun s238 () Bool ((as is-Val Bool) s7))
+[GOOD] (define-fun s239 () Int (getVal_1 s7))
+[GOOD] (define-fun s240 () Bool (< s239 s75))
+[GOOD] (define-fun s241 () Bool (and s238 s240))
+[GOOD] (define-fun s242 () Bool (= s75 s239))
+[GOOD] (define-fun s243 () Bool (and s238 s242))
+[GOOD] (define-fun s244 () Bool (> s239 s75))
+[GOOD] (define-fun s245 () Bool (and s238 s244))
+[GOOD] (define-fun s246 () Int (ite s245 s84 s85))
+[GOOD] (define-fun s247 () Int (ite s243 s81 s246))
+[GOOD] (define-fun s248 () Int (ite s241 s78 s247))
+[GOOD] (define-fun s249 () Int (ite s230 s72 s248))
+[GOOD] (define-fun s250 () Int (ite s237 s71 s249))
+[GOOD] (define-fun s251 () Int (ite s233 s64 s250))
+[GOOD] (define-fun s252 () Int (+ s229 s251))
+[GOOD] (define-fun s253 () Bool ((as is-Var Bool) s8))
+[GOOD] (define-fun s254 () String (getVar_1 s8))
+[GOOD] (define-fun s255 () Bool (= s61 s254))
+[GOOD] (define-fun s256 () Bool (and s253 s255))
+[GOOD] (define-fun s257 () Bool (= s65 s254))
+[GOOD] (define-fun s258 () Bool (= s67 s254))
+[GOOD] (define-fun s259 () Bool (or s257 s258))
+[GOOD] (define-fun s260 () Bool (and s253 s259))
+[GOOD] (define-fun s261 () Bool ((as is-Val Bool) s8))
+[GOOD] (define-fun s262 () Int (getVal_1 s8))
+[GOOD] (define-fun s263 () Bool (< s262 s75))
+[GOOD] (define-fun s264 () Bool (and s261 s263))
+[GOOD] (define-fun s265 () Bool (= s75 s262))
+[GOOD] (define-fun s266 () Bool (and s261 s265))
+[GOOD] (define-fun s267 () Bool (> s262 s75))
+[GOOD] (define-fun s268 () Bool (and s261 s267))
+[GOOD] (define-fun s269 () Int (ite s268 s84 s85))
+[GOOD] (define-fun s270 () Int (ite s266 s81 s269))
+[GOOD] (define-fun s271 () Int (ite s264 s78 s270))
+[GOOD] (define-fun s272 () Int (ite s253 s72 s271))
+[GOOD] (define-fun s273 () Int (ite s260 s71 s272))
+[GOOD] (define-fun s274 () Int (ite s256 s64 s273))
+[GOOD] (define-fun s275 () Int (+ s252 s274))
+[GOOD] (define-fun s276 () Bool ((as is-Var Bool) s9))
+[GOOD] (define-fun s277 () String (getVar_1 s9))
+[GOOD] (define-fun s278 () Bool (= s61 s277))
+[GOOD] (define-fun s279 () Bool (and s276 s278))
+[GOOD] (define-fun s280 () Bool (= s65 s277))
+[GOOD] (define-fun s281 () Bool (= s67 s277))
+[GOOD] (define-fun s282 () Bool (or s280 s281))
+[GOOD] (define-fun s283 () Bool (and s276 s282))
+[GOOD] (define-fun s284 () Bool ((as is-Val Bool) s9))
+[GOOD] (define-fun s285 () Int (getVal_1 s9))
+[GOOD] (define-fun s286 () Bool (< s285 s75))
+[GOOD] (define-fun s287 () Bool (and s284 s286))
+[GOOD] (define-fun s288 () Bool (= s75 s285))
+[GOOD] (define-fun s289 () Bool (and s284 s288))
+[GOOD] (define-fun s290 () Bool (> s285 s75))
+[GOOD] (define-fun s291 () Bool (and s284 s290))
+[GOOD] (define-fun s292 () Int (ite s291 s84 s85))
+[GOOD] (define-fun s293 () Int (ite s289 s81 s292))
+[GOOD] (define-fun s294 () Int (ite s287 s78 s293))
+[GOOD] (define-fun s295 () Int (ite s276 s72 s294))
+[GOOD] (define-fun s296 () Int (ite s283 s71 s295))
+[GOOD] (define-fun s297 () Int (ite s279 s64 s296))
+[GOOD] (define-fun s298 () Int (+ s275 s297))
+[GOOD] (define-fun s299 () Bool ((as is-Var Bool) s10))
+[GOOD] (define-fun s300 () String (getVar_1 s10))
+[GOOD] (define-fun s301 () Bool (= s61 s300))
+[GOOD] (define-fun s302 () Bool (and s299 s301))
+[GOOD] (define-fun s303 () Bool (= s65 s300))
+[GOOD] (define-fun s304 () Bool (= s67 s300))
+[GOOD] (define-fun s305 () Bool (or s303 s304))
+[GOOD] (define-fun s306 () Bool (and s299 s305))
+[GOOD] (define-fun s307 () Bool ((as is-Val Bool) s10))
+[GOOD] (define-fun s308 () Int (getVal_1 s10))
+[GOOD] (define-fun s309 () Bool (< s308 s75))
+[GOOD] (define-fun s310 () Bool (and s307 s309))
+[GOOD] (define-fun s311 () Bool (= s75 s308))
+[GOOD] (define-fun s312 () Bool (and s307 s311))
+[GOOD] (define-fun s313 () Bool (> s308 s75))
+[GOOD] (define-fun s314 () Bool (and s307 s313))
+[GOOD] (define-fun s315 () Int (ite s314 s84 s85))
+[GOOD] (define-fun s316 () Int (ite s312 s81 s315))
+[GOOD] (define-fun s317 () Int (ite s310 s78 s316))
+[GOOD] (define-fun s318 () Int (ite s299 s72 s317))
+[GOOD] (define-fun s319 () Int (ite s306 s71 s318))
+[GOOD] (define-fun s320 () Int (ite s302 s64 s319))
+[GOOD] (define-fun s321 () Int (+ s298 s320))
+[GOOD] (define-fun s322 () Bool ((as is-Var Bool) s11))
+[GOOD] (define-fun s323 () String (getVar_1 s11))
+[GOOD] (define-fun s324 () Bool (= s61 s323))
+[GOOD] (define-fun s325 () Bool (and s322 s324))
+[GOOD] (define-fun s326 () Bool (= s65 s323))
+[GOOD] (define-fun s327 () Bool (= s67 s323))
+[GOOD] (define-fun s328 () Bool (or s326 s327))
+[GOOD] (define-fun s329 () Bool (and s322 s328))
+[GOOD] (define-fun s330 () Bool ((as is-Val Bool) s11))
+[GOOD] (define-fun s331 () Int (getVal_1 s11))
+[GOOD] (define-fun s332 () Bool (< s331 s75))
+[GOOD] (define-fun s333 () Bool (and s330 s332))
+[GOOD] (define-fun s334 () Bool (= s75 s331))
+[GOOD] (define-fun s335 () Bool (and s330 s334))
+[GOOD] (define-fun s336 () Bool (> s331 s75))
+[GOOD] (define-fun s337 () Bool (and s330 s336))
+[GOOD] (define-fun s338 () Int (ite s337 s84 s85))
+[GOOD] (define-fun s339 () Int (ite s335 s81 s338))
+[GOOD] (define-fun s340 () Int (ite s333 s78 s339))
+[GOOD] (define-fun s341 () Int (ite s322 s72 s340))
+[GOOD] (define-fun s342 () Int (ite s329 s71 s341))
+[GOOD] (define-fun s343 () Int (ite s325 s64 s342))
+[GOOD] (define-fun s344 () Int (+ s321 s343))
+[GOOD] (define-fun s345 () Bool ((as is-Var Bool) s12))
+[GOOD] (define-fun s346 () String (getVar_1 s12))
+[GOOD] (define-fun s347 () Bool (= s61 s346))
+[GOOD] (define-fun s348 () Bool (and s345 s347))
+[GOOD] (define-fun s349 () Bool (= s65 s346))
+[GOOD] (define-fun s350 () Bool (= s67 s346))
+[GOOD] (define-fun s351 () Bool (or s349 s350))
+[GOOD] (define-fun s352 () Bool (and s345 s351))
+[GOOD] (define-fun s353 () Bool ((as is-Val Bool) s12))
+[GOOD] (define-fun s354 () Int (getVal_1 s12))
+[GOOD] (define-fun s355 () Bool (< s354 s75))
+[GOOD] (define-fun s356 () Bool (and s353 s355))
+[GOOD] (define-fun s357 () Bool (= s75 s354))
+[GOOD] (define-fun s358 () Bool (and s353 s357))
+[GOOD] (define-fun s359 () Bool (> s354 s75))
+[GOOD] (define-fun s360 () Bool (and s353 s359))
+[GOOD] (define-fun s361 () Int (ite s360 s84 s85))
+[GOOD] (define-fun s362 () Int (ite s358 s81 s361))
+[GOOD] (define-fun s363 () Int (ite s356 s78 s362))
+[GOOD] (define-fun s364 () Int (ite s345 s72 s363))
+[GOOD] (define-fun s365 () Int (ite s352 s71 s364))
+[GOOD] (define-fun s366 () Int (ite s348 s64 s365))
+[GOOD] (define-fun s367 () Int (+ s344 s366))
+[GOOD] (define-fun s368 () Bool ((as is-Var Bool) s13))
+[GOOD] (define-fun s369 () String (getVar_1 s13))
+[GOOD] (define-fun s370 () Bool (= s61 s369))
+[GOOD] (define-fun s371 () Bool (and s368 s370))
+[GOOD] (define-fun s372 () Bool (= s65 s369))
+[GOOD] (define-fun s373 () Bool (= s67 s369))
+[GOOD] (define-fun s374 () Bool (or s372 s373))
+[GOOD] (define-fun s375 () Bool (and s368 s374))
+[GOOD] (define-fun s376 () Bool ((as is-Val Bool) s13))
+[GOOD] (define-fun s377 () Int (getVal_1 s13))
+[GOOD] (define-fun s378 () Bool (< s377 s75))
+[GOOD] (define-fun s379 () Bool (and s376 s378))
+[GOOD] (define-fun s380 () Bool (= s75 s377))
+[GOOD] (define-fun s381 () Bool (and s376 s380))
+[GOOD] (define-fun s382 () Bool (> s377 s75))
+[GOOD] (define-fun s383 () Bool (and s376 s382))
+[GOOD] (define-fun s384 () Int (ite s383 s84 s85))
+[GOOD] (define-fun s385 () Int (ite s381 s81 s384))
+[GOOD] (define-fun s386 () Int (ite s379 s78 s385))
+[GOOD] (define-fun s387 () Int (ite s368 s72 s386))
+[GOOD] (define-fun s388 () Int (ite s375 s71 s387))
+[GOOD] (define-fun s389 () Int (ite s371 s64 s388))
+[GOOD] (define-fun s390 () Int (+ s367 s389))
+[GOOD] (define-fun s391 () Bool ((as is-Var Bool) s14))
+[GOOD] (define-fun s392 () String (getVar_1 s14))
+[GOOD] (define-fun s393 () Bool (= s61 s392))
+[GOOD] (define-fun s394 () Bool (and s391 s393))
+[GOOD] (define-fun s395 () Bool (= s65 s392))
+[GOOD] (define-fun s396 () Bool (= s67 s392))
+[GOOD] (define-fun s397 () Bool (or s395 s396))
+[GOOD] (define-fun s398 () Bool (and s391 s397))
+[GOOD] (define-fun s399 () Bool ((as is-Val Bool) s14))
+[GOOD] (define-fun s400 () Int (getVal_1 s14))
+[GOOD] (define-fun s401 () Bool (< s400 s75))
+[GOOD] (define-fun s402 () Bool (and s399 s401))
+[GOOD] (define-fun s403 () Bool (= s75 s400))
+[GOOD] (define-fun s404 () Bool (and s399 s403))
+[GOOD] (define-fun s405 () Bool (> s400 s75))
+[GOOD] (define-fun s406 () Bool (and s399 s405))
+[GOOD] (define-fun s407 () Int (ite s406 s84 s85))
+[GOOD] (define-fun s408 () Int (ite s404 s81 s407))
+[GOOD] (define-fun s409 () Int (ite s402 s78 s408))
+[GOOD] (define-fun s410 () Int (ite s391 s72 s409))
+[GOOD] (define-fun s411 () Int (ite s398 s71 s410))
+[GOOD] (define-fun s412 () Int (ite s394 s64 s411))
+[GOOD] (define-fun s413 () Int (+ s390 s412))
+[GOOD] (define-fun s415 () Bool (distinct s413 s414))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s58)
+[GOOD] (assert s415)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr10c.gold b/SBVTestSuite/GoldFiles/adt_pexpr10c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr10c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr11.gold b/SBVTestSuite/GoldFiles/adt_pexpr11.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr11.gold
@@ -0,0 +1,102 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () (Expr String Int) ((as Val (Expr String Int)) 10))
+[GOOD] (define-fun s8 () String "a")
+[GOOD] (define-fun s11 () Int 0)
+[GOOD] (define-fun s12 () String "b")
+[GOOD] (define-fun s14 () String "c")
+[GOOD] (define-fun s18 () Int 1)
+[GOOD] (define-fun s19 () Int 2)
+[GOOD] (define-fun s22 () Int 10)
+[GOOD] (define-fun s25 () Int 3)
+[GOOD] (define-fun s28 () Int 4)
+[GOOD] (define-fun s31 () Int 5)
+[GOOD] (define-fun s32 () Int 6)
+[GOOD] (define-fun s62 () Int 8)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int))
+[GOOD] (declare-fun s1 () (Expr String Int))
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (= s0 s2))
+[GOOD] (define-fun s4 () Bool (= s1 s2))
+[GOOD] (define-fun s5 () Bool (and s3 s4))
+[GOOD] (define-fun s6 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s7 () String (getVar_1 s0))
+[GOOD] (define-fun s9 () Bool (= s7 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s13 () Bool (= s7 s12))
+[GOOD] (define-fun s15 () Bool (= s7 s14))
+[GOOD] (define-fun s16 () Bool (or s13 s15))
+[GOOD] (define-fun s17 () Bool (and s6 s16))
+[GOOD] (define-fun s20 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s21 () Int (getVal_1 s0))
+[GOOD] (define-fun s23 () Bool (< s21 s22))
+[GOOD] (define-fun s24 () Bool (and s20 s23))
+[GOOD] (define-fun s26 () Bool (= s21 s22))
+[GOOD] (define-fun s27 () Bool (and s20 s26))
+[GOOD] (define-fun s29 () Bool (> s21 s22))
+[GOOD] (define-fun s30 () Bool (and s20 s29))
+[GOOD] (define-fun s33 () Int (ite s30 s31 s32))
+[GOOD] (define-fun s34 () Int (ite s27 s28 s33))
+[GOOD] (define-fun s35 () Int (ite s24 s25 s34))
+[GOOD] (define-fun s36 () Int (ite s6 s19 s35))
+[GOOD] (define-fun s37 () Int (ite s17 s18 s36))
+[GOOD] (define-fun s38 () Int (ite s10 s11 s37))
+[GOOD] (define-fun s39 () Bool ((as is-Var Bool) s1))
+[GOOD] (define-fun s40 () String (getVar_1 s1))
+[GOOD] (define-fun s41 () Bool (= s8 s40))
+[GOOD] (define-fun s42 () Bool (and s39 s41))
+[GOOD] (define-fun s43 () Bool (= s12 s40))
+[GOOD] (define-fun s44 () Bool (= s14 s40))
+[GOOD] (define-fun s45 () Bool (or s43 s44))
+[GOOD] (define-fun s46 () Bool (and s39 s45))
+[GOOD] (define-fun s47 () Bool ((as is-Val Bool) s1))
+[GOOD] (define-fun s48 () Int (getVal_1 s1))
+[GOOD] (define-fun s49 () Bool (< s48 s22))
+[GOOD] (define-fun s50 () Bool (and s47 s49))
+[GOOD] (define-fun s51 () Bool (= s22 s48))
+[GOOD] (define-fun s52 () Bool (and s47 s51))
+[GOOD] (define-fun s53 () Bool (> s48 s22))
+[GOOD] (define-fun s54 () Bool (and s47 s53))
+[GOOD] (define-fun s55 () Int (ite s54 s31 s32))
+[GOOD] (define-fun s56 () Int (ite s52 s28 s55))
+[GOOD] (define-fun s57 () Int (ite s50 s25 s56))
+[GOOD] (define-fun s58 () Int (ite s39 s19 s57))
+[GOOD] (define-fun s59 () Int (ite s46 s18 s58))
+[GOOD] (define-fun s60 () Int (ite s42 s11 s59))
+[GOOD] (define-fun s61 () Int (+ s38 s60))
+[GOOD] (define-fun s63 () Bool (distinct s61 s62))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s5)
+[GOOD] (assert s63)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr11c.gold b/SBVTestSuite/GoldFiles/adt_pexpr11c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr11c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr12.gold b/SBVTestSuite/GoldFiles/adt_pexpr12.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr12.gold
@@ -0,0 +1,319 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s10 () (Expr String Int) ((as Val (Expr String Int)) 11))
+[GOOD] (define-fun s12 () (Expr String Int) ((as Val (Expr String Int)) 12))
+[GOOD] (define-fun s14 () (Expr String Int) ((as Val (Expr String Int)) 13))
+[GOOD] (define-fun s16 () (Expr String Int) ((as Val (Expr String Int)) 14))
+[GOOD] (define-fun s18 () (Expr String Int) ((as Val (Expr String Int)) 15))
+[GOOD] (define-fun s20 () (Expr String Int) ((as Val (Expr String Int)) 16))
+[GOOD] (define-fun s22 () (Expr String Int) ((as Val (Expr String Int)) 17))
+[GOOD] (define-fun s24 () (Expr String Int) ((as Val (Expr String Int)) 18))
+[GOOD] (define-fun s26 () (Expr String Int) ((as Val (Expr String Int)) 19))
+[GOOD] (define-fun s28 () (Expr String Int) ((as Val (Expr String Int)) 20))
+[GOOD] (define-fun s41 () String "a")
+[GOOD] (define-fun s44 () Int 0)
+[GOOD] (define-fun s45 () String "b")
+[GOOD] (define-fun s47 () String "c")
+[GOOD] (define-fun s51 () Int 1)
+[GOOD] (define-fun s52 () Int 2)
+[GOOD] (define-fun s55 () Int 10)
+[GOOD] (define-fun s58 () Int 3)
+[GOOD] (define-fun s61 () Int 4)
+[GOOD] (define-fun s64 () Int 5)
+[GOOD] (define-fun s65 () Int 6)
+[GOOD] (define-fun s279 () Int 50)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int))
+[GOOD] (declare-fun s1 () (Expr String Int))
+[GOOD] (declare-fun s2 () (Expr String Int))
+[GOOD] (declare-fun s3 () (Expr String Int))
+[GOOD] (declare-fun s4 () (Expr String Int))
+[GOOD] (declare-fun s5 () (Expr String Int))
+[GOOD] (declare-fun s6 () (Expr String Int))
+[GOOD] (declare-fun s7 () (Expr String Int))
+[GOOD] (declare-fun s8 () (Expr String Int))
+[GOOD] (declare-fun s9 () (Expr String Int))
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s11 () Bool (= s0 s10))
+[GOOD] (define-fun s13 () Bool (= s1 s12))
+[GOOD] (define-fun s15 () Bool (= s2 s14))
+[GOOD] (define-fun s17 () Bool (= s3 s16))
+[GOOD] (define-fun s19 () Bool (= s4 s18))
+[GOOD] (define-fun s21 () Bool (= s5 s20))
+[GOOD] (define-fun s23 () Bool (= s6 s22))
+[GOOD] (define-fun s25 () Bool (= s7 s24))
+[GOOD] (define-fun s27 () Bool (= s8 s26))
+[GOOD] (define-fun s29 () Bool (= s9 s28))
+[GOOD] (define-fun s30 () Bool (and s27 s29))
+[GOOD] (define-fun s31 () Bool (and s25 s30))
+[GOOD] (define-fun s32 () Bool (and s23 s31))
+[GOOD] (define-fun s33 () Bool (and s21 s32))
+[GOOD] (define-fun s34 () Bool (and s19 s33))
+[GOOD] (define-fun s35 () Bool (and s17 s34))
+[GOOD] (define-fun s36 () Bool (and s15 s35))
+[GOOD] (define-fun s37 () Bool (and s13 s36))
+[GOOD] (define-fun s38 () Bool (and s11 s37))
+[GOOD] (define-fun s39 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s40 () String (getVar_1 s0))
+[GOOD] (define-fun s42 () Bool (= s40 s41))
+[GOOD] (define-fun s43 () Bool (and s39 s42))
+[GOOD] (define-fun s46 () Bool (= s40 s45))
+[GOOD] (define-fun s48 () Bool (= s40 s47))
+[GOOD] (define-fun s49 () Bool (or s46 s48))
+[GOOD] (define-fun s50 () Bool (and s39 s49))
+[GOOD] (define-fun s53 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s54 () Int (getVal_1 s0))
+[GOOD] (define-fun s56 () Bool (< s54 s55))
+[GOOD] (define-fun s57 () Bool (and s53 s56))
+[GOOD] (define-fun s59 () Bool (= s54 s55))
+[GOOD] (define-fun s60 () Bool (and s53 s59))
+[GOOD] (define-fun s62 () Bool (> s54 s55))
+[GOOD] (define-fun s63 () Bool (and s53 s62))
+[GOOD] (define-fun s66 () Int (ite s63 s64 s65))
+[GOOD] (define-fun s67 () Int (ite s60 s61 s66))
+[GOOD] (define-fun s68 () Int (ite s57 s58 s67))
+[GOOD] (define-fun s69 () Int (ite s39 s52 s68))
+[GOOD] (define-fun s70 () Int (ite s50 s51 s69))
+[GOOD] (define-fun s71 () Int (ite s43 s44 s70))
+[GOOD] (define-fun s72 () Bool ((as is-Var Bool) s1))
+[GOOD] (define-fun s73 () String (getVar_1 s1))
+[GOOD] (define-fun s74 () Bool (= s41 s73))
+[GOOD] (define-fun s75 () Bool (and s72 s74))
+[GOOD] (define-fun s76 () Bool (= s45 s73))
+[GOOD] (define-fun s77 () Bool (= s47 s73))
+[GOOD] (define-fun s78 () Bool (or s76 s77))
+[GOOD] (define-fun s79 () Bool (and s72 s78))
+[GOOD] (define-fun s80 () Bool ((as is-Val Bool) s1))
+[GOOD] (define-fun s81 () Int (getVal_1 s1))
+[GOOD] (define-fun s82 () Bool (< s81 s55))
+[GOOD] (define-fun s83 () Bool (and s80 s82))
+[GOOD] (define-fun s84 () Bool (= s55 s81))
+[GOOD] (define-fun s85 () Bool (and s80 s84))
+[GOOD] (define-fun s86 () Bool (> s81 s55))
+[GOOD] (define-fun s87 () Bool (and s80 s86))
+[GOOD] (define-fun s88 () Int (ite s87 s64 s65))
+[GOOD] (define-fun s89 () Int (ite s85 s61 s88))
+[GOOD] (define-fun s90 () Int (ite s83 s58 s89))
+[GOOD] (define-fun s91 () Int (ite s72 s52 s90))
+[GOOD] (define-fun s92 () Int (ite s79 s51 s91))
+[GOOD] (define-fun s93 () Int (ite s75 s44 s92))
+[GOOD] (define-fun s94 () Int (+ s71 s93))
+[GOOD] (define-fun s95 () Bool ((as is-Var Bool) s2))
+[GOOD] (define-fun s96 () String (getVar_1 s2))
+[GOOD] (define-fun s97 () Bool (= s41 s96))
+[GOOD] (define-fun s98 () Bool (and s95 s97))
+[GOOD] (define-fun s99 () Bool (= s45 s96))
+[GOOD] (define-fun s100 () Bool (= s47 s96))
+[GOOD] (define-fun s101 () Bool (or s99 s100))
+[GOOD] (define-fun s102 () Bool (and s95 s101))
+[GOOD] (define-fun s103 () Bool ((as is-Val Bool) s2))
+[GOOD] (define-fun s104 () Int (getVal_1 s2))
+[GOOD] (define-fun s105 () Bool (< s104 s55))
+[GOOD] (define-fun s106 () Bool (and s103 s105))
+[GOOD] (define-fun s107 () Bool (= s55 s104))
+[GOOD] (define-fun s108 () Bool (and s103 s107))
+[GOOD] (define-fun s109 () Bool (> s104 s55))
+[GOOD] (define-fun s110 () Bool (and s103 s109))
+[GOOD] (define-fun s111 () Int (ite s110 s64 s65))
+[GOOD] (define-fun s112 () Int (ite s108 s61 s111))
+[GOOD] (define-fun s113 () Int (ite s106 s58 s112))
+[GOOD] (define-fun s114 () Int (ite s95 s52 s113))
+[GOOD] (define-fun s115 () Int (ite s102 s51 s114))
+[GOOD] (define-fun s116 () Int (ite s98 s44 s115))
+[GOOD] (define-fun s117 () Int (+ s94 s116))
+[GOOD] (define-fun s118 () Bool ((as is-Var Bool) s3))
+[GOOD] (define-fun s119 () String (getVar_1 s3))
+[GOOD] (define-fun s120 () Bool (= s41 s119))
+[GOOD] (define-fun s121 () Bool (and s118 s120))
+[GOOD] (define-fun s122 () Bool (= s45 s119))
+[GOOD] (define-fun s123 () Bool (= s47 s119))
+[GOOD] (define-fun s124 () Bool (or s122 s123))
+[GOOD] (define-fun s125 () Bool (and s118 s124))
+[GOOD] (define-fun s126 () Bool ((as is-Val Bool) s3))
+[GOOD] (define-fun s127 () Int (getVal_1 s3))
+[GOOD] (define-fun s128 () Bool (< s127 s55))
+[GOOD] (define-fun s129 () Bool (and s126 s128))
+[GOOD] (define-fun s130 () Bool (= s55 s127))
+[GOOD] (define-fun s131 () Bool (and s126 s130))
+[GOOD] (define-fun s132 () Bool (> s127 s55))
+[GOOD] (define-fun s133 () Bool (and s126 s132))
+[GOOD] (define-fun s134 () Int (ite s133 s64 s65))
+[GOOD] (define-fun s135 () Int (ite s131 s61 s134))
+[GOOD] (define-fun s136 () Int (ite s129 s58 s135))
+[GOOD] (define-fun s137 () Int (ite s118 s52 s136))
+[GOOD] (define-fun s138 () Int (ite s125 s51 s137))
+[GOOD] (define-fun s139 () Int (ite s121 s44 s138))
+[GOOD] (define-fun s140 () Int (+ s117 s139))
+[GOOD] (define-fun s141 () Bool ((as is-Var Bool) s4))
+[GOOD] (define-fun s142 () String (getVar_1 s4))
+[GOOD] (define-fun s143 () Bool (= s41 s142))
+[GOOD] (define-fun s144 () Bool (and s141 s143))
+[GOOD] (define-fun s145 () Bool (= s45 s142))
+[GOOD] (define-fun s146 () Bool (= s47 s142))
+[GOOD] (define-fun s147 () Bool (or s145 s146))
+[GOOD] (define-fun s148 () Bool (and s141 s147))
+[GOOD] (define-fun s149 () Bool ((as is-Val Bool) s4))
+[GOOD] (define-fun s150 () Int (getVal_1 s4))
+[GOOD] (define-fun s151 () Bool (< s150 s55))
+[GOOD] (define-fun s152 () Bool (and s149 s151))
+[GOOD] (define-fun s153 () Bool (= s55 s150))
+[GOOD] (define-fun s154 () Bool (and s149 s153))
+[GOOD] (define-fun s155 () Bool (> s150 s55))
+[GOOD] (define-fun s156 () Bool (and s149 s155))
+[GOOD] (define-fun s157 () Int (ite s156 s64 s65))
+[GOOD] (define-fun s158 () Int (ite s154 s61 s157))
+[GOOD] (define-fun s159 () Int (ite s152 s58 s158))
+[GOOD] (define-fun s160 () Int (ite s141 s52 s159))
+[GOOD] (define-fun s161 () Int (ite s148 s51 s160))
+[GOOD] (define-fun s162 () Int (ite s144 s44 s161))
+[GOOD] (define-fun s163 () Int (+ s140 s162))
+[GOOD] (define-fun s164 () Bool ((as is-Var Bool) s5))
+[GOOD] (define-fun s165 () String (getVar_1 s5))
+[GOOD] (define-fun s166 () Bool (= s41 s165))
+[GOOD] (define-fun s167 () Bool (and s164 s166))
+[GOOD] (define-fun s168 () Bool (= s45 s165))
+[GOOD] (define-fun s169 () Bool (= s47 s165))
+[GOOD] (define-fun s170 () Bool (or s168 s169))
+[GOOD] (define-fun s171 () Bool (and s164 s170))
+[GOOD] (define-fun s172 () Bool ((as is-Val Bool) s5))
+[GOOD] (define-fun s173 () Int (getVal_1 s5))
+[GOOD] (define-fun s174 () Bool (< s173 s55))
+[GOOD] (define-fun s175 () Bool (and s172 s174))
+[GOOD] (define-fun s176 () Bool (= s55 s173))
+[GOOD] (define-fun s177 () Bool (and s172 s176))
+[GOOD] (define-fun s178 () Bool (> s173 s55))
+[GOOD] (define-fun s179 () Bool (and s172 s178))
+[GOOD] (define-fun s180 () Int (ite s179 s64 s65))
+[GOOD] (define-fun s181 () Int (ite s177 s61 s180))
+[GOOD] (define-fun s182 () Int (ite s175 s58 s181))
+[GOOD] (define-fun s183 () Int (ite s164 s52 s182))
+[GOOD] (define-fun s184 () Int (ite s171 s51 s183))
+[GOOD] (define-fun s185 () Int (ite s167 s44 s184))
+[GOOD] (define-fun s186 () Int (+ s163 s185))
+[GOOD] (define-fun s187 () Bool ((as is-Var Bool) s6))
+[GOOD] (define-fun s188 () String (getVar_1 s6))
+[GOOD] (define-fun s189 () Bool (= s41 s188))
+[GOOD] (define-fun s190 () Bool (and s187 s189))
+[GOOD] (define-fun s191 () Bool (= s45 s188))
+[GOOD] (define-fun s192 () Bool (= s47 s188))
+[GOOD] (define-fun s193 () Bool (or s191 s192))
+[GOOD] (define-fun s194 () Bool (and s187 s193))
+[GOOD] (define-fun s195 () Bool ((as is-Val Bool) s6))
+[GOOD] (define-fun s196 () Int (getVal_1 s6))
+[GOOD] (define-fun s197 () Bool (< s196 s55))
+[GOOD] (define-fun s198 () Bool (and s195 s197))
+[GOOD] (define-fun s199 () Bool (= s55 s196))
+[GOOD] (define-fun s200 () Bool (and s195 s199))
+[GOOD] (define-fun s201 () Bool (> s196 s55))
+[GOOD] (define-fun s202 () Bool (and s195 s201))
+[GOOD] (define-fun s203 () Int (ite s202 s64 s65))
+[GOOD] (define-fun s204 () Int (ite s200 s61 s203))
+[GOOD] (define-fun s205 () Int (ite s198 s58 s204))
+[GOOD] (define-fun s206 () Int (ite s187 s52 s205))
+[GOOD] (define-fun s207 () Int (ite s194 s51 s206))
+[GOOD] (define-fun s208 () Int (ite s190 s44 s207))
+[GOOD] (define-fun s209 () Int (+ s186 s208))
+[GOOD] (define-fun s210 () Bool ((as is-Var Bool) s7))
+[GOOD] (define-fun s211 () String (getVar_1 s7))
+[GOOD] (define-fun s212 () Bool (= s41 s211))
+[GOOD] (define-fun s213 () Bool (and s210 s212))
+[GOOD] (define-fun s214 () Bool (= s45 s211))
+[GOOD] (define-fun s215 () Bool (= s47 s211))
+[GOOD] (define-fun s216 () Bool (or s214 s215))
+[GOOD] (define-fun s217 () Bool (and s210 s216))
+[GOOD] (define-fun s218 () Bool ((as is-Val Bool) s7))
+[GOOD] (define-fun s219 () Int (getVal_1 s7))
+[GOOD] (define-fun s220 () Bool (< s219 s55))
+[GOOD] (define-fun s221 () Bool (and s218 s220))
+[GOOD] (define-fun s222 () Bool (= s55 s219))
+[GOOD] (define-fun s223 () Bool (and s218 s222))
+[GOOD] (define-fun s224 () Bool (> s219 s55))
+[GOOD] (define-fun s225 () Bool (and s218 s224))
+[GOOD] (define-fun s226 () Int (ite s225 s64 s65))
+[GOOD] (define-fun s227 () Int (ite s223 s61 s226))
+[GOOD] (define-fun s228 () Int (ite s221 s58 s227))
+[GOOD] (define-fun s229 () Int (ite s210 s52 s228))
+[GOOD] (define-fun s230 () Int (ite s217 s51 s229))
+[GOOD] (define-fun s231 () Int (ite s213 s44 s230))
+[GOOD] (define-fun s232 () Int (+ s209 s231))
+[GOOD] (define-fun s233 () Bool ((as is-Var Bool) s8))
+[GOOD] (define-fun s234 () String (getVar_1 s8))
+[GOOD] (define-fun s235 () Bool (= s41 s234))
+[GOOD] (define-fun s236 () Bool (and s233 s235))
+[GOOD] (define-fun s237 () Bool (= s45 s234))
+[GOOD] (define-fun s238 () Bool (= s47 s234))
+[GOOD] (define-fun s239 () Bool (or s237 s238))
+[GOOD] (define-fun s240 () Bool (and s233 s239))
+[GOOD] (define-fun s241 () Bool ((as is-Val Bool) s8))
+[GOOD] (define-fun s242 () Int (getVal_1 s8))
+[GOOD] (define-fun s243 () Bool (< s242 s55))
+[GOOD] (define-fun s244 () Bool (and s241 s243))
+[GOOD] (define-fun s245 () Bool (= s55 s242))
+[GOOD] (define-fun s246 () Bool (and s241 s245))
+[GOOD] (define-fun s247 () Bool (> s242 s55))
+[GOOD] (define-fun s248 () Bool (and s241 s247))
+[GOOD] (define-fun s249 () Int (ite s248 s64 s65))
+[GOOD] (define-fun s250 () Int (ite s246 s61 s249))
+[GOOD] (define-fun s251 () Int (ite s244 s58 s250))
+[GOOD] (define-fun s252 () Int (ite s233 s52 s251))
+[GOOD] (define-fun s253 () Int (ite s240 s51 s252))
+[GOOD] (define-fun s254 () Int (ite s236 s44 s253))
+[GOOD] (define-fun s255 () Int (+ s232 s254))
+[GOOD] (define-fun s256 () Bool ((as is-Var Bool) s9))
+[GOOD] (define-fun s257 () String (getVar_1 s9))
+[GOOD] (define-fun s258 () Bool (= s41 s257))
+[GOOD] (define-fun s259 () Bool (and s256 s258))
+[GOOD] (define-fun s260 () Bool (= s45 s257))
+[GOOD] (define-fun s261 () Bool (= s47 s257))
+[GOOD] (define-fun s262 () Bool (or s260 s261))
+[GOOD] (define-fun s263 () Bool (and s256 s262))
+[GOOD] (define-fun s264 () Bool ((as is-Val Bool) s9))
+[GOOD] (define-fun s265 () Int (getVal_1 s9))
+[GOOD] (define-fun s266 () Bool (< s265 s55))
+[GOOD] (define-fun s267 () Bool (and s264 s266))
+[GOOD] (define-fun s268 () Bool (= s55 s265))
+[GOOD] (define-fun s269 () Bool (and s264 s268))
+[GOOD] (define-fun s270 () Bool (> s265 s55))
+[GOOD] (define-fun s271 () Bool (and s264 s270))
+[GOOD] (define-fun s272 () Int (ite s271 s64 s65))
+[GOOD] (define-fun s273 () Int (ite s269 s61 s272))
+[GOOD] (define-fun s274 () Int (ite s267 s58 s273))
+[GOOD] (define-fun s275 () Int (ite s256 s52 s274))
+[GOOD] (define-fun s276 () Int (ite s263 s51 s275))
+[GOOD] (define-fun s277 () Int (ite s259 s44 s276))
+[GOOD] (define-fun s278 () Int (+ s255 s277))
+[GOOD] (define-fun s280 () Bool (distinct s278 s279))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s38)
+[GOOD] (assert s280)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr12c.gold b/SBVTestSuite/GoldFiles/adt_pexpr12c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr12c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr13.gold b/SBVTestSuite/GoldFiles/adt_pexpr13.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr13.gold
@@ -0,0 +1,75 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (Expr String Int) ((as Val (Expr String Int)) 3))
+[GOOD] (define-fun s5 () String "a")
+[GOOD] (define-fun s8 () Int 0)
+[GOOD] (define-fun s9 () String "b")
+[GOOD] (define-fun s11 () String "c")
+[GOOD] (define-fun s15 () Int 1)
+[GOOD] (define-fun s16 () Int 2)
+[GOOD] (define-fun s19 () Int 10)
+[GOOD] (define-fun s22 () Int 3)
+[GOOD] (define-fun s25 () Int 4)
+[GOOD] (define-fun s28 () Int 5)
+[GOOD] (define-fun s29 () Int 6)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int))
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s4 () String (getVar_1 s0))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool (and s3 s6))
+[GOOD] (define-fun s10 () Bool (= s4 s9))
+[GOOD] (define-fun s12 () Bool (= s4 s11))
+[GOOD] (define-fun s13 () Bool (or s10 s12))
+[GOOD] (define-fun s14 () Bool (and s3 s13))
+[GOOD] (define-fun s17 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s18 () Int (getVal_1 s0))
+[GOOD] (define-fun s20 () Bool (< s18 s19))
+[GOOD] (define-fun s21 () Bool (and s17 s20))
+[GOOD] (define-fun s23 () Bool (= s18 s19))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s26 () Bool (> s18 s19))
+[GOOD] (define-fun s27 () Bool (and s17 s26))
+[GOOD] (define-fun s30 () Int (ite s27 s28 s29))
+[GOOD] (define-fun s31 () Int (ite s24 s25 s30))
+[GOOD] (define-fun s32 () Int (ite s21 s22 s31))
+[GOOD] (define-fun s33 () Int (ite s3 s16 s32))
+[GOOD] (define-fun s34 () Int (ite s14 s15 s33))
+[GOOD] (define-fun s35 () Int (ite s7 s8 s34))
+[GOOD] (define-fun s36 () Bool (distinct s22 s35))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s36)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr13c.gold b/SBVTestSuite/GoldFiles/adt_pexpr13c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr13c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr14.gold b/SBVTestSuite/GoldFiles/adt_pexpr14.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr14.gold
@@ -0,0 +1,75 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (Expr String Int) ((as Add (Expr String Int)) ((as Val (Expr String Int)) 3) ((as Val (Expr String Int)) 4)))
+[GOOD] (define-fun s5 () String "a")
+[GOOD] (define-fun s8 () Int 0)
+[GOOD] (define-fun s9 () String "b")
+[GOOD] (define-fun s11 () String "c")
+[GOOD] (define-fun s15 () Int 1)
+[GOOD] (define-fun s16 () Int 2)
+[GOOD] (define-fun s19 () Int 10)
+[GOOD] (define-fun s22 () Int 3)
+[GOOD] (define-fun s25 () Int 4)
+[GOOD] (define-fun s28 () Int 5)
+[GOOD] (define-fun s29 () Int 6)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int))
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s4 () String (getVar_1 s0))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool (and s3 s6))
+[GOOD] (define-fun s10 () Bool (= s4 s9))
+[GOOD] (define-fun s12 () Bool (= s4 s11))
+[GOOD] (define-fun s13 () Bool (or s10 s12))
+[GOOD] (define-fun s14 () Bool (and s3 s13))
+[GOOD] (define-fun s17 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s18 () Int (getVal_1 s0))
+[GOOD] (define-fun s20 () Bool (< s18 s19))
+[GOOD] (define-fun s21 () Bool (and s17 s20))
+[GOOD] (define-fun s23 () Bool (= s18 s19))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s26 () Bool (> s18 s19))
+[GOOD] (define-fun s27 () Bool (and s17 s26))
+[GOOD] (define-fun s30 () Int (ite s27 s28 s29))
+[GOOD] (define-fun s31 () Int (ite s24 s25 s30))
+[GOOD] (define-fun s32 () Int (ite s21 s22 s31))
+[GOOD] (define-fun s33 () Int (ite s3 s16 s32))
+[GOOD] (define-fun s34 () Int (ite s14 s15 s33))
+[GOOD] (define-fun s35 () Int (ite s7 s8 s34))
+[GOOD] (define-fun s36 () Bool (distinct s29 s35))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s36)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr14c.gold b/SBVTestSuite/GoldFiles/adt_pexpr14c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr14c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr15.gold b/SBVTestSuite/GoldFiles/adt_pexpr15.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr15.gold
@@ -0,0 +1,75 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (Expr String Int) ((as Mul (Expr String Int)) ((as Val (Expr String Int)) 3) ((as Add (Expr String Int)) ((as Val (Expr String Int)) 3) ((as Val (Expr String Int)) 4))))
+[GOOD] (define-fun s5 () String "a")
+[GOOD] (define-fun s8 () Int 0)
+[GOOD] (define-fun s9 () String "b")
+[GOOD] (define-fun s11 () String "c")
+[GOOD] (define-fun s15 () Int 1)
+[GOOD] (define-fun s16 () Int 2)
+[GOOD] (define-fun s19 () Int 10)
+[GOOD] (define-fun s22 () Int 3)
+[GOOD] (define-fun s25 () Int 4)
+[GOOD] (define-fun s28 () Int 5)
+[GOOD] (define-fun s29 () Int 6)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int))
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s4 () String (getVar_1 s0))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool (and s3 s6))
+[GOOD] (define-fun s10 () Bool (= s4 s9))
+[GOOD] (define-fun s12 () Bool (= s4 s11))
+[GOOD] (define-fun s13 () Bool (or s10 s12))
+[GOOD] (define-fun s14 () Bool (and s3 s13))
+[GOOD] (define-fun s17 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s18 () Int (getVal_1 s0))
+[GOOD] (define-fun s20 () Bool (< s18 s19))
+[GOOD] (define-fun s21 () Bool (and s17 s20))
+[GOOD] (define-fun s23 () Bool (= s18 s19))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s26 () Bool (> s18 s19))
+[GOOD] (define-fun s27 () Bool (and s17 s26))
+[GOOD] (define-fun s30 () Int (ite s27 s28 s29))
+[GOOD] (define-fun s31 () Int (ite s24 s25 s30))
+[GOOD] (define-fun s32 () Int (ite s21 s22 s31))
+[GOOD] (define-fun s33 () Int (ite s3 s16 s32))
+[GOOD] (define-fun s34 () Int (ite s14 s15 s33))
+[GOOD] (define-fun s35 () Int (ite s7 s8 s34))
+[GOOD] (define-fun s36 () Bool (distinct s29 s35))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s36)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr15c.gold b/SBVTestSuite/GoldFiles/adt_pexpr15c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr15c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr16.gold b/SBVTestSuite/GoldFiles/adt_pexpr16.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr16.gold
@@ -0,0 +1,75 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (Expr String Int) ((as Let (Expr String Int)) "a" ((as Mul (Expr String Int)) ((as Val (Expr String Int)) 3) ((as Add (Expr String Int)) ((as Val (Expr String Int)) 3) ((as Val (Expr String Int)) 4))) ((as Add (Expr String Int)) ((as Var (Expr String Int)) "a") ((as Add (Expr String Int)) ((as Val (Expr String Int)) 3) ((as Val (Expr String Int)) 4)))))
+[GOOD] (define-fun s5 () String "a")
+[GOOD] (define-fun s8 () Int 0)
+[GOOD] (define-fun s9 () String "b")
+[GOOD] (define-fun s11 () String "c")
+[GOOD] (define-fun s15 () Int 1)
+[GOOD] (define-fun s16 () Int 2)
+[GOOD] (define-fun s19 () Int 10)
+[GOOD] (define-fun s22 () Int 3)
+[GOOD] (define-fun s25 () Int 4)
+[GOOD] (define-fun s28 () Int 5)
+[GOOD] (define-fun s29 () Int 6)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int))
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s4 () String (getVar_1 s0))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool (and s3 s6))
+[GOOD] (define-fun s10 () Bool (= s4 s9))
+[GOOD] (define-fun s12 () Bool (= s4 s11))
+[GOOD] (define-fun s13 () Bool (or s10 s12))
+[GOOD] (define-fun s14 () Bool (and s3 s13))
+[GOOD] (define-fun s17 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s18 () Int (getVal_1 s0))
+[GOOD] (define-fun s20 () Bool (< s18 s19))
+[GOOD] (define-fun s21 () Bool (and s17 s20))
+[GOOD] (define-fun s23 () Bool (= s18 s19))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s26 () Bool (> s18 s19))
+[GOOD] (define-fun s27 () Bool (and s17 s26))
+[GOOD] (define-fun s30 () Int (ite s27 s28 s29))
+[GOOD] (define-fun s31 () Int (ite s24 s25 s30))
+[GOOD] (define-fun s32 () Int (ite s21 s22 s31))
+[GOOD] (define-fun s33 () Int (ite s3 s16 s32))
+[GOOD] (define-fun s34 () Int (ite s14 s15 s33))
+[GOOD] (define-fun s35 () Int (ite s7 s8 s34))
+[GOOD] (define-fun s36 () Bool (distinct s29 s35))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s36)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr16c.gold b/SBVTestSuite/GoldFiles/adt_pexpr16c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr16c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr17.gold b/SBVTestSuite/GoldFiles/adt_pexpr17.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr17.gold
@@ -0,0 +1,75 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (Expr String Int) ((as Add (Expr String Int)) ((as Let (Expr String Int)) "a" ((as Mul (Expr String Int)) ((as Val (Expr String Int)) 3) ((as Add (Expr String Int)) ((as Val (Expr String Int)) 3) ((as Val (Expr String Int)) 4))) ((as Add (Expr String Int)) ((as Var (Expr String Int)) "a") ((as Add (Expr String Int)) ((as Val (Expr String Int)) 3) ((as Val (Expr String Int)) 4)))) ((as Let (Expr String Int)) "a" ((as Let (Expr String Int)) "a" ((as Mul (Expr String Int)) ((as Val (Expr String Int)) 3) ((as Add (Expr String Int)) ((as Val (Expr String Int)) 3) ((as Val (Expr String Int)) 4))) ((as Add (Expr String Int)) ((as Var (Expr String Int)) "a") ((as Add (Expr String Int)) ((as Val (Expr String Int)) 3) ((as Val (Expr String Int)) 4)))) ((as Add (Expr String Int)) ((as Var (Expr String Int)) "a") ((as Add (Expr String Int)) ((as Val (Expr String Int)) 3) ((as Val (Expr String Int)) 4))))))
+[GOOD] (define-fun s5 () String "a")
+[GOOD] (define-fun s8 () Int 0)
+[GOOD] (define-fun s9 () String "b")
+[GOOD] (define-fun s11 () String "c")
+[GOOD] (define-fun s15 () Int 1)
+[GOOD] (define-fun s16 () Int 2)
+[GOOD] (define-fun s19 () Int 10)
+[GOOD] (define-fun s22 () Int 3)
+[GOOD] (define-fun s25 () Int 4)
+[GOOD] (define-fun s28 () Int 5)
+[GOOD] (define-fun s29 () Int 6)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int))
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s4 () String (getVar_1 s0))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool (and s3 s6))
+[GOOD] (define-fun s10 () Bool (= s4 s9))
+[GOOD] (define-fun s12 () Bool (= s4 s11))
+[GOOD] (define-fun s13 () Bool (or s10 s12))
+[GOOD] (define-fun s14 () Bool (and s3 s13))
+[GOOD] (define-fun s17 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s18 () Int (getVal_1 s0))
+[GOOD] (define-fun s20 () Bool (< s18 s19))
+[GOOD] (define-fun s21 () Bool (and s17 s20))
+[GOOD] (define-fun s23 () Bool (= s18 s19))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s26 () Bool (> s18 s19))
+[GOOD] (define-fun s27 () Bool (and s17 s26))
+[GOOD] (define-fun s30 () Int (ite s27 s28 s29))
+[GOOD] (define-fun s31 () Int (ite s24 s25 s30))
+[GOOD] (define-fun s32 () Int (ite s21 s22 s31))
+[GOOD] (define-fun s33 () Int (ite s3 s16 s32))
+[GOOD] (define-fun s34 () Int (ite s14 s15 s33))
+[GOOD] (define-fun s35 () Int (ite s7 s8 s34))
+[GOOD] (define-fun s36 () Bool (distinct s29 s35))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s36)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr17c.gold b/SBVTestSuite/GoldFiles/adt_pexpr17c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr17c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr18.gold b/SBVTestSuite/GoldFiles/adt_pexpr18.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr18.gold
@@ -0,0 +1,75 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (Expr String Int) ((as Let (Expr String Int)) "a" ((as Add (Expr String Int)) ((as Let (Expr String Int)) "a" ((as Mul (Expr String Int)) ((as Val (Expr String Int)) 3) ((as Add (Expr String Int)) ((as Val (Expr String Int)) 3) ((as Val (Expr String Int)) 4))) ((as Add (Expr String Int)) ((as Var (Expr String Int)) "a") ((as Add (Expr String Int)) ((as Val (Expr String Int)) 3) ((as Val (Expr String Int)) 4)))) ((as Let (Expr String Int)) "a" ((as Let (Expr String Int)) "a" ((as Mul (Expr String Int)) ((as Val (Expr String Int)) 3) ((as Add (Expr String Int)) ((as Val (Expr String Int)) 3) ((as Val (Expr String Int)) 4))) ((as Add (Expr String Int)) ((as Var (Expr String Int)) "a") ((as Add (Expr String Int)) ((as Val (Expr String Int)) 3) ((as Val (Expr String Int)) 4)))) ((as Add (Expr String Int)) ((as Var (Expr String Int)) "a") ((as Add (Expr String Int)) ((as Val (Expr String Int)) 3) ((as Val (Expr String Int)) 4))))) ((as Mul (Expr String Int)) ((as Var (Expr String Int)) "a") ((as Var (Expr String Int)) "a"))))
+[GOOD] (define-fun s5 () String "a")
+[GOOD] (define-fun s8 () Int 0)
+[GOOD] (define-fun s9 () String "b")
+[GOOD] (define-fun s11 () String "c")
+[GOOD] (define-fun s15 () Int 1)
+[GOOD] (define-fun s16 () Int 2)
+[GOOD] (define-fun s19 () Int 10)
+[GOOD] (define-fun s22 () Int 3)
+[GOOD] (define-fun s25 () Int 4)
+[GOOD] (define-fun s28 () Int 5)
+[GOOD] (define-fun s29 () Int 6)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int))
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s4 () String (getVar_1 s0))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool (and s3 s6))
+[GOOD] (define-fun s10 () Bool (= s4 s9))
+[GOOD] (define-fun s12 () Bool (= s4 s11))
+[GOOD] (define-fun s13 () Bool (or s10 s12))
+[GOOD] (define-fun s14 () Bool (and s3 s13))
+[GOOD] (define-fun s17 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s18 () Int (getVal_1 s0))
+[GOOD] (define-fun s20 () Bool (< s18 s19))
+[GOOD] (define-fun s21 () Bool (and s17 s20))
+[GOOD] (define-fun s23 () Bool (= s18 s19))
+[GOOD] (define-fun s24 () Bool (and s17 s23))
+[GOOD] (define-fun s26 () Bool (> s18 s19))
+[GOOD] (define-fun s27 () Bool (and s17 s26))
+[GOOD] (define-fun s30 () Int (ite s27 s28 s29))
+[GOOD] (define-fun s31 () Int (ite s24 s25 s30))
+[GOOD] (define-fun s32 () Int (ite s21 s22 s31))
+[GOOD] (define-fun s33 () Int (ite s3 s16 s32))
+[GOOD] (define-fun s34 () Int (ite s14 s15 s33))
+[GOOD] (define-fun s35 () Int (ite s7 s8 s34))
+[GOOD] (define-fun s36 () Bool (distinct s29 s35))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s36)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr18c.gold b/SBVTestSuite/GoldFiles/adt_pexpr18c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr18c.gold
@@ -0,0 +1,25 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; external query, using all logics.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+All good.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr19.gold b/SBVTestSuite/GoldFiles/adt_pexpr19.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr19.gold
@@ -0,0 +1,41 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr Int (_ BitVec 8))) ; tracks user variable "x"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Let Bool) s0))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s1)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (Let 2 (Var 3) (Var 4))))
+Result: (let 2 = 3 in 4)
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr20.gold b/SBVTestSuite/GoldFiles/adt_pexpr20.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr20.gold
@@ -0,0 +1,51 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has rational values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] (declare-datatype SBVRational ((SBV.Rational (sbv.rat.numerator Int) (sbv.rat.denominator Int))))
+
+[GOOD] (define-fun sbv.rat.eq ((x SBVRational) (y SBVRational)) Bool
+          (= (* (sbv.rat.numerator   x) (sbv.rat.denominator y))
+             (* (sbv.rat.denominator x) (sbv.rat.numerator   y)))
+       )
+
+[GOOD] (define-fun sbv.rat.notEq ((x SBVRational) (y SBVRational)) Bool
+          (not (sbv.rat.eq x y))
+       )
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr (_ BitVec 8) SBVRational)) ; tracks user variable "x"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Mul Bool) s0))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s1)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (Mul (Var #x00) (Var #x00))))
+Result: (0 * 0)
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pexpr21.gold b/SBVTestSuite/GoldFiles/adt_pexpr21.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pexpr21.gold
@@ -0,0 +1,52 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] (declare-datatypes ((SBVEither 2)) ((par (T1 T2)
+                                           ((left_SBVEither  (get_left_SBVEither  T1))
+                                            (right_SBVEither (get_right_SBVEither T2))))))
+[GOOD] (declare-datatypes ((SBVMaybe 1)) ((par (T)
+                                           ((nothing_SBVMaybe)
+                                            (just_SBVMaybe (get_just_SBVMaybe T))))))
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr (SBVMaybe (SBVTuple2 Int String)) (SBVEither (_ BitVec 8) (_ BitVec 16)))) ; tracks user variable "x"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Let Bool) s0))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s1)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (Let nothing_SBVMaybe
+            (Val (right_SBVEither #x0000))
+            (Val (right_SBVEither #x0000)))))
+Result: (let Nothing = Right 0 in Right 0)
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pgen00.gold b/SBVTestSuite/GoldFiles/adt_pgen00.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pgen00.gold
@@ -0,0 +1,284 @@
+[MEASURE] Verifying termination measures for: eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer), eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer), get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer), valid @(SBV [[Char]] -> SBV (Expr [Char] Integer) -> SBV Bool)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): not in a multi-member cycle, skipping mutual check
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)
+[MEASURE] Checking: eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): barified = "|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|"
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2),("|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)|",2)]
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): recursive calls found = 6
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): trying sbv.dt.size.Expr arg2
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): sbv.dt.size.Expr arg2 -> OK (structural recursion)
+[MEASURE] eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer): sbv.dt.size.Expr arg2 -> OK
+[MEASURE] Passed (terminating): eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)
+[MEASURE] Checking: get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): barified = "|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|"
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): Uninterpreted ops in DAG: [("|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|",2)]
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): recursive calls found = 1
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): trying length arg1
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Bool (>= s4 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 String Int))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () String) ; tracks user variable "arg1"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () (SBVTuple2 String Int) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () String (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool (and s6 s9))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s12 () Int (- s4 s3))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 String Int)) (seq.extract s0 s3 s12))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Int (ite s5 s2 s15))
+[GOOD] (define-fun s17 () Int (seq.len s13))
+[GOOD] (define-fun s18 () Bool (not s10))
+[GOOD] (define-fun s19 () Bool (and s6 s18))
+[GOOD] (define-fun s20 () Bool (> s4 s17))
+[GOOD] (define-fun s21 () Bool (=> s19 s20))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer): length arg1 -> OK
+[MEASURE] Passed (terminating): get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)
+[MEASURE] Checking: valid @(SBV [[Char]] -> SBV (Expr [Char] Integer) -> SBV Bool)
+[MEASURE] valid @(SBV [[Char]] -> SBV (Expr [Char] Integer) -> SBV Bool): barified = "|valid @(SBV [[Char]] -> SBV (Expr [Char] Integer) -> SBV Bool)|"
+[MEASURE] valid @(SBV [[Char]] -> SBV (Expr [Char] Integer) -> SBV Bool): Uninterpreted ops in DAG: [("|valid @(SBV [[Char]] -> SBV (Expr [Char] Integer) -> SBV Bool)|",2),("|valid @(SBV [[Char]] -> SBV (Expr [Char] Integer) -> SBV Bool)|",2),("|valid @(SBV [[Char]] -> SBV (Expr [Char] Integer) -> SBV Bool)|",2),("|valid @(SBV [[Char]] -> SBV (Expr [Char] Integer) -> SBV Bool)|",2),("|valid @(SBV [[Char]] -> SBV (Expr [Char] Integer) -> SBV Bool)|",2),("|valid @(SBV [[Char]] -> SBV (Expr [Char] Integer) -> SBV Bool)|",2)]
+[MEASURE] valid @(SBV [[Char]] -> SBV (Expr [Char] Integer) -> SBV Bool): recursive calls found = 6
+[MEASURE] valid @(SBV [[Char]] -> SBV (Expr [Char] Integer) -> SBV Bool): trying sbv.dt.size.Expr arg2
+[MEASURE] valid @(SBV [[Char]] -> SBV (Expr [Char] Integer) -> SBV Bool): sbv.dt.size.Expr arg2 -> OK (structural recursion)
+[MEASURE] valid @(SBV [[Char]] -> SBV (Expr [Char] Integer) -> SBV Bool): sbv.dt.size.Expr arg2 -> OK
+[MEASURE] Passed (terminating): valid @(SBV [[Char]] -> SBV (Expr [Char] Integer) -> SBV Bool)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (Seq String) (as seq.empty (Seq String)))
+[GOOD] (define-fun s3 () (Seq (SBVTuple2 String Int)) (as seq.empty (Seq (SBVTuple2 String Int))))
+[GOOD] (define-fun s5 () Int 12)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int)) ; tracks user variable "a"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |valid @(SBV [[Char]] -> SBV (Expr [Char] Integer) -> SBV Bool)| :: [SString] -> Expr String Integer -> SBool [Recursive]
+[GOOD] (define-fun-rec |valid @(SBV [[Char]] -> SBV (Expr [Char] Integer) -> SBV Bool)| ((l1_s0 (Seq String)) (l1_s1 (Expr String Int))) Bool
+                                 (let ((l1_s2 ((as is-Val Bool) l1_s1)))
+                                 (let ((l1_s3 ((as is-Var Bool) l1_s1)))
+                                 (let ((l1_s4 (getVar_1 l1_s1)))
+                                 (let ((l1_s5 (str.in_re l1_s4 (re.++ (re.range "a" "z") (re.* (re.union (re.range "a" "z") (re.range "A" "Z") (re.range "0" "9")))))))
+                                 (let ((l1_s6 (seq.unit l1_s4)))
+                                 (let ((l1_s7 (seq.contains l1_s0 l1_s6)))
+                                 (let ((l1_s8 (and l1_s5 l1_s7)))
+                                 (let ((l1_s9 ((as is-Add Bool) l1_s1)))
+                                 (let ((l1_s10 (getAdd_1 l1_s1)))
+                                 (let ((l1_s11 (|valid @(SBV [[Char]] -> SBV (Expr [Char] Integer) -> SBV Bool)| l1_s0 l1_s10)))
+                                 (let ((l1_s12 (getAdd_2 l1_s1)))
+                                 (let ((l1_s13 (|valid @(SBV [[Char]] -> SBV (Expr [Char] Integer) -> SBV Bool)| l1_s0 l1_s12)))
+                                 (let ((l1_s14 (and l1_s11 l1_s13)))
+                                 (let ((l1_s15 ((as is-Mul Bool) l1_s1)))
+                                 (let ((l1_s16 (getMul_1 l1_s1)))
+                                 (let ((l1_s17 (|valid @(SBV [[Char]] -> SBV (Expr [Char] Integer) -> SBV Bool)| l1_s0 l1_s16)))
+                                 (let ((l1_s18 (getMul_2 l1_s1)))
+                                 (let ((l1_s19 (|valid @(SBV [[Char]] -> SBV (Expr [Char] Integer) -> SBV Bool)| l1_s0 l1_s18)))
+                                 (let ((l1_s20 (and l1_s17 l1_s19)))
+                                 (let ((l1_s21 (getLet_1 l1_s1)))
+                                 (let ((l1_s22 (str.in_re l1_s21 (re.++ (re.range "a" "z") (re.* (re.union (re.range "a" "z") (re.range "A" "Z") (re.range "0" "9")))))))
+                                 (let ((l1_s23 (getLet_2 l1_s1)))
+                                 (let ((l1_s24 (|valid @(SBV [[Char]] -> SBV (Expr [Char] Integer) -> SBV Bool)| l1_s0 l1_s23)))
+                                 (let ((l1_s25 (seq.unit l1_s21)))
+                                 (let ((l1_s26 (seq.++ l1_s25 l1_s0)))
+                                 (let ((l1_s27 (getLet_3 l1_s1)))
+                                 (let ((l1_s28 (|valid @(SBV [[Char]] -> SBV (Expr [Char] Integer) -> SBV Bool)| l1_s26 l1_s27)))
+                                 (let ((l1_s29 (and l1_s24 l1_s28)))
+                                 (let ((l1_s30 (and l1_s22 l1_s29)))
+                                 (let ((l1_s31 (ite l1_s15 l1_s20 l1_s30)))
+                                 (let ((l1_s32 (ite l1_s9 l1_s14 l1_s31)))
+                                 (let ((l1_s33 (ite l1_s3 l1_s8 l1_s32)))
+                                 (let ((l1_s34 (or l1_s2 l1_s33)))
+                                 l1_s34))))))))))))))))))))))))))))))))))
+[GOOD] ; |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| :: [(SString, SInteger)] -> SString -> SInteger [Recursive]
+[GOOD] (define-fun-rec |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| ((l2_s0 (Seq (SBVTuple2 String Int))) (l2_s1 String)) Int
+                                                 (let ((l2_s3 0))
+                                                 (let ((l2_s11 1))
+                                                 (let ((l2_s2 (seq.len l2_s0)))
+                                                 (let ((l2_s4 (= l2_s2 l2_s3)))
+                                                 (let ((l2_s5 (not l2_s4)))
+                                                 (let ((l2_s6 (seq.nth l2_s0 l2_s3)))
+                                                 (let ((l2_s7 (proj_1_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s8 (= l2_s1 l2_s7)))
+                                                 (let ((l2_s9 (and l2_s5 l2_s8)))
+                                                 (let ((l2_s10 (proj_2_SBVTuple2 l2_s6)))
+                                                 (let ((l2_s12 (- l2_s2 l2_s11)))
+                                                 (let ((l2_s13 (seq.extract l2_s0 l2_s11 l2_s12)))
+                                                 (let ((l2_s14 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l2_s13 l2_s1)))
+                                                 (let ((l2_s15 (ite l2_s9 l2_s10 l2_s14)))
+                                                 (let ((l2_s16 (ite l2_s4 l2_s3 l2_s15)))
+                                                 l2_s16))))))))))))))))
+[GOOD] ; |eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| :: [(SString, SInteger)] -> Expr String Integer -> SInteger [Recursive] [Refers to: |get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)|]
+[GOOD] (define-fun-rec |eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| ((l1_s0 (Seq (SBVTuple2 String Int))) (l1_s1 (Expr String Int))) Int
+                                 (let ((l1_s2 ((as is-Val Bool) l1_s1)))
+                                 (let ((l1_s3 (getVal_1 l1_s1)))
+                                 (let ((l1_s4 ((as is-Var Bool) l1_s1)))
+                                 (let ((l1_s5 (getVar_1 l1_s1)))
+                                 (let ((l1_s6 (|get @(SBV [([Char],Integer)] -> SBV [Char] -> SBV Integer)| l1_s0 l1_s5)))
+                                 (let ((l1_s7 ((as is-Add Bool) l1_s1)))
+                                 (let ((l1_s8 (getAdd_1 l1_s1)))
+                                 (let ((l1_s9 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s0 l1_s8)))
+                                 (let ((l1_s10 (getAdd_2 l1_s1)))
+                                 (let ((l1_s11 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s0 l1_s10)))
+                                 (let ((l1_s12 (+ l1_s9 l1_s11)))
+                                 (let ((l1_s13 ((as is-Mul Bool) l1_s1)))
+                                 (let ((l1_s14 (getMul_1 l1_s1)))
+                                 (let ((l1_s15 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s0 l1_s14)))
+                                 (let ((l1_s16 (getMul_2 l1_s1)))
+                                 (let ((l1_s17 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s0 l1_s16)))
+                                 (let ((l1_s18 (* l1_s15 l1_s17)))
+                                 (let ((l1_s19 (getLet_1 l1_s1)))
+                                 (let ((l1_s20 (getLet_2 l1_s1)))
+                                 (let ((l1_s21 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s0 l1_s20)))
+                                 (let ((l1_s22 ((as mkSBVTuple2 (SBVTuple2 String Int)) l1_s19 l1_s21)))
+                                 (let ((l1_s23 (seq.unit l1_s22)))
+                                 (let ((l1_s24 (seq.++ l1_s23 l1_s0)))
+                                 (let ((l1_s25 (getLet_3 l1_s1)))
+                                 (let ((l1_s26 (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| l1_s24 l1_s25)))
+                                 (let ((l1_s27 (ite l1_s13 l1_s18 l1_s26)))
+                                 (let ((l1_s28 (ite l1_s7 l1_s12 l1_s27)))
+                                 (let ((l1_s29 (ite l1_s4 l1_s6 l1_s28)))
+                                 (let ((l1_s30 (ite l1_s2 l1_s3 l1_s29)))
+                                 l1_s30))))))))))))))))))))))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (|valid @(SBV [[Char]] -> SBV (Expr [Char] Integer) -> SBV Bool)| s1 s0))
+[GOOD] (define-fun s4 () Int (|eval @(SBV [([Char],Integer)] -> SBV (Expr [Char] Integer) -> SBV Integer)| s3 s0))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool ((as is-Let Bool) s0))
+[GOOD] (define-fun s8 () (Expr String Int) (getLet_3 s0))
+[GOOD] (define-fun s9 () Bool ((as is-Let Bool) s8))
+[GOOD] (define-fun s10 () (Expr String Int) (getLet_3 s8))
+[GOOD] (define-fun s11 () Bool ((as is-Add Bool) s10))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s6)
+[GOOD] (assert s7)
+[GOOD] (assert s9)
+[GOOD] (assert s11)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (Let "a"
+            (Let "t" (Val (- 3)) (Var "t"))
+            (Let "k"
+                 (Mul (Val 7) (Var "a"))
+                 (Add (Val 12)
+                      (Mul (Mul (Val 4) (Val 3))
+                           (Mul (Var "k")
+                                (Mul (Val 5)
+                                     (Add (Add (Val 6) (Var "k"))
+                                          (Let "l" (Var "k") (Val 15)))))))))))
+
+Got: (let a = (let t = -3 in t) in (let k = (7 * a) in (12 + ((4 * 3) * (k * (5 * ((6 + k) + (let l = k in 15))))))))
+DONE
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pgen01.gold b/SBVTestSuite/GoldFiles/adt_pgen01.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pgen01.gold
@@ -0,0 +1,83 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () String "a")
+[GOOD] (define-fun s6 () Int 0)
+[GOOD] (define-fun s7 () String "b")
+[GOOD] (define-fun s9 () String "c")
+[GOOD] (define-fun s13 () Int 1)
+[GOOD] (define-fun s14 () Int 2)
+[GOOD] (define-fun s17 () Int 10)
+[GOOD] (define-fun s20 () Int 3)
+[GOOD] (define-fun s23 () Int 4)
+[GOOD] (define-fun s26 () Int 5)
+[GOOD] (define-fun s28 () Int 6)
+[GOOD] (define-fun s30 () Int 7)
+[GOOD] (define-fun s32 () Int 8)
+[GOOD] (define-fun s33 () Int 100)
+[GOOD] (define-fun s43 () Int (- 1))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int)) ; tracks user variable "a"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s2 () String (getVar_1 s0))
+[GOOD] (define-fun s4 () Bool (= s2 s3))
+[GOOD] (define-fun s5 () Bool (and s1 s4))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s10 () Bool (= s2 s9))
+[GOOD] (define-fun s11 () Bool (or s8 s10))
+[GOOD] (define-fun s12 () Bool (and s1 s11))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s16 () Int (getVal_1 s0))
+[GOOD] (define-fun s18 () Bool (< s16 s17))
+[GOOD] (define-fun s19 () Bool (and s15 s18))
+[GOOD] (define-fun s21 () Bool (= s16 s17))
+[GOOD] (define-fun s22 () Bool (and s15 s21))
+[GOOD] (define-fun s24 () Bool (> s16 s17))
+[GOOD] (define-fun s25 () Bool (and s15 s24))
+[GOOD] (define-fun s27 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s29 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s31 () Bool ((as is-Let Bool) s0))
+[GOOD] (define-fun s34 () Int (ite s31 s32 s33))
+[GOOD] (define-fun s35 () Int (ite s29 s30 s34))
+[GOOD] (define-fun s36 () Int (ite s27 s28 s35))
+[GOOD] (define-fun s37 () Int (ite s25 s26 s36))
+[GOOD] (define-fun s38 () Int (ite s22 s23 s37))
+[GOOD] (define-fun s39 () Int (ite s19 s20 s38))
+[GOOD] (define-fun s40 () Int (ite s1 s14 s39))
+[GOOD] (define-fun s41 () Int (ite s12 s13 s40))
+[GOOD] (define-fun s42 () Int (ite s5 s6 s41))
+[GOOD] (define-fun s44 () Bool (= s42 s43))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s44)
+[SEND] (check-sat)
+[RECV] unsat
+
+UNSAT
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pgen02.gold b/SBVTestSuite/GoldFiles/adt_pgen02.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pgen02.gold
@@ -0,0 +1,85 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () String "a")
+[GOOD] (define-fun s6 () Int 0)
+[GOOD] (define-fun s7 () String "b")
+[GOOD] (define-fun s9 () String "c")
+[GOOD] (define-fun s13 () Int 1)
+[GOOD] (define-fun s14 () Int 2)
+[GOOD] (define-fun s17 () Int 10)
+[GOOD] (define-fun s20 () Int 3)
+[GOOD] (define-fun s23 () Int 4)
+[GOOD] (define-fun s26 () Int 5)
+[GOOD] (define-fun s28 () Int 6)
+[GOOD] (define-fun s30 () Int 7)
+[GOOD] (define-fun s32 () Int 8)
+[GOOD] (define-fun s33 () Int 100)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int)) ; tracks user variable "a"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s2 () String (getVar_1 s0))
+[GOOD] (define-fun s4 () Bool (= s2 s3))
+[GOOD] (define-fun s5 () Bool (and s1 s4))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s10 () Bool (= s2 s9))
+[GOOD] (define-fun s11 () Bool (or s8 s10))
+[GOOD] (define-fun s12 () Bool (and s1 s11))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s16 () Int (getVal_1 s0))
+[GOOD] (define-fun s18 () Bool (< s16 s17))
+[GOOD] (define-fun s19 () Bool (and s15 s18))
+[GOOD] (define-fun s21 () Bool (= s16 s17))
+[GOOD] (define-fun s22 () Bool (and s15 s21))
+[GOOD] (define-fun s24 () Bool (> s16 s17))
+[GOOD] (define-fun s25 () Bool (and s15 s24))
+[GOOD] (define-fun s27 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s29 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s31 () Bool ((as is-Let Bool) s0))
+[GOOD] (define-fun s34 () Int (ite s31 s32 s33))
+[GOOD] (define-fun s35 () Int (ite s29 s30 s34))
+[GOOD] (define-fun s36 () Int (ite s27 s28 s35))
+[GOOD] (define-fun s37 () Int (ite s25 s26 s36))
+[GOOD] (define-fun s38 () Int (ite s22 s23 s37))
+[GOOD] (define-fun s39 () Int (ite s19 s20 s38))
+[GOOD] (define-fun s40 () Int (ite s1 s14 s39))
+[GOOD] (define-fun s41 () Int (ite s12 s13 s40))
+[GOOD] (define-fun s42 () Int (ite s5 s6 s41))
+[GOOD] (define-fun s43 () Bool (= s6 s42))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s43)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (Var "a")))
+
+Got: a
+DONE
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pgen03.gold b/SBVTestSuite/GoldFiles/adt_pgen03.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pgen03.gold
@@ -0,0 +1,85 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () String "a")
+[GOOD] (define-fun s6 () Int 0)
+[GOOD] (define-fun s7 () String "b")
+[GOOD] (define-fun s9 () String "c")
+[GOOD] (define-fun s13 () Int 1)
+[GOOD] (define-fun s14 () Int 2)
+[GOOD] (define-fun s17 () Int 10)
+[GOOD] (define-fun s20 () Int 3)
+[GOOD] (define-fun s23 () Int 4)
+[GOOD] (define-fun s26 () Int 5)
+[GOOD] (define-fun s28 () Int 6)
+[GOOD] (define-fun s30 () Int 7)
+[GOOD] (define-fun s32 () Int 8)
+[GOOD] (define-fun s33 () Int 100)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int)) ; tracks user variable "a"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s2 () String (getVar_1 s0))
+[GOOD] (define-fun s4 () Bool (= s2 s3))
+[GOOD] (define-fun s5 () Bool (and s1 s4))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s10 () Bool (= s2 s9))
+[GOOD] (define-fun s11 () Bool (or s8 s10))
+[GOOD] (define-fun s12 () Bool (and s1 s11))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s16 () Int (getVal_1 s0))
+[GOOD] (define-fun s18 () Bool (< s16 s17))
+[GOOD] (define-fun s19 () Bool (and s15 s18))
+[GOOD] (define-fun s21 () Bool (= s16 s17))
+[GOOD] (define-fun s22 () Bool (and s15 s21))
+[GOOD] (define-fun s24 () Bool (> s16 s17))
+[GOOD] (define-fun s25 () Bool (and s15 s24))
+[GOOD] (define-fun s27 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s29 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s31 () Bool ((as is-Let Bool) s0))
+[GOOD] (define-fun s34 () Int (ite s31 s32 s33))
+[GOOD] (define-fun s35 () Int (ite s29 s30 s34))
+[GOOD] (define-fun s36 () Int (ite s27 s28 s35))
+[GOOD] (define-fun s37 () Int (ite s25 s26 s36))
+[GOOD] (define-fun s38 () Int (ite s22 s23 s37))
+[GOOD] (define-fun s39 () Int (ite s19 s20 s38))
+[GOOD] (define-fun s40 () Int (ite s1 s14 s39))
+[GOOD] (define-fun s41 () Int (ite s12 s13 s40))
+[GOOD] (define-fun s42 () Int (ite s5 s6 s41))
+[GOOD] (define-fun s43 () Bool (= s13 s42))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s43)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (Var "b")))
+
+Got: b
+DONE
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pgen04.gold b/SBVTestSuite/GoldFiles/adt_pgen04.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pgen04.gold
@@ -0,0 +1,85 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () String "a")
+[GOOD] (define-fun s6 () Int 0)
+[GOOD] (define-fun s7 () String "b")
+[GOOD] (define-fun s9 () String "c")
+[GOOD] (define-fun s13 () Int 1)
+[GOOD] (define-fun s14 () Int 2)
+[GOOD] (define-fun s17 () Int 10)
+[GOOD] (define-fun s20 () Int 3)
+[GOOD] (define-fun s23 () Int 4)
+[GOOD] (define-fun s26 () Int 5)
+[GOOD] (define-fun s28 () Int 6)
+[GOOD] (define-fun s30 () Int 7)
+[GOOD] (define-fun s32 () Int 8)
+[GOOD] (define-fun s33 () Int 100)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int)) ; tracks user variable "a"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s2 () String (getVar_1 s0))
+[GOOD] (define-fun s4 () Bool (= s2 s3))
+[GOOD] (define-fun s5 () Bool (and s1 s4))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s10 () Bool (= s2 s9))
+[GOOD] (define-fun s11 () Bool (or s8 s10))
+[GOOD] (define-fun s12 () Bool (and s1 s11))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s16 () Int (getVal_1 s0))
+[GOOD] (define-fun s18 () Bool (< s16 s17))
+[GOOD] (define-fun s19 () Bool (and s15 s18))
+[GOOD] (define-fun s21 () Bool (= s16 s17))
+[GOOD] (define-fun s22 () Bool (and s15 s21))
+[GOOD] (define-fun s24 () Bool (> s16 s17))
+[GOOD] (define-fun s25 () Bool (and s15 s24))
+[GOOD] (define-fun s27 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s29 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s31 () Bool ((as is-Let Bool) s0))
+[GOOD] (define-fun s34 () Int (ite s31 s32 s33))
+[GOOD] (define-fun s35 () Int (ite s29 s30 s34))
+[GOOD] (define-fun s36 () Int (ite s27 s28 s35))
+[GOOD] (define-fun s37 () Int (ite s25 s26 s36))
+[GOOD] (define-fun s38 () Int (ite s22 s23 s37))
+[GOOD] (define-fun s39 () Int (ite s19 s20 s38))
+[GOOD] (define-fun s40 () Int (ite s1 s14 s39))
+[GOOD] (define-fun s41 () Int (ite s12 s13 s40))
+[GOOD] (define-fun s42 () Int (ite s5 s6 s41))
+[GOOD] (define-fun s43 () Bool (= s14 s42))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s43)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (Var "")))
+
+Got: 
+DONE
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pgen05.gold b/SBVTestSuite/GoldFiles/adt_pgen05.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pgen05.gold
@@ -0,0 +1,85 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () String "a")
+[GOOD] (define-fun s6 () Int 0)
+[GOOD] (define-fun s7 () String "b")
+[GOOD] (define-fun s9 () String "c")
+[GOOD] (define-fun s13 () Int 1)
+[GOOD] (define-fun s14 () Int 2)
+[GOOD] (define-fun s17 () Int 10)
+[GOOD] (define-fun s20 () Int 3)
+[GOOD] (define-fun s23 () Int 4)
+[GOOD] (define-fun s26 () Int 5)
+[GOOD] (define-fun s28 () Int 6)
+[GOOD] (define-fun s30 () Int 7)
+[GOOD] (define-fun s32 () Int 8)
+[GOOD] (define-fun s33 () Int 100)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int)) ; tracks user variable "a"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s2 () String (getVar_1 s0))
+[GOOD] (define-fun s4 () Bool (= s2 s3))
+[GOOD] (define-fun s5 () Bool (and s1 s4))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s10 () Bool (= s2 s9))
+[GOOD] (define-fun s11 () Bool (or s8 s10))
+[GOOD] (define-fun s12 () Bool (and s1 s11))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s16 () Int (getVal_1 s0))
+[GOOD] (define-fun s18 () Bool (< s16 s17))
+[GOOD] (define-fun s19 () Bool (and s15 s18))
+[GOOD] (define-fun s21 () Bool (= s16 s17))
+[GOOD] (define-fun s22 () Bool (and s15 s21))
+[GOOD] (define-fun s24 () Bool (> s16 s17))
+[GOOD] (define-fun s25 () Bool (and s15 s24))
+[GOOD] (define-fun s27 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s29 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s31 () Bool ((as is-Let Bool) s0))
+[GOOD] (define-fun s34 () Int (ite s31 s32 s33))
+[GOOD] (define-fun s35 () Int (ite s29 s30 s34))
+[GOOD] (define-fun s36 () Int (ite s27 s28 s35))
+[GOOD] (define-fun s37 () Int (ite s25 s26 s36))
+[GOOD] (define-fun s38 () Int (ite s22 s23 s37))
+[GOOD] (define-fun s39 () Int (ite s19 s20 s38))
+[GOOD] (define-fun s40 () Int (ite s1 s14 s39))
+[GOOD] (define-fun s41 () Int (ite s12 s13 s40))
+[GOOD] (define-fun s42 () Int (ite s5 s6 s41))
+[GOOD] (define-fun s43 () Bool (= s20 s42))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s43)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (Val 0)))
+
+Got: 0
+DONE
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pgen06.gold b/SBVTestSuite/GoldFiles/adt_pgen06.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pgen06.gold
@@ -0,0 +1,85 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () String "a")
+[GOOD] (define-fun s6 () Int 0)
+[GOOD] (define-fun s7 () String "b")
+[GOOD] (define-fun s9 () String "c")
+[GOOD] (define-fun s13 () Int 1)
+[GOOD] (define-fun s14 () Int 2)
+[GOOD] (define-fun s17 () Int 10)
+[GOOD] (define-fun s20 () Int 3)
+[GOOD] (define-fun s23 () Int 4)
+[GOOD] (define-fun s26 () Int 5)
+[GOOD] (define-fun s28 () Int 6)
+[GOOD] (define-fun s30 () Int 7)
+[GOOD] (define-fun s32 () Int 8)
+[GOOD] (define-fun s33 () Int 100)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int)) ; tracks user variable "a"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s2 () String (getVar_1 s0))
+[GOOD] (define-fun s4 () Bool (= s2 s3))
+[GOOD] (define-fun s5 () Bool (and s1 s4))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s10 () Bool (= s2 s9))
+[GOOD] (define-fun s11 () Bool (or s8 s10))
+[GOOD] (define-fun s12 () Bool (and s1 s11))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s16 () Int (getVal_1 s0))
+[GOOD] (define-fun s18 () Bool (< s16 s17))
+[GOOD] (define-fun s19 () Bool (and s15 s18))
+[GOOD] (define-fun s21 () Bool (= s16 s17))
+[GOOD] (define-fun s22 () Bool (and s15 s21))
+[GOOD] (define-fun s24 () Bool (> s16 s17))
+[GOOD] (define-fun s25 () Bool (and s15 s24))
+[GOOD] (define-fun s27 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s29 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s31 () Bool ((as is-Let Bool) s0))
+[GOOD] (define-fun s34 () Int (ite s31 s32 s33))
+[GOOD] (define-fun s35 () Int (ite s29 s30 s34))
+[GOOD] (define-fun s36 () Int (ite s27 s28 s35))
+[GOOD] (define-fun s37 () Int (ite s25 s26 s36))
+[GOOD] (define-fun s38 () Int (ite s22 s23 s37))
+[GOOD] (define-fun s39 () Int (ite s19 s20 s38))
+[GOOD] (define-fun s40 () Int (ite s1 s14 s39))
+[GOOD] (define-fun s41 () Int (ite s12 s13 s40))
+[GOOD] (define-fun s42 () Int (ite s5 s6 s41))
+[GOOD] (define-fun s43 () Bool (= s23 s42))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s43)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (Val 10)))
+
+Got: 10
+DONE
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pgen07.gold b/SBVTestSuite/GoldFiles/adt_pgen07.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pgen07.gold
@@ -0,0 +1,85 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () String "a")
+[GOOD] (define-fun s6 () Int 0)
+[GOOD] (define-fun s7 () String "b")
+[GOOD] (define-fun s9 () String "c")
+[GOOD] (define-fun s13 () Int 1)
+[GOOD] (define-fun s14 () Int 2)
+[GOOD] (define-fun s17 () Int 10)
+[GOOD] (define-fun s20 () Int 3)
+[GOOD] (define-fun s23 () Int 4)
+[GOOD] (define-fun s26 () Int 5)
+[GOOD] (define-fun s28 () Int 6)
+[GOOD] (define-fun s30 () Int 7)
+[GOOD] (define-fun s32 () Int 8)
+[GOOD] (define-fun s33 () Int 100)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int)) ; tracks user variable "a"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s2 () String (getVar_1 s0))
+[GOOD] (define-fun s4 () Bool (= s2 s3))
+[GOOD] (define-fun s5 () Bool (and s1 s4))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s10 () Bool (= s2 s9))
+[GOOD] (define-fun s11 () Bool (or s8 s10))
+[GOOD] (define-fun s12 () Bool (and s1 s11))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s16 () Int (getVal_1 s0))
+[GOOD] (define-fun s18 () Bool (< s16 s17))
+[GOOD] (define-fun s19 () Bool (and s15 s18))
+[GOOD] (define-fun s21 () Bool (= s16 s17))
+[GOOD] (define-fun s22 () Bool (and s15 s21))
+[GOOD] (define-fun s24 () Bool (> s16 s17))
+[GOOD] (define-fun s25 () Bool (and s15 s24))
+[GOOD] (define-fun s27 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s29 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s31 () Bool ((as is-Let Bool) s0))
+[GOOD] (define-fun s34 () Int (ite s31 s32 s33))
+[GOOD] (define-fun s35 () Int (ite s29 s30 s34))
+[GOOD] (define-fun s36 () Int (ite s27 s28 s35))
+[GOOD] (define-fun s37 () Int (ite s25 s26 s36))
+[GOOD] (define-fun s38 () Int (ite s22 s23 s37))
+[GOOD] (define-fun s39 () Int (ite s19 s20 s38))
+[GOOD] (define-fun s40 () Int (ite s1 s14 s39))
+[GOOD] (define-fun s41 () Int (ite s12 s13 s40))
+[GOOD] (define-fun s42 () Int (ite s5 s6 s41))
+[GOOD] (define-fun s43 () Bool (= s26 s42))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s43)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (Val 11)))
+
+Got: 11
+DONE
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pgen08.gold b/SBVTestSuite/GoldFiles/adt_pgen08.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pgen08.gold
@@ -0,0 +1,85 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () String "a")
+[GOOD] (define-fun s6 () Int 0)
+[GOOD] (define-fun s7 () String "b")
+[GOOD] (define-fun s9 () String "c")
+[GOOD] (define-fun s13 () Int 1)
+[GOOD] (define-fun s14 () Int 2)
+[GOOD] (define-fun s17 () Int 10)
+[GOOD] (define-fun s20 () Int 3)
+[GOOD] (define-fun s23 () Int 4)
+[GOOD] (define-fun s26 () Int 5)
+[GOOD] (define-fun s28 () Int 6)
+[GOOD] (define-fun s30 () Int 7)
+[GOOD] (define-fun s32 () Int 8)
+[GOOD] (define-fun s33 () Int 100)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int)) ; tracks user variable "a"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s2 () String (getVar_1 s0))
+[GOOD] (define-fun s4 () Bool (= s2 s3))
+[GOOD] (define-fun s5 () Bool (and s1 s4))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s10 () Bool (= s2 s9))
+[GOOD] (define-fun s11 () Bool (or s8 s10))
+[GOOD] (define-fun s12 () Bool (and s1 s11))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s16 () Int (getVal_1 s0))
+[GOOD] (define-fun s18 () Bool (< s16 s17))
+[GOOD] (define-fun s19 () Bool (and s15 s18))
+[GOOD] (define-fun s21 () Bool (= s16 s17))
+[GOOD] (define-fun s22 () Bool (and s15 s21))
+[GOOD] (define-fun s24 () Bool (> s16 s17))
+[GOOD] (define-fun s25 () Bool (and s15 s24))
+[GOOD] (define-fun s27 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s29 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s31 () Bool ((as is-Let Bool) s0))
+[GOOD] (define-fun s34 () Int (ite s31 s32 s33))
+[GOOD] (define-fun s35 () Int (ite s29 s30 s34))
+[GOOD] (define-fun s36 () Int (ite s27 s28 s35))
+[GOOD] (define-fun s37 () Int (ite s25 s26 s36))
+[GOOD] (define-fun s38 () Int (ite s22 s23 s37))
+[GOOD] (define-fun s39 () Int (ite s19 s20 s38))
+[GOOD] (define-fun s40 () Int (ite s1 s14 s39))
+[GOOD] (define-fun s41 () Int (ite s12 s13 s40))
+[GOOD] (define-fun s42 () Int (ite s5 s6 s41))
+[GOOD] (define-fun s43 () Bool (= s28 s42))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s43)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (Add (Val 3) (Val 2))))
+
+Got: (3 + 2)
+DONE
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pgen09.gold b/SBVTestSuite/GoldFiles/adt_pgen09.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pgen09.gold
@@ -0,0 +1,85 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () String "a")
+[GOOD] (define-fun s6 () Int 0)
+[GOOD] (define-fun s7 () String "b")
+[GOOD] (define-fun s9 () String "c")
+[GOOD] (define-fun s13 () Int 1)
+[GOOD] (define-fun s14 () Int 2)
+[GOOD] (define-fun s17 () Int 10)
+[GOOD] (define-fun s20 () Int 3)
+[GOOD] (define-fun s23 () Int 4)
+[GOOD] (define-fun s26 () Int 5)
+[GOOD] (define-fun s28 () Int 6)
+[GOOD] (define-fun s30 () Int 7)
+[GOOD] (define-fun s32 () Int 8)
+[GOOD] (define-fun s33 () Int 100)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int)) ; tracks user variable "a"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s2 () String (getVar_1 s0))
+[GOOD] (define-fun s4 () Bool (= s2 s3))
+[GOOD] (define-fun s5 () Bool (and s1 s4))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s10 () Bool (= s2 s9))
+[GOOD] (define-fun s11 () Bool (or s8 s10))
+[GOOD] (define-fun s12 () Bool (and s1 s11))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s16 () Int (getVal_1 s0))
+[GOOD] (define-fun s18 () Bool (< s16 s17))
+[GOOD] (define-fun s19 () Bool (and s15 s18))
+[GOOD] (define-fun s21 () Bool (= s16 s17))
+[GOOD] (define-fun s22 () Bool (and s15 s21))
+[GOOD] (define-fun s24 () Bool (> s16 s17))
+[GOOD] (define-fun s25 () Bool (and s15 s24))
+[GOOD] (define-fun s27 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s29 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s31 () Bool ((as is-Let Bool) s0))
+[GOOD] (define-fun s34 () Int (ite s31 s32 s33))
+[GOOD] (define-fun s35 () Int (ite s29 s30 s34))
+[GOOD] (define-fun s36 () Int (ite s27 s28 s35))
+[GOOD] (define-fun s37 () Int (ite s25 s26 s36))
+[GOOD] (define-fun s38 () Int (ite s22 s23 s37))
+[GOOD] (define-fun s39 () Int (ite s19 s20 s38))
+[GOOD] (define-fun s40 () Int (ite s1 s14 s39))
+[GOOD] (define-fun s41 () Int (ite s12 s13 s40))
+[GOOD] (define-fun s42 () Int (ite s5 s6 s41))
+[GOOD] (define-fun s43 () Bool (= s30 s42))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s43)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (Mul (Val 3) (Val 2))))
+
+Got: (3 * 2)
+DONE
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pgen10.gold b/SBVTestSuite/GoldFiles/adt_pgen10.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pgen10.gold
@@ -0,0 +1,85 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () String "a")
+[GOOD] (define-fun s6 () Int 0)
+[GOOD] (define-fun s7 () String "b")
+[GOOD] (define-fun s9 () String "c")
+[GOOD] (define-fun s13 () Int 1)
+[GOOD] (define-fun s14 () Int 2)
+[GOOD] (define-fun s17 () Int 10)
+[GOOD] (define-fun s20 () Int 3)
+[GOOD] (define-fun s23 () Int 4)
+[GOOD] (define-fun s26 () Int 5)
+[GOOD] (define-fun s28 () Int 6)
+[GOOD] (define-fun s30 () Int 7)
+[GOOD] (define-fun s32 () Int 8)
+[GOOD] (define-fun s33 () Int 100)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int)) ; tracks user variable "a"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s2 () String (getVar_1 s0))
+[GOOD] (define-fun s4 () Bool (= s2 s3))
+[GOOD] (define-fun s5 () Bool (and s1 s4))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s10 () Bool (= s2 s9))
+[GOOD] (define-fun s11 () Bool (or s8 s10))
+[GOOD] (define-fun s12 () Bool (and s1 s11))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s16 () Int (getVal_1 s0))
+[GOOD] (define-fun s18 () Bool (< s16 s17))
+[GOOD] (define-fun s19 () Bool (and s15 s18))
+[GOOD] (define-fun s21 () Bool (= s16 s17))
+[GOOD] (define-fun s22 () Bool (and s15 s21))
+[GOOD] (define-fun s24 () Bool (> s16 s17))
+[GOOD] (define-fun s25 () Bool (and s15 s24))
+[GOOD] (define-fun s27 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s29 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s31 () Bool ((as is-Let Bool) s0))
+[GOOD] (define-fun s34 () Int (ite s31 s32 s33))
+[GOOD] (define-fun s35 () Int (ite s29 s30 s34))
+[GOOD] (define-fun s36 () Int (ite s27 s28 s35))
+[GOOD] (define-fun s37 () Int (ite s25 s26 s36))
+[GOOD] (define-fun s38 () Int (ite s22 s23 s37))
+[GOOD] (define-fun s39 () Int (ite s19 s20 s38))
+[GOOD] (define-fun s40 () Int (ite s1 s14 s39))
+[GOOD] (define-fun s41 () Int (ite s12 s13 s40))
+[GOOD] (define-fun s42 () Int (ite s5 s6 s41))
+[GOOD] (define-fun s43 () Bool (= s32 s42))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s43)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 (Let "!0!" (Val 3) (Val 2))))
+
+Got: (let !0! = 3 in 2)
+DONE
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pgen11.gold b/SBVTestSuite/GoldFiles/adt_pgen11.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pgen11.gold
@@ -0,0 +1,83 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () String "a")
+[GOOD] (define-fun s6 () Int 0)
+[GOOD] (define-fun s7 () String "b")
+[GOOD] (define-fun s9 () String "c")
+[GOOD] (define-fun s13 () Int 1)
+[GOOD] (define-fun s14 () Int 2)
+[GOOD] (define-fun s17 () Int 10)
+[GOOD] (define-fun s20 () Int 3)
+[GOOD] (define-fun s23 () Int 4)
+[GOOD] (define-fun s26 () Int 5)
+[GOOD] (define-fun s28 () Int 6)
+[GOOD] (define-fun s30 () Int 7)
+[GOOD] (define-fun s32 () Int 8)
+[GOOD] (define-fun s33 () Int 100)
+[GOOD] (define-fun s43 () Int 9)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int)) ; tracks user variable "a"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s2 () String (getVar_1 s0))
+[GOOD] (define-fun s4 () Bool (= s2 s3))
+[GOOD] (define-fun s5 () Bool (and s1 s4))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s10 () Bool (= s2 s9))
+[GOOD] (define-fun s11 () Bool (or s8 s10))
+[GOOD] (define-fun s12 () Bool (and s1 s11))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s16 () Int (getVal_1 s0))
+[GOOD] (define-fun s18 () Bool (< s16 s17))
+[GOOD] (define-fun s19 () Bool (and s15 s18))
+[GOOD] (define-fun s21 () Bool (= s16 s17))
+[GOOD] (define-fun s22 () Bool (and s15 s21))
+[GOOD] (define-fun s24 () Bool (> s16 s17))
+[GOOD] (define-fun s25 () Bool (and s15 s24))
+[GOOD] (define-fun s27 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s29 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s31 () Bool ((as is-Let Bool) s0))
+[GOOD] (define-fun s34 () Int (ite s31 s32 s33))
+[GOOD] (define-fun s35 () Int (ite s29 s30 s34))
+[GOOD] (define-fun s36 () Int (ite s27 s28 s35))
+[GOOD] (define-fun s37 () Int (ite s25 s26 s36))
+[GOOD] (define-fun s38 () Int (ite s22 s23 s37))
+[GOOD] (define-fun s39 () Int (ite s19 s20 s38))
+[GOOD] (define-fun s40 () Int (ite s1 s14 s39))
+[GOOD] (define-fun s41 () Int (ite s12 s13 s40))
+[GOOD] (define-fun s42 () Int (ite s5 s6 s41))
+[GOOD] (define-fun s44 () Bool (= s42 s43))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s44)
+[SEND] (check-sat)
+[RECV] unsat
+
+UNSAT
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/adt_pgen12.gold b/SBVTestSuite/GoldFiles/adt_pgen12.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/adt_pgen12.gold
@@ -0,0 +1,82 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Expr
+[GOOD] (declare-datatype Expr (par (nm val) (
+           (Val (getVal_1 val))
+           (Var (getVar_1 nm))
+           (Add (getAdd_1 (Expr nm val)) (getAdd_2 (Expr nm val)))
+           (Mul (getMul_1 (Expr nm val)) (getMul_2 (Expr nm val)))
+           (Let (getLet_1 nm) (getLet_2 (Expr nm val)) (getLet_3 (Expr nm val)))
+       )))
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () String "a")
+[GOOD] (define-fun s6 () Int 0)
+[GOOD] (define-fun s7 () String "b")
+[GOOD] (define-fun s9 () String "c")
+[GOOD] (define-fun s13 () Int 1)
+[GOOD] (define-fun s14 () Int 2)
+[GOOD] (define-fun s17 () Int 10)
+[GOOD] (define-fun s20 () Int 3)
+[GOOD] (define-fun s23 () Int 4)
+[GOOD] (define-fun s26 () Int 5)
+[GOOD] (define-fun s28 () Int 6)
+[GOOD] (define-fun s30 () Int 7)
+[GOOD] (define-fun s32 () Int 8)
+[GOOD] (define-fun s33 () Int 100)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Expr String Int)) ; tracks user variable "a"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Bool ((as is-Var Bool) s0))
+[GOOD] (define-fun s2 () String (getVar_1 s0))
+[GOOD] (define-fun s4 () Bool (= s2 s3))
+[GOOD] (define-fun s5 () Bool (and s1 s4))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s10 () Bool (= s2 s9))
+[GOOD] (define-fun s11 () Bool (or s8 s10))
+[GOOD] (define-fun s12 () Bool (and s1 s11))
+[GOOD] (define-fun s15 () Bool ((as is-Val Bool) s0))
+[GOOD] (define-fun s16 () Int (getVal_1 s0))
+[GOOD] (define-fun s18 () Bool (< s16 s17))
+[GOOD] (define-fun s19 () Bool (and s15 s18))
+[GOOD] (define-fun s21 () Bool (= s16 s17))
+[GOOD] (define-fun s22 () Bool (and s15 s21))
+[GOOD] (define-fun s24 () Bool (> s16 s17))
+[GOOD] (define-fun s25 () Bool (and s15 s24))
+[GOOD] (define-fun s27 () Bool ((as is-Add Bool) s0))
+[GOOD] (define-fun s29 () Bool ((as is-Mul Bool) s0))
+[GOOD] (define-fun s31 () Bool ((as is-Let Bool) s0))
+[GOOD] (define-fun s34 () Int (ite s31 s32 s33))
+[GOOD] (define-fun s35 () Int (ite s29 s30 s34))
+[GOOD] (define-fun s36 () Int (ite s27 s28 s35))
+[GOOD] (define-fun s37 () Int (ite s25 s26 s36))
+[GOOD] (define-fun s38 () Int (ite s22 s23 s37))
+[GOOD] (define-fun s39 () Int (ite s19 s20 s38))
+[GOOD] (define-fun s40 () Int (ite s1 s14 s39))
+[GOOD] (define-fun s41 () Int (ite s12 s13 s40))
+[GOOD] (define-fun s42 () Int (ite s5 s6 s41))
+[GOOD] (define-fun s43 () Bool (= s33 s42))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s43)
+[SEND] (check-sat)
+[RECV] unsat
+
+UNSAT
+*** Solver   : Z3
+*** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/aes128Dec.gold b/SBVTestSuite/GoldFiles/aes128Dec.gold
--- a/SBVTestSuite/GoldFiles/aes128Dec.gold
+++ b/SBVTestSuite/GoldFiles/aes128Dec.gold
@@ -12,2426 +12,4426 @@
 aes128Dec.o: aes128Dec.c aes128Dec.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
-aes128Dec_driver.o: aes128Dec_driver.c
-	${CC} ${CCFLAGS} -c $< -o $@
-
-aes128Dec_driver: aes128Dec.o aes128Dec_driver.o
-	${CC} ${CCFLAGS} $^ -o $@
-
-clean:
-	rm -f *.o
-
-veryclean: clean
-	rm -f aes128Dec_driver
-== END: "Makefile" ==================
-== BEGIN: "aes128Dec.h" ================
-/* Header file for aes128Dec. Automatically generated by SBV. Do not edit! */
-
-#ifndef __aes128Dec__HEADER_INCLUDED__
-#define __aes128Dec__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 prototype: */
-void aes128Dec(const SWord32 *pt, const SWord32 *key, SWord32 *ct);
-
-#endif /* __aes128Dec__HEADER_INCLUDED__ */
-== END: "aes128Dec.h" ==================
-== BEGIN: "aes128Dec_driver.c" ================
-/* Example driver program for aes128Dec. */
-/* Automatically generated by SBV. Edit as you see fit! */
-
-#include <stdio.h>
-#include "aes128Dec.h"
-
-int main(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 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 ct[4];
-
-  aes128Dec(pt, key, ct);
-
-  printf("aes128Dec(pt, key, 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]);
-
-  return 0;
-}
-== END: "aes128Dec_driver.c" ==================
-== BEGIN: "aes128Dec.c" ================
-/* File: "aes128Dec.c". Automatically generated by SBV. Do not edit! */
-
-#include "aes128Dec.h"
-
-void aes128Dec(const SWord32 *pt, const SWord32 *key, SWord32 *ct)
-{
-  const SWord32 s0 = pt[0];
-  const SWord32 s1 = pt[1];
-  const SWord32 s2 = pt[2];
-  const SWord32 s3 = pt[3];
-  const SWord32 s4 = key[0];
-  const SWord32 s5 = key[1];
-  const SWord32 s6 = key[2];
-  const SWord32 s7 = key[3];
-  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[] = {
-      0x51f4a750UL, 0x7e416553UL, 0x1a17a4c3UL, 0x3a275e96UL,
-      0x3bab6bcbUL, 0x1f9d45f1UL, 0xacfa58abUL, 0x4be30393UL,
-      0x2030fa55UL, 0xad766df6UL, 0x88cc7691UL, 0xf5024c25UL,
-      0x4fe5d7fcUL, 0xc52acbd7UL, 0x26354480UL, 0xb562a38fUL,
-      0xdeb15a49UL, 0x25ba1b67UL, 0x45ea0e98UL, 0x5dfec0e1UL,
-      0xc32f7502UL, 0x814cf012UL, 0x8d4697a3UL, 0x6bd3f9c6UL,
-      0x038f5fe7UL, 0x15929c95UL, 0xbf6d7aebUL, 0x955259daUL,
-      0xd4be832dUL, 0x587421d3UL, 0x49e06929UL, 0x8ec9c844UL,
-      0x75c2896aUL, 0xf48e7978UL, 0x99583e6bUL, 0x27b971ddUL,
-      0xbee14fb6UL, 0xf088ad17UL, 0xc920ac66UL, 0x7dce3ab4UL,
-      0x63df4a18UL, 0xe51a3182UL, 0x97513360UL, 0x62537f45UL,
-      0xb16477e0UL, 0xbb6bae84UL, 0xfe81a01cUL, 0xf9082b94UL,
-      0x70486858UL, 0x8f45fd19UL, 0x94de6c87UL, 0x527bf8b7UL,
-      0xab73d323UL, 0x724b02e2UL, 0xe31f8f57UL, 0x6655ab2aUL,
-      0xb2eb2807UL, 0x2fb5c203UL, 0x86c57b9aUL, 0xd33708a5UL,
-      0x302887f2UL, 0x23bfa5b2UL, 0x02036abaUL, 0xed16825cUL,
-      0x8acf1c2bUL, 0xa779b492UL, 0xf307f2f0UL, 0x4e69e2a1UL,
-      0x65daf4cdUL, 0x0605bed5UL, 0xd134621fUL, 0xc4a6fe8aUL,
-      0x342e539dUL, 0xa2f355a0UL, 0x058ae132UL, 0xa4f6eb75UL,
-      0x0b83ec39UL, 0x4060efaaUL, 0x5e719f06UL, 0xbd6e1051UL,
-      0x3e218af9UL, 0x96dd063dUL, 0xdd3e05aeUL, 0x4de6bd46UL,
-      0x91548db5UL, 0x71c45d05UL, 0x0406d46fUL, 0x605015ffUL,
-      0x1998fb24UL, 0xd6bde997UL, 0x894043ccUL, 0x67d99e77UL,
-      0xb0e842bdUL, 0x07898b88UL, 0xe7195b38UL, 0x79c8eedbUL,
-      0xa17c0a47UL, 0x7c420fe9UL, 0xf8841ec9UL, 0x00000000UL,
-      0x09808683UL, 0x322bed48UL, 0x1e1170acUL, 0x6c5a724eUL,
-      0xfd0efffbUL, 0x0f853856UL, 0x3daed51eUL, 0x362d3927UL,
-      0x0a0fd964UL, 0x685ca621UL, 0x9b5b54d1UL, 0x24362e3aUL,
-      0x0c0a67b1UL, 0x9357e70fUL, 0xb4ee96d2UL, 0x1b9b919eUL,
-      0x80c0c54fUL, 0x61dc20a2UL, 0x5a774b69UL, 0x1c121a16UL,
-      0xe293ba0aUL, 0xc0a02ae5UL, 0x3c22e043UL, 0x121b171dUL,
-      0x0e090d0bUL, 0xf28bc7adUL, 0x2db6a8b9UL, 0x141ea9c8UL,
-      0x57f11985UL, 0xaf75074cUL, 0xee99ddbbUL, 0xa37f60fdUL,
-      0xf701269fUL, 0x5c72f5bcUL, 0x44663bc5UL, 0x5bfb7e34UL,
-      0x8b432976UL, 0xcb23c6dcUL, 0xb6edfc68UL, 0xb8e4f163UL,
-      0xd731dccaUL, 0x42638510UL, 0x13972240UL, 0x84c61120UL,
-      0x854a247dUL, 0xd2bb3df8UL, 0xaef93211UL, 0xc729a16dUL,
-      0x1d9e2f4bUL, 0xdcb230f3UL, 0x0d8652ecUL, 0x77c1e3d0UL,
-      0x2bb3166cUL, 0xa970b999UL, 0x119448faUL, 0x47e96422UL,
-      0xa8fc8cc4UL, 0xa0f03f1aUL, 0x567d2cd8UL, 0x223390efUL,
-      0x87494ec7UL, 0xd938d1c1UL, 0x8ccaa2feUL, 0x98d40b36UL,
-      0xa6f581cfUL, 0xa57ade28UL, 0xdab78e26UL, 0x3fadbfa4UL,
-      0x2c3a9de4UL, 0x5078920dUL, 0x6a5fcc9bUL, 0x547e4662UL,
-      0xf68d13c2UL, 0x90d8b8e8UL, 0x2e39f75eUL, 0x82c3aff5UL,
-      0x9f5d80beUL, 0x69d0937cUL, 0x6fd52da9UL, 0xcf2512b3UL,
-      0xc8ac993bUL, 0x10187da7UL, 0xe89c636eUL, 0xdb3bbb7bUL,
-      0xcd267809UL, 0x6e5918f4UL, 0xec9ab701UL, 0x834f9aa8UL,
-      0xe6956e65UL, 0xaaffe67eUL, 0x21bccf08UL, 0xef15e8e6UL,
-      0xbae79bd9UL, 0x4a6f36ceUL, 0xea9f09d4UL, 0x29b07cd6UL,
-      0x31a4b2afUL, 0x2a3f2331UL, 0xc6a59430UL, 0x35a266c0UL,
-      0x744ebc37UL, 0xfc82caa6UL, 0xe090d0b0UL, 0x33a7d815UL,
-      0xf104984aUL, 0x41ecdaf7UL, 0x7fcd500eUL, 0x1791f62fUL,
-      0x764dd68dUL, 0x43efb04dUL, 0xccaa4d54UL, 0xe49604dfUL,
-      0x9ed1b5e3UL, 0x4c6a881bUL, 0xc12c1fb8UL, 0x4665517fUL,
-      0x9d5eea04UL, 0x018c355dUL, 0xfa877473UL, 0xfb0b412eUL,
-      0xb3671d5aUL, 0x92dbd252UL, 0xe9105633UL, 0x6dd64713UL,
-      0x9ad7618cUL, 0x37a10c7aUL, 0x59f8148eUL, 0xeb133c89UL,
-      0xcea927eeUL, 0xb761c935UL, 0xe11ce5edUL, 0x7a47b13cUL,
-      0x9cd2df59UL, 0x55f2733fUL, 0x1814ce79UL, 0x73c737bfUL,
-      0x53f7cdeaUL, 0x5ffdaa5bUL, 0xdf3d6f14UL, 0x7844db86UL,
-      0xcaaff381UL, 0xb968c43eUL, 0x3824342cUL, 0xc2a3405fUL,
-      0x161dc372UL, 0xbce2250cUL, 0x283c498bUL, 0xff0d9541UL,
-      0x39a80171UL, 0x080cb3deUL, 0xd8b4e49cUL, 0x6456c190UL,
-      0x7bcb8461UL, 0xd532b670UL, 0x486c5c74UL, 0xd0b85742UL
-  };
-  static const SWord8 table2[] = {
-       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
-  };
-  static const SWord32 table3[] = {
-      0x5051f4a7UL, 0x537e4165UL, 0xc31a17a4UL, 0x963a275eUL,
-      0xcb3bab6bUL, 0xf11f9d45UL, 0xabacfa58UL, 0x934be303UL,
-      0x552030faUL, 0xf6ad766dUL, 0x9188cc76UL, 0x25f5024cUL,
-      0xfc4fe5d7UL, 0xd7c52acbUL, 0x80263544UL, 0x8fb562a3UL,
-      0x49deb15aUL, 0x6725ba1bUL, 0x9845ea0eUL, 0xe15dfec0UL,
-      0x02c32f75UL, 0x12814cf0UL, 0xa38d4697UL, 0xc66bd3f9UL,
-      0xe7038f5fUL, 0x9515929cUL, 0xebbf6d7aUL, 0xda955259UL,
-      0x2dd4be83UL, 0xd3587421UL, 0x2949e069UL, 0x448ec9c8UL,
-      0x6a75c289UL, 0x78f48e79UL, 0x6b99583eUL, 0xdd27b971UL,
-      0xb6bee14fUL, 0x17f088adUL, 0x66c920acUL, 0xb47dce3aUL,
-      0x1863df4aUL, 0x82e51a31UL, 0x60975133UL, 0x4562537fUL,
-      0xe0b16477UL, 0x84bb6baeUL, 0x1cfe81a0UL, 0x94f9082bUL,
-      0x58704868UL, 0x198f45fdUL, 0x8794de6cUL, 0xb7527bf8UL,
-      0x23ab73d3UL, 0xe2724b02UL, 0x57e31f8fUL, 0x2a6655abUL,
-      0x07b2eb28UL, 0x032fb5c2UL, 0x9a86c57bUL, 0xa5d33708UL,
-      0xf2302887UL, 0xb223bfa5UL, 0xba02036aUL, 0x5ced1682UL,
-      0x2b8acf1cUL, 0x92a779b4UL, 0xf0f307f2UL, 0xa14e69e2UL,
-      0xcd65daf4UL, 0xd50605beUL, 0x1fd13462UL, 0x8ac4a6feUL,
-      0x9d342e53UL, 0xa0a2f355UL, 0x32058ae1UL, 0x75a4f6ebUL,
-      0x390b83ecUL, 0xaa4060efUL, 0x065e719fUL, 0x51bd6e10UL,
-      0xf93e218aUL, 0x3d96dd06UL, 0xaedd3e05UL, 0x464de6bdUL,
-      0xb591548dUL, 0x0571c45dUL, 0x6f0406d4UL, 0xff605015UL,
-      0x241998fbUL, 0x97d6bde9UL, 0xcc894043UL, 0x7767d99eUL,
-      0xbdb0e842UL, 0x8807898bUL, 0x38e7195bUL, 0xdb79c8eeUL,
-      0x47a17c0aUL, 0xe97c420fUL, 0xc9f8841eUL, 0x00000000UL,
-      0x83098086UL, 0x48322bedUL, 0xac1e1170UL, 0x4e6c5a72UL,
-      0xfbfd0effUL, 0x560f8538UL, 0x1e3daed5UL, 0x27362d39UL,
-      0x640a0fd9UL, 0x21685ca6UL, 0xd19b5b54UL, 0x3a24362eUL,
-      0xb10c0a67UL, 0x0f9357e7UL, 0xd2b4ee96UL, 0x9e1b9b91UL,
-      0x4f80c0c5UL, 0xa261dc20UL, 0x695a774bUL, 0x161c121aUL,
-      0x0ae293baUL, 0xe5c0a02aUL, 0x433c22e0UL, 0x1d121b17UL,
-      0x0b0e090dUL, 0xadf28bc7UL, 0xb92db6a8UL, 0xc8141ea9UL,
-      0x8557f119UL, 0x4caf7507UL, 0xbbee99ddUL, 0xfda37f60UL,
-      0x9ff70126UL, 0xbc5c72f5UL, 0xc544663bUL, 0x345bfb7eUL,
-      0x768b4329UL, 0xdccb23c6UL, 0x68b6edfcUL, 0x63b8e4f1UL,
-      0xcad731dcUL, 0x10426385UL, 0x40139722UL, 0x2084c611UL,
-      0x7d854a24UL, 0xf8d2bb3dUL, 0x11aef932UL, 0x6dc729a1UL,
-      0x4b1d9e2fUL, 0xf3dcb230UL, 0xec0d8652UL, 0xd077c1e3UL,
-      0x6c2bb316UL, 0x99a970b9UL, 0xfa119448UL, 0x2247e964UL,
-      0xc4a8fc8cUL, 0x1aa0f03fUL, 0xd8567d2cUL, 0xef223390UL,
-      0xc787494eUL, 0xc1d938d1UL, 0xfe8ccaa2UL, 0x3698d40bUL,
-      0xcfa6f581UL, 0x28a57adeUL, 0x26dab78eUL, 0xa43fadbfUL,
-      0xe42c3a9dUL, 0x0d507892UL, 0x9b6a5fccUL, 0x62547e46UL,
-      0xc2f68d13UL, 0xe890d8b8UL, 0x5e2e39f7UL, 0xf582c3afUL,
-      0xbe9f5d80UL, 0x7c69d093UL, 0xa96fd52dUL, 0xb3cf2512UL,
-      0x3bc8ac99UL, 0xa710187dUL, 0x6ee89c63UL, 0x7bdb3bbbUL,
-      0x09cd2678UL, 0xf46e5918UL, 0x01ec9ab7UL, 0xa8834f9aUL,
-      0x65e6956eUL, 0x7eaaffe6UL, 0x0821bccfUL, 0xe6ef15e8UL,
-      0xd9bae79bUL, 0xce4a6f36UL, 0xd4ea9f09UL, 0xd629b07cUL,
-      0xaf31a4b2UL, 0x312a3f23UL, 0x30c6a594UL, 0xc035a266UL,
-      0x37744ebcUL, 0xa6fc82caUL, 0xb0e090d0UL, 0x1533a7d8UL,
-      0x4af10498UL, 0xf741ecdaUL, 0x0e7fcd50UL, 0x2f1791f6UL,
-      0x8d764dd6UL, 0x4d43efb0UL, 0x54ccaa4dUL, 0xdfe49604UL,
-      0xe39ed1b5UL, 0x1b4c6a88UL, 0xb8c12c1fUL, 0x7f466551UL,
-      0x049d5eeaUL, 0x5d018c35UL, 0x73fa8774UL, 0x2efb0b41UL,
-      0x5ab3671dUL, 0x5292dbd2UL, 0x33e91056UL, 0x136dd647UL,
-      0x8c9ad761UL, 0x7a37a10cUL, 0x8e59f814UL, 0x89eb133cUL,
-      0xeecea927UL, 0x35b761c9UL, 0xede11ce5UL, 0x3c7a47b1UL,
-      0x599cd2dfUL, 0x3f55f273UL, 0x791814ceUL, 0xbf73c737UL,
-      0xea53f7cdUL, 0x5b5ffdaaUL, 0x14df3d6fUL, 0x867844dbUL,
-      0x81caaff3UL, 0x3eb968c4UL, 0x2c382434UL, 0x5fc2a340UL,
-      0x72161dc3UL, 0x0cbce225UL, 0x8b283c49UL, 0x41ff0d95UL,
-      0x7139a801UL, 0xde080cb3UL, 0x9cd8b4e4UL, 0x906456c1UL,
-      0x617bcb84UL, 0x70d532b6UL, 0x74486c5cUL, 0x42d0b857UL
-  };
-  static const SWord32 table4[] = {
-      0xa75051f4UL, 0x65537e41UL, 0xa4c31a17UL, 0x5e963a27UL,
-      0x6bcb3babUL, 0x45f11f9dUL, 0x58abacfaUL, 0x03934be3UL,
-      0xfa552030UL, 0x6df6ad76UL, 0x769188ccUL, 0x4c25f502UL,
-      0xd7fc4fe5UL, 0xcbd7c52aUL, 0x44802635UL, 0xa38fb562UL,
-      0x5a49deb1UL, 0x1b6725baUL, 0x0e9845eaUL, 0xc0e15dfeUL,
-      0x7502c32fUL, 0xf012814cUL, 0x97a38d46UL, 0xf9c66bd3UL,
-      0x5fe7038fUL, 0x9c951592UL, 0x7aebbf6dUL, 0x59da9552UL,
-      0x832dd4beUL, 0x21d35874UL, 0x692949e0UL, 0xc8448ec9UL,
-      0x896a75c2UL, 0x7978f48eUL, 0x3e6b9958UL, 0x71dd27b9UL,
-      0x4fb6bee1UL, 0xad17f088UL, 0xac66c920UL, 0x3ab47dceUL,
-      0x4a1863dfUL, 0x3182e51aUL, 0x33609751UL, 0x7f456253UL,
-      0x77e0b164UL, 0xae84bb6bUL, 0xa01cfe81UL, 0x2b94f908UL,
-      0x68587048UL, 0xfd198f45UL, 0x6c8794deUL, 0xf8b7527bUL,
-      0xd323ab73UL, 0x02e2724bUL, 0x8f57e31fUL, 0xab2a6655UL,
-      0x2807b2ebUL, 0xc2032fb5UL, 0x7b9a86c5UL, 0x08a5d337UL,
-      0x87f23028UL, 0xa5b223bfUL, 0x6aba0203UL, 0x825ced16UL,
-      0x1c2b8acfUL, 0xb492a779UL, 0xf2f0f307UL, 0xe2a14e69UL,
-      0xf4cd65daUL, 0xbed50605UL, 0x621fd134UL, 0xfe8ac4a6UL,
-      0x539d342eUL, 0x55a0a2f3UL, 0xe132058aUL, 0xeb75a4f6UL,
-      0xec390b83UL, 0xefaa4060UL, 0x9f065e71UL, 0x1051bd6eUL,
-      0x8af93e21UL, 0x063d96ddUL, 0x05aedd3eUL, 0xbd464de6UL,
-      0x8db59154UL, 0x5d0571c4UL, 0xd46f0406UL, 0x15ff6050UL,
-      0xfb241998UL, 0xe997d6bdUL, 0x43cc8940UL, 0x9e7767d9UL,
-      0x42bdb0e8UL, 0x8b880789UL, 0x5b38e719UL, 0xeedb79c8UL,
-      0x0a47a17cUL, 0x0fe97c42UL, 0x1ec9f884UL, 0x00000000UL,
-      0x86830980UL, 0xed48322bUL, 0x70ac1e11UL, 0x724e6c5aUL,
-      0xfffbfd0eUL, 0x38560f85UL, 0xd51e3daeUL, 0x3927362dUL,
-      0xd9640a0fUL, 0xa621685cUL, 0x54d19b5bUL, 0x2e3a2436UL,
-      0x67b10c0aUL, 0xe70f9357UL, 0x96d2b4eeUL, 0x919e1b9bUL,
-      0xc54f80c0UL, 0x20a261dcUL, 0x4b695a77UL, 0x1a161c12UL,
-      0xba0ae293UL, 0x2ae5c0a0UL, 0xe0433c22UL, 0x171d121bUL,
-      0x0d0b0e09UL, 0xc7adf28bUL, 0xa8b92db6UL, 0xa9c8141eUL,
-      0x198557f1UL, 0x074caf75UL, 0xddbbee99UL, 0x60fda37fUL,
-      0x269ff701UL, 0xf5bc5c72UL, 0x3bc54466UL, 0x7e345bfbUL,
-      0x29768b43UL, 0xc6dccb23UL, 0xfc68b6edUL, 0xf163b8e4UL,
-      0xdccad731UL, 0x85104263UL, 0x22401397UL, 0x112084c6UL,
-      0x247d854aUL, 0x3df8d2bbUL, 0x3211aef9UL, 0xa16dc729UL,
-      0x2f4b1d9eUL, 0x30f3dcb2UL, 0x52ec0d86UL, 0xe3d077c1UL,
-      0x166c2bb3UL, 0xb999a970UL, 0x48fa1194UL, 0x642247e9UL,
-      0x8cc4a8fcUL, 0x3f1aa0f0UL, 0x2cd8567dUL, 0x90ef2233UL,
-      0x4ec78749UL, 0xd1c1d938UL, 0xa2fe8ccaUL, 0x0b3698d4UL,
-      0x81cfa6f5UL, 0xde28a57aUL, 0x8e26dab7UL, 0xbfa43fadUL,
-      0x9de42c3aUL, 0x920d5078UL, 0xcc9b6a5fUL, 0x4662547eUL,
-      0x13c2f68dUL, 0xb8e890d8UL, 0xf75e2e39UL, 0xaff582c3UL,
-      0x80be9f5dUL, 0x937c69d0UL, 0x2da96fd5UL, 0x12b3cf25UL,
-      0x993bc8acUL, 0x7da71018UL, 0x636ee89cUL, 0xbb7bdb3bUL,
-      0x7809cd26UL, 0x18f46e59UL, 0xb701ec9aUL, 0x9aa8834fUL,
-      0x6e65e695UL, 0xe67eaaffUL, 0xcf0821bcUL, 0xe8e6ef15UL,
-      0x9bd9bae7UL, 0x36ce4a6fUL, 0x09d4ea9fUL, 0x7cd629b0UL,
-      0xb2af31a4UL, 0x23312a3fUL, 0x9430c6a5UL, 0x66c035a2UL,
-      0xbc37744eUL, 0xcaa6fc82UL, 0xd0b0e090UL, 0xd81533a7UL,
-      0x984af104UL, 0xdaf741ecUL, 0x500e7fcdUL, 0xf62f1791UL,
-      0xd68d764dUL, 0xb04d43efUL, 0x4d54ccaaUL, 0x04dfe496UL,
-      0xb5e39ed1UL, 0x881b4c6aUL, 0x1fb8c12cUL, 0x517f4665UL,
-      0xea049d5eUL, 0x355d018cUL, 0x7473fa87UL, 0x412efb0bUL,
-      0x1d5ab367UL, 0xd25292dbUL, 0x5633e910UL, 0x47136dd6UL,
-      0x618c9ad7UL, 0x0c7a37a1UL, 0x148e59f8UL, 0x3c89eb13UL,
-      0x27eecea9UL, 0xc935b761UL, 0xe5ede11cUL, 0xb13c7a47UL,
-      0xdf599cd2UL, 0x733f55f2UL, 0xce791814UL, 0x37bf73c7UL,
-      0xcdea53f7UL, 0xaa5b5ffdUL, 0x6f14df3dUL, 0xdb867844UL,
-      0xf381caafUL, 0xc43eb968UL, 0x342c3824UL, 0x405fc2a3UL,
-      0xc372161dUL, 0x250cbce2UL, 0x498b283cUL, 0x9541ff0dUL,
-      0x017139a8UL, 0xb3de080cUL, 0xe49cd8b4UL, 0xc1906456UL,
-      0x84617bcbUL, 0xb670d532UL, 0x5c74486cUL, 0x5742d0b8UL
-  };
-  static const SWord32 table5[] = {
-      0xf4a75051UL, 0x4165537eUL, 0x17a4c31aUL, 0x275e963aUL,
-      0xab6bcb3bUL, 0x9d45f11fUL, 0xfa58abacUL, 0xe303934bUL,
-      0x30fa5520UL, 0x766df6adUL, 0xcc769188UL, 0x024c25f5UL,
-      0xe5d7fc4fUL, 0x2acbd7c5UL, 0x35448026UL, 0x62a38fb5UL,
-      0xb15a49deUL, 0xba1b6725UL, 0xea0e9845UL, 0xfec0e15dUL,
-      0x2f7502c3UL, 0x4cf01281UL, 0x4697a38dUL, 0xd3f9c66bUL,
-      0x8f5fe703UL, 0x929c9515UL, 0x6d7aebbfUL, 0x5259da95UL,
-      0xbe832dd4UL, 0x7421d358UL, 0xe0692949UL, 0xc9c8448eUL,
-      0xc2896a75UL, 0x8e7978f4UL, 0x583e6b99UL, 0xb971dd27UL,
-      0xe14fb6beUL, 0x88ad17f0UL, 0x20ac66c9UL, 0xce3ab47dUL,
-      0xdf4a1863UL, 0x1a3182e5UL, 0x51336097UL, 0x537f4562UL,
-      0x6477e0b1UL, 0x6bae84bbUL, 0x81a01cfeUL, 0x082b94f9UL,
-      0x48685870UL, 0x45fd198fUL, 0xde6c8794UL, 0x7bf8b752UL,
-      0x73d323abUL, 0x4b02e272UL, 0x1f8f57e3UL, 0x55ab2a66UL,
-      0xeb2807b2UL, 0xb5c2032fUL, 0xc57b9a86UL, 0x3708a5d3UL,
-      0x2887f230UL, 0xbfa5b223UL, 0x036aba02UL, 0x16825cedUL,
-      0xcf1c2b8aUL, 0x79b492a7UL, 0x07f2f0f3UL, 0x69e2a14eUL,
-      0xdaf4cd65UL, 0x05bed506UL, 0x34621fd1UL, 0xa6fe8ac4UL,
-      0x2e539d34UL, 0xf355a0a2UL, 0x8ae13205UL, 0xf6eb75a4UL,
-      0x83ec390bUL, 0x60efaa40UL, 0x719f065eUL, 0x6e1051bdUL,
-      0x218af93eUL, 0xdd063d96UL, 0x3e05aeddUL, 0xe6bd464dUL,
-      0x548db591UL, 0xc45d0571UL, 0x06d46f04UL, 0x5015ff60UL,
-      0x98fb2419UL, 0xbde997d6UL, 0x4043cc89UL, 0xd99e7767UL,
-      0xe842bdb0UL, 0x898b8807UL, 0x195b38e7UL, 0xc8eedb79UL,
-      0x7c0a47a1UL, 0x420fe97cUL, 0x841ec9f8UL, 0x00000000UL,
-      0x80868309UL, 0x2bed4832UL, 0x1170ac1eUL, 0x5a724e6cUL,
-      0x0efffbfdUL, 0x8538560fUL, 0xaed51e3dUL, 0x2d392736UL,
-      0x0fd9640aUL, 0x5ca62168UL, 0x5b54d19bUL, 0x362e3a24UL,
-      0x0a67b10cUL, 0x57e70f93UL, 0xee96d2b4UL, 0x9b919e1bUL,
-      0xc0c54f80UL, 0xdc20a261UL, 0x774b695aUL, 0x121a161cUL,
-      0x93ba0ae2UL, 0xa02ae5c0UL, 0x22e0433cUL, 0x1b171d12UL,
-      0x090d0b0eUL, 0x8bc7adf2UL, 0xb6a8b92dUL, 0x1ea9c814UL,
-      0xf1198557UL, 0x75074cafUL, 0x99ddbbeeUL, 0x7f60fda3UL,
-      0x01269ff7UL, 0x72f5bc5cUL, 0x663bc544UL, 0xfb7e345bUL,
-      0x4329768bUL, 0x23c6dccbUL, 0xedfc68b6UL, 0xe4f163b8UL,
-      0x31dccad7UL, 0x63851042UL, 0x97224013UL, 0xc6112084UL,
-      0x4a247d85UL, 0xbb3df8d2UL, 0xf93211aeUL, 0x29a16dc7UL,
-      0x9e2f4b1dUL, 0xb230f3dcUL, 0x8652ec0dUL, 0xc1e3d077UL,
-      0xb3166c2bUL, 0x70b999a9UL, 0x9448fa11UL, 0xe9642247UL,
-      0xfc8cc4a8UL, 0xf03f1aa0UL, 0x7d2cd856UL, 0x3390ef22UL,
-      0x494ec787UL, 0x38d1c1d9UL, 0xcaa2fe8cUL, 0xd40b3698UL,
-      0xf581cfa6UL, 0x7ade28a5UL, 0xb78e26daUL, 0xadbfa43fUL,
-      0x3a9de42cUL, 0x78920d50UL, 0x5fcc9b6aUL, 0x7e466254UL,
-      0x8d13c2f6UL, 0xd8b8e890UL, 0x39f75e2eUL, 0xc3aff582UL,
-      0x5d80be9fUL, 0xd0937c69UL, 0xd52da96fUL, 0x2512b3cfUL,
-      0xac993bc8UL, 0x187da710UL, 0x9c636ee8UL, 0x3bbb7bdbUL,
-      0x267809cdUL, 0x5918f46eUL, 0x9ab701ecUL, 0x4f9aa883UL,
-      0x956e65e6UL, 0xffe67eaaUL, 0xbccf0821UL, 0x15e8e6efUL,
-      0xe79bd9baUL, 0x6f36ce4aUL, 0x9f09d4eaUL, 0xb07cd629UL,
-      0xa4b2af31UL, 0x3f23312aUL, 0xa59430c6UL, 0xa266c035UL,
-      0x4ebc3774UL, 0x82caa6fcUL, 0x90d0b0e0UL, 0xa7d81533UL,
-      0x04984af1UL, 0xecdaf741UL, 0xcd500e7fUL, 0x91f62f17UL,
-      0x4dd68d76UL, 0xefb04d43UL, 0xaa4d54ccUL, 0x9604dfe4UL,
-      0xd1b5e39eUL, 0x6a881b4cUL, 0x2c1fb8c1UL, 0x65517f46UL,
-      0x5eea049dUL, 0x8c355d01UL, 0x877473faUL, 0x0b412efbUL,
-      0x671d5ab3UL, 0xdbd25292UL, 0x105633e9UL, 0xd647136dUL,
-      0xd7618c9aUL, 0xa10c7a37UL, 0xf8148e59UL, 0x133c89ebUL,
-      0xa927eeceUL, 0x61c935b7UL, 0x1ce5ede1UL, 0x47b13c7aUL,
-      0xd2df599cUL, 0xf2733f55UL, 0x14ce7918UL, 0xc737bf73UL,
-      0xf7cdea53UL, 0xfdaa5b5fUL, 0x3d6f14dfUL, 0x44db8678UL,
-      0xaff381caUL, 0x68c43eb9UL, 0x24342c38UL, 0xa3405fc2UL,
-      0x1dc37216UL, 0xe2250cbcUL, 0x3c498b28UL, 0x0d9541ffUL,
-      0xa8017139UL, 0x0cb3de08UL, 0xb4e49cd8UL, 0x56c19064UL,
-      0xcb84617bUL, 0x32b670d5UL, 0x6c5c7448UL, 0xb85742d0UL
-  };
-  static const SWord8 table6[] = {
-        0,  14,  28,  18,  56,  54,  36,  42, 112, 126, 108,  98,  72,
-       70,  84,  90, 224, 238, 252, 242, 216, 214, 196, 202, 144, 158,
-      140, 130, 168, 166, 180, 186, 219, 213, 199, 201, 227, 237, 255,
-      241, 171, 165, 183, 185, 147, 157, 143, 129,  59,  53,  39,  41,
-        3,  13,  31,  17,  75,  69,  87,  89, 115, 125, 111,  97, 173,
-      163, 177, 191, 149, 155, 137, 135, 221, 211, 193, 207, 229, 235,
-      249, 247,  77,  67,  81,  95, 117, 123, 105, 103,  61,  51,  33,
-       47,   5,  11,  25,  23, 118, 120, 106, 100,  78,  64,  82,  92,
-        6,   8,  26,  20,  62,  48,  34,  44, 150, 152, 138, 132, 174,
-      160, 178, 188, 230, 232, 250, 244, 222, 208, 194, 204,  65,  79,
-       93,  83, 121, 119, 101, 107,  49,  63,  45,  35,   9,   7,  21,
-       27, 161, 175, 189, 179, 153, 151, 133, 139, 209, 223, 205, 195,
-      233, 231, 245, 251, 154, 148, 134, 136, 162, 172, 190, 176, 234,
-      228, 246, 248, 210, 220, 206, 192, 122, 116, 102, 104,  66,  76,
-       94,  80,  10,   4,  22,  24,  50,  60,  46,  32, 236, 226, 240,
-      254, 212, 218, 200, 198, 156, 146, 128, 142, 164, 170, 184, 182,
-       12,   2,  16,  30,  52,  58,  40,  38, 124, 114,  96, 110,  68,
-       74,  88,  86,  55,  57,  43,  37,  15,   1,  19,  29,  71,  73,
-       91,  85, 127, 113,  99, 109, 215, 217, 203, 197, 239, 225, 243,
-      253, 167, 169, 187, 181, 159, 145, 131, 141
-  };
-  static const SWord8 table7[] = {
-        0,  11,  22,  29,  44,  39,  58,  49,  88,  83,  78,  69, 116,
-      127,  98, 105, 176, 187, 166, 173, 156, 151, 138, 129, 232, 227,
-      254, 245, 196, 207, 210, 217, 123, 112, 109, 102,  87,  92,  65,
-       74,  35,  40,  53,  62,  15,   4,  25,  18, 203, 192, 221, 214,
-      231, 236, 241, 250, 147, 152, 133, 142, 191, 180, 169, 162, 246,
-      253, 224, 235, 218, 209, 204, 199, 174, 165, 184, 179, 130, 137,
-      148, 159,  70,  77,  80,  91, 106,  97, 124, 119,  30,  21,   8,
-        3,  50,  57,  36,  47, 141, 134, 155, 144, 161, 170, 183, 188,
-      213, 222, 195, 200, 249, 242, 239, 228,  61,  54,  43,  32,  17,
-       26,   7,  12, 101, 110, 115, 120,  73,  66,  95,  84, 247, 252,
-      225, 234, 219, 208, 205, 198, 175, 164, 185, 178, 131, 136, 149,
-      158,  71,  76,  81,  90, 107,  96, 125, 118,  31,  20,   9,   2,
-       51,  56,  37,  46, 140, 135, 154, 145, 160, 171, 182, 189, 212,
-      223, 194, 201, 248, 243, 238, 229,  60,  55,  42,  33,  16,  27,
-        6,  13, 100, 111, 114, 121,  72,  67,  94,  85,   1,  10,  23,
-       28,  45,  38,  59,  48,  89,  82,  79,  68, 117, 126,  99, 104,
-      177, 186, 167, 172, 157, 150, 139, 128, 233, 226, 255, 244, 197,
-      206, 211, 216, 122, 113, 108, 103,  86,  93,  64,  75,  34,  41,
-       52,  63,  14,   5,  24,  19, 202, 193, 220, 215, 230, 237, 240,
-      251, 146, 153, 132, 143, 190, 181, 168, 163
-  };
-  static const SWord8 table8[] = {
-        0,  13,  26,  23,  52,  57,  46,  35, 104, 101, 114, 127,  92,
-       81,  70,  75, 208, 221, 202, 199, 228, 233, 254, 243, 184, 181,
-      162, 175, 140, 129, 150, 155, 187, 182, 161, 172, 143, 130, 149,
-      152, 211, 222, 201, 196, 231, 234, 253, 240, 107, 102, 113, 124,
-       95,  82,  69,  72,   3,  14,  25,  20,  55,  58,  45,  32, 109,
-       96, 119, 122,  89,  84,  67,  78,   5,   8,  31,  18,  49,  60,
-       43,  38, 189, 176, 167, 170, 137, 132, 147, 158, 213, 216, 207,
-      194, 225, 236, 251, 246, 214, 219, 204, 193, 226, 239, 248, 245,
-      190, 179, 164, 169, 138, 135, 144, 157,   6,  11,  28,  17,  50,
-       63,  40,  37, 110,  99, 116, 121,  90,  87,  64,  77, 218, 215,
-      192, 205, 238, 227, 244, 249, 178, 191, 168, 165, 134, 139, 156,
-      145,  10,   7,  16,  29,  62,  51,  36,  41,  98, 111, 120, 117,
-       86,  91,  76,  65,  97, 108, 123, 118,  85,  88,  79,  66,   9,
-        4,  19,  30,  61,  48,  39,  42, 177, 188, 171, 166, 133, 136,
-      159, 146, 217, 212, 195, 206, 237, 224, 247, 250, 183, 186, 173,
-      160, 131, 142, 153, 148, 223, 210, 197, 200, 235, 230, 241, 252,
-      103, 106, 125, 112,  83,  94,  73,  68,  15,   2,  21,  24,  59,
-       54,  33,  44,  12,   1,  22,  27,  56,  53,  34,  47, 100, 105,
-      126, 115,  80,  93,  74,  71, 220, 209, 198, 203, 232, 229, 242,
-      255, 180, 185, 174, 163, 128, 141, 154, 151
-  };
-  static const SWord8 table9[] = {
-        0,   9,  18,  27,  36,  45,  54,  63,  72,  65,  90,  83, 108,
-      101, 126, 119, 144, 153, 130, 139, 180, 189, 166, 175, 216, 209,
-      202, 195, 252, 245, 238, 231,  59,  50,  41,  32,  31,  22,  13,
-        4, 115, 122,  97, 104,  87,  94,  69,  76, 171, 162, 185, 176,
-      143, 134, 157, 148, 227, 234, 241, 248, 199, 206, 213, 220, 118,
-      127, 100, 109,  82,  91,  64,  73,  62,  55,  44,  37,  26,  19,
-        8,   1, 230, 239, 244, 253, 194, 203, 208, 217, 174, 167, 188,
-      181, 138, 131, 152, 145,  77,  68,  95,  86, 105,  96, 123, 114,
-        5,  12,  23,  30,  33,  40,  51,  58, 221, 212, 207, 198, 249,
-      240, 235, 226, 149, 156, 135, 142, 177, 184, 163, 170, 236, 229,
-      254, 247, 200, 193, 218, 211, 164, 173, 182, 191, 128, 137, 146,
-      155, 124, 117, 110, 103,  88,  81,  74,  67,  52,  61,  38,  47,
-       16,  25,   2,  11, 215, 222, 197, 204, 243, 250, 225, 232, 159,
-      150, 141, 132, 187, 178, 169, 160,  71,  78,  85,  92,  99, 106,
-      113, 120,  15,   6,  29,  20,  43,  34,  57,  48, 154, 147, 136,
-      129, 190, 183, 172, 165, 210, 219, 192, 201, 246, 255, 228, 237,
-       10,   3,  24,  17,  46,  39,  60,  53,  66,  75,  80,  89, 102,
-      111, 116, 125, 161, 168, 179, 186, 133, 140, 151, 158, 233, 224,
-      251, 242, 205, 196, 223, 214,  49,  56,  35,  42,  21,  28,   7,
-       14, 121, 112, 107,  98,  93,  84,  79,  70
-  };
-  const SWord32 s520 = (s7 << 8) | (s7 >> 24);
-  const SWord8  s521 = (SWord8) (s520 >> 24);
-  const SWord8  s522 = table2[s521];
-  const SWord8  s523 = 1 ^ s522;
-  const SWord8  s524 = (SWord8) (s520 >> 16);
-  const SWord8  s525 = table2[s524];
-  const SWord16 s526 = (((SWord16) s523) << 8) | ((SWord16) s525);
-  const SWord8  s527 = (SWord8) (s520 >> 8);
-  const SWord8  s528 = table2[s527];
-  const SWord8  s529 = (SWord8) s520;
-  const SWord8  s530 = table2[s529];
-  const SWord16 s531 = (((SWord16) s528) << 8) | ((SWord16) s530);
-  const SWord32 s532 = (((SWord32) s526) << 16) | ((SWord32) s531);
-  const SWord32 s533 = s4 ^ s532;
-  const SWord32 s534 = s5 ^ s533;
-  const SWord32 s535 = s6 ^ s534;
-  const SWord32 s536 = s7 ^ s535;
-  const SWord32 s537 = (s536 << 8) | (s536 >> 24);
-  const SWord8  s538 = (SWord8) (s537 >> 24);
-  const SWord8  s539 = table2[s538];
-  const SWord8  s540 = 2 ^ s539;
-  const SWord8  s541 = (SWord8) (s537 >> 16);
-  const SWord8  s542 = table2[s541];
-  const SWord16 s543 = (((SWord16) s540) << 8) | ((SWord16) s542);
-  const SWord8  s544 = (SWord8) (s537 >> 8);
-  const SWord8  s545 = table2[s544];
-  const SWord8  s546 = (SWord8) s537;
-  const SWord8  s547 = table2[s546];
-  const SWord16 s548 = (((SWord16) s545) << 8) | ((SWord16) s547);
-  const SWord32 s549 = (((SWord32) s543) << 16) | ((SWord32) s548);
-  const SWord32 s550 = s533 ^ s549;
-  const SWord32 s551 = s534 ^ s550;
-  const SWord32 s552 = s535 ^ s551;
-  const SWord32 s553 = s536 ^ s552;
-  const SWord32 s554 = (s553 << 8) | (s553 >> 24);
-  const SWord8  s555 = (SWord8) (s554 >> 24);
-  const SWord8  s556 = table2[s555];
-  const SWord8  s557 = 4 ^ s556;
-  const SWord8  s558 = (SWord8) (s554 >> 16);
-  const SWord8  s559 = table2[s558];
-  const SWord16 s560 = (((SWord16) s557) << 8) | ((SWord16) s559);
-  const SWord8  s561 = (SWord8) (s554 >> 8);
-  const SWord8  s562 = table2[s561];
-  const SWord8  s563 = (SWord8) s554;
-  const SWord8  s564 = table2[s563];
-  const SWord16 s565 = (((SWord16) s562) << 8) | ((SWord16) s564);
-  const SWord32 s566 = (((SWord32) s560) << 16) | ((SWord32) s565);
-  const SWord32 s567 = s550 ^ s566;
-  const SWord32 s568 = s551 ^ s567;
-  const SWord32 s569 = s552 ^ s568;
-  const SWord32 s570 = s553 ^ s569;
-  const SWord32 s571 = (s570 << 8) | (s570 >> 24);
-  const SWord8  s572 = (SWord8) (s571 >> 24);
-  const SWord8  s573 = table2[s572];
-  const SWord8  s574 = 8 ^ s573;
-  const SWord8  s575 = (SWord8) (s571 >> 16);
-  const SWord8  s576 = table2[s575];
-  const SWord16 s577 = (((SWord16) s574) << 8) | ((SWord16) s576);
-  const SWord8  s578 = (SWord8) (s571 >> 8);
-  const SWord8  s579 = table2[s578];
-  const SWord8  s580 = (SWord8) s571;
-  const SWord8  s581 = table2[s580];
-  const SWord16 s582 = (((SWord16) s579) << 8) | ((SWord16) s581);
-  const SWord32 s583 = (((SWord32) s577) << 16) | ((SWord32) s582);
-  const SWord32 s584 = s567 ^ s583;
-  const SWord32 s585 = s568 ^ s584;
-  const SWord32 s586 = s569 ^ s585;
-  const SWord32 s587 = s570 ^ s586;
-  const SWord32 s588 = (s587 << 8) | (s587 >> 24);
-  const SWord8  s589 = (SWord8) (s588 >> 24);
-  const SWord8  s590 = table2[s589];
-  const SWord8  s591 = 16 ^ s590;
-  const SWord8  s592 = (SWord8) (s588 >> 16);
-  const SWord8  s593 = table2[s592];
-  const SWord16 s594 = (((SWord16) s591) << 8) | ((SWord16) s593);
-  const SWord8  s595 = (SWord8) (s588 >> 8);
-  const SWord8  s596 = table2[s595];
-  const SWord8  s597 = (SWord8) s588;
-  const SWord8  s598 = table2[s597];
-  const SWord16 s599 = (((SWord16) s596) << 8) | ((SWord16) s598);
-  const SWord32 s600 = (((SWord32) s594) << 16) | ((SWord32) s599);
-  const SWord32 s601 = s584 ^ s600;
-  const SWord32 s602 = s585 ^ s601;
-  const SWord32 s603 = s586 ^ s602;
-  const SWord32 s604 = s587 ^ s603;
-  const SWord32 s605 = (s604 << 8) | (s604 >> 24);
-  const SWord8  s606 = (SWord8) (s605 >> 24);
-  const SWord8  s607 = table2[s606];
-  const SWord8  s608 = 32 ^ s607;
-  const SWord8  s609 = (SWord8) (s605 >> 16);
-  const SWord8  s610 = table2[s609];
-  const SWord16 s611 = (((SWord16) s608) << 8) | ((SWord16) s610);
-  const SWord8  s612 = (SWord8) (s605 >> 8);
-  const SWord8  s613 = table2[s612];
-  const SWord8  s614 = (SWord8) s605;
-  const SWord8  s615 = table2[s614];
-  const SWord16 s616 = (((SWord16) s613) << 8) | ((SWord16) s615);
-  const SWord32 s617 = (((SWord32) s611) << 16) | ((SWord32) s616);
-  const SWord32 s618 = s601 ^ s617;
-  const SWord32 s619 = s602 ^ s618;
-  const SWord32 s620 = s603 ^ s619;
-  const SWord32 s621 = s604 ^ s620;
-  const SWord32 s622 = (s621 << 8) | (s621 >> 24);
-  const SWord8  s623 = (SWord8) (s622 >> 24);
-  const SWord8  s624 = table2[s623];
-  const SWord8  s625 = 64 ^ s624;
-  const SWord8  s626 = (SWord8) (s622 >> 16);
-  const SWord8  s627 = table2[s626];
-  const SWord16 s628 = (((SWord16) s625) << 8) | ((SWord16) s627);
-  const SWord8  s629 = (SWord8) (s622 >> 8);
-  const SWord8  s630 = table2[s629];
-  const SWord8  s631 = (SWord8) s622;
-  const SWord8  s632 = table2[s631];
-  const SWord16 s633 = (((SWord16) s630) << 8) | ((SWord16) s632);
-  const SWord32 s634 = (((SWord32) s628) << 16) | ((SWord32) s633);
-  const SWord32 s635 = s618 ^ s634;
-  const SWord32 s636 = s619 ^ s635;
-  const SWord32 s637 = s620 ^ s636;
-  const SWord32 s638 = s621 ^ s637;
-  const SWord32 s639 = (s638 << 8) | (s638 >> 24);
-  const SWord8  s640 = (SWord8) (s639 >> 24);
-  const SWord8  s641 = table2[s640];
-  const SWord8  s642 = 128 ^ s641;
-  const SWord8  s643 = (SWord8) (s639 >> 16);
-  const SWord8  s644 = table2[s643];
-  const SWord16 s645 = (((SWord16) s642) << 8) | ((SWord16) s644);
-  const SWord8  s646 = (SWord8) (s639 >> 8);
-  const SWord8  s647 = table2[s646];
-  const SWord8  s648 = (SWord8) s639;
-  const SWord8  s649 = table2[s648];
-  const SWord16 s650 = (((SWord16) s647) << 8) | ((SWord16) s649);
-  const SWord32 s651 = (((SWord32) s645) << 16) | ((SWord32) s650);
-  const SWord32 s652 = s635 ^ s651;
-  const SWord32 s653 = s636 ^ s652;
-  const SWord32 s654 = s637 ^ s653;
-  const SWord32 s655 = s638 ^ s654;
-  const SWord32 s656 = (s655 << 8) | (s655 >> 24);
-  const SWord8  s657 = (SWord8) (s656 >> 24);
-  const SWord8  s658 = table2[s657];
-  const SWord8  s659 = 27 ^ s658;
-  const SWord8  s660 = (SWord8) (s656 >> 16);
-  const SWord8  s661 = table2[s660];
-  const SWord16 s662 = (((SWord16) s659) << 8) | ((SWord16) s661);
-  const SWord8  s663 = (SWord8) (s656 >> 8);
-  const SWord8  s664 = table2[s663];
-  const SWord8  s665 = (SWord8) s656;
-  const SWord8  s666 = table2[s665];
-  const SWord16 s667 = (((SWord16) s664) << 8) | ((SWord16) s666);
-  const SWord32 s668 = (((SWord32) s662) << 16) | ((SWord32) s667);
-  const SWord32 s669 = s652 ^ s668;
-  const SWord32 s670 = s653 ^ s669;
-  const SWord32 s671 = s654 ^ s670;
-  const SWord32 s672 = s655 ^ s671;
-  const SWord32 s673 = (s672 << 8) | (s672 >> 24);
-  const SWord8  s674 = (SWord8) (s673 >> 24);
-  const SWord8  s675 = table2[s674];
-  const SWord8  s676 = 54 ^ s675;
-  const SWord8  s677 = (SWord8) (s673 >> 16);
-  const SWord8  s678 = table2[s677];
-  const SWord16 s679 = (((SWord16) s676) << 8) | ((SWord16) s678);
-  const SWord8  s680 = (SWord8) (s673 >> 8);
-  const SWord8  s681 = table2[s680];
-  const SWord8  s682 = (SWord8) s673;
-  const SWord8  s683 = table2[s682];
-  const SWord16 s684 = (((SWord16) s681) << 8) | ((SWord16) s683);
-  const SWord32 s685 = (((SWord32) s679) << 16) | ((SWord32) s684);
-  const SWord32 s686 = s669 ^ s685;
-  const SWord32 s687 = s0 ^ s686;
-  const SWord8  s688 = (SWord8) (s687 >> 24);
-  const SWord32 s689 = table1[s688];
-  const SWord32 s945 = s670 ^ s686;
-  const SWord32 s946 = s671 ^ s945;
-  const SWord32 s947 = s672 ^ s946;
-  const SWord32 s948 = s3 ^ s947;
-  const SWord8  s949 = (SWord8) (s948 >> 16);
-  const SWord32 s950 = table3[s949];
-  const SWord32 s951 = s689 ^ s950;
-  const SWord32 s1207 = s2 ^ s946;
-  const SWord8  s1208 = (SWord8) (s1207 >> 8);
-  const SWord32 s1209 = table4[s1208];
-  const SWord32 s1210 = s951 ^ s1209;
-  const SWord32 s1466 = s1 ^ s945;
-  const SWord8  s1467 = (SWord8) s1466;
-  const SWord32 s1468 = table5[s1467];
-  const SWord32 s1469 = s1210 ^ s1468;
-  const SWord8  s1470 = (SWord8) (s669 >> 24);
-  const SWord8  s1471 = table6[s1470];
-  const SWord8  s1472 = (SWord8) (s669 >> 16);
-  const SWord8  s1473 = table7[s1472];
-  const SWord8  s1474 = (SWord8) (s669 >> 8);
-  const SWord8  s1475 = table8[s1474];
-  const SWord8  s1476 = (SWord8) s669;
-  const SWord8  s1477 = table9[s1476];
-  const SWord8  s1478 = s1475 ^ s1477;
-  const SWord8  s1479 = s1473 ^ s1478;
-  const SWord8  s1480 = s1471 ^ s1479;
-  const SWord8  s1481 = table9[s1470];
-  const SWord8  s1482 = table6[s1472];
-  const SWord8  s1483 = table7[s1474];
-  const SWord8  s1484 = table8[s1476];
-  const SWord8  s1485 = s1483 ^ s1484;
-  const SWord8  s1486 = s1482 ^ s1485;
-  const SWord8  s1487 = s1481 ^ s1486;
-  const SWord16 s1488 = (((SWord16) s1480) << 8) | ((SWord16) s1487);
-  const SWord8  s1489 = table8[s1470];
-  const SWord8  s1490 = table9[s1472];
-  const SWord8  s1491 = table6[s1474];
-  const SWord8  s1492 = table7[s1476];
-  const SWord8  s1493 = s1491 ^ s1492;
-  const SWord8  s1494 = s1490 ^ s1493;
-  const SWord8  s1495 = s1489 ^ s1494;
-  const SWord8  s1496 = table7[s1470];
-  const SWord8  s1497 = table8[s1472];
-  const SWord8  s1498 = table9[s1474];
-  const SWord8  s1499 = table6[s1476];
-  const SWord8  s1500 = s1498 ^ s1499;
-  const SWord8  s1501 = s1497 ^ s1500;
-  const SWord8  s1502 = s1496 ^ s1501;
-  const SWord16 s1503 = (((SWord16) s1495) << 8) | ((SWord16) s1502);
-  const SWord32 s1504 = (((SWord32) s1488) << 16) | ((SWord32) s1503);
-  const SWord32 s1505 = s1469 ^ s1504;
-  const SWord8  s1506 = (SWord8) (s1505 >> 24);
-  const SWord32 s1507 = table1[s1506];
-  const SWord8  s1508 = (SWord8) (s948 >> 24);
-  const SWord32 s1509 = table1[s1508];
-  const SWord8  s1510 = (SWord8) (s1207 >> 16);
-  const SWord32 s1511 = table3[s1510];
-  const SWord32 s1512 = s1509 ^ s1511;
-  const SWord8  s1513 = (SWord8) (s1466 >> 8);
-  const SWord32 s1514 = table4[s1513];
-  const SWord32 s1515 = s1512 ^ s1514;
-  const SWord8  s1516 = (SWord8) s687;
-  const SWord32 s1517 = table5[s1516];
-  const SWord32 s1518 = s1515 ^ s1517;
-  const SWord8  s1519 = (SWord8) (s672 >> 24);
-  const SWord8  s1520 = table6[s1519];
-  const SWord8  s1521 = (SWord8) (s672 >> 16);
-  const SWord8  s1522 = table7[s1521];
-  const SWord8  s1523 = (SWord8) (s672 >> 8);
-  const SWord8  s1524 = table8[s1523];
-  const SWord8  s1525 = (SWord8) s672;
-  const SWord8  s1526 = table9[s1525];
-  const SWord8  s1527 = s1524 ^ s1526;
-  const SWord8  s1528 = s1522 ^ s1527;
-  const SWord8  s1529 = s1520 ^ s1528;
-  const SWord8  s1530 = table9[s1519];
-  const SWord8  s1531 = table6[s1521];
-  const SWord8  s1532 = table7[s1523];
-  const SWord8  s1533 = table8[s1525];
-  const SWord8  s1534 = s1532 ^ s1533;
-  const SWord8  s1535 = s1531 ^ s1534;
-  const SWord8  s1536 = s1530 ^ s1535;
-  const SWord16 s1537 = (((SWord16) s1529) << 8) | ((SWord16) s1536);
-  const SWord8  s1538 = table8[s1519];
-  const SWord8  s1539 = table9[s1521];
-  const SWord8  s1540 = table6[s1523];
-  const SWord8  s1541 = table7[s1525];
-  const SWord8  s1542 = s1540 ^ s1541;
-  const SWord8  s1543 = s1539 ^ s1542;
-  const SWord8  s1544 = s1538 ^ s1543;
-  const SWord8  s1545 = table7[s1519];
-  const SWord8  s1546 = table8[s1521];
-  const SWord8  s1547 = table9[s1523];
-  const SWord8  s1548 = table6[s1525];
-  const SWord8  s1549 = s1547 ^ s1548;
-  const SWord8  s1550 = s1546 ^ s1549;
-  const SWord8  s1551 = s1545 ^ s1550;
-  const SWord16 s1552 = (((SWord16) s1544) << 8) | ((SWord16) s1551);
-  const SWord32 s1553 = (((SWord32) s1537) << 16) | ((SWord32) s1552);
-  const SWord32 s1554 = s1518 ^ s1553;
-  const SWord8  s1555 = (SWord8) (s1554 >> 16);
-  const SWord32 s1556 = table3[s1555];
-  const SWord32 s1557 = s1507 ^ s1556;
-  const SWord8  s1558 = (SWord8) (s1207 >> 24);
-  const SWord32 s1559 = table1[s1558];
-  const SWord8  s1560 = (SWord8) (s1466 >> 16);
-  const SWord32 s1561 = table3[s1560];
-  const SWord32 s1562 = s1559 ^ s1561;
-  const SWord8  s1563 = (SWord8) (s687 >> 8);
-  const SWord32 s1564 = table4[s1563];
-  const SWord32 s1565 = s1562 ^ s1564;
-  const SWord8  s1566 = (SWord8) s948;
-  const SWord32 s1567 = table5[s1566];
-  const SWord32 s1568 = s1565 ^ s1567;
-  const SWord8  s1569 = (SWord8) (s671 >> 24);
-  const SWord8  s1570 = table6[s1569];
-  const SWord8  s1571 = (SWord8) (s671 >> 16);
-  const SWord8  s1572 = table7[s1571];
-  const SWord8  s1573 = (SWord8) (s671 >> 8);
-  const SWord8  s1574 = table8[s1573];
-  const SWord8  s1575 = (SWord8) s671;
-  const SWord8  s1576 = table9[s1575];
-  const SWord8  s1577 = s1574 ^ s1576;
-  const SWord8  s1578 = s1572 ^ s1577;
-  const SWord8  s1579 = s1570 ^ s1578;
-  const SWord8  s1580 = table9[s1569];
-  const SWord8  s1581 = table6[s1571];
-  const SWord8  s1582 = table7[s1573];
-  const SWord8  s1583 = table8[s1575];
-  const SWord8  s1584 = s1582 ^ s1583;
-  const SWord8  s1585 = s1581 ^ s1584;
-  const SWord8  s1586 = s1580 ^ s1585;
-  const SWord16 s1587 = (((SWord16) s1579) << 8) | ((SWord16) s1586);
-  const SWord8  s1588 = table8[s1569];
-  const SWord8  s1589 = table9[s1571];
-  const SWord8  s1590 = table6[s1573];
-  const SWord8  s1591 = table7[s1575];
-  const SWord8  s1592 = s1590 ^ s1591;
-  const SWord8  s1593 = s1589 ^ s1592;
-  const SWord8  s1594 = s1588 ^ s1593;
-  const SWord8  s1595 = table7[s1569];
-  const SWord8  s1596 = table8[s1571];
-  const SWord8  s1597 = table9[s1573];
-  const SWord8  s1598 = table6[s1575];
-  const SWord8  s1599 = s1597 ^ s1598;
-  const SWord8  s1600 = s1596 ^ s1599;
-  const SWord8  s1601 = s1595 ^ s1600;
-  const SWord16 s1602 = (((SWord16) s1594) << 8) | ((SWord16) s1601);
-  const SWord32 s1603 = (((SWord32) s1587) << 16) | ((SWord32) s1602);
-  const SWord32 s1604 = s1568 ^ s1603;
-  const SWord8  s1605 = (SWord8) (s1604 >> 8);
-  const SWord32 s1606 = table4[s1605];
-  const SWord32 s1607 = s1557 ^ s1606;
-  const SWord8  s1608 = (SWord8) (s1466 >> 24);
-  const SWord32 s1609 = table1[s1608];
-  const SWord8  s1610 = (SWord8) (s687 >> 16);
-  const SWord32 s1611 = table3[s1610];
-  const SWord32 s1612 = s1609 ^ s1611;
-  const SWord8  s1613 = (SWord8) (s948 >> 8);
-  const SWord32 s1614 = table4[s1613];
-  const SWord32 s1615 = s1612 ^ s1614;
-  const SWord8  s1616 = (SWord8) s1207;
-  const SWord32 s1617 = table5[s1616];
-  const SWord32 s1618 = s1615 ^ s1617;
-  const SWord8  s1619 = (SWord8) (s670 >> 24);
-  const SWord8  s1620 = table6[s1619];
-  const SWord8  s1621 = (SWord8) (s670 >> 16);
-  const SWord8  s1622 = table7[s1621];
-  const SWord8  s1623 = (SWord8) (s670 >> 8);
-  const SWord8  s1624 = table8[s1623];
-  const SWord8  s1625 = (SWord8) s670;
-  const SWord8  s1626 = table9[s1625];
-  const SWord8  s1627 = s1624 ^ s1626;
-  const SWord8  s1628 = s1622 ^ s1627;
-  const SWord8  s1629 = s1620 ^ s1628;
-  const SWord8  s1630 = table9[s1619];
-  const SWord8  s1631 = table6[s1621];
-  const SWord8  s1632 = table7[s1623];
-  const SWord8  s1633 = table8[s1625];
-  const SWord8  s1634 = s1632 ^ s1633;
-  const SWord8  s1635 = s1631 ^ s1634;
-  const SWord8  s1636 = s1630 ^ s1635;
-  const SWord16 s1637 = (((SWord16) s1629) << 8) | ((SWord16) s1636);
-  const SWord8  s1638 = table8[s1619];
-  const SWord8  s1639 = table9[s1621];
-  const SWord8  s1640 = table6[s1623];
-  const SWord8  s1641 = table7[s1625];
-  const SWord8  s1642 = s1640 ^ s1641;
-  const SWord8  s1643 = s1639 ^ s1642;
-  const SWord8  s1644 = s1638 ^ s1643;
-  const SWord8  s1645 = table7[s1619];
-  const SWord8  s1646 = table8[s1621];
-  const SWord8  s1647 = table9[s1623];
-  const SWord8  s1648 = table6[s1625];
-  const SWord8  s1649 = s1647 ^ s1648;
-  const SWord8  s1650 = s1646 ^ s1649;
-  const SWord8  s1651 = s1645 ^ s1650;
-  const SWord16 s1652 = (((SWord16) s1644) << 8) | ((SWord16) s1651);
-  const SWord32 s1653 = (((SWord32) s1637) << 16) | ((SWord32) s1652);
-  const SWord32 s1654 = s1618 ^ s1653;
-  const SWord8  s1655 = (SWord8) s1654;
-  const SWord32 s1656 = table5[s1655];
-  const SWord32 s1657 = s1607 ^ s1656;
-  const SWord8  s1658 = (SWord8) (s652 >> 24);
-  const SWord8  s1659 = table6[s1658];
-  const SWord8  s1660 = (SWord8) (s652 >> 16);
-  const SWord8  s1661 = table7[s1660];
-  const SWord8  s1662 = (SWord8) (s652 >> 8);
-  const SWord8  s1663 = table8[s1662];
-  const SWord8  s1664 = (SWord8) s652;
-  const SWord8  s1665 = table9[s1664];
-  const SWord8  s1666 = s1663 ^ s1665;
-  const SWord8  s1667 = s1661 ^ s1666;
-  const SWord8  s1668 = s1659 ^ s1667;
-  const SWord8  s1669 = table9[s1658];
-  const SWord8  s1670 = table6[s1660];
-  const SWord8  s1671 = table7[s1662];
-  const SWord8  s1672 = table8[s1664];
-  const SWord8  s1673 = s1671 ^ s1672;
-  const SWord8  s1674 = s1670 ^ s1673;
-  const SWord8  s1675 = s1669 ^ s1674;
-  const SWord16 s1676 = (((SWord16) s1668) << 8) | ((SWord16) s1675);
-  const SWord8  s1677 = table8[s1658];
-  const SWord8  s1678 = table9[s1660];
-  const SWord8  s1679 = table6[s1662];
-  const SWord8  s1680 = table7[s1664];
-  const SWord8  s1681 = s1679 ^ s1680;
-  const SWord8  s1682 = s1678 ^ s1681;
-  const SWord8  s1683 = s1677 ^ s1682;
-  const SWord8  s1684 = table7[s1658];
-  const SWord8  s1685 = table8[s1660];
-  const SWord8  s1686 = table9[s1662];
-  const SWord8  s1687 = table6[s1664];
-  const SWord8  s1688 = s1686 ^ s1687;
-  const SWord8  s1689 = s1685 ^ s1688;
-  const SWord8  s1690 = s1684 ^ s1689;
-  const SWord16 s1691 = (((SWord16) s1683) << 8) | ((SWord16) s1690);
-  const SWord32 s1692 = (((SWord32) s1676) << 16) | ((SWord32) s1691);
-  const SWord32 s1693 = s1657 ^ s1692;
-  const SWord8  s1694 = (SWord8) (s1693 >> 24);
-  const SWord32 s1695 = table1[s1694];
-  const SWord8  s1696 = (SWord8) (s1554 >> 24);
-  const SWord32 s1697 = table1[s1696];
-  const SWord8  s1698 = (SWord8) (s1604 >> 16);
-  const SWord32 s1699 = table3[s1698];
-  const SWord32 s1700 = s1697 ^ s1699;
-  const SWord8  s1701 = (SWord8) (s1654 >> 8);
-  const SWord32 s1702 = table4[s1701];
-  const SWord32 s1703 = s1700 ^ s1702;
-  const SWord8  s1704 = (SWord8) s1505;
-  const SWord32 s1705 = table5[s1704];
-  const SWord32 s1706 = s1703 ^ s1705;
-  const SWord8  s1707 = (SWord8) (s655 >> 24);
-  const SWord8  s1708 = table6[s1707];
-  const SWord8  s1709 = (SWord8) (s655 >> 16);
-  const SWord8  s1710 = table7[s1709];
-  const SWord8  s1711 = (SWord8) (s655 >> 8);
-  const SWord8  s1712 = table8[s1711];
-  const SWord8  s1713 = (SWord8) s655;
-  const SWord8  s1714 = table9[s1713];
-  const SWord8  s1715 = s1712 ^ s1714;
-  const SWord8  s1716 = s1710 ^ s1715;
-  const SWord8  s1717 = s1708 ^ s1716;
-  const SWord8  s1718 = table9[s1707];
-  const SWord8  s1719 = table6[s1709];
-  const SWord8  s1720 = table7[s1711];
-  const SWord8  s1721 = table8[s1713];
-  const SWord8  s1722 = s1720 ^ s1721;
-  const SWord8  s1723 = s1719 ^ s1722;
-  const SWord8  s1724 = s1718 ^ s1723;
-  const SWord16 s1725 = (((SWord16) s1717) << 8) | ((SWord16) s1724);
-  const SWord8  s1726 = table8[s1707];
-  const SWord8  s1727 = table9[s1709];
-  const SWord8  s1728 = table6[s1711];
-  const SWord8  s1729 = table7[s1713];
-  const SWord8  s1730 = s1728 ^ s1729;
-  const SWord8  s1731 = s1727 ^ s1730;
-  const SWord8  s1732 = s1726 ^ s1731;
-  const SWord8  s1733 = table7[s1707];
-  const SWord8  s1734 = table8[s1709];
-  const SWord8  s1735 = table9[s1711];
-  const SWord8  s1736 = table6[s1713];
-  const SWord8  s1737 = s1735 ^ s1736;
-  const SWord8  s1738 = s1734 ^ s1737;
-  const SWord8  s1739 = s1733 ^ s1738;
-  const SWord16 s1740 = (((SWord16) s1732) << 8) | ((SWord16) s1739);
-  const SWord32 s1741 = (((SWord32) s1725) << 16) | ((SWord32) s1740);
-  const SWord32 s1742 = s1706 ^ s1741;
-  const SWord8  s1743 = (SWord8) (s1742 >> 16);
-  const SWord32 s1744 = table3[s1743];
-  const SWord32 s1745 = s1695 ^ s1744;
-  const SWord8  s1746 = (SWord8) (s1604 >> 24);
-  const SWord32 s1747 = table1[s1746];
-  const SWord8  s1748 = (SWord8) (s1654 >> 16);
-  const SWord32 s1749 = table3[s1748];
-  const SWord32 s1750 = s1747 ^ s1749;
-  const SWord8  s1751 = (SWord8) (s1505 >> 8);
-  const SWord32 s1752 = table4[s1751];
-  const SWord32 s1753 = s1750 ^ s1752;
-  const SWord8  s1754 = (SWord8) s1554;
-  const SWord32 s1755 = table5[s1754];
-  const SWord32 s1756 = s1753 ^ s1755;
-  const SWord8  s1757 = (SWord8) (s654 >> 24);
-  const SWord8  s1758 = table6[s1757];
-  const SWord8  s1759 = (SWord8) (s654 >> 16);
-  const SWord8  s1760 = table7[s1759];
-  const SWord8  s1761 = (SWord8) (s654 >> 8);
-  const SWord8  s1762 = table8[s1761];
-  const SWord8  s1763 = (SWord8) s654;
-  const SWord8  s1764 = table9[s1763];
-  const SWord8  s1765 = s1762 ^ s1764;
-  const SWord8  s1766 = s1760 ^ s1765;
-  const SWord8  s1767 = s1758 ^ s1766;
-  const SWord8  s1768 = table9[s1757];
-  const SWord8  s1769 = table6[s1759];
-  const SWord8  s1770 = table7[s1761];
-  const SWord8  s1771 = table8[s1763];
-  const SWord8  s1772 = s1770 ^ s1771;
-  const SWord8  s1773 = s1769 ^ s1772;
-  const SWord8  s1774 = s1768 ^ s1773;
-  const SWord16 s1775 = (((SWord16) s1767) << 8) | ((SWord16) s1774);
-  const SWord8  s1776 = table8[s1757];
-  const SWord8  s1777 = table9[s1759];
-  const SWord8  s1778 = table6[s1761];
-  const SWord8  s1779 = table7[s1763];
-  const SWord8  s1780 = s1778 ^ s1779;
-  const SWord8  s1781 = s1777 ^ s1780;
-  const SWord8  s1782 = s1776 ^ s1781;
-  const SWord8  s1783 = table7[s1757];
-  const SWord8  s1784 = table8[s1759];
-  const SWord8  s1785 = table9[s1761];
-  const SWord8  s1786 = table6[s1763];
-  const SWord8  s1787 = s1785 ^ s1786;
-  const SWord8  s1788 = s1784 ^ s1787;
-  const SWord8  s1789 = s1783 ^ s1788;
-  const SWord16 s1790 = (((SWord16) s1782) << 8) | ((SWord16) s1789);
-  const SWord32 s1791 = (((SWord32) s1775) << 16) | ((SWord32) s1790);
-  const SWord32 s1792 = s1756 ^ s1791;
-  const SWord8  s1793 = (SWord8) (s1792 >> 8);
-  const SWord32 s1794 = table4[s1793];
-  const SWord32 s1795 = s1745 ^ s1794;
-  const SWord8  s1796 = (SWord8) (s1654 >> 24);
-  const SWord32 s1797 = table1[s1796];
-  const SWord8  s1798 = (SWord8) (s1505 >> 16);
-  const SWord32 s1799 = table3[s1798];
-  const SWord32 s1800 = s1797 ^ s1799;
-  const SWord8  s1801 = (SWord8) (s1554 >> 8);
-  const SWord32 s1802 = table4[s1801];
-  const SWord32 s1803 = s1800 ^ s1802;
-  const SWord8  s1804 = (SWord8) s1604;
-  const SWord32 s1805 = table5[s1804];
-  const SWord32 s1806 = s1803 ^ s1805;
-  const SWord8  s1807 = (SWord8) (s653 >> 24);
-  const SWord8  s1808 = table6[s1807];
-  const SWord8  s1809 = (SWord8) (s653 >> 16);
-  const SWord8  s1810 = table7[s1809];
-  const SWord8  s1811 = (SWord8) (s653 >> 8);
-  const SWord8  s1812 = table8[s1811];
-  const SWord8  s1813 = (SWord8) s653;
-  const SWord8  s1814 = table9[s1813];
-  const SWord8  s1815 = s1812 ^ s1814;
-  const SWord8  s1816 = s1810 ^ s1815;
-  const SWord8  s1817 = s1808 ^ s1816;
-  const SWord8  s1818 = table9[s1807];
-  const SWord8  s1819 = table6[s1809];
-  const SWord8  s1820 = table7[s1811];
-  const SWord8  s1821 = table8[s1813];
-  const SWord8  s1822 = s1820 ^ s1821;
-  const SWord8  s1823 = s1819 ^ s1822;
-  const SWord8  s1824 = s1818 ^ s1823;
-  const SWord16 s1825 = (((SWord16) s1817) << 8) | ((SWord16) s1824);
-  const SWord8  s1826 = table8[s1807];
-  const SWord8  s1827 = table9[s1809];
-  const SWord8  s1828 = table6[s1811];
-  const SWord8  s1829 = table7[s1813];
-  const SWord8  s1830 = s1828 ^ s1829;
-  const SWord8  s1831 = s1827 ^ s1830;
-  const SWord8  s1832 = s1826 ^ s1831;
-  const SWord8  s1833 = table7[s1807];
-  const SWord8  s1834 = table8[s1809];
-  const SWord8  s1835 = table9[s1811];
-  const SWord8  s1836 = table6[s1813];
-  const SWord8  s1837 = s1835 ^ s1836;
-  const SWord8  s1838 = s1834 ^ s1837;
-  const SWord8  s1839 = s1833 ^ s1838;
-  const SWord16 s1840 = (((SWord16) s1832) << 8) | ((SWord16) s1839);
-  const SWord32 s1841 = (((SWord32) s1825) << 16) | ((SWord32) s1840);
-  const SWord32 s1842 = s1806 ^ s1841;
-  const SWord8  s1843 = (SWord8) s1842;
-  const SWord32 s1844 = table5[s1843];
-  const SWord32 s1845 = s1795 ^ s1844;
-  const SWord8  s1846 = (SWord8) (s635 >> 24);
-  const SWord8  s1847 = table6[s1846];
-  const SWord8  s1848 = (SWord8) (s635 >> 16);
-  const SWord8  s1849 = table7[s1848];
-  const SWord8  s1850 = (SWord8) (s635 >> 8);
-  const SWord8  s1851 = table8[s1850];
-  const SWord8  s1852 = (SWord8) s635;
-  const SWord8  s1853 = table9[s1852];
-  const SWord8  s1854 = s1851 ^ s1853;
-  const SWord8  s1855 = s1849 ^ s1854;
-  const SWord8  s1856 = s1847 ^ s1855;
-  const SWord8  s1857 = table9[s1846];
-  const SWord8  s1858 = table6[s1848];
-  const SWord8  s1859 = table7[s1850];
-  const SWord8  s1860 = table8[s1852];
-  const SWord8  s1861 = s1859 ^ s1860;
-  const SWord8  s1862 = s1858 ^ s1861;
-  const SWord8  s1863 = s1857 ^ s1862;
-  const SWord16 s1864 = (((SWord16) s1856) << 8) | ((SWord16) s1863);
-  const SWord8  s1865 = table8[s1846];
-  const SWord8  s1866 = table9[s1848];
-  const SWord8  s1867 = table6[s1850];
-  const SWord8  s1868 = table7[s1852];
-  const SWord8  s1869 = s1867 ^ s1868;
-  const SWord8  s1870 = s1866 ^ s1869;
-  const SWord8  s1871 = s1865 ^ s1870;
-  const SWord8  s1872 = table7[s1846];
-  const SWord8  s1873 = table8[s1848];
-  const SWord8  s1874 = table9[s1850];
-  const SWord8  s1875 = table6[s1852];
-  const SWord8  s1876 = s1874 ^ s1875;
-  const SWord8  s1877 = s1873 ^ s1876;
-  const SWord8  s1878 = s1872 ^ s1877;
-  const SWord16 s1879 = (((SWord16) s1871) << 8) | ((SWord16) s1878);
-  const SWord32 s1880 = (((SWord32) s1864) << 16) | ((SWord32) s1879);
-  const SWord32 s1881 = s1845 ^ s1880;
-  const SWord8  s1882 = (SWord8) (s1881 >> 24);
-  const SWord32 s1883 = table1[s1882];
-  const SWord8  s1884 = (SWord8) (s1742 >> 24);
-  const SWord32 s1885 = table1[s1884];
-  const SWord8  s1886 = (SWord8) (s1792 >> 16);
-  const SWord32 s1887 = table3[s1886];
-  const SWord32 s1888 = s1885 ^ s1887;
-  const SWord8  s1889 = (SWord8) (s1842 >> 8);
-  const SWord32 s1890 = table4[s1889];
-  const SWord32 s1891 = s1888 ^ s1890;
-  const SWord8  s1892 = (SWord8) s1693;
-  const SWord32 s1893 = table5[s1892];
-  const SWord32 s1894 = s1891 ^ s1893;
-  const SWord8  s1895 = (SWord8) (s638 >> 24);
-  const SWord8  s1896 = table6[s1895];
-  const SWord8  s1897 = (SWord8) (s638 >> 16);
-  const SWord8  s1898 = table7[s1897];
-  const SWord8  s1899 = (SWord8) (s638 >> 8);
-  const SWord8  s1900 = table8[s1899];
-  const SWord8  s1901 = (SWord8) s638;
-  const SWord8  s1902 = table9[s1901];
-  const SWord8  s1903 = s1900 ^ s1902;
-  const SWord8  s1904 = s1898 ^ s1903;
-  const SWord8  s1905 = s1896 ^ s1904;
-  const SWord8  s1906 = table9[s1895];
-  const SWord8  s1907 = table6[s1897];
-  const SWord8  s1908 = table7[s1899];
-  const SWord8  s1909 = table8[s1901];
-  const SWord8  s1910 = s1908 ^ s1909;
-  const SWord8  s1911 = s1907 ^ s1910;
-  const SWord8  s1912 = s1906 ^ s1911;
-  const SWord16 s1913 = (((SWord16) s1905) << 8) | ((SWord16) s1912);
-  const SWord8  s1914 = table8[s1895];
-  const SWord8  s1915 = table9[s1897];
-  const SWord8  s1916 = table6[s1899];
-  const SWord8  s1917 = table7[s1901];
-  const SWord8  s1918 = s1916 ^ s1917;
-  const SWord8  s1919 = s1915 ^ s1918;
-  const SWord8  s1920 = s1914 ^ s1919;
-  const SWord8  s1921 = table7[s1895];
-  const SWord8  s1922 = table8[s1897];
-  const SWord8  s1923 = table9[s1899];
-  const SWord8  s1924 = table6[s1901];
-  const SWord8  s1925 = s1923 ^ s1924;
-  const SWord8  s1926 = s1922 ^ s1925;
-  const SWord8  s1927 = s1921 ^ s1926;
-  const SWord16 s1928 = (((SWord16) s1920) << 8) | ((SWord16) s1927);
-  const SWord32 s1929 = (((SWord32) s1913) << 16) | ((SWord32) s1928);
-  const SWord32 s1930 = s1894 ^ s1929;
-  const SWord8  s1931 = (SWord8) (s1930 >> 16);
-  const SWord32 s1932 = table3[s1931];
-  const SWord32 s1933 = s1883 ^ s1932;
-  const SWord8  s1934 = (SWord8) (s1792 >> 24);
-  const SWord32 s1935 = table1[s1934];
-  const SWord8  s1936 = (SWord8) (s1842 >> 16);
-  const SWord32 s1937 = table3[s1936];
-  const SWord32 s1938 = s1935 ^ s1937;
-  const SWord8  s1939 = (SWord8) (s1693 >> 8);
-  const SWord32 s1940 = table4[s1939];
-  const SWord32 s1941 = s1938 ^ s1940;
-  const SWord8  s1942 = (SWord8) s1742;
-  const SWord32 s1943 = table5[s1942];
-  const SWord32 s1944 = s1941 ^ s1943;
-  const SWord8  s1945 = (SWord8) (s637 >> 24);
-  const SWord8  s1946 = table6[s1945];
-  const SWord8  s1947 = (SWord8) (s637 >> 16);
-  const SWord8  s1948 = table7[s1947];
-  const SWord8  s1949 = (SWord8) (s637 >> 8);
-  const SWord8  s1950 = table8[s1949];
-  const SWord8  s1951 = (SWord8) s637;
-  const SWord8  s1952 = table9[s1951];
-  const SWord8  s1953 = s1950 ^ s1952;
-  const SWord8  s1954 = s1948 ^ s1953;
-  const SWord8  s1955 = s1946 ^ s1954;
-  const SWord8  s1956 = table9[s1945];
-  const SWord8  s1957 = table6[s1947];
-  const SWord8  s1958 = table7[s1949];
-  const SWord8  s1959 = table8[s1951];
-  const SWord8  s1960 = s1958 ^ s1959;
-  const SWord8  s1961 = s1957 ^ s1960;
-  const SWord8  s1962 = s1956 ^ s1961;
-  const SWord16 s1963 = (((SWord16) s1955) << 8) | ((SWord16) s1962);
-  const SWord8  s1964 = table8[s1945];
-  const SWord8  s1965 = table9[s1947];
-  const SWord8  s1966 = table6[s1949];
-  const SWord8  s1967 = table7[s1951];
-  const SWord8  s1968 = s1966 ^ s1967;
-  const SWord8  s1969 = s1965 ^ s1968;
-  const SWord8  s1970 = s1964 ^ s1969;
-  const SWord8  s1971 = table7[s1945];
-  const SWord8  s1972 = table8[s1947];
-  const SWord8  s1973 = table9[s1949];
-  const SWord8  s1974 = table6[s1951];
-  const SWord8  s1975 = s1973 ^ s1974;
-  const SWord8  s1976 = s1972 ^ s1975;
-  const SWord8  s1977 = s1971 ^ s1976;
-  const SWord16 s1978 = (((SWord16) s1970) << 8) | ((SWord16) s1977);
-  const SWord32 s1979 = (((SWord32) s1963) << 16) | ((SWord32) s1978);
-  const SWord32 s1980 = s1944 ^ s1979;
-  const SWord8  s1981 = (SWord8) (s1980 >> 8);
-  const SWord32 s1982 = table4[s1981];
-  const SWord32 s1983 = s1933 ^ s1982;
-  const SWord8  s1984 = (SWord8) (s1842 >> 24);
-  const SWord32 s1985 = table1[s1984];
-  const SWord8  s1986 = (SWord8) (s1693 >> 16);
-  const SWord32 s1987 = table3[s1986];
-  const SWord32 s1988 = s1985 ^ s1987;
-  const SWord8  s1989 = (SWord8) (s1742 >> 8);
-  const SWord32 s1990 = table4[s1989];
-  const SWord32 s1991 = s1988 ^ s1990;
-  const SWord8  s1992 = (SWord8) s1792;
-  const SWord32 s1993 = table5[s1992];
-  const SWord32 s1994 = s1991 ^ s1993;
-  const SWord8  s1995 = (SWord8) (s636 >> 24);
-  const SWord8  s1996 = table6[s1995];
-  const SWord8  s1997 = (SWord8) (s636 >> 16);
-  const SWord8  s1998 = table7[s1997];
-  const SWord8  s1999 = (SWord8) (s636 >> 8);
-  const SWord8  s2000 = table8[s1999];
-  const SWord8  s2001 = (SWord8) s636;
-  const SWord8  s2002 = table9[s2001];
-  const SWord8  s2003 = s2000 ^ s2002;
-  const SWord8  s2004 = s1998 ^ s2003;
-  const SWord8  s2005 = s1996 ^ s2004;
-  const SWord8  s2006 = table9[s1995];
-  const SWord8  s2007 = table6[s1997];
-  const SWord8  s2008 = table7[s1999];
-  const SWord8  s2009 = table8[s2001];
-  const SWord8  s2010 = s2008 ^ s2009;
-  const SWord8  s2011 = s2007 ^ s2010;
-  const SWord8  s2012 = s2006 ^ s2011;
-  const SWord16 s2013 = (((SWord16) s2005) << 8) | ((SWord16) s2012);
-  const SWord8  s2014 = table8[s1995];
-  const SWord8  s2015 = table9[s1997];
-  const SWord8  s2016 = table6[s1999];
-  const SWord8  s2017 = table7[s2001];
-  const SWord8  s2018 = s2016 ^ s2017;
-  const SWord8  s2019 = s2015 ^ s2018;
-  const SWord8  s2020 = s2014 ^ s2019;
-  const SWord8  s2021 = table7[s1995];
-  const SWord8  s2022 = table8[s1997];
-  const SWord8  s2023 = table9[s1999];
-  const SWord8  s2024 = table6[s2001];
-  const SWord8  s2025 = s2023 ^ s2024;
-  const SWord8  s2026 = s2022 ^ s2025;
-  const SWord8  s2027 = s2021 ^ s2026;
-  const SWord16 s2028 = (((SWord16) s2020) << 8) | ((SWord16) s2027);
-  const SWord32 s2029 = (((SWord32) s2013) << 16) | ((SWord32) s2028);
-  const SWord32 s2030 = s1994 ^ s2029;
-  const SWord8  s2031 = (SWord8) s2030;
-  const SWord32 s2032 = table5[s2031];
-  const SWord32 s2033 = s1983 ^ s2032;
-  const SWord8  s2034 = (SWord8) (s618 >> 24);
-  const SWord8  s2035 = table6[s2034];
-  const SWord8  s2036 = (SWord8) (s618 >> 16);
-  const SWord8  s2037 = table7[s2036];
-  const SWord8  s2038 = (SWord8) (s618 >> 8);
-  const SWord8  s2039 = table8[s2038];
-  const SWord8  s2040 = (SWord8) s618;
-  const SWord8  s2041 = table9[s2040];
-  const SWord8  s2042 = s2039 ^ s2041;
-  const SWord8  s2043 = s2037 ^ s2042;
-  const SWord8  s2044 = s2035 ^ s2043;
-  const SWord8  s2045 = table9[s2034];
-  const SWord8  s2046 = table6[s2036];
-  const SWord8  s2047 = table7[s2038];
-  const SWord8  s2048 = table8[s2040];
-  const SWord8  s2049 = s2047 ^ s2048;
-  const SWord8  s2050 = s2046 ^ s2049;
-  const SWord8  s2051 = s2045 ^ s2050;
-  const SWord16 s2052 = (((SWord16) s2044) << 8) | ((SWord16) s2051);
-  const SWord8  s2053 = table8[s2034];
-  const SWord8  s2054 = table9[s2036];
-  const SWord8  s2055 = table6[s2038];
-  const SWord8  s2056 = table7[s2040];
-  const SWord8  s2057 = s2055 ^ s2056;
-  const SWord8  s2058 = s2054 ^ s2057;
-  const SWord8  s2059 = s2053 ^ s2058;
-  const SWord8  s2060 = table7[s2034];
-  const SWord8  s2061 = table8[s2036];
-  const SWord8  s2062 = table9[s2038];
-  const SWord8  s2063 = table6[s2040];
-  const SWord8  s2064 = s2062 ^ s2063;
-  const SWord8  s2065 = s2061 ^ s2064;
-  const SWord8  s2066 = s2060 ^ s2065;
-  const SWord16 s2067 = (((SWord16) s2059) << 8) | ((SWord16) s2066);
-  const SWord32 s2068 = (((SWord32) s2052) << 16) | ((SWord32) s2067);
-  const SWord32 s2069 = s2033 ^ s2068;
-  const SWord8  s2070 = (SWord8) (s2069 >> 24);
-  const SWord32 s2071 = table1[s2070];
-  const SWord8  s2072 = (SWord8) (s1930 >> 24);
-  const SWord32 s2073 = table1[s2072];
-  const SWord8  s2074 = (SWord8) (s1980 >> 16);
-  const SWord32 s2075 = table3[s2074];
-  const SWord32 s2076 = s2073 ^ s2075;
-  const SWord8  s2077 = (SWord8) (s2030 >> 8);
-  const SWord32 s2078 = table4[s2077];
-  const SWord32 s2079 = s2076 ^ s2078;
-  const SWord8  s2080 = (SWord8) s1881;
-  const SWord32 s2081 = table5[s2080];
-  const SWord32 s2082 = s2079 ^ s2081;
-  const SWord8  s2083 = (SWord8) (s621 >> 24);
-  const SWord8  s2084 = table6[s2083];
-  const SWord8  s2085 = (SWord8) (s621 >> 16);
-  const SWord8  s2086 = table7[s2085];
-  const SWord8  s2087 = (SWord8) (s621 >> 8);
-  const SWord8  s2088 = table8[s2087];
-  const SWord8  s2089 = (SWord8) s621;
-  const SWord8  s2090 = table9[s2089];
-  const SWord8  s2091 = s2088 ^ s2090;
-  const SWord8  s2092 = s2086 ^ s2091;
-  const SWord8  s2093 = s2084 ^ s2092;
-  const SWord8  s2094 = table9[s2083];
-  const SWord8  s2095 = table6[s2085];
-  const SWord8  s2096 = table7[s2087];
-  const SWord8  s2097 = table8[s2089];
-  const SWord8  s2098 = s2096 ^ s2097;
-  const SWord8  s2099 = s2095 ^ s2098;
-  const SWord8  s2100 = s2094 ^ s2099;
-  const SWord16 s2101 = (((SWord16) s2093) << 8) | ((SWord16) s2100);
-  const SWord8  s2102 = table8[s2083];
-  const SWord8  s2103 = table9[s2085];
-  const SWord8  s2104 = table6[s2087];
-  const SWord8  s2105 = table7[s2089];
-  const SWord8  s2106 = s2104 ^ s2105;
-  const SWord8  s2107 = s2103 ^ s2106;
-  const SWord8  s2108 = s2102 ^ s2107;
-  const SWord8  s2109 = table7[s2083];
-  const SWord8  s2110 = table8[s2085];
-  const SWord8  s2111 = table9[s2087];
-  const SWord8  s2112 = table6[s2089];
-  const SWord8  s2113 = s2111 ^ s2112;
-  const SWord8  s2114 = s2110 ^ s2113;
-  const SWord8  s2115 = s2109 ^ s2114;
-  const SWord16 s2116 = (((SWord16) s2108) << 8) | ((SWord16) s2115);
-  const SWord32 s2117 = (((SWord32) s2101) << 16) | ((SWord32) s2116);
-  const SWord32 s2118 = s2082 ^ s2117;
-  const SWord8  s2119 = (SWord8) (s2118 >> 16);
-  const SWord32 s2120 = table3[s2119];
-  const SWord32 s2121 = s2071 ^ s2120;
-  const SWord8  s2122 = (SWord8) (s1980 >> 24);
-  const SWord32 s2123 = table1[s2122];
-  const SWord8  s2124 = (SWord8) (s2030 >> 16);
-  const SWord32 s2125 = table3[s2124];
-  const SWord32 s2126 = s2123 ^ s2125;
-  const SWord8  s2127 = (SWord8) (s1881 >> 8);
-  const SWord32 s2128 = table4[s2127];
-  const SWord32 s2129 = s2126 ^ s2128;
-  const SWord8  s2130 = (SWord8) s1930;
-  const SWord32 s2131 = table5[s2130];
-  const SWord32 s2132 = s2129 ^ s2131;
-  const SWord8  s2133 = (SWord8) (s620 >> 24);
-  const SWord8  s2134 = table6[s2133];
-  const SWord8  s2135 = (SWord8) (s620 >> 16);
-  const SWord8  s2136 = table7[s2135];
-  const SWord8  s2137 = (SWord8) (s620 >> 8);
-  const SWord8  s2138 = table8[s2137];
-  const SWord8  s2139 = (SWord8) s620;
-  const SWord8  s2140 = table9[s2139];
-  const SWord8  s2141 = s2138 ^ s2140;
-  const SWord8  s2142 = s2136 ^ s2141;
-  const SWord8  s2143 = s2134 ^ s2142;
-  const SWord8  s2144 = table9[s2133];
-  const SWord8  s2145 = table6[s2135];
-  const SWord8  s2146 = table7[s2137];
-  const SWord8  s2147 = table8[s2139];
-  const SWord8  s2148 = s2146 ^ s2147;
-  const SWord8  s2149 = s2145 ^ s2148;
-  const SWord8  s2150 = s2144 ^ s2149;
-  const SWord16 s2151 = (((SWord16) s2143) << 8) | ((SWord16) s2150);
-  const SWord8  s2152 = table8[s2133];
-  const SWord8  s2153 = table9[s2135];
-  const SWord8  s2154 = table6[s2137];
-  const SWord8  s2155 = table7[s2139];
-  const SWord8  s2156 = s2154 ^ s2155;
-  const SWord8  s2157 = s2153 ^ s2156;
-  const SWord8  s2158 = s2152 ^ s2157;
-  const SWord8  s2159 = table7[s2133];
-  const SWord8  s2160 = table8[s2135];
-  const SWord8  s2161 = table9[s2137];
-  const SWord8  s2162 = table6[s2139];
-  const SWord8  s2163 = s2161 ^ s2162;
-  const SWord8  s2164 = s2160 ^ s2163;
-  const SWord8  s2165 = s2159 ^ s2164;
-  const SWord16 s2166 = (((SWord16) s2158) << 8) | ((SWord16) s2165);
-  const SWord32 s2167 = (((SWord32) s2151) << 16) | ((SWord32) s2166);
-  const SWord32 s2168 = s2132 ^ s2167;
-  const SWord8  s2169 = (SWord8) (s2168 >> 8);
-  const SWord32 s2170 = table4[s2169];
-  const SWord32 s2171 = s2121 ^ s2170;
-  const SWord8  s2172 = (SWord8) (s2030 >> 24);
-  const SWord32 s2173 = table1[s2172];
-  const SWord8  s2174 = (SWord8) (s1881 >> 16);
-  const SWord32 s2175 = table3[s2174];
-  const SWord32 s2176 = s2173 ^ s2175;
-  const SWord8  s2177 = (SWord8) (s1930 >> 8);
-  const SWord32 s2178 = table4[s2177];
-  const SWord32 s2179 = s2176 ^ s2178;
-  const SWord8  s2180 = (SWord8) s1980;
-  const SWord32 s2181 = table5[s2180];
-  const SWord32 s2182 = s2179 ^ s2181;
-  const SWord8  s2183 = (SWord8) (s619 >> 24);
-  const SWord8  s2184 = table6[s2183];
-  const SWord8  s2185 = (SWord8) (s619 >> 16);
-  const SWord8  s2186 = table7[s2185];
-  const SWord8  s2187 = (SWord8) (s619 >> 8);
-  const SWord8  s2188 = table8[s2187];
-  const SWord8  s2189 = (SWord8) s619;
-  const SWord8  s2190 = table9[s2189];
-  const SWord8  s2191 = s2188 ^ s2190;
-  const SWord8  s2192 = s2186 ^ s2191;
-  const SWord8  s2193 = s2184 ^ s2192;
-  const SWord8  s2194 = table9[s2183];
-  const SWord8  s2195 = table6[s2185];
-  const SWord8  s2196 = table7[s2187];
-  const SWord8  s2197 = table8[s2189];
-  const SWord8  s2198 = s2196 ^ s2197;
-  const SWord8  s2199 = s2195 ^ s2198;
-  const SWord8  s2200 = s2194 ^ s2199;
-  const SWord16 s2201 = (((SWord16) s2193) << 8) | ((SWord16) s2200);
-  const SWord8  s2202 = table8[s2183];
-  const SWord8  s2203 = table9[s2185];
-  const SWord8  s2204 = table6[s2187];
-  const SWord8  s2205 = table7[s2189];
-  const SWord8  s2206 = s2204 ^ s2205;
-  const SWord8  s2207 = s2203 ^ s2206;
-  const SWord8  s2208 = s2202 ^ s2207;
-  const SWord8  s2209 = table7[s2183];
-  const SWord8  s2210 = table8[s2185];
-  const SWord8  s2211 = table9[s2187];
-  const SWord8  s2212 = table6[s2189];
-  const SWord8  s2213 = s2211 ^ s2212;
-  const SWord8  s2214 = s2210 ^ s2213;
-  const SWord8  s2215 = s2209 ^ s2214;
-  const SWord16 s2216 = (((SWord16) s2208) << 8) | ((SWord16) s2215);
-  const SWord32 s2217 = (((SWord32) s2201) << 16) | ((SWord32) s2216);
-  const SWord32 s2218 = s2182 ^ s2217;
-  const SWord8  s2219 = (SWord8) s2218;
-  const SWord32 s2220 = table5[s2219];
-  const SWord32 s2221 = s2171 ^ s2220;
-  const SWord8  s2222 = (SWord8) (s601 >> 24);
-  const SWord8  s2223 = table6[s2222];
-  const SWord8  s2224 = (SWord8) (s601 >> 16);
-  const SWord8  s2225 = table7[s2224];
-  const SWord8  s2226 = (SWord8) (s601 >> 8);
-  const SWord8  s2227 = table8[s2226];
-  const SWord8  s2228 = (SWord8) s601;
-  const SWord8  s2229 = table9[s2228];
-  const SWord8  s2230 = s2227 ^ s2229;
-  const SWord8  s2231 = s2225 ^ s2230;
-  const SWord8  s2232 = s2223 ^ s2231;
-  const SWord8  s2233 = table9[s2222];
-  const SWord8  s2234 = table6[s2224];
-  const SWord8  s2235 = table7[s2226];
-  const SWord8  s2236 = table8[s2228];
-  const SWord8  s2237 = s2235 ^ s2236;
-  const SWord8  s2238 = s2234 ^ s2237;
-  const SWord8  s2239 = s2233 ^ s2238;
-  const SWord16 s2240 = (((SWord16) s2232) << 8) | ((SWord16) s2239);
-  const SWord8  s2241 = table8[s2222];
-  const SWord8  s2242 = table9[s2224];
-  const SWord8  s2243 = table6[s2226];
-  const SWord8  s2244 = table7[s2228];
-  const SWord8  s2245 = s2243 ^ s2244;
-  const SWord8  s2246 = s2242 ^ s2245;
-  const SWord8  s2247 = s2241 ^ s2246;
-  const SWord8  s2248 = table7[s2222];
-  const SWord8  s2249 = table8[s2224];
-  const SWord8  s2250 = table9[s2226];
-  const SWord8  s2251 = table6[s2228];
-  const SWord8  s2252 = s2250 ^ s2251;
-  const SWord8  s2253 = s2249 ^ s2252;
-  const SWord8  s2254 = s2248 ^ s2253;
-  const SWord16 s2255 = (((SWord16) s2247) << 8) | ((SWord16) s2254);
-  const SWord32 s2256 = (((SWord32) s2240) << 16) | ((SWord32) s2255);
-  const SWord32 s2257 = s2221 ^ s2256;
-  const SWord8  s2258 = (SWord8) (s2257 >> 24);
-  const SWord32 s2259 = table1[s2258];
-  const SWord8  s2260 = (SWord8) (s2118 >> 24);
-  const SWord32 s2261 = table1[s2260];
-  const SWord8  s2262 = (SWord8) (s2168 >> 16);
-  const SWord32 s2263 = table3[s2262];
-  const SWord32 s2264 = s2261 ^ s2263;
-  const SWord8  s2265 = (SWord8) (s2218 >> 8);
-  const SWord32 s2266 = table4[s2265];
-  const SWord32 s2267 = s2264 ^ s2266;
-  const SWord8  s2268 = (SWord8) s2069;
-  const SWord32 s2269 = table5[s2268];
-  const SWord32 s2270 = s2267 ^ s2269;
-  const SWord8  s2271 = (SWord8) (s604 >> 24);
-  const SWord8  s2272 = table6[s2271];
-  const SWord8  s2273 = (SWord8) (s604 >> 16);
-  const SWord8  s2274 = table7[s2273];
-  const SWord8  s2275 = (SWord8) (s604 >> 8);
-  const SWord8  s2276 = table8[s2275];
-  const SWord8  s2277 = (SWord8) s604;
-  const SWord8  s2278 = table9[s2277];
-  const SWord8  s2279 = s2276 ^ s2278;
-  const SWord8  s2280 = s2274 ^ s2279;
-  const SWord8  s2281 = s2272 ^ s2280;
-  const SWord8  s2282 = table9[s2271];
-  const SWord8  s2283 = table6[s2273];
-  const SWord8  s2284 = table7[s2275];
-  const SWord8  s2285 = table8[s2277];
-  const SWord8  s2286 = s2284 ^ s2285;
-  const SWord8  s2287 = s2283 ^ s2286;
-  const SWord8  s2288 = s2282 ^ s2287;
-  const SWord16 s2289 = (((SWord16) s2281) << 8) | ((SWord16) s2288);
-  const SWord8  s2290 = table8[s2271];
-  const SWord8  s2291 = table9[s2273];
-  const SWord8  s2292 = table6[s2275];
-  const SWord8  s2293 = table7[s2277];
-  const SWord8  s2294 = s2292 ^ s2293;
-  const SWord8  s2295 = s2291 ^ s2294;
-  const SWord8  s2296 = s2290 ^ s2295;
-  const SWord8  s2297 = table7[s2271];
-  const SWord8  s2298 = table8[s2273];
-  const SWord8  s2299 = table9[s2275];
-  const SWord8  s2300 = table6[s2277];
-  const SWord8  s2301 = s2299 ^ s2300;
-  const SWord8  s2302 = s2298 ^ s2301;
-  const SWord8  s2303 = s2297 ^ s2302;
-  const SWord16 s2304 = (((SWord16) s2296) << 8) | ((SWord16) s2303);
-  const SWord32 s2305 = (((SWord32) s2289) << 16) | ((SWord32) s2304);
-  const SWord32 s2306 = s2270 ^ s2305;
-  const SWord8  s2307 = (SWord8) (s2306 >> 16);
-  const SWord32 s2308 = table3[s2307];
-  const SWord32 s2309 = s2259 ^ s2308;
-  const SWord8  s2310 = (SWord8) (s2168 >> 24);
-  const SWord32 s2311 = table1[s2310];
-  const SWord8  s2312 = (SWord8) (s2218 >> 16);
-  const SWord32 s2313 = table3[s2312];
-  const SWord32 s2314 = s2311 ^ s2313;
-  const SWord8  s2315 = (SWord8) (s2069 >> 8);
-  const SWord32 s2316 = table4[s2315];
-  const SWord32 s2317 = s2314 ^ s2316;
-  const SWord8  s2318 = (SWord8) s2118;
-  const SWord32 s2319 = table5[s2318];
-  const SWord32 s2320 = s2317 ^ s2319;
-  const SWord8  s2321 = (SWord8) (s603 >> 24);
-  const SWord8  s2322 = table6[s2321];
-  const SWord8  s2323 = (SWord8) (s603 >> 16);
-  const SWord8  s2324 = table7[s2323];
-  const SWord8  s2325 = (SWord8) (s603 >> 8);
-  const SWord8  s2326 = table8[s2325];
-  const SWord8  s2327 = (SWord8) s603;
-  const SWord8  s2328 = table9[s2327];
-  const SWord8  s2329 = s2326 ^ s2328;
-  const SWord8  s2330 = s2324 ^ s2329;
-  const SWord8  s2331 = s2322 ^ s2330;
-  const SWord8  s2332 = table9[s2321];
-  const SWord8  s2333 = table6[s2323];
-  const SWord8  s2334 = table7[s2325];
-  const SWord8  s2335 = table8[s2327];
-  const SWord8  s2336 = s2334 ^ s2335;
-  const SWord8  s2337 = s2333 ^ s2336;
-  const SWord8  s2338 = s2332 ^ s2337;
-  const SWord16 s2339 = (((SWord16) s2331) << 8) | ((SWord16) s2338);
-  const SWord8  s2340 = table8[s2321];
-  const SWord8  s2341 = table9[s2323];
-  const SWord8  s2342 = table6[s2325];
-  const SWord8  s2343 = table7[s2327];
-  const SWord8  s2344 = s2342 ^ s2343;
-  const SWord8  s2345 = s2341 ^ s2344;
-  const SWord8  s2346 = s2340 ^ s2345;
-  const SWord8  s2347 = table7[s2321];
-  const SWord8  s2348 = table8[s2323];
-  const SWord8  s2349 = table9[s2325];
-  const SWord8  s2350 = table6[s2327];
-  const SWord8  s2351 = s2349 ^ s2350;
-  const SWord8  s2352 = s2348 ^ s2351;
-  const SWord8  s2353 = s2347 ^ s2352;
-  const SWord16 s2354 = (((SWord16) s2346) << 8) | ((SWord16) s2353);
-  const SWord32 s2355 = (((SWord32) s2339) << 16) | ((SWord32) s2354);
-  const SWord32 s2356 = s2320 ^ s2355;
-  const SWord8  s2357 = (SWord8) (s2356 >> 8);
-  const SWord32 s2358 = table4[s2357];
-  const SWord32 s2359 = s2309 ^ s2358;
-  const SWord8  s2360 = (SWord8) (s2218 >> 24);
-  const SWord32 s2361 = table1[s2360];
-  const SWord8  s2362 = (SWord8) (s2069 >> 16);
-  const SWord32 s2363 = table3[s2362];
-  const SWord32 s2364 = s2361 ^ s2363;
-  const SWord8  s2365 = (SWord8) (s2118 >> 8);
-  const SWord32 s2366 = table4[s2365];
-  const SWord32 s2367 = s2364 ^ s2366;
-  const SWord8  s2368 = (SWord8) s2168;
-  const SWord32 s2369 = table5[s2368];
-  const SWord32 s2370 = s2367 ^ s2369;
-  const SWord8  s2371 = (SWord8) (s602 >> 24);
-  const SWord8  s2372 = table6[s2371];
-  const SWord8  s2373 = (SWord8) (s602 >> 16);
-  const SWord8  s2374 = table7[s2373];
-  const SWord8  s2375 = (SWord8) (s602 >> 8);
-  const SWord8  s2376 = table8[s2375];
-  const SWord8  s2377 = (SWord8) s602;
-  const SWord8  s2378 = table9[s2377];
-  const SWord8  s2379 = s2376 ^ s2378;
-  const SWord8  s2380 = s2374 ^ s2379;
-  const SWord8  s2381 = s2372 ^ s2380;
-  const SWord8  s2382 = table9[s2371];
-  const SWord8  s2383 = table6[s2373];
-  const SWord8  s2384 = table7[s2375];
-  const SWord8  s2385 = table8[s2377];
-  const SWord8  s2386 = s2384 ^ s2385;
-  const SWord8  s2387 = s2383 ^ s2386;
-  const SWord8  s2388 = s2382 ^ s2387;
-  const SWord16 s2389 = (((SWord16) s2381) << 8) | ((SWord16) s2388);
-  const SWord8  s2390 = table8[s2371];
-  const SWord8  s2391 = table9[s2373];
-  const SWord8  s2392 = table6[s2375];
-  const SWord8  s2393 = table7[s2377];
-  const SWord8  s2394 = s2392 ^ s2393;
-  const SWord8  s2395 = s2391 ^ s2394;
-  const SWord8  s2396 = s2390 ^ s2395;
-  const SWord8  s2397 = table7[s2371];
-  const SWord8  s2398 = table8[s2373];
-  const SWord8  s2399 = table9[s2375];
-  const SWord8  s2400 = table6[s2377];
-  const SWord8  s2401 = s2399 ^ s2400;
-  const SWord8  s2402 = s2398 ^ s2401;
-  const SWord8  s2403 = s2397 ^ s2402;
-  const SWord16 s2404 = (((SWord16) s2396) << 8) | ((SWord16) s2403);
-  const SWord32 s2405 = (((SWord32) s2389) << 16) | ((SWord32) s2404);
-  const SWord32 s2406 = s2370 ^ s2405;
-  const SWord8  s2407 = (SWord8) s2406;
-  const SWord32 s2408 = table5[s2407];
-  const SWord32 s2409 = s2359 ^ s2408;
-  const SWord8  s2410 = (SWord8) (s584 >> 24);
-  const SWord8  s2411 = table6[s2410];
-  const SWord8  s2412 = (SWord8) (s584 >> 16);
-  const SWord8  s2413 = table7[s2412];
-  const SWord8  s2414 = (SWord8) (s584 >> 8);
-  const SWord8  s2415 = table8[s2414];
-  const SWord8  s2416 = (SWord8) s584;
-  const SWord8  s2417 = table9[s2416];
-  const SWord8  s2418 = s2415 ^ s2417;
-  const SWord8  s2419 = s2413 ^ s2418;
-  const SWord8  s2420 = s2411 ^ s2419;
-  const SWord8  s2421 = table9[s2410];
-  const SWord8  s2422 = table6[s2412];
-  const SWord8  s2423 = table7[s2414];
-  const SWord8  s2424 = table8[s2416];
-  const SWord8  s2425 = s2423 ^ s2424;
-  const SWord8  s2426 = s2422 ^ s2425;
-  const SWord8  s2427 = s2421 ^ s2426;
-  const SWord16 s2428 = (((SWord16) s2420) << 8) | ((SWord16) s2427);
-  const SWord8  s2429 = table8[s2410];
-  const SWord8  s2430 = table9[s2412];
-  const SWord8  s2431 = table6[s2414];
-  const SWord8  s2432 = table7[s2416];
-  const SWord8  s2433 = s2431 ^ s2432;
-  const SWord8  s2434 = s2430 ^ s2433;
-  const SWord8  s2435 = s2429 ^ s2434;
-  const SWord8  s2436 = table7[s2410];
-  const SWord8  s2437 = table8[s2412];
-  const SWord8  s2438 = table9[s2414];
-  const SWord8  s2439 = table6[s2416];
-  const SWord8  s2440 = s2438 ^ s2439;
-  const SWord8  s2441 = s2437 ^ s2440;
-  const SWord8  s2442 = s2436 ^ s2441;
-  const SWord16 s2443 = (((SWord16) s2435) << 8) | ((SWord16) s2442);
-  const SWord32 s2444 = (((SWord32) s2428) << 16) | ((SWord32) s2443);
-  const SWord32 s2445 = s2409 ^ s2444;
-  const SWord8  s2446 = (SWord8) (s2445 >> 24);
-  const SWord32 s2447 = table1[s2446];
-  const SWord8  s2448 = (SWord8) (s2306 >> 24);
-  const SWord32 s2449 = table1[s2448];
-  const SWord8  s2450 = (SWord8) (s2356 >> 16);
-  const SWord32 s2451 = table3[s2450];
-  const SWord32 s2452 = s2449 ^ s2451;
-  const SWord8  s2453 = (SWord8) (s2406 >> 8);
-  const SWord32 s2454 = table4[s2453];
-  const SWord32 s2455 = s2452 ^ s2454;
-  const SWord8  s2456 = (SWord8) s2257;
-  const SWord32 s2457 = table5[s2456];
-  const SWord32 s2458 = s2455 ^ s2457;
-  const SWord8  s2459 = (SWord8) (s587 >> 24);
-  const SWord8  s2460 = table6[s2459];
-  const SWord8  s2461 = (SWord8) (s587 >> 16);
-  const SWord8  s2462 = table7[s2461];
-  const SWord8  s2463 = (SWord8) (s587 >> 8);
-  const SWord8  s2464 = table8[s2463];
-  const SWord8  s2465 = (SWord8) s587;
-  const SWord8  s2466 = table9[s2465];
-  const SWord8  s2467 = s2464 ^ s2466;
-  const SWord8  s2468 = s2462 ^ s2467;
-  const SWord8  s2469 = s2460 ^ s2468;
-  const SWord8  s2470 = table9[s2459];
-  const SWord8  s2471 = table6[s2461];
-  const SWord8  s2472 = table7[s2463];
-  const SWord8  s2473 = table8[s2465];
-  const SWord8  s2474 = s2472 ^ s2473;
-  const SWord8  s2475 = s2471 ^ s2474;
-  const SWord8  s2476 = s2470 ^ s2475;
-  const SWord16 s2477 = (((SWord16) s2469) << 8) | ((SWord16) s2476);
-  const SWord8  s2478 = table8[s2459];
-  const SWord8  s2479 = table9[s2461];
-  const SWord8  s2480 = table6[s2463];
-  const SWord8  s2481 = table7[s2465];
-  const SWord8  s2482 = s2480 ^ s2481;
-  const SWord8  s2483 = s2479 ^ s2482;
-  const SWord8  s2484 = s2478 ^ s2483;
-  const SWord8  s2485 = table7[s2459];
-  const SWord8  s2486 = table8[s2461];
-  const SWord8  s2487 = table9[s2463];
-  const SWord8  s2488 = table6[s2465];
-  const SWord8  s2489 = s2487 ^ s2488;
-  const SWord8  s2490 = s2486 ^ s2489;
-  const SWord8  s2491 = s2485 ^ s2490;
-  const SWord16 s2492 = (((SWord16) s2484) << 8) | ((SWord16) s2491);
-  const SWord32 s2493 = (((SWord32) s2477) << 16) | ((SWord32) s2492);
-  const SWord32 s2494 = s2458 ^ s2493;
-  const SWord8  s2495 = (SWord8) (s2494 >> 16);
-  const SWord32 s2496 = table3[s2495];
-  const SWord32 s2497 = s2447 ^ s2496;
-  const SWord8  s2498 = (SWord8) (s2356 >> 24);
-  const SWord32 s2499 = table1[s2498];
-  const SWord8  s2500 = (SWord8) (s2406 >> 16);
-  const SWord32 s2501 = table3[s2500];
-  const SWord32 s2502 = s2499 ^ s2501;
-  const SWord8  s2503 = (SWord8) (s2257 >> 8);
-  const SWord32 s2504 = table4[s2503];
-  const SWord32 s2505 = s2502 ^ s2504;
-  const SWord8  s2506 = (SWord8) s2306;
-  const SWord32 s2507 = table5[s2506];
-  const SWord32 s2508 = s2505 ^ s2507;
-  const SWord8  s2509 = (SWord8) (s586 >> 24);
-  const SWord8  s2510 = table6[s2509];
-  const SWord8  s2511 = (SWord8) (s586 >> 16);
-  const SWord8  s2512 = table7[s2511];
-  const SWord8  s2513 = (SWord8) (s586 >> 8);
-  const SWord8  s2514 = table8[s2513];
-  const SWord8  s2515 = (SWord8) s586;
-  const SWord8  s2516 = table9[s2515];
-  const SWord8  s2517 = s2514 ^ s2516;
-  const SWord8  s2518 = s2512 ^ s2517;
-  const SWord8  s2519 = s2510 ^ s2518;
-  const SWord8  s2520 = table9[s2509];
-  const SWord8  s2521 = table6[s2511];
-  const SWord8  s2522 = table7[s2513];
-  const SWord8  s2523 = table8[s2515];
-  const SWord8  s2524 = s2522 ^ s2523;
-  const SWord8  s2525 = s2521 ^ s2524;
-  const SWord8  s2526 = s2520 ^ s2525;
-  const SWord16 s2527 = (((SWord16) s2519) << 8) | ((SWord16) s2526);
-  const SWord8  s2528 = table8[s2509];
-  const SWord8  s2529 = table9[s2511];
-  const SWord8  s2530 = table6[s2513];
-  const SWord8  s2531 = table7[s2515];
-  const SWord8  s2532 = s2530 ^ s2531;
-  const SWord8  s2533 = s2529 ^ s2532;
-  const SWord8  s2534 = s2528 ^ s2533;
-  const SWord8  s2535 = table7[s2509];
-  const SWord8  s2536 = table8[s2511];
-  const SWord8  s2537 = table9[s2513];
-  const SWord8  s2538 = table6[s2515];
-  const SWord8  s2539 = s2537 ^ s2538;
-  const SWord8  s2540 = s2536 ^ s2539;
-  const SWord8  s2541 = s2535 ^ s2540;
-  const SWord16 s2542 = (((SWord16) s2534) << 8) | ((SWord16) s2541);
-  const SWord32 s2543 = (((SWord32) s2527) << 16) | ((SWord32) s2542);
-  const SWord32 s2544 = s2508 ^ s2543;
-  const SWord8  s2545 = (SWord8) (s2544 >> 8);
-  const SWord32 s2546 = table4[s2545];
-  const SWord32 s2547 = s2497 ^ s2546;
-  const SWord8  s2548 = (SWord8) (s2406 >> 24);
-  const SWord32 s2549 = table1[s2548];
-  const SWord8  s2550 = (SWord8) (s2257 >> 16);
-  const SWord32 s2551 = table3[s2550];
-  const SWord32 s2552 = s2549 ^ s2551;
-  const SWord8  s2553 = (SWord8) (s2306 >> 8);
-  const SWord32 s2554 = table4[s2553];
-  const SWord32 s2555 = s2552 ^ s2554;
-  const SWord8  s2556 = (SWord8) s2356;
-  const SWord32 s2557 = table5[s2556];
-  const SWord32 s2558 = s2555 ^ s2557;
-  const SWord8  s2559 = (SWord8) (s585 >> 24);
-  const SWord8  s2560 = table6[s2559];
-  const SWord8  s2561 = (SWord8) (s585 >> 16);
-  const SWord8  s2562 = table7[s2561];
-  const SWord8  s2563 = (SWord8) (s585 >> 8);
-  const SWord8  s2564 = table8[s2563];
-  const SWord8  s2565 = (SWord8) s585;
-  const SWord8  s2566 = table9[s2565];
-  const SWord8  s2567 = s2564 ^ s2566;
-  const SWord8  s2568 = s2562 ^ s2567;
-  const SWord8  s2569 = s2560 ^ s2568;
-  const SWord8  s2570 = table9[s2559];
-  const SWord8  s2571 = table6[s2561];
-  const SWord8  s2572 = table7[s2563];
-  const SWord8  s2573 = table8[s2565];
-  const SWord8  s2574 = s2572 ^ s2573;
-  const SWord8  s2575 = s2571 ^ s2574;
-  const SWord8  s2576 = s2570 ^ s2575;
-  const SWord16 s2577 = (((SWord16) s2569) << 8) | ((SWord16) s2576);
-  const SWord8  s2578 = table8[s2559];
-  const SWord8  s2579 = table9[s2561];
-  const SWord8  s2580 = table6[s2563];
-  const SWord8  s2581 = table7[s2565];
-  const SWord8  s2582 = s2580 ^ s2581;
-  const SWord8  s2583 = s2579 ^ s2582;
-  const SWord8  s2584 = s2578 ^ s2583;
-  const SWord8  s2585 = table7[s2559];
-  const SWord8  s2586 = table8[s2561];
-  const SWord8  s2587 = table9[s2563];
-  const SWord8  s2588 = table6[s2565];
-  const SWord8  s2589 = s2587 ^ s2588;
-  const SWord8  s2590 = s2586 ^ s2589;
-  const SWord8  s2591 = s2585 ^ s2590;
-  const SWord16 s2592 = (((SWord16) s2584) << 8) | ((SWord16) s2591);
-  const SWord32 s2593 = (((SWord32) s2577) << 16) | ((SWord32) s2592);
-  const SWord32 s2594 = s2558 ^ s2593;
-  const SWord8  s2595 = (SWord8) s2594;
-  const SWord32 s2596 = table5[s2595];
-  const SWord32 s2597 = s2547 ^ s2596;
-  const SWord8  s2598 = (SWord8) (s567 >> 24);
-  const SWord8  s2599 = table6[s2598];
-  const SWord8  s2600 = (SWord8) (s567 >> 16);
-  const SWord8  s2601 = table7[s2600];
-  const SWord8  s2602 = (SWord8) (s567 >> 8);
-  const SWord8  s2603 = table8[s2602];
-  const SWord8  s2604 = (SWord8) s567;
-  const SWord8  s2605 = table9[s2604];
-  const SWord8  s2606 = s2603 ^ s2605;
-  const SWord8  s2607 = s2601 ^ s2606;
-  const SWord8  s2608 = s2599 ^ s2607;
-  const SWord8  s2609 = table9[s2598];
-  const SWord8  s2610 = table6[s2600];
-  const SWord8  s2611 = table7[s2602];
-  const SWord8  s2612 = table8[s2604];
-  const SWord8  s2613 = s2611 ^ s2612;
-  const SWord8  s2614 = s2610 ^ s2613;
-  const SWord8  s2615 = s2609 ^ s2614;
-  const SWord16 s2616 = (((SWord16) s2608) << 8) | ((SWord16) s2615);
-  const SWord8  s2617 = table8[s2598];
-  const SWord8  s2618 = table9[s2600];
-  const SWord8  s2619 = table6[s2602];
-  const SWord8  s2620 = table7[s2604];
-  const SWord8  s2621 = s2619 ^ s2620;
-  const SWord8  s2622 = s2618 ^ s2621;
-  const SWord8  s2623 = s2617 ^ s2622;
-  const SWord8  s2624 = table7[s2598];
-  const SWord8  s2625 = table8[s2600];
-  const SWord8  s2626 = table9[s2602];
-  const SWord8  s2627 = table6[s2604];
-  const SWord8  s2628 = s2626 ^ s2627;
-  const SWord8  s2629 = s2625 ^ s2628;
-  const SWord8  s2630 = s2624 ^ s2629;
-  const SWord16 s2631 = (((SWord16) s2623) << 8) | ((SWord16) s2630);
-  const SWord32 s2632 = (((SWord32) s2616) << 16) | ((SWord32) s2631);
-  const SWord32 s2633 = s2597 ^ s2632;
-  const SWord8  s2634 = (SWord8) (s2633 >> 24);
-  const SWord32 s2635 = table1[s2634];
-  const SWord8  s2636 = (SWord8) (s2494 >> 24);
-  const SWord32 s2637 = table1[s2636];
-  const SWord8  s2638 = (SWord8) (s2544 >> 16);
-  const SWord32 s2639 = table3[s2638];
-  const SWord32 s2640 = s2637 ^ s2639;
-  const SWord8  s2641 = (SWord8) (s2594 >> 8);
-  const SWord32 s2642 = table4[s2641];
-  const SWord32 s2643 = s2640 ^ s2642;
-  const SWord8  s2644 = (SWord8) s2445;
-  const SWord32 s2645 = table5[s2644];
-  const SWord32 s2646 = s2643 ^ s2645;
-  const SWord8  s2647 = (SWord8) (s570 >> 24);
-  const SWord8  s2648 = table6[s2647];
-  const SWord8  s2649 = (SWord8) (s570 >> 16);
-  const SWord8  s2650 = table7[s2649];
-  const SWord8  s2651 = (SWord8) (s570 >> 8);
-  const SWord8  s2652 = table8[s2651];
-  const SWord8  s2653 = (SWord8) s570;
-  const SWord8  s2654 = table9[s2653];
-  const SWord8  s2655 = s2652 ^ s2654;
-  const SWord8  s2656 = s2650 ^ s2655;
-  const SWord8  s2657 = s2648 ^ s2656;
-  const SWord8  s2658 = table9[s2647];
-  const SWord8  s2659 = table6[s2649];
-  const SWord8  s2660 = table7[s2651];
-  const SWord8  s2661 = table8[s2653];
-  const SWord8  s2662 = s2660 ^ s2661;
-  const SWord8  s2663 = s2659 ^ s2662;
-  const SWord8  s2664 = s2658 ^ s2663;
-  const SWord16 s2665 = (((SWord16) s2657) << 8) | ((SWord16) s2664);
-  const SWord8  s2666 = table8[s2647];
-  const SWord8  s2667 = table9[s2649];
-  const SWord8  s2668 = table6[s2651];
-  const SWord8  s2669 = table7[s2653];
-  const SWord8  s2670 = s2668 ^ s2669;
-  const SWord8  s2671 = s2667 ^ s2670;
-  const SWord8  s2672 = s2666 ^ s2671;
-  const SWord8  s2673 = table7[s2647];
-  const SWord8  s2674 = table8[s2649];
-  const SWord8  s2675 = table9[s2651];
-  const SWord8  s2676 = table6[s2653];
-  const SWord8  s2677 = s2675 ^ s2676;
-  const SWord8  s2678 = s2674 ^ s2677;
-  const SWord8  s2679 = s2673 ^ s2678;
-  const SWord16 s2680 = (((SWord16) s2672) << 8) | ((SWord16) s2679);
-  const SWord32 s2681 = (((SWord32) s2665) << 16) | ((SWord32) s2680);
-  const SWord32 s2682 = s2646 ^ s2681;
-  const SWord8  s2683 = (SWord8) (s2682 >> 16);
-  const SWord32 s2684 = table3[s2683];
-  const SWord32 s2685 = s2635 ^ s2684;
-  const SWord8  s2686 = (SWord8) (s2544 >> 24);
-  const SWord32 s2687 = table1[s2686];
-  const SWord8  s2688 = (SWord8) (s2594 >> 16);
-  const SWord32 s2689 = table3[s2688];
-  const SWord32 s2690 = s2687 ^ s2689;
-  const SWord8  s2691 = (SWord8) (s2445 >> 8);
-  const SWord32 s2692 = table4[s2691];
-  const SWord32 s2693 = s2690 ^ s2692;
-  const SWord8  s2694 = (SWord8) s2494;
-  const SWord32 s2695 = table5[s2694];
-  const SWord32 s2696 = s2693 ^ s2695;
-  const SWord8  s2697 = (SWord8) (s569 >> 24);
-  const SWord8  s2698 = table6[s2697];
-  const SWord8  s2699 = (SWord8) (s569 >> 16);
-  const SWord8  s2700 = table7[s2699];
-  const SWord8  s2701 = (SWord8) (s569 >> 8);
-  const SWord8  s2702 = table8[s2701];
-  const SWord8  s2703 = (SWord8) s569;
-  const SWord8  s2704 = table9[s2703];
-  const SWord8  s2705 = s2702 ^ s2704;
-  const SWord8  s2706 = s2700 ^ s2705;
-  const SWord8  s2707 = s2698 ^ s2706;
-  const SWord8  s2708 = table9[s2697];
-  const SWord8  s2709 = table6[s2699];
-  const SWord8  s2710 = table7[s2701];
-  const SWord8  s2711 = table8[s2703];
-  const SWord8  s2712 = s2710 ^ s2711;
-  const SWord8  s2713 = s2709 ^ s2712;
-  const SWord8  s2714 = s2708 ^ s2713;
-  const SWord16 s2715 = (((SWord16) s2707) << 8) | ((SWord16) s2714);
-  const SWord8  s2716 = table8[s2697];
-  const SWord8  s2717 = table9[s2699];
-  const SWord8  s2718 = table6[s2701];
-  const SWord8  s2719 = table7[s2703];
-  const SWord8  s2720 = s2718 ^ s2719;
-  const SWord8  s2721 = s2717 ^ s2720;
-  const SWord8  s2722 = s2716 ^ s2721;
-  const SWord8  s2723 = table7[s2697];
-  const SWord8  s2724 = table8[s2699];
-  const SWord8  s2725 = table9[s2701];
-  const SWord8  s2726 = table6[s2703];
-  const SWord8  s2727 = s2725 ^ s2726;
-  const SWord8  s2728 = s2724 ^ s2727;
-  const SWord8  s2729 = s2723 ^ s2728;
-  const SWord16 s2730 = (((SWord16) s2722) << 8) | ((SWord16) s2729);
-  const SWord32 s2731 = (((SWord32) s2715) << 16) | ((SWord32) s2730);
-  const SWord32 s2732 = s2696 ^ s2731;
-  const SWord8  s2733 = (SWord8) (s2732 >> 8);
-  const SWord32 s2734 = table4[s2733];
-  const SWord32 s2735 = s2685 ^ s2734;
-  const SWord8  s2736 = (SWord8) (s2594 >> 24);
-  const SWord32 s2737 = table1[s2736];
-  const SWord8  s2738 = (SWord8) (s2445 >> 16);
-  const SWord32 s2739 = table3[s2738];
-  const SWord32 s2740 = s2737 ^ s2739;
-  const SWord8  s2741 = (SWord8) (s2494 >> 8);
-  const SWord32 s2742 = table4[s2741];
-  const SWord32 s2743 = s2740 ^ s2742;
-  const SWord8  s2744 = (SWord8) s2544;
-  const SWord32 s2745 = table5[s2744];
-  const SWord32 s2746 = s2743 ^ s2745;
-  const SWord8  s2747 = (SWord8) (s568 >> 24);
-  const SWord8  s2748 = table6[s2747];
-  const SWord8  s2749 = (SWord8) (s568 >> 16);
-  const SWord8  s2750 = table7[s2749];
-  const SWord8  s2751 = (SWord8) (s568 >> 8);
-  const SWord8  s2752 = table8[s2751];
-  const SWord8  s2753 = (SWord8) s568;
-  const SWord8  s2754 = table9[s2753];
-  const SWord8  s2755 = s2752 ^ s2754;
-  const SWord8  s2756 = s2750 ^ s2755;
-  const SWord8  s2757 = s2748 ^ s2756;
-  const SWord8  s2758 = table9[s2747];
-  const SWord8  s2759 = table6[s2749];
-  const SWord8  s2760 = table7[s2751];
-  const SWord8  s2761 = table8[s2753];
-  const SWord8  s2762 = s2760 ^ s2761;
-  const SWord8  s2763 = s2759 ^ s2762;
-  const SWord8  s2764 = s2758 ^ s2763;
-  const SWord16 s2765 = (((SWord16) s2757) << 8) | ((SWord16) s2764);
-  const SWord8  s2766 = table8[s2747];
-  const SWord8  s2767 = table9[s2749];
-  const SWord8  s2768 = table6[s2751];
-  const SWord8  s2769 = table7[s2753];
-  const SWord8  s2770 = s2768 ^ s2769;
-  const SWord8  s2771 = s2767 ^ s2770;
-  const SWord8  s2772 = s2766 ^ s2771;
-  const SWord8  s2773 = table7[s2747];
-  const SWord8  s2774 = table8[s2749];
-  const SWord8  s2775 = table9[s2751];
-  const SWord8  s2776 = table6[s2753];
-  const SWord8  s2777 = s2775 ^ s2776;
-  const SWord8  s2778 = s2774 ^ s2777;
-  const SWord8  s2779 = s2773 ^ s2778;
-  const SWord16 s2780 = (((SWord16) s2772) << 8) | ((SWord16) s2779);
-  const SWord32 s2781 = (((SWord32) s2765) << 16) | ((SWord32) s2780);
-  const SWord32 s2782 = s2746 ^ s2781;
-  const SWord8  s2783 = (SWord8) s2782;
-  const SWord32 s2784 = table5[s2783];
-  const SWord32 s2785 = s2735 ^ s2784;
-  const SWord8  s2786 = (SWord8) (s550 >> 24);
-  const SWord8  s2787 = table6[s2786];
-  const SWord8  s2788 = (SWord8) (s550 >> 16);
-  const SWord8  s2789 = table7[s2788];
-  const SWord8  s2790 = (SWord8) (s550 >> 8);
-  const SWord8  s2791 = table8[s2790];
-  const SWord8  s2792 = (SWord8) s550;
-  const SWord8  s2793 = table9[s2792];
-  const SWord8  s2794 = s2791 ^ s2793;
-  const SWord8  s2795 = s2789 ^ s2794;
-  const SWord8  s2796 = s2787 ^ s2795;
-  const SWord8  s2797 = table9[s2786];
-  const SWord8  s2798 = table6[s2788];
-  const SWord8  s2799 = table7[s2790];
-  const SWord8  s2800 = table8[s2792];
-  const SWord8  s2801 = s2799 ^ s2800;
-  const SWord8  s2802 = s2798 ^ s2801;
-  const SWord8  s2803 = s2797 ^ s2802;
-  const SWord16 s2804 = (((SWord16) s2796) << 8) | ((SWord16) s2803);
-  const SWord8  s2805 = table8[s2786];
-  const SWord8  s2806 = table9[s2788];
-  const SWord8  s2807 = table6[s2790];
-  const SWord8  s2808 = table7[s2792];
-  const SWord8  s2809 = s2807 ^ s2808;
-  const SWord8  s2810 = s2806 ^ s2809;
-  const SWord8  s2811 = s2805 ^ s2810;
-  const SWord8  s2812 = table7[s2786];
-  const SWord8  s2813 = table8[s2788];
-  const SWord8  s2814 = table9[s2790];
-  const SWord8  s2815 = table6[s2792];
-  const SWord8  s2816 = s2814 ^ s2815;
-  const SWord8  s2817 = s2813 ^ s2816;
-  const SWord8  s2818 = s2812 ^ s2817;
-  const SWord16 s2819 = (((SWord16) s2811) << 8) | ((SWord16) s2818);
-  const SWord32 s2820 = (((SWord32) s2804) << 16) | ((SWord32) s2819);
-  const SWord32 s2821 = s2785 ^ s2820;
-  const SWord8  s2822 = (SWord8) (s2821 >> 24);
-  const SWord32 s2823 = table1[s2822];
-  const SWord8  s2824 = (SWord8) (s2682 >> 24);
-  const SWord32 s2825 = table1[s2824];
-  const SWord8  s2826 = (SWord8) (s2732 >> 16);
-  const SWord32 s2827 = table3[s2826];
-  const SWord32 s2828 = s2825 ^ s2827;
-  const SWord8  s2829 = (SWord8) (s2782 >> 8);
-  const SWord32 s2830 = table4[s2829];
-  const SWord32 s2831 = s2828 ^ s2830;
-  const SWord8  s2832 = (SWord8) s2633;
-  const SWord32 s2833 = table5[s2832];
-  const SWord32 s2834 = s2831 ^ s2833;
-  const SWord8  s2835 = (SWord8) (s553 >> 24);
-  const SWord8  s2836 = table6[s2835];
-  const SWord8  s2837 = (SWord8) (s553 >> 16);
-  const SWord8  s2838 = table7[s2837];
-  const SWord8  s2839 = (SWord8) (s553 >> 8);
-  const SWord8  s2840 = table8[s2839];
-  const SWord8  s2841 = (SWord8) s553;
-  const SWord8  s2842 = table9[s2841];
-  const SWord8  s2843 = s2840 ^ s2842;
-  const SWord8  s2844 = s2838 ^ s2843;
-  const SWord8  s2845 = s2836 ^ s2844;
-  const SWord8  s2846 = table9[s2835];
-  const SWord8  s2847 = table6[s2837];
-  const SWord8  s2848 = table7[s2839];
-  const SWord8  s2849 = table8[s2841];
-  const SWord8  s2850 = s2848 ^ s2849;
-  const SWord8  s2851 = s2847 ^ s2850;
-  const SWord8  s2852 = s2846 ^ s2851;
-  const SWord16 s2853 = (((SWord16) s2845) << 8) | ((SWord16) s2852);
-  const SWord8  s2854 = table8[s2835];
-  const SWord8  s2855 = table9[s2837];
-  const SWord8  s2856 = table6[s2839];
-  const SWord8  s2857 = table7[s2841];
-  const SWord8  s2858 = s2856 ^ s2857;
-  const SWord8  s2859 = s2855 ^ s2858;
-  const SWord8  s2860 = s2854 ^ s2859;
-  const SWord8  s2861 = table7[s2835];
-  const SWord8  s2862 = table8[s2837];
-  const SWord8  s2863 = table9[s2839];
-  const SWord8  s2864 = table6[s2841];
-  const SWord8  s2865 = s2863 ^ s2864;
-  const SWord8  s2866 = s2862 ^ s2865;
-  const SWord8  s2867 = s2861 ^ s2866;
-  const SWord16 s2868 = (((SWord16) s2860) << 8) | ((SWord16) s2867);
-  const SWord32 s2869 = (((SWord32) s2853) << 16) | ((SWord32) s2868);
-  const SWord32 s2870 = s2834 ^ s2869;
-  const SWord8  s2871 = (SWord8) (s2870 >> 16);
-  const SWord32 s2872 = table3[s2871];
-  const SWord32 s2873 = s2823 ^ s2872;
-  const SWord8  s2874 = (SWord8) (s2732 >> 24);
-  const SWord32 s2875 = table1[s2874];
-  const SWord8  s2876 = (SWord8) (s2782 >> 16);
-  const SWord32 s2877 = table3[s2876];
-  const SWord32 s2878 = s2875 ^ s2877;
-  const SWord8  s2879 = (SWord8) (s2633 >> 8);
-  const SWord32 s2880 = table4[s2879];
-  const SWord32 s2881 = s2878 ^ s2880;
-  const SWord8  s2882 = (SWord8) s2682;
-  const SWord32 s2883 = table5[s2882];
-  const SWord32 s2884 = s2881 ^ s2883;
-  const SWord8  s2885 = (SWord8) (s552 >> 24);
-  const SWord8  s2886 = table6[s2885];
-  const SWord8  s2887 = (SWord8) (s552 >> 16);
-  const SWord8  s2888 = table7[s2887];
-  const SWord8  s2889 = (SWord8) (s552 >> 8);
-  const SWord8  s2890 = table8[s2889];
-  const SWord8  s2891 = (SWord8) s552;
-  const SWord8  s2892 = table9[s2891];
-  const SWord8  s2893 = s2890 ^ s2892;
-  const SWord8  s2894 = s2888 ^ s2893;
-  const SWord8  s2895 = s2886 ^ s2894;
-  const SWord8  s2896 = table9[s2885];
-  const SWord8  s2897 = table6[s2887];
-  const SWord8  s2898 = table7[s2889];
-  const SWord8  s2899 = table8[s2891];
-  const SWord8  s2900 = s2898 ^ s2899;
-  const SWord8  s2901 = s2897 ^ s2900;
-  const SWord8  s2902 = s2896 ^ s2901;
-  const SWord16 s2903 = (((SWord16) s2895) << 8) | ((SWord16) s2902);
-  const SWord8  s2904 = table8[s2885];
-  const SWord8  s2905 = table9[s2887];
-  const SWord8  s2906 = table6[s2889];
-  const SWord8  s2907 = table7[s2891];
-  const SWord8  s2908 = s2906 ^ s2907;
-  const SWord8  s2909 = s2905 ^ s2908;
-  const SWord8  s2910 = s2904 ^ s2909;
-  const SWord8  s2911 = table7[s2885];
-  const SWord8  s2912 = table8[s2887];
-  const SWord8  s2913 = table9[s2889];
-  const SWord8  s2914 = table6[s2891];
-  const SWord8  s2915 = s2913 ^ s2914;
-  const SWord8  s2916 = s2912 ^ s2915;
-  const SWord8  s2917 = s2911 ^ s2916;
-  const SWord16 s2918 = (((SWord16) s2910) << 8) | ((SWord16) s2917);
-  const SWord32 s2919 = (((SWord32) s2903) << 16) | ((SWord32) s2918);
-  const SWord32 s2920 = s2884 ^ s2919;
-  const SWord8  s2921 = (SWord8) (s2920 >> 8);
-  const SWord32 s2922 = table4[s2921];
-  const SWord32 s2923 = s2873 ^ s2922;
-  const SWord8  s2924 = (SWord8) (s2782 >> 24);
-  const SWord32 s2925 = table1[s2924];
-  const SWord8  s2926 = (SWord8) (s2633 >> 16);
-  const SWord32 s2927 = table3[s2926];
-  const SWord32 s2928 = s2925 ^ s2927;
-  const SWord8  s2929 = (SWord8) (s2682 >> 8);
-  const SWord32 s2930 = table4[s2929];
-  const SWord32 s2931 = s2928 ^ s2930;
-  const SWord8  s2932 = (SWord8) s2732;
-  const SWord32 s2933 = table5[s2932];
-  const SWord32 s2934 = s2931 ^ s2933;
-  const SWord8  s2935 = (SWord8) (s551 >> 24);
-  const SWord8  s2936 = table6[s2935];
-  const SWord8  s2937 = (SWord8) (s551 >> 16);
-  const SWord8  s2938 = table7[s2937];
-  const SWord8  s2939 = (SWord8) (s551 >> 8);
-  const SWord8  s2940 = table8[s2939];
-  const SWord8  s2941 = (SWord8) s551;
-  const SWord8  s2942 = table9[s2941];
-  const SWord8  s2943 = s2940 ^ s2942;
-  const SWord8  s2944 = s2938 ^ s2943;
-  const SWord8  s2945 = s2936 ^ s2944;
-  const SWord8  s2946 = table9[s2935];
-  const SWord8  s2947 = table6[s2937];
-  const SWord8  s2948 = table7[s2939];
-  const SWord8  s2949 = table8[s2941];
-  const SWord8  s2950 = s2948 ^ s2949;
-  const SWord8  s2951 = s2947 ^ s2950;
-  const SWord8  s2952 = s2946 ^ s2951;
-  const SWord16 s2953 = (((SWord16) s2945) << 8) | ((SWord16) s2952);
-  const SWord8  s2954 = table8[s2935];
-  const SWord8  s2955 = table9[s2937];
-  const SWord8  s2956 = table6[s2939];
-  const SWord8  s2957 = table7[s2941];
-  const SWord8  s2958 = s2956 ^ s2957;
-  const SWord8  s2959 = s2955 ^ s2958;
-  const SWord8  s2960 = s2954 ^ s2959;
-  const SWord8  s2961 = table7[s2935];
-  const SWord8  s2962 = table8[s2937];
-  const SWord8  s2963 = table9[s2939];
-  const SWord8  s2964 = table6[s2941];
-  const SWord8  s2965 = s2963 ^ s2964;
-  const SWord8  s2966 = s2962 ^ s2965;
-  const SWord8  s2967 = s2961 ^ s2966;
-  const SWord16 s2968 = (((SWord16) s2960) << 8) | ((SWord16) s2967);
-  const SWord32 s2969 = (((SWord32) s2953) << 16) | ((SWord32) s2968);
-  const SWord32 s2970 = s2934 ^ s2969;
-  const SWord8  s2971 = (SWord8) s2970;
-  const SWord32 s2972 = table5[s2971];
-  const SWord32 s2973 = s2923 ^ s2972;
-  const SWord8  s2974 = (SWord8) (s533 >> 24);
-  const SWord8  s2975 = table6[s2974];
-  const SWord8  s2976 = (SWord8) (s533 >> 16);
-  const SWord8  s2977 = table7[s2976];
-  const SWord8  s2978 = (SWord8) (s533 >> 8);
-  const SWord8  s2979 = table8[s2978];
-  const SWord8  s2980 = (SWord8) s533;
-  const SWord8  s2981 = table9[s2980];
-  const SWord8  s2982 = s2979 ^ s2981;
-  const SWord8  s2983 = s2977 ^ s2982;
-  const SWord8  s2984 = s2975 ^ s2983;
-  const SWord8  s2985 = table9[s2974];
-  const SWord8  s2986 = table6[s2976];
-  const SWord8  s2987 = table7[s2978];
-  const SWord8  s2988 = table8[s2980];
-  const SWord8  s2989 = s2987 ^ s2988;
-  const SWord8  s2990 = s2986 ^ s2989;
-  const SWord8  s2991 = s2985 ^ s2990;
-  const SWord16 s2992 = (((SWord16) s2984) << 8) | ((SWord16) s2991);
-  const SWord8  s2993 = table8[s2974];
-  const SWord8  s2994 = table9[s2976];
-  const SWord8  s2995 = table6[s2978];
-  const SWord8  s2996 = table7[s2980];
-  const SWord8  s2997 = s2995 ^ s2996;
-  const SWord8  s2998 = s2994 ^ s2997;
-  const SWord8  s2999 = s2993 ^ s2998;
-  const SWord8  s3000 = table7[s2974];
-  const SWord8  s3001 = table8[s2976];
-  const SWord8  s3002 = table9[s2978];
-  const SWord8  s3003 = table6[s2980];
-  const SWord8  s3004 = s3002 ^ s3003;
-  const SWord8  s3005 = s3001 ^ s3004;
-  const SWord8  s3006 = s3000 ^ s3005;
-  const SWord16 s3007 = (((SWord16) s2999) << 8) | ((SWord16) s3006);
-  const SWord32 s3008 = (((SWord32) s2992) << 16) | ((SWord32) s3007);
-  const SWord32 s3009 = s2973 ^ s3008;
-  const SWord8  s3010 = (SWord8) (s3009 >> 24);
-  const SWord8  s3011 = table0[s3010];
-  const SWord8  s3012 = (SWord8) (s2870 >> 24);
-  const SWord32 s3013 = table1[s3012];
-  const SWord8  s3014 = (SWord8) (s2920 >> 16);
-  const SWord32 s3015 = table3[s3014];
-  const SWord32 s3016 = s3013 ^ s3015;
-  const SWord8  s3017 = (SWord8) (s2970 >> 8);
-  const SWord32 s3018 = table4[s3017];
-  const SWord32 s3019 = s3016 ^ s3018;
-  const SWord8  s3020 = (SWord8) s2821;
-  const SWord32 s3021 = table5[s3020];
-  const SWord32 s3022 = s3019 ^ s3021;
-  const SWord8  s3023 = (SWord8) (s536 >> 24);
-  const SWord8  s3024 = table6[s3023];
-  const SWord8  s3025 = (SWord8) (s536 >> 16);
-  const SWord8  s3026 = table7[s3025];
-  const SWord8  s3027 = (SWord8) (s536 >> 8);
-  const SWord8  s3028 = table8[s3027];
-  const SWord8  s3029 = (SWord8) s536;
-  const SWord8  s3030 = table9[s3029];
-  const SWord8  s3031 = s3028 ^ s3030;
-  const SWord8  s3032 = s3026 ^ s3031;
-  const SWord8  s3033 = s3024 ^ s3032;
-  const SWord8  s3034 = table9[s3023];
-  const SWord8  s3035 = table6[s3025];
-  const SWord8  s3036 = table7[s3027];
-  const SWord8  s3037 = table8[s3029];
-  const SWord8  s3038 = s3036 ^ s3037;
-  const SWord8  s3039 = s3035 ^ s3038;
-  const SWord8  s3040 = s3034 ^ s3039;
-  const SWord16 s3041 = (((SWord16) s3033) << 8) | ((SWord16) s3040);
-  const SWord8  s3042 = table8[s3023];
-  const SWord8  s3043 = table9[s3025];
-  const SWord8  s3044 = table6[s3027];
-  const SWord8  s3045 = table7[s3029];
-  const SWord8  s3046 = s3044 ^ s3045;
-  const SWord8  s3047 = s3043 ^ s3046;
-  const SWord8  s3048 = s3042 ^ s3047;
-  const SWord8  s3049 = table7[s3023];
-  const SWord8  s3050 = table8[s3025];
-  const SWord8  s3051 = table9[s3027];
-  const SWord8  s3052 = table6[s3029];
-  const SWord8  s3053 = s3051 ^ s3052;
-  const SWord8  s3054 = s3050 ^ s3053;
-  const SWord8  s3055 = s3049 ^ s3054;
-  const SWord16 s3056 = (((SWord16) s3048) << 8) | ((SWord16) s3055);
-  const SWord32 s3057 = (((SWord32) s3041) << 16) | ((SWord32) s3056);
-  const SWord32 s3058 = s3022 ^ s3057;
-  const SWord8  s3059 = (SWord8) (s3058 >> 16);
-  const SWord8  s3060 = table0[s3059];
-  const SWord16 s3061 = (((SWord16) s3011) << 8) | ((SWord16) s3060);
-  const SWord8  s3062 = (SWord8) (s2920 >> 24);
-  const SWord32 s3063 = table1[s3062];
-  const SWord8  s3064 = (SWord8) (s2970 >> 16);
-  const SWord32 s3065 = table3[s3064];
-  const SWord32 s3066 = s3063 ^ s3065;
-  const SWord8  s3067 = (SWord8) (s2821 >> 8);
-  const SWord32 s3068 = table4[s3067];
-  const SWord32 s3069 = s3066 ^ s3068;
-  const SWord8  s3070 = (SWord8) s2870;
-  const SWord32 s3071 = table5[s3070];
-  const SWord32 s3072 = s3069 ^ s3071;
-  const SWord8  s3073 = (SWord8) (s535 >> 24);
-  const SWord8  s3074 = table6[s3073];
-  const SWord8  s3075 = (SWord8) (s535 >> 16);
-  const SWord8  s3076 = table7[s3075];
-  const SWord8  s3077 = (SWord8) (s535 >> 8);
-  const SWord8  s3078 = table8[s3077];
-  const SWord8  s3079 = (SWord8) s535;
-  const SWord8  s3080 = table9[s3079];
-  const SWord8  s3081 = s3078 ^ s3080;
-  const SWord8  s3082 = s3076 ^ s3081;
-  const SWord8  s3083 = s3074 ^ s3082;
-  const SWord8  s3084 = table9[s3073];
-  const SWord8  s3085 = table6[s3075];
-  const SWord8  s3086 = table7[s3077];
-  const SWord8  s3087 = table8[s3079];
-  const SWord8  s3088 = s3086 ^ s3087;
-  const SWord8  s3089 = s3085 ^ s3088;
-  const SWord8  s3090 = s3084 ^ s3089;
-  const SWord16 s3091 = (((SWord16) s3083) << 8) | ((SWord16) s3090);
-  const SWord8  s3092 = table8[s3073];
-  const SWord8  s3093 = table9[s3075];
-  const SWord8  s3094 = table6[s3077];
-  const SWord8  s3095 = table7[s3079];
-  const SWord8  s3096 = s3094 ^ s3095;
-  const SWord8  s3097 = s3093 ^ s3096;
-  const SWord8  s3098 = s3092 ^ s3097;
-  const SWord8  s3099 = table7[s3073];
-  const SWord8  s3100 = table8[s3075];
-  const SWord8  s3101 = table9[s3077];
-  const SWord8  s3102 = table6[s3079];
-  const SWord8  s3103 = s3101 ^ s3102;
-  const SWord8  s3104 = s3100 ^ s3103;
-  const SWord8  s3105 = s3099 ^ s3104;
-  const SWord16 s3106 = (((SWord16) s3098) << 8) | ((SWord16) s3105);
-  const SWord32 s3107 = (((SWord32) s3091) << 16) | ((SWord32) s3106);
-  const SWord32 s3108 = s3072 ^ s3107;
-  const SWord8  s3109 = (SWord8) (s3108 >> 8);
-  const SWord8  s3110 = table0[s3109];
-  const SWord8  s3111 = (SWord8) (s2970 >> 24);
-  const SWord32 s3112 = table1[s3111];
-  const SWord8  s3113 = (SWord8) (s2821 >> 16);
-  const SWord32 s3114 = table3[s3113];
-  const SWord32 s3115 = s3112 ^ s3114;
-  const SWord8  s3116 = (SWord8) (s2870 >> 8);
-  const SWord32 s3117 = table4[s3116];
-  const SWord32 s3118 = s3115 ^ s3117;
-  const SWord8  s3119 = (SWord8) s2920;
-  const SWord32 s3120 = table5[s3119];
-  const SWord32 s3121 = s3118 ^ s3120;
-  const SWord8  s3122 = (SWord8) (s534 >> 24);
-  const SWord8  s3123 = table6[s3122];
-  const SWord8  s3124 = (SWord8) (s534 >> 16);
-  const SWord8  s3125 = table7[s3124];
-  const SWord8  s3126 = (SWord8) (s534 >> 8);
-  const SWord8  s3127 = table8[s3126];
-  const SWord8  s3128 = (SWord8) s534;
-  const SWord8  s3129 = table9[s3128];
-  const SWord8  s3130 = s3127 ^ s3129;
-  const SWord8  s3131 = s3125 ^ s3130;
-  const SWord8  s3132 = s3123 ^ s3131;
-  const SWord8  s3133 = table9[s3122];
-  const SWord8  s3134 = table6[s3124];
-  const SWord8  s3135 = table7[s3126];
-  const SWord8  s3136 = table8[s3128];
-  const SWord8  s3137 = s3135 ^ s3136;
-  const SWord8  s3138 = s3134 ^ s3137;
-  const SWord8  s3139 = s3133 ^ s3138;
-  const SWord16 s3140 = (((SWord16) s3132) << 8) | ((SWord16) s3139);
-  const SWord8  s3141 = table8[s3122];
-  const SWord8  s3142 = table9[s3124];
-  const SWord8  s3143 = table6[s3126];
-  const SWord8  s3144 = table7[s3128];
-  const SWord8  s3145 = s3143 ^ s3144;
-  const SWord8  s3146 = s3142 ^ s3145;
-  const SWord8  s3147 = s3141 ^ s3146;
-  const SWord8  s3148 = table7[s3122];
-  const SWord8  s3149 = table8[s3124];
-  const SWord8  s3150 = table9[s3126];
-  const SWord8  s3151 = table6[s3128];
-  const SWord8  s3152 = s3150 ^ s3151;
-  const SWord8  s3153 = s3149 ^ s3152;
-  const SWord8  s3154 = s3148 ^ s3153;
-  const SWord16 s3155 = (((SWord16) s3147) << 8) | ((SWord16) s3154);
-  const SWord32 s3156 = (((SWord32) s3140) << 16) | ((SWord32) s3155);
-  const SWord32 s3157 = s3121 ^ s3156;
-  const SWord8  s3158 = (SWord8) s3157;
-  const SWord8  s3159 = table0[s3158];
-  const SWord16 s3160 = (((SWord16) s3110) << 8) | ((SWord16) s3159);
-  const SWord32 s3161 = (((SWord32) s3061) << 16) | ((SWord32) s3160);
-  const SWord32 s3162 = s4 ^ s3161;
-  const SWord8  s3163 = (SWord8) (s3157 >> 24);
-  const SWord8  s3164 = table0[s3163];
-  const SWord8  s3165 = (SWord8) (s3009 >> 16);
-  const SWord8  s3166 = table0[s3165];
-  const SWord16 s3167 = (((SWord16) s3164) << 8) | ((SWord16) s3166);
-  const SWord8  s3168 = (SWord8) (s3058 >> 8);
-  const SWord8  s3169 = table0[s3168];
-  const SWord8  s3170 = (SWord8) s3108;
-  const SWord8  s3171 = table0[s3170];
-  const SWord16 s3172 = (((SWord16) s3169) << 8) | ((SWord16) s3171);
-  const SWord32 s3173 = (((SWord32) s3167) << 16) | ((SWord32) s3172);
-  const SWord32 s3174 = s5 ^ s3173;
-  const SWord8  s3175 = (SWord8) (s3108 >> 24);
-  const SWord8  s3176 = table0[s3175];
-  const SWord8  s3177 = (SWord8) (s3157 >> 16);
-  const SWord8  s3178 = table0[s3177];
-  const SWord16 s3179 = (((SWord16) s3176) << 8) | ((SWord16) s3178);
-  const SWord8  s3180 = (SWord8) (s3009 >> 8);
-  const SWord8  s3181 = table0[s3180];
-  const SWord8  s3182 = (SWord8) s3058;
-  const SWord8  s3183 = table0[s3182];
-  const SWord16 s3184 = (((SWord16) s3181) << 8) | ((SWord16) s3183);
-  const SWord32 s3185 = (((SWord32) s3179) << 16) | ((SWord32) s3184);
-  const SWord32 s3186 = s6 ^ s3185;
-  const SWord8  s3187 = (SWord8) (s3058 >> 24);
-  const SWord8  s3188 = table0[s3187];
-  const SWord8  s3189 = (SWord8) (s3108 >> 16);
-  const SWord8  s3190 = table0[s3189];
-  const SWord16 s3191 = (((SWord16) s3188) << 8) | ((SWord16) s3190);
-  const SWord8  s3192 = (SWord8) (s3157 >> 8);
-  const SWord8  s3193 = table0[s3192];
-  const SWord8  s3194 = (SWord8) s3009;
-  const SWord8  s3195 = table0[s3194];
-  const SWord16 s3196 = (((SWord16) s3193) << 8) | ((SWord16) s3195);
-  const SWord32 s3197 = (((SWord32) s3191) << 16) | ((SWord32) s3196);
-  const SWord32 s3198 = s7 ^ s3197;
-
-  ct[0] = s3162;
-  ct[1] = s3174;
-  ct[2] = s3186;
-  ct[3] = s3198;
+aes128Dec_driver.o: aes128Dec_driver.c aes128Dec.h
+	${CC} ${CCFLAGS} -c $< -o $@
+
+aes128Dec_driver: aes128Dec.o aes128Dec_driver.o
+	${CC} ${CCFLAGS} $^ -o $@ ${LDFLAGS}
+
+clean:
+	rm -f *.o
+
+veryclean: clean
+	rm -f aes128Dec_driver
+== END: "Makefile" ==================
+== BEGIN: "aes128Dec.h" ================
+/* Header file for aes128Dec. Automatically generated by SBV. Do not edit! */
+
+#ifndef SBV_GENERATED_aes128Dec_HEADER_INCLUDED
+#define SBV_GENERATED_aes128Dec_HEADER_INCLUDED
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <math.h>
+
+/* Floating-point calling convention:
+ * Enter generated code in FE_TONEAREST (round-to-nearest, ties-to-even).
+ * Callbacks must preserve this mode before returning or re-entering.
+ * Generated code does not check or change the hardware rounding mode.
+ * Custom builds must disable implicit FP contraction, including at LTO link time.
+ */
+
+/* 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 prototype: */
+void aes128Dec(const SWord32 *pt, const SWord32 *key, SWord32 *ct);
+
+#endif /* SBV_GENERATED_aes128Dec_HEADER_INCLUDED */
+== END: "aes128Dec.h" ==================
+== BEGIN: "aes128Dec_driver.c" ================
+/* Example driver program for aes128Dec. */
+/* Automatically generated by SBV. Edit as you see fit! */
+
+#include <stdio.h>
+#include "aes128Dec.h"
+
+int main(void)
+{
+  const SWord32 sbv_driver_input_0[4] = {
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL
+  };
+
+  printf("Contents of input array pt:\n");
+  int sbv_driver_input_0_ctr;
+  for(sbv_driver_input_0_ctr = 0; sbv_driver_input_0_ctr < 4 ; ++sbv_driver_input_0_ctr)
+  { printf("  pt[%1d] = ", sbv_driver_input_0_ctr);
+    printf("0x%08"PRIx32"UL", sbv_driver_input_0[sbv_driver_input_0_ctr]);
+    printf("\n");
+  }
+
+  const SWord32 sbv_driver_input_1[4] = {
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL
+  };
+
+  printf("Contents of input array key:\n");
+  int sbv_driver_input_1_ctr;
+  for(sbv_driver_input_1_ctr = 0; sbv_driver_input_1_ctr < 4 ; ++sbv_driver_input_1_ctr)
+  { printf("  key[%1d] = ", sbv_driver_input_1_ctr);
+    printf("0x%08"PRIx32"UL", sbv_driver_input_1[sbv_driver_input_1_ctr]);
+    printf("\n");
+  }
+
+  SWord32 sbv_driver_output_0[4];
+
+  aes128Dec(sbv_driver_input_0, sbv_driver_input_1,
+            sbv_driver_output_0);
+
+  printf("aes128Dec(pt, key, ct) ->\n");
+  int sbv_driver_output_0_ctr;
+  for(sbv_driver_output_0_ctr = 0; sbv_driver_output_0_ctr < 4 ; ++sbv_driver_output_0_ctr)
+  { printf("  ct[%1d] = ", sbv_driver_output_0_ctr);
+    printf("0x%08"PRIx32"UL", sbv_driver_output_0[sbv_driver_output_0_ctr]);
+    printf("\n");
+  }
+
+  return 0;
+}
+== END: "aes128Dec_driver.c" ==================
+== BEGIN: "aes128Dec.c" ================
+/* File: "aes128Dec.c". Automatically generated by SBV. Do not edit! */
+
+#include "aes128Dec.h"
+
+/* Exact bit-vector runtime. All arithmetic is modulo the declared width. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static inline SBV_CGEN_UNUSED SWord32 sbv_bv_u32_rotl(SWord32 a, uint64_t amount)
+{
+  amount %= 32;
+  if (amount == 0) return a;
+  return (SWord32) ((((uint64_t) (SWord32) a) << amount) | (((uint64_t) (SWord32) a) >> (32 - amount)));
+}
+
+static inline SBV_CGEN_UNUSED SWord32 sbv_bv_u32_rotr(SWord32 a, uint64_t amount)
+{
+  amount %= 32;
+  if (amount == 0) return a;
+  return (SWord32) ((((uint64_t) (SWord32) a) >> amount) | (((uint64_t) (SWord32) a) << (32 - amount)));
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_31_24_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 24)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_23_16_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 16)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord16 sbv_bv_join_u8_u8_u16(SWord8 high, SWord8 low)
+{
+  SWord16 r = (SWord16) 0; uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord16) ((uint64_t) r | ((uint64_t) (((((uint64_t) low) >> (i)) & UINT64_C(1)) != 0) << (i))); }
+  for (i = 0; i < 8; ++i) { r = (SWord16) ((uint64_t) r | ((uint64_t) (((((uint64_t) high) >> (i)) & UINT64_C(1)) != 0) << (i + 8))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_15_8_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 8)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_7_0_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord32 sbv_bv_join_u16_u16_u32(SWord16 high, SWord16 low)
+{
+  SWord32 r = (SWord32) 0; uint64_t i;
+  for (i = 0; i < 16; ++i) { r = (SWord32) ((uint64_t) r | ((uint64_t) (((((uint64_t) low) >> (i)) & UINT64_C(1)) != 0) << (i))); }
+  for (i = 0; i < 16; ++i) { r = (SWord32) ((uint64_t) r | ((uint64_t) (((((uint64_t) high) >> (i)) & UINT64_C(1)) != 0) << (i + 16))); }
+  return r;
+}
+
+
+void aes128Dec(const SWord32 *sbv_input_0,
+               const SWord32 *sbv_input_1, SWord32 *sbv_output_0)
+{
+  const SWord32 s0 = sbv_input_0[0];
+  const SWord32 s1 = sbv_input_0[1];
+  const SWord32 s2 = sbv_input_0[2];
+  const SWord32 s3 = sbv_input_0[3];
+  const SWord32 s4 = sbv_input_1[0];
+  const SWord32 s5 = sbv_input_1[1];
+  const SWord32 s6 = sbv_input_1[2];
+  const SWord32 s7 = sbv_input_1[3];
+  const SWord32 s520 = sbv_bv_u32_rotl(s7, 8);
+  const SWord8  s521 = sbv_bv_extract_u32_31_24_u8(s520);
+  const SWord8  s524 = sbv_bv_extract_u32_23_16_u8(s520);
+  const SWord8  s527 = sbv_bv_extract_u32_15_8_u8(s520);
+  const SWord8  s529 = sbv_bv_extract_u32_7_0_u8(s520);
+        SWord8  s522;
+        SWord8  s523;
+        SWord8  s525;
+        SWord16 s526;
+        SWord8  s528;
+        SWord8  s530;
+        SWord16 s531;
+        SWord32 s532;
+        SWord32 s533;
+        SWord32 s534;
+        SWord32 s535;
+        SWord32 s536;
+        SWord32 s537;
+        SWord8  s538;
+        SWord8  s539;
+        SWord8  s540;
+        SWord8  s541;
+        SWord8  s542;
+        SWord16 s543;
+        SWord8  s544;
+        SWord8  s545;
+        SWord8  s546;
+        SWord8  s547;
+        SWord16 s548;
+        SWord32 s549;
+        SWord32 s550;
+        SWord32 s551;
+        SWord32 s552;
+        SWord32 s553;
+        SWord32 s554;
+        SWord8  s555;
+        SWord8  s556;
+        SWord8  s557;
+        SWord8  s558;
+        SWord8  s559;
+        SWord16 s560;
+        SWord8  s561;
+        SWord8  s562;
+        SWord8  s563;
+        SWord8  s564;
+        SWord16 s565;
+        SWord32 s566;
+        SWord32 s567;
+        SWord32 s568;
+        SWord32 s569;
+        SWord32 s570;
+        SWord32 s571;
+        SWord8  s572;
+        SWord8  s573;
+        SWord8  s574;
+        SWord8  s575;
+        SWord8  s576;
+        SWord16 s577;
+        SWord8  s578;
+        SWord8  s579;
+        SWord8  s580;
+        SWord8  s581;
+        SWord16 s582;
+        SWord32 s583;
+        SWord32 s584;
+        SWord32 s585;
+        SWord32 s586;
+        SWord32 s587;
+        SWord32 s588;
+        SWord8  s589;
+        SWord8  s590;
+        SWord8  s591;
+        SWord8  s592;
+        SWord8  s593;
+        SWord16 s594;
+        SWord8  s595;
+        SWord8  s596;
+        SWord8  s597;
+        SWord8  s598;
+        SWord16 s599;
+        SWord32 s600;
+        SWord32 s601;
+        SWord32 s602;
+        SWord32 s603;
+        SWord32 s604;
+        SWord32 s605;
+        SWord8  s606;
+        SWord8  s607;
+        SWord8  s608;
+        SWord8  s609;
+        SWord8  s610;
+        SWord16 s611;
+        SWord8  s612;
+        SWord8  s613;
+        SWord8  s614;
+        SWord8  s615;
+        SWord16 s616;
+        SWord32 s617;
+        SWord32 s618;
+        SWord32 s619;
+        SWord32 s620;
+        SWord32 s621;
+        SWord32 s622;
+        SWord8  s623;
+        SWord8  s624;
+        SWord8  s625;
+        SWord8  s626;
+        SWord8  s627;
+        SWord16 s628;
+        SWord8  s629;
+        SWord8  s630;
+        SWord8  s631;
+        SWord8  s632;
+        SWord16 s633;
+        SWord32 s634;
+        SWord32 s635;
+        SWord32 s636;
+        SWord32 s637;
+        SWord32 s638;
+        SWord32 s639;
+        SWord8  s640;
+        SWord8  s641;
+        SWord8  s642;
+        SWord8  s643;
+        SWord8  s644;
+        SWord16 s645;
+        SWord8  s646;
+        SWord8  s647;
+        SWord8  s648;
+        SWord8  s649;
+        SWord16 s650;
+        SWord32 s651;
+        SWord32 s652;
+        SWord32 s653;
+        SWord32 s654;
+        SWord32 s655;
+        SWord32 s656;
+        SWord8  s657;
+        SWord8  s658;
+        SWord8  s659;
+        SWord8  s660;
+        SWord8  s661;
+        SWord16 s662;
+        SWord8  s663;
+        SWord8  s664;
+        SWord8  s665;
+        SWord8  s666;
+        SWord16 s667;
+        SWord32 s668;
+        SWord32 s669;
+        SWord32 s670;
+        SWord32 s671;
+        SWord32 s672;
+        SWord32 s673;
+        SWord8  s674;
+        SWord8  s675;
+        SWord8  s676;
+        SWord8  s677;
+        SWord8  s678;
+        SWord16 s679;
+        SWord8  s680;
+        SWord8  s681;
+        SWord8  s682;
+        SWord8  s683;
+        SWord16 s684;
+        SWord32 s685;
+        SWord32 s686;
+        SWord32 s687;
+        SWord8  s688;
+        SWord32 s689;
+        SWord32 s945;
+        SWord32 s946;
+        SWord32 s947;
+        SWord32 s948;
+        SWord8  s949;
+        SWord32 s950;
+        SWord32 s951;
+        SWord32 s1207;
+        SWord8  s1208;
+        SWord32 s1209;
+        SWord32 s1210;
+        SWord32 s1466;
+        SWord8  s1467;
+        SWord32 s1468;
+        SWord32 s1469;
+        SWord8  s1470;
+        SWord8  s1471;
+        SWord8  s1472;
+        SWord8  s1473;
+        SWord8  s1474;
+        SWord8  s1475;
+        SWord8  s1476;
+        SWord8  s1477;
+        SWord8  s1478;
+        SWord8  s1479;
+        SWord8  s1480;
+        SWord8  s1481;
+        SWord8  s1482;
+        SWord8  s1483;
+        SWord8  s1484;
+        SWord8  s1485;
+        SWord8  s1486;
+        SWord8  s1487;
+        SWord16 s1488;
+        SWord8  s1489;
+        SWord8  s1490;
+        SWord8  s1491;
+        SWord8  s1492;
+        SWord8  s1493;
+        SWord8  s1494;
+        SWord8  s1495;
+        SWord8  s1496;
+        SWord8  s1497;
+        SWord8  s1498;
+        SWord8  s1499;
+        SWord8  s1500;
+        SWord8  s1501;
+        SWord8  s1502;
+        SWord16 s1503;
+        SWord32 s1504;
+        SWord32 s1505;
+        SWord8  s1506;
+        SWord32 s1507;
+        SWord8  s1508;
+        SWord32 s1509;
+        SWord8  s1510;
+        SWord32 s1511;
+        SWord32 s1512;
+        SWord8  s1513;
+        SWord32 s1514;
+        SWord32 s1515;
+        SWord8  s1516;
+        SWord32 s1517;
+        SWord32 s1518;
+        SWord8  s1519;
+        SWord8  s1520;
+        SWord8  s1521;
+        SWord8  s1522;
+        SWord8  s1523;
+        SWord8  s1524;
+        SWord8  s1525;
+        SWord8  s1526;
+        SWord8  s1527;
+        SWord8  s1528;
+        SWord8  s1529;
+        SWord8  s1530;
+        SWord8  s1531;
+        SWord8  s1532;
+        SWord8  s1533;
+        SWord8  s1534;
+        SWord8  s1535;
+        SWord8  s1536;
+        SWord16 s1537;
+        SWord8  s1538;
+        SWord8  s1539;
+        SWord8  s1540;
+        SWord8  s1541;
+        SWord8  s1542;
+        SWord8  s1543;
+        SWord8  s1544;
+        SWord8  s1545;
+        SWord8  s1546;
+        SWord8  s1547;
+        SWord8  s1548;
+        SWord8  s1549;
+        SWord8  s1550;
+        SWord8  s1551;
+        SWord16 s1552;
+        SWord32 s1553;
+        SWord32 s1554;
+        SWord8  s1555;
+        SWord32 s1556;
+        SWord32 s1557;
+        SWord8  s1558;
+        SWord32 s1559;
+        SWord8  s1560;
+        SWord32 s1561;
+        SWord32 s1562;
+        SWord8  s1563;
+        SWord32 s1564;
+        SWord32 s1565;
+        SWord8  s1566;
+        SWord32 s1567;
+        SWord32 s1568;
+        SWord8  s1569;
+        SWord8  s1570;
+        SWord8  s1571;
+        SWord8  s1572;
+        SWord8  s1573;
+        SWord8  s1574;
+        SWord8  s1575;
+        SWord8  s1576;
+        SWord8  s1577;
+        SWord8  s1578;
+        SWord8  s1579;
+        SWord8  s1580;
+        SWord8  s1581;
+        SWord8  s1582;
+        SWord8  s1583;
+        SWord8  s1584;
+        SWord8  s1585;
+        SWord8  s1586;
+        SWord16 s1587;
+        SWord8  s1588;
+        SWord8  s1589;
+        SWord8  s1590;
+        SWord8  s1591;
+        SWord8  s1592;
+        SWord8  s1593;
+        SWord8  s1594;
+        SWord8  s1595;
+        SWord8  s1596;
+        SWord8  s1597;
+        SWord8  s1598;
+        SWord8  s1599;
+        SWord8  s1600;
+        SWord8  s1601;
+        SWord16 s1602;
+        SWord32 s1603;
+        SWord32 s1604;
+        SWord8  s1605;
+        SWord32 s1606;
+        SWord32 s1607;
+        SWord8  s1608;
+        SWord32 s1609;
+        SWord8  s1610;
+        SWord32 s1611;
+        SWord32 s1612;
+        SWord8  s1613;
+        SWord32 s1614;
+        SWord32 s1615;
+        SWord8  s1616;
+        SWord32 s1617;
+        SWord32 s1618;
+        SWord8  s1619;
+        SWord8  s1620;
+        SWord8  s1621;
+        SWord8  s1622;
+        SWord8  s1623;
+        SWord8  s1624;
+        SWord8  s1625;
+        SWord8  s1626;
+        SWord8  s1627;
+        SWord8  s1628;
+        SWord8  s1629;
+        SWord8  s1630;
+        SWord8  s1631;
+        SWord8  s1632;
+        SWord8  s1633;
+        SWord8  s1634;
+        SWord8  s1635;
+        SWord8  s1636;
+        SWord16 s1637;
+        SWord8  s1638;
+        SWord8  s1639;
+        SWord8  s1640;
+        SWord8  s1641;
+        SWord8  s1642;
+        SWord8  s1643;
+        SWord8  s1644;
+        SWord8  s1645;
+        SWord8  s1646;
+        SWord8  s1647;
+        SWord8  s1648;
+        SWord8  s1649;
+        SWord8  s1650;
+        SWord8  s1651;
+        SWord16 s1652;
+        SWord32 s1653;
+        SWord32 s1654;
+        SWord8  s1655;
+        SWord32 s1656;
+        SWord32 s1657;
+        SWord8  s1658;
+        SWord8  s1659;
+        SWord8  s1660;
+        SWord8  s1661;
+        SWord8  s1662;
+        SWord8  s1663;
+        SWord8  s1664;
+        SWord8  s1665;
+        SWord8  s1666;
+        SWord8  s1667;
+        SWord8  s1668;
+        SWord8  s1669;
+        SWord8  s1670;
+        SWord8  s1671;
+        SWord8  s1672;
+        SWord8  s1673;
+        SWord8  s1674;
+        SWord8  s1675;
+        SWord16 s1676;
+        SWord8  s1677;
+        SWord8  s1678;
+        SWord8  s1679;
+        SWord8  s1680;
+        SWord8  s1681;
+        SWord8  s1682;
+        SWord8  s1683;
+        SWord8  s1684;
+        SWord8  s1685;
+        SWord8  s1686;
+        SWord8  s1687;
+        SWord8  s1688;
+        SWord8  s1689;
+        SWord8  s1690;
+        SWord16 s1691;
+        SWord32 s1692;
+        SWord32 s1693;
+        SWord8  s1694;
+        SWord32 s1695;
+        SWord8  s1696;
+        SWord32 s1697;
+        SWord8  s1698;
+        SWord32 s1699;
+        SWord32 s1700;
+        SWord8  s1701;
+        SWord32 s1702;
+        SWord32 s1703;
+        SWord8  s1704;
+        SWord32 s1705;
+        SWord32 s1706;
+        SWord8  s1707;
+        SWord8  s1708;
+        SWord8  s1709;
+        SWord8  s1710;
+        SWord8  s1711;
+        SWord8  s1712;
+        SWord8  s1713;
+        SWord8  s1714;
+        SWord8  s1715;
+        SWord8  s1716;
+        SWord8  s1717;
+        SWord8  s1718;
+        SWord8  s1719;
+        SWord8  s1720;
+        SWord8  s1721;
+        SWord8  s1722;
+        SWord8  s1723;
+        SWord8  s1724;
+        SWord16 s1725;
+        SWord8  s1726;
+        SWord8  s1727;
+        SWord8  s1728;
+        SWord8  s1729;
+        SWord8  s1730;
+        SWord8  s1731;
+        SWord8  s1732;
+        SWord8  s1733;
+        SWord8  s1734;
+        SWord8  s1735;
+        SWord8  s1736;
+        SWord8  s1737;
+        SWord8  s1738;
+        SWord8  s1739;
+        SWord16 s1740;
+        SWord32 s1741;
+        SWord32 s1742;
+        SWord8  s1743;
+        SWord32 s1744;
+        SWord32 s1745;
+        SWord8  s1746;
+        SWord32 s1747;
+        SWord8  s1748;
+        SWord32 s1749;
+        SWord32 s1750;
+        SWord8  s1751;
+        SWord32 s1752;
+        SWord32 s1753;
+        SWord8  s1754;
+        SWord32 s1755;
+        SWord32 s1756;
+        SWord8  s1757;
+        SWord8  s1758;
+        SWord8  s1759;
+        SWord8  s1760;
+        SWord8  s1761;
+        SWord8  s1762;
+        SWord8  s1763;
+        SWord8  s1764;
+        SWord8  s1765;
+        SWord8  s1766;
+        SWord8  s1767;
+        SWord8  s1768;
+        SWord8  s1769;
+        SWord8  s1770;
+        SWord8  s1771;
+        SWord8  s1772;
+        SWord8  s1773;
+        SWord8  s1774;
+        SWord16 s1775;
+        SWord8  s1776;
+        SWord8  s1777;
+        SWord8  s1778;
+        SWord8  s1779;
+        SWord8  s1780;
+        SWord8  s1781;
+        SWord8  s1782;
+        SWord8  s1783;
+        SWord8  s1784;
+        SWord8  s1785;
+        SWord8  s1786;
+        SWord8  s1787;
+        SWord8  s1788;
+        SWord8  s1789;
+        SWord16 s1790;
+        SWord32 s1791;
+        SWord32 s1792;
+        SWord8  s1793;
+        SWord32 s1794;
+        SWord32 s1795;
+        SWord8  s1796;
+        SWord32 s1797;
+        SWord8  s1798;
+        SWord32 s1799;
+        SWord32 s1800;
+        SWord8  s1801;
+        SWord32 s1802;
+        SWord32 s1803;
+        SWord8  s1804;
+        SWord32 s1805;
+        SWord32 s1806;
+        SWord8  s1807;
+        SWord8  s1808;
+        SWord8  s1809;
+        SWord8  s1810;
+        SWord8  s1811;
+        SWord8  s1812;
+        SWord8  s1813;
+        SWord8  s1814;
+        SWord8  s1815;
+        SWord8  s1816;
+        SWord8  s1817;
+        SWord8  s1818;
+        SWord8  s1819;
+        SWord8  s1820;
+        SWord8  s1821;
+        SWord8  s1822;
+        SWord8  s1823;
+        SWord8  s1824;
+        SWord16 s1825;
+        SWord8  s1826;
+        SWord8  s1827;
+        SWord8  s1828;
+        SWord8  s1829;
+        SWord8  s1830;
+        SWord8  s1831;
+        SWord8  s1832;
+        SWord8  s1833;
+        SWord8  s1834;
+        SWord8  s1835;
+        SWord8  s1836;
+        SWord8  s1837;
+        SWord8  s1838;
+        SWord8  s1839;
+        SWord16 s1840;
+        SWord32 s1841;
+        SWord32 s1842;
+        SWord8  s1843;
+        SWord32 s1844;
+        SWord32 s1845;
+        SWord8  s1846;
+        SWord8  s1847;
+        SWord8  s1848;
+        SWord8  s1849;
+        SWord8  s1850;
+        SWord8  s1851;
+        SWord8  s1852;
+        SWord8  s1853;
+        SWord8  s1854;
+        SWord8  s1855;
+        SWord8  s1856;
+        SWord8  s1857;
+        SWord8  s1858;
+        SWord8  s1859;
+        SWord8  s1860;
+        SWord8  s1861;
+        SWord8  s1862;
+        SWord8  s1863;
+        SWord16 s1864;
+        SWord8  s1865;
+        SWord8  s1866;
+        SWord8  s1867;
+        SWord8  s1868;
+        SWord8  s1869;
+        SWord8  s1870;
+        SWord8  s1871;
+        SWord8  s1872;
+        SWord8  s1873;
+        SWord8  s1874;
+        SWord8  s1875;
+        SWord8  s1876;
+        SWord8  s1877;
+        SWord8  s1878;
+        SWord16 s1879;
+        SWord32 s1880;
+        SWord32 s1881;
+        SWord8  s1882;
+        SWord32 s1883;
+        SWord8  s1884;
+        SWord32 s1885;
+        SWord8  s1886;
+        SWord32 s1887;
+        SWord32 s1888;
+        SWord8  s1889;
+        SWord32 s1890;
+        SWord32 s1891;
+        SWord8  s1892;
+        SWord32 s1893;
+        SWord32 s1894;
+        SWord8  s1895;
+        SWord8  s1896;
+        SWord8  s1897;
+        SWord8  s1898;
+        SWord8  s1899;
+        SWord8  s1900;
+        SWord8  s1901;
+        SWord8  s1902;
+        SWord8  s1903;
+        SWord8  s1904;
+        SWord8  s1905;
+        SWord8  s1906;
+        SWord8  s1907;
+        SWord8  s1908;
+        SWord8  s1909;
+        SWord8  s1910;
+        SWord8  s1911;
+        SWord8  s1912;
+        SWord16 s1913;
+        SWord8  s1914;
+        SWord8  s1915;
+        SWord8  s1916;
+        SWord8  s1917;
+        SWord8  s1918;
+        SWord8  s1919;
+        SWord8  s1920;
+        SWord8  s1921;
+        SWord8  s1922;
+        SWord8  s1923;
+        SWord8  s1924;
+        SWord8  s1925;
+        SWord8  s1926;
+        SWord8  s1927;
+        SWord16 s1928;
+        SWord32 s1929;
+        SWord32 s1930;
+        SWord8  s1931;
+        SWord32 s1932;
+        SWord32 s1933;
+        SWord8  s1934;
+        SWord32 s1935;
+        SWord8  s1936;
+        SWord32 s1937;
+        SWord32 s1938;
+        SWord8  s1939;
+        SWord32 s1940;
+        SWord32 s1941;
+        SWord8  s1942;
+        SWord32 s1943;
+        SWord32 s1944;
+        SWord8  s1945;
+        SWord8  s1946;
+        SWord8  s1947;
+        SWord8  s1948;
+        SWord8  s1949;
+        SWord8  s1950;
+        SWord8  s1951;
+        SWord8  s1952;
+        SWord8  s1953;
+        SWord8  s1954;
+        SWord8  s1955;
+        SWord8  s1956;
+        SWord8  s1957;
+        SWord8  s1958;
+        SWord8  s1959;
+        SWord8  s1960;
+        SWord8  s1961;
+        SWord8  s1962;
+        SWord16 s1963;
+        SWord8  s1964;
+        SWord8  s1965;
+        SWord8  s1966;
+        SWord8  s1967;
+        SWord8  s1968;
+        SWord8  s1969;
+        SWord8  s1970;
+        SWord8  s1971;
+        SWord8  s1972;
+        SWord8  s1973;
+        SWord8  s1974;
+        SWord8  s1975;
+        SWord8  s1976;
+        SWord8  s1977;
+        SWord16 s1978;
+        SWord32 s1979;
+        SWord32 s1980;
+        SWord8  s1981;
+        SWord32 s1982;
+        SWord32 s1983;
+        SWord8  s1984;
+        SWord32 s1985;
+        SWord8  s1986;
+        SWord32 s1987;
+        SWord32 s1988;
+        SWord8  s1989;
+        SWord32 s1990;
+        SWord32 s1991;
+        SWord8  s1992;
+        SWord32 s1993;
+        SWord32 s1994;
+        SWord8  s1995;
+        SWord8  s1996;
+        SWord8  s1997;
+        SWord8  s1998;
+        SWord8  s1999;
+        SWord8  s2000;
+        SWord8  s2001;
+        SWord8  s2002;
+        SWord8  s2003;
+        SWord8  s2004;
+        SWord8  s2005;
+        SWord8  s2006;
+        SWord8  s2007;
+        SWord8  s2008;
+        SWord8  s2009;
+        SWord8  s2010;
+        SWord8  s2011;
+        SWord8  s2012;
+        SWord16 s2013;
+        SWord8  s2014;
+        SWord8  s2015;
+        SWord8  s2016;
+        SWord8  s2017;
+        SWord8  s2018;
+        SWord8  s2019;
+        SWord8  s2020;
+        SWord8  s2021;
+        SWord8  s2022;
+        SWord8  s2023;
+        SWord8  s2024;
+        SWord8  s2025;
+        SWord8  s2026;
+        SWord8  s2027;
+        SWord16 s2028;
+        SWord32 s2029;
+        SWord32 s2030;
+        SWord8  s2031;
+        SWord32 s2032;
+        SWord32 s2033;
+        SWord8  s2034;
+        SWord8  s2035;
+        SWord8  s2036;
+        SWord8  s2037;
+        SWord8  s2038;
+        SWord8  s2039;
+        SWord8  s2040;
+        SWord8  s2041;
+        SWord8  s2042;
+        SWord8  s2043;
+        SWord8  s2044;
+        SWord8  s2045;
+        SWord8  s2046;
+        SWord8  s2047;
+        SWord8  s2048;
+        SWord8  s2049;
+        SWord8  s2050;
+        SWord8  s2051;
+        SWord16 s2052;
+        SWord8  s2053;
+        SWord8  s2054;
+        SWord8  s2055;
+        SWord8  s2056;
+        SWord8  s2057;
+        SWord8  s2058;
+        SWord8  s2059;
+        SWord8  s2060;
+        SWord8  s2061;
+        SWord8  s2062;
+        SWord8  s2063;
+        SWord8  s2064;
+        SWord8  s2065;
+        SWord8  s2066;
+        SWord16 s2067;
+        SWord32 s2068;
+        SWord32 s2069;
+        SWord8  s2070;
+        SWord32 s2071;
+        SWord8  s2072;
+        SWord32 s2073;
+        SWord8  s2074;
+        SWord32 s2075;
+        SWord32 s2076;
+        SWord8  s2077;
+        SWord32 s2078;
+        SWord32 s2079;
+        SWord8  s2080;
+        SWord32 s2081;
+        SWord32 s2082;
+        SWord8  s2083;
+        SWord8  s2084;
+        SWord8  s2085;
+        SWord8  s2086;
+        SWord8  s2087;
+        SWord8  s2088;
+        SWord8  s2089;
+        SWord8  s2090;
+        SWord8  s2091;
+        SWord8  s2092;
+        SWord8  s2093;
+        SWord8  s2094;
+        SWord8  s2095;
+        SWord8  s2096;
+        SWord8  s2097;
+        SWord8  s2098;
+        SWord8  s2099;
+        SWord8  s2100;
+        SWord16 s2101;
+        SWord8  s2102;
+        SWord8  s2103;
+        SWord8  s2104;
+        SWord8  s2105;
+        SWord8  s2106;
+        SWord8  s2107;
+        SWord8  s2108;
+        SWord8  s2109;
+        SWord8  s2110;
+        SWord8  s2111;
+        SWord8  s2112;
+        SWord8  s2113;
+        SWord8  s2114;
+        SWord8  s2115;
+        SWord16 s2116;
+        SWord32 s2117;
+        SWord32 s2118;
+        SWord8  s2119;
+        SWord32 s2120;
+        SWord32 s2121;
+        SWord8  s2122;
+        SWord32 s2123;
+        SWord8  s2124;
+        SWord32 s2125;
+        SWord32 s2126;
+        SWord8  s2127;
+        SWord32 s2128;
+        SWord32 s2129;
+        SWord8  s2130;
+        SWord32 s2131;
+        SWord32 s2132;
+        SWord8  s2133;
+        SWord8  s2134;
+        SWord8  s2135;
+        SWord8  s2136;
+        SWord8  s2137;
+        SWord8  s2138;
+        SWord8  s2139;
+        SWord8  s2140;
+        SWord8  s2141;
+        SWord8  s2142;
+        SWord8  s2143;
+        SWord8  s2144;
+        SWord8  s2145;
+        SWord8  s2146;
+        SWord8  s2147;
+        SWord8  s2148;
+        SWord8  s2149;
+        SWord8  s2150;
+        SWord16 s2151;
+        SWord8  s2152;
+        SWord8  s2153;
+        SWord8  s2154;
+        SWord8  s2155;
+        SWord8  s2156;
+        SWord8  s2157;
+        SWord8  s2158;
+        SWord8  s2159;
+        SWord8  s2160;
+        SWord8  s2161;
+        SWord8  s2162;
+        SWord8  s2163;
+        SWord8  s2164;
+        SWord8  s2165;
+        SWord16 s2166;
+        SWord32 s2167;
+        SWord32 s2168;
+        SWord8  s2169;
+        SWord32 s2170;
+        SWord32 s2171;
+        SWord8  s2172;
+        SWord32 s2173;
+        SWord8  s2174;
+        SWord32 s2175;
+        SWord32 s2176;
+        SWord8  s2177;
+        SWord32 s2178;
+        SWord32 s2179;
+        SWord8  s2180;
+        SWord32 s2181;
+        SWord32 s2182;
+        SWord8  s2183;
+        SWord8  s2184;
+        SWord8  s2185;
+        SWord8  s2186;
+        SWord8  s2187;
+        SWord8  s2188;
+        SWord8  s2189;
+        SWord8  s2190;
+        SWord8  s2191;
+        SWord8  s2192;
+        SWord8  s2193;
+        SWord8  s2194;
+        SWord8  s2195;
+        SWord8  s2196;
+        SWord8  s2197;
+        SWord8  s2198;
+        SWord8  s2199;
+        SWord8  s2200;
+        SWord16 s2201;
+        SWord8  s2202;
+        SWord8  s2203;
+        SWord8  s2204;
+        SWord8  s2205;
+        SWord8  s2206;
+        SWord8  s2207;
+        SWord8  s2208;
+        SWord8  s2209;
+        SWord8  s2210;
+        SWord8  s2211;
+        SWord8  s2212;
+        SWord8  s2213;
+        SWord8  s2214;
+        SWord8  s2215;
+        SWord16 s2216;
+        SWord32 s2217;
+        SWord32 s2218;
+        SWord8  s2219;
+        SWord32 s2220;
+        SWord32 s2221;
+        SWord8  s2222;
+        SWord8  s2223;
+        SWord8  s2224;
+        SWord8  s2225;
+        SWord8  s2226;
+        SWord8  s2227;
+        SWord8  s2228;
+        SWord8  s2229;
+        SWord8  s2230;
+        SWord8  s2231;
+        SWord8  s2232;
+        SWord8  s2233;
+        SWord8  s2234;
+        SWord8  s2235;
+        SWord8  s2236;
+        SWord8  s2237;
+        SWord8  s2238;
+        SWord8  s2239;
+        SWord16 s2240;
+        SWord8  s2241;
+        SWord8  s2242;
+        SWord8  s2243;
+        SWord8  s2244;
+        SWord8  s2245;
+        SWord8  s2246;
+        SWord8  s2247;
+        SWord8  s2248;
+        SWord8  s2249;
+        SWord8  s2250;
+        SWord8  s2251;
+        SWord8  s2252;
+        SWord8  s2253;
+        SWord8  s2254;
+        SWord16 s2255;
+        SWord32 s2256;
+        SWord32 s2257;
+        SWord8  s2258;
+        SWord32 s2259;
+        SWord8  s2260;
+        SWord32 s2261;
+        SWord8  s2262;
+        SWord32 s2263;
+        SWord32 s2264;
+        SWord8  s2265;
+        SWord32 s2266;
+        SWord32 s2267;
+        SWord8  s2268;
+        SWord32 s2269;
+        SWord32 s2270;
+        SWord8  s2271;
+        SWord8  s2272;
+        SWord8  s2273;
+        SWord8  s2274;
+        SWord8  s2275;
+        SWord8  s2276;
+        SWord8  s2277;
+        SWord8  s2278;
+        SWord8  s2279;
+        SWord8  s2280;
+        SWord8  s2281;
+        SWord8  s2282;
+        SWord8  s2283;
+        SWord8  s2284;
+        SWord8  s2285;
+        SWord8  s2286;
+        SWord8  s2287;
+        SWord8  s2288;
+        SWord16 s2289;
+        SWord8  s2290;
+        SWord8  s2291;
+        SWord8  s2292;
+        SWord8  s2293;
+        SWord8  s2294;
+        SWord8  s2295;
+        SWord8  s2296;
+        SWord8  s2297;
+        SWord8  s2298;
+        SWord8  s2299;
+        SWord8  s2300;
+        SWord8  s2301;
+        SWord8  s2302;
+        SWord8  s2303;
+        SWord16 s2304;
+        SWord32 s2305;
+        SWord32 s2306;
+        SWord8  s2307;
+        SWord32 s2308;
+        SWord32 s2309;
+        SWord8  s2310;
+        SWord32 s2311;
+        SWord8  s2312;
+        SWord32 s2313;
+        SWord32 s2314;
+        SWord8  s2315;
+        SWord32 s2316;
+        SWord32 s2317;
+        SWord8  s2318;
+        SWord32 s2319;
+        SWord32 s2320;
+        SWord8  s2321;
+        SWord8  s2322;
+        SWord8  s2323;
+        SWord8  s2324;
+        SWord8  s2325;
+        SWord8  s2326;
+        SWord8  s2327;
+        SWord8  s2328;
+        SWord8  s2329;
+        SWord8  s2330;
+        SWord8  s2331;
+        SWord8  s2332;
+        SWord8  s2333;
+        SWord8  s2334;
+        SWord8  s2335;
+        SWord8  s2336;
+        SWord8  s2337;
+        SWord8  s2338;
+        SWord16 s2339;
+        SWord8  s2340;
+        SWord8  s2341;
+        SWord8  s2342;
+        SWord8  s2343;
+        SWord8  s2344;
+        SWord8  s2345;
+        SWord8  s2346;
+        SWord8  s2347;
+        SWord8  s2348;
+        SWord8  s2349;
+        SWord8  s2350;
+        SWord8  s2351;
+        SWord8  s2352;
+        SWord8  s2353;
+        SWord16 s2354;
+        SWord32 s2355;
+        SWord32 s2356;
+        SWord8  s2357;
+        SWord32 s2358;
+        SWord32 s2359;
+        SWord8  s2360;
+        SWord32 s2361;
+        SWord8  s2362;
+        SWord32 s2363;
+        SWord32 s2364;
+        SWord8  s2365;
+        SWord32 s2366;
+        SWord32 s2367;
+        SWord8  s2368;
+        SWord32 s2369;
+        SWord32 s2370;
+        SWord8  s2371;
+        SWord8  s2372;
+        SWord8  s2373;
+        SWord8  s2374;
+        SWord8  s2375;
+        SWord8  s2376;
+        SWord8  s2377;
+        SWord8  s2378;
+        SWord8  s2379;
+        SWord8  s2380;
+        SWord8  s2381;
+        SWord8  s2382;
+        SWord8  s2383;
+        SWord8  s2384;
+        SWord8  s2385;
+        SWord8  s2386;
+        SWord8  s2387;
+        SWord8  s2388;
+        SWord16 s2389;
+        SWord8  s2390;
+        SWord8  s2391;
+        SWord8  s2392;
+        SWord8  s2393;
+        SWord8  s2394;
+        SWord8  s2395;
+        SWord8  s2396;
+        SWord8  s2397;
+        SWord8  s2398;
+        SWord8  s2399;
+        SWord8  s2400;
+        SWord8  s2401;
+        SWord8  s2402;
+        SWord8  s2403;
+        SWord16 s2404;
+        SWord32 s2405;
+        SWord32 s2406;
+        SWord8  s2407;
+        SWord32 s2408;
+        SWord32 s2409;
+        SWord8  s2410;
+        SWord8  s2411;
+        SWord8  s2412;
+        SWord8  s2413;
+        SWord8  s2414;
+        SWord8  s2415;
+        SWord8  s2416;
+        SWord8  s2417;
+        SWord8  s2418;
+        SWord8  s2419;
+        SWord8  s2420;
+        SWord8  s2421;
+        SWord8  s2422;
+        SWord8  s2423;
+        SWord8  s2424;
+        SWord8  s2425;
+        SWord8  s2426;
+        SWord8  s2427;
+        SWord16 s2428;
+        SWord8  s2429;
+        SWord8  s2430;
+        SWord8  s2431;
+        SWord8  s2432;
+        SWord8  s2433;
+        SWord8  s2434;
+        SWord8  s2435;
+        SWord8  s2436;
+        SWord8  s2437;
+        SWord8  s2438;
+        SWord8  s2439;
+        SWord8  s2440;
+        SWord8  s2441;
+        SWord8  s2442;
+        SWord16 s2443;
+        SWord32 s2444;
+        SWord32 s2445;
+        SWord8  s2446;
+        SWord32 s2447;
+        SWord8  s2448;
+        SWord32 s2449;
+        SWord8  s2450;
+        SWord32 s2451;
+        SWord32 s2452;
+        SWord8  s2453;
+        SWord32 s2454;
+        SWord32 s2455;
+        SWord8  s2456;
+        SWord32 s2457;
+        SWord32 s2458;
+        SWord8  s2459;
+        SWord8  s2460;
+        SWord8  s2461;
+        SWord8  s2462;
+        SWord8  s2463;
+        SWord8  s2464;
+        SWord8  s2465;
+        SWord8  s2466;
+        SWord8  s2467;
+        SWord8  s2468;
+        SWord8  s2469;
+        SWord8  s2470;
+        SWord8  s2471;
+        SWord8  s2472;
+        SWord8  s2473;
+        SWord8  s2474;
+        SWord8  s2475;
+        SWord8  s2476;
+        SWord16 s2477;
+        SWord8  s2478;
+        SWord8  s2479;
+        SWord8  s2480;
+        SWord8  s2481;
+        SWord8  s2482;
+        SWord8  s2483;
+        SWord8  s2484;
+        SWord8  s2485;
+        SWord8  s2486;
+        SWord8  s2487;
+        SWord8  s2488;
+        SWord8  s2489;
+        SWord8  s2490;
+        SWord8  s2491;
+        SWord16 s2492;
+        SWord32 s2493;
+        SWord32 s2494;
+        SWord8  s2495;
+        SWord32 s2496;
+        SWord32 s2497;
+        SWord8  s2498;
+        SWord32 s2499;
+        SWord8  s2500;
+        SWord32 s2501;
+        SWord32 s2502;
+        SWord8  s2503;
+        SWord32 s2504;
+        SWord32 s2505;
+        SWord8  s2506;
+        SWord32 s2507;
+        SWord32 s2508;
+        SWord8  s2509;
+        SWord8  s2510;
+        SWord8  s2511;
+        SWord8  s2512;
+        SWord8  s2513;
+        SWord8  s2514;
+        SWord8  s2515;
+        SWord8  s2516;
+        SWord8  s2517;
+        SWord8  s2518;
+        SWord8  s2519;
+        SWord8  s2520;
+        SWord8  s2521;
+        SWord8  s2522;
+        SWord8  s2523;
+        SWord8  s2524;
+        SWord8  s2525;
+        SWord8  s2526;
+        SWord16 s2527;
+        SWord8  s2528;
+        SWord8  s2529;
+        SWord8  s2530;
+        SWord8  s2531;
+        SWord8  s2532;
+        SWord8  s2533;
+        SWord8  s2534;
+        SWord8  s2535;
+        SWord8  s2536;
+        SWord8  s2537;
+        SWord8  s2538;
+        SWord8  s2539;
+        SWord8  s2540;
+        SWord8  s2541;
+        SWord16 s2542;
+        SWord32 s2543;
+        SWord32 s2544;
+        SWord8  s2545;
+        SWord32 s2546;
+        SWord32 s2547;
+        SWord8  s2548;
+        SWord32 s2549;
+        SWord8  s2550;
+        SWord32 s2551;
+        SWord32 s2552;
+        SWord8  s2553;
+        SWord32 s2554;
+        SWord32 s2555;
+        SWord8  s2556;
+        SWord32 s2557;
+        SWord32 s2558;
+        SWord8  s2559;
+        SWord8  s2560;
+        SWord8  s2561;
+        SWord8  s2562;
+        SWord8  s2563;
+        SWord8  s2564;
+        SWord8  s2565;
+        SWord8  s2566;
+        SWord8  s2567;
+        SWord8  s2568;
+        SWord8  s2569;
+        SWord8  s2570;
+        SWord8  s2571;
+        SWord8  s2572;
+        SWord8  s2573;
+        SWord8  s2574;
+        SWord8  s2575;
+        SWord8  s2576;
+        SWord16 s2577;
+        SWord8  s2578;
+        SWord8  s2579;
+        SWord8  s2580;
+        SWord8  s2581;
+        SWord8  s2582;
+        SWord8  s2583;
+        SWord8  s2584;
+        SWord8  s2585;
+        SWord8  s2586;
+        SWord8  s2587;
+        SWord8  s2588;
+        SWord8  s2589;
+        SWord8  s2590;
+        SWord8  s2591;
+        SWord16 s2592;
+        SWord32 s2593;
+        SWord32 s2594;
+        SWord8  s2595;
+        SWord32 s2596;
+        SWord32 s2597;
+        SWord8  s2598;
+        SWord8  s2599;
+        SWord8  s2600;
+        SWord8  s2601;
+        SWord8  s2602;
+        SWord8  s2603;
+        SWord8  s2604;
+        SWord8  s2605;
+        SWord8  s2606;
+        SWord8  s2607;
+        SWord8  s2608;
+        SWord8  s2609;
+        SWord8  s2610;
+        SWord8  s2611;
+        SWord8  s2612;
+        SWord8  s2613;
+        SWord8  s2614;
+        SWord8  s2615;
+        SWord16 s2616;
+        SWord8  s2617;
+        SWord8  s2618;
+        SWord8  s2619;
+        SWord8  s2620;
+        SWord8  s2621;
+        SWord8  s2622;
+        SWord8  s2623;
+        SWord8  s2624;
+        SWord8  s2625;
+        SWord8  s2626;
+        SWord8  s2627;
+        SWord8  s2628;
+        SWord8  s2629;
+        SWord8  s2630;
+        SWord16 s2631;
+        SWord32 s2632;
+        SWord32 s2633;
+        SWord8  s2634;
+        SWord32 s2635;
+        SWord8  s2636;
+        SWord32 s2637;
+        SWord8  s2638;
+        SWord32 s2639;
+        SWord32 s2640;
+        SWord8  s2641;
+        SWord32 s2642;
+        SWord32 s2643;
+        SWord8  s2644;
+        SWord32 s2645;
+        SWord32 s2646;
+        SWord8  s2647;
+        SWord8  s2648;
+        SWord8  s2649;
+        SWord8  s2650;
+        SWord8  s2651;
+        SWord8  s2652;
+        SWord8  s2653;
+        SWord8  s2654;
+        SWord8  s2655;
+        SWord8  s2656;
+        SWord8  s2657;
+        SWord8  s2658;
+        SWord8  s2659;
+        SWord8  s2660;
+        SWord8  s2661;
+        SWord8  s2662;
+        SWord8  s2663;
+        SWord8  s2664;
+        SWord16 s2665;
+        SWord8  s2666;
+        SWord8  s2667;
+        SWord8  s2668;
+        SWord8  s2669;
+        SWord8  s2670;
+        SWord8  s2671;
+        SWord8  s2672;
+        SWord8  s2673;
+        SWord8  s2674;
+        SWord8  s2675;
+        SWord8  s2676;
+        SWord8  s2677;
+        SWord8  s2678;
+        SWord8  s2679;
+        SWord16 s2680;
+        SWord32 s2681;
+        SWord32 s2682;
+        SWord8  s2683;
+        SWord32 s2684;
+        SWord32 s2685;
+        SWord8  s2686;
+        SWord32 s2687;
+        SWord8  s2688;
+        SWord32 s2689;
+        SWord32 s2690;
+        SWord8  s2691;
+        SWord32 s2692;
+        SWord32 s2693;
+        SWord8  s2694;
+        SWord32 s2695;
+        SWord32 s2696;
+        SWord8  s2697;
+        SWord8  s2698;
+        SWord8  s2699;
+        SWord8  s2700;
+        SWord8  s2701;
+        SWord8  s2702;
+        SWord8  s2703;
+        SWord8  s2704;
+        SWord8  s2705;
+        SWord8  s2706;
+        SWord8  s2707;
+        SWord8  s2708;
+        SWord8  s2709;
+        SWord8  s2710;
+        SWord8  s2711;
+        SWord8  s2712;
+        SWord8  s2713;
+        SWord8  s2714;
+        SWord16 s2715;
+        SWord8  s2716;
+        SWord8  s2717;
+        SWord8  s2718;
+        SWord8  s2719;
+        SWord8  s2720;
+        SWord8  s2721;
+        SWord8  s2722;
+        SWord8  s2723;
+        SWord8  s2724;
+        SWord8  s2725;
+        SWord8  s2726;
+        SWord8  s2727;
+        SWord8  s2728;
+        SWord8  s2729;
+        SWord16 s2730;
+        SWord32 s2731;
+        SWord32 s2732;
+        SWord8  s2733;
+        SWord32 s2734;
+        SWord32 s2735;
+        SWord8  s2736;
+        SWord32 s2737;
+        SWord8  s2738;
+        SWord32 s2739;
+        SWord32 s2740;
+        SWord8  s2741;
+        SWord32 s2742;
+        SWord32 s2743;
+        SWord8  s2744;
+        SWord32 s2745;
+        SWord32 s2746;
+        SWord8  s2747;
+        SWord8  s2748;
+        SWord8  s2749;
+        SWord8  s2750;
+        SWord8  s2751;
+        SWord8  s2752;
+        SWord8  s2753;
+        SWord8  s2754;
+        SWord8  s2755;
+        SWord8  s2756;
+        SWord8  s2757;
+        SWord8  s2758;
+        SWord8  s2759;
+        SWord8  s2760;
+        SWord8  s2761;
+        SWord8  s2762;
+        SWord8  s2763;
+        SWord8  s2764;
+        SWord16 s2765;
+        SWord8  s2766;
+        SWord8  s2767;
+        SWord8  s2768;
+        SWord8  s2769;
+        SWord8  s2770;
+        SWord8  s2771;
+        SWord8  s2772;
+        SWord8  s2773;
+        SWord8  s2774;
+        SWord8  s2775;
+        SWord8  s2776;
+        SWord8  s2777;
+        SWord8  s2778;
+        SWord8  s2779;
+        SWord16 s2780;
+        SWord32 s2781;
+        SWord32 s2782;
+        SWord8  s2783;
+        SWord32 s2784;
+        SWord32 s2785;
+        SWord8  s2786;
+        SWord8  s2787;
+        SWord8  s2788;
+        SWord8  s2789;
+        SWord8  s2790;
+        SWord8  s2791;
+        SWord8  s2792;
+        SWord8  s2793;
+        SWord8  s2794;
+        SWord8  s2795;
+        SWord8  s2796;
+        SWord8  s2797;
+        SWord8  s2798;
+        SWord8  s2799;
+        SWord8  s2800;
+        SWord8  s2801;
+        SWord8  s2802;
+        SWord8  s2803;
+        SWord16 s2804;
+        SWord8  s2805;
+        SWord8  s2806;
+        SWord8  s2807;
+        SWord8  s2808;
+        SWord8  s2809;
+        SWord8  s2810;
+        SWord8  s2811;
+        SWord8  s2812;
+        SWord8  s2813;
+        SWord8  s2814;
+        SWord8  s2815;
+        SWord8  s2816;
+        SWord8  s2817;
+        SWord8  s2818;
+        SWord16 s2819;
+        SWord32 s2820;
+        SWord32 s2821;
+        SWord8  s2822;
+        SWord32 s2823;
+        SWord8  s2824;
+        SWord32 s2825;
+        SWord8  s2826;
+        SWord32 s2827;
+        SWord32 s2828;
+        SWord8  s2829;
+        SWord32 s2830;
+        SWord32 s2831;
+        SWord8  s2832;
+        SWord32 s2833;
+        SWord32 s2834;
+        SWord8  s2835;
+        SWord8  s2836;
+        SWord8  s2837;
+        SWord8  s2838;
+        SWord8  s2839;
+        SWord8  s2840;
+        SWord8  s2841;
+        SWord8  s2842;
+        SWord8  s2843;
+        SWord8  s2844;
+        SWord8  s2845;
+        SWord8  s2846;
+        SWord8  s2847;
+        SWord8  s2848;
+        SWord8  s2849;
+        SWord8  s2850;
+        SWord8  s2851;
+        SWord8  s2852;
+        SWord16 s2853;
+        SWord8  s2854;
+        SWord8  s2855;
+        SWord8  s2856;
+        SWord8  s2857;
+        SWord8  s2858;
+        SWord8  s2859;
+        SWord8  s2860;
+        SWord8  s2861;
+        SWord8  s2862;
+        SWord8  s2863;
+        SWord8  s2864;
+        SWord8  s2865;
+        SWord8  s2866;
+        SWord8  s2867;
+        SWord16 s2868;
+        SWord32 s2869;
+        SWord32 s2870;
+        SWord8  s2871;
+        SWord32 s2872;
+        SWord32 s2873;
+        SWord8  s2874;
+        SWord32 s2875;
+        SWord8  s2876;
+        SWord32 s2877;
+        SWord32 s2878;
+        SWord8  s2879;
+        SWord32 s2880;
+        SWord32 s2881;
+        SWord8  s2882;
+        SWord32 s2883;
+        SWord32 s2884;
+        SWord8  s2885;
+        SWord8  s2886;
+        SWord8  s2887;
+        SWord8  s2888;
+        SWord8  s2889;
+        SWord8  s2890;
+        SWord8  s2891;
+        SWord8  s2892;
+        SWord8  s2893;
+        SWord8  s2894;
+        SWord8  s2895;
+        SWord8  s2896;
+        SWord8  s2897;
+        SWord8  s2898;
+        SWord8  s2899;
+        SWord8  s2900;
+        SWord8  s2901;
+        SWord8  s2902;
+        SWord16 s2903;
+        SWord8  s2904;
+        SWord8  s2905;
+        SWord8  s2906;
+        SWord8  s2907;
+        SWord8  s2908;
+        SWord8  s2909;
+        SWord8  s2910;
+        SWord8  s2911;
+        SWord8  s2912;
+        SWord8  s2913;
+        SWord8  s2914;
+        SWord8  s2915;
+        SWord8  s2916;
+        SWord8  s2917;
+        SWord16 s2918;
+        SWord32 s2919;
+        SWord32 s2920;
+        SWord8  s2921;
+        SWord32 s2922;
+        SWord32 s2923;
+        SWord8  s2924;
+        SWord32 s2925;
+        SWord8  s2926;
+        SWord32 s2927;
+        SWord32 s2928;
+        SWord8  s2929;
+        SWord32 s2930;
+        SWord32 s2931;
+        SWord8  s2932;
+        SWord32 s2933;
+        SWord32 s2934;
+        SWord8  s2935;
+        SWord8  s2936;
+        SWord8  s2937;
+        SWord8  s2938;
+        SWord8  s2939;
+        SWord8  s2940;
+        SWord8  s2941;
+        SWord8  s2942;
+        SWord8  s2943;
+        SWord8  s2944;
+        SWord8  s2945;
+        SWord8  s2946;
+        SWord8  s2947;
+        SWord8  s2948;
+        SWord8  s2949;
+        SWord8  s2950;
+        SWord8  s2951;
+        SWord8  s2952;
+        SWord16 s2953;
+        SWord8  s2954;
+        SWord8  s2955;
+        SWord8  s2956;
+        SWord8  s2957;
+        SWord8  s2958;
+        SWord8  s2959;
+        SWord8  s2960;
+        SWord8  s2961;
+        SWord8  s2962;
+        SWord8  s2963;
+        SWord8  s2964;
+        SWord8  s2965;
+        SWord8  s2966;
+        SWord8  s2967;
+        SWord16 s2968;
+        SWord32 s2969;
+        SWord32 s2970;
+        SWord8  s2971;
+        SWord32 s2972;
+        SWord32 s2973;
+        SWord8  s2974;
+        SWord8  s2975;
+        SWord8  s2976;
+        SWord8  s2977;
+        SWord8  s2978;
+        SWord8  s2979;
+        SWord8  s2980;
+        SWord8  s2981;
+        SWord8  s2982;
+        SWord8  s2983;
+        SWord8  s2984;
+        SWord8  s2985;
+        SWord8  s2986;
+        SWord8  s2987;
+        SWord8  s2988;
+        SWord8  s2989;
+        SWord8  s2990;
+        SWord8  s2991;
+        SWord16 s2992;
+        SWord8  s2993;
+        SWord8  s2994;
+        SWord8  s2995;
+        SWord8  s2996;
+        SWord8  s2997;
+        SWord8  s2998;
+        SWord8  s2999;
+        SWord8  s3000;
+        SWord8  s3001;
+        SWord8  s3002;
+        SWord8  s3003;
+        SWord8  s3004;
+        SWord8  s3005;
+        SWord8  s3006;
+        SWord16 s3007;
+        SWord32 s3008;
+        SWord32 s3009;
+        SWord8  s3010;
+        SWord8  s3011;
+        SWord8  s3012;
+        SWord32 s3013;
+        SWord8  s3014;
+        SWord32 s3015;
+        SWord32 s3016;
+        SWord8  s3017;
+        SWord32 s3018;
+        SWord32 s3019;
+        SWord8  s3020;
+        SWord32 s3021;
+        SWord32 s3022;
+        SWord8  s3023;
+        SWord8  s3024;
+        SWord8  s3025;
+        SWord8  s3026;
+        SWord8  s3027;
+        SWord8  s3028;
+        SWord8  s3029;
+        SWord8  s3030;
+        SWord8  s3031;
+        SWord8  s3032;
+        SWord8  s3033;
+        SWord8  s3034;
+        SWord8  s3035;
+        SWord8  s3036;
+        SWord8  s3037;
+        SWord8  s3038;
+        SWord8  s3039;
+        SWord8  s3040;
+        SWord16 s3041;
+        SWord8  s3042;
+        SWord8  s3043;
+        SWord8  s3044;
+        SWord8  s3045;
+        SWord8  s3046;
+        SWord8  s3047;
+        SWord8  s3048;
+        SWord8  s3049;
+        SWord8  s3050;
+        SWord8  s3051;
+        SWord8  s3052;
+        SWord8  s3053;
+        SWord8  s3054;
+        SWord8  s3055;
+        SWord16 s3056;
+        SWord32 s3057;
+        SWord32 s3058;
+        SWord8  s3059;
+        SWord8  s3060;
+        SWord16 s3061;
+        SWord8  s3062;
+        SWord32 s3063;
+        SWord8  s3064;
+        SWord32 s3065;
+        SWord32 s3066;
+        SWord8  s3067;
+        SWord32 s3068;
+        SWord32 s3069;
+        SWord8  s3070;
+        SWord32 s3071;
+        SWord32 s3072;
+        SWord8  s3073;
+        SWord8  s3074;
+        SWord8  s3075;
+        SWord8  s3076;
+        SWord8  s3077;
+        SWord8  s3078;
+        SWord8  s3079;
+        SWord8  s3080;
+        SWord8  s3081;
+        SWord8  s3082;
+        SWord8  s3083;
+        SWord8  s3084;
+        SWord8  s3085;
+        SWord8  s3086;
+        SWord8  s3087;
+        SWord8  s3088;
+        SWord8  s3089;
+        SWord8  s3090;
+        SWord16 s3091;
+        SWord8  s3092;
+        SWord8  s3093;
+        SWord8  s3094;
+        SWord8  s3095;
+        SWord8  s3096;
+        SWord8  s3097;
+        SWord8  s3098;
+        SWord8  s3099;
+        SWord8  s3100;
+        SWord8  s3101;
+        SWord8  s3102;
+        SWord8  s3103;
+        SWord8  s3104;
+        SWord8  s3105;
+        SWord16 s3106;
+        SWord32 s3107;
+        SWord32 s3108;
+        SWord8  s3109;
+        SWord8  s3110;
+        SWord8  s3111;
+        SWord32 s3112;
+        SWord8  s3113;
+        SWord32 s3114;
+        SWord32 s3115;
+        SWord8  s3116;
+        SWord32 s3117;
+        SWord32 s3118;
+        SWord8  s3119;
+        SWord32 s3120;
+        SWord32 s3121;
+        SWord8  s3122;
+        SWord8  s3123;
+        SWord8  s3124;
+        SWord8  s3125;
+        SWord8  s3126;
+        SWord8  s3127;
+        SWord8  s3128;
+        SWord8  s3129;
+        SWord8  s3130;
+        SWord8  s3131;
+        SWord8  s3132;
+        SWord8  s3133;
+        SWord8  s3134;
+        SWord8  s3135;
+        SWord8  s3136;
+        SWord8  s3137;
+        SWord8  s3138;
+        SWord8  s3139;
+        SWord16 s3140;
+        SWord8  s3141;
+        SWord8  s3142;
+        SWord8  s3143;
+        SWord8  s3144;
+        SWord8  s3145;
+        SWord8  s3146;
+        SWord8  s3147;
+        SWord8  s3148;
+        SWord8  s3149;
+        SWord8  s3150;
+        SWord8  s3151;
+        SWord8  s3152;
+        SWord8  s3153;
+        SWord8  s3154;
+        SWord16 s3155;
+        SWord32 s3156;
+        SWord32 s3157;
+        SWord8  s3158;
+        SWord8  s3159;
+        SWord16 s3160;
+        SWord32 s3161;
+        SWord32 s3162;
+        SWord8  s3163;
+        SWord8  s3164;
+        SWord8  s3165;
+        SWord8  s3166;
+        SWord16 s3167;
+        SWord8  s3168;
+        SWord8  s3169;
+        SWord8  s3170;
+        SWord8  s3171;
+        SWord16 s3172;
+        SWord32 s3173;
+        SWord32 s3174;
+        SWord8  s3175;
+        SWord8  s3176;
+        SWord8  s3177;
+        SWord8  s3178;
+        SWord16 s3179;
+        SWord8  s3180;
+        SWord8  s3181;
+        SWord8  s3182;
+        SWord8  s3183;
+        SWord16 s3184;
+        SWord32 s3185;
+        SWord32 s3186;
+        SWord8  s3187;
+        SWord8  s3188;
+        SWord8  s3189;
+        SWord8  s3190;
+        SWord16 s3191;
+        SWord8  s3192;
+        SWord8  s3193;
+        SWord8  s3194;
+        SWord8  s3195;
+        SWord16 s3196;
+        SWord32 s3197;
+        SWord32 s3198;
+  static const SWord8 table2[] = {
+       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
+  };
+  s522 = table2[s521];
+  s523 = 1 ^ s522;
+  s525 = table2[s524];
+  s526 = sbv_bv_join_u8_u8_u16(s523, s525);
+  s528 = table2[s527];
+  s530 = table2[s529];
+  s531 = sbv_bv_join_u8_u8_u16(s528, s530);
+  s532 = sbv_bv_join_u16_u16_u32(s526, s531);
+  s533 = s4 ^ s532;
+  s534 = s5 ^ s533;
+  s535 = s6 ^ s534;
+  s536 = s7 ^ s535;
+  s537 = sbv_bv_u32_rotl(s536, 8);
+  s538 = sbv_bv_extract_u32_31_24_u8(s537);
+  s539 = table2[s538];
+  s540 = 2 ^ s539;
+  s541 = sbv_bv_extract_u32_23_16_u8(s537);
+  s542 = table2[s541];
+  s543 = sbv_bv_join_u8_u8_u16(s540, s542);
+  s544 = sbv_bv_extract_u32_15_8_u8(s537);
+  s545 = table2[s544];
+  s546 = sbv_bv_extract_u32_7_0_u8(s537);
+  s547 = table2[s546];
+  s548 = sbv_bv_join_u8_u8_u16(s545, s547);
+  s549 = sbv_bv_join_u16_u16_u32(s543, s548);
+  s550 = s533 ^ s549;
+  s551 = s534 ^ s550;
+  s552 = s535 ^ s551;
+  s553 = s536 ^ s552;
+  s554 = sbv_bv_u32_rotl(s553, 8);
+  s555 = sbv_bv_extract_u32_31_24_u8(s554);
+  s556 = table2[s555];
+  s557 = 4 ^ s556;
+  s558 = sbv_bv_extract_u32_23_16_u8(s554);
+  s559 = table2[s558];
+  s560 = sbv_bv_join_u8_u8_u16(s557, s559);
+  s561 = sbv_bv_extract_u32_15_8_u8(s554);
+  s562 = table2[s561];
+  s563 = sbv_bv_extract_u32_7_0_u8(s554);
+  s564 = table2[s563];
+  s565 = sbv_bv_join_u8_u8_u16(s562, s564);
+  s566 = sbv_bv_join_u16_u16_u32(s560, s565);
+  s567 = s550 ^ s566;
+  s568 = s551 ^ s567;
+  s569 = s552 ^ s568;
+  s570 = s553 ^ s569;
+  s571 = sbv_bv_u32_rotl(s570, 8);
+  s572 = sbv_bv_extract_u32_31_24_u8(s571);
+  s573 = table2[s572];
+  s574 = 8 ^ s573;
+  s575 = sbv_bv_extract_u32_23_16_u8(s571);
+  s576 = table2[s575];
+  s577 = sbv_bv_join_u8_u8_u16(s574, s576);
+  s578 = sbv_bv_extract_u32_15_8_u8(s571);
+  s579 = table2[s578];
+  s580 = sbv_bv_extract_u32_7_0_u8(s571);
+  s581 = table2[s580];
+  s582 = sbv_bv_join_u8_u8_u16(s579, s581);
+  s583 = sbv_bv_join_u16_u16_u32(s577, s582);
+  s584 = s567 ^ s583;
+  s585 = s568 ^ s584;
+  s586 = s569 ^ s585;
+  s587 = s570 ^ s586;
+  s588 = sbv_bv_u32_rotl(s587, 8);
+  s589 = sbv_bv_extract_u32_31_24_u8(s588);
+  s590 = table2[s589];
+  s591 = 16 ^ s590;
+  s592 = sbv_bv_extract_u32_23_16_u8(s588);
+  s593 = table2[s592];
+  s594 = sbv_bv_join_u8_u8_u16(s591, s593);
+  s595 = sbv_bv_extract_u32_15_8_u8(s588);
+  s596 = table2[s595];
+  s597 = sbv_bv_extract_u32_7_0_u8(s588);
+  s598 = table2[s597];
+  s599 = sbv_bv_join_u8_u8_u16(s596, s598);
+  s600 = sbv_bv_join_u16_u16_u32(s594, s599);
+  s601 = s584 ^ s600;
+  s602 = s585 ^ s601;
+  s603 = s586 ^ s602;
+  s604 = s587 ^ s603;
+  s605 = sbv_bv_u32_rotl(s604, 8);
+  s606 = sbv_bv_extract_u32_31_24_u8(s605);
+  s607 = table2[s606];
+  s608 = 32 ^ s607;
+  s609 = sbv_bv_extract_u32_23_16_u8(s605);
+  s610 = table2[s609];
+  s611 = sbv_bv_join_u8_u8_u16(s608, s610);
+  s612 = sbv_bv_extract_u32_15_8_u8(s605);
+  s613 = table2[s612];
+  s614 = sbv_bv_extract_u32_7_0_u8(s605);
+  s615 = table2[s614];
+  s616 = sbv_bv_join_u8_u8_u16(s613, s615);
+  s617 = sbv_bv_join_u16_u16_u32(s611, s616);
+  s618 = s601 ^ s617;
+  s619 = s602 ^ s618;
+  s620 = s603 ^ s619;
+  s621 = s604 ^ s620;
+  s622 = sbv_bv_u32_rotl(s621, 8);
+  s623 = sbv_bv_extract_u32_31_24_u8(s622);
+  s624 = table2[s623];
+  s625 = 64 ^ s624;
+  s626 = sbv_bv_extract_u32_23_16_u8(s622);
+  s627 = table2[s626];
+  s628 = sbv_bv_join_u8_u8_u16(s625, s627);
+  s629 = sbv_bv_extract_u32_15_8_u8(s622);
+  s630 = table2[s629];
+  s631 = sbv_bv_extract_u32_7_0_u8(s622);
+  s632 = table2[s631];
+  s633 = sbv_bv_join_u8_u8_u16(s630, s632);
+  s634 = sbv_bv_join_u16_u16_u32(s628, s633);
+  s635 = s618 ^ s634;
+  s636 = s619 ^ s635;
+  s637 = s620 ^ s636;
+  s638 = s621 ^ s637;
+  s639 = sbv_bv_u32_rotl(s638, 8);
+  s640 = sbv_bv_extract_u32_31_24_u8(s639);
+  s641 = table2[s640];
+  s642 = 128 ^ s641;
+  s643 = sbv_bv_extract_u32_23_16_u8(s639);
+  s644 = table2[s643];
+  s645 = sbv_bv_join_u8_u8_u16(s642, s644);
+  s646 = sbv_bv_extract_u32_15_8_u8(s639);
+  s647 = table2[s646];
+  s648 = sbv_bv_extract_u32_7_0_u8(s639);
+  s649 = table2[s648];
+  s650 = sbv_bv_join_u8_u8_u16(s647, s649);
+  s651 = sbv_bv_join_u16_u16_u32(s645, s650);
+  s652 = s635 ^ s651;
+  s653 = s636 ^ s652;
+  s654 = s637 ^ s653;
+  s655 = s638 ^ s654;
+  s656 = sbv_bv_u32_rotl(s655, 8);
+  s657 = sbv_bv_extract_u32_31_24_u8(s656);
+  s658 = table2[s657];
+  s659 = 27 ^ s658;
+  s660 = sbv_bv_extract_u32_23_16_u8(s656);
+  s661 = table2[s660];
+  s662 = sbv_bv_join_u8_u8_u16(s659, s661);
+  s663 = sbv_bv_extract_u32_15_8_u8(s656);
+  s664 = table2[s663];
+  s665 = sbv_bv_extract_u32_7_0_u8(s656);
+  s666 = table2[s665];
+  s667 = sbv_bv_join_u8_u8_u16(s664, s666);
+  s668 = sbv_bv_join_u16_u16_u32(s662, s667);
+  s669 = s652 ^ s668;
+  s670 = s653 ^ s669;
+  s671 = s654 ^ s670;
+  s672 = s655 ^ s671;
+  s673 = sbv_bv_u32_rotl(s672, 8);
+  s674 = sbv_bv_extract_u32_31_24_u8(s673);
+  s675 = table2[s674];
+  s676 = 54 ^ s675;
+  s677 = sbv_bv_extract_u32_23_16_u8(s673);
+  s678 = table2[s677];
+  s679 = sbv_bv_join_u8_u8_u16(s676, s678);
+  s680 = sbv_bv_extract_u32_15_8_u8(s673);
+  s681 = table2[s680];
+  s682 = sbv_bv_extract_u32_7_0_u8(s673);
+  s683 = table2[s682];
+  s684 = sbv_bv_join_u8_u8_u16(s681, s683);
+  s685 = sbv_bv_join_u16_u16_u32(s679, s684);
+  s686 = s669 ^ s685;
+  s687 = s0 ^ s686;
+  s688 = sbv_bv_extract_u32_31_24_u8(s687);
+  static const SWord32 table1[] = {
+      0x51f4a750UL, 0x7e416553UL, 0x1a17a4c3UL, 0x3a275e96UL,
+      0x3bab6bcbUL, 0x1f9d45f1UL, 0xacfa58abUL, 0x4be30393UL,
+      0x2030fa55UL, 0xad766df6UL, 0x88cc7691UL, 0xf5024c25UL,
+      0x4fe5d7fcUL, 0xc52acbd7UL, 0x26354480UL, 0xb562a38fUL,
+      0xdeb15a49UL, 0x25ba1b67UL, 0x45ea0e98UL, 0x5dfec0e1UL,
+      0xc32f7502UL, 0x814cf012UL, 0x8d4697a3UL, 0x6bd3f9c6UL,
+      0x038f5fe7UL, 0x15929c95UL, 0xbf6d7aebUL, 0x955259daUL,
+      0xd4be832dUL, 0x587421d3UL, 0x49e06929UL, 0x8ec9c844UL,
+      0x75c2896aUL, 0xf48e7978UL, 0x99583e6bUL, 0x27b971ddUL,
+      0xbee14fb6UL, 0xf088ad17UL, 0xc920ac66UL, 0x7dce3ab4UL,
+      0x63df4a18UL, 0xe51a3182UL, 0x97513360UL, 0x62537f45UL,
+      0xb16477e0UL, 0xbb6bae84UL, 0xfe81a01cUL, 0xf9082b94UL,
+      0x70486858UL, 0x8f45fd19UL, 0x94de6c87UL, 0x527bf8b7UL,
+      0xab73d323UL, 0x724b02e2UL, 0xe31f8f57UL, 0x6655ab2aUL,
+      0xb2eb2807UL, 0x2fb5c203UL, 0x86c57b9aUL, 0xd33708a5UL,
+      0x302887f2UL, 0x23bfa5b2UL, 0x02036abaUL, 0xed16825cUL,
+      0x8acf1c2bUL, 0xa779b492UL, 0xf307f2f0UL, 0x4e69e2a1UL,
+      0x65daf4cdUL, 0x0605bed5UL, 0xd134621fUL, 0xc4a6fe8aUL,
+      0x342e539dUL, 0xa2f355a0UL, 0x058ae132UL, 0xa4f6eb75UL,
+      0x0b83ec39UL, 0x4060efaaUL, 0x5e719f06UL, 0xbd6e1051UL,
+      0x3e218af9UL, 0x96dd063dUL, 0xdd3e05aeUL, 0x4de6bd46UL,
+      0x91548db5UL, 0x71c45d05UL, 0x0406d46fUL, 0x605015ffUL,
+      0x1998fb24UL, 0xd6bde997UL, 0x894043ccUL, 0x67d99e77UL,
+      0xb0e842bdUL, 0x07898b88UL, 0xe7195b38UL, 0x79c8eedbUL,
+      0xa17c0a47UL, 0x7c420fe9UL, 0xf8841ec9UL, 0x00000000UL,
+      0x09808683UL, 0x322bed48UL, 0x1e1170acUL, 0x6c5a724eUL,
+      0xfd0efffbUL, 0x0f853856UL, 0x3daed51eUL, 0x362d3927UL,
+      0x0a0fd964UL, 0x685ca621UL, 0x9b5b54d1UL, 0x24362e3aUL,
+      0x0c0a67b1UL, 0x9357e70fUL, 0xb4ee96d2UL, 0x1b9b919eUL,
+      0x80c0c54fUL, 0x61dc20a2UL, 0x5a774b69UL, 0x1c121a16UL,
+      0xe293ba0aUL, 0xc0a02ae5UL, 0x3c22e043UL, 0x121b171dUL,
+      0x0e090d0bUL, 0xf28bc7adUL, 0x2db6a8b9UL, 0x141ea9c8UL,
+      0x57f11985UL, 0xaf75074cUL, 0xee99ddbbUL, 0xa37f60fdUL,
+      0xf701269fUL, 0x5c72f5bcUL, 0x44663bc5UL, 0x5bfb7e34UL,
+      0x8b432976UL, 0xcb23c6dcUL, 0xb6edfc68UL, 0xb8e4f163UL,
+      0xd731dccaUL, 0x42638510UL, 0x13972240UL, 0x84c61120UL,
+      0x854a247dUL, 0xd2bb3df8UL, 0xaef93211UL, 0xc729a16dUL,
+      0x1d9e2f4bUL, 0xdcb230f3UL, 0x0d8652ecUL, 0x77c1e3d0UL,
+      0x2bb3166cUL, 0xa970b999UL, 0x119448faUL, 0x47e96422UL,
+      0xa8fc8cc4UL, 0xa0f03f1aUL, 0x567d2cd8UL, 0x223390efUL,
+      0x87494ec7UL, 0xd938d1c1UL, 0x8ccaa2feUL, 0x98d40b36UL,
+      0xa6f581cfUL, 0xa57ade28UL, 0xdab78e26UL, 0x3fadbfa4UL,
+      0x2c3a9de4UL, 0x5078920dUL, 0x6a5fcc9bUL, 0x547e4662UL,
+      0xf68d13c2UL, 0x90d8b8e8UL, 0x2e39f75eUL, 0x82c3aff5UL,
+      0x9f5d80beUL, 0x69d0937cUL, 0x6fd52da9UL, 0xcf2512b3UL,
+      0xc8ac993bUL, 0x10187da7UL, 0xe89c636eUL, 0xdb3bbb7bUL,
+      0xcd267809UL, 0x6e5918f4UL, 0xec9ab701UL, 0x834f9aa8UL,
+      0xe6956e65UL, 0xaaffe67eUL, 0x21bccf08UL, 0xef15e8e6UL,
+      0xbae79bd9UL, 0x4a6f36ceUL, 0xea9f09d4UL, 0x29b07cd6UL,
+      0x31a4b2afUL, 0x2a3f2331UL, 0xc6a59430UL, 0x35a266c0UL,
+      0x744ebc37UL, 0xfc82caa6UL, 0xe090d0b0UL, 0x33a7d815UL,
+      0xf104984aUL, 0x41ecdaf7UL, 0x7fcd500eUL, 0x1791f62fUL,
+      0x764dd68dUL, 0x43efb04dUL, 0xccaa4d54UL, 0xe49604dfUL,
+      0x9ed1b5e3UL, 0x4c6a881bUL, 0xc12c1fb8UL, 0x4665517fUL,
+      0x9d5eea04UL, 0x018c355dUL, 0xfa877473UL, 0xfb0b412eUL,
+      0xb3671d5aUL, 0x92dbd252UL, 0xe9105633UL, 0x6dd64713UL,
+      0x9ad7618cUL, 0x37a10c7aUL, 0x59f8148eUL, 0xeb133c89UL,
+      0xcea927eeUL, 0xb761c935UL, 0xe11ce5edUL, 0x7a47b13cUL,
+      0x9cd2df59UL, 0x55f2733fUL, 0x1814ce79UL, 0x73c737bfUL,
+      0x53f7cdeaUL, 0x5ffdaa5bUL, 0xdf3d6f14UL, 0x7844db86UL,
+      0xcaaff381UL, 0xb968c43eUL, 0x3824342cUL, 0xc2a3405fUL,
+      0x161dc372UL, 0xbce2250cUL, 0x283c498bUL, 0xff0d9541UL,
+      0x39a80171UL, 0x080cb3deUL, 0xd8b4e49cUL, 0x6456c190UL,
+      0x7bcb8461UL, 0xd532b670UL, 0x486c5c74UL, 0xd0b85742UL
+  };
+  s689 = table1[s688];
+  s945 = s670 ^ s686;
+  s946 = s671 ^ s945;
+  s947 = s672 ^ s946;
+  s948 = s3 ^ s947;
+  s949 = sbv_bv_extract_u32_23_16_u8(s948);
+  static const SWord32 table3[] = {
+      0x5051f4a7UL, 0x537e4165UL, 0xc31a17a4UL, 0x963a275eUL,
+      0xcb3bab6bUL, 0xf11f9d45UL, 0xabacfa58UL, 0x934be303UL,
+      0x552030faUL, 0xf6ad766dUL, 0x9188cc76UL, 0x25f5024cUL,
+      0xfc4fe5d7UL, 0xd7c52acbUL, 0x80263544UL, 0x8fb562a3UL,
+      0x49deb15aUL, 0x6725ba1bUL, 0x9845ea0eUL, 0xe15dfec0UL,
+      0x02c32f75UL, 0x12814cf0UL, 0xa38d4697UL, 0xc66bd3f9UL,
+      0xe7038f5fUL, 0x9515929cUL, 0xebbf6d7aUL, 0xda955259UL,
+      0x2dd4be83UL, 0xd3587421UL, 0x2949e069UL, 0x448ec9c8UL,
+      0x6a75c289UL, 0x78f48e79UL, 0x6b99583eUL, 0xdd27b971UL,
+      0xb6bee14fUL, 0x17f088adUL, 0x66c920acUL, 0xb47dce3aUL,
+      0x1863df4aUL, 0x82e51a31UL, 0x60975133UL, 0x4562537fUL,
+      0xe0b16477UL, 0x84bb6baeUL, 0x1cfe81a0UL, 0x94f9082bUL,
+      0x58704868UL, 0x198f45fdUL, 0x8794de6cUL, 0xb7527bf8UL,
+      0x23ab73d3UL, 0xe2724b02UL, 0x57e31f8fUL, 0x2a6655abUL,
+      0x07b2eb28UL, 0x032fb5c2UL, 0x9a86c57bUL, 0xa5d33708UL,
+      0xf2302887UL, 0xb223bfa5UL, 0xba02036aUL, 0x5ced1682UL,
+      0x2b8acf1cUL, 0x92a779b4UL, 0xf0f307f2UL, 0xa14e69e2UL,
+      0xcd65daf4UL, 0xd50605beUL, 0x1fd13462UL, 0x8ac4a6feUL,
+      0x9d342e53UL, 0xa0a2f355UL, 0x32058ae1UL, 0x75a4f6ebUL,
+      0x390b83ecUL, 0xaa4060efUL, 0x065e719fUL, 0x51bd6e10UL,
+      0xf93e218aUL, 0x3d96dd06UL, 0xaedd3e05UL, 0x464de6bdUL,
+      0xb591548dUL, 0x0571c45dUL, 0x6f0406d4UL, 0xff605015UL,
+      0x241998fbUL, 0x97d6bde9UL, 0xcc894043UL, 0x7767d99eUL,
+      0xbdb0e842UL, 0x8807898bUL, 0x38e7195bUL, 0xdb79c8eeUL,
+      0x47a17c0aUL, 0xe97c420fUL, 0xc9f8841eUL, 0x00000000UL,
+      0x83098086UL, 0x48322bedUL, 0xac1e1170UL, 0x4e6c5a72UL,
+      0xfbfd0effUL, 0x560f8538UL, 0x1e3daed5UL, 0x27362d39UL,
+      0x640a0fd9UL, 0x21685ca6UL, 0xd19b5b54UL, 0x3a24362eUL,
+      0xb10c0a67UL, 0x0f9357e7UL, 0xd2b4ee96UL, 0x9e1b9b91UL,
+      0x4f80c0c5UL, 0xa261dc20UL, 0x695a774bUL, 0x161c121aUL,
+      0x0ae293baUL, 0xe5c0a02aUL, 0x433c22e0UL, 0x1d121b17UL,
+      0x0b0e090dUL, 0xadf28bc7UL, 0xb92db6a8UL, 0xc8141ea9UL,
+      0x8557f119UL, 0x4caf7507UL, 0xbbee99ddUL, 0xfda37f60UL,
+      0x9ff70126UL, 0xbc5c72f5UL, 0xc544663bUL, 0x345bfb7eUL,
+      0x768b4329UL, 0xdccb23c6UL, 0x68b6edfcUL, 0x63b8e4f1UL,
+      0xcad731dcUL, 0x10426385UL, 0x40139722UL, 0x2084c611UL,
+      0x7d854a24UL, 0xf8d2bb3dUL, 0x11aef932UL, 0x6dc729a1UL,
+      0x4b1d9e2fUL, 0xf3dcb230UL, 0xec0d8652UL, 0xd077c1e3UL,
+      0x6c2bb316UL, 0x99a970b9UL, 0xfa119448UL, 0x2247e964UL,
+      0xc4a8fc8cUL, 0x1aa0f03fUL, 0xd8567d2cUL, 0xef223390UL,
+      0xc787494eUL, 0xc1d938d1UL, 0xfe8ccaa2UL, 0x3698d40bUL,
+      0xcfa6f581UL, 0x28a57adeUL, 0x26dab78eUL, 0xa43fadbfUL,
+      0xe42c3a9dUL, 0x0d507892UL, 0x9b6a5fccUL, 0x62547e46UL,
+      0xc2f68d13UL, 0xe890d8b8UL, 0x5e2e39f7UL, 0xf582c3afUL,
+      0xbe9f5d80UL, 0x7c69d093UL, 0xa96fd52dUL, 0xb3cf2512UL,
+      0x3bc8ac99UL, 0xa710187dUL, 0x6ee89c63UL, 0x7bdb3bbbUL,
+      0x09cd2678UL, 0xf46e5918UL, 0x01ec9ab7UL, 0xa8834f9aUL,
+      0x65e6956eUL, 0x7eaaffe6UL, 0x0821bccfUL, 0xe6ef15e8UL,
+      0xd9bae79bUL, 0xce4a6f36UL, 0xd4ea9f09UL, 0xd629b07cUL,
+      0xaf31a4b2UL, 0x312a3f23UL, 0x30c6a594UL, 0xc035a266UL,
+      0x37744ebcUL, 0xa6fc82caUL, 0xb0e090d0UL, 0x1533a7d8UL,
+      0x4af10498UL, 0xf741ecdaUL, 0x0e7fcd50UL, 0x2f1791f6UL,
+      0x8d764dd6UL, 0x4d43efb0UL, 0x54ccaa4dUL, 0xdfe49604UL,
+      0xe39ed1b5UL, 0x1b4c6a88UL, 0xb8c12c1fUL, 0x7f466551UL,
+      0x049d5eeaUL, 0x5d018c35UL, 0x73fa8774UL, 0x2efb0b41UL,
+      0x5ab3671dUL, 0x5292dbd2UL, 0x33e91056UL, 0x136dd647UL,
+      0x8c9ad761UL, 0x7a37a10cUL, 0x8e59f814UL, 0x89eb133cUL,
+      0xeecea927UL, 0x35b761c9UL, 0xede11ce5UL, 0x3c7a47b1UL,
+      0x599cd2dfUL, 0x3f55f273UL, 0x791814ceUL, 0xbf73c737UL,
+      0xea53f7cdUL, 0x5b5ffdaaUL, 0x14df3d6fUL, 0x867844dbUL,
+      0x81caaff3UL, 0x3eb968c4UL, 0x2c382434UL, 0x5fc2a340UL,
+      0x72161dc3UL, 0x0cbce225UL, 0x8b283c49UL, 0x41ff0d95UL,
+      0x7139a801UL, 0xde080cb3UL, 0x9cd8b4e4UL, 0x906456c1UL,
+      0x617bcb84UL, 0x70d532b6UL, 0x74486c5cUL, 0x42d0b857UL
+  };
+  s950 = table3[s949];
+  s951 = s689 ^ s950;
+  s1207 = s2 ^ s946;
+  s1208 = sbv_bv_extract_u32_15_8_u8(s1207);
+  static const SWord32 table4[] = {
+      0xa75051f4UL, 0x65537e41UL, 0xa4c31a17UL, 0x5e963a27UL,
+      0x6bcb3babUL, 0x45f11f9dUL, 0x58abacfaUL, 0x03934be3UL,
+      0xfa552030UL, 0x6df6ad76UL, 0x769188ccUL, 0x4c25f502UL,
+      0xd7fc4fe5UL, 0xcbd7c52aUL, 0x44802635UL, 0xa38fb562UL,
+      0x5a49deb1UL, 0x1b6725baUL, 0x0e9845eaUL, 0xc0e15dfeUL,
+      0x7502c32fUL, 0xf012814cUL, 0x97a38d46UL, 0xf9c66bd3UL,
+      0x5fe7038fUL, 0x9c951592UL, 0x7aebbf6dUL, 0x59da9552UL,
+      0x832dd4beUL, 0x21d35874UL, 0x692949e0UL, 0xc8448ec9UL,
+      0x896a75c2UL, 0x7978f48eUL, 0x3e6b9958UL, 0x71dd27b9UL,
+      0x4fb6bee1UL, 0xad17f088UL, 0xac66c920UL, 0x3ab47dceUL,
+      0x4a1863dfUL, 0x3182e51aUL, 0x33609751UL, 0x7f456253UL,
+      0x77e0b164UL, 0xae84bb6bUL, 0xa01cfe81UL, 0x2b94f908UL,
+      0x68587048UL, 0xfd198f45UL, 0x6c8794deUL, 0xf8b7527bUL,
+      0xd323ab73UL, 0x02e2724bUL, 0x8f57e31fUL, 0xab2a6655UL,
+      0x2807b2ebUL, 0xc2032fb5UL, 0x7b9a86c5UL, 0x08a5d337UL,
+      0x87f23028UL, 0xa5b223bfUL, 0x6aba0203UL, 0x825ced16UL,
+      0x1c2b8acfUL, 0xb492a779UL, 0xf2f0f307UL, 0xe2a14e69UL,
+      0xf4cd65daUL, 0xbed50605UL, 0x621fd134UL, 0xfe8ac4a6UL,
+      0x539d342eUL, 0x55a0a2f3UL, 0xe132058aUL, 0xeb75a4f6UL,
+      0xec390b83UL, 0xefaa4060UL, 0x9f065e71UL, 0x1051bd6eUL,
+      0x8af93e21UL, 0x063d96ddUL, 0x05aedd3eUL, 0xbd464de6UL,
+      0x8db59154UL, 0x5d0571c4UL, 0xd46f0406UL, 0x15ff6050UL,
+      0xfb241998UL, 0xe997d6bdUL, 0x43cc8940UL, 0x9e7767d9UL,
+      0x42bdb0e8UL, 0x8b880789UL, 0x5b38e719UL, 0xeedb79c8UL,
+      0x0a47a17cUL, 0x0fe97c42UL, 0x1ec9f884UL, 0x00000000UL,
+      0x86830980UL, 0xed48322bUL, 0x70ac1e11UL, 0x724e6c5aUL,
+      0xfffbfd0eUL, 0x38560f85UL, 0xd51e3daeUL, 0x3927362dUL,
+      0xd9640a0fUL, 0xa621685cUL, 0x54d19b5bUL, 0x2e3a2436UL,
+      0x67b10c0aUL, 0xe70f9357UL, 0x96d2b4eeUL, 0x919e1b9bUL,
+      0xc54f80c0UL, 0x20a261dcUL, 0x4b695a77UL, 0x1a161c12UL,
+      0xba0ae293UL, 0x2ae5c0a0UL, 0xe0433c22UL, 0x171d121bUL,
+      0x0d0b0e09UL, 0xc7adf28bUL, 0xa8b92db6UL, 0xa9c8141eUL,
+      0x198557f1UL, 0x074caf75UL, 0xddbbee99UL, 0x60fda37fUL,
+      0x269ff701UL, 0xf5bc5c72UL, 0x3bc54466UL, 0x7e345bfbUL,
+      0x29768b43UL, 0xc6dccb23UL, 0xfc68b6edUL, 0xf163b8e4UL,
+      0xdccad731UL, 0x85104263UL, 0x22401397UL, 0x112084c6UL,
+      0x247d854aUL, 0x3df8d2bbUL, 0x3211aef9UL, 0xa16dc729UL,
+      0x2f4b1d9eUL, 0x30f3dcb2UL, 0x52ec0d86UL, 0xe3d077c1UL,
+      0x166c2bb3UL, 0xb999a970UL, 0x48fa1194UL, 0x642247e9UL,
+      0x8cc4a8fcUL, 0x3f1aa0f0UL, 0x2cd8567dUL, 0x90ef2233UL,
+      0x4ec78749UL, 0xd1c1d938UL, 0xa2fe8ccaUL, 0x0b3698d4UL,
+      0x81cfa6f5UL, 0xde28a57aUL, 0x8e26dab7UL, 0xbfa43fadUL,
+      0x9de42c3aUL, 0x920d5078UL, 0xcc9b6a5fUL, 0x4662547eUL,
+      0x13c2f68dUL, 0xb8e890d8UL, 0xf75e2e39UL, 0xaff582c3UL,
+      0x80be9f5dUL, 0x937c69d0UL, 0x2da96fd5UL, 0x12b3cf25UL,
+      0x993bc8acUL, 0x7da71018UL, 0x636ee89cUL, 0xbb7bdb3bUL,
+      0x7809cd26UL, 0x18f46e59UL, 0xb701ec9aUL, 0x9aa8834fUL,
+      0x6e65e695UL, 0xe67eaaffUL, 0xcf0821bcUL, 0xe8e6ef15UL,
+      0x9bd9bae7UL, 0x36ce4a6fUL, 0x09d4ea9fUL, 0x7cd629b0UL,
+      0xb2af31a4UL, 0x23312a3fUL, 0x9430c6a5UL, 0x66c035a2UL,
+      0xbc37744eUL, 0xcaa6fc82UL, 0xd0b0e090UL, 0xd81533a7UL,
+      0x984af104UL, 0xdaf741ecUL, 0x500e7fcdUL, 0xf62f1791UL,
+      0xd68d764dUL, 0xb04d43efUL, 0x4d54ccaaUL, 0x04dfe496UL,
+      0xb5e39ed1UL, 0x881b4c6aUL, 0x1fb8c12cUL, 0x517f4665UL,
+      0xea049d5eUL, 0x355d018cUL, 0x7473fa87UL, 0x412efb0bUL,
+      0x1d5ab367UL, 0xd25292dbUL, 0x5633e910UL, 0x47136dd6UL,
+      0x618c9ad7UL, 0x0c7a37a1UL, 0x148e59f8UL, 0x3c89eb13UL,
+      0x27eecea9UL, 0xc935b761UL, 0xe5ede11cUL, 0xb13c7a47UL,
+      0xdf599cd2UL, 0x733f55f2UL, 0xce791814UL, 0x37bf73c7UL,
+      0xcdea53f7UL, 0xaa5b5ffdUL, 0x6f14df3dUL, 0xdb867844UL,
+      0xf381caafUL, 0xc43eb968UL, 0x342c3824UL, 0x405fc2a3UL,
+      0xc372161dUL, 0x250cbce2UL, 0x498b283cUL, 0x9541ff0dUL,
+      0x017139a8UL, 0xb3de080cUL, 0xe49cd8b4UL, 0xc1906456UL,
+      0x84617bcbUL, 0xb670d532UL, 0x5c74486cUL, 0x5742d0b8UL
+  };
+  s1209 = table4[s1208];
+  s1210 = s951 ^ s1209;
+  s1466 = s1 ^ s945;
+  s1467 = sbv_bv_extract_u32_7_0_u8(s1466);
+  static const SWord32 table5[] = {
+      0xf4a75051UL, 0x4165537eUL, 0x17a4c31aUL, 0x275e963aUL,
+      0xab6bcb3bUL, 0x9d45f11fUL, 0xfa58abacUL, 0xe303934bUL,
+      0x30fa5520UL, 0x766df6adUL, 0xcc769188UL, 0x024c25f5UL,
+      0xe5d7fc4fUL, 0x2acbd7c5UL, 0x35448026UL, 0x62a38fb5UL,
+      0xb15a49deUL, 0xba1b6725UL, 0xea0e9845UL, 0xfec0e15dUL,
+      0x2f7502c3UL, 0x4cf01281UL, 0x4697a38dUL, 0xd3f9c66bUL,
+      0x8f5fe703UL, 0x929c9515UL, 0x6d7aebbfUL, 0x5259da95UL,
+      0xbe832dd4UL, 0x7421d358UL, 0xe0692949UL, 0xc9c8448eUL,
+      0xc2896a75UL, 0x8e7978f4UL, 0x583e6b99UL, 0xb971dd27UL,
+      0xe14fb6beUL, 0x88ad17f0UL, 0x20ac66c9UL, 0xce3ab47dUL,
+      0xdf4a1863UL, 0x1a3182e5UL, 0x51336097UL, 0x537f4562UL,
+      0x6477e0b1UL, 0x6bae84bbUL, 0x81a01cfeUL, 0x082b94f9UL,
+      0x48685870UL, 0x45fd198fUL, 0xde6c8794UL, 0x7bf8b752UL,
+      0x73d323abUL, 0x4b02e272UL, 0x1f8f57e3UL, 0x55ab2a66UL,
+      0xeb2807b2UL, 0xb5c2032fUL, 0xc57b9a86UL, 0x3708a5d3UL,
+      0x2887f230UL, 0xbfa5b223UL, 0x036aba02UL, 0x16825cedUL,
+      0xcf1c2b8aUL, 0x79b492a7UL, 0x07f2f0f3UL, 0x69e2a14eUL,
+      0xdaf4cd65UL, 0x05bed506UL, 0x34621fd1UL, 0xa6fe8ac4UL,
+      0x2e539d34UL, 0xf355a0a2UL, 0x8ae13205UL, 0xf6eb75a4UL,
+      0x83ec390bUL, 0x60efaa40UL, 0x719f065eUL, 0x6e1051bdUL,
+      0x218af93eUL, 0xdd063d96UL, 0x3e05aeddUL, 0xe6bd464dUL,
+      0x548db591UL, 0xc45d0571UL, 0x06d46f04UL, 0x5015ff60UL,
+      0x98fb2419UL, 0xbde997d6UL, 0x4043cc89UL, 0xd99e7767UL,
+      0xe842bdb0UL, 0x898b8807UL, 0x195b38e7UL, 0xc8eedb79UL,
+      0x7c0a47a1UL, 0x420fe97cUL, 0x841ec9f8UL, 0x00000000UL,
+      0x80868309UL, 0x2bed4832UL, 0x1170ac1eUL, 0x5a724e6cUL,
+      0x0efffbfdUL, 0x8538560fUL, 0xaed51e3dUL, 0x2d392736UL,
+      0x0fd9640aUL, 0x5ca62168UL, 0x5b54d19bUL, 0x362e3a24UL,
+      0x0a67b10cUL, 0x57e70f93UL, 0xee96d2b4UL, 0x9b919e1bUL,
+      0xc0c54f80UL, 0xdc20a261UL, 0x774b695aUL, 0x121a161cUL,
+      0x93ba0ae2UL, 0xa02ae5c0UL, 0x22e0433cUL, 0x1b171d12UL,
+      0x090d0b0eUL, 0x8bc7adf2UL, 0xb6a8b92dUL, 0x1ea9c814UL,
+      0xf1198557UL, 0x75074cafUL, 0x99ddbbeeUL, 0x7f60fda3UL,
+      0x01269ff7UL, 0x72f5bc5cUL, 0x663bc544UL, 0xfb7e345bUL,
+      0x4329768bUL, 0x23c6dccbUL, 0xedfc68b6UL, 0xe4f163b8UL,
+      0x31dccad7UL, 0x63851042UL, 0x97224013UL, 0xc6112084UL,
+      0x4a247d85UL, 0xbb3df8d2UL, 0xf93211aeUL, 0x29a16dc7UL,
+      0x9e2f4b1dUL, 0xb230f3dcUL, 0x8652ec0dUL, 0xc1e3d077UL,
+      0xb3166c2bUL, 0x70b999a9UL, 0x9448fa11UL, 0xe9642247UL,
+      0xfc8cc4a8UL, 0xf03f1aa0UL, 0x7d2cd856UL, 0x3390ef22UL,
+      0x494ec787UL, 0x38d1c1d9UL, 0xcaa2fe8cUL, 0xd40b3698UL,
+      0xf581cfa6UL, 0x7ade28a5UL, 0xb78e26daUL, 0xadbfa43fUL,
+      0x3a9de42cUL, 0x78920d50UL, 0x5fcc9b6aUL, 0x7e466254UL,
+      0x8d13c2f6UL, 0xd8b8e890UL, 0x39f75e2eUL, 0xc3aff582UL,
+      0x5d80be9fUL, 0xd0937c69UL, 0xd52da96fUL, 0x2512b3cfUL,
+      0xac993bc8UL, 0x187da710UL, 0x9c636ee8UL, 0x3bbb7bdbUL,
+      0x267809cdUL, 0x5918f46eUL, 0x9ab701ecUL, 0x4f9aa883UL,
+      0x956e65e6UL, 0xffe67eaaUL, 0xbccf0821UL, 0x15e8e6efUL,
+      0xe79bd9baUL, 0x6f36ce4aUL, 0x9f09d4eaUL, 0xb07cd629UL,
+      0xa4b2af31UL, 0x3f23312aUL, 0xa59430c6UL, 0xa266c035UL,
+      0x4ebc3774UL, 0x82caa6fcUL, 0x90d0b0e0UL, 0xa7d81533UL,
+      0x04984af1UL, 0xecdaf741UL, 0xcd500e7fUL, 0x91f62f17UL,
+      0x4dd68d76UL, 0xefb04d43UL, 0xaa4d54ccUL, 0x9604dfe4UL,
+      0xd1b5e39eUL, 0x6a881b4cUL, 0x2c1fb8c1UL, 0x65517f46UL,
+      0x5eea049dUL, 0x8c355d01UL, 0x877473faUL, 0x0b412efbUL,
+      0x671d5ab3UL, 0xdbd25292UL, 0x105633e9UL, 0xd647136dUL,
+      0xd7618c9aUL, 0xa10c7a37UL, 0xf8148e59UL, 0x133c89ebUL,
+      0xa927eeceUL, 0x61c935b7UL, 0x1ce5ede1UL, 0x47b13c7aUL,
+      0xd2df599cUL, 0xf2733f55UL, 0x14ce7918UL, 0xc737bf73UL,
+      0xf7cdea53UL, 0xfdaa5b5fUL, 0x3d6f14dfUL, 0x44db8678UL,
+      0xaff381caUL, 0x68c43eb9UL, 0x24342c38UL, 0xa3405fc2UL,
+      0x1dc37216UL, 0xe2250cbcUL, 0x3c498b28UL, 0x0d9541ffUL,
+      0xa8017139UL, 0x0cb3de08UL, 0xb4e49cd8UL, 0x56c19064UL,
+      0xcb84617bUL, 0x32b670d5UL, 0x6c5c7448UL, 0xb85742d0UL
+  };
+  s1468 = table5[s1467];
+  s1469 = s1210 ^ s1468;
+  s1470 = sbv_bv_extract_u32_31_24_u8(s669);
+  static const SWord8 table6[] = {
+        0,  14,  28,  18,  56,  54,  36,  42, 112, 126, 108,  98,  72,
+       70,  84,  90, 224, 238, 252, 242, 216, 214, 196, 202, 144, 158,
+      140, 130, 168, 166, 180, 186, 219, 213, 199, 201, 227, 237, 255,
+      241, 171, 165, 183, 185, 147, 157, 143, 129,  59,  53,  39,  41,
+        3,  13,  31,  17,  75,  69,  87,  89, 115, 125, 111,  97, 173,
+      163, 177, 191, 149, 155, 137, 135, 221, 211, 193, 207, 229, 235,
+      249, 247,  77,  67,  81,  95, 117, 123, 105, 103,  61,  51,  33,
+       47,   5,  11,  25,  23, 118, 120, 106, 100,  78,  64,  82,  92,
+        6,   8,  26,  20,  62,  48,  34,  44, 150, 152, 138, 132, 174,
+      160, 178, 188, 230, 232, 250, 244, 222, 208, 194, 204,  65,  79,
+       93,  83, 121, 119, 101, 107,  49,  63,  45,  35,   9,   7,  21,
+       27, 161, 175, 189, 179, 153, 151, 133, 139, 209, 223, 205, 195,
+      233, 231, 245, 251, 154, 148, 134, 136, 162, 172, 190, 176, 234,
+      228, 246, 248, 210, 220, 206, 192, 122, 116, 102, 104,  66,  76,
+       94,  80,  10,   4,  22,  24,  50,  60,  46,  32, 236, 226, 240,
+      254, 212, 218, 200, 198, 156, 146, 128, 142, 164, 170, 184, 182,
+       12,   2,  16,  30,  52,  58,  40,  38, 124, 114,  96, 110,  68,
+       74,  88,  86,  55,  57,  43,  37,  15,   1,  19,  29,  71,  73,
+       91,  85, 127, 113,  99, 109, 215, 217, 203, 197, 239, 225, 243,
+      253, 167, 169, 187, 181, 159, 145, 131, 141
+  };
+  s1471 = table6[s1470];
+  s1472 = sbv_bv_extract_u32_23_16_u8(s669);
+  static const SWord8 table7[] = {
+        0,  11,  22,  29,  44,  39,  58,  49,  88,  83,  78,  69, 116,
+      127,  98, 105, 176, 187, 166, 173, 156, 151, 138, 129, 232, 227,
+      254, 245, 196, 207, 210, 217, 123, 112, 109, 102,  87,  92,  65,
+       74,  35,  40,  53,  62,  15,   4,  25,  18, 203, 192, 221, 214,
+      231, 236, 241, 250, 147, 152, 133, 142, 191, 180, 169, 162, 246,
+      253, 224, 235, 218, 209, 204, 199, 174, 165, 184, 179, 130, 137,
+      148, 159,  70,  77,  80,  91, 106,  97, 124, 119,  30,  21,   8,
+        3,  50,  57,  36,  47, 141, 134, 155, 144, 161, 170, 183, 188,
+      213, 222, 195, 200, 249, 242, 239, 228,  61,  54,  43,  32,  17,
+       26,   7,  12, 101, 110, 115, 120,  73,  66,  95,  84, 247, 252,
+      225, 234, 219, 208, 205, 198, 175, 164, 185, 178, 131, 136, 149,
+      158,  71,  76,  81,  90, 107,  96, 125, 118,  31,  20,   9,   2,
+       51,  56,  37,  46, 140, 135, 154, 145, 160, 171, 182, 189, 212,
+      223, 194, 201, 248, 243, 238, 229,  60,  55,  42,  33,  16,  27,
+        6,  13, 100, 111, 114, 121,  72,  67,  94,  85,   1,  10,  23,
+       28,  45,  38,  59,  48,  89,  82,  79,  68, 117, 126,  99, 104,
+      177, 186, 167, 172, 157, 150, 139, 128, 233, 226, 255, 244, 197,
+      206, 211, 216, 122, 113, 108, 103,  86,  93,  64,  75,  34,  41,
+       52,  63,  14,   5,  24,  19, 202, 193, 220, 215, 230, 237, 240,
+      251, 146, 153, 132, 143, 190, 181, 168, 163
+  };
+  s1473 = table7[s1472];
+  s1474 = sbv_bv_extract_u32_15_8_u8(s669);
+  static const SWord8 table8[] = {
+        0,  13,  26,  23,  52,  57,  46,  35, 104, 101, 114, 127,  92,
+       81,  70,  75, 208, 221, 202, 199, 228, 233, 254, 243, 184, 181,
+      162, 175, 140, 129, 150, 155, 187, 182, 161, 172, 143, 130, 149,
+      152, 211, 222, 201, 196, 231, 234, 253, 240, 107, 102, 113, 124,
+       95,  82,  69,  72,   3,  14,  25,  20,  55,  58,  45,  32, 109,
+       96, 119, 122,  89,  84,  67,  78,   5,   8,  31,  18,  49,  60,
+       43,  38, 189, 176, 167, 170, 137, 132, 147, 158, 213, 216, 207,
+      194, 225, 236, 251, 246, 214, 219, 204, 193, 226, 239, 248, 245,
+      190, 179, 164, 169, 138, 135, 144, 157,   6,  11,  28,  17,  50,
+       63,  40,  37, 110,  99, 116, 121,  90,  87,  64,  77, 218, 215,
+      192, 205, 238, 227, 244, 249, 178, 191, 168, 165, 134, 139, 156,
+      145,  10,   7,  16,  29,  62,  51,  36,  41,  98, 111, 120, 117,
+       86,  91,  76,  65,  97, 108, 123, 118,  85,  88,  79,  66,   9,
+        4,  19,  30,  61,  48,  39,  42, 177, 188, 171, 166, 133, 136,
+      159, 146, 217, 212, 195, 206, 237, 224, 247, 250, 183, 186, 173,
+      160, 131, 142, 153, 148, 223, 210, 197, 200, 235, 230, 241, 252,
+      103, 106, 125, 112,  83,  94,  73,  68,  15,   2,  21,  24,  59,
+       54,  33,  44,  12,   1,  22,  27,  56,  53,  34,  47, 100, 105,
+      126, 115,  80,  93,  74,  71, 220, 209, 198, 203, 232, 229, 242,
+      255, 180, 185, 174, 163, 128, 141, 154, 151
+  };
+  s1475 = table8[s1474];
+  s1476 = sbv_bv_extract_u32_7_0_u8(s669);
+  static const SWord8 table9[] = {
+        0,   9,  18,  27,  36,  45,  54,  63,  72,  65,  90,  83, 108,
+      101, 126, 119, 144, 153, 130, 139, 180, 189, 166, 175, 216, 209,
+      202, 195, 252, 245, 238, 231,  59,  50,  41,  32,  31,  22,  13,
+        4, 115, 122,  97, 104,  87,  94,  69,  76, 171, 162, 185, 176,
+      143, 134, 157, 148, 227, 234, 241, 248, 199, 206, 213, 220, 118,
+      127, 100, 109,  82,  91,  64,  73,  62,  55,  44,  37,  26,  19,
+        8,   1, 230, 239, 244, 253, 194, 203, 208, 217, 174, 167, 188,
+      181, 138, 131, 152, 145,  77,  68,  95,  86, 105,  96, 123, 114,
+        5,  12,  23,  30,  33,  40,  51,  58, 221, 212, 207, 198, 249,
+      240, 235, 226, 149, 156, 135, 142, 177, 184, 163, 170, 236, 229,
+      254, 247, 200, 193, 218, 211, 164, 173, 182, 191, 128, 137, 146,
+      155, 124, 117, 110, 103,  88,  81,  74,  67,  52,  61,  38,  47,
+       16,  25,   2,  11, 215, 222, 197, 204, 243, 250, 225, 232, 159,
+      150, 141, 132, 187, 178, 169, 160,  71,  78,  85,  92,  99, 106,
+      113, 120,  15,   6,  29,  20,  43,  34,  57,  48, 154, 147, 136,
+      129, 190, 183, 172, 165, 210, 219, 192, 201, 246, 255, 228, 237,
+       10,   3,  24,  17,  46,  39,  60,  53,  66,  75,  80,  89, 102,
+      111, 116, 125, 161, 168, 179, 186, 133, 140, 151, 158, 233, 224,
+      251, 242, 205, 196, 223, 214,  49,  56,  35,  42,  21,  28,   7,
+       14, 121, 112, 107,  98,  93,  84,  79,  70
+  };
+  s1477 = table9[s1476];
+  s1478 = s1475 ^ s1477;
+  s1479 = s1473 ^ s1478;
+  s1480 = s1471 ^ s1479;
+  s1481 = table9[s1470];
+  s1482 = table6[s1472];
+  s1483 = table7[s1474];
+  s1484 = table8[s1476];
+  s1485 = s1483 ^ s1484;
+  s1486 = s1482 ^ s1485;
+  s1487 = s1481 ^ s1486;
+  s1488 = sbv_bv_join_u8_u8_u16(s1480, s1487);
+  s1489 = table8[s1470];
+  s1490 = table9[s1472];
+  s1491 = table6[s1474];
+  s1492 = table7[s1476];
+  s1493 = s1491 ^ s1492;
+  s1494 = s1490 ^ s1493;
+  s1495 = s1489 ^ s1494;
+  s1496 = table7[s1470];
+  s1497 = table8[s1472];
+  s1498 = table9[s1474];
+  s1499 = table6[s1476];
+  s1500 = s1498 ^ s1499;
+  s1501 = s1497 ^ s1500;
+  s1502 = s1496 ^ s1501;
+  s1503 = sbv_bv_join_u8_u8_u16(s1495, s1502);
+  s1504 = sbv_bv_join_u16_u16_u32(s1488, s1503);
+  s1505 = s1469 ^ s1504;
+  s1506 = sbv_bv_extract_u32_31_24_u8(s1505);
+  s1507 = table1[s1506];
+  s1508 = sbv_bv_extract_u32_31_24_u8(s948);
+  s1509 = table1[s1508];
+  s1510 = sbv_bv_extract_u32_23_16_u8(s1207);
+  s1511 = table3[s1510];
+  s1512 = s1509 ^ s1511;
+  s1513 = sbv_bv_extract_u32_15_8_u8(s1466);
+  s1514 = table4[s1513];
+  s1515 = s1512 ^ s1514;
+  s1516 = sbv_bv_extract_u32_7_0_u8(s687);
+  s1517 = table5[s1516];
+  s1518 = s1515 ^ s1517;
+  s1519 = sbv_bv_extract_u32_31_24_u8(s672);
+  s1520 = table6[s1519];
+  s1521 = sbv_bv_extract_u32_23_16_u8(s672);
+  s1522 = table7[s1521];
+  s1523 = sbv_bv_extract_u32_15_8_u8(s672);
+  s1524 = table8[s1523];
+  s1525 = sbv_bv_extract_u32_7_0_u8(s672);
+  s1526 = table9[s1525];
+  s1527 = s1524 ^ s1526;
+  s1528 = s1522 ^ s1527;
+  s1529 = s1520 ^ s1528;
+  s1530 = table9[s1519];
+  s1531 = table6[s1521];
+  s1532 = table7[s1523];
+  s1533 = table8[s1525];
+  s1534 = s1532 ^ s1533;
+  s1535 = s1531 ^ s1534;
+  s1536 = s1530 ^ s1535;
+  s1537 = sbv_bv_join_u8_u8_u16(s1529, s1536);
+  s1538 = table8[s1519];
+  s1539 = table9[s1521];
+  s1540 = table6[s1523];
+  s1541 = table7[s1525];
+  s1542 = s1540 ^ s1541;
+  s1543 = s1539 ^ s1542;
+  s1544 = s1538 ^ s1543;
+  s1545 = table7[s1519];
+  s1546 = table8[s1521];
+  s1547 = table9[s1523];
+  s1548 = table6[s1525];
+  s1549 = s1547 ^ s1548;
+  s1550 = s1546 ^ s1549;
+  s1551 = s1545 ^ s1550;
+  s1552 = sbv_bv_join_u8_u8_u16(s1544, s1551);
+  s1553 = sbv_bv_join_u16_u16_u32(s1537, s1552);
+  s1554 = s1518 ^ s1553;
+  s1555 = sbv_bv_extract_u32_23_16_u8(s1554);
+  s1556 = table3[s1555];
+  s1557 = s1507 ^ s1556;
+  s1558 = sbv_bv_extract_u32_31_24_u8(s1207);
+  s1559 = table1[s1558];
+  s1560 = sbv_bv_extract_u32_23_16_u8(s1466);
+  s1561 = table3[s1560];
+  s1562 = s1559 ^ s1561;
+  s1563 = sbv_bv_extract_u32_15_8_u8(s687);
+  s1564 = table4[s1563];
+  s1565 = s1562 ^ s1564;
+  s1566 = sbv_bv_extract_u32_7_0_u8(s948);
+  s1567 = table5[s1566];
+  s1568 = s1565 ^ s1567;
+  s1569 = sbv_bv_extract_u32_31_24_u8(s671);
+  s1570 = table6[s1569];
+  s1571 = sbv_bv_extract_u32_23_16_u8(s671);
+  s1572 = table7[s1571];
+  s1573 = sbv_bv_extract_u32_15_8_u8(s671);
+  s1574 = table8[s1573];
+  s1575 = sbv_bv_extract_u32_7_0_u8(s671);
+  s1576 = table9[s1575];
+  s1577 = s1574 ^ s1576;
+  s1578 = s1572 ^ s1577;
+  s1579 = s1570 ^ s1578;
+  s1580 = table9[s1569];
+  s1581 = table6[s1571];
+  s1582 = table7[s1573];
+  s1583 = table8[s1575];
+  s1584 = s1582 ^ s1583;
+  s1585 = s1581 ^ s1584;
+  s1586 = s1580 ^ s1585;
+  s1587 = sbv_bv_join_u8_u8_u16(s1579, s1586);
+  s1588 = table8[s1569];
+  s1589 = table9[s1571];
+  s1590 = table6[s1573];
+  s1591 = table7[s1575];
+  s1592 = s1590 ^ s1591;
+  s1593 = s1589 ^ s1592;
+  s1594 = s1588 ^ s1593;
+  s1595 = table7[s1569];
+  s1596 = table8[s1571];
+  s1597 = table9[s1573];
+  s1598 = table6[s1575];
+  s1599 = s1597 ^ s1598;
+  s1600 = s1596 ^ s1599;
+  s1601 = s1595 ^ s1600;
+  s1602 = sbv_bv_join_u8_u8_u16(s1594, s1601);
+  s1603 = sbv_bv_join_u16_u16_u32(s1587, s1602);
+  s1604 = s1568 ^ s1603;
+  s1605 = sbv_bv_extract_u32_15_8_u8(s1604);
+  s1606 = table4[s1605];
+  s1607 = s1557 ^ s1606;
+  s1608 = sbv_bv_extract_u32_31_24_u8(s1466);
+  s1609 = table1[s1608];
+  s1610 = sbv_bv_extract_u32_23_16_u8(s687);
+  s1611 = table3[s1610];
+  s1612 = s1609 ^ s1611;
+  s1613 = sbv_bv_extract_u32_15_8_u8(s948);
+  s1614 = table4[s1613];
+  s1615 = s1612 ^ s1614;
+  s1616 = sbv_bv_extract_u32_7_0_u8(s1207);
+  s1617 = table5[s1616];
+  s1618 = s1615 ^ s1617;
+  s1619 = sbv_bv_extract_u32_31_24_u8(s670);
+  s1620 = table6[s1619];
+  s1621 = sbv_bv_extract_u32_23_16_u8(s670);
+  s1622 = table7[s1621];
+  s1623 = sbv_bv_extract_u32_15_8_u8(s670);
+  s1624 = table8[s1623];
+  s1625 = sbv_bv_extract_u32_7_0_u8(s670);
+  s1626 = table9[s1625];
+  s1627 = s1624 ^ s1626;
+  s1628 = s1622 ^ s1627;
+  s1629 = s1620 ^ s1628;
+  s1630 = table9[s1619];
+  s1631 = table6[s1621];
+  s1632 = table7[s1623];
+  s1633 = table8[s1625];
+  s1634 = s1632 ^ s1633;
+  s1635 = s1631 ^ s1634;
+  s1636 = s1630 ^ s1635;
+  s1637 = sbv_bv_join_u8_u8_u16(s1629, s1636);
+  s1638 = table8[s1619];
+  s1639 = table9[s1621];
+  s1640 = table6[s1623];
+  s1641 = table7[s1625];
+  s1642 = s1640 ^ s1641;
+  s1643 = s1639 ^ s1642;
+  s1644 = s1638 ^ s1643;
+  s1645 = table7[s1619];
+  s1646 = table8[s1621];
+  s1647 = table9[s1623];
+  s1648 = table6[s1625];
+  s1649 = s1647 ^ s1648;
+  s1650 = s1646 ^ s1649;
+  s1651 = s1645 ^ s1650;
+  s1652 = sbv_bv_join_u8_u8_u16(s1644, s1651);
+  s1653 = sbv_bv_join_u16_u16_u32(s1637, s1652);
+  s1654 = s1618 ^ s1653;
+  s1655 = sbv_bv_extract_u32_7_0_u8(s1654);
+  s1656 = table5[s1655];
+  s1657 = s1607 ^ s1656;
+  s1658 = sbv_bv_extract_u32_31_24_u8(s652);
+  s1659 = table6[s1658];
+  s1660 = sbv_bv_extract_u32_23_16_u8(s652);
+  s1661 = table7[s1660];
+  s1662 = sbv_bv_extract_u32_15_8_u8(s652);
+  s1663 = table8[s1662];
+  s1664 = sbv_bv_extract_u32_7_0_u8(s652);
+  s1665 = table9[s1664];
+  s1666 = s1663 ^ s1665;
+  s1667 = s1661 ^ s1666;
+  s1668 = s1659 ^ s1667;
+  s1669 = table9[s1658];
+  s1670 = table6[s1660];
+  s1671 = table7[s1662];
+  s1672 = table8[s1664];
+  s1673 = s1671 ^ s1672;
+  s1674 = s1670 ^ s1673;
+  s1675 = s1669 ^ s1674;
+  s1676 = sbv_bv_join_u8_u8_u16(s1668, s1675);
+  s1677 = table8[s1658];
+  s1678 = table9[s1660];
+  s1679 = table6[s1662];
+  s1680 = table7[s1664];
+  s1681 = s1679 ^ s1680;
+  s1682 = s1678 ^ s1681;
+  s1683 = s1677 ^ s1682;
+  s1684 = table7[s1658];
+  s1685 = table8[s1660];
+  s1686 = table9[s1662];
+  s1687 = table6[s1664];
+  s1688 = s1686 ^ s1687;
+  s1689 = s1685 ^ s1688;
+  s1690 = s1684 ^ s1689;
+  s1691 = sbv_bv_join_u8_u8_u16(s1683, s1690);
+  s1692 = sbv_bv_join_u16_u16_u32(s1676, s1691);
+  s1693 = s1657 ^ s1692;
+  s1694 = sbv_bv_extract_u32_31_24_u8(s1693);
+  s1695 = table1[s1694];
+  s1696 = sbv_bv_extract_u32_31_24_u8(s1554);
+  s1697 = table1[s1696];
+  s1698 = sbv_bv_extract_u32_23_16_u8(s1604);
+  s1699 = table3[s1698];
+  s1700 = s1697 ^ s1699;
+  s1701 = sbv_bv_extract_u32_15_8_u8(s1654);
+  s1702 = table4[s1701];
+  s1703 = s1700 ^ s1702;
+  s1704 = sbv_bv_extract_u32_7_0_u8(s1505);
+  s1705 = table5[s1704];
+  s1706 = s1703 ^ s1705;
+  s1707 = sbv_bv_extract_u32_31_24_u8(s655);
+  s1708 = table6[s1707];
+  s1709 = sbv_bv_extract_u32_23_16_u8(s655);
+  s1710 = table7[s1709];
+  s1711 = sbv_bv_extract_u32_15_8_u8(s655);
+  s1712 = table8[s1711];
+  s1713 = sbv_bv_extract_u32_7_0_u8(s655);
+  s1714 = table9[s1713];
+  s1715 = s1712 ^ s1714;
+  s1716 = s1710 ^ s1715;
+  s1717 = s1708 ^ s1716;
+  s1718 = table9[s1707];
+  s1719 = table6[s1709];
+  s1720 = table7[s1711];
+  s1721 = table8[s1713];
+  s1722 = s1720 ^ s1721;
+  s1723 = s1719 ^ s1722;
+  s1724 = s1718 ^ s1723;
+  s1725 = sbv_bv_join_u8_u8_u16(s1717, s1724);
+  s1726 = table8[s1707];
+  s1727 = table9[s1709];
+  s1728 = table6[s1711];
+  s1729 = table7[s1713];
+  s1730 = s1728 ^ s1729;
+  s1731 = s1727 ^ s1730;
+  s1732 = s1726 ^ s1731;
+  s1733 = table7[s1707];
+  s1734 = table8[s1709];
+  s1735 = table9[s1711];
+  s1736 = table6[s1713];
+  s1737 = s1735 ^ s1736;
+  s1738 = s1734 ^ s1737;
+  s1739 = s1733 ^ s1738;
+  s1740 = sbv_bv_join_u8_u8_u16(s1732, s1739);
+  s1741 = sbv_bv_join_u16_u16_u32(s1725, s1740);
+  s1742 = s1706 ^ s1741;
+  s1743 = sbv_bv_extract_u32_23_16_u8(s1742);
+  s1744 = table3[s1743];
+  s1745 = s1695 ^ s1744;
+  s1746 = sbv_bv_extract_u32_31_24_u8(s1604);
+  s1747 = table1[s1746];
+  s1748 = sbv_bv_extract_u32_23_16_u8(s1654);
+  s1749 = table3[s1748];
+  s1750 = s1747 ^ s1749;
+  s1751 = sbv_bv_extract_u32_15_8_u8(s1505);
+  s1752 = table4[s1751];
+  s1753 = s1750 ^ s1752;
+  s1754 = sbv_bv_extract_u32_7_0_u8(s1554);
+  s1755 = table5[s1754];
+  s1756 = s1753 ^ s1755;
+  s1757 = sbv_bv_extract_u32_31_24_u8(s654);
+  s1758 = table6[s1757];
+  s1759 = sbv_bv_extract_u32_23_16_u8(s654);
+  s1760 = table7[s1759];
+  s1761 = sbv_bv_extract_u32_15_8_u8(s654);
+  s1762 = table8[s1761];
+  s1763 = sbv_bv_extract_u32_7_0_u8(s654);
+  s1764 = table9[s1763];
+  s1765 = s1762 ^ s1764;
+  s1766 = s1760 ^ s1765;
+  s1767 = s1758 ^ s1766;
+  s1768 = table9[s1757];
+  s1769 = table6[s1759];
+  s1770 = table7[s1761];
+  s1771 = table8[s1763];
+  s1772 = s1770 ^ s1771;
+  s1773 = s1769 ^ s1772;
+  s1774 = s1768 ^ s1773;
+  s1775 = sbv_bv_join_u8_u8_u16(s1767, s1774);
+  s1776 = table8[s1757];
+  s1777 = table9[s1759];
+  s1778 = table6[s1761];
+  s1779 = table7[s1763];
+  s1780 = s1778 ^ s1779;
+  s1781 = s1777 ^ s1780;
+  s1782 = s1776 ^ s1781;
+  s1783 = table7[s1757];
+  s1784 = table8[s1759];
+  s1785 = table9[s1761];
+  s1786 = table6[s1763];
+  s1787 = s1785 ^ s1786;
+  s1788 = s1784 ^ s1787;
+  s1789 = s1783 ^ s1788;
+  s1790 = sbv_bv_join_u8_u8_u16(s1782, s1789);
+  s1791 = sbv_bv_join_u16_u16_u32(s1775, s1790);
+  s1792 = s1756 ^ s1791;
+  s1793 = sbv_bv_extract_u32_15_8_u8(s1792);
+  s1794 = table4[s1793];
+  s1795 = s1745 ^ s1794;
+  s1796 = sbv_bv_extract_u32_31_24_u8(s1654);
+  s1797 = table1[s1796];
+  s1798 = sbv_bv_extract_u32_23_16_u8(s1505);
+  s1799 = table3[s1798];
+  s1800 = s1797 ^ s1799;
+  s1801 = sbv_bv_extract_u32_15_8_u8(s1554);
+  s1802 = table4[s1801];
+  s1803 = s1800 ^ s1802;
+  s1804 = sbv_bv_extract_u32_7_0_u8(s1604);
+  s1805 = table5[s1804];
+  s1806 = s1803 ^ s1805;
+  s1807 = sbv_bv_extract_u32_31_24_u8(s653);
+  s1808 = table6[s1807];
+  s1809 = sbv_bv_extract_u32_23_16_u8(s653);
+  s1810 = table7[s1809];
+  s1811 = sbv_bv_extract_u32_15_8_u8(s653);
+  s1812 = table8[s1811];
+  s1813 = sbv_bv_extract_u32_7_0_u8(s653);
+  s1814 = table9[s1813];
+  s1815 = s1812 ^ s1814;
+  s1816 = s1810 ^ s1815;
+  s1817 = s1808 ^ s1816;
+  s1818 = table9[s1807];
+  s1819 = table6[s1809];
+  s1820 = table7[s1811];
+  s1821 = table8[s1813];
+  s1822 = s1820 ^ s1821;
+  s1823 = s1819 ^ s1822;
+  s1824 = s1818 ^ s1823;
+  s1825 = sbv_bv_join_u8_u8_u16(s1817, s1824);
+  s1826 = table8[s1807];
+  s1827 = table9[s1809];
+  s1828 = table6[s1811];
+  s1829 = table7[s1813];
+  s1830 = s1828 ^ s1829;
+  s1831 = s1827 ^ s1830;
+  s1832 = s1826 ^ s1831;
+  s1833 = table7[s1807];
+  s1834 = table8[s1809];
+  s1835 = table9[s1811];
+  s1836 = table6[s1813];
+  s1837 = s1835 ^ s1836;
+  s1838 = s1834 ^ s1837;
+  s1839 = s1833 ^ s1838;
+  s1840 = sbv_bv_join_u8_u8_u16(s1832, s1839);
+  s1841 = sbv_bv_join_u16_u16_u32(s1825, s1840);
+  s1842 = s1806 ^ s1841;
+  s1843 = sbv_bv_extract_u32_7_0_u8(s1842);
+  s1844 = table5[s1843];
+  s1845 = s1795 ^ s1844;
+  s1846 = sbv_bv_extract_u32_31_24_u8(s635);
+  s1847 = table6[s1846];
+  s1848 = sbv_bv_extract_u32_23_16_u8(s635);
+  s1849 = table7[s1848];
+  s1850 = sbv_bv_extract_u32_15_8_u8(s635);
+  s1851 = table8[s1850];
+  s1852 = sbv_bv_extract_u32_7_0_u8(s635);
+  s1853 = table9[s1852];
+  s1854 = s1851 ^ s1853;
+  s1855 = s1849 ^ s1854;
+  s1856 = s1847 ^ s1855;
+  s1857 = table9[s1846];
+  s1858 = table6[s1848];
+  s1859 = table7[s1850];
+  s1860 = table8[s1852];
+  s1861 = s1859 ^ s1860;
+  s1862 = s1858 ^ s1861;
+  s1863 = s1857 ^ s1862;
+  s1864 = sbv_bv_join_u8_u8_u16(s1856, s1863);
+  s1865 = table8[s1846];
+  s1866 = table9[s1848];
+  s1867 = table6[s1850];
+  s1868 = table7[s1852];
+  s1869 = s1867 ^ s1868;
+  s1870 = s1866 ^ s1869;
+  s1871 = s1865 ^ s1870;
+  s1872 = table7[s1846];
+  s1873 = table8[s1848];
+  s1874 = table9[s1850];
+  s1875 = table6[s1852];
+  s1876 = s1874 ^ s1875;
+  s1877 = s1873 ^ s1876;
+  s1878 = s1872 ^ s1877;
+  s1879 = sbv_bv_join_u8_u8_u16(s1871, s1878);
+  s1880 = sbv_bv_join_u16_u16_u32(s1864, s1879);
+  s1881 = s1845 ^ s1880;
+  s1882 = sbv_bv_extract_u32_31_24_u8(s1881);
+  s1883 = table1[s1882];
+  s1884 = sbv_bv_extract_u32_31_24_u8(s1742);
+  s1885 = table1[s1884];
+  s1886 = sbv_bv_extract_u32_23_16_u8(s1792);
+  s1887 = table3[s1886];
+  s1888 = s1885 ^ s1887;
+  s1889 = sbv_bv_extract_u32_15_8_u8(s1842);
+  s1890 = table4[s1889];
+  s1891 = s1888 ^ s1890;
+  s1892 = sbv_bv_extract_u32_7_0_u8(s1693);
+  s1893 = table5[s1892];
+  s1894 = s1891 ^ s1893;
+  s1895 = sbv_bv_extract_u32_31_24_u8(s638);
+  s1896 = table6[s1895];
+  s1897 = sbv_bv_extract_u32_23_16_u8(s638);
+  s1898 = table7[s1897];
+  s1899 = sbv_bv_extract_u32_15_8_u8(s638);
+  s1900 = table8[s1899];
+  s1901 = sbv_bv_extract_u32_7_0_u8(s638);
+  s1902 = table9[s1901];
+  s1903 = s1900 ^ s1902;
+  s1904 = s1898 ^ s1903;
+  s1905 = s1896 ^ s1904;
+  s1906 = table9[s1895];
+  s1907 = table6[s1897];
+  s1908 = table7[s1899];
+  s1909 = table8[s1901];
+  s1910 = s1908 ^ s1909;
+  s1911 = s1907 ^ s1910;
+  s1912 = s1906 ^ s1911;
+  s1913 = sbv_bv_join_u8_u8_u16(s1905, s1912);
+  s1914 = table8[s1895];
+  s1915 = table9[s1897];
+  s1916 = table6[s1899];
+  s1917 = table7[s1901];
+  s1918 = s1916 ^ s1917;
+  s1919 = s1915 ^ s1918;
+  s1920 = s1914 ^ s1919;
+  s1921 = table7[s1895];
+  s1922 = table8[s1897];
+  s1923 = table9[s1899];
+  s1924 = table6[s1901];
+  s1925 = s1923 ^ s1924;
+  s1926 = s1922 ^ s1925;
+  s1927 = s1921 ^ s1926;
+  s1928 = sbv_bv_join_u8_u8_u16(s1920, s1927);
+  s1929 = sbv_bv_join_u16_u16_u32(s1913, s1928);
+  s1930 = s1894 ^ s1929;
+  s1931 = sbv_bv_extract_u32_23_16_u8(s1930);
+  s1932 = table3[s1931];
+  s1933 = s1883 ^ s1932;
+  s1934 = sbv_bv_extract_u32_31_24_u8(s1792);
+  s1935 = table1[s1934];
+  s1936 = sbv_bv_extract_u32_23_16_u8(s1842);
+  s1937 = table3[s1936];
+  s1938 = s1935 ^ s1937;
+  s1939 = sbv_bv_extract_u32_15_8_u8(s1693);
+  s1940 = table4[s1939];
+  s1941 = s1938 ^ s1940;
+  s1942 = sbv_bv_extract_u32_7_0_u8(s1742);
+  s1943 = table5[s1942];
+  s1944 = s1941 ^ s1943;
+  s1945 = sbv_bv_extract_u32_31_24_u8(s637);
+  s1946 = table6[s1945];
+  s1947 = sbv_bv_extract_u32_23_16_u8(s637);
+  s1948 = table7[s1947];
+  s1949 = sbv_bv_extract_u32_15_8_u8(s637);
+  s1950 = table8[s1949];
+  s1951 = sbv_bv_extract_u32_7_0_u8(s637);
+  s1952 = table9[s1951];
+  s1953 = s1950 ^ s1952;
+  s1954 = s1948 ^ s1953;
+  s1955 = s1946 ^ s1954;
+  s1956 = table9[s1945];
+  s1957 = table6[s1947];
+  s1958 = table7[s1949];
+  s1959 = table8[s1951];
+  s1960 = s1958 ^ s1959;
+  s1961 = s1957 ^ s1960;
+  s1962 = s1956 ^ s1961;
+  s1963 = sbv_bv_join_u8_u8_u16(s1955, s1962);
+  s1964 = table8[s1945];
+  s1965 = table9[s1947];
+  s1966 = table6[s1949];
+  s1967 = table7[s1951];
+  s1968 = s1966 ^ s1967;
+  s1969 = s1965 ^ s1968;
+  s1970 = s1964 ^ s1969;
+  s1971 = table7[s1945];
+  s1972 = table8[s1947];
+  s1973 = table9[s1949];
+  s1974 = table6[s1951];
+  s1975 = s1973 ^ s1974;
+  s1976 = s1972 ^ s1975;
+  s1977 = s1971 ^ s1976;
+  s1978 = sbv_bv_join_u8_u8_u16(s1970, s1977);
+  s1979 = sbv_bv_join_u16_u16_u32(s1963, s1978);
+  s1980 = s1944 ^ s1979;
+  s1981 = sbv_bv_extract_u32_15_8_u8(s1980);
+  s1982 = table4[s1981];
+  s1983 = s1933 ^ s1982;
+  s1984 = sbv_bv_extract_u32_31_24_u8(s1842);
+  s1985 = table1[s1984];
+  s1986 = sbv_bv_extract_u32_23_16_u8(s1693);
+  s1987 = table3[s1986];
+  s1988 = s1985 ^ s1987;
+  s1989 = sbv_bv_extract_u32_15_8_u8(s1742);
+  s1990 = table4[s1989];
+  s1991 = s1988 ^ s1990;
+  s1992 = sbv_bv_extract_u32_7_0_u8(s1792);
+  s1993 = table5[s1992];
+  s1994 = s1991 ^ s1993;
+  s1995 = sbv_bv_extract_u32_31_24_u8(s636);
+  s1996 = table6[s1995];
+  s1997 = sbv_bv_extract_u32_23_16_u8(s636);
+  s1998 = table7[s1997];
+  s1999 = sbv_bv_extract_u32_15_8_u8(s636);
+  s2000 = table8[s1999];
+  s2001 = sbv_bv_extract_u32_7_0_u8(s636);
+  s2002 = table9[s2001];
+  s2003 = s2000 ^ s2002;
+  s2004 = s1998 ^ s2003;
+  s2005 = s1996 ^ s2004;
+  s2006 = table9[s1995];
+  s2007 = table6[s1997];
+  s2008 = table7[s1999];
+  s2009 = table8[s2001];
+  s2010 = s2008 ^ s2009;
+  s2011 = s2007 ^ s2010;
+  s2012 = s2006 ^ s2011;
+  s2013 = sbv_bv_join_u8_u8_u16(s2005, s2012);
+  s2014 = table8[s1995];
+  s2015 = table9[s1997];
+  s2016 = table6[s1999];
+  s2017 = table7[s2001];
+  s2018 = s2016 ^ s2017;
+  s2019 = s2015 ^ s2018;
+  s2020 = s2014 ^ s2019;
+  s2021 = table7[s1995];
+  s2022 = table8[s1997];
+  s2023 = table9[s1999];
+  s2024 = table6[s2001];
+  s2025 = s2023 ^ s2024;
+  s2026 = s2022 ^ s2025;
+  s2027 = s2021 ^ s2026;
+  s2028 = sbv_bv_join_u8_u8_u16(s2020, s2027);
+  s2029 = sbv_bv_join_u16_u16_u32(s2013, s2028);
+  s2030 = s1994 ^ s2029;
+  s2031 = sbv_bv_extract_u32_7_0_u8(s2030);
+  s2032 = table5[s2031];
+  s2033 = s1983 ^ s2032;
+  s2034 = sbv_bv_extract_u32_31_24_u8(s618);
+  s2035 = table6[s2034];
+  s2036 = sbv_bv_extract_u32_23_16_u8(s618);
+  s2037 = table7[s2036];
+  s2038 = sbv_bv_extract_u32_15_8_u8(s618);
+  s2039 = table8[s2038];
+  s2040 = sbv_bv_extract_u32_7_0_u8(s618);
+  s2041 = table9[s2040];
+  s2042 = s2039 ^ s2041;
+  s2043 = s2037 ^ s2042;
+  s2044 = s2035 ^ s2043;
+  s2045 = table9[s2034];
+  s2046 = table6[s2036];
+  s2047 = table7[s2038];
+  s2048 = table8[s2040];
+  s2049 = s2047 ^ s2048;
+  s2050 = s2046 ^ s2049;
+  s2051 = s2045 ^ s2050;
+  s2052 = sbv_bv_join_u8_u8_u16(s2044, s2051);
+  s2053 = table8[s2034];
+  s2054 = table9[s2036];
+  s2055 = table6[s2038];
+  s2056 = table7[s2040];
+  s2057 = s2055 ^ s2056;
+  s2058 = s2054 ^ s2057;
+  s2059 = s2053 ^ s2058;
+  s2060 = table7[s2034];
+  s2061 = table8[s2036];
+  s2062 = table9[s2038];
+  s2063 = table6[s2040];
+  s2064 = s2062 ^ s2063;
+  s2065 = s2061 ^ s2064;
+  s2066 = s2060 ^ s2065;
+  s2067 = sbv_bv_join_u8_u8_u16(s2059, s2066);
+  s2068 = sbv_bv_join_u16_u16_u32(s2052, s2067);
+  s2069 = s2033 ^ s2068;
+  s2070 = sbv_bv_extract_u32_31_24_u8(s2069);
+  s2071 = table1[s2070];
+  s2072 = sbv_bv_extract_u32_31_24_u8(s1930);
+  s2073 = table1[s2072];
+  s2074 = sbv_bv_extract_u32_23_16_u8(s1980);
+  s2075 = table3[s2074];
+  s2076 = s2073 ^ s2075;
+  s2077 = sbv_bv_extract_u32_15_8_u8(s2030);
+  s2078 = table4[s2077];
+  s2079 = s2076 ^ s2078;
+  s2080 = sbv_bv_extract_u32_7_0_u8(s1881);
+  s2081 = table5[s2080];
+  s2082 = s2079 ^ s2081;
+  s2083 = sbv_bv_extract_u32_31_24_u8(s621);
+  s2084 = table6[s2083];
+  s2085 = sbv_bv_extract_u32_23_16_u8(s621);
+  s2086 = table7[s2085];
+  s2087 = sbv_bv_extract_u32_15_8_u8(s621);
+  s2088 = table8[s2087];
+  s2089 = sbv_bv_extract_u32_7_0_u8(s621);
+  s2090 = table9[s2089];
+  s2091 = s2088 ^ s2090;
+  s2092 = s2086 ^ s2091;
+  s2093 = s2084 ^ s2092;
+  s2094 = table9[s2083];
+  s2095 = table6[s2085];
+  s2096 = table7[s2087];
+  s2097 = table8[s2089];
+  s2098 = s2096 ^ s2097;
+  s2099 = s2095 ^ s2098;
+  s2100 = s2094 ^ s2099;
+  s2101 = sbv_bv_join_u8_u8_u16(s2093, s2100);
+  s2102 = table8[s2083];
+  s2103 = table9[s2085];
+  s2104 = table6[s2087];
+  s2105 = table7[s2089];
+  s2106 = s2104 ^ s2105;
+  s2107 = s2103 ^ s2106;
+  s2108 = s2102 ^ s2107;
+  s2109 = table7[s2083];
+  s2110 = table8[s2085];
+  s2111 = table9[s2087];
+  s2112 = table6[s2089];
+  s2113 = s2111 ^ s2112;
+  s2114 = s2110 ^ s2113;
+  s2115 = s2109 ^ s2114;
+  s2116 = sbv_bv_join_u8_u8_u16(s2108, s2115);
+  s2117 = sbv_bv_join_u16_u16_u32(s2101, s2116);
+  s2118 = s2082 ^ s2117;
+  s2119 = sbv_bv_extract_u32_23_16_u8(s2118);
+  s2120 = table3[s2119];
+  s2121 = s2071 ^ s2120;
+  s2122 = sbv_bv_extract_u32_31_24_u8(s1980);
+  s2123 = table1[s2122];
+  s2124 = sbv_bv_extract_u32_23_16_u8(s2030);
+  s2125 = table3[s2124];
+  s2126 = s2123 ^ s2125;
+  s2127 = sbv_bv_extract_u32_15_8_u8(s1881);
+  s2128 = table4[s2127];
+  s2129 = s2126 ^ s2128;
+  s2130 = sbv_bv_extract_u32_7_0_u8(s1930);
+  s2131 = table5[s2130];
+  s2132 = s2129 ^ s2131;
+  s2133 = sbv_bv_extract_u32_31_24_u8(s620);
+  s2134 = table6[s2133];
+  s2135 = sbv_bv_extract_u32_23_16_u8(s620);
+  s2136 = table7[s2135];
+  s2137 = sbv_bv_extract_u32_15_8_u8(s620);
+  s2138 = table8[s2137];
+  s2139 = sbv_bv_extract_u32_7_0_u8(s620);
+  s2140 = table9[s2139];
+  s2141 = s2138 ^ s2140;
+  s2142 = s2136 ^ s2141;
+  s2143 = s2134 ^ s2142;
+  s2144 = table9[s2133];
+  s2145 = table6[s2135];
+  s2146 = table7[s2137];
+  s2147 = table8[s2139];
+  s2148 = s2146 ^ s2147;
+  s2149 = s2145 ^ s2148;
+  s2150 = s2144 ^ s2149;
+  s2151 = sbv_bv_join_u8_u8_u16(s2143, s2150);
+  s2152 = table8[s2133];
+  s2153 = table9[s2135];
+  s2154 = table6[s2137];
+  s2155 = table7[s2139];
+  s2156 = s2154 ^ s2155;
+  s2157 = s2153 ^ s2156;
+  s2158 = s2152 ^ s2157;
+  s2159 = table7[s2133];
+  s2160 = table8[s2135];
+  s2161 = table9[s2137];
+  s2162 = table6[s2139];
+  s2163 = s2161 ^ s2162;
+  s2164 = s2160 ^ s2163;
+  s2165 = s2159 ^ s2164;
+  s2166 = sbv_bv_join_u8_u8_u16(s2158, s2165);
+  s2167 = sbv_bv_join_u16_u16_u32(s2151, s2166);
+  s2168 = s2132 ^ s2167;
+  s2169 = sbv_bv_extract_u32_15_8_u8(s2168);
+  s2170 = table4[s2169];
+  s2171 = s2121 ^ s2170;
+  s2172 = sbv_bv_extract_u32_31_24_u8(s2030);
+  s2173 = table1[s2172];
+  s2174 = sbv_bv_extract_u32_23_16_u8(s1881);
+  s2175 = table3[s2174];
+  s2176 = s2173 ^ s2175;
+  s2177 = sbv_bv_extract_u32_15_8_u8(s1930);
+  s2178 = table4[s2177];
+  s2179 = s2176 ^ s2178;
+  s2180 = sbv_bv_extract_u32_7_0_u8(s1980);
+  s2181 = table5[s2180];
+  s2182 = s2179 ^ s2181;
+  s2183 = sbv_bv_extract_u32_31_24_u8(s619);
+  s2184 = table6[s2183];
+  s2185 = sbv_bv_extract_u32_23_16_u8(s619);
+  s2186 = table7[s2185];
+  s2187 = sbv_bv_extract_u32_15_8_u8(s619);
+  s2188 = table8[s2187];
+  s2189 = sbv_bv_extract_u32_7_0_u8(s619);
+  s2190 = table9[s2189];
+  s2191 = s2188 ^ s2190;
+  s2192 = s2186 ^ s2191;
+  s2193 = s2184 ^ s2192;
+  s2194 = table9[s2183];
+  s2195 = table6[s2185];
+  s2196 = table7[s2187];
+  s2197 = table8[s2189];
+  s2198 = s2196 ^ s2197;
+  s2199 = s2195 ^ s2198;
+  s2200 = s2194 ^ s2199;
+  s2201 = sbv_bv_join_u8_u8_u16(s2193, s2200);
+  s2202 = table8[s2183];
+  s2203 = table9[s2185];
+  s2204 = table6[s2187];
+  s2205 = table7[s2189];
+  s2206 = s2204 ^ s2205;
+  s2207 = s2203 ^ s2206;
+  s2208 = s2202 ^ s2207;
+  s2209 = table7[s2183];
+  s2210 = table8[s2185];
+  s2211 = table9[s2187];
+  s2212 = table6[s2189];
+  s2213 = s2211 ^ s2212;
+  s2214 = s2210 ^ s2213;
+  s2215 = s2209 ^ s2214;
+  s2216 = sbv_bv_join_u8_u8_u16(s2208, s2215);
+  s2217 = sbv_bv_join_u16_u16_u32(s2201, s2216);
+  s2218 = s2182 ^ s2217;
+  s2219 = sbv_bv_extract_u32_7_0_u8(s2218);
+  s2220 = table5[s2219];
+  s2221 = s2171 ^ s2220;
+  s2222 = sbv_bv_extract_u32_31_24_u8(s601);
+  s2223 = table6[s2222];
+  s2224 = sbv_bv_extract_u32_23_16_u8(s601);
+  s2225 = table7[s2224];
+  s2226 = sbv_bv_extract_u32_15_8_u8(s601);
+  s2227 = table8[s2226];
+  s2228 = sbv_bv_extract_u32_7_0_u8(s601);
+  s2229 = table9[s2228];
+  s2230 = s2227 ^ s2229;
+  s2231 = s2225 ^ s2230;
+  s2232 = s2223 ^ s2231;
+  s2233 = table9[s2222];
+  s2234 = table6[s2224];
+  s2235 = table7[s2226];
+  s2236 = table8[s2228];
+  s2237 = s2235 ^ s2236;
+  s2238 = s2234 ^ s2237;
+  s2239 = s2233 ^ s2238;
+  s2240 = sbv_bv_join_u8_u8_u16(s2232, s2239);
+  s2241 = table8[s2222];
+  s2242 = table9[s2224];
+  s2243 = table6[s2226];
+  s2244 = table7[s2228];
+  s2245 = s2243 ^ s2244;
+  s2246 = s2242 ^ s2245;
+  s2247 = s2241 ^ s2246;
+  s2248 = table7[s2222];
+  s2249 = table8[s2224];
+  s2250 = table9[s2226];
+  s2251 = table6[s2228];
+  s2252 = s2250 ^ s2251;
+  s2253 = s2249 ^ s2252;
+  s2254 = s2248 ^ s2253;
+  s2255 = sbv_bv_join_u8_u8_u16(s2247, s2254);
+  s2256 = sbv_bv_join_u16_u16_u32(s2240, s2255);
+  s2257 = s2221 ^ s2256;
+  s2258 = sbv_bv_extract_u32_31_24_u8(s2257);
+  s2259 = table1[s2258];
+  s2260 = sbv_bv_extract_u32_31_24_u8(s2118);
+  s2261 = table1[s2260];
+  s2262 = sbv_bv_extract_u32_23_16_u8(s2168);
+  s2263 = table3[s2262];
+  s2264 = s2261 ^ s2263;
+  s2265 = sbv_bv_extract_u32_15_8_u8(s2218);
+  s2266 = table4[s2265];
+  s2267 = s2264 ^ s2266;
+  s2268 = sbv_bv_extract_u32_7_0_u8(s2069);
+  s2269 = table5[s2268];
+  s2270 = s2267 ^ s2269;
+  s2271 = sbv_bv_extract_u32_31_24_u8(s604);
+  s2272 = table6[s2271];
+  s2273 = sbv_bv_extract_u32_23_16_u8(s604);
+  s2274 = table7[s2273];
+  s2275 = sbv_bv_extract_u32_15_8_u8(s604);
+  s2276 = table8[s2275];
+  s2277 = sbv_bv_extract_u32_7_0_u8(s604);
+  s2278 = table9[s2277];
+  s2279 = s2276 ^ s2278;
+  s2280 = s2274 ^ s2279;
+  s2281 = s2272 ^ s2280;
+  s2282 = table9[s2271];
+  s2283 = table6[s2273];
+  s2284 = table7[s2275];
+  s2285 = table8[s2277];
+  s2286 = s2284 ^ s2285;
+  s2287 = s2283 ^ s2286;
+  s2288 = s2282 ^ s2287;
+  s2289 = sbv_bv_join_u8_u8_u16(s2281, s2288);
+  s2290 = table8[s2271];
+  s2291 = table9[s2273];
+  s2292 = table6[s2275];
+  s2293 = table7[s2277];
+  s2294 = s2292 ^ s2293;
+  s2295 = s2291 ^ s2294;
+  s2296 = s2290 ^ s2295;
+  s2297 = table7[s2271];
+  s2298 = table8[s2273];
+  s2299 = table9[s2275];
+  s2300 = table6[s2277];
+  s2301 = s2299 ^ s2300;
+  s2302 = s2298 ^ s2301;
+  s2303 = s2297 ^ s2302;
+  s2304 = sbv_bv_join_u8_u8_u16(s2296, s2303);
+  s2305 = sbv_bv_join_u16_u16_u32(s2289, s2304);
+  s2306 = s2270 ^ s2305;
+  s2307 = sbv_bv_extract_u32_23_16_u8(s2306);
+  s2308 = table3[s2307];
+  s2309 = s2259 ^ s2308;
+  s2310 = sbv_bv_extract_u32_31_24_u8(s2168);
+  s2311 = table1[s2310];
+  s2312 = sbv_bv_extract_u32_23_16_u8(s2218);
+  s2313 = table3[s2312];
+  s2314 = s2311 ^ s2313;
+  s2315 = sbv_bv_extract_u32_15_8_u8(s2069);
+  s2316 = table4[s2315];
+  s2317 = s2314 ^ s2316;
+  s2318 = sbv_bv_extract_u32_7_0_u8(s2118);
+  s2319 = table5[s2318];
+  s2320 = s2317 ^ s2319;
+  s2321 = sbv_bv_extract_u32_31_24_u8(s603);
+  s2322 = table6[s2321];
+  s2323 = sbv_bv_extract_u32_23_16_u8(s603);
+  s2324 = table7[s2323];
+  s2325 = sbv_bv_extract_u32_15_8_u8(s603);
+  s2326 = table8[s2325];
+  s2327 = sbv_bv_extract_u32_7_0_u8(s603);
+  s2328 = table9[s2327];
+  s2329 = s2326 ^ s2328;
+  s2330 = s2324 ^ s2329;
+  s2331 = s2322 ^ s2330;
+  s2332 = table9[s2321];
+  s2333 = table6[s2323];
+  s2334 = table7[s2325];
+  s2335 = table8[s2327];
+  s2336 = s2334 ^ s2335;
+  s2337 = s2333 ^ s2336;
+  s2338 = s2332 ^ s2337;
+  s2339 = sbv_bv_join_u8_u8_u16(s2331, s2338);
+  s2340 = table8[s2321];
+  s2341 = table9[s2323];
+  s2342 = table6[s2325];
+  s2343 = table7[s2327];
+  s2344 = s2342 ^ s2343;
+  s2345 = s2341 ^ s2344;
+  s2346 = s2340 ^ s2345;
+  s2347 = table7[s2321];
+  s2348 = table8[s2323];
+  s2349 = table9[s2325];
+  s2350 = table6[s2327];
+  s2351 = s2349 ^ s2350;
+  s2352 = s2348 ^ s2351;
+  s2353 = s2347 ^ s2352;
+  s2354 = sbv_bv_join_u8_u8_u16(s2346, s2353);
+  s2355 = sbv_bv_join_u16_u16_u32(s2339, s2354);
+  s2356 = s2320 ^ s2355;
+  s2357 = sbv_bv_extract_u32_15_8_u8(s2356);
+  s2358 = table4[s2357];
+  s2359 = s2309 ^ s2358;
+  s2360 = sbv_bv_extract_u32_31_24_u8(s2218);
+  s2361 = table1[s2360];
+  s2362 = sbv_bv_extract_u32_23_16_u8(s2069);
+  s2363 = table3[s2362];
+  s2364 = s2361 ^ s2363;
+  s2365 = sbv_bv_extract_u32_15_8_u8(s2118);
+  s2366 = table4[s2365];
+  s2367 = s2364 ^ s2366;
+  s2368 = sbv_bv_extract_u32_7_0_u8(s2168);
+  s2369 = table5[s2368];
+  s2370 = s2367 ^ s2369;
+  s2371 = sbv_bv_extract_u32_31_24_u8(s602);
+  s2372 = table6[s2371];
+  s2373 = sbv_bv_extract_u32_23_16_u8(s602);
+  s2374 = table7[s2373];
+  s2375 = sbv_bv_extract_u32_15_8_u8(s602);
+  s2376 = table8[s2375];
+  s2377 = sbv_bv_extract_u32_7_0_u8(s602);
+  s2378 = table9[s2377];
+  s2379 = s2376 ^ s2378;
+  s2380 = s2374 ^ s2379;
+  s2381 = s2372 ^ s2380;
+  s2382 = table9[s2371];
+  s2383 = table6[s2373];
+  s2384 = table7[s2375];
+  s2385 = table8[s2377];
+  s2386 = s2384 ^ s2385;
+  s2387 = s2383 ^ s2386;
+  s2388 = s2382 ^ s2387;
+  s2389 = sbv_bv_join_u8_u8_u16(s2381, s2388);
+  s2390 = table8[s2371];
+  s2391 = table9[s2373];
+  s2392 = table6[s2375];
+  s2393 = table7[s2377];
+  s2394 = s2392 ^ s2393;
+  s2395 = s2391 ^ s2394;
+  s2396 = s2390 ^ s2395;
+  s2397 = table7[s2371];
+  s2398 = table8[s2373];
+  s2399 = table9[s2375];
+  s2400 = table6[s2377];
+  s2401 = s2399 ^ s2400;
+  s2402 = s2398 ^ s2401;
+  s2403 = s2397 ^ s2402;
+  s2404 = sbv_bv_join_u8_u8_u16(s2396, s2403);
+  s2405 = sbv_bv_join_u16_u16_u32(s2389, s2404);
+  s2406 = s2370 ^ s2405;
+  s2407 = sbv_bv_extract_u32_7_0_u8(s2406);
+  s2408 = table5[s2407];
+  s2409 = s2359 ^ s2408;
+  s2410 = sbv_bv_extract_u32_31_24_u8(s584);
+  s2411 = table6[s2410];
+  s2412 = sbv_bv_extract_u32_23_16_u8(s584);
+  s2413 = table7[s2412];
+  s2414 = sbv_bv_extract_u32_15_8_u8(s584);
+  s2415 = table8[s2414];
+  s2416 = sbv_bv_extract_u32_7_0_u8(s584);
+  s2417 = table9[s2416];
+  s2418 = s2415 ^ s2417;
+  s2419 = s2413 ^ s2418;
+  s2420 = s2411 ^ s2419;
+  s2421 = table9[s2410];
+  s2422 = table6[s2412];
+  s2423 = table7[s2414];
+  s2424 = table8[s2416];
+  s2425 = s2423 ^ s2424;
+  s2426 = s2422 ^ s2425;
+  s2427 = s2421 ^ s2426;
+  s2428 = sbv_bv_join_u8_u8_u16(s2420, s2427);
+  s2429 = table8[s2410];
+  s2430 = table9[s2412];
+  s2431 = table6[s2414];
+  s2432 = table7[s2416];
+  s2433 = s2431 ^ s2432;
+  s2434 = s2430 ^ s2433;
+  s2435 = s2429 ^ s2434;
+  s2436 = table7[s2410];
+  s2437 = table8[s2412];
+  s2438 = table9[s2414];
+  s2439 = table6[s2416];
+  s2440 = s2438 ^ s2439;
+  s2441 = s2437 ^ s2440;
+  s2442 = s2436 ^ s2441;
+  s2443 = sbv_bv_join_u8_u8_u16(s2435, s2442);
+  s2444 = sbv_bv_join_u16_u16_u32(s2428, s2443);
+  s2445 = s2409 ^ s2444;
+  s2446 = sbv_bv_extract_u32_31_24_u8(s2445);
+  s2447 = table1[s2446];
+  s2448 = sbv_bv_extract_u32_31_24_u8(s2306);
+  s2449 = table1[s2448];
+  s2450 = sbv_bv_extract_u32_23_16_u8(s2356);
+  s2451 = table3[s2450];
+  s2452 = s2449 ^ s2451;
+  s2453 = sbv_bv_extract_u32_15_8_u8(s2406);
+  s2454 = table4[s2453];
+  s2455 = s2452 ^ s2454;
+  s2456 = sbv_bv_extract_u32_7_0_u8(s2257);
+  s2457 = table5[s2456];
+  s2458 = s2455 ^ s2457;
+  s2459 = sbv_bv_extract_u32_31_24_u8(s587);
+  s2460 = table6[s2459];
+  s2461 = sbv_bv_extract_u32_23_16_u8(s587);
+  s2462 = table7[s2461];
+  s2463 = sbv_bv_extract_u32_15_8_u8(s587);
+  s2464 = table8[s2463];
+  s2465 = sbv_bv_extract_u32_7_0_u8(s587);
+  s2466 = table9[s2465];
+  s2467 = s2464 ^ s2466;
+  s2468 = s2462 ^ s2467;
+  s2469 = s2460 ^ s2468;
+  s2470 = table9[s2459];
+  s2471 = table6[s2461];
+  s2472 = table7[s2463];
+  s2473 = table8[s2465];
+  s2474 = s2472 ^ s2473;
+  s2475 = s2471 ^ s2474;
+  s2476 = s2470 ^ s2475;
+  s2477 = sbv_bv_join_u8_u8_u16(s2469, s2476);
+  s2478 = table8[s2459];
+  s2479 = table9[s2461];
+  s2480 = table6[s2463];
+  s2481 = table7[s2465];
+  s2482 = s2480 ^ s2481;
+  s2483 = s2479 ^ s2482;
+  s2484 = s2478 ^ s2483;
+  s2485 = table7[s2459];
+  s2486 = table8[s2461];
+  s2487 = table9[s2463];
+  s2488 = table6[s2465];
+  s2489 = s2487 ^ s2488;
+  s2490 = s2486 ^ s2489;
+  s2491 = s2485 ^ s2490;
+  s2492 = sbv_bv_join_u8_u8_u16(s2484, s2491);
+  s2493 = sbv_bv_join_u16_u16_u32(s2477, s2492);
+  s2494 = s2458 ^ s2493;
+  s2495 = sbv_bv_extract_u32_23_16_u8(s2494);
+  s2496 = table3[s2495];
+  s2497 = s2447 ^ s2496;
+  s2498 = sbv_bv_extract_u32_31_24_u8(s2356);
+  s2499 = table1[s2498];
+  s2500 = sbv_bv_extract_u32_23_16_u8(s2406);
+  s2501 = table3[s2500];
+  s2502 = s2499 ^ s2501;
+  s2503 = sbv_bv_extract_u32_15_8_u8(s2257);
+  s2504 = table4[s2503];
+  s2505 = s2502 ^ s2504;
+  s2506 = sbv_bv_extract_u32_7_0_u8(s2306);
+  s2507 = table5[s2506];
+  s2508 = s2505 ^ s2507;
+  s2509 = sbv_bv_extract_u32_31_24_u8(s586);
+  s2510 = table6[s2509];
+  s2511 = sbv_bv_extract_u32_23_16_u8(s586);
+  s2512 = table7[s2511];
+  s2513 = sbv_bv_extract_u32_15_8_u8(s586);
+  s2514 = table8[s2513];
+  s2515 = sbv_bv_extract_u32_7_0_u8(s586);
+  s2516 = table9[s2515];
+  s2517 = s2514 ^ s2516;
+  s2518 = s2512 ^ s2517;
+  s2519 = s2510 ^ s2518;
+  s2520 = table9[s2509];
+  s2521 = table6[s2511];
+  s2522 = table7[s2513];
+  s2523 = table8[s2515];
+  s2524 = s2522 ^ s2523;
+  s2525 = s2521 ^ s2524;
+  s2526 = s2520 ^ s2525;
+  s2527 = sbv_bv_join_u8_u8_u16(s2519, s2526);
+  s2528 = table8[s2509];
+  s2529 = table9[s2511];
+  s2530 = table6[s2513];
+  s2531 = table7[s2515];
+  s2532 = s2530 ^ s2531;
+  s2533 = s2529 ^ s2532;
+  s2534 = s2528 ^ s2533;
+  s2535 = table7[s2509];
+  s2536 = table8[s2511];
+  s2537 = table9[s2513];
+  s2538 = table6[s2515];
+  s2539 = s2537 ^ s2538;
+  s2540 = s2536 ^ s2539;
+  s2541 = s2535 ^ s2540;
+  s2542 = sbv_bv_join_u8_u8_u16(s2534, s2541);
+  s2543 = sbv_bv_join_u16_u16_u32(s2527, s2542);
+  s2544 = s2508 ^ s2543;
+  s2545 = sbv_bv_extract_u32_15_8_u8(s2544);
+  s2546 = table4[s2545];
+  s2547 = s2497 ^ s2546;
+  s2548 = sbv_bv_extract_u32_31_24_u8(s2406);
+  s2549 = table1[s2548];
+  s2550 = sbv_bv_extract_u32_23_16_u8(s2257);
+  s2551 = table3[s2550];
+  s2552 = s2549 ^ s2551;
+  s2553 = sbv_bv_extract_u32_15_8_u8(s2306);
+  s2554 = table4[s2553];
+  s2555 = s2552 ^ s2554;
+  s2556 = sbv_bv_extract_u32_7_0_u8(s2356);
+  s2557 = table5[s2556];
+  s2558 = s2555 ^ s2557;
+  s2559 = sbv_bv_extract_u32_31_24_u8(s585);
+  s2560 = table6[s2559];
+  s2561 = sbv_bv_extract_u32_23_16_u8(s585);
+  s2562 = table7[s2561];
+  s2563 = sbv_bv_extract_u32_15_8_u8(s585);
+  s2564 = table8[s2563];
+  s2565 = sbv_bv_extract_u32_7_0_u8(s585);
+  s2566 = table9[s2565];
+  s2567 = s2564 ^ s2566;
+  s2568 = s2562 ^ s2567;
+  s2569 = s2560 ^ s2568;
+  s2570 = table9[s2559];
+  s2571 = table6[s2561];
+  s2572 = table7[s2563];
+  s2573 = table8[s2565];
+  s2574 = s2572 ^ s2573;
+  s2575 = s2571 ^ s2574;
+  s2576 = s2570 ^ s2575;
+  s2577 = sbv_bv_join_u8_u8_u16(s2569, s2576);
+  s2578 = table8[s2559];
+  s2579 = table9[s2561];
+  s2580 = table6[s2563];
+  s2581 = table7[s2565];
+  s2582 = s2580 ^ s2581;
+  s2583 = s2579 ^ s2582;
+  s2584 = s2578 ^ s2583;
+  s2585 = table7[s2559];
+  s2586 = table8[s2561];
+  s2587 = table9[s2563];
+  s2588 = table6[s2565];
+  s2589 = s2587 ^ s2588;
+  s2590 = s2586 ^ s2589;
+  s2591 = s2585 ^ s2590;
+  s2592 = sbv_bv_join_u8_u8_u16(s2584, s2591);
+  s2593 = sbv_bv_join_u16_u16_u32(s2577, s2592);
+  s2594 = s2558 ^ s2593;
+  s2595 = sbv_bv_extract_u32_7_0_u8(s2594);
+  s2596 = table5[s2595];
+  s2597 = s2547 ^ s2596;
+  s2598 = sbv_bv_extract_u32_31_24_u8(s567);
+  s2599 = table6[s2598];
+  s2600 = sbv_bv_extract_u32_23_16_u8(s567);
+  s2601 = table7[s2600];
+  s2602 = sbv_bv_extract_u32_15_8_u8(s567);
+  s2603 = table8[s2602];
+  s2604 = sbv_bv_extract_u32_7_0_u8(s567);
+  s2605 = table9[s2604];
+  s2606 = s2603 ^ s2605;
+  s2607 = s2601 ^ s2606;
+  s2608 = s2599 ^ s2607;
+  s2609 = table9[s2598];
+  s2610 = table6[s2600];
+  s2611 = table7[s2602];
+  s2612 = table8[s2604];
+  s2613 = s2611 ^ s2612;
+  s2614 = s2610 ^ s2613;
+  s2615 = s2609 ^ s2614;
+  s2616 = sbv_bv_join_u8_u8_u16(s2608, s2615);
+  s2617 = table8[s2598];
+  s2618 = table9[s2600];
+  s2619 = table6[s2602];
+  s2620 = table7[s2604];
+  s2621 = s2619 ^ s2620;
+  s2622 = s2618 ^ s2621;
+  s2623 = s2617 ^ s2622;
+  s2624 = table7[s2598];
+  s2625 = table8[s2600];
+  s2626 = table9[s2602];
+  s2627 = table6[s2604];
+  s2628 = s2626 ^ s2627;
+  s2629 = s2625 ^ s2628;
+  s2630 = s2624 ^ s2629;
+  s2631 = sbv_bv_join_u8_u8_u16(s2623, s2630);
+  s2632 = sbv_bv_join_u16_u16_u32(s2616, s2631);
+  s2633 = s2597 ^ s2632;
+  s2634 = sbv_bv_extract_u32_31_24_u8(s2633);
+  s2635 = table1[s2634];
+  s2636 = sbv_bv_extract_u32_31_24_u8(s2494);
+  s2637 = table1[s2636];
+  s2638 = sbv_bv_extract_u32_23_16_u8(s2544);
+  s2639 = table3[s2638];
+  s2640 = s2637 ^ s2639;
+  s2641 = sbv_bv_extract_u32_15_8_u8(s2594);
+  s2642 = table4[s2641];
+  s2643 = s2640 ^ s2642;
+  s2644 = sbv_bv_extract_u32_7_0_u8(s2445);
+  s2645 = table5[s2644];
+  s2646 = s2643 ^ s2645;
+  s2647 = sbv_bv_extract_u32_31_24_u8(s570);
+  s2648 = table6[s2647];
+  s2649 = sbv_bv_extract_u32_23_16_u8(s570);
+  s2650 = table7[s2649];
+  s2651 = sbv_bv_extract_u32_15_8_u8(s570);
+  s2652 = table8[s2651];
+  s2653 = sbv_bv_extract_u32_7_0_u8(s570);
+  s2654 = table9[s2653];
+  s2655 = s2652 ^ s2654;
+  s2656 = s2650 ^ s2655;
+  s2657 = s2648 ^ s2656;
+  s2658 = table9[s2647];
+  s2659 = table6[s2649];
+  s2660 = table7[s2651];
+  s2661 = table8[s2653];
+  s2662 = s2660 ^ s2661;
+  s2663 = s2659 ^ s2662;
+  s2664 = s2658 ^ s2663;
+  s2665 = sbv_bv_join_u8_u8_u16(s2657, s2664);
+  s2666 = table8[s2647];
+  s2667 = table9[s2649];
+  s2668 = table6[s2651];
+  s2669 = table7[s2653];
+  s2670 = s2668 ^ s2669;
+  s2671 = s2667 ^ s2670;
+  s2672 = s2666 ^ s2671;
+  s2673 = table7[s2647];
+  s2674 = table8[s2649];
+  s2675 = table9[s2651];
+  s2676 = table6[s2653];
+  s2677 = s2675 ^ s2676;
+  s2678 = s2674 ^ s2677;
+  s2679 = s2673 ^ s2678;
+  s2680 = sbv_bv_join_u8_u8_u16(s2672, s2679);
+  s2681 = sbv_bv_join_u16_u16_u32(s2665, s2680);
+  s2682 = s2646 ^ s2681;
+  s2683 = sbv_bv_extract_u32_23_16_u8(s2682);
+  s2684 = table3[s2683];
+  s2685 = s2635 ^ s2684;
+  s2686 = sbv_bv_extract_u32_31_24_u8(s2544);
+  s2687 = table1[s2686];
+  s2688 = sbv_bv_extract_u32_23_16_u8(s2594);
+  s2689 = table3[s2688];
+  s2690 = s2687 ^ s2689;
+  s2691 = sbv_bv_extract_u32_15_8_u8(s2445);
+  s2692 = table4[s2691];
+  s2693 = s2690 ^ s2692;
+  s2694 = sbv_bv_extract_u32_7_0_u8(s2494);
+  s2695 = table5[s2694];
+  s2696 = s2693 ^ s2695;
+  s2697 = sbv_bv_extract_u32_31_24_u8(s569);
+  s2698 = table6[s2697];
+  s2699 = sbv_bv_extract_u32_23_16_u8(s569);
+  s2700 = table7[s2699];
+  s2701 = sbv_bv_extract_u32_15_8_u8(s569);
+  s2702 = table8[s2701];
+  s2703 = sbv_bv_extract_u32_7_0_u8(s569);
+  s2704 = table9[s2703];
+  s2705 = s2702 ^ s2704;
+  s2706 = s2700 ^ s2705;
+  s2707 = s2698 ^ s2706;
+  s2708 = table9[s2697];
+  s2709 = table6[s2699];
+  s2710 = table7[s2701];
+  s2711 = table8[s2703];
+  s2712 = s2710 ^ s2711;
+  s2713 = s2709 ^ s2712;
+  s2714 = s2708 ^ s2713;
+  s2715 = sbv_bv_join_u8_u8_u16(s2707, s2714);
+  s2716 = table8[s2697];
+  s2717 = table9[s2699];
+  s2718 = table6[s2701];
+  s2719 = table7[s2703];
+  s2720 = s2718 ^ s2719;
+  s2721 = s2717 ^ s2720;
+  s2722 = s2716 ^ s2721;
+  s2723 = table7[s2697];
+  s2724 = table8[s2699];
+  s2725 = table9[s2701];
+  s2726 = table6[s2703];
+  s2727 = s2725 ^ s2726;
+  s2728 = s2724 ^ s2727;
+  s2729 = s2723 ^ s2728;
+  s2730 = sbv_bv_join_u8_u8_u16(s2722, s2729);
+  s2731 = sbv_bv_join_u16_u16_u32(s2715, s2730);
+  s2732 = s2696 ^ s2731;
+  s2733 = sbv_bv_extract_u32_15_8_u8(s2732);
+  s2734 = table4[s2733];
+  s2735 = s2685 ^ s2734;
+  s2736 = sbv_bv_extract_u32_31_24_u8(s2594);
+  s2737 = table1[s2736];
+  s2738 = sbv_bv_extract_u32_23_16_u8(s2445);
+  s2739 = table3[s2738];
+  s2740 = s2737 ^ s2739;
+  s2741 = sbv_bv_extract_u32_15_8_u8(s2494);
+  s2742 = table4[s2741];
+  s2743 = s2740 ^ s2742;
+  s2744 = sbv_bv_extract_u32_7_0_u8(s2544);
+  s2745 = table5[s2744];
+  s2746 = s2743 ^ s2745;
+  s2747 = sbv_bv_extract_u32_31_24_u8(s568);
+  s2748 = table6[s2747];
+  s2749 = sbv_bv_extract_u32_23_16_u8(s568);
+  s2750 = table7[s2749];
+  s2751 = sbv_bv_extract_u32_15_8_u8(s568);
+  s2752 = table8[s2751];
+  s2753 = sbv_bv_extract_u32_7_0_u8(s568);
+  s2754 = table9[s2753];
+  s2755 = s2752 ^ s2754;
+  s2756 = s2750 ^ s2755;
+  s2757 = s2748 ^ s2756;
+  s2758 = table9[s2747];
+  s2759 = table6[s2749];
+  s2760 = table7[s2751];
+  s2761 = table8[s2753];
+  s2762 = s2760 ^ s2761;
+  s2763 = s2759 ^ s2762;
+  s2764 = s2758 ^ s2763;
+  s2765 = sbv_bv_join_u8_u8_u16(s2757, s2764);
+  s2766 = table8[s2747];
+  s2767 = table9[s2749];
+  s2768 = table6[s2751];
+  s2769 = table7[s2753];
+  s2770 = s2768 ^ s2769;
+  s2771 = s2767 ^ s2770;
+  s2772 = s2766 ^ s2771;
+  s2773 = table7[s2747];
+  s2774 = table8[s2749];
+  s2775 = table9[s2751];
+  s2776 = table6[s2753];
+  s2777 = s2775 ^ s2776;
+  s2778 = s2774 ^ s2777;
+  s2779 = s2773 ^ s2778;
+  s2780 = sbv_bv_join_u8_u8_u16(s2772, s2779);
+  s2781 = sbv_bv_join_u16_u16_u32(s2765, s2780);
+  s2782 = s2746 ^ s2781;
+  s2783 = sbv_bv_extract_u32_7_0_u8(s2782);
+  s2784 = table5[s2783];
+  s2785 = s2735 ^ s2784;
+  s2786 = sbv_bv_extract_u32_31_24_u8(s550);
+  s2787 = table6[s2786];
+  s2788 = sbv_bv_extract_u32_23_16_u8(s550);
+  s2789 = table7[s2788];
+  s2790 = sbv_bv_extract_u32_15_8_u8(s550);
+  s2791 = table8[s2790];
+  s2792 = sbv_bv_extract_u32_7_0_u8(s550);
+  s2793 = table9[s2792];
+  s2794 = s2791 ^ s2793;
+  s2795 = s2789 ^ s2794;
+  s2796 = s2787 ^ s2795;
+  s2797 = table9[s2786];
+  s2798 = table6[s2788];
+  s2799 = table7[s2790];
+  s2800 = table8[s2792];
+  s2801 = s2799 ^ s2800;
+  s2802 = s2798 ^ s2801;
+  s2803 = s2797 ^ s2802;
+  s2804 = sbv_bv_join_u8_u8_u16(s2796, s2803);
+  s2805 = table8[s2786];
+  s2806 = table9[s2788];
+  s2807 = table6[s2790];
+  s2808 = table7[s2792];
+  s2809 = s2807 ^ s2808;
+  s2810 = s2806 ^ s2809;
+  s2811 = s2805 ^ s2810;
+  s2812 = table7[s2786];
+  s2813 = table8[s2788];
+  s2814 = table9[s2790];
+  s2815 = table6[s2792];
+  s2816 = s2814 ^ s2815;
+  s2817 = s2813 ^ s2816;
+  s2818 = s2812 ^ s2817;
+  s2819 = sbv_bv_join_u8_u8_u16(s2811, s2818);
+  s2820 = sbv_bv_join_u16_u16_u32(s2804, s2819);
+  s2821 = s2785 ^ s2820;
+  s2822 = sbv_bv_extract_u32_31_24_u8(s2821);
+  s2823 = table1[s2822];
+  s2824 = sbv_bv_extract_u32_31_24_u8(s2682);
+  s2825 = table1[s2824];
+  s2826 = sbv_bv_extract_u32_23_16_u8(s2732);
+  s2827 = table3[s2826];
+  s2828 = s2825 ^ s2827;
+  s2829 = sbv_bv_extract_u32_15_8_u8(s2782);
+  s2830 = table4[s2829];
+  s2831 = s2828 ^ s2830;
+  s2832 = sbv_bv_extract_u32_7_0_u8(s2633);
+  s2833 = table5[s2832];
+  s2834 = s2831 ^ s2833;
+  s2835 = sbv_bv_extract_u32_31_24_u8(s553);
+  s2836 = table6[s2835];
+  s2837 = sbv_bv_extract_u32_23_16_u8(s553);
+  s2838 = table7[s2837];
+  s2839 = sbv_bv_extract_u32_15_8_u8(s553);
+  s2840 = table8[s2839];
+  s2841 = sbv_bv_extract_u32_7_0_u8(s553);
+  s2842 = table9[s2841];
+  s2843 = s2840 ^ s2842;
+  s2844 = s2838 ^ s2843;
+  s2845 = s2836 ^ s2844;
+  s2846 = table9[s2835];
+  s2847 = table6[s2837];
+  s2848 = table7[s2839];
+  s2849 = table8[s2841];
+  s2850 = s2848 ^ s2849;
+  s2851 = s2847 ^ s2850;
+  s2852 = s2846 ^ s2851;
+  s2853 = sbv_bv_join_u8_u8_u16(s2845, s2852);
+  s2854 = table8[s2835];
+  s2855 = table9[s2837];
+  s2856 = table6[s2839];
+  s2857 = table7[s2841];
+  s2858 = s2856 ^ s2857;
+  s2859 = s2855 ^ s2858;
+  s2860 = s2854 ^ s2859;
+  s2861 = table7[s2835];
+  s2862 = table8[s2837];
+  s2863 = table9[s2839];
+  s2864 = table6[s2841];
+  s2865 = s2863 ^ s2864;
+  s2866 = s2862 ^ s2865;
+  s2867 = s2861 ^ s2866;
+  s2868 = sbv_bv_join_u8_u8_u16(s2860, s2867);
+  s2869 = sbv_bv_join_u16_u16_u32(s2853, s2868);
+  s2870 = s2834 ^ s2869;
+  s2871 = sbv_bv_extract_u32_23_16_u8(s2870);
+  s2872 = table3[s2871];
+  s2873 = s2823 ^ s2872;
+  s2874 = sbv_bv_extract_u32_31_24_u8(s2732);
+  s2875 = table1[s2874];
+  s2876 = sbv_bv_extract_u32_23_16_u8(s2782);
+  s2877 = table3[s2876];
+  s2878 = s2875 ^ s2877;
+  s2879 = sbv_bv_extract_u32_15_8_u8(s2633);
+  s2880 = table4[s2879];
+  s2881 = s2878 ^ s2880;
+  s2882 = sbv_bv_extract_u32_7_0_u8(s2682);
+  s2883 = table5[s2882];
+  s2884 = s2881 ^ s2883;
+  s2885 = sbv_bv_extract_u32_31_24_u8(s552);
+  s2886 = table6[s2885];
+  s2887 = sbv_bv_extract_u32_23_16_u8(s552);
+  s2888 = table7[s2887];
+  s2889 = sbv_bv_extract_u32_15_8_u8(s552);
+  s2890 = table8[s2889];
+  s2891 = sbv_bv_extract_u32_7_0_u8(s552);
+  s2892 = table9[s2891];
+  s2893 = s2890 ^ s2892;
+  s2894 = s2888 ^ s2893;
+  s2895 = s2886 ^ s2894;
+  s2896 = table9[s2885];
+  s2897 = table6[s2887];
+  s2898 = table7[s2889];
+  s2899 = table8[s2891];
+  s2900 = s2898 ^ s2899;
+  s2901 = s2897 ^ s2900;
+  s2902 = s2896 ^ s2901;
+  s2903 = sbv_bv_join_u8_u8_u16(s2895, s2902);
+  s2904 = table8[s2885];
+  s2905 = table9[s2887];
+  s2906 = table6[s2889];
+  s2907 = table7[s2891];
+  s2908 = s2906 ^ s2907;
+  s2909 = s2905 ^ s2908;
+  s2910 = s2904 ^ s2909;
+  s2911 = table7[s2885];
+  s2912 = table8[s2887];
+  s2913 = table9[s2889];
+  s2914 = table6[s2891];
+  s2915 = s2913 ^ s2914;
+  s2916 = s2912 ^ s2915;
+  s2917 = s2911 ^ s2916;
+  s2918 = sbv_bv_join_u8_u8_u16(s2910, s2917);
+  s2919 = sbv_bv_join_u16_u16_u32(s2903, s2918);
+  s2920 = s2884 ^ s2919;
+  s2921 = sbv_bv_extract_u32_15_8_u8(s2920);
+  s2922 = table4[s2921];
+  s2923 = s2873 ^ s2922;
+  s2924 = sbv_bv_extract_u32_31_24_u8(s2782);
+  s2925 = table1[s2924];
+  s2926 = sbv_bv_extract_u32_23_16_u8(s2633);
+  s2927 = table3[s2926];
+  s2928 = s2925 ^ s2927;
+  s2929 = sbv_bv_extract_u32_15_8_u8(s2682);
+  s2930 = table4[s2929];
+  s2931 = s2928 ^ s2930;
+  s2932 = sbv_bv_extract_u32_7_0_u8(s2732);
+  s2933 = table5[s2932];
+  s2934 = s2931 ^ s2933;
+  s2935 = sbv_bv_extract_u32_31_24_u8(s551);
+  s2936 = table6[s2935];
+  s2937 = sbv_bv_extract_u32_23_16_u8(s551);
+  s2938 = table7[s2937];
+  s2939 = sbv_bv_extract_u32_15_8_u8(s551);
+  s2940 = table8[s2939];
+  s2941 = sbv_bv_extract_u32_7_0_u8(s551);
+  s2942 = table9[s2941];
+  s2943 = s2940 ^ s2942;
+  s2944 = s2938 ^ s2943;
+  s2945 = s2936 ^ s2944;
+  s2946 = table9[s2935];
+  s2947 = table6[s2937];
+  s2948 = table7[s2939];
+  s2949 = table8[s2941];
+  s2950 = s2948 ^ s2949;
+  s2951 = s2947 ^ s2950;
+  s2952 = s2946 ^ s2951;
+  s2953 = sbv_bv_join_u8_u8_u16(s2945, s2952);
+  s2954 = table8[s2935];
+  s2955 = table9[s2937];
+  s2956 = table6[s2939];
+  s2957 = table7[s2941];
+  s2958 = s2956 ^ s2957;
+  s2959 = s2955 ^ s2958;
+  s2960 = s2954 ^ s2959;
+  s2961 = table7[s2935];
+  s2962 = table8[s2937];
+  s2963 = table9[s2939];
+  s2964 = table6[s2941];
+  s2965 = s2963 ^ s2964;
+  s2966 = s2962 ^ s2965;
+  s2967 = s2961 ^ s2966;
+  s2968 = sbv_bv_join_u8_u8_u16(s2960, s2967);
+  s2969 = sbv_bv_join_u16_u16_u32(s2953, s2968);
+  s2970 = s2934 ^ s2969;
+  s2971 = sbv_bv_extract_u32_7_0_u8(s2970);
+  s2972 = table5[s2971];
+  s2973 = s2923 ^ s2972;
+  s2974 = sbv_bv_extract_u32_31_24_u8(s533);
+  s2975 = table6[s2974];
+  s2976 = sbv_bv_extract_u32_23_16_u8(s533);
+  s2977 = table7[s2976];
+  s2978 = sbv_bv_extract_u32_15_8_u8(s533);
+  s2979 = table8[s2978];
+  s2980 = sbv_bv_extract_u32_7_0_u8(s533);
+  s2981 = table9[s2980];
+  s2982 = s2979 ^ s2981;
+  s2983 = s2977 ^ s2982;
+  s2984 = s2975 ^ s2983;
+  s2985 = table9[s2974];
+  s2986 = table6[s2976];
+  s2987 = table7[s2978];
+  s2988 = table8[s2980];
+  s2989 = s2987 ^ s2988;
+  s2990 = s2986 ^ s2989;
+  s2991 = s2985 ^ s2990;
+  s2992 = sbv_bv_join_u8_u8_u16(s2984, s2991);
+  s2993 = table8[s2974];
+  s2994 = table9[s2976];
+  s2995 = table6[s2978];
+  s2996 = table7[s2980];
+  s2997 = s2995 ^ s2996;
+  s2998 = s2994 ^ s2997;
+  s2999 = s2993 ^ s2998;
+  s3000 = table7[s2974];
+  s3001 = table8[s2976];
+  s3002 = table9[s2978];
+  s3003 = table6[s2980];
+  s3004 = s3002 ^ s3003;
+  s3005 = s3001 ^ s3004;
+  s3006 = s3000 ^ s3005;
+  s3007 = sbv_bv_join_u8_u8_u16(s2999, s3006);
+  s3008 = sbv_bv_join_u16_u16_u32(s2992, s3007);
+  s3009 = s2973 ^ s3008;
+  s3010 = sbv_bv_extract_u32_31_24_u8(s3009);
+  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
+  };
+  s3011 = table0[s3010];
+  s3012 = sbv_bv_extract_u32_31_24_u8(s2870);
+  s3013 = table1[s3012];
+  s3014 = sbv_bv_extract_u32_23_16_u8(s2920);
+  s3015 = table3[s3014];
+  s3016 = s3013 ^ s3015;
+  s3017 = sbv_bv_extract_u32_15_8_u8(s2970);
+  s3018 = table4[s3017];
+  s3019 = s3016 ^ s3018;
+  s3020 = sbv_bv_extract_u32_7_0_u8(s2821);
+  s3021 = table5[s3020];
+  s3022 = s3019 ^ s3021;
+  s3023 = sbv_bv_extract_u32_31_24_u8(s536);
+  s3024 = table6[s3023];
+  s3025 = sbv_bv_extract_u32_23_16_u8(s536);
+  s3026 = table7[s3025];
+  s3027 = sbv_bv_extract_u32_15_8_u8(s536);
+  s3028 = table8[s3027];
+  s3029 = sbv_bv_extract_u32_7_0_u8(s536);
+  s3030 = table9[s3029];
+  s3031 = s3028 ^ s3030;
+  s3032 = s3026 ^ s3031;
+  s3033 = s3024 ^ s3032;
+  s3034 = table9[s3023];
+  s3035 = table6[s3025];
+  s3036 = table7[s3027];
+  s3037 = table8[s3029];
+  s3038 = s3036 ^ s3037;
+  s3039 = s3035 ^ s3038;
+  s3040 = s3034 ^ s3039;
+  s3041 = sbv_bv_join_u8_u8_u16(s3033, s3040);
+  s3042 = table8[s3023];
+  s3043 = table9[s3025];
+  s3044 = table6[s3027];
+  s3045 = table7[s3029];
+  s3046 = s3044 ^ s3045;
+  s3047 = s3043 ^ s3046;
+  s3048 = s3042 ^ s3047;
+  s3049 = table7[s3023];
+  s3050 = table8[s3025];
+  s3051 = table9[s3027];
+  s3052 = table6[s3029];
+  s3053 = s3051 ^ s3052;
+  s3054 = s3050 ^ s3053;
+  s3055 = s3049 ^ s3054;
+  s3056 = sbv_bv_join_u8_u8_u16(s3048, s3055);
+  s3057 = sbv_bv_join_u16_u16_u32(s3041, s3056);
+  s3058 = s3022 ^ s3057;
+  s3059 = sbv_bv_extract_u32_23_16_u8(s3058);
+  s3060 = table0[s3059];
+  s3061 = sbv_bv_join_u8_u8_u16(s3011, s3060);
+  s3062 = sbv_bv_extract_u32_31_24_u8(s2920);
+  s3063 = table1[s3062];
+  s3064 = sbv_bv_extract_u32_23_16_u8(s2970);
+  s3065 = table3[s3064];
+  s3066 = s3063 ^ s3065;
+  s3067 = sbv_bv_extract_u32_15_8_u8(s2821);
+  s3068 = table4[s3067];
+  s3069 = s3066 ^ s3068;
+  s3070 = sbv_bv_extract_u32_7_0_u8(s2870);
+  s3071 = table5[s3070];
+  s3072 = s3069 ^ s3071;
+  s3073 = sbv_bv_extract_u32_31_24_u8(s535);
+  s3074 = table6[s3073];
+  s3075 = sbv_bv_extract_u32_23_16_u8(s535);
+  s3076 = table7[s3075];
+  s3077 = sbv_bv_extract_u32_15_8_u8(s535);
+  s3078 = table8[s3077];
+  s3079 = sbv_bv_extract_u32_7_0_u8(s535);
+  s3080 = table9[s3079];
+  s3081 = s3078 ^ s3080;
+  s3082 = s3076 ^ s3081;
+  s3083 = s3074 ^ s3082;
+  s3084 = table9[s3073];
+  s3085 = table6[s3075];
+  s3086 = table7[s3077];
+  s3087 = table8[s3079];
+  s3088 = s3086 ^ s3087;
+  s3089 = s3085 ^ s3088;
+  s3090 = s3084 ^ s3089;
+  s3091 = sbv_bv_join_u8_u8_u16(s3083, s3090);
+  s3092 = table8[s3073];
+  s3093 = table9[s3075];
+  s3094 = table6[s3077];
+  s3095 = table7[s3079];
+  s3096 = s3094 ^ s3095;
+  s3097 = s3093 ^ s3096;
+  s3098 = s3092 ^ s3097;
+  s3099 = table7[s3073];
+  s3100 = table8[s3075];
+  s3101 = table9[s3077];
+  s3102 = table6[s3079];
+  s3103 = s3101 ^ s3102;
+  s3104 = s3100 ^ s3103;
+  s3105 = s3099 ^ s3104;
+  s3106 = sbv_bv_join_u8_u8_u16(s3098, s3105);
+  s3107 = sbv_bv_join_u16_u16_u32(s3091, s3106);
+  s3108 = s3072 ^ s3107;
+  s3109 = sbv_bv_extract_u32_15_8_u8(s3108);
+  s3110 = table0[s3109];
+  s3111 = sbv_bv_extract_u32_31_24_u8(s2970);
+  s3112 = table1[s3111];
+  s3113 = sbv_bv_extract_u32_23_16_u8(s2821);
+  s3114 = table3[s3113];
+  s3115 = s3112 ^ s3114;
+  s3116 = sbv_bv_extract_u32_15_8_u8(s2870);
+  s3117 = table4[s3116];
+  s3118 = s3115 ^ s3117;
+  s3119 = sbv_bv_extract_u32_7_0_u8(s2920);
+  s3120 = table5[s3119];
+  s3121 = s3118 ^ s3120;
+  s3122 = sbv_bv_extract_u32_31_24_u8(s534);
+  s3123 = table6[s3122];
+  s3124 = sbv_bv_extract_u32_23_16_u8(s534);
+  s3125 = table7[s3124];
+  s3126 = sbv_bv_extract_u32_15_8_u8(s534);
+  s3127 = table8[s3126];
+  s3128 = sbv_bv_extract_u32_7_0_u8(s534);
+  s3129 = table9[s3128];
+  s3130 = s3127 ^ s3129;
+  s3131 = s3125 ^ s3130;
+  s3132 = s3123 ^ s3131;
+  s3133 = table9[s3122];
+  s3134 = table6[s3124];
+  s3135 = table7[s3126];
+  s3136 = table8[s3128];
+  s3137 = s3135 ^ s3136;
+  s3138 = s3134 ^ s3137;
+  s3139 = s3133 ^ s3138;
+  s3140 = sbv_bv_join_u8_u8_u16(s3132, s3139);
+  s3141 = table8[s3122];
+  s3142 = table9[s3124];
+  s3143 = table6[s3126];
+  s3144 = table7[s3128];
+  s3145 = s3143 ^ s3144;
+  s3146 = s3142 ^ s3145;
+  s3147 = s3141 ^ s3146;
+  s3148 = table7[s3122];
+  s3149 = table8[s3124];
+  s3150 = table9[s3126];
+  s3151 = table6[s3128];
+  s3152 = s3150 ^ s3151;
+  s3153 = s3149 ^ s3152;
+  s3154 = s3148 ^ s3153;
+  s3155 = sbv_bv_join_u8_u8_u16(s3147, s3154);
+  s3156 = sbv_bv_join_u16_u16_u32(s3140, s3155);
+  s3157 = s3121 ^ s3156;
+  s3158 = sbv_bv_extract_u32_7_0_u8(s3157);
+  s3159 = table0[s3158];
+  s3160 = sbv_bv_join_u8_u8_u16(s3110, s3159);
+  s3161 = sbv_bv_join_u16_u16_u32(s3061, s3160);
+  s3162 = s4 ^ s3161;
+  s3163 = sbv_bv_extract_u32_31_24_u8(s3157);
+  s3164 = table0[s3163];
+  s3165 = sbv_bv_extract_u32_23_16_u8(s3009);
+  s3166 = table0[s3165];
+  s3167 = sbv_bv_join_u8_u8_u16(s3164, s3166);
+  s3168 = sbv_bv_extract_u32_15_8_u8(s3058);
+  s3169 = table0[s3168];
+  s3170 = sbv_bv_extract_u32_7_0_u8(s3108);
+  s3171 = table0[s3170];
+  s3172 = sbv_bv_join_u8_u8_u16(s3169, s3171);
+  s3173 = sbv_bv_join_u16_u16_u32(s3167, s3172);
+  s3174 = s5 ^ s3173;
+  s3175 = sbv_bv_extract_u32_31_24_u8(s3108);
+  s3176 = table0[s3175];
+  s3177 = sbv_bv_extract_u32_23_16_u8(s3157);
+  s3178 = table0[s3177];
+  s3179 = sbv_bv_join_u8_u8_u16(s3176, s3178);
+  s3180 = sbv_bv_extract_u32_15_8_u8(s3009);
+  s3181 = table0[s3180];
+  s3182 = sbv_bv_extract_u32_7_0_u8(s3058);
+  s3183 = table0[s3182];
+  s3184 = sbv_bv_join_u8_u8_u16(s3181, s3183);
+  s3185 = sbv_bv_join_u16_u16_u32(s3179, s3184);
+  s3186 = s6 ^ s3185;
+  s3187 = sbv_bv_extract_u32_31_24_u8(s3058);
+  s3188 = table0[s3187];
+  s3189 = sbv_bv_extract_u32_23_16_u8(s3108);
+  s3190 = table0[s3189];
+  s3191 = sbv_bv_join_u8_u8_u16(s3188, s3190);
+  s3192 = sbv_bv_extract_u32_15_8_u8(s3157);
+  s3193 = table0[s3192];
+  s3194 = sbv_bv_extract_u32_7_0_u8(s3009);
+  s3195 = table0[s3194];
+  s3196 = sbv_bv_join_u8_u8_u16(s3193, s3195);
+  s3197 = sbv_bv_join_u16_u16_u32(s3191, s3196);
+  s3198 = s7 ^ s3197;
+
+  sbv_output_0[0] = s3162;
+  sbv_output_0[1] = s3174;
+  sbv_output_0[2] = s3186;
+  sbv_output_0[3] = s3198;
 }
 == END: "aes128Dec.c" ==================
diff --git a/SBVTestSuite/GoldFiles/aes128Enc.gold b/SBVTestSuite/GoldFiles/aes128Enc.gold
--- a/SBVTestSuite/GoldFiles/aes128Enc.gold
+++ b/SBVTestSuite/GoldFiles/aes128Enc.gold
@@ -12,1056 +12,1776 @@
 aes128Enc.o: aes128Enc.c aes128Enc.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
-aes128Enc_driver.o: aes128Enc_driver.c
-	${CC} ${CCFLAGS} -c $< -o $@
-
-aes128Enc_driver: aes128Enc.o aes128Enc_driver.o
-	${CC} ${CCFLAGS} $^ -o $@
-
-clean:
-	rm -f *.o
-
-veryclean: clean
-	rm -f aes128Enc_driver
-== END: "Makefile" ==================
-== BEGIN: "aes128Enc.h" ================
-/* Header file for aes128Enc. Automatically generated by SBV. Do not edit! */
-
-#ifndef __aes128Enc__HEADER_INCLUDED__
-#define __aes128Enc__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 prototype: */
-void aes128Enc(const SWord32 *pt, const SWord32 *key, SWord32 *ct);
-
-#endif /* __aes128Enc__HEADER_INCLUDED__ */
-== END: "aes128Enc.h" ==================
-== BEGIN: "aes128Enc_driver.c" ================
-/* Example driver program for aes128Enc. */
-/* Automatically generated by SBV. Edit as you see fit! */
-
-#include <stdio.h>
-#include "aes128Enc.h"
-
-int main(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 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 ct[4];
-
-  aes128Enc(pt, key, ct);
-
-  printf("aes128Enc(pt, key, 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]);
-
-  return 0;
-}
-== END: "aes128Enc_driver.c" ==================
-== BEGIN: "aes128Enc.c" ================
-/* File: "aes128Enc.c". Automatically generated by SBV. Do not edit! */
-
-#include "aes128Enc.h"
-
-void aes128Enc(const SWord32 *pt, const SWord32 *key, SWord32 *ct)
-{
-  const SWord32 s0 = pt[0];
-  const SWord32 s1 = pt[1];
-  const SWord32 s2 = pt[2];
-  const SWord32 s3 = pt[3];
-  const SWord32 s4 = key[0];
-  const SWord32 s5 = key[1];
-  const SWord32 s6 = key[2];
-  const SWord32 s7 = 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
-  };
-  static const SWord32 table1[] = {
-      0xc66363a5UL, 0xf87c7c84UL, 0xee777799UL, 0xf67b7b8dUL,
-      0xfff2f20dUL, 0xd66b6bbdUL, 0xde6f6fb1UL, 0x91c5c554UL,
-      0x60303050UL, 0x02010103UL, 0xce6767a9UL, 0x562b2b7dUL,
-      0xe7fefe19UL, 0xb5d7d762UL, 0x4dababe6UL, 0xec76769aUL,
-      0x8fcaca45UL, 0x1f82829dUL, 0x89c9c940UL, 0xfa7d7d87UL,
-      0xeffafa15UL, 0xb25959ebUL, 0x8e4747c9UL, 0xfbf0f00bUL,
-      0x41adadecUL, 0xb3d4d467UL, 0x5fa2a2fdUL, 0x45afafeaUL,
-      0x239c9cbfUL, 0x53a4a4f7UL, 0xe4727296UL, 0x9bc0c05bUL,
-      0x75b7b7c2UL, 0xe1fdfd1cUL, 0x3d9393aeUL, 0x4c26266aUL,
-      0x6c36365aUL, 0x7e3f3f41UL, 0xf5f7f702UL, 0x83cccc4fUL,
-      0x6834345cUL, 0x51a5a5f4UL, 0xd1e5e534UL, 0xf9f1f108UL,
-      0xe2717193UL, 0xabd8d873UL, 0x62313153UL, 0x2a15153fUL,
-      0x0804040cUL, 0x95c7c752UL, 0x46232365UL, 0x9dc3c35eUL,
-      0x30181828UL, 0x379696a1UL, 0x0a05050fUL, 0x2f9a9ab5UL,
-      0x0e070709UL, 0x24121236UL, 0x1b80809bUL, 0xdfe2e23dUL,
-      0xcdebeb26UL, 0x4e272769UL, 0x7fb2b2cdUL, 0xea75759fUL,
-      0x1209091bUL, 0x1d83839eUL, 0x582c2c74UL, 0x341a1a2eUL,
-      0x361b1b2dUL, 0xdc6e6eb2UL, 0xb45a5aeeUL, 0x5ba0a0fbUL,
-      0xa45252f6UL, 0x763b3b4dUL, 0xb7d6d661UL, 0x7db3b3ceUL,
-      0x5229297bUL, 0xdde3e33eUL, 0x5e2f2f71UL, 0x13848497UL,
-      0xa65353f5UL, 0xb9d1d168UL, 0x00000000UL, 0xc1eded2cUL,
-      0x40202060UL, 0xe3fcfc1fUL, 0x79b1b1c8UL, 0xb65b5bedUL,
-      0xd46a6abeUL, 0x8dcbcb46UL, 0x67bebed9UL, 0x7239394bUL,
-      0x944a4adeUL, 0x984c4cd4UL, 0xb05858e8UL, 0x85cfcf4aUL,
-      0xbbd0d06bUL, 0xc5efef2aUL, 0x4faaaae5UL, 0xedfbfb16UL,
-      0x864343c5UL, 0x9a4d4dd7UL, 0x66333355UL, 0x11858594UL,
-      0x8a4545cfUL, 0xe9f9f910UL, 0x04020206UL, 0xfe7f7f81UL,
-      0xa05050f0UL, 0x783c3c44UL, 0x259f9fbaUL, 0x4ba8a8e3UL,
-      0xa25151f3UL, 0x5da3a3feUL, 0x804040c0UL, 0x058f8f8aUL,
-      0x3f9292adUL, 0x219d9dbcUL, 0x70383848UL, 0xf1f5f504UL,
-      0x63bcbcdfUL, 0x77b6b6c1UL, 0xafdada75UL, 0x42212163UL,
-      0x20101030UL, 0xe5ffff1aUL, 0xfdf3f30eUL, 0xbfd2d26dUL,
-      0x81cdcd4cUL, 0x180c0c14UL, 0x26131335UL, 0xc3ecec2fUL,
-      0xbe5f5fe1UL, 0x359797a2UL, 0x884444ccUL, 0x2e171739UL,
-      0x93c4c457UL, 0x55a7a7f2UL, 0xfc7e7e82UL, 0x7a3d3d47UL,
-      0xc86464acUL, 0xba5d5de7UL, 0x3219192bUL, 0xe6737395UL,
-      0xc06060a0UL, 0x19818198UL, 0x9e4f4fd1UL, 0xa3dcdc7fUL,
-      0x44222266UL, 0x542a2a7eUL, 0x3b9090abUL, 0x0b888883UL,
-      0x8c4646caUL, 0xc7eeee29UL, 0x6bb8b8d3UL, 0x2814143cUL,
-      0xa7dede79UL, 0xbc5e5ee2UL, 0x160b0b1dUL, 0xaddbdb76UL,
-      0xdbe0e03bUL, 0x64323256UL, 0x743a3a4eUL, 0x140a0a1eUL,
-      0x924949dbUL, 0x0c06060aUL, 0x4824246cUL, 0xb85c5ce4UL,
-      0x9fc2c25dUL, 0xbdd3d36eUL, 0x43acacefUL, 0xc46262a6UL,
-      0x399191a8UL, 0x319595a4UL, 0xd3e4e437UL, 0xf279798bUL,
-      0xd5e7e732UL, 0x8bc8c843UL, 0x6e373759UL, 0xda6d6db7UL,
-      0x018d8d8cUL, 0xb1d5d564UL, 0x9c4e4ed2UL, 0x49a9a9e0UL,
-      0xd86c6cb4UL, 0xac5656faUL, 0xf3f4f407UL, 0xcfeaea25UL,
-      0xca6565afUL, 0xf47a7a8eUL, 0x47aeaee9UL, 0x10080818UL,
-      0x6fbabad5UL, 0xf0787888UL, 0x4a25256fUL, 0x5c2e2e72UL,
-      0x381c1c24UL, 0x57a6a6f1UL, 0x73b4b4c7UL, 0x97c6c651UL,
-      0xcbe8e823UL, 0xa1dddd7cUL, 0xe874749cUL, 0x3e1f1f21UL,
-      0x964b4bddUL, 0x61bdbddcUL, 0x0d8b8b86UL, 0x0f8a8a85UL,
-      0xe0707090UL, 0x7c3e3e42UL, 0x71b5b5c4UL, 0xcc6666aaUL,
-      0x904848d8UL, 0x06030305UL, 0xf7f6f601UL, 0x1c0e0e12UL,
-      0xc26161a3UL, 0x6a35355fUL, 0xae5757f9UL, 0x69b9b9d0UL,
-      0x17868691UL, 0x99c1c158UL, 0x3a1d1d27UL, 0x279e9eb9UL,
-      0xd9e1e138UL, 0xebf8f813UL, 0x2b9898b3UL, 0x22111133UL,
-      0xd26969bbUL, 0xa9d9d970UL, 0x078e8e89UL, 0x339494a7UL,
-      0x2d9b9bb6UL, 0x3c1e1e22UL, 0x15878792UL, 0xc9e9e920UL,
-      0x87cece49UL, 0xaa5555ffUL, 0x50282878UL, 0xa5dfdf7aUL,
-      0x038c8c8fUL, 0x59a1a1f8UL, 0x09898980UL, 0x1a0d0d17UL,
-      0x65bfbfdaUL, 0xd7e6e631UL, 0x844242c6UL, 0xd06868b8UL,
-      0x824141c3UL, 0x299999b0UL, 0x5a2d2d77UL, 0x1e0f0f11UL,
-      0x7bb0b0cbUL, 0xa85454fcUL, 0x6dbbbbd6UL, 0x2c16163aUL
-  };
-  static const SWord32 table2[] = {
-      0xa5c66363UL, 0x84f87c7cUL, 0x99ee7777UL, 0x8df67b7bUL,
-      0x0dfff2f2UL, 0xbdd66b6bUL, 0xb1de6f6fUL, 0x5491c5c5UL,
-      0x50603030UL, 0x03020101UL, 0xa9ce6767UL, 0x7d562b2bUL,
-      0x19e7fefeUL, 0x62b5d7d7UL, 0xe64dababUL, 0x9aec7676UL,
-      0x458fcacaUL, 0x9d1f8282UL, 0x4089c9c9UL, 0x87fa7d7dUL,
-      0x15effafaUL, 0xebb25959UL, 0xc98e4747UL, 0x0bfbf0f0UL,
-      0xec41adadUL, 0x67b3d4d4UL, 0xfd5fa2a2UL, 0xea45afafUL,
-      0xbf239c9cUL, 0xf753a4a4UL, 0x96e47272UL, 0x5b9bc0c0UL,
-      0xc275b7b7UL, 0x1ce1fdfdUL, 0xae3d9393UL, 0x6a4c2626UL,
-      0x5a6c3636UL, 0x417e3f3fUL, 0x02f5f7f7UL, 0x4f83ccccUL,
-      0x5c683434UL, 0xf451a5a5UL, 0x34d1e5e5UL, 0x08f9f1f1UL,
-      0x93e27171UL, 0x73abd8d8UL, 0x53623131UL, 0x3f2a1515UL,
-      0x0c080404UL, 0x5295c7c7UL, 0x65462323UL, 0x5e9dc3c3UL,
-      0x28301818UL, 0xa1379696UL, 0x0f0a0505UL, 0xb52f9a9aUL,
-      0x090e0707UL, 0x36241212UL, 0x9b1b8080UL, 0x3ddfe2e2UL,
-      0x26cdebebUL, 0x694e2727UL, 0xcd7fb2b2UL, 0x9fea7575UL,
-      0x1b120909UL, 0x9e1d8383UL, 0x74582c2cUL, 0x2e341a1aUL,
-      0x2d361b1bUL, 0xb2dc6e6eUL, 0xeeb45a5aUL, 0xfb5ba0a0UL,
-      0xf6a45252UL, 0x4d763b3bUL, 0x61b7d6d6UL, 0xce7db3b3UL,
-      0x7b522929UL, 0x3edde3e3UL, 0x715e2f2fUL, 0x97138484UL,
-      0xf5a65353UL, 0x68b9d1d1UL, 0x00000000UL, 0x2cc1ededUL,
-      0x60402020UL, 0x1fe3fcfcUL, 0xc879b1b1UL, 0xedb65b5bUL,
-      0xbed46a6aUL, 0x468dcbcbUL, 0xd967bebeUL, 0x4b723939UL,
-      0xde944a4aUL, 0xd4984c4cUL, 0xe8b05858UL, 0x4a85cfcfUL,
-      0x6bbbd0d0UL, 0x2ac5efefUL, 0xe54faaaaUL, 0x16edfbfbUL,
-      0xc5864343UL, 0xd79a4d4dUL, 0x55663333UL, 0x94118585UL,
-      0xcf8a4545UL, 0x10e9f9f9UL, 0x06040202UL, 0x81fe7f7fUL,
-      0xf0a05050UL, 0x44783c3cUL, 0xba259f9fUL, 0xe34ba8a8UL,
-      0xf3a25151UL, 0xfe5da3a3UL, 0xc0804040UL, 0x8a058f8fUL,
-      0xad3f9292UL, 0xbc219d9dUL, 0x48703838UL, 0x04f1f5f5UL,
-      0xdf63bcbcUL, 0xc177b6b6UL, 0x75afdadaUL, 0x63422121UL,
-      0x30201010UL, 0x1ae5ffffUL, 0x0efdf3f3UL, 0x6dbfd2d2UL,
-      0x4c81cdcdUL, 0x14180c0cUL, 0x35261313UL, 0x2fc3ececUL,
-      0xe1be5f5fUL, 0xa2359797UL, 0xcc884444UL, 0x392e1717UL,
-      0x5793c4c4UL, 0xf255a7a7UL, 0x82fc7e7eUL, 0x477a3d3dUL,
-      0xacc86464UL, 0xe7ba5d5dUL, 0x2b321919UL, 0x95e67373UL,
-      0xa0c06060UL, 0x98198181UL, 0xd19e4f4fUL, 0x7fa3dcdcUL,
-      0x66442222UL, 0x7e542a2aUL, 0xab3b9090UL, 0x830b8888UL,
-      0xca8c4646UL, 0x29c7eeeeUL, 0xd36bb8b8UL, 0x3c281414UL,
-      0x79a7dedeUL, 0xe2bc5e5eUL, 0x1d160b0bUL, 0x76addbdbUL,
-      0x3bdbe0e0UL, 0x56643232UL, 0x4e743a3aUL, 0x1e140a0aUL,
-      0xdb924949UL, 0x0a0c0606UL, 0x6c482424UL, 0xe4b85c5cUL,
-      0x5d9fc2c2UL, 0x6ebdd3d3UL, 0xef43acacUL, 0xa6c46262UL,
-      0xa8399191UL, 0xa4319595UL, 0x37d3e4e4UL, 0x8bf27979UL,
-      0x32d5e7e7UL, 0x438bc8c8UL, 0x596e3737UL, 0xb7da6d6dUL,
-      0x8c018d8dUL, 0x64b1d5d5UL, 0xd29c4e4eUL, 0xe049a9a9UL,
-      0xb4d86c6cUL, 0xfaac5656UL, 0x07f3f4f4UL, 0x25cfeaeaUL,
-      0xafca6565UL, 0x8ef47a7aUL, 0xe947aeaeUL, 0x18100808UL,
-      0xd56fbabaUL, 0x88f07878UL, 0x6f4a2525UL, 0x725c2e2eUL,
-      0x24381c1cUL, 0xf157a6a6UL, 0xc773b4b4UL, 0x5197c6c6UL,
-      0x23cbe8e8UL, 0x7ca1ddddUL, 0x9ce87474UL, 0x213e1f1fUL,
-      0xdd964b4bUL, 0xdc61bdbdUL, 0x860d8b8bUL, 0x850f8a8aUL,
-      0x90e07070UL, 0x427c3e3eUL, 0xc471b5b5UL, 0xaacc6666UL,
-      0xd8904848UL, 0x05060303UL, 0x01f7f6f6UL, 0x121c0e0eUL,
-      0xa3c26161UL, 0x5f6a3535UL, 0xf9ae5757UL, 0xd069b9b9UL,
-      0x91178686UL, 0x5899c1c1UL, 0x273a1d1dUL, 0xb9279e9eUL,
-      0x38d9e1e1UL, 0x13ebf8f8UL, 0xb32b9898UL, 0x33221111UL,
-      0xbbd26969UL, 0x70a9d9d9UL, 0x89078e8eUL, 0xa7339494UL,
-      0xb62d9b9bUL, 0x223c1e1eUL, 0x92158787UL, 0x20c9e9e9UL,
-      0x4987ceceUL, 0xffaa5555UL, 0x78502828UL, 0x7aa5dfdfUL,
-      0x8f038c8cUL, 0xf859a1a1UL, 0x80098989UL, 0x171a0d0dUL,
-      0xda65bfbfUL, 0x31d7e6e6UL, 0xc6844242UL, 0xb8d06868UL,
-      0xc3824141UL, 0xb0299999UL, 0x775a2d2dUL, 0x111e0f0fUL,
-      0xcb7bb0b0UL, 0xfca85454UL, 0xd66dbbbbUL, 0x3a2c1616UL
-  };
-  static const SWord32 table3[] = {
-      0x63a5c663UL, 0x7c84f87cUL, 0x7799ee77UL, 0x7b8df67bUL,
-      0xf20dfff2UL, 0x6bbdd66bUL, 0x6fb1de6fUL, 0xc55491c5UL,
-      0x30506030UL, 0x01030201UL, 0x67a9ce67UL, 0x2b7d562bUL,
-      0xfe19e7feUL, 0xd762b5d7UL, 0xabe64dabUL, 0x769aec76UL,
-      0xca458fcaUL, 0x829d1f82UL, 0xc94089c9UL, 0x7d87fa7dUL,
-      0xfa15effaUL, 0x59ebb259UL, 0x47c98e47UL, 0xf00bfbf0UL,
-      0xadec41adUL, 0xd467b3d4UL, 0xa2fd5fa2UL, 0xafea45afUL,
-      0x9cbf239cUL, 0xa4f753a4UL, 0x7296e472UL, 0xc05b9bc0UL,
-      0xb7c275b7UL, 0xfd1ce1fdUL, 0x93ae3d93UL, 0x266a4c26UL,
-      0x365a6c36UL, 0x3f417e3fUL, 0xf702f5f7UL, 0xcc4f83ccUL,
-      0x345c6834UL, 0xa5f451a5UL, 0xe534d1e5UL, 0xf108f9f1UL,
-      0x7193e271UL, 0xd873abd8UL, 0x31536231UL, 0x153f2a15UL,
-      0x040c0804UL, 0xc75295c7UL, 0x23654623UL, 0xc35e9dc3UL,
-      0x18283018UL, 0x96a13796UL, 0x050f0a05UL, 0x9ab52f9aUL,
-      0x07090e07UL, 0x12362412UL, 0x809b1b80UL, 0xe23ddfe2UL,
-      0xeb26cdebUL, 0x27694e27UL, 0xb2cd7fb2UL, 0x759fea75UL,
-      0x091b1209UL, 0x839e1d83UL, 0x2c74582cUL, 0x1a2e341aUL,
-      0x1b2d361bUL, 0x6eb2dc6eUL, 0x5aeeb45aUL, 0xa0fb5ba0UL,
-      0x52f6a452UL, 0x3b4d763bUL, 0xd661b7d6UL, 0xb3ce7db3UL,
-      0x297b5229UL, 0xe33edde3UL, 0x2f715e2fUL, 0x84971384UL,
-      0x53f5a653UL, 0xd168b9d1UL, 0x00000000UL, 0xed2cc1edUL,
-      0x20604020UL, 0xfc1fe3fcUL, 0xb1c879b1UL, 0x5bedb65bUL,
-      0x6abed46aUL, 0xcb468dcbUL, 0xbed967beUL, 0x394b7239UL,
-      0x4ade944aUL, 0x4cd4984cUL, 0x58e8b058UL, 0xcf4a85cfUL,
-      0xd06bbbd0UL, 0xef2ac5efUL, 0xaae54faaUL, 0xfb16edfbUL,
-      0x43c58643UL, 0x4dd79a4dUL, 0x33556633UL, 0x85941185UL,
-      0x45cf8a45UL, 0xf910e9f9UL, 0x02060402UL, 0x7f81fe7fUL,
-      0x50f0a050UL, 0x3c44783cUL, 0x9fba259fUL, 0xa8e34ba8UL,
-      0x51f3a251UL, 0xa3fe5da3UL, 0x40c08040UL, 0x8f8a058fUL,
-      0x92ad3f92UL, 0x9dbc219dUL, 0x38487038UL, 0xf504f1f5UL,
-      0xbcdf63bcUL, 0xb6c177b6UL, 0xda75afdaUL, 0x21634221UL,
-      0x10302010UL, 0xff1ae5ffUL, 0xf30efdf3UL, 0xd26dbfd2UL,
-      0xcd4c81cdUL, 0x0c14180cUL, 0x13352613UL, 0xec2fc3ecUL,
-      0x5fe1be5fUL, 0x97a23597UL, 0x44cc8844UL, 0x17392e17UL,
-      0xc45793c4UL, 0xa7f255a7UL, 0x7e82fc7eUL, 0x3d477a3dUL,
-      0x64acc864UL, 0x5de7ba5dUL, 0x192b3219UL, 0x7395e673UL,
-      0x60a0c060UL, 0x81981981UL, 0x4fd19e4fUL, 0xdc7fa3dcUL,
-      0x22664422UL, 0x2a7e542aUL, 0x90ab3b90UL, 0x88830b88UL,
-      0x46ca8c46UL, 0xee29c7eeUL, 0xb8d36bb8UL, 0x143c2814UL,
-      0xde79a7deUL, 0x5ee2bc5eUL, 0x0b1d160bUL, 0xdb76addbUL,
-      0xe03bdbe0UL, 0x32566432UL, 0x3a4e743aUL, 0x0a1e140aUL,
-      0x49db9249UL, 0x060a0c06UL, 0x246c4824UL, 0x5ce4b85cUL,
-      0xc25d9fc2UL, 0xd36ebdd3UL, 0xacef43acUL, 0x62a6c462UL,
-      0x91a83991UL, 0x95a43195UL, 0xe437d3e4UL, 0x798bf279UL,
-      0xe732d5e7UL, 0xc8438bc8UL, 0x37596e37UL, 0x6db7da6dUL,
-      0x8d8c018dUL, 0xd564b1d5UL, 0x4ed29c4eUL, 0xa9e049a9UL,
-      0x6cb4d86cUL, 0x56faac56UL, 0xf407f3f4UL, 0xea25cfeaUL,
-      0x65afca65UL, 0x7a8ef47aUL, 0xaee947aeUL, 0x08181008UL,
-      0xbad56fbaUL, 0x7888f078UL, 0x256f4a25UL, 0x2e725c2eUL,
-      0x1c24381cUL, 0xa6f157a6UL, 0xb4c773b4UL, 0xc65197c6UL,
-      0xe823cbe8UL, 0xdd7ca1ddUL, 0x749ce874UL, 0x1f213e1fUL,
-      0x4bdd964bUL, 0xbddc61bdUL, 0x8b860d8bUL, 0x8a850f8aUL,
-      0x7090e070UL, 0x3e427c3eUL, 0xb5c471b5UL, 0x66aacc66UL,
-      0x48d89048UL, 0x03050603UL, 0xf601f7f6UL, 0x0e121c0eUL,
-      0x61a3c261UL, 0x355f6a35UL, 0x57f9ae57UL, 0xb9d069b9UL,
-      0x86911786UL, 0xc15899c1UL, 0x1d273a1dUL, 0x9eb9279eUL,
-      0xe138d9e1UL, 0xf813ebf8UL, 0x98b32b98UL, 0x11332211UL,
-      0x69bbd269UL, 0xd970a9d9UL, 0x8e89078eUL, 0x94a73394UL,
-      0x9bb62d9bUL, 0x1e223c1eUL, 0x87921587UL, 0xe920c9e9UL,
-      0xce4987ceUL, 0x55ffaa55UL, 0x28785028UL, 0xdf7aa5dfUL,
-      0x8c8f038cUL, 0xa1f859a1UL, 0x89800989UL, 0x0d171a0dUL,
-      0xbfda65bfUL, 0xe631d7e6UL, 0x42c68442UL, 0x68b8d068UL,
-      0x41c38241UL, 0x99b02999UL, 0x2d775a2dUL, 0x0f111e0fUL,
-      0xb0cb7bb0UL, 0x54fca854UL, 0xbbd66dbbUL, 0x163a2c16UL
-  };
-  static const SWord32 table4[] = {
-      0x6363a5c6UL, 0x7c7c84f8UL, 0x777799eeUL, 0x7b7b8df6UL,
-      0xf2f20dffUL, 0x6b6bbdd6UL, 0x6f6fb1deUL, 0xc5c55491UL,
-      0x30305060UL, 0x01010302UL, 0x6767a9ceUL, 0x2b2b7d56UL,
-      0xfefe19e7UL, 0xd7d762b5UL, 0xababe64dUL, 0x76769aecUL,
-      0xcaca458fUL, 0x82829d1fUL, 0xc9c94089UL, 0x7d7d87faUL,
-      0xfafa15efUL, 0x5959ebb2UL, 0x4747c98eUL, 0xf0f00bfbUL,
-      0xadadec41UL, 0xd4d467b3UL, 0xa2a2fd5fUL, 0xafafea45UL,
-      0x9c9cbf23UL, 0xa4a4f753UL, 0x727296e4UL, 0xc0c05b9bUL,
-      0xb7b7c275UL, 0xfdfd1ce1UL, 0x9393ae3dUL, 0x26266a4cUL,
-      0x36365a6cUL, 0x3f3f417eUL, 0xf7f702f5UL, 0xcccc4f83UL,
-      0x34345c68UL, 0xa5a5f451UL, 0xe5e534d1UL, 0xf1f108f9UL,
-      0x717193e2UL, 0xd8d873abUL, 0x31315362UL, 0x15153f2aUL,
-      0x04040c08UL, 0xc7c75295UL, 0x23236546UL, 0xc3c35e9dUL,
-      0x18182830UL, 0x9696a137UL, 0x05050f0aUL, 0x9a9ab52fUL,
-      0x0707090eUL, 0x12123624UL, 0x80809b1bUL, 0xe2e23ddfUL,
-      0xebeb26cdUL, 0x2727694eUL, 0xb2b2cd7fUL, 0x75759feaUL,
-      0x09091b12UL, 0x83839e1dUL, 0x2c2c7458UL, 0x1a1a2e34UL,
-      0x1b1b2d36UL, 0x6e6eb2dcUL, 0x5a5aeeb4UL, 0xa0a0fb5bUL,
-      0x5252f6a4UL, 0x3b3b4d76UL, 0xd6d661b7UL, 0xb3b3ce7dUL,
-      0x29297b52UL, 0xe3e33eddUL, 0x2f2f715eUL, 0x84849713UL,
-      0x5353f5a6UL, 0xd1d168b9UL, 0x00000000UL, 0xeded2cc1UL,
-      0x20206040UL, 0xfcfc1fe3UL, 0xb1b1c879UL, 0x5b5bedb6UL,
-      0x6a6abed4UL, 0xcbcb468dUL, 0xbebed967UL, 0x39394b72UL,
-      0x4a4ade94UL, 0x4c4cd498UL, 0x5858e8b0UL, 0xcfcf4a85UL,
-      0xd0d06bbbUL, 0xefef2ac5UL, 0xaaaae54fUL, 0xfbfb16edUL,
-      0x4343c586UL, 0x4d4dd79aUL, 0x33335566UL, 0x85859411UL,
-      0x4545cf8aUL, 0xf9f910e9UL, 0x02020604UL, 0x7f7f81feUL,
-      0x5050f0a0UL, 0x3c3c4478UL, 0x9f9fba25UL, 0xa8a8e34bUL,
-      0x5151f3a2UL, 0xa3a3fe5dUL, 0x4040c080UL, 0x8f8f8a05UL,
-      0x9292ad3fUL, 0x9d9dbc21UL, 0x38384870UL, 0xf5f504f1UL,
-      0xbcbcdf63UL, 0xb6b6c177UL, 0xdada75afUL, 0x21216342UL,
-      0x10103020UL, 0xffff1ae5UL, 0xf3f30efdUL, 0xd2d26dbfUL,
-      0xcdcd4c81UL, 0x0c0c1418UL, 0x13133526UL, 0xecec2fc3UL,
-      0x5f5fe1beUL, 0x9797a235UL, 0x4444cc88UL, 0x1717392eUL,
-      0xc4c45793UL, 0xa7a7f255UL, 0x7e7e82fcUL, 0x3d3d477aUL,
-      0x6464acc8UL, 0x5d5de7baUL, 0x19192b32UL, 0x737395e6UL,
-      0x6060a0c0UL, 0x81819819UL, 0x4f4fd19eUL, 0xdcdc7fa3UL,
-      0x22226644UL, 0x2a2a7e54UL, 0x9090ab3bUL, 0x8888830bUL,
-      0x4646ca8cUL, 0xeeee29c7UL, 0xb8b8d36bUL, 0x14143c28UL,
-      0xdede79a7UL, 0x5e5ee2bcUL, 0x0b0b1d16UL, 0xdbdb76adUL,
-      0xe0e03bdbUL, 0x32325664UL, 0x3a3a4e74UL, 0x0a0a1e14UL,
-      0x4949db92UL, 0x06060a0cUL, 0x24246c48UL, 0x5c5ce4b8UL,
-      0xc2c25d9fUL, 0xd3d36ebdUL, 0xacacef43UL, 0x6262a6c4UL,
-      0x9191a839UL, 0x9595a431UL, 0xe4e437d3UL, 0x79798bf2UL,
-      0xe7e732d5UL, 0xc8c8438bUL, 0x3737596eUL, 0x6d6db7daUL,
-      0x8d8d8c01UL, 0xd5d564b1UL, 0x4e4ed29cUL, 0xa9a9e049UL,
-      0x6c6cb4d8UL, 0x5656faacUL, 0xf4f407f3UL, 0xeaea25cfUL,
-      0x6565afcaUL, 0x7a7a8ef4UL, 0xaeaee947UL, 0x08081810UL,
-      0xbabad56fUL, 0x787888f0UL, 0x25256f4aUL, 0x2e2e725cUL,
-      0x1c1c2438UL, 0xa6a6f157UL, 0xb4b4c773UL, 0xc6c65197UL,
-      0xe8e823cbUL, 0xdddd7ca1UL, 0x74749ce8UL, 0x1f1f213eUL,
-      0x4b4bdd96UL, 0xbdbddc61UL, 0x8b8b860dUL, 0x8a8a850fUL,
-      0x707090e0UL, 0x3e3e427cUL, 0xb5b5c471UL, 0x6666aaccUL,
-      0x4848d890UL, 0x03030506UL, 0xf6f601f7UL, 0x0e0e121cUL,
-      0x6161a3c2UL, 0x35355f6aUL, 0x5757f9aeUL, 0xb9b9d069UL,
-      0x86869117UL, 0xc1c15899UL, 0x1d1d273aUL, 0x9e9eb927UL,
-      0xe1e138d9UL, 0xf8f813ebUL, 0x9898b32bUL, 0x11113322UL,
-      0x6969bbd2UL, 0xd9d970a9UL, 0x8e8e8907UL, 0x9494a733UL,
-      0x9b9bb62dUL, 0x1e1e223cUL, 0x87879215UL, 0xe9e920c9UL,
-      0xcece4987UL, 0x5555ffaaUL, 0x28287850UL, 0xdfdf7aa5UL,
-      0x8c8c8f03UL, 0xa1a1f859UL, 0x89898009UL, 0x0d0d171aUL,
-      0xbfbfda65UL, 0xe6e631d7UL, 0x4242c684UL, 0x6868b8d0UL,
-      0x4141c382UL, 0x9999b029UL, 0x2d2d775aUL, 0x0f0f111eUL,
-      0xb0b0cb7bUL, 0x5454fca8UL, 0xbbbbd66dUL, 0x16163a2cUL
-  };
-  const SWord32 s520 = s0 ^ s4;
-  const SWord8  s521 = (SWord8) (s520 >> 24);
-  const SWord32 s522 = table1[s521];
-  const SWord32 s778 = s1 ^ s5;
-  const SWord8  s779 = (SWord8) (s778 >> 16);
-  const SWord32 s780 = table2[s779];
-  const SWord32 s781 = s522 ^ s780;
-  const SWord32 s1037 = s2 ^ s6;
-  const SWord8  s1038 = (SWord8) (s1037 >> 8);
-  const SWord32 s1039 = table3[s1038];
-  const SWord32 s1040 = s781 ^ s1039;
-  const SWord32 s1296 = s3 ^ s7;
-  const SWord8  s1297 = (SWord8) s1296;
-  const SWord32 s1298 = table4[s1297];
-  const SWord32 s1299 = s1040 ^ s1298;
-  const SWord32 s1300 = (s7 << 8) | (s7 >> 24);
-  const SWord8  s1301 = (SWord8) (s1300 >> 24);
-  const SWord8  s1302 = table0[s1301];
-  const SWord8  s1303 = 1 ^ s1302;
-  const SWord8  s1304 = (SWord8) (s1300 >> 16);
-  const SWord8  s1305 = table0[s1304];
-  const SWord16 s1306 = (((SWord16) s1303) << 8) | ((SWord16) s1305);
-  const SWord8  s1307 = (SWord8) (s1300 >> 8);
-  const SWord8  s1308 = table0[s1307];
-  const SWord8  s1309 = (SWord8) s1300;
-  const SWord8  s1310 = table0[s1309];
-  const SWord16 s1311 = (((SWord16) s1308) << 8) | ((SWord16) s1310);
-  const SWord32 s1312 = (((SWord32) s1306) << 16) | ((SWord32) s1311);
-  const SWord32 s1313 = s4 ^ s1312;
-  const SWord32 s1314 = s1299 ^ s1313;
-  const SWord8  s1315 = (SWord8) (s1314 >> 24);
-  const SWord32 s1316 = table1[s1315];
-  const SWord8  s1317 = (SWord8) (s778 >> 24);
-  const SWord32 s1318 = table1[s1317];
-  const SWord8  s1319 = (SWord8) (s1037 >> 16);
-  const SWord32 s1320 = table2[s1319];
-  const SWord32 s1321 = s1318 ^ s1320;
-  const SWord8  s1322 = (SWord8) (s1296 >> 8);
-  const SWord32 s1323 = table3[s1322];
-  const SWord32 s1324 = s1321 ^ s1323;
-  const SWord8  s1325 = (SWord8) s520;
-  const SWord32 s1326 = table4[s1325];
-  const SWord32 s1327 = s1324 ^ s1326;
-  const SWord32 s1328 = s5 ^ s1313;
-  const SWord32 s1329 = s1327 ^ s1328;
-  const SWord8  s1330 = (SWord8) (s1329 >> 16);
-  const SWord32 s1331 = table2[s1330];
-  const SWord32 s1332 = s1316 ^ s1331;
-  const SWord8  s1333 = (SWord8) (s1037 >> 24);
-  const SWord32 s1334 = table1[s1333];
-  const SWord8  s1335 = (SWord8) (s1296 >> 16);
-  const SWord32 s1336 = table2[s1335];
-  const SWord32 s1337 = s1334 ^ s1336;
-  const SWord8  s1338 = (SWord8) (s520 >> 8);
-  const SWord32 s1339 = table3[s1338];
-  const SWord32 s1340 = s1337 ^ s1339;
-  const SWord8  s1341 = (SWord8) s778;
-  const SWord32 s1342 = table4[s1341];
-  const SWord32 s1343 = s1340 ^ s1342;
-  const SWord32 s1344 = s6 ^ s1328;
-  const SWord32 s1345 = s1343 ^ s1344;
-  const SWord8  s1346 = (SWord8) (s1345 >> 8);
-  const SWord32 s1347 = table3[s1346];
-  const SWord32 s1348 = s1332 ^ s1347;
-  const SWord8  s1349 = (SWord8) (s1296 >> 24);
-  const SWord32 s1350 = table1[s1349];
-  const SWord8  s1351 = (SWord8) (s520 >> 16);
-  const SWord32 s1352 = table2[s1351];
-  const SWord32 s1353 = s1350 ^ s1352;
-  const SWord8  s1354 = (SWord8) (s778 >> 8);
-  const SWord32 s1355 = table3[s1354];
-  const SWord32 s1356 = s1353 ^ s1355;
-  const SWord8  s1357 = (SWord8) s1037;
-  const SWord32 s1358 = table4[s1357];
-  const SWord32 s1359 = s1356 ^ s1358;
-  const SWord32 s1360 = s7 ^ s1344;
-  const SWord32 s1361 = s1359 ^ s1360;
-  const SWord8  s1362 = (SWord8) s1361;
-  const SWord32 s1363 = table4[s1362];
-  const SWord32 s1364 = s1348 ^ s1363;
-  const SWord32 s1365 = (s1360 << 8) | (s1360 >> 24);
-  const SWord8  s1366 = (SWord8) (s1365 >> 24);
-  const SWord8  s1367 = table0[s1366];
-  const SWord8  s1368 = 2 ^ s1367;
-  const SWord8  s1369 = (SWord8) (s1365 >> 16);
-  const SWord8  s1370 = table0[s1369];
-  const SWord16 s1371 = (((SWord16) s1368) << 8) | ((SWord16) s1370);
-  const SWord8  s1372 = (SWord8) (s1365 >> 8);
-  const SWord8  s1373 = table0[s1372];
-  const SWord8  s1374 = (SWord8) s1365;
-  const SWord8  s1375 = table0[s1374];
-  const SWord16 s1376 = (((SWord16) s1373) << 8) | ((SWord16) s1375);
-  const SWord32 s1377 = (((SWord32) s1371) << 16) | ((SWord32) s1376);
-  const SWord32 s1378 = s1313 ^ s1377;
-  const SWord32 s1379 = s1364 ^ s1378;
-  const SWord8  s1380 = (SWord8) (s1379 >> 24);
-  const SWord32 s1381 = table1[s1380];
-  const SWord8  s1382 = (SWord8) (s1329 >> 24);
-  const SWord32 s1383 = table1[s1382];
-  const SWord8  s1384 = (SWord8) (s1345 >> 16);
-  const SWord32 s1385 = table2[s1384];
-  const SWord32 s1386 = s1383 ^ s1385;
-  const SWord8  s1387 = (SWord8) (s1361 >> 8);
-  const SWord32 s1388 = table3[s1387];
-  const SWord32 s1389 = s1386 ^ s1388;
-  const SWord8  s1390 = (SWord8) s1314;
-  const SWord32 s1391 = table4[s1390];
-  const SWord32 s1392 = s1389 ^ s1391;
-  const SWord32 s1393 = s1328 ^ s1378;
-  const SWord32 s1394 = s1392 ^ s1393;
-  const SWord8  s1395 = (SWord8) (s1394 >> 16);
-  const SWord32 s1396 = table2[s1395];
-  const SWord32 s1397 = s1381 ^ s1396;
-  const SWord8  s1398 = (SWord8) (s1345 >> 24);
-  const SWord32 s1399 = table1[s1398];
-  const SWord8  s1400 = (SWord8) (s1361 >> 16);
-  const SWord32 s1401 = table2[s1400];
-  const SWord32 s1402 = s1399 ^ s1401;
-  const SWord8  s1403 = (SWord8) (s1314 >> 8);
-  const SWord32 s1404 = table3[s1403];
-  const SWord32 s1405 = s1402 ^ s1404;
-  const SWord8  s1406 = (SWord8) s1329;
-  const SWord32 s1407 = table4[s1406];
-  const SWord32 s1408 = s1405 ^ s1407;
-  const SWord32 s1409 = s1344 ^ s1393;
-  const SWord32 s1410 = s1408 ^ s1409;
-  const SWord8  s1411 = (SWord8) (s1410 >> 8);
-  const SWord32 s1412 = table3[s1411];
-  const SWord32 s1413 = s1397 ^ s1412;
-  const SWord8  s1414 = (SWord8) (s1361 >> 24);
-  const SWord32 s1415 = table1[s1414];
-  const SWord8  s1416 = (SWord8) (s1314 >> 16);
-  const SWord32 s1417 = table2[s1416];
-  const SWord32 s1418 = s1415 ^ s1417;
-  const SWord8  s1419 = (SWord8) (s1329 >> 8);
-  const SWord32 s1420 = table3[s1419];
-  const SWord32 s1421 = s1418 ^ s1420;
-  const SWord8  s1422 = (SWord8) s1345;
-  const SWord32 s1423 = table4[s1422];
-  const SWord32 s1424 = s1421 ^ s1423;
-  const SWord32 s1425 = s1360 ^ s1409;
-  const SWord32 s1426 = s1424 ^ s1425;
-  const SWord8  s1427 = (SWord8) s1426;
-  const SWord32 s1428 = table4[s1427];
-  const SWord32 s1429 = s1413 ^ s1428;
-  const SWord32 s1430 = (s1425 << 8) | (s1425 >> 24);
-  const SWord8  s1431 = (SWord8) (s1430 >> 24);
-  const SWord8  s1432 = table0[s1431];
-  const SWord8  s1433 = 4 ^ s1432;
-  const SWord8  s1434 = (SWord8) (s1430 >> 16);
-  const SWord8  s1435 = table0[s1434];
-  const SWord16 s1436 = (((SWord16) s1433) << 8) | ((SWord16) s1435);
-  const SWord8  s1437 = (SWord8) (s1430 >> 8);
-  const SWord8  s1438 = table0[s1437];
-  const SWord8  s1439 = (SWord8) s1430;
-  const SWord8  s1440 = table0[s1439];
-  const SWord16 s1441 = (((SWord16) s1438) << 8) | ((SWord16) s1440);
-  const SWord32 s1442 = (((SWord32) s1436) << 16) | ((SWord32) s1441);
-  const SWord32 s1443 = s1378 ^ s1442;
-  const SWord32 s1444 = s1429 ^ s1443;
-  const SWord8  s1445 = (SWord8) (s1444 >> 24);
-  const SWord32 s1446 = table1[s1445];
-  const SWord8  s1447 = (SWord8) (s1394 >> 24);
-  const SWord32 s1448 = table1[s1447];
-  const SWord8  s1449 = (SWord8) (s1410 >> 16);
-  const SWord32 s1450 = table2[s1449];
-  const SWord32 s1451 = s1448 ^ s1450;
-  const SWord8  s1452 = (SWord8) (s1426 >> 8);
-  const SWord32 s1453 = table3[s1452];
-  const SWord32 s1454 = s1451 ^ s1453;
-  const SWord8  s1455 = (SWord8) s1379;
-  const SWord32 s1456 = table4[s1455];
-  const SWord32 s1457 = s1454 ^ s1456;
-  const SWord32 s1458 = s1393 ^ s1443;
-  const SWord32 s1459 = s1457 ^ s1458;
-  const SWord8  s1460 = (SWord8) (s1459 >> 16);
-  const SWord32 s1461 = table2[s1460];
-  const SWord32 s1462 = s1446 ^ s1461;
-  const SWord8  s1463 = (SWord8) (s1410 >> 24);
-  const SWord32 s1464 = table1[s1463];
-  const SWord8  s1465 = (SWord8) (s1426 >> 16);
-  const SWord32 s1466 = table2[s1465];
-  const SWord32 s1467 = s1464 ^ s1466;
-  const SWord8  s1468 = (SWord8) (s1379 >> 8);
-  const SWord32 s1469 = table3[s1468];
-  const SWord32 s1470 = s1467 ^ s1469;
-  const SWord8  s1471 = (SWord8) s1394;
-  const SWord32 s1472 = table4[s1471];
-  const SWord32 s1473 = s1470 ^ s1472;
-  const SWord32 s1474 = s1409 ^ s1458;
-  const SWord32 s1475 = s1473 ^ s1474;
-  const SWord8  s1476 = (SWord8) (s1475 >> 8);
-  const SWord32 s1477 = table3[s1476];
-  const SWord32 s1478 = s1462 ^ s1477;
-  const SWord8  s1479 = (SWord8) (s1426 >> 24);
-  const SWord32 s1480 = table1[s1479];
-  const SWord8  s1481 = (SWord8) (s1379 >> 16);
-  const SWord32 s1482 = table2[s1481];
-  const SWord32 s1483 = s1480 ^ s1482;
-  const SWord8  s1484 = (SWord8) (s1394 >> 8);
-  const SWord32 s1485 = table3[s1484];
-  const SWord32 s1486 = s1483 ^ s1485;
-  const SWord8  s1487 = (SWord8) s1410;
-  const SWord32 s1488 = table4[s1487];
-  const SWord32 s1489 = s1486 ^ s1488;
-  const SWord32 s1490 = s1425 ^ s1474;
-  const SWord32 s1491 = s1489 ^ s1490;
-  const SWord8  s1492 = (SWord8) s1491;
-  const SWord32 s1493 = table4[s1492];
-  const SWord32 s1494 = s1478 ^ s1493;
-  const SWord32 s1495 = (s1490 << 8) | (s1490 >> 24);
-  const SWord8  s1496 = (SWord8) (s1495 >> 24);
-  const SWord8  s1497 = table0[s1496];
-  const SWord8  s1498 = 8 ^ s1497;
-  const SWord8  s1499 = (SWord8) (s1495 >> 16);
-  const SWord8  s1500 = table0[s1499];
-  const SWord16 s1501 = (((SWord16) s1498) << 8) | ((SWord16) s1500);
-  const SWord8  s1502 = (SWord8) (s1495 >> 8);
-  const SWord8  s1503 = table0[s1502];
-  const SWord8  s1504 = (SWord8) s1495;
-  const SWord8  s1505 = table0[s1504];
-  const SWord16 s1506 = (((SWord16) s1503) << 8) | ((SWord16) s1505);
-  const SWord32 s1507 = (((SWord32) s1501) << 16) | ((SWord32) s1506);
-  const SWord32 s1508 = s1443 ^ s1507;
-  const SWord32 s1509 = s1494 ^ s1508;
-  const SWord8  s1510 = (SWord8) (s1509 >> 24);
-  const SWord32 s1511 = table1[s1510];
-  const SWord8  s1512 = (SWord8) (s1459 >> 24);
-  const SWord32 s1513 = table1[s1512];
-  const SWord8  s1514 = (SWord8) (s1475 >> 16);
-  const SWord32 s1515 = table2[s1514];
-  const SWord32 s1516 = s1513 ^ s1515;
-  const SWord8  s1517 = (SWord8) (s1491 >> 8);
-  const SWord32 s1518 = table3[s1517];
-  const SWord32 s1519 = s1516 ^ s1518;
-  const SWord8  s1520 = (SWord8) s1444;
-  const SWord32 s1521 = table4[s1520];
-  const SWord32 s1522 = s1519 ^ s1521;
-  const SWord32 s1523 = s1458 ^ s1508;
-  const SWord32 s1524 = s1522 ^ s1523;
-  const SWord8  s1525 = (SWord8) (s1524 >> 16);
-  const SWord32 s1526 = table2[s1525];
-  const SWord32 s1527 = s1511 ^ s1526;
-  const SWord8  s1528 = (SWord8) (s1475 >> 24);
-  const SWord32 s1529 = table1[s1528];
-  const SWord8  s1530 = (SWord8) (s1491 >> 16);
-  const SWord32 s1531 = table2[s1530];
-  const SWord32 s1532 = s1529 ^ s1531;
-  const SWord8  s1533 = (SWord8) (s1444 >> 8);
-  const SWord32 s1534 = table3[s1533];
-  const SWord32 s1535 = s1532 ^ s1534;
-  const SWord8  s1536 = (SWord8) s1459;
-  const SWord32 s1537 = table4[s1536];
-  const SWord32 s1538 = s1535 ^ s1537;
-  const SWord32 s1539 = s1474 ^ s1523;
-  const SWord32 s1540 = s1538 ^ s1539;
-  const SWord8  s1541 = (SWord8) (s1540 >> 8);
-  const SWord32 s1542 = table3[s1541];
-  const SWord32 s1543 = s1527 ^ s1542;
-  const SWord8  s1544 = (SWord8) (s1491 >> 24);
-  const SWord32 s1545 = table1[s1544];
-  const SWord8  s1546 = (SWord8) (s1444 >> 16);
-  const SWord32 s1547 = table2[s1546];
-  const SWord32 s1548 = s1545 ^ s1547;
-  const SWord8  s1549 = (SWord8) (s1459 >> 8);
-  const SWord32 s1550 = table3[s1549];
-  const SWord32 s1551 = s1548 ^ s1550;
-  const SWord8  s1552 = (SWord8) s1475;
-  const SWord32 s1553 = table4[s1552];
-  const SWord32 s1554 = s1551 ^ s1553;
-  const SWord32 s1555 = s1490 ^ s1539;
-  const SWord32 s1556 = s1554 ^ s1555;
-  const SWord8  s1557 = (SWord8) s1556;
-  const SWord32 s1558 = table4[s1557];
-  const SWord32 s1559 = s1543 ^ s1558;
-  const SWord32 s1560 = (s1555 << 8) | (s1555 >> 24);
-  const SWord8  s1561 = (SWord8) (s1560 >> 24);
-  const SWord8  s1562 = table0[s1561];
-  const SWord8  s1563 = 16 ^ s1562;
-  const SWord8  s1564 = (SWord8) (s1560 >> 16);
-  const SWord8  s1565 = table0[s1564];
-  const SWord16 s1566 = (((SWord16) s1563) << 8) | ((SWord16) s1565);
-  const SWord8  s1567 = (SWord8) (s1560 >> 8);
-  const SWord8  s1568 = table0[s1567];
-  const SWord8  s1569 = (SWord8) s1560;
-  const SWord8  s1570 = table0[s1569];
-  const SWord16 s1571 = (((SWord16) s1568) << 8) | ((SWord16) s1570);
-  const SWord32 s1572 = (((SWord32) s1566) << 16) | ((SWord32) s1571);
-  const SWord32 s1573 = s1508 ^ s1572;
-  const SWord32 s1574 = s1559 ^ s1573;
-  const SWord8  s1575 = (SWord8) (s1574 >> 24);
-  const SWord32 s1576 = table1[s1575];
-  const SWord8  s1577 = (SWord8) (s1524 >> 24);
-  const SWord32 s1578 = table1[s1577];
-  const SWord8  s1579 = (SWord8) (s1540 >> 16);
-  const SWord32 s1580 = table2[s1579];
-  const SWord32 s1581 = s1578 ^ s1580;
-  const SWord8  s1582 = (SWord8) (s1556 >> 8);
-  const SWord32 s1583 = table3[s1582];
-  const SWord32 s1584 = s1581 ^ s1583;
-  const SWord8  s1585 = (SWord8) s1509;
-  const SWord32 s1586 = table4[s1585];
-  const SWord32 s1587 = s1584 ^ s1586;
-  const SWord32 s1588 = s1523 ^ s1573;
-  const SWord32 s1589 = s1587 ^ s1588;
-  const SWord8  s1590 = (SWord8) (s1589 >> 16);
-  const SWord32 s1591 = table2[s1590];
-  const SWord32 s1592 = s1576 ^ s1591;
-  const SWord8  s1593 = (SWord8) (s1540 >> 24);
-  const SWord32 s1594 = table1[s1593];
-  const SWord8  s1595 = (SWord8) (s1556 >> 16);
-  const SWord32 s1596 = table2[s1595];
-  const SWord32 s1597 = s1594 ^ s1596;
-  const SWord8  s1598 = (SWord8) (s1509 >> 8);
-  const SWord32 s1599 = table3[s1598];
-  const SWord32 s1600 = s1597 ^ s1599;
-  const SWord8  s1601 = (SWord8) s1524;
-  const SWord32 s1602 = table4[s1601];
-  const SWord32 s1603 = s1600 ^ s1602;
-  const SWord32 s1604 = s1539 ^ s1588;
-  const SWord32 s1605 = s1603 ^ s1604;
-  const SWord8  s1606 = (SWord8) (s1605 >> 8);
-  const SWord32 s1607 = table3[s1606];
-  const SWord32 s1608 = s1592 ^ s1607;
-  const SWord8  s1609 = (SWord8) (s1556 >> 24);
-  const SWord32 s1610 = table1[s1609];
-  const SWord8  s1611 = (SWord8) (s1509 >> 16);
-  const SWord32 s1612 = table2[s1611];
-  const SWord32 s1613 = s1610 ^ s1612;
-  const SWord8  s1614 = (SWord8) (s1524 >> 8);
-  const SWord32 s1615 = table3[s1614];
-  const SWord32 s1616 = s1613 ^ s1615;
-  const SWord8  s1617 = (SWord8) s1540;
-  const SWord32 s1618 = table4[s1617];
-  const SWord32 s1619 = s1616 ^ s1618;
-  const SWord32 s1620 = s1555 ^ s1604;
-  const SWord32 s1621 = s1619 ^ s1620;
-  const SWord8  s1622 = (SWord8) s1621;
-  const SWord32 s1623 = table4[s1622];
-  const SWord32 s1624 = s1608 ^ s1623;
-  const SWord32 s1625 = (s1620 << 8) | (s1620 >> 24);
-  const SWord8  s1626 = (SWord8) (s1625 >> 24);
-  const SWord8  s1627 = table0[s1626];
-  const SWord8  s1628 = 32 ^ s1627;
-  const SWord8  s1629 = (SWord8) (s1625 >> 16);
-  const SWord8  s1630 = table0[s1629];
-  const SWord16 s1631 = (((SWord16) s1628) << 8) | ((SWord16) s1630);
-  const SWord8  s1632 = (SWord8) (s1625 >> 8);
-  const SWord8  s1633 = table0[s1632];
-  const SWord8  s1634 = (SWord8) s1625;
-  const SWord8  s1635 = table0[s1634];
-  const SWord16 s1636 = (((SWord16) s1633) << 8) | ((SWord16) s1635);
-  const SWord32 s1637 = (((SWord32) s1631) << 16) | ((SWord32) s1636);
-  const SWord32 s1638 = s1573 ^ s1637;
-  const SWord32 s1639 = s1624 ^ s1638;
-  const SWord8  s1640 = (SWord8) (s1639 >> 24);
-  const SWord32 s1641 = table1[s1640];
-  const SWord8  s1642 = (SWord8) (s1589 >> 24);
-  const SWord32 s1643 = table1[s1642];
-  const SWord8  s1644 = (SWord8) (s1605 >> 16);
-  const SWord32 s1645 = table2[s1644];
-  const SWord32 s1646 = s1643 ^ s1645;
-  const SWord8  s1647 = (SWord8) (s1621 >> 8);
-  const SWord32 s1648 = table3[s1647];
-  const SWord32 s1649 = s1646 ^ s1648;
-  const SWord8  s1650 = (SWord8) s1574;
-  const SWord32 s1651 = table4[s1650];
-  const SWord32 s1652 = s1649 ^ s1651;
-  const SWord32 s1653 = s1588 ^ s1638;
-  const SWord32 s1654 = s1652 ^ s1653;
-  const SWord8  s1655 = (SWord8) (s1654 >> 16);
-  const SWord32 s1656 = table2[s1655];
-  const SWord32 s1657 = s1641 ^ s1656;
-  const SWord8  s1658 = (SWord8) (s1605 >> 24);
-  const SWord32 s1659 = table1[s1658];
-  const SWord8  s1660 = (SWord8) (s1621 >> 16);
-  const SWord32 s1661 = table2[s1660];
-  const SWord32 s1662 = s1659 ^ s1661;
-  const SWord8  s1663 = (SWord8) (s1574 >> 8);
-  const SWord32 s1664 = table3[s1663];
-  const SWord32 s1665 = s1662 ^ s1664;
-  const SWord8  s1666 = (SWord8) s1589;
-  const SWord32 s1667 = table4[s1666];
-  const SWord32 s1668 = s1665 ^ s1667;
-  const SWord32 s1669 = s1604 ^ s1653;
-  const SWord32 s1670 = s1668 ^ s1669;
-  const SWord8  s1671 = (SWord8) (s1670 >> 8);
-  const SWord32 s1672 = table3[s1671];
-  const SWord32 s1673 = s1657 ^ s1672;
-  const SWord8  s1674 = (SWord8) (s1621 >> 24);
-  const SWord32 s1675 = table1[s1674];
-  const SWord8  s1676 = (SWord8) (s1574 >> 16);
-  const SWord32 s1677 = table2[s1676];
-  const SWord32 s1678 = s1675 ^ s1677;
-  const SWord8  s1679 = (SWord8) (s1589 >> 8);
-  const SWord32 s1680 = table3[s1679];
-  const SWord32 s1681 = s1678 ^ s1680;
-  const SWord8  s1682 = (SWord8) s1605;
-  const SWord32 s1683 = table4[s1682];
-  const SWord32 s1684 = s1681 ^ s1683;
-  const SWord32 s1685 = s1620 ^ s1669;
-  const SWord32 s1686 = s1684 ^ s1685;
-  const SWord8  s1687 = (SWord8) s1686;
-  const SWord32 s1688 = table4[s1687];
-  const SWord32 s1689 = s1673 ^ s1688;
-  const SWord32 s1690 = (s1685 << 8) | (s1685 >> 24);
-  const SWord8  s1691 = (SWord8) (s1690 >> 24);
-  const SWord8  s1692 = table0[s1691];
-  const SWord8  s1693 = 64 ^ s1692;
-  const SWord8  s1694 = (SWord8) (s1690 >> 16);
-  const SWord8  s1695 = table0[s1694];
-  const SWord16 s1696 = (((SWord16) s1693) << 8) | ((SWord16) s1695);
-  const SWord8  s1697 = (SWord8) (s1690 >> 8);
-  const SWord8  s1698 = table0[s1697];
-  const SWord8  s1699 = (SWord8) s1690;
-  const SWord8  s1700 = table0[s1699];
-  const SWord16 s1701 = (((SWord16) s1698) << 8) | ((SWord16) s1700);
-  const SWord32 s1702 = (((SWord32) s1696) << 16) | ((SWord32) s1701);
-  const SWord32 s1703 = s1638 ^ s1702;
-  const SWord32 s1704 = s1689 ^ s1703;
-  const SWord8  s1705 = (SWord8) (s1704 >> 24);
-  const SWord32 s1706 = table1[s1705];
-  const SWord8  s1707 = (SWord8) (s1654 >> 24);
-  const SWord32 s1708 = table1[s1707];
-  const SWord8  s1709 = (SWord8) (s1670 >> 16);
-  const SWord32 s1710 = table2[s1709];
-  const SWord32 s1711 = s1708 ^ s1710;
-  const SWord8  s1712 = (SWord8) (s1686 >> 8);
-  const SWord32 s1713 = table3[s1712];
-  const SWord32 s1714 = s1711 ^ s1713;
-  const SWord8  s1715 = (SWord8) s1639;
-  const SWord32 s1716 = table4[s1715];
-  const SWord32 s1717 = s1714 ^ s1716;
-  const SWord32 s1718 = s1653 ^ s1703;
-  const SWord32 s1719 = s1717 ^ s1718;
-  const SWord8  s1720 = (SWord8) (s1719 >> 16);
-  const SWord32 s1721 = table2[s1720];
-  const SWord32 s1722 = s1706 ^ s1721;
-  const SWord8  s1723 = (SWord8) (s1670 >> 24);
-  const SWord32 s1724 = table1[s1723];
-  const SWord8  s1725 = (SWord8) (s1686 >> 16);
-  const SWord32 s1726 = table2[s1725];
-  const SWord32 s1727 = s1724 ^ s1726;
-  const SWord8  s1728 = (SWord8) (s1639 >> 8);
-  const SWord32 s1729 = table3[s1728];
-  const SWord32 s1730 = s1727 ^ s1729;
-  const SWord8  s1731 = (SWord8) s1654;
-  const SWord32 s1732 = table4[s1731];
-  const SWord32 s1733 = s1730 ^ s1732;
-  const SWord32 s1734 = s1669 ^ s1718;
-  const SWord32 s1735 = s1733 ^ s1734;
-  const SWord8  s1736 = (SWord8) (s1735 >> 8);
-  const SWord32 s1737 = table3[s1736];
-  const SWord32 s1738 = s1722 ^ s1737;
-  const SWord8  s1739 = (SWord8) (s1686 >> 24);
-  const SWord32 s1740 = table1[s1739];
-  const SWord8  s1741 = (SWord8) (s1639 >> 16);
-  const SWord32 s1742 = table2[s1741];
-  const SWord32 s1743 = s1740 ^ s1742;
-  const SWord8  s1744 = (SWord8) (s1654 >> 8);
-  const SWord32 s1745 = table3[s1744];
-  const SWord32 s1746 = s1743 ^ s1745;
-  const SWord8  s1747 = (SWord8) s1670;
-  const SWord32 s1748 = table4[s1747];
-  const SWord32 s1749 = s1746 ^ s1748;
-  const SWord32 s1750 = s1685 ^ s1734;
-  const SWord32 s1751 = s1749 ^ s1750;
-  const SWord8  s1752 = (SWord8) s1751;
-  const SWord32 s1753 = table4[s1752];
-  const SWord32 s1754 = s1738 ^ s1753;
-  const SWord32 s1755 = (s1750 << 8) | (s1750 >> 24);
-  const SWord8  s1756 = (SWord8) (s1755 >> 24);
-  const SWord8  s1757 = table0[s1756];
-  const SWord8  s1758 = 128 ^ s1757;
-  const SWord8  s1759 = (SWord8) (s1755 >> 16);
-  const SWord8  s1760 = table0[s1759];
-  const SWord16 s1761 = (((SWord16) s1758) << 8) | ((SWord16) s1760);
-  const SWord8  s1762 = (SWord8) (s1755 >> 8);
-  const SWord8  s1763 = table0[s1762];
-  const SWord8  s1764 = (SWord8) s1755;
-  const SWord8  s1765 = table0[s1764];
-  const SWord16 s1766 = (((SWord16) s1763) << 8) | ((SWord16) s1765);
-  const SWord32 s1767 = (((SWord32) s1761) << 16) | ((SWord32) s1766);
-  const SWord32 s1768 = s1703 ^ s1767;
-  const SWord32 s1769 = s1754 ^ s1768;
-  const SWord8  s1770 = (SWord8) (s1769 >> 24);
-  const SWord32 s1771 = table1[s1770];
-  const SWord8  s1772 = (SWord8) (s1719 >> 24);
-  const SWord32 s1773 = table1[s1772];
-  const SWord8  s1774 = (SWord8) (s1735 >> 16);
-  const SWord32 s1775 = table2[s1774];
-  const SWord32 s1776 = s1773 ^ s1775;
-  const SWord8  s1777 = (SWord8) (s1751 >> 8);
-  const SWord32 s1778 = table3[s1777];
-  const SWord32 s1779 = s1776 ^ s1778;
-  const SWord8  s1780 = (SWord8) s1704;
-  const SWord32 s1781 = table4[s1780];
-  const SWord32 s1782 = s1779 ^ s1781;
-  const SWord32 s1783 = s1718 ^ s1768;
-  const SWord32 s1784 = s1782 ^ s1783;
-  const SWord8  s1785 = (SWord8) (s1784 >> 16);
-  const SWord32 s1786 = table2[s1785];
-  const SWord32 s1787 = s1771 ^ s1786;
-  const SWord8  s1788 = (SWord8) (s1735 >> 24);
-  const SWord32 s1789 = table1[s1788];
-  const SWord8  s1790 = (SWord8) (s1751 >> 16);
-  const SWord32 s1791 = table2[s1790];
-  const SWord32 s1792 = s1789 ^ s1791;
-  const SWord8  s1793 = (SWord8) (s1704 >> 8);
-  const SWord32 s1794 = table3[s1793];
-  const SWord32 s1795 = s1792 ^ s1794;
-  const SWord8  s1796 = (SWord8) s1719;
-  const SWord32 s1797 = table4[s1796];
-  const SWord32 s1798 = s1795 ^ s1797;
-  const SWord32 s1799 = s1734 ^ s1783;
-  const SWord32 s1800 = s1798 ^ s1799;
-  const SWord8  s1801 = (SWord8) (s1800 >> 8);
-  const SWord32 s1802 = table3[s1801];
-  const SWord32 s1803 = s1787 ^ s1802;
-  const SWord8  s1804 = (SWord8) (s1751 >> 24);
-  const SWord32 s1805 = table1[s1804];
-  const SWord8  s1806 = (SWord8) (s1704 >> 16);
-  const SWord32 s1807 = table2[s1806];
-  const SWord32 s1808 = s1805 ^ s1807;
-  const SWord8  s1809 = (SWord8) (s1719 >> 8);
-  const SWord32 s1810 = table3[s1809];
-  const SWord32 s1811 = s1808 ^ s1810;
-  const SWord8  s1812 = (SWord8) s1735;
-  const SWord32 s1813 = table4[s1812];
-  const SWord32 s1814 = s1811 ^ s1813;
-  const SWord32 s1815 = s1750 ^ s1799;
-  const SWord32 s1816 = s1814 ^ s1815;
-  const SWord8  s1817 = (SWord8) s1816;
-  const SWord32 s1818 = table4[s1817];
-  const SWord32 s1819 = s1803 ^ s1818;
-  const SWord32 s1820 = (s1815 << 8) | (s1815 >> 24);
-  const SWord8  s1821 = (SWord8) (s1820 >> 24);
-  const SWord8  s1822 = table0[s1821];
-  const SWord8  s1823 = 27 ^ s1822;
-  const SWord8  s1824 = (SWord8) (s1820 >> 16);
-  const SWord8  s1825 = table0[s1824];
-  const SWord16 s1826 = (((SWord16) s1823) << 8) | ((SWord16) s1825);
-  const SWord8  s1827 = (SWord8) (s1820 >> 8);
-  const SWord8  s1828 = table0[s1827];
-  const SWord8  s1829 = (SWord8) s1820;
-  const SWord8  s1830 = table0[s1829];
-  const SWord16 s1831 = (((SWord16) s1828) << 8) | ((SWord16) s1830);
-  const SWord32 s1832 = (((SWord32) s1826) << 16) | ((SWord32) s1831);
-  const SWord32 s1833 = s1768 ^ s1832;
-  const SWord32 s1834 = s1819 ^ s1833;
-  const SWord8  s1835 = (SWord8) (s1834 >> 24);
-  const SWord8  s1836 = table0[s1835];
-  const SWord8  s1837 = (SWord8) (s1784 >> 24);
-  const SWord32 s1838 = table1[s1837];
-  const SWord8  s1839 = (SWord8) (s1800 >> 16);
-  const SWord32 s1840 = table2[s1839];
-  const SWord32 s1841 = s1838 ^ s1840;
-  const SWord8  s1842 = (SWord8) (s1816 >> 8);
-  const SWord32 s1843 = table3[s1842];
-  const SWord32 s1844 = s1841 ^ s1843;
-  const SWord8  s1845 = (SWord8) s1769;
-  const SWord32 s1846 = table4[s1845];
-  const SWord32 s1847 = s1844 ^ s1846;
-  const SWord32 s1848 = s1783 ^ s1833;
-  const SWord32 s1849 = s1847 ^ s1848;
-  const SWord8  s1850 = (SWord8) (s1849 >> 16);
-  const SWord8  s1851 = table0[s1850];
-  const SWord16 s1852 = (((SWord16) s1836) << 8) | ((SWord16) s1851);
-  const SWord8  s1853 = (SWord8) (s1800 >> 24);
-  const SWord32 s1854 = table1[s1853];
-  const SWord8  s1855 = (SWord8) (s1816 >> 16);
-  const SWord32 s1856 = table2[s1855];
-  const SWord32 s1857 = s1854 ^ s1856;
-  const SWord8  s1858 = (SWord8) (s1769 >> 8);
-  const SWord32 s1859 = table3[s1858];
-  const SWord32 s1860 = s1857 ^ s1859;
-  const SWord8  s1861 = (SWord8) s1784;
-  const SWord32 s1862 = table4[s1861];
-  const SWord32 s1863 = s1860 ^ s1862;
-  const SWord32 s1864 = s1799 ^ s1848;
-  const SWord32 s1865 = s1863 ^ s1864;
-  const SWord8  s1866 = (SWord8) (s1865 >> 8);
-  const SWord8  s1867 = table0[s1866];
-  const SWord8  s1868 = (SWord8) (s1816 >> 24);
-  const SWord32 s1869 = table1[s1868];
-  const SWord8  s1870 = (SWord8) (s1769 >> 16);
-  const SWord32 s1871 = table2[s1870];
-  const SWord32 s1872 = s1869 ^ s1871;
-  const SWord8  s1873 = (SWord8) (s1784 >> 8);
-  const SWord32 s1874 = table3[s1873];
-  const SWord32 s1875 = s1872 ^ s1874;
-  const SWord8  s1876 = (SWord8) s1800;
-  const SWord32 s1877 = table4[s1876];
-  const SWord32 s1878 = s1875 ^ s1877;
-  const SWord32 s1879 = s1815 ^ s1864;
-  const SWord32 s1880 = s1878 ^ s1879;
-  const SWord8  s1881 = (SWord8) s1880;
-  const SWord8  s1882 = table0[s1881];
-  const SWord16 s1883 = (((SWord16) s1867) << 8) | ((SWord16) s1882);
-  const SWord32 s1884 = (((SWord32) s1852) << 16) | ((SWord32) s1883);
-  const SWord32 s1885 = (s1879 << 8) | (s1879 >> 24);
-  const SWord8  s1886 = (SWord8) (s1885 >> 24);
-  const SWord8  s1887 = table0[s1886];
-  const SWord8  s1888 = 54 ^ s1887;
-  const SWord8  s1889 = (SWord8) (s1885 >> 16);
-  const SWord8  s1890 = table0[s1889];
-  const SWord16 s1891 = (((SWord16) s1888) << 8) | ((SWord16) s1890);
-  const SWord8  s1892 = (SWord8) (s1885 >> 8);
-  const SWord8  s1893 = table0[s1892];
-  const SWord8  s1894 = (SWord8) s1885;
-  const SWord8  s1895 = table0[s1894];
-  const SWord16 s1896 = (((SWord16) s1893) << 8) | ((SWord16) s1895);
-  const SWord32 s1897 = (((SWord32) s1891) << 16) | ((SWord32) s1896);
-  const SWord32 s1898 = s1833 ^ s1897;
-  const SWord32 s1899 = s1884 ^ s1898;
-  const SWord8  s1900 = (SWord8) (s1849 >> 24);
-  const SWord8  s1901 = table0[s1900];
-  const SWord8  s1902 = (SWord8) (s1865 >> 16);
-  const SWord8  s1903 = table0[s1902];
-  const SWord16 s1904 = (((SWord16) s1901) << 8) | ((SWord16) s1903);
-  const SWord8  s1905 = (SWord8) (s1880 >> 8);
-  const SWord8  s1906 = table0[s1905];
-  const SWord8  s1907 = (SWord8) s1834;
-  const SWord8  s1908 = table0[s1907];
-  const SWord16 s1909 = (((SWord16) s1906) << 8) | ((SWord16) s1908);
-  const SWord32 s1910 = (((SWord32) s1904) << 16) | ((SWord32) s1909);
-  const SWord32 s1911 = s1848 ^ s1898;
-  const SWord32 s1912 = s1910 ^ s1911;
-  const SWord8  s1913 = (SWord8) (s1865 >> 24);
-  const SWord8  s1914 = table0[s1913];
-  const SWord8  s1915 = (SWord8) (s1880 >> 16);
-  const SWord8  s1916 = table0[s1915];
-  const SWord16 s1917 = (((SWord16) s1914) << 8) | ((SWord16) s1916);
-  const SWord8  s1918 = (SWord8) (s1834 >> 8);
-  const SWord8  s1919 = table0[s1918];
-  const SWord8  s1920 = (SWord8) s1849;
-  const SWord8  s1921 = table0[s1920];
-  const SWord16 s1922 = (((SWord16) s1919) << 8) | ((SWord16) s1921);
-  const SWord32 s1923 = (((SWord32) s1917) << 16) | ((SWord32) s1922);
-  const SWord32 s1924 = s1864 ^ s1911;
-  const SWord32 s1925 = s1923 ^ s1924;
-  const SWord8  s1926 = (SWord8) (s1880 >> 24);
-  const SWord8  s1927 = table0[s1926];
-  const SWord8  s1928 = (SWord8) (s1834 >> 16);
-  const SWord8  s1929 = table0[s1928];
-  const SWord16 s1930 = (((SWord16) s1927) << 8) | ((SWord16) s1929);
-  const SWord8  s1931 = (SWord8) (s1849 >> 8);
-  const SWord8  s1932 = table0[s1931];
-  const SWord8  s1933 = (SWord8) s1865;
-  const SWord8  s1934 = table0[s1933];
-  const SWord16 s1935 = (((SWord16) s1932) << 8) | ((SWord16) s1934);
-  const SWord32 s1936 = (((SWord32) s1930) << 16) | ((SWord32) s1935);
-  const SWord32 s1937 = s1879 ^ s1924;
-  const SWord32 s1938 = s1936 ^ s1937;
-
-  ct[0] = s1899;
-  ct[1] = s1912;
-  ct[2] = s1925;
-  ct[3] = s1938;
+aes128Enc_driver.o: aes128Enc_driver.c aes128Enc.h
+	${CC} ${CCFLAGS} -c $< -o $@
+
+aes128Enc_driver: aes128Enc.o aes128Enc_driver.o
+	${CC} ${CCFLAGS} $^ -o $@ ${LDFLAGS}
+
+clean:
+	rm -f *.o
+
+veryclean: clean
+	rm -f aes128Enc_driver
+== END: "Makefile" ==================
+== BEGIN: "aes128Enc.h" ================
+/* Header file for aes128Enc. Automatically generated by SBV. Do not edit! */
+
+#ifndef SBV_GENERATED_aes128Enc_HEADER_INCLUDED
+#define SBV_GENERATED_aes128Enc_HEADER_INCLUDED
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <math.h>
+
+/* Floating-point calling convention:
+ * Enter generated code in FE_TONEAREST (round-to-nearest, ties-to-even).
+ * Callbacks must preserve this mode before returning or re-entering.
+ * Generated code does not check or change the hardware rounding mode.
+ * Custom builds must disable implicit FP contraction, including at LTO link time.
+ */
+
+/* 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 prototype: */
+void aes128Enc(const SWord32 *pt, const SWord32 *key, SWord32 *ct);
+
+#endif /* SBV_GENERATED_aes128Enc_HEADER_INCLUDED */
+== END: "aes128Enc.h" ==================
+== BEGIN: "aes128Enc_driver.c" ================
+/* Example driver program for aes128Enc. */
+/* Automatically generated by SBV. Edit as you see fit! */
+
+#include <stdio.h>
+#include "aes128Enc.h"
+
+int main(void)
+{
+  const SWord32 sbv_driver_input_0[4] = {
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL
+  };
+
+  printf("Contents of input array pt:\n");
+  int sbv_driver_input_0_ctr;
+  for(sbv_driver_input_0_ctr = 0; sbv_driver_input_0_ctr < 4 ; ++sbv_driver_input_0_ctr)
+  { printf("  pt[%1d] = ", sbv_driver_input_0_ctr);
+    printf("0x%08"PRIx32"UL", sbv_driver_input_0[sbv_driver_input_0_ctr]);
+    printf("\n");
+  }
+
+  const SWord32 sbv_driver_input_1[4] = {
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL
+  };
+
+  printf("Contents of input array key:\n");
+  int sbv_driver_input_1_ctr;
+  for(sbv_driver_input_1_ctr = 0; sbv_driver_input_1_ctr < 4 ; ++sbv_driver_input_1_ctr)
+  { printf("  key[%1d] = ", sbv_driver_input_1_ctr);
+    printf("0x%08"PRIx32"UL", sbv_driver_input_1[sbv_driver_input_1_ctr]);
+    printf("\n");
+  }
+
+  SWord32 sbv_driver_output_0[4];
+
+  aes128Enc(sbv_driver_input_0, sbv_driver_input_1,
+            sbv_driver_output_0);
+
+  printf("aes128Enc(pt, key, ct) ->\n");
+  int sbv_driver_output_0_ctr;
+  for(sbv_driver_output_0_ctr = 0; sbv_driver_output_0_ctr < 4 ; ++sbv_driver_output_0_ctr)
+  { printf("  ct[%1d] = ", sbv_driver_output_0_ctr);
+    printf("0x%08"PRIx32"UL", sbv_driver_output_0[sbv_driver_output_0_ctr]);
+    printf("\n");
+  }
+
+  return 0;
+}
+== END: "aes128Enc_driver.c" ==================
+== BEGIN: "aes128Enc.c" ================
+/* File: "aes128Enc.c". Automatically generated by SBV. Do not edit! */
+
+#include "aes128Enc.h"
+
+/* Exact bit-vector runtime. All arithmetic is modulo the declared width. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_31_24_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 24)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_23_16_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 16)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_15_8_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 8)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_7_0_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord32 sbv_bv_u32_rotl(SWord32 a, uint64_t amount)
+{
+  amount %= 32;
+  if (amount == 0) return a;
+  return (SWord32) ((((uint64_t) (SWord32) a) << amount) | (((uint64_t) (SWord32) a) >> (32 - amount)));
+}
+
+static inline SBV_CGEN_UNUSED SWord32 sbv_bv_u32_rotr(SWord32 a, uint64_t amount)
+{
+  amount %= 32;
+  if (amount == 0) return a;
+  return (SWord32) ((((uint64_t) (SWord32) a) >> amount) | (((uint64_t) (SWord32) a) << (32 - amount)));
+}
+
+static inline SBV_CGEN_UNUSED SWord16 sbv_bv_join_u8_u8_u16(SWord8 high, SWord8 low)
+{
+  SWord16 r = (SWord16) 0; uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord16) ((uint64_t) r | ((uint64_t) (((((uint64_t) low) >> (i)) & UINT64_C(1)) != 0) << (i))); }
+  for (i = 0; i < 8; ++i) { r = (SWord16) ((uint64_t) r | ((uint64_t) (((((uint64_t) high) >> (i)) & UINT64_C(1)) != 0) << (i + 8))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord32 sbv_bv_join_u16_u16_u32(SWord16 high, SWord16 low)
+{
+  SWord32 r = (SWord32) 0; uint64_t i;
+  for (i = 0; i < 16; ++i) { r = (SWord32) ((uint64_t) r | ((uint64_t) (((((uint64_t) low) >> (i)) & UINT64_C(1)) != 0) << (i))); }
+  for (i = 0; i < 16; ++i) { r = (SWord32) ((uint64_t) r | ((uint64_t) (((((uint64_t) high) >> (i)) & UINT64_C(1)) != 0) << (i + 16))); }
+  return r;
+}
+
+
+void aes128Enc(const SWord32 *sbv_input_0,
+               const SWord32 *sbv_input_1, SWord32 *sbv_output_0)
+{
+  const SWord32 s0 = sbv_input_0[0];
+  const SWord32 s1 = sbv_input_0[1];
+  const SWord32 s2 = sbv_input_0[2];
+  const SWord32 s3 = sbv_input_0[3];
+  const SWord32 s4 = sbv_input_1[0];
+  const SWord32 s5 = sbv_input_1[1];
+  const SWord32 s6 = sbv_input_1[2];
+  const SWord32 s7 = sbv_input_1[3];
+  const SWord32 s520 = s0 ^ s4;
+  const SWord8  s521 = sbv_bv_extract_u32_31_24_u8(s520);
+  const SWord32 s778 = s1 ^ s5;
+  const SWord8  s779 = sbv_bv_extract_u32_23_16_u8(s778);
+  const SWord32 s1037 = s2 ^ s6;
+  const SWord8  s1038 = sbv_bv_extract_u32_15_8_u8(s1037);
+  const SWord32 s1296 = s3 ^ s7;
+  const SWord8  s1297 = sbv_bv_extract_u32_7_0_u8(s1296);
+  const SWord32 s1300 = sbv_bv_u32_rotl(s7, 8);
+  const SWord8  s1301 = sbv_bv_extract_u32_31_24_u8(s1300);
+  const SWord8  s1304 = sbv_bv_extract_u32_23_16_u8(s1300);
+  const SWord8  s1307 = sbv_bv_extract_u32_15_8_u8(s1300);
+  const SWord8  s1309 = sbv_bv_extract_u32_7_0_u8(s1300);
+  const SWord8  s1317 = sbv_bv_extract_u32_31_24_u8(s778);
+  const SWord8  s1319 = sbv_bv_extract_u32_23_16_u8(s1037);
+  const SWord8  s1322 = sbv_bv_extract_u32_15_8_u8(s1296);
+  const SWord8  s1325 = sbv_bv_extract_u32_7_0_u8(s520);
+  const SWord8  s1333 = sbv_bv_extract_u32_31_24_u8(s1037);
+  const SWord8  s1335 = sbv_bv_extract_u32_23_16_u8(s1296);
+  const SWord8  s1338 = sbv_bv_extract_u32_15_8_u8(s520);
+  const SWord8  s1341 = sbv_bv_extract_u32_7_0_u8(s778);
+  const SWord8  s1349 = sbv_bv_extract_u32_31_24_u8(s1296);
+  const SWord8  s1351 = sbv_bv_extract_u32_23_16_u8(s520);
+  const SWord8  s1354 = sbv_bv_extract_u32_15_8_u8(s778);
+  const SWord8  s1357 = sbv_bv_extract_u32_7_0_u8(s1037);
+        SWord32 s522;
+        SWord32 s780;
+        SWord32 s781;
+        SWord32 s1039;
+        SWord32 s1040;
+        SWord32 s1298;
+        SWord32 s1299;
+        SWord8  s1302;
+        SWord8  s1303;
+        SWord8  s1305;
+        SWord16 s1306;
+        SWord8  s1308;
+        SWord8  s1310;
+        SWord16 s1311;
+        SWord32 s1312;
+        SWord32 s1313;
+        SWord32 s1314;
+        SWord8  s1315;
+        SWord32 s1316;
+        SWord32 s1318;
+        SWord32 s1320;
+        SWord32 s1321;
+        SWord32 s1323;
+        SWord32 s1324;
+        SWord32 s1326;
+        SWord32 s1327;
+        SWord32 s1328;
+        SWord32 s1329;
+        SWord8  s1330;
+        SWord32 s1331;
+        SWord32 s1332;
+        SWord32 s1334;
+        SWord32 s1336;
+        SWord32 s1337;
+        SWord32 s1339;
+        SWord32 s1340;
+        SWord32 s1342;
+        SWord32 s1343;
+        SWord32 s1344;
+        SWord32 s1345;
+        SWord8  s1346;
+        SWord32 s1347;
+        SWord32 s1348;
+        SWord32 s1350;
+        SWord32 s1352;
+        SWord32 s1353;
+        SWord32 s1355;
+        SWord32 s1356;
+        SWord32 s1358;
+        SWord32 s1359;
+        SWord32 s1360;
+        SWord32 s1361;
+        SWord8  s1362;
+        SWord32 s1363;
+        SWord32 s1364;
+        SWord32 s1365;
+        SWord8  s1366;
+        SWord8  s1367;
+        SWord8  s1368;
+        SWord8  s1369;
+        SWord8  s1370;
+        SWord16 s1371;
+        SWord8  s1372;
+        SWord8  s1373;
+        SWord8  s1374;
+        SWord8  s1375;
+        SWord16 s1376;
+        SWord32 s1377;
+        SWord32 s1378;
+        SWord32 s1379;
+        SWord8  s1380;
+        SWord32 s1381;
+        SWord8  s1382;
+        SWord32 s1383;
+        SWord8  s1384;
+        SWord32 s1385;
+        SWord32 s1386;
+        SWord8  s1387;
+        SWord32 s1388;
+        SWord32 s1389;
+        SWord8  s1390;
+        SWord32 s1391;
+        SWord32 s1392;
+        SWord32 s1393;
+        SWord32 s1394;
+        SWord8  s1395;
+        SWord32 s1396;
+        SWord32 s1397;
+        SWord8  s1398;
+        SWord32 s1399;
+        SWord8  s1400;
+        SWord32 s1401;
+        SWord32 s1402;
+        SWord8  s1403;
+        SWord32 s1404;
+        SWord32 s1405;
+        SWord8  s1406;
+        SWord32 s1407;
+        SWord32 s1408;
+        SWord32 s1409;
+        SWord32 s1410;
+        SWord8  s1411;
+        SWord32 s1412;
+        SWord32 s1413;
+        SWord8  s1414;
+        SWord32 s1415;
+        SWord8  s1416;
+        SWord32 s1417;
+        SWord32 s1418;
+        SWord8  s1419;
+        SWord32 s1420;
+        SWord32 s1421;
+        SWord8  s1422;
+        SWord32 s1423;
+        SWord32 s1424;
+        SWord32 s1425;
+        SWord32 s1426;
+        SWord8  s1427;
+        SWord32 s1428;
+        SWord32 s1429;
+        SWord32 s1430;
+        SWord8  s1431;
+        SWord8  s1432;
+        SWord8  s1433;
+        SWord8  s1434;
+        SWord8  s1435;
+        SWord16 s1436;
+        SWord8  s1437;
+        SWord8  s1438;
+        SWord8  s1439;
+        SWord8  s1440;
+        SWord16 s1441;
+        SWord32 s1442;
+        SWord32 s1443;
+        SWord32 s1444;
+        SWord8  s1445;
+        SWord32 s1446;
+        SWord8  s1447;
+        SWord32 s1448;
+        SWord8  s1449;
+        SWord32 s1450;
+        SWord32 s1451;
+        SWord8  s1452;
+        SWord32 s1453;
+        SWord32 s1454;
+        SWord8  s1455;
+        SWord32 s1456;
+        SWord32 s1457;
+        SWord32 s1458;
+        SWord32 s1459;
+        SWord8  s1460;
+        SWord32 s1461;
+        SWord32 s1462;
+        SWord8  s1463;
+        SWord32 s1464;
+        SWord8  s1465;
+        SWord32 s1466;
+        SWord32 s1467;
+        SWord8  s1468;
+        SWord32 s1469;
+        SWord32 s1470;
+        SWord8  s1471;
+        SWord32 s1472;
+        SWord32 s1473;
+        SWord32 s1474;
+        SWord32 s1475;
+        SWord8  s1476;
+        SWord32 s1477;
+        SWord32 s1478;
+        SWord8  s1479;
+        SWord32 s1480;
+        SWord8  s1481;
+        SWord32 s1482;
+        SWord32 s1483;
+        SWord8  s1484;
+        SWord32 s1485;
+        SWord32 s1486;
+        SWord8  s1487;
+        SWord32 s1488;
+        SWord32 s1489;
+        SWord32 s1490;
+        SWord32 s1491;
+        SWord8  s1492;
+        SWord32 s1493;
+        SWord32 s1494;
+        SWord32 s1495;
+        SWord8  s1496;
+        SWord8  s1497;
+        SWord8  s1498;
+        SWord8  s1499;
+        SWord8  s1500;
+        SWord16 s1501;
+        SWord8  s1502;
+        SWord8  s1503;
+        SWord8  s1504;
+        SWord8  s1505;
+        SWord16 s1506;
+        SWord32 s1507;
+        SWord32 s1508;
+        SWord32 s1509;
+        SWord8  s1510;
+        SWord32 s1511;
+        SWord8  s1512;
+        SWord32 s1513;
+        SWord8  s1514;
+        SWord32 s1515;
+        SWord32 s1516;
+        SWord8  s1517;
+        SWord32 s1518;
+        SWord32 s1519;
+        SWord8  s1520;
+        SWord32 s1521;
+        SWord32 s1522;
+        SWord32 s1523;
+        SWord32 s1524;
+        SWord8  s1525;
+        SWord32 s1526;
+        SWord32 s1527;
+        SWord8  s1528;
+        SWord32 s1529;
+        SWord8  s1530;
+        SWord32 s1531;
+        SWord32 s1532;
+        SWord8  s1533;
+        SWord32 s1534;
+        SWord32 s1535;
+        SWord8  s1536;
+        SWord32 s1537;
+        SWord32 s1538;
+        SWord32 s1539;
+        SWord32 s1540;
+        SWord8  s1541;
+        SWord32 s1542;
+        SWord32 s1543;
+        SWord8  s1544;
+        SWord32 s1545;
+        SWord8  s1546;
+        SWord32 s1547;
+        SWord32 s1548;
+        SWord8  s1549;
+        SWord32 s1550;
+        SWord32 s1551;
+        SWord8  s1552;
+        SWord32 s1553;
+        SWord32 s1554;
+        SWord32 s1555;
+        SWord32 s1556;
+        SWord8  s1557;
+        SWord32 s1558;
+        SWord32 s1559;
+        SWord32 s1560;
+        SWord8  s1561;
+        SWord8  s1562;
+        SWord8  s1563;
+        SWord8  s1564;
+        SWord8  s1565;
+        SWord16 s1566;
+        SWord8  s1567;
+        SWord8  s1568;
+        SWord8  s1569;
+        SWord8  s1570;
+        SWord16 s1571;
+        SWord32 s1572;
+        SWord32 s1573;
+        SWord32 s1574;
+        SWord8  s1575;
+        SWord32 s1576;
+        SWord8  s1577;
+        SWord32 s1578;
+        SWord8  s1579;
+        SWord32 s1580;
+        SWord32 s1581;
+        SWord8  s1582;
+        SWord32 s1583;
+        SWord32 s1584;
+        SWord8  s1585;
+        SWord32 s1586;
+        SWord32 s1587;
+        SWord32 s1588;
+        SWord32 s1589;
+        SWord8  s1590;
+        SWord32 s1591;
+        SWord32 s1592;
+        SWord8  s1593;
+        SWord32 s1594;
+        SWord8  s1595;
+        SWord32 s1596;
+        SWord32 s1597;
+        SWord8  s1598;
+        SWord32 s1599;
+        SWord32 s1600;
+        SWord8  s1601;
+        SWord32 s1602;
+        SWord32 s1603;
+        SWord32 s1604;
+        SWord32 s1605;
+        SWord8  s1606;
+        SWord32 s1607;
+        SWord32 s1608;
+        SWord8  s1609;
+        SWord32 s1610;
+        SWord8  s1611;
+        SWord32 s1612;
+        SWord32 s1613;
+        SWord8  s1614;
+        SWord32 s1615;
+        SWord32 s1616;
+        SWord8  s1617;
+        SWord32 s1618;
+        SWord32 s1619;
+        SWord32 s1620;
+        SWord32 s1621;
+        SWord8  s1622;
+        SWord32 s1623;
+        SWord32 s1624;
+        SWord32 s1625;
+        SWord8  s1626;
+        SWord8  s1627;
+        SWord8  s1628;
+        SWord8  s1629;
+        SWord8  s1630;
+        SWord16 s1631;
+        SWord8  s1632;
+        SWord8  s1633;
+        SWord8  s1634;
+        SWord8  s1635;
+        SWord16 s1636;
+        SWord32 s1637;
+        SWord32 s1638;
+        SWord32 s1639;
+        SWord8  s1640;
+        SWord32 s1641;
+        SWord8  s1642;
+        SWord32 s1643;
+        SWord8  s1644;
+        SWord32 s1645;
+        SWord32 s1646;
+        SWord8  s1647;
+        SWord32 s1648;
+        SWord32 s1649;
+        SWord8  s1650;
+        SWord32 s1651;
+        SWord32 s1652;
+        SWord32 s1653;
+        SWord32 s1654;
+        SWord8  s1655;
+        SWord32 s1656;
+        SWord32 s1657;
+        SWord8  s1658;
+        SWord32 s1659;
+        SWord8  s1660;
+        SWord32 s1661;
+        SWord32 s1662;
+        SWord8  s1663;
+        SWord32 s1664;
+        SWord32 s1665;
+        SWord8  s1666;
+        SWord32 s1667;
+        SWord32 s1668;
+        SWord32 s1669;
+        SWord32 s1670;
+        SWord8  s1671;
+        SWord32 s1672;
+        SWord32 s1673;
+        SWord8  s1674;
+        SWord32 s1675;
+        SWord8  s1676;
+        SWord32 s1677;
+        SWord32 s1678;
+        SWord8  s1679;
+        SWord32 s1680;
+        SWord32 s1681;
+        SWord8  s1682;
+        SWord32 s1683;
+        SWord32 s1684;
+        SWord32 s1685;
+        SWord32 s1686;
+        SWord8  s1687;
+        SWord32 s1688;
+        SWord32 s1689;
+        SWord32 s1690;
+        SWord8  s1691;
+        SWord8  s1692;
+        SWord8  s1693;
+        SWord8  s1694;
+        SWord8  s1695;
+        SWord16 s1696;
+        SWord8  s1697;
+        SWord8  s1698;
+        SWord8  s1699;
+        SWord8  s1700;
+        SWord16 s1701;
+        SWord32 s1702;
+        SWord32 s1703;
+        SWord32 s1704;
+        SWord8  s1705;
+        SWord32 s1706;
+        SWord8  s1707;
+        SWord32 s1708;
+        SWord8  s1709;
+        SWord32 s1710;
+        SWord32 s1711;
+        SWord8  s1712;
+        SWord32 s1713;
+        SWord32 s1714;
+        SWord8  s1715;
+        SWord32 s1716;
+        SWord32 s1717;
+        SWord32 s1718;
+        SWord32 s1719;
+        SWord8  s1720;
+        SWord32 s1721;
+        SWord32 s1722;
+        SWord8  s1723;
+        SWord32 s1724;
+        SWord8  s1725;
+        SWord32 s1726;
+        SWord32 s1727;
+        SWord8  s1728;
+        SWord32 s1729;
+        SWord32 s1730;
+        SWord8  s1731;
+        SWord32 s1732;
+        SWord32 s1733;
+        SWord32 s1734;
+        SWord32 s1735;
+        SWord8  s1736;
+        SWord32 s1737;
+        SWord32 s1738;
+        SWord8  s1739;
+        SWord32 s1740;
+        SWord8  s1741;
+        SWord32 s1742;
+        SWord32 s1743;
+        SWord8  s1744;
+        SWord32 s1745;
+        SWord32 s1746;
+        SWord8  s1747;
+        SWord32 s1748;
+        SWord32 s1749;
+        SWord32 s1750;
+        SWord32 s1751;
+        SWord8  s1752;
+        SWord32 s1753;
+        SWord32 s1754;
+        SWord32 s1755;
+        SWord8  s1756;
+        SWord8  s1757;
+        SWord8  s1758;
+        SWord8  s1759;
+        SWord8  s1760;
+        SWord16 s1761;
+        SWord8  s1762;
+        SWord8  s1763;
+        SWord8  s1764;
+        SWord8  s1765;
+        SWord16 s1766;
+        SWord32 s1767;
+        SWord32 s1768;
+        SWord32 s1769;
+        SWord8  s1770;
+        SWord32 s1771;
+        SWord8  s1772;
+        SWord32 s1773;
+        SWord8  s1774;
+        SWord32 s1775;
+        SWord32 s1776;
+        SWord8  s1777;
+        SWord32 s1778;
+        SWord32 s1779;
+        SWord8  s1780;
+        SWord32 s1781;
+        SWord32 s1782;
+        SWord32 s1783;
+        SWord32 s1784;
+        SWord8  s1785;
+        SWord32 s1786;
+        SWord32 s1787;
+        SWord8  s1788;
+        SWord32 s1789;
+        SWord8  s1790;
+        SWord32 s1791;
+        SWord32 s1792;
+        SWord8  s1793;
+        SWord32 s1794;
+        SWord32 s1795;
+        SWord8  s1796;
+        SWord32 s1797;
+        SWord32 s1798;
+        SWord32 s1799;
+        SWord32 s1800;
+        SWord8  s1801;
+        SWord32 s1802;
+        SWord32 s1803;
+        SWord8  s1804;
+        SWord32 s1805;
+        SWord8  s1806;
+        SWord32 s1807;
+        SWord32 s1808;
+        SWord8  s1809;
+        SWord32 s1810;
+        SWord32 s1811;
+        SWord8  s1812;
+        SWord32 s1813;
+        SWord32 s1814;
+        SWord32 s1815;
+        SWord32 s1816;
+        SWord8  s1817;
+        SWord32 s1818;
+        SWord32 s1819;
+        SWord32 s1820;
+        SWord8  s1821;
+        SWord8  s1822;
+        SWord8  s1823;
+        SWord8  s1824;
+        SWord8  s1825;
+        SWord16 s1826;
+        SWord8  s1827;
+        SWord8  s1828;
+        SWord8  s1829;
+        SWord8  s1830;
+        SWord16 s1831;
+        SWord32 s1832;
+        SWord32 s1833;
+        SWord32 s1834;
+        SWord8  s1835;
+        SWord8  s1836;
+        SWord8  s1837;
+        SWord32 s1838;
+        SWord8  s1839;
+        SWord32 s1840;
+        SWord32 s1841;
+        SWord8  s1842;
+        SWord32 s1843;
+        SWord32 s1844;
+        SWord8  s1845;
+        SWord32 s1846;
+        SWord32 s1847;
+        SWord32 s1848;
+        SWord32 s1849;
+        SWord8  s1850;
+        SWord8  s1851;
+        SWord16 s1852;
+        SWord8  s1853;
+        SWord32 s1854;
+        SWord8  s1855;
+        SWord32 s1856;
+        SWord32 s1857;
+        SWord8  s1858;
+        SWord32 s1859;
+        SWord32 s1860;
+        SWord8  s1861;
+        SWord32 s1862;
+        SWord32 s1863;
+        SWord32 s1864;
+        SWord32 s1865;
+        SWord8  s1866;
+        SWord8  s1867;
+        SWord8  s1868;
+        SWord32 s1869;
+        SWord8  s1870;
+        SWord32 s1871;
+        SWord32 s1872;
+        SWord8  s1873;
+        SWord32 s1874;
+        SWord32 s1875;
+        SWord8  s1876;
+        SWord32 s1877;
+        SWord32 s1878;
+        SWord32 s1879;
+        SWord32 s1880;
+        SWord8  s1881;
+        SWord8  s1882;
+        SWord16 s1883;
+        SWord32 s1884;
+        SWord32 s1885;
+        SWord8  s1886;
+        SWord8  s1887;
+        SWord8  s1888;
+        SWord8  s1889;
+        SWord8  s1890;
+        SWord16 s1891;
+        SWord8  s1892;
+        SWord8  s1893;
+        SWord8  s1894;
+        SWord8  s1895;
+        SWord16 s1896;
+        SWord32 s1897;
+        SWord32 s1898;
+        SWord32 s1899;
+        SWord8  s1900;
+        SWord8  s1901;
+        SWord8  s1902;
+        SWord8  s1903;
+        SWord16 s1904;
+        SWord8  s1905;
+        SWord8  s1906;
+        SWord8  s1907;
+        SWord8  s1908;
+        SWord16 s1909;
+        SWord32 s1910;
+        SWord32 s1911;
+        SWord32 s1912;
+        SWord8  s1913;
+        SWord8  s1914;
+        SWord8  s1915;
+        SWord8  s1916;
+        SWord16 s1917;
+        SWord8  s1918;
+        SWord8  s1919;
+        SWord8  s1920;
+        SWord8  s1921;
+        SWord16 s1922;
+        SWord32 s1923;
+        SWord32 s1924;
+        SWord32 s1925;
+        SWord8  s1926;
+        SWord8  s1927;
+        SWord8  s1928;
+        SWord8  s1929;
+        SWord16 s1930;
+        SWord8  s1931;
+        SWord8  s1932;
+        SWord8  s1933;
+        SWord8  s1934;
+        SWord16 s1935;
+        SWord32 s1936;
+        SWord32 s1937;
+        SWord32 s1938;
+  static const SWord32 table1[] = {
+      0xc66363a5UL, 0xf87c7c84UL, 0xee777799UL, 0xf67b7b8dUL,
+      0xfff2f20dUL, 0xd66b6bbdUL, 0xde6f6fb1UL, 0x91c5c554UL,
+      0x60303050UL, 0x02010103UL, 0xce6767a9UL, 0x562b2b7dUL,
+      0xe7fefe19UL, 0xb5d7d762UL, 0x4dababe6UL, 0xec76769aUL,
+      0x8fcaca45UL, 0x1f82829dUL, 0x89c9c940UL, 0xfa7d7d87UL,
+      0xeffafa15UL, 0xb25959ebUL, 0x8e4747c9UL, 0xfbf0f00bUL,
+      0x41adadecUL, 0xb3d4d467UL, 0x5fa2a2fdUL, 0x45afafeaUL,
+      0x239c9cbfUL, 0x53a4a4f7UL, 0xe4727296UL, 0x9bc0c05bUL,
+      0x75b7b7c2UL, 0xe1fdfd1cUL, 0x3d9393aeUL, 0x4c26266aUL,
+      0x6c36365aUL, 0x7e3f3f41UL, 0xf5f7f702UL, 0x83cccc4fUL,
+      0x6834345cUL, 0x51a5a5f4UL, 0xd1e5e534UL, 0xf9f1f108UL,
+      0xe2717193UL, 0xabd8d873UL, 0x62313153UL, 0x2a15153fUL,
+      0x0804040cUL, 0x95c7c752UL, 0x46232365UL, 0x9dc3c35eUL,
+      0x30181828UL, 0x379696a1UL, 0x0a05050fUL, 0x2f9a9ab5UL,
+      0x0e070709UL, 0x24121236UL, 0x1b80809bUL, 0xdfe2e23dUL,
+      0xcdebeb26UL, 0x4e272769UL, 0x7fb2b2cdUL, 0xea75759fUL,
+      0x1209091bUL, 0x1d83839eUL, 0x582c2c74UL, 0x341a1a2eUL,
+      0x361b1b2dUL, 0xdc6e6eb2UL, 0xb45a5aeeUL, 0x5ba0a0fbUL,
+      0xa45252f6UL, 0x763b3b4dUL, 0xb7d6d661UL, 0x7db3b3ceUL,
+      0x5229297bUL, 0xdde3e33eUL, 0x5e2f2f71UL, 0x13848497UL,
+      0xa65353f5UL, 0xb9d1d168UL, 0x00000000UL, 0xc1eded2cUL,
+      0x40202060UL, 0xe3fcfc1fUL, 0x79b1b1c8UL, 0xb65b5bedUL,
+      0xd46a6abeUL, 0x8dcbcb46UL, 0x67bebed9UL, 0x7239394bUL,
+      0x944a4adeUL, 0x984c4cd4UL, 0xb05858e8UL, 0x85cfcf4aUL,
+      0xbbd0d06bUL, 0xc5efef2aUL, 0x4faaaae5UL, 0xedfbfb16UL,
+      0x864343c5UL, 0x9a4d4dd7UL, 0x66333355UL, 0x11858594UL,
+      0x8a4545cfUL, 0xe9f9f910UL, 0x04020206UL, 0xfe7f7f81UL,
+      0xa05050f0UL, 0x783c3c44UL, 0x259f9fbaUL, 0x4ba8a8e3UL,
+      0xa25151f3UL, 0x5da3a3feUL, 0x804040c0UL, 0x058f8f8aUL,
+      0x3f9292adUL, 0x219d9dbcUL, 0x70383848UL, 0xf1f5f504UL,
+      0x63bcbcdfUL, 0x77b6b6c1UL, 0xafdada75UL, 0x42212163UL,
+      0x20101030UL, 0xe5ffff1aUL, 0xfdf3f30eUL, 0xbfd2d26dUL,
+      0x81cdcd4cUL, 0x180c0c14UL, 0x26131335UL, 0xc3ecec2fUL,
+      0xbe5f5fe1UL, 0x359797a2UL, 0x884444ccUL, 0x2e171739UL,
+      0x93c4c457UL, 0x55a7a7f2UL, 0xfc7e7e82UL, 0x7a3d3d47UL,
+      0xc86464acUL, 0xba5d5de7UL, 0x3219192bUL, 0xe6737395UL,
+      0xc06060a0UL, 0x19818198UL, 0x9e4f4fd1UL, 0xa3dcdc7fUL,
+      0x44222266UL, 0x542a2a7eUL, 0x3b9090abUL, 0x0b888883UL,
+      0x8c4646caUL, 0xc7eeee29UL, 0x6bb8b8d3UL, 0x2814143cUL,
+      0xa7dede79UL, 0xbc5e5ee2UL, 0x160b0b1dUL, 0xaddbdb76UL,
+      0xdbe0e03bUL, 0x64323256UL, 0x743a3a4eUL, 0x140a0a1eUL,
+      0x924949dbUL, 0x0c06060aUL, 0x4824246cUL, 0xb85c5ce4UL,
+      0x9fc2c25dUL, 0xbdd3d36eUL, 0x43acacefUL, 0xc46262a6UL,
+      0x399191a8UL, 0x319595a4UL, 0xd3e4e437UL, 0xf279798bUL,
+      0xd5e7e732UL, 0x8bc8c843UL, 0x6e373759UL, 0xda6d6db7UL,
+      0x018d8d8cUL, 0xb1d5d564UL, 0x9c4e4ed2UL, 0x49a9a9e0UL,
+      0xd86c6cb4UL, 0xac5656faUL, 0xf3f4f407UL, 0xcfeaea25UL,
+      0xca6565afUL, 0xf47a7a8eUL, 0x47aeaee9UL, 0x10080818UL,
+      0x6fbabad5UL, 0xf0787888UL, 0x4a25256fUL, 0x5c2e2e72UL,
+      0x381c1c24UL, 0x57a6a6f1UL, 0x73b4b4c7UL, 0x97c6c651UL,
+      0xcbe8e823UL, 0xa1dddd7cUL, 0xe874749cUL, 0x3e1f1f21UL,
+      0x964b4bddUL, 0x61bdbddcUL, 0x0d8b8b86UL, 0x0f8a8a85UL,
+      0xe0707090UL, 0x7c3e3e42UL, 0x71b5b5c4UL, 0xcc6666aaUL,
+      0x904848d8UL, 0x06030305UL, 0xf7f6f601UL, 0x1c0e0e12UL,
+      0xc26161a3UL, 0x6a35355fUL, 0xae5757f9UL, 0x69b9b9d0UL,
+      0x17868691UL, 0x99c1c158UL, 0x3a1d1d27UL, 0x279e9eb9UL,
+      0xd9e1e138UL, 0xebf8f813UL, 0x2b9898b3UL, 0x22111133UL,
+      0xd26969bbUL, 0xa9d9d970UL, 0x078e8e89UL, 0x339494a7UL,
+      0x2d9b9bb6UL, 0x3c1e1e22UL, 0x15878792UL, 0xc9e9e920UL,
+      0x87cece49UL, 0xaa5555ffUL, 0x50282878UL, 0xa5dfdf7aUL,
+      0x038c8c8fUL, 0x59a1a1f8UL, 0x09898980UL, 0x1a0d0d17UL,
+      0x65bfbfdaUL, 0xd7e6e631UL, 0x844242c6UL, 0xd06868b8UL,
+      0x824141c3UL, 0x299999b0UL, 0x5a2d2d77UL, 0x1e0f0f11UL,
+      0x7bb0b0cbUL, 0xa85454fcUL, 0x6dbbbbd6UL, 0x2c16163aUL
+  };
+  s522 = table1[s521];
+  static const SWord32 table2[] = {
+      0xa5c66363UL, 0x84f87c7cUL, 0x99ee7777UL, 0x8df67b7bUL,
+      0x0dfff2f2UL, 0xbdd66b6bUL, 0xb1de6f6fUL, 0x5491c5c5UL,
+      0x50603030UL, 0x03020101UL, 0xa9ce6767UL, 0x7d562b2bUL,
+      0x19e7fefeUL, 0x62b5d7d7UL, 0xe64dababUL, 0x9aec7676UL,
+      0x458fcacaUL, 0x9d1f8282UL, 0x4089c9c9UL, 0x87fa7d7dUL,
+      0x15effafaUL, 0xebb25959UL, 0xc98e4747UL, 0x0bfbf0f0UL,
+      0xec41adadUL, 0x67b3d4d4UL, 0xfd5fa2a2UL, 0xea45afafUL,
+      0xbf239c9cUL, 0xf753a4a4UL, 0x96e47272UL, 0x5b9bc0c0UL,
+      0xc275b7b7UL, 0x1ce1fdfdUL, 0xae3d9393UL, 0x6a4c2626UL,
+      0x5a6c3636UL, 0x417e3f3fUL, 0x02f5f7f7UL, 0x4f83ccccUL,
+      0x5c683434UL, 0xf451a5a5UL, 0x34d1e5e5UL, 0x08f9f1f1UL,
+      0x93e27171UL, 0x73abd8d8UL, 0x53623131UL, 0x3f2a1515UL,
+      0x0c080404UL, 0x5295c7c7UL, 0x65462323UL, 0x5e9dc3c3UL,
+      0x28301818UL, 0xa1379696UL, 0x0f0a0505UL, 0xb52f9a9aUL,
+      0x090e0707UL, 0x36241212UL, 0x9b1b8080UL, 0x3ddfe2e2UL,
+      0x26cdebebUL, 0x694e2727UL, 0xcd7fb2b2UL, 0x9fea7575UL,
+      0x1b120909UL, 0x9e1d8383UL, 0x74582c2cUL, 0x2e341a1aUL,
+      0x2d361b1bUL, 0xb2dc6e6eUL, 0xeeb45a5aUL, 0xfb5ba0a0UL,
+      0xf6a45252UL, 0x4d763b3bUL, 0x61b7d6d6UL, 0xce7db3b3UL,
+      0x7b522929UL, 0x3edde3e3UL, 0x715e2f2fUL, 0x97138484UL,
+      0xf5a65353UL, 0x68b9d1d1UL, 0x00000000UL, 0x2cc1ededUL,
+      0x60402020UL, 0x1fe3fcfcUL, 0xc879b1b1UL, 0xedb65b5bUL,
+      0xbed46a6aUL, 0x468dcbcbUL, 0xd967bebeUL, 0x4b723939UL,
+      0xde944a4aUL, 0xd4984c4cUL, 0xe8b05858UL, 0x4a85cfcfUL,
+      0x6bbbd0d0UL, 0x2ac5efefUL, 0xe54faaaaUL, 0x16edfbfbUL,
+      0xc5864343UL, 0xd79a4d4dUL, 0x55663333UL, 0x94118585UL,
+      0xcf8a4545UL, 0x10e9f9f9UL, 0x06040202UL, 0x81fe7f7fUL,
+      0xf0a05050UL, 0x44783c3cUL, 0xba259f9fUL, 0xe34ba8a8UL,
+      0xf3a25151UL, 0xfe5da3a3UL, 0xc0804040UL, 0x8a058f8fUL,
+      0xad3f9292UL, 0xbc219d9dUL, 0x48703838UL, 0x04f1f5f5UL,
+      0xdf63bcbcUL, 0xc177b6b6UL, 0x75afdadaUL, 0x63422121UL,
+      0x30201010UL, 0x1ae5ffffUL, 0x0efdf3f3UL, 0x6dbfd2d2UL,
+      0x4c81cdcdUL, 0x14180c0cUL, 0x35261313UL, 0x2fc3ececUL,
+      0xe1be5f5fUL, 0xa2359797UL, 0xcc884444UL, 0x392e1717UL,
+      0x5793c4c4UL, 0xf255a7a7UL, 0x82fc7e7eUL, 0x477a3d3dUL,
+      0xacc86464UL, 0xe7ba5d5dUL, 0x2b321919UL, 0x95e67373UL,
+      0xa0c06060UL, 0x98198181UL, 0xd19e4f4fUL, 0x7fa3dcdcUL,
+      0x66442222UL, 0x7e542a2aUL, 0xab3b9090UL, 0x830b8888UL,
+      0xca8c4646UL, 0x29c7eeeeUL, 0xd36bb8b8UL, 0x3c281414UL,
+      0x79a7dedeUL, 0xe2bc5e5eUL, 0x1d160b0bUL, 0x76addbdbUL,
+      0x3bdbe0e0UL, 0x56643232UL, 0x4e743a3aUL, 0x1e140a0aUL,
+      0xdb924949UL, 0x0a0c0606UL, 0x6c482424UL, 0xe4b85c5cUL,
+      0x5d9fc2c2UL, 0x6ebdd3d3UL, 0xef43acacUL, 0xa6c46262UL,
+      0xa8399191UL, 0xa4319595UL, 0x37d3e4e4UL, 0x8bf27979UL,
+      0x32d5e7e7UL, 0x438bc8c8UL, 0x596e3737UL, 0xb7da6d6dUL,
+      0x8c018d8dUL, 0x64b1d5d5UL, 0xd29c4e4eUL, 0xe049a9a9UL,
+      0xb4d86c6cUL, 0xfaac5656UL, 0x07f3f4f4UL, 0x25cfeaeaUL,
+      0xafca6565UL, 0x8ef47a7aUL, 0xe947aeaeUL, 0x18100808UL,
+      0xd56fbabaUL, 0x88f07878UL, 0x6f4a2525UL, 0x725c2e2eUL,
+      0x24381c1cUL, 0xf157a6a6UL, 0xc773b4b4UL, 0x5197c6c6UL,
+      0x23cbe8e8UL, 0x7ca1ddddUL, 0x9ce87474UL, 0x213e1f1fUL,
+      0xdd964b4bUL, 0xdc61bdbdUL, 0x860d8b8bUL, 0x850f8a8aUL,
+      0x90e07070UL, 0x427c3e3eUL, 0xc471b5b5UL, 0xaacc6666UL,
+      0xd8904848UL, 0x05060303UL, 0x01f7f6f6UL, 0x121c0e0eUL,
+      0xa3c26161UL, 0x5f6a3535UL, 0xf9ae5757UL, 0xd069b9b9UL,
+      0x91178686UL, 0x5899c1c1UL, 0x273a1d1dUL, 0xb9279e9eUL,
+      0x38d9e1e1UL, 0x13ebf8f8UL, 0xb32b9898UL, 0x33221111UL,
+      0xbbd26969UL, 0x70a9d9d9UL, 0x89078e8eUL, 0xa7339494UL,
+      0xb62d9b9bUL, 0x223c1e1eUL, 0x92158787UL, 0x20c9e9e9UL,
+      0x4987ceceUL, 0xffaa5555UL, 0x78502828UL, 0x7aa5dfdfUL,
+      0x8f038c8cUL, 0xf859a1a1UL, 0x80098989UL, 0x171a0d0dUL,
+      0xda65bfbfUL, 0x31d7e6e6UL, 0xc6844242UL, 0xb8d06868UL,
+      0xc3824141UL, 0xb0299999UL, 0x775a2d2dUL, 0x111e0f0fUL,
+      0xcb7bb0b0UL, 0xfca85454UL, 0xd66dbbbbUL, 0x3a2c1616UL
+  };
+  s780 = table2[s779];
+  s781 = s522 ^ s780;
+  static const SWord32 table3[] = {
+      0x63a5c663UL, 0x7c84f87cUL, 0x7799ee77UL, 0x7b8df67bUL,
+      0xf20dfff2UL, 0x6bbdd66bUL, 0x6fb1de6fUL, 0xc55491c5UL,
+      0x30506030UL, 0x01030201UL, 0x67a9ce67UL, 0x2b7d562bUL,
+      0xfe19e7feUL, 0xd762b5d7UL, 0xabe64dabUL, 0x769aec76UL,
+      0xca458fcaUL, 0x829d1f82UL, 0xc94089c9UL, 0x7d87fa7dUL,
+      0xfa15effaUL, 0x59ebb259UL, 0x47c98e47UL, 0xf00bfbf0UL,
+      0xadec41adUL, 0xd467b3d4UL, 0xa2fd5fa2UL, 0xafea45afUL,
+      0x9cbf239cUL, 0xa4f753a4UL, 0x7296e472UL, 0xc05b9bc0UL,
+      0xb7c275b7UL, 0xfd1ce1fdUL, 0x93ae3d93UL, 0x266a4c26UL,
+      0x365a6c36UL, 0x3f417e3fUL, 0xf702f5f7UL, 0xcc4f83ccUL,
+      0x345c6834UL, 0xa5f451a5UL, 0xe534d1e5UL, 0xf108f9f1UL,
+      0x7193e271UL, 0xd873abd8UL, 0x31536231UL, 0x153f2a15UL,
+      0x040c0804UL, 0xc75295c7UL, 0x23654623UL, 0xc35e9dc3UL,
+      0x18283018UL, 0x96a13796UL, 0x050f0a05UL, 0x9ab52f9aUL,
+      0x07090e07UL, 0x12362412UL, 0x809b1b80UL, 0xe23ddfe2UL,
+      0xeb26cdebUL, 0x27694e27UL, 0xb2cd7fb2UL, 0x759fea75UL,
+      0x091b1209UL, 0x839e1d83UL, 0x2c74582cUL, 0x1a2e341aUL,
+      0x1b2d361bUL, 0x6eb2dc6eUL, 0x5aeeb45aUL, 0xa0fb5ba0UL,
+      0x52f6a452UL, 0x3b4d763bUL, 0xd661b7d6UL, 0xb3ce7db3UL,
+      0x297b5229UL, 0xe33edde3UL, 0x2f715e2fUL, 0x84971384UL,
+      0x53f5a653UL, 0xd168b9d1UL, 0x00000000UL, 0xed2cc1edUL,
+      0x20604020UL, 0xfc1fe3fcUL, 0xb1c879b1UL, 0x5bedb65bUL,
+      0x6abed46aUL, 0xcb468dcbUL, 0xbed967beUL, 0x394b7239UL,
+      0x4ade944aUL, 0x4cd4984cUL, 0x58e8b058UL, 0xcf4a85cfUL,
+      0xd06bbbd0UL, 0xef2ac5efUL, 0xaae54faaUL, 0xfb16edfbUL,
+      0x43c58643UL, 0x4dd79a4dUL, 0x33556633UL, 0x85941185UL,
+      0x45cf8a45UL, 0xf910e9f9UL, 0x02060402UL, 0x7f81fe7fUL,
+      0x50f0a050UL, 0x3c44783cUL, 0x9fba259fUL, 0xa8e34ba8UL,
+      0x51f3a251UL, 0xa3fe5da3UL, 0x40c08040UL, 0x8f8a058fUL,
+      0x92ad3f92UL, 0x9dbc219dUL, 0x38487038UL, 0xf504f1f5UL,
+      0xbcdf63bcUL, 0xb6c177b6UL, 0xda75afdaUL, 0x21634221UL,
+      0x10302010UL, 0xff1ae5ffUL, 0xf30efdf3UL, 0xd26dbfd2UL,
+      0xcd4c81cdUL, 0x0c14180cUL, 0x13352613UL, 0xec2fc3ecUL,
+      0x5fe1be5fUL, 0x97a23597UL, 0x44cc8844UL, 0x17392e17UL,
+      0xc45793c4UL, 0xa7f255a7UL, 0x7e82fc7eUL, 0x3d477a3dUL,
+      0x64acc864UL, 0x5de7ba5dUL, 0x192b3219UL, 0x7395e673UL,
+      0x60a0c060UL, 0x81981981UL, 0x4fd19e4fUL, 0xdc7fa3dcUL,
+      0x22664422UL, 0x2a7e542aUL, 0x90ab3b90UL, 0x88830b88UL,
+      0x46ca8c46UL, 0xee29c7eeUL, 0xb8d36bb8UL, 0x143c2814UL,
+      0xde79a7deUL, 0x5ee2bc5eUL, 0x0b1d160bUL, 0xdb76addbUL,
+      0xe03bdbe0UL, 0x32566432UL, 0x3a4e743aUL, 0x0a1e140aUL,
+      0x49db9249UL, 0x060a0c06UL, 0x246c4824UL, 0x5ce4b85cUL,
+      0xc25d9fc2UL, 0xd36ebdd3UL, 0xacef43acUL, 0x62a6c462UL,
+      0x91a83991UL, 0x95a43195UL, 0xe437d3e4UL, 0x798bf279UL,
+      0xe732d5e7UL, 0xc8438bc8UL, 0x37596e37UL, 0x6db7da6dUL,
+      0x8d8c018dUL, 0xd564b1d5UL, 0x4ed29c4eUL, 0xa9e049a9UL,
+      0x6cb4d86cUL, 0x56faac56UL, 0xf407f3f4UL, 0xea25cfeaUL,
+      0x65afca65UL, 0x7a8ef47aUL, 0xaee947aeUL, 0x08181008UL,
+      0xbad56fbaUL, 0x7888f078UL, 0x256f4a25UL, 0x2e725c2eUL,
+      0x1c24381cUL, 0xa6f157a6UL, 0xb4c773b4UL, 0xc65197c6UL,
+      0xe823cbe8UL, 0xdd7ca1ddUL, 0x749ce874UL, 0x1f213e1fUL,
+      0x4bdd964bUL, 0xbddc61bdUL, 0x8b860d8bUL, 0x8a850f8aUL,
+      0x7090e070UL, 0x3e427c3eUL, 0xb5c471b5UL, 0x66aacc66UL,
+      0x48d89048UL, 0x03050603UL, 0xf601f7f6UL, 0x0e121c0eUL,
+      0x61a3c261UL, 0x355f6a35UL, 0x57f9ae57UL, 0xb9d069b9UL,
+      0x86911786UL, 0xc15899c1UL, 0x1d273a1dUL, 0x9eb9279eUL,
+      0xe138d9e1UL, 0xf813ebf8UL, 0x98b32b98UL, 0x11332211UL,
+      0x69bbd269UL, 0xd970a9d9UL, 0x8e89078eUL, 0x94a73394UL,
+      0x9bb62d9bUL, 0x1e223c1eUL, 0x87921587UL, 0xe920c9e9UL,
+      0xce4987ceUL, 0x55ffaa55UL, 0x28785028UL, 0xdf7aa5dfUL,
+      0x8c8f038cUL, 0xa1f859a1UL, 0x89800989UL, 0x0d171a0dUL,
+      0xbfda65bfUL, 0xe631d7e6UL, 0x42c68442UL, 0x68b8d068UL,
+      0x41c38241UL, 0x99b02999UL, 0x2d775a2dUL, 0x0f111e0fUL,
+      0xb0cb7bb0UL, 0x54fca854UL, 0xbbd66dbbUL, 0x163a2c16UL
+  };
+  s1039 = table3[s1038];
+  s1040 = s781 ^ s1039;
+  static const SWord32 table4[] = {
+      0x6363a5c6UL, 0x7c7c84f8UL, 0x777799eeUL, 0x7b7b8df6UL,
+      0xf2f20dffUL, 0x6b6bbdd6UL, 0x6f6fb1deUL, 0xc5c55491UL,
+      0x30305060UL, 0x01010302UL, 0x6767a9ceUL, 0x2b2b7d56UL,
+      0xfefe19e7UL, 0xd7d762b5UL, 0xababe64dUL, 0x76769aecUL,
+      0xcaca458fUL, 0x82829d1fUL, 0xc9c94089UL, 0x7d7d87faUL,
+      0xfafa15efUL, 0x5959ebb2UL, 0x4747c98eUL, 0xf0f00bfbUL,
+      0xadadec41UL, 0xd4d467b3UL, 0xa2a2fd5fUL, 0xafafea45UL,
+      0x9c9cbf23UL, 0xa4a4f753UL, 0x727296e4UL, 0xc0c05b9bUL,
+      0xb7b7c275UL, 0xfdfd1ce1UL, 0x9393ae3dUL, 0x26266a4cUL,
+      0x36365a6cUL, 0x3f3f417eUL, 0xf7f702f5UL, 0xcccc4f83UL,
+      0x34345c68UL, 0xa5a5f451UL, 0xe5e534d1UL, 0xf1f108f9UL,
+      0x717193e2UL, 0xd8d873abUL, 0x31315362UL, 0x15153f2aUL,
+      0x04040c08UL, 0xc7c75295UL, 0x23236546UL, 0xc3c35e9dUL,
+      0x18182830UL, 0x9696a137UL, 0x05050f0aUL, 0x9a9ab52fUL,
+      0x0707090eUL, 0x12123624UL, 0x80809b1bUL, 0xe2e23ddfUL,
+      0xebeb26cdUL, 0x2727694eUL, 0xb2b2cd7fUL, 0x75759feaUL,
+      0x09091b12UL, 0x83839e1dUL, 0x2c2c7458UL, 0x1a1a2e34UL,
+      0x1b1b2d36UL, 0x6e6eb2dcUL, 0x5a5aeeb4UL, 0xa0a0fb5bUL,
+      0x5252f6a4UL, 0x3b3b4d76UL, 0xd6d661b7UL, 0xb3b3ce7dUL,
+      0x29297b52UL, 0xe3e33eddUL, 0x2f2f715eUL, 0x84849713UL,
+      0x5353f5a6UL, 0xd1d168b9UL, 0x00000000UL, 0xeded2cc1UL,
+      0x20206040UL, 0xfcfc1fe3UL, 0xb1b1c879UL, 0x5b5bedb6UL,
+      0x6a6abed4UL, 0xcbcb468dUL, 0xbebed967UL, 0x39394b72UL,
+      0x4a4ade94UL, 0x4c4cd498UL, 0x5858e8b0UL, 0xcfcf4a85UL,
+      0xd0d06bbbUL, 0xefef2ac5UL, 0xaaaae54fUL, 0xfbfb16edUL,
+      0x4343c586UL, 0x4d4dd79aUL, 0x33335566UL, 0x85859411UL,
+      0x4545cf8aUL, 0xf9f910e9UL, 0x02020604UL, 0x7f7f81feUL,
+      0x5050f0a0UL, 0x3c3c4478UL, 0x9f9fba25UL, 0xa8a8e34bUL,
+      0x5151f3a2UL, 0xa3a3fe5dUL, 0x4040c080UL, 0x8f8f8a05UL,
+      0x9292ad3fUL, 0x9d9dbc21UL, 0x38384870UL, 0xf5f504f1UL,
+      0xbcbcdf63UL, 0xb6b6c177UL, 0xdada75afUL, 0x21216342UL,
+      0x10103020UL, 0xffff1ae5UL, 0xf3f30efdUL, 0xd2d26dbfUL,
+      0xcdcd4c81UL, 0x0c0c1418UL, 0x13133526UL, 0xecec2fc3UL,
+      0x5f5fe1beUL, 0x9797a235UL, 0x4444cc88UL, 0x1717392eUL,
+      0xc4c45793UL, 0xa7a7f255UL, 0x7e7e82fcUL, 0x3d3d477aUL,
+      0x6464acc8UL, 0x5d5de7baUL, 0x19192b32UL, 0x737395e6UL,
+      0x6060a0c0UL, 0x81819819UL, 0x4f4fd19eUL, 0xdcdc7fa3UL,
+      0x22226644UL, 0x2a2a7e54UL, 0x9090ab3bUL, 0x8888830bUL,
+      0x4646ca8cUL, 0xeeee29c7UL, 0xb8b8d36bUL, 0x14143c28UL,
+      0xdede79a7UL, 0x5e5ee2bcUL, 0x0b0b1d16UL, 0xdbdb76adUL,
+      0xe0e03bdbUL, 0x32325664UL, 0x3a3a4e74UL, 0x0a0a1e14UL,
+      0x4949db92UL, 0x06060a0cUL, 0x24246c48UL, 0x5c5ce4b8UL,
+      0xc2c25d9fUL, 0xd3d36ebdUL, 0xacacef43UL, 0x6262a6c4UL,
+      0x9191a839UL, 0x9595a431UL, 0xe4e437d3UL, 0x79798bf2UL,
+      0xe7e732d5UL, 0xc8c8438bUL, 0x3737596eUL, 0x6d6db7daUL,
+      0x8d8d8c01UL, 0xd5d564b1UL, 0x4e4ed29cUL, 0xa9a9e049UL,
+      0x6c6cb4d8UL, 0x5656faacUL, 0xf4f407f3UL, 0xeaea25cfUL,
+      0x6565afcaUL, 0x7a7a8ef4UL, 0xaeaee947UL, 0x08081810UL,
+      0xbabad56fUL, 0x787888f0UL, 0x25256f4aUL, 0x2e2e725cUL,
+      0x1c1c2438UL, 0xa6a6f157UL, 0xb4b4c773UL, 0xc6c65197UL,
+      0xe8e823cbUL, 0xdddd7ca1UL, 0x74749ce8UL, 0x1f1f213eUL,
+      0x4b4bdd96UL, 0xbdbddc61UL, 0x8b8b860dUL, 0x8a8a850fUL,
+      0x707090e0UL, 0x3e3e427cUL, 0xb5b5c471UL, 0x6666aaccUL,
+      0x4848d890UL, 0x03030506UL, 0xf6f601f7UL, 0x0e0e121cUL,
+      0x6161a3c2UL, 0x35355f6aUL, 0x5757f9aeUL, 0xb9b9d069UL,
+      0x86869117UL, 0xc1c15899UL, 0x1d1d273aUL, 0x9e9eb927UL,
+      0xe1e138d9UL, 0xf8f813ebUL, 0x9898b32bUL, 0x11113322UL,
+      0x6969bbd2UL, 0xd9d970a9UL, 0x8e8e8907UL, 0x9494a733UL,
+      0x9b9bb62dUL, 0x1e1e223cUL, 0x87879215UL, 0xe9e920c9UL,
+      0xcece4987UL, 0x5555ffaaUL, 0x28287850UL, 0xdfdf7aa5UL,
+      0x8c8c8f03UL, 0xa1a1f859UL, 0x89898009UL, 0x0d0d171aUL,
+      0xbfbfda65UL, 0xe6e631d7UL, 0x4242c684UL, 0x6868b8d0UL,
+      0x4141c382UL, 0x9999b029UL, 0x2d2d775aUL, 0x0f0f111eUL,
+      0xb0b0cb7bUL, 0x5454fca8UL, 0xbbbbd66dUL, 0x16163a2cUL
+  };
+  s1298 = table4[s1297];
+  s1299 = s1040 ^ s1298;
+  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
+  };
+  s1302 = table0[s1301];
+  s1303 = 1 ^ s1302;
+  s1305 = table0[s1304];
+  s1306 = sbv_bv_join_u8_u8_u16(s1303, s1305);
+  s1308 = table0[s1307];
+  s1310 = table0[s1309];
+  s1311 = sbv_bv_join_u8_u8_u16(s1308, s1310);
+  s1312 = sbv_bv_join_u16_u16_u32(s1306, s1311);
+  s1313 = s4 ^ s1312;
+  s1314 = s1299 ^ s1313;
+  s1315 = sbv_bv_extract_u32_31_24_u8(s1314);
+  s1316 = table1[s1315];
+  s1318 = table1[s1317];
+  s1320 = table2[s1319];
+  s1321 = s1318 ^ s1320;
+  s1323 = table3[s1322];
+  s1324 = s1321 ^ s1323;
+  s1326 = table4[s1325];
+  s1327 = s1324 ^ s1326;
+  s1328 = s5 ^ s1313;
+  s1329 = s1327 ^ s1328;
+  s1330 = sbv_bv_extract_u32_23_16_u8(s1329);
+  s1331 = table2[s1330];
+  s1332 = s1316 ^ s1331;
+  s1334 = table1[s1333];
+  s1336 = table2[s1335];
+  s1337 = s1334 ^ s1336;
+  s1339 = table3[s1338];
+  s1340 = s1337 ^ s1339;
+  s1342 = table4[s1341];
+  s1343 = s1340 ^ s1342;
+  s1344 = s6 ^ s1328;
+  s1345 = s1343 ^ s1344;
+  s1346 = sbv_bv_extract_u32_15_8_u8(s1345);
+  s1347 = table3[s1346];
+  s1348 = s1332 ^ s1347;
+  s1350 = table1[s1349];
+  s1352 = table2[s1351];
+  s1353 = s1350 ^ s1352;
+  s1355 = table3[s1354];
+  s1356 = s1353 ^ s1355;
+  s1358 = table4[s1357];
+  s1359 = s1356 ^ s1358;
+  s1360 = s7 ^ s1344;
+  s1361 = s1359 ^ s1360;
+  s1362 = sbv_bv_extract_u32_7_0_u8(s1361);
+  s1363 = table4[s1362];
+  s1364 = s1348 ^ s1363;
+  s1365 = sbv_bv_u32_rotl(s1360, 8);
+  s1366 = sbv_bv_extract_u32_31_24_u8(s1365);
+  s1367 = table0[s1366];
+  s1368 = 2 ^ s1367;
+  s1369 = sbv_bv_extract_u32_23_16_u8(s1365);
+  s1370 = table0[s1369];
+  s1371 = sbv_bv_join_u8_u8_u16(s1368, s1370);
+  s1372 = sbv_bv_extract_u32_15_8_u8(s1365);
+  s1373 = table0[s1372];
+  s1374 = sbv_bv_extract_u32_7_0_u8(s1365);
+  s1375 = table0[s1374];
+  s1376 = sbv_bv_join_u8_u8_u16(s1373, s1375);
+  s1377 = sbv_bv_join_u16_u16_u32(s1371, s1376);
+  s1378 = s1313 ^ s1377;
+  s1379 = s1364 ^ s1378;
+  s1380 = sbv_bv_extract_u32_31_24_u8(s1379);
+  s1381 = table1[s1380];
+  s1382 = sbv_bv_extract_u32_31_24_u8(s1329);
+  s1383 = table1[s1382];
+  s1384 = sbv_bv_extract_u32_23_16_u8(s1345);
+  s1385 = table2[s1384];
+  s1386 = s1383 ^ s1385;
+  s1387 = sbv_bv_extract_u32_15_8_u8(s1361);
+  s1388 = table3[s1387];
+  s1389 = s1386 ^ s1388;
+  s1390 = sbv_bv_extract_u32_7_0_u8(s1314);
+  s1391 = table4[s1390];
+  s1392 = s1389 ^ s1391;
+  s1393 = s1328 ^ s1378;
+  s1394 = s1392 ^ s1393;
+  s1395 = sbv_bv_extract_u32_23_16_u8(s1394);
+  s1396 = table2[s1395];
+  s1397 = s1381 ^ s1396;
+  s1398 = sbv_bv_extract_u32_31_24_u8(s1345);
+  s1399 = table1[s1398];
+  s1400 = sbv_bv_extract_u32_23_16_u8(s1361);
+  s1401 = table2[s1400];
+  s1402 = s1399 ^ s1401;
+  s1403 = sbv_bv_extract_u32_15_8_u8(s1314);
+  s1404 = table3[s1403];
+  s1405 = s1402 ^ s1404;
+  s1406 = sbv_bv_extract_u32_7_0_u8(s1329);
+  s1407 = table4[s1406];
+  s1408 = s1405 ^ s1407;
+  s1409 = s1344 ^ s1393;
+  s1410 = s1408 ^ s1409;
+  s1411 = sbv_bv_extract_u32_15_8_u8(s1410);
+  s1412 = table3[s1411];
+  s1413 = s1397 ^ s1412;
+  s1414 = sbv_bv_extract_u32_31_24_u8(s1361);
+  s1415 = table1[s1414];
+  s1416 = sbv_bv_extract_u32_23_16_u8(s1314);
+  s1417 = table2[s1416];
+  s1418 = s1415 ^ s1417;
+  s1419 = sbv_bv_extract_u32_15_8_u8(s1329);
+  s1420 = table3[s1419];
+  s1421 = s1418 ^ s1420;
+  s1422 = sbv_bv_extract_u32_7_0_u8(s1345);
+  s1423 = table4[s1422];
+  s1424 = s1421 ^ s1423;
+  s1425 = s1360 ^ s1409;
+  s1426 = s1424 ^ s1425;
+  s1427 = sbv_bv_extract_u32_7_0_u8(s1426);
+  s1428 = table4[s1427];
+  s1429 = s1413 ^ s1428;
+  s1430 = sbv_bv_u32_rotl(s1425, 8);
+  s1431 = sbv_bv_extract_u32_31_24_u8(s1430);
+  s1432 = table0[s1431];
+  s1433 = 4 ^ s1432;
+  s1434 = sbv_bv_extract_u32_23_16_u8(s1430);
+  s1435 = table0[s1434];
+  s1436 = sbv_bv_join_u8_u8_u16(s1433, s1435);
+  s1437 = sbv_bv_extract_u32_15_8_u8(s1430);
+  s1438 = table0[s1437];
+  s1439 = sbv_bv_extract_u32_7_0_u8(s1430);
+  s1440 = table0[s1439];
+  s1441 = sbv_bv_join_u8_u8_u16(s1438, s1440);
+  s1442 = sbv_bv_join_u16_u16_u32(s1436, s1441);
+  s1443 = s1378 ^ s1442;
+  s1444 = s1429 ^ s1443;
+  s1445 = sbv_bv_extract_u32_31_24_u8(s1444);
+  s1446 = table1[s1445];
+  s1447 = sbv_bv_extract_u32_31_24_u8(s1394);
+  s1448 = table1[s1447];
+  s1449 = sbv_bv_extract_u32_23_16_u8(s1410);
+  s1450 = table2[s1449];
+  s1451 = s1448 ^ s1450;
+  s1452 = sbv_bv_extract_u32_15_8_u8(s1426);
+  s1453 = table3[s1452];
+  s1454 = s1451 ^ s1453;
+  s1455 = sbv_bv_extract_u32_7_0_u8(s1379);
+  s1456 = table4[s1455];
+  s1457 = s1454 ^ s1456;
+  s1458 = s1393 ^ s1443;
+  s1459 = s1457 ^ s1458;
+  s1460 = sbv_bv_extract_u32_23_16_u8(s1459);
+  s1461 = table2[s1460];
+  s1462 = s1446 ^ s1461;
+  s1463 = sbv_bv_extract_u32_31_24_u8(s1410);
+  s1464 = table1[s1463];
+  s1465 = sbv_bv_extract_u32_23_16_u8(s1426);
+  s1466 = table2[s1465];
+  s1467 = s1464 ^ s1466;
+  s1468 = sbv_bv_extract_u32_15_8_u8(s1379);
+  s1469 = table3[s1468];
+  s1470 = s1467 ^ s1469;
+  s1471 = sbv_bv_extract_u32_7_0_u8(s1394);
+  s1472 = table4[s1471];
+  s1473 = s1470 ^ s1472;
+  s1474 = s1409 ^ s1458;
+  s1475 = s1473 ^ s1474;
+  s1476 = sbv_bv_extract_u32_15_8_u8(s1475);
+  s1477 = table3[s1476];
+  s1478 = s1462 ^ s1477;
+  s1479 = sbv_bv_extract_u32_31_24_u8(s1426);
+  s1480 = table1[s1479];
+  s1481 = sbv_bv_extract_u32_23_16_u8(s1379);
+  s1482 = table2[s1481];
+  s1483 = s1480 ^ s1482;
+  s1484 = sbv_bv_extract_u32_15_8_u8(s1394);
+  s1485 = table3[s1484];
+  s1486 = s1483 ^ s1485;
+  s1487 = sbv_bv_extract_u32_7_0_u8(s1410);
+  s1488 = table4[s1487];
+  s1489 = s1486 ^ s1488;
+  s1490 = s1425 ^ s1474;
+  s1491 = s1489 ^ s1490;
+  s1492 = sbv_bv_extract_u32_7_0_u8(s1491);
+  s1493 = table4[s1492];
+  s1494 = s1478 ^ s1493;
+  s1495 = sbv_bv_u32_rotl(s1490, 8);
+  s1496 = sbv_bv_extract_u32_31_24_u8(s1495);
+  s1497 = table0[s1496];
+  s1498 = 8 ^ s1497;
+  s1499 = sbv_bv_extract_u32_23_16_u8(s1495);
+  s1500 = table0[s1499];
+  s1501 = sbv_bv_join_u8_u8_u16(s1498, s1500);
+  s1502 = sbv_bv_extract_u32_15_8_u8(s1495);
+  s1503 = table0[s1502];
+  s1504 = sbv_bv_extract_u32_7_0_u8(s1495);
+  s1505 = table0[s1504];
+  s1506 = sbv_bv_join_u8_u8_u16(s1503, s1505);
+  s1507 = sbv_bv_join_u16_u16_u32(s1501, s1506);
+  s1508 = s1443 ^ s1507;
+  s1509 = s1494 ^ s1508;
+  s1510 = sbv_bv_extract_u32_31_24_u8(s1509);
+  s1511 = table1[s1510];
+  s1512 = sbv_bv_extract_u32_31_24_u8(s1459);
+  s1513 = table1[s1512];
+  s1514 = sbv_bv_extract_u32_23_16_u8(s1475);
+  s1515 = table2[s1514];
+  s1516 = s1513 ^ s1515;
+  s1517 = sbv_bv_extract_u32_15_8_u8(s1491);
+  s1518 = table3[s1517];
+  s1519 = s1516 ^ s1518;
+  s1520 = sbv_bv_extract_u32_7_0_u8(s1444);
+  s1521 = table4[s1520];
+  s1522 = s1519 ^ s1521;
+  s1523 = s1458 ^ s1508;
+  s1524 = s1522 ^ s1523;
+  s1525 = sbv_bv_extract_u32_23_16_u8(s1524);
+  s1526 = table2[s1525];
+  s1527 = s1511 ^ s1526;
+  s1528 = sbv_bv_extract_u32_31_24_u8(s1475);
+  s1529 = table1[s1528];
+  s1530 = sbv_bv_extract_u32_23_16_u8(s1491);
+  s1531 = table2[s1530];
+  s1532 = s1529 ^ s1531;
+  s1533 = sbv_bv_extract_u32_15_8_u8(s1444);
+  s1534 = table3[s1533];
+  s1535 = s1532 ^ s1534;
+  s1536 = sbv_bv_extract_u32_7_0_u8(s1459);
+  s1537 = table4[s1536];
+  s1538 = s1535 ^ s1537;
+  s1539 = s1474 ^ s1523;
+  s1540 = s1538 ^ s1539;
+  s1541 = sbv_bv_extract_u32_15_8_u8(s1540);
+  s1542 = table3[s1541];
+  s1543 = s1527 ^ s1542;
+  s1544 = sbv_bv_extract_u32_31_24_u8(s1491);
+  s1545 = table1[s1544];
+  s1546 = sbv_bv_extract_u32_23_16_u8(s1444);
+  s1547 = table2[s1546];
+  s1548 = s1545 ^ s1547;
+  s1549 = sbv_bv_extract_u32_15_8_u8(s1459);
+  s1550 = table3[s1549];
+  s1551 = s1548 ^ s1550;
+  s1552 = sbv_bv_extract_u32_7_0_u8(s1475);
+  s1553 = table4[s1552];
+  s1554 = s1551 ^ s1553;
+  s1555 = s1490 ^ s1539;
+  s1556 = s1554 ^ s1555;
+  s1557 = sbv_bv_extract_u32_7_0_u8(s1556);
+  s1558 = table4[s1557];
+  s1559 = s1543 ^ s1558;
+  s1560 = sbv_bv_u32_rotl(s1555, 8);
+  s1561 = sbv_bv_extract_u32_31_24_u8(s1560);
+  s1562 = table0[s1561];
+  s1563 = 16 ^ s1562;
+  s1564 = sbv_bv_extract_u32_23_16_u8(s1560);
+  s1565 = table0[s1564];
+  s1566 = sbv_bv_join_u8_u8_u16(s1563, s1565);
+  s1567 = sbv_bv_extract_u32_15_8_u8(s1560);
+  s1568 = table0[s1567];
+  s1569 = sbv_bv_extract_u32_7_0_u8(s1560);
+  s1570 = table0[s1569];
+  s1571 = sbv_bv_join_u8_u8_u16(s1568, s1570);
+  s1572 = sbv_bv_join_u16_u16_u32(s1566, s1571);
+  s1573 = s1508 ^ s1572;
+  s1574 = s1559 ^ s1573;
+  s1575 = sbv_bv_extract_u32_31_24_u8(s1574);
+  s1576 = table1[s1575];
+  s1577 = sbv_bv_extract_u32_31_24_u8(s1524);
+  s1578 = table1[s1577];
+  s1579 = sbv_bv_extract_u32_23_16_u8(s1540);
+  s1580 = table2[s1579];
+  s1581 = s1578 ^ s1580;
+  s1582 = sbv_bv_extract_u32_15_8_u8(s1556);
+  s1583 = table3[s1582];
+  s1584 = s1581 ^ s1583;
+  s1585 = sbv_bv_extract_u32_7_0_u8(s1509);
+  s1586 = table4[s1585];
+  s1587 = s1584 ^ s1586;
+  s1588 = s1523 ^ s1573;
+  s1589 = s1587 ^ s1588;
+  s1590 = sbv_bv_extract_u32_23_16_u8(s1589);
+  s1591 = table2[s1590];
+  s1592 = s1576 ^ s1591;
+  s1593 = sbv_bv_extract_u32_31_24_u8(s1540);
+  s1594 = table1[s1593];
+  s1595 = sbv_bv_extract_u32_23_16_u8(s1556);
+  s1596 = table2[s1595];
+  s1597 = s1594 ^ s1596;
+  s1598 = sbv_bv_extract_u32_15_8_u8(s1509);
+  s1599 = table3[s1598];
+  s1600 = s1597 ^ s1599;
+  s1601 = sbv_bv_extract_u32_7_0_u8(s1524);
+  s1602 = table4[s1601];
+  s1603 = s1600 ^ s1602;
+  s1604 = s1539 ^ s1588;
+  s1605 = s1603 ^ s1604;
+  s1606 = sbv_bv_extract_u32_15_8_u8(s1605);
+  s1607 = table3[s1606];
+  s1608 = s1592 ^ s1607;
+  s1609 = sbv_bv_extract_u32_31_24_u8(s1556);
+  s1610 = table1[s1609];
+  s1611 = sbv_bv_extract_u32_23_16_u8(s1509);
+  s1612 = table2[s1611];
+  s1613 = s1610 ^ s1612;
+  s1614 = sbv_bv_extract_u32_15_8_u8(s1524);
+  s1615 = table3[s1614];
+  s1616 = s1613 ^ s1615;
+  s1617 = sbv_bv_extract_u32_7_0_u8(s1540);
+  s1618 = table4[s1617];
+  s1619 = s1616 ^ s1618;
+  s1620 = s1555 ^ s1604;
+  s1621 = s1619 ^ s1620;
+  s1622 = sbv_bv_extract_u32_7_0_u8(s1621);
+  s1623 = table4[s1622];
+  s1624 = s1608 ^ s1623;
+  s1625 = sbv_bv_u32_rotl(s1620, 8);
+  s1626 = sbv_bv_extract_u32_31_24_u8(s1625);
+  s1627 = table0[s1626];
+  s1628 = 32 ^ s1627;
+  s1629 = sbv_bv_extract_u32_23_16_u8(s1625);
+  s1630 = table0[s1629];
+  s1631 = sbv_bv_join_u8_u8_u16(s1628, s1630);
+  s1632 = sbv_bv_extract_u32_15_8_u8(s1625);
+  s1633 = table0[s1632];
+  s1634 = sbv_bv_extract_u32_7_0_u8(s1625);
+  s1635 = table0[s1634];
+  s1636 = sbv_bv_join_u8_u8_u16(s1633, s1635);
+  s1637 = sbv_bv_join_u16_u16_u32(s1631, s1636);
+  s1638 = s1573 ^ s1637;
+  s1639 = s1624 ^ s1638;
+  s1640 = sbv_bv_extract_u32_31_24_u8(s1639);
+  s1641 = table1[s1640];
+  s1642 = sbv_bv_extract_u32_31_24_u8(s1589);
+  s1643 = table1[s1642];
+  s1644 = sbv_bv_extract_u32_23_16_u8(s1605);
+  s1645 = table2[s1644];
+  s1646 = s1643 ^ s1645;
+  s1647 = sbv_bv_extract_u32_15_8_u8(s1621);
+  s1648 = table3[s1647];
+  s1649 = s1646 ^ s1648;
+  s1650 = sbv_bv_extract_u32_7_0_u8(s1574);
+  s1651 = table4[s1650];
+  s1652 = s1649 ^ s1651;
+  s1653 = s1588 ^ s1638;
+  s1654 = s1652 ^ s1653;
+  s1655 = sbv_bv_extract_u32_23_16_u8(s1654);
+  s1656 = table2[s1655];
+  s1657 = s1641 ^ s1656;
+  s1658 = sbv_bv_extract_u32_31_24_u8(s1605);
+  s1659 = table1[s1658];
+  s1660 = sbv_bv_extract_u32_23_16_u8(s1621);
+  s1661 = table2[s1660];
+  s1662 = s1659 ^ s1661;
+  s1663 = sbv_bv_extract_u32_15_8_u8(s1574);
+  s1664 = table3[s1663];
+  s1665 = s1662 ^ s1664;
+  s1666 = sbv_bv_extract_u32_7_0_u8(s1589);
+  s1667 = table4[s1666];
+  s1668 = s1665 ^ s1667;
+  s1669 = s1604 ^ s1653;
+  s1670 = s1668 ^ s1669;
+  s1671 = sbv_bv_extract_u32_15_8_u8(s1670);
+  s1672 = table3[s1671];
+  s1673 = s1657 ^ s1672;
+  s1674 = sbv_bv_extract_u32_31_24_u8(s1621);
+  s1675 = table1[s1674];
+  s1676 = sbv_bv_extract_u32_23_16_u8(s1574);
+  s1677 = table2[s1676];
+  s1678 = s1675 ^ s1677;
+  s1679 = sbv_bv_extract_u32_15_8_u8(s1589);
+  s1680 = table3[s1679];
+  s1681 = s1678 ^ s1680;
+  s1682 = sbv_bv_extract_u32_7_0_u8(s1605);
+  s1683 = table4[s1682];
+  s1684 = s1681 ^ s1683;
+  s1685 = s1620 ^ s1669;
+  s1686 = s1684 ^ s1685;
+  s1687 = sbv_bv_extract_u32_7_0_u8(s1686);
+  s1688 = table4[s1687];
+  s1689 = s1673 ^ s1688;
+  s1690 = sbv_bv_u32_rotl(s1685, 8);
+  s1691 = sbv_bv_extract_u32_31_24_u8(s1690);
+  s1692 = table0[s1691];
+  s1693 = 64 ^ s1692;
+  s1694 = sbv_bv_extract_u32_23_16_u8(s1690);
+  s1695 = table0[s1694];
+  s1696 = sbv_bv_join_u8_u8_u16(s1693, s1695);
+  s1697 = sbv_bv_extract_u32_15_8_u8(s1690);
+  s1698 = table0[s1697];
+  s1699 = sbv_bv_extract_u32_7_0_u8(s1690);
+  s1700 = table0[s1699];
+  s1701 = sbv_bv_join_u8_u8_u16(s1698, s1700);
+  s1702 = sbv_bv_join_u16_u16_u32(s1696, s1701);
+  s1703 = s1638 ^ s1702;
+  s1704 = s1689 ^ s1703;
+  s1705 = sbv_bv_extract_u32_31_24_u8(s1704);
+  s1706 = table1[s1705];
+  s1707 = sbv_bv_extract_u32_31_24_u8(s1654);
+  s1708 = table1[s1707];
+  s1709 = sbv_bv_extract_u32_23_16_u8(s1670);
+  s1710 = table2[s1709];
+  s1711 = s1708 ^ s1710;
+  s1712 = sbv_bv_extract_u32_15_8_u8(s1686);
+  s1713 = table3[s1712];
+  s1714 = s1711 ^ s1713;
+  s1715 = sbv_bv_extract_u32_7_0_u8(s1639);
+  s1716 = table4[s1715];
+  s1717 = s1714 ^ s1716;
+  s1718 = s1653 ^ s1703;
+  s1719 = s1717 ^ s1718;
+  s1720 = sbv_bv_extract_u32_23_16_u8(s1719);
+  s1721 = table2[s1720];
+  s1722 = s1706 ^ s1721;
+  s1723 = sbv_bv_extract_u32_31_24_u8(s1670);
+  s1724 = table1[s1723];
+  s1725 = sbv_bv_extract_u32_23_16_u8(s1686);
+  s1726 = table2[s1725];
+  s1727 = s1724 ^ s1726;
+  s1728 = sbv_bv_extract_u32_15_8_u8(s1639);
+  s1729 = table3[s1728];
+  s1730 = s1727 ^ s1729;
+  s1731 = sbv_bv_extract_u32_7_0_u8(s1654);
+  s1732 = table4[s1731];
+  s1733 = s1730 ^ s1732;
+  s1734 = s1669 ^ s1718;
+  s1735 = s1733 ^ s1734;
+  s1736 = sbv_bv_extract_u32_15_8_u8(s1735);
+  s1737 = table3[s1736];
+  s1738 = s1722 ^ s1737;
+  s1739 = sbv_bv_extract_u32_31_24_u8(s1686);
+  s1740 = table1[s1739];
+  s1741 = sbv_bv_extract_u32_23_16_u8(s1639);
+  s1742 = table2[s1741];
+  s1743 = s1740 ^ s1742;
+  s1744 = sbv_bv_extract_u32_15_8_u8(s1654);
+  s1745 = table3[s1744];
+  s1746 = s1743 ^ s1745;
+  s1747 = sbv_bv_extract_u32_7_0_u8(s1670);
+  s1748 = table4[s1747];
+  s1749 = s1746 ^ s1748;
+  s1750 = s1685 ^ s1734;
+  s1751 = s1749 ^ s1750;
+  s1752 = sbv_bv_extract_u32_7_0_u8(s1751);
+  s1753 = table4[s1752];
+  s1754 = s1738 ^ s1753;
+  s1755 = sbv_bv_u32_rotl(s1750, 8);
+  s1756 = sbv_bv_extract_u32_31_24_u8(s1755);
+  s1757 = table0[s1756];
+  s1758 = 128 ^ s1757;
+  s1759 = sbv_bv_extract_u32_23_16_u8(s1755);
+  s1760 = table0[s1759];
+  s1761 = sbv_bv_join_u8_u8_u16(s1758, s1760);
+  s1762 = sbv_bv_extract_u32_15_8_u8(s1755);
+  s1763 = table0[s1762];
+  s1764 = sbv_bv_extract_u32_7_0_u8(s1755);
+  s1765 = table0[s1764];
+  s1766 = sbv_bv_join_u8_u8_u16(s1763, s1765);
+  s1767 = sbv_bv_join_u16_u16_u32(s1761, s1766);
+  s1768 = s1703 ^ s1767;
+  s1769 = s1754 ^ s1768;
+  s1770 = sbv_bv_extract_u32_31_24_u8(s1769);
+  s1771 = table1[s1770];
+  s1772 = sbv_bv_extract_u32_31_24_u8(s1719);
+  s1773 = table1[s1772];
+  s1774 = sbv_bv_extract_u32_23_16_u8(s1735);
+  s1775 = table2[s1774];
+  s1776 = s1773 ^ s1775;
+  s1777 = sbv_bv_extract_u32_15_8_u8(s1751);
+  s1778 = table3[s1777];
+  s1779 = s1776 ^ s1778;
+  s1780 = sbv_bv_extract_u32_7_0_u8(s1704);
+  s1781 = table4[s1780];
+  s1782 = s1779 ^ s1781;
+  s1783 = s1718 ^ s1768;
+  s1784 = s1782 ^ s1783;
+  s1785 = sbv_bv_extract_u32_23_16_u8(s1784);
+  s1786 = table2[s1785];
+  s1787 = s1771 ^ s1786;
+  s1788 = sbv_bv_extract_u32_31_24_u8(s1735);
+  s1789 = table1[s1788];
+  s1790 = sbv_bv_extract_u32_23_16_u8(s1751);
+  s1791 = table2[s1790];
+  s1792 = s1789 ^ s1791;
+  s1793 = sbv_bv_extract_u32_15_8_u8(s1704);
+  s1794 = table3[s1793];
+  s1795 = s1792 ^ s1794;
+  s1796 = sbv_bv_extract_u32_7_0_u8(s1719);
+  s1797 = table4[s1796];
+  s1798 = s1795 ^ s1797;
+  s1799 = s1734 ^ s1783;
+  s1800 = s1798 ^ s1799;
+  s1801 = sbv_bv_extract_u32_15_8_u8(s1800);
+  s1802 = table3[s1801];
+  s1803 = s1787 ^ s1802;
+  s1804 = sbv_bv_extract_u32_31_24_u8(s1751);
+  s1805 = table1[s1804];
+  s1806 = sbv_bv_extract_u32_23_16_u8(s1704);
+  s1807 = table2[s1806];
+  s1808 = s1805 ^ s1807;
+  s1809 = sbv_bv_extract_u32_15_8_u8(s1719);
+  s1810 = table3[s1809];
+  s1811 = s1808 ^ s1810;
+  s1812 = sbv_bv_extract_u32_7_0_u8(s1735);
+  s1813 = table4[s1812];
+  s1814 = s1811 ^ s1813;
+  s1815 = s1750 ^ s1799;
+  s1816 = s1814 ^ s1815;
+  s1817 = sbv_bv_extract_u32_7_0_u8(s1816);
+  s1818 = table4[s1817];
+  s1819 = s1803 ^ s1818;
+  s1820 = sbv_bv_u32_rotl(s1815, 8);
+  s1821 = sbv_bv_extract_u32_31_24_u8(s1820);
+  s1822 = table0[s1821];
+  s1823 = 27 ^ s1822;
+  s1824 = sbv_bv_extract_u32_23_16_u8(s1820);
+  s1825 = table0[s1824];
+  s1826 = sbv_bv_join_u8_u8_u16(s1823, s1825);
+  s1827 = sbv_bv_extract_u32_15_8_u8(s1820);
+  s1828 = table0[s1827];
+  s1829 = sbv_bv_extract_u32_7_0_u8(s1820);
+  s1830 = table0[s1829];
+  s1831 = sbv_bv_join_u8_u8_u16(s1828, s1830);
+  s1832 = sbv_bv_join_u16_u16_u32(s1826, s1831);
+  s1833 = s1768 ^ s1832;
+  s1834 = s1819 ^ s1833;
+  s1835 = sbv_bv_extract_u32_31_24_u8(s1834);
+  s1836 = table0[s1835];
+  s1837 = sbv_bv_extract_u32_31_24_u8(s1784);
+  s1838 = table1[s1837];
+  s1839 = sbv_bv_extract_u32_23_16_u8(s1800);
+  s1840 = table2[s1839];
+  s1841 = s1838 ^ s1840;
+  s1842 = sbv_bv_extract_u32_15_8_u8(s1816);
+  s1843 = table3[s1842];
+  s1844 = s1841 ^ s1843;
+  s1845 = sbv_bv_extract_u32_7_0_u8(s1769);
+  s1846 = table4[s1845];
+  s1847 = s1844 ^ s1846;
+  s1848 = s1783 ^ s1833;
+  s1849 = s1847 ^ s1848;
+  s1850 = sbv_bv_extract_u32_23_16_u8(s1849);
+  s1851 = table0[s1850];
+  s1852 = sbv_bv_join_u8_u8_u16(s1836, s1851);
+  s1853 = sbv_bv_extract_u32_31_24_u8(s1800);
+  s1854 = table1[s1853];
+  s1855 = sbv_bv_extract_u32_23_16_u8(s1816);
+  s1856 = table2[s1855];
+  s1857 = s1854 ^ s1856;
+  s1858 = sbv_bv_extract_u32_15_8_u8(s1769);
+  s1859 = table3[s1858];
+  s1860 = s1857 ^ s1859;
+  s1861 = sbv_bv_extract_u32_7_0_u8(s1784);
+  s1862 = table4[s1861];
+  s1863 = s1860 ^ s1862;
+  s1864 = s1799 ^ s1848;
+  s1865 = s1863 ^ s1864;
+  s1866 = sbv_bv_extract_u32_15_8_u8(s1865);
+  s1867 = table0[s1866];
+  s1868 = sbv_bv_extract_u32_31_24_u8(s1816);
+  s1869 = table1[s1868];
+  s1870 = sbv_bv_extract_u32_23_16_u8(s1769);
+  s1871 = table2[s1870];
+  s1872 = s1869 ^ s1871;
+  s1873 = sbv_bv_extract_u32_15_8_u8(s1784);
+  s1874 = table3[s1873];
+  s1875 = s1872 ^ s1874;
+  s1876 = sbv_bv_extract_u32_7_0_u8(s1800);
+  s1877 = table4[s1876];
+  s1878 = s1875 ^ s1877;
+  s1879 = s1815 ^ s1864;
+  s1880 = s1878 ^ s1879;
+  s1881 = sbv_bv_extract_u32_7_0_u8(s1880);
+  s1882 = table0[s1881];
+  s1883 = sbv_bv_join_u8_u8_u16(s1867, s1882);
+  s1884 = sbv_bv_join_u16_u16_u32(s1852, s1883);
+  s1885 = sbv_bv_u32_rotl(s1879, 8);
+  s1886 = sbv_bv_extract_u32_31_24_u8(s1885);
+  s1887 = table0[s1886];
+  s1888 = 54 ^ s1887;
+  s1889 = sbv_bv_extract_u32_23_16_u8(s1885);
+  s1890 = table0[s1889];
+  s1891 = sbv_bv_join_u8_u8_u16(s1888, s1890);
+  s1892 = sbv_bv_extract_u32_15_8_u8(s1885);
+  s1893 = table0[s1892];
+  s1894 = sbv_bv_extract_u32_7_0_u8(s1885);
+  s1895 = table0[s1894];
+  s1896 = sbv_bv_join_u8_u8_u16(s1893, s1895);
+  s1897 = sbv_bv_join_u16_u16_u32(s1891, s1896);
+  s1898 = s1833 ^ s1897;
+  s1899 = s1884 ^ s1898;
+  s1900 = sbv_bv_extract_u32_31_24_u8(s1849);
+  s1901 = table0[s1900];
+  s1902 = sbv_bv_extract_u32_23_16_u8(s1865);
+  s1903 = table0[s1902];
+  s1904 = sbv_bv_join_u8_u8_u16(s1901, s1903);
+  s1905 = sbv_bv_extract_u32_15_8_u8(s1880);
+  s1906 = table0[s1905];
+  s1907 = sbv_bv_extract_u32_7_0_u8(s1834);
+  s1908 = table0[s1907];
+  s1909 = sbv_bv_join_u8_u8_u16(s1906, s1908);
+  s1910 = sbv_bv_join_u16_u16_u32(s1904, s1909);
+  s1911 = s1848 ^ s1898;
+  s1912 = s1910 ^ s1911;
+  s1913 = sbv_bv_extract_u32_31_24_u8(s1865);
+  s1914 = table0[s1913];
+  s1915 = sbv_bv_extract_u32_23_16_u8(s1880);
+  s1916 = table0[s1915];
+  s1917 = sbv_bv_join_u8_u8_u16(s1914, s1916);
+  s1918 = sbv_bv_extract_u32_15_8_u8(s1834);
+  s1919 = table0[s1918];
+  s1920 = sbv_bv_extract_u32_7_0_u8(s1849);
+  s1921 = table0[s1920];
+  s1922 = sbv_bv_join_u8_u8_u16(s1919, s1921);
+  s1923 = sbv_bv_join_u16_u16_u32(s1917, s1922);
+  s1924 = s1864 ^ s1911;
+  s1925 = s1923 ^ s1924;
+  s1926 = sbv_bv_extract_u32_31_24_u8(s1880);
+  s1927 = table0[s1926];
+  s1928 = sbv_bv_extract_u32_23_16_u8(s1834);
+  s1929 = table0[s1928];
+  s1930 = sbv_bv_join_u8_u8_u16(s1927, s1929);
+  s1931 = sbv_bv_extract_u32_15_8_u8(s1849);
+  s1932 = table0[s1931];
+  s1933 = sbv_bv_extract_u32_7_0_u8(s1865);
+  s1934 = table0[s1933];
+  s1935 = sbv_bv_join_u8_u8_u16(s1932, s1934);
+  s1936 = sbv_bv_join_u16_u16_u32(s1930, s1935);
+  s1937 = s1879 ^ s1924;
+  s1938 = s1936 ^ s1937;
+
+  sbv_output_0[0] = s1899;
+  sbv_output_0[1] = s1912;
+  sbv_output_0[2] = s1925;
+  sbv_output_0[3] = s1938;
 }
 == END: "aes128Enc.c" ==================
diff --git a/SBVTestSuite/GoldFiles/aes128Lib.gold b/SBVTestSuite/GoldFiles/aes128Lib.gold
--- a/SBVTestSuite/GoldFiles/aes128Lib.gold
+++ b/SBVTestSuite/GoldFiles/aes128Lib.gold
@@ -3,5077 +3,8670 @@
 
 #include "aes128Lib.h"
 
-void aes128KeySchedule(const SWord32 *key, SWord32 *encKS,
-                       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
-  };
-  static const SWord8 table1[] = {
-        0,  14,  28,  18,  56,  54,  36,  42, 112, 126, 108,  98,  72,
-       70,  84,  90, 224, 238, 252, 242, 216, 214, 196, 202, 144, 158,
-      140, 130, 168, 166, 180, 186, 219, 213, 199, 201, 227, 237, 255,
-      241, 171, 165, 183, 185, 147, 157, 143, 129,  59,  53,  39,  41,
-        3,  13,  31,  17,  75,  69,  87,  89, 115, 125, 111,  97, 173,
-      163, 177, 191, 149, 155, 137, 135, 221, 211, 193, 207, 229, 235,
-      249, 247,  77,  67,  81,  95, 117, 123, 105, 103,  61,  51,  33,
-       47,   5,  11,  25,  23, 118, 120, 106, 100,  78,  64,  82,  92,
-        6,   8,  26,  20,  62,  48,  34,  44, 150, 152, 138, 132, 174,
-      160, 178, 188, 230, 232, 250, 244, 222, 208, 194, 204,  65,  79,
-       93,  83, 121, 119, 101, 107,  49,  63,  45,  35,   9,   7,  21,
-       27, 161, 175, 189, 179, 153, 151, 133, 139, 209, 223, 205, 195,
-      233, 231, 245, 251, 154, 148, 134, 136, 162, 172, 190, 176, 234,
-      228, 246, 248, 210, 220, 206, 192, 122, 116, 102, 104,  66,  76,
-       94,  80,  10,   4,  22,  24,  50,  60,  46,  32, 236, 226, 240,
-      254, 212, 218, 200, 198, 156, 146, 128, 142, 164, 170, 184, 182,
-       12,   2,  16,  30,  52,  58,  40,  38, 124, 114,  96, 110,  68,
-       74,  88,  86,  55,  57,  43,  37,  15,   1,  19,  29,  71,  73,
-       91,  85, 127, 113,  99, 109, 215, 217, 203, 197, 239, 225, 243,
-      253, 167, 169, 187, 181, 159, 145, 131, 141
-  };
-  static const SWord8 table2[] = {
-        0,  11,  22,  29,  44,  39,  58,  49,  88,  83,  78,  69, 116,
-      127,  98, 105, 176, 187, 166, 173, 156, 151, 138, 129, 232, 227,
-      254, 245, 196, 207, 210, 217, 123, 112, 109, 102,  87,  92,  65,
-       74,  35,  40,  53,  62,  15,   4,  25,  18, 203, 192, 221, 214,
-      231, 236, 241, 250, 147, 152, 133, 142, 191, 180, 169, 162, 246,
-      253, 224, 235, 218, 209, 204, 199, 174, 165, 184, 179, 130, 137,
-      148, 159,  70,  77,  80,  91, 106,  97, 124, 119,  30,  21,   8,
-        3,  50,  57,  36,  47, 141, 134, 155, 144, 161, 170, 183, 188,
-      213, 222, 195, 200, 249, 242, 239, 228,  61,  54,  43,  32,  17,
-       26,   7,  12, 101, 110, 115, 120,  73,  66,  95,  84, 247, 252,
-      225, 234, 219, 208, 205, 198, 175, 164, 185, 178, 131, 136, 149,
-      158,  71,  76,  81,  90, 107,  96, 125, 118,  31,  20,   9,   2,
-       51,  56,  37,  46, 140, 135, 154, 145, 160, 171, 182, 189, 212,
-      223, 194, 201, 248, 243, 238, 229,  60,  55,  42,  33,  16,  27,
-        6,  13, 100, 111, 114, 121,  72,  67,  94,  85,   1,  10,  23,
-       28,  45,  38,  59,  48,  89,  82,  79,  68, 117, 126,  99, 104,
-      177, 186, 167, 172, 157, 150, 139, 128, 233, 226, 255, 244, 197,
-      206, 211, 216, 122, 113, 108, 103,  86,  93,  64,  75,  34,  41,
-       52,  63,  14,   5,  24,  19, 202, 193, 220, 215, 230, 237, 240,
-      251, 146, 153, 132, 143, 190, 181, 168, 163
-  };
-  static const SWord8 table3[] = {
-        0,  13,  26,  23,  52,  57,  46,  35, 104, 101, 114, 127,  92,
-       81,  70,  75, 208, 221, 202, 199, 228, 233, 254, 243, 184, 181,
-      162, 175, 140, 129, 150, 155, 187, 182, 161, 172, 143, 130, 149,
-      152, 211, 222, 201, 196, 231, 234, 253, 240, 107, 102, 113, 124,
-       95,  82,  69,  72,   3,  14,  25,  20,  55,  58,  45,  32, 109,
-       96, 119, 122,  89,  84,  67,  78,   5,   8,  31,  18,  49,  60,
-       43,  38, 189, 176, 167, 170, 137, 132, 147, 158, 213, 216, 207,
-      194, 225, 236, 251, 246, 214, 219, 204, 193, 226, 239, 248, 245,
-      190, 179, 164, 169, 138, 135, 144, 157,   6,  11,  28,  17,  50,
-       63,  40,  37, 110,  99, 116, 121,  90,  87,  64,  77, 218, 215,
-      192, 205, 238, 227, 244, 249, 178, 191, 168, 165, 134, 139, 156,
-      145,  10,   7,  16,  29,  62,  51,  36,  41,  98, 111, 120, 117,
-       86,  91,  76,  65,  97, 108, 123, 118,  85,  88,  79,  66,   9,
-        4,  19,  30,  61,  48,  39,  42, 177, 188, 171, 166, 133, 136,
-      159, 146, 217, 212, 195, 206, 237, 224, 247, 250, 183, 186, 173,
-      160, 131, 142, 153, 148, 223, 210, 197, 200, 235, 230, 241, 252,
-      103, 106, 125, 112,  83,  94,  73,  68,  15,   2,  21,  24,  59,
-       54,  33,  44,  12,   1,  22,  27,  56,  53,  34,  47, 100, 105,
-      126, 115,  80,  93,  74,  71, 220, 209, 198, 203, 232, 229, 242,
-      255, 180, 185, 174, 163, 128, 141, 154, 151
-  };
-  static const SWord8 table4[] = {
-        0,   9,  18,  27,  36,  45,  54,  63,  72,  65,  90,  83, 108,
-      101, 126, 119, 144, 153, 130, 139, 180, 189, 166, 175, 216, 209,
-      202, 195, 252, 245, 238, 231,  59,  50,  41,  32,  31,  22,  13,
-        4, 115, 122,  97, 104,  87,  94,  69,  76, 171, 162, 185, 176,
-      143, 134, 157, 148, 227, 234, 241, 248, 199, 206, 213, 220, 118,
-      127, 100, 109,  82,  91,  64,  73,  62,  55,  44,  37,  26,  19,
-        8,   1, 230, 239, 244, 253, 194, 203, 208, 217, 174, 167, 188,
-      181, 138, 131, 152, 145,  77,  68,  95,  86, 105,  96, 123, 114,
-        5,  12,  23,  30,  33,  40,  51,  58, 221, 212, 207, 198, 249,
-      240, 235, 226, 149, 156, 135, 142, 177, 184, 163, 170, 236, 229,
-      254, 247, 200, 193, 218, 211, 164, 173, 182, 191, 128, 137, 146,
-      155, 124, 117, 110, 103,  88,  81,  74,  67,  52,  61,  38,  47,
-       16,  25,   2,  11, 215, 222, 197, 204, 243, 250, 225, 232, 159,
-      150, 141, 132, 187, 178, 169, 160,  71,  78,  85,  92,  99, 106,
-      113, 120,  15,   6,  29,  20,  43,  34,  57,  48, 154, 147, 136,
-      129, 190, 183, 172, 165, 210, 219, 192, 201, 246, 255, 228, 237,
-       10,   3,  24,  17,  46,  39,  60,  53,  66,  75,  80,  89, 102,
-      111, 116, 125, 161, 168, 179, 186, 133, 140, 151, 158, 233, 224,
-      251, 242, 205, 196, 223, 214,  49,  56,  35,  42,  21,  28,   7,
-       14, 121, 112, 107,  98,  93,  84,  79,  70
-  };
-  const SWord32 s260 = (s3 << 8) | (s3 >> 24);
-  const SWord8  s261 = (SWord8) (s260 >> 24);
-  const SWord8  s262 = table0[s261];
-  const SWord8  s263 = 1 ^ s262;
-  const SWord8  s264 = (SWord8) (s260 >> 16);
-  const SWord8  s265 = table0[s264];
-  const SWord16 s266 = (((SWord16) s263) << 8) | ((SWord16) s265);
-  const SWord8  s267 = (SWord8) (s260 >> 8);
-  const SWord8  s268 = table0[s267];
-  const SWord8  s269 = (SWord8) s260;
-  const SWord8  s270 = table0[s269];
-  const SWord16 s271 = (((SWord16) s268) << 8) | ((SWord16) s270);
-  const SWord32 s272 = (((SWord32) s266) << 16) | ((SWord32) s271);
-  const SWord32 s273 = s0 ^ s272;
-  const SWord32 s274 = s1 ^ s273;
-  const SWord32 s275 = s2 ^ s274;
-  const SWord32 s276 = s3 ^ s275;
-  const SWord32 s277 = (s276 << 8) | (s276 >> 24);
-  const SWord8  s278 = (SWord8) (s277 >> 24);
-  const SWord8  s279 = table0[s278];
-  const SWord8  s280 = 2 ^ s279;
-  const SWord8  s281 = (SWord8) (s277 >> 16);
-  const SWord8  s282 = table0[s281];
-  const SWord16 s283 = (((SWord16) s280) << 8) | ((SWord16) s282);
-  const SWord8  s284 = (SWord8) (s277 >> 8);
-  const SWord8  s285 = table0[s284];
-  const SWord8  s286 = (SWord8) s277;
-  const SWord8  s287 = table0[s286];
-  const SWord16 s288 = (((SWord16) s285) << 8) | ((SWord16) s287);
-  const SWord32 s289 = (((SWord32) s283) << 16) | ((SWord32) s288);
-  const SWord32 s290 = s273 ^ s289;
-  const SWord32 s291 = s274 ^ s290;
-  const SWord32 s292 = s275 ^ s291;
-  const SWord32 s293 = s276 ^ s292;
-  const SWord32 s294 = (s293 << 8) | (s293 >> 24);
-  const SWord8  s295 = (SWord8) (s294 >> 24);
-  const SWord8  s296 = table0[s295];
-  const SWord8  s297 = 4 ^ s296;
-  const SWord8  s298 = (SWord8) (s294 >> 16);
-  const SWord8  s299 = table0[s298];
-  const SWord16 s300 = (((SWord16) s297) << 8) | ((SWord16) s299);
-  const SWord8  s301 = (SWord8) (s294 >> 8);
-  const SWord8  s302 = table0[s301];
-  const SWord8  s303 = (SWord8) s294;
-  const SWord8  s304 = table0[s303];
-  const SWord16 s305 = (((SWord16) s302) << 8) | ((SWord16) s304);
-  const SWord32 s306 = (((SWord32) s300) << 16) | ((SWord32) s305);
-  const SWord32 s307 = s290 ^ s306;
-  const SWord32 s308 = s291 ^ s307;
-  const SWord32 s309 = s292 ^ s308;
-  const SWord32 s310 = s293 ^ s309;
-  const SWord32 s311 = (s310 << 8) | (s310 >> 24);
-  const SWord8  s312 = (SWord8) (s311 >> 24);
-  const SWord8  s313 = table0[s312];
-  const SWord8  s314 = 8 ^ s313;
-  const SWord8  s315 = (SWord8) (s311 >> 16);
-  const SWord8  s316 = table0[s315];
-  const SWord16 s317 = (((SWord16) s314) << 8) | ((SWord16) s316);
-  const SWord8  s318 = (SWord8) (s311 >> 8);
-  const SWord8  s319 = table0[s318];
-  const SWord8  s320 = (SWord8) s311;
-  const SWord8  s321 = table0[s320];
-  const SWord16 s322 = (((SWord16) s319) << 8) | ((SWord16) s321);
-  const SWord32 s323 = (((SWord32) s317) << 16) | ((SWord32) s322);
-  const SWord32 s324 = s307 ^ s323;
-  const SWord32 s325 = s308 ^ s324;
-  const SWord32 s326 = s309 ^ s325;
-  const SWord32 s327 = s310 ^ s326;
-  const SWord32 s328 = (s327 << 8) | (s327 >> 24);
-  const SWord8  s329 = (SWord8) (s328 >> 24);
-  const SWord8  s330 = table0[s329];
-  const SWord8  s331 = 16 ^ s330;
-  const SWord8  s332 = (SWord8) (s328 >> 16);
-  const SWord8  s333 = table0[s332];
-  const SWord16 s334 = (((SWord16) s331) << 8) | ((SWord16) s333);
-  const SWord8  s335 = (SWord8) (s328 >> 8);
-  const SWord8  s336 = table0[s335];
-  const SWord8  s337 = (SWord8) s328;
-  const SWord8  s338 = table0[s337];
-  const SWord16 s339 = (((SWord16) s336) << 8) | ((SWord16) s338);
-  const SWord32 s340 = (((SWord32) s334) << 16) | ((SWord32) s339);
-  const SWord32 s341 = s324 ^ s340;
-  const SWord32 s342 = s325 ^ s341;
-  const SWord32 s343 = s326 ^ s342;
-  const SWord32 s344 = s327 ^ s343;
-  const SWord32 s345 = (s344 << 8) | (s344 >> 24);
-  const SWord8  s346 = (SWord8) (s345 >> 24);
-  const SWord8  s347 = table0[s346];
-  const SWord8  s348 = 32 ^ s347;
-  const SWord8  s349 = (SWord8) (s345 >> 16);
-  const SWord8  s350 = table0[s349];
-  const SWord16 s351 = (((SWord16) s348) << 8) | ((SWord16) s350);
-  const SWord8  s352 = (SWord8) (s345 >> 8);
-  const SWord8  s353 = table0[s352];
-  const SWord8  s354 = (SWord8) s345;
-  const SWord8  s355 = table0[s354];
-  const SWord16 s356 = (((SWord16) s353) << 8) | ((SWord16) s355);
-  const SWord32 s357 = (((SWord32) s351) << 16) | ((SWord32) s356);
-  const SWord32 s358 = s341 ^ s357;
-  const SWord32 s359 = s342 ^ s358;
-  const SWord32 s360 = s343 ^ s359;
-  const SWord32 s361 = s344 ^ s360;
-  const SWord32 s362 = (s361 << 8) | (s361 >> 24);
-  const SWord8  s363 = (SWord8) (s362 >> 24);
-  const SWord8  s364 = table0[s363];
-  const SWord8  s365 = 64 ^ s364;
-  const SWord8  s366 = (SWord8) (s362 >> 16);
-  const SWord8  s367 = table0[s366];
-  const SWord16 s368 = (((SWord16) s365) << 8) | ((SWord16) s367);
-  const SWord8  s369 = (SWord8) (s362 >> 8);
-  const SWord8  s370 = table0[s369];
-  const SWord8  s371 = (SWord8) s362;
-  const SWord8  s372 = table0[s371];
-  const SWord16 s373 = (((SWord16) s370) << 8) | ((SWord16) s372);
-  const SWord32 s374 = (((SWord32) s368) << 16) | ((SWord32) s373);
-  const SWord32 s375 = s358 ^ s374;
-  const SWord32 s376 = s359 ^ s375;
-  const SWord32 s377 = s360 ^ s376;
-  const SWord32 s378 = s361 ^ s377;
-  const SWord32 s379 = (s378 << 8) | (s378 >> 24);
-  const SWord8  s380 = (SWord8) (s379 >> 24);
-  const SWord8  s381 = table0[s380];
-  const SWord8  s382 = 128 ^ s381;
-  const SWord8  s383 = (SWord8) (s379 >> 16);
-  const SWord8  s384 = table0[s383];
-  const SWord16 s385 = (((SWord16) s382) << 8) | ((SWord16) s384);
-  const SWord8  s386 = (SWord8) (s379 >> 8);
-  const SWord8  s387 = table0[s386];
-  const SWord8  s388 = (SWord8) s379;
-  const SWord8  s389 = table0[s388];
-  const SWord16 s390 = (((SWord16) s387) << 8) | ((SWord16) s389);
-  const SWord32 s391 = (((SWord32) s385) << 16) | ((SWord32) s390);
-  const SWord32 s392 = s375 ^ s391;
-  const SWord32 s393 = s376 ^ s392;
-  const SWord32 s394 = s377 ^ s393;
-  const SWord32 s395 = s378 ^ s394;
-  const SWord32 s396 = (s395 << 8) | (s395 >> 24);
-  const SWord8  s397 = (SWord8) (s396 >> 24);
-  const SWord8  s398 = table0[s397];
-  const SWord8  s399 = 27 ^ s398;
-  const SWord8  s400 = (SWord8) (s396 >> 16);
-  const SWord8  s401 = table0[s400];
-  const SWord16 s402 = (((SWord16) s399) << 8) | ((SWord16) s401);
-  const SWord8  s403 = (SWord8) (s396 >> 8);
-  const SWord8  s404 = table0[s403];
-  const SWord8  s405 = (SWord8) s396;
-  const SWord8  s406 = table0[s405];
-  const SWord16 s407 = (((SWord16) s404) << 8) | ((SWord16) s406);
-  const SWord32 s408 = (((SWord32) s402) << 16) | ((SWord32) s407);
-  const SWord32 s409 = s392 ^ s408;
-  const SWord32 s410 = s393 ^ s409;
-  const SWord32 s411 = s394 ^ s410;
-  const SWord32 s412 = s395 ^ s411;
-  const SWord32 s413 = (s412 << 8) | (s412 >> 24);
-  const SWord8  s414 = (SWord8) (s413 >> 24);
-  const SWord8  s415 = table0[s414];
-  const SWord8  s416 = 54 ^ s415;
-  const SWord8  s417 = (SWord8) (s413 >> 16);
-  const SWord8  s418 = table0[s417];
-  const SWord16 s419 = (((SWord16) s416) << 8) | ((SWord16) s418);
-  const SWord8  s420 = (SWord8) (s413 >> 8);
-  const SWord8  s421 = table0[s420];
-  const SWord8  s422 = (SWord8) s413;
-  const SWord8  s423 = table0[s422];
-  const SWord16 s424 = (((SWord16) s421) << 8) | ((SWord16) s423);
-  const SWord32 s425 = (((SWord32) s419) << 16) | ((SWord32) s424);
-  const SWord32 s426 = s409 ^ s425;
-  const SWord32 s427 = s410 ^ s426;
-  const SWord32 s428 = s411 ^ s427;
-  const SWord32 s429 = s412 ^ s428;
-  const SWord8  s430 = (SWord8) (s409 >> 24);
-  const SWord8  s431 = table1[s430];
-  const SWord8  s432 = (SWord8) (s409 >> 16);
-  const SWord8  s433 = table2[s432];
-  const SWord8  s434 = (SWord8) (s409 >> 8);
-  const SWord8  s435 = table3[s434];
-  const SWord8  s436 = (SWord8) s409;
-  const SWord8  s437 = table4[s436];
-  const SWord8  s438 = s435 ^ s437;
-  const SWord8  s439 = s433 ^ s438;
-  const SWord8  s440 = s431 ^ s439;
-  const SWord8  s441 = table4[s430];
-  const SWord8  s442 = table1[s432];
-  const SWord8  s443 = table2[s434];
-  const SWord8  s444 = table3[s436];
-  const SWord8  s445 = s443 ^ s444;
-  const SWord8  s446 = s442 ^ s445;
-  const SWord8  s447 = s441 ^ s446;
-  const SWord16 s448 = (((SWord16) s440) << 8) | ((SWord16) s447);
-  const SWord8  s449 = table3[s430];
-  const SWord8  s450 = table4[s432];
-  const SWord8  s451 = table1[s434];
-  const SWord8  s452 = table2[s436];
-  const SWord8  s453 = s451 ^ s452;
-  const SWord8  s454 = s450 ^ s453;
-  const SWord8  s455 = s449 ^ s454;
-  const SWord8  s456 = table2[s430];
-  const SWord8  s457 = table3[s432];
-  const SWord8  s458 = table4[s434];
-  const SWord8  s459 = table1[s436];
-  const SWord8  s460 = s458 ^ s459;
-  const SWord8  s461 = s457 ^ s460;
-  const SWord8  s462 = s456 ^ s461;
-  const SWord16 s463 = (((SWord16) s455) << 8) | ((SWord16) s462);
-  const SWord32 s464 = (((SWord32) s448) << 16) | ((SWord32) s463);
-  const SWord8  s465 = (SWord8) (s410 >> 24);
-  const SWord8  s466 = table1[s465];
-  const SWord8  s467 = (SWord8) (s410 >> 16);
-  const SWord8  s468 = table2[s467];
-  const SWord8  s469 = (SWord8) (s410 >> 8);
-  const SWord8  s470 = table3[s469];
-  const SWord8  s471 = (SWord8) s410;
-  const SWord8  s472 = table4[s471];
-  const SWord8  s473 = s470 ^ s472;
-  const SWord8  s474 = s468 ^ s473;
-  const SWord8  s475 = s466 ^ s474;
-  const SWord8  s476 = table4[s465];
-  const SWord8  s477 = table1[s467];
-  const SWord8  s478 = table2[s469];
-  const SWord8  s479 = table3[s471];
-  const SWord8  s480 = s478 ^ s479;
-  const SWord8  s481 = s477 ^ s480;
-  const SWord8  s482 = s476 ^ s481;
-  const SWord16 s483 = (((SWord16) s475) << 8) | ((SWord16) s482);
-  const SWord8  s484 = table3[s465];
-  const SWord8  s485 = table4[s467];
-  const SWord8  s486 = table1[s469];
-  const SWord8  s487 = table2[s471];
-  const SWord8  s488 = s486 ^ s487;
-  const SWord8  s489 = s485 ^ s488;
-  const SWord8  s490 = s484 ^ s489;
-  const SWord8  s491 = table2[s465];
-  const SWord8  s492 = table3[s467];
-  const SWord8  s493 = table4[s469];
-  const SWord8  s494 = table1[s471];
-  const SWord8  s495 = s493 ^ s494;
-  const SWord8  s496 = s492 ^ s495;
-  const SWord8  s497 = s491 ^ s496;
-  const SWord16 s498 = (((SWord16) s490) << 8) | ((SWord16) s497);
-  const SWord32 s499 = (((SWord32) s483) << 16) | ((SWord32) s498);
-  const SWord8  s500 = (SWord8) (s411 >> 24);
-  const SWord8  s501 = table1[s500];
-  const SWord8  s502 = (SWord8) (s411 >> 16);
-  const SWord8  s503 = table2[s502];
-  const SWord8  s504 = (SWord8) (s411 >> 8);
-  const SWord8  s505 = table3[s504];
-  const SWord8  s506 = (SWord8) s411;
-  const SWord8  s507 = table4[s506];
-  const SWord8  s508 = s505 ^ s507;
-  const SWord8  s509 = s503 ^ s508;
-  const SWord8  s510 = s501 ^ s509;
-  const SWord8  s511 = table4[s500];
-  const SWord8  s512 = table1[s502];
-  const SWord8  s513 = table2[s504];
-  const SWord8  s514 = table3[s506];
-  const SWord8  s515 = s513 ^ s514;
-  const SWord8  s516 = s512 ^ s515;
-  const SWord8  s517 = s511 ^ s516;
-  const SWord16 s518 = (((SWord16) s510) << 8) | ((SWord16) s517);
-  const SWord8  s519 = table3[s500];
-  const SWord8  s520 = table4[s502];
-  const SWord8  s521 = table1[s504];
-  const SWord8  s522 = table2[s506];
-  const SWord8  s523 = s521 ^ s522;
-  const SWord8  s524 = s520 ^ s523;
-  const SWord8  s525 = s519 ^ s524;
-  const SWord8  s526 = table2[s500];
-  const SWord8  s527 = table3[s502];
-  const SWord8  s528 = table4[s504];
-  const SWord8  s529 = table1[s506];
-  const SWord8  s530 = s528 ^ s529;
-  const SWord8  s531 = s527 ^ s530;
-  const SWord8  s532 = s526 ^ s531;
-  const SWord16 s533 = (((SWord16) s525) << 8) | ((SWord16) s532);
-  const SWord32 s534 = (((SWord32) s518) << 16) | ((SWord32) s533);
-  const SWord8  s535 = (SWord8) (s412 >> 24);
-  const SWord8  s536 = table1[s535];
-  const SWord8  s537 = (SWord8) (s412 >> 16);
-  const SWord8  s538 = table2[s537];
-  const SWord8  s539 = (SWord8) (s412 >> 8);
-  const SWord8  s540 = table3[s539];
-  const SWord8  s541 = (SWord8) s412;
-  const SWord8  s542 = table4[s541];
-  const SWord8  s543 = s540 ^ s542;
-  const SWord8  s544 = s538 ^ s543;
-  const SWord8  s545 = s536 ^ s544;
-  const SWord8  s546 = table4[s535];
-  const SWord8  s547 = table1[s537];
-  const SWord8  s548 = table2[s539];
-  const SWord8  s549 = table3[s541];
-  const SWord8  s550 = s548 ^ s549;
-  const SWord8  s551 = s547 ^ s550;
-  const SWord8  s552 = s546 ^ s551;
-  const SWord16 s553 = (((SWord16) s545) << 8) | ((SWord16) s552);
-  const SWord8  s554 = table3[s535];
-  const SWord8  s555 = table4[s537];
-  const SWord8  s556 = table1[s539];
-  const SWord8  s557 = table2[s541];
-  const SWord8  s558 = s556 ^ s557;
-  const SWord8  s559 = s555 ^ s558;
-  const SWord8  s560 = s554 ^ s559;
-  const SWord8  s561 = table2[s535];
-  const SWord8  s562 = table3[s537];
-  const SWord8  s563 = table4[s539];
-  const SWord8  s564 = table1[s541];
-  const SWord8  s565 = s563 ^ s564;
-  const SWord8  s566 = s562 ^ s565;
-  const SWord8  s567 = s561 ^ s566;
-  const SWord16 s568 = (((SWord16) s560) << 8) | ((SWord16) s567);
-  const SWord32 s569 = (((SWord32) s553) << 16) | ((SWord32) s568);
-  const SWord8  s570 = (SWord8) (s392 >> 24);
-  const SWord8  s571 = table1[s570];
-  const SWord8  s572 = (SWord8) (s392 >> 16);
-  const SWord8  s573 = table2[s572];
-  const SWord8  s574 = (SWord8) (s392 >> 8);
-  const SWord8  s575 = table3[s574];
-  const SWord8  s576 = (SWord8) s392;
-  const SWord8  s577 = table4[s576];
-  const SWord8  s578 = s575 ^ s577;
-  const SWord8  s579 = s573 ^ s578;
-  const SWord8  s580 = s571 ^ s579;
-  const SWord8  s581 = table4[s570];
-  const SWord8  s582 = table1[s572];
-  const SWord8  s583 = table2[s574];
-  const SWord8  s584 = table3[s576];
-  const SWord8  s585 = s583 ^ s584;
-  const SWord8  s586 = s582 ^ s585;
-  const SWord8  s587 = s581 ^ s586;
-  const SWord16 s588 = (((SWord16) s580) << 8) | ((SWord16) s587);
-  const SWord8  s589 = table3[s570];
-  const SWord8  s590 = table4[s572];
-  const SWord8  s591 = table1[s574];
-  const SWord8  s592 = table2[s576];
-  const SWord8  s593 = s591 ^ s592;
-  const SWord8  s594 = s590 ^ s593;
-  const SWord8  s595 = s589 ^ s594;
-  const SWord8  s596 = table2[s570];
-  const SWord8  s597 = table3[s572];
-  const SWord8  s598 = table4[s574];
-  const SWord8  s599 = table1[s576];
-  const SWord8  s600 = s598 ^ s599;
-  const SWord8  s601 = s597 ^ s600;
-  const SWord8  s602 = s596 ^ s601;
-  const SWord16 s603 = (((SWord16) s595) << 8) | ((SWord16) s602);
-  const SWord32 s604 = (((SWord32) s588) << 16) | ((SWord32) s603);
-  const SWord8  s605 = (SWord8) (s393 >> 24);
-  const SWord8  s606 = table1[s605];
-  const SWord8  s607 = (SWord8) (s393 >> 16);
-  const SWord8  s608 = table2[s607];
-  const SWord8  s609 = (SWord8) (s393 >> 8);
-  const SWord8  s610 = table3[s609];
-  const SWord8  s611 = (SWord8) s393;
-  const SWord8  s612 = table4[s611];
-  const SWord8  s613 = s610 ^ s612;
-  const SWord8  s614 = s608 ^ s613;
-  const SWord8  s615 = s606 ^ s614;
-  const SWord8  s616 = table4[s605];
-  const SWord8  s617 = table1[s607];
-  const SWord8  s618 = table2[s609];
-  const SWord8  s619 = table3[s611];
-  const SWord8  s620 = s618 ^ s619;
-  const SWord8  s621 = s617 ^ s620;
-  const SWord8  s622 = s616 ^ s621;
-  const SWord16 s623 = (((SWord16) s615) << 8) | ((SWord16) s622);
-  const SWord8  s624 = table3[s605];
-  const SWord8  s625 = table4[s607];
-  const SWord8  s626 = table1[s609];
-  const SWord8  s627 = table2[s611];
-  const SWord8  s628 = s626 ^ s627;
-  const SWord8  s629 = s625 ^ s628;
-  const SWord8  s630 = s624 ^ s629;
-  const SWord8  s631 = table2[s605];
-  const SWord8  s632 = table3[s607];
-  const SWord8  s633 = table4[s609];
-  const SWord8  s634 = table1[s611];
-  const SWord8  s635 = s633 ^ s634;
-  const SWord8  s636 = s632 ^ s635;
-  const SWord8  s637 = s631 ^ s636;
-  const SWord16 s638 = (((SWord16) s630) << 8) | ((SWord16) s637);
-  const SWord32 s639 = (((SWord32) s623) << 16) | ((SWord32) s638);
-  const SWord8  s640 = (SWord8) (s394 >> 24);
-  const SWord8  s641 = table1[s640];
-  const SWord8  s642 = (SWord8) (s394 >> 16);
-  const SWord8  s643 = table2[s642];
-  const SWord8  s644 = (SWord8) (s394 >> 8);
-  const SWord8  s645 = table3[s644];
-  const SWord8  s646 = (SWord8) s394;
-  const SWord8  s647 = table4[s646];
-  const SWord8  s648 = s645 ^ s647;
-  const SWord8  s649 = s643 ^ s648;
-  const SWord8  s650 = s641 ^ s649;
-  const SWord8  s651 = table4[s640];
-  const SWord8  s652 = table1[s642];
-  const SWord8  s653 = table2[s644];
-  const SWord8  s654 = table3[s646];
-  const SWord8  s655 = s653 ^ s654;
-  const SWord8  s656 = s652 ^ s655;
-  const SWord8  s657 = s651 ^ s656;
-  const SWord16 s658 = (((SWord16) s650) << 8) | ((SWord16) s657);
-  const SWord8  s659 = table3[s640];
-  const SWord8  s660 = table4[s642];
-  const SWord8  s661 = table1[s644];
-  const SWord8  s662 = table2[s646];
-  const SWord8  s663 = s661 ^ s662;
-  const SWord8  s664 = s660 ^ s663;
-  const SWord8  s665 = s659 ^ s664;
-  const SWord8  s666 = table2[s640];
-  const SWord8  s667 = table3[s642];
-  const SWord8  s668 = table4[s644];
-  const SWord8  s669 = table1[s646];
-  const SWord8  s670 = s668 ^ s669;
-  const SWord8  s671 = s667 ^ s670;
-  const SWord8  s672 = s666 ^ s671;
-  const SWord16 s673 = (((SWord16) s665) << 8) | ((SWord16) s672);
-  const SWord32 s674 = (((SWord32) s658) << 16) | ((SWord32) s673);
-  const SWord8  s675 = (SWord8) (s395 >> 24);
-  const SWord8  s676 = table1[s675];
-  const SWord8  s677 = (SWord8) (s395 >> 16);
-  const SWord8  s678 = table2[s677];
-  const SWord8  s679 = (SWord8) (s395 >> 8);
-  const SWord8  s680 = table3[s679];
-  const SWord8  s681 = (SWord8) s395;
-  const SWord8  s682 = table4[s681];
-  const SWord8  s683 = s680 ^ s682;
-  const SWord8  s684 = s678 ^ s683;
-  const SWord8  s685 = s676 ^ s684;
-  const SWord8  s686 = table4[s675];
-  const SWord8  s687 = table1[s677];
-  const SWord8  s688 = table2[s679];
-  const SWord8  s689 = table3[s681];
-  const SWord8  s690 = s688 ^ s689;
-  const SWord8  s691 = s687 ^ s690;
-  const SWord8  s692 = s686 ^ s691;
-  const SWord16 s693 = (((SWord16) s685) << 8) | ((SWord16) s692);
-  const SWord8  s694 = table3[s675];
-  const SWord8  s695 = table4[s677];
-  const SWord8  s696 = table1[s679];
-  const SWord8  s697 = table2[s681];
-  const SWord8  s698 = s696 ^ s697;
-  const SWord8  s699 = s695 ^ s698;
-  const SWord8  s700 = s694 ^ s699;
-  const SWord8  s701 = table2[s675];
-  const SWord8  s702 = table3[s677];
-  const SWord8  s703 = table4[s679];
-  const SWord8  s704 = table1[s681];
-  const SWord8  s705 = s703 ^ s704;
-  const SWord8  s706 = s702 ^ s705;
-  const SWord8  s707 = s701 ^ s706;
-  const SWord16 s708 = (((SWord16) s700) << 8) | ((SWord16) s707);
-  const SWord32 s709 = (((SWord32) s693) << 16) | ((SWord32) s708);
-  const SWord8  s710 = (SWord8) (s375 >> 24);
-  const SWord8  s711 = table1[s710];
-  const SWord8  s712 = (SWord8) (s375 >> 16);
-  const SWord8  s713 = table2[s712];
-  const SWord8  s714 = (SWord8) (s375 >> 8);
-  const SWord8  s715 = table3[s714];
-  const SWord8  s716 = (SWord8) s375;
-  const SWord8  s717 = table4[s716];
-  const SWord8  s718 = s715 ^ s717;
-  const SWord8  s719 = s713 ^ s718;
-  const SWord8  s720 = s711 ^ s719;
-  const SWord8  s721 = table4[s710];
-  const SWord8  s722 = table1[s712];
-  const SWord8  s723 = table2[s714];
-  const SWord8  s724 = table3[s716];
-  const SWord8  s725 = s723 ^ s724;
-  const SWord8  s726 = s722 ^ s725;
-  const SWord8  s727 = s721 ^ s726;
-  const SWord16 s728 = (((SWord16) s720) << 8) | ((SWord16) s727);
-  const SWord8  s729 = table3[s710];
-  const SWord8  s730 = table4[s712];
-  const SWord8  s731 = table1[s714];
-  const SWord8  s732 = table2[s716];
-  const SWord8  s733 = s731 ^ s732;
-  const SWord8  s734 = s730 ^ s733;
-  const SWord8  s735 = s729 ^ s734;
-  const SWord8  s736 = table2[s710];
-  const SWord8  s737 = table3[s712];
-  const SWord8  s738 = table4[s714];
-  const SWord8  s739 = table1[s716];
-  const SWord8  s740 = s738 ^ s739;
-  const SWord8  s741 = s737 ^ s740;
-  const SWord8  s742 = s736 ^ s741;
-  const SWord16 s743 = (((SWord16) s735) << 8) | ((SWord16) s742);
-  const SWord32 s744 = (((SWord32) s728) << 16) | ((SWord32) s743);
-  const SWord8  s745 = (SWord8) (s376 >> 24);
-  const SWord8  s746 = table1[s745];
-  const SWord8  s747 = (SWord8) (s376 >> 16);
-  const SWord8  s748 = table2[s747];
-  const SWord8  s749 = (SWord8) (s376 >> 8);
-  const SWord8  s750 = table3[s749];
-  const SWord8  s751 = (SWord8) s376;
-  const SWord8  s752 = table4[s751];
-  const SWord8  s753 = s750 ^ s752;
-  const SWord8  s754 = s748 ^ s753;
-  const SWord8  s755 = s746 ^ s754;
-  const SWord8  s756 = table4[s745];
-  const SWord8  s757 = table1[s747];
-  const SWord8  s758 = table2[s749];
-  const SWord8  s759 = table3[s751];
-  const SWord8  s760 = s758 ^ s759;
-  const SWord8  s761 = s757 ^ s760;
-  const SWord8  s762 = s756 ^ s761;
-  const SWord16 s763 = (((SWord16) s755) << 8) | ((SWord16) s762);
-  const SWord8  s764 = table3[s745];
-  const SWord8  s765 = table4[s747];
-  const SWord8  s766 = table1[s749];
-  const SWord8  s767 = table2[s751];
-  const SWord8  s768 = s766 ^ s767;
-  const SWord8  s769 = s765 ^ s768;
-  const SWord8  s770 = s764 ^ s769;
-  const SWord8  s771 = table2[s745];
-  const SWord8  s772 = table3[s747];
-  const SWord8  s773 = table4[s749];
-  const SWord8  s774 = table1[s751];
-  const SWord8  s775 = s773 ^ s774;
-  const SWord8  s776 = s772 ^ s775;
-  const SWord8  s777 = s771 ^ s776;
-  const SWord16 s778 = (((SWord16) s770) << 8) | ((SWord16) s777);
-  const SWord32 s779 = (((SWord32) s763) << 16) | ((SWord32) s778);
-  const SWord8  s780 = (SWord8) (s377 >> 24);
-  const SWord8  s781 = table1[s780];
-  const SWord8  s782 = (SWord8) (s377 >> 16);
-  const SWord8  s783 = table2[s782];
-  const SWord8  s784 = (SWord8) (s377 >> 8);
-  const SWord8  s785 = table3[s784];
-  const SWord8  s786 = (SWord8) s377;
-  const SWord8  s787 = table4[s786];
-  const SWord8  s788 = s785 ^ s787;
-  const SWord8  s789 = s783 ^ s788;
-  const SWord8  s790 = s781 ^ s789;
-  const SWord8  s791 = table4[s780];
-  const SWord8  s792 = table1[s782];
-  const SWord8  s793 = table2[s784];
-  const SWord8  s794 = table3[s786];
-  const SWord8  s795 = s793 ^ s794;
-  const SWord8  s796 = s792 ^ s795;
-  const SWord8  s797 = s791 ^ s796;
-  const SWord16 s798 = (((SWord16) s790) << 8) | ((SWord16) s797);
-  const SWord8  s799 = table3[s780];
-  const SWord8  s800 = table4[s782];
-  const SWord8  s801 = table1[s784];
-  const SWord8  s802 = table2[s786];
-  const SWord8  s803 = s801 ^ s802;
-  const SWord8  s804 = s800 ^ s803;
-  const SWord8  s805 = s799 ^ s804;
-  const SWord8  s806 = table2[s780];
-  const SWord8  s807 = table3[s782];
-  const SWord8  s808 = table4[s784];
-  const SWord8  s809 = table1[s786];
-  const SWord8  s810 = s808 ^ s809;
-  const SWord8  s811 = s807 ^ s810;
-  const SWord8  s812 = s806 ^ s811;
-  const SWord16 s813 = (((SWord16) s805) << 8) | ((SWord16) s812);
-  const SWord32 s814 = (((SWord32) s798) << 16) | ((SWord32) s813);
-  const SWord8  s815 = (SWord8) (s378 >> 24);
-  const SWord8  s816 = table1[s815];
-  const SWord8  s817 = (SWord8) (s378 >> 16);
-  const SWord8  s818 = table2[s817];
-  const SWord8  s819 = (SWord8) (s378 >> 8);
-  const SWord8  s820 = table3[s819];
-  const SWord8  s821 = (SWord8) s378;
-  const SWord8  s822 = table4[s821];
-  const SWord8  s823 = s820 ^ s822;
-  const SWord8  s824 = s818 ^ s823;
-  const SWord8  s825 = s816 ^ s824;
-  const SWord8  s826 = table4[s815];
-  const SWord8  s827 = table1[s817];
-  const SWord8  s828 = table2[s819];
-  const SWord8  s829 = table3[s821];
-  const SWord8  s830 = s828 ^ s829;
-  const SWord8  s831 = s827 ^ s830;
-  const SWord8  s832 = s826 ^ s831;
-  const SWord16 s833 = (((SWord16) s825) << 8) | ((SWord16) s832);
-  const SWord8  s834 = table3[s815];
-  const SWord8  s835 = table4[s817];
-  const SWord8  s836 = table1[s819];
-  const SWord8  s837 = table2[s821];
-  const SWord8  s838 = s836 ^ s837;
-  const SWord8  s839 = s835 ^ s838;
-  const SWord8  s840 = s834 ^ s839;
-  const SWord8  s841 = table2[s815];
-  const SWord8  s842 = table3[s817];
-  const SWord8  s843 = table4[s819];
-  const SWord8  s844 = table1[s821];
-  const SWord8  s845 = s843 ^ s844;
-  const SWord8  s846 = s842 ^ s845;
-  const SWord8  s847 = s841 ^ s846;
-  const SWord16 s848 = (((SWord16) s840) << 8) | ((SWord16) s847);
-  const SWord32 s849 = (((SWord32) s833) << 16) | ((SWord32) s848);
-  const SWord8  s850 = (SWord8) (s358 >> 24);
-  const SWord8  s851 = table1[s850];
-  const SWord8  s852 = (SWord8) (s358 >> 16);
-  const SWord8  s853 = table2[s852];
-  const SWord8  s854 = (SWord8) (s358 >> 8);
-  const SWord8  s855 = table3[s854];
-  const SWord8  s856 = (SWord8) s358;
-  const SWord8  s857 = table4[s856];
-  const SWord8  s858 = s855 ^ s857;
-  const SWord8  s859 = s853 ^ s858;
-  const SWord8  s860 = s851 ^ s859;
-  const SWord8  s861 = table4[s850];
-  const SWord8  s862 = table1[s852];
-  const SWord8  s863 = table2[s854];
-  const SWord8  s864 = table3[s856];
-  const SWord8  s865 = s863 ^ s864;
-  const SWord8  s866 = s862 ^ s865;
-  const SWord8  s867 = s861 ^ s866;
-  const SWord16 s868 = (((SWord16) s860) << 8) | ((SWord16) s867);
-  const SWord8  s869 = table3[s850];
-  const SWord8  s870 = table4[s852];
-  const SWord8  s871 = table1[s854];
-  const SWord8  s872 = table2[s856];
-  const SWord8  s873 = s871 ^ s872;
-  const SWord8  s874 = s870 ^ s873;
-  const SWord8  s875 = s869 ^ s874;
-  const SWord8  s876 = table2[s850];
-  const SWord8  s877 = table3[s852];
-  const SWord8  s878 = table4[s854];
-  const SWord8  s879 = table1[s856];
-  const SWord8  s880 = s878 ^ s879;
-  const SWord8  s881 = s877 ^ s880;
-  const SWord8  s882 = s876 ^ s881;
-  const SWord16 s883 = (((SWord16) s875) << 8) | ((SWord16) s882);
-  const SWord32 s884 = (((SWord32) s868) << 16) | ((SWord32) s883);
-  const SWord8  s885 = (SWord8) (s359 >> 24);
-  const SWord8  s886 = table1[s885];
-  const SWord8  s887 = (SWord8) (s359 >> 16);
-  const SWord8  s888 = table2[s887];
-  const SWord8  s889 = (SWord8) (s359 >> 8);
-  const SWord8  s890 = table3[s889];
-  const SWord8  s891 = (SWord8) s359;
-  const SWord8  s892 = table4[s891];
-  const SWord8  s893 = s890 ^ s892;
-  const SWord8  s894 = s888 ^ s893;
-  const SWord8  s895 = s886 ^ s894;
-  const SWord8  s896 = table4[s885];
-  const SWord8  s897 = table1[s887];
-  const SWord8  s898 = table2[s889];
-  const SWord8  s899 = table3[s891];
-  const SWord8  s900 = s898 ^ s899;
-  const SWord8  s901 = s897 ^ s900;
-  const SWord8  s902 = s896 ^ s901;
-  const SWord16 s903 = (((SWord16) s895) << 8) | ((SWord16) s902);
-  const SWord8  s904 = table3[s885];
-  const SWord8  s905 = table4[s887];
-  const SWord8  s906 = table1[s889];
-  const SWord8  s907 = table2[s891];
-  const SWord8  s908 = s906 ^ s907;
-  const SWord8  s909 = s905 ^ s908;
-  const SWord8  s910 = s904 ^ s909;
-  const SWord8  s911 = table2[s885];
-  const SWord8  s912 = table3[s887];
-  const SWord8  s913 = table4[s889];
-  const SWord8  s914 = table1[s891];
-  const SWord8  s915 = s913 ^ s914;
-  const SWord8  s916 = s912 ^ s915;
-  const SWord8  s917 = s911 ^ s916;
-  const SWord16 s918 = (((SWord16) s910) << 8) | ((SWord16) s917);
-  const SWord32 s919 = (((SWord32) s903) << 16) | ((SWord32) s918);
-  const SWord8  s920 = (SWord8) (s360 >> 24);
-  const SWord8  s921 = table1[s920];
-  const SWord8  s922 = (SWord8) (s360 >> 16);
-  const SWord8  s923 = table2[s922];
-  const SWord8  s924 = (SWord8) (s360 >> 8);
-  const SWord8  s925 = table3[s924];
-  const SWord8  s926 = (SWord8) s360;
-  const SWord8  s927 = table4[s926];
-  const SWord8  s928 = s925 ^ s927;
-  const SWord8  s929 = s923 ^ s928;
-  const SWord8  s930 = s921 ^ s929;
-  const SWord8  s931 = table4[s920];
-  const SWord8  s932 = table1[s922];
-  const SWord8  s933 = table2[s924];
-  const SWord8  s934 = table3[s926];
-  const SWord8  s935 = s933 ^ s934;
-  const SWord8  s936 = s932 ^ s935;
-  const SWord8  s937 = s931 ^ s936;
-  const SWord16 s938 = (((SWord16) s930) << 8) | ((SWord16) s937);
-  const SWord8  s939 = table3[s920];
-  const SWord8  s940 = table4[s922];
-  const SWord8  s941 = table1[s924];
-  const SWord8  s942 = table2[s926];
-  const SWord8  s943 = s941 ^ s942;
-  const SWord8  s944 = s940 ^ s943;
-  const SWord8  s945 = s939 ^ s944;
-  const SWord8  s946 = table2[s920];
-  const SWord8  s947 = table3[s922];
-  const SWord8  s948 = table4[s924];
-  const SWord8  s949 = table1[s926];
-  const SWord8  s950 = s948 ^ s949;
-  const SWord8  s951 = s947 ^ s950;
-  const SWord8  s952 = s946 ^ s951;
-  const SWord16 s953 = (((SWord16) s945) << 8) | ((SWord16) s952);
-  const SWord32 s954 = (((SWord32) s938) << 16) | ((SWord32) s953);
-  const SWord8  s955 = (SWord8) (s361 >> 24);
-  const SWord8  s956 = table1[s955];
-  const SWord8  s957 = (SWord8) (s361 >> 16);
-  const SWord8  s958 = table2[s957];
-  const SWord8  s959 = (SWord8) (s361 >> 8);
-  const SWord8  s960 = table3[s959];
-  const SWord8  s961 = (SWord8) s361;
-  const SWord8  s962 = table4[s961];
-  const SWord8  s963 = s960 ^ s962;
-  const SWord8  s964 = s958 ^ s963;
-  const SWord8  s965 = s956 ^ s964;
-  const SWord8  s966 = table4[s955];
-  const SWord8  s967 = table1[s957];
-  const SWord8  s968 = table2[s959];
-  const SWord8  s969 = table3[s961];
-  const SWord8  s970 = s968 ^ s969;
-  const SWord8  s971 = s967 ^ s970;
-  const SWord8  s972 = s966 ^ s971;
-  const SWord16 s973 = (((SWord16) s965) << 8) | ((SWord16) s972);
-  const SWord8  s974 = table3[s955];
-  const SWord8  s975 = table4[s957];
-  const SWord8  s976 = table1[s959];
-  const SWord8  s977 = table2[s961];
-  const SWord8  s978 = s976 ^ s977;
-  const SWord8  s979 = s975 ^ s978;
-  const SWord8  s980 = s974 ^ s979;
-  const SWord8  s981 = table2[s955];
-  const SWord8  s982 = table3[s957];
-  const SWord8  s983 = table4[s959];
-  const SWord8  s984 = table1[s961];
-  const SWord8  s985 = s983 ^ s984;
-  const SWord8  s986 = s982 ^ s985;
-  const SWord8  s987 = s981 ^ s986;
-  const SWord16 s988 = (((SWord16) s980) << 8) | ((SWord16) s987);
-  const SWord32 s989 = (((SWord32) s973) << 16) | ((SWord32) s988);
-  const SWord8  s990 = (SWord8) (s341 >> 24);
-  const SWord8  s991 = table1[s990];
-  const SWord8  s992 = (SWord8) (s341 >> 16);
-  const SWord8  s993 = table2[s992];
-  const SWord8  s994 = (SWord8) (s341 >> 8);
-  const SWord8  s995 = table3[s994];
-  const SWord8  s996 = (SWord8) s341;
-  const SWord8  s997 = table4[s996];
-  const SWord8  s998 = s995 ^ s997;
-  const SWord8  s999 = s993 ^ s998;
-  const SWord8  s1000 = s991 ^ s999;
-  const SWord8  s1001 = table4[s990];
-  const SWord8  s1002 = table1[s992];
-  const SWord8  s1003 = table2[s994];
-  const SWord8  s1004 = table3[s996];
-  const SWord8  s1005 = s1003 ^ s1004;
-  const SWord8  s1006 = s1002 ^ s1005;
-  const SWord8  s1007 = s1001 ^ s1006;
-  const SWord16 s1008 = (((SWord16) s1000) << 8) | ((SWord16) s1007);
-  const SWord8  s1009 = table3[s990];
-  const SWord8  s1010 = table4[s992];
-  const SWord8  s1011 = table1[s994];
-  const SWord8  s1012 = table2[s996];
-  const SWord8  s1013 = s1011 ^ s1012;
-  const SWord8  s1014 = s1010 ^ s1013;
-  const SWord8  s1015 = s1009 ^ s1014;
-  const SWord8  s1016 = table2[s990];
-  const SWord8  s1017 = table3[s992];
-  const SWord8  s1018 = table4[s994];
-  const SWord8  s1019 = table1[s996];
-  const SWord8  s1020 = s1018 ^ s1019;
-  const SWord8  s1021 = s1017 ^ s1020;
-  const SWord8  s1022 = s1016 ^ s1021;
-  const SWord16 s1023 = (((SWord16) s1015) << 8) | ((SWord16) s1022);
-  const SWord32 s1024 = (((SWord32) s1008) << 16) | ((SWord32) s1023);
-  const SWord8  s1025 = (SWord8) (s342 >> 24);
-  const SWord8  s1026 = table1[s1025];
-  const SWord8  s1027 = (SWord8) (s342 >> 16);
-  const SWord8  s1028 = table2[s1027];
-  const SWord8  s1029 = (SWord8) (s342 >> 8);
-  const SWord8  s1030 = table3[s1029];
-  const SWord8  s1031 = (SWord8) s342;
-  const SWord8  s1032 = table4[s1031];
-  const SWord8  s1033 = s1030 ^ s1032;
-  const SWord8  s1034 = s1028 ^ s1033;
-  const SWord8  s1035 = s1026 ^ s1034;
-  const SWord8  s1036 = table4[s1025];
-  const SWord8  s1037 = table1[s1027];
-  const SWord8  s1038 = table2[s1029];
-  const SWord8  s1039 = table3[s1031];
-  const SWord8  s1040 = s1038 ^ s1039;
-  const SWord8  s1041 = s1037 ^ s1040;
-  const SWord8  s1042 = s1036 ^ s1041;
-  const SWord16 s1043 = (((SWord16) s1035) << 8) | ((SWord16) s1042);
-  const SWord8  s1044 = table3[s1025];
-  const SWord8  s1045 = table4[s1027];
-  const SWord8  s1046 = table1[s1029];
-  const SWord8  s1047 = table2[s1031];
-  const SWord8  s1048 = s1046 ^ s1047;
-  const SWord8  s1049 = s1045 ^ s1048;
-  const SWord8  s1050 = s1044 ^ s1049;
-  const SWord8  s1051 = table2[s1025];
-  const SWord8  s1052 = table3[s1027];
-  const SWord8  s1053 = table4[s1029];
-  const SWord8  s1054 = table1[s1031];
-  const SWord8  s1055 = s1053 ^ s1054;
-  const SWord8  s1056 = s1052 ^ s1055;
-  const SWord8  s1057 = s1051 ^ s1056;
-  const SWord16 s1058 = (((SWord16) s1050) << 8) | ((SWord16) s1057);
-  const SWord32 s1059 = (((SWord32) s1043) << 16) | ((SWord32) s1058);
-  const SWord8  s1060 = (SWord8) (s343 >> 24);
-  const SWord8  s1061 = table1[s1060];
-  const SWord8  s1062 = (SWord8) (s343 >> 16);
-  const SWord8  s1063 = table2[s1062];
-  const SWord8  s1064 = (SWord8) (s343 >> 8);
-  const SWord8  s1065 = table3[s1064];
-  const SWord8  s1066 = (SWord8) s343;
-  const SWord8  s1067 = table4[s1066];
-  const SWord8  s1068 = s1065 ^ s1067;
-  const SWord8  s1069 = s1063 ^ s1068;
-  const SWord8  s1070 = s1061 ^ s1069;
-  const SWord8  s1071 = table4[s1060];
-  const SWord8  s1072 = table1[s1062];
-  const SWord8  s1073 = table2[s1064];
-  const SWord8  s1074 = table3[s1066];
-  const SWord8  s1075 = s1073 ^ s1074;
-  const SWord8  s1076 = s1072 ^ s1075;
-  const SWord8  s1077 = s1071 ^ s1076;
-  const SWord16 s1078 = (((SWord16) s1070) << 8) | ((SWord16) s1077);
-  const SWord8  s1079 = table3[s1060];
-  const SWord8  s1080 = table4[s1062];
-  const SWord8  s1081 = table1[s1064];
-  const SWord8  s1082 = table2[s1066];
-  const SWord8  s1083 = s1081 ^ s1082;
-  const SWord8  s1084 = s1080 ^ s1083;
-  const SWord8  s1085 = s1079 ^ s1084;
-  const SWord8  s1086 = table2[s1060];
-  const SWord8  s1087 = table3[s1062];
-  const SWord8  s1088 = table4[s1064];
-  const SWord8  s1089 = table1[s1066];
-  const SWord8  s1090 = s1088 ^ s1089;
-  const SWord8  s1091 = s1087 ^ s1090;
-  const SWord8  s1092 = s1086 ^ s1091;
-  const SWord16 s1093 = (((SWord16) s1085) << 8) | ((SWord16) s1092);
-  const SWord32 s1094 = (((SWord32) s1078) << 16) | ((SWord32) s1093);
-  const SWord8  s1095 = (SWord8) (s344 >> 24);
-  const SWord8  s1096 = table1[s1095];
-  const SWord8  s1097 = (SWord8) (s344 >> 16);
-  const SWord8  s1098 = table2[s1097];
-  const SWord8  s1099 = (SWord8) (s344 >> 8);
-  const SWord8  s1100 = table3[s1099];
-  const SWord8  s1101 = (SWord8) s344;
-  const SWord8  s1102 = table4[s1101];
-  const SWord8  s1103 = s1100 ^ s1102;
-  const SWord8  s1104 = s1098 ^ s1103;
-  const SWord8  s1105 = s1096 ^ s1104;
-  const SWord8  s1106 = table4[s1095];
-  const SWord8  s1107 = table1[s1097];
-  const SWord8  s1108 = table2[s1099];
-  const SWord8  s1109 = table3[s1101];
-  const SWord8  s1110 = s1108 ^ s1109;
-  const SWord8  s1111 = s1107 ^ s1110;
-  const SWord8  s1112 = s1106 ^ s1111;
-  const SWord16 s1113 = (((SWord16) s1105) << 8) | ((SWord16) s1112);
-  const SWord8  s1114 = table3[s1095];
-  const SWord8  s1115 = table4[s1097];
-  const SWord8  s1116 = table1[s1099];
-  const SWord8  s1117 = table2[s1101];
-  const SWord8  s1118 = s1116 ^ s1117;
-  const SWord8  s1119 = s1115 ^ s1118;
-  const SWord8  s1120 = s1114 ^ s1119;
-  const SWord8  s1121 = table2[s1095];
-  const SWord8  s1122 = table3[s1097];
-  const SWord8  s1123 = table4[s1099];
-  const SWord8  s1124 = table1[s1101];
-  const SWord8  s1125 = s1123 ^ s1124;
-  const SWord8  s1126 = s1122 ^ s1125;
-  const SWord8  s1127 = s1121 ^ s1126;
-  const SWord16 s1128 = (((SWord16) s1120) << 8) | ((SWord16) s1127);
-  const SWord32 s1129 = (((SWord32) s1113) << 16) | ((SWord32) s1128);
-  const SWord8  s1130 = (SWord8) (s324 >> 24);
-  const SWord8  s1131 = table1[s1130];
-  const SWord8  s1132 = (SWord8) (s324 >> 16);
-  const SWord8  s1133 = table2[s1132];
-  const SWord8  s1134 = (SWord8) (s324 >> 8);
-  const SWord8  s1135 = table3[s1134];
-  const SWord8  s1136 = (SWord8) s324;
-  const SWord8  s1137 = table4[s1136];
-  const SWord8  s1138 = s1135 ^ s1137;
-  const SWord8  s1139 = s1133 ^ s1138;
-  const SWord8  s1140 = s1131 ^ s1139;
-  const SWord8  s1141 = table4[s1130];
-  const SWord8  s1142 = table1[s1132];
-  const SWord8  s1143 = table2[s1134];
-  const SWord8  s1144 = table3[s1136];
-  const SWord8  s1145 = s1143 ^ s1144;
-  const SWord8  s1146 = s1142 ^ s1145;
-  const SWord8  s1147 = s1141 ^ s1146;
-  const SWord16 s1148 = (((SWord16) s1140) << 8) | ((SWord16) s1147);
-  const SWord8  s1149 = table3[s1130];
-  const SWord8  s1150 = table4[s1132];
-  const SWord8  s1151 = table1[s1134];
-  const SWord8  s1152 = table2[s1136];
-  const SWord8  s1153 = s1151 ^ s1152;
-  const SWord8  s1154 = s1150 ^ s1153;
-  const SWord8  s1155 = s1149 ^ s1154;
-  const SWord8  s1156 = table2[s1130];
-  const SWord8  s1157 = table3[s1132];
-  const SWord8  s1158 = table4[s1134];
-  const SWord8  s1159 = table1[s1136];
-  const SWord8  s1160 = s1158 ^ s1159;
-  const SWord8  s1161 = s1157 ^ s1160;
-  const SWord8  s1162 = s1156 ^ s1161;
-  const SWord16 s1163 = (((SWord16) s1155) << 8) | ((SWord16) s1162);
-  const SWord32 s1164 = (((SWord32) s1148) << 16) | ((SWord32) s1163);
-  const SWord8  s1165 = (SWord8) (s325 >> 24);
-  const SWord8  s1166 = table1[s1165];
-  const SWord8  s1167 = (SWord8) (s325 >> 16);
-  const SWord8  s1168 = table2[s1167];
-  const SWord8  s1169 = (SWord8) (s325 >> 8);
-  const SWord8  s1170 = table3[s1169];
-  const SWord8  s1171 = (SWord8) s325;
-  const SWord8  s1172 = table4[s1171];
-  const SWord8  s1173 = s1170 ^ s1172;
-  const SWord8  s1174 = s1168 ^ s1173;
-  const SWord8  s1175 = s1166 ^ s1174;
-  const SWord8  s1176 = table4[s1165];
-  const SWord8  s1177 = table1[s1167];
-  const SWord8  s1178 = table2[s1169];
-  const SWord8  s1179 = table3[s1171];
-  const SWord8  s1180 = s1178 ^ s1179;
-  const SWord8  s1181 = s1177 ^ s1180;
-  const SWord8  s1182 = s1176 ^ s1181;
-  const SWord16 s1183 = (((SWord16) s1175) << 8) | ((SWord16) s1182);
-  const SWord8  s1184 = table3[s1165];
-  const SWord8  s1185 = table4[s1167];
-  const SWord8  s1186 = table1[s1169];
-  const SWord8  s1187 = table2[s1171];
-  const SWord8  s1188 = s1186 ^ s1187;
-  const SWord8  s1189 = s1185 ^ s1188;
-  const SWord8  s1190 = s1184 ^ s1189;
-  const SWord8  s1191 = table2[s1165];
-  const SWord8  s1192 = table3[s1167];
-  const SWord8  s1193 = table4[s1169];
-  const SWord8  s1194 = table1[s1171];
-  const SWord8  s1195 = s1193 ^ s1194;
-  const SWord8  s1196 = s1192 ^ s1195;
-  const SWord8  s1197 = s1191 ^ s1196;
-  const SWord16 s1198 = (((SWord16) s1190) << 8) | ((SWord16) s1197);
-  const SWord32 s1199 = (((SWord32) s1183) << 16) | ((SWord32) s1198);
-  const SWord8  s1200 = (SWord8) (s326 >> 24);
-  const SWord8  s1201 = table1[s1200];
-  const SWord8  s1202 = (SWord8) (s326 >> 16);
-  const SWord8  s1203 = table2[s1202];
-  const SWord8  s1204 = (SWord8) (s326 >> 8);
-  const SWord8  s1205 = table3[s1204];
-  const SWord8  s1206 = (SWord8) s326;
-  const SWord8  s1207 = table4[s1206];
-  const SWord8  s1208 = s1205 ^ s1207;
-  const SWord8  s1209 = s1203 ^ s1208;
-  const SWord8  s1210 = s1201 ^ s1209;
-  const SWord8  s1211 = table4[s1200];
-  const SWord8  s1212 = table1[s1202];
-  const SWord8  s1213 = table2[s1204];
-  const SWord8  s1214 = table3[s1206];
-  const SWord8  s1215 = s1213 ^ s1214;
-  const SWord8  s1216 = s1212 ^ s1215;
-  const SWord8  s1217 = s1211 ^ s1216;
-  const SWord16 s1218 = (((SWord16) s1210) << 8) | ((SWord16) s1217);
-  const SWord8  s1219 = table3[s1200];
-  const SWord8  s1220 = table4[s1202];
-  const SWord8  s1221 = table1[s1204];
-  const SWord8  s1222 = table2[s1206];
-  const SWord8  s1223 = s1221 ^ s1222;
-  const SWord8  s1224 = s1220 ^ s1223;
-  const SWord8  s1225 = s1219 ^ s1224;
-  const SWord8  s1226 = table2[s1200];
-  const SWord8  s1227 = table3[s1202];
-  const SWord8  s1228 = table4[s1204];
-  const SWord8  s1229 = table1[s1206];
-  const SWord8  s1230 = s1228 ^ s1229;
-  const SWord8  s1231 = s1227 ^ s1230;
-  const SWord8  s1232 = s1226 ^ s1231;
-  const SWord16 s1233 = (((SWord16) s1225) << 8) | ((SWord16) s1232);
-  const SWord32 s1234 = (((SWord32) s1218) << 16) | ((SWord32) s1233);
-  const SWord8  s1235 = (SWord8) (s327 >> 24);
-  const SWord8  s1236 = table1[s1235];
-  const SWord8  s1237 = (SWord8) (s327 >> 16);
-  const SWord8  s1238 = table2[s1237];
-  const SWord8  s1239 = (SWord8) (s327 >> 8);
-  const SWord8  s1240 = table3[s1239];
-  const SWord8  s1241 = (SWord8) s327;
-  const SWord8  s1242 = table4[s1241];
-  const SWord8  s1243 = s1240 ^ s1242;
-  const SWord8  s1244 = s1238 ^ s1243;
-  const SWord8  s1245 = s1236 ^ s1244;
-  const SWord8  s1246 = table4[s1235];
-  const SWord8  s1247 = table1[s1237];
-  const SWord8  s1248 = table2[s1239];
-  const SWord8  s1249 = table3[s1241];
-  const SWord8  s1250 = s1248 ^ s1249;
-  const SWord8  s1251 = s1247 ^ s1250;
-  const SWord8  s1252 = s1246 ^ s1251;
-  const SWord16 s1253 = (((SWord16) s1245) << 8) | ((SWord16) s1252);
-  const SWord8  s1254 = table3[s1235];
-  const SWord8  s1255 = table4[s1237];
-  const SWord8  s1256 = table1[s1239];
-  const SWord8  s1257 = table2[s1241];
-  const SWord8  s1258 = s1256 ^ s1257;
-  const SWord8  s1259 = s1255 ^ s1258;
-  const SWord8  s1260 = s1254 ^ s1259;
-  const SWord8  s1261 = table2[s1235];
-  const SWord8  s1262 = table3[s1237];
-  const SWord8  s1263 = table4[s1239];
-  const SWord8  s1264 = table1[s1241];
-  const SWord8  s1265 = s1263 ^ s1264;
-  const SWord8  s1266 = s1262 ^ s1265;
-  const SWord8  s1267 = s1261 ^ s1266;
-  const SWord16 s1268 = (((SWord16) s1260) << 8) | ((SWord16) s1267);
-  const SWord32 s1269 = (((SWord32) s1253) << 16) | ((SWord32) s1268);
-  const SWord8  s1270 = (SWord8) (s307 >> 24);
-  const SWord8  s1271 = table1[s1270];
-  const SWord8  s1272 = (SWord8) (s307 >> 16);
-  const SWord8  s1273 = table2[s1272];
-  const SWord8  s1274 = (SWord8) (s307 >> 8);
-  const SWord8  s1275 = table3[s1274];
-  const SWord8  s1276 = (SWord8) s307;
-  const SWord8  s1277 = table4[s1276];
-  const SWord8  s1278 = s1275 ^ s1277;
-  const SWord8  s1279 = s1273 ^ s1278;
-  const SWord8  s1280 = s1271 ^ s1279;
-  const SWord8  s1281 = table4[s1270];
-  const SWord8  s1282 = table1[s1272];
-  const SWord8  s1283 = table2[s1274];
-  const SWord8  s1284 = table3[s1276];
-  const SWord8  s1285 = s1283 ^ s1284;
-  const SWord8  s1286 = s1282 ^ s1285;
-  const SWord8  s1287 = s1281 ^ s1286;
-  const SWord16 s1288 = (((SWord16) s1280) << 8) | ((SWord16) s1287);
-  const SWord8  s1289 = table3[s1270];
-  const SWord8  s1290 = table4[s1272];
-  const SWord8  s1291 = table1[s1274];
-  const SWord8  s1292 = table2[s1276];
-  const SWord8  s1293 = s1291 ^ s1292;
-  const SWord8  s1294 = s1290 ^ s1293;
-  const SWord8  s1295 = s1289 ^ s1294;
-  const SWord8  s1296 = table2[s1270];
-  const SWord8  s1297 = table3[s1272];
-  const SWord8  s1298 = table4[s1274];
-  const SWord8  s1299 = table1[s1276];
-  const SWord8  s1300 = s1298 ^ s1299;
-  const SWord8  s1301 = s1297 ^ s1300;
-  const SWord8  s1302 = s1296 ^ s1301;
-  const SWord16 s1303 = (((SWord16) s1295) << 8) | ((SWord16) s1302);
-  const SWord32 s1304 = (((SWord32) s1288) << 16) | ((SWord32) s1303);
-  const SWord8  s1305 = (SWord8) (s308 >> 24);
-  const SWord8  s1306 = table1[s1305];
-  const SWord8  s1307 = (SWord8) (s308 >> 16);
-  const SWord8  s1308 = table2[s1307];
-  const SWord8  s1309 = (SWord8) (s308 >> 8);
-  const SWord8  s1310 = table3[s1309];
-  const SWord8  s1311 = (SWord8) s308;
-  const SWord8  s1312 = table4[s1311];
-  const SWord8  s1313 = s1310 ^ s1312;
-  const SWord8  s1314 = s1308 ^ s1313;
-  const SWord8  s1315 = s1306 ^ s1314;
-  const SWord8  s1316 = table4[s1305];
-  const SWord8  s1317 = table1[s1307];
-  const SWord8  s1318 = table2[s1309];
-  const SWord8  s1319 = table3[s1311];
-  const SWord8  s1320 = s1318 ^ s1319;
-  const SWord8  s1321 = s1317 ^ s1320;
-  const SWord8  s1322 = s1316 ^ s1321;
-  const SWord16 s1323 = (((SWord16) s1315) << 8) | ((SWord16) s1322);
-  const SWord8  s1324 = table3[s1305];
-  const SWord8  s1325 = table4[s1307];
-  const SWord8  s1326 = table1[s1309];
-  const SWord8  s1327 = table2[s1311];
-  const SWord8  s1328 = s1326 ^ s1327;
-  const SWord8  s1329 = s1325 ^ s1328;
-  const SWord8  s1330 = s1324 ^ s1329;
-  const SWord8  s1331 = table2[s1305];
-  const SWord8  s1332 = table3[s1307];
-  const SWord8  s1333 = table4[s1309];
-  const SWord8  s1334 = table1[s1311];
-  const SWord8  s1335 = s1333 ^ s1334;
-  const SWord8  s1336 = s1332 ^ s1335;
-  const SWord8  s1337 = s1331 ^ s1336;
-  const SWord16 s1338 = (((SWord16) s1330) << 8) | ((SWord16) s1337);
-  const SWord32 s1339 = (((SWord32) s1323) << 16) | ((SWord32) s1338);
-  const SWord8  s1340 = (SWord8) (s309 >> 24);
-  const SWord8  s1341 = table1[s1340];
-  const SWord8  s1342 = (SWord8) (s309 >> 16);
-  const SWord8  s1343 = table2[s1342];
-  const SWord8  s1344 = (SWord8) (s309 >> 8);
-  const SWord8  s1345 = table3[s1344];
-  const SWord8  s1346 = (SWord8) s309;
-  const SWord8  s1347 = table4[s1346];
-  const SWord8  s1348 = s1345 ^ s1347;
-  const SWord8  s1349 = s1343 ^ s1348;
-  const SWord8  s1350 = s1341 ^ s1349;
-  const SWord8  s1351 = table4[s1340];
-  const SWord8  s1352 = table1[s1342];
-  const SWord8  s1353 = table2[s1344];
-  const SWord8  s1354 = table3[s1346];
-  const SWord8  s1355 = s1353 ^ s1354;
-  const SWord8  s1356 = s1352 ^ s1355;
-  const SWord8  s1357 = s1351 ^ s1356;
-  const SWord16 s1358 = (((SWord16) s1350) << 8) | ((SWord16) s1357);
-  const SWord8  s1359 = table3[s1340];
-  const SWord8  s1360 = table4[s1342];
-  const SWord8  s1361 = table1[s1344];
-  const SWord8  s1362 = table2[s1346];
-  const SWord8  s1363 = s1361 ^ s1362;
-  const SWord8  s1364 = s1360 ^ s1363;
-  const SWord8  s1365 = s1359 ^ s1364;
-  const SWord8  s1366 = table2[s1340];
-  const SWord8  s1367 = table3[s1342];
-  const SWord8  s1368 = table4[s1344];
-  const SWord8  s1369 = table1[s1346];
-  const SWord8  s1370 = s1368 ^ s1369;
-  const SWord8  s1371 = s1367 ^ s1370;
-  const SWord8  s1372 = s1366 ^ s1371;
-  const SWord16 s1373 = (((SWord16) s1365) << 8) | ((SWord16) s1372);
-  const SWord32 s1374 = (((SWord32) s1358) << 16) | ((SWord32) s1373);
-  const SWord8  s1375 = (SWord8) (s310 >> 24);
-  const SWord8  s1376 = table1[s1375];
-  const SWord8  s1377 = (SWord8) (s310 >> 16);
-  const SWord8  s1378 = table2[s1377];
-  const SWord8  s1379 = (SWord8) (s310 >> 8);
-  const SWord8  s1380 = table3[s1379];
-  const SWord8  s1381 = (SWord8) s310;
-  const SWord8  s1382 = table4[s1381];
-  const SWord8  s1383 = s1380 ^ s1382;
-  const SWord8  s1384 = s1378 ^ s1383;
-  const SWord8  s1385 = s1376 ^ s1384;
-  const SWord8  s1386 = table4[s1375];
-  const SWord8  s1387 = table1[s1377];
-  const SWord8  s1388 = table2[s1379];
-  const SWord8  s1389 = table3[s1381];
-  const SWord8  s1390 = s1388 ^ s1389;
-  const SWord8  s1391 = s1387 ^ s1390;
-  const SWord8  s1392 = s1386 ^ s1391;
-  const SWord16 s1393 = (((SWord16) s1385) << 8) | ((SWord16) s1392);
-  const SWord8  s1394 = table3[s1375];
-  const SWord8  s1395 = table4[s1377];
-  const SWord8  s1396 = table1[s1379];
-  const SWord8  s1397 = table2[s1381];
-  const SWord8  s1398 = s1396 ^ s1397;
-  const SWord8  s1399 = s1395 ^ s1398;
-  const SWord8  s1400 = s1394 ^ s1399;
-  const SWord8  s1401 = table2[s1375];
-  const SWord8  s1402 = table3[s1377];
-  const SWord8  s1403 = table4[s1379];
-  const SWord8  s1404 = table1[s1381];
-  const SWord8  s1405 = s1403 ^ s1404;
-  const SWord8  s1406 = s1402 ^ s1405;
-  const SWord8  s1407 = s1401 ^ s1406;
-  const SWord16 s1408 = (((SWord16) s1400) << 8) | ((SWord16) s1407);
-  const SWord32 s1409 = (((SWord32) s1393) << 16) | ((SWord32) s1408);
-  const SWord8  s1410 = (SWord8) (s290 >> 24);
-  const SWord8  s1411 = table1[s1410];
-  const SWord8  s1412 = (SWord8) (s290 >> 16);
-  const SWord8  s1413 = table2[s1412];
-  const SWord8  s1414 = (SWord8) (s290 >> 8);
-  const SWord8  s1415 = table3[s1414];
-  const SWord8  s1416 = (SWord8) s290;
-  const SWord8  s1417 = table4[s1416];
-  const SWord8  s1418 = s1415 ^ s1417;
-  const SWord8  s1419 = s1413 ^ s1418;
-  const SWord8  s1420 = s1411 ^ s1419;
-  const SWord8  s1421 = table4[s1410];
-  const SWord8  s1422 = table1[s1412];
-  const SWord8  s1423 = table2[s1414];
-  const SWord8  s1424 = table3[s1416];
-  const SWord8  s1425 = s1423 ^ s1424;
-  const SWord8  s1426 = s1422 ^ s1425;
-  const SWord8  s1427 = s1421 ^ s1426;
-  const SWord16 s1428 = (((SWord16) s1420) << 8) | ((SWord16) s1427);
-  const SWord8  s1429 = table3[s1410];
-  const SWord8  s1430 = table4[s1412];
-  const SWord8  s1431 = table1[s1414];
-  const SWord8  s1432 = table2[s1416];
-  const SWord8  s1433 = s1431 ^ s1432;
-  const SWord8  s1434 = s1430 ^ s1433;
-  const SWord8  s1435 = s1429 ^ s1434;
-  const SWord8  s1436 = table2[s1410];
-  const SWord8  s1437 = table3[s1412];
-  const SWord8  s1438 = table4[s1414];
-  const SWord8  s1439 = table1[s1416];
-  const SWord8  s1440 = s1438 ^ s1439;
-  const SWord8  s1441 = s1437 ^ s1440;
-  const SWord8  s1442 = s1436 ^ s1441;
-  const SWord16 s1443 = (((SWord16) s1435) << 8) | ((SWord16) s1442);
-  const SWord32 s1444 = (((SWord32) s1428) << 16) | ((SWord32) s1443);
-  const SWord8  s1445 = (SWord8) (s291 >> 24);
-  const SWord8  s1446 = table1[s1445];
-  const SWord8  s1447 = (SWord8) (s291 >> 16);
-  const SWord8  s1448 = table2[s1447];
-  const SWord8  s1449 = (SWord8) (s291 >> 8);
-  const SWord8  s1450 = table3[s1449];
-  const SWord8  s1451 = (SWord8) s291;
-  const SWord8  s1452 = table4[s1451];
-  const SWord8  s1453 = s1450 ^ s1452;
-  const SWord8  s1454 = s1448 ^ s1453;
-  const SWord8  s1455 = s1446 ^ s1454;
-  const SWord8  s1456 = table4[s1445];
-  const SWord8  s1457 = table1[s1447];
-  const SWord8  s1458 = table2[s1449];
-  const SWord8  s1459 = table3[s1451];
-  const SWord8  s1460 = s1458 ^ s1459;
-  const SWord8  s1461 = s1457 ^ s1460;
-  const SWord8  s1462 = s1456 ^ s1461;
-  const SWord16 s1463 = (((SWord16) s1455) << 8) | ((SWord16) s1462);
-  const SWord8  s1464 = table3[s1445];
-  const SWord8  s1465 = table4[s1447];
-  const SWord8  s1466 = table1[s1449];
-  const SWord8  s1467 = table2[s1451];
-  const SWord8  s1468 = s1466 ^ s1467;
-  const SWord8  s1469 = s1465 ^ s1468;
-  const SWord8  s1470 = s1464 ^ s1469;
-  const SWord8  s1471 = table2[s1445];
-  const SWord8  s1472 = table3[s1447];
-  const SWord8  s1473 = table4[s1449];
-  const SWord8  s1474 = table1[s1451];
-  const SWord8  s1475 = s1473 ^ s1474;
-  const SWord8  s1476 = s1472 ^ s1475;
-  const SWord8  s1477 = s1471 ^ s1476;
-  const SWord16 s1478 = (((SWord16) s1470) << 8) | ((SWord16) s1477);
-  const SWord32 s1479 = (((SWord32) s1463) << 16) | ((SWord32) s1478);
-  const SWord8  s1480 = (SWord8) (s292 >> 24);
-  const SWord8  s1481 = table1[s1480];
-  const SWord8  s1482 = (SWord8) (s292 >> 16);
-  const SWord8  s1483 = table2[s1482];
-  const SWord8  s1484 = (SWord8) (s292 >> 8);
-  const SWord8  s1485 = table3[s1484];
-  const SWord8  s1486 = (SWord8) s292;
-  const SWord8  s1487 = table4[s1486];
-  const SWord8  s1488 = s1485 ^ s1487;
-  const SWord8  s1489 = s1483 ^ s1488;
-  const SWord8  s1490 = s1481 ^ s1489;
-  const SWord8  s1491 = table4[s1480];
-  const SWord8  s1492 = table1[s1482];
-  const SWord8  s1493 = table2[s1484];
-  const SWord8  s1494 = table3[s1486];
-  const SWord8  s1495 = s1493 ^ s1494;
-  const SWord8  s1496 = s1492 ^ s1495;
-  const SWord8  s1497 = s1491 ^ s1496;
-  const SWord16 s1498 = (((SWord16) s1490) << 8) | ((SWord16) s1497);
-  const SWord8  s1499 = table3[s1480];
-  const SWord8  s1500 = table4[s1482];
-  const SWord8  s1501 = table1[s1484];
-  const SWord8  s1502 = table2[s1486];
-  const SWord8  s1503 = s1501 ^ s1502;
-  const SWord8  s1504 = s1500 ^ s1503;
-  const SWord8  s1505 = s1499 ^ s1504;
-  const SWord8  s1506 = table2[s1480];
-  const SWord8  s1507 = table3[s1482];
-  const SWord8  s1508 = table4[s1484];
-  const SWord8  s1509 = table1[s1486];
-  const SWord8  s1510 = s1508 ^ s1509;
-  const SWord8  s1511 = s1507 ^ s1510;
-  const SWord8  s1512 = s1506 ^ s1511;
-  const SWord16 s1513 = (((SWord16) s1505) << 8) | ((SWord16) s1512);
-  const SWord32 s1514 = (((SWord32) s1498) << 16) | ((SWord32) s1513);
-  const SWord8  s1515 = (SWord8) (s293 >> 24);
-  const SWord8  s1516 = table1[s1515];
-  const SWord8  s1517 = (SWord8) (s293 >> 16);
-  const SWord8  s1518 = table2[s1517];
-  const SWord8  s1519 = (SWord8) (s293 >> 8);
-  const SWord8  s1520 = table3[s1519];
-  const SWord8  s1521 = (SWord8) s293;
-  const SWord8  s1522 = table4[s1521];
-  const SWord8  s1523 = s1520 ^ s1522;
-  const SWord8  s1524 = s1518 ^ s1523;
-  const SWord8  s1525 = s1516 ^ s1524;
-  const SWord8  s1526 = table4[s1515];
-  const SWord8  s1527 = table1[s1517];
-  const SWord8  s1528 = table2[s1519];
-  const SWord8  s1529 = table3[s1521];
-  const SWord8  s1530 = s1528 ^ s1529;
-  const SWord8  s1531 = s1527 ^ s1530;
-  const SWord8  s1532 = s1526 ^ s1531;
-  const SWord16 s1533 = (((SWord16) s1525) << 8) | ((SWord16) s1532);
-  const SWord8  s1534 = table3[s1515];
-  const SWord8  s1535 = table4[s1517];
-  const SWord8  s1536 = table1[s1519];
-  const SWord8  s1537 = table2[s1521];
-  const SWord8  s1538 = s1536 ^ s1537;
-  const SWord8  s1539 = s1535 ^ s1538;
-  const SWord8  s1540 = s1534 ^ s1539;
-  const SWord8  s1541 = table2[s1515];
-  const SWord8  s1542 = table3[s1517];
-  const SWord8  s1543 = table4[s1519];
-  const SWord8  s1544 = table1[s1521];
-  const SWord8  s1545 = s1543 ^ s1544;
-  const SWord8  s1546 = s1542 ^ s1545;
-  const SWord8  s1547 = s1541 ^ s1546;
-  const SWord16 s1548 = (((SWord16) s1540) << 8) | ((SWord16) s1547);
-  const SWord32 s1549 = (((SWord32) s1533) << 16) | ((SWord32) s1548);
-  const SWord8  s1550 = (SWord8) (s273 >> 24);
-  const SWord8  s1551 = table1[s1550];
-  const SWord8  s1552 = (SWord8) (s273 >> 16);
-  const SWord8  s1553 = table2[s1552];
-  const SWord8  s1554 = (SWord8) (s273 >> 8);
-  const SWord8  s1555 = table3[s1554];
-  const SWord8  s1556 = (SWord8) s273;
-  const SWord8  s1557 = table4[s1556];
-  const SWord8  s1558 = s1555 ^ s1557;
-  const SWord8  s1559 = s1553 ^ s1558;
-  const SWord8  s1560 = s1551 ^ s1559;
-  const SWord8  s1561 = table4[s1550];
-  const SWord8  s1562 = table1[s1552];
-  const SWord8  s1563 = table2[s1554];
-  const SWord8  s1564 = table3[s1556];
-  const SWord8  s1565 = s1563 ^ s1564;
-  const SWord8  s1566 = s1562 ^ s1565;
-  const SWord8  s1567 = s1561 ^ s1566;
-  const SWord16 s1568 = (((SWord16) s1560) << 8) | ((SWord16) s1567);
-  const SWord8  s1569 = table3[s1550];
-  const SWord8  s1570 = table4[s1552];
-  const SWord8  s1571 = table1[s1554];
-  const SWord8  s1572 = table2[s1556];
-  const SWord8  s1573 = s1571 ^ s1572;
-  const SWord8  s1574 = s1570 ^ s1573;
-  const SWord8  s1575 = s1569 ^ s1574;
-  const SWord8  s1576 = table2[s1550];
-  const SWord8  s1577 = table3[s1552];
-  const SWord8  s1578 = table4[s1554];
-  const SWord8  s1579 = table1[s1556];
-  const SWord8  s1580 = s1578 ^ s1579;
-  const SWord8  s1581 = s1577 ^ s1580;
-  const SWord8  s1582 = s1576 ^ s1581;
-  const SWord16 s1583 = (((SWord16) s1575) << 8) | ((SWord16) s1582);
-  const SWord32 s1584 = (((SWord32) s1568) << 16) | ((SWord32) s1583);
-  const SWord8  s1585 = (SWord8) (s274 >> 24);
-  const SWord8  s1586 = table1[s1585];
-  const SWord8  s1587 = (SWord8) (s274 >> 16);
-  const SWord8  s1588 = table2[s1587];
-  const SWord8  s1589 = (SWord8) (s274 >> 8);
-  const SWord8  s1590 = table3[s1589];
-  const SWord8  s1591 = (SWord8) s274;
-  const SWord8  s1592 = table4[s1591];
-  const SWord8  s1593 = s1590 ^ s1592;
-  const SWord8  s1594 = s1588 ^ s1593;
-  const SWord8  s1595 = s1586 ^ s1594;
-  const SWord8  s1596 = table4[s1585];
-  const SWord8  s1597 = table1[s1587];
-  const SWord8  s1598 = table2[s1589];
-  const SWord8  s1599 = table3[s1591];
-  const SWord8  s1600 = s1598 ^ s1599;
-  const SWord8  s1601 = s1597 ^ s1600;
-  const SWord8  s1602 = s1596 ^ s1601;
-  const SWord16 s1603 = (((SWord16) s1595) << 8) | ((SWord16) s1602);
-  const SWord8  s1604 = table3[s1585];
-  const SWord8  s1605 = table4[s1587];
-  const SWord8  s1606 = table1[s1589];
-  const SWord8  s1607 = table2[s1591];
-  const SWord8  s1608 = s1606 ^ s1607;
-  const SWord8  s1609 = s1605 ^ s1608;
-  const SWord8  s1610 = s1604 ^ s1609;
-  const SWord8  s1611 = table2[s1585];
-  const SWord8  s1612 = table3[s1587];
-  const SWord8  s1613 = table4[s1589];
-  const SWord8  s1614 = table1[s1591];
-  const SWord8  s1615 = s1613 ^ s1614;
-  const SWord8  s1616 = s1612 ^ s1615;
-  const SWord8  s1617 = s1611 ^ s1616;
-  const SWord16 s1618 = (((SWord16) s1610) << 8) | ((SWord16) s1617);
-  const SWord32 s1619 = (((SWord32) s1603) << 16) | ((SWord32) s1618);
-  const SWord8  s1620 = (SWord8) (s275 >> 24);
-  const SWord8  s1621 = table1[s1620];
-  const SWord8  s1622 = (SWord8) (s275 >> 16);
-  const SWord8  s1623 = table2[s1622];
-  const SWord8  s1624 = (SWord8) (s275 >> 8);
-  const SWord8  s1625 = table3[s1624];
-  const SWord8  s1626 = (SWord8) s275;
-  const SWord8  s1627 = table4[s1626];
-  const SWord8  s1628 = s1625 ^ s1627;
-  const SWord8  s1629 = s1623 ^ s1628;
-  const SWord8  s1630 = s1621 ^ s1629;
-  const SWord8  s1631 = table4[s1620];
-  const SWord8  s1632 = table1[s1622];
-  const SWord8  s1633 = table2[s1624];
-  const SWord8  s1634 = table3[s1626];
-  const SWord8  s1635 = s1633 ^ s1634;
-  const SWord8  s1636 = s1632 ^ s1635;
-  const SWord8  s1637 = s1631 ^ s1636;
-  const SWord16 s1638 = (((SWord16) s1630) << 8) | ((SWord16) s1637);
-  const SWord8  s1639 = table3[s1620];
-  const SWord8  s1640 = table4[s1622];
-  const SWord8  s1641 = table1[s1624];
-  const SWord8  s1642 = table2[s1626];
-  const SWord8  s1643 = s1641 ^ s1642;
-  const SWord8  s1644 = s1640 ^ s1643;
-  const SWord8  s1645 = s1639 ^ s1644;
-  const SWord8  s1646 = table2[s1620];
-  const SWord8  s1647 = table3[s1622];
-  const SWord8  s1648 = table4[s1624];
-  const SWord8  s1649 = table1[s1626];
-  const SWord8  s1650 = s1648 ^ s1649;
-  const SWord8  s1651 = s1647 ^ s1650;
-  const SWord8  s1652 = s1646 ^ s1651;
-  const SWord16 s1653 = (((SWord16) s1645) << 8) | ((SWord16) s1652);
-  const SWord32 s1654 = (((SWord32) s1638) << 16) | ((SWord32) s1653);
-  const SWord8  s1655 = (SWord8) (s276 >> 24);
-  const SWord8  s1656 = table1[s1655];
-  const SWord8  s1657 = (SWord8) (s276 >> 16);
-  const SWord8  s1658 = table2[s1657];
-  const SWord8  s1659 = (SWord8) (s276 >> 8);
-  const SWord8  s1660 = table3[s1659];
-  const SWord8  s1661 = (SWord8) s276;
-  const SWord8  s1662 = table4[s1661];
-  const SWord8  s1663 = s1660 ^ s1662;
-  const SWord8  s1664 = s1658 ^ s1663;
-  const SWord8  s1665 = s1656 ^ s1664;
-  const SWord8  s1666 = table4[s1655];
-  const SWord8  s1667 = table1[s1657];
-  const SWord8  s1668 = table2[s1659];
-  const SWord8  s1669 = table3[s1661];
-  const SWord8  s1670 = s1668 ^ s1669;
-  const SWord8  s1671 = s1667 ^ s1670;
-  const SWord8  s1672 = s1666 ^ s1671;
-  const SWord16 s1673 = (((SWord16) s1665) << 8) | ((SWord16) s1672);
-  const SWord8  s1674 = table3[s1655];
-  const SWord8  s1675 = table4[s1657];
-  const SWord8  s1676 = table1[s1659];
-  const SWord8  s1677 = table2[s1661];
-  const SWord8  s1678 = s1676 ^ s1677;
-  const SWord8  s1679 = s1675 ^ s1678;
-  const SWord8  s1680 = s1674 ^ s1679;
-  const SWord8  s1681 = table2[s1655];
-  const SWord8  s1682 = table3[s1657];
-  const SWord8  s1683 = table4[s1659];
-  const SWord8  s1684 = table1[s1661];
-  const SWord8  s1685 = s1683 ^ s1684;
-  const SWord8  s1686 = s1682 ^ s1685;
-  const SWord8  s1687 = s1681 ^ s1686;
-  const SWord16 s1688 = (((SWord16) s1680) << 8) | ((SWord16) s1687);
-  const SWord32 s1689 = (((SWord32) s1673) << 16) | ((SWord32) s1688);
-
-  encKS[0] = s0;
-  encKS[1] = s1;
-  encKS[2] = s2;
-  encKS[3] = s3;
-  encKS[4] = s273;
-  encKS[5] = s274;
-  encKS[6] = s275;
-  encKS[7] = s276;
-  encKS[8] = s290;
-  encKS[9] = s291;
-  encKS[10] = s292;
-  encKS[11] = s293;
-  encKS[12] = s307;
-  encKS[13] = s308;
-  encKS[14] = s309;
-  encKS[15] = s310;
-  encKS[16] = s324;
-  encKS[17] = s325;
-  encKS[18] = s326;
-  encKS[19] = s327;
-  encKS[20] = s341;
-  encKS[21] = s342;
-  encKS[22] = s343;
-  encKS[23] = s344;
-  encKS[24] = s358;
-  encKS[25] = s359;
-  encKS[26] = s360;
-  encKS[27] = s361;
-  encKS[28] = s375;
-  encKS[29] = s376;
-  encKS[30] = s377;
-  encKS[31] = s378;
-  encKS[32] = s392;
-  encKS[33] = s393;
-  encKS[34] = s394;
-  encKS[35] = s395;
-  encKS[36] = s409;
-  encKS[37] = s410;
-  encKS[38] = s411;
-  encKS[39] = s412;
-  encKS[40] = s426;
-  encKS[41] = s427;
-  encKS[42] = s428;
-  encKS[43] = s429;
-  decKS[0] = s426;
-  decKS[1] = s427;
-  decKS[2] = s428;
-  decKS[3] = s429;
-  decKS[4] = s464;
-  decKS[5] = s499;
-  decKS[6] = s534;
-  decKS[7] = s569;
-  decKS[8] = s604;
-  decKS[9] = s639;
-  decKS[10] = s674;
-  decKS[11] = s709;
-  decKS[12] = s744;
-  decKS[13] = s779;
-  decKS[14] = s814;
-  decKS[15] = s849;
-  decKS[16] = s884;
-  decKS[17] = s919;
-  decKS[18] = s954;
-  decKS[19] = s989;
-  decKS[20] = s1024;
-  decKS[21] = s1059;
-  decKS[22] = s1094;
-  decKS[23] = s1129;
-  decKS[24] = s1164;
-  decKS[25] = s1199;
-  decKS[26] = s1234;
-  decKS[27] = s1269;
-  decKS[28] = s1304;
-  decKS[29] = s1339;
-  decKS[30] = s1374;
-  decKS[31] = s1409;
-  decKS[32] = s1444;
-  decKS[33] = s1479;
-  decKS[34] = s1514;
-  decKS[35] = s1549;
-  decKS[36] = s1584;
-  decKS[37] = s1619;
-  decKS[38] = s1654;
-  decKS[39] = s1689;
-  decKS[40] = s0;
-  decKS[41] = s1;
-  decKS[42] = s2;
-  decKS[43] = s3;
-}
-== END: "aes128KeySchedule.c" ==================
-== BEGIN: "aes128BlockEncrypt.c" ================
-/* File: "aes128BlockEncrypt.c". Automatically generated by SBV. Do not edit! */
-
-#include "aes128Lib.h"
-
-void aes128BlockEncrypt(const SWord32 *pt, const SWord32 *xkey,
-                        SWord32 *ct)
-{
-  const SWord32 s0 = pt[0];
-  const SWord32 s1 = pt[1];
-  const SWord32 s2 = pt[2];
-  const SWord32 s3 = pt[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[] = {
-       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
-  };
-  static const SWord32 table1[] = {
-      0xc66363a5UL, 0xf87c7c84UL, 0xee777799UL, 0xf67b7b8dUL,
-      0xfff2f20dUL, 0xd66b6bbdUL, 0xde6f6fb1UL, 0x91c5c554UL,
-      0x60303050UL, 0x02010103UL, 0xce6767a9UL, 0x562b2b7dUL,
-      0xe7fefe19UL, 0xb5d7d762UL, 0x4dababe6UL, 0xec76769aUL,
-      0x8fcaca45UL, 0x1f82829dUL, 0x89c9c940UL, 0xfa7d7d87UL,
-      0xeffafa15UL, 0xb25959ebUL, 0x8e4747c9UL, 0xfbf0f00bUL,
-      0x41adadecUL, 0xb3d4d467UL, 0x5fa2a2fdUL, 0x45afafeaUL,
-      0x239c9cbfUL, 0x53a4a4f7UL, 0xe4727296UL, 0x9bc0c05bUL,
-      0x75b7b7c2UL, 0xe1fdfd1cUL, 0x3d9393aeUL, 0x4c26266aUL,
-      0x6c36365aUL, 0x7e3f3f41UL, 0xf5f7f702UL, 0x83cccc4fUL,
-      0x6834345cUL, 0x51a5a5f4UL, 0xd1e5e534UL, 0xf9f1f108UL,
-      0xe2717193UL, 0xabd8d873UL, 0x62313153UL, 0x2a15153fUL,
-      0x0804040cUL, 0x95c7c752UL, 0x46232365UL, 0x9dc3c35eUL,
-      0x30181828UL, 0x379696a1UL, 0x0a05050fUL, 0x2f9a9ab5UL,
-      0x0e070709UL, 0x24121236UL, 0x1b80809bUL, 0xdfe2e23dUL,
-      0xcdebeb26UL, 0x4e272769UL, 0x7fb2b2cdUL, 0xea75759fUL,
-      0x1209091bUL, 0x1d83839eUL, 0x582c2c74UL, 0x341a1a2eUL,
-      0x361b1b2dUL, 0xdc6e6eb2UL, 0xb45a5aeeUL, 0x5ba0a0fbUL,
-      0xa45252f6UL, 0x763b3b4dUL, 0xb7d6d661UL, 0x7db3b3ceUL,
-      0x5229297bUL, 0xdde3e33eUL, 0x5e2f2f71UL, 0x13848497UL,
-      0xa65353f5UL, 0xb9d1d168UL, 0x00000000UL, 0xc1eded2cUL,
-      0x40202060UL, 0xe3fcfc1fUL, 0x79b1b1c8UL, 0xb65b5bedUL,
-      0xd46a6abeUL, 0x8dcbcb46UL, 0x67bebed9UL, 0x7239394bUL,
-      0x944a4adeUL, 0x984c4cd4UL, 0xb05858e8UL, 0x85cfcf4aUL,
-      0xbbd0d06bUL, 0xc5efef2aUL, 0x4faaaae5UL, 0xedfbfb16UL,
-      0x864343c5UL, 0x9a4d4dd7UL, 0x66333355UL, 0x11858594UL,
-      0x8a4545cfUL, 0xe9f9f910UL, 0x04020206UL, 0xfe7f7f81UL,
-      0xa05050f0UL, 0x783c3c44UL, 0x259f9fbaUL, 0x4ba8a8e3UL,
-      0xa25151f3UL, 0x5da3a3feUL, 0x804040c0UL, 0x058f8f8aUL,
-      0x3f9292adUL, 0x219d9dbcUL, 0x70383848UL, 0xf1f5f504UL,
-      0x63bcbcdfUL, 0x77b6b6c1UL, 0xafdada75UL, 0x42212163UL,
-      0x20101030UL, 0xe5ffff1aUL, 0xfdf3f30eUL, 0xbfd2d26dUL,
-      0x81cdcd4cUL, 0x180c0c14UL, 0x26131335UL, 0xc3ecec2fUL,
-      0xbe5f5fe1UL, 0x359797a2UL, 0x884444ccUL, 0x2e171739UL,
-      0x93c4c457UL, 0x55a7a7f2UL, 0xfc7e7e82UL, 0x7a3d3d47UL,
-      0xc86464acUL, 0xba5d5de7UL, 0x3219192bUL, 0xe6737395UL,
-      0xc06060a0UL, 0x19818198UL, 0x9e4f4fd1UL, 0xa3dcdc7fUL,
-      0x44222266UL, 0x542a2a7eUL, 0x3b9090abUL, 0x0b888883UL,
-      0x8c4646caUL, 0xc7eeee29UL, 0x6bb8b8d3UL, 0x2814143cUL,
-      0xa7dede79UL, 0xbc5e5ee2UL, 0x160b0b1dUL, 0xaddbdb76UL,
-      0xdbe0e03bUL, 0x64323256UL, 0x743a3a4eUL, 0x140a0a1eUL,
-      0x924949dbUL, 0x0c06060aUL, 0x4824246cUL, 0xb85c5ce4UL,
-      0x9fc2c25dUL, 0xbdd3d36eUL, 0x43acacefUL, 0xc46262a6UL,
-      0x399191a8UL, 0x319595a4UL, 0xd3e4e437UL, 0xf279798bUL,
-      0xd5e7e732UL, 0x8bc8c843UL, 0x6e373759UL, 0xda6d6db7UL,
-      0x018d8d8cUL, 0xb1d5d564UL, 0x9c4e4ed2UL, 0x49a9a9e0UL,
-      0xd86c6cb4UL, 0xac5656faUL, 0xf3f4f407UL, 0xcfeaea25UL,
-      0xca6565afUL, 0xf47a7a8eUL, 0x47aeaee9UL, 0x10080818UL,
-      0x6fbabad5UL, 0xf0787888UL, 0x4a25256fUL, 0x5c2e2e72UL,
-      0x381c1c24UL, 0x57a6a6f1UL, 0x73b4b4c7UL, 0x97c6c651UL,
-      0xcbe8e823UL, 0xa1dddd7cUL, 0xe874749cUL, 0x3e1f1f21UL,
-      0x964b4bddUL, 0x61bdbddcUL, 0x0d8b8b86UL, 0x0f8a8a85UL,
-      0xe0707090UL, 0x7c3e3e42UL, 0x71b5b5c4UL, 0xcc6666aaUL,
-      0x904848d8UL, 0x06030305UL, 0xf7f6f601UL, 0x1c0e0e12UL,
-      0xc26161a3UL, 0x6a35355fUL, 0xae5757f9UL, 0x69b9b9d0UL,
-      0x17868691UL, 0x99c1c158UL, 0x3a1d1d27UL, 0x279e9eb9UL,
-      0xd9e1e138UL, 0xebf8f813UL, 0x2b9898b3UL, 0x22111133UL,
-      0xd26969bbUL, 0xa9d9d970UL, 0x078e8e89UL, 0x339494a7UL,
-      0x2d9b9bb6UL, 0x3c1e1e22UL, 0x15878792UL, 0xc9e9e920UL,
-      0x87cece49UL, 0xaa5555ffUL, 0x50282878UL, 0xa5dfdf7aUL,
-      0x038c8c8fUL, 0x59a1a1f8UL, 0x09898980UL, 0x1a0d0d17UL,
-      0x65bfbfdaUL, 0xd7e6e631UL, 0x844242c6UL, 0xd06868b8UL,
-      0x824141c3UL, 0x299999b0UL, 0x5a2d2d77UL, 0x1e0f0f11UL,
-      0x7bb0b0cbUL, 0xa85454fcUL, 0x6dbbbbd6UL, 0x2c16163aUL
-  };
-  static const SWord32 table2[] = {
-      0xa5c66363UL, 0x84f87c7cUL, 0x99ee7777UL, 0x8df67b7bUL,
-      0x0dfff2f2UL, 0xbdd66b6bUL, 0xb1de6f6fUL, 0x5491c5c5UL,
-      0x50603030UL, 0x03020101UL, 0xa9ce6767UL, 0x7d562b2bUL,
-      0x19e7fefeUL, 0x62b5d7d7UL, 0xe64dababUL, 0x9aec7676UL,
-      0x458fcacaUL, 0x9d1f8282UL, 0x4089c9c9UL, 0x87fa7d7dUL,
-      0x15effafaUL, 0xebb25959UL, 0xc98e4747UL, 0x0bfbf0f0UL,
-      0xec41adadUL, 0x67b3d4d4UL, 0xfd5fa2a2UL, 0xea45afafUL,
-      0xbf239c9cUL, 0xf753a4a4UL, 0x96e47272UL, 0x5b9bc0c0UL,
-      0xc275b7b7UL, 0x1ce1fdfdUL, 0xae3d9393UL, 0x6a4c2626UL,
-      0x5a6c3636UL, 0x417e3f3fUL, 0x02f5f7f7UL, 0x4f83ccccUL,
-      0x5c683434UL, 0xf451a5a5UL, 0x34d1e5e5UL, 0x08f9f1f1UL,
-      0x93e27171UL, 0x73abd8d8UL, 0x53623131UL, 0x3f2a1515UL,
-      0x0c080404UL, 0x5295c7c7UL, 0x65462323UL, 0x5e9dc3c3UL,
-      0x28301818UL, 0xa1379696UL, 0x0f0a0505UL, 0xb52f9a9aUL,
-      0x090e0707UL, 0x36241212UL, 0x9b1b8080UL, 0x3ddfe2e2UL,
-      0x26cdebebUL, 0x694e2727UL, 0xcd7fb2b2UL, 0x9fea7575UL,
-      0x1b120909UL, 0x9e1d8383UL, 0x74582c2cUL, 0x2e341a1aUL,
-      0x2d361b1bUL, 0xb2dc6e6eUL, 0xeeb45a5aUL, 0xfb5ba0a0UL,
-      0xf6a45252UL, 0x4d763b3bUL, 0x61b7d6d6UL, 0xce7db3b3UL,
-      0x7b522929UL, 0x3edde3e3UL, 0x715e2f2fUL, 0x97138484UL,
-      0xf5a65353UL, 0x68b9d1d1UL, 0x00000000UL, 0x2cc1ededUL,
-      0x60402020UL, 0x1fe3fcfcUL, 0xc879b1b1UL, 0xedb65b5bUL,
-      0xbed46a6aUL, 0x468dcbcbUL, 0xd967bebeUL, 0x4b723939UL,
-      0xde944a4aUL, 0xd4984c4cUL, 0xe8b05858UL, 0x4a85cfcfUL,
-      0x6bbbd0d0UL, 0x2ac5efefUL, 0xe54faaaaUL, 0x16edfbfbUL,
-      0xc5864343UL, 0xd79a4d4dUL, 0x55663333UL, 0x94118585UL,
-      0xcf8a4545UL, 0x10e9f9f9UL, 0x06040202UL, 0x81fe7f7fUL,
-      0xf0a05050UL, 0x44783c3cUL, 0xba259f9fUL, 0xe34ba8a8UL,
-      0xf3a25151UL, 0xfe5da3a3UL, 0xc0804040UL, 0x8a058f8fUL,
-      0xad3f9292UL, 0xbc219d9dUL, 0x48703838UL, 0x04f1f5f5UL,
-      0xdf63bcbcUL, 0xc177b6b6UL, 0x75afdadaUL, 0x63422121UL,
-      0x30201010UL, 0x1ae5ffffUL, 0x0efdf3f3UL, 0x6dbfd2d2UL,
-      0x4c81cdcdUL, 0x14180c0cUL, 0x35261313UL, 0x2fc3ececUL,
-      0xe1be5f5fUL, 0xa2359797UL, 0xcc884444UL, 0x392e1717UL,
-      0x5793c4c4UL, 0xf255a7a7UL, 0x82fc7e7eUL, 0x477a3d3dUL,
-      0xacc86464UL, 0xe7ba5d5dUL, 0x2b321919UL, 0x95e67373UL,
-      0xa0c06060UL, 0x98198181UL, 0xd19e4f4fUL, 0x7fa3dcdcUL,
-      0x66442222UL, 0x7e542a2aUL, 0xab3b9090UL, 0x830b8888UL,
-      0xca8c4646UL, 0x29c7eeeeUL, 0xd36bb8b8UL, 0x3c281414UL,
-      0x79a7dedeUL, 0xe2bc5e5eUL, 0x1d160b0bUL, 0x76addbdbUL,
-      0x3bdbe0e0UL, 0x56643232UL, 0x4e743a3aUL, 0x1e140a0aUL,
-      0xdb924949UL, 0x0a0c0606UL, 0x6c482424UL, 0xe4b85c5cUL,
-      0x5d9fc2c2UL, 0x6ebdd3d3UL, 0xef43acacUL, 0xa6c46262UL,
-      0xa8399191UL, 0xa4319595UL, 0x37d3e4e4UL, 0x8bf27979UL,
-      0x32d5e7e7UL, 0x438bc8c8UL, 0x596e3737UL, 0xb7da6d6dUL,
-      0x8c018d8dUL, 0x64b1d5d5UL, 0xd29c4e4eUL, 0xe049a9a9UL,
-      0xb4d86c6cUL, 0xfaac5656UL, 0x07f3f4f4UL, 0x25cfeaeaUL,
-      0xafca6565UL, 0x8ef47a7aUL, 0xe947aeaeUL, 0x18100808UL,
-      0xd56fbabaUL, 0x88f07878UL, 0x6f4a2525UL, 0x725c2e2eUL,
-      0x24381c1cUL, 0xf157a6a6UL, 0xc773b4b4UL, 0x5197c6c6UL,
-      0x23cbe8e8UL, 0x7ca1ddddUL, 0x9ce87474UL, 0x213e1f1fUL,
-      0xdd964b4bUL, 0xdc61bdbdUL, 0x860d8b8bUL, 0x850f8a8aUL,
-      0x90e07070UL, 0x427c3e3eUL, 0xc471b5b5UL, 0xaacc6666UL,
-      0xd8904848UL, 0x05060303UL, 0x01f7f6f6UL, 0x121c0e0eUL,
-      0xa3c26161UL, 0x5f6a3535UL, 0xf9ae5757UL, 0xd069b9b9UL,
-      0x91178686UL, 0x5899c1c1UL, 0x273a1d1dUL, 0xb9279e9eUL,
-      0x38d9e1e1UL, 0x13ebf8f8UL, 0xb32b9898UL, 0x33221111UL,
-      0xbbd26969UL, 0x70a9d9d9UL, 0x89078e8eUL, 0xa7339494UL,
-      0xb62d9b9bUL, 0x223c1e1eUL, 0x92158787UL, 0x20c9e9e9UL,
-      0x4987ceceUL, 0xffaa5555UL, 0x78502828UL, 0x7aa5dfdfUL,
-      0x8f038c8cUL, 0xf859a1a1UL, 0x80098989UL, 0x171a0d0dUL,
-      0xda65bfbfUL, 0x31d7e6e6UL, 0xc6844242UL, 0xb8d06868UL,
-      0xc3824141UL, 0xb0299999UL, 0x775a2d2dUL, 0x111e0f0fUL,
-      0xcb7bb0b0UL, 0xfca85454UL, 0xd66dbbbbUL, 0x3a2c1616UL
-  };
-  static const SWord32 table3[] = {
-      0x63a5c663UL, 0x7c84f87cUL, 0x7799ee77UL, 0x7b8df67bUL,
-      0xf20dfff2UL, 0x6bbdd66bUL, 0x6fb1de6fUL, 0xc55491c5UL,
-      0x30506030UL, 0x01030201UL, 0x67a9ce67UL, 0x2b7d562bUL,
-      0xfe19e7feUL, 0xd762b5d7UL, 0xabe64dabUL, 0x769aec76UL,
-      0xca458fcaUL, 0x829d1f82UL, 0xc94089c9UL, 0x7d87fa7dUL,
-      0xfa15effaUL, 0x59ebb259UL, 0x47c98e47UL, 0xf00bfbf0UL,
-      0xadec41adUL, 0xd467b3d4UL, 0xa2fd5fa2UL, 0xafea45afUL,
-      0x9cbf239cUL, 0xa4f753a4UL, 0x7296e472UL, 0xc05b9bc0UL,
-      0xb7c275b7UL, 0xfd1ce1fdUL, 0x93ae3d93UL, 0x266a4c26UL,
-      0x365a6c36UL, 0x3f417e3fUL, 0xf702f5f7UL, 0xcc4f83ccUL,
-      0x345c6834UL, 0xa5f451a5UL, 0xe534d1e5UL, 0xf108f9f1UL,
-      0x7193e271UL, 0xd873abd8UL, 0x31536231UL, 0x153f2a15UL,
-      0x040c0804UL, 0xc75295c7UL, 0x23654623UL, 0xc35e9dc3UL,
-      0x18283018UL, 0x96a13796UL, 0x050f0a05UL, 0x9ab52f9aUL,
-      0x07090e07UL, 0x12362412UL, 0x809b1b80UL, 0xe23ddfe2UL,
-      0xeb26cdebUL, 0x27694e27UL, 0xb2cd7fb2UL, 0x759fea75UL,
-      0x091b1209UL, 0x839e1d83UL, 0x2c74582cUL, 0x1a2e341aUL,
-      0x1b2d361bUL, 0x6eb2dc6eUL, 0x5aeeb45aUL, 0xa0fb5ba0UL,
-      0x52f6a452UL, 0x3b4d763bUL, 0xd661b7d6UL, 0xb3ce7db3UL,
-      0x297b5229UL, 0xe33edde3UL, 0x2f715e2fUL, 0x84971384UL,
-      0x53f5a653UL, 0xd168b9d1UL, 0x00000000UL, 0xed2cc1edUL,
-      0x20604020UL, 0xfc1fe3fcUL, 0xb1c879b1UL, 0x5bedb65bUL,
-      0x6abed46aUL, 0xcb468dcbUL, 0xbed967beUL, 0x394b7239UL,
-      0x4ade944aUL, 0x4cd4984cUL, 0x58e8b058UL, 0xcf4a85cfUL,
-      0xd06bbbd0UL, 0xef2ac5efUL, 0xaae54faaUL, 0xfb16edfbUL,
-      0x43c58643UL, 0x4dd79a4dUL, 0x33556633UL, 0x85941185UL,
-      0x45cf8a45UL, 0xf910e9f9UL, 0x02060402UL, 0x7f81fe7fUL,
-      0x50f0a050UL, 0x3c44783cUL, 0x9fba259fUL, 0xa8e34ba8UL,
-      0x51f3a251UL, 0xa3fe5da3UL, 0x40c08040UL, 0x8f8a058fUL,
-      0x92ad3f92UL, 0x9dbc219dUL, 0x38487038UL, 0xf504f1f5UL,
-      0xbcdf63bcUL, 0xb6c177b6UL, 0xda75afdaUL, 0x21634221UL,
-      0x10302010UL, 0xff1ae5ffUL, 0xf30efdf3UL, 0xd26dbfd2UL,
-      0xcd4c81cdUL, 0x0c14180cUL, 0x13352613UL, 0xec2fc3ecUL,
-      0x5fe1be5fUL, 0x97a23597UL, 0x44cc8844UL, 0x17392e17UL,
-      0xc45793c4UL, 0xa7f255a7UL, 0x7e82fc7eUL, 0x3d477a3dUL,
-      0x64acc864UL, 0x5de7ba5dUL, 0x192b3219UL, 0x7395e673UL,
-      0x60a0c060UL, 0x81981981UL, 0x4fd19e4fUL, 0xdc7fa3dcUL,
-      0x22664422UL, 0x2a7e542aUL, 0x90ab3b90UL, 0x88830b88UL,
-      0x46ca8c46UL, 0xee29c7eeUL, 0xb8d36bb8UL, 0x143c2814UL,
-      0xde79a7deUL, 0x5ee2bc5eUL, 0x0b1d160bUL, 0xdb76addbUL,
-      0xe03bdbe0UL, 0x32566432UL, 0x3a4e743aUL, 0x0a1e140aUL,
-      0x49db9249UL, 0x060a0c06UL, 0x246c4824UL, 0x5ce4b85cUL,
-      0xc25d9fc2UL, 0xd36ebdd3UL, 0xacef43acUL, 0x62a6c462UL,
-      0x91a83991UL, 0x95a43195UL, 0xe437d3e4UL, 0x798bf279UL,
-      0xe732d5e7UL, 0xc8438bc8UL, 0x37596e37UL, 0x6db7da6dUL,
-      0x8d8c018dUL, 0xd564b1d5UL, 0x4ed29c4eUL, 0xa9e049a9UL,
-      0x6cb4d86cUL, 0x56faac56UL, 0xf407f3f4UL, 0xea25cfeaUL,
-      0x65afca65UL, 0x7a8ef47aUL, 0xaee947aeUL, 0x08181008UL,
-      0xbad56fbaUL, 0x7888f078UL, 0x256f4a25UL, 0x2e725c2eUL,
-      0x1c24381cUL, 0xa6f157a6UL, 0xb4c773b4UL, 0xc65197c6UL,
-      0xe823cbe8UL, 0xdd7ca1ddUL, 0x749ce874UL, 0x1f213e1fUL,
-      0x4bdd964bUL, 0xbddc61bdUL, 0x8b860d8bUL, 0x8a850f8aUL,
-      0x7090e070UL, 0x3e427c3eUL, 0xb5c471b5UL, 0x66aacc66UL,
-      0x48d89048UL, 0x03050603UL, 0xf601f7f6UL, 0x0e121c0eUL,
-      0x61a3c261UL, 0x355f6a35UL, 0x57f9ae57UL, 0xb9d069b9UL,
-      0x86911786UL, 0xc15899c1UL, 0x1d273a1dUL, 0x9eb9279eUL,
-      0xe138d9e1UL, 0xf813ebf8UL, 0x98b32b98UL, 0x11332211UL,
-      0x69bbd269UL, 0xd970a9d9UL, 0x8e89078eUL, 0x94a73394UL,
-      0x9bb62d9bUL, 0x1e223c1eUL, 0x87921587UL, 0xe920c9e9UL,
-      0xce4987ceUL, 0x55ffaa55UL, 0x28785028UL, 0xdf7aa5dfUL,
-      0x8c8f038cUL, 0xa1f859a1UL, 0x89800989UL, 0x0d171a0dUL,
-      0xbfda65bfUL, 0xe631d7e6UL, 0x42c68442UL, 0x68b8d068UL,
-      0x41c38241UL, 0x99b02999UL, 0x2d775a2dUL, 0x0f111e0fUL,
-      0xb0cb7bb0UL, 0x54fca854UL, 0xbbd66dbbUL, 0x163a2c16UL
-  };
-  static const SWord32 table4[] = {
-      0x6363a5c6UL, 0x7c7c84f8UL, 0x777799eeUL, 0x7b7b8df6UL,
-      0xf2f20dffUL, 0x6b6bbdd6UL, 0x6f6fb1deUL, 0xc5c55491UL,
-      0x30305060UL, 0x01010302UL, 0x6767a9ceUL, 0x2b2b7d56UL,
-      0xfefe19e7UL, 0xd7d762b5UL, 0xababe64dUL, 0x76769aecUL,
-      0xcaca458fUL, 0x82829d1fUL, 0xc9c94089UL, 0x7d7d87faUL,
-      0xfafa15efUL, 0x5959ebb2UL, 0x4747c98eUL, 0xf0f00bfbUL,
-      0xadadec41UL, 0xd4d467b3UL, 0xa2a2fd5fUL, 0xafafea45UL,
-      0x9c9cbf23UL, 0xa4a4f753UL, 0x727296e4UL, 0xc0c05b9bUL,
-      0xb7b7c275UL, 0xfdfd1ce1UL, 0x9393ae3dUL, 0x26266a4cUL,
-      0x36365a6cUL, 0x3f3f417eUL, 0xf7f702f5UL, 0xcccc4f83UL,
-      0x34345c68UL, 0xa5a5f451UL, 0xe5e534d1UL, 0xf1f108f9UL,
-      0x717193e2UL, 0xd8d873abUL, 0x31315362UL, 0x15153f2aUL,
-      0x04040c08UL, 0xc7c75295UL, 0x23236546UL, 0xc3c35e9dUL,
-      0x18182830UL, 0x9696a137UL, 0x05050f0aUL, 0x9a9ab52fUL,
-      0x0707090eUL, 0x12123624UL, 0x80809b1bUL, 0xe2e23ddfUL,
-      0xebeb26cdUL, 0x2727694eUL, 0xb2b2cd7fUL, 0x75759feaUL,
-      0x09091b12UL, 0x83839e1dUL, 0x2c2c7458UL, 0x1a1a2e34UL,
-      0x1b1b2d36UL, 0x6e6eb2dcUL, 0x5a5aeeb4UL, 0xa0a0fb5bUL,
-      0x5252f6a4UL, 0x3b3b4d76UL, 0xd6d661b7UL, 0xb3b3ce7dUL,
-      0x29297b52UL, 0xe3e33eddUL, 0x2f2f715eUL, 0x84849713UL,
-      0x5353f5a6UL, 0xd1d168b9UL, 0x00000000UL, 0xeded2cc1UL,
-      0x20206040UL, 0xfcfc1fe3UL, 0xb1b1c879UL, 0x5b5bedb6UL,
-      0x6a6abed4UL, 0xcbcb468dUL, 0xbebed967UL, 0x39394b72UL,
-      0x4a4ade94UL, 0x4c4cd498UL, 0x5858e8b0UL, 0xcfcf4a85UL,
-      0xd0d06bbbUL, 0xefef2ac5UL, 0xaaaae54fUL, 0xfbfb16edUL,
-      0x4343c586UL, 0x4d4dd79aUL, 0x33335566UL, 0x85859411UL,
-      0x4545cf8aUL, 0xf9f910e9UL, 0x02020604UL, 0x7f7f81feUL,
-      0x5050f0a0UL, 0x3c3c4478UL, 0x9f9fba25UL, 0xa8a8e34bUL,
-      0x5151f3a2UL, 0xa3a3fe5dUL, 0x4040c080UL, 0x8f8f8a05UL,
-      0x9292ad3fUL, 0x9d9dbc21UL, 0x38384870UL, 0xf5f504f1UL,
-      0xbcbcdf63UL, 0xb6b6c177UL, 0xdada75afUL, 0x21216342UL,
-      0x10103020UL, 0xffff1ae5UL, 0xf3f30efdUL, 0xd2d26dbfUL,
-      0xcdcd4c81UL, 0x0c0c1418UL, 0x13133526UL, 0xecec2fc3UL,
-      0x5f5fe1beUL, 0x9797a235UL, 0x4444cc88UL, 0x1717392eUL,
-      0xc4c45793UL, 0xa7a7f255UL, 0x7e7e82fcUL, 0x3d3d477aUL,
-      0x6464acc8UL, 0x5d5de7baUL, 0x19192b32UL, 0x737395e6UL,
-      0x6060a0c0UL, 0x81819819UL, 0x4f4fd19eUL, 0xdcdc7fa3UL,
-      0x22226644UL, 0x2a2a7e54UL, 0x9090ab3bUL, 0x8888830bUL,
-      0x4646ca8cUL, 0xeeee29c7UL, 0xb8b8d36bUL, 0x14143c28UL,
-      0xdede79a7UL, 0x5e5ee2bcUL, 0x0b0b1d16UL, 0xdbdb76adUL,
-      0xe0e03bdbUL, 0x32325664UL, 0x3a3a4e74UL, 0x0a0a1e14UL,
-      0x4949db92UL, 0x06060a0cUL, 0x24246c48UL, 0x5c5ce4b8UL,
-      0xc2c25d9fUL, 0xd3d36ebdUL, 0xacacef43UL, 0x6262a6c4UL,
-      0x9191a839UL, 0x9595a431UL, 0xe4e437d3UL, 0x79798bf2UL,
-      0xe7e732d5UL, 0xc8c8438bUL, 0x3737596eUL, 0x6d6db7daUL,
-      0x8d8d8c01UL, 0xd5d564b1UL, 0x4e4ed29cUL, 0xa9a9e049UL,
-      0x6c6cb4d8UL, 0x5656faacUL, 0xf4f407f3UL, 0xeaea25cfUL,
-      0x6565afcaUL, 0x7a7a8ef4UL, 0xaeaee947UL, 0x08081810UL,
-      0xbabad56fUL, 0x787888f0UL, 0x25256f4aUL, 0x2e2e725cUL,
-      0x1c1c2438UL, 0xa6a6f157UL, 0xb4b4c773UL, 0xc6c65197UL,
-      0xe8e823cbUL, 0xdddd7ca1UL, 0x74749ce8UL, 0x1f1f213eUL,
-      0x4b4bdd96UL, 0xbdbddc61UL, 0x8b8b860dUL, 0x8a8a850fUL,
-      0x707090e0UL, 0x3e3e427cUL, 0xb5b5c471UL, 0x6666aaccUL,
-      0x4848d890UL, 0x03030506UL, 0xf6f601f7UL, 0x0e0e121cUL,
-      0x6161a3c2UL, 0x35355f6aUL, 0x5757f9aeUL, 0xb9b9d069UL,
-      0x86869117UL, 0xc1c15899UL, 0x1d1d273aUL, 0x9e9eb927UL,
-      0xe1e138d9UL, 0xf8f813ebUL, 0x9898b32bUL, 0x11113322UL,
-      0x6969bbd2UL, 0xd9d970a9UL, 0x8e8e8907UL, 0x9494a733UL,
-      0x9b9bb62dUL, 0x1e1e223cUL, 0x87879215UL, 0xe9e920c9UL,
-      0xcece4987UL, 0x5555ffaaUL, 0x28287850UL, 0xdfdf7aa5UL,
-      0x8c8c8f03UL, 0xa1a1f859UL, 0x89898009UL, 0x0d0d171aUL,
-      0xbfbfda65UL, 0xe6e631d7UL, 0x4242c684UL, 0x6868b8d0UL,
-      0x4141c382UL, 0x9999b029UL, 0x2d2d775aUL, 0x0f0f111eUL,
-      0xb0b0cb7bUL, 0x5454fca8UL, 0xbbbbd66dUL, 0x16163a2cUL
-  };
-  const SWord32 s560 = s0 ^ s4;
-  const SWord8  s561 = (SWord8) (s560 >> 24);
-  const SWord32 s562 = table1[s561];
-  const SWord32 s818 = s1 ^ s5;
-  const SWord8  s819 = (SWord8) (s818 >> 16);
-  const SWord32 s820 = table2[s819];
-  const SWord32 s821 = s562 ^ s820;
-  const SWord32 s1077 = s2 ^ s6;
-  const SWord8  s1078 = (SWord8) (s1077 >> 8);
-  const SWord32 s1079 = table3[s1078];
-  const SWord32 s1080 = s821 ^ s1079;
-  const SWord32 s1336 = s3 ^ s7;
-  const SWord8  s1337 = (SWord8) s1336;
-  const SWord32 s1338 = table4[s1337];
-  const SWord32 s1339 = s1080 ^ s1338;
-  const SWord32 s1340 = s8 ^ s1339;
-  const SWord8  s1341 = (SWord8) (s1340 >> 24);
-  const SWord32 s1342 = table1[s1341];
-  const SWord8  s1343 = (SWord8) (s818 >> 24);
-  const SWord32 s1344 = table1[s1343];
-  const SWord8  s1345 = (SWord8) (s1077 >> 16);
-  const SWord32 s1346 = table2[s1345];
-  const SWord32 s1347 = s1344 ^ s1346;
-  const SWord8  s1348 = (SWord8) (s1336 >> 8);
-  const SWord32 s1349 = table3[s1348];
-  const SWord32 s1350 = s1347 ^ s1349;
-  const SWord8  s1351 = (SWord8) s560;
-  const SWord32 s1352 = table4[s1351];
-  const SWord32 s1353 = s1350 ^ s1352;
-  const SWord32 s1354 = s9 ^ s1353;
-  const SWord8  s1355 = (SWord8) (s1354 >> 16);
-  const SWord32 s1356 = table2[s1355];
-  const SWord32 s1357 = s1342 ^ s1356;
-  const SWord8  s1358 = (SWord8) (s1077 >> 24);
-  const SWord32 s1359 = table1[s1358];
-  const SWord8  s1360 = (SWord8) (s1336 >> 16);
-  const SWord32 s1361 = table2[s1360];
-  const SWord32 s1362 = s1359 ^ s1361;
-  const SWord8  s1363 = (SWord8) (s560 >> 8);
-  const SWord32 s1364 = table3[s1363];
-  const SWord32 s1365 = s1362 ^ s1364;
-  const SWord8  s1366 = (SWord8) s818;
-  const SWord32 s1367 = table4[s1366];
-  const SWord32 s1368 = s1365 ^ s1367;
-  const SWord32 s1369 = s10 ^ s1368;
-  const SWord8  s1370 = (SWord8) (s1369 >> 8);
-  const SWord32 s1371 = table3[s1370];
-  const SWord32 s1372 = s1357 ^ s1371;
-  const SWord8  s1373 = (SWord8) (s1336 >> 24);
-  const SWord32 s1374 = table1[s1373];
-  const SWord8  s1375 = (SWord8) (s560 >> 16);
-  const SWord32 s1376 = table2[s1375];
-  const SWord32 s1377 = s1374 ^ s1376;
-  const SWord8  s1378 = (SWord8) (s818 >> 8);
-  const SWord32 s1379 = table3[s1378];
-  const SWord32 s1380 = s1377 ^ s1379;
-  const SWord8  s1381 = (SWord8) s1077;
-  const SWord32 s1382 = table4[s1381];
-  const SWord32 s1383 = s1380 ^ s1382;
-  const SWord32 s1384 = s11 ^ s1383;
-  const SWord8  s1385 = (SWord8) s1384;
-  const SWord32 s1386 = table4[s1385];
-  const SWord32 s1387 = s1372 ^ s1386;
-  const SWord32 s1388 = s12 ^ s1387;
-  const SWord8  s1389 = (SWord8) (s1388 >> 24);
-  const SWord32 s1390 = table1[s1389];
-  const SWord8  s1391 = (SWord8) (s1354 >> 24);
-  const SWord32 s1392 = table1[s1391];
-  const SWord8  s1393 = (SWord8) (s1369 >> 16);
-  const SWord32 s1394 = table2[s1393];
-  const SWord32 s1395 = s1392 ^ s1394;
-  const SWord8  s1396 = (SWord8) (s1384 >> 8);
-  const SWord32 s1397 = table3[s1396];
-  const SWord32 s1398 = s1395 ^ s1397;
-  const SWord8  s1399 = (SWord8) s1340;
-  const SWord32 s1400 = table4[s1399];
-  const SWord32 s1401 = s1398 ^ s1400;
-  const SWord32 s1402 = s13 ^ s1401;
-  const SWord8  s1403 = (SWord8) (s1402 >> 16);
-  const SWord32 s1404 = table2[s1403];
-  const SWord32 s1405 = s1390 ^ s1404;
-  const SWord8  s1406 = (SWord8) (s1369 >> 24);
-  const SWord32 s1407 = table1[s1406];
-  const SWord8  s1408 = (SWord8) (s1384 >> 16);
-  const SWord32 s1409 = table2[s1408];
-  const SWord32 s1410 = s1407 ^ s1409;
-  const SWord8  s1411 = (SWord8) (s1340 >> 8);
-  const SWord32 s1412 = table3[s1411];
-  const SWord32 s1413 = s1410 ^ s1412;
-  const SWord8  s1414 = (SWord8) s1354;
-  const SWord32 s1415 = table4[s1414];
-  const SWord32 s1416 = s1413 ^ s1415;
-  const SWord32 s1417 = s14 ^ s1416;
-  const SWord8  s1418 = (SWord8) (s1417 >> 8);
-  const SWord32 s1419 = table3[s1418];
-  const SWord32 s1420 = s1405 ^ s1419;
-  const SWord8  s1421 = (SWord8) (s1384 >> 24);
-  const SWord32 s1422 = table1[s1421];
-  const SWord8  s1423 = (SWord8) (s1340 >> 16);
-  const SWord32 s1424 = table2[s1423];
-  const SWord32 s1425 = s1422 ^ s1424;
-  const SWord8  s1426 = (SWord8) (s1354 >> 8);
-  const SWord32 s1427 = table3[s1426];
-  const SWord32 s1428 = s1425 ^ s1427;
-  const SWord8  s1429 = (SWord8) s1369;
-  const SWord32 s1430 = table4[s1429];
-  const SWord32 s1431 = s1428 ^ s1430;
-  const SWord32 s1432 = s15 ^ s1431;
-  const SWord8  s1433 = (SWord8) s1432;
-  const SWord32 s1434 = table4[s1433];
-  const SWord32 s1435 = s1420 ^ s1434;
-  const SWord32 s1436 = s16 ^ s1435;
-  const SWord8  s1437 = (SWord8) (s1436 >> 24);
-  const SWord32 s1438 = table1[s1437];
-  const SWord8  s1439 = (SWord8) (s1402 >> 24);
-  const SWord32 s1440 = table1[s1439];
-  const SWord8  s1441 = (SWord8) (s1417 >> 16);
-  const SWord32 s1442 = table2[s1441];
-  const SWord32 s1443 = s1440 ^ s1442;
-  const SWord8  s1444 = (SWord8) (s1432 >> 8);
-  const SWord32 s1445 = table3[s1444];
-  const SWord32 s1446 = s1443 ^ s1445;
-  const SWord8  s1447 = (SWord8) s1388;
-  const SWord32 s1448 = table4[s1447];
-  const SWord32 s1449 = s1446 ^ s1448;
-  const SWord32 s1450 = s17 ^ s1449;
-  const SWord8  s1451 = (SWord8) (s1450 >> 16);
-  const SWord32 s1452 = table2[s1451];
-  const SWord32 s1453 = s1438 ^ s1452;
-  const SWord8  s1454 = (SWord8) (s1417 >> 24);
-  const SWord32 s1455 = table1[s1454];
-  const SWord8  s1456 = (SWord8) (s1432 >> 16);
-  const SWord32 s1457 = table2[s1456];
-  const SWord32 s1458 = s1455 ^ s1457;
-  const SWord8  s1459 = (SWord8) (s1388 >> 8);
-  const SWord32 s1460 = table3[s1459];
-  const SWord32 s1461 = s1458 ^ s1460;
-  const SWord8  s1462 = (SWord8) s1402;
-  const SWord32 s1463 = table4[s1462];
-  const SWord32 s1464 = s1461 ^ s1463;
-  const SWord32 s1465 = s18 ^ s1464;
-  const SWord8  s1466 = (SWord8) (s1465 >> 8);
-  const SWord32 s1467 = table3[s1466];
-  const SWord32 s1468 = s1453 ^ s1467;
-  const SWord8  s1469 = (SWord8) (s1432 >> 24);
-  const SWord32 s1470 = table1[s1469];
-  const SWord8  s1471 = (SWord8) (s1388 >> 16);
-  const SWord32 s1472 = table2[s1471];
-  const SWord32 s1473 = s1470 ^ s1472;
-  const SWord8  s1474 = (SWord8) (s1402 >> 8);
-  const SWord32 s1475 = table3[s1474];
-  const SWord32 s1476 = s1473 ^ s1475;
-  const SWord8  s1477 = (SWord8) s1417;
-  const SWord32 s1478 = table4[s1477];
-  const SWord32 s1479 = s1476 ^ s1478;
-  const SWord32 s1480 = s19 ^ s1479;
-  const SWord8  s1481 = (SWord8) s1480;
-  const SWord32 s1482 = table4[s1481];
-  const SWord32 s1483 = s1468 ^ s1482;
-  const SWord32 s1484 = s20 ^ s1483;
-  const SWord8  s1485 = (SWord8) (s1484 >> 24);
-  const SWord32 s1486 = table1[s1485];
-  const SWord8  s1487 = (SWord8) (s1450 >> 24);
-  const SWord32 s1488 = table1[s1487];
-  const SWord8  s1489 = (SWord8) (s1465 >> 16);
-  const SWord32 s1490 = table2[s1489];
-  const SWord32 s1491 = s1488 ^ s1490;
-  const SWord8  s1492 = (SWord8) (s1480 >> 8);
-  const SWord32 s1493 = table3[s1492];
-  const SWord32 s1494 = s1491 ^ s1493;
-  const SWord8  s1495 = (SWord8) s1436;
-  const SWord32 s1496 = table4[s1495];
-  const SWord32 s1497 = s1494 ^ s1496;
-  const SWord32 s1498 = s21 ^ s1497;
-  const SWord8  s1499 = (SWord8) (s1498 >> 16);
-  const SWord32 s1500 = table2[s1499];
-  const SWord32 s1501 = s1486 ^ s1500;
-  const SWord8  s1502 = (SWord8) (s1465 >> 24);
-  const SWord32 s1503 = table1[s1502];
-  const SWord8  s1504 = (SWord8) (s1480 >> 16);
-  const SWord32 s1505 = table2[s1504];
-  const SWord32 s1506 = s1503 ^ s1505;
-  const SWord8  s1507 = (SWord8) (s1436 >> 8);
-  const SWord32 s1508 = table3[s1507];
-  const SWord32 s1509 = s1506 ^ s1508;
-  const SWord8  s1510 = (SWord8) s1450;
-  const SWord32 s1511 = table4[s1510];
-  const SWord32 s1512 = s1509 ^ s1511;
-  const SWord32 s1513 = s22 ^ s1512;
-  const SWord8  s1514 = (SWord8) (s1513 >> 8);
-  const SWord32 s1515 = table3[s1514];
-  const SWord32 s1516 = s1501 ^ s1515;
-  const SWord8  s1517 = (SWord8) (s1480 >> 24);
-  const SWord32 s1518 = table1[s1517];
-  const SWord8  s1519 = (SWord8) (s1436 >> 16);
-  const SWord32 s1520 = table2[s1519];
-  const SWord32 s1521 = s1518 ^ s1520;
-  const SWord8  s1522 = (SWord8) (s1450 >> 8);
-  const SWord32 s1523 = table3[s1522];
-  const SWord32 s1524 = s1521 ^ s1523;
-  const SWord8  s1525 = (SWord8) s1465;
-  const SWord32 s1526 = table4[s1525];
-  const SWord32 s1527 = s1524 ^ s1526;
-  const SWord32 s1528 = s23 ^ s1527;
-  const SWord8  s1529 = (SWord8) s1528;
-  const SWord32 s1530 = table4[s1529];
-  const SWord32 s1531 = s1516 ^ s1530;
-  const SWord32 s1532 = s24 ^ s1531;
-  const SWord8  s1533 = (SWord8) (s1532 >> 24);
-  const SWord32 s1534 = table1[s1533];
-  const SWord8  s1535 = (SWord8) (s1498 >> 24);
-  const SWord32 s1536 = table1[s1535];
-  const SWord8  s1537 = (SWord8) (s1513 >> 16);
-  const SWord32 s1538 = table2[s1537];
-  const SWord32 s1539 = s1536 ^ s1538;
-  const SWord8  s1540 = (SWord8) (s1528 >> 8);
-  const SWord32 s1541 = table3[s1540];
-  const SWord32 s1542 = s1539 ^ s1541;
-  const SWord8  s1543 = (SWord8) s1484;
-  const SWord32 s1544 = table4[s1543];
-  const SWord32 s1545 = s1542 ^ s1544;
-  const SWord32 s1546 = s25 ^ s1545;
-  const SWord8  s1547 = (SWord8) (s1546 >> 16);
-  const SWord32 s1548 = table2[s1547];
-  const SWord32 s1549 = s1534 ^ s1548;
-  const SWord8  s1550 = (SWord8) (s1513 >> 24);
-  const SWord32 s1551 = table1[s1550];
-  const SWord8  s1552 = (SWord8) (s1528 >> 16);
-  const SWord32 s1553 = table2[s1552];
-  const SWord32 s1554 = s1551 ^ s1553;
-  const SWord8  s1555 = (SWord8) (s1484 >> 8);
-  const SWord32 s1556 = table3[s1555];
-  const SWord32 s1557 = s1554 ^ s1556;
-  const SWord8  s1558 = (SWord8) s1498;
-  const SWord32 s1559 = table4[s1558];
-  const SWord32 s1560 = s1557 ^ s1559;
-  const SWord32 s1561 = s26 ^ s1560;
-  const SWord8  s1562 = (SWord8) (s1561 >> 8);
-  const SWord32 s1563 = table3[s1562];
-  const SWord32 s1564 = s1549 ^ s1563;
-  const SWord8  s1565 = (SWord8) (s1528 >> 24);
-  const SWord32 s1566 = table1[s1565];
-  const SWord8  s1567 = (SWord8) (s1484 >> 16);
-  const SWord32 s1568 = table2[s1567];
-  const SWord32 s1569 = s1566 ^ s1568;
-  const SWord8  s1570 = (SWord8) (s1498 >> 8);
-  const SWord32 s1571 = table3[s1570];
-  const SWord32 s1572 = s1569 ^ s1571;
-  const SWord8  s1573 = (SWord8) s1513;
-  const SWord32 s1574 = table4[s1573];
-  const SWord32 s1575 = s1572 ^ s1574;
-  const SWord32 s1576 = s27 ^ s1575;
-  const SWord8  s1577 = (SWord8) s1576;
-  const SWord32 s1578 = table4[s1577];
-  const SWord32 s1579 = s1564 ^ s1578;
-  const SWord32 s1580 = s28 ^ s1579;
-  const SWord8  s1581 = (SWord8) (s1580 >> 24);
-  const SWord32 s1582 = table1[s1581];
-  const SWord8  s1583 = (SWord8) (s1546 >> 24);
-  const SWord32 s1584 = table1[s1583];
-  const SWord8  s1585 = (SWord8) (s1561 >> 16);
-  const SWord32 s1586 = table2[s1585];
-  const SWord32 s1587 = s1584 ^ s1586;
-  const SWord8  s1588 = (SWord8) (s1576 >> 8);
-  const SWord32 s1589 = table3[s1588];
-  const SWord32 s1590 = s1587 ^ s1589;
-  const SWord8  s1591 = (SWord8) s1532;
-  const SWord32 s1592 = table4[s1591];
-  const SWord32 s1593 = s1590 ^ s1592;
-  const SWord32 s1594 = s29 ^ s1593;
-  const SWord8  s1595 = (SWord8) (s1594 >> 16);
-  const SWord32 s1596 = table2[s1595];
-  const SWord32 s1597 = s1582 ^ s1596;
-  const SWord8  s1598 = (SWord8) (s1561 >> 24);
-  const SWord32 s1599 = table1[s1598];
-  const SWord8  s1600 = (SWord8) (s1576 >> 16);
-  const SWord32 s1601 = table2[s1600];
-  const SWord32 s1602 = s1599 ^ s1601;
-  const SWord8  s1603 = (SWord8) (s1532 >> 8);
-  const SWord32 s1604 = table3[s1603];
-  const SWord32 s1605 = s1602 ^ s1604;
-  const SWord8  s1606 = (SWord8) s1546;
-  const SWord32 s1607 = table4[s1606];
-  const SWord32 s1608 = s1605 ^ s1607;
-  const SWord32 s1609 = s30 ^ s1608;
-  const SWord8  s1610 = (SWord8) (s1609 >> 8);
-  const SWord32 s1611 = table3[s1610];
-  const SWord32 s1612 = s1597 ^ s1611;
-  const SWord8  s1613 = (SWord8) (s1576 >> 24);
-  const SWord32 s1614 = table1[s1613];
-  const SWord8  s1615 = (SWord8) (s1532 >> 16);
-  const SWord32 s1616 = table2[s1615];
-  const SWord32 s1617 = s1614 ^ s1616;
-  const SWord8  s1618 = (SWord8) (s1546 >> 8);
-  const SWord32 s1619 = table3[s1618];
-  const SWord32 s1620 = s1617 ^ s1619;
-  const SWord8  s1621 = (SWord8) s1561;
-  const SWord32 s1622 = table4[s1621];
-  const SWord32 s1623 = s1620 ^ s1622;
-  const SWord32 s1624 = s31 ^ s1623;
-  const SWord8  s1625 = (SWord8) s1624;
-  const SWord32 s1626 = table4[s1625];
-  const SWord32 s1627 = s1612 ^ s1626;
-  const SWord32 s1628 = s32 ^ s1627;
-  const SWord8  s1629 = (SWord8) (s1628 >> 24);
-  const SWord32 s1630 = table1[s1629];
-  const SWord8  s1631 = (SWord8) (s1594 >> 24);
-  const SWord32 s1632 = table1[s1631];
-  const SWord8  s1633 = (SWord8) (s1609 >> 16);
-  const SWord32 s1634 = table2[s1633];
-  const SWord32 s1635 = s1632 ^ s1634;
-  const SWord8  s1636 = (SWord8) (s1624 >> 8);
-  const SWord32 s1637 = table3[s1636];
-  const SWord32 s1638 = s1635 ^ s1637;
-  const SWord8  s1639 = (SWord8) s1580;
-  const SWord32 s1640 = table4[s1639];
-  const SWord32 s1641 = s1638 ^ s1640;
-  const SWord32 s1642 = s33 ^ s1641;
-  const SWord8  s1643 = (SWord8) (s1642 >> 16);
-  const SWord32 s1644 = table2[s1643];
-  const SWord32 s1645 = s1630 ^ s1644;
-  const SWord8  s1646 = (SWord8) (s1609 >> 24);
-  const SWord32 s1647 = table1[s1646];
-  const SWord8  s1648 = (SWord8) (s1624 >> 16);
-  const SWord32 s1649 = table2[s1648];
-  const SWord32 s1650 = s1647 ^ s1649;
-  const SWord8  s1651 = (SWord8) (s1580 >> 8);
-  const SWord32 s1652 = table3[s1651];
-  const SWord32 s1653 = s1650 ^ s1652;
-  const SWord8  s1654 = (SWord8) s1594;
-  const SWord32 s1655 = table4[s1654];
-  const SWord32 s1656 = s1653 ^ s1655;
-  const SWord32 s1657 = s34 ^ s1656;
-  const SWord8  s1658 = (SWord8) (s1657 >> 8);
-  const SWord32 s1659 = table3[s1658];
-  const SWord32 s1660 = s1645 ^ s1659;
-  const SWord8  s1661 = (SWord8) (s1624 >> 24);
-  const SWord32 s1662 = table1[s1661];
-  const SWord8  s1663 = (SWord8) (s1580 >> 16);
-  const SWord32 s1664 = table2[s1663];
-  const SWord32 s1665 = s1662 ^ s1664;
-  const SWord8  s1666 = (SWord8) (s1594 >> 8);
-  const SWord32 s1667 = table3[s1666];
-  const SWord32 s1668 = s1665 ^ s1667;
-  const SWord8  s1669 = (SWord8) s1609;
-  const SWord32 s1670 = table4[s1669];
-  const SWord32 s1671 = s1668 ^ s1670;
-  const SWord32 s1672 = s35 ^ s1671;
-  const SWord8  s1673 = (SWord8) s1672;
-  const SWord32 s1674 = table4[s1673];
-  const SWord32 s1675 = s1660 ^ s1674;
-  const SWord32 s1676 = s36 ^ s1675;
-  const SWord8  s1677 = (SWord8) (s1676 >> 24);
-  const SWord32 s1678 = table1[s1677];
-  const SWord8  s1679 = (SWord8) (s1642 >> 24);
-  const SWord32 s1680 = table1[s1679];
-  const SWord8  s1681 = (SWord8) (s1657 >> 16);
-  const SWord32 s1682 = table2[s1681];
-  const SWord32 s1683 = s1680 ^ s1682;
-  const SWord8  s1684 = (SWord8) (s1672 >> 8);
-  const SWord32 s1685 = table3[s1684];
-  const SWord32 s1686 = s1683 ^ s1685;
-  const SWord8  s1687 = (SWord8) s1628;
-  const SWord32 s1688 = table4[s1687];
-  const SWord32 s1689 = s1686 ^ s1688;
-  const SWord32 s1690 = s37 ^ s1689;
-  const SWord8  s1691 = (SWord8) (s1690 >> 16);
-  const SWord32 s1692 = table2[s1691];
-  const SWord32 s1693 = s1678 ^ s1692;
-  const SWord8  s1694 = (SWord8) (s1657 >> 24);
-  const SWord32 s1695 = table1[s1694];
-  const SWord8  s1696 = (SWord8) (s1672 >> 16);
-  const SWord32 s1697 = table2[s1696];
-  const SWord32 s1698 = s1695 ^ s1697;
-  const SWord8  s1699 = (SWord8) (s1628 >> 8);
-  const SWord32 s1700 = table3[s1699];
-  const SWord32 s1701 = s1698 ^ s1700;
-  const SWord8  s1702 = (SWord8) s1642;
-  const SWord32 s1703 = table4[s1702];
-  const SWord32 s1704 = s1701 ^ s1703;
-  const SWord32 s1705 = s38 ^ s1704;
-  const SWord8  s1706 = (SWord8) (s1705 >> 8);
-  const SWord32 s1707 = table3[s1706];
-  const SWord32 s1708 = s1693 ^ s1707;
-  const SWord8  s1709 = (SWord8) (s1672 >> 24);
-  const SWord32 s1710 = table1[s1709];
-  const SWord8  s1711 = (SWord8) (s1628 >> 16);
-  const SWord32 s1712 = table2[s1711];
-  const SWord32 s1713 = s1710 ^ s1712;
-  const SWord8  s1714 = (SWord8) (s1642 >> 8);
-  const SWord32 s1715 = table3[s1714];
-  const SWord32 s1716 = s1713 ^ s1715;
-  const SWord8  s1717 = (SWord8) s1657;
-  const SWord32 s1718 = table4[s1717];
-  const SWord32 s1719 = s1716 ^ s1718;
-  const SWord32 s1720 = s39 ^ s1719;
-  const SWord8  s1721 = (SWord8) s1720;
-  const SWord32 s1722 = table4[s1721];
-  const SWord32 s1723 = s1708 ^ s1722;
-  const SWord32 s1724 = s40 ^ s1723;
-  const SWord8  s1725 = (SWord8) (s1724 >> 24);
-  const SWord8  s1726 = table0[s1725];
-  const SWord8  s1727 = (SWord8) (s1690 >> 24);
-  const SWord32 s1728 = table1[s1727];
-  const SWord8  s1729 = (SWord8) (s1705 >> 16);
-  const SWord32 s1730 = table2[s1729];
-  const SWord32 s1731 = s1728 ^ s1730;
-  const SWord8  s1732 = (SWord8) (s1720 >> 8);
-  const SWord32 s1733 = table3[s1732];
-  const SWord32 s1734 = s1731 ^ s1733;
-  const SWord8  s1735 = (SWord8) s1676;
-  const SWord32 s1736 = table4[s1735];
-  const SWord32 s1737 = s1734 ^ s1736;
-  const SWord32 s1738 = s41 ^ s1737;
-  const SWord8  s1739 = (SWord8) (s1738 >> 16);
-  const SWord8  s1740 = table0[s1739];
-  const SWord16 s1741 = (((SWord16) s1726) << 8) | ((SWord16) s1740);
-  const SWord8  s1742 = (SWord8) (s1705 >> 24);
-  const SWord32 s1743 = table1[s1742];
-  const SWord8  s1744 = (SWord8) (s1720 >> 16);
-  const SWord32 s1745 = table2[s1744];
-  const SWord32 s1746 = s1743 ^ s1745;
-  const SWord8  s1747 = (SWord8) (s1676 >> 8);
-  const SWord32 s1748 = table3[s1747];
-  const SWord32 s1749 = s1746 ^ s1748;
-  const SWord8  s1750 = (SWord8) s1690;
-  const SWord32 s1751 = table4[s1750];
-  const SWord32 s1752 = s1749 ^ s1751;
-  const SWord32 s1753 = s42 ^ s1752;
-  const SWord8  s1754 = (SWord8) (s1753 >> 8);
-  const SWord8  s1755 = table0[s1754];
-  const SWord8  s1756 = (SWord8) (s1720 >> 24);
-  const SWord32 s1757 = table1[s1756];
-  const SWord8  s1758 = (SWord8) (s1676 >> 16);
-  const SWord32 s1759 = table2[s1758];
-  const SWord32 s1760 = s1757 ^ s1759;
-  const SWord8  s1761 = (SWord8) (s1690 >> 8);
-  const SWord32 s1762 = table3[s1761];
-  const SWord32 s1763 = s1760 ^ s1762;
-  const SWord8  s1764 = (SWord8) s1705;
-  const SWord32 s1765 = table4[s1764];
-  const SWord32 s1766 = s1763 ^ s1765;
-  const SWord32 s1767 = s43 ^ s1766;
-  const SWord8  s1768 = (SWord8) s1767;
-  const SWord8  s1769 = table0[s1768];
-  const SWord16 s1770 = (((SWord16) s1755) << 8) | ((SWord16) s1769);
-  const SWord32 s1771 = (((SWord32) s1741) << 16) | ((SWord32) s1770);
-  const SWord32 s1772 = s44 ^ s1771;
-  const SWord8  s1773 = (SWord8) (s1738 >> 24);
-  const SWord8  s1774 = table0[s1773];
-  const SWord8  s1775 = (SWord8) (s1753 >> 16);
-  const SWord8  s1776 = table0[s1775];
-  const SWord16 s1777 = (((SWord16) s1774) << 8) | ((SWord16) s1776);
-  const SWord8  s1778 = (SWord8) (s1767 >> 8);
-  const SWord8  s1779 = table0[s1778];
-  const SWord8  s1780 = (SWord8) s1724;
-  const SWord8  s1781 = table0[s1780];
-  const SWord16 s1782 = (((SWord16) s1779) << 8) | ((SWord16) s1781);
-  const SWord32 s1783 = (((SWord32) s1777) << 16) | ((SWord32) s1782);
-  const SWord32 s1784 = s45 ^ s1783;
-  const SWord8  s1785 = (SWord8) (s1753 >> 24);
-  const SWord8  s1786 = table0[s1785];
-  const SWord8  s1787 = (SWord8) (s1767 >> 16);
-  const SWord8  s1788 = table0[s1787];
-  const SWord16 s1789 = (((SWord16) s1786) << 8) | ((SWord16) s1788);
-  const SWord8  s1790 = (SWord8) (s1724 >> 8);
-  const SWord8  s1791 = table0[s1790];
-  const SWord8  s1792 = (SWord8) s1738;
-  const SWord8  s1793 = table0[s1792];
-  const SWord16 s1794 = (((SWord16) s1791) << 8) | ((SWord16) s1793);
-  const SWord32 s1795 = (((SWord32) s1789) << 16) | ((SWord32) s1794);
-  const SWord32 s1796 = s46 ^ s1795;
-  const SWord8  s1797 = (SWord8) (s1767 >> 24);
-  const SWord8  s1798 = table0[s1797];
-  const SWord8  s1799 = (SWord8) (s1724 >> 16);
-  const SWord8  s1800 = table0[s1799];
-  const SWord16 s1801 = (((SWord16) s1798) << 8) | ((SWord16) s1800);
-  const SWord8  s1802 = (SWord8) (s1738 >> 8);
-  const SWord8  s1803 = table0[s1802];
-  const SWord8  s1804 = (SWord8) s1753;
-  const SWord8  s1805 = table0[s1804];
-  const SWord16 s1806 = (((SWord16) s1803) << 8) | ((SWord16) s1805);
-  const SWord32 s1807 = (((SWord32) s1801) << 16) | ((SWord32) s1806);
-  const SWord32 s1808 = s47 ^ s1807;
-
-  ct[0] = s1772;
-  ct[1] = s1784;
-  ct[2] = s1796;
-  ct[3] = s1808;
-}
-== END: "aes128BlockEncrypt.c" ==================
-== BEGIN: "aes128BlockDecrypt.c" ================
-/* File: "aes128BlockDecrypt.c". Automatically generated by SBV. Do not edit! */
-
-#include "aes128Lib.h"
-
-void aes128BlockDecrypt(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[] = {
-      0x51f4a750UL, 0x7e416553UL, 0x1a17a4c3UL, 0x3a275e96UL,
-      0x3bab6bcbUL, 0x1f9d45f1UL, 0xacfa58abUL, 0x4be30393UL,
-      0x2030fa55UL, 0xad766df6UL, 0x88cc7691UL, 0xf5024c25UL,
-      0x4fe5d7fcUL, 0xc52acbd7UL, 0x26354480UL, 0xb562a38fUL,
-      0xdeb15a49UL, 0x25ba1b67UL, 0x45ea0e98UL, 0x5dfec0e1UL,
-      0xc32f7502UL, 0x814cf012UL, 0x8d4697a3UL, 0x6bd3f9c6UL,
-      0x038f5fe7UL, 0x15929c95UL, 0xbf6d7aebUL, 0x955259daUL,
-      0xd4be832dUL, 0x587421d3UL, 0x49e06929UL, 0x8ec9c844UL,
-      0x75c2896aUL, 0xf48e7978UL, 0x99583e6bUL, 0x27b971ddUL,
-      0xbee14fb6UL, 0xf088ad17UL, 0xc920ac66UL, 0x7dce3ab4UL,
-      0x63df4a18UL, 0xe51a3182UL, 0x97513360UL, 0x62537f45UL,
-      0xb16477e0UL, 0xbb6bae84UL, 0xfe81a01cUL, 0xf9082b94UL,
-      0x70486858UL, 0x8f45fd19UL, 0x94de6c87UL, 0x527bf8b7UL,
-      0xab73d323UL, 0x724b02e2UL, 0xe31f8f57UL, 0x6655ab2aUL,
-      0xb2eb2807UL, 0x2fb5c203UL, 0x86c57b9aUL, 0xd33708a5UL,
-      0x302887f2UL, 0x23bfa5b2UL, 0x02036abaUL, 0xed16825cUL,
-      0x8acf1c2bUL, 0xa779b492UL, 0xf307f2f0UL, 0x4e69e2a1UL,
-      0x65daf4cdUL, 0x0605bed5UL, 0xd134621fUL, 0xc4a6fe8aUL,
-      0x342e539dUL, 0xa2f355a0UL, 0x058ae132UL, 0xa4f6eb75UL,
-      0x0b83ec39UL, 0x4060efaaUL, 0x5e719f06UL, 0xbd6e1051UL,
-      0x3e218af9UL, 0x96dd063dUL, 0xdd3e05aeUL, 0x4de6bd46UL,
-      0x91548db5UL, 0x71c45d05UL, 0x0406d46fUL, 0x605015ffUL,
-      0x1998fb24UL, 0xd6bde997UL, 0x894043ccUL, 0x67d99e77UL,
-      0xb0e842bdUL, 0x07898b88UL, 0xe7195b38UL, 0x79c8eedbUL,
-      0xa17c0a47UL, 0x7c420fe9UL, 0xf8841ec9UL, 0x00000000UL,
-      0x09808683UL, 0x322bed48UL, 0x1e1170acUL, 0x6c5a724eUL,
-      0xfd0efffbUL, 0x0f853856UL, 0x3daed51eUL, 0x362d3927UL,
-      0x0a0fd964UL, 0x685ca621UL, 0x9b5b54d1UL, 0x24362e3aUL,
-      0x0c0a67b1UL, 0x9357e70fUL, 0xb4ee96d2UL, 0x1b9b919eUL,
-      0x80c0c54fUL, 0x61dc20a2UL, 0x5a774b69UL, 0x1c121a16UL,
-      0xe293ba0aUL, 0xc0a02ae5UL, 0x3c22e043UL, 0x121b171dUL,
-      0x0e090d0bUL, 0xf28bc7adUL, 0x2db6a8b9UL, 0x141ea9c8UL,
-      0x57f11985UL, 0xaf75074cUL, 0xee99ddbbUL, 0xa37f60fdUL,
-      0xf701269fUL, 0x5c72f5bcUL, 0x44663bc5UL, 0x5bfb7e34UL,
-      0x8b432976UL, 0xcb23c6dcUL, 0xb6edfc68UL, 0xb8e4f163UL,
-      0xd731dccaUL, 0x42638510UL, 0x13972240UL, 0x84c61120UL,
-      0x854a247dUL, 0xd2bb3df8UL, 0xaef93211UL, 0xc729a16dUL,
-      0x1d9e2f4bUL, 0xdcb230f3UL, 0x0d8652ecUL, 0x77c1e3d0UL,
-      0x2bb3166cUL, 0xa970b999UL, 0x119448faUL, 0x47e96422UL,
-      0xa8fc8cc4UL, 0xa0f03f1aUL, 0x567d2cd8UL, 0x223390efUL,
-      0x87494ec7UL, 0xd938d1c1UL, 0x8ccaa2feUL, 0x98d40b36UL,
-      0xa6f581cfUL, 0xa57ade28UL, 0xdab78e26UL, 0x3fadbfa4UL,
-      0x2c3a9de4UL, 0x5078920dUL, 0x6a5fcc9bUL, 0x547e4662UL,
-      0xf68d13c2UL, 0x90d8b8e8UL, 0x2e39f75eUL, 0x82c3aff5UL,
-      0x9f5d80beUL, 0x69d0937cUL, 0x6fd52da9UL, 0xcf2512b3UL,
-      0xc8ac993bUL, 0x10187da7UL, 0xe89c636eUL, 0xdb3bbb7bUL,
-      0xcd267809UL, 0x6e5918f4UL, 0xec9ab701UL, 0x834f9aa8UL,
-      0xe6956e65UL, 0xaaffe67eUL, 0x21bccf08UL, 0xef15e8e6UL,
-      0xbae79bd9UL, 0x4a6f36ceUL, 0xea9f09d4UL, 0x29b07cd6UL,
-      0x31a4b2afUL, 0x2a3f2331UL, 0xc6a59430UL, 0x35a266c0UL,
-      0x744ebc37UL, 0xfc82caa6UL, 0xe090d0b0UL, 0x33a7d815UL,
-      0xf104984aUL, 0x41ecdaf7UL, 0x7fcd500eUL, 0x1791f62fUL,
-      0x764dd68dUL, 0x43efb04dUL, 0xccaa4d54UL, 0xe49604dfUL,
-      0x9ed1b5e3UL, 0x4c6a881bUL, 0xc12c1fb8UL, 0x4665517fUL,
-      0x9d5eea04UL, 0x018c355dUL, 0xfa877473UL, 0xfb0b412eUL,
-      0xb3671d5aUL, 0x92dbd252UL, 0xe9105633UL, 0x6dd64713UL,
-      0x9ad7618cUL, 0x37a10c7aUL, 0x59f8148eUL, 0xeb133c89UL,
-      0xcea927eeUL, 0xb761c935UL, 0xe11ce5edUL, 0x7a47b13cUL,
-      0x9cd2df59UL, 0x55f2733fUL, 0x1814ce79UL, 0x73c737bfUL,
-      0x53f7cdeaUL, 0x5ffdaa5bUL, 0xdf3d6f14UL, 0x7844db86UL,
-      0xcaaff381UL, 0xb968c43eUL, 0x3824342cUL, 0xc2a3405fUL,
-      0x161dc372UL, 0xbce2250cUL, 0x283c498bUL, 0xff0d9541UL,
-      0x39a80171UL, 0x080cb3deUL, 0xd8b4e49cUL, 0x6456c190UL,
-      0x7bcb8461UL, 0xd532b670UL, 0x486c5c74UL, 0xd0b85742UL
-  };
-  static const SWord32 table2[] = {
-      0x5051f4a7UL, 0x537e4165UL, 0xc31a17a4UL, 0x963a275eUL,
-      0xcb3bab6bUL, 0xf11f9d45UL, 0xabacfa58UL, 0x934be303UL,
-      0x552030faUL, 0xf6ad766dUL, 0x9188cc76UL, 0x25f5024cUL,
-      0xfc4fe5d7UL, 0xd7c52acbUL, 0x80263544UL, 0x8fb562a3UL,
-      0x49deb15aUL, 0x6725ba1bUL, 0x9845ea0eUL, 0xe15dfec0UL,
-      0x02c32f75UL, 0x12814cf0UL, 0xa38d4697UL, 0xc66bd3f9UL,
-      0xe7038f5fUL, 0x9515929cUL, 0xebbf6d7aUL, 0xda955259UL,
-      0x2dd4be83UL, 0xd3587421UL, 0x2949e069UL, 0x448ec9c8UL,
-      0x6a75c289UL, 0x78f48e79UL, 0x6b99583eUL, 0xdd27b971UL,
-      0xb6bee14fUL, 0x17f088adUL, 0x66c920acUL, 0xb47dce3aUL,
-      0x1863df4aUL, 0x82e51a31UL, 0x60975133UL, 0x4562537fUL,
-      0xe0b16477UL, 0x84bb6baeUL, 0x1cfe81a0UL, 0x94f9082bUL,
-      0x58704868UL, 0x198f45fdUL, 0x8794de6cUL, 0xb7527bf8UL,
-      0x23ab73d3UL, 0xe2724b02UL, 0x57e31f8fUL, 0x2a6655abUL,
-      0x07b2eb28UL, 0x032fb5c2UL, 0x9a86c57bUL, 0xa5d33708UL,
-      0xf2302887UL, 0xb223bfa5UL, 0xba02036aUL, 0x5ced1682UL,
-      0x2b8acf1cUL, 0x92a779b4UL, 0xf0f307f2UL, 0xa14e69e2UL,
-      0xcd65daf4UL, 0xd50605beUL, 0x1fd13462UL, 0x8ac4a6feUL,
-      0x9d342e53UL, 0xa0a2f355UL, 0x32058ae1UL, 0x75a4f6ebUL,
-      0x390b83ecUL, 0xaa4060efUL, 0x065e719fUL, 0x51bd6e10UL,
-      0xf93e218aUL, 0x3d96dd06UL, 0xaedd3e05UL, 0x464de6bdUL,
-      0xb591548dUL, 0x0571c45dUL, 0x6f0406d4UL, 0xff605015UL,
-      0x241998fbUL, 0x97d6bde9UL, 0xcc894043UL, 0x7767d99eUL,
-      0xbdb0e842UL, 0x8807898bUL, 0x38e7195bUL, 0xdb79c8eeUL,
-      0x47a17c0aUL, 0xe97c420fUL, 0xc9f8841eUL, 0x00000000UL,
-      0x83098086UL, 0x48322bedUL, 0xac1e1170UL, 0x4e6c5a72UL,
-      0xfbfd0effUL, 0x560f8538UL, 0x1e3daed5UL, 0x27362d39UL,
-      0x640a0fd9UL, 0x21685ca6UL, 0xd19b5b54UL, 0x3a24362eUL,
-      0xb10c0a67UL, 0x0f9357e7UL, 0xd2b4ee96UL, 0x9e1b9b91UL,
-      0x4f80c0c5UL, 0xa261dc20UL, 0x695a774bUL, 0x161c121aUL,
-      0x0ae293baUL, 0xe5c0a02aUL, 0x433c22e0UL, 0x1d121b17UL,
-      0x0b0e090dUL, 0xadf28bc7UL, 0xb92db6a8UL, 0xc8141ea9UL,
-      0x8557f119UL, 0x4caf7507UL, 0xbbee99ddUL, 0xfda37f60UL,
-      0x9ff70126UL, 0xbc5c72f5UL, 0xc544663bUL, 0x345bfb7eUL,
-      0x768b4329UL, 0xdccb23c6UL, 0x68b6edfcUL, 0x63b8e4f1UL,
-      0xcad731dcUL, 0x10426385UL, 0x40139722UL, 0x2084c611UL,
-      0x7d854a24UL, 0xf8d2bb3dUL, 0x11aef932UL, 0x6dc729a1UL,
-      0x4b1d9e2fUL, 0xf3dcb230UL, 0xec0d8652UL, 0xd077c1e3UL,
-      0x6c2bb316UL, 0x99a970b9UL, 0xfa119448UL, 0x2247e964UL,
-      0xc4a8fc8cUL, 0x1aa0f03fUL, 0xd8567d2cUL, 0xef223390UL,
-      0xc787494eUL, 0xc1d938d1UL, 0xfe8ccaa2UL, 0x3698d40bUL,
-      0xcfa6f581UL, 0x28a57adeUL, 0x26dab78eUL, 0xa43fadbfUL,
-      0xe42c3a9dUL, 0x0d507892UL, 0x9b6a5fccUL, 0x62547e46UL,
-      0xc2f68d13UL, 0xe890d8b8UL, 0x5e2e39f7UL, 0xf582c3afUL,
-      0xbe9f5d80UL, 0x7c69d093UL, 0xa96fd52dUL, 0xb3cf2512UL,
-      0x3bc8ac99UL, 0xa710187dUL, 0x6ee89c63UL, 0x7bdb3bbbUL,
-      0x09cd2678UL, 0xf46e5918UL, 0x01ec9ab7UL, 0xa8834f9aUL,
-      0x65e6956eUL, 0x7eaaffe6UL, 0x0821bccfUL, 0xe6ef15e8UL,
-      0xd9bae79bUL, 0xce4a6f36UL, 0xd4ea9f09UL, 0xd629b07cUL,
-      0xaf31a4b2UL, 0x312a3f23UL, 0x30c6a594UL, 0xc035a266UL,
-      0x37744ebcUL, 0xa6fc82caUL, 0xb0e090d0UL, 0x1533a7d8UL,
-      0x4af10498UL, 0xf741ecdaUL, 0x0e7fcd50UL, 0x2f1791f6UL,
-      0x8d764dd6UL, 0x4d43efb0UL, 0x54ccaa4dUL, 0xdfe49604UL,
-      0xe39ed1b5UL, 0x1b4c6a88UL, 0xb8c12c1fUL, 0x7f466551UL,
-      0x049d5eeaUL, 0x5d018c35UL, 0x73fa8774UL, 0x2efb0b41UL,
-      0x5ab3671dUL, 0x5292dbd2UL, 0x33e91056UL, 0x136dd647UL,
-      0x8c9ad761UL, 0x7a37a10cUL, 0x8e59f814UL, 0x89eb133cUL,
-      0xeecea927UL, 0x35b761c9UL, 0xede11ce5UL, 0x3c7a47b1UL,
-      0x599cd2dfUL, 0x3f55f273UL, 0x791814ceUL, 0xbf73c737UL,
-      0xea53f7cdUL, 0x5b5ffdaaUL, 0x14df3d6fUL, 0x867844dbUL,
-      0x81caaff3UL, 0x3eb968c4UL, 0x2c382434UL, 0x5fc2a340UL,
-      0x72161dc3UL, 0x0cbce225UL, 0x8b283c49UL, 0x41ff0d95UL,
-      0x7139a801UL, 0xde080cb3UL, 0x9cd8b4e4UL, 0x906456c1UL,
-      0x617bcb84UL, 0x70d532b6UL, 0x74486c5cUL, 0x42d0b857UL
-  };
-  static const SWord32 table3[] = {
-      0xa75051f4UL, 0x65537e41UL, 0xa4c31a17UL, 0x5e963a27UL,
-      0x6bcb3babUL, 0x45f11f9dUL, 0x58abacfaUL, 0x03934be3UL,
-      0xfa552030UL, 0x6df6ad76UL, 0x769188ccUL, 0x4c25f502UL,
-      0xd7fc4fe5UL, 0xcbd7c52aUL, 0x44802635UL, 0xa38fb562UL,
-      0x5a49deb1UL, 0x1b6725baUL, 0x0e9845eaUL, 0xc0e15dfeUL,
-      0x7502c32fUL, 0xf012814cUL, 0x97a38d46UL, 0xf9c66bd3UL,
-      0x5fe7038fUL, 0x9c951592UL, 0x7aebbf6dUL, 0x59da9552UL,
-      0x832dd4beUL, 0x21d35874UL, 0x692949e0UL, 0xc8448ec9UL,
-      0x896a75c2UL, 0x7978f48eUL, 0x3e6b9958UL, 0x71dd27b9UL,
-      0x4fb6bee1UL, 0xad17f088UL, 0xac66c920UL, 0x3ab47dceUL,
-      0x4a1863dfUL, 0x3182e51aUL, 0x33609751UL, 0x7f456253UL,
-      0x77e0b164UL, 0xae84bb6bUL, 0xa01cfe81UL, 0x2b94f908UL,
-      0x68587048UL, 0xfd198f45UL, 0x6c8794deUL, 0xf8b7527bUL,
-      0xd323ab73UL, 0x02e2724bUL, 0x8f57e31fUL, 0xab2a6655UL,
-      0x2807b2ebUL, 0xc2032fb5UL, 0x7b9a86c5UL, 0x08a5d337UL,
-      0x87f23028UL, 0xa5b223bfUL, 0x6aba0203UL, 0x825ced16UL,
-      0x1c2b8acfUL, 0xb492a779UL, 0xf2f0f307UL, 0xe2a14e69UL,
-      0xf4cd65daUL, 0xbed50605UL, 0x621fd134UL, 0xfe8ac4a6UL,
-      0x539d342eUL, 0x55a0a2f3UL, 0xe132058aUL, 0xeb75a4f6UL,
-      0xec390b83UL, 0xefaa4060UL, 0x9f065e71UL, 0x1051bd6eUL,
-      0x8af93e21UL, 0x063d96ddUL, 0x05aedd3eUL, 0xbd464de6UL,
-      0x8db59154UL, 0x5d0571c4UL, 0xd46f0406UL, 0x15ff6050UL,
-      0xfb241998UL, 0xe997d6bdUL, 0x43cc8940UL, 0x9e7767d9UL,
-      0x42bdb0e8UL, 0x8b880789UL, 0x5b38e719UL, 0xeedb79c8UL,
-      0x0a47a17cUL, 0x0fe97c42UL, 0x1ec9f884UL, 0x00000000UL,
-      0x86830980UL, 0xed48322bUL, 0x70ac1e11UL, 0x724e6c5aUL,
-      0xfffbfd0eUL, 0x38560f85UL, 0xd51e3daeUL, 0x3927362dUL,
-      0xd9640a0fUL, 0xa621685cUL, 0x54d19b5bUL, 0x2e3a2436UL,
-      0x67b10c0aUL, 0xe70f9357UL, 0x96d2b4eeUL, 0x919e1b9bUL,
-      0xc54f80c0UL, 0x20a261dcUL, 0x4b695a77UL, 0x1a161c12UL,
-      0xba0ae293UL, 0x2ae5c0a0UL, 0xe0433c22UL, 0x171d121bUL,
-      0x0d0b0e09UL, 0xc7adf28bUL, 0xa8b92db6UL, 0xa9c8141eUL,
-      0x198557f1UL, 0x074caf75UL, 0xddbbee99UL, 0x60fda37fUL,
-      0x269ff701UL, 0xf5bc5c72UL, 0x3bc54466UL, 0x7e345bfbUL,
-      0x29768b43UL, 0xc6dccb23UL, 0xfc68b6edUL, 0xf163b8e4UL,
-      0xdccad731UL, 0x85104263UL, 0x22401397UL, 0x112084c6UL,
-      0x247d854aUL, 0x3df8d2bbUL, 0x3211aef9UL, 0xa16dc729UL,
-      0x2f4b1d9eUL, 0x30f3dcb2UL, 0x52ec0d86UL, 0xe3d077c1UL,
-      0x166c2bb3UL, 0xb999a970UL, 0x48fa1194UL, 0x642247e9UL,
-      0x8cc4a8fcUL, 0x3f1aa0f0UL, 0x2cd8567dUL, 0x90ef2233UL,
-      0x4ec78749UL, 0xd1c1d938UL, 0xa2fe8ccaUL, 0x0b3698d4UL,
-      0x81cfa6f5UL, 0xde28a57aUL, 0x8e26dab7UL, 0xbfa43fadUL,
-      0x9de42c3aUL, 0x920d5078UL, 0xcc9b6a5fUL, 0x4662547eUL,
-      0x13c2f68dUL, 0xb8e890d8UL, 0xf75e2e39UL, 0xaff582c3UL,
-      0x80be9f5dUL, 0x937c69d0UL, 0x2da96fd5UL, 0x12b3cf25UL,
-      0x993bc8acUL, 0x7da71018UL, 0x636ee89cUL, 0xbb7bdb3bUL,
-      0x7809cd26UL, 0x18f46e59UL, 0xb701ec9aUL, 0x9aa8834fUL,
-      0x6e65e695UL, 0xe67eaaffUL, 0xcf0821bcUL, 0xe8e6ef15UL,
-      0x9bd9bae7UL, 0x36ce4a6fUL, 0x09d4ea9fUL, 0x7cd629b0UL,
-      0xb2af31a4UL, 0x23312a3fUL, 0x9430c6a5UL, 0x66c035a2UL,
-      0xbc37744eUL, 0xcaa6fc82UL, 0xd0b0e090UL, 0xd81533a7UL,
-      0x984af104UL, 0xdaf741ecUL, 0x500e7fcdUL, 0xf62f1791UL,
-      0xd68d764dUL, 0xb04d43efUL, 0x4d54ccaaUL, 0x04dfe496UL,
-      0xb5e39ed1UL, 0x881b4c6aUL, 0x1fb8c12cUL, 0x517f4665UL,
-      0xea049d5eUL, 0x355d018cUL, 0x7473fa87UL, 0x412efb0bUL,
-      0x1d5ab367UL, 0xd25292dbUL, 0x5633e910UL, 0x47136dd6UL,
-      0x618c9ad7UL, 0x0c7a37a1UL, 0x148e59f8UL, 0x3c89eb13UL,
-      0x27eecea9UL, 0xc935b761UL, 0xe5ede11cUL, 0xb13c7a47UL,
-      0xdf599cd2UL, 0x733f55f2UL, 0xce791814UL, 0x37bf73c7UL,
-      0xcdea53f7UL, 0xaa5b5ffdUL, 0x6f14df3dUL, 0xdb867844UL,
-      0xf381caafUL, 0xc43eb968UL, 0x342c3824UL, 0x405fc2a3UL,
-      0xc372161dUL, 0x250cbce2UL, 0x498b283cUL, 0x9541ff0dUL,
-      0x017139a8UL, 0xb3de080cUL, 0xe49cd8b4UL, 0xc1906456UL,
-      0x84617bcbUL, 0xb670d532UL, 0x5c74486cUL, 0x5742d0b8UL
-  };
-  static const SWord32 table4[] = {
-      0xf4a75051UL, 0x4165537eUL, 0x17a4c31aUL, 0x275e963aUL,
-      0xab6bcb3bUL, 0x9d45f11fUL, 0xfa58abacUL, 0xe303934bUL,
-      0x30fa5520UL, 0x766df6adUL, 0xcc769188UL, 0x024c25f5UL,
-      0xe5d7fc4fUL, 0x2acbd7c5UL, 0x35448026UL, 0x62a38fb5UL,
-      0xb15a49deUL, 0xba1b6725UL, 0xea0e9845UL, 0xfec0e15dUL,
-      0x2f7502c3UL, 0x4cf01281UL, 0x4697a38dUL, 0xd3f9c66bUL,
-      0x8f5fe703UL, 0x929c9515UL, 0x6d7aebbfUL, 0x5259da95UL,
-      0xbe832dd4UL, 0x7421d358UL, 0xe0692949UL, 0xc9c8448eUL,
-      0xc2896a75UL, 0x8e7978f4UL, 0x583e6b99UL, 0xb971dd27UL,
-      0xe14fb6beUL, 0x88ad17f0UL, 0x20ac66c9UL, 0xce3ab47dUL,
-      0xdf4a1863UL, 0x1a3182e5UL, 0x51336097UL, 0x537f4562UL,
-      0x6477e0b1UL, 0x6bae84bbUL, 0x81a01cfeUL, 0x082b94f9UL,
-      0x48685870UL, 0x45fd198fUL, 0xde6c8794UL, 0x7bf8b752UL,
-      0x73d323abUL, 0x4b02e272UL, 0x1f8f57e3UL, 0x55ab2a66UL,
-      0xeb2807b2UL, 0xb5c2032fUL, 0xc57b9a86UL, 0x3708a5d3UL,
-      0x2887f230UL, 0xbfa5b223UL, 0x036aba02UL, 0x16825cedUL,
-      0xcf1c2b8aUL, 0x79b492a7UL, 0x07f2f0f3UL, 0x69e2a14eUL,
-      0xdaf4cd65UL, 0x05bed506UL, 0x34621fd1UL, 0xa6fe8ac4UL,
-      0x2e539d34UL, 0xf355a0a2UL, 0x8ae13205UL, 0xf6eb75a4UL,
-      0x83ec390bUL, 0x60efaa40UL, 0x719f065eUL, 0x6e1051bdUL,
-      0x218af93eUL, 0xdd063d96UL, 0x3e05aeddUL, 0xe6bd464dUL,
-      0x548db591UL, 0xc45d0571UL, 0x06d46f04UL, 0x5015ff60UL,
-      0x98fb2419UL, 0xbde997d6UL, 0x4043cc89UL, 0xd99e7767UL,
-      0xe842bdb0UL, 0x898b8807UL, 0x195b38e7UL, 0xc8eedb79UL,
-      0x7c0a47a1UL, 0x420fe97cUL, 0x841ec9f8UL, 0x00000000UL,
-      0x80868309UL, 0x2bed4832UL, 0x1170ac1eUL, 0x5a724e6cUL,
-      0x0efffbfdUL, 0x8538560fUL, 0xaed51e3dUL, 0x2d392736UL,
-      0x0fd9640aUL, 0x5ca62168UL, 0x5b54d19bUL, 0x362e3a24UL,
-      0x0a67b10cUL, 0x57e70f93UL, 0xee96d2b4UL, 0x9b919e1bUL,
-      0xc0c54f80UL, 0xdc20a261UL, 0x774b695aUL, 0x121a161cUL,
-      0x93ba0ae2UL, 0xa02ae5c0UL, 0x22e0433cUL, 0x1b171d12UL,
-      0x090d0b0eUL, 0x8bc7adf2UL, 0xb6a8b92dUL, 0x1ea9c814UL,
-      0xf1198557UL, 0x75074cafUL, 0x99ddbbeeUL, 0x7f60fda3UL,
-      0x01269ff7UL, 0x72f5bc5cUL, 0x663bc544UL, 0xfb7e345bUL,
-      0x4329768bUL, 0x23c6dccbUL, 0xedfc68b6UL, 0xe4f163b8UL,
-      0x31dccad7UL, 0x63851042UL, 0x97224013UL, 0xc6112084UL,
-      0x4a247d85UL, 0xbb3df8d2UL, 0xf93211aeUL, 0x29a16dc7UL,
-      0x9e2f4b1dUL, 0xb230f3dcUL, 0x8652ec0dUL, 0xc1e3d077UL,
-      0xb3166c2bUL, 0x70b999a9UL, 0x9448fa11UL, 0xe9642247UL,
-      0xfc8cc4a8UL, 0xf03f1aa0UL, 0x7d2cd856UL, 0x3390ef22UL,
-      0x494ec787UL, 0x38d1c1d9UL, 0xcaa2fe8cUL, 0xd40b3698UL,
-      0xf581cfa6UL, 0x7ade28a5UL, 0xb78e26daUL, 0xadbfa43fUL,
-      0x3a9de42cUL, 0x78920d50UL, 0x5fcc9b6aUL, 0x7e466254UL,
-      0x8d13c2f6UL, 0xd8b8e890UL, 0x39f75e2eUL, 0xc3aff582UL,
-      0x5d80be9fUL, 0xd0937c69UL, 0xd52da96fUL, 0x2512b3cfUL,
-      0xac993bc8UL, 0x187da710UL, 0x9c636ee8UL, 0x3bbb7bdbUL,
-      0x267809cdUL, 0x5918f46eUL, 0x9ab701ecUL, 0x4f9aa883UL,
-      0x956e65e6UL, 0xffe67eaaUL, 0xbccf0821UL, 0x15e8e6efUL,
-      0xe79bd9baUL, 0x6f36ce4aUL, 0x9f09d4eaUL, 0xb07cd629UL,
-      0xa4b2af31UL, 0x3f23312aUL, 0xa59430c6UL, 0xa266c035UL,
-      0x4ebc3774UL, 0x82caa6fcUL, 0x90d0b0e0UL, 0xa7d81533UL,
-      0x04984af1UL, 0xecdaf741UL, 0xcd500e7fUL, 0x91f62f17UL,
-      0x4dd68d76UL, 0xefb04d43UL, 0xaa4d54ccUL, 0x9604dfe4UL,
-      0xd1b5e39eUL, 0x6a881b4cUL, 0x2c1fb8c1UL, 0x65517f46UL,
-      0x5eea049dUL, 0x8c355d01UL, 0x877473faUL, 0x0b412efbUL,
-      0x671d5ab3UL, 0xdbd25292UL, 0x105633e9UL, 0xd647136dUL,
-      0xd7618c9aUL, 0xa10c7a37UL, 0xf8148e59UL, 0x133c89ebUL,
-      0xa927eeceUL, 0x61c935b7UL, 0x1ce5ede1UL, 0x47b13c7aUL,
-      0xd2df599cUL, 0xf2733f55UL, 0x14ce7918UL, 0xc737bf73UL,
-      0xf7cdea53UL, 0xfdaa5b5fUL, 0x3d6f14dfUL, 0x44db8678UL,
-      0xaff381caUL, 0x68c43eb9UL, 0x24342c38UL, 0xa3405fc2UL,
-      0x1dc37216UL, 0xe2250cbcUL, 0x3c498b28UL, 0x0d9541ffUL,
-      0xa8017139UL, 0x0cb3de08UL, 0xb4e49cd8UL, 0x56c19064UL,
-      0xcb84617bUL, 0x32b670d5UL, 0x6c5c7448UL, 0xb85742d0UL
-  };
-  const SWord32 s560 = s0 ^ s4;
-  const SWord8  s561 = (SWord8) (s560 >> 24);
-  const SWord32 s562 = table1[s561];
-  const SWord32 s818 = s3 ^ s7;
-  const SWord8  s819 = (SWord8) (s818 >> 16);
-  const SWord32 s820 = table2[s819];
-  const SWord32 s821 = s562 ^ s820;
-  const SWord32 s1077 = s2 ^ s6;
-  const SWord8  s1078 = (SWord8) (s1077 >> 8);
-  const SWord32 s1079 = table3[s1078];
-  const SWord32 s1080 = s821 ^ s1079;
-  const SWord32 s1336 = s1 ^ s5;
-  const SWord8  s1337 = (SWord8) s1336;
-  const SWord32 s1338 = table4[s1337];
-  const SWord32 s1339 = s1080 ^ s1338;
-  const SWord32 s1340 = s8 ^ s1339;
-  const SWord8  s1341 = (SWord8) (s1340 >> 24);
-  const SWord32 s1342 = table1[s1341];
-  const SWord8  s1343 = (SWord8) (s818 >> 24);
-  const SWord32 s1344 = table1[s1343];
-  const SWord8  s1345 = (SWord8) (s1077 >> 16);
-  const SWord32 s1346 = table2[s1345];
-  const SWord32 s1347 = s1344 ^ s1346;
-  const SWord8  s1348 = (SWord8) (s1336 >> 8);
-  const SWord32 s1349 = table3[s1348];
-  const SWord32 s1350 = s1347 ^ s1349;
-  const SWord8  s1351 = (SWord8) s560;
-  const SWord32 s1352 = table4[s1351];
-  const SWord32 s1353 = s1350 ^ s1352;
-  const SWord32 s1354 = s11 ^ s1353;
-  const SWord8  s1355 = (SWord8) (s1354 >> 16);
-  const SWord32 s1356 = table2[s1355];
-  const SWord32 s1357 = s1342 ^ s1356;
-  const SWord8  s1358 = (SWord8) (s1077 >> 24);
-  const SWord32 s1359 = table1[s1358];
-  const SWord8  s1360 = (SWord8) (s1336 >> 16);
-  const SWord32 s1361 = table2[s1360];
-  const SWord32 s1362 = s1359 ^ s1361;
-  const SWord8  s1363 = (SWord8) (s560 >> 8);
-  const SWord32 s1364 = table3[s1363];
-  const SWord32 s1365 = s1362 ^ s1364;
-  const SWord8  s1366 = (SWord8) s818;
-  const SWord32 s1367 = table4[s1366];
-  const SWord32 s1368 = s1365 ^ s1367;
-  const SWord32 s1369 = s10 ^ s1368;
-  const SWord8  s1370 = (SWord8) (s1369 >> 8);
-  const SWord32 s1371 = table3[s1370];
-  const SWord32 s1372 = s1357 ^ s1371;
-  const SWord8  s1373 = (SWord8) (s1336 >> 24);
-  const SWord32 s1374 = table1[s1373];
-  const SWord8  s1375 = (SWord8) (s560 >> 16);
-  const SWord32 s1376 = table2[s1375];
-  const SWord32 s1377 = s1374 ^ s1376;
-  const SWord8  s1378 = (SWord8) (s818 >> 8);
-  const SWord32 s1379 = table3[s1378];
-  const SWord32 s1380 = s1377 ^ s1379;
-  const SWord8  s1381 = (SWord8) s1077;
-  const SWord32 s1382 = table4[s1381];
-  const SWord32 s1383 = s1380 ^ s1382;
-  const SWord32 s1384 = s9 ^ s1383;
-  const SWord8  s1385 = (SWord8) s1384;
-  const SWord32 s1386 = table4[s1385];
-  const SWord32 s1387 = s1372 ^ s1386;
-  const SWord32 s1388 = s12 ^ s1387;
-  const SWord8  s1389 = (SWord8) (s1388 >> 24);
-  const SWord32 s1390 = table1[s1389];
-  const SWord8  s1391 = (SWord8) (s1354 >> 24);
-  const SWord32 s1392 = table1[s1391];
-  const SWord8  s1393 = (SWord8) (s1369 >> 16);
-  const SWord32 s1394 = table2[s1393];
-  const SWord32 s1395 = s1392 ^ s1394;
-  const SWord8  s1396 = (SWord8) (s1384 >> 8);
-  const SWord32 s1397 = table3[s1396];
-  const SWord32 s1398 = s1395 ^ s1397;
-  const SWord8  s1399 = (SWord8) s1340;
-  const SWord32 s1400 = table4[s1399];
-  const SWord32 s1401 = s1398 ^ s1400;
-  const SWord32 s1402 = s15 ^ s1401;
-  const SWord8  s1403 = (SWord8) (s1402 >> 16);
-  const SWord32 s1404 = table2[s1403];
-  const SWord32 s1405 = s1390 ^ s1404;
-  const SWord8  s1406 = (SWord8) (s1369 >> 24);
-  const SWord32 s1407 = table1[s1406];
-  const SWord8  s1408 = (SWord8) (s1384 >> 16);
-  const SWord32 s1409 = table2[s1408];
-  const SWord32 s1410 = s1407 ^ s1409;
-  const SWord8  s1411 = (SWord8) (s1340 >> 8);
-  const SWord32 s1412 = table3[s1411];
-  const SWord32 s1413 = s1410 ^ s1412;
-  const SWord8  s1414 = (SWord8) s1354;
-  const SWord32 s1415 = table4[s1414];
-  const SWord32 s1416 = s1413 ^ s1415;
-  const SWord32 s1417 = s14 ^ s1416;
-  const SWord8  s1418 = (SWord8) (s1417 >> 8);
-  const SWord32 s1419 = table3[s1418];
-  const SWord32 s1420 = s1405 ^ s1419;
-  const SWord8  s1421 = (SWord8) (s1384 >> 24);
-  const SWord32 s1422 = table1[s1421];
-  const SWord8  s1423 = (SWord8) (s1340 >> 16);
-  const SWord32 s1424 = table2[s1423];
-  const SWord32 s1425 = s1422 ^ s1424;
-  const SWord8  s1426 = (SWord8) (s1354 >> 8);
-  const SWord32 s1427 = table3[s1426];
-  const SWord32 s1428 = s1425 ^ s1427;
-  const SWord8  s1429 = (SWord8) s1369;
-  const SWord32 s1430 = table4[s1429];
-  const SWord32 s1431 = s1428 ^ s1430;
-  const SWord32 s1432 = s13 ^ s1431;
-  const SWord8  s1433 = (SWord8) s1432;
-  const SWord32 s1434 = table4[s1433];
-  const SWord32 s1435 = s1420 ^ s1434;
-  const SWord32 s1436 = s16 ^ s1435;
-  const SWord8  s1437 = (SWord8) (s1436 >> 24);
-  const SWord32 s1438 = table1[s1437];
-  const SWord8  s1439 = (SWord8) (s1402 >> 24);
-  const SWord32 s1440 = table1[s1439];
-  const SWord8  s1441 = (SWord8) (s1417 >> 16);
-  const SWord32 s1442 = table2[s1441];
-  const SWord32 s1443 = s1440 ^ s1442;
-  const SWord8  s1444 = (SWord8) (s1432 >> 8);
-  const SWord32 s1445 = table3[s1444];
-  const SWord32 s1446 = s1443 ^ s1445;
-  const SWord8  s1447 = (SWord8) s1388;
-  const SWord32 s1448 = table4[s1447];
-  const SWord32 s1449 = s1446 ^ s1448;
-  const SWord32 s1450 = s19 ^ s1449;
-  const SWord8  s1451 = (SWord8) (s1450 >> 16);
-  const SWord32 s1452 = table2[s1451];
-  const SWord32 s1453 = s1438 ^ s1452;
-  const SWord8  s1454 = (SWord8) (s1417 >> 24);
-  const SWord32 s1455 = table1[s1454];
-  const SWord8  s1456 = (SWord8) (s1432 >> 16);
-  const SWord32 s1457 = table2[s1456];
-  const SWord32 s1458 = s1455 ^ s1457;
-  const SWord8  s1459 = (SWord8) (s1388 >> 8);
-  const SWord32 s1460 = table3[s1459];
-  const SWord32 s1461 = s1458 ^ s1460;
-  const SWord8  s1462 = (SWord8) s1402;
-  const SWord32 s1463 = table4[s1462];
-  const SWord32 s1464 = s1461 ^ s1463;
-  const SWord32 s1465 = s18 ^ s1464;
-  const SWord8  s1466 = (SWord8) (s1465 >> 8);
-  const SWord32 s1467 = table3[s1466];
-  const SWord32 s1468 = s1453 ^ s1467;
-  const SWord8  s1469 = (SWord8) (s1432 >> 24);
-  const SWord32 s1470 = table1[s1469];
-  const SWord8  s1471 = (SWord8) (s1388 >> 16);
-  const SWord32 s1472 = table2[s1471];
-  const SWord32 s1473 = s1470 ^ s1472;
-  const SWord8  s1474 = (SWord8) (s1402 >> 8);
-  const SWord32 s1475 = table3[s1474];
-  const SWord32 s1476 = s1473 ^ s1475;
-  const SWord8  s1477 = (SWord8) s1417;
-  const SWord32 s1478 = table4[s1477];
-  const SWord32 s1479 = s1476 ^ s1478;
-  const SWord32 s1480 = s17 ^ s1479;
-  const SWord8  s1481 = (SWord8) s1480;
-  const SWord32 s1482 = table4[s1481];
-  const SWord32 s1483 = s1468 ^ s1482;
-  const SWord32 s1484 = s20 ^ s1483;
-  const SWord8  s1485 = (SWord8) (s1484 >> 24);
-  const SWord32 s1486 = table1[s1485];
-  const SWord8  s1487 = (SWord8) (s1450 >> 24);
-  const SWord32 s1488 = table1[s1487];
-  const SWord8  s1489 = (SWord8) (s1465 >> 16);
-  const SWord32 s1490 = table2[s1489];
-  const SWord32 s1491 = s1488 ^ s1490;
-  const SWord8  s1492 = (SWord8) (s1480 >> 8);
-  const SWord32 s1493 = table3[s1492];
-  const SWord32 s1494 = s1491 ^ s1493;
-  const SWord8  s1495 = (SWord8) s1436;
-  const SWord32 s1496 = table4[s1495];
-  const SWord32 s1497 = s1494 ^ s1496;
-  const SWord32 s1498 = s23 ^ s1497;
-  const SWord8  s1499 = (SWord8) (s1498 >> 16);
-  const SWord32 s1500 = table2[s1499];
-  const SWord32 s1501 = s1486 ^ s1500;
-  const SWord8  s1502 = (SWord8) (s1465 >> 24);
-  const SWord32 s1503 = table1[s1502];
-  const SWord8  s1504 = (SWord8) (s1480 >> 16);
-  const SWord32 s1505 = table2[s1504];
-  const SWord32 s1506 = s1503 ^ s1505;
-  const SWord8  s1507 = (SWord8) (s1436 >> 8);
-  const SWord32 s1508 = table3[s1507];
-  const SWord32 s1509 = s1506 ^ s1508;
-  const SWord8  s1510 = (SWord8) s1450;
-  const SWord32 s1511 = table4[s1510];
-  const SWord32 s1512 = s1509 ^ s1511;
-  const SWord32 s1513 = s22 ^ s1512;
-  const SWord8  s1514 = (SWord8) (s1513 >> 8);
-  const SWord32 s1515 = table3[s1514];
-  const SWord32 s1516 = s1501 ^ s1515;
-  const SWord8  s1517 = (SWord8) (s1480 >> 24);
-  const SWord32 s1518 = table1[s1517];
-  const SWord8  s1519 = (SWord8) (s1436 >> 16);
-  const SWord32 s1520 = table2[s1519];
-  const SWord32 s1521 = s1518 ^ s1520;
-  const SWord8  s1522 = (SWord8) (s1450 >> 8);
-  const SWord32 s1523 = table3[s1522];
-  const SWord32 s1524 = s1521 ^ s1523;
-  const SWord8  s1525 = (SWord8) s1465;
-  const SWord32 s1526 = table4[s1525];
-  const SWord32 s1527 = s1524 ^ s1526;
-  const SWord32 s1528 = s21 ^ s1527;
-  const SWord8  s1529 = (SWord8) s1528;
-  const SWord32 s1530 = table4[s1529];
-  const SWord32 s1531 = s1516 ^ s1530;
-  const SWord32 s1532 = s24 ^ s1531;
-  const SWord8  s1533 = (SWord8) (s1532 >> 24);
-  const SWord32 s1534 = table1[s1533];
-  const SWord8  s1535 = (SWord8) (s1498 >> 24);
-  const SWord32 s1536 = table1[s1535];
-  const SWord8  s1537 = (SWord8) (s1513 >> 16);
-  const SWord32 s1538 = table2[s1537];
-  const SWord32 s1539 = s1536 ^ s1538;
-  const SWord8  s1540 = (SWord8) (s1528 >> 8);
-  const SWord32 s1541 = table3[s1540];
-  const SWord32 s1542 = s1539 ^ s1541;
-  const SWord8  s1543 = (SWord8) s1484;
-  const SWord32 s1544 = table4[s1543];
-  const SWord32 s1545 = s1542 ^ s1544;
-  const SWord32 s1546 = s27 ^ s1545;
-  const SWord8  s1547 = (SWord8) (s1546 >> 16);
-  const SWord32 s1548 = table2[s1547];
-  const SWord32 s1549 = s1534 ^ s1548;
-  const SWord8  s1550 = (SWord8) (s1513 >> 24);
-  const SWord32 s1551 = table1[s1550];
-  const SWord8  s1552 = (SWord8) (s1528 >> 16);
-  const SWord32 s1553 = table2[s1552];
-  const SWord32 s1554 = s1551 ^ s1553;
-  const SWord8  s1555 = (SWord8) (s1484 >> 8);
-  const SWord32 s1556 = table3[s1555];
-  const SWord32 s1557 = s1554 ^ s1556;
-  const SWord8  s1558 = (SWord8) s1498;
-  const SWord32 s1559 = table4[s1558];
-  const SWord32 s1560 = s1557 ^ s1559;
-  const SWord32 s1561 = s26 ^ s1560;
-  const SWord8  s1562 = (SWord8) (s1561 >> 8);
-  const SWord32 s1563 = table3[s1562];
-  const SWord32 s1564 = s1549 ^ s1563;
-  const SWord8  s1565 = (SWord8) (s1528 >> 24);
-  const SWord32 s1566 = table1[s1565];
-  const SWord8  s1567 = (SWord8) (s1484 >> 16);
-  const SWord32 s1568 = table2[s1567];
-  const SWord32 s1569 = s1566 ^ s1568;
-  const SWord8  s1570 = (SWord8) (s1498 >> 8);
-  const SWord32 s1571 = table3[s1570];
-  const SWord32 s1572 = s1569 ^ s1571;
-  const SWord8  s1573 = (SWord8) s1513;
-  const SWord32 s1574 = table4[s1573];
-  const SWord32 s1575 = s1572 ^ s1574;
-  const SWord32 s1576 = s25 ^ s1575;
-  const SWord8  s1577 = (SWord8) s1576;
-  const SWord32 s1578 = table4[s1577];
-  const SWord32 s1579 = s1564 ^ s1578;
-  const SWord32 s1580 = s28 ^ s1579;
-  const SWord8  s1581 = (SWord8) (s1580 >> 24);
-  const SWord32 s1582 = table1[s1581];
-  const SWord8  s1583 = (SWord8) (s1546 >> 24);
-  const SWord32 s1584 = table1[s1583];
-  const SWord8  s1585 = (SWord8) (s1561 >> 16);
-  const SWord32 s1586 = table2[s1585];
-  const SWord32 s1587 = s1584 ^ s1586;
-  const SWord8  s1588 = (SWord8) (s1576 >> 8);
-  const SWord32 s1589 = table3[s1588];
-  const SWord32 s1590 = s1587 ^ s1589;
-  const SWord8  s1591 = (SWord8) s1532;
-  const SWord32 s1592 = table4[s1591];
-  const SWord32 s1593 = s1590 ^ s1592;
-  const SWord32 s1594 = s31 ^ s1593;
-  const SWord8  s1595 = (SWord8) (s1594 >> 16);
-  const SWord32 s1596 = table2[s1595];
-  const SWord32 s1597 = s1582 ^ s1596;
-  const SWord8  s1598 = (SWord8) (s1561 >> 24);
-  const SWord32 s1599 = table1[s1598];
-  const SWord8  s1600 = (SWord8) (s1576 >> 16);
-  const SWord32 s1601 = table2[s1600];
-  const SWord32 s1602 = s1599 ^ s1601;
-  const SWord8  s1603 = (SWord8) (s1532 >> 8);
-  const SWord32 s1604 = table3[s1603];
-  const SWord32 s1605 = s1602 ^ s1604;
-  const SWord8  s1606 = (SWord8) s1546;
-  const SWord32 s1607 = table4[s1606];
-  const SWord32 s1608 = s1605 ^ s1607;
-  const SWord32 s1609 = s30 ^ s1608;
-  const SWord8  s1610 = (SWord8) (s1609 >> 8);
-  const SWord32 s1611 = table3[s1610];
-  const SWord32 s1612 = s1597 ^ s1611;
-  const SWord8  s1613 = (SWord8) (s1576 >> 24);
-  const SWord32 s1614 = table1[s1613];
-  const SWord8  s1615 = (SWord8) (s1532 >> 16);
-  const SWord32 s1616 = table2[s1615];
-  const SWord32 s1617 = s1614 ^ s1616;
-  const SWord8  s1618 = (SWord8) (s1546 >> 8);
-  const SWord32 s1619 = table3[s1618];
-  const SWord32 s1620 = s1617 ^ s1619;
-  const SWord8  s1621 = (SWord8) s1561;
-  const SWord32 s1622 = table4[s1621];
-  const SWord32 s1623 = s1620 ^ s1622;
-  const SWord32 s1624 = s29 ^ s1623;
-  const SWord8  s1625 = (SWord8) s1624;
-  const SWord32 s1626 = table4[s1625];
-  const SWord32 s1627 = s1612 ^ s1626;
-  const SWord32 s1628 = s32 ^ s1627;
-  const SWord8  s1629 = (SWord8) (s1628 >> 24);
-  const SWord32 s1630 = table1[s1629];
-  const SWord8  s1631 = (SWord8) (s1594 >> 24);
-  const SWord32 s1632 = table1[s1631];
-  const SWord8  s1633 = (SWord8) (s1609 >> 16);
-  const SWord32 s1634 = table2[s1633];
-  const SWord32 s1635 = s1632 ^ s1634;
-  const SWord8  s1636 = (SWord8) (s1624 >> 8);
-  const SWord32 s1637 = table3[s1636];
-  const SWord32 s1638 = s1635 ^ s1637;
-  const SWord8  s1639 = (SWord8) s1580;
-  const SWord32 s1640 = table4[s1639];
-  const SWord32 s1641 = s1638 ^ s1640;
-  const SWord32 s1642 = s35 ^ s1641;
-  const SWord8  s1643 = (SWord8) (s1642 >> 16);
-  const SWord32 s1644 = table2[s1643];
-  const SWord32 s1645 = s1630 ^ s1644;
-  const SWord8  s1646 = (SWord8) (s1609 >> 24);
-  const SWord32 s1647 = table1[s1646];
-  const SWord8  s1648 = (SWord8) (s1624 >> 16);
-  const SWord32 s1649 = table2[s1648];
-  const SWord32 s1650 = s1647 ^ s1649;
-  const SWord8  s1651 = (SWord8) (s1580 >> 8);
-  const SWord32 s1652 = table3[s1651];
-  const SWord32 s1653 = s1650 ^ s1652;
-  const SWord8  s1654 = (SWord8) s1594;
-  const SWord32 s1655 = table4[s1654];
-  const SWord32 s1656 = s1653 ^ s1655;
-  const SWord32 s1657 = s34 ^ s1656;
-  const SWord8  s1658 = (SWord8) (s1657 >> 8);
-  const SWord32 s1659 = table3[s1658];
-  const SWord32 s1660 = s1645 ^ s1659;
-  const SWord8  s1661 = (SWord8) (s1624 >> 24);
-  const SWord32 s1662 = table1[s1661];
-  const SWord8  s1663 = (SWord8) (s1580 >> 16);
-  const SWord32 s1664 = table2[s1663];
-  const SWord32 s1665 = s1662 ^ s1664;
-  const SWord8  s1666 = (SWord8) (s1594 >> 8);
-  const SWord32 s1667 = table3[s1666];
-  const SWord32 s1668 = s1665 ^ s1667;
-  const SWord8  s1669 = (SWord8) s1609;
-  const SWord32 s1670 = table4[s1669];
-  const SWord32 s1671 = s1668 ^ s1670;
-  const SWord32 s1672 = s33 ^ s1671;
-  const SWord8  s1673 = (SWord8) s1672;
-  const SWord32 s1674 = table4[s1673];
-  const SWord32 s1675 = s1660 ^ s1674;
-  const SWord32 s1676 = s36 ^ s1675;
-  const SWord8  s1677 = (SWord8) (s1676 >> 24);
-  const SWord32 s1678 = table1[s1677];
-  const SWord8  s1679 = (SWord8) (s1642 >> 24);
-  const SWord32 s1680 = table1[s1679];
-  const SWord8  s1681 = (SWord8) (s1657 >> 16);
-  const SWord32 s1682 = table2[s1681];
-  const SWord32 s1683 = s1680 ^ s1682;
-  const SWord8  s1684 = (SWord8) (s1672 >> 8);
-  const SWord32 s1685 = table3[s1684];
-  const SWord32 s1686 = s1683 ^ s1685;
-  const SWord8  s1687 = (SWord8) s1628;
-  const SWord32 s1688 = table4[s1687];
-  const SWord32 s1689 = s1686 ^ s1688;
-  const SWord32 s1690 = s39 ^ s1689;
-  const SWord8  s1691 = (SWord8) (s1690 >> 16);
-  const SWord32 s1692 = table2[s1691];
-  const SWord32 s1693 = s1678 ^ s1692;
-  const SWord8  s1694 = (SWord8) (s1657 >> 24);
-  const SWord32 s1695 = table1[s1694];
-  const SWord8  s1696 = (SWord8) (s1672 >> 16);
-  const SWord32 s1697 = table2[s1696];
-  const SWord32 s1698 = s1695 ^ s1697;
-  const SWord8  s1699 = (SWord8) (s1628 >> 8);
-  const SWord32 s1700 = table3[s1699];
-  const SWord32 s1701 = s1698 ^ s1700;
-  const SWord8  s1702 = (SWord8) s1642;
-  const SWord32 s1703 = table4[s1702];
-  const SWord32 s1704 = s1701 ^ s1703;
-  const SWord32 s1705 = s38 ^ s1704;
-  const SWord8  s1706 = (SWord8) (s1705 >> 8);
-  const SWord32 s1707 = table3[s1706];
-  const SWord32 s1708 = s1693 ^ s1707;
-  const SWord8  s1709 = (SWord8) (s1672 >> 24);
-  const SWord32 s1710 = table1[s1709];
-  const SWord8  s1711 = (SWord8) (s1628 >> 16);
-  const SWord32 s1712 = table2[s1711];
-  const SWord32 s1713 = s1710 ^ s1712;
-  const SWord8  s1714 = (SWord8) (s1642 >> 8);
-  const SWord32 s1715 = table3[s1714];
-  const SWord32 s1716 = s1713 ^ s1715;
-  const SWord8  s1717 = (SWord8) s1657;
-  const SWord32 s1718 = table4[s1717];
-  const SWord32 s1719 = s1716 ^ s1718;
-  const SWord32 s1720 = s37 ^ s1719;
-  const SWord8  s1721 = (SWord8) s1720;
-  const SWord32 s1722 = table4[s1721];
-  const SWord32 s1723 = s1708 ^ s1722;
-  const SWord32 s1724 = s40 ^ s1723;
-  const SWord8  s1725 = (SWord8) (s1724 >> 24);
-  const SWord8  s1726 = table0[s1725];
-  const SWord8  s1727 = (SWord8) (s1690 >> 24);
-  const SWord32 s1728 = table1[s1727];
-  const SWord8  s1729 = (SWord8) (s1705 >> 16);
-  const SWord32 s1730 = table2[s1729];
-  const SWord32 s1731 = s1728 ^ s1730;
-  const SWord8  s1732 = (SWord8) (s1720 >> 8);
-  const SWord32 s1733 = table3[s1732];
-  const SWord32 s1734 = s1731 ^ s1733;
-  const SWord8  s1735 = (SWord8) s1676;
-  const SWord32 s1736 = table4[s1735];
-  const SWord32 s1737 = s1734 ^ s1736;
-  const SWord32 s1738 = s43 ^ s1737;
-  const SWord8  s1739 = (SWord8) (s1738 >> 16);
-  const SWord8  s1740 = table0[s1739];
-  const SWord16 s1741 = (((SWord16) s1726) << 8) | ((SWord16) s1740);
-  const SWord8  s1742 = (SWord8) (s1705 >> 24);
-  const SWord32 s1743 = table1[s1742];
-  const SWord8  s1744 = (SWord8) (s1720 >> 16);
-  const SWord32 s1745 = table2[s1744];
-  const SWord32 s1746 = s1743 ^ s1745;
-  const SWord8  s1747 = (SWord8) (s1676 >> 8);
-  const SWord32 s1748 = table3[s1747];
-  const SWord32 s1749 = s1746 ^ s1748;
-  const SWord8  s1750 = (SWord8) s1690;
-  const SWord32 s1751 = table4[s1750];
-  const SWord32 s1752 = s1749 ^ s1751;
-  const SWord32 s1753 = s42 ^ s1752;
-  const SWord8  s1754 = (SWord8) (s1753 >> 8);
-  const SWord8  s1755 = table0[s1754];
-  const SWord8  s1756 = (SWord8) (s1720 >> 24);
-  const SWord32 s1757 = table1[s1756];
-  const SWord8  s1758 = (SWord8) (s1676 >> 16);
-  const SWord32 s1759 = table2[s1758];
-  const SWord32 s1760 = s1757 ^ s1759;
-  const SWord8  s1761 = (SWord8) (s1690 >> 8);
-  const SWord32 s1762 = table3[s1761];
-  const SWord32 s1763 = s1760 ^ s1762;
-  const SWord8  s1764 = (SWord8) s1705;
-  const SWord32 s1765 = table4[s1764];
-  const SWord32 s1766 = s1763 ^ s1765;
-  const SWord32 s1767 = s41 ^ s1766;
-  const SWord8  s1768 = (SWord8) s1767;
-  const SWord8  s1769 = table0[s1768];
-  const SWord16 s1770 = (((SWord16) s1755) << 8) | ((SWord16) s1769);
-  const SWord32 s1771 = (((SWord32) s1741) << 16) | ((SWord32) s1770);
-  const SWord32 s1772 = s44 ^ s1771;
-  const SWord8  s1773 = (SWord8) (s1767 >> 24);
-  const SWord8  s1774 = table0[s1773];
-  const SWord8  s1775 = (SWord8) (s1724 >> 16);
-  const SWord8  s1776 = table0[s1775];
-  const SWord16 s1777 = (((SWord16) s1774) << 8) | ((SWord16) s1776);
-  const SWord8  s1778 = (SWord8) (s1738 >> 8);
-  const SWord8  s1779 = table0[s1778];
-  const SWord8  s1780 = (SWord8) s1753;
-  const SWord8  s1781 = table0[s1780];
-  const SWord16 s1782 = (((SWord16) s1779) << 8) | ((SWord16) s1781);
-  const SWord32 s1783 = (((SWord32) s1777) << 16) | ((SWord32) s1782);
-  const SWord32 s1784 = s45 ^ s1783;
-  const SWord8  s1785 = (SWord8) (s1753 >> 24);
-  const SWord8  s1786 = table0[s1785];
-  const SWord8  s1787 = (SWord8) (s1767 >> 16);
-  const SWord8  s1788 = table0[s1787];
-  const SWord16 s1789 = (((SWord16) s1786) << 8) | ((SWord16) s1788);
-  const SWord8  s1790 = (SWord8) (s1724 >> 8);
-  const SWord8  s1791 = table0[s1790];
-  const SWord8  s1792 = (SWord8) s1738;
-  const SWord8  s1793 = table0[s1792];
-  const SWord16 s1794 = (((SWord16) s1791) << 8) | ((SWord16) s1793);
-  const SWord32 s1795 = (((SWord32) s1789) << 16) | ((SWord32) s1794);
-  const SWord32 s1796 = s46 ^ s1795;
-  const SWord8  s1797 = (SWord8) (s1738 >> 24);
-  const SWord8  s1798 = table0[s1797];
-  const SWord8  s1799 = (SWord8) (s1753 >> 16);
-  const SWord8  s1800 = table0[s1799];
-  const SWord16 s1801 = (((SWord16) s1798) << 8) | ((SWord16) s1800);
-  const SWord8  s1802 = (SWord8) (s1767 >> 8);
-  const SWord8  s1803 = table0[s1802];
-  const SWord8  s1804 = (SWord8) s1724;
-  const SWord8  s1805 = table0[s1804];
-  const SWord16 s1806 = (((SWord16) s1803) << 8) | ((SWord16) s1805);
-  const SWord32 s1807 = (((SWord32) s1801) << 16) | ((SWord32) s1806);
-  const SWord32 s1808 = s47 ^ s1807;
-
-  pt[0] = s1772;
-  pt[1] = s1784;
-  pt[2] = s1796;
-  pt[3] = s1808;
-}
-== END: "aes128BlockDecrypt.c" ==================
-== 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:
-	rm -f *.o
-
-veryclean: clean
-	rm -f aes128Lib.a aes128Lib_driver
+/* Exact bit-vector runtime. All arithmetic is modulo the declared width. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static inline SBV_CGEN_UNUSED SWord32 sbv_bv_u32_rotl(SWord32 a, uint64_t amount)
+{
+  amount %= 32;
+  if (amount == 0) return a;
+  return (SWord32) ((((uint64_t) (SWord32) a) << amount) | (((uint64_t) (SWord32) a) >> (32 - amount)));
+}
+
+static inline SBV_CGEN_UNUSED SWord32 sbv_bv_u32_rotr(SWord32 a, uint64_t amount)
+{
+  amount %= 32;
+  if (amount == 0) return a;
+  return (SWord32) ((((uint64_t) (SWord32) a) >> amount) | (((uint64_t) (SWord32) a) << (32 - amount)));
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_31_24_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 24)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_23_16_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 16)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord16 sbv_bv_join_u8_u8_u16(SWord8 high, SWord8 low)
+{
+  SWord16 r = (SWord16) 0; uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord16) ((uint64_t) r | ((uint64_t) (((((uint64_t) low) >> (i)) & UINT64_C(1)) != 0) << (i))); }
+  for (i = 0; i < 8; ++i) { r = (SWord16) ((uint64_t) r | ((uint64_t) (((((uint64_t) high) >> (i)) & UINT64_C(1)) != 0) << (i + 8))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_15_8_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 8)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_7_0_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord32 sbv_bv_join_u16_u16_u32(SWord16 high, SWord16 low)
+{
+  SWord32 r = (SWord32) 0; uint64_t i;
+  for (i = 0; i < 16; ++i) { r = (SWord32) ((uint64_t) r | ((uint64_t) (((((uint64_t) low) >> (i)) & UINT64_C(1)) != 0) << (i))); }
+  for (i = 0; i < 16; ++i) { r = (SWord32) ((uint64_t) r | ((uint64_t) (((((uint64_t) high) >> (i)) & UINT64_C(1)) != 0) << (i + 16))); }
+  return r;
+}
+
+
+void aes128KeySchedule(const SWord32 *sbv_input_0,
+                       SWord32 *sbv_output_0, SWord32 *sbv_output_1)
+{
+  const SWord32 s0 = sbv_input_0[0];
+  const SWord32 s1 = sbv_input_0[1];
+  const SWord32 s2 = sbv_input_0[2];
+  const SWord32 s3 = sbv_input_0[3];
+  const SWord32 s260 = sbv_bv_u32_rotl(s3, 8);
+  const SWord8  s261 = sbv_bv_extract_u32_31_24_u8(s260);
+  const SWord8  s264 = sbv_bv_extract_u32_23_16_u8(s260);
+  const SWord8  s267 = sbv_bv_extract_u32_15_8_u8(s260);
+  const SWord8  s269 = sbv_bv_extract_u32_7_0_u8(s260);
+        SWord8  s262;
+        SWord8  s263;
+        SWord8  s265;
+        SWord16 s266;
+        SWord8  s268;
+        SWord8  s270;
+        SWord16 s271;
+        SWord32 s272;
+        SWord32 s273;
+        SWord32 s274;
+        SWord32 s275;
+        SWord32 s276;
+        SWord32 s277;
+        SWord8  s278;
+        SWord8  s279;
+        SWord8  s280;
+        SWord8  s281;
+        SWord8  s282;
+        SWord16 s283;
+        SWord8  s284;
+        SWord8  s285;
+        SWord8  s286;
+        SWord8  s287;
+        SWord16 s288;
+        SWord32 s289;
+        SWord32 s290;
+        SWord32 s291;
+        SWord32 s292;
+        SWord32 s293;
+        SWord32 s294;
+        SWord8  s295;
+        SWord8  s296;
+        SWord8  s297;
+        SWord8  s298;
+        SWord8  s299;
+        SWord16 s300;
+        SWord8  s301;
+        SWord8  s302;
+        SWord8  s303;
+        SWord8  s304;
+        SWord16 s305;
+        SWord32 s306;
+        SWord32 s307;
+        SWord32 s308;
+        SWord32 s309;
+        SWord32 s310;
+        SWord32 s311;
+        SWord8  s312;
+        SWord8  s313;
+        SWord8  s314;
+        SWord8  s315;
+        SWord8  s316;
+        SWord16 s317;
+        SWord8  s318;
+        SWord8  s319;
+        SWord8  s320;
+        SWord8  s321;
+        SWord16 s322;
+        SWord32 s323;
+        SWord32 s324;
+        SWord32 s325;
+        SWord32 s326;
+        SWord32 s327;
+        SWord32 s328;
+        SWord8  s329;
+        SWord8  s330;
+        SWord8  s331;
+        SWord8  s332;
+        SWord8  s333;
+        SWord16 s334;
+        SWord8  s335;
+        SWord8  s336;
+        SWord8  s337;
+        SWord8  s338;
+        SWord16 s339;
+        SWord32 s340;
+        SWord32 s341;
+        SWord32 s342;
+        SWord32 s343;
+        SWord32 s344;
+        SWord32 s345;
+        SWord8  s346;
+        SWord8  s347;
+        SWord8  s348;
+        SWord8  s349;
+        SWord8  s350;
+        SWord16 s351;
+        SWord8  s352;
+        SWord8  s353;
+        SWord8  s354;
+        SWord8  s355;
+        SWord16 s356;
+        SWord32 s357;
+        SWord32 s358;
+        SWord32 s359;
+        SWord32 s360;
+        SWord32 s361;
+        SWord32 s362;
+        SWord8  s363;
+        SWord8  s364;
+        SWord8  s365;
+        SWord8  s366;
+        SWord8  s367;
+        SWord16 s368;
+        SWord8  s369;
+        SWord8  s370;
+        SWord8  s371;
+        SWord8  s372;
+        SWord16 s373;
+        SWord32 s374;
+        SWord32 s375;
+        SWord32 s376;
+        SWord32 s377;
+        SWord32 s378;
+        SWord32 s379;
+        SWord8  s380;
+        SWord8  s381;
+        SWord8  s382;
+        SWord8  s383;
+        SWord8  s384;
+        SWord16 s385;
+        SWord8  s386;
+        SWord8  s387;
+        SWord8  s388;
+        SWord8  s389;
+        SWord16 s390;
+        SWord32 s391;
+        SWord32 s392;
+        SWord32 s393;
+        SWord32 s394;
+        SWord32 s395;
+        SWord32 s396;
+        SWord8  s397;
+        SWord8  s398;
+        SWord8  s399;
+        SWord8  s400;
+        SWord8  s401;
+        SWord16 s402;
+        SWord8  s403;
+        SWord8  s404;
+        SWord8  s405;
+        SWord8  s406;
+        SWord16 s407;
+        SWord32 s408;
+        SWord32 s409;
+        SWord32 s410;
+        SWord32 s411;
+        SWord32 s412;
+        SWord32 s413;
+        SWord8  s414;
+        SWord8  s415;
+        SWord8  s416;
+        SWord8  s417;
+        SWord8  s418;
+        SWord16 s419;
+        SWord8  s420;
+        SWord8  s421;
+        SWord8  s422;
+        SWord8  s423;
+        SWord16 s424;
+        SWord32 s425;
+        SWord32 s426;
+        SWord32 s427;
+        SWord32 s428;
+        SWord32 s429;
+        SWord8  s430;
+        SWord8  s431;
+        SWord8  s432;
+        SWord8  s433;
+        SWord8  s434;
+        SWord8  s435;
+        SWord8  s436;
+        SWord8  s437;
+        SWord8  s438;
+        SWord8  s439;
+        SWord8  s440;
+        SWord8  s441;
+        SWord8  s442;
+        SWord8  s443;
+        SWord8  s444;
+        SWord8  s445;
+        SWord8  s446;
+        SWord8  s447;
+        SWord16 s448;
+        SWord8  s449;
+        SWord8  s450;
+        SWord8  s451;
+        SWord8  s452;
+        SWord8  s453;
+        SWord8  s454;
+        SWord8  s455;
+        SWord8  s456;
+        SWord8  s457;
+        SWord8  s458;
+        SWord8  s459;
+        SWord8  s460;
+        SWord8  s461;
+        SWord8  s462;
+        SWord16 s463;
+        SWord32 s464;
+        SWord8  s465;
+        SWord8  s466;
+        SWord8  s467;
+        SWord8  s468;
+        SWord8  s469;
+        SWord8  s470;
+        SWord8  s471;
+        SWord8  s472;
+        SWord8  s473;
+        SWord8  s474;
+        SWord8  s475;
+        SWord8  s476;
+        SWord8  s477;
+        SWord8  s478;
+        SWord8  s479;
+        SWord8  s480;
+        SWord8  s481;
+        SWord8  s482;
+        SWord16 s483;
+        SWord8  s484;
+        SWord8  s485;
+        SWord8  s486;
+        SWord8  s487;
+        SWord8  s488;
+        SWord8  s489;
+        SWord8  s490;
+        SWord8  s491;
+        SWord8  s492;
+        SWord8  s493;
+        SWord8  s494;
+        SWord8  s495;
+        SWord8  s496;
+        SWord8  s497;
+        SWord16 s498;
+        SWord32 s499;
+        SWord8  s500;
+        SWord8  s501;
+        SWord8  s502;
+        SWord8  s503;
+        SWord8  s504;
+        SWord8  s505;
+        SWord8  s506;
+        SWord8  s507;
+        SWord8  s508;
+        SWord8  s509;
+        SWord8  s510;
+        SWord8  s511;
+        SWord8  s512;
+        SWord8  s513;
+        SWord8  s514;
+        SWord8  s515;
+        SWord8  s516;
+        SWord8  s517;
+        SWord16 s518;
+        SWord8  s519;
+        SWord8  s520;
+        SWord8  s521;
+        SWord8  s522;
+        SWord8  s523;
+        SWord8  s524;
+        SWord8  s525;
+        SWord8  s526;
+        SWord8  s527;
+        SWord8  s528;
+        SWord8  s529;
+        SWord8  s530;
+        SWord8  s531;
+        SWord8  s532;
+        SWord16 s533;
+        SWord32 s534;
+        SWord8  s535;
+        SWord8  s536;
+        SWord8  s537;
+        SWord8  s538;
+        SWord8  s539;
+        SWord8  s540;
+        SWord8  s541;
+        SWord8  s542;
+        SWord8  s543;
+        SWord8  s544;
+        SWord8  s545;
+        SWord8  s546;
+        SWord8  s547;
+        SWord8  s548;
+        SWord8  s549;
+        SWord8  s550;
+        SWord8  s551;
+        SWord8  s552;
+        SWord16 s553;
+        SWord8  s554;
+        SWord8  s555;
+        SWord8  s556;
+        SWord8  s557;
+        SWord8  s558;
+        SWord8  s559;
+        SWord8  s560;
+        SWord8  s561;
+        SWord8  s562;
+        SWord8  s563;
+        SWord8  s564;
+        SWord8  s565;
+        SWord8  s566;
+        SWord8  s567;
+        SWord16 s568;
+        SWord32 s569;
+        SWord8  s570;
+        SWord8  s571;
+        SWord8  s572;
+        SWord8  s573;
+        SWord8  s574;
+        SWord8  s575;
+        SWord8  s576;
+        SWord8  s577;
+        SWord8  s578;
+        SWord8  s579;
+        SWord8  s580;
+        SWord8  s581;
+        SWord8  s582;
+        SWord8  s583;
+        SWord8  s584;
+        SWord8  s585;
+        SWord8  s586;
+        SWord8  s587;
+        SWord16 s588;
+        SWord8  s589;
+        SWord8  s590;
+        SWord8  s591;
+        SWord8  s592;
+        SWord8  s593;
+        SWord8  s594;
+        SWord8  s595;
+        SWord8  s596;
+        SWord8  s597;
+        SWord8  s598;
+        SWord8  s599;
+        SWord8  s600;
+        SWord8  s601;
+        SWord8  s602;
+        SWord16 s603;
+        SWord32 s604;
+        SWord8  s605;
+        SWord8  s606;
+        SWord8  s607;
+        SWord8  s608;
+        SWord8  s609;
+        SWord8  s610;
+        SWord8  s611;
+        SWord8  s612;
+        SWord8  s613;
+        SWord8  s614;
+        SWord8  s615;
+        SWord8  s616;
+        SWord8  s617;
+        SWord8  s618;
+        SWord8  s619;
+        SWord8  s620;
+        SWord8  s621;
+        SWord8  s622;
+        SWord16 s623;
+        SWord8  s624;
+        SWord8  s625;
+        SWord8  s626;
+        SWord8  s627;
+        SWord8  s628;
+        SWord8  s629;
+        SWord8  s630;
+        SWord8  s631;
+        SWord8  s632;
+        SWord8  s633;
+        SWord8  s634;
+        SWord8  s635;
+        SWord8  s636;
+        SWord8  s637;
+        SWord16 s638;
+        SWord32 s639;
+        SWord8  s640;
+        SWord8  s641;
+        SWord8  s642;
+        SWord8  s643;
+        SWord8  s644;
+        SWord8  s645;
+        SWord8  s646;
+        SWord8  s647;
+        SWord8  s648;
+        SWord8  s649;
+        SWord8  s650;
+        SWord8  s651;
+        SWord8  s652;
+        SWord8  s653;
+        SWord8  s654;
+        SWord8  s655;
+        SWord8  s656;
+        SWord8  s657;
+        SWord16 s658;
+        SWord8  s659;
+        SWord8  s660;
+        SWord8  s661;
+        SWord8  s662;
+        SWord8  s663;
+        SWord8  s664;
+        SWord8  s665;
+        SWord8  s666;
+        SWord8  s667;
+        SWord8  s668;
+        SWord8  s669;
+        SWord8  s670;
+        SWord8  s671;
+        SWord8  s672;
+        SWord16 s673;
+        SWord32 s674;
+        SWord8  s675;
+        SWord8  s676;
+        SWord8  s677;
+        SWord8  s678;
+        SWord8  s679;
+        SWord8  s680;
+        SWord8  s681;
+        SWord8  s682;
+        SWord8  s683;
+        SWord8  s684;
+        SWord8  s685;
+        SWord8  s686;
+        SWord8  s687;
+        SWord8  s688;
+        SWord8  s689;
+        SWord8  s690;
+        SWord8  s691;
+        SWord8  s692;
+        SWord16 s693;
+        SWord8  s694;
+        SWord8  s695;
+        SWord8  s696;
+        SWord8  s697;
+        SWord8  s698;
+        SWord8  s699;
+        SWord8  s700;
+        SWord8  s701;
+        SWord8  s702;
+        SWord8  s703;
+        SWord8  s704;
+        SWord8  s705;
+        SWord8  s706;
+        SWord8  s707;
+        SWord16 s708;
+        SWord32 s709;
+        SWord8  s710;
+        SWord8  s711;
+        SWord8  s712;
+        SWord8  s713;
+        SWord8  s714;
+        SWord8  s715;
+        SWord8  s716;
+        SWord8  s717;
+        SWord8  s718;
+        SWord8  s719;
+        SWord8  s720;
+        SWord8  s721;
+        SWord8  s722;
+        SWord8  s723;
+        SWord8  s724;
+        SWord8  s725;
+        SWord8  s726;
+        SWord8  s727;
+        SWord16 s728;
+        SWord8  s729;
+        SWord8  s730;
+        SWord8  s731;
+        SWord8  s732;
+        SWord8  s733;
+        SWord8  s734;
+        SWord8  s735;
+        SWord8  s736;
+        SWord8  s737;
+        SWord8  s738;
+        SWord8  s739;
+        SWord8  s740;
+        SWord8  s741;
+        SWord8  s742;
+        SWord16 s743;
+        SWord32 s744;
+        SWord8  s745;
+        SWord8  s746;
+        SWord8  s747;
+        SWord8  s748;
+        SWord8  s749;
+        SWord8  s750;
+        SWord8  s751;
+        SWord8  s752;
+        SWord8  s753;
+        SWord8  s754;
+        SWord8  s755;
+        SWord8  s756;
+        SWord8  s757;
+        SWord8  s758;
+        SWord8  s759;
+        SWord8  s760;
+        SWord8  s761;
+        SWord8  s762;
+        SWord16 s763;
+        SWord8  s764;
+        SWord8  s765;
+        SWord8  s766;
+        SWord8  s767;
+        SWord8  s768;
+        SWord8  s769;
+        SWord8  s770;
+        SWord8  s771;
+        SWord8  s772;
+        SWord8  s773;
+        SWord8  s774;
+        SWord8  s775;
+        SWord8  s776;
+        SWord8  s777;
+        SWord16 s778;
+        SWord32 s779;
+        SWord8  s780;
+        SWord8  s781;
+        SWord8  s782;
+        SWord8  s783;
+        SWord8  s784;
+        SWord8  s785;
+        SWord8  s786;
+        SWord8  s787;
+        SWord8  s788;
+        SWord8  s789;
+        SWord8  s790;
+        SWord8  s791;
+        SWord8  s792;
+        SWord8  s793;
+        SWord8  s794;
+        SWord8  s795;
+        SWord8  s796;
+        SWord8  s797;
+        SWord16 s798;
+        SWord8  s799;
+        SWord8  s800;
+        SWord8  s801;
+        SWord8  s802;
+        SWord8  s803;
+        SWord8  s804;
+        SWord8  s805;
+        SWord8  s806;
+        SWord8  s807;
+        SWord8  s808;
+        SWord8  s809;
+        SWord8  s810;
+        SWord8  s811;
+        SWord8  s812;
+        SWord16 s813;
+        SWord32 s814;
+        SWord8  s815;
+        SWord8  s816;
+        SWord8  s817;
+        SWord8  s818;
+        SWord8  s819;
+        SWord8  s820;
+        SWord8  s821;
+        SWord8  s822;
+        SWord8  s823;
+        SWord8  s824;
+        SWord8  s825;
+        SWord8  s826;
+        SWord8  s827;
+        SWord8  s828;
+        SWord8  s829;
+        SWord8  s830;
+        SWord8  s831;
+        SWord8  s832;
+        SWord16 s833;
+        SWord8  s834;
+        SWord8  s835;
+        SWord8  s836;
+        SWord8  s837;
+        SWord8  s838;
+        SWord8  s839;
+        SWord8  s840;
+        SWord8  s841;
+        SWord8  s842;
+        SWord8  s843;
+        SWord8  s844;
+        SWord8  s845;
+        SWord8  s846;
+        SWord8  s847;
+        SWord16 s848;
+        SWord32 s849;
+        SWord8  s850;
+        SWord8  s851;
+        SWord8  s852;
+        SWord8  s853;
+        SWord8  s854;
+        SWord8  s855;
+        SWord8  s856;
+        SWord8  s857;
+        SWord8  s858;
+        SWord8  s859;
+        SWord8  s860;
+        SWord8  s861;
+        SWord8  s862;
+        SWord8  s863;
+        SWord8  s864;
+        SWord8  s865;
+        SWord8  s866;
+        SWord8  s867;
+        SWord16 s868;
+        SWord8  s869;
+        SWord8  s870;
+        SWord8  s871;
+        SWord8  s872;
+        SWord8  s873;
+        SWord8  s874;
+        SWord8  s875;
+        SWord8  s876;
+        SWord8  s877;
+        SWord8  s878;
+        SWord8  s879;
+        SWord8  s880;
+        SWord8  s881;
+        SWord8  s882;
+        SWord16 s883;
+        SWord32 s884;
+        SWord8  s885;
+        SWord8  s886;
+        SWord8  s887;
+        SWord8  s888;
+        SWord8  s889;
+        SWord8  s890;
+        SWord8  s891;
+        SWord8  s892;
+        SWord8  s893;
+        SWord8  s894;
+        SWord8  s895;
+        SWord8  s896;
+        SWord8  s897;
+        SWord8  s898;
+        SWord8  s899;
+        SWord8  s900;
+        SWord8  s901;
+        SWord8  s902;
+        SWord16 s903;
+        SWord8  s904;
+        SWord8  s905;
+        SWord8  s906;
+        SWord8  s907;
+        SWord8  s908;
+        SWord8  s909;
+        SWord8  s910;
+        SWord8  s911;
+        SWord8  s912;
+        SWord8  s913;
+        SWord8  s914;
+        SWord8  s915;
+        SWord8  s916;
+        SWord8  s917;
+        SWord16 s918;
+        SWord32 s919;
+        SWord8  s920;
+        SWord8  s921;
+        SWord8  s922;
+        SWord8  s923;
+        SWord8  s924;
+        SWord8  s925;
+        SWord8  s926;
+        SWord8  s927;
+        SWord8  s928;
+        SWord8  s929;
+        SWord8  s930;
+        SWord8  s931;
+        SWord8  s932;
+        SWord8  s933;
+        SWord8  s934;
+        SWord8  s935;
+        SWord8  s936;
+        SWord8  s937;
+        SWord16 s938;
+        SWord8  s939;
+        SWord8  s940;
+        SWord8  s941;
+        SWord8  s942;
+        SWord8  s943;
+        SWord8  s944;
+        SWord8  s945;
+        SWord8  s946;
+        SWord8  s947;
+        SWord8  s948;
+        SWord8  s949;
+        SWord8  s950;
+        SWord8  s951;
+        SWord8  s952;
+        SWord16 s953;
+        SWord32 s954;
+        SWord8  s955;
+        SWord8  s956;
+        SWord8  s957;
+        SWord8  s958;
+        SWord8  s959;
+        SWord8  s960;
+        SWord8  s961;
+        SWord8  s962;
+        SWord8  s963;
+        SWord8  s964;
+        SWord8  s965;
+        SWord8  s966;
+        SWord8  s967;
+        SWord8  s968;
+        SWord8  s969;
+        SWord8  s970;
+        SWord8  s971;
+        SWord8  s972;
+        SWord16 s973;
+        SWord8  s974;
+        SWord8  s975;
+        SWord8  s976;
+        SWord8  s977;
+        SWord8  s978;
+        SWord8  s979;
+        SWord8  s980;
+        SWord8  s981;
+        SWord8  s982;
+        SWord8  s983;
+        SWord8  s984;
+        SWord8  s985;
+        SWord8  s986;
+        SWord8  s987;
+        SWord16 s988;
+        SWord32 s989;
+        SWord8  s990;
+        SWord8  s991;
+        SWord8  s992;
+        SWord8  s993;
+        SWord8  s994;
+        SWord8  s995;
+        SWord8  s996;
+        SWord8  s997;
+        SWord8  s998;
+        SWord8  s999;
+        SWord8  s1000;
+        SWord8  s1001;
+        SWord8  s1002;
+        SWord8  s1003;
+        SWord8  s1004;
+        SWord8  s1005;
+        SWord8  s1006;
+        SWord8  s1007;
+        SWord16 s1008;
+        SWord8  s1009;
+        SWord8  s1010;
+        SWord8  s1011;
+        SWord8  s1012;
+        SWord8  s1013;
+        SWord8  s1014;
+        SWord8  s1015;
+        SWord8  s1016;
+        SWord8  s1017;
+        SWord8  s1018;
+        SWord8  s1019;
+        SWord8  s1020;
+        SWord8  s1021;
+        SWord8  s1022;
+        SWord16 s1023;
+        SWord32 s1024;
+        SWord8  s1025;
+        SWord8  s1026;
+        SWord8  s1027;
+        SWord8  s1028;
+        SWord8  s1029;
+        SWord8  s1030;
+        SWord8  s1031;
+        SWord8  s1032;
+        SWord8  s1033;
+        SWord8  s1034;
+        SWord8  s1035;
+        SWord8  s1036;
+        SWord8  s1037;
+        SWord8  s1038;
+        SWord8  s1039;
+        SWord8  s1040;
+        SWord8  s1041;
+        SWord8  s1042;
+        SWord16 s1043;
+        SWord8  s1044;
+        SWord8  s1045;
+        SWord8  s1046;
+        SWord8  s1047;
+        SWord8  s1048;
+        SWord8  s1049;
+        SWord8  s1050;
+        SWord8  s1051;
+        SWord8  s1052;
+        SWord8  s1053;
+        SWord8  s1054;
+        SWord8  s1055;
+        SWord8  s1056;
+        SWord8  s1057;
+        SWord16 s1058;
+        SWord32 s1059;
+        SWord8  s1060;
+        SWord8  s1061;
+        SWord8  s1062;
+        SWord8  s1063;
+        SWord8  s1064;
+        SWord8  s1065;
+        SWord8  s1066;
+        SWord8  s1067;
+        SWord8  s1068;
+        SWord8  s1069;
+        SWord8  s1070;
+        SWord8  s1071;
+        SWord8  s1072;
+        SWord8  s1073;
+        SWord8  s1074;
+        SWord8  s1075;
+        SWord8  s1076;
+        SWord8  s1077;
+        SWord16 s1078;
+        SWord8  s1079;
+        SWord8  s1080;
+        SWord8  s1081;
+        SWord8  s1082;
+        SWord8  s1083;
+        SWord8  s1084;
+        SWord8  s1085;
+        SWord8  s1086;
+        SWord8  s1087;
+        SWord8  s1088;
+        SWord8  s1089;
+        SWord8  s1090;
+        SWord8  s1091;
+        SWord8  s1092;
+        SWord16 s1093;
+        SWord32 s1094;
+        SWord8  s1095;
+        SWord8  s1096;
+        SWord8  s1097;
+        SWord8  s1098;
+        SWord8  s1099;
+        SWord8  s1100;
+        SWord8  s1101;
+        SWord8  s1102;
+        SWord8  s1103;
+        SWord8  s1104;
+        SWord8  s1105;
+        SWord8  s1106;
+        SWord8  s1107;
+        SWord8  s1108;
+        SWord8  s1109;
+        SWord8  s1110;
+        SWord8  s1111;
+        SWord8  s1112;
+        SWord16 s1113;
+        SWord8  s1114;
+        SWord8  s1115;
+        SWord8  s1116;
+        SWord8  s1117;
+        SWord8  s1118;
+        SWord8  s1119;
+        SWord8  s1120;
+        SWord8  s1121;
+        SWord8  s1122;
+        SWord8  s1123;
+        SWord8  s1124;
+        SWord8  s1125;
+        SWord8  s1126;
+        SWord8  s1127;
+        SWord16 s1128;
+        SWord32 s1129;
+        SWord8  s1130;
+        SWord8  s1131;
+        SWord8  s1132;
+        SWord8  s1133;
+        SWord8  s1134;
+        SWord8  s1135;
+        SWord8  s1136;
+        SWord8  s1137;
+        SWord8  s1138;
+        SWord8  s1139;
+        SWord8  s1140;
+        SWord8  s1141;
+        SWord8  s1142;
+        SWord8  s1143;
+        SWord8  s1144;
+        SWord8  s1145;
+        SWord8  s1146;
+        SWord8  s1147;
+        SWord16 s1148;
+        SWord8  s1149;
+        SWord8  s1150;
+        SWord8  s1151;
+        SWord8  s1152;
+        SWord8  s1153;
+        SWord8  s1154;
+        SWord8  s1155;
+        SWord8  s1156;
+        SWord8  s1157;
+        SWord8  s1158;
+        SWord8  s1159;
+        SWord8  s1160;
+        SWord8  s1161;
+        SWord8  s1162;
+        SWord16 s1163;
+        SWord32 s1164;
+        SWord8  s1165;
+        SWord8  s1166;
+        SWord8  s1167;
+        SWord8  s1168;
+        SWord8  s1169;
+        SWord8  s1170;
+        SWord8  s1171;
+        SWord8  s1172;
+        SWord8  s1173;
+        SWord8  s1174;
+        SWord8  s1175;
+        SWord8  s1176;
+        SWord8  s1177;
+        SWord8  s1178;
+        SWord8  s1179;
+        SWord8  s1180;
+        SWord8  s1181;
+        SWord8  s1182;
+        SWord16 s1183;
+        SWord8  s1184;
+        SWord8  s1185;
+        SWord8  s1186;
+        SWord8  s1187;
+        SWord8  s1188;
+        SWord8  s1189;
+        SWord8  s1190;
+        SWord8  s1191;
+        SWord8  s1192;
+        SWord8  s1193;
+        SWord8  s1194;
+        SWord8  s1195;
+        SWord8  s1196;
+        SWord8  s1197;
+        SWord16 s1198;
+        SWord32 s1199;
+        SWord8  s1200;
+        SWord8  s1201;
+        SWord8  s1202;
+        SWord8  s1203;
+        SWord8  s1204;
+        SWord8  s1205;
+        SWord8  s1206;
+        SWord8  s1207;
+        SWord8  s1208;
+        SWord8  s1209;
+        SWord8  s1210;
+        SWord8  s1211;
+        SWord8  s1212;
+        SWord8  s1213;
+        SWord8  s1214;
+        SWord8  s1215;
+        SWord8  s1216;
+        SWord8  s1217;
+        SWord16 s1218;
+        SWord8  s1219;
+        SWord8  s1220;
+        SWord8  s1221;
+        SWord8  s1222;
+        SWord8  s1223;
+        SWord8  s1224;
+        SWord8  s1225;
+        SWord8  s1226;
+        SWord8  s1227;
+        SWord8  s1228;
+        SWord8  s1229;
+        SWord8  s1230;
+        SWord8  s1231;
+        SWord8  s1232;
+        SWord16 s1233;
+        SWord32 s1234;
+        SWord8  s1235;
+        SWord8  s1236;
+        SWord8  s1237;
+        SWord8  s1238;
+        SWord8  s1239;
+        SWord8  s1240;
+        SWord8  s1241;
+        SWord8  s1242;
+        SWord8  s1243;
+        SWord8  s1244;
+        SWord8  s1245;
+        SWord8  s1246;
+        SWord8  s1247;
+        SWord8  s1248;
+        SWord8  s1249;
+        SWord8  s1250;
+        SWord8  s1251;
+        SWord8  s1252;
+        SWord16 s1253;
+        SWord8  s1254;
+        SWord8  s1255;
+        SWord8  s1256;
+        SWord8  s1257;
+        SWord8  s1258;
+        SWord8  s1259;
+        SWord8  s1260;
+        SWord8  s1261;
+        SWord8  s1262;
+        SWord8  s1263;
+        SWord8  s1264;
+        SWord8  s1265;
+        SWord8  s1266;
+        SWord8  s1267;
+        SWord16 s1268;
+        SWord32 s1269;
+        SWord8  s1270;
+        SWord8  s1271;
+        SWord8  s1272;
+        SWord8  s1273;
+        SWord8  s1274;
+        SWord8  s1275;
+        SWord8  s1276;
+        SWord8  s1277;
+        SWord8  s1278;
+        SWord8  s1279;
+        SWord8  s1280;
+        SWord8  s1281;
+        SWord8  s1282;
+        SWord8  s1283;
+        SWord8  s1284;
+        SWord8  s1285;
+        SWord8  s1286;
+        SWord8  s1287;
+        SWord16 s1288;
+        SWord8  s1289;
+        SWord8  s1290;
+        SWord8  s1291;
+        SWord8  s1292;
+        SWord8  s1293;
+        SWord8  s1294;
+        SWord8  s1295;
+        SWord8  s1296;
+        SWord8  s1297;
+        SWord8  s1298;
+        SWord8  s1299;
+        SWord8  s1300;
+        SWord8  s1301;
+        SWord8  s1302;
+        SWord16 s1303;
+        SWord32 s1304;
+        SWord8  s1305;
+        SWord8  s1306;
+        SWord8  s1307;
+        SWord8  s1308;
+        SWord8  s1309;
+        SWord8  s1310;
+        SWord8  s1311;
+        SWord8  s1312;
+        SWord8  s1313;
+        SWord8  s1314;
+        SWord8  s1315;
+        SWord8  s1316;
+        SWord8  s1317;
+        SWord8  s1318;
+        SWord8  s1319;
+        SWord8  s1320;
+        SWord8  s1321;
+        SWord8  s1322;
+        SWord16 s1323;
+        SWord8  s1324;
+        SWord8  s1325;
+        SWord8  s1326;
+        SWord8  s1327;
+        SWord8  s1328;
+        SWord8  s1329;
+        SWord8  s1330;
+        SWord8  s1331;
+        SWord8  s1332;
+        SWord8  s1333;
+        SWord8  s1334;
+        SWord8  s1335;
+        SWord8  s1336;
+        SWord8  s1337;
+        SWord16 s1338;
+        SWord32 s1339;
+        SWord8  s1340;
+        SWord8  s1341;
+        SWord8  s1342;
+        SWord8  s1343;
+        SWord8  s1344;
+        SWord8  s1345;
+        SWord8  s1346;
+        SWord8  s1347;
+        SWord8  s1348;
+        SWord8  s1349;
+        SWord8  s1350;
+        SWord8  s1351;
+        SWord8  s1352;
+        SWord8  s1353;
+        SWord8  s1354;
+        SWord8  s1355;
+        SWord8  s1356;
+        SWord8  s1357;
+        SWord16 s1358;
+        SWord8  s1359;
+        SWord8  s1360;
+        SWord8  s1361;
+        SWord8  s1362;
+        SWord8  s1363;
+        SWord8  s1364;
+        SWord8  s1365;
+        SWord8  s1366;
+        SWord8  s1367;
+        SWord8  s1368;
+        SWord8  s1369;
+        SWord8  s1370;
+        SWord8  s1371;
+        SWord8  s1372;
+        SWord16 s1373;
+        SWord32 s1374;
+        SWord8  s1375;
+        SWord8  s1376;
+        SWord8  s1377;
+        SWord8  s1378;
+        SWord8  s1379;
+        SWord8  s1380;
+        SWord8  s1381;
+        SWord8  s1382;
+        SWord8  s1383;
+        SWord8  s1384;
+        SWord8  s1385;
+        SWord8  s1386;
+        SWord8  s1387;
+        SWord8  s1388;
+        SWord8  s1389;
+        SWord8  s1390;
+        SWord8  s1391;
+        SWord8  s1392;
+        SWord16 s1393;
+        SWord8  s1394;
+        SWord8  s1395;
+        SWord8  s1396;
+        SWord8  s1397;
+        SWord8  s1398;
+        SWord8  s1399;
+        SWord8  s1400;
+        SWord8  s1401;
+        SWord8  s1402;
+        SWord8  s1403;
+        SWord8  s1404;
+        SWord8  s1405;
+        SWord8  s1406;
+        SWord8  s1407;
+        SWord16 s1408;
+        SWord32 s1409;
+        SWord8  s1410;
+        SWord8  s1411;
+        SWord8  s1412;
+        SWord8  s1413;
+        SWord8  s1414;
+        SWord8  s1415;
+        SWord8  s1416;
+        SWord8  s1417;
+        SWord8  s1418;
+        SWord8  s1419;
+        SWord8  s1420;
+        SWord8  s1421;
+        SWord8  s1422;
+        SWord8  s1423;
+        SWord8  s1424;
+        SWord8  s1425;
+        SWord8  s1426;
+        SWord8  s1427;
+        SWord16 s1428;
+        SWord8  s1429;
+        SWord8  s1430;
+        SWord8  s1431;
+        SWord8  s1432;
+        SWord8  s1433;
+        SWord8  s1434;
+        SWord8  s1435;
+        SWord8  s1436;
+        SWord8  s1437;
+        SWord8  s1438;
+        SWord8  s1439;
+        SWord8  s1440;
+        SWord8  s1441;
+        SWord8  s1442;
+        SWord16 s1443;
+        SWord32 s1444;
+        SWord8  s1445;
+        SWord8  s1446;
+        SWord8  s1447;
+        SWord8  s1448;
+        SWord8  s1449;
+        SWord8  s1450;
+        SWord8  s1451;
+        SWord8  s1452;
+        SWord8  s1453;
+        SWord8  s1454;
+        SWord8  s1455;
+        SWord8  s1456;
+        SWord8  s1457;
+        SWord8  s1458;
+        SWord8  s1459;
+        SWord8  s1460;
+        SWord8  s1461;
+        SWord8  s1462;
+        SWord16 s1463;
+        SWord8  s1464;
+        SWord8  s1465;
+        SWord8  s1466;
+        SWord8  s1467;
+        SWord8  s1468;
+        SWord8  s1469;
+        SWord8  s1470;
+        SWord8  s1471;
+        SWord8  s1472;
+        SWord8  s1473;
+        SWord8  s1474;
+        SWord8  s1475;
+        SWord8  s1476;
+        SWord8  s1477;
+        SWord16 s1478;
+        SWord32 s1479;
+        SWord8  s1480;
+        SWord8  s1481;
+        SWord8  s1482;
+        SWord8  s1483;
+        SWord8  s1484;
+        SWord8  s1485;
+        SWord8  s1486;
+        SWord8  s1487;
+        SWord8  s1488;
+        SWord8  s1489;
+        SWord8  s1490;
+        SWord8  s1491;
+        SWord8  s1492;
+        SWord8  s1493;
+        SWord8  s1494;
+        SWord8  s1495;
+        SWord8  s1496;
+        SWord8  s1497;
+        SWord16 s1498;
+        SWord8  s1499;
+        SWord8  s1500;
+        SWord8  s1501;
+        SWord8  s1502;
+        SWord8  s1503;
+        SWord8  s1504;
+        SWord8  s1505;
+        SWord8  s1506;
+        SWord8  s1507;
+        SWord8  s1508;
+        SWord8  s1509;
+        SWord8  s1510;
+        SWord8  s1511;
+        SWord8  s1512;
+        SWord16 s1513;
+        SWord32 s1514;
+        SWord8  s1515;
+        SWord8  s1516;
+        SWord8  s1517;
+        SWord8  s1518;
+        SWord8  s1519;
+        SWord8  s1520;
+        SWord8  s1521;
+        SWord8  s1522;
+        SWord8  s1523;
+        SWord8  s1524;
+        SWord8  s1525;
+        SWord8  s1526;
+        SWord8  s1527;
+        SWord8  s1528;
+        SWord8  s1529;
+        SWord8  s1530;
+        SWord8  s1531;
+        SWord8  s1532;
+        SWord16 s1533;
+        SWord8  s1534;
+        SWord8  s1535;
+        SWord8  s1536;
+        SWord8  s1537;
+        SWord8  s1538;
+        SWord8  s1539;
+        SWord8  s1540;
+        SWord8  s1541;
+        SWord8  s1542;
+        SWord8  s1543;
+        SWord8  s1544;
+        SWord8  s1545;
+        SWord8  s1546;
+        SWord8  s1547;
+        SWord16 s1548;
+        SWord32 s1549;
+        SWord8  s1550;
+        SWord8  s1551;
+        SWord8  s1552;
+        SWord8  s1553;
+        SWord8  s1554;
+        SWord8  s1555;
+        SWord8  s1556;
+        SWord8  s1557;
+        SWord8  s1558;
+        SWord8  s1559;
+        SWord8  s1560;
+        SWord8  s1561;
+        SWord8  s1562;
+        SWord8  s1563;
+        SWord8  s1564;
+        SWord8  s1565;
+        SWord8  s1566;
+        SWord8  s1567;
+        SWord16 s1568;
+        SWord8  s1569;
+        SWord8  s1570;
+        SWord8  s1571;
+        SWord8  s1572;
+        SWord8  s1573;
+        SWord8  s1574;
+        SWord8  s1575;
+        SWord8  s1576;
+        SWord8  s1577;
+        SWord8  s1578;
+        SWord8  s1579;
+        SWord8  s1580;
+        SWord8  s1581;
+        SWord8  s1582;
+        SWord16 s1583;
+        SWord32 s1584;
+        SWord8  s1585;
+        SWord8  s1586;
+        SWord8  s1587;
+        SWord8  s1588;
+        SWord8  s1589;
+        SWord8  s1590;
+        SWord8  s1591;
+        SWord8  s1592;
+        SWord8  s1593;
+        SWord8  s1594;
+        SWord8  s1595;
+        SWord8  s1596;
+        SWord8  s1597;
+        SWord8  s1598;
+        SWord8  s1599;
+        SWord8  s1600;
+        SWord8  s1601;
+        SWord8  s1602;
+        SWord16 s1603;
+        SWord8  s1604;
+        SWord8  s1605;
+        SWord8  s1606;
+        SWord8  s1607;
+        SWord8  s1608;
+        SWord8  s1609;
+        SWord8  s1610;
+        SWord8  s1611;
+        SWord8  s1612;
+        SWord8  s1613;
+        SWord8  s1614;
+        SWord8  s1615;
+        SWord8  s1616;
+        SWord8  s1617;
+        SWord16 s1618;
+        SWord32 s1619;
+        SWord8  s1620;
+        SWord8  s1621;
+        SWord8  s1622;
+        SWord8  s1623;
+        SWord8  s1624;
+        SWord8  s1625;
+        SWord8  s1626;
+        SWord8  s1627;
+        SWord8  s1628;
+        SWord8  s1629;
+        SWord8  s1630;
+        SWord8  s1631;
+        SWord8  s1632;
+        SWord8  s1633;
+        SWord8  s1634;
+        SWord8  s1635;
+        SWord8  s1636;
+        SWord8  s1637;
+        SWord16 s1638;
+        SWord8  s1639;
+        SWord8  s1640;
+        SWord8  s1641;
+        SWord8  s1642;
+        SWord8  s1643;
+        SWord8  s1644;
+        SWord8  s1645;
+        SWord8  s1646;
+        SWord8  s1647;
+        SWord8  s1648;
+        SWord8  s1649;
+        SWord8  s1650;
+        SWord8  s1651;
+        SWord8  s1652;
+        SWord16 s1653;
+        SWord32 s1654;
+        SWord8  s1655;
+        SWord8  s1656;
+        SWord8  s1657;
+        SWord8  s1658;
+        SWord8  s1659;
+        SWord8  s1660;
+        SWord8  s1661;
+        SWord8  s1662;
+        SWord8  s1663;
+        SWord8  s1664;
+        SWord8  s1665;
+        SWord8  s1666;
+        SWord8  s1667;
+        SWord8  s1668;
+        SWord8  s1669;
+        SWord8  s1670;
+        SWord8  s1671;
+        SWord8  s1672;
+        SWord16 s1673;
+        SWord8  s1674;
+        SWord8  s1675;
+        SWord8  s1676;
+        SWord8  s1677;
+        SWord8  s1678;
+        SWord8  s1679;
+        SWord8  s1680;
+        SWord8  s1681;
+        SWord8  s1682;
+        SWord8  s1683;
+        SWord8  s1684;
+        SWord8  s1685;
+        SWord8  s1686;
+        SWord8  s1687;
+        SWord16 s1688;
+        SWord32 s1689;
+  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
+  };
+  s262 = table0[s261];
+  s263 = 1 ^ s262;
+  s265 = table0[s264];
+  s266 = sbv_bv_join_u8_u8_u16(s263, s265);
+  s268 = table0[s267];
+  s270 = table0[s269];
+  s271 = sbv_bv_join_u8_u8_u16(s268, s270);
+  s272 = sbv_bv_join_u16_u16_u32(s266, s271);
+  s273 = s0 ^ s272;
+  s274 = s1 ^ s273;
+  s275 = s2 ^ s274;
+  s276 = s3 ^ s275;
+  s277 = sbv_bv_u32_rotl(s276, 8);
+  s278 = sbv_bv_extract_u32_31_24_u8(s277);
+  s279 = table0[s278];
+  s280 = 2 ^ s279;
+  s281 = sbv_bv_extract_u32_23_16_u8(s277);
+  s282 = table0[s281];
+  s283 = sbv_bv_join_u8_u8_u16(s280, s282);
+  s284 = sbv_bv_extract_u32_15_8_u8(s277);
+  s285 = table0[s284];
+  s286 = sbv_bv_extract_u32_7_0_u8(s277);
+  s287 = table0[s286];
+  s288 = sbv_bv_join_u8_u8_u16(s285, s287);
+  s289 = sbv_bv_join_u16_u16_u32(s283, s288);
+  s290 = s273 ^ s289;
+  s291 = s274 ^ s290;
+  s292 = s275 ^ s291;
+  s293 = s276 ^ s292;
+  s294 = sbv_bv_u32_rotl(s293, 8);
+  s295 = sbv_bv_extract_u32_31_24_u8(s294);
+  s296 = table0[s295];
+  s297 = 4 ^ s296;
+  s298 = sbv_bv_extract_u32_23_16_u8(s294);
+  s299 = table0[s298];
+  s300 = sbv_bv_join_u8_u8_u16(s297, s299);
+  s301 = sbv_bv_extract_u32_15_8_u8(s294);
+  s302 = table0[s301];
+  s303 = sbv_bv_extract_u32_7_0_u8(s294);
+  s304 = table0[s303];
+  s305 = sbv_bv_join_u8_u8_u16(s302, s304);
+  s306 = sbv_bv_join_u16_u16_u32(s300, s305);
+  s307 = s290 ^ s306;
+  s308 = s291 ^ s307;
+  s309 = s292 ^ s308;
+  s310 = s293 ^ s309;
+  s311 = sbv_bv_u32_rotl(s310, 8);
+  s312 = sbv_bv_extract_u32_31_24_u8(s311);
+  s313 = table0[s312];
+  s314 = 8 ^ s313;
+  s315 = sbv_bv_extract_u32_23_16_u8(s311);
+  s316 = table0[s315];
+  s317 = sbv_bv_join_u8_u8_u16(s314, s316);
+  s318 = sbv_bv_extract_u32_15_8_u8(s311);
+  s319 = table0[s318];
+  s320 = sbv_bv_extract_u32_7_0_u8(s311);
+  s321 = table0[s320];
+  s322 = sbv_bv_join_u8_u8_u16(s319, s321);
+  s323 = sbv_bv_join_u16_u16_u32(s317, s322);
+  s324 = s307 ^ s323;
+  s325 = s308 ^ s324;
+  s326 = s309 ^ s325;
+  s327 = s310 ^ s326;
+  s328 = sbv_bv_u32_rotl(s327, 8);
+  s329 = sbv_bv_extract_u32_31_24_u8(s328);
+  s330 = table0[s329];
+  s331 = 16 ^ s330;
+  s332 = sbv_bv_extract_u32_23_16_u8(s328);
+  s333 = table0[s332];
+  s334 = sbv_bv_join_u8_u8_u16(s331, s333);
+  s335 = sbv_bv_extract_u32_15_8_u8(s328);
+  s336 = table0[s335];
+  s337 = sbv_bv_extract_u32_7_0_u8(s328);
+  s338 = table0[s337];
+  s339 = sbv_bv_join_u8_u8_u16(s336, s338);
+  s340 = sbv_bv_join_u16_u16_u32(s334, s339);
+  s341 = s324 ^ s340;
+  s342 = s325 ^ s341;
+  s343 = s326 ^ s342;
+  s344 = s327 ^ s343;
+  s345 = sbv_bv_u32_rotl(s344, 8);
+  s346 = sbv_bv_extract_u32_31_24_u8(s345);
+  s347 = table0[s346];
+  s348 = 32 ^ s347;
+  s349 = sbv_bv_extract_u32_23_16_u8(s345);
+  s350 = table0[s349];
+  s351 = sbv_bv_join_u8_u8_u16(s348, s350);
+  s352 = sbv_bv_extract_u32_15_8_u8(s345);
+  s353 = table0[s352];
+  s354 = sbv_bv_extract_u32_7_0_u8(s345);
+  s355 = table0[s354];
+  s356 = sbv_bv_join_u8_u8_u16(s353, s355);
+  s357 = sbv_bv_join_u16_u16_u32(s351, s356);
+  s358 = s341 ^ s357;
+  s359 = s342 ^ s358;
+  s360 = s343 ^ s359;
+  s361 = s344 ^ s360;
+  s362 = sbv_bv_u32_rotl(s361, 8);
+  s363 = sbv_bv_extract_u32_31_24_u8(s362);
+  s364 = table0[s363];
+  s365 = 64 ^ s364;
+  s366 = sbv_bv_extract_u32_23_16_u8(s362);
+  s367 = table0[s366];
+  s368 = sbv_bv_join_u8_u8_u16(s365, s367);
+  s369 = sbv_bv_extract_u32_15_8_u8(s362);
+  s370 = table0[s369];
+  s371 = sbv_bv_extract_u32_7_0_u8(s362);
+  s372 = table0[s371];
+  s373 = sbv_bv_join_u8_u8_u16(s370, s372);
+  s374 = sbv_bv_join_u16_u16_u32(s368, s373);
+  s375 = s358 ^ s374;
+  s376 = s359 ^ s375;
+  s377 = s360 ^ s376;
+  s378 = s361 ^ s377;
+  s379 = sbv_bv_u32_rotl(s378, 8);
+  s380 = sbv_bv_extract_u32_31_24_u8(s379);
+  s381 = table0[s380];
+  s382 = 128 ^ s381;
+  s383 = sbv_bv_extract_u32_23_16_u8(s379);
+  s384 = table0[s383];
+  s385 = sbv_bv_join_u8_u8_u16(s382, s384);
+  s386 = sbv_bv_extract_u32_15_8_u8(s379);
+  s387 = table0[s386];
+  s388 = sbv_bv_extract_u32_7_0_u8(s379);
+  s389 = table0[s388];
+  s390 = sbv_bv_join_u8_u8_u16(s387, s389);
+  s391 = sbv_bv_join_u16_u16_u32(s385, s390);
+  s392 = s375 ^ s391;
+  s393 = s376 ^ s392;
+  s394 = s377 ^ s393;
+  s395 = s378 ^ s394;
+  s396 = sbv_bv_u32_rotl(s395, 8);
+  s397 = sbv_bv_extract_u32_31_24_u8(s396);
+  s398 = table0[s397];
+  s399 = 27 ^ s398;
+  s400 = sbv_bv_extract_u32_23_16_u8(s396);
+  s401 = table0[s400];
+  s402 = sbv_bv_join_u8_u8_u16(s399, s401);
+  s403 = sbv_bv_extract_u32_15_8_u8(s396);
+  s404 = table0[s403];
+  s405 = sbv_bv_extract_u32_7_0_u8(s396);
+  s406 = table0[s405];
+  s407 = sbv_bv_join_u8_u8_u16(s404, s406);
+  s408 = sbv_bv_join_u16_u16_u32(s402, s407);
+  s409 = s392 ^ s408;
+  s410 = s393 ^ s409;
+  s411 = s394 ^ s410;
+  s412 = s395 ^ s411;
+  s413 = sbv_bv_u32_rotl(s412, 8);
+  s414 = sbv_bv_extract_u32_31_24_u8(s413);
+  s415 = table0[s414];
+  s416 = 54 ^ s415;
+  s417 = sbv_bv_extract_u32_23_16_u8(s413);
+  s418 = table0[s417];
+  s419 = sbv_bv_join_u8_u8_u16(s416, s418);
+  s420 = sbv_bv_extract_u32_15_8_u8(s413);
+  s421 = table0[s420];
+  s422 = sbv_bv_extract_u32_7_0_u8(s413);
+  s423 = table0[s422];
+  s424 = sbv_bv_join_u8_u8_u16(s421, s423);
+  s425 = sbv_bv_join_u16_u16_u32(s419, s424);
+  s426 = s409 ^ s425;
+  s427 = s410 ^ s426;
+  s428 = s411 ^ s427;
+  s429 = s412 ^ s428;
+  s430 = sbv_bv_extract_u32_31_24_u8(s409);
+  static const SWord8 table1[] = {
+        0,  14,  28,  18,  56,  54,  36,  42, 112, 126, 108,  98,  72,
+       70,  84,  90, 224, 238, 252, 242, 216, 214, 196, 202, 144, 158,
+      140, 130, 168, 166, 180, 186, 219, 213, 199, 201, 227, 237, 255,
+      241, 171, 165, 183, 185, 147, 157, 143, 129,  59,  53,  39,  41,
+        3,  13,  31,  17,  75,  69,  87,  89, 115, 125, 111,  97, 173,
+      163, 177, 191, 149, 155, 137, 135, 221, 211, 193, 207, 229, 235,
+      249, 247,  77,  67,  81,  95, 117, 123, 105, 103,  61,  51,  33,
+       47,   5,  11,  25,  23, 118, 120, 106, 100,  78,  64,  82,  92,
+        6,   8,  26,  20,  62,  48,  34,  44, 150, 152, 138, 132, 174,
+      160, 178, 188, 230, 232, 250, 244, 222, 208, 194, 204,  65,  79,
+       93,  83, 121, 119, 101, 107,  49,  63,  45,  35,   9,   7,  21,
+       27, 161, 175, 189, 179, 153, 151, 133, 139, 209, 223, 205, 195,
+      233, 231, 245, 251, 154, 148, 134, 136, 162, 172, 190, 176, 234,
+      228, 246, 248, 210, 220, 206, 192, 122, 116, 102, 104,  66,  76,
+       94,  80,  10,   4,  22,  24,  50,  60,  46,  32, 236, 226, 240,
+      254, 212, 218, 200, 198, 156, 146, 128, 142, 164, 170, 184, 182,
+       12,   2,  16,  30,  52,  58,  40,  38, 124, 114,  96, 110,  68,
+       74,  88,  86,  55,  57,  43,  37,  15,   1,  19,  29,  71,  73,
+       91,  85, 127, 113,  99, 109, 215, 217, 203, 197, 239, 225, 243,
+      253, 167, 169, 187, 181, 159, 145, 131, 141
+  };
+  s431 = table1[s430];
+  s432 = sbv_bv_extract_u32_23_16_u8(s409);
+  static const SWord8 table2[] = {
+        0,  11,  22,  29,  44,  39,  58,  49,  88,  83,  78,  69, 116,
+      127,  98, 105, 176, 187, 166, 173, 156, 151, 138, 129, 232, 227,
+      254, 245, 196, 207, 210, 217, 123, 112, 109, 102,  87,  92,  65,
+       74,  35,  40,  53,  62,  15,   4,  25,  18, 203, 192, 221, 214,
+      231, 236, 241, 250, 147, 152, 133, 142, 191, 180, 169, 162, 246,
+      253, 224, 235, 218, 209, 204, 199, 174, 165, 184, 179, 130, 137,
+      148, 159,  70,  77,  80,  91, 106,  97, 124, 119,  30,  21,   8,
+        3,  50,  57,  36,  47, 141, 134, 155, 144, 161, 170, 183, 188,
+      213, 222, 195, 200, 249, 242, 239, 228,  61,  54,  43,  32,  17,
+       26,   7,  12, 101, 110, 115, 120,  73,  66,  95,  84, 247, 252,
+      225, 234, 219, 208, 205, 198, 175, 164, 185, 178, 131, 136, 149,
+      158,  71,  76,  81,  90, 107,  96, 125, 118,  31,  20,   9,   2,
+       51,  56,  37,  46, 140, 135, 154, 145, 160, 171, 182, 189, 212,
+      223, 194, 201, 248, 243, 238, 229,  60,  55,  42,  33,  16,  27,
+        6,  13, 100, 111, 114, 121,  72,  67,  94,  85,   1,  10,  23,
+       28,  45,  38,  59,  48,  89,  82,  79,  68, 117, 126,  99, 104,
+      177, 186, 167, 172, 157, 150, 139, 128, 233, 226, 255, 244, 197,
+      206, 211, 216, 122, 113, 108, 103,  86,  93,  64,  75,  34,  41,
+       52,  63,  14,   5,  24,  19, 202, 193, 220, 215, 230, 237, 240,
+      251, 146, 153, 132, 143, 190, 181, 168, 163
+  };
+  s433 = table2[s432];
+  s434 = sbv_bv_extract_u32_15_8_u8(s409);
+  static const SWord8 table3[] = {
+        0,  13,  26,  23,  52,  57,  46,  35, 104, 101, 114, 127,  92,
+       81,  70,  75, 208, 221, 202, 199, 228, 233, 254, 243, 184, 181,
+      162, 175, 140, 129, 150, 155, 187, 182, 161, 172, 143, 130, 149,
+      152, 211, 222, 201, 196, 231, 234, 253, 240, 107, 102, 113, 124,
+       95,  82,  69,  72,   3,  14,  25,  20,  55,  58,  45,  32, 109,
+       96, 119, 122,  89,  84,  67,  78,   5,   8,  31,  18,  49,  60,
+       43,  38, 189, 176, 167, 170, 137, 132, 147, 158, 213, 216, 207,
+      194, 225, 236, 251, 246, 214, 219, 204, 193, 226, 239, 248, 245,
+      190, 179, 164, 169, 138, 135, 144, 157,   6,  11,  28,  17,  50,
+       63,  40,  37, 110,  99, 116, 121,  90,  87,  64,  77, 218, 215,
+      192, 205, 238, 227, 244, 249, 178, 191, 168, 165, 134, 139, 156,
+      145,  10,   7,  16,  29,  62,  51,  36,  41,  98, 111, 120, 117,
+       86,  91,  76,  65,  97, 108, 123, 118,  85,  88,  79,  66,   9,
+        4,  19,  30,  61,  48,  39,  42, 177, 188, 171, 166, 133, 136,
+      159, 146, 217, 212, 195, 206, 237, 224, 247, 250, 183, 186, 173,
+      160, 131, 142, 153, 148, 223, 210, 197, 200, 235, 230, 241, 252,
+      103, 106, 125, 112,  83,  94,  73,  68,  15,   2,  21,  24,  59,
+       54,  33,  44,  12,   1,  22,  27,  56,  53,  34,  47, 100, 105,
+      126, 115,  80,  93,  74,  71, 220, 209, 198, 203, 232, 229, 242,
+      255, 180, 185, 174, 163, 128, 141, 154, 151
+  };
+  s435 = table3[s434];
+  s436 = sbv_bv_extract_u32_7_0_u8(s409);
+  static const SWord8 table4[] = {
+        0,   9,  18,  27,  36,  45,  54,  63,  72,  65,  90,  83, 108,
+      101, 126, 119, 144, 153, 130, 139, 180, 189, 166, 175, 216, 209,
+      202, 195, 252, 245, 238, 231,  59,  50,  41,  32,  31,  22,  13,
+        4, 115, 122,  97, 104,  87,  94,  69,  76, 171, 162, 185, 176,
+      143, 134, 157, 148, 227, 234, 241, 248, 199, 206, 213, 220, 118,
+      127, 100, 109,  82,  91,  64,  73,  62,  55,  44,  37,  26,  19,
+        8,   1, 230, 239, 244, 253, 194, 203, 208, 217, 174, 167, 188,
+      181, 138, 131, 152, 145,  77,  68,  95,  86, 105,  96, 123, 114,
+        5,  12,  23,  30,  33,  40,  51,  58, 221, 212, 207, 198, 249,
+      240, 235, 226, 149, 156, 135, 142, 177, 184, 163, 170, 236, 229,
+      254, 247, 200, 193, 218, 211, 164, 173, 182, 191, 128, 137, 146,
+      155, 124, 117, 110, 103,  88,  81,  74,  67,  52,  61,  38,  47,
+       16,  25,   2,  11, 215, 222, 197, 204, 243, 250, 225, 232, 159,
+      150, 141, 132, 187, 178, 169, 160,  71,  78,  85,  92,  99, 106,
+      113, 120,  15,   6,  29,  20,  43,  34,  57,  48, 154, 147, 136,
+      129, 190, 183, 172, 165, 210, 219, 192, 201, 246, 255, 228, 237,
+       10,   3,  24,  17,  46,  39,  60,  53,  66,  75,  80,  89, 102,
+      111, 116, 125, 161, 168, 179, 186, 133, 140, 151, 158, 233, 224,
+      251, 242, 205, 196, 223, 214,  49,  56,  35,  42,  21,  28,   7,
+       14, 121, 112, 107,  98,  93,  84,  79,  70
+  };
+  s437 = table4[s436];
+  s438 = s435 ^ s437;
+  s439 = s433 ^ s438;
+  s440 = s431 ^ s439;
+  s441 = table4[s430];
+  s442 = table1[s432];
+  s443 = table2[s434];
+  s444 = table3[s436];
+  s445 = s443 ^ s444;
+  s446 = s442 ^ s445;
+  s447 = s441 ^ s446;
+  s448 = sbv_bv_join_u8_u8_u16(s440, s447);
+  s449 = table3[s430];
+  s450 = table4[s432];
+  s451 = table1[s434];
+  s452 = table2[s436];
+  s453 = s451 ^ s452;
+  s454 = s450 ^ s453;
+  s455 = s449 ^ s454;
+  s456 = table2[s430];
+  s457 = table3[s432];
+  s458 = table4[s434];
+  s459 = table1[s436];
+  s460 = s458 ^ s459;
+  s461 = s457 ^ s460;
+  s462 = s456 ^ s461;
+  s463 = sbv_bv_join_u8_u8_u16(s455, s462);
+  s464 = sbv_bv_join_u16_u16_u32(s448, s463);
+  s465 = sbv_bv_extract_u32_31_24_u8(s410);
+  s466 = table1[s465];
+  s467 = sbv_bv_extract_u32_23_16_u8(s410);
+  s468 = table2[s467];
+  s469 = sbv_bv_extract_u32_15_8_u8(s410);
+  s470 = table3[s469];
+  s471 = sbv_bv_extract_u32_7_0_u8(s410);
+  s472 = table4[s471];
+  s473 = s470 ^ s472;
+  s474 = s468 ^ s473;
+  s475 = s466 ^ s474;
+  s476 = table4[s465];
+  s477 = table1[s467];
+  s478 = table2[s469];
+  s479 = table3[s471];
+  s480 = s478 ^ s479;
+  s481 = s477 ^ s480;
+  s482 = s476 ^ s481;
+  s483 = sbv_bv_join_u8_u8_u16(s475, s482);
+  s484 = table3[s465];
+  s485 = table4[s467];
+  s486 = table1[s469];
+  s487 = table2[s471];
+  s488 = s486 ^ s487;
+  s489 = s485 ^ s488;
+  s490 = s484 ^ s489;
+  s491 = table2[s465];
+  s492 = table3[s467];
+  s493 = table4[s469];
+  s494 = table1[s471];
+  s495 = s493 ^ s494;
+  s496 = s492 ^ s495;
+  s497 = s491 ^ s496;
+  s498 = sbv_bv_join_u8_u8_u16(s490, s497);
+  s499 = sbv_bv_join_u16_u16_u32(s483, s498);
+  s500 = sbv_bv_extract_u32_31_24_u8(s411);
+  s501 = table1[s500];
+  s502 = sbv_bv_extract_u32_23_16_u8(s411);
+  s503 = table2[s502];
+  s504 = sbv_bv_extract_u32_15_8_u8(s411);
+  s505 = table3[s504];
+  s506 = sbv_bv_extract_u32_7_0_u8(s411);
+  s507 = table4[s506];
+  s508 = s505 ^ s507;
+  s509 = s503 ^ s508;
+  s510 = s501 ^ s509;
+  s511 = table4[s500];
+  s512 = table1[s502];
+  s513 = table2[s504];
+  s514 = table3[s506];
+  s515 = s513 ^ s514;
+  s516 = s512 ^ s515;
+  s517 = s511 ^ s516;
+  s518 = sbv_bv_join_u8_u8_u16(s510, s517);
+  s519 = table3[s500];
+  s520 = table4[s502];
+  s521 = table1[s504];
+  s522 = table2[s506];
+  s523 = s521 ^ s522;
+  s524 = s520 ^ s523;
+  s525 = s519 ^ s524;
+  s526 = table2[s500];
+  s527 = table3[s502];
+  s528 = table4[s504];
+  s529 = table1[s506];
+  s530 = s528 ^ s529;
+  s531 = s527 ^ s530;
+  s532 = s526 ^ s531;
+  s533 = sbv_bv_join_u8_u8_u16(s525, s532);
+  s534 = sbv_bv_join_u16_u16_u32(s518, s533);
+  s535 = sbv_bv_extract_u32_31_24_u8(s412);
+  s536 = table1[s535];
+  s537 = sbv_bv_extract_u32_23_16_u8(s412);
+  s538 = table2[s537];
+  s539 = sbv_bv_extract_u32_15_8_u8(s412);
+  s540 = table3[s539];
+  s541 = sbv_bv_extract_u32_7_0_u8(s412);
+  s542 = table4[s541];
+  s543 = s540 ^ s542;
+  s544 = s538 ^ s543;
+  s545 = s536 ^ s544;
+  s546 = table4[s535];
+  s547 = table1[s537];
+  s548 = table2[s539];
+  s549 = table3[s541];
+  s550 = s548 ^ s549;
+  s551 = s547 ^ s550;
+  s552 = s546 ^ s551;
+  s553 = sbv_bv_join_u8_u8_u16(s545, s552);
+  s554 = table3[s535];
+  s555 = table4[s537];
+  s556 = table1[s539];
+  s557 = table2[s541];
+  s558 = s556 ^ s557;
+  s559 = s555 ^ s558;
+  s560 = s554 ^ s559;
+  s561 = table2[s535];
+  s562 = table3[s537];
+  s563 = table4[s539];
+  s564 = table1[s541];
+  s565 = s563 ^ s564;
+  s566 = s562 ^ s565;
+  s567 = s561 ^ s566;
+  s568 = sbv_bv_join_u8_u8_u16(s560, s567);
+  s569 = sbv_bv_join_u16_u16_u32(s553, s568);
+  s570 = sbv_bv_extract_u32_31_24_u8(s392);
+  s571 = table1[s570];
+  s572 = sbv_bv_extract_u32_23_16_u8(s392);
+  s573 = table2[s572];
+  s574 = sbv_bv_extract_u32_15_8_u8(s392);
+  s575 = table3[s574];
+  s576 = sbv_bv_extract_u32_7_0_u8(s392);
+  s577 = table4[s576];
+  s578 = s575 ^ s577;
+  s579 = s573 ^ s578;
+  s580 = s571 ^ s579;
+  s581 = table4[s570];
+  s582 = table1[s572];
+  s583 = table2[s574];
+  s584 = table3[s576];
+  s585 = s583 ^ s584;
+  s586 = s582 ^ s585;
+  s587 = s581 ^ s586;
+  s588 = sbv_bv_join_u8_u8_u16(s580, s587);
+  s589 = table3[s570];
+  s590 = table4[s572];
+  s591 = table1[s574];
+  s592 = table2[s576];
+  s593 = s591 ^ s592;
+  s594 = s590 ^ s593;
+  s595 = s589 ^ s594;
+  s596 = table2[s570];
+  s597 = table3[s572];
+  s598 = table4[s574];
+  s599 = table1[s576];
+  s600 = s598 ^ s599;
+  s601 = s597 ^ s600;
+  s602 = s596 ^ s601;
+  s603 = sbv_bv_join_u8_u8_u16(s595, s602);
+  s604 = sbv_bv_join_u16_u16_u32(s588, s603);
+  s605 = sbv_bv_extract_u32_31_24_u8(s393);
+  s606 = table1[s605];
+  s607 = sbv_bv_extract_u32_23_16_u8(s393);
+  s608 = table2[s607];
+  s609 = sbv_bv_extract_u32_15_8_u8(s393);
+  s610 = table3[s609];
+  s611 = sbv_bv_extract_u32_7_0_u8(s393);
+  s612 = table4[s611];
+  s613 = s610 ^ s612;
+  s614 = s608 ^ s613;
+  s615 = s606 ^ s614;
+  s616 = table4[s605];
+  s617 = table1[s607];
+  s618 = table2[s609];
+  s619 = table3[s611];
+  s620 = s618 ^ s619;
+  s621 = s617 ^ s620;
+  s622 = s616 ^ s621;
+  s623 = sbv_bv_join_u8_u8_u16(s615, s622);
+  s624 = table3[s605];
+  s625 = table4[s607];
+  s626 = table1[s609];
+  s627 = table2[s611];
+  s628 = s626 ^ s627;
+  s629 = s625 ^ s628;
+  s630 = s624 ^ s629;
+  s631 = table2[s605];
+  s632 = table3[s607];
+  s633 = table4[s609];
+  s634 = table1[s611];
+  s635 = s633 ^ s634;
+  s636 = s632 ^ s635;
+  s637 = s631 ^ s636;
+  s638 = sbv_bv_join_u8_u8_u16(s630, s637);
+  s639 = sbv_bv_join_u16_u16_u32(s623, s638);
+  s640 = sbv_bv_extract_u32_31_24_u8(s394);
+  s641 = table1[s640];
+  s642 = sbv_bv_extract_u32_23_16_u8(s394);
+  s643 = table2[s642];
+  s644 = sbv_bv_extract_u32_15_8_u8(s394);
+  s645 = table3[s644];
+  s646 = sbv_bv_extract_u32_7_0_u8(s394);
+  s647 = table4[s646];
+  s648 = s645 ^ s647;
+  s649 = s643 ^ s648;
+  s650 = s641 ^ s649;
+  s651 = table4[s640];
+  s652 = table1[s642];
+  s653 = table2[s644];
+  s654 = table3[s646];
+  s655 = s653 ^ s654;
+  s656 = s652 ^ s655;
+  s657 = s651 ^ s656;
+  s658 = sbv_bv_join_u8_u8_u16(s650, s657);
+  s659 = table3[s640];
+  s660 = table4[s642];
+  s661 = table1[s644];
+  s662 = table2[s646];
+  s663 = s661 ^ s662;
+  s664 = s660 ^ s663;
+  s665 = s659 ^ s664;
+  s666 = table2[s640];
+  s667 = table3[s642];
+  s668 = table4[s644];
+  s669 = table1[s646];
+  s670 = s668 ^ s669;
+  s671 = s667 ^ s670;
+  s672 = s666 ^ s671;
+  s673 = sbv_bv_join_u8_u8_u16(s665, s672);
+  s674 = sbv_bv_join_u16_u16_u32(s658, s673);
+  s675 = sbv_bv_extract_u32_31_24_u8(s395);
+  s676 = table1[s675];
+  s677 = sbv_bv_extract_u32_23_16_u8(s395);
+  s678 = table2[s677];
+  s679 = sbv_bv_extract_u32_15_8_u8(s395);
+  s680 = table3[s679];
+  s681 = sbv_bv_extract_u32_7_0_u8(s395);
+  s682 = table4[s681];
+  s683 = s680 ^ s682;
+  s684 = s678 ^ s683;
+  s685 = s676 ^ s684;
+  s686 = table4[s675];
+  s687 = table1[s677];
+  s688 = table2[s679];
+  s689 = table3[s681];
+  s690 = s688 ^ s689;
+  s691 = s687 ^ s690;
+  s692 = s686 ^ s691;
+  s693 = sbv_bv_join_u8_u8_u16(s685, s692);
+  s694 = table3[s675];
+  s695 = table4[s677];
+  s696 = table1[s679];
+  s697 = table2[s681];
+  s698 = s696 ^ s697;
+  s699 = s695 ^ s698;
+  s700 = s694 ^ s699;
+  s701 = table2[s675];
+  s702 = table3[s677];
+  s703 = table4[s679];
+  s704 = table1[s681];
+  s705 = s703 ^ s704;
+  s706 = s702 ^ s705;
+  s707 = s701 ^ s706;
+  s708 = sbv_bv_join_u8_u8_u16(s700, s707);
+  s709 = sbv_bv_join_u16_u16_u32(s693, s708);
+  s710 = sbv_bv_extract_u32_31_24_u8(s375);
+  s711 = table1[s710];
+  s712 = sbv_bv_extract_u32_23_16_u8(s375);
+  s713 = table2[s712];
+  s714 = sbv_bv_extract_u32_15_8_u8(s375);
+  s715 = table3[s714];
+  s716 = sbv_bv_extract_u32_7_0_u8(s375);
+  s717 = table4[s716];
+  s718 = s715 ^ s717;
+  s719 = s713 ^ s718;
+  s720 = s711 ^ s719;
+  s721 = table4[s710];
+  s722 = table1[s712];
+  s723 = table2[s714];
+  s724 = table3[s716];
+  s725 = s723 ^ s724;
+  s726 = s722 ^ s725;
+  s727 = s721 ^ s726;
+  s728 = sbv_bv_join_u8_u8_u16(s720, s727);
+  s729 = table3[s710];
+  s730 = table4[s712];
+  s731 = table1[s714];
+  s732 = table2[s716];
+  s733 = s731 ^ s732;
+  s734 = s730 ^ s733;
+  s735 = s729 ^ s734;
+  s736 = table2[s710];
+  s737 = table3[s712];
+  s738 = table4[s714];
+  s739 = table1[s716];
+  s740 = s738 ^ s739;
+  s741 = s737 ^ s740;
+  s742 = s736 ^ s741;
+  s743 = sbv_bv_join_u8_u8_u16(s735, s742);
+  s744 = sbv_bv_join_u16_u16_u32(s728, s743);
+  s745 = sbv_bv_extract_u32_31_24_u8(s376);
+  s746 = table1[s745];
+  s747 = sbv_bv_extract_u32_23_16_u8(s376);
+  s748 = table2[s747];
+  s749 = sbv_bv_extract_u32_15_8_u8(s376);
+  s750 = table3[s749];
+  s751 = sbv_bv_extract_u32_7_0_u8(s376);
+  s752 = table4[s751];
+  s753 = s750 ^ s752;
+  s754 = s748 ^ s753;
+  s755 = s746 ^ s754;
+  s756 = table4[s745];
+  s757 = table1[s747];
+  s758 = table2[s749];
+  s759 = table3[s751];
+  s760 = s758 ^ s759;
+  s761 = s757 ^ s760;
+  s762 = s756 ^ s761;
+  s763 = sbv_bv_join_u8_u8_u16(s755, s762);
+  s764 = table3[s745];
+  s765 = table4[s747];
+  s766 = table1[s749];
+  s767 = table2[s751];
+  s768 = s766 ^ s767;
+  s769 = s765 ^ s768;
+  s770 = s764 ^ s769;
+  s771 = table2[s745];
+  s772 = table3[s747];
+  s773 = table4[s749];
+  s774 = table1[s751];
+  s775 = s773 ^ s774;
+  s776 = s772 ^ s775;
+  s777 = s771 ^ s776;
+  s778 = sbv_bv_join_u8_u8_u16(s770, s777);
+  s779 = sbv_bv_join_u16_u16_u32(s763, s778);
+  s780 = sbv_bv_extract_u32_31_24_u8(s377);
+  s781 = table1[s780];
+  s782 = sbv_bv_extract_u32_23_16_u8(s377);
+  s783 = table2[s782];
+  s784 = sbv_bv_extract_u32_15_8_u8(s377);
+  s785 = table3[s784];
+  s786 = sbv_bv_extract_u32_7_0_u8(s377);
+  s787 = table4[s786];
+  s788 = s785 ^ s787;
+  s789 = s783 ^ s788;
+  s790 = s781 ^ s789;
+  s791 = table4[s780];
+  s792 = table1[s782];
+  s793 = table2[s784];
+  s794 = table3[s786];
+  s795 = s793 ^ s794;
+  s796 = s792 ^ s795;
+  s797 = s791 ^ s796;
+  s798 = sbv_bv_join_u8_u8_u16(s790, s797);
+  s799 = table3[s780];
+  s800 = table4[s782];
+  s801 = table1[s784];
+  s802 = table2[s786];
+  s803 = s801 ^ s802;
+  s804 = s800 ^ s803;
+  s805 = s799 ^ s804;
+  s806 = table2[s780];
+  s807 = table3[s782];
+  s808 = table4[s784];
+  s809 = table1[s786];
+  s810 = s808 ^ s809;
+  s811 = s807 ^ s810;
+  s812 = s806 ^ s811;
+  s813 = sbv_bv_join_u8_u8_u16(s805, s812);
+  s814 = sbv_bv_join_u16_u16_u32(s798, s813);
+  s815 = sbv_bv_extract_u32_31_24_u8(s378);
+  s816 = table1[s815];
+  s817 = sbv_bv_extract_u32_23_16_u8(s378);
+  s818 = table2[s817];
+  s819 = sbv_bv_extract_u32_15_8_u8(s378);
+  s820 = table3[s819];
+  s821 = sbv_bv_extract_u32_7_0_u8(s378);
+  s822 = table4[s821];
+  s823 = s820 ^ s822;
+  s824 = s818 ^ s823;
+  s825 = s816 ^ s824;
+  s826 = table4[s815];
+  s827 = table1[s817];
+  s828 = table2[s819];
+  s829 = table3[s821];
+  s830 = s828 ^ s829;
+  s831 = s827 ^ s830;
+  s832 = s826 ^ s831;
+  s833 = sbv_bv_join_u8_u8_u16(s825, s832);
+  s834 = table3[s815];
+  s835 = table4[s817];
+  s836 = table1[s819];
+  s837 = table2[s821];
+  s838 = s836 ^ s837;
+  s839 = s835 ^ s838;
+  s840 = s834 ^ s839;
+  s841 = table2[s815];
+  s842 = table3[s817];
+  s843 = table4[s819];
+  s844 = table1[s821];
+  s845 = s843 ^ s844;
+  s846 = s842 ^ s845;
+  s847 = s841 ^ s846;
+  s848 = sbv_bv_join_u8_u8_u16(s840, s847);
+  s849 = sbv_bv_join_u16_u16_u32(s833, s848);
+  s850 = sbv_bv_extract_u32_31_24_u8(s358);
+  s851 = table1[s850];
+  s852 = sbv_bv_extract_u32_23_16_u8(s358);
+  s853 = table2[s852];
+  s854 = sbv_bv_extract_u32_15_8_u8(s358);
+  s855 = table3[s854];
+  s856 = sbv_bv_extract_u32_7_0_u8(s358);
+  s857 = table4[s856];
+  s858 = s855 ^ s857;
+  s859 = s853 ^ s858;
+  s860 = s851 ^ s859;
+  s861 = table4[s850];
+  s862 = table1[s852];
+  s863 = table2[s854];
+  s864 = table3[s856];
+  s865 = s863 ^ s864;
+  s866 = s862 ^ s865;
+  s867 = s861 ^ s866;
+  s868 = sbv_bv_join_u8_u8_u16(s860, s867);
+  s869 = table3[s850];
+  s870 = table4[s852];
+  s871 = table1[s854];
+  s872 = table2[s856];
+  s873 = s871 ^ s872;
+  s874 = s870 ^ s873;
+  s875 = s869 ^ s874;
+  s876 = table2[s850];
+  s877 = table3[s852];
+  s878 = table4[s854];
+  s879 = table1[s856];
+  s880 = s878 ^ s879;
+  s881 = s877 ^ s880;
+  s882 = s876 ^ s881;
+  s883 = sbv_bv_join_u8_u8_u16(s875, s882);
+  s884 = sbv_bv_join_u16_u16_u32(s868, s883);
+  s885 = sbv_bv_extract_u32_31_24_u8(s359);
+  s886 = table1[s885];
+  s887 = sbv_bv_extract_u32_23_16_u8(s359);
+  s888 = table2[s887];
+  s889 = sbv_bv_extract_u32_15_8_u8(s359);
+  s890 = table3[s889];
+  s891 = sbv_bv_extract_u32_7_0_u8(s359);
+  s892 = table4[s891];
+  s893 = s890 ^ s892;
+  s894 = s888 ^ s893;
+  s895 = s886 ^ s894;
+  s896 = table4[s885];
+  s897 = table1[s887];
+  s898 = table2[s889];
+  s899 = table3[s891];
+  s900 = s898 ^ s899;
+  s901 = s897 ^ s900;
+  s902 = s896 ^ s901;
+  s903 = sbv_bv_join_u8_u8_u16(s895, s902);
+  s904 = table3[s885];
+  s905 = table4[s887];
+  s906 = table1[s889];
+  s907 = table2[s891];
+  s908 = s906 ^ s907;
+  s909 = s905 ^ s908;
+  s910 = s904 ^ s909;
+  s911 = table2[s885];
+  s912 = table3[s887];
+  s913 = table4[s889];
+  s914 = table1[s891];
+  s915 = s913 ^ s914;
+  s916 = s912 ^ s915;
+  s917 = s911 ^ s916;
+  s918 = sbv_bv_join_u8_u8_u16(s910, s917);
+  s919 = sbv_bv_join_u16_u16_u32(s903, s918);
+  s920 = sbv_bv_extract_u32_31_24_u8(s360);
+  s921 = table1[s920];
+  s922 = sbv_bv_extract_u32_23_16_u8(s360);
+  s923 = table2[s922];
+  s924 = sbv_bv_extract_u32_15_8_u8(s360);
+  s925 = table3[s924];
+  s926 = sbv_bv_extract_u32_7_0_u8(s360);
+  s927 = table4[s926];
+  s928 = s925 ^ s927;
+  s929 = s923 ^ s928;
+  s930 = s921 ^ s929;
+  s931 = table4[s920];
+  s932 = table1[s922];
+  s933 = table2[s924];
+  s934 = table3[s926];
+  s935 = s933 ^ s934;
+  s936 = s932 ^ s935;
+  s937 = s931 ^ s936;
+  s938 = sbv_bv_join_u8_u8_u16(s930, s937);
+  s939 = table3[s920];
+  s940 = table4[s922];
+  s941 = table1[s924];
+  s942 = table2[s926];
+  s943 = s941 ^ s942;
+  s944 = s940 ^ s943;
+  s945 = s939 ^ s944;
+  s946 = table2[s920];
+  s947 = table3[s922];
+  s948 = table4[s924];
+  s949 = table1[s926];
+  s950 = s948 ^ s949;
+  s951 = s947 ^ s950;
+  s952 = s946 ^ s951;
+  s953 = sbv_bv_join_u8_u8_u16(s945, s952);
+  s954 = sbv_bv_join_u16_u16_u32(s938, s953);
+  s955 = sbv_bv_extract_u32_31_24_u8(s361);
+  s956 = table1[s955];
+  s957 = sbv_bv_extract_u32_23_16_u8(s361);
+  s958 = table2[s957];
+  s959 = sbv_bv_extract_u32_15_8_u8(s361);
+  s960 = table3[s959];
+  s961 = sbv_bv_extract_u32_7_0_u8(s361);
+  s962 = table4[s961];
+  s963 = s960 ^ s962;
+  s964 = s958 ^ s963;
+  s965 = s956 ^ s964;
+  s966 = table4[s955];
+  s967 = table1[s957];
+  s968 = table2[s959];
+  s969 = table3[s961];
+  s970 = s968 ^ s969;
+  s971 = s967 ^ s970;
+  s972 = s966 ^ s971;
+  s973 = sbv_bv_join_u8_u8_u16(s965, s972);
+  s974 = table3[s955];
+  s975 = table4[s957];
+  s976 = table1[s959];
+  s977 = table2[s961];
+  s978 = s976 ^ s977;
+  s979 = s975 ^ s978;
+  s980 = s974 ^ s979;
+  s981 = table2[s955];
+  s982 = table3[s957];
+  s983 = table4[s959];
+  s984 = table1[s961];
+  s985 = s983 ^ s984;
+  s986 = s982 ^ s985;
+  s987 = s981 ^ s986;
+  s988 = sbv_bv_join_u8_u8_u16(s980, s987);
+  s989 = sbv_bv_join_u16_u16_u32(s973, s988);
+  s990 = sbv_bv_extract_u32_31_24_u8(s341);
+  s991 = table1[s990];
+  s992 = sbv_bv_extract_u32_23_16_u8(s341);
+  s993 = table2[s992];
+  s994 = sbv_bv_extract_u32_15_8_u8(s341);
+  s995 = table3[s994];
+  s996 = sbv_bv_extract_u32_7_0_u8(s341);
+  s997 = table4[s996];
+  s998 = s995 ^ s997;
+  s999 = s993 ^ s998;
+  s1000 = s991 ^ s999;
+  s1001 = table4[s990];
+  s1002 = table1[s992];
+  s1003 = table2[s994];
+  s1004 = table3[s996];
+  s1005 = s1003 ^ s1004;
+  s1006 = s1002 ^ s1005;
+  s1007 = s1001 ^ s1006;
+  s1008 = sbv_bv_join_u8_u8_u16(s1000, s1007);
+  s1009 = table3[s990];
+  s1010 = table4[s992];
+  s1011 = table1[s994];
+  s1012 = table2[s996];
+  s1013 = s1011 ^ s1012;
+  s1014 = s1010 ^ s1013;
+  s1015 = s1009 ^ s1014;
+  s1016 = table2[s990];
+  s1017 = table3[s992];
+  s1018 = table4[s994];
+  s1019 = table1[s996];
+  s1020 = s1018 ^ s1019;
+  s1021 = s1017 ^ s1020;
+  s1022 = s1016 ^ s1021;
+  s1023 = sbv_bv_join_u8_u8_u16(s1015, s1022);
+  s1024 = sbv_bv_join_u16_u16_u32(s1008, s1023);
+  s1025 = sbv_bv_extract_u32_31_24_u8(s342);
+  s1026 = table1[s1025];
+  s1027 = sbv_bv_extract_u32_23_16_u8(s342);
+  s1028 = table2[s1027];
+  s1029 = sbv_bv_extract_u32_15_8_u8(s342);
+  s1030 = table3[s1029];
+  s1031 = sbv_bv_extract_u32_7_0_u8(s342);
+  s1032 = table4[s1031];
+  s1033 = s1030 ^ s1032;
+  s1034 = s1028 ^ s1033;
+  s1035 = s1026 ^ s1034;
+  s1036 = table4[s1025];
+  s1037 = table1[s1027];
+  s1038 = table2[s1029];
+  s1039 = table3[s1031];
+  s1040 = s1038 ^ s1039;
+  s1041 = s1037 ^ s1040;
+  s1042 = s1036 ^ s1041;
+  s1043 = sbv_bv_join_u8_u8_u16(s1035, s1042);
+  s1044 = table3[s1025];
+  s1045 = table4[s1027];
+  s1046 = table1[s1029];
+  s1047 = table2[s1031];
+  s1048 = s1046 ^ s1047;
+  s1049 = s1045 ^ s1048;
+  s1050 = s1044 ^ s1049;
+  s1051 = table2[s1025];
+  s1052 = table3[s1027];
+  s1053 = table4[s1029];
+  s1054 = table1[s1031];
+  s1055 = s1053 ^ s1054;
+  s1056 = s1052 ^ s1055;
+  s1057 = s1051 ^ s1056;
+  s1058 = sbv_bv_join_u8_u8_u16(s1050, s1057);
+  s1059 = sbv_bv_join_u16_u16_u32(s1043, s1058);
+  s1060 = sbv_bv_extract_u32_31_24_u8(s343);
+  s1061 = table1[s1060];
+  s1062 = sbv_bv_extract_u32_23_16_u8(s343);
+  s1063 = table2[s1062];
+  s1064 = sbv_bv_extract_u32_15_8_u8(s343);
+  s1065 = table3[s1064];
+  s1066 = sbv_bv_extract_u32_7_0_u8(s343);
+  s1067 = table4[s1066];
+  s1068 = s1065 ^ s1067;
+  s1069 = s1063 ^ s1068;
+  s1070 = s1061 ^ s1069;
+  s1071 = table4[s1060];
+  s1072 = table1[s1062];
+  s1073 = table2[s1064];
+  s1074 = table3[s1066];
+  s1075 = s1073 ^ s1074;
+  s1076 = s1072 ^ s1075;
+  s1077 = s1071 ^ s1076;
+  s1078 = sbv_bv_join_u8_u8_u16(s1070, s1077);
+  s1079 = table3[s1060];
+  s1080 = table4[s1062];
+  s1081 = table1[s1064];
+  s1082 = table2[s1066];
+  s1083 = s1081 ^ s1082;
+  s1084 = s1080 ^ s1083;
+  s1085 = s1079 ^ s1084;
+  s1086 = table2[s1060];
+  s1087 = table3[s1062];
+  s1088 = table4[s1064];
+  s1089 = table1[s1066];
+  s1090 = s1088 ^ s1089;
+  s1091 = s1087 ^ s1090;
+  s1092 = s1086 ^ s1091;
+  s1093 = sbv_bv_join_u8_u8_u16(s1085, s1092);
+  s1094 = sbv_bv_join_u16_u16_u32(s1078, s1093);
+  s1095 = sbv_bv_extract_u32_31_24_u8(s344);
+  s1096 = table1[s1095];
+  s1097 = sbv_bv_extract_u32_23_16_u8(s344);
+  s1098 = table2[s1097];
+  s1099 = sbv_bv_extract_u32_15_8_u8(s344);
+  s1100 = table3[s1099];
+  s1101 = sbv_bv_extract_u32_7_0_u8(s344);
+  s1102 = table4[s1101];
+  s1103 = s1100 ^ s1102;
+  s1104 = s1098 ^ s1103;
+  s1105 = s1096 ^ s1104;
+  s1106 = table4[s1095];
+  s1107 = table1[s1097];
+  s1108 = table2[s1099];
+  s1109 = table3[s1101];
+  s1110 = s1108 ^ s1109;
+  s1111 = s1107 ^ s1110;
+  s1112 = s1106 ^ s1111;
+  s1113 = sbv_bv_join_u8_u8_u16(s1105, s1112);
+  s1114 = table3[s1095];
+  s1115 = table4[s1097];
+  s1116 = table1[s1099];
+  s1117 = table2[s1101];
+  s1118 = s1116 ^ s1117;
+  s1119 = s1115 ^ s1118;
+  s1120 = s1114 ^ s1119;
+  s1121 = table2[s1095];
+  s1122 = table3[s1097];
+  s1123 = table4[s1099];
+  s1124 = table1[s1101];
+  s1125 = s1123 ^ s1124;
+  s1126 = s1122 ^ s1125;
+  s1127 = s1121 ^ s1126;
+  s1128 = sbv_bv_join_u8_u8_u16(s1120, s1127);
+  s1129 = sbv_bv_join_u16_u16_u32(s1113, s1128);
+  s1130 = sbv_bv_extract_u32_31_24_u8(s324);
+  s1131 = table1[s1130];
+  s1132 = sbv_bv_extract_u32_23_16_u8(s324);
+  s1133 = table2[s1132];
+  s1134 = sbv_bv_extract_u32_15_8_u8(s324);
+  s1135 = table3[s1134];
+  s1136 = sbv_bv_extract_u32_7_0_u8(s324);
+  s1137 = table4[s1136];
+  s1138 = s1135 ^ s1137;
+  s1139 = s1133 ^ s1138;
+  s1140 = s1131 ^ s1139;
+  s1141 = table4[s1130];
+  s1142 = table1[s1132];
+  s1143 = table2[s1134];
+  s1144 = table3[s1136];
+  s1145 = s1143 ^ s1144;
+  s1146 = s1142 ^ s1145;
+  s1147 = s1141 ^ s1146;
+  s1148 = sbv_bv_join_u8_u8_u16(s1140, s1147);
+  s1149 = table3[s1130];
+  s1150 = table4[s1132];
+  s1151 = table1[s1134];
+  s1152 = table2[s1136];
+  s1153 = s1151 ^ s1152;
+  s1154 = s1150 ^ s1153;
+  s1155 = s1149 ^ s1154;
+  s1156 = table2[s1130];
+  s1157 = table3[s1132];
+  s1158 = table4[s1134];
+  s1159 = table1[s1136];
+  s1160 = s1158 ^ s1159;
+  s1161 = s1157 ^ s1160;
+  s1162 = s1156 ^ s1161;
+  s1163 = sbv_bv_join_u8_u8_u16(s1155, s1162);
+  s1164 = sbv_bv_join_u16_u16_u32(s1148, s1163);
+  s1165 = sbv_bv_extract_u32_31_24_u8(s325);
+  s1166 = table1[s1165];
+  s1167 = sbv_bv_extract_u32_23_16_u8(s325);
+  s1168 = table2[s1167];
+  s1169 = sbv_bv_extract_u32_15_8_u8(s325);
+  s1170 = table3[s1169];
+  s1171 = sbv_bv_extract_u32_7_0_u8(s325);
+  s1172 = table4[s1171];
+  s1173 = s1170 ^ s1172;
+  s1174 = s1168 ^ s1173;
+  s1175 = s1166 ^ s1174;
+  s1176 = table4[s1165];
+  s1177 = table1[s1167];
+  s1178 = table2[s1169];
+  s1179 = table3[s1171];
+  s1180 = s1178 ^ s1179;
+  s1181 = s1177 ^ s1180;
+  s1182 = s1176 ^ s1181;
+  s1183 = sbv_bv_join_u8_u8_u16(s1175, s1182);
+  s1184 = table3[s1165];
+  s1185 = table4[s1167];
+  s1186 = table1[s1169];
+  s1187 = table2[s1171];
+  s1188 = s1186 ^ s1187;
+  s1189 = s1185 ^ s1188;
+  s1190 = s1184 ^ s1189;
+  s1191 = table2[s1165];
+  s1192 = table3[s1167];
+  s1193 = table4[s1169];
+  s1194 = table1[s1171];
+  s1195 = s1193 ^ s1194;
+  s1196 = s1192 ^ s1195;
+  s1197 = s1191 ^ s1196;
+  s1198 = sbv_bv_join_u8_u8_u16(s1190, s1197);
+  s1199 = sbv_bv_join_u16_u16_u32(s1183, s1198);
+  s1200 = sbv_bv_extract_u32_31_24_u8(s326);
+  s1201 = table1[s1200];
+  s1202 = sbv_bv_extract_u32_23_16_u8(s326);
+  s1203 = table2[s1202];
+  s1204 = sbv_bv_extract_u32_15_8_u8(s326);
+  s1205 = table3[s1204];
+  s1206 = sbv_bv_extract_u32_7_0_u8(s326);
+  s1207 = table4[s1206];
+  s1208 = s1205 ^ s1207;
+  s1209 = s1203 ^ s1208;
+  s1210 = s1201 ^ s1209;
+  s1211 = table4[s1200];
+  s1212 = table1[s1202];
+  s1213 = table2[s1204];
+  s1214 = table3[s1206];
+  s1215 = s1213 ^ s1214;
+  s1216 = s1212 ^ s1215;
+  s1217 = s1211 ^ s1216;
+  s1218 = sbv_bv_join_u8_u8_u16(s1210, s1217);
+  s1219 = table3[s1200];
+  s1220 = table4[s1202];
+  s1221 = table1[s1204];
+  s1222 = table2[s1206];
+  s1223 = s1221 ^ s1222;
+  s1224 = s1220 ^ s1223;
+  s1225 = s1219 ^ s1224;
+  s1226 = table2[s1200];
+  s1227 = table3[s1202];
+  s1228 = table4[s1204];
+  s1229 = table1[s1206];
+  s1230 = s1228 ^ s1229;
+  s1231 = s1227 ^ s1230;
+  s1232 = s1226 ^ s1231;
+  s1233 = sbv_bv_join_u8_u8_u16(s1225, s1232);
+  s1234 = sbv_bv_join_u16_u16_u32(s1218, s1233);
+  s1235 = sbv_bv_extract_u32_31_24_u8(s327);
+  s1236 = table1[s1235];
+  s1237 = sbv_bv_extract_u32_23_16_u8(s327);
+  s1238 = table2[s1237];
+  s1239 = sbv_bv_extract_u32_15_8_u8(s327);
+  s1240 = table3[s1239];
+  s1241 = sbv_bv_extract_u32_7_0_u8(s327);
+  s1242 = table4[s1241];
+  s1243 = s1240 ^ s1242;
+  s1244 = s1238 ^ s1243;
+  s1245 = s1236 ^ s1244;
+  s1246 = table4[s1235];
+  s1247 = table1[s1237];
+  s1248 = table2[s1239];
+  s1249 = table3[s1241];
+  s1250 = s1248 ^ s1249;
+  s1251 = s1247 ^ s1250;
+  s1252 = s1246 ^ s1251;
+  s1253 = sbv_bv_join_u8_u8_u16(s1245, s1252);
+  s1254 = table3[s1235];
+  s1255 = table4[s1237];
+  s1256 = table1[s1239];
+  s1257 = table2[s1241];
+  s1258 = s1256 ^ s1257;
+  s1259 = s1255 ^ s1258;
+  s1260 = s1254 ^ s1259;
+  s1261 = table2[s1235];
+  s1262 = table3[s1237];
+  s1263 = table4[s1239];
+  s1264 = table1[s1241];
+  s1265 = s1263 ^ s1264;
+  s1266 = s1262 ^ s1265;
+  s1267 = s1261 ^ s1266;
+  s1268 = sbv_bv_join_u8_u8_u16(s1260, s1267);
+  s1269 = sbv_bv_join_u16_u16_u32(s1253, s1268);
+  s1270 = sbv_bv_extract_u32_31_24_u8(s307);
+  s1271 = table1[s1270];
+  s1272 = sbv_bv_extract_u32_23_16_u8(s307);
+  s1273 = table2[s1272];
+  s1274 = sbv_bv_extract_u32_15_8_u8(s307);
+  s1275 = table3[s1274];
+  s1276 = sbv_bv_extract_u32_7_0_u8(s307);
+  s1277 = table4[s1276];
+  s1278 = s1275 ^ s1277;
+  s1279 = s1273 ^ s1278;
+  s1280 = s1271 ^ s1279;
+  s1281 = table4[s1270];
+  s1282 = table1[s1272];
+  s1283 = table2[s1274];
+  s1284 = table3[s1276];
+  s1285 = s1283 ^ s1284;
+  s1286 = s1282 ^ s1285;
+  s1287 = s1281 ^ s1286;
+  s1288 = sbv_bv_join_u8_u8_u16(s1280, s1287);
+  s1289 = table3[s1270];
+  s1290 = table4[s1272];
+  s1291 = table1[s1274];
+  s1292 = table2[s1276];
+  s1293 = s1291 ^ s1292;
+  s1294 = s1290 ^ s1293;
+  s1295 = s1289 ^ s1294;
+  s1296 = table2[s1270];
+  s1297 = table3[s1272];
+  s1298 = table4[s1274];
+  s1299 = table1[s1276];
+  s1300 = s1298 ^ s1299;
+  s1301 = s1297 ^ s1300;
+  s1302 = s1296 ^ s1301;
+  s1303 = sbv_bv_join_u8_u8_u16(s1295, s1302);
+  s1304 = sbv_bv_join_u16_u16_u32(s1288, s1303);
+  s1305 = sbv_bv_extract_u32_31_24_u8(s308);
+  s1306 = table1[s1305];
+  s1307 = sbv_bv_extract_u32_23_16_u8(s308);
+  s1308 = table2[s1307];
+  s1309 = sbv_bv_extract_u32_15_8_u8(s308);
+  s1310 = table3[s1309];
+  s1311 = sbv_bv_extract_u32_7_0_u8(s308);
+  s1312 = table4[s1311];
+  s1313 = s1310 ^ s1312;
+  s1314 = s1308 ^ s1313;
+  s1315 = s1306 ^ s1314;
+  s1316 = table4[s1305];
+  s1317 = table1[s1307];
+  s1318 = table2[s1309];
+  s1319 = table3[s1311];
+  s1320 = s1318 ^ s1319;
+  s1321 = s1317 ^ s1320;
+  s1322 = s1316 ^ s1321;
+  s1323 = sbv_bv_join_u8_u8_u16(s1315, s1322);
+  s1324 = table3[s1305];
+  s1325 = table4[s1307];
+  s1326 = table1[s1309];
+  s1327 = table2[s1311];
+  s1328 = s1326 ^ s1327;
+  s1329 = s1325 ^ s1328;
+  s1330 = s1324 ^ s1329;
+  s1331 = table2[s1305];
+  s1332 = table3[s1307];
+  s1333 = table4[s1309];
+  s1334 = table1[s1311];
+  s1335 = s1333 ^ s1334;
+  s1336 = s1332 ^ s1335;
+  s1337 = s1331 ^ s1336;
+  s1338 = sbv_bv_join_u8_u8_u16(s1330, s1337);
+  s1339 = sbv_bv_join_u16_u16_u32(s1323, s1338);
+  s1340 = sbv_bv_extract_u32_31_24_u8(s309);
+  s1341 = table1[s1340];
+  s1342 = sbv_bv_extract_u32_23_16_u8(s309);
+  s1343 = table2[s1342];
+  s1344 = sbv_bv_extract_u32_15_8_u8(s309);
+  s1345 = table3[s1344];
+  s1346 = sbv_bv_extract_u32_7_0_u8(s309);
+  s1347 = table4[s1346];
+  s1348 = s1345 ^ s1347;
+  s1349 = s1343 ^ s1348;
+  s1350 = s1341 ^ s1349;
+  s1351 = table4[s1340];
+  s1352 = table1[s1342];
+  s1353 = table2[s1344];
+  s1354 = table3[s1346];
+  s1355 = s1353 ^ s1354;
+  s1356 = s1352 ^ s1355;
+  s1357 = s1351 ^ s1356;
+  s1358 = sbv_bv_join_u8_u8_u16(s1350, s1357);
+  s1359 = table3[s1340];
+  s1360 = table4[s1342];
+  s1361 = table1[s1344];
+  s1362 = table2[s1346];
+  s1363 = s1361 ^ s1362;
+  s1364 = s1360 ^ s1363;
+  s1365 = s1359 ^ s1364;
+  s1366 = table2[s1340];
+  s1367 = table3[s1342];
+  s1368 = table4[s1344];
+  s1369 = table1[s1346];
+  s1370 = s1368 ^ s1369;
+  s1371 = s1367 ^ s1370;
+  s1372 = s1366 ^ s1371;
+  s1373 = sbv_bv_join_u8_u8_u16(s1365, s1372);
+  s1374 = sbv_bv_join_u16_u16_u32(s1358, s1373);
+  s1375 = sbv_bv_extract_u32_31_24_u8(s310);
+  s1376 = table1[s1375];
+  s1377 = sbv_bv_extract_u32_23_16_u8(s310);
+  s1378 = table2[s1377];
+  s1379 = sbv_bv_extract_u32_15_8_u8(s310);
+  s1380 = table3[s1379];
+  s1381 = sbv_bv_extract_u32_7_0_u8(s310);
+  s1382 = table4[s1381];
+  s1383 = s1380 ^ s1382;
+  s1384 = s1378 ^ s1383;
+  s1385 = s1376 ^ s1384;
+  s1386 = table4[s1375];
+  s1387 = table1[s1377];
+  s1388 = table2[s1379];
+  s1389 = table3[s1381];
+  s1390 = s1388 ^ s1389;
+  s1391 = s1387 ^ s1390;
+  s1392 = s1386 ^ s1391;
+  s1393 = sbv_bv_join_u8_u8_u16(s1385, s1392);
+  s1394 = table3[s1375];
+  s1395 = table4[s1377];
+  s1396 = table1[s1379];
+  s1397 = table2[s1381];
+  s1398 = s1396 ^ s1397;
+  s1399 = s1395 ^ s1398;
+  s1400 = s1394 ^ s1399;
+  s1401 = table2[s1375];
+  s1402 = table3[s1377];
+  s1403 = table4[s1379];
+  s1404 = table1[s1381];
+  s1405 = s1403 ^ s1404;
+  s1406 = s1402 ^ s1405;
+  s1407 = s1401 ^ s1406;
+  s1408 = sbv_bv_join_u8_u8_u16(s1400, s1407);
+  s1409 = sbv_bv_join_u16_u16_u32(s1393, s1408);
+  s1410 = sbv_bv_extract_u32_31_24_u8(s290);
+  s1411 = table1[s1410];
+  s1412 = sbv_bv_extract_u32_23_16_u8(s290);
+  s1413 = table2[s1412];
+  s1414 = sbv_bv_extract_u32_15_8_u8(s290);
+  s1415 = table3[s1414];
+  s1416 = sbv_bv_extract_u32_7_0_u8(s290);
+  s1417 = table4[s1416];
+  s1418 = s1415 ^ s1417;
+  s1419 = s1413 ^ s1418;
+  s1420 = s1411 ^ s1419;
+  s1421 = table4[s1410];
+  s1422 = table1[s1412];
+  s1423 = table2[s1414];
+  s1424 = table3[s1416];
+  s1425 = s1423 ^ s1424;
+  s1426 = s1422 ^ s1425;
+  s1427 = s1421 ^ s1426;
+  s1428 = sbv_bv_join_u8_u8_u16(s1420, s1427);
+  s1429 = table3[s1410];
+  s1430 = table4[s1412];
+  s1431 = table1[s1414];
+  s1432 = table2[s1416];
+  s1433 = s1431 ^ s1432;
+  s1434 = s1430 ^ s1433;
+  s1435 = s1429 ^ s1434;
+  s1436 = table2[s1410];
+  s1437 = table3[s1412];
+  s1438 = table4[s1414];
+  s1439 = table1[s1416];
+  s1440 = s1438 ^ s1439;
+  s1441 = s1437 ^ s1440;
+  s1442 = s1436 ^ s1441;
+  s1443 = sbv_bv_join_u8_u8_u16(s1435, s1442);
+  s1444 = sbv_bv_join_u16_u16_u32(s1428, s1443);
+  s1445 = sbv_bv_extract_u32_31_24_u8(s291);
+  s1446 = table1[s1445];
+  s1447 = sbv_bv_extract_u32_23_16_u8(s291);
+  s1448 = table2[s1447];
+  s1449 = sbv_bv_extract_u32_15_8_u8(s291);
+  s1450 = table3[s1449];
+  s1451 = sbv_bv_extract_u32_7_0_u8(s291);
+  s1452 = table4[s1451];
+  s1453 = s1450 ^ s1452;
+  s1454 = s1448 ^ s1453;
+  s1455 = s1446 ^ s1454;
+  s1456 = table4[s1445];
+  s1457 = table1[s1447];
+  s1458 = table2[s1449];
+  s1459 = table3[s1451];
+  s1460 = s1458 ^ s1459;
+  s1461 = s1457 ^ s1460;
+  s1462 = s1456 ^ s1461;
+  s1463 = sbv_bv_join_u8_u8_u16(s1455, s1462);
+  s1464 = table3[s1445];
+  s1465 = table4[s1447];
+  s1466 = table1[s1449];
+  s1467 = table2[s1451];
+  s1468 = s1466 ^ s1467;
+  s1469 = s1465 ^ s1468;
+  s1470 = s1464 ^ s1469;
+  s1471 = table2[s1445];
+  s1472 = table3[s1447];
+  s1473 = table4[s1449];
+  s1474 = table1[s1451];
+  s1475 = s1473 ^ s1474;
+  s1476 = s1472 ^ s1475;
+  s1477 = s1471 ^ s1476;
+  s1478 = sbv_bv_join_u8_u8_u16(s1470, s1477);
+  s1479 = sbv_bv_join_u16_u16_u32(s1463, s1478);
+  s1480 = sbv_bv_extract_u32_31_24_u8(s292);
+  s1481 = table1[s1480];
+  s1482 = sbv_bv_extract_u32_23_16_u8(s292);
+  s1483 = table2[s1482];
+  s1484 = sbv_bv_extract_u32_15_8_u8(s292);
+  s1485 = table3[s1484];
+  s1486 = sbv_bv_extract_u32_7_0_u8(s292);
+  s1487 = table4[s1486];
+  s1488 = s1485 ^ s1487;
+  s1489 = s1483 ^ s1488;
+  s1490 = s1481 ^ s1489;
+  s1491 = table4[s1480];
+  s1492 = table1[s1482];
+  s1493 = table2[s1484];
+  s1494 = table3[s1486];
+  s1495 = s1493 ^ s1494;
+  s1496 = s1492 ^ s1495;
+  s1497 = s1491 ^ s1496;
+  s1498 = sbv_bv_join_u8_u8_u16(s1490, s1497);
+  s1499 = table3[s1480];
+  s1500 = table4[s1482];
+  s1501 = table1[s1484];
+  s1502 = table2[s1486];
+  s1503 = s1501 ^ s1502;
+  s1504 = s1500 ^ s1503;
+  s1505 = s1499 ^ s1504;
+  s1506 = table2[s1480];
+  s1507 = table3[s1482];
+  s1508 = table4[s1484];
+  s1509 = table1[s1486];
+  s1510 = s1508 ^ s1509;
+  s1511 = s1507 ^ s1510;
+  s1512 = s1506 ^ s1511;
+  s1513 = sbv_bv_join_u8_u8_u16(s1505, s1512);
+  s1514 = sbv_bv_join_u16_u16_u32(s1498, s1513);
+  s1515 = sbv_bv_extract_u32_31_24_u8(s293);
+  s1516 = table1[s1515];
+  s1517 = sbv_bv_extract_u32_23_16_u8(s293);
+  s1518 = table2[s1517];
+  s1519 = sbv_bv_extract_u32_15_8_u8(s293);
+  s1520 = table3[s1519];
+  s1521 = sbv_bv_extract_u32_7_0_u8(s293);
+  s1522 = table4[s1521];
+  s1523 = s1520 ^ s1522;
+  s1524 = s1518 ^ s1523;
+  s1525 = s1516 ^ s1524;
+  s1526 = table4[s1515];
+  s1527 = table1[s1517];
+  s1528 = table2[s1519];
+  s1529 = table3[s1521];
+  s1530 = s1528 ^ s1529;
+  s1531 = s1527 ^ s1530;
+  s1532 = s1526 ^ s1531;
+  s1533 = sbv_bv_join_u8_u8_u16(s1525, s1532);
+  s1534 = table3[s1515];
+  s1535 = table4[s1517];
+  s1536 = table1[s1519];
+  s1537 = table2[s1521];
+  s1538 = s1536 ^ s1537;
+  s1539 = s1535 ^ s1538;
+  s1540 = s1534 ^ s1539;
+  s1541 = table2[s1515];
+  s1542 = table3[s1517];
+  s1543 = table4[s1519];
+  s1544 = table1[s1521];
+  s1545 = s1543 ^ s1544;
+  s1546 = s1542 ^ s1545;
+  s1547 = s1541 ^ s1546;
+  s1548 = sbv_bv_join_u8_u8_u16(s1540, s1547);
+  s1549 = sbv_bv_join_u16_u16_u32(s1533, s1548);
+  s1550 = sbv_bv_extract_u32_31_24_u8(s273);
+  s1551 = table1[s1550];
+  s1552 = sbv_bv_extract_u32_23_16_u8(s273);
+  s1553 = table2[s1552];
+  s1554 = sbv_bv_extract_u32_15_8_u8(s273);
+  s1555 = table3[s1554];
+  s1556 = sbv_bv_extract_u32_7_0_u8(s273);
+  s1557 = table4[s1556];
+  s1558 = s1555 ^ s1557;
+  s1559 = s1553 ^ s1558;
+  s1560 = s1551 ^ s1559;
+  s1561 = table4[s1550];
+  s1562 = table1[s1552];
+  s1563 = table2[s1554];
+  s1564 = table3[s1556];
+  s1565 = s1563 ^ s1564;
+  s1566 = s1562 ^ s1565;
+  s1567 = s1561 ^ s1566;
+  s1568 = sbv_bv_join_u8_u8_u16(s1560, s1567);
+  s1569 = table3[s1550];
+  s1570 = table4[s1552];
+  s1571 = table1[s1554];
+  s1572 = table2[s1556];
+  s1573 = s1571 ^ s1572;
+  s1574 = s1570 ^ s1573;
+  s1575 = s1569 ^ s1574;
+  s1576 = table2[s1550];
+  s1577 = table3[s1552];
+  s1578 = table4[s1554];
+  s1579 = table1[s1556];
+  s1580 = s1578 ^ s1579;
+  s1581 = s1577 ^ s1580;
+  s1582 = s1576 ^ s1581;
+  s1583 = sbv_bv_join_u8_u8_u16(s1575, s1582);
+  s1584 = sbv_bv_join_u16_u16_u32(s1568, s1583);
+  s1585 = sbv_bv_extract_u32_31_24_u8(s274);
+  s1586 = table1[s1585];
+  s1587 = sbv_bv_extract_u32_23_16_u8(s274);
+  s1588 = table2[s1587];
+  s1589 = sbv_bv_extract_u32_15_8_u8(s274);
+  s1590 = table3[s1589];
+  s1591 = sbv_bv_extract_u32_7_0_u8(s274);
+  s1592 = table4[s1591];
+  s1593 = s1590 ^ s1592;
+  s1594 = s1588 ^ s1593;
+  s1595 = s1586 ^ s1594;
+  s1596 = table4[s1585];
+  s1597 = table1[s1587];
+  s1598 = table2[s1589];
+  s1599 = table3[s1591];
+  s1600 = s1598 ^ s1599;
+  s1601 = s1597 ^ s1600;
+  s1602 = s1596 ^ s1601;
+  s1603 = sbv_bv_join_u8_u8_u16(s1595, s1602);
+  s1604 = table3[s1585];
+  s1605 = table4[s1587];
+  s1606 = table1[s1589];
+  s1607 = table2[s1591];
+  s1608 = s1606 ^ s1607;
+  s1609 = s1605 ^ s1608;
+  s1610 = s1604 ^ s1609;
+  s1611 = table2[s1585];
+  s1612 = table3[s1587];
+  s1613 = table4[s1589];
+  s1614 = table1[s1591];
+  s1615 = s1613 ^ s1614;
+  s1616 = s1612 ^ s1615;
+  s1617 = s1611 ^ s1616;
+  s1618 = sbv_bv_join_u8_u8_u16(s1610, s1617);
+  s1619 = sbv_bv_join_u16_u16_u32(s1603, s1618);
+  s1620 = sbv_bv_extract_u32_31_24_u8(s275);
+  s1621 = table1[s1620];
+  s1622 = sbv_bv_extract_u32_23_16_u8(s275);
+  s1623 = table2[s1622];
+  s1624 = sbv_bv_extract_u32_15_8_u8(s275);
+  s1625 = table3[s1624];
+  s1626 = sbv_bv_extract_u32_7_0_u8(s275);
+  s1627 = table4[s1626];
+  s1628 = s1625 ^ s1627;
+  s1629 = s1623 ^ s1628;
+  s1630 = s1621 ^ s1629;
+  s1631 = table4[s1620];
+  s1632 = table1[s1622];
+  s1633 = table2[s1624];
+  s1634 = table3[s1626];
+  s1635 = s1633 ^ s1634;
+  s1636 = s1632 ^ s1635;
+  s1637 = s1631 ^ s1636;
+  s1638 = sbv_bv_join_u8_u8_u16(s1630, s1637);
+  s1639 = table3[s1620];
+  s1640 = table4[s1622];
+  s1641 = table1[s1624];
+  s1642 = table2[s1626];
+  s1643 = s1641 ^ s1642;
+  s1644 = s1640 ^ s1643;
+  s1645 = s1639 ^ s1644;
+  s1646 = table2[s1620];
+  s1647 = table3[s1622];
+  s1648 = table4[s1624];
+  s1649 = table1[s1626];
+  s1650 = s1648 ^ s1649;
+  s1651 = s1647 ^ s1650;
+  s1652 = s1646 ^ s1651;
+  s1653 = sbv_bv_join_u8_u8_u16(s1645, s1652);
+  s1654 = sbv_bv_join_u16_u16_u32(s1638, s1653);
+  s1655 = sbv_bv_extract_u32_31_24_u8(s276);
+  s1656 = table1[s1655];
+  s1657 = sbv_bv_extract_u32_23_16_u8(s276);
+  s1658 = table2[s1657];
+  s1659 = sbv_bv_extract_u32_15_8_u8(s276);
+  s1660 = table3[s1659];
+  s1661 = sbv_bv_extract_u32_7_0_u8(s276);
+  s1662 = table4[s1661];
+  s1663 = s1660 ^ s1662;
+  s1664 = s1658 ^ s1663;
+  s1665 = s1656 ^ s1664;
+  s1666 = table4[s1655];
+  s1667 = table1[s1657];
+  s1668 = table2[s1659];
+  s1669 = table3[s1661];
+  s1670 = s1668 ^ s1669;
+  s1671 = s1667 ^ s1670;
+  s1672 = s1666 ^ s1671;
+  s1673 = sbv_bv_join_u8_u8_u16(s1665, s1672);
+  s1674 = table3[s1655];
+  s1675 = table4[s1657];
+  s1676 = table1[s1659];
+  s1677 = table2[s1661];
+  s1678 = s1676 ^ s1677;
+  s1679 = s1675 ^ s1678;
+  s1680 = s1674 ^ s1679;
+  s1681 = table2[s1655];
+  s1682 = table3[s1657];
+  s1683 = table4[s1659];
+  s1684 = table1[s1661];
+  s1685 = s1683 ^ s1684;
+  s1686 = s1682 ^ s1685;
+  s1687 = s1681 ^ s1686;
+  s1688 = sbv_bv_join_u8_u8_u16(s1680, s1687);
+  s1689 = sbv_bv_join_u16_u16_u32(s1673, s1688);
+
+  sbv_output_0[0] = s0;
+  sbv_output_0[1] = s1;
+  sbv_output_0[2] = s2;
+  sbv_output_0[3] = s3;
+  sbv_output_0[4] = s273;
+  sbv_output_0[5] = s274;
+  sbv_output_0[6] = s275;
+  sbv_output_0[7] = s276;
+  sbv_output_0[8] = s290;
+  sbv_output_0[9] = s291;
+  sbv_output_0[10] = s292;
+  sbv_output_0[11] = s293;
+  sbv_output_0[12] = s307;
+  sbv_output_0[13] = s308;
+  sbv_output_0[14] = s309;
+  sbv_output_0[15] = s310;
+  sbv_output_0[16] = s324;
+  sbv_output_0[17] = s325;
+  sbv_output_0[18] = s326;
+  sbv_output_0[19] = s327;
+  sbv_output_0[20] = s341;
+  sbv_output_0[21] = s342;
+  sbv_output_0[22] = s343;
+  sbv_output_0[23] = s344;
+  sbv_output_0[24] = s358;
+  sbv_output_0[25] = s359;
+  sbv_output_0[26] = s360;
+  sbv_output_0[27] = s361;
+  sbv_output_0[28] = s375;
+  sbv_output_0[29] = s376;
+  sbv_output_0[30] = s377;
+  sbv_output_0[31] = s378;
+  sbv_output_0[32] = s392;
+  sbv_output_0[33] = s393;
+  sbv_output_0[34] = s394;
+  sbv_output_0[35] = s395;
+  sbv_output_0[36] = s409;
+  sbv_output_0[37] = s410;
+  sbv_output_0[38] = s411;
+  sbv_output_0[39] = s412;
+  sbv_output_0[40] = s426;
+  sbv_output_0[41] = s427;
+  sbv_output_0[42] = s428;
+  sbv_output_0[43] = s429;
+  sbv_output_1[0] = s426;
+  sbv_output_1[1] = s427;
+  sbv_output_1[2] = s428;
+  sbv_output_1[3] = s429;
+  sbv_output_1[4] = s464;
+  sbv_output_1[5] = s499;
+  sbv_output_1[6] = s534;
+  sbv_output_1[7] = s569;
+  sbv_output_1[8] = s604;
+  sbv_output_1[9] = s639;
+  sbv_output_1[10] = s674;
+  sbv_output_1[11] = s709;
+  sbv_output_1[12] = s744;
+  sbv_output_1[13] = s779;
+  sbv_output_1[14] = s814;
+  sbv_output_1[15] = s849;
+  sbv_output_1[16] = s884;
+  sbv_output_1[17] = s919;
+  sbv_output_1[18] = s954;
+  sbv_output_1[19] = s989;
+  sbv_output_1[20] = s1024;
+  sbv_output_1[21] = s1059;
+  sbv_output_1[22] = s1094;
+  sbv_output_1[23] = s1129;
+  sbv_output_1[24] = s1164;
+  sbv_output_1[25] = s1199;
+  sbv_output_1[26] = s1234;
+  sbv_output_1[27] = s1269;
+  sbv_output_1[28] = s1304;
+  sbv_output_1[29] = s1339;
+  sbv_output_1[30] = s1374;
+  sbv_output_1[31] = s1409;
+  sbv_output_1[32] = s1444;
+  sbv_output_1[33] = s1479;
+  sbv_output_1[34] = s1514;
+  sbv_output_1[35] = s1549;
+  sbv_output_1[36] = s1584;
+  sbv_output_1[37] = s1619;
+  sbv_output_1[38] = s1654;
+  sbv_output_1[39] = s1689;
+  sbv_output_1[40] = s0;
+  sbv_output_1[41] = s1;
+  sbv_output_1[42] = s2;
+  sbv_output_1[43] = s3;
+}
+== END: "aes128KeySchedule.c" ==================
+== BEGIN: "aes128BlockEncrypt.c" ================
+/* File: "aes128BlockEncrypt.c". Automatically generated by SBV. Do not edit! */
+
+#include "aes128Lib.h"
+
+/* Exact bit-vector runtime. All arithmetic is modulo the declared width. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_31_24_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 24)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_23_16_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 16)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_15_8_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 8)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_7_0_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord16 sbv_bv_join_u8_u8_u16(SWord8 high, SWord8 low)
+{
+  SWord16 r = (SWord16) 0; uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord16) ((uint64_t) r | ((uint64_t) (((((uint64_t) low) >> (i)) & UINT64_C(1)) != 0) << (i))); }
+  for (i = 0; i < 8; ++i) { r = (SWord16) ((uint64_t) r | ((uint64_t) (((((uint64_t) high) >> (i)) & UINT64_C(1)) != 0) << (i + 8))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord32 sbv_bv_join_u16_u16_u32(SWord16 high, SWord16 low)
+{
+  SWord32 r = (SWord32) 0; uint64_t i;
+  for (i = 0; i < 16; ++i) { r = (SWord32) ((uint64_t) r | ((uint64_t) (((((uint64_t) low) >> (i)) & UINT64_C(1)) != 0) << (i))); }
+  for (i = 0; i < 16; ++i) { r = (SWord32) ((uint64_t) r | ((uint64_t) (((((uint64_t) high) >> (i)) & UINT64_C(1)) != 0) << (i + 16))); }
+  return r;
+}
+
+
+void aes128BlockEncrypt(const SWord32 *sbv_input_0,
+                        const SWord32 *sbv_input_1, SWord32 *sbv_output_0)
+{
+  const SWord32 s0 = sbv_input_0[0];
+  const SWord32 s1 = sbv_input_0[1];
+  const SWord32 s2 = sbv_input_0[2];
+  const SWord32 s3 = sbv_input_0[3];
+  const SWord32 s4 = sbv_input_1[0];
+  const SWord32 s5 = sbv_input_1[1];
+  const SWord32 s6 = sbv_input_1[2];
+  const SWord32 s7 = sbv_input_1[3];
+  const SWord32 s8 = sbv_input_1[4];
+  const SWord32 s9 = sbv_input_1[5];
+  const SWord32 s10 = sbv_input_1[6];
+  const SWord32 s11 = sbv_input_1[7];
+  const SWord32 s12 = sbv_input_1[8];
+  const SWord32 s13 = sbv_input_1[9];
+  const SWord32 s14 = sbv_input_1[10];
+  const SWord32 s15 = sbv_input_1[11];
+  const SWord32 s16 = sbv_input_1[12];
+  const SWord32 s17 = sbv_input_1[13];
+  const SWord32 s18 = sbv_input_1[14];
+  const SWord32 s19 = sbv_input_1[15];
+  const SWord32 s20 = sbv_input_1[16];
+  const SWord32 s21 = sbv_input_1[17];
+  const SWord32 s22 = sbv_input_1[18];
+  const SWord32 s23 = sbv_input_1[19];
+  const SWord32 s24 = sbv_input_1[20];
+  const SWord32 s25 = sbv_input_1[21];
+  const SWord32 s26 = sbv_input_1[22];
+  const SWord32 s27 = sbv_input_1[23];
+  const SWord32 s28 = sbv_input_1[24];
+  const SWord32 s29 = sbv_input_1[25];
+  const SWord32 s30 = sbv_input_1[26];
+  const SWord32 s31 = sbv_input_1[27];
+  const SWord32 s32 = sbv_input_1[28];
+  const SWord32 s33 = sbv_input_1[29];
+  const SWord32 s34 = sbv_input_1[30];
+  const SWord32 s35 = sbv_input_1[31];
+  const SWord32 s36 = sbv_input_1[32];
+  const SWord32 s37 = sbv_input_1[33];
+  const SWord32 s38 = sbv_input_1[34];
+  const SWord32 s39 = sbv_input_1[35];
+  const SWord32 s40 = sbv_input_1[36];
+  const SWord32 s41 = sbv_input_1[37];
+  const SWord32 s42 = sbv_input_1[38];
+  const SWord32 s43 = sbv_input_1[39];
+  const SWord32 s44 = sbv_input_1[40];
+  const SWord32 s45 = sbv_input_1[41];
+  const SWord32 s46 = sbv_input_1[42];
+  const SWord32 s47 = sbv_input_1[43];
+  const SWord32 s560 = s0 ^ s4;
+  const SWord8  s561 = sbv_bv_extract_u32_31_24_u8(s560);
+  const SWord32 s818 = s1 ^ s5;
+  const SWord8  s819 = sbv_bv_extract_u32_23_16_u8(s818);
+  const SWord32 s1077 = s2 ^ s6;
+  const SWord8  s1078 = sbv_bv_extract_u32_15_8_u8(s1077);
+  const SWord32 s1336 = s3 ^ s7;
+  const SWord8  s1337 = sbv_bv_extract_u32_7_0_u8(s1336);
+  const SWord8  s1343 = sbv_bv_extract_u32_31_24_u8(s818);
+  const SWord8  s1345 = sbv_bv_extract_u32_23_16_u8(s1077);
+  const SWord8  s1348 = sbv_bv_extract_u32_15_8_u8(s1336);
+  const SWord8  s1351 = sbv_bv_extract_u32_7_0_u8(s560);
+  const SWord8  s1358 = sbv_bv_extract_u32_31_24_u8(s1077);
+  const SWord8  s1360 = sbv_bv_extract_u32_23_16_u8(s1336);
+  const SWord8  s1363 = sbv_bv_extract_u32_15_8_u8(s560);
+  const SWord8  s1366 = sbv_bv_extract_u32_7_0_u8(s818);
+  const SWord8  s1373 = sbv_bv_extract_u32_31_24_u8(s1336);
+  const SWord8  s1375 = sbv_bv_extract_u32_23_16_u8(s560);
+  const SWord8  s1378 = sbv_bv_extract_u32_15_8_u8(s818);
+  const SWord8  s1381 = sbv_bv_extract_u32_7_0_u8(s1077);
+        SWord32 s562;
+        SWord32 s820;
+        SWord32 s821;
+        SWord32 s1079;
+        SWord32 s1080;
+        SWord32 s1338;
+        SWord32 s1339;
+        SWord32 s1340;
+        SWord8  s1341;
+        SWord32 s1342;
+        SWord32 s1344;
+        SWord32 s1346;
+        SWord32 s1347;
+        SWord32 s1349;
+        SWord32 s1350;
+        SWord32 s1352;
+        SWord32 s1353;
+        SWord32 s1354;
+        SWord8  s1355;
+        SWord32 s1356;
+        SWord32 s1357;
+        SWord32 s1359;
+        SWord32 s1361;
+        SWord32 s1362;
+        SWord32 s1364;
+        SWord32 s1365;
+        SWord32 s1367;
+        SWord32 s1368;
+        SWord32 s1369;
+        SWord8  s1370;
+        SWord32 s1371;
+        SWord32 s1372;
+        SWord32 s1374;
+        SWord32 s1376;
+        SWord32 s1377;
+        SWord32 s1379;
+        SWord32 s1380;
+        SWord32 s1382;
+        SWord32 s1383;
+        SWord32 s1384;
+        SWord8  s1385;
+        SWord32 s1386;
+        SWord32 s1387;
+        SWord32 s1388;
+        SWord8  s1389;
+        SWord32 s1390;
+        SWord8  s1391;
+        SWord32 s1392;
+        SWord8  s1393;
+        SWord32 s1394;
+        SWord32 s1395;
+        SWord8  s1396;
+        SWord32 s1397;
+        SWord32 s1398;
+        SWord8  s1399;
+        SWord32 s1400;
+        SWord32 s1401;
+        SWord32 s1402;
+        SWord8  s1403;
+        SWord32 s1404;
+        SWord32 s1405;
+        SWord8  s1406;
+        SWord32 s1407;
+        SWord8  s1408;
+        SWord32 s1409;
+        SWord32 s1410;
+        SWord8  s1411;
+        SWord32 s1412;
+        SWord32 s1413;
+        SWord8  s1414;
+        SWord32 s1415;
+        SWord32 s1416;
+        SWord32 s1417;
+        SWord8  s1418;
+        SWord32 s1419;
+        SWord32 s1420;
+        SWord8  s1421;
+        SWord32 s1422;
+        SWord8  s1423;
+        SWord32 s1424;
+        SWord32 s1425;
+        SWord8  s1426;
+        SWord32 s1427;
+        SWord32 s1428;
+        SWord8  s1429;
+        SWord32 s1430;
+        SWord32 s1431;
+        SWord32 s1432;
+        SWord8  s1433;
+        SWord32 s1434;
+        SWord32 s1435;
+        SWord32 s1436;
+        SWord8  s1437;
+        SWord32 s1438;
+        SWord8  s1439;
+        SWord32 s1440;
+        SWord8  s1441;
+        SWord32 s1442;
+        SWord32 s1443;
+        SWord8  s1444;
+        SWord32 s1445;
+        SWord32 s1446;
+        SWord8  s1447;
+        SWord32 s1448;
+        SWord32 s1449;
+        SWord32 s1450;
+        SWord8  s1451;
+        SWord32 s1452;
+        SWord32 s1453;
+        SWord8  s1454;
+        SWord32 s1455;
+        SWord8  s1456;
+        SWord32 s1457;
+        SWord32 s1458;
+        SWord8  s1459;
+        SWord32 s1460;
+        SWord32 s1461;
+        SWord8  s1462;
+        SWord32 s1463;
+        SWord32 s1464;
+        SWord32 s1465;
+        SWord8  s1466;
+        SWord32 s1467;
+        SWord32 s1468;
+        SWord8  s1469;
+        SWord32 s1470;
+        SWord8  s1471;
+        SWord32 s1472;
+        SWord32 s1473;
+        SWord8  s1474;
+        SWord32 s1475;
+        SWord32 s1476;
+        SWord8  s1477;
+        SWord32 s1478;
+        SWord32 s1479;
+        SWord32 s1480;
+        SWord8  s1481;
+        SWord32 s1482;
+        SWord32 s1483;
+        SWord32 s1484;
+        SWord8  s1485;
+        SWord32 s1486;
+        SWord8  s1487;
+        SWord32 s1488;
+        SWord8  s1489;
+        SWord32 s1490;
+        SWord32 s1491;
+        SWord8  s1492;
+        SWord32 s1493;
+        SWord32 s1494;
+        SWord8  s1495;
+        SWord32 s1496;
+        SWord32 s1497;
+        SWord32 s1498;
+        SWord8  s1499;
+        SWord32 s1500;
+        SWord32 s1501;
+        SWord8  s1502;
+        SWord32 s1503;
+        SWord8  s1504;
+        SWord32 s1505;
+        SWord32 s1506;
+        SWord8  s1507;
+        SWord32 s1508;
+        SWord32 s1509;
+        SWord8  s1510;
+        SWord32 s1511;
+        SWord32 s1512;
+        SWord32 s1513;
+        SWord8  s1514;
+        SWord32 s1515;
+        SWord32 s1516;
+        SWord8  s1517;
+        SWord32 s1518;
+        SWord8  s1519;
+        SWord32 s1520;
+        SWord32 s1521;
+        SWord8  s1522;
+        SWord32 s1523;
+        SWord32 s1524;
+        SWord8  s1525;
+        SWord32 s1526;
+        SWord32 s1527;
+        SWord32 s1528;
+        SWord8  s1529;
+        SWord32 s1530;
+        SWord32 s1531;
+        SWord32 s1532;
+        SWord8  s1533;
+        SWord32 s1534;
+        SWord8  s1535;
+        SWord32 s1536;
+        SWord8  s1537;
+        SWord32 s1538;
+        SWord32 s1539;
+        SWord8  s1540;
+        SWord32 s1541;
+        SWord32 s1542;
+        SWord8  s1543;
+        SWord32 s1544;
+        SWord32 s1545;
+        SWord32 s1546;
+        SWord8  s1547;
+        SWord32 s1548;
+        SWord32 s1549;
+        SWord8  s1550;
+        SWord32 s1551;
+        SWord8  s1552;
+        SWord32 s1553;
+        SWord32 s1554;
+        SWord8  s1555;
+        SWord32 s1556;
+        SWord32 s1557;
+        SWord8  s1558;
+        SWord32 s1559;
+        SWord32 s1560;
+        SWord32 s1561;
+        SWord8  s1562;
+        SWord32 s1563;
+        SWord32 s1564;
+        SWord8  s1565;
+        SWord32 s1566;
+        SWord8  s1567;
+        SWord32 s1568;
+        SWord32 s1569;
+        SWord8  s1570;
+        SWord32 s1571;
+        SWord32 s1572;
+        SWord8  s1573;
+        SWord32 s1574;
+        SWord32 s1575;
+        SWord32 s1576;
+        SWord8  s1577;
+        SWord32 s1578;
+        SWord32 s1579;
+        SWord32 s1580;
+        SWord8  s1581;
+        SWord32 s1582;
+        SWord8  s1583;
+        SWord32 s1584;
+        SWord8  s1585;
+        SWord32 s1586;
+        SWord32 s1587;
+        SWord8  s1588;
+        SWord32 s1589;
+        SWord32 s1590;
+        SWord8  s1591;
+        SWord32 s1592;
+        SWord32 s1593;
+        SWord32 s1594;
+        SWord8  s1595;
+        SWord32 s1596;
+        SWord32 s1597;
+        SWord8  s1598;
+        SWord32 s1599;
+        SWord8  s1600;
+        SWord32 s1601;
+        SWord32 s1602;
+        SWord8  s1603;
+        SWord32 s1604;
+        SWord32 s1605;
+        SWord8  s1606;
+        SWord32 s1607;
+        SWord32 s1608;
+        SWord32 s1609;
+        SWord8  s1610;
+        SWord32 s1611;
+        SWord32 s1612;
+        SWord8  s1613;
+        SWord32 s1614;
+        SWord8  s1615;
+        SWord32 s1616;
+        SWord32 s1617;
+        SWord8  s1618;
+        SWord32 s1619;
+        SWord32 s1620;
+        SWord8  s1621;
+        SWord32 s1622;
+        SWord32 s1623;
+        SWord32 s1624;
+        SWord8  s1625;
+        SWord32 s1626;
+        SWord32 s1627;
+        SWord32 s1628;
+        SWord8  s1629;
+        SWord32 s1630;
+        SWord8  s1631;
+        SWord32 s1632;
+        SWord8  s1633;
+        SWord32 s1634;
+        SWord32 s1635;
+        SWord8  s1636;
+        SWord32 s1637;
+        SWord32 s1638;
+        SWord8  s1639;
+        SWord32 s1640;
+        SWord32 s1641;
+        SWord32 s1642;
+        SWord8  s1643;
+        SWord32 s1644;
+        SWord32 s1645;
+        SWord8  s1646;
+        SWord32 s1647;
+        SWord8  s1648;
+        SWord32 s1649;
+        SWord32 s1650;
+        SWord8  s1651;
+        SWord32 s1652;
+        SWord32 s1653;
+        SWord8  s1654;
+        SWord32 s1655;
+        SWord32 s1656;
+        SWord32 s1657;
+        SWord8  s1658;
+        SWord32 s1659;
+        SWord32 s1660;
+        SWord8  s1661;
+        SWord32 s1662;
+        SWord8  s1663;
+        SWord32 s1664;
+        SWord32 s1665;
+        SWord8  s1666;
+        SWord32 s1667;
+        SWord32 s1668;
+        SWord8  s1669;
+        SWord32 s1670;
+        SWord32 s1671;
+        SWord32 s1672;
+        SWord8  s1673;
+        SWord32 s1674;
+        SWord32 s1675;
+        SWord32 s1676;
+        SWord8  s1677;
+        SWord32 s1678;
+        SWord8  s1679;
+        SWord32 s1680;
+        SWord8  s1681;
+        SWord32 s1682;
+        SWord32 s1683;
+        SWord8  s1684;
+        SWord32 s1685;
+        SWord32 s1686;
+        SWord8  s1687;
+        SWord32 s1688;
+        SWord32 s1689;
+        SWord32 s1690;
+        SWord8  s1691;
+        SWord32 s1692;
+        SWord32 s1693;
+        SWord8  s1694;
+        SWord32 s1695;
+        SWord8  s1696;
+        SWord32 s1697;
+        SWord32 s1698;
+        SWord8  s1699;
+        SWord32 s1700;
+        SWord32 s1701;
+        SWord8  s1702;
+        SWord32 s1703;
+        SWord32 s1704;
+        SWord32 s1705;
+        SWord8  s1706;
+        SWord32 s1707;
+        SWord32 s1708;
+        SWord8  s1709;
+        SWord32 s1710;
+        SWord8  s1711;
+        SWord32 s1712;
+        SWord32 s1713;
+        SWord8  s1714;
+        SWord32 s1715;
+        SWord32 s1716;
+        SWord8  s1717;
+        SWord32 s1718;
+        SWord32 s1719;
+        SWord32 s1720;
+        SWord8  s1721;
+        SWord32 s1722;
+        SWord32 s1723;
+        SWord32 s1724;
+        SWord8  s1725;
+        SWord8  s1726;
+        SWord8  s1727;
+        SWord32 s1728;
+        SWord8  s1729;
+        SWord32 s1730;
+        SWord32 s1731;
+        SWord8  s1732;
+        SWord32 s1733;
+        SWord32 s1734;
+        SWord8  s1735;
+        SWord32 s1736;
+        SWord32 s1737;
+        SWord32 s1738;
+        SWord8  s1739;
+        SWord8  s1740;
+        SWord16 s1741;
+        SWord8  s1742;
+        SWord32 s1743;
+        SWord8  s1744;
+        SWord32 s1745;
+        SWord32 s1746;
+        SWord8  s1747;
+        SWord32 s1748;
+        SWord32 s1749;
+        SWord8  s1750;
+        SWord32 s1751;
+        SWord32 s1752;
+        SWord32 s1753;
+        SWord8  s1754;
+        SWord8  s1755;
+        SWord8  s1756;
+        SWord32 s1757;
+        SWord8  s1758;
+        SWord32 s1759;
+        SWord32 s1760;
+        SWord8  s1761;
+        SWord32 s1762;
+        SWord32 s1763;
+        SWord8  s1764;
+        SWord32 s1765;
+        SWord32 s1766;
+        SWord32 s1767;
+        SWord8  s1768;
+        SWord8  s1769;
+        SWord16 s1770;
+        SWord32 s1771;
+        SWord32 s1772;
+        SWord8  s1773;
+        SWord8  s1774;
+        SWord8  s1775;
+        SWord8  s1776;
+        SWord16 s1777;
+        SWord8  s1778;
+        SWord8  s1779;
+        SWord8  s1780;
+        SWord8  s1781;
+        SWord16 s1782;
+        SWord32 s1783;
+        SWord32 s1784;
+        SWord8  s1785;
+        SWord8  s1786;
+        SWord8  s1787;
+        SWord8  s1788;
+        SWord16 s1789;
+        SWord8  s1790;
+        SWord8  s1791;
+        SWord8  s1792;
+        SWord8  s1793;
+        SWord16 s1794;
+        SWord32 s1795;
+        SWord32 s1796;
+        SWord8  s1797;
+        SWord8  s1798;
+        SWord8  s1799;
+        SWord8  s1800;
+        SWord16 s1801;
+        SWord8  s1802;
+        SWord8  s1803;
+        SWord8  s1804;
+        SWord8  s1805;
+        SWord16 s1806;
+        SWord32 s1807;
+        SWord32 s1808;
+  static const SWord32 table1[] = {
+      0xc66363a5UL, 0xf87c7c84UL, 0xee777799UL, 0xf67b7b8dUL,
+      0xfff2f20dUL, 0xd66b6bbdUL, 0xde6f6fb1UL, 0x91c5c554UL,
+      0x60303050UL, 0x02010103UL, 0xce6767a9UL, 0x562b2b7dUL,
+      0xe7fefe19UL, 0xb5d7d762UL, 0x4dababe6UL, 0xec76769aUL,
+      0x8fcaca45UL, 0x1f82829dUL, 0x89c9c940UL, 0xfa7d7d87UL,
+      0xeffafa15UL, 0xb25959ebUL, 0x8e4747c9UL, 0xfbf0f00bUL,
+      0x41adadecUL, 0xb3d4d467UL, 0x5fa2a2fdUL, 0x45afafeaUL,
+      0x239c9cbfUL, 0x53a4a4f7UL, 0xe4727296UL, 0x9bc0c05bUL,
+      0x75b7b7c2UL, 0xe1fdfd1cUL, 0x3d9393aeUL, 0x4c26266aUL,
+      0x6c36365aUL, 0x7e3f3f41UL, 0xf5f7f702UL, 0x83cccc4fUL,
+      0x6834345cUL, 0x51a5a5f4UL, 0xd1e5e534UL, 0xf9f1f108UL,
+      0xe2717193UL, 0xabd8d873UL, 0x62313153UL, 0x2a15153fUL,
+      0x0804040cUL, 0x95c7c752UL, 0x46232365UL, 0x9dc3c35eUL,
+      0x30181828UL, 0x379696a1UL, 0x0a05050fUL, 0x2f9a9ab5UL,
+      0x0e070709UL, 0x24121236UL, 0x1b80809bUL, 0xdfe2e23dUL,
+      0xcdebeb26UL, 0x4e272769UL, 0x7fb2b2cdUL, 0xea75759fUL,
+      0x1209091bUL, 0x1d83839eUL, 0x582c2c74UL, 0x341a1a2eUL,
+      0x361b1b2dUL, 0xdc6e6eb2UL, 0xb45a5aeeUL, 0x5ba0a0fbUL,
+      0xa45252f6UL, 0x763b3b4dUL, 0xb7d6d661UL, 0x7db3b3ceUL,
+      0x5229297bUL, 0xdde3e33eUL, 0x5e2f2f71UL, 0x13848497UL,
+      0xa65353f5UL, 0xb9d1d168UL, 0x00000000UL, 0xc1eded2cUL,
+      0x40202060UL, 0xe3fcfc1fUL, 0x79b1b1c8UL, 0xb65b5bedUL,
+      0xd46a6abeUL, 0x8dcbcb46UL, 0x67bebed9UL, 0x7239394bUL,
+      0x944a4adeUL, 0x984c4cd4UL, 0xb05858e8UL, 0x85cfcf4aUL,
+      0xbbd0d06bUL, 0xc5efef2aUL, 0x4faaaae5UL, 0xedfbfb16UL,
+      0x864343c5UL, 0x9a4d4dd7UL, 0x66333355UL, 0x11858594UL,
+      0x8a4545cfUL, 0xe9f9f910UL, 0x04020206UL, 0xfe7f7f81UL,
+      0xa05050f0UL, 0x783c3c44UL, 0x259f9fbaUL, 0x4ba8a8e3UL,
+      0xa25151f3UL, 0x5da3a3feUL, 0x804040c0UL, 0x058f8f8aUL,
+      0x3f9292adUL, 0x219d9dbcUL, 0x70383848UL, 0xf1f5f504UL,
+      0x63bcbcdfUL, 0x77b6b6c1UL, 0xafdada75UL, 0x42212163UL,
+      0x20101030UL, 0xe5ffff1aUL, 0xfdf3f30eUL, 0xbfd2d26dUL,
+      0x81cdcd4cUL, 0x180c0c14UL, 0x26131335UL, 0xc3ecec2fUL,
+      0xbe5f5fe1UL, 0x359797a2UL, 0x884444ccUL, 0x2e171739UL,
+      0x93c4c457UL, 0x55a7a7f2UL, 0xfc7e7e82UL, 0x7a3d3d47UL,
+      0xc86464acUL, 0xba5d5de7UL, 0x3219192bUL, 0xe6737395UL,
+      0xc06060a0UL, 0x19818198UL, 0x9e4f4fd1UL, 0xa3dcdc7fUL,
+      0x44222266UL, 0x542a2a7eUL, 0x3b9090abUL, 0x0b888883UL,
+      0x8c4646caUL, 0xc7eeee29UL, 0x6bb8b8d3UL, 0x2814143cUL,
+      0xa7dede79UL, 0xbc5e5ee2UL, 0x160b0b1dUL, 0xaddbdb76UL,
+      0xdbe0e03bUL, 0x64323256UL, 0x743a3a4eUL, 0x140a0a1eUL,
+      0x924949dbUL, 0x0c06060aUL, 0x4824246cUL, 0xb85c5ce4UL,
+      0x9fc2c25dUL, 0xbdd3d36eUL, 0x43acacefUL, 0xc46262a6UL,
+      0x399191a8UL, 0x319595a4UL, 0xd3e4e437UL, 0xf279798bUL,
+      0xd5e7e732UL, 0x8bc8c843UL, 0x6e373759UL, 0xda6d6db7UL,
+      0x018d8d8cUL, 0xb1d5d564UL, 0x9c4e4ed2UL, 0x49a9a9e0UL,
+      0xd86c6cb4UL, 0xac5656faUL, 0xf3f4f407UL, 0xcfeaea25UL,
+      0xca6565afUL, 0xf47a7a8eUL, 0x47aeaee9UL, 0x10080818UL,
+      0x6fbabad5UL, 0xf0787888UL, 0x4a25256fUL, 0x5c2e2e72UL,
+      0x381c1c24UL, 0x57a6a6f1UL, 0x73b4b4c7UL, 0x97c6c651UL,
+      0xcbe8e823UL, 0xa1dddd7cUL, 0xe874749cUL, 0x3e1f1f21UL,
+      0x964b4bddUL, 0x61bdbddcUL, 0x0d8b8b86UL, 0x0f8a8a85UL,
+      0xe0707090UL, 0x7c3e3e42UL, 0x71b5b5c4UL, 0xcc6666aaUL,
+      0x904848d8UL, 0x06030305UL, 0xf7f6f601UL, 0x1c0e0e12UL,
+      0xc26161a3UL, 0x6a35355fUL, 0xae5757f9UL, 0x69b9b9d0UL,
+      0x17868691UL, 0x99c1c158UL, 0x3a1d1d27UL, 0x279e9eb9UL,
+      0xd9e1e138UL, 0xebf8f813UL, 0x2b9898b3UL, 0x22111133UL,
+      0xd26969bbUL, 0xa9d9d970UL, 0x078e8e89UL, 0x339494a7UL,
+      0x2d9b9bb6UL, 0x3c1e1e22UL, 0x15878792UL, 0xc9e9e920UL,
+      0x87cece49UL, 0xaa5555ffUL, 0x50282878UL, 0xa5dfdf7aUL,
+      0x038c8c8fUL, 0x59a1a1f8UL, 0x09898980UL, 0x1a0d0d17UL,
+      0x65bfbfdaUL, 0xd7e6e631UL, 0x844242c6UL, 0xd06868b8UL,
+      0x824141c3UL, 0x299999b0UL, 0x5a2d2d77UL, 0x1e0f0f11UL,
+      0x7bb0b0cbUL, 0xa85454fcUL, 0x6dbbbbd6UL, 0x2c16163aUL
+  };
+  s562 = table1[s561];
+  static const SWord32 table2[] = {
+      0xa5c66363UL, 0x84f87c7cUL, 0x99ee7777UL, 0x8df67b7bUL,
+      0x0dfff2f2UL, 0xbdd66b6bUL, 0xb1de6f6fUL, 0x5491c5c5UL,
+      0x50603030UL, 0x03020101UL, 0xa9ce6767UL, 0x7d562b2bUL,
+      0x19e7fefeUL, 0x62b5d7d7UL, 0xe64dababUL, 0x9aec7676UL,
+      0x458fcacaUL, 0x9d1f8282UL, 0x4089c9c9UL, 0x87fa7d7dUL,
+      0x15effafaUL, 0xebb25959UL, 0xc98e4747UL, 0x0bfbf0f0UL,
+      0xec41adadUL, 0x67b3d4d4UL, 0xfd5fa2a2UL, 0xea45afafUL,
+      0xbf239c9cUL, 0xf753a4a4UL, 0x96e47272UL, 0x5b9bc0c0UL,
+      0xc275b7b7UL, 0x1ce1fdfdUL, 0xae3d9393UL, 0x6a4c2626UL,
+      0x5a6c3636UL, 0x417e3f3fUL, 0x02f5f7f7UL, 0x4f83ccccUL,
+      0x5c683434UL, 0xf451a5a5UL, 0x34d1e5e5UL, 0x08f9f1f1UL,
+      0x93e27171UL, 0x73abd8d8UL, 0x53623131UL, 0x3f2a1515UL,
+      0x0c080404UL, 0x5295c7c7UL, 0x65462323UL, 0x5e9dc3c3UL,
+      0x28301818UL, 0xa1379696UL, 0x0f0a0505UL, 0xb52f9a9aUL,
+      0x090e0707UL, 0x36241212UL, 0x9b1b8080UL, 0x3ddfe2e2UL,
+      0x26cdebebUL, 0x694e2727UL, 0xcd7fb2b2UL, 0x9fea7575UL,
+      0x1b120909UL, 0x9e1d8383UL, 0x74582c2cUL, 0x2e341a1aUL,
+      0x2d361b1bUL, 0xb2dc6e6eUL, 0xeeb45a5aUL, 0xfb5ba0a0UL,
+      0xf6a45252UL, 0x4d763b3bUL, 0x61b7d6d6UL, 0xce7db3b3UL,
+      0x7b522929UL, 0x3edde3e3UL, 0x715e2f2fUL, 0x97138484UL,
+      0xf5a65353UL, 0x68b9d1d1UL, 0x00000000UL, 0x2cc1ededUL,
+      0x60402020UL, 0x1fe3fcfcUL, 0xc879b1b1UL, 0xedb65b5bUL,
+      0xbed46a6aUL, 0x468dcbcbUL, 0xd967bebeUL, 0x4b723939UL,
+      0xde944a4aUL, 0xd4984c4cUL, 0xe8b05858UL, 0x4a85cfcfUL,
+      0x6bbbd0d0UL, 0x2ac5efefUL, 0xe54faaaaUL, 0x16edfbfbUL,
+      0xc5864343UL, 0xd79a4d4dUL, 0x55663333UL, 0x94118585UL,
+      0xcf8a4545UL, 0x10e9f9f9UL, 0x06040202UL, 0x81fe7f7fUL,
+      0xf0a05050UL, 0x44783c3cUL, 0xba259f9fUL, 0xe34ba8a8UL,
+      0xf3a25151UL, 0xfe5da3a3UL, 0xc0804040UL, 0x8a058f8fUL,
+      0xad3f9292UL, 0xbc219d9dUL, 0x48703838UL, 0x04f1f5f5UL,
+      0xdf63bcbcUL, 0xc177b6b6UL, 0x75afdadaUL, 0x63422121UL,
+      0x30201010UL, 0x1ae5ffffUL, 0x0efdf3f3UL, 0x6dbfd2d2UL,
+      0x4c81cdcdUL, 0x14180c0cUL, 0x35261313UL, 0x2fc3ececUL,
+      0xe1be5f5fUL, 0xa2359797UL, 0xcc884444UL, 0x392e1717UL,
+      0x5793c4c4UL, 0xf255a7a7UL, 0x82fc7e7eUL, 0x477a3d3dUL,
+      0xacc86464UL, 0xe7ba5d5dUL, 0x2b321919UL, 0x95e67373UL,
+      0xa0c06060UL, 0x98198181UL, 0xd19e4f4fUL, 0x7fa3dcdcUL,
+      0x66442222UL, 0x7e542a2aUL, 0xab3b9090UL, 0x830b8888UL,
+      0xca8c4646UL, 0x29c7eeeeUL, 0xd36bb8b8UL, 0x3c281414UL,
+      0x79a7dedeUL, 0xe2bc5e5eUL, 0x1d160b0bUL, 0x76addbdbUL,
+      0x3bdbe0e0UL, 0x56643232UL, 0x4e743a3aUL, 0x1e140a0aUL,
+      0xdb924949UL, 0x0a0c0606UL, 0x6c482424UL, 0xe4b85c5cUL,
+      0x5d9fc2c2UL, 0x6ebdd3d3UL, 0xef43acacUL, 0xa6c46262UL,
+      0xa8399191UL, 0xa4319595UL, 0x37d3e4e4UL, 0x8bf27979UL,
+      0x32d5e7e7UL, 0x438bc8c8UL, 0x596e3737UL, 0xb7da6d6dUL,
+      0x8c018d8dUL, 0x64b1d5d5UL, 0xd29c4e4eUL, 0xe049a9a9UL,
+      0xb4d86c6cUL, 0xfaac5656UL, 0x07f3f4f4UL, 0x25cfeaeaUL,
+      0xafca6565UL, 0x8ef47a7aUL, 0xe947aeaeUL, 0x18100808UL,
+      0xd56fbabaUL, 0x88f07878UL, 0x6f4a2525UL, 0x725c2e2eUL,
+      0x24381c1cUL, 0xf157a6a6UL, 0xc773b4b4UL, 0x5197c6c6UL,
+      0x23cbe8e8UL, 0x7ca1ddddUL, 0x9ce87474UL, 0x213e1f1fUL,
+      0xdd964b4bUL, 0xdc61bdbdUL, 0x860d8b8bUL, 0x850f8a8aUL,
+      0x90e07070UL, 0x427c3e3eUL, 0xc471b5b5UL, 0xaacc6666UL,
+      0xd8904848UL, 0x05060303UL, 0x01f7f6f6UL, 0x121c0e0eUL,
+      0xa3c26161UL, 0x5f6a3535UL, 0xf9ae5757UL, 0xd069b9b9UL,
+      0x91178686UL, 0x5899c1c1UL, 0x273a1d1dUL, 0xb9279e9eUL,
+      0x38d9e1e1UL, 0x13ebf8f8UL, 0xb32b9898UL, 0x33221111UL,
+      0xbbd26969UL, 0x70a9d9d9UL, 0x89078e8eUL, 0xa7339494UL,
+      0xb62d9b9bUL, 0x223c1e1eUL, 0x92158787UL, 0x20c9e9e9UL,
+      0x4987ceceUL, 0xffaa5555UL, 0x78502828UL, 0x7aa5dfdfUL,
+      0x8f038c8cUL, 0xf859a1a1UL, 0x80098989UL, 0x171a0d0dUL,
+      0xda65bfbfUL, 0x31d7e6e6UL, 0xc6844242UL, 0xb8d06868UL,
+      0xc3824141UL, 0xb0299999UL, 0x775a2d2dUL, 0x111e0f0fUL,
+      0xcb7bb0b0UL, 0xfca85454UL, 0xd66dbbbbUL, 0x3a2c1616UL
+  };
+  s820 = table2[s819];
+  s821 = s562 ^ s820;
+  static const SWord32 table3[] = {
+      0x63a5c663UL, 0x7c84f87cUL, 0x7799ee77UL, 0x7b8df67bUL,
+      0xf20dfff2UL, 0x6bbdd66bUL, 0x6fb1de6fUL, 0xc55491c5UL,
+      0x30506030UL, 0x01030201UL, 0x67a9ce67UL, 0x2b7d562bUL,
+      0xfe19e7feUL, 0xd762b5d7UL, 0xabe64dabUL, 0x769aec76UL,
+      0xca458fcaUL, 0x829d1f82UL, 0xc94089c9UL, 0x7d87fa7dUL,
+      0xfa15effaUL, 0x59ebb259UL, 0x47c98e47UL, 0xf00bfbf0UL,
+      0xadec41adUL, 0xd467b3d4UL, 0xa2fd5fa2UL, 0xafea45afUL,
+      0x9cbf239cUL, 0xa4f753a4UL, 0x7296e472UL, 0xc05b9bc0UL,
+      0xb7c275b7UL, 0xfd1ce1fdUL, 0x93ae3d93UL, 0x266a4c26UL,
+      0x365a6c36UL, 0x3f417e3fUL, 0xf702f5f7UL, 0xcc4f83ccUL,
+      0x345c6834UL, 0xa5f451a5UL, 0xe534d1e5UL, 0xf108f9f1UL,
+      0x7193e271UL, 0xd873abd8UL, 0x31536231UL, 0x153f2a15UL,
+      0x040c0804UL, 0xc75295c7UL, 0x23654623UL, 0xc35e9dc3UL,
+      0x18283018UL, 0x96a13796UL, 0x050f0a05UL, 0x9ab52f9aUL,
+      0x07090e07UL, 0x12362412UL, 0x809b1b80UL, 0xe23ddfe2UL,
+      0xeb26cdebUL, 0x27694e27UL, 0xb2cd7fb2UL, 0x759fea75UL,
+      0x091b1209UL, 0x839e1d83UL, 0x2c74582cUL, 0x1a2e341aUL,
+      0x1b2d361bUL, 0x6eb2dc6eUL, 0x5aeeb45aUL, 0xa0fb5ba0UL,
+      0x52f6a452UL, 0x3b4d763bUL, 0xd661b7d6UL, 0xb3ce7db3UL,
+      0x297b5229UL, 0xe33edde3UL, 0x2f715e2fUL, 0x84971384UL,
+      0x53f5a653UL, 0xd168b9d1UL, 0x00000000UL, 0xed2cc1edUL,
+      0x20604020UL, 0xfc1fe3fcUL, 0xb1c879b1UL, 0x5bedb65bUL,
+      0x6abed46aUL, 0xcb468dcbUL, 0xbed967beUL, 0x394b7239UL,
+      0x4ade944aUL, 0x4cd4984cUL, 0x58e8b058UL, 0xcf4a85cfUL,
+      0xd06bbbd0UL, 0xef2ac5efUL, 0xaae54faaUL, 0xfb16edfbUL,
+      0x43c58643UL, 0x4dd79a4dUL, 0x33556633UL, 0x85941185UL,
+      0x45cf8a45UL, 0xf910e9f9UL, 0x02060402UL, 0x7f81fe7fUL,
+      0x50f0a050UL, 0x3c44783cUL, 0x9fba259fUL, 0xa8e34ba8UL,
+      0x51f3a251UL, 0xa3fe5da3UL, 0x40c08040UL, 0x8f8a058fUL,
+      0x92ad3f92UL, 0x9dbc219dUL, 0x38487038UL, 0xf504f1f5UL,
+      0xbcdf63bcUL, 0xb6c177b6UL, 0xda75afdaUL, 0x21634221UL,
+      0x10302010UL, 0xff1ae5ffUL, 0xf30efdf3UL, 0xd26dbfd2UL,
+      0xcd4c81cdUL, 0x0c14180cUL, 0x13352613UL, 0xec2fc3ecUL,
+      0x5fe1be5fUL, 0x97a23597UL, 0x44cc8844UL, 0x17392e17UL,
+      0xc45793c4UL, 0xa7f255a7UL, 0x7e82fc7eUL, 0x3d477a3dUL,
+      0x64acc864UL, 0x5de7ba5dUL, 0x192b3219UL, 0x7395e673UL,
+      0x60a0c060UL, 0x81981981UL, 0x4fd19e4fUL, 0xdc7fa3dcUL,
+      0x22664422UL, 0x2a7e542aUL, 0x90ab3b90UL, 0x88830b88UL,
+      0x46ca8c46UL, 0xee29c7eeUL, 0xb8d36bb8UL, 0x143c2814UL,
+      0xde79a7deUL, 0x5ee2bc5eUL, 0x0b1d160bUL, 0xdb76addbUL,
+      0xe03bdbe0UL, 0x32566432UL, 0x3a4e743aUL, 0x0a1e140aUL,
+      0x49db9249UL, 0x060a0c06UL, 0x246c4824UL, 0x5ce4b85cUL,
+      0xc25d9fc2UL, 0xd36ebdd3UL, 0xacef43acUL, 0x62a6c462UL,
+      0x91a83991UL, 0x95a43195UL, 0xe437d3e4UL, 0x798bf279UL,
+      0xe732d5e7UL, 0xc8438bc8UL, 0x37596e37UL, 0x6db7da6dUL,
+      0x8d8c018dUL, 0xd564b1d5UL, 0x4ed29c4eUL, 0xa9e049a9UL,
+      0x6cb4d86cUL, 0x56faac56UL, 0xf407f3f4UL, 0xea25cfeaUL,
+      0x65afca65UL, 0x7a8ef47aUL, 0xaee947aeUL, 0x08181008UL,
+      0xbad56fbaUL, 0x7888f078UL, 0x256f4a25UL, 0x2e725c2eUL,
+      0x1c24381cUL, 0xa6f157a6UL, 0xb4c773b4UL, 0xc65197c6UL,
+      0xe823cbe8UL, 0xdd7ca1ddUL, 0x749ce874UL, 0x1f213e1fUL,
+      0x4bdd964bUL, 0xbddc61bdUL, 0x8b860d8bUL, 0x8a850f8aUL,
+      0x7090e070UL, 0x3e427c3eUL, 0xb5c471b5UL, 0x66aacc66UL,
+      0x48d89048UL, 0x03050603UL, 0xf601f7f6UL, 0x0e121c0eUL,
+      0x61a3c261UL, 0x355f6a35UL, 0x57f9ae57UL, 0xb9d069b9UL,
+      0x86911786UL, 0xc15899c1UL, 0x1d273a1dUL, 0x9eb9279eUL,
+      0xe138d9e1UL, 0xf813ebf8UL, 0x98b32b98UL, 0x11332211UL,
+      0x69bbd269UL, 0xd970a9d9UL, 0x8e89078eUL, 0x94a73394UL,
+      0x9bb62d9bUL, 0x1e223c1eUL, 0x87921587UL, 0xe920c9e9UL,
+      0xce4987ceUL, 0x55ffaa55UL, 0x28785028UL, 0xdf7aa5dfUL,
+      0x8c8f038cUL, 0xa1f859a1UL, 0x89800989UL, 0x0d171a0dUL,
+      0xbfda65bfUL, 0xe631d7e6UL, 0x42c68442UL, 0x68b8d068UL,
+      0x41c38241UL, 0x99b02999UL, 0x2d775a2dUL, 0x0f111e0fUL,
+      0xb0cb7bb0UL, 0x54fca854UL, 0xbbd66dbbUL, 0x163a2c16UL
+  };
+  s1079 = table3[s1078];
+  s1080 = s821 ^ s1079;
+  static const SWord32 table4[] = {
+      0x6363a5c6UL, 0x7c7c84f8UL, 0x777799eeUL, 0x7b7b8df6UL,
+      0xf2f20dffUL, 0x6b6bbdd6UL, 0x6f6fb1deUL, 0xc5c55491UL,
+      0x30305060UL, 0x01010302UL, 0x6767a9ceUL, 0x2b2b7d56UL,
+      0xfefe19e7UL, 0xd7d762b5UL, 0xababe64dUL, 0x76769aecUL,
+      0xcaca458fUL, 0x82829d1fUL, 0xc9c94089UL, 0x7d7d87faUL,
+      0xfafa15efUL, 0x5959ebb2UL, 0x4747c98eUL, 0xf0f00bfbUL,
+      0xadadec41UL, 0xd4d467b3UL, 0xa2a2fd5fUL, 0xafafea45UL,
+      0x9c9cbf23UL, 0xa4a4f753UL, 0x727296e4UL, 0xc0c05b9bUL,
+      0xb7b7c275UL, 0xfdfd1ce1UL, 0x9393ae3dUL, 0x26266a4cUL,
+      0x36365a6cUL, 0x3f3f417eUL, 0xf7f702f5UL, 0xcccc4f83UL,
+      0x34345c68UL, 0xa5a5f451UL, 0xe5e534d1UL, 0xf1f108f9UL,
+      0x717193e2UL, 0xd8d873abUL, 0x31315362UL, 0x15153f2aUL,
+      0x04040c08UL, 0xc7c75295UL, 0x23236546UL, 0xc3c35e9dUL,
+      0x18182830UL, 0x9696a137UL, 0x05050f0aUL, 0x9a9ab52fUL,
+      0x0707090eUL, 0x12123624UL, 0x80809b1bUL, 0xe2e23ddfUL,
+      0xebeb26cdUL, 0x2727694eUL, 0xb2b2cd7fUL, 0x75759feaUL,
+      0x09091b12UL, 0x83839e1dUL, 0x2c2c7458UL, 0x1a1a2e34UL,
+      0x1b1b2d36UL, 0x6e6eb2dcUL, 0x5a5aeeb4UL, 0xa0a0fb5bUL,
+      0x5252f6a4UL, 0x3b3b4d76UL, 0xd6d661b7UL, 0xb3b3ce7dUL,
+      0x29297b52UL, 0xe3e33eddUL, 0x2f2f715eUL, 0x84849713UL,
+      0x5353f5a6UL, 0xd1d168b9UL, 0x00000000UL, 0xeded2cc1UL,
+      0x20206040UL, 0xfcfc1fe3UL, 0xb1b1c879UL, 0x5b5bedb6UL,
+      0x6a6abed4UL, 0xcbcb468dUL, 0xbebed967UL, 0x39394b72UL,
+      0x4a4ade94UL, 0x4c4cd498UL, 0x5858e8b0UL, 0xcfcf4a85UL,
+      0xd0d06bbbUL, 0xefef2ac5UL, 0xaaaae54fUL, 0xfbfb16edUL,
+      0x4343c586UL, 0x4d4dd79aUL, 0x33335566UL, 0x85859411UL,
+      0x4545cf8aUL, 0xf9f910e9UL, 0x02020604UL, 0x7f7f81feUL,
+      0x5050f0a0UL, 0x3c3c4478UL, 0x9f9fba25UL, 0xa8a8e34bUL,
+      0x5151f3a2UL, 0xa3a3fe5dUL, 0x4040c080UL, 0x8f8f8a05UL,
+      0x9292ad3fUL, 0x9d9dbc21UL, 0x38384870UL, 0xf5f504f1UL,
+      0xbcbcdf63UL, 0xb6b6c177UL, 0xdada75afUL, 0x21216342UL,
+      0x10103020UL, 0xffff1ae5UL, 0xf3f30efdUL, 0xd2d26dbfUL,
+      0xcdcd4c81UL, 0x0c0c1418UL, 0x13133526UL, 0xecec2fc3UL,
+      0x5f5fe1beUL, 0x9797a235UL, 0x4444cc88UL, 0x1717392eUL,
+      0xc4c45793UL, 0xa7a7f255UL, 0x7e7e82fcUL, 0x3d3d477aUL,
+      0x6464acc8UL, 0x5d5de7baUL, 0x19192b32UL, 0x737395e6UL,
+      0x6060a0c0UL, 0x81819819UL, 0x4f4fd19eUL, 0xdcdc7fa3UL,
+      0x22226644UL, 0x2a2a7e54UL, 0x9090ab3bUL, 0x8888830bUL,
+      0x4646ca8cUL, 0xeeee29c7UL, 0xb8b8d36bUL, 0x14143c28UL,
+      0xdede79a7UL, 0x5e5ee2bcUL, 0x0b0b1d16UL, 0xdbdb76adUL,
+      0xe0e03bdbUL, 0x32325664UL, 0x3a3a4e74UL, 0x0a0a1e14UL,
+      0x4949db92UL, 0x06060a0cUL, 0x24246c48UL, 0x5c5ce4b8UL,
+      0xc2c25d9fUL, 0xd3d36ebdUL, 0xacacef43UL, 0x6262a6c4UL,
+      0x9191a839UL, 0x9595a431UL, 0xe4e437d3UL, 0x79798bf2UL,
+      0xe7e732d5UL, 0xc8c8438bUL, 0x3737596eUL, 0x6d6db7daUL,
+      0x8d8d8c01UL, 0xd5d564b1UL, 0x4e4ed29cUL, 0xa9a9e049UL,
+      0x6c6cb4d8UL, 0x5656faacUL, 0xf4f407f3UL, 0xeaea25cfUL,
+      0x6565afcaUL, 0x7a7a8ef4UL, 0xaeaee947UL, 0x08081810UL,
+      0xbabad56fUL, 0x787888f0UL, 0x25256f4aUL, 0x2e2e725cUL,
+      0x1c1c2438UL, 0xa6a6f157UL, 0xb4b4c773UL, 0xc6c65197UL,
+      0xe8e823cbUL, 0xdddd7ca1UL, 0x74749ce8UL, 0x1f1f213eUL,
+      0x4b4bdd96UL, 0xbdbddc61UL, 0x8b8b860dUL, 0x8a8a850fUL,
+      0x707090e0UL, 0x3e3e427cUL, 0xb5b5c471UL, 0x6666aaccUL,
+      0x4848d890UL, 0x03030506UL, 0xf6f601f7UL, 0x0e0e121cUL,
+      0x6161a3c2UL, 0x35355f6aUL, 0x5757f9aeUL, 0xb9b9d069UL,
+      0x86869117UL, 0xc1c15899UL, 0x1d1d273aUL, 0x9e9eb927UL,
+      0xe1e138d9UL, 0xf8f813ebUL, 0x9898b32bUL, 0x11113322UL,
+      0x6969bbd2UL, 0xd9d970a9UL, 0x8e8e8907UL, 0x9494a733UL,
+      0x9b9bb62dUL, 0x1e1e223cUL, 0x87879215UL, 0xe9e920c9UL,
+      0xcece4987UL, 0x5555ffaaUL, 0x28287850UL, 0xdfdf7aa5UL,
+      0x8c8c8f03UL, 0xa1a1f859UL, 0x89898009UL, 0x0d0d171aUL,
+      0xbfbfda65UL, 0xe6e631d7UL, 0x4242c684UL, 0x6868b8d0UL,
+      0x4141c382UL, 0x9999b029UL, 0x2d2d775aUL, 0x0f0f111eUL,
+      0xb0b0cb7bUL, 0x5454fca8UL, 0xbbbbd66dUL, 0x16163a2cUL
+  };
+  s1338 = table4[s1337];
+  s1339 = s1080 ^ s1338;
+  s1340 = s8 ^ s1339;
+  s1341 = sbv_bv_extract_u32_31_24_u8(s1340);
+  s1342 = table1[s1341];
+  s1344 = table1[s1343];
+  s1346 = table2[s1345];
+  s1347 = s1344 ^ s1346;
+  s1349 = table3[s1348];
+  s1350 = s1347 ^ s1349;
+  s1352 = table4[s1351];
+  s1353 = s1350 ^ s1352;
+  s1354 = s9 ^ s1353;
+  s1355 = sbv_bv_extract_u32_23_16_u8(s1354);
+  s1356 = table2[s1355];
+  s1357 = s1342 ^ s1356;
+  s1359 = table1[s1358];
+  s1361 = table2[s1360];
+  s1362 = s1359 ^ s1361;
+  s1364 = table3[s1363];
+  s1365 = s1362 ^ s1364;
+  s1367 = table4[s1366];
+  s1368 = s1365 ^ s1367;
+  s1369 = s10 ^ s1368;
+  s1370 = sbv_bv_extract_u32_15_8_u8(s1369);
+  s1371 = table3[s1370];
+  s1372 = s1357 ^ s1371;
+  s1374 = table1[s1373];
+  s1376 = table2[s1375];
+  s1377 = s1374 ^ s1376;
+  s1379 = table3[s1378];
+  s1380 = s1377 ^ s1379;
+  s1382 = table4[s1381];
+  s1383 = s1380 ^ s1382;
+  s1384 = s11 ^ s1383;
+  s1385 = sbv_bv_extract_u32_7_0_u8(s1384);
+  s1386 = table4[s1385];
+  s1387 = s1372 ^ s1386;
+  s1388 = s12 ^ s1387;
+  s1389 = sbv_bv_extract_u32_31_24_u8(s1388);
+  s1390 = table1[s1389];
+  s1391 = sbv_bv_extract_u32_31_24_u8(s1354);
+  s1392 = table1[s1391];
+  s1393 = sbv_bv_extract_u32_23_16_u8(s1369);
+  s1394 = table2[s1393];
+  s1395 = s1392 ^ s1394;
+  s1396 = sbv_bv_extract_u32_15_8_u8(s1384);
+  s1397 = table3[s1396];
+  s1398 = s1395 ^ s1397;
+  s1399 = sbv_bv_extract_u32_7_0_u8(s1340);
+  s1400 = table4[s1399];
+  s1401 = s1398 ^ s1400;
+  s1402 = s13 ^ s1401;
+  s1403 = sbv_bv_extract_u32_23_16_u8(s1402);
+  s1404 = table2[s1403];
+  s1405 = s1390 ^ s1404;
+  s1406 = sbv_bv_extract_u32_31_24_u8(s1369);
+  s1407 = table1[s1406];
+  s1408 = sbv_bv_extract_u32_23_16_u8(s1384);
+  s1409 = table2[s1408];
+  s1410 = s1407 ^ s1409;
+  s1411 = sbv_bv_extract_u32_15_8_u8(s1340);
+  s1412 = table3[s1411];
+  s1413 = s1410 ^ s1412;
+  s1414 = sbv_bv_extract_u32_7_0_u8(s1354);
+  s1415 = table4[s1414];
+  s1416 = s1413 ^ s1415;
+  s1417 = s14 ^ s1416;
+  s1418 = sbv_bv_extract_u32_15_8_u8(s1417);
+  s1419 = table3[s1418];
+  s1420 = s1405 ^ s1419;
+  s1421 = sbv_bv_extract_u32_31_24_u8(s1384);
+  s1422 = table1[s1421];
+  s1423 = sbv_bv_extract_u32_23_16_u8(s1340);
+  s1424 = table2[s1423];
+  s1425 = s1422 ^ s1424;
+  s1426 = sbv_bv_extract_u32_15_8_u8(s1354);
+  s1427 = table3[s1426];
+  s1428 = s1425 ^ s1427;
+  s1429 = sbv_bv_extract_u32_7_0_u8(s1369);
+  s1430 = table4[s1429];
+  s1431 = s1428 ^ s1430;
+  s1432 = s15 ^ s1431;
+  s1433 = sbv_bv_extract_u32_7_0_u8(s1432);
+  s1434 = table4[s1433];
+  s1435 = s1420 ^ s1434;
+  s1436 = s16 ^ s1435;
+  s1437 = sbv_bv_extract_u32_31_24_u8(s1436);
+  s1438 = table1[s1437];
+  s1439 = sbv_bv_extract_u32_31_24_u8(s1402);
+  s1440 = table1[s1439];
+  s1441 = sbv_bv_extract_u32_23_16_u8(s1417);
+  s1442 = table2[s1441];
+  s1443 = s1440 ^ s1442;
+  s1444 = sbv_bv_extract_u32_15_8_u8(s1432);
+  s1445 = table3[s1444];
+  s1446 = s1443 ^ s1445;
+  s1447 = sbv_bv_extract_u32_7_0_u8(s1388);
+  s1448 = table4[s1447];
+  s1449 = s1446 ^ s1448;
+  s1450 = s17 ^ s1449;
+  s1451 = sbv_bv_extract_u32_23_16_u8(s1450);
+  s1452 = table2[s1451];
+  s1453 = s1438 ^ s1452;
+  s1454 = sbv_bv_extract_u32_31_24_u8(s1417);
+  s1455 = table1[s1454];
+  s1456 = sbv_bv_extract_u32_23_16_u8(s1432);
+  s1457 = table2[s1456];
+  s1458 = s1455 ^ s1457;
+  s1459 = sbv_bv_extract_u32_15_8_u8(s1388);
+  s1460 = table3[s1459];
+  s1461 = s1458 ^ s1460;
+  s1462 = sbv_bv_extract_u32_7_0_u8(s1402);
+  s1463 = table4[s1462];
+  s1464 = s1461 ^ s1463;
+  s1465 = s18 ^ s1464;
+  s1466 = sbv_bv_extract_u32_15_8_u8(s1465);
+  s1467 = table3[s1466];
+  s1468 = s1453 ^ s1467;
+  s1469 = sbv_bv_extract_u32_31_24_u8(s1432);
+  s1470 = table1[s1469];
+  s1471 = sbv_bv_extract_u32_23_16_u8(s1388);
+  s1472 = table2[s1471];
+  s1473 = s1470 ^ s1472;
+  s1474 = sbv_bv_extract_u32_15_8_u8(s1402);
+  s1475 = table3[s1474];
+  s1476 = s1473 ^ s1475;
+  s1477 = sbv_bv_extract_u32_7_0_u8(s1417);
+  s1478 = table4[s1477];
+  s1479 = s1476 ^ s1478;
+  s1480 = s19 ^ s1479;
+  s1481 = sbv_bv_extract_u32_7_0_u8(s1480);
+  s1482 = table4[s1481];
+  s1483 = s1468 ^ s1482;
+  s1484 = s20 ^ s1483;
+  s1485 = sbv_bv_extract_u32_31_24_u8(s1484);
+  s1486 = table1[s1485];
+  s1487 = sbv_bv_extract_u32_31_24_u8(s1450);
+  s1488 = table1[s1487];
+  s1489 = sbv_bv_extract_u32_23_16_u8(s1465);
+  s1490 = table2[s1489];
+  s1491 = s1488 ^ s1490;
+  s1492 = sbv_bv_extract_u32_15_8_u8(s1480);
+  s1493 = table3[s1492];
+  s1494 = s1491 ^ s1493;
+  s1495 = sbv_bv_extract_u32_7_0_u8(s1436);
+  s1496 = table4[s1495];
+  s1497 = s1494 ^ s1496;
+  s1498 = s21 ^ s1497;
+  s1499 = sbv_bv_extract_u32_23_16_u8(s1498);
+  s1500 = table2[s1499];
+  s1501 = s1486 ^ s1500;
+  s1502 = sbv_bv_extract_u32_31_24_u8(s1465);
+  s1503 = table1[s1502];
+  s1504 = sbv_bv_extract_u32_23_16_u8(s1480);
+  s1505 = table2[s1504];
+  s1506 = s1503 ^ s1505;
+  s1507 = sbv_bv_extract_u32_15_8_u8(s1436);
+  s1508 = table3[s1507];
+  s1509 = s1506 ^ s1508;
+  s1510 = sbv_bv_extract_u32_7_0_u8(s1450);
+  s1511 = table4[s1510];
+  s1512 = s1509 ^ s1511;
+  s1513 = s22 ^ s1512;
+  s1514 = sbv_bv_extract_u32_15_8_u8(s1513);
+  s1515 = table3[s1514];
+  s1516 = s1501 ^ s1515;
+  s1517 = sbv_bv_extract_u32_31_24_u8(s1480);
+  s1518 = table1[s1517];
+  s1519 = sbv_bv_extract_u32_23_16_u8(s1436);
+  s1520 = table2[s1519];
+  s1521 = s1518 ^ s1520;
+  s1522 = sbv_bv_extract_u32_15_8_u8(s1450);
+  s1523 = table3[s1522];
+  s1524 = s1521 ^ s1523;
+  s1525 = sbv_bv_extract_u32_7_0_u8(s1465);
+  s1526 = table4[s1525];
+  s1527 = s1524 ^ s1526;
+  s1528 = s23 ^ s1527;
+  s1529 = sbv_bv_extract_u32_7_0_u8(s1528);
+  s1530 = table4[s1529];
+  s1531 = s1516 ^ s1530;
+  s1532 = s24 ^ s1531;
+  s1533 = sbv_bv_extract_u32_31_24_u8(s1532);
+  s1534 = table1[s1533];
+  s1535 = sbv_bv_extract_u32_31_24_u8(s1498);
+  s1536 = table1[s1535];
+  s1537 = sbv_bv_extract_u32_23_16_u8(s1513);
+  s1538 = table2[s1537];
+  s1539 = s1536 ^ s1538;
+  s1540 = sbv_bv_extract_u32_15_8_u8(s1528);
+  s1541 = table3[s1540];
+  s1542 = s1539 ^ s1541;
+  s1543 = sbv_bv_extract_u32_7_0_u8(s1484);
+  s1544 = table4[s1543];
+  s1545 = s1542 ^ s1544;
+  s1546 = s25 ^ s1545;
+  s1547 = sbv_bv_extract_u32_23_16_u8(s1546);
+  s1548 = table2[s1547];
+  s1549 = s1534 ^ s1548;
+  s1550 = sbv_bv_extract_u32_31_24_u8(s1513);
+  s1551 = table1[s1550];
+  s1552 = sbv_bv_extract_u32_23_16_u8(s1528);
+  s1553 = table2[s1552];
+  s1554 = s1551 ^ s1553;
+  s1555 = sbv_bv_extract_u32_15_8_u8(s1484);
+  s1556 = table3[s1555];
+  s1557 = s1554 ^ s1556;
+  s1558 = sbv_bv_extract_u32_7_0_u8(s1498);
+  s1559 = table4[s1558];
+  s1560 = s1557 ^ s1559;
+  s1561 = s26 ^ s1560;
+  s1562 = sbv_bv_extract_u32_15_8_u8(s1561);
+  s1563 = table3[s1562];
+  s1564 = s1549 ^ s1563;
+  s1565 = sbv_bv_extract_u32_31_24_u8(s1528);
+  s1566 = table1[s1565];
+  s1567 = sbv_bv_extract_u32_23_16_u8(s1484);
+  s1568 = table2[s1567];
+  s1569 = s1566 ^ s1568;
+  s1570 = sbv_bv_extract_u32_15_8_u8(s1498);
+  s1571 = table3[s1570];
+  s1572 = s1569 ^ s1571;
+  s1573 = sbv_bv_extract_u32_7_0_u8(s1513);
+  s1574 = table4[s1573];
+  s1575 = s1572 ^ s1574;
+  s1576 = s27 ^ s1575;
+  s1577 = sbv_bv_extract_u32_7_0_u8(s1576);
+  s1578 = table4[s1577];
+  s1579 = s1564 ^ s1578;
+  s1580 = s28 ^ s1579;
+  s1581 = sbv_bv_extract_u32_31_24_u8(s1580);
+  s1582 = table1[s1581];
+  s1583 = sbv_bv_extract_u32_31_24_u8(s1546);
+  s1584 = table1[s1583];
+  s1585 = sbv_bv_extract_u32_23_16_u8(s1561);
+  s1586 = table2[s1585];
+  s1587 = s1584 ^ s1586;
+  s1588 = sbv_bv_extract_u32_15_8_u8(s1576);
+  s1589 = table3[s1588];
+  s1590 = s1587 ^ s1589;
+  s1591 = sbv_bv_extract_u32_7_0_u8(s1532);
+  s1592 = table4[s1591];
+  s1593 = s1590 ^ s1592;
+  s1594 = s29 ^ s1593;
+  s1595 = sbv_bv_extract_u32_23_16_u8(s1594);
+  s1596 = table2[s1595];
+  s1597 = s1582 ^ s1596;
+  s1598 = sbv_bv_extract_u32_31_24_u8(s1561);
+  s1599 = table1[s1598];
+  s1600 = sbv_bv_extract_u32_23_16_u8(s1576);
+  s1601 = table2[s1600];
+  s1602 = s1599 ^ s1601;
+  s1603 = sbv_bv_extract_u32_15_8_u8(s1532);
+  s1604 = table3[s1603];
+  s1605 = s1602 ^ s1604;
+  s1606 = sbv_bv_extract_u32_7_0_u8(s1546);
+  s1607 = table4[s1606];
+  s1608 = s1605 ^ s1607;
+  s1609 = s30 ^ s1608;
+  s1610 = sbv_bv_extract_u32_15_8_u8(s1609);
+  s1611 = table3[s1610];
+  s1612 = s1597 ^ s1611;
+  s1613 = sbv_bv_extract_u32_31_24_u8(s1576);
+  s1614 = table1[s1613];
+  s1615 = sbv_bv_extract_u32_23_16_u8(s1532);
+  s1616 = table2[s1615];
+  s1617 = s1614 ^ s1616;
+  s1618 = sbv_bv_extract_u32_15_8_u8(s1546);
+  s1619 = table3[s1618];
+  s1620 = s1617 ^ s1619;
+  s1621 = sbv_bv_extract_u32_7_0_u8(s1561);
+  s1622 = table4[s1621];
+  s1623 = s1620 ^ s1622;
+  s1624 = s31 ^ s1623;
+  s1625 = sbv_bv_extract_u32_7_0_u8(s1624);
+  s1626 = table4[s1625];
+  s1627 = s1612 ^ s1626;
+  s1628 = s32 ^ s1627;
+  s1629 = sbv_bv_extract_u32_31_24_u8(s1628);
+  s1630 = table1[s1629];
+  s1631 = sbv_bv_extract_u32_31_24_u8(s1594);
+  s1632 = table1[s1631];
+  s1633 = sbv_bv_extract_u32_23_16_u8(s1609);
+  s1634 = table2[s1633];
+  s1635 = s1632 ^ s1634;
+  s1636 = sbv_bv_extract_u32_15_8_u8(s1624);
+  s1637 = table3[s1636];
+  s1638 = s1635 ^ s1637;
+  s1639 = sbv_bv_extract_u32_7_0_u8(s1580);
+  s1640 = table4[s1639];
+  s1641 = s1638 ^ s1640;
+  s1642 = s33 ^ s1641;
+  s1643 = sbv_bv_extract_u32_23_16_u8(s1642);
+  s1644 = table2[s1643];
+  s1645 = s1630 ^ s1644;
+  s1646 = sbv_bv_extract_u32_31_24_u8(s1609);
+  s1647 = table1[s1646];
+  s1648 = sbv_bv_extract_u32_23_16_u8(s1624);
+  s1649 = table2[s1648];
+  s1650 = s1647 ^ s1649;
+  s1651 = sbv_bv_extract_u32_15_8_u8(s1580);
+  s1652 = table3[s1651];
+  s1653 = s1650 ^ s1652;
+  s1654 = sbv_bv_extract_u32_7_0_u8(s1594);
+  s1655 = table4[s1654];
+  s1656 = s1653 ^ s1655;
+  s1657 = s34 ^ s1656;
+  s1658 = sbv_bv_extract_u32_15_8_u8(s1657);
+  s1659 = table3[s1658];
+  s1660 = s1645 ^ s1659;
+  s1661 = sbv_bv_extract_u32_31_24_u8(s1624);
+  s1662 = table1[s1661];
+  s1663 = sbv_bv_extract_u32_23_16_u8(s1580);
+  s1664 = table2[s1663];
+  s1665 = s1662 ^ s1664;
+  s1666 = sbv_bv_extract_u32_15_8_u8(s1594);
+  s1667 = table3[s1666];
+  s1668 = s1665 ^ s1667;
+  s1669 = sbv_bv_extract_u32_7_0_u8(s1609);
+  s1670 = table4[s1669];
+  s1671 = s1668 ^ s1670;
+  s1672 = s35 ^ s1671;
+  s1673 = sbv_bv_extract_u32_7_0_u8(s1672);
+  s1674 = table4[s1673];
+  s1675 = s1660 ^ s1674;
+  s1676 = s36 ^ s1675;
+  s1677 = sbv_bv_extract_u32_31_24_u8(s1676);
+  s1678 = table1[s1677];
+  s1679 = sbv_bv_extract_u32_31_24_u8(s1642);
+  s1680 = table1[s1679];
+  s1681 = sbv_bv_extract_u32_23_16_u8(s1657);
+  s1682 = table2[s1681];
+  s1683 = s1680 ^ s1682;
+  s1684 = sbv_bv_extract_u32_15_8_u8(s1672);
+  s1685 = table3[s1684];
+  s1686 = s1683 ^ s1685;
+  s1687 = sbv_bv_extract_u32_7_0_u8(s1628);
+  s1688 = table4[s1687];
+  s1689 = s1686 ^ s1688;
+  s1690 = s37 ^ s1689;
+  s1691 = sbv_bv_extract_u32_23_16_u8(s1690);
+  s1692 = table2[s1691];
+  s1693 = s1678 ^ s1692;
+  s1694 = sbv_bv_extract_u32_31_24_u8(s1657);
+  s1695 = table1[s1694];
+  s1696 = sbv_bv_extract_u32_23_16_u8(s1672);
+  s1697 = table2[s1696];
+  s1698 = s1695 ^ s1697;
+  s1699 = sbv_bv_extract_u32_15_8_u8(s1628);
+  s1700 = table3[s1699];
+  s1701 = s1698 ^ s1700;
+  s1702 = sbv_bv_extract_u32_7_0_u8(s1642);
+  s1703 = table4[s1702];
+  s1704 = s1701 ^ s1703;
+  s1705 = s38 ^ s1704;
+  s1706 = sbv_bv_extract_u32_15_8_u8(s1705);
+  s1707 = table3[s1706];
+  s1708 = s1693 ^ s1707;
+  s1709 = sbv_bv_extract_u32_31_24_u8(s1672);
+  s1710 = table1[s1709];
+  s1711 = sbv_bv_extract_u32_23_16_u8(s1628);
+  s1712 = table2[s1711];
+  s1713 = s1710 ^ s1712;
+  s1714 = sbv_bv_extract_u32_15_8_u8(s1642);
+  s1715 = table3[s1714];
+  s1716 = s1713 ^ s1715;
+  s1717 = sbv_bv_extract_u32_7_0_u8(s1657);
+  s1718 = table4[s1717];
+  s1719 = s1716 ^ s1718;
+  s1720 = s39 ^ s1719;
+  s1721 = sbv_bv_extract_u32_7_0_u8(s1720);
+  s1722 = table4[s1721];
+  s1723 = s1708 ^ s1722;
+  s1724 = s40 ^ s1723;
+  s1725 = sbv_bv_extract_u32_31_24_u8(s1724);
+  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
+  };
+  s1726 = table0[s1725];
+  s1727 = sbv_bv_extract_u32_31_24_u8(s1690);
+  s1728 = table1[s1727];
+  s1729 = sbv_bv_extract_u32_23_16_u8(s1705);
+  s1730 = table2[s1729];
+  s1731 = s1728 ^ s1730;
+  s1732 = sbv_bv_extract_u32_15_8_u8(s1720);
+  s1733 = table3[s1732];
+  s1734 = s1731 ^ s1733;
+  s1735 = sbv_bv_extract_u32_7_0_u8(s1676);
+  s1736 = table4[s1735];
+  s1737 = s1734 ^ s1736;
+  s1738 = s41 ^ s1737;
+  s1739 = sbv_bv_extract_u32_23_16_u8(s1738);
+  s1740 = table0[s1739];
+  s1741 = sbv_bv_join_u8_u8_u16(s1726, s1740);
+  s1742 = sbv_bv_extract_u32_31_24_u8(s1705);
+  s1743 = table1[s1742];
+  s1744 = sbv_bv_extract_u32_23_16_u8(s1720);
+  s1745 = table2[s1744];
+  s1746 = s1743 ^ s1745;
+  s1747 = sbv_bv_extract_u32_15_8_u8(s1676);
+  s1748 = table3[s1747];
+  s1749 = s1746 ^ s1748;
+  s1750 = sbv_bv_extract_u32_7_0_u8(s1690);
+  s1751 = table4[s1750];
+  s1752 = s1749 ^ s1751;
+  s1753 = s42 ^ s1752;
+  s1754 = sbv_bv_extract_u32_15_8_u8(s1753);
+  s1755 = table0[s1754];
+  s1756 = sbv_bv_extract_u32_31_24_u8(s1720);
+  s1757 = table1[s1756];
+  s1758 = sbv_bv_extract_u32_23_16_u8(s1676);
+  s1759 = table2[s1758];
+  s1760 = s1757 ^ s1759;
+  s1761 = sbv_bv_extract_u32_15_8_u8(s1690);
+  s1762 = table3[s1761];
+  s1763 = s1760 ^ s1762;
+  s1764 = sbv_bv_extract_u32_7_0_u8(s1705);
+  s1765 = table4[s1764];
+  s1766 = s1763 ^ s1765;
+  s1767 = s43 ^ s1766;
+  s1768 = sbv_bv_extract_u32_7_0_u8(s1767);
+  s1769 = table0[s1768];
+  s1770 = sbv_bv_join_u8_u8_u16(s1755, s1769);
+  s1771 = sbv_bv_join_u16_u16_u32(s1741, s1770);
+  s1772 = s44 ^ s1771;
+  s1773 = sbv_bv_extract_u32_31_24_u8(s1738);
+  s1774 = table0[s1773];
+  s1775 = sbv_bv_extract_u32_23_16_u8(s1753);
+  s1776 = table0[s1775];
+  s1777 = sbv_bv_join_u8_u8_u16(s1774, s1776);
+  s1778 = sbv_bv_extract_u32_15_8_u8(s1767);
+  s1779 = table0[s1778];
+  s1780 = sbv_bv_extract_u32_7_0_u8(s1724);
+  s1781 = table0[s1780];
+  s1782 = sbv_bv_join_u8_u8_u16(s1779, s1781);
+  s1783 = sbv_bv_join_u16_u16_u32(s1777, s1782);
+  s1784 = s45 ^ s1783;
+  s1785 = sbv_bv_extract_u32_31_24_u8(s1753);
+  s1786 = table0[s1785];
+  s1787 = sbv_bv_extract_u32_23_16_u8(s1767);
+  s1788 = table0[s1787];
+  s1789 = sbv_bv_join_u8_u8_u16(s1786, s1788);
+  s1790 = sbv_bv_extract_u32_15_8_u8(s1724);
+  s1791 = table0[s1790];
+  s1792 = sbv_bv_extract_u32_7_0_u8(s1738);
+  s1793 = table0[s1792];
+  s1794 = sbv_bv_join_u8_u8_u16(s1791, s1793);
+  s1795 = sbv_bv_join_u16_u16_u32(s1789, s1794);
+  s1796 = s46 ^ s1795;
+  s1797 = sbv_bv_extract_u32_31_24_u8(s1767);
+  s1798 = table0[s1797];
+  s1799 = sbv_bv_extract_u32_23_16_u8(s1724);
+  s1800 = table0[s1799];
+  s1801 = sbv_bv_join_u8_u8_u16(s1798, s1800);
+  s1802 = sbv_bv_extract_u32_15_8_u8(s1738);
+  s1803 = table0[s1802];
+  s1804 = sbv_bv_extract_u32_7_0_u8(s1753);
+  s1805 = table0[s1804];
+  s1806 = sbv_bv_join_u8_u8_u16(s1803, s1805);
+  s1807 = sbv_bv_join_u16_u16_u32(s1801, s1806);
+  s1808 = s47 ^ s1807;
+
+  sbv_output_0[0] = s1772;
+  sbv_output_0[1] = s1784;
+  sbv_output_0[2] = s1796;
+  sbv_output_0[3] = s1808;
+}
+== END: "aes128BlockEncrypt.c" ==================
+== BEGIN: "aes128BlockDecrypt.c" ================
+/* File: "aes128BlockDecrypt.c". Automatically generated by SBV. Do not edit! */
+
+#include "aes128Lib.h"
+
+/* Exact bit-vector runtime. All arithmetic is modulo the declared width. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_31_24_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 24)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_23_16_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 16)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_15_8_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 8)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_7_0_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord16 sbv_bv_join_u8_u8_u16(SWord8 high, SWord8 low)
+{
+  SWord16 r = (SWord16) 0; uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord16) ((uint64_t) r | ((uint64_t) (((((uint64_t) low) >> (i)) & UINT64_C(1)) != 0) << (i))); }
+  for (i = 0; i < 8; ++i) { r = (SWord16) ((uint64_t) r | ((uint64_t) (((((uint64_t) high) >> (i)) & UINT64_C(1)) != 0) << (i + 8))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord32 sbv_bv_join_u16_u16_u32(SWord16 high, SWord16 low)
+{
+  SWord32 r = (SWord32) 0; uint64_t i;
+  for (i = 0; i < 16; ++i) { r = (SWord32) ((uint64_t) r | ((uint64_t) (((((uint64_t) low) >> (i)) & UINT64_C(1)) != 0) << (i))); }
+  for (i = 0; i < 16; ++i) { r = (SWord32) ((uint64_t) r | ((uint64_t) (((((uint64_t) high) >> (i)) & UINT64_C(1)) != 0) << (i + 16))); }
+  return r;
+}
+
+
+void aes128BlockDecrypt(const SWord32 *sbv_input_0,
+                        const SWord32 *sbv_input_1, SWord32 *sbv_output_0)
+{
+  const SWord32 s0 = sbv_input_0[0];
+  const SWord32 s1 = sbv_input_0[1];
+  const SWord32 s2 = sbv_input_0[2];
+  const SWord32 s3 = sbv_input_0[3];
+  const SWord32 s4 = sbv_input_1[0];
+  const SWord32 s5 = sbv_input_1[1];
+  const SWord32 s6 = sbv_input_1[2];
+  const SWord32 s7 = sbv_input_1[3];
+  const SWord32 s8 = sbv_input_1[4];
+  const SWord32 s9 = sbv_input_1[5];
+  const SWord32 s10 = sbv_input_1[6];
+  const SWord32 s11 = sbv_input_1[7];
+  const SWord32 s12 = sbv_input_1[8];
+  const SWord32 s13 = sbv_input_1[9];
+  const SWord32 s14 = sbv_input_1[10];
+  const SWord32 s15 = sbv_input_1[11];
+  const SWord32 s16 = sbv_input_1[12];
+  const SWord32 s17 = sbv_input_1[13];
+  const SWord32 s18 = sbv_input_1[14];
+  const SWord32 s19 = sbv_input_1[15];
+  const SWord32 s20 = sbv_input_1[16];
+  const SWord32 s21 = sbv_input_1[17];
+  const SWord32 s22 = sbv_input_1[18];
+  const SWord32 s23 = sbv_input_1[19];
+  const SWord32 s24 = sbv_input_1[20];
+  const SWord32 s25 = sbv_input_1[21];
+  const SWord32 s26 = sbv_input_1[22];
+  const SWord32 s27 = sbv_input_1[23];
+  const SWord32 s28 = sbv_input_1[24];
+  const SWord32 s29 = sbv_input_1[25];
+  const SWord32 s30 = sbv_input_1[26];
+  const SWord32 s31 = sbv_input_1[27];
+  const SWord32 s32 = sbv_input_1[28];
+  const SWord32 s33 = sbv_input_1[29];
+  const SWord32 s34 = sbv_input_1[30];
+  const SWord32 s35 = sbv_input_1[31];
+  const SWord32 s36 = sbv_input_1[32];
+  const SWord32 s37 = sbv_input_1[33];
+  const SWord32 s38 = sbv_input_1[34];
+  const SWord32 s39 = sbv_input_1[35];
+  const SWord32 s40 = sbv_input_1[36];
+  const SWord32 s41 = sbv_input_1[37];
+  const SWord32 s42 = sbv_input_1[38];
+  const SWord32 s43 = sbv_input_1[39];
+  const SWord32 s44 = sbv_input_1[40];
+  const SWord32 s45 = sbv_input_1[41];
+  const SWord32 s46 = sbv_input_1[42];
+  const SWord32 s47 = sbv_input_1[43];
+  const SWord32 s560 = s0 ^ s4;
+  const SWord8  s561 = sbv_bv_extract_u32_31_24_u8(s560);
+  const SWord32 s818 = s3 ^ s7;
+  const SWord8  s819 = sbv_bv_extract_u32_23_16_u8(s818);
+  const SWord32 s1077 = s2 ^ s6;
+  const SWord8  s1078 = sbv_bv_extract_u32_15_8_u8(s1077);
+  const SWord32 s1336 = s1 ^ s5;
+  const SWord8  s1337 = sbv_bv_extract_u32_7_0_u8(s1336);
+  const SWord8  s1343 = sbv_bv_extract_u32_31_24_u8(s818);
+  const SWord8  s1345 = sbv_bv_extract_u32_23_16_u8(s1077);
+  const SWord8  s1348 = sbv_bv_extract_u32_15_8_u8(s1336);
+  const SWord8  s1351 = sbv_bv_extract_u32_7_0_u8(s560);
+  const SWord8  s1358 = sbv_bv_extract_u32_31_24_u8(s1077);
+  const SWord8  s1360 = sbv_bv_extract_u32_23_16_u8(s1336);
+  const SWord8  s1363 = sbv_bv_extract_u32_15_8_u8(s560);
+  const SWord8  s1366 = sbv_bv_extract_u32_7_0_u8(s818);
+  const SWord8  s1373 = sbv_bv_extract_u32_31_24_u8(s1336);
+  const SWord8  s1375 = sbv_bv_extract_u32_23_16_u8(s560);
+  const SWord8  s1378 = sbv_bv_extract_u32_15_8_u8(s818);
+  const SWord8  s1381 = sbv_bv_extract_u32_7_0_u8(s1077);
+        SWord32 s562;
+        SWord32 s820;
+        SWord32 s821;
+        SWord32 s1079;
+        SWord32 s1080;
+        SWord32 s1338;
+        SWord32 s1339;
+        SWord32 s1340;
+        SWord8  s1341;
+        SWord32 s1342;
+        SWord32 s1344;
+        SWord32 s1346;
+        SWord32 s1347;
+        SWord32 s1349;
+        SWord32 s1350;
+        SWord32 s1352;
+        SWord32 s1353;
+        SWord32 s1354;
+        SWord8  s1355;
+        SWord32 s1356;
+        SWord32 s1357;
+        SWord32 s1359;
+        SWord32 s1361;
+        SWord32 s1362;
+        SWord32 s1364;
+        SWord32 s1365;
+        SWord32 s1367;
+        SWord32 s1368;
+        SWord32 s1369;
+        SWord8  s1370;
+        SWord32 s1371;
+        SWord32 s1372;
+        SWord32 s1374;
+        SWord32 s1376;
+        SWord32 s1377;
+        SWord32 s1379;
+        SWord32 s1380;
+        SWord32 s1382;
+        SWord32 s1383;
+        SWord32 s1384;
+        SWord8  s1385;
+        SWord32 s1386;
+        SWord32 s1387;
+        SWord32 s1388;
+        SWord8  s1389;
+        SWord32 s1390;
+        SWord8  s1391;
+        SWord32 s1392;
+        SWord8  s1393;
+        SWord32 s1394;
+        SWord32 s1395;
+        SWord8  s1396;
+        SWord32 s1397;
+        SWord32 s1398;
+        SWord8  s1399;
+        SWord32 s1400;
+        SWord32 s1401;
+        SWord32 s1402;
+        SWord8  s1403;
+        SWord32 s1404;
+        SWord32 s1405;
+        SWord8  s1406;
+        SWord32 s1407;
+        SWord8  s1408;
+        SWord32 s1409;
+        SWord32 s1410;
+        SWord8  s1411;
+        SWord32 s1412;
+        SWord32 s1413;
+        SWord8  s1414;
+        SWord32 s1415;
+        SWord32 s1416;
+        SWord32 s1417;
+        SWord8  s1418;
+        SWord32 s1419;
+        SWord32 s1420;
+        SWord8  s1421;
+        SWord32 s1422;
+        SWord8  s1423;
+        SWord32 s1424;
+        SWord32 s1425;
+        SWord8  s1426;
+        SWord32 s1427;
+        SWord32 s1428;
+        SWord8  s1429;
+        SWord32 s1430;
+        SWord32 s1431;
+        SWord32 s1432;
+        SWord8  s1433;
+        SWord32 s1434;
+        SWord32 s1435;
+        SWord32 s1436;
+        SWord8  s1437;
+        SWord32 s1438;
+        SWord8  s1439;
+        SWord32 s1440;
+        SWord8  s1441;
+        SWord32 s1442;
+        SWord32 s1443;
+        SWord8  s1444;
+        SWord32 s1445;
+        SWord32 s1446;
+        SWord8  s1447;
+        SWord32 s1448;
+        SWord32 s1449;
+        SWord32 s1450;
+        SWord8  s1451;
+        SWord32 s1452;
+        SWord32 s1453;
+        SWord8  s1454;
+        SWord32 s1455;
+        SWord8  s1456;
+        SWord32 s1457;
+        SWord32 s1458;
+        SWord8  s1459;
+        SWord32 s1460;
+        SWord32 s1461;
+        SWord8  s1462;
+        SWord32 s1463;
+        SWord32 s1464;
+        SWord32 s1465;
+        SWord8  s1466;
+        SWord32 s1467;
+        SWord32 s1468;
+        SWord8  s1469;
+        SWord32 s1470;
+        SWord8  s1471;
+        SWord32 s1472;
+        SWord32 s1473;
+        SWord8  s1474;
+        SWord32 s1475;
+        SWord32 s1476;
+        SWord8  s1477;
+        SWord32 s1478;
+        SWord32 s1479;
+        SWord32 s1480;
+        SWord8  s1481;
+        SWord32 s1482;
+        SWord32 s1483;
+        SWord32 s1484;
+        SWord8  s1485;
+        SWord32 s1486;
+        SWord8  s1487;
+        SWord32 s1488;
+        SWord8  s1489;
+        SWord32 s1490;
+        SWord32 s1491;
+        SWord8  s1492;
+        SWord32 s1493;
+        SWord32 s1494;
+        SWord8  s1495;
+        SWord32 s1496;
+        SWord32 s1497;
+        SWord32 s1498;
+        SWord8  s1499;
+        SWord32 s1500;
+        SWord32 s1501;
+        SWord8  s1502;
+        SWord32 s1503;
+        SWord8  s1504;
+        SWord32 s1505;
+        SWord32 s1506;
+        SWord8  s1507;
+        SWord32 s1508;
+        SWord32 s1509;
+        SWord8  s1510;
+        SWord32 s1511;
+        SWord32 s1512;
+        SWord32 s1513;
+        SWord8  s1514;
+        SWord32 s1515;
+        SWord32 s1516;
+        SWord8  s1517;
+        SWord32 s1518;
+        SWord8  s1519;
+        SWord32 s1520;
+        SWord32 s1521;
+        SWord8  s1522;
+        SWord32 s1523;
+        SWord32 s1524;
+        SWord8  s1525;
+        SWord32 s1526;
+        SWord32 s1527;
+        SWord32 s1528;
+        SWord8  s1529;
+        SWord32 s1530;
+        SWord32 s1531;
+        SWord32 s1532;
+        SWord8  s1533;
+        SWord32 s1534;
+        SWord8  s1535;
+        SWord32 s1536;
+        SWord8  s1537;
+        SWord32 s1538;
+        SWord32 s1539;
+        SWord8  s1540;
+        SWord32 s1541;
+        SWord32 s1542;
+        SWord8  s1543;
+        SWord32 s1544;
+        SWord32 s1545;
+        SWord32 s1546;
+        SWord8  s1547;
+        SWord32 s1548;
+        SWord32 s1549;
+        SWord8  s1550;
+        SWord32 s1551;
+        SWord8  s1552;
+        SWord32 s1553;
+        SWord32 s1554;
+        SWord8  s1555;
+        SWord32 s1556;
+        SWord32 s1557;
+        SWord8  s1558;
+        SWord32 s1559;
+        SWord32 s1560;
+        SWord32 s1561;
+        SWord8  s1562;
+        SWord32 s1563;
+        SWord32 s1564;
+        SWord8  s1565;
+        SWord32 s1566;
+        SWord8  s1567;
+        SWord32 s1568;
+        SWord32 s1569;
+        SWord8  s1570;
+        SWord32 s1571;
+        SWord32 s1572;
+        SWord8  s1573;
+        SWord32 s1574;
+        SWord32 s1575;
+        SWord32 s1576;
+        SWord8  s1577;
+        SWord32 s1578;
+        SWord32 s1579;
+        SWord32 s1580;
+        SWord8  s1581;
+        SWord32 s1582;
+        SWord8  s1583;
+        SWord32 s1584;
+        SWord8  s1585;
+        SWord32 s1586;
+        SWord32 s1587;
+        SWord8  s1588;
+        SWord32 s1589;
+        SWord32 s1590;
+        SWord8  s1591;
+        SWord32 s1592;
+        SWord32 s1593;
+        SWord32 s1594;
+        SWord8  s1595;
+        SWord32 s1596;
+        SWord32 s1597;
+        SWord8  s1598;
+        SWord32 s1599;
+        SWord8  s1600;
+        SWord32 s1601;
+        SWord32 s1602;
+        SWord8  s1603;
+        SWord32 s1604;
+        SWord32 s1605;
+        SWord8  s1606;
+        SWord32 s1607;
+        SWord32 s1608;
+        SWord32 s1609;
+        SWord8  s1610;
+        SWord32 s1611;
+        SWord32 s1612;
+        SWord8  s1613;
+        SWord32 s1614;
+        SWord8  s1615;
+        SWord32 s1616;
+        SWord32 s1617;
+        SWord8  s1618;
+        SWord32 s1619;
+        SWord32 s1620;
+        SWord8  s1621;
+        SWord32 s1622;
+        SWord32 s1623;
+        SWord32 s1624;
+        SWord8  s1625;
+        SWord32 s1626;
+        SWord32 s1627;
+        SWord32 s1628;
+        SWord8  s1629;
+        SWord32 s1630;
+        SWord8  s1631;
+        SWord32 s1632;
+        SWord8  s1633;
+        SWord32 s1634;
+        SWord32 s1635;
+        SWord8  s1636;
+        SWord32 s1637;
+        SWord32 s1638;
+        SWord8  s1639;
+        SWord32 s1640;
+        SWord32 s1641;
+        SWord32 s1642;
+        SWord8  s1643;
+        SWord32 s1644;
+        SWord32 s1645;
+        SWord8  s1646;
+        SWord32 s1647;
+        SWord8  s1648;
+        SWord32 s1649;
+        SWord32 s1650;
+        SWord8  s1651;
+        SWord32 s1652;
+        SWord32 s1653;
+        SWord8  s1654;
+        SWord32 s1655;
+        SWord32 s1656;
+        SWord32 s1657;
+        SWord8  s1658;
+        SWord32 s1659;
+        SWord32 s1660;
+        SWord8  s1661;
+        SWord32 s1662;
+        SWord8  s1663;
+        SWord32 s1664;
+        SWord32 s1665;
+        SWord8  s1666;
+        SWord32 s1667;
+        SWord32 s1668;
+        SWord8  s1669;
+        SWord32 s1670;
+        SWord32 s1671;
+        SWord32 s1672;
+        SWord8  s1673;
+        SWord32 s1674;
+        SWord32 s1675;
+        SWord32 s1676;
+        SWord8  s1677;
+        SWord32 s1678;
+        SWord8  s1679;
+        SWord32 s1680;
+        SWord8  s1681;
+        SWord32 s1682;
+        SWord32 s1683;
+        SWord8  s1684;
+        SWord32 s1685;
+        SWord32 s1686;
+        SWord8  s1687;
+        SWord32 s1688;
+        SWord32 s1689;
+        SWord32 s1690;
+        SWord8  s1691;
+        SWord32 s1692;
+        SWord32 s1693;
+        SWord8  s1694;
+        SWord32 s1695;
+        SWord8  s1696;
+        SWord32 s1697;
+        SWord32 s1698;
+        SWord8  s1699;
+        SWord32 s1700;
+        SWord32 s1701;
+        SWord8  s1702;
+        SWord32 s1703;
+        SWord32 s1704;
+        SWord32 s1705;
+        SWord8  s1706;
+        SWord32 s1707;
+        SWord32 s1708;
+        SWord8  s1709;
+        SWord32 s1710;
+        SWord8  s1711;
+        SWord32 s1712;
+        SWord32 s1713;
+        SWord8  s1714;
+        SWord32 s1715;
+        SWord32 s1716;
+        SWord8  s1717;
+        SWord32 s1718;
+        SWord32 s1719;
+        SWord32 s1720;
+        SWord8  s1721;
+        SWord32 s1722;
+        SWord32 s1723;
+        SWord32 s1724;
+        SWord8  s1725;
+        SWord8  s1726;
+        SWord8  s1727;
+        SWord32 s1728;
+        SWord8  s1729;
+        SWord32 s1730;
+        SWord32 s1731;
+        SWord8  s1732;
+        SWord32 s1733;
+        SWord32 s1734;
+        SWord8  s1735;
+        SWord32 s1736;
+        SWord32 s1737;
+        SWord32 s1738;
+        SWord8  s1739;
+        SWord8  s1740;
+        SWord16 s1741;
+        SWord8  s1742;
+        SWord32 s1743;
+        SWord8  s1744;
+        SWord32 s1745;
+        SWord32 s1746;
+        SWord8  s1747;
+        SWord32 s1748;
+        SWord32 s1749;
+        SWord8  s1750;
+        SWord32 s1751;
+        SWord32 s1752;
+        SWord32 s1753;
+        SWord8  s1754;
+        SWord8  s1755;
+        SWord8  s1756;
+        SWord32 s1757;
+        SWord8  s1758;
+        SWord32 s1759;
+        SWord32 s1760;
+        SWord8  s1761;
+        SWord32 s1762;
+        SWord32 s1763;
+        SWord8  s1764;
+        SWord32 s1765;
+        SWord32 s1766;
+        SWord32 s1767;
+        SWord8  s1768;
+        SWord8  s1769;
+        SWord16 s1770;
+        SWord32 s1771;
+        SWord32 s1772;
+        SWord8  s1773;
+        SWord8  s1774;
+        SWord8  s1775;
+        SWord8  s1776;
+        SWord16 s1777;
+        SWord8  s1778;
+        SWord8  s1779;
+        SWord8  s1780;
+        SWord8  s1781;
+        SWord16 s1782;
+        SWord32 s1783;
+        SWord32 s1784;
+        SWord8  s1785;
+        SWord8  s1786;
+        SWord8  s1787;
+        SWord8  s1788;
+        SWord16 s1789;
+        SWord8  s1790;
+        SWord8  s1791;
+        SWord8  s1792;
+        SWord8  s1793;
+        SWord16 s1794;
+        SWord32 s1795;
+        SWord32 s1796;
+        SWord8  s1797;
+        SWord8  s1798;
+        SWord8  s1799;
+        SWord8  s1800;
+        SWord16 s1801;
+        SWord8  s1802;
+        SWord8  s1803;
+        SWord8  s1804;
+        SWord8  s1805;
+        SWord16 s1806;
+        SWord32 s1807;
+        SWord32 s1808;
+  static const SWord32 table1[] = {
+      0x51f4a750UL, 0x7e416553UL, 0x1a17a4c3UL, 0x3a275e96UL,
+      0x3bab6bcbUL, 0x1f9d45f1UL, 0xacfa58abUL, 0x4be30393UL,
+      0x2030fa55UL, 0xad766df6UL, 0x88cc7691UL, 0xf5024c25UL,
+      0x4fe5d7fcUL, 0xc52acbd7UL, 0x26354480UL, 0xb562a38fUL,
+      0xdeb15a49UL, 0x25ba1b67UL, 0x45ea0e98UL, 0x5dfec0e1UL,
+      0xc32f7502UL, 0x814cf012UL, 0x8d4697a3UL, 0x6bd3f9c6UL,
+      0x038f5fe7UL, 0x15929c95UL, 0xbf6d7aebUL, 0x955259daUL,
+      0xd4be832dUL, 0x587421d3UL, 0x49e06929UL, 0x8ec9c844UL,
+      0x75c2896aUL, 0xf48e7978UL, 0x99583e6bUL, 0x27b971ddUL,
+      0xbee14fb6UL, 0xf088ad17UL, 0xc920ac66UL, 0x7dce3ab4UL,
+      0x63df4a18UL, 0xe51a3182UL, 0x97513360UL, 0x62537f45UL,
+      0xb16477e0UL, 0xbb6bae84UL, 0xfe81a01cUL, 0xf9082b94UL,
+      0x70486858UL, 0x8f45fd19UL, 0x94de6c87UL, 0x527bf8b7UL,
+      0xab73d323UL, 0x724b02e2UL, 0xe31f8f57UL, 0x6655ab2aUL,
+      0xb2eb2807UL, 0x2fb5c203UL, 0x86c57b9aUL, 0xd33708a5UL,
+      0x302887f2UL, 0x23bfa5b2UL, 0x02036abaUL, 0xed16825cUL,
+      0x8acf1c2bUL, 0xa779b492UL, 0xf307f2f0UL, 0x4e69e2a1UL,
+      0x65daf4cdUL, 0x0605bed5UL, 0xd134621fUL, 0xc4a6fe8aUL,
+      0x342e539dUL, 0xa2f355a0UL, 0x058ae132UL, 0xa4f6eb75UL,
+      0x0b83ec39UL, 0x4060efaaUL, 0x5e719f06UL, 0xbd6e1051UL,
+      0x3e218af9UL, 0x96dd063dUL, 0xdd3e05aeUL, 0x4de6bd46UL,
+      0x91548db5UL, 0x71c45d05UL, 0x0406d46fUL, 0x605015ffUL,
+      0x1998fb24UL, 0xd6bde997UL, 0x894043ccUL, 0x67d99e77UL,
+      0xb0e842bdUL, 0x07898b88UL, 0xe7195b38UL, 0x79c8eedbUL,
+      0xa17c0a47UL, 0x7c420fe9UL, 0xf8841ec9UL, 0x00000000UL,
+      0x09808683UL, 0x322bed48UL, 0x1e1170acUL, 0x6c5a724eUL,
+      0xfd0efffbUL, 0x0f853856UL, 0x3daed51eUL, 0x362d3927UL,
+      0x0a0fd964UL, 0x685ca621UL, 0x9b5b54d1UL, 0x24362e3aUL,
+      0x0c0a67b1UL, 0x9357e70fUL, 0xb4ee96d2UL, 0x1b9b919eUL,
+      0x80c0c54fUL, 0x61dc20a2UL, 0x5a774b69UL, 0x1c121a16UL,
+      0xe293ba0aUL, 0xc0a02ae5UL, 0x3c22e043UL, 0x121b171dUL,
+      0x0e090d0bUL, 0xf28bc7adUL, 0x2db6a8b9UL, 0x141ea9c8UL,
+      0x57f11985UL, 0xaf75074cUL, 0xee99ddbbUL, 0xa37f60fdUL,
+      0xf701269fUL, 0x5c72f5bcUL, 0x44663bc5UL, 0x5bfb7e34UL,
+      0x8b432976UL, 0xcb23c6dcUL, 0xb6edfc68UL, 0xb8e4f163UL,
+      0xd731dccaUL, 0x42638510UL, 0x13972240UL, 0x84c61120UL,
+      0x854a247dUL, 0xd2bb3df8UL, 0xaef93211UL, 0xc729a16dUL,
+      0x1d9e2f4bUL, 0xdcb230f3UL, 0x0d8652ecUL, 0x77c1e3d0UL,
+      0x2bb3166cUL, 0xa970b999UL, 0x119448faUL, 0x47e96422UL,
+      0xa8fc8cc4UL, 0xa0f03f1aUL, 0x567d2cd8UL, 0x223390efUL,
+      0x87494ec7UL, 0xd938d1c1UL, 0x8ccaa2feUL, 0x98d40b36UL,
+      0xa6f581cfUL, 0xa57ade28UL, 0xdab78e26UL, 0x3fadbfa4UL,
+      0x2c3a9de4UL, 0x5078920dUL, 0x6a5fcc9bUL, 0x547e4662UL,
+      0xf68d13c2UL, 0x90d8b8e8UL, 0x2e39f75eUL, 0x82c3aff5UL,
+      0x9f5d80beUL, 0x69d0937cUL, 0x6fd52da9UL, 0xcf2512b3UL,
+      0xc8ac993bUL, 0x10187da7UL, 0xe89c636eUL, 0xdb3bbb7bUL,
+      0xcd267809UL, 0x6e5918f4UL, 0xec9ab701UL, 0x834f9aa8UL,
+      0xe6956e65UL, 0xaaffe67eUL, 0x21bccf08UL, 0xef15e8e6UL,
+      0xbae79bd9UL, 0x4a6f36ceUL, 0xea9f09d4UL, 0x29b07cd6UL,
+      0x31a4b2afUL, 0x2a3f2331UL, 0xc6a59430UL, 0x35a266c0UL,
+      0x744ebc37UL, 0xfc82caa6UL, 0xe090d0b0UL, 0x33a7d815UL,
+      0xf104984aUL, 0x41ecdaf7UL, 0x7fcd500eUL, 0x1791f62fUL,
+      0x764dd68dUL, 0x43efb04dUL, 0xccaa4d54UL, 0xe49604dfUL,
+      0x9ed1b5e3UL, 0x4c6a881bUL, 0xc12c1fb8UL, 0x4665517fUL,
+      0x9d5eea04UL, 0x018c355dUL, 0xfa877473UL, 0xfb0b412eUL,
+      0xb3671d5aUL, 0x92dbd252UL, 0xe9105633UL, 0x6dd64713UL,
+      0x9ad7618cUL, 0x37a10c7aUL, 0x59f8148eUL, 0xeb133c89UL,
+      0xcea927eeUL, 0xb761c935UL, 0xe11ce5edUL, 0x7a47b13cUL,
+      0x9cd2df59UL, 0x55f2733fUL, 0x1814ce79UL, 0x73c737bfUL,
+      0x53f7cdeaUL, 0x5ffdaa5bUL, 0xdf3d6f14UL, 0x7844db86UL,
+      0xcaaff381UL, 0xb968c43eUL, 0x3824342cUL, 0xc2a3405fUL,
+      0x161dc372UL, 0xbce2250cUL, 0x283c498bUL, 0xff0d9541UL,
+      0x39a80171UL, 0x080cb3deUL, 0xd8b4e49cUL, 0x6456c190UL,
+      0x7bcb8461UL, 0xd532b670UL, 0x486c5c74UL, 0xd0b85742UL
+  };
+  s562 = table1[s561];
+  static const SWord32 table2[] = {
+      0x5051f4a7UL, 0x537e4165UL, 0xc31a17a4UL, 0x963a275eUL,
+      0xcb3bab6bUL, 0xf11f9d45UL, 0xabacfa58UL, 0x934be303UL,
+      0x552030faUL, 0xf6ad766dUL, 0x9188cc76UL, 0x25f5024cUL,
+      0xfc4fe5d7UL, 0xd7c52acbUL, 0x80263544UL, 0x8fb562a3UL,
+      0x49deb15aUL, 0x6725ba1bUL, 0x9845ea0eUL, 0xe15dfec0UL,
+      0x02c32f75UL, 0x12814cf0UL, 0xa38d4697UL, 0xc66bd3f9UL,
+      0xe7038f5fUL, 0x9515929cUL, 0xebbf6d7aUL, 0xda955259UL,
+      0x2dd4be83UL, 0xd3587421UL, 0x2949e069UL, 0x448ec9c8UL,
+      0x6a75c289UL, 0x78f48e79UL, 0x6b99583eUL, 0xdd27b971UL,
+      0xb6bee14fUL, 0x17f088adUL, 0x66c920acUL, 0xb47dce3aUL,
+      0x1863df4aUL, 0x82e51a31UL, 0x60975133UL, 0x4562537fUL,
+      0xe0b16477UL, 0x84bb6baeUL, 0x1cfe81a0UL, 0x94f9082bUL,
+      0x58704868UL, 0x198f45fdUL, 0x8794de6cUL, 0xb7527bf8UL,
+      0x23ab73d3UL, 0xe2724b02UL, 0x57e31f8fUL, 0x2a6655abUL,
+      0x07b2eb28UL, 0x032fb5c2UL, 0x9a86c57bUL, 0xa5d33708UL,
+      0xf2302887UL, 0xb223bfa5UL, 0xba02036aUL, 0x5ced1682UL,
+      0x2b8acf1cUL, 0x92a779b4UL, 0xf0f307f2UL, 0xa14e69e2UL,
+      0xcd65daf4UL, 0xd50605beUL, 0x1fd13462UL, 0x8ac4a6feUL,
+      0x9d342e53UL, 0xa0a2f355UL, 0x32058ae1UL, 0x75a4f6ebUL,
+      0x390b83ecUL, 0xaa4060efUL, 0x065e719fUL, 0x51bd6e10UL,
+      0xf93e218aUL, 0x3d96dd06UL, 0xaedd3e05UL, 0x464de6bdUL,
+      0xb591548dUL, 0x0571c45dUL, 0x6f0406d4UL, 0xff605015UL,
+      0x241998fbUL, 0x97d6bde9UL, 0xcc894043UL, 0x7767d99eUL,
+      0xbdb0e842UL, 0x8807898bUL, 0x38e7195bUL, 0xdb79c8eeUL,
+      0x47a17c0aUL, 0xe97c420fUL, 0xc9f8841eUL, 0x00000000UL,
+      0x83098086UL, 0x48322bedUL, 0xac1e1170UL, 0x4e6c5a72UL,
+      0xfbfd0effUL, 0x560f8538UL, 0x1e3daed5UL, 0x27362d39UL,
+      0x640a0fd9UL, 0x21685ca6UL, 0xd19b5b54UL, 0x3a24362eUL,
+      0xb10c0a67UL, 0x0f9357e7UL, 0xd2b4ee96UL, 0x9e1b9b91UL,
+      0x4f80c0c5UL, 0xa261dc20UL, 0x695a774bUL, 0x161c121aUL,
+      0x0ae293baUL, 0xe5c0a02aUL, 0x433c22e0UL, 0x1d121b17UL,
+      0x0b0e090dUL, 0xadf28bc7UL, 0xb92db6a8UL, 0xc8141ea9UL,
+      0x8557f119UL, 0x4caf7507UL, 0xbbee99ddUL, 0xfda37f60UL,
+      0x9ff70126UL, 0xbc5c72f5UL, 0xc544663bUL, 0x345bfb7eUL,
+      0x768b4329UL, 0xdccb23c6UL, 0x68b6edfcUL, 0x63b8e4f1UL,
+      0xcad731dcUL, 0x10426385UL, 0x40139722UL, 0x2084c611UL,
+      0x7d854a24UL, 0xf8d2bb3dUL, 0x11aef932UL, 0x6dc729a1UL,
+      0x4b1d9e2fUL, 0xf3dcb230UL, 0xec0d8652UL, 0xd077c1e3UL,
+      0x6c2bb316UL, 0x99a970b9UL, 0xfa119448UL, 0x2247e964UL,
+      0xc4a8fc8cUL, 0x1aa0f03fUL, 0xd8567d2cUL, 0xef223390UL,
+      0xc787494eUL, 0xc1d938d1UL, 0xfe8ccaa2UL, 0x3698d40bUL,
+      0xcfa6f581UL, 0x28a57adeUL, 0x26dab78eUL, 0xa43fadbfUL,
+      0xe42c3a9dUL, 0x0d507892UL, 0x9b6a5fccUL, 0x62547e46UL,
+      0xc2f68d13UL, 0xe890d8b8UL, 0x5e2e39f7UL, 0xf582c3afUL,
+      0xbe9f5d80UL, 0x7c69d093UL, 0xa96fd52dUL, 0xb3cf2512UL,
+      0x3bc8ac99UL, 0xa710187dUL, 0x6ee89c63UL, 0x7bdb3bbbUL,
+      0x09cd2678UL, 0xf46e5918UL, 0x01ec9ab7UL, 0xa8834f9aUL,
+      0x65e6956eUL, 0x7eaaffe6UL, 0x0821bccfUL, 0xe6ef15e8UL,
+      0xd9bae79bUL, 0xce4a6f36UL, 0xd4ea9f09UL, 0xd629b07cUL,
+      0xaf31a4b2UL, 0x312a3f23UL, 0x30c6a594UL, 0xc035a266UL,
+      0x37744ebcUL, 0xa6fc82caUL, 0xb0e090d0UL, 0x1533a7d8UL,
+      0x4af10498UL, 0xf741ecdaUL, 0x0e7fcd50UL, 0x2f1791f6UL,
+      0x8d764dd6UL, 0x4d43efb0UL, 0x54ccaa4dUL, 0xdfe49604UL,
+      0xe39ed1b5UL, 0x1b4c6a88UL, 0xb8c12c1fUL, 0x7f466551UL,
+      0x049d5eeaUL, 0x5d018c35UL, 0x73fa8774UL, 0x2efb0b41UL,
+      0x5ab3671dUL, 0x5292dbd2UL, 0x33e91056UL, 0x136dd647UL,
+      0x8c9ad761UL, 0x7a37a10cUL, 0x8e59f814UL, 0x89eb133cUL,
+      0xeecea927UL, 0x35b761c9UL, 0xede11ce5UL, 0x3c7a47b1UL,
+      0x599cd2dfUL, 0x3f55f273UL, 0x791814ceUL, 0xbf73c737UL,
+      0xea53f7cdUL, 0x5b5ffdaaUL, 0x14df3d6fUL, 0x867844dbUL,
+      0x81caaff3UL, 0x3eb968c4UL, 0x2c382434UL, 0x5fc2a340UL,
+      0x72161dc3UL, 0x0cbce225UL, 0x8b283c49UL, 0x41ff0d95UL,
+      0x7139a801UL, 0xde080cb3UL, 0x9cd8b4e4UL, 0x906456c1UL,
+      0x617bcb84UL, 0x70d532b6UL, 0x74486c5cUL, 0x42d0b857UL
+  };
+  s820 = table2[s819];
+  s821 = s562 ^ s820;
+  static const SWord32 table3[] = {
+      0xa75051f4UL, 0x65537e41UL, 0xa4c31a17UL, 0x5e963a27UL,
+      0x6bcb3babUL, 0x45f11f9dUL, 0x58abacfaUL, 0x03934be3UL,
+      0xfa552030UL, 0x6df6ad76UL, 0x769188ccUL, 0x4c25f502UL,
+      0xd7fc4fe5UL, 0xcbd7c52aUL, 0x44802635UL, 0xa38fb562UL,
+      0x5a49deb1UL, 0x1b6725baUL, 0x0e9845eaUL, 0xc0e15dfeUL,
+      0x7502c32fUL, 0xf012814cUL, 0x97a38d46UL, 0xf9c66bd3UL,
+      0x5fe7038fUL, 0x9c951592UL, 0x7aebbf6dUL, 0x59da9552UL,
+      0x832dd4beUL, 0x21d35874UL, 0x692949e0UL, 0xc8448ec9UL,
+      0x896a75c2UL, 0x7978f48eUL, 0x3e6b9958UL, 0x71dd27b9UL,
+      0x4fb6bee1UL, 0xad17f088UL, 0xac66c920UL, 0x3ab47dceUL,
+      0x4a1863dfUL, 0x3182e51aUL, 0x33609751UL, 0x7f456253UL,
+      0x77e0b164UL, 0xae84bb6bUL, 0xa01cfe81UL, 0x2b94f908UL,
+      0x68587048UL, 0xfd198f45UL, 0x6c8794deUL, 0xf8b7527bUL,
+      0xd323ab73UL, 0x02e2724bUL, 0x8f57e31fUL, 0xab2a6655UL,
+      0x2807b2ebUL, 0xc2032fb5UL, 0x7b9a86c5UL, 0x08a5d337UL,
+      0x87f23028UL, 0xa5b223bfUL, 0x6aba0203UL, 0x825ced16UL,
+      0x1c2b8acfUL, 0xb492a779UL, 0xf2f0f307UL, 0xe2a14e69UL,
+      0xf4cd65daUL, 0xbed50605UL, 0x621fd134UL, 0xfe8ac4a6UL,
+      0x539d342eUL, 0x55a0a2f3UL, 0xe132058aUL, 0xeb75a4f6UL,
+      0xec390b83UL, 0xefaa4060UL, 0x9f065e71UL, 0x1051bd6eUL,
+      0x8af93e21UL, 0x063d96ddUL, 0x05aedd3eUL, 0xbd464de6UL,
+      0x8db59154UL, 0x5d0571c4UL, 0xd46f0406UL, 0x15ff6050UL,
+      0xfb241998UL, 0xe997d6bdUL, 0x43cc8940UL, 0x9e7767d9UL,
+      0x42bdb0e8UL, 0x8b880789UL, 0x5b38e719UL, 0xeedb79c8UL,
+      0x0a47a17cUL, 0x0fe97c42UL, 0x1ec9f884UL, 0x00000000UL,
+      0x86830980UL, 0xed48322bUL, 0x70ac1e11UL, 0x724e6c5aUL,
+      0xfffbfd0eUL, 0x38560f85UL, 0xd51e3daeUL, 0x3927362dUL,
+      0xd9640a0fUL, 0xa621685cUL, 0x54d19b5bUL, 0x2e3a2436UL,
+      0x67b10c0aUL, 0xe70f9357UL, 0x96d2b4eeUL, 0x919e1b9bUL,
+      0xc54f80c0UL, 0x20a261dcUL, 0x4b695a77UL, 0x1a161c12UL,
+      0xba0ae293UL, 0x2ae5c0a0UL, 0xe0433c22UL, 0x171d121bUL,
+      0x0d0b0e09UL, 0xc7adf28bUL, 0xa8b92db6UL, 0xa9c8141eUL,
+      0x198557f1UL, 0x074caf75UL, 0xddbbee99UL, 0x60fda37fUL,
+      0x269ff701UL, 0xf5bc5c72UL, 0x3bc54466UL, 0x7e345bfbUL,
+      0x29768b43UL, 0xc6dccb23UL, 0xfc68b6edUL, 0xf163b8e4UL,
+      0xdccad731UL, 0x85104263UL, 0x22401397UL, 0x112084c6UL,
+      0x247d854aUL, 0x3df8d2bbUL, 0x3211aef9UL, 0xa16dc729UL,
+      0x2f4b1d9eUL, 0x30f3dcb2UL, 0x52ec0d86UL, 0xe3d077c1UL,
+      0x166c2bb3UL, 0xb999a970UL, 0x48fa1194UL, 0x642247e9UL,
+      0x8cc4a8fcUL, 0x3f1aa0f0UL, 0x2cd8567dUL, 0x90ef2233UL,
+      0x4ec78749UL, 0xd1c1d938UL, 0xa2fe8ccaUL, 0x0b3698d4UL,
+      0x81cfa6f5UL, 0xde28a57aUL, 0x8e26dab7UL, 0xbfa43fadUL,
+      0x9de42c3aUL, 0x920d5078UL, 0xcc9b6a5fUL, 0x4662547eUL,
+      0x13c2f68dUL, 0xb8e890d8UL, 0xf75e2e39UL, 0xaff582c3UL,
+      0x80be9f5dUL, 0x937c69d0UL, 0x2da96fd5UL, 0x12b3cf25UL,
+      0x993bc8acUL, 0x7da71018UL, 0x636ee89cUL, 0xbb7bdb3bUL,
+      0x7809cd26UL, 0x18f46e59UL, 0xb701ec9aUL, 0x9aa8834fUL,
+      0x6e65e695UL, 0xe67eaaffUL, 0xcf0821bcUL, 0xe8e6ef15UL,
+      0x9bd9bae7UL, 0x36ce4a6fUL, 0x09d4ea9fUL, 0x7cd629b0UL,
+      0xb2af31a4UL, 0x23312a3fUL, 0x9430c6a5UL, 0x66c035a2UL,
+      0xbc37744eUL, 0xcaa6fc82UL, 0xd0b0e090UL, 0xd81533a7UL,
+      0x984af104UL, 0xdaf741ecUL, 0x500e7fcdUL, 0xf62f1791UL,
+      0xd68d764dUL, 0xb04d43efUL, 0x4d54ccaaUL, 0x04dfe496UL,
+      0xb5e39ed1UL, 0x881b4c6aUL, 0x1fb8c12cUL, 0x517f4665UL,
+      0xea049d5eUL, 0x355d018cUL, 0x7473fa87UL, 0x412efb0bUL,
+      0x1d5ab367UL, 0xd25292dbUL, 0x5633e910UL, 0x47136dd6UL,
+      0x618c9ad7UL, 0x0c7a37a1UL, 0x148e59f8UL, 0x3c89eb13UL,
+      0x27eecea9UL, 0xc935b761UL, 0xe5ede11cUL, 0xb13c7a47UL,
+      0xdf599cd2UL, 0x733f55f2UL, 0xce791814UL, 0x37bf73c7UL,
+      0xcdea53f7UL, 0xaa5b5ffdUL, 0x6f14df3dUL, 0xdb867844UL,
+      0xf381caafUL, 0xc43eb968UL, 0x342c3824UL, 0x405fc2a3UL,
+      0xc372161dUL, 0x250cbce2UL, 0x498b283cUL, 0x9541ff0dUL,
+      0x017139a8UL, 0xb3de080cUL, 0xe49cd8b4UL, 0xc1906456UL,
+      0x84617bcbUL, 0xb670d532UL, 0x5c74486cUL, 0x5742d0b8UL
+  };
+  s1079 = table3[s1078];
+  s1080 = s821 ^ s1079;
+  static const SWord32 table4[] = {
+      0xf4a75051UL, 0x4165537eUL, 0x17a4c31aUL, 0x275e963aUL,
+      0xab6bcb3bUL, 0x9d45f11fUL, 0xfa58abacUL, 0xe303934bUL,
+      0x30fa5520UL, 0x766df6adUL, 0xcc769188UL, 0x024c25f5UL,
+      0xe5d7fc4fUL, 0x2acbd7c5UL, 0x35448026UL, 0x62a38fb5UL,
+      0xb15a49deUL, 0xba1b6725UL, 0xea0e9845UL, 0xfec0e15dUL,
+      0x2f7502c3UL, 0x4cf01281UL, 0x4697a38dUL, 0xd3f9c66bUL,
+      0x8f5fe703UL, 0x929c9515UL, 0x6d7aebbfUL, 0x5259da95UL,
+      0xbe832dd4UL, 0x7421d358UL, 0xe0692949UL, 0xc9c8448eUL,
+      0xc2896a75UL, 0x8e7978f4UL, 0x583e6b99UL, 0xb971dd27UL,
+      0xe14fb6beUL, 0x88ad17f0UL, 0x20ac66c9UL, 0xce3ab47dUL,
+      0xdf4a1863UL, 0x1a3182e5UL, 0x51336097UL, 0x537f4562UL,
+      0x6477e0b1UL, 0x6bae84bbUL, 0x81a01cfeUL, 0x082b94f9UL,
+      0x48685870UL, 0x45fd198fUL, 0xde6c8794UL, 0x7bf8b752UL,
+      0x73d323abUL, 0x4b02e272UL, 0x1f8f57e3UL, 0x55ab2a66UL,
+      0xeb2807b2UL, 0xb5c2032fUL, 0xc57b9a86UL, 0x3708a5d3UL,
+      0x2887f230UL, 0xbfa5b223UL, 0x036aba02UL, 0x16825cedUL,
+      0xcf1c2b8aUL, 0x79b492a7UL, 0x07f2f0f3UL, 0x69e2a14eUL,
+      0xdaf4cd65UL, 0x05bed506UL, 0x34621fd1UL, 0xa6fe8ac4UL,
+      0x2e539d34UL, 0xf355a0a2UL, 0x8ae13205UL, 0xf6eb75a4UL,
+      0x83ec390bUL, 0x60efaa40UL, 0x719f065eUL, 0x6e1051bdUL,
+      0x218af93eUL, 0xdd063d96UL, 0x3e05aeddUL, 0xe6bd464dUL,
+      0x548db591UL, 0xc45d0571UL, 0x06d46f04UL, 0x5015ff60UL,
+      0x98fb2419UL, 0xbde997d6UL, 0x4043cc89UL, 0xd99e7767UL,
+      0xe842bdb0UL, 0x898b8807UL, 0x195b38e7UL, 0xc8eedb79UL,
+      0x7c0a47a1UL, 0x420fe97cUL, 0x841ec9f8UL, 0x00000000UL,
+      0x80868309UL, 0x2bed4832UL, 0x1170ac1eUL, 0x5a724e6cUL,
+      0x0efffbfdUL, 0x8538560fUL, 0xaed51e3dUL, 0x2d392736UL,
+      0x0fd9640aUL, 0x5ca62168UL, 0x5b54d19bUL, 0x362e3a24UL,
+      0x0a67b10cUL, 0x57e70f93UL, 0xee96d2b4UL, 0x9b919e1bUL,
+      0xc0c54f80UL, 0xdc20a261UL, 0x774b695aUL, 0x121a161cUL,
+      0x93ba0ae2UL, 0xa02ae5c0UL, 0x22e0433cUL, 0x1b171d12UL,
+      0x090d0b0eUL, 0x8bc7adf2UL, 0xb6a8b92dUL, 0x1ea9c814UL,
+      0xf1198557UL, 0x75074cafUL, 0x99ddbbeeUL, 0x7f60fda3UL,
+      0x01269ff7UL, 0x72f5bc5cUL, 0x663bc544UL, 0xfb7e345bUL,
+      0x4329768bUL, 0x23c6dccbUL, 0xedfc68b6UL, 0xe4f163b8UL,
+      0x31dccad7UL, 0x63851042UL, 0x97224013UL, 0xc6112084UL,
+      0x4a247d85UL, 0xbb3df8d2UL, 0xf93211aeUL, 0x29a16dc7UL,
+      0x9e2f4b1dUL, 0xb230f3dcUL, 0x8652ec0dUL, 0xc1e3d077UL,
+      0xb3166c2bUL, 0x70b999a9UL, 0x9448fa11UL, 0xe9642247UL,
+      0xfc8cc4a8UL, 0xf03f1aa0UL, 0x7d2cd856UL, 0x3390ef22UL,
+      0x494ec787UL, 0x38d1c1d9UL, 0xcaa2fe8cUL, 0xd40b3698UL,
+      0xf581cfa6UL, 0x7ade28a5UL, 0xb78e26daUL, 0xadbfa43fUL,
+      0x3a9de42cUL, 0x78920d50UL, 0x5fcc9b6aUL, 0x7e466254UL,
+      0x8d13c2f6UL, 0xd8b8e890UL, 0x39f75e2eUL, 0xc3aff582UL,
+      0x5d80be9fUL, 0xd0937c69UL, 0xd52da96fUL, 0x2512b3cfUL,
+      0xac993bc8UL, 0x187da710UL, 0x9c636ee8UL, 0x3bbb7bdbUL,
+      0x267809cdUL, 0x5918f46eUL, 0x9ab701ecUL, 0x4f9aa883UL,
+      0x956e65e6UL, 0xffe67eaaUL, 0xbccf0821UL, 0x15e8e6efUL,
+      0xe79bd9baUL, 0x6f36ce4aUL, 0x9f09d4eaUL, 0xb07cd629UL,
+      0xa4b2af31UL, 0x3f23312aUL, 0xa59430c6UL, 0xa266c035UL,
+      0x4ebc3774UL, 0x82caa6fcUL, 0x90d0b0e0UL, 0xa7d81533UL,
+      0x04984af1UL, 0xecdaf741UL, 0xcd500e7fUL, 0x91f62f17UL,
+      0x4dd68d76UL, 0xefb04d43UL, 0xaa4d54ccUL, 0x9604dfe4UL,
+      0xd1b5e39eUL, 0x6a881b4cUL, 0x2c1fb8c1UL, 0x65517f46UL,
+      0x5eea049dUL, 0x8c355d01UL, 0x877473faUL, 0x0b412efbUL,
+      0x671d5ab3UL, 0xdbd25292UL, 0x105633e9UL, 0xd647136dUL,
+      0xd7618c9aUL, 0xa10c7a37UL, 0xf8148e59UL, 0x133c89ebUL,
+      0xa927eeceUL, 0x61c935b7UL, 0x1ce5ede1UL, 0x47b13c7aUL,
+      0xd2df599cUL, 0xf2733f55UL, 0x14ce7918UL, 0xc737bf73UL,
+      0xf7cdea53UL, 0xfdaa5b5fUL, 0x3d6f14dfUL, 0x44db8678UL,
+      0xaff381caUL, 0x68c43eb9UL, 0x24342c38UL, 0xa3405fc2UL,
+      0x1dc37216UL, 0xe2250cbcUL, 0x3c498b28UL, 0x0d9541ffUL,
+      0xa8017139UL, 0x0cb3de08UL, 0xb4e49cd8UL, 0x56c19064UL,
+      0xcb84617bUL, 0x32b670d5UL, 0x6c5c7448UL, 0xb85742d0UL
+  };
+  s1338 = table4[s1337];
+  s1339 = s1080 ^ s1338;
+  s1340 = s8 ^ s1339;
+  s1341 = sbv_bv_extract_u32_31_24_u8(s1340);
+  s1342 = table1[s1341];
+  s1344 = table1[s1343];
+  s1346 = table2[s1345];
+  s1347 = s1344 ^ s1346;
+  s1349 = table3[s1348];
+  s1350 = s1347 ^ s1349;
+  s1352 = table4[s1351];
+  s1353 = s1350 ^ s1352;
+  s1354 = s11 ^ s1353;
+  s1355 = sbv_bv_extract_u32_23_16_u8(s1354);
+  s1356 = table2[s1355];
+  s1357 = s1342 ^ s1356;
+  s1359 = table1[s1358];
+  s1361 = table2[s1360];
+  s1362 = s1359 ^ s1361;
+  s1364 = table3[s1363];
+  s1365 = s1362 ^ s1364;
+  s1367 = table4[s1366];
+  s1368 = s1365 ^ s1367;
+  s1369 = s10 ^ s1368;
+  s1370 = sbv_bv_extract_u32_15_8_u8(s1369);
+  s1371 = table3[s1370];
+  s1372 = s1357 ^ s1371;
+  s1374 = table1[s1373];
+  s1376 = table2[s1375];
+  s1377 = s1374 ^ s1376;
+  s1379 = table3[s1378];
+  s1380 = s1377 ^ s1379;
+  s1382 = table4[s1381];
+  s1383 = s1380 ^ s1382;
+  s1384 = s9 ^ s1383;
+  s1385 = sbv_bv_extract_u32_7_0_u8(s1384);
+  s1386 = table4[s1385];
+  s1387 = s1372 ^ s1386;
+  s1388 = s12 ^ s1387;
+  s1389 = sbv_bv_extract_u32_31_24_u8(s1388);
+  s1390 = table1[s1389];
+  s1391 = sbv_bv_extract_u32_31_24_u8(s1354);
+  s1392 = table1[s1391];
+  s1393 = sbv_bv_extract_u32_23_16_u8(s1369);
+  s1394 = table2[s1393];
+  s1395 = s1392 ^ s1394;
+  s1396 = sbv_bv_extract_u32_15_8_u8(s1384);
+  s1397 = table3[s1396];
+  s1398 = s1395 ^ s1397;
+  s1399 = sbv_bv_extract_u32_7_0_u8(s1340);
+  s1400 = table4[s1399];
+  s1401 = s1398 ^ s1400;
+  s1402 = s15 ^ s1401;
+  s1403 = sbv_bv_extract_u32_23_16_u8(s1402);
+  s1404 = table2[s1403];
+  s1405 = s1390 ^ s1404;
+  s1406 = sbv_bv_extract_u32_31_24_u8(s1369);
+  s1407 = table1[s1406];
+  s1408 = sbv_bv_extract_u32_23_16_u8(s1384);
+  s1409 = table2[s1408];
+  s1410 = s1407 ^ s1409;
+  s1411 = sbv_bv_extract_u32_15_8_u8(s1340);
+  s1412 = table3[s1411];
+  s1413 = s1410 ^ s1412;
+  s1414 = sbv_bv_extract_u32_7_0_u8(s1354);
+  s1415 = table4[s1414];
+  s1416 = s1413 ^ s1415;
+  s1417 = s14 ^ s1416;
+  s1418 = sbv_bv_extract_u32_15_8_u8(s1417);
+  s1419 = table3[s1418];
+  s1420 = s1405 ^ s1419;
+  s1421 = sbv_bv_extract_u32_31_24_u8(s1384);
+  s1422 = table1[s1421];
+  s1423 = sbv_bv_extract_u32_23_16_u8(s1340);
+  s1424 = table2[s1423];
+  s1425 = s1422 ^ s1424;
+  s1426 = sbv_bv_extract_u32_15_8_u8(s1354);
+  s1427 = table3[s1426];
+  s1428 = s1425 ^ s1427;
+  s1429 = sbv_bv_extract_u32_7_0_u8(s1369);
+  s1430 = table4[s1429];
+  s1431 = s1428 ^ s1430;
+  s1432 = s13 ^ s1431;
+  s1433 = sbv_bv_extract_u32_7_0_u8(s1432);
+  s1434 = table4[s1433];
+  s1435 = s1420 ^ s1434;
+  s1436 = s16 ^ s1435;
+  s1437 = sbv_bv_extract_u32_31_24_u8(s1436);
+  s1438 = table1[s1437];
+  s1439 = sbv_bv_extract_u32_31_24_u8(s1402);
+  s1440 = table1[s1439];
+  s1441 = sbv_bv_extract_u32_23_16_u8(s1417);
+  s1442 = table2[s1441];
+  s1443 = s1440 ^ s1442;
+  s1444 = sbv_bv_extract_u32_15_8_u8(s1432);
+  s1445 = table3[s1444];
+  s1446 = s1443 ^ s1445;
+  s1447 = sbv_bv_extract_u32_7_0_u8(s1388);
+  s1448 = table4[s1447];
+  s1449 = s1446 ^ s1448;
+  s1450 = s19 ^ s1449;
+  s1451 = sbv_bv_extract_u32_23_16_u8(s1450);
+  s1452 = table2[s1451];
+  s1453 = s1438 ^ s1452;
+  s1454 = sbv_bv_extract_u32_31_24_u8(s1417);
+  s1455 = table1[s1454];
+  s1456 = sbv_bv_extract_u32_23_16_u8(s1432);
+  s1457 = table2[s1456];
+  s1458 = s1455 ^ s1457;
+  s1459 = sbv_bv_extract_u32_15_8_u8(s1388);
+  s1460 = table3[s1459];
+  s1461 = s1458 ^ s1460;
+  s1462 = sbv_bv_extract_u32_7_0_u8(s1402);
+  s1463 = table4[s1462];
+  s1464 = s1461 ^ s1463;
+  s1465 = s18 ^ s1464;
+  s1466 = sbv_bv_extract_u32_15_8_u8(s1465);
+  s1467 = table3[s1466];
+  s1468 = s1453 ^ s1467;
+  s1469 = sbv_bv_extract_u32_31_24_u8(s1432);
+  s1470 = table1[s1469];
+  s1471 = sbv_bv_extract_u32_23_16_u8(s1388);
+  s1472 = table2[s1471];
+  s1473 = s1470 ^ s1472;
+  s1474 = sbv_bv_extract_u32_15_8_u8(s1402);
+  s1475 = table3[s1474];
+  s1476 = s1473 ^ s1475;
+  s1477 = sbv_bv_extract_u32_7_0_u8(s1417);
+  s1478 = table4[s1477];
+  s1479 = s1476 ^ s1478;
+  s1480 = s17 ^ s1479;
+  s1481 = sbv_bv_extract_u32_7_0_u8(s1480);
+  s1482 = table4[s1481];
+  s1483 = s1468 ^ s1482;
+  s1484 = s20 ^ s1483;
+  s1485 = sbv_bv_extract_u32_31_24_u8(s1484);
+  s1486 = table1[s1485];
+  s1487 = sbv_bv_extract_u32_31_24_u8(s1450);
+  s1488 = table1[s1487];
+  s1489 = sbv_bv_extract_u32_23_16_u8(s1465);
+  s1490 = table2[s1489];
+  s1491 = s1488 ^ s1490;
+  s1492 = sbv_bv_extract_u32_15_8_u8(s1480);
+  s1493 = table3[s1492];
+  s1494 = s1491 ^ s1493;
+  s1495 = sbv_bv_extract_u32_7_0_u8(s1436);
+  s1496 = table4[s1495];
+  s1497 = s1494 ^ s1496;
+  s1498 = s23 ^ s1497;
+  s1499 = sbv_bv_extract_u32_23_16_u8(s1498);
+  s1500 = table2[s1499];
+  s1501 = s1486 ^ s1500;
+  s1502 = sbv_bv_extract_u32_31_24_u8(s1465);
+  s1503 = table1[s1502];
+  s1504 = sbv_bv_extract_u32_23_16_u8(s1480);
+  s1505 = table2[s1504];
+  s1506 = s1503 ^ s1505;
+  s1507 = sbv_bv_extract_u32_15_8_u8(s1436);
+  s1508 = table3[s1507];
+  s1509 = s1506 ^ s1508;
+  s1510 = sbv_bv_extract_u32_7_0_u8(s1450);
+  s1511 = table4[s1510];
+  s1512 = s1509 ^ s1511;
+  s1513 = s22 ^ s1512;
+  s1514 = sbv_bv_extract_u32_15_8_u8(s1513);
+  s1515 = table3[s1514];
+  s1516 = s1501 ^ s1515;
+  s1517 = sbv_bv_extract_u32_31_24_u8(s1480);
+  s1518 = table1[s1517];
+  s1519 = sbv_bv_extract_u32_23_16_u8(s1436);
+  s1520 = table2[s1519];
+  s1521 = s1518 ^ s1520;
+  s1522 = sbv_bv_extract_u32_15_8_u8(s1450);
+  s1523 = table3[s1522];
+  s1524 = s1521 ^ s1523;
+  s1525 = sbv_bv_extract_u32_7_0_u8(s1465);
+  s1526 = table4[s1525];
+  s1527 = s1524 ^ s1526;
+  s1528 = s21 ^ s1527;
+  s1529 = sbv_bv_extract_u32_7_0_u8(s1528);
+  s1530 = table4[s1529];
+  s1531 = s1516 ^ s1530;
+  s1532 = s24 ^ s1531;
+  s1533 = sbv_bv_extract_u32_31_24_u8(s1532);
+  s1534 = table1[s1533];
+  s1535 = sbv_bv_extract_u32_31_24_u8(s1498);
+  s1536 = table1[s1535];
+  s1537 = sbv_bv_extract_u32_23_16_u8(s1513);
+  s1538 = table2[s1537];
+  s1539 = s1536 ^ s1538;
+  s1540 = sbv_bv_extract_u32_15_8_u8(s1528);
+  s1541 = table3[s1540];
+  s1542 = s1539 ^ s1541;
+  s1543 = sbv_bv_extract_u32_7_0_u8(s1484);
+  s1544 = table4[s1543];
+  s1545 = s1542 ^ s1544;
+  s1546 = s27 ^ s1545;
+  s1547 = sbv_bv_extract_u32_23_16_u8(s1546);
+  s1548 = table2[s1547];
+  s1549 = s1534 ^ s1548;
+  s1550 = sbv_bv_extract_u32_31_24_u8(s1513);
+  s1551 = table1[s1550];
+  s1552 = sbv_bv_extract_u32_23_16_u8(s1528);
+  s1553 = table2[s1552];
+  s1554 = s1551 ^ s1553;
+  s1555 = sbv_bv_extract_u32_15_8_u8(s1484);
+  s1556 = table3[s1555];
+  s1557 = s1554 ^ s1556;
+  s1558 = sbv_bv_extract_u32_7_0_u8(s1498);
+  s1559 = table4[s1558];
+  s1560 = s1557 ^ s1559;
+  s1561 = s26 ^ s1560;
+  s1562 = sbv_bv_extract_u32_15_8_u8(s1561);
+  s1563 = table3[s1562];
+  s1564 = s1549 ^ s1563;
+  s1565 = sbv_bv_extract_u32_31_24_u8(s1528);
+  s1566 = table1[s1565];
+  s1567 = sbv_bv_extract_u32_23_16_u8(s1484);
+  s1568 = table2[s1567];
+  s1569 = s1566 ^ s1568;
+  s1570 = sbv_bv_extract_u32_15_8_u8(s1498);
+  s1571 = table3[s1570];
+  s1572 = s1569 ^ s1571;
+  s1573 = sbv_bv_extract_u32_7_0_u8(s1513);
+  s1574 = table4[s1573];
+  s1575 = s1572 ^ s1574;
+  s1576 = s25 ^ s1575;
+  s1577 = sbv_bv_extract_u32_7_0_u8(s1576);
+  s1578 = table4[s1577];
+  s1579 = s1564 ^ s1578;
+  s1580 = s28 ^ s1579;
+  s1581 = sbv_bv_extract_u32_31_24_u8(s1580);
+  s1582 = table1[s1581];
+  s1583 = sbv_bv_extract_u32_31_24_u8(s1546);
+  s1584 = table1[s1583];
+  s1585 = sbv_bv_extract_u32_23_16_u8(s1561);
+  s1586 = table2[s1585];
+  s1587 = s1584 ^ s1586;
+  s1588 = sbv_bv_extract_u32_15_8_u8(s1576);
+  s1589 = table3[s1588];
+  s1590 = s1587 ^ s1589;
+  s1591 = sbv_bv_extract_u32_7_0_u8(s1532);
+  s1592 = table4[s1591];
+  s1593 = s1590 ^ s1592;
+  s1594 = s31 ^ s1593;
+  s1595 = sbv_bv_extract_u32_23_16_u8(s1594);
+  s1596 = table2[s1595];
+  s1597 = s1582 ^ s1596;
+  s1598 = sbv_bv_extract_u32_31_24_u8(s1561);
+  s1599 = table1[s1598];
+  s1600 = sbv_bv_extract_u32_23_16_u8(s1576);
+  s1601 = table2[s1600];
+  s1602 = s1599 ^ s1601;
+  s1603 = sbv_bv_extract_u32_15_8_u8(s1532);
+  s1604 = table3[s1603];
+  s1605 = s1602 ^ s1604;
+  s1606 = sbv_bv_extract_u32_7_0_u8(s1546);
+  s1607 = table4[s1606];
+  s1608 = s1605 ^ s1607;
+  s1609 = s30 ^ s1608;
+  s1610 = sbv_bv_extract_u32_15_8_u8(s1609);
+  s1611 = table3[s1610];
+  s1612 = s1597 ^ s1611;
+  s1613 = sbv_bv_extract_u32_31_24_u8(s1576);
+  s1614 = table1[s1613];
+  s1615 = sbv_bv_extract_u32_23_16_u8(s1532);
+  s1616 = table2[s1615];
+  s1617 = s1614 ^ s1616;
+  s1618 = sbv_bv_extract_u32_15_8_u8(s1546);
+  s1619 = table3[s1618];
+  s1620 = s1617 ^ s1619;
+  s1621 = sbv_bv_extract_u32_7_0_u8(s1561);
+  s1622 = table4[s1621];
+  s1623 = s1620 ^ s1622;
+  s1624 = s29 ^ s1623;
+  s1625 = sbv_bv_extract_u32_7_0_u8(s1624);
+  s1626 = table4[s1625];
+  s1627 = s1612 ^ s1626;
+  s1628 = s32 ^ s1627;
+  s1629 = sbv_bv_extract_u32_31_24_u8(s1628);
+  s1630 = table1[s1629];
+  s1631 = sbv_bv_extract_u32_31_24_u8(s1594);
+  s1632 = table1[s1631];
+  s1633 = sbv_bv_extract_u32_23_16_u8(s1609);
+  s1634 = table2[s1633];
+  s1635 = s1632 ^ s1634;
+  s1636 = sbv_bv_extract_u32_15_8_u8(s1624);
+  s1637 = table3[s1636];
+  s1638 = s1635 ^ s1637;
+  s1639 = sbv_bv_extract_u32_7_0_u8(s1580);
+  s1640 = table4[s1639];
+  s1641 = s1638 ^ s1640;
+  s1642 = s35 ^ s1641;
+  s1643 = sbv_bv_extract_u32_23_16_u8(s1642);
+  s1644 = table2[s1643];
+  s1645 = s1630 ^ s1644;
+  s1646 = sbv_bv_extract_u32_31_24_u8(s1609);
+  s1647 = table1[s1646];
+  s1648 = sbv_bv_extract_u32_23_16_u8(s1624);
+  s1649 = table2[s1648];
+  s1650 = s1647 ^ s1649;
+  s1651 = sbv_bv_extract_u32_15_8_u8(s1580);
+  s1652 = table3[s1651];
+  s1653 = s1650 ^ s1652;
+  s1654 = sbv_bv_extract_u32_7_0_u8(s1594);
+  s1655 = table4[s1654];
+  s1656 = s1653 ^ s1655;
+  s1657 = s34 ^ s1656;
+  s1658 = sbv_bv_extract_u32_15_8_u8(s1657);
+  s1659 = table3[s1658];
+  s1660 = s1645 ^ s1659;
+  s1661 = sbv_bv_extract_u32_31_24_u8(s1624);
+  s1662 = table1[s1661];
+  s1663 = sbv_bv_extract_u32_23_16_u8(s1580);
+  s1664 = table2[s1663];
+  s1665 = s1662 ^ s1664;
+  s1666 = sbv_bv_extract_u32_15_8_u8(s1594);
+  s1667 = table3[s1666];
+  s1668 = s1665 ^ s1667;
+  s1669 = sbv_bv_extract_u32_7_0_u8(s1609);
+  s1670 = table4[s1669];
+  s1671 = s1668 ^ s1670;
+  s1672 = s33 ^ s1671;
+  s1673 = sbv_bv_extract_u32_7_0_u8(s1672);
+  s1674 = table4[s1673];
+  s1675 = s1660 ^ s1674;
+  s1676 = s36 ^ s1675;
+  s1677 = sbv_bv_extract_u32_31_24_u8(s1676);
+  s1678 = table1[s1677];
+  s1679 = sbv_bv_extract_u32_31_24_u8(s1642);
+  s1680 = table1[s1679];
+  s1681 = sbv_bv_extract_u32_23_16_u8(s1657);
+  s1682 = table2[s1681];
+  s1683 = s1680 ^ s1682;
+  s1684 = sbv_bv_extract_u32_15_8_u8(s1672);
+  s1685 = table3[s1684];
+  s1686 = s1683 ^ s1685;
+  s1687 = sbv_bv_extract_u32_7_0_u8(s1628);
+  s1688 = table4[s1687];
+  s1689 = s1686 ^ s1688;
+  s1690 = s39 ^ s1689;
+  s1691 = sbv_bv_extract_u32_23_16_u8(s1690);
+  s1692 = table2[s1691];
+  s1693 = s1678 ^ s1692;
+  s1694 = sbv_bv_extract_u32_31_24_u8(s1657);
+  s1695 = table1[s1694];
+  s1696 = sbv_bv_extract_u32_23_16_u8(s1672);
+  s1697 = table2[s1696];
+  s1698 = s1695 ^ s1697;
+  s1699 = sbv_bv_extract_u32_15_8_u8(s1628);
+  s1700 = table3[s1699];
+  s1701 = s1698 ^ s1700;
+  s1702 = sbv_bv_extract_u32_7_0_u8(s1642);
+  s1703 = table4[s1702];
+  s1704 = s1701 ^ s1703;
+  s1705 = s38 ^ s1704;
+  s1706 = sbv_bv_extract_u32_15_8_u8(s1705);
+  s1707 = table3[s1706];
+  s1708 = s1693 ^ s1707;
+  s1709 = sbv_bv_extract_u32_31_24_u8(s1672);
+  s1710 = table1[s1709];
+  s1711 = sbv_bv_extract_u32_23_16_u8(s1628);
+  s1712 = table2[s1711];
+  s1713 = s1710 ^ s1712;
+  s1714 = sbv_bv_extract_u32_15_8_u8(s1642);
+  s1715 = table3[s1714];
+  s1716 = s1713 ^ s1715;
+  s1717 = sbv_bv_extract_u32_7_0_u8(s1657);
+  s1718 = table4[s1717];
+  s1719 = s1716 ^ s1718;
+  s1720 = s37 ^ s1719;
+  s1721 = sbv_bv_extract_u32_7_0_u8(s1720);
+  s1722 = table4[s1721];
+  s1723 = s1708 ^ s1722;
+  s1724 = s40 ^ s1723;
+  s1725 = sbv_bv_extract_u32_31_24_u8(s1724);
+  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
+  };
+  s1726 = table0[s1725];
+  s1727 = sbv_bv_extract_u32_31_24_u8(s1690);
+  s1728 = table1[s1727];
+  s1729 = sbv_bv_extract_u32_23_16_u8(s1705);
+  s1730 = table2[s1729];
+  s1731 = s1728 ^ s1730;
+  s1732 = sbv_bv_extract_u32_15_8_u8(s1720);
+  s1733 = table3[s1732];
+  s1734 = s1731 ^ s1733;
+  s1735 = sbv_bv_extract_u32_7_0_u8(s1676);
+  s1736 = table4[s1735];
+  s1737 = s1734 ^ s1736;
+  s1738 = s43 ^ s1737;
+  s1739 = sbv_bv_extract_u32_23_16_u8(s1738);
+  s1740 = table0[s1739];
+  s1741 = sbv_bv_join_u8_u8_u16(s1726, s1740);
+  s1742 = sbv_bv_extract_u32_31_24_u8(s1705);
+  s1743 = table1[s1742];
+  s1744 = sbv_bv_extract_u32_23_16_u8(s1720);
+  s1745 = table2[s1744];
+  s1746 = s1743 ^ s1745;
+  s1747 = sbv_bv_extract_u32_15_8_u8(s1676);
+  s1748 = table3[s1747];
+  s1749 = s1746 ^ s1748;
+  s1750 = sbv_bv_extract_u32_7_0_u8(s1690);
+  s1751 = table4[s1750];
+  s1752 = s1749 ^ s1751;
+  s1753 = s42 ^ s1752;
+  s1754 = sbv_bv_extract_u32_15_8_u8(s1753);
+  s1755 = table0[s1754];
+  s1756 = sbv_bv_extract_u32_31_24_u8(s1720);
+  s1757 = table1[s1756];
+  s1758 = sbv_bv_extract_u32_23_16_u8(s1676);
+  s1759 = table2[s1758];
+  s1760 = s1757 ^ s1759;
+  s1761 = sbv_bv_extract_u32_15_8_u8(s1690);
+  s1762 = table3[s1761];
+  s1763 = s1760 ^ s1762;
+  s1764 = sbv_bv_extract_u32_7_0_u8(s1705);
+  s1765 = table4[s1764];
+  s1766 = s1763 ^ s1765;
+  s1767 = s41 ^ s1766;
+  s1768 = sbv_bv_extract_u32_7_0_u8(s1767);
+  s1769 = table0[s1768];
+  s1770 = sbv_bv_join_u8_u8_u16(s1755, s1769);
+  s1771 = sbv_bv_join_u16_u16_u32(s1741, s1770);
+  s1772 = s44 ^ s1771;
+  s1773 = sbv_bv_extract_u32_31_24_u8(s1767);
+  s1774 = table0[s1773];
+  s1775 = sbv_bv_extract_u32_23_16_u8(s1724);
+  s1776 = table0[s1775];
+  s1777 = sbv_bv_join_u8_u8_u16(s1774, s1776);
+  s1778 = sbv_bv_extract_u32_15_8_u8(s1738);
+  s1779 = table0[s1778];
+  s1780 = sbv_bv_extract_u32_7_0_u8(s1753);
+  s1781 = table0[s1780];
+  s1782 = sbv_bv_join_u8_u8_u16(s1779, s1781);
+  s1783 = sbv_bv_join_u16_u16_u32(s1777, s1782);
+  s1784 = s45 ^ s1783;
+  s1785 = sbv_bv_extract_u32_31_24_u8(s1753);
+  s1786 = table0[s1785];
+  s1787 = sbv_bv_extract_u32_23_16_u8(s1767);
+  s1788 = table0[s1787];
+  s1789 = sbv_bv_join_u8_u8_u16(s1786, s1788);
+  s1790 = sbv_bv_extract_u32_15_8_u8(s1724);
+  s1791 = table0[s1790];
+  s1792 = sbv_bv_extract_u32_7_0_u8(s1738);
+  s1793 = table0[s1792];
+  s1794 = sbv_bv_join_u8_u8_u16(s1791, s1793);
+  s1795 = sbv_bv_join_u16_u16_u32(s1789, s1794);
+  s1796 = s46 ^ s1795;
+  s1797 = sbv_bv_extract_u32_31_24_u8(s1738);
+  s1798 = table0[s1797];
+  s1799 = sbv_bv_extract_u32_23_16_u8(s1753);
+  s1800 = table0[s1799];
+  s1801 = sbv_bv_join_u8_u8_u16(s1798, s1800);
+  s1802 = sbv_bv_extract_u32_15_8_u8(s1767);
+  s1803 = table0[s1802];
+  s1804 = sbv_bv_extract_u32_7_0_u8(s1724);
+  s1805 = table0[s1804];
+  s1806 = sbv_bv_join_u8_u8_u16(s1803, s1805);
+  s1807 = sbv_bv_join_u16_u16_u32(s1801, s1806);
+  s1808 = s47 ^ s1807;
+
+  sbv_output_0[0] = s1772;
+  sbv_output_0[1] = s1784;
+  sbv_output_0[2] = s1796;
+  sbv_output_0[3] = s1808;
+}
+== END: "aes128BlockDecrypt.c" ==================
+== BEGIN: "aes128InvKeySchedule.c" ================
+/* File: "aes128InvKeySchedule.c". Automatically generated by SBV. Do not edit! */
+
+#include "aes128Lib.h"
+
+/* Exact bit-vector runtime. All arithmetic is modulo the declared width. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static inline SBV_CGEN_UNUSED SWord32 sbv_bv_u32_rotl(SWord32 a, uint64_t amount)
+{
+  amount %= 32;
+  if (amount == 0) return a;
+  return (SWord32) ((((uint64_t) (SWord32) a) << amount) | (((uint64_t) (SWord32) a) >> (32 - amount)));
+}
+
+static inline SBV_CGEN_UNUSED SWord32 sbv_bv_u32_rotr(SWord32 a, uint64_t amount)
+{
+  amount %= 32;
+  if (amount == 0) return a;
+  return (SWord32) ((((uint64_t) (SWord32) a) >> amount) | (((uint64_t) (SWord32) a) << (32 - amount)));
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_31_24_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 24)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_23_16_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 16)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord16 sbv_bv_join_u8_u8_u16(SWord8 high, SWord8 low)
+{
+  SWord16 r = (SWord16) 0; uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord16) ((uint64_t) r | ((uint64_t) (((((uint64_t) low) >> (i)) & UINT64_C(1)) != 0) << (i))); }
+  for (i = 0; i < 8; ++i) { r = (SWord16) ((uint64_t) r | ((uint64_t) (((((uint64_t) high) >> (i)) & UINT64_C(1)) != 0) << (i + 8))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_15_8_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 8)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_7_0_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord32 sbv_bv_join_u16_u16_u32(SWord16 high, SWord16 low)
+{
+  SWord32 r = (SWord32) 0; uint64_t i;
+  for (i = 0; i < 16; ++i) { r = (SWord32) ((uint64_t) r | ((uint64_t) (((((uint64_t) low) >> (i)) & UINT64_C(1)) != 0) << (i))); }
+  for (i = 0; i < 16; ++i) { r = (SWord32) ((uint64_t) r | ((uint64_t) (((((uint64_t) high) >> (i)) & UINT64_C(1)) != 0) << (i + 16))); }
+  return r;
+}
+
+
+void aes128InvKeySchedule(const SWord32 *sbv_input_0,
+                          SWord32 *sbv_output_0)
+{
+  const SWord32 s0 = sbv_input_0[0];
+  const SWord32 s1 = sbv_input_0[1];
+  const SWord32 s2 = sbv_input_0[2];
+  const SWord32 s3 = sbv_input_0[3];
+  const SWord32 s260 = s2 ^ s3;
+  const SWord32 s261 = sbv_bv_u32_rotl(s260, 8);
+  const SWord8  s262 = sbv_bv_extract_u32_31_24_u8(s261);
+  const SWord8  s265 = sbv_bv_extract_u32_23_16_u8(s261);
+  const SWord8  s268 = sbv_bv_extract_u32_15_8_u8(s261);
+  const SWord8  s270 = sbv_bv_extract_u32_7_0_u8(s261);
+  const SWord32 s275 = s0 ^ s1;
+  const SWord32 s276 = s1 ^ s2;
+  const SWord32 s277 = s260 ^ s276;
+  const SWord32 s278 = sbv_bv_u32_rotl(s277, 8);
+  const SWord8  s279 = sbv_bv_extract_u32_31_24_u8(s278);
+  const SWord8  s282 = sbv_bv_extract_u32_23_16_u8(s278);
+  const SWord8  s285 = sbv_bv_extract_u32_15_8_u8(s278);
+  const SWord8  s287 = sbv_bv_extract_u32_7_0_u8(s278);
+  const SWord32 s293 = s275 ^ s276;
+  const SWord32 s294 = s277 ^ s293;
+  const SWord32 s295 = sbv_bv_u32_rotl(s294, 8);
+  const SWord8  s296 = sbv_bv_extract_u32_31_24_u8(s295);
+  const SWord8  s299 = sbv_bv_extract_u32_23_16_u8(s295);
+  const SWord8  s302 = sbv_bv_extract_u32_15_8_u8(s295);
+  const SWord8  s304 = sbv_bv_extract_u32_7_0_u8(s295);
+        SWord8  s263;
+        SWord8  s264;
+        SWord8  s266;
+        SWord16 s267;
+        SWord8  s269;
+        SWord8  s271;
+        SWord16 s272;
+        SWord32 s273;
+        SWord32 s274;
+        SWord8  s280;
+        SWord8  s281;
+        SWord8  s283;
+        SWord16 s284;
+        SWord8  s286;
+        SWord8  s288;
+        SWord16 s289;
+        SWord32 s290;
+        SWord32 s291;
+        SWord32 s292;
+        SWord8  s297;
+        SWord8  s298;
+        SWord8  s300;
+        SWord16 s301;
+        SWord8  s303;
+        SWord8  s305;
+        SWord16 s306;
+        SWord32 s307;
+        SWord32 s308;
+        SWord32 s309;
+        SWord32 s310;
+        SWord32 s311;
+        SWord32 s312;
+        SWord8  s313;
+        SWord8  s314;
+        SWord8  s315;
+        SWord8  s316;
+        SWord8  s317;
+        SWord16 s318;
+        SWord8  s319;
+        SWord8  s320;
+        SWord8  s321;
+        SWord8  s322;
+        SWord16 s323;
+        SWord32 s324;
+        SWord32 s325;
+        SWord32 s326;
+        SWord32 s327;
+        SWord32 s328;
+        SWord32 s329;
+        SWord8  s330;
+        SWord8  s331;
+        SWord8  s332;
+        SWord8  s333;
+        SWord8  s334;
+        SWord16 s335;
+        SWord8  s336;
+        SWord8  s337;
+        SWord8  s338;
+        SWord8  s339;
+        SWord16 s340;
+        SWord32 s341;
+        SWord32 s342;
+        SWord32 s343;
+        SWord32 s344;
+        SWord32 s345;
+        SWord32 s346;
+        SWord8  s347;
+        SWord8  s348;
+        SWord8  s349;
+        SWord8  s350;
+        SWord8  s351;
+        SWord16 s352;
+        SWord8  s353;
+        SWord8  s354;
+        SWord8  s355;
+        SWord8  s356;
+        SWord16 s357;
+        SWord32 s358;
+        SWord32 s359;
+        SWord32 s360;
+        SWord32 s361;
+        SWord32 s362;
+        SWord32 s363;
+        SWord8  s364;
+        SWord8  s365;
+        SWord8  s366;
+        SWord8  s367;
+        SWord8  s368;
+        SWord16 s369;
+        SWord8  s370;
+        SWord8  s371;
+        SWord8  s372;
+        SWord8  s373;
+        SWord16 s374;
+        SWord32 s375;
+        SWord32 s376;
+        SWord32 s377;
+        SWord32 s378;
+        SWord32 s379;
+        SWord32 s380;
+        SWord8  s381;
+        SWord8  s382;
+        SWord8  s383;
+        SWord8  s384;
+        SWord8  s385;
+        SWord16 s386;
+        SWord8  s387;
+        SWord8  s388;
+        SWord8  s389;
+        SWord8  s390;
+        SWord16 s391;
+        SWord32 s392;
+        SWord32 s393;
+        SWord32 s394;
+        SWord32 s395;
+        SWord32 s396;
+        SWord32 s397;
+        SWord8  s398;
+        SWord8  s399;
+        SWord8  s400;
+        SWord8  s401;
+        SWord8  s402;
+        SWord16 s403;
+        SWord8  s404;
+        SWord8  s405;
+        SWord8  s406;
+        SWord8  s407;
+        SWord16 s408;
+        SWord32 s409;
+        SWord32 s410;
+        SWord32 s411;
+        SWord32 s412;
+        SWord32 s413;
+        SWord32 s414;
+        SWord8  s415;
+        SWord8  s416;
+        SWord8  s417;
+        SWord8  s418;
+        SWord8  s419;
+        SWord16 s420;
+        SWord8  s421;
+        SWord8  s422;
+        SWord8  s423;
+        SWord8  s424;
+        SWord16 s425;
+        SWord32 s426;
+        SWord32 s427;
+        SWord32 s428;
+        SWord32 s429;
+  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
+  };
+  s263 = table0[s262];
+  s264 = 54 ^ s263;
+  s266 = table0[s265];
+  s267 = sbv_bv_join_u8_u8_u16(s264, s266);
+  s269 = table0[s268];
+  s271 = table0[s270];
+  s272 = sbv_bv_join_u8_u8_u16(s269, s271);
+  s273 = sbv_bv_join_u16_u16_u32(s267, s272);
+  s274 = s0 ^ s273;
+  s280 = table0[s279];
+  s281 = 27 ^ s280;
+  s283 = table0[s282];
+  s284 = sbv_bv_join_u8_u8_u16(s281, s283);
+  s286 = table0[s285];
+  s288 = table0[s287];
+  s289 = sbv_bv_join_u8_u8_u16(s286, s288);
+  s290 = sbv_bv_join_u16_u16_u32(s284, s289);
+  s291 = s274 ^ s290;
+  s292 = s274 ^ s275;
+  s297 = table0[s296];
+  s298 = 128 ^ s297;
+  s300 = table0[s299];
+  s301 = sbv_bv_join_u8_u8_u16(s298, s300);
+  s303 = table0[s302];
+  s305 = table0[s304];
+  s306 = sbv_bv_join_u8_u8_u16(s303, s305);
+  s307 = sbv_bv_join_u16_u16_u32(s301, s306);
+  s308 = s291 ^ s307;
+  s309 = s291 ^ s292;
+  s310 = s292 ^ s293;
+  s311 = s294 ^ s310;
+  s312 = sbv_bv_u32_rotl(s311, 8);
+  s313 = sbv_bv_extract_u32_31_24_u8(s312);
+  s314 = table0[s313];
+  s315 = 64 ^ s314;
+  s316 = sbv_bv_extract_u32_23_16_u8(s312);
+  s317 = table0[s316];
+  s318 = sbv_bv_join_u8_u8_u16(s315, s317);
+  s319 = sbv_bv_extract_u32_15_8_u8(s312);
+  s320 = table0[s319];
+  s321 = sbv_bv_extract_u32_7_0_u8(s312);
+  s322 = table0[s321];
+  s323 = sbv_bv_join_u8_u8_u16(s320, s322);
+  s324 = sbv_bv_join_u16_u16_u32(s318, s323);
+  s325 = s308 ^ s324;
+  s326 = s308 ^ s309;
+  s327 = s309 ^ s310;
+  s328 = s311 ^ s327;
+  s329 = sbv_bv_u32_rotl(s328, 8);
+  s330 = sbv_bv_extract_u32_31_24_u8(s329);
+  s331 = table0[s330];
+  s332 = 32 ^ s331;
+  s333 = sbv_bv_extract_u32_23_16_u8(s329);
+  s334 = table0[s333];
+  s335 = sbv_bv_join_u8_u8_u16(s332, s334);
+  s336 = sbv_bv_extract_u32_15_8_u8(s329);
+  s337 = table0[s336];
+  s338 = sbv_bv_extract_u32_7_0_u8(s329);
+  s339 = table0[s338];
+  s340 = sbv_bv_join_u8_u8_u16(s337, s339);
+  s341 = sbv_bv_join_u16_u16_u32(s335, s340);
+  s342 = s325 ^ s341;
+  s343 = s325 ^ s326;
+  s344 = s326 ^ s327;
+  s345 = s328 ^ s344;
+  s346 = sbv_bv_u32_rotl(s345, 8);
+  s347 = sbv_bv_extract_u32_31_24_u8(s346);
+  s348 = table0[s347];
+  s349 = 16 ^ s348;
+  s350 = sbv_bv_extract_u32_23_16_u8(s346);
+  s351 = table0[s350];
+  s352 = sbv_bv_join_u8_u8_u16(s349, s351);
+  s353 = sbv_bv_extract_u32_15_8_u8(s346);
+  s354 = table0[s353];
+  s355 = sbv_bv_extract_u32_7_0_u8(s346);
+  s356 = table0[s355];
+  s357 = sbv_bv_join_u8_u8_u16(s354, s356);
+  s358 = sbv_bv_join_u16_u16_u32(s352, s357);
+  s359 = s342 ^ s358;
+  s360 = s342 ^ s343;
+  s361 = s343 ^ s344;
+  s362 = s345 ^ s361;
+  s363 = sbv_bv_u32_rotl(s362, 8);
+  s364 = sbv_bv_extract_u32_31_24_u8(s363);
+  s365 = table0[s364];
+  s366 = 8 ^ s365;
+  s367 = sbv_bv_extract_u32_23_16_u8(s363);
+  s368 = table0[s367];
+  s369 = sbv_bv_join_u8_u8_u16(s366, s368);
+  s370 = sbv_bv_extract_u32_15_8_u8(s363);
+  s371 = table0[s370];
+  s372 = sbv_bv_extract_u32_7_0_u8(s363);
+  s373 = table0[s372];
+  s374 = sbv_bv_join_u8_u8_u16(s371, s373);
+  s375 = sbv_bv_join_u16_u16_u32(s369, s374);
+  s376 = s359 ^ s375;
+  s377 = s359 ^ s360;
+  s378 = s360 ^ s361;
+  s379 = s362 ^ s378;
+  s380 = sbv_bv_u32_rotl(s379, 8);
+  s381 = sbv_bv_extract_u32_31_24_u8(s380);
+  s382 = table0[s381];
+  s383 = 4 ^ s382;
+  s384 = sbv_bv_extract_u32_23_16_u8(s380);
+  s385 = table0[s384];
+  s386 = sbv_bv_join_u8_u8_u16(s383, s385);
+  s387 = sbv_bv_extract_u32_15_8_u8(s380);
+  s388 = table0[s387];
+  s389 = sbv_bv_extract_u32_7_0_u8(s380);
+  s390 = table0[s389];
+  s391 = sbv_bv_join_u8_u8_u16(s388, s390);
+  s392 = sbv_bv_join_u16_u16_u32(s386, s391);
+  s393 = s376 ^ s392;
+  s394 = s376 ^ s377;
+  s395 = s377 ^ s378;
+  s396 = s379 ^ s395;
+  s397 = sbv_bv_u32_rotl(s396, 8);
+  s398 = sbv_bv_extract_u32_31_24_u8(s397);
+  s399 = table0[s398];
+  s400 = 2 ^ s399;
+  s401 = sbv_bv_extract_u32_23_16_u8(s397);
+  s402 = table0[s401];
+  s403 = sbv_bv_join_u8_u8_u16(s400, s402);
+  s404 = sbv_bv_extract_u32_15_8_u8(s397);
+  s405 = table0[s404];
+  s406 = sbv_bv_extract_u32_7_0_u8(s397);
+  s407 = table0[s406];
+  s408 = sbv_bv_join_u8_u8_u16(s405, s407);
+  s409 = sbv_bv_join_u16_u16_u32(s403, s408);
+  s410 = s393 ^ s409;
+  s411 = s393 ^ s394;
+  s412 = s394 ^ s395;
+  s413 = s396 ^ s412;
+  s414 = sbv_bv_u32_rotl(s413, 8);
+  s415 = sbv_bv_extract_u32_31_24_u8(s414);
+  s416 = table0[s415];
+  s417 = 1 ^ s416;
+  s418 = sbv_bv_extract_u32_23_16_u8(s414);
+  s419 = table0[s418];
+  s420 = sbv_bv_join_u8_u8_u16(s417, s419);
+  s421 = sbv_bv_extract_u32_15_8_u8(s414);
+  s422 = table0[s421];
+  s423 = sbv_bv_extract_u32_7_0_u8(s414);
+  s424 = table0[s423];
+  s425 = sbv_bv_join_u8_u8_u16(s422, s424);
+  s426 = sbv_bv_join_u16_u16_u32(s420, s425);
+  s427 = s410 ^ s426;
+  s428 = s410 ^ s411;
+  s429 = s411 ^ s412;
+
+  sbv_output_0[0] = s0;
+  sbv_output_0[1] = s1;
+  sbv_output_0[2] = s2;
+  sbv_output_0[3] = s3;
+  sbv_output_0[4] = s274;
+  sbv_output_0[5] = s275;
+  sbv_output_0[6] = s276;
+  sbv_output_0[7] = s260;
+  sbv_output_0[8] = s291;
+  sbv_output_0[9] = s292;
+  sbv_output_0[10] = s293;
+  sbv_output_0[11] = s277;
+  sbv_output_0[12] = s308;
+  sbv_output_0[13] = s309;
+  sbv_output_0[14] = s310;
+  sbv_output_0[15] = s294;
+  sbv_output_0[16] = s325;
+  sbv_output_0[17] = s326;
+  sbv_output_0[18] = s327;
+  sbv_output_0[19] = s311;
+  sbv_output_0[20] = s342;
+  sbv_output_0[21] = s343;
+  sbv_output_0[22] = s344;
+  sbv_output_0[23] = s328;
+  sbv_output_0[24] = s359;
+  sbv_output_0[25] = s360;
+  sbv_output_0[26] = s361;
+  sbv_output_0[27] = s345;
+  sbv_output_0[28] = s376;
+  sbv_output_0[29] = s377;
+  sbv_output_0[30] = s378;
+  sbv_output_0[31] = s362;
+  sbv_output_0[32] = s393;
+  sbv_output_0[33] = s394;
+  sbv_output_0[34] = s395;
+  sbv_output_0[35] = s379;
+  sbv_output_0[36] = s410;
+  sbv_output_0[37] = s411;
+  sbv_output_0[38] = s412;
+  sbv_output_0[39] = s396;
+  sbv_output_0[40] = s427;
+  sbv_output_0[41] = s428;
+  sbv_output_0[42] = s429;
+  sbv_output_0[43] = s413;
+}
+== END: "aes128InvKeySchedule.c" ==================
+== BEGIN: "aes128OTFDecrypt.c" ================
+/* File: "aes128OTFDecrypt.c". Automatically generated by SBV. Do not edit! */
+
+#include "aes128Lib.h"
+
+/* Exact bit-vector runtime. All arithmetic is modulo the declared width. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_31_24_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 24)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_23_16_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 16)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_15_8_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 8)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_7_0_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord16 sbv_bv_join_u8_u8_u16(SWord8 high, SWord8 low)
+{
+  SWord16 r = (SWord16) 0; uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord16) ((uint64_t) r | ((uint64_t) (((((uint64_t) low) >> (i)) & UINT64_C(1)) != 0) << (i))); }
+  for (i = 0; i < 8; ++i) { r = (SWord16) ((uint64_t) r | ((uint64_t) (((((uint64_t) high) >> (i)) & UINT64_C(1)) != 0) << (i + 8))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord32 sbv_bv_join_u16_u16_u32(SWord16 high, SWord16 low)
+{
+  SWord32 r = (SWord32) 0; uint64_t i;
+  for (i = 0; i < 16; ++i) { r = (SWord32) ((uint64_t) r | ((uint64_t) (((((uint64_t) low) >> (i)) & UINT64_C(1)) != 0) << (i))); }
+  for (i = 0; i < 16; ++i) { r = (SWord32) ((uint64_t) r | ((uint64_t) (((((uint64_t) high) >> (i)) & UINT64_C(1)) != 0) << (i + 16))); }
+  return r;
+}
+
+
+void aes128OTFDecrypt(const SWord32 *sbv_input_0,
+                      const SWord32 *sbv_input_1, SWord32 *sbv_output_0)
+{
+  const SWord32 s0 = sbv_input_0[0];
+  const SWord32 s1 = sbv_input_0[1];
+  const SWord32 s2 = sbv_input_0[2];
+  const SWord32 s3 = sbv_input_0[3];
+  const SWord32 s4 = sbv_input_1[0];
+  const SWord32 s5 = sbv_input_1[1];
+  const SWord32 s6 = sbv_input_1[2];
+  const SWord32 s7 = sbv_input_1[3];
+  const SWord32 s8 = sbv_input_1[4];
+  const SWord32 s9 = sbv_input_1[5];
+  const SWord32 s10 = sbv_input_1[6];
+  const SWord32 s11 = sbv_input_1[7];
+  const SWord32 s12 = sbv_input_1[8];
+  const SWord32 s13 = sbv_input_1[9];
+  const SWord32 s14 = sbv_input_1[10];
+  const SWord32 s15 = sbv_input_1[11];
+  const SWord32 s16 = sbv_input_1[12];
+  const SWord32 s17 = sbv_input_1[13];
+  const SWord32 s18 = sbv_input_1[14];
+  const SWord32 s19 = sbv_input_1[15];
+  const SWord32 s20 = sbv_input_1[16];
+  const SWord32 s21 = sbv_input_1[17];
+  const SWord32 s22 = sbv_input_1[18];
+  const SWord32 s23 = sbv_input_1[19];
+  const SWord32 s24 = sbv_input_1[20];
+  const SWord32 s25 = sbv_input_1[21];
+  const SWord32 s26 = sbv_input_1[22];
+  const SWord32 s27 = sbv_input_1[23];
+  const SWord32 s28 = sbv_input_1[24];
+  const SWord32 s29 = sbv_input_1[25];
+  const SWord32 s30 = sbv_input_1[26];
+  const SWord32 s31 = sbv_input_1[27];
+  const SWord32 s32 = sbv_input_1[28];
+  const SWord32 s33 = sbv_input_1[29];
+  const SWord32 s34 = sbv_input_1[30];
+  const SWord32 s35 = sbv_input_1[31];
+  const SWord32 s36 = sbv_input_1[32];
+  const SWord32 s37 = sbv_input_1[33];
+  const SWord32 s38 = sbv_input_1[34];
+  const SWord32 s39 = sbv_input_1[35];
+  const SWord32 s40 = sbv_input_1[36];
+  const SWord32 s41 = sbv_input_1[37];
+  const SWord32 s42 = sbv_input_1[38];
+  const SWord32 s43 = sbv_input_1[39];
+  const SWord32 s44 = sbv_input_1[40];
+  const SWord32 s45 = sbv_input_1[41];
+  const SWord32 s46 = sbv_input_1[42];
+  const SWord32 s47 = sbv_input_1[43];
+  const SWord32 s560 = s0 ^ s4;
+  const SWord8  s561 = sbv_bv_extract_u32_31_24_u8(s560);
+  const SWord8  s563 = sbv_bv_extract_u32_31_24_u8(s8);
+  const SWord32 s821 = s3 ^ s7;
+  const SWord8  s822 = sbv_bv_extract_u32_23_16_u8(s821);
+  const SWord8  s824 = sbv_bv_extract_u32_23_16_u8(s8);
+  const SWord32 s1083 = s2 ^ s6;
+  const SWord8  s1084 = sbv_bv_extract_u32_15_8_u8(s1083);
+  const SWord8  s1086 = sbv_bv_extract_u32_15_8_u8(s8);
+  const SWord32 s1345 = s1 ^ s5;
+  const SWord8  s1346 = sbv_bv_extract_u32_7_0_u8(s1345);
+  const SWord8  s1348 = sbv_bv_extract_u32_7_0_u8(s8);
+  const SWord8  s1354 = sbv_bv_extract_u32_31_24_u8(s12);
+  const SWord8  s1357 = sbv_bv_extract_u32_31_24_u8(s821);
+  const SWord8  s1359 = sbv_bv_extract_u32_31_24_u8(s11);
+  const SWord8  s1362 = sbv_bv_extract_u32_23_16_u8(s1083);
+  const SWord8  s1364 = sbv_bv_extract_u32_23_16_u8(s11);
+  const SWord8  s1368 = sbv_bv_extract_u32_15_8_u8(s1345);
+  const SWord8  s1370 = sbv_bv_extract_u32_15_8_u8(s11);
+  const SWord8  s1374 = sbv_bv_extract_u32_7_0_u8(s560);
+  const SWord8  s1376 = sbv_bv_extract_u32_7_0_u8(s11);
+  const SWord8  s1382 = sbv_bv_extract_u32_23_16_u8(s12);
+  const SWord8  s1386 = sbv_bv_extract_u32_31_24_u8(s1083);
+  const SWord8  s1388 = sbv_bv_extract_u32_31_24_u8(s10);
+  const SWord8  s1391 = sbv_bv_extract_u32_23_16_u8(s1345);
+  const SWord8  s1393 = sbv_bv_extract_u32_23_16_u8(s10);
+  const SWord8  s1397 = sbv_bv_extract_u32_15_8_u8(s560);
+  const SWord8  s1399 = sbv_bv_extract_u32_15_8_u8(s10);
+  const SWord8  s1403 = sbv_bv_extract_u32_7_0_u8(s821);
+  const SWord8  s1405 = sbv_bv_extract_u32_7_0_u8(s10);
+  const SWord8  s1411 = sbv_bv_extract_u32_15_8_u8(s12);
+  const SWord8  s1415 = sbv_bv_extract_u32_31_24_u8(s1345);
+  const SWord8  s1417 = sbv_bv_extract_u32_31_24_u8(s9);
+  const SWord8  s1420 = sbv_bv_extract_u32_23_16_u8(s560);
+  const SWord8  s1422 = sbv_bv_extract_u32_23_16_u8(s9);
+  const SWord8  s1426 = sbv_bv_extract_u32_15_8_u8(s821);
+  const SWord8  s1428 = sbv_bv_extract_u32_15_8_u8(s9);
+  const SWord8  s1432 = sbv_bv_extract_u32_7_0_u8(s1083);
+  const SWord8  s1434 = sbv_bv_extract_u32_7_0_u8(s9);
+  const SWord8  s1440 = sbv_bv_extract_u32_7_0_u8(s12);
+  const SWord8  s1446 = sbv_bv_extract_u32_31_24_u8(s16);
+  const SWord8  s1451 = sbv_bv_extract_u32_31_24_u8(s15);
+  const SWord8  s1456 = sbv_bv_extract_u32_23_16_u8(s15);
+  const SWord8  s1462 = sbv_bv_extract_u32_15_8_u8(s15);
+  const SWord8  s1468 = sbv_bv_extract_u32_7_0_u8(s15);
+  const SWord8  s1474 = sbv_bv_extract_u32_23_16_u8(s16);
+  const SWord8  s1480 = sbv_bv_extract_u32_31_24_u8(s14);
+  const SWord8  s1485 = sbv_bv_extract_u32_23_16_u8(s14);
+  const SWord8  s1491 = sbv_bv_extract_u32_15_8_u8(s14);
+  const SWord8  s1497 = sbv_bv_extract_u32_7_0_u8(s14);
+  const SWord8  s1503 = sbv_bv_extract_u32_15_8_u8(s16);
+  const SWord8  s1509 = sbv_bv_extract_u32_31_24_u8(s13);
+  const SWord8  s1514 = sbv_bv_extract_u32_23_16_u8(s13);
+  const SWord8  s1520 = sbv_bv_extract_u32_15_8_u8(s13);
+  const SWord8  s1526 = sbv_bv_extract_u32_7_0_u8(s13);
+  const SWord8  s1532 = sbv_bv_extract_u32_7_0_u8(s16);
+  const SWord8  s1538 = sbv_bv_extract_u32_31_24_u8(s20);
+  const SWord8  s1543 = sbv_bv_extract_u32_31_24_u8(s19);
+  const SWord8  s1548 = sbv_bv_extract_u32_23_16_u8(s19);
+  const SWord8  s1554 = sbv_bv_extract_u32_15_8_u8(s19);
+  const SWord8  s1560 = sbv_bv_extract_u32_7_0_u8(s19);
+  const SWord8  s1566 = sbv_bv_extract_u32_23_16_u8(s20);
+  const SWord8  s1572 = sbv_bv_extract_u32_31_24_u8(s18);
+  const SWord8  s1577 = sbv_bv_extract_u32_23_16_u8(s18);
+  const SWord8  s1583 = sbv_bv_extract_u32_15_8_u8(s18);
+  const SWord8  s1589 = sbv_bv_extract_u32_7_0_u8(s18);
+  const SWord8  s1595 = sbv_bv_extract_u32_15_8_u8(s20);
+  const SWord8  s1601 = sbv_bv_extract_u32_31_24_u8(s17);
+  const SWord8  s1606 = sbv_bv_extract_u32_23_16_u8(s17);
+  const SWord8  s1612 = sbv_bv_extract_u32_15_8_u8(s17);
+  const SWord8  s1618 = sbv_bv_extract_u32_7_0_u8(s17);
+  const SWord8  s1624 = sbv_bv_extract_u32_7_0_u8(s20);
+  const SWord8  s1630 = sbv_bv_extract_u32_31_24_u8(s24);
+  const SWord8  s1635 = sbv_bv_extract_u32_31_24_u8(s23);
+  const SWord8  s1640 = sbv_bv_extract_u32_23_16_u8(s23);
+  const SWord8  s1646 = sbv_bv_extract_u32_15_8_u8(s23);
+  const SWord8  s1652 = sbv_bv_extract_u32_7_0_u8(s23);
+  const SWord8  s1658 = sbv_bv_extract_u32_23_16_u8(s24);
+  const SWord8  s1664 = sbv_bv_extract_u32_31_24_u8(s22);
+  const SWord8  s1669 = sbv_bv_extract_u32_23_16_u8(s22);
+  const SWord8  s1675 = sbv_bv_extract_u32_15_8_u8(s22);
+  const SWord8  s1681 = sbv_bv_extract_u32_7_0_u8(s22);
+  const SWord8  s1687 = sbv_bv_extract_u32_15_8_u8(s24);
+  const SWord8  s1693 = sbv_bv_extract_u32_31_24_u8(s21);
+  const SWord8  s1698 = sbv_bv_extract_u32_23_16_u8(s21);
+  const SWord8  s1704 = sbv_bv_extract_u32_15_8_u8(s21);
+  const SWord8  s1710 = sbv_bv_extract_u32_7_0_u8(s21);
+  const SWord8  s1716 = sbv_bv_extract_u32_7_0_u8(s24);
+  const SWord8  s1722 = sbv_bv_extract_u32_31_24_u8(s28);
+  const SWord8  s1727 = sbv_bv_extract_u32_31_24_u8(s27);
+  const SWord8  s1732 = sbv_bv_extract_u32_23_16_u8(s27);
+  const SWord8  s1738 = sbv_bv_extract_u32_15_8_u8(s27);
+  const SWord8  s1744 = sbv_bv_extract_u32_7_0_u8(s27);
+  const SWord8  s1750 = sbv_bv_extract_u32_23_16_u8(s28);
+  const SWord8  s1756 = sbv_bv_extract_u32_31_24_u8(s26);
+  const SWord8  s1761 = sbv_bv_extract_u32_23_16_u8(s26);
+  const SWord8  s1767 = sbv_bv_extract_u32_15_8_u8(s26);
+  const SWord8  s1773 = sbv_bv_extract_u32_7_0_u8(s26);
+  const SWord8  s1779 = sbv_bv_extract_u32_15_8_u8(s28);
+  const SWord8  s1785 = sbv_bv_extract_u32_31_24_u8(s25);
+  const SWord8  s1790 = sbv_bv_extract_u32_23_16_u8(s25);
+  const SWord8  s1796 = sbv_bv_extract_u32_15_8_u8(s25);
+  const SWord8  s1802 = sbv_bv_extract_u32_7_0_u8(s25);
+  const SWord8  s1808 = sbv_bv_extract_u32_7_0_u8(s28);
+  const SWord8  s1814 = sbv_bv_extract_u32_31_24_u8(s32);
+  const SWord8  s1819 = sbv_bv_extract_u32_31_24_u8(s31);
+  const SWord8  s1824 = sbv_bv_extract_u32_23_16_u8(s31);
+  const SWord8  s1830 = sbv_bv_extract_u32_15_8_u8(s31);
+  const SWord8  s1836 = sbv_bv_extract_u32_7_0_u8(s31);
+  const SWord8  s1842 = sbv_bv_extract_u32_23_16_u8(s32);
+  const SWord8  s1848 = sbv_bv_extract_u32_31_24_u8(s30);
+  const SWord8  s1853 = sbv_bv_extract_u32_23_16_u8(s30);
+  const SWord8  s1859 = sbv_bv_extract_u32_15_8_u8(s30);
+  const SWord8  s1865 = sbv_bv_extract_u32_7_0_u8(s30);
+  const SWord8  s1871 = sbv_bv_extract_u32_15_8_u8(s32);
+  const SWord8  s1877 = sbv_bv_extract_u32_31_24_u8(s29);
+  const SWord8  s1882 = sbv_bv_extract_u32_23_16_u8(s29);
+  const SWord8  s1888 = sbv_bv_extract_u32_15_8_u8(s29);
+  const SWord8  s1894 = sbv_bv_extract_u32_7_0_u8(s29);
+  const SWord8  s1900 = sbv_bv_extract_u32_7_0_u8(s32);
+  const SWord8  s1906 = sbv_bv_extract_u32_31_24_u8(s36);
+  const SWord8  s1911 = sbv_bv_extract_u32_31_24_u8(s35);
+  const SWord8  s1916 = sbv_bv_extract_u32_23_16_u8(s35);
+  const SWord8  s1922 = sbv_bv_extract_u32_15_8_u8(s35);
+  const SWord8  s1928 = sbv_bv_extract_u32_7_0_u8(s35);
+  const SWord8  s1934 = sbv_bv_extract_u32_23_16_u8(s36);
+  const SWord8  s1940 = sbv_bv_extract_u32_31_24_u8(s34);
+  const SWord8  s1945 = sbv_bv_extract_u32_23_16_u8(s34);
+  const SWord8  s1951 = sbv_bv_extract_u32_15_8_u8(s34);
+  const SWord8  s1957 = sbv_bv_extract_u32_7_0_u8(s34);
+  const SWord8  s1963 = sbv_bv_extract_u32_15_8_u8(s36);
+  const SWord8  s1969 = sbv_bv_extract_u32_31_24_u8(s33);
+  const SWord8  s1974 = sbv_bv_extract_u32_23_16_u8(s33);
+  const SWord8  s1980 = sbv_bv_extract_u32_15_8_u8(s33);
+  const SWord8  s1986 = sbv_bv_extract_u32_7_0_u8(s33);
+  const SWord8  s1992 = sbv_bv_extract_u32_7_0_u8(s36);
+  const SWord8  s1998 = sbv_bv_extract_u32_31_24_u8(s40);
+  const SWord8  s2003 = sbv_bv_extract_u32_31_24_u8(s39);
+  const SWord8  s2008 = sbv_bv_extract_u32_23_16_u8(s39);
+  const SWord8  s2014 = sbv_bv_extract_u32_15_8_u8(s39);
+  const SWord8  s2020 = sbv_bv_extract_u32_7_0_u8(s39);
+  const SWord8  s2026 = sbv_bv_extract_u32_23_16_u8(s40);
+  const SWord8  s2032 = sbv_bv_extract_u32_31_24_u8(s38);
+  const SWord8  s2037 = sbv_bv_extract_u32_23_16_u8(s38);
+  const SWord8  s2043 = sbv_bv_extract_u32_15_8_u8(s38);
+  const SWord8  s2049 = sbv_bv_extract_u32_7_0_u8(s38);
+  const SWord8  s2055 = sbv_bv_extract_u32_15_8_u8(s40);
+  const SWord8  s2061 = sbv_bv_extract_u32_31_24_u8(s37);
+  const SWord8  s2066 = sbv_bv_extract_u32_23_16_u8(s37);
+  const SWord8  s2072 = sbv_bv_extract_u32_15_8_u8(s37);
+  const SWord8  s2078 = sbv_bv_extract_u32_7_0_u8(s37);
+  const SWord8  s2084 = sbv_bv_extract_u32_7_0_u8(s40);
+  const SWord8  s2092 = sbv_bv_extract_u32_31_24_u8(s43);
+  const SWord8  s2097 = sbv_bv_extract_u32_23_16_u8(s43);
+  const SWord8  s2103 = sbv_bv_extract_u32_15_8_u8(s43);
+  const SWord8  s2109 = sbv_bv_extract_u32_7_0_u8(s43);
+  const SWord8  s2118 = sbv_bv_extract_u32_31_24_u8(s42);
+  const SWord8  s2123 = sbv_bv_extract_u32_23_16_u8(s42);
+  const SWord8  s2129 = sbv_bv_extract_u32_15_8_u8(s42);
+  const SWord8  s2135 = sbv_bv_extract_u32_7_0_u8(s42);
+  const SWord8  s2143 = sbv_bv_extract_u32_31_24_u8(s41);
+  const SWord8  s2148 = sbv_bv_extract_u32_23_16_u8(s41);
+  const SWord8  s2154 = sbv_bv_extract_u32_15_8_u8(s41);
+  const SWord8  s2160 = sbv_bv_extract_u32_7_0_u8(s41);
+        SWord8  s562;
+        SWord8  s564;
+        SWord32 s565;
+        SWord8  s823;
+        SWord8  s825;
+        SWord32 s826;
+        SWord32 s827;
+        SWord8  s1085;
+        SWord8  s1087;
+        SWord32 s1088;
+        SWord32 s1089;
+        SWord8  s1347;
+        SWord8  s1349;
+        SWord32 s1350;
+        SWord32 s1351;
+        SWord8  s1352;
+        SWord8  s1353;
+        SWord8  s1355;
+        SWord32 s1356;
+        SWord8  s1358;
+        SWord8  s1360;
+        SWord32 s1361;
+        SWord8  s1363;
+        SWord8  s1365;
+        SWord32 s1366;
+        SWord32 s1367;
+        SWord8  s1369;
+        SWord8  s1371;
+        SWord32 s1372;
+        SWord32 s1373;
+        SWord8  s1375;
+        SWord8  s1377;
+        SWord32 s1378;
+        SWord32 s1379;
+        SWord8  s1380;
+        SWord8  s1381;
+        SWord8  s1383;
+        SWord32 s1384;
+        SWord32 s1385;
+        SWord8  s1387;
+        SWord8  s1389;
+        SWord32 s1390;
+        SWord8  s1392;
+        SWord8  s1394;
+        SWord32 s1395;
+        SWord32 s1396;
+        SWord8  s1398;
+        SWord8  s1400;
+        SWord32 s1401;
+        SWord32 s1402;
+        SWord8  s1404;
+        SWord8  s1406;
+        SWord32 s1407;
+        SWord32 s1408;
+        SWord8  s1409;
+        SWord8  s1410;
+        SWord8  s1412;
+        SWord32 s1413;
+        SWord32 s1414;
+        SWord8  s1416;
+        SWord8  s1418;
+        SWord32 s1419;
+        SWord8  s1421;
+        SWord8  s1423;
+        SWord32 s1424;
+        SWord32 s1425;
+        SWord8  s1427;
+        SWord8  s1429;
+        SWord32 s1430;
+        SWord32 s1431;
+        SWord8  s1433;
+        SWord8  s1435;
+        SWord32 s1436;
+        SWord32 s1437;
+        SWord8  s1438;
+        SWord8  s1439;
+        SWord8  s1441;
+        SWord32 s1442;
+        SWord32 s1443;
+        SWord8  s1444;
+        SWord8  s1445;
+        SWord8  s1447;
+        SWord32 s1448;
+        SWord8  s1449;
+        SWord8  s1450;
+        SWord8  s1452;
+        SWord32 s1453;
+        SWord8  s1454;
+        SWord8  s1455;
+        SWord8  s1457;
+        SWord32 s1458;
+        SWord32 s1459;
+        SWord8  s1460;
+        SWord8  s1461;
+        SWord8  s1463;
+        SWord32 s1464;
+        SWord32 s1465;
+        SWord8  s1466;
+        SWord8  s1467;
+        SWord8  s1469;
+        SWord32 s1470;
+        SWord32 s1471;
+        SWord8  s1472;
+        SWord8  s1473;
+        SWord8  s1475;
+        SWord32 s1476;
+        SWord32 s1477;
+        SWord8  s1478;
+        SWord8  s1479;
+        SWord8  s1481;
+        SWord32 s1482;
+        SWord8  s1483;
+        SWord8  s1484;
+        SWord8  s1486;
+        SWord32 s1487;
+        SWord32 s1488;
+        SWord8  s1489;
+        SWord8  s1490;
+        SWord8  s1492;
+        SWord32 s1493;
+        SWord32 s1494;
+        SWord8  s1495;
+        SWord8  s1496;
+        SWord8  s1498;
+        SWord32 s1499;
+        SWord32 s1500;
+        SWord8  s1501;
+        SWord8  s1502;
+        SWord8  s1504;
+        SWord32 s1505;
+        SWord32 s1506;
+        SWord8  s1507;
+        SWord8  s1508;
+        SWord8  s1510;
+        SWord32 s1511;
+        SWord8  s1512;
+        SWord8  s1513;
+        SWord8  s1515;
+        SWord32 s1516;
+        SWord32 s1517;
+        SWord8  s1518;
+        SWord8  s1519;
+        SWord8  s1521;
+        SWord32 s1522;
+        SWord32 s1523;
+        SWord8  s1524;
+        SWord8  s1525;
+        SWord8  s1527;
+        SWord32 s1528;
+        SWord32 s1529;
+        SWord8  s1530;
+        SWord8  s1531;
+        SWord8  s1533;
+        SWord32 s1534;
+        SWord32 s1535;
+        SWord8  s1536;
+        SWord8  s1537;
+        SWord8  s1539;
+        SWord32 s1540;
+        SWord8  s1541;
+        SWord8  s1542;
+        SWord8  s1544;
+        SWord32 s1545;
+        SWord8  s1546;
+        SWord8  s1547;
+        SWord8  s1549;
+        SWord32 s1550;
+        SWord32 s1551;
+        SWord8  s1552;
+        SWord8  s1553;
+        SWord8  s1555;
+        SWord32 s1556;
+        SWord32 s1557;
+        SWord8  s1558;
+        SWord8  s1559;
+        SWord8  s1561;
+        SWord32 s1562;
+        SWord32 s1563;
+        SWord8  s1564;
+        SWord8  s1565;
+        SWord8  s1567;
+        SWord32 s1568;
+        SWord32 s1569;
+        SWord8  s1570;
+        SWord8  s1571;
+        SWord8  s1573;
+        SWord32 s1574;
+        SWord8  s1575;
+        SWord8  s1576;
+        SWord8  s1578;
+        SWord32 s1579;
+        SWord32 s1580;
+        SWord8  s1581;
+        SWord8  s1582;
+        SWord8  s1584;
+        SWord32 s1585;
+        SWord32 s1586;
+        SWord8  s1587;
+        SWord8  s1588;
+        SWord8  s1590;
+        SWord32 s1591;
+        SWord32 s1592;
+        SWord8  s1593;
+        SWord8  s1594;
+        SWord8  s1596;
+        SWord32 s1597;
+        SWord32 s1598;
+        SWord8  s1599;
+        SWord8  s1600;
+        SWord8  s1602;
+        SWord32 s1603;
+        SWord8  s1604;
+        SWord8  s1605;
+        SWord8  s1607;
+        SWord32 s1608;
+        SWord32 s1609;
+        SWord8  s1610;
+        SWord8  s1611;
+        SWord8  s1613;
+        SWord32 s1614;
+        SWord32 s1615;
+        SWord8  s1616;
+        SWord8  s1617;
+        SWord8  s1619;
+        SWord32 s1620;
+        SWord32 s1621;
+        SWord8  s1622;
+        SWord8  s1623;
+        SWord8  s1625;
+        SWord32 s1626;
+        SWord32 s1627;
+        SWord8  s1628;
+        SWord8  s1629;
+        SWord8  s1631;
+        SWord32 s1632;
+        SWord8  s1633;
+        SWord8  s1634;
+        SWord8  s1636;
+        SWord32 s1637;
+        SWord8  s1638;
+        SWord8  s1639;
+        SWord8  s1641;
+        SWord32 s1642;
+        SWord32 s1643;
+        SWord8  s1644;
+        SWord8  s1645;
+        SWord8  s1647;
+        SWord32 s1648;
+        SWord32 s1649;
+        SWord8  s1650;
+        SWord8  s1651;
+        SWord8  s1653;
+        SWord32 s1654;
+        SWord32 s1655;
+        SWord8  s1656;
+        SWord8  s1657;
+        SWord8  s1659;
+        SWord32 s1660;
+        SWord32 s1661;
+        SWord8  s1662;
+        SWord8  s1663;
+        SWord8  s1665;
+        SWord32 s1666;
+        SWord8  s1667;
+        SWord8  s1668;
+        SWord8  s1670;
+        SWord32 s1671;
+        SWord32 s1672;
+        SWord8  s1673;
+        SWord8  s1674;
+        SWord8  s1676;
+        SWord32 s1677;
+        SWord32 s1678;
+        SWord8  s1679;
+        SWord8  s1680;
+        SWord8  s1682;
+        SWord32 s1683;
+        SWord32 s1684;
+        SWord8  s1685;
+        SWord8  s1686;
+        SWord8  s1688;
+        SWord32 s1689;
+        SWord32 s1690;
+        SWord8  s1691;
+        SWord8  s1692;
+        SWord8  s1694;
+        SWord32 s1695;
+        SWord8  s1696;
+        SWord8  s1697;
+        SWord8  s1699;
+        SWord32 s1700;
+        SWord32 s1701;
+        SWord8  s1702;
+        SWord8  s1703;
+        SWord8  s1705;
+        SWord32 s1706;
+        SWord32 s1707;
+        SWord8  s1708;
+        SWord8  s1709;
+        SWord8  s1711;
+        SWord32 s1712;
+        SWord32 s1713;
+        SWord8  s1714;
+        SWord8  s1715;
+        SWord8  s1717;
+        SWord32 s1718;
+        SWord32 s1719;
+        SWord8  s1720;
+        SWord8  s1721;
+        SWord8  s1723;
+        SWord32 s1724;
+        SWord8  s1725;
+        SWord8  s1726;
+        SWord8  s1728;
+        SWord32 s1729;
+        SWord8  s1730;
+        SWord8  s1731;
+        SWord8  s1733;
+        SWord32 s1734;
+        SWord32 s1735;
+        SWord8  s1736;
+        SWord8  s1737;
+        SWord8  s1739;
+        SWord32 s1740;
+        SWord32 s1741;
+        SWord8  s1742;
+        SWord8  s1743;
+        SWord8  s1745;
+        SWord32 s1746;
+        SWord32 s1747;
+        SWord8  s1748;
+        SWord8  s1749;
+        SWord8  s1751;
+        SWord32 s1752;
+        SWord32 s1753;
+        SWord8  s1754;
+        SWord8  s1755;
+        SWord8  s1757;
+        SWord32 s1758;
+        SWord8  s1759;
+        SWord8  s1760;
+        SWord8  s1762;
+        SWord32 s1763;
+        SWord32 s1764;
+        SWord8  s1765;
+        SWord8  s1766;
+        SWord8  s1768;
+        SWord32 s1769;
+        SWord32 s1770;
+        SWord8  s1771;
+        SWord8  s1772;
+        SWord8  s1774;
+        SWord32 s1775;
+        SWord32 s1776;
+        SWord8  s1777;
+        SWord8  s1778;
+        SWord8  s1780;
+        SWord32 s1781;
+        SWord32 s1782;
+        SWord8  s1783;
+        SWord8  s1784;
+        SWord8  s1786;
+        SWord32 s1787;
+        SWord8  s1788;
+        SWord8  s1789;
+        SWord8  s1791;
+        SWord32 s1792;
+        SWord32 s1793;
+        SWord8  s1794;
+        SWord8  s1795;
+        SWord8  s1797;
+        SWord32 s1798;
+        SWord32 s1799;
+        SWord8  s1800;
+        SWord8  s1801;
+        SWord8  s1803;
+        SWord32 s1804;
+        SWord32 s1805;
+        SWord8  s1806;
+        SWord8  s1807;
+        SWord8  s1809;
+        SWord32 s1810;
+        SWord32 s1811;
+        SWord8  s1812;
+        SWord8  s1813;
+        SWord8  s1815;
+        SWord32 s1816;
+        SWord8  s1817;
+        SWord8  s1818;
+        SWord8  s1820;
+        SWord32 s1821;
+        SWord8  s1822;
+        SWord8  s1823;
+        SWord8  s1825;
+        SWord32 s1826;
+        SWord32 s1827;
+        SWord8  s1828;
+        SWord8  s1829;
+        SWord8  s1831;
+        SWord32 s1832;
+        SWord32 s1833;
+        SWord8  s1834;
+        SWord8  s1835;
+        SWord8  s1837;
+        SWord32 s1838;
+        SWord32 s1839;
+        SWord8  s1840;
+        SWord8  s1841;
+        SWord8  s1843;
+        SWord32 s1844;
+        SWord32 s1845;
+        SWord8  s1846;
+        SWord8  s1847;
+        SWord8  s1849;
+        SWord32 s1850;
+        SWord8  s1851;
+        SWord8  s1852;
+        SWord8  s1854;
+        SWord32 s1855;
+        SWord32 s1856;
+        SWord8  s1857;
+        SWord8  s1858;
+        SWord8  s1860;
+        SWord32 s1861;
+        SWord32 s1862;
+        SWord8  s1863;
+        SWord8  s1864;
+        SWord8  s1866;
+        SWord32 s1867;
+        SWord32 s1868;
+        SWord8  s1869;
+        SWord8  s1870;
+        SWord8  s1872;
+        SWord32 s1873;
+        SWord32 s1874;
+        SWord8  s1875;
+        SWord8  s1876;
+        SWord8  s1878;
+        SWord32 s1879;
+        SWord8  s1880;
+        SWord8  s1881;
+        SWord8  s1883;
+        SWord32 s1884;
+        SWord32 s1885;
+        SWord8  s1886;
+        SWord8  s1887;
+        SWord8  s1889;
+        SWord32 s1890;
+        SWord32 s1891;
+        SWord8  s1892;
+        SWord8  s1893;
+        SWord8  s1895;
+        SWord32 s1896;
+        SWord32 s1897;
+        SWord8  s1898;
+        SWord8  s1899;
+        SWord8  s1901;
+        SWord32 s1902;
+        SWord32 s1903;
+        SWord8  s1904;
+        SWord8  s1905;
+        SWord8  s1907;
+        SWord32 s1908;
+        SWord8  s1909;
+        SWord8  s1910;
+        SWord8  s1912;
+        SWord32 s1913;
+        SWord8  s1914;
+        SWord8  s1915;
+        SWord8  s1917;
+        SWord32 s1918;
+        SWord32 s1919;
+        SWord8  s1920;
+        SWord8  s1921;
+        SWord8  s1923;
+        SWord32 s1924;
+        SWord32 s1925;
+        SWord8  s1926;
+        SWord8  s1927;
+        SWord8  s1929;
+        SWord32 s1930;
+        SWord32 s1931;
+        SWord8  s1932;
+        SWord8  s1933;
+        SWord8  s1935;
+        SWord32 s1936;
+        SWord32 s1937;
+        SWord8  s1938;
+        SWord8  s1939;
+        SWord8  s1941;
+        SWord32 s1942;
+        SWord8  s1943;
+        SWord8  s1944;
+        SWord8  s1946;
+        SWord32 s1947;
+        SWord32 s1948;
+        SWord8  s1949;
+        SWord8  s1950;
+        SWord8  s1952;
+        SWord32 s1953;
+        SWord32 s1954;
+        SWord8  s1955;
+        SWord8  s1956;
+        SWord8  s1958;
+        SWord32 s1959;
+        SWord32 s1960;
+        SWord8  s1961;
+        SWord8  s1962;
+        SWord8  s1964;
+        SWord32 s1965;
+        SWord32 s1966;
+        SWord8  s1967;
+        SWord8  s1968;
+        SWord8  s1970;
+        SWord32 s1971;
+        SWord8  s1972;
+        SWord8  s1973;
+        SWord8  s1975;
+        SWord32 s1976;
+        SWord32 s1977;
+        SWord8  s1978;
+        SWord8  s1979;
+        SWord8  s1981;
+        SWord32 s1982;
+        SWord32 s1983;
+        SWord8  s1984;
+        SWord8  s1985;
+        SWord8  s1987;
+        SWord32 s1988;
+        SWord32 s1989;
+        SWord8  s1990;
+        SWord8  s1991;
+        SWord8  s1993;
+        SWord32 s1994;
+        SWord32 s1995;
+        SWord8  s1996;
+        SWord8  s1997;
+        SWord8  s1999;
+        SWord32 s2000;
+        SWord8  s2001;
+        SWord8  s2002;
+        SWord8  s2004;
+        SWord32 s2005;
+        SWord8  s2006;
+        SWord8  s2007;
+        SWord8  s2009;
+        SWord32 s2010;
+        SWord32 s2011;
+        SWord8  s2012;
+        SWord8  s2013;
+        SWord8  s2015;
+        SWord32 s2016;
+        SWord32 s2017;
+        SWord8  s2018;
+        SWord8  s2019;
+        SWord8  s2021;
+        SWord32 s2022;
+        SWord32 s2023;
+        SWord8  s2024;
+        SWord8  s2025;
+        SWord8  s2027;
+        SWord32 s2028;
+        SWord32 s2029;
+        SWord8  s2030;
+        SWord8  s2031;
+        SWord8  s2033;
+        SWord32 s2034;
+        SWord8  s2035;
+        SWord8  s2036;
+        SWord8  s2038;
+        SWord32 s2039;
+        SWord32 s2040;
+        SWord8  s2041;
+        SWord8  s2042;
+        SWord8  s2044;
+        SWord32 s2045;
+        SWord32 s2046;
+        SWord8  s2047;
+        SWord8  s2048;
+        SWord8  s2050;
+        SWord32 s2051;
+        SWord32 s2052;
+        SWord8  s2053;
+        SWord8  s2054;
+        SWord8  s2056;
+        SWord32 s2057;
+        SWord32 s2058;
+        SWord8  s2059;
+        SWord8  s2060;
+        SWord8  s2062;
+        SWord32 s2063;
+        SWord8  s2064;
+        SWord8  s2065;
+        SWord8  s2067;
+        SWord32 s2068;
+        SWord32 s2069;
+        SWord8  s2070;
+        SWord8  s2071;
+        SWord8  s2073;
+        SWord32 s2074;
+        SWord32 s2075;
+        SWord8  s2076;
+        SWord8  s2077;
+        SWord8  s2079;
+        SWord32 s2080;
+        SWord32 s2081;
+        SWord8  s2082;
+        SWord8  s2083;
+        SWord8  s2085;
+        SWord32 s2086;
+        SWord32 s2087;
+        SWord8  s2088;
+        SWord8  s2089;
+        SWord8  s2090;
+        SWord8  s2091;
+        SWord8  s2093;
+        SWord32 s2094;
+        SWord8  s2095;
+        SWord8  s2096;
+        SWord8  s2098;
+        SWord32 s2099;
+        SWord32 s2100;
+        SWord8  s2101;
+        SWord8  s2102;
+        SWord8  s2104;
+        SWord32 s2105;
+        SWord32 s2106;
+        SWord8  s2107;
+        SWord8  s2108;
+        SWord8  s2110;
+        SWord32 s2111;
+        SWord32 s2112;
+        SWord8  s2113;
+        SWord8  s2114;
+        SWord16 s2115;
+        SWord8  s2116;
+        SWord8  s2117;
+        SWord8  s2119;
+        SWord32 s2120;
+        SWord8  s2121;
+        SWord8  s2122;
+        SWord8  s2124;
+        SWord32 s2125;
+        SWord32 s2126;
+        SWord8  s2127;
+        SWord8  s2128;
+        SWord8  s2130;
+        SWord32 s2131;
+        SWord32 s2132;
+        SWord8  s2133;
+        SWord8  s2134;
+        SWord8  s2136;
+        SWord32 s2137;
+        SWord32 s2138;
+        SWord8  s2139;
+        SWord8  s2140;
+        SWord8  s2141;
+        SWord8  s2142;
+        SWord8  s2144;
+        SWord32 s2145;
+        SWord8  s2146;
+        SWord8  s2147;
+        SWord8  s2149;
+        SWord32 s2150;
+        SWord32 s2151;
+        SWord8  s2152;
+        SWord8  s2153;
+        SWord8  s2155;
+        SWord32 s2156;
+        SWord32 s2157;
+        SWord8  s2158;
+        SWord8  s2159;
+        SWord8  s2161;
+        SWord32 s2162;
+        SWord32 s2163;
+        SWord8  s2164;
+        SWord8  s2165;
+        SWord16 s2166;
+        SWord32 s2167;
+        SWord32 s2168;
+        SWord8  s2169;
+        SWord8  s2170;
+        SWord8  s2171;
+        SWord8  s2172;
+        SWord16 s2173;
+        SWord8  s2174;
+        SWord8  s2175;
+        SWord8  s2176;
+        SWord8  s2177;
+        SWord16 s2178;
+        SWord32 s2179;
+        SWord32 s2180;
+        SWord8  s2181;
+        SWord8  s2182;
+        SWord8  s2183;
+        SWord8  s2184;
+        SWord16 s2185;
+        SWord8  s2186;
+        SWord8  s2187;
+        SWord8  s2188;
+        SWord8  s2189;
+        SWord16 s2190;
+        SWord32 s2191;
+        SWord32 s2192;
+        SWord8  s2193;
+        SWord8  s2194;
+        SWord8  s2195;
+        SWord8  s2196;
+        SWord16 s2197;
+        SWord8  s2198;
+        SWord8  s2199;
+        SWord8  s2200;
+        SWord8  s2201;
+        SWord16 s2202;
+        SWord32 s2203;
+        SWord32 s2204;
+  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
+  };
+  s562 = table0[s561];
+  s564 = s562 ^ s563;
+  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
+  };
+  s565 = table1[s564];
+  s823 = table0[s822];
+  s825 = s823 ^ s824;
+  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
+  };
+  s826 = table2[s825];
+  s827 = s565 ^ s826;
+  s1085 = table0[s1084];
+  s1087 = s1085 ^ s1086;
+  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
+  };
+  s1088 = table3[s1087];
+  s1089 = s827 ^ s1088;
+  s1347 = table0[s1346];
+  s1349 = s1347 ^ s1348;
+  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
+  };
+  s1350 = table4[s1349];
+  s1351 = s1089 ^ s1350;
+  s1352 = sbv_bv_extract_u32_31_24_u8(s1351);
+  s1353 = table0[s1352];
+  s1355 = s1353 ^ s1354;
+  s1356 = table1[s1355];
+  s1358 = table0[s1357];
+  s1360 = s1358 ^ s1359;
+  s1361 = table1[s1360];
+  s1363 = table0[s1362];
+  s1365 = s1363 ^ s1364;
+  s1366 = table2[s1365];
+  s1367 = s1361 ^ s1366;
+  s1369 = table0[s1368];
+  s1371 = s1369 ^ s1370;
+  s1372 = table3[s1371];
+  s1373 = s1367 ^ s1372;
+  s1375 = table0[s1374];
+  s1377 = s1375 ^ s1376;
+  s1378 = table4[s1377];
+  s1379 = s1373 ^ s1378;
+  s1380 = sbv_bv_extract_u32_23_16_u8(s1379);
+  s1381 = table0[s1380];
+  s1383 = s1381 ^ s1382;
+  s1384 = table2[s1383];
+  s1385 = s1356 ^ s1384;
+  s1387 = table0[s1386];
+  s1389 = s1387 ^ s1388;
+  s1390 = table1[s1389];
+  s1392 = table0[s1391];
+  s1394 = s1392 ^ s1393;
+  s1395 = table2[s1394];
+  s1396 = s1390 ^ s1395;
+  s1398 = table0[s1397];
+  s1400 = s1398 ^ s1399;
+  s1401 = table3[s1400];
+  s1402 = s1396 ^ s1401;
+  s1404 = table0[s1403];
+  s1406 = s1404 ^ s1405;
+  s1407 = table4[s1406];
+  s1408 = s1402 ^ s1407;
+  s1409 = sbv_bv_extract_u32_15_8_u8(s1408);
+  s1410 = table0[s1409];
+  s1412 = s1410 ^ s1411;
+  s1413 = table3[s1412];
+  s1414 = s1385 ^ s1413;
+  s1416 = table0[s1415];
+  s1418 = s1416 ^ s1417;
+  s1419 = table1[s1418];
+  s1421 = table0[s1420];
+  s1423 = s1421 ^ s1422;
+  s1424 = table2[s1423];
+  s1425 = s1419 ^ s1424;
+  s1427 = table0[s1426];
+  s1429 = s1427 ^ s1428;
+  s1430 = table3[s1429];
+  s1431 = s1425 ^ s1430;
+  s1433 = table0[s1432];
+  s1435 = s1433 ^ s1434;
+  s1436 = table4[s1435];
+  s1437 = s1431 ^ s1436;
+  s1438 = sbv_bv_extract_u32_7_0_u8(s1437);
+  s1439 = table0[s1438];
+  s1441 = s1439 ^ s1440;
+  s1442 = table4[s1441];
+  s1443 = s1414 ^ s1442;
+  s1444 = sbv_bv_extract_u32_31_24_u8(s1443);
+  s1445 = table0[s1444];
+  s1447 = s1445 ^ s1446;
+  s1448 = table1[s1447];
+  s1449 = sbv_bv_extract_u32_31_24_u8(s1379);
+  s1450 = table0[s1449];
+  s1452 = s1450 ^ s1451;
+  s1453 = table1[s1452];
+  s1454 = sbv_bv_extract_u32_23_16_u8(s1408);
+  s1455 = table0[s1454];
+  s1457 = s1455 ^ s1456;
+  s1458 = table2[s1457];
+  s1459 = s1453 ^ s1458;
+  s1460 = sbv_bv_extract_u32_15_8_u8(s1437);
+  s1461 = table0[s1460];
+  s1463 = s1461 ^ s1462;
+  s1464 = table3[s1463];
+  s1465 = s1459 ^ s1464;
+  s1466 = sbv_bv_extract_u32_7_0_u8(s1351);
+  s1467 = table0[s1466];
+  s1469 = s1467 ^ s1468;
+  s1470 = table4[s1469];
+  s1471 = s1465 ^ s1470;
+  s1472 = sbv_bv_extract_u32_23_16_u8(s1471);
+  s1473 = table0[s1472];
+  s1475 = s1473 ^ s1474;
+  s1476 = table2[s1475];
+  s1477 = s1448 ^ s1476;
+  s1478 = sbv_bv_extract_u32_31_24_u8(s1408);
+  s1479 = table0[s1478];
+  s1481 = s1479 ^ s1480;
+  s1482 = table1[s1481];
+  s1483 = sbv_bv_extract_u32_23_16_u8(s1437);
+  s1484 = table0[s1483];
+  s1486 = s1484 ^ s1485;
+  s1487 = table2[s1486];
+  s1488 = s1482 ^ s1487;
+  s1489 = sbv_bv_extract_u32_15_8_u8(s1351);
+  s1490 = table0[s1489];
+  s1492 = s1490 ^ s1491;
+  s1493 = table3[s1492];
+  s1494 = s1488 ^ s1493;
+  s1495 = sbv_bv_extract_u32_7_0_u8(s1379);
+  s1496 = table0[s1495];
+  s1498 = s1496 ^ s1497;
+  s1499 = table4[s1498];
+  s1500 = s1494 ^ s1499;
+  s1501 = sbv_bv_extract_u32_15_8_u8(s1500);
+  s1502 = table0[s1501];
+  s1504 = s1502 ^ s1503;
+  s1505 = table3[s1504];
+  s1506 = s1477 ^ s1505;
+  s1507 = sbv_bv_extract_u32_31_24_u8(s1437);
+  s1508 = table0[s1507];
+  s1510 = s1508 ^ s1509;
+  s1511 = table1[s1510];
+  s1512 = sbv_bv_extract_u32_23_16_u8(s1351);
+  s1513 = table0[s1512];
+  s1515 = s1513 ^ s1514;
+  s1516 = table2[s1515];
+  s1517 = s1511 ^ s1516;
+  s1518 = sbv_bv_extract_u32_15_8_u8(s1379);
+  s1519 = table0[s1518];
+  s1521 = s1519 ^ s1520;
+  s1522 = table3[s1521];
+  s1523 = s1517 ^ s1522;
+  s1524 = sbv_bv_extract_u32_7_0_u8(s1408);
+  s1525 = table0[s1524];
+  s1527 = s1525 ^ s1526;
+  s1528 = table4[s1527];
+  s1529 = s1523 ^ s1528;
+  s1530 = sbv_bv_extract_u32_7_0_u8(s1529);
+  s1531 = table0[s1530];
+  s1533 = s1531 ^ s1532;
+  s1534 = table4[s1533];
+  s1535 = s1506 ^ s1534;
+  s1536 = sbv_bv_extract_u32_31_24_u8(s1535);
+  s1537 = table0[s1536];
+  s1539 = s1537 ^ s1538;
+  s1540 = table1[s1539];
+  s1541 = sbv_bv_extract_u32_31_24_u8(s1471);
+  s1542 = table0[s1541];
+  s1544 = s1542 ^ s1543;
+  s1545 = table1[s1544];
+  s1546 = sbv_bv_extract_u32_23_16_u8(s1500);
+  s1547 = table0[s1546];
+  s1549 = s1547 ^ s1548;
+  s1550 = table2[s1549];
+  s1551 = s1545 ^ s1550;
+  s1552 = sbv_bv_extract_u32_15_8_u8(s1529);
+  s1553 = table0[s1552];
+  s1555 = s1553 ^ s1554;
+  s1556 = table3[s1555];
+  s1557 = s1551 ^ s1556;
+  s1558 = sbv_bv_extract_u32_7_0_u8(s1443);
+  s1559 = table0[s1558];
+  s1561 = s1559 ^ s1560;
+  s1562 = table4[s1561];
+  s1563 = s1557 ^ s1562;
+  s1564 = sbv_bv_extract_u32_23_16_u8(s1563);
+  s1565 = table0[s1564];
+  s1567 = s1565 ^ s1566;
+  s1568 = table2[s1567];
+  s1569 = s1540 ^ s1568;
+  s1570 = sbv_bv_extract_u32_31_24_u8(s1500);
+  s1571 = table0[s1570];
+  s1573 = s1571 ^ s1572;
+  s1574 = table1[s1573];
+  s1575 = sbv_bv_extract_u32_23_16_u8(s1529);
+  s1576 = table0[s1575];
+  s1578 = s1576 ^ s1577;
+  s1579 = table2[s1578];
+  s1580 = s1574 ^ s1579;
+  s1581 = sbv_bv_extract_u32_15_8_u8(s1443);
+  s1582 = table0[s1581];
+  s1584 = s1582 ^ s1583;
+  s1585 = table3[s1584];
+  s1586 = s1580 ^ s1585;
+  s1587 = sbv_bv_extract_u32_7_0_u8(s1471);
+  s1588 = table0[s1587];
+  s1590 = s1588 ^ s1589;
+  s1591 = table4[s1590];
+  s1592 = s1586 ^ s1591;
+  s1593 = sbv_bv_extract_u32_15_8_u8(s1592);
+  s1594 = table0[s1593];
+  s1596 = s1594 ^ s1595;
+  s1597 = table3[s1596];
+  s1598 = s1569 ^ s1597;
+  s1599 = sbv_bv_extract_u32_31_24_u8(s1529);
+  s1600 = table0[s1599];
+  s1602 = s1600 ^ s1601;
+  s1603 = table1[s1602];
+  s1604 = sbv_bv_extract_u32_23_16_u8(s1443);
+  s1605 = table0[s1604];
+  s1607 = s1605 ^ s1606;
+  s1608 = table2[s1607];
+  s1609 = s1603 ^ s1608;
+  s1610 = sbv_bv_extract_u32_15_8_u8(s1471);
+  s1611 = table0[s1610];
+  s1613 = s1611 ^ s1612;
+  s1614 = table3[s1613];
+  s1615 = s1609 ^ s1614;
+  s1616 = sbv_bv_extract_u32_7_0_u8(s1500);
+  s1617 = table0[s1616];
+  s1619 = s1617 ^ s1618;
+  s1620 = table4[s1619];
+  s1621 = s1615 ^ s1620;
+  s1622 = sbv_bv_extract_u32_7_0_u8(s1621);
+  s1623 = table0[s1622];
+  s1625 = s1623 ^ s1624;
+  s1626 = table4[s1625];
+  s1627 = s1598 ^ s1626;
+  s1628 = sbv_bv_extract_u32_31_24_u8(s1627);
+  s1629 = table0[s1628];
+  s1631 = s1629 ^ s1630;
+  s1632 = table1[s1631];
+  s1633 = sbv_bv_extract_u32_31_24_u8(s1563);
+  s1634 = table0[s1633];
+  s1636 = s1634 ^ s1635;
+  s1637 = table1[s1636];
+  s1638 = sbv_bv_extract_u32_23_16_u8(s1592);
+  s1639 = table0[s1638];
+  s1641 = s1639 ^ s1640;
+  s1642 = table2[s1641];
+  s1643 = s1637 ^ s1642;
+  s1644 = sbv_bv_extract_u32_15_8_u8(s1621);
+  s1645 = table0[s1644];
+  s1647 = s1645 ^ s1646;
+  s1648 = table3[s1647];
+  s1649 = s1643 ^ s1648;
+  s1650 = sbv_bv_extract_u32_7_0_u8(s1535);
+  s1651 = table0[s1650];
+  s1653 = s1651 ^ s1652;
+  s1654 = table4[s1653];
+  s1655 = s1649 ^ s1654;
+  s1656 = sbv_bv_extract_u32_23_16_u8(s1655);
+  s1657 = table0[s1656];
+  s1659 = s1657 ^ s1658;
+  s1660 = table2[s1659];
+  s1661 = s1632 ^ s1660;
+  s1662 = sbv_bv_extract_u32_31_24_u8(s1592);
+  s1663 = table0[s1662];
+  s1665 = s1663 ^ s1664;
+  s1666 = table1[s1665];
+  s1667 = sbv_bv_extract_u32_23_16_u8(s1621);
+  s1668 = table0[s1667];
+  s1670 = s1668 ^ s1669;
+  s1671 = table2[s1670];
+  s1672 = s1666 ^ s1671;
+  s1673 = sbv_bv_extract_u32_15_8_u8(s1535);
+  s1674 = table0[s1673];
+  s1676 = s1674 ^ s1675;
+  s1677 = table3[s1676];
+  s1678 = s1672 ^ s1677;
+  s1679 = sbv_bv_extract_u32_7_0_u8(s1563);
+  s1680 = table0[s1679];
+  s1682 = s1680 ^ s1681;
+  s1683 = table4[s1682];
+  s1684 = s1678 ^ s1683;
+  s1685 = sbv_bv_extract_u32_15_8_u8(s1684);
+  s1686 = table0[s1685];
+  s1688 = s1686 ^ s1687;
+  s1689 = table3[s1688];
+  s1690 = s1661 ^ s1689;
+  s1691 = sbv_bv_extract_u32_31_24_u8(s1621);
+  s1692 = table0[s1691];
+  s1694 = s1692 ^ s1693;
+  s1695 = table1[s1694];
+  s1696 = sbv_bv_extract_u32_23_16_u8(s1535);
+  s1697 = table0[s1696];
+  s1699 = s1697 ^ s1698;
+  s1700 = table2[s1699];
+  s1701 = s1695 ^ s1700;
+  s1702 = sbv_bv_extract_u32_15_8_u8(s1563);
+  s1703 = table0[s1702];
+  s1705 = s1703 ^ s1704;
+  s1706 = table3[s1705];
+  s1707 = s1701 ^ s1706;
+  s1708 = sbv_bv_extract_u32_7_0_u8(s1592);
+  s1709 = table0[s1708];
+  s1711 = s1709 ^ s1710;
+  s1712 = table4[s1711];
+  s1713 = s1707 ^ s1712;
+  s1714 = sbv_bv_extract_u32_7_0_u8(s1713);
+  s1715 = table0[s1714];
+  s1717 = s1715 ^ s1716;
+  s1718 = table4[s1717];
+  s1719 = s1690 ^ s1718;
+  s1720 = sbv_bv_extract_u32_31_24_u8(s1719);
+  s1721 = table0[s1720];
+  s1723 = s1721 ^ s1722;
+  s1724 = table1[s1723];
+  s1725 = sbv_bv_extract_u32_31_24_u8(s1655);
+  s1726 = table0[s1725];
+  s1728 = s1726 ^ s1727;
+  s1729 = table1[s1728];
+  s1730 = sbv_bv_extract_u32_23_16_u8(s1684);
+  s1731 = table0[s1730];
+  s1733 = s1731 ^ s1732;
+  s1734 = table2[s1733];
+  s1735 = s1729 ^ s1734;
+  s1736 = sbv_bv_extract_u32_15_8_u8(s1713);
+  s1737 = table0[s1736];
+  s1739 = s1737 ^ s1738;
+  s1740 = table3[s1739];
+  s1741 = s1735 ^ s1740;
+  s1742 = sbv_bv_extract_u32_7_0_u8(s1627);
+  s1743 = table0[s1742];
+  s1745 = s1743 ^ s1744;
+  s1746 = table4[s1745];
+  s1747 = s1741 ^ s1746;
+  s1748 = sbv_bv_extract_u32_23_16_u8(s1747);
+  s1749 = table0[s1748];
+  s1751 = s1749 ^ s1750;
+  s1752 = table2[s1751];
+  s1753 = s1724 ^ s1752;
+  s1754 = sbv_bv_extract_u32_31_24_u8(s1684);
+  s1755 = table0[s1754];
+  s1757 = s1755 ^ s1756;
+  s1758 = table1[s1757];
+  s1759 = sbv_bv_extract_u32_23_16_u8(s1713);
+  s1760 = table0[s1759];
+  s1762 = s1760 ^ s1761;
+  s1763 = table2[s1762];
+  s1764 = s1758 ^ s1763;
+  s1765 = sbv_bv_extract_u32_15_8_u8(s1627);
+  s1766 = table0[s1765];
+  s1768 = s1766 ^ s1767;
+  s1769 = table3[s1768];
+  s1770 = s1764 ^ s1769;
+  s1771 = sbv_bv_extract_u32_7_0_u8(s1655);
+  s1772 = table0[s1771];
+  s1774 = s1772 ^ s1773;
+  s1775 = table4[s1774];
+  s1776 = s1770 ^ s1775;
+  s1777 = sbv_bv_extract_u32_15_8_u8(s1776);
+  s1778 = table0[s1777];
+  s1780 = s1778 ^ s1779;
+  s1781 = table3[s1780];
+  s1782 = s1753 ^ s1781;
+  s1783 = sbv_bv_extract_u32_31_24_u8(s1713);
+  s1784 = table0[s1783];
+  s1786 = s1784 ^ s1785;
+  s1787 = table1[s1786];
+  s1788 = sbv_bv_extract_u32_23_16_u8(s1627);
+  s1789 = table0[s1788];
+  s1791 = s1789 ^ s1790;
+  s1792 = table2[s1791];
+  s1793 = s1787 ^ s1792;
+  s1794 = sbv_bv_extract_u32_15_8_u8(s1655);
+  s1795 = table0[s1794];
+  s1797 = s1795 ^ s1796;
+  s1798 = table3[s1797];
+  s1799 = s1793 ^ s1798;
+  s1800 = sbv_bv_extract_u32_7_0_u8(s1684);
+  s1801 = table0[s1800];
+  s1803 = s1801 ^ s1802;
+  s1804 = table4[s1803];
+  s1805 = s1799 ^ s1804;
+  s1806 = sbv_bv_extract_u32_7_0_u8(s1805);
+  s1807 = table0[s1806];
+  s1809 = s1807 ^ s1808;
+  s1810 = table4[s1809];
+  s1811 = s1782 ^ s1810;
+  s1812 = sbv_bv_extract_u32_31_24_u8(s1811);
+  s1813 = table0[s1812];
+  s1815 = s1813 ^ s1814;
+  s1816 = table1[s1815];
+  s1817 = sbv_bv_extract_u32_31_24_u8(s1747);
+  s1818 = table0[s1817];
+  s1820 = s1818 ^ s1819;
+  s1821 = table1[s1820];
+  s1822 = sbv_bv_extract_u32_23_16_u8(s1776);
+  s1823 = table0[s1822];
+  s1825 = s1823 ^ s1824;
+  s1826 = table2[s1825];
+  s1827 = s1821 ^ s1826;
+  s1828 = sbv_bv_extract_u32_15_8_u8(s1805);
+  s1829 = table0[s1828];
+  s1831 = s1829 ^ s1830;
+  s1832 = table3[s1831];
+  s1833 = s1827 ^ s1832;
+  s1834 = sbv_bv_extract_u32_7_0_u8(s1719);
+  s1835 = table0[s1834];
+  s1837 = s1835 ^ s1836;
+  s1838 = table4[s1837];
+  s1839 = s1833 ^ s1838;
+  s1840 = sbv_bv_extract_u32_23_16_u8(s1839);
+  s1841 = table0[s1840];
+  s1843 = s1841 ^ s1842;
+  s1844 = table2[s1843];
+  s1845 = s1816 ^ s1844;
+  s1846 = sbv_bv_extract_u32_31_24_u8(s1776);
+  s1847 = table0[s1846];
+  s1849 = s1847 ^ s1848;
+  s1850 = table1[s1849];
+  s1851 = sbv_bv_extract_u32_23_16_u8(s1805);
+  s1852 = table0[s1851];
+  s1854 = s1852 ^ s1853;
+  s1855 = table2[s1854];
+  s1856 = s1850 ^ s1855;
+  s1857 = sbv_bv_extract_u32_15_8_u8(s1719);
+  s1858 = table0[s1857];
+  s1860 = s1858 ^ s1859;
+  s1861 = table3[s1860];
+  s1862 = s1856 ^ s1861;
+  s1863 = sbv_bv_extract_u32_7_0_u8(s1747);
+  s1864 = table0[s1863];
+  s1866 = s1864 ^ s1865;
+  s1867 = table4[s1866];
+  s1868 = s1862 ^ s1867;
+  s1869 = sbv_bv_extract_u32_15_8_u8(s1868);
+  s1870 = table0[s1869];
+  s1872 = s1870 ^ s1871;
+  s1873 = table3[s1872];
+  s1874 = s1845 ^ s1873;
+  s1875 = sbv_bv_extract_u32_31_24_u8(s1805);
+  s1876 = table0[s1875];
+  s1878 = s1876 ^ s1877;
+  s1879 = table1[s1878];
+  s1880 = sbv_bv_extract_u32_23_16_u8(s1719);
+  s1881 = table0[s1880];
+  s1883 = s1881 ^ s1882;
+  s1884 = table2[s1883];
+  s1885 = s1879 ^ s1884;
+  s1886 = sbv_bv_extract_u32_15_8_u8(s1747);
+  s1887 = table0[s1886];
+  s1889 = s1887 ^ s1888;
+  s1890 = table3[s1889];
+  s1891 = s1885 ^ s1890;
+  s1892 = sbv_bv_extract_u32_7_0_u8(s1776);
+  s1893 = table0[s1892];
+  s1895 = s1893 ^ s1894;
+  s1896 = table4[s1895];
+  s1897 = s1891 ^ s1896;
+  s1898 = sbv_bv_extract_u32_7_0_u8(s1897);
+  s1899 = table0[s1898];
+  s1901 = s1899 ^ s1900;
+  s1902 = table4[s1901];
+  s1903 = s1874 ^ s1902;
+  s1904 = sbv_bv_extract_u32_31_24_u8(s1903);
+  s1905 = table0[s1904];
+  s1907 = s1905 ^ s1906;
+  s1908 = table1[s1907];
+  s1909 = sbv_bv_extract_u32_31_24_u8(s1839);
+  s1910 = table0[s1909];
+  s1912 = s1910 ^ s1911;
+  s1913 = table1[s1912];
+  s1914 = sbv_bv_extract_u32_23_16_u8(s1868);
+  s1915 = table0[s1914];
+  s1917 = s1915 ^ s1916;
+  s1918 = table2[s1917];
+  s1919 = s1913 ^ s1918;
+  s1920 = sbv_bv_extract_u32_15_8_u8(s1897);
+  s1921 = table0[s1920];
+  s1923 = s1921 ^ s1922;
+  s1924 = table3[s1923];
+  s1925 = s1919 ^ s1924;
+  s1926 = sbv_bv_extract_u32_7_0_u8(s1811);
+  s1927 = table0[s1926];
+  s1929 = s1927 ^ s1928;
+  s1930 = table4[s1929];
+  s1931 = s1925 ^ s1930;
+  s1932 = sbv_bv_extract_u32_23_16_u8(s1931);
+  s1933 = table0[s1932];
+  s1935 = s1933 ^ s1934;
+  s1936 = table2[s1935];
+  s1937 = s1908 ^ s1936;
+  s1938 = sbv_bv_extract_u32_31_24_u8(s1868);
+  s1939 = table0[s1938];
+  s1941 = s1939 ^ s1940;
+  s1942 = table1[s1941];
+  s1943 = sbv_bv_extract_u32_23_16_u8(s1897);
+  s1944 = table0[s1943];
+  s1946 = s1944 ^ s1945;
+  s1947 = table2[s1946];
+  s1948 = s1942 ^ s1947;
+  s1949 = sbv_bv_extract_u32_15_8_u8(s1811);
+  s1950 = table0[s1949];
+  s1952 = s1950 ^ s1951;
+  s1953 = table3[s1952];
+  s1954 = s1948 ^ s1953;
+  s1955 = sbv_bv_extract_u32_7_0_u8(s1839);
+  s1956 = table0[s1955];
+  s1958 = s1956 ^ s1957;
+  s1959 = table4[s1958];
+  s1960 = s1954 ^ s1959;
+  s1961 = sbv_bv_extract_u32_15_8_u8(s1960);
+  s1962 = table0[s1961];
+  s1964 = s1962 ^ s1963;
+  s1965 = table3[s1964];
+  s1966 = s1937 ^ s1965;
+  s1967 = sbv_bv_extract_u32_31_24_u8(s1897);
+  s1968 = table0[s1967];
+  s1970 = s1968 ^ s1969;
+  s1971 = table1[s1970];
+  s1972 = sbv_bv_extract_u32_23_16_u8(s1811);
+  s1973 = table0[s1972];
+  s1975 = s1973 ^ s1974;
+  s1976 = table2[s1975];
+  s1977 = s1971 ^ s1976;
+  s1978 = sbv_bv_extract_u32_15_8_u8(s1839);
+  s1979 = table0[s1978];
+  s1981 = s1979 ^ s1980;
+  s1982 = table3[s1981];
+  s1983 = s1977 ^ s1982;
+  s1984 = sbv_bv_extract_u32_7_0_u8(s1868);
+  s1985 = table0[s1984];
+  s1987 = s1985 ^ s1986;
+  s1988 = table4[s1987];
+  s1989 = s1983 ^ s1988;
+  s1990 = sbv_bv_extract_u32_7_0_u8(s1989);
+  s1991 = table0[s1990];
+  s1993 = s1991 ^ s1992;
+  s1994 = table4[s1993];
+  s1995 = s1966 ^ s1994;
+  s1996 = sbv_bv_extract_u32_31_24_u8(s1995);
+  s1997 = table0[s1996];
+  s1999 = s1997 ^ s1998;
+  s2000 = table1[s1999];
+  s2001 = sbv_bv_extract_u32_31_24_u8(s1931);
+  s2002 = table0[s2001];
+  s2004 = s2002 ^ s2003;
+  s2005 = table1[s2004];
+  s2006 = sbv_bv_extract_u32_23_16_u8(s1960);
+  s2007 = table0[s2006];
+  s2009 = s2007 ^ s2008;
+  s2010 = table2[s2009];
+  s2011 = s2005 ^ s2010;
+  s2012 = sbv_bv_extract_u32_15_8_u8(s1989);
+  s2013 = table0[s2012];
+  s2015 = s2013 ^ s2014;
+  s2016 = table3[s2015];
+  s2017 = s2011 ^ s2016;
+  s2018 = sbv_bv_extract_u32_7_0_u8(s1903);
+  s2019 = table0[s2018];
+  s2021 = s2019 ^ s2020;
+  s2022 = table4[s2021];
+  s2023 = s2017 ^ s2022;
+  s2024 = sbv_bv_extract_u32_23_16_u8(s2023);
+  s2025 = table0[s2024];
+  s2027 = s2025 ^ s2026;
+  s2028 = table2[s2027];
+  s2029 = s2000 ^ s2028;
+  s2030 = sbv_bv_extract_u32_31_24_u8(s1960);
+  s2031 = table0[s2030];
+  s2033 = s2031 ^ s2032;
+  s2034 = table1[s2033];
+  s2035 = sbv_bv_extract_u32_23_16_u8(s1989);
+  s2036 = table0[s2035];
+  s2038 = s2036 ^ s2037;
+  s2039 = table2[s2038];
+  s2040 = s2034 ^ s2039;
+  s2041 = sbv_bv_extract_u32_15_8_u8(s1903);
+  s2042 = table0[s2041];
+  s2044 = s2042 ^ s2043;
+  s2045 = table3[s2044];
+  s2046 = s2040 ^ s2045;
+  s2047 = sbv_bv_extract_u32_7_0_u8(s1931);
+  s2048 = table0[s2047];
+  s2050 = s2048 ^ s2049;
+  s2051 = table4[s2050];
+  s2052 = s2046 ^ s2051;
+  s2053 = sbv_bv_extract_u32_15_8_u8(s2052);
+  s2054 = table0[s2053];
+  s2056 = s2054 ^ s2055;
+  s2057 = table3[s2056];
+  s2058 = s2029 ^ s2057;
+  s2059 = sbv_bv_extract_u32_31_24_u8(s1989);
+  s2060 = table0[s2059];
+  s2062 = s2060 ^ s2061;
+  s2063 = table1[s2062];
+  s2064 = sbv_bv_extract_u32_23_16_u8(s1903);
+  s2065 = table0[s2064];
+  s2067 = s2065 ^ s2066;
+  s2068 = table2[s2067];
+  s2069 = s2063 ^ s2068;
+  s2070 = sbv_bv_extract_u32_15_8_u8(s1931);
+  s2071 = table0[s2070];
+  s2073 = s2071 ^ s2072;
+  s2074 = table3[s2073];
+  s2075 = s2069 ^ s2074;
+  s2076 = sbv_bv_extract_u32_7_0_u8(s1960);
+  s2077 = table0[s2076];
+  s2079 = s2077 ^ s2078;
+  s2080 = table4[s2079];
+  s2081 = s2075 ^ s2080;
+  s2082 = sbv_bv_extract_u32_7_0_u8(s2081);
+  s2083 = table0[s2082];
+  s2085 = s2083 ^ s2084;
+  s2086 = table4[s2085];
+  s2087 = s2058 ^ s2086;
+  s2088 = sbv_bv_extract_u32_31_24_u8(s2087);
+  s2089 = table0[s2088];
+  s2090 = sbv_bv_extract_u32_31_24_u8(s2023);
+  s2091 = table0[s2090];
+  s2093 = s2091 ^ s2092;
+  s2094 = table1[s2093];
+  s2095 = sbv_bv_extract_u32_23_16_u8(s2052);
+  s2096 = table0[s2095];
+  s2098 = s2096 ^ s2097;
+  s2099 = table2[s2098];
+  s2100 = s2094 ^ s2099;
+  s2101 = sbv_bv_extract_u32_15_8_u8(s2081);
+  s2102 = table0[s2101];
+  s2104 = s2102 ^ s2103;
+  s2105 = table3[s2104];
+  s2106 = s2100 ^ s2105;
+  s2107 = sbv_bv_extract_u32_7_0_u8(s1995);
+  s2108 = table0[s2107];
+  s2110 = s2108 ^ s2109;
+  s2111 = table4[s2110];
+  s2112 = s2106 ^ s2111;
+  s2113 = sbv_bv_extract_u32_23_16_u8(s2112);
+  s2114 = table0[s2113];
+  s2115 = sbv_bv_join_u8_u8_u16(s2089, s2114);
+  s2116 = sbv_bv_extract_u32_31_24_u8(s2052);
+  s2117 = table0[s2116];
+  s2119 = s2117 ^ s2118;
+  s2120 = table1[s2119];
+  s2121 = sbv_bv_extract_u32_23_16_u8(s2081);
+  s2122 = table0[s2121];
+  s2124 = s2122 ^ s2123;
+  s2125 = table2[s2124];
+  s2126 = s2120 ^ s2125;
+  s2127 = sbv_bv_extract_u32_15_8_u8(s1995);
+  s2128 = table0[s2127];
+  s2130 = s2128 ^ s2129;
+  s2131 = table3[s2130];
+  s2132 = s2126 ^ s2131;
+  s2133 = sbv_bv_extract_u32_7_0_u8(s2023);
+  s2134 = table0[s2133];
+  s2136 = s2134 ^ s2135;
+  s2137 = table4[s2136];
+  s2138 = s2132 ^ s2137;
+  s2139 = sbv_bv_extract_u32_15_8_u8(s2138);
+  s2140 = table0[s2139];
+  s2141 = sbv_bv_extract_u32_31_24_u8(s2081);
+  s2142 = table0[s2141];
+  s2144 = s2142 ^ s2143;
+  s2145 = table1[s2144];
+  s2146 = sbv_bv_extract_u32_23_16_u8(s1995);
+  s2147 = table0[s2146];
+  s2149 = s2147 ^ s2148;
+  s2150 = table2[s2149];
+  s2151 = s2145 ^ s2150;
+  s2152 = sbv_bv_extract_u32_15_8_u8(s2023);
+  s2153 = table0[s2152];
+  s2155 = s2153 ^ s2154;
+  s2156 = table3[s2155];
+  s2157 = s2151 ^ s2156;
+  s2158 = sbv_bv_extract_u32_7_0_u8(s2052);
+  s2159 = table0[s2158];
+  s2161 = s2159 ^ s2160;
+  s2162 = table4[s2161];
+  s2163 = s2157 ^ s2162;
+  s2164 = sbv_bv_extract_u32_7_0_u8(s2163);
+  s2165 = table0[s2164];
+  s2166 = sbv_bv_join_u8_u8_u16(s2140, s2165);
+  s2167 = sbv_bv_join_u16_u16_u32(s2115, s2166);
+  s2168 = s44 ^ s2167;
+  s2169 = sbv_bv_extract_u32_31_24_u8(s2163);
+  s2170 = table0[s2169];
+  s2171 = sbv_bv_extract_u32_23_16_u8(s2087);
+  s2172 = table0[s2171];
+  s2173 = sbv_bv_join_u8_u8_u16(s2170, s2172);
+  s2174 = sbv_bv_extract_u32_15_8_u8(s2112);
+  s2175 = table0[s2174];
+  s2176 = sbv_bv_extract_u32_7_0_u8(s2138);
+  s2177 = table0[s2176];
+  s2178 = sbv_bv_join_u8_u8_u16(s2175, s2177);
+  s2179 = sbv_bv_join_u16_u16_u32(s2173, s2178);
+  s2180 = s45 ^ s2179;
+  s2181 = sbv_bv_extract_u32_31_24_u8(s2138);
+  s2182 = table0[s2181];
+  s2183 = sbv_bv_extract_u32_23_16_u8(s2163);
+  s2184 = table0[s2183];
+  s2185 = sbv_bv_join_u8_u8_u16(s2182, s2184);
+  s2186 = sbv_bv_extract_u32_15_8_u8(s2087);
+  s2187 = table0[s2186];
+  s2188 = sbv_bv_extract_u32_7_0_u8(s2112);
+  s2189 = table0[s2188];
+  s2190 = sbv_bv_join_u8_u8_u16(s2187, s2189);
+  s2191 = sbv_bv_join_u16_u16_u32(s2185, s2190);
+  s2192 = s46 ^ s2191;
+  s2193 = sbv_bv_extract_u32_31_24_u8(s2112);
+  s2194 = table0[s2193];
+  s2195 = sbv_bv_extract_u32_23_16_u8(s2138);
+  s2196 = table0[s2195];
+  s2197 = sbv_bv_join_u8_u8_u16(s2194, s2196);
+  s2198 = sbv_bv_extract_u32_15_8_u8(s2163);
+  s2199 = table0[s2198];
+  s2200 = sbv_bv_extract_u32_7_0_u8(s2087);
+  s2201 = table0[s2200];
+  s2202 = sbv_bv_join_u8_u8_u16(s2199, s2201);
+  s2203 = sbv_bv_join_u16_u16_u32(s2197, s2202);
+  s2204 = s47 ^ s2203;
+
+  sbv_output_0[0] = s2168;
+  sbv_output_0[1] = s2180;
+  sbv_output_0[2] = s2192;
+  sbv_output_0[3] = s2204;
+}
+== END: "aes128OTFDecrypt.c" ==================
+== BEGIN: "aes128Lib.h" ================
+/* Header file for aes128Lib. Automatically generated by SBV. Do not edit! */
+
+#ifndef SBV_GENERATED_aes128Lib_HEADER_INCLUDED
+#define SBV_GENERATED_aes128Lib_HEADER_INCLUDED
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <math.h>
+
+/* Floating-point calling convention:
+ * Enter generated code in FE_TONEAREST (round-to-nearest, ties-to-even).
+ * Callbacks must preserve this mode before returning or re-entering.
+ * Generated code does not check or change the hardware rounding mode.
+ * Custom builds must disable implicit FP contraction, including at LTO link time.
+ */
+
+/* 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 /* SBV_GENERATED_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 sbv_driver_input_0[4] = {
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL
+  };
+
+  printf("Contents of input array key:\n");
+  int sbv_driver_input_0_ctr;
+  for(sbv_driver_input_0_ctr = 0; sbv_driver_input_0_ctr < 4 ; ++sbv_driver_input_0_ctr)
+  { printf("  key[%1d] = ", sbv_driver_input_0_ctr);
+    printf("0x%08"PRIx32"UL", sbv_driver_input_0[sbv_driver_input_0_ctr]);
+    printf("\n");
+  }
+
+  SWord32 sbv_driver_output_0[44];
+  SWord32 sbv_driver_output_1[44];
+
+  aes128KeySchedule(sbv_driver_input_0, sbv_driver_output_0,
+                    sbv_driver_output_1);
+
+  printf("aes128KeySchedule(key, encKS, decKS) ->\n");
+  int sbv_driver_output_0_ctr;
+  for(sbv_driver_output_0_ctr = 0; sbv_driver_output_0_ctr < 44 ; ++sbv_driver_output_0_ctr)
+  { printf("  encKS[%2d] = ", sbv_driver_output_0_ctr);
+    printf("0x%08"PRIx32"UL", sbv_driver_output_0[sbv_driver_output_0_ctr]);
+    printf("\n");
+  }
+  int sbv_driver_output_1_ctr;
+  for(sbv_driver_output_1_ctr = 0; sbv_driver_output_1_ctr < 44 ; ++sbv_driver_output_1_ctr)
+  { printf("  decKS[%2d] = ", sbv_driver_output_1_ctr);
+    printf("0x%08"PRIx32"UL", sbv_driver_output_1[sbv_driver_output_1_ctr]);
+    printf("\n");
+  }
+}
+
+void aes128BlockEncrypt_driver(void)
+{
+  const SWord32 sbv_driver_input_0[4] = {
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL
+  };
+
+  printf("Contents of input array pt:\n");
+  int sbv_driver_input_0_ctr;
+  for(sbv_driver_input_0_ctr = 0; sbv_driver_input_0_ctr < 4 ; ++sbv_driver_input_0_ctr)
+  { printf("  pt[%1d] = ", sbv_driver_input_0_ctr);
+    printf("0x%08"PRIx32"UL", sbv_driver_input_0[sbv_driver_input_0_ctr]);
+    printf("\n");
+  }
+
+  const SWord32 sbv_driver_input_1[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 sbv_driver_input_1_ctr;
+  for(sbv_driver_input_1_ctr = 0; sbv_driver_input_1_ctr < 44 ; ++sbv_driver_input_1_ctr)
+  { printf("  xkey[%2d] = ", sbv_driver_input_1_ctr);
+    printf("0x%08"PRIx32"UL", sbv_driver_input_1[sbv_driver_input_1_ctr]);
+    printf("\n");
+  }
+
+  SWord32 sbv_driver_output_0[4];
+
+  aes128BlockEncrypt(sbv_driver_input_0, sbv_driver_input_1,
+                     sbv_driver_output_0);
+
+  printf("aes128BlockEncrypt(pt, xkey, ct) ->\n");
+  int sbv_driver_output_0_ctr;
+  for(sbv_driver_output_0_ctr = 0; sbv_driver_output_0_ctr < 4 ; ++sbv_driver_output_0_ctr)
+  { printf("  ct[%1d] = ", sbv_driver_output_0_ctr);
+    printf("0x%08"PRIx32"UL", sbv_driver_output_0[sbv_driver_output_0_ctr]);
+    printf("\n");
+  }
+}
+
+void aes128BlockDecrypt_driver(void)
+{
+  const SWord32 sbv_driver_input_0[4] = {
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL
+  };
+
+  printf("Contents of input array ct:\n");
+  int sbv_driver_input_0_ctr;
+  for(sbv_driver_input_0_ctr = 0; sbv_driver_input_0_ctr < 4 ; ++sbv_driver_input_0_ctr)
+  { printf("  ct[%1d] = ", sbv_driver_input_0_ctr);
+    printf("0x%08"PRIx32"UL", sbv_driver_input_0[sbv_driver_input_0_ctr]);
+    printf("\n");
+  }
+
+  const SWord32 sbv_driver_input_1[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 sbv_driver_input_1_ctr;
+  for(sbv_driver_input_1_ctr = 0; sbv_driver_input_1_ctr < 44 ; ++sbv_driver_input_1_ctr)
+  { printf("  xkey[%2d] = ", sbv_driver_input_1_ctr);
+    printf("0x%08"PRIx32"UL", sbv_driver_input_1[sbv_driver_input_1_ctr]);
+    printf("\n");
+  }
+
+  SWord32 sbv_driver_output_0[4];
+
+  aes128BlockDecrypt(sbv_driver_input_0, sbv_driver_input_1,
+                     sbv_driver_output_0);
+
+  printf("aes128BlockDecrypt(ct, xkey, pt) ->\n");
+  int sbv_driver_output_0_ctr;
+  for(sbv_driver_output_0_ctr = 0; sbv_driver_output_0_ctr < 4 ; ++sbv_driver_output_0_ctr)
+  { printf("  pt[%1d] = ", sbv_driver_output_0_ctr);
+    printf("0x%08"PRIx32"UL", sbv_driver_output_0[sbv_driver_output_0_ctr]);
+    printf("\n");
+  }
+}
+
+void aes128InvKeySchedule_driver(void)
+{
+  const SWord32 sbv_driver_input_0[4] = {
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL
+  };
+
+  printf("Contents of input array key:\n");
+  int sbv_driver_input_0_ctr;
+  for(sbv_driver_input_0_ctr = 0; sbv_driver_input_0_ctr < 4 ; ++sbv_driver_input_0_ctr)
+  { printf("  key[%1d] = ", sbv_driver_input_0_ctr);
+    printf("0x%08"PRIx32"UL", sbv_driver_input_0[sbv_driver_input_0_ctr]);
+    printf("\n");
+  }
+
+  SWord32 sbv_driver_output_0[44];
+
+  aes128InvKeySchedule(sbv_driver_input_0, sbv_driver_output_0);
+
+  printf("aes128InvKeySchedule(key, decKS) ->\n");
+  int sbv_driver_output_0_ctr;
+  for(sbv_driver_output_0_ctr = 0; sbv_driver_output_0_ctr < 44 ; ++sbv_driver_output_0_ctr)
+  { printf("  decKS[%2d] = ", sbv_driver_output_0_ctr);
+    printf("0x%08"PRIx32"UL", sbv_driver_output_0[sbv_driver_output_0_ctr]);
+    printf("\n");
+  }
+}
+
+void aes128OTFDecrypt_driver(void)
+{
+  const SWord32 sbv_driver_input_0[4] = {
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL
+  };
+
+  printf("Contents of input array ct:\n");
+  int sbv_driver_input_0_ctr;
+  for(sbv_driver_input_0_ctr = 0; sbv_driver_input_0_ctr < 4 ; ++sbv_driver_input_0_ctr)
+  { printf("  ct[%1d] = ", sbv_driver_input_0_ctr);
+    printf("0x%08"PRIx32"UL", sbv_driver_input_0[sbv_driver_input_0_ctr]);
+    printf("\n");
+  }
+
+  const SWord32 sbv_driver_input_1[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 sbv_driver_input_1_ctr;
+  for(sbv_driver_input_1_ctr = 0; sbv_driver_input_1_ctr < 44 ; ++sbv_driver_input_1_ctr)
+  { printf("  xkey[%2d] = ", sbv_driver_input_1_ctr);
+    printf("0x%08"PRIx32"UL", sbv_driver_input_1[sbv_driver_input_1_ctr]);
+    printf("\n");
+  }
+
+  SWord32 sbv_driver_output_0[4];
+
+  aes128OTFDecrypt(sbv_driver_input_0, sbv_driver_input_1,
+                   sbv_driver_output_0);
+
+  printf("aes128OTFDecrypt(ct, xkey, pt) ->\n");
+  int sbv_driver_output_0_ctr;
+  for(sbv_driver_output_0_ctr = 0; sbv_driver_output_0_ctr < 4 ; ++sbv_driver_output_0_ctr)
+  { printf("  pt[%1d] = ", sbv_driver_output_0_ctr);
+    printf("0x%08"PRIx32"UL", sbv_driver_output_0[sbv_driver_output_0_ctr]);
+    printf("\n");
+  }
+}
+
+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
+	rm -f $@.tmp
+	${AR} ${ARFLAGS} $@.tmp $^
+	mv -f $@.tmp $@
+
+aes128Lib_driver: aes128Lib_driver.c aes128Lib.h aes128Lib.a
+	${CC} ${CCFLAGS} $< -o $@ aes128Lib.a ${LDFLAGS}
+
+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:
+	rm -f *.o
+
+veryclean: clean
+	rm -f aes128Lib.a aes128Lib_driver aes128Lib.a.tmp
 == END: "Makefile" ==================
diff --git a/SBVTestSuite/GoldFiles/allSat7.gold b/SBVTestSuite/GoldFiles/allSat7.gold
--- a/SBVTestSuite/GoldFiles/allSat7.gold
+++ b/SBVTestSuite/GoldFiles/allSat7.gold
@@ -6,34452 +6,34451 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
-[GOOD] ; --- tuples ---
-[GOOD] ; --- sums ---
-[GOOD] ; --- literal constants ---
-[GOOD] (define-fun s3 () Int 1)
-[GOOD] (define-fun s5 () Int 15)
-[GOOD] ; --- top level inputs ---
-[GOOD] (declare-fun s0 () Int) ; tracks user variable "x"
-[GOOD] (declare-fun s1 () Int) ; tracks user variable "y"
-[GOOD] (declare-fun s2 () Int) ; tracks user variable "z"
-[GOOD] ; --- constant tables ---
-[GOOD] ; --- non-constant tables ---
-[GOOD] ; --- uninterpreted constants ---
-[GOOD] ; --- user defined functions ---
-[GOOD] ; --- assignments ---
-[GOOD] (define-fun s4 () Bool (>= s0 s3))
-[GOOD] (define-fun s6 () Bool (<= s0 s5))
-[GOOD] (define-fun s7 () Bool (and s4 s6))
-[GOOD] (define-fun s8 () Bool (>= s1 s3))
-[GOOD] (define-fun s9 () Bool (<= s1 s5))
-[GOOD] (define-fun s10 () Bool (and s8 s9))
-[GOOD] (define-fun s11 () Bool (>= s2 s3))
-[GOOD] (define-fun s12 () Bool (<= s2 s5))
-[GOOD] (define-fun s13 () Bool (and s11 s12))
-[GOOD] (define-fun s14 () Bool (distinct s0 s1 s2))
-[GOOD] ; --- delayedEqualities ---
-[GOOD] ; --- formula ---
-[GOOD] (assert s7)
-[GOOD] (assert s10)
-[GOOD] (assert s13)
-[GOOD] (assert s14)
-*** Checking Satisfiability, all solutions..
-Fast allSat, Looking for solution 1
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (define-fun s15 () Bool (distinct s0 s3))
-[GOOD] (assert s15)
-Fast allSat, Looking for solution 2
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (define-fun s16 () Int 3)
-[GOOD] (define-fun s17 () Bool (distinct s0 s16))
-[GOOD] (assert s17)
-Fast allSat, Looking for solution 3
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (define-fun s18 () Int 2)
-[GOOD] (define-fun s19 () Bool (distinct s0 s18))
-[GOOD] (assert s19)
-Fast allSat, Looking for solution 4
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (define-fun s20 () Int 4)
-[GOOD] (define-fun s21 () Bool (distinct s0 s20))
-[GOOD] (assert s21)
-Fast allSat, Looking for solution 5
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (define-fun s22 () Int 5)
-[GOOD] (define-fun s23 () Bool (distinct s0 s22))
-[GOOD] (assert s23)
-Fast allSat, Looking for solution 6
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (define-fun s24 () Int 6)
-[GOOD] (define-fun s25 () Bool (distinct s0 s24))
-[GOOD] (assert s25)
-Fast allSat, Looking for solution 7
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (define-fun s26 () Int 7)
-[GOOD] (define-fun s27 () Bool (distinct s0 s26))
-[GOOD] (assert s27)
-Fast allSat, Looking for solution 8
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (define-fun s28 () Int 8)
-[GOOD] (define-fun s29 () Bool (distinct s0 s28))
-[GOOD] (assert s29)
-Fast allSat, Looking for solution 9
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (define-fun s30 () Int 9)
-[GOOD] (define-fun s31 () Bool (distinct s0 s30))
-[GOOD] (assert s31)
-Fast allSat, Looking for solution 10
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (define-fun s32 () Int 10)
-[GOOD] (define-fun s33 () Bool (distinct s0 s32))
-[GOOD] (assert s33)
-Fast allSat, Looking for solution 11
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (define-fun s34 () Int 11)
-[GOOD] (define-fun s35 () Bool (distinct s0 s34))
-[GOOD] (assert s35)
-Fast allSat, Looking for solution 12
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (define-fun s36 () Int 12)
-[GOOD] (define-fun s37 () Bool (distinct s0 s36))
-[GOOD] (assert s37)
-Fast allSat, Looking for solution 13
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (define-fun s38 () Int 13)
-[GOOD] (define-fun s39 () Bool (distinct s0 s38))
-[GOOD] (assert s39)
-Fast allSat, Looking for solution 14
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (define-fun s40 () Int 14)
-[GOOD] (define-fun s41 () Bool (distinct s0 s40))
-[GOOD] (assert s41)
-Fast allSat, Looking for solution 15
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (define-fun s42 () Bool (distinct s0 s5))
-[GOOD] (assert s42)
-Fast allSat, Looking for solution 16
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (define-fun s43 () Bool (distinct s1 s38))
-[GOOD] (assert s43)
-[GOOD] (define-fun s44 () Bool (= s0 s5))
-[GOOD] (assert s44)
-Fast allSat, Looking for solution 16
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (define-fun s45 () Bool (distinct s1 s36))
-[GOOD] (assert s45)
-Fast allSat, Looking for solution 17
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (define-fun s46 () Bool (distinct s1 s34))
-[GOOD] (assert s46)
-Fast allSat, Looking for solution 18
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (define-fun s47 () Bool (distinct s1 s32))
-[GOOD] (assert s47)
-Fast allSat, Looking for solution 19
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (define-fun s48 () Bool (distinct s1 s30))
-[GOOD] (assert s48)
-Fast allSat, Looking for solution 20
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (define-fun s49 () Bool (distinct s1 s28))
-[GOOD] (assert s49)
-Fast allSat, Looking for solution 21
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (define-fun s50 () Bool (distinct s1 s26))
-[GOOD] (assert s50)
-Fast allSat, Looking for solution 22
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (define-fun s51 () Bool (distinct s1 s24))
-[GOOD] (assert s51)
-Fast allSat, Looking for solution 23
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (define-fun s52 () Bool (distinct s1 s22))
-[GOOD] (assert s52)
-Fast allSat, Looking for solution 24
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (define-fun s53 () Bool (distinct s1 s20))
-[GOOD] (assert s53)
-Fast allSat, Looking for solution 25
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (define-fun s54 () Bool (distinct s1 s16))
-[GOOD] (assert s54)
-Fast allSat, Looking for solution 26
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (define-fun s55 () Bool (distinct s1 s18))
-[GOOD] (assert s55)
-Fast allSat, Looking for solution 27
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (define-fun s56 () Bool (distinct s1 s3))
-[GOOD] (assert s56)
-Fast allSat, Looking for solution 28
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (define-fun s57 () Bool (distinct s1 s40))
-[GOOD] (assert s57)
-Fast allSat, Looking for solution 29
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (define-fun s58 () Bool (distinct s2 s38))
-[GOOD] (assert s58)
-[GOOD] (define-fun s59 () Bool (= s1 s40))
-[GOOD] (assert s59)
-Fast allSat, Looking for solution 29
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (define-fun s60 () Bool (distinct s2 s36))
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 30
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (define-fun s61 () Bool (distinct s2 s34))
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 31
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (define-fun s62 () Bool (distinct s2 s32))
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 32
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (define-fun s63 () Bool (distinct s2 s30))
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 33
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (define-fun s64 () Bool (distinct s2 s28))
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 34
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (define-fun s65 () Bool (distinct s2 s26))
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 35
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (define-fun s66 () Bool (distinct s2 s24))
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 36
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (define-fun s67 () Bool (distinct s2 s22))
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 37
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (define-fun s68 () Bool (distinct s2 s20))
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 38
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (define-fun s69 () Bool (distinct s2 s16))
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 39
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (define-fun s70 () Bool (distinct s2 s18))
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 40
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (define-fun s71 () Bool (distinct s2 s3))
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 41
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (define-fun s72 () Bool (distinct s2 s40))
-[GOOD] (assert s72)
-[GOOD] (define-fun s73 () Bool (= s1 s3))
-[GOOD] (assert s73)
-Fast allSat, Looking for solution 41
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 42
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 43
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 44
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 45
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 46
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 47
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 48
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 49
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 50
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 51
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 52
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 53
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s72)
-[GOOD] (define-fun s74 () Bool (= s1 s18))
-[GOOD] (assert s74)
-Fast allSat, Looking for solution 53
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 54
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 55
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 56
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 57
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 58
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 59
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 60
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 61
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 62
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 63
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 64
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 65
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s72)
-[GOOD] (define-fun s75 () Bool (= s1 s16))
-[GOOD] (assert s75)
-Fast allSat, Looking for solution 65
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 66
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 67
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 68
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 69
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 70
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 71
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 72
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 73
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 74
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 75
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 76
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 77
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s72)
-[GOOD] (define-fun s76 () Bool (= s1 s20))
-[GOOD] (assert s76)
-Fast allSat, Looking for solution 77
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 78
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 79
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 80
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 81
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 82
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 83
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 84
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 85
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 86
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 87
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 88
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 89
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s72)
-[GOOD] (define-fun s77 () Bool (= s1 s22))
-[GOOD] (assert s77)
-Fast allSat, Looking for solution 89
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 90
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 91
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 92
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 93
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 94
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 95
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 96
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 97
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 98
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 99
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 100
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 101
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s72)
-[GOOD] (define-fun s78 () Bool (= s1 s24))
-[GOOD] (assert s78)
-Fast allSat, Looking for solution 101
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 102
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 103
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 104
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 105
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 106
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 107
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 108
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 109
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 110
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 111
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 112
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 113
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s72)
-[GOOD] (define-fun s79 () Bool (= s1 s26))
-[GOOD] (assert s79)
-Fast allSat, Looking for solution 113
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 114
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 115
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 116
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 117
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 118
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 119
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 120
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 121
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 122
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 123
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 124
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 125
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s72)
-[GOOD] (define-fun s80 () Bool (= s1 s28))
-[GOOD] (assert s80)
-Fast allSat, Looking for solution 125
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 126
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 127
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 128
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 129
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 130
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 131
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 132
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 133
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 134
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 135
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 136
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 137
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s72)
-[GOOD] (define-fun s81 () Bool (= s1 s30))
-[GOOD] (assert s81)
-Fast allSat, Looking for solution 137
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 138
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 139
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 140
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 141
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 142
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 143
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 144
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 145
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 146
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 147
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 148
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 149
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s72)
-[GOOD] (define-fun s82 () Bool (= s1 s32))
-[GOOD] (assert s82)
-Fast allSat, Looking for solution 149
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 150
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 151
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 152
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 153
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 154
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 155
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 156
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 157
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 158
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 159
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 160
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 161
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s72)
-[GOOD] (define-fun s83 () Bool (= s1 s34))
-[GOOD] (assert s83)
-Fast allSat, Looking for solution 161
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 162
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 163
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 164
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 165
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 166
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 167
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 168
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 169
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 170
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 171
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 172
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 173
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s72)
-[GOOD] (define-fun s84 () Bool (= s1 s36))
-[GOOD] (assert s84)
-Fast allSat, Looking for solution 173
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 174
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 175
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 176
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 177
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 178
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 179
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 180
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 181
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 182
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 183
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 184
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 185
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s72)
-[GOOD] (assert s44)
-[GOOD] (define-fun s85 () Bool (= s1 s38))
-[GOOD] (assert s85)
-Fast allSat, Looking for solution 185
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 186
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 187
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 188
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 189
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 190
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 191
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 192
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 193
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 194
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 195
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 196
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 15))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 197
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s43)
-[GOOD] (define-fun s86 () Bool (= s0 s40))
-[GOOD] (assert s86)
-Fast allSat, Looking for solution 197
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s45)
-Fast allSat, Looking for solution 198
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s46)
-Fast allSat, Looking for solution 199
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s47)
-Fast allSat, Looking for solution 200
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s48)
-Fast allSat, Looking for solution 201
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s49)
-Fast allSat, Looking for solution 202
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s50)
-Fast allSat, Looking for solution 203
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s51)
-Fast allSat, Looking for solution 204
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s52)
-Fast allSat, Looking for solution 205
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s53)
-Fast allSat, Looking for solution 206
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s54)
-Fast allSat, Looking for solution 207
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s55)
-Fast allSat, Looking for solution 208
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (define-fun s87 () Bool (distinct s1 s5))
-[GOOD] (assert s87)
-Fast allSat, Looking for solution 209
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s56)
-Fast allSat, Looking for solution 210
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s70)
-[GOOD] (assert s73)
-Fast allSat, Looking for solution 210
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 211
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 212
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 213
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 214
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 215
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 216
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 217
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 218
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 219
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 220
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 221
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (define-fun s88 () Bool (distinct s2 s5))
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 222
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s58)
-[GOOD] (define-fun s89 () Bool (= s1 s5))
-[GOOD] (assert s89)
-Fast allSat, Looking for solution 222
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 223
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 224
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 225
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 226
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 227
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 228
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 229
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 230
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 231
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 232
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 233
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 234
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s71)
-[GOOD] (assert s74)
-Fast allSat, Looking for solution 234
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 235
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 236
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 237
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 238
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 239
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 240
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 241
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 242
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 243
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 244
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 245
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 246
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s70)
-[GOOD] (assert s75)
-Fast allSat, Looking for solution 246
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 247
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 248
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 249
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 250
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 251
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 252
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 253
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 254
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 255
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 256
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 257
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 258
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s69)
-[GOOD] (assert s76)
-Fast allSat, Looking for solution 258
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 259
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 260
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 261
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 262
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 263
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 264
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 265
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 266
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 267
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 268
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 269
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 270
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s68)
-[GOOD] (assert s77)
-Fast allSat, Looking for solution 270
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 271
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 272
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 273
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 274
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 275
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 276
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 277
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 278
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 279
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 280
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 281
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 282
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s67)
-[GOOD] (assert s78)
-Fast allSat, Looking for solution 282
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 283
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 284
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 285
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 286
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 287
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 288
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 289
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 290
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 291
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 292
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 293
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 294
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s66)
-[GOOD] (assert s79)
-Fast allSat, Looking for solution 294
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 295
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 296
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 297
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 298
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 299
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 300
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 301
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 302
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 303
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 304
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 305
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 306
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s65)
-[GOOD] (assert s80)
-Fast allSat, Looking for solution 306
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 307
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 308
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 309
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 310
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 311
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 312
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 313
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 314
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 315
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 316
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 317
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 318
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s64)
-[GOOD] (assert s81)
-Fast allSat, Looking for solution 318
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 319
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 320
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 321
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 322
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 323
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 324
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 325
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 326
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 327
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 328
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 329
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 330
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s63)
-[GOOD] (assert s82)
-Fast allSat, Looking for solution 330
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 331
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 332
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 333
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 334
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 335
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 336
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 337
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 338
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 339
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 340
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 341
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 342
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s62)
-[GOOD] (assert s83)
-Fast allSat, Looking for solution 342
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 343
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 344
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 345
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 346
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 347
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 348
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 349
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 350
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 351
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 352
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 353
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 354
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s61)
-[GOOD] (assert s84)
-Fast allSat, Looking for solution 354
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 355
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 356
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 357
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 358
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 359
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 360
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 361
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 362
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 363
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 364
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 365
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 366
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s86)
-[GOOD] (assert s85)
-Fast allSat, Looking for solution 366
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 367
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 368
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 369
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 370
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 371
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 372
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 373
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 374
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 375
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 376
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 377
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 14))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 378
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s45)
-[GOOD] (define-fun s90 () Bool (= s0 s38))
-[GOOD] (assert s90)
-Fast allSat, Looking for solution 378
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s46)
-Fast allSat, Looking for solution 379
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s47)
-Fast allSat, Looking for solution 380
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s48)
-Fast allSat, Looking for solution 381
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s49)
-Fast allSat, Looking for solution 382
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s50)
-Fast allSat, Looking for solution 383
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s51)
-Fast allSat, Looking for solution 384
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s52)
-Fast allSat, Looking for solution 385
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s53)
-Fast allSat, Looking for solution 386
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s54)
-Fast allSat, Looking for solution 387
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s55)
-Fast allSat, Looking for solution 388
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s57)
-Fast allSat, Looking for solution 389
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s87)
-Fast allSat, Looking for solution 390
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s56)
-Fast allSat, Looking for solution 391
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s70)
-[GOOD] (assert s73)
-Fast allSat, Looking for solution 391
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 392
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 393
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 394
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 395
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 396
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 397
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 398
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 399
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 400
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 401
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 402
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 403
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s60)
-[GOOD] (assert s89)
-Fast allSat, Looking for solution 403
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 404
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 405
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 406
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 407
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 408
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 409
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 410
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 411
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 412
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 413
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 414
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 415
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s60)
-[GOOD] (assert s59)
-Fast allSat, Looking for solution 415
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 416
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 417
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 418
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 419
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 420
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 421
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 422
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 423
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 424
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 425
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 426
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 427
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s71)
-[GOOD] (assert s74)
-Fast allSat, Looking for solution 427
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 428
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 429
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 430
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 431
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 432
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 433
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 434
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 435
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 436
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 437
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 438
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 439
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s70)
-[GOOD] (assert s75)
-Fast allSat, Looking for solution 439
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 440
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 441
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 442
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 443
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 444
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 445
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 446
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 447
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 448
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 449
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 450
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 451
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s69)
-[GOOD] (assert s76)
-Fast allSat, Looking for solution 451
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 452
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 453
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 454
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 455
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 456
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 457
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 458
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 459
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 460
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 461
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 462
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 463
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s68)
-[GOOD] (assert s77)
-Fast allSat, Looking for solution 463
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 464
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 465
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 466
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 467
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 468
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 469
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 470
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 471
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 472
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 473
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 474
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 475
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s67)
-[GOOD] (assert s78)
-Fast allSat, Looking for solution 475
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 476
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 477
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 478
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 479
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 480
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 481
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 482
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 483
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 484
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 485
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 486
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 487
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s66)
-[GOOD] (assert s79)
-Fast allSat, Looking for solution 487
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 488
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 489
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 490
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 491
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 492
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 493
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 494
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 495
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 496
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 497
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 498
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 499
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s65)
-[GOOD] (assert s80)
-Fast allSat, Looking for solution 499
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 500
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 501
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 502
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 503
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 504
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 505
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 506
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 507
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 508
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 509
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 510
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 511
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s64)
-[GOOD] (assert s81)
-Fast allSat, Looking for solution 511
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 512
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 513
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 514
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 515
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 516
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 517
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 518
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 519
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 520
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 521
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 522
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 523
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s63)
-[GOOD] (assert s82)
-Fast allSat, Looking for solution 523
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 524
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 525
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 526
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 527
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 528
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 529
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 530
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 531
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 532
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 533
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 534
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 535
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s62)
-[GOOD] (assert s83)
-Fast allSat, Looking for solution 535
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 536
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 537
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 538
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 539
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 540
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 541
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 542
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 543
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 544
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 545
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 546
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 547
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s72)
-[GOOD] (assert s90)
-[GOOD] (assert s84)
-Fast allSat, Looking for solution 547
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 548
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 549
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 550
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 551
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 552
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 553
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 554
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 555
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 556
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 557
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 558
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 13))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 559
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s46)
-[GOOD] (define-fun s91 () Bool (= s0 s36))
-[GOOD] (assert s91)
-Fast allSat, Looking for solution 559
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s47)
-Fast allSat, Looking for solution 560
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s48)
-Fast allSat, Looking for solution 561
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s49)
-Fast allSat, Looking for solution 562
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s50)
-Fast allSat, Looking for solution 563
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s51)
-Fast allSat, Looking for solution 564
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s52)
-Fast allSat, Looking for solution 565
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s53)
-Fast allSat, Looking for solution 566
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s54)
-Fast allSat, Looking for solution 567
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s55)
-Fast allSat, Looking for solution 568
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s43)
-Fast allSat, Looking for solution 569
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s57)
-Fast allSat, Looking for solution 570
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s87)
-Fast allSat, Looking for solution 571
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s56)
-Fast allSat, Looking for solution 572
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s70)
-[GOOD] (assert s73)
-Fast allSat, Looking for solution 572
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 573
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 574
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 575
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 576
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 577
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 578
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 579
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 580
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 581
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 582
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 583
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 584
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s61)
-[GOOD] (assert s89)
-Fast allSat, Looking for solution 584
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 585
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 586
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 587
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 588
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 589
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 590
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 591
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 592
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 593
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 594
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 595
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 596
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s61)
-[GOOD] (assert s59)
-Fast allSat, Looking for solution 596
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 597
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 598
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 599
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 600
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 601
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 602
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 603
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 604
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 605
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 606
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 607
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 608
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s61)
-[GOOD] (assert s85)
-Fast allSat, Looking for solution 608
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 609
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 610
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 611
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 612
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 613
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 614
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 615
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 616
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 617
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 618
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 619
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 620
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s71)
-[GOOD] (assert s74)
-Fast allSat, Looking for solution 620
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 621
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 622
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 623
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 624
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 625
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 626
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 627
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 628
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 629
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 630
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 631
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 632
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s70)
-[GOOD] (assert s75)
-Fast allSat, Looking for solution 632
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 633
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 634
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 635
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 636
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 637
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 638
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 639
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 640
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 641
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 642
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 643
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 644
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s69)
-[GOOD] (assert s76)
-Fast allSat, Looking for solution 644
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 645
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 646
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 647
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 648
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 649
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 650
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 651
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 652
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 653
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 654
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 655
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 656
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s68)
-[GOOD] (assert s77)
-Fast allSat, Looking for solution 656
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 657
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 658
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 659
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 660
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 661
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 662
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 663
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 664
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 665
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 666
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 667
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 668
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s67)
-[GOOD] (assert s78)
-Fast allSat, Looking for solution 668
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 669
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 670
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 671
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 672
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 673
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 674
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 675
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 676
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 677
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 678
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 679
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 680
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s66)
-[GOOD] (assert s79)
-Fast allSat, Looking for solution 680
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 681
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 682
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 683
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 684
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 685
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 686
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 687
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 688
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 689
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 690
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 691
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 692
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s65)
-[GOOD] (assert s80)
-Fast allSat, Looking for solution 692
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 693
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 694
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 695
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 696
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 697
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 698
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 699
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 700
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 701
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 702
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 703
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 704
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s64)
-[GOOD] (assert s81)
-Fast allSat, Looking for solution 704
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 705
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 706
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 707
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 708
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 709
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 710
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 711
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 712
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 713
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 714
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 715
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 716
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s63)
-[GOOD] (assert s82)
-Fast allSat, Looking for solution 716
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 717
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 718
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 719
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 720
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 721
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 722
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 723
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 724
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 725
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 726
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 727
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 728
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s58)
-[GOOD] (assert s91)
-[GOOD] (assert s83)
-Fast allSat, Looking for solution 728
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 729
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 730
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 731
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 732
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 733
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 734
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 735
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 736
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 737
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 738
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 739
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 12))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 740
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s47)
-[GOOD] (define-fun s92 () Bool (= s0 s34))
-[GOOD] (assert s92)
-Fast allSat, Looking for solution 740
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s48)
-Fast allSat, Looking for solution 741
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s49)
-Fast allSat, Looking for solution 742
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s50)
-Fast allSat, Looking for solution 743
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s51)
-Fast allSat, Looking for solution 744
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s52)
-Fast allSat, Looking for solution 745
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s53)
-Fast allSat, Looking for solution 746
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s54)
-Fast allSat, Looking for solution 747
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s55)
-Fast allSat, Looking for solution 748
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s56)
-Fast allSat, Looking for solution 749
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s45)
-Fast allSat, Looking for solution 750
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s43)
-Fast allSat, Looking for solution 751
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s57)
-Fast allSat, Looking for solution 752
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s87)
-Fast allSat, Looking for solution 753
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s72)
-[GOOD] (assert s89)
-Fast allSat, Looking for solution 753
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 754
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 755
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 756
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 757
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 758
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 759
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 760
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 761
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 762
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 763
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 764
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 765
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s59)
-Fast allSat, Looking for solution 765
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 766
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 767
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 768
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 769
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 770
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 771
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 772
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 773
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 774
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 775
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 776
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 777
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s85)
-Fast allSat, Looking for solution 777
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 778
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 779
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 780
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 781
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 782
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 783
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 784
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 785
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 786
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 787
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 788
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 789
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s84)
-Fast allSat, Looking for solution 789
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 790
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 791
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 792
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 793
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 794
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 795
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 796
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 797
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 798
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 799
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 800
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 801
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s73)
-Fast allSat, Looking for solution 801
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 802
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 803
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 804
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 805
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 806
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 807
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 808
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 809
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 810
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 811
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 812
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 813
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s74)
-Fast allSat, Looking for solution 813
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 814
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 815
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 816
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 817
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 818
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 819
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 820
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 821
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 822
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 823
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 824
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 825
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s75)
-Fast allSat, Looking for solution 825
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 826
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 827
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 828
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 829
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 830
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 831
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 832
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 833
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 834
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 835
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 836
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 837
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s76)
-Fast allSat, Looking for solution 837
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 838
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 839
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 840
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 841
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 842
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 843
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 844
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 845
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 846
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 847
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 848
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 849
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s77)
-Fast allSat, Looking for solution 849
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 850
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 851
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 852
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 853
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 854
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 855
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 856
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 857
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 858
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 859
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 860
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 861
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s78)
-Fast allSat, Looking for solution 861
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 862
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 863
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 864
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 865
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 866
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 867
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 868
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 869
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 870
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 871
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 872
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 873
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s79)
-Fast allSat, Looking for solution 873
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 874
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 875
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 876
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 877
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 878
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 879
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 880
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 881
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 882
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 883
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 884
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 885
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s80)
-Fast allSat, Looking for solution 885
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 886
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 887
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 888
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 889
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 890
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 891
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 892
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 893
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 894
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 895
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 896
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 897
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s81)
-Fast allSat, Looking for solution 897
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 898
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 899
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 900
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 901
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 902
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 903
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 904
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 905
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 906
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 907
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 908
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 909
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s60)
-[GOOD] (assert s92)
-[GOOD] (assert s82)
-Fast allSat, Looking for solution 909
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 910
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 911
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 912
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 913
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 914
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 915
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 916
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 917
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 918
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 919
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 920
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 11))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 921
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s48)
-[GOOD] (define-fun s93 () Bool (= s0 s32))
-[GOOD] (assert s93)
-Fast allSat, Looking for solution 921
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s49)
-Fast allSat, Looking for solution 922
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s50)
-Fast allSat, Looking for solution 923
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s51)
-Fast allSat, Looking for solution 924
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s52)
-Fast allSat, Looking for solution 925
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s53)
-Fast allSat, Looking for solution 926
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s54)
-Fast allSat, Looking for solution 927
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s55)
-Fast allSat, Looking for solution 928
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s46)
-Fast allSat, Looking for solution 929
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s45)
-Fast allSat, Looking for solution 930
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s43)
-Fast allSat, Looking for solution 931
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s57)
-Fast allSat, Looking for solution 932
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s87)
-Fast allSat, Looking for solution 933
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s56)
-Fast allSat, Looking for solution 934
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s70)
-[GOOD] (assert s73)
-Fast allSat, Looking for solution 934
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 935
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 936
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 937
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 938
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 939
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 940
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 941
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 942
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 943
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 944
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 945
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 946
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s63)
-[GOOD] (assert s89)
-Fast allSat, Looking for solution 946
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 947
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 948
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 949
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 950
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 951
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 952
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 953
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 954
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 955
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 956
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 957
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 958
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s63)
-[GOOD] (assert s59)
-Fast allSat, Looking for solution 958
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 959
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 960
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 961
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 962
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 963
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 964
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 965
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 966
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 967
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 968
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 969
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 970
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s63)
-[GOOD] (assert s85)
-Fast allSat, Looking for solution 970
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 971
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 972
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 973
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 974
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 975
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 976
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 977
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 978
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 979
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 980
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 981
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 982
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s63)
-[GOOD] (assert s84)
-Fast allSat, Looking for solution 982
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 983
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 984
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 985
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 986
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 987
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 988
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 989
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 990
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 991
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 992
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 993
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 994
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s63)
-[GOOD] (assert s83)
-Fast allSat, Looking for solution 994
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 995
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 996
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 997
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 998
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 999
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1000
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1001
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1002
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1003
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1004
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1005
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1006
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s71)
-[GOOD] (assert s74)
-Fast allSat, Looking for solution 1006
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1007
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1008
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1009
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1010
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1011
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1012
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1013
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1014
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1015
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1016
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1017
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1018
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s70)
-[GOOD] (assert s75)
-Fast allSat, Looking for solution 1018
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1019
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1020
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1021
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1022
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1023
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1024
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1025
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1026
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1027
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1028
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1029
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1030
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s69)
-[GOOD] (assert s76)
-Fast allSat, Looking for solution 1030
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1031
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1032
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1033
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1034
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1035
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1036
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1037
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1038
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1039
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1040
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1041
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1042
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s68)
-[GOOD] (assert s77)
-Fast allSat, Looking for solution 1042
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1043
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1044
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1045
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1046
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1047
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1048
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1049
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1050
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1051
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1052
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1053
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1054
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s67)
-[GOOD] (assert s78)
-Fast allSat, Looking for solution 1054
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1055
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1056
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1057
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1058
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1059
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1060
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1061
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1062
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1063
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1064
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1065
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1066
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s66)
-[GOOD] (assert s79)
-Fast allSat, Looking for solution 1066
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1067
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1068
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1069
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1070
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1071
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1072
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1073
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1074
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1075
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1076
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1077
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1078
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s65)
-[GOOD] (assert s80)
-Fast allSat, Looking for solution 1078
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1079
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1080
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1081
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1082
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1083
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1084
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1085
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1086
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1087
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1088
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1089
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1090
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s61)
-[GOOD] (assert s93)
-[GOOD] (assert s81)
-Fast allSat, Looking for solution 1090
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1091
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1092
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1093
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1094
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1095
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1096
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1097
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1098
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1099
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1100
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1101
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 10))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1102
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s49)
-[GOOD] (define-fun s94 () Bool (= s0 s30))
-[GOOD] (assert s94)
-Fast allSat, Looking for solution 1102
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s50)
-Fast allSat, Looking for solution 1103
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s51)
-Fast allSat, Looking for solution 1104
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s52)
-Fast allSat, Looking for solution 1105
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s53)
-Fast allSat, Looking for solution 1106
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s54)
-Fast allSat, Looking for solution 1107
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s55)
-Fast allSat, Looking for solution 1108
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s47)
-Fast allSat, Looking for solution 1109
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s46)
-Fast allSat, Looking for solution 1110
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s45)
-Fast allSat, Looking for solution 1111
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s43)
-Fast allSat, Looking for solution 1112
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s57)
-Fast allSat, Looking for solution 1113
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s87)
-Fast allSat, Looking for solution 1114
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s56)
-Fast allSat, Looking for solution 1115
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s70)
-[GOOD] (assert s73)
-Fast allSat, Looking for solution 1115
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1116
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1117
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1118
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1119
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1120
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1121
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1122
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1123
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1124
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1125
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1126
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1127
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s64)
-[GOOD] (assert s89)
-Fast allSat, Looking for solution 1127
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1128
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1129
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1130
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1131
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1132
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1133
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1134
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1135
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1136
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1137
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1138
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1139
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s64)
-[GOOD] (assert s59)
-Fast allSat, Looking for solution 1139
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1140
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1141
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1142
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1143
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1144
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1145
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1146
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1147
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1148
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1149
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1150
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1151
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s64)
-[GOOD] (assert s85)
-Fast allSat, Looking for solution 1151
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1152
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1153
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1154
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1155
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1156
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1157
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1158
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1159
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1160
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1161
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1162
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1163
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s64)
-[GOOD] (assert s84)
-Fast allSat, Looking for solution 1163
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1164
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1165
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1166
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1167
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1168
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1169
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1170
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1171
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1172
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1173
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1174
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1175
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s64)
-[GOOD] (assert s83)
-Fast allSat, Looking for solution 1175
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1176
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1177
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1178
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1179
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1180
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1181
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1182
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1183
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1184
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1185
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1186
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1187
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s64)
-[GOOD] (assert s82)
-Fast allSat, Looking for solution 1187
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1188
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1189
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1190
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1191
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1192
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1193
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1194
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1195
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1196
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1197
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1198
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1199
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s71)
-[GOOD] (assert s74)
-Fast allSat, Looking for solution 1199
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1200
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1201
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1202
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1203
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1204
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1205
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1206
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1207
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1208
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1209
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1210
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1211
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s70)
-[GOOD] (assert s75)
-Fast allSat, Looking for solution 1211
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1212
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1213
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1214
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1215
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1216
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1217
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1218
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1219
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1220
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1221
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1222
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1223
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s69)
-[GOOD] (assert s76)
-Fast allSat, Looking for solution 1223
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1224
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1225
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1226
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1227
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1228
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1229
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1230
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1231
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1232
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1233
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1234
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1235
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s68)
-[GOOD] (assert s77)
-Fast allSat, Looking for solution 1235
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1236
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1237
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1238
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1239
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1240
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1241
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1242
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1243
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1244
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1245
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1246
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1247
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s67)
-[GOOD] (assert s78)
-Fast allSat, Looking for solution 1247
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1248
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1249
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1250
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1251
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1252
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1253
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1254
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1255
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1256
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1257
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1258
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1259
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s66)
-[GOOD] (assert s79)
-Fast allSat, Looking for solution 1259
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1260
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1261
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1262
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1263
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1264
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1265
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1266
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1267
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1268
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1269
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1270
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1271
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s62)
-[GOOD] (assert s94)
-[GOOD] (assert s80)
-Fast allSat, Looking for solution 1271
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1272
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1273
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1274
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1275
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1276
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1277
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1278
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1279
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1280
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1281
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1282
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 9))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1283
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s50)
-[GOOD] (define-fun s95 () Bool (= s0 s28))
-[GOOD] (assert s95)
-Fast allSat, Looking for solution 1283
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s87)
-Fast allSat, Looking for solution 1284
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s57)
-Fast allSat, Looking for solution 1285
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s43)
-Fast allSat, Looking for solution 1286
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s45)
-Fast allSat, Looking for solution 1287
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s46)
-Fast allSat, Looking for solution 1288
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s47)
-Fast allSat, Looking for solution 1289
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s51)
-Fast allSat, Looking for solution 1290
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s52)
-Fast allSat, Looking for solution 1291
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s53)
-Fast allSat, Looking for solution 1292
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s54)
-Fast allSat, Looking for solution 1293
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s55)
-Fast allSat, Looking for solution 1294
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s48)
-Fast allSat, Looking for solution 1295
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s56)
-Fast allSat, Looking for solution 1296
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s63)
-[GOOD] (assert s73)
-Fast allSat, Looking for solution 1296
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1297
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1298
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1299
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1300
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1301
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1302
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1303
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1304
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1305
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1306
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1307
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1308
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s65)
-[GOOD] (assert s81)
-Fast allSat, Looking for solution 1308
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1309
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1310
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1311
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1312
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1313
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1314
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1315
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1316
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1317
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1318
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1319
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1320
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s71)
-[GOOD] (assert s74)
-Fast allSat, Looking for solution 1320
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1321
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1322
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1323
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1324
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1325
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1326
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1327
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1328
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1329
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1330
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1331
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1332
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s70)
-[GOOD] (assert s75)
-Fast allSat, Looking for solution 1332
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1333
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1334
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1335
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1336
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1337
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1338
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1339
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1340
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1341
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1342
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1343
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1344
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s69)
-[GOOD] (assert s76)
-Fast allSat, Looking for solution 1344
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1345
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1346
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1347
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1348
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1349
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1350
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1351
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1352
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1353
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1354
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1355
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1356
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s68)
-[GOOD] (assert s77)
-Fast allSat, Looking for solution 1356
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1357
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1358
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1359
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1360
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1361
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1362
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1363
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1364
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1365
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1366
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1367
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1368
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s67)
-[GOOD] (assert s78)
-Fast allSat, Looking for solution 1368
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1369
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1370
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1371
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1372
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1373
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1374
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1375
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1376
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1377
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1378
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1379
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1380
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s63)
-[GOOD] (assert s82)
-Fast allSat, Looking for solution 1380
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1381
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1382
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1383
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1384
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1385
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1386
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1387
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1388
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1389
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1390
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1391
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1392
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s62)
-[GOOD] (assert s83)
-Fast allSat, Looking for solution 1392
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1393
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1394
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1395
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1396
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1397
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1398
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1399
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1400
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1401
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1402
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1403
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1404
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s61)
-[GOOD] (assert s84)
-Fast allSat, Looking for solution 1404
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1405
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1406
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1407
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1408
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1409
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1410
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1411
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1412
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1413
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1414
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1415
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1416
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s60)
-[GOOD] (assert s85)
-Fast allSat, Looking for solution 1416
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1417
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1418
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1419
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1420
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1421
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1422
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1423
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1424
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1425
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1426
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1427
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1428
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s58)
-[GOOD] (assert s59)
-Fast allSat, Looking for solution 1428
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1429
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1430
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1431
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1432
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1433
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1434
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1435
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1436
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1437
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1438
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1439
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1440
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s72)
-[GOOD] (assert s89)
-Fast allSat, Looking for solution 1440
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1441
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1442
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1443
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1444
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1445
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1446
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1447
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1448
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1449
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1450
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1451
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1452
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s63)
-[GOOD] (assert s95)
-[GOOD] (assert s79)
-Fast allSat, Looking for solution 1452
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1453
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1454
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1455
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1456
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1457
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1458
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1459
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1460
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1461
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1462
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1463
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 8))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1464
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s51)
-[GOOD] (define-fun s96 () Bool (= s0 s26))
-[GOOD] (assert s96)
-Fast allSat, Looking for solution 1464
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s87)
-Fast allSat, Looking for solution 1465
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s57)
-Fast allSat, Looking for solution 1466
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s43)
-Fast allSat, Looking for solution 1467
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s45)
-Fast allSat, Looking for solution 1468
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s46)
-Fast allSat, Looking for solution 1469
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s47)
-Fast allSat, Looking for solution 1470
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s48)
-Fast allSat, Looking for solution 1471
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s52)
-Fast allSat, Looking for solution 1472
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s53)
-Fast allSat, Looking for solution 1473
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s54)
-Fast allSat, Looking for solution 1474
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s55)
-Fast allSat, Looking for solution 1475
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s49)
-Fast allSat, Looking for solution 1476
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s56)
-Fast allSat, Looking for solution 1477
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s64)
-[GOOD] (assert s73)
-Fast allSat, Looking for solution 1477
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1478
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1479
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1480
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1481
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1482
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1483
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1484
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1485
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1486
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1487
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1488
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1489
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s66)
-[GOOD] (assert s80)
-Fast allSat, Looking for solution 1489
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1490
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1491
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1492
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1493
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1494
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1495
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1496
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1497
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1498
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1499
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1500
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1501
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s71)
-[GOOD] (assert s74)
-Fast allSat, Looking for solution 1501
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1502
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1503
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1504
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1505
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1506
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1507
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1508
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1509
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1510
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1511
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1512
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1513
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s70)
-[GOOD] (assert s75)
-Fast allSat, Looking for solution 1513
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1514
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1515
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1516
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1517
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1518
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1519
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1520
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1521
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1522
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1523
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1524
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1525
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s69)
-[GOOD] (assert s76)
-Fast allSat, Looking for solution 1525
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1526
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1527
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1528
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1529
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1530
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1531
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1532
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1533
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1534
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1535
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1536
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1537
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s68)
-[GOOD] (assert s77)
-Fast allSat, Looking for solution 1537
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1538
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1539
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1540
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1541
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1542
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1543
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1544
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1545
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1546
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1547
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1548
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1549
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s64)
-[GOOD] (assert s81)
-Fast allSat, Looking for solution 1549
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1550
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1551
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1552
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1553
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1554
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1555
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1556
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1557
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1558
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1559
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1560
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1561
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s63)
-[GOOD] (assert s82)
-Fast allSat, Looking for solution 1561
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1562
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1563
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1564
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1565
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1566
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1567
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1568
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1569
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1570
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1571
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1572
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1573
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s62)
-[GOOD] (assert s83)
-Fast allSat, Looking for solution 1573
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1574
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1575
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1576
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1577
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1578
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1579
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1580
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1581
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1582
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1583
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1584
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1585
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s61)
-[GOOD] (assert s84)
-Fast allSat, Looking for solution 1585
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1586
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1587
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1588
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1589
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1590
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1591
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1592
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1593
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1594
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1595
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1596
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1597
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s60)
-[GOOD] (assert s85)
-Fast allSat, Looking for solution 1597
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1598
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1599
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1600
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1601
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1602
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1603
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1604
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1605
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1606
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1607
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1608
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1609
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s58)
-[GOOD] (assert s59)
-Fast allSat, Looking for solution 1609
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1610
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1611
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1612
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1613
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1614
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1615
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1616
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1617
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1618
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1619
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1620
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1621
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s72)
-[GOOD] (assert s89)
-Fast allSat, Looking for solution 1621
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1622
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1623
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1624
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1625
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1626
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1627
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1628
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1629
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1630
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1631
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1632
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1633
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s64)
-[GOOD] (assert s96)
-[GOOD] (assert s78)
-Fast allSat, Looking for solution 1633
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1634
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1635
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1636
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1637
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1638
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1639
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1640
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1641
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1642
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1643
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1644
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 7))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1645
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s52)
-[GOOD] (define-fun s97 () Bool (= s0 s24))
-[GOOD] (assert s97)
-Fast allSat, Looking for solution 1645
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s53)
-Fast allSat, Looking for solution 1646
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s54)
-Fast allSat, Looking for solution 1647
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s55)
-Fast allSat, Looking for solution 1648
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s56)
-Fast allSat, Looking for solution 1649
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s50)
-Fast allSat, Looking for solution 1650
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s49)
-Fast allSat, Looking for solution 1651
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s48)
-Fast allSat, Looking for solution 1652
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s47)
-Fast allSat, Looking for solution 1653
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s46)
-Fast allSat, Looking for solution 1654
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s45)
-Fast allSat, Looking for solution 1655
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s43)
-Fast allSat, Looking for solution 1656
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s57)
-Fast allSat, Looking for solution 1657
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s87)
-Fast allSat, Looking for solution 1658
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s72)
-[GOOD] (assert s89)
-Fast allSat, Looking for solution 1658
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1659
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1660
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1661
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1662
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1663
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1664
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1665
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1666
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1667
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1668
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1669
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1670
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s59)
-Fast allSat, Looking for solution 1670
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1671
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1672
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1673
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1674
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1675
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1676
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1677
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1678
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1679
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1680
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1681
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1682
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s85)
-Fast allSat, Looking for solution 1682
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1683
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1684
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1685
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1686
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1687
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1688
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1689
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1690
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1691
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1692
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1693
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1694
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s84)
-Fast allSat, Looking for solution 1694
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1695
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1696
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1697
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1698
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1699
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1700
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1701
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1702
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1703
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1704
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1705
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1706
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s83)
-Fast allSat, Looking for solution 1706
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1707
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1708
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1709
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1710
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1711
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1712
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1713
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1714
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1715
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1716
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1717
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1718
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s82)
-Fast allSat, Looking for solution 1718
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1719
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1720
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1721
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1722
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1723
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1724
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1725
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1726
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1727
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1728
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1729
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1730
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s81)
-Fast allSat, Looking for solution 1730
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1731
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1732
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1733
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1734
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1735
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1736
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1737
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1738
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1739
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1740
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1741
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1742
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s80)
-Fast allSat, Looking for solution 1742
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1743
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1744
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1745
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1746
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1747
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1748
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1749
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1750
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1751
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1752
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1753
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1754
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s79)
-Fast allSat, Looking for solution 1754
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1755
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1756
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1757
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1758
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1759
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1760
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1761
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1762
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1763
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1764
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1765
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1766
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s73)
-Fast allSat, Looking for solution 1766
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1767
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1768
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1769
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1770
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1771
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1772
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1773
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1774
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1775
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1776
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1777
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1778
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s74)
-Fast allSat, Looking for solution 1778
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1779
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1780
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1781
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1782
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1783
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1784
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1785
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1786
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1787
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1788
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1789
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1790
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s75)
-Fast allSat, Looking for solution 1790
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1791
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1792
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1793
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1794
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1795
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1796
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1797
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1798
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1799
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1800
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1801
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1802
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s76)
-Fast allSat, Looking for solution 1802
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1803
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1804
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1805
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1806
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1807
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1808
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1809
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1810
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 1811
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1812
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1813
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1814
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s65)
-[GOOD] (assert s97)
-[GOOD] (assert s77)
-Fast allSat, Looking for solution 1814
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1815
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1816
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1817
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1818
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1819
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1820
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1821
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1822
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1823
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1824
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1825
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 6))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1826
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s53)
-[GOOD] (define-fun s98 () Bool (= s0 s22))
-[GOOD] (assert s98)
-Fast allSat, Looking for solution 1826
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s54)
-Fast allSat, Looking for solution 1827
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s55)
-Fast allSat, Looking for solution 1828
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s56)
-Fast allSat, Looking for solution 1829
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s51)
-Fast allSat, Looking for solution 1830
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s50)
-Fast allSat, Looking for solution 1831
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s49)
-Fast allSat, Looking for solution 1832
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s48)
-Fast allSat, Looking for solution 1833
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s47)
-Fast allSat, Looking for solution 1834
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s46)
-Fast allSat, Looking for solution 1835
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s45)
-Fast allSat, Looking for solution 1836
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s43)
-Fast allSat, Looking for solution 1837
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s57)
-Fast allSat, Looking for solution 1838
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s87)
-Fast allSat, Looking for solution 1839
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s72)
-[GOOD] (assert s89)
-Fast allSat, Looking for solution 1839
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1840
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1841
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1842
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1843
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1844
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1845
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1846
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1847
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1848
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1849
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1850
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1851
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s59)
-Fast allSat, Looking for solution 1851
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1852
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1853
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1854
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1855
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1856
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1857
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1858
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1859
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1860
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1861
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1862
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1863
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s85)
-Fast allSat, Looking for solution 1863
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1864
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1865
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1866
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1867
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1868
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1869
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1870
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1871
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1872
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1873
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1874
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1875
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s84)
-Fast allSat, Looking for solution 1875
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1876
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1877
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1878
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1879
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1880
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1881
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1882
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1883
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1884
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1885
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1886
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1887
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s83)
-Fast allSat, Looking for solution 1887
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1888
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1889
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1890
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1891
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1892
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1893
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1894
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1895
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1896
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1897
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1898
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1899
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s82)
-Fast allSat, Looking for solution 1899
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1900
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1901
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1902
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1903
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1904
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1905
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1906
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1907
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1908
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1909
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1910
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1911
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s81)
-Fast allSat, Looking for solution 1911
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1912
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1913
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1914
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1915
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1916
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1917
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1918
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1919
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1920
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1921
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1922
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1923
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s80)
-Fast allSat, Looking for solution 1923
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1924
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1925
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1926
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1927
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1928
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1929
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1930
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1931
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1932
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1933
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1934
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1935
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s79)
-Fast allSat, Looking for solution 1935
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1936
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1937
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1938
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1939
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1940
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1941
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1942
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1943
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1944
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1945
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1946
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1947
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s78)
-Fast allSat, Looking for solution 1947
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1948
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1949
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1950
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1951
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1952
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1953
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1954
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1955
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1956
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1957
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1958
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1959
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s73)
-Fast allSat, Looking for solution 1959
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1960
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1961
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1962
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1963
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1964
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1965
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1966
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1967
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1968
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1969
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1970
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1971
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s74)
-Fast allSat, Looking for solution 1971
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1972
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1973
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1974
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1975
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1976
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1977
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1978
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1979
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1980
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1981
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 1982
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1983
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s75)
-Fast allSat, Looking for solution 1983
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 1984
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 1985
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 1986
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 1987
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 1988
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 1989
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 1990
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 1991
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 1992
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1993
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1994
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1995
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s66)
-[GOOD] (assert s98)
-[GOOD] (assert s76)
-Fast allSat, Looking for solution 1995
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 1996
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 1997
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 1998
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 1999
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2000
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2001
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2002
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2003
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2004
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 2005
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2006
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 5))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 2007
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s54)
-[GOOD] (define-fun s99 () Bool (= s0 s20))
-[GOOD] (assert s99)
-Fast allSat, Looking for solution 2007
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s55)
-Fast allSat, Looking for solution 2008
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s52)
-Fast allSat, Looking for solution 2009
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s51)
-Fast allSat, Looking for solution 2010
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s50)
-Fast allSat, Looking for solution 2011
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s49)
-Fast allSat, Looking for solution 2012
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s48)
-Fast allSat, Looking for solution 2013
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s47)
-Fast allSat, Looking for solution 2014
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s46)
-Fast allSat, Looking for solution 2015
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s45)
-Fast allSat, Looking for solution 2016
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s43)
-Fast allSat, Looking for solution 2017
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s57)
-Fast allSat, Looking for solution 2018
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s87)
-Fast allSat, Looking for solution 2019
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s56)
-Fast allSat, Looking for solution 2020
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s70)
-[GOOD] (assert s73)
-Fast allSat, Looking for solution 2020
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 2021
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2022
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2023
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2024
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2025
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2026
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2027
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2028
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2029
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2030
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2031
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 2032
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s69)
-[GOOD] (assert s89)
-Fast allSat, Looking for solution 2032
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2033
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2034
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2035
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2036
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2037
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2038
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2039
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2040
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2041
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2042
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2043
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 2044
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s69)
-[GOOD] (assert s59)
-Fast allSat, Looking for solution 2044
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2045
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2046
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2047
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2048
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2049
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2050
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2051
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2052
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2053
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 2054
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2055
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 2056
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s69)
-[GOOD] (assert s85)
-Fast allSat, Looking for solution 2056
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2057
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2058
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2059
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2060
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2061
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2062
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2063
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2064
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2065
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 2066
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2067
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 2068
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s69)
-[GOOD] (assert s84)
-Fast allSat, Looking for solution 2068
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2069
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2070
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2071
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2072
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2073
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2074
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2075
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2076
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2077
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 2078
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2079
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 2080
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s69)
-[GOOD] (assert s83)
-Fast allSat, Looking for solution 2080
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2081
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2082
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2083
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2084
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2085
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2086
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2087
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2088
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2089
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 2090
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2091
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 2092
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s69)
-[GOOD] (assert s82)
-Fast allSat, Looking for solution 2092
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 2093
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2094
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2095
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2096
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2097
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2098
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2099
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2100
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2101
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2102
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2103
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 2104
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s69)
-[GOOD] (assert s81)
-Fast allSat, Looking for solution 2104
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 2105
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2106
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2107
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2108
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2109
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2110
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2111
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2112
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2113
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2114
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2115
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 2116
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s69)
-[GOOD] (assert s80)
-Fast allSat, Looking for solution 2116
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 2117
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2118
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2119
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2120
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2121
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2122
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2123
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2124
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2125
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2126
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2127
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 2128
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s69)
-[GOOD] (assert s79)
-Fast allSat, Looking for solution 2128
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 2129
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2130
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2131
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2132
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2133
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2134
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2135
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2136
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2137
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2138
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2139
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 2140
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s69)
-[GOOD] (assert s78)
-Fast allSat, Looking for solution 2140
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 2141
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2142
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2143
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2144
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2145
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2146
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2147
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2148
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2149
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2150
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2151
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 2152
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s69)
-[GOOD] (assert s77)
-Fast allSat, Looking for solution 2152
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 2153
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2154
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2155
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2156
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2157
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2158
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2159
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2160
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2161
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2162
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2163
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 2164
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s71)
-[GOOD] (assert s74)
-Fast allSat, Looking for solution 2164
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 2165
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2166
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2167
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2168
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2169
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2170
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2171
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2172
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2173
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2174
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2175
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 2176
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s67)
-[GOOD] (assert s99)
-[GOOD] (assert s75)
-Fast allSat, Looking for solution 2176
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 2177
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2178
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2179
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2180
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2181
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2182
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2183
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2184
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2185
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2186
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2187
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 4))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 2188
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s56)
-[GOOD] (define-fun s100 () Bool (= s0 s18))
-[GOOD] (assert s100)
-Fast allSat, Looking for solution 2188
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s54)
-Fast allSat, Looking for solution 2189
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s53)
-Fast allSat, Looking for solution 2190
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s52)
-Fast allSat, Looking for solution 2191
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s51)
-Fast allSat, Looking for solution 2192
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s50)
-Fast allSat, Looking for solution 2193
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s49)
-Fast allSat, Looking for solution 2194
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s48)
-Fast allSat, Looking for solution 2195
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s47)
-Fast allSat, Looking for solution 2196
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s46)
-Fast allSat, Looking for solution 2197
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s45)
-Fast allSat, Looking for solution 2198
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s43)
-Fast allSat, Looking for solution 2199
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s57)
-Fast allSat, Looking for solution 2200
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s87)
-Fast allSat, Looking for solution 2201
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s71)
-[GOOD] (assert s89)
-Fast allSat, Looking for solution 2201
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 2202
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2203
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2204
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2205
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2206
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2207
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2208
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2209
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2210
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2211
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2212
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2213
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s71)
-[GOOD] (assert s59)
-Fast allSat, Looking for solution 2213
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2214
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2215
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2216
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2217
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2218
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2219
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2220
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2221
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2222
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2223
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 2224
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 2225
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s71)
-[GOOD] (assert s85)
-Fast allSat, Looking for solution 2225
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2226
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 2227
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2228
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2229
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2230
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2231
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2232
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2233
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2234
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2235
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2236
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 2237
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s71)
-[GOOD] (assert s84)
-Fast allSat, Looking for solution 2237
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2238
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2239
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2240
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2241
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2242
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2243
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2244
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2245
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 2246
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2247
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2248
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 2249
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s71)
-[GOOD] (assert s83)
-Fast allSat, Looking for solution 2249
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 2250
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2251
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2252
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2253
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2254
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2255
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2256
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2257
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2258
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2259
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2260
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 2261
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s71)
-[GOOD] (assert s82)
-Fast allSat, Looking for solution 2261
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2262
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2263
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2264
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2265
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2266
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2267
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 2268
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2269
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2270
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2271
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2272
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 2273
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s71)
-[GOOD] (assert s81)
-Fast allSat, Looking for solution 2273
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 2274
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2275
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2276
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2277
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2278
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2279
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2280
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2281
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2282
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2283
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2284
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 2285
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s71)
-[GOOD] (assert s80)
-Fast allSat, Looking for solution 2285
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2286
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2287
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2288
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2289
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 2290
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2291
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2292
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2293
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2294
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2295
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2296
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 2297
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s71)
-[GOOD] (assert s79)
-Fast allSat, Looking for solution 2297
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 2298
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2299
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2300
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2301
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2302
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2303
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2304
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2305
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2306
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2307
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2308
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 2309
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s71)
-[GOOD] (assert s78)
-Fast allSat, Looking for solution 2309
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2310
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2311
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 2312
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2313
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2314
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2315
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2316
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2317
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2318
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2319
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2320
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 2321
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s71)
-[GOOD] (assert s77)
-Fast allSat, Looking for solution 2321
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 2322
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2323
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2324
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2325
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2326
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2327
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2328
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2329
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2330
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2331
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2332
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 2333
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s71)
-[GOOD] (assert s76)
-Fast allSat, Looking for solution 2333
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 2334
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2335
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2336
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2337
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2338
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2339
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2340
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2341
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2342
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2343
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2344
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 2345
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s71)
-[GOOD] (assert s75)
-Fast allSat, Looking for solution 2345
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 2346
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2347
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2348
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2349
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2350
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2351
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2352
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2353
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2354
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2355
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2356
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2357
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s69)
-[GOOD] (assert s100)
-[GOOD] (assert s73)
-Fast allSat, Looking for solution 2357
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2358
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2359
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2360
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2361
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2362
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2363
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2364
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2365
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2366
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2367
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2368
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 2))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 2369
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s56)
-[GOOD] (define-fun s101 () Bool (= s0 s16))
-[GOOD] (assert s101)
-Fast allSat, Looking for solution 2369
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s55)
-Fast allSat, Looking for solution 2370
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s53)
-Fast allSat, Looking for solution 2371
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s52)
-Fast allSat, Looking for solution 2372
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s51)
-Fast allSat, Looking for solution 2373
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s50)
-Fast allSat, Looking for solution 2374
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s49)
-Fast allSat, Looking for solution 2375
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s48)
-Fast allSat, Looking for solution 2376
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s47)
-Fast allSat, Looking for solution 2377
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s46)
-Fast allSat, Looking for solution 2378
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s45)
-Fast allSat, Looking for solution 2379
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s43)
-Fast allSat, Looking for solution 2380
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s57)
-Fast allSat, Looking for solution 2381
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s87)
-Fast allSat, Looking for solution 2382
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s72)
-[GOOD] (assert s89)
-Fast allSat, Looking for solution 2382
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2383
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2384
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2385
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2386
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2387
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2388
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2389
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2390
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2391
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2392
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2393
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 2394
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s59)
-Fast allSat, Looking for solution 2394
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2395
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 2396
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2397
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2398
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2399
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2400
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2401
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2402
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2403
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2404
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2405
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2406
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s85)
-Fast allSat, Looking for solution 2406
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2407
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2408
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2409
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2410
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2411
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2412
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2413
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2414
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2415
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2416
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2417
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 2418
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s84)
-Fast allSat, Looking for solution 2418
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2419
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 2420
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2421
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2422
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2423
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2424
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2425
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2426
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2427
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2428
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2429
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2430
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s83)
-Fast allSat, Looking for solution 2430
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2431
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2432
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2433
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2434
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2435
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2436
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2437
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2438
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2439
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2440
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2441
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 2442
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s82)
-Fast allSat, Looking for solution 2442
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2443
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 2444
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2445
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2446
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2447
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2448
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2449
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2450
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2451
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2452
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2453
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2454
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s81)
-Fast allSat, Looking for solution 2454
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2455
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2456
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2457
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2458
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2459
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2460
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2461
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2462
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2463
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2464
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2465
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 2466
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s80)
-Fast allSat, Looking for solution 2466
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2467
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 2468
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2469
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2470
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2471
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2472
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2473
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2474
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2475
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2476
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2477
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2478
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s79)
-Fast allSat, Looking for solution 2478
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2479
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2480
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2481
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2482
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2483
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2484
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2485
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2486
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2487
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2488
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2489
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 2490
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s78)
-Fast allSat, Looking for solution 2490
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2491
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 2492
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2493
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2494
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2495
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2496
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2497
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2498
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2499
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2500
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2501
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2502
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s77)
-Fast allSat, Looking for solution 2502
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2503
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2504
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2505
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2506
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2507
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2508
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2509
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2510
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2511
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2512
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2513
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 2514
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s76)
-Fast allSat, Looking for solution 2514
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2515
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 2516
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2517
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2518
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2519
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2520
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2521
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2522
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2523
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2524
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2525
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2526
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s74)
-Fast allSat, Looking for solution 2526
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2527
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2528
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2529
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2530
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2531
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2532
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2533
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2534
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2535
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2536
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2537
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 1))
-[GOOD] (push 1)
-[GOOD] (assert s71)
-Fast allSat, Looking for solution 2538
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s70)
-[GOOD] (assert s101)
-[GOOD] (assert s73)
-Fast allSat, Looking for solution 2538
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2539
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2540
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2541
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2542
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2543
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2544
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2545
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2546
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2547
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2548
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2549
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 3))
-[SEND] (get-value (s1))
-[RECV] ((s1 1))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s88)
-Fast allSat, Looking for solution 2550
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s55)
-[GOOD] (define-fun s102 () Bool (= s0 s3))
-[GOOD] (assert s102)
-Fast allSat, Looking for solution 2550
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s54)
-Fast allSat, Looking for solution 2551
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s53)
-Fast allSat, Looking for solution 2552
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s52)
-Fast allSat, Looking for solution 2553
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s51)
-Fast allSat, Looking for solution 2554
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s50)
-Fast allSat, Looking for solution 2555
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s49)
-Fast allSat, Looking for solution 2556
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s48)
-Fast allSat, Looking for solution 2557
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s47)
-Fast allSat, Looking for solution 2558
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s46)
-Fast allSat, Looking for solution 2559
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s45)
-Fast allSat, Looking for solution 2560
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s43)
-Fast allSat, Looking for solution 2561
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 15))
-[GOOD] (push 1)
-[GOOD] (assert s57)
-Fast allSat, Looking for solution 2562
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s87)
-Fast allSat, Looking for solution 2563
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s72)
-[GOOD] (assert s89)
-Fast allSat, Looking for solution 2563
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2564
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2565
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2566
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2567
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2568
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2569
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2570
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2571
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2572
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2573
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 2574
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 15))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2575
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s59)
-Fast allSat, Looking for solution 2575
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2576
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 2577
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2578
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2579
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2580
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2581
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2582
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2583
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2584
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2585
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2586
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 14))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2587
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s85)
-Fast allSat, Looking for solution 2587
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2588
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2589
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2590
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2591
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2592
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2593
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2594
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2595
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2596
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2597
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 2598
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 13))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2599
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s84)
-Fast allSat, Looking for solution 2599
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2600
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 2601
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2602
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2603
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2604
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2605
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2606
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2607
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2608
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2609
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2610
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 12))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2611
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s83)
-Fast allSat, Looking for solution 2611
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2612
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2613
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2614
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2615
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2616
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2617
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2618
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 2619
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2620
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2621
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2622
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 11))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2623
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s82)
-Fast allSat, Looking for solution 2623
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2624
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2625
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2626
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2627
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2628
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2629
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 2630
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2631
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2632
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2633
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2634
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 10))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2635
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s81)
-Fast allSat, Looking for solution 2635
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2636
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2637
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2638
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2639
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2640
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 2641
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2642
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2643
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2644
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2645
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2646
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 9))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2647
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s80)
-Fast allSat, Looking for solution 2647
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2648
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2649
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2650
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2651
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 2652
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2653
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2654
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2655
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2656
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2657
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2658
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 8))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2659
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s79)
-Fast allSat, Looking for solution 2659
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2660
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2661
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2662
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 2663
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2664
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2665
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2666
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2667
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2668
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2669
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2670
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 7))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2671
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s78)
-Fast allSat, Looking for solution 2671
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2672
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2673
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 2674
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2675
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2676
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2677
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2678
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2679
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2680
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2681
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2682
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 6))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2683
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s77)
-Fast allSat, Looking for solution 2683
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2684
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 2685
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2686
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2687
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2688
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2689
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2690
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2691
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2692
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2693
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2694
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 5))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2695
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s76)
-Fast allSat, Looking for solution 2695
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 3))
-[GOOD] (push 1)
-[GOOD] (assert s69)
-Fast allSat, Looking for solution 2696
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2697
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2698
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2699
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2700
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2701
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2702
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2703
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2704
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2705
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2706
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 4))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2707
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s88)
-[GOOD] (assert s75)
-Fast allSat, Looking for solution 2707
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 2))
-[GOOD] (push 1)
-[GOOD] (assert s70)
-Fast allSat, Looking for solution 2708
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2709
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2710
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2711
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2712
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2713
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2714
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2715
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2716
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2717
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2718
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 3))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
-Fast allSat, Looking for solution 2719
-[SEND] (check-sat)
-[RECV] unsat
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (pop 1)
-[GOOD] (push 1)
-[GOOD] (assert s69)
-[GOOD] (assert s102)
-[GOOD] (assert s74)
-Fast allSat, Looking for solution 2719
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 4))
-[GOOD] (push 1)
-[GOOD] (assert s68)
-Fast allSat, Looking for solution 2720
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 5))
-[GOOD] (push 1)
-[GOOD] (assert s67)
-Fast allSat, Looking for solution 2721
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 6))
-[GOOD] (push 1)
-[GOOD] (assert s66)
-Fast allSat, Looking for solution 2722
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 7))
-[GOOD] (push 1)
-[GOOD] (assert s65)
-Fast allSat, Looking for solution 2723
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 8))
-[GOOD] (push 1)
-[GOOD] (assert s64)
-Fast allSat, Looking for solution 2724
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 9))
-[GOOD] (push 1)
-[GOOD] (assert s63)
-Fast allSat, Looking for solution 2725
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 10))
-[GOOD] (push 1)
-[GOOD] (assert s62)
-Fast allSat, Looking for solution 2726
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 11))
-[GOOD] (push 1)
-[GOOD] (assert s61)
-Fast allSat, Looking for solution 2727
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 12))
-[GOOD] (push 1)
-[GOOD] (assert s60)
-Fast allSat, Looking for solution 2728
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 13))
-[GOOD] (push 1)
-[GOOD] (assert s58)
-Fast allSat, Looking for solution 2729
-[SEND] (check-sat)
-[RECV] sat
-[SEND] (get-value (s0))
-[RECV] ((s0 1))
-[SEND] (get-value (s1))
-[RECV] ((s1 2))
-[SEND] (get-value (s2))
-[RECV] ((s2 14))
-[GOOD] (push 1)
-[GOOD] (assert s72)
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] (define-fun s5 () Int 15)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "x"
+[GOOD] (declare-fun s1 () Int) ; tracks user variable "y"
+[GOOD] (declare-fun s2 () Int) ; tracks user variable "z"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (>= s0 s3))
+[GOOD] (define-fun s6 () Bool (<= s0 s5))
+[GOOD] (define-fun s7 () Bool (and s4 s6))
+[GOOD] (define-fun s8 () Bool (>= s1 s3))
+[GOOD] (define-fun s9 () Bool (<= s1 s5))
+[GOOD] (define-fun s10 () Bool (and s8 s9))
+[GOOD] (define-fun s11 () Bool (>= s2 s3))
+[GOOD] (define-fun s12 () Bool (<= s2 s5))
+[GOOD] (define-fun s13 () Bool (and s11 s12))
+[GOOD] (define-fun s14 () Bool (distinct s0 s1 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s7)
+[GOOD] (assert s10)
+[GOOD] (assert s13)
+[GOOD] (assert s14)
+*** Checking Satisfiability, all solutions..
+Fast allSat, Looking for solution 1
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (define-fun s15 () Bool (distinct s0 s3))
+[GOOD] (assert s15)
+Fast allSat, Looking for solution 2
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (define-fun s16 () Int 2)
+[GOOD] (define-fun s17 () Bool (distinct s0 s16))
+[GOOD] (assert s17)
+Fast allSat, Looking for solution 3
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (define-fun s18 () Int 3)
+[GOOD] (define-fun s19 () Bool (distinct s0 s18))
+[GOOD] (assert s19)
+Fast allSat, Looking for solution 4
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (define-fun s20 () Int 4)
+[GOOD] (define-fun s21 () Bool (distinct s0 s20))
+[GOOD] (assert s21)
+Fast allSat, Looking for solution 5
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (define-fun s22 () Int 5)
+[GOOD] (define-fun s23 () Bool (distinct s0 s22))
+[GOOD] (assert s23)
+Fast allSat, Looking for solution 6
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (define-fun s24 () Int 6)
+[GOOD] (define-fun s25 () Bool (distinct s0 s24))
+[GOOD] (assert s25)
+Fast allSat, Looking for solution 7
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (define-fun s26 () Int 7)
+[GOOD] (define-fun s27 () Bool (distinct s0 s26))
+[GOOD] (assert s27)
+Fast allSat, Looking for solution 8
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (define-fun s28 () Int 8)
+[GOOD] (define-fun s29 () Bool (distinct s0 s28))
+[GOOD] (assert s29)
+Fast allSat, Looking for solution 9
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (define-fun s30 () Int 9)
+[GOOD] (define-fun s31 () Bool (distinct s0 s30))
+[GOOD] (assert s31)
+Fast allSat, Looking for solution 10
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (define-fun s32 () Int 10)
+[GOOD] (define-fun s33 () Bool (distinct s0 s32))
+[GOOD] (assert s33)
+Fast allSat, Looking for solution 11
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (define-fun s34 () Int 11)
+[GOOD] (define-fun s35 () Bool (distinct s0 s34))
+[GOOD] (assert s35)
+Fast allSat, Looking for solution 12
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (define-fun s36 () Int 12)
+[GOOD] (define-fun s37 () Bool (distinct s0 s36))
+[GOOD] (assert s37)
+Fast allSat, Looking for solution 13
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (define-fun s38 () Int 13)
+[GOOD] (define-fun s39 () Bool (distinct s0 s38))
+[GOOD] (assert s39)
+Fast allSat, Looking for solution 14
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (define-fun s40 () Int 14)
+[GOOD] (define-fun s41 () Bool (distinct s0 s40))
+[GOOD] (assert s41)
+Fast allSat, Looking for solution 15
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (define-fun s42 () Bool (distinct s0 s5))
+[GOOD] (assert s42)
+Fast allSat, Looking for solution 16
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (define-fun s43 () Bool (distinct s1 s40))
+[GOOD] (assert s43)
+[GOOD] (define-fun s44 () Bool (= s0 s5))
+[GOOD] (assert s44)
+Fast allSat, Looking for solution 16
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (define-fun s45 () Bool (distinct s1 s38))
+[GOOD] (assert s45)
+Fast allSat, Looking for solution 17
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (define-fun s46 () Bool (distinct s1 s36))
+[GOOD] (assert s46)
+Fast allSat, Looking for solution 18
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (define-fun s47 () Bool (distinct s1 s34))
+[GOOD] (assert s47)
+Fast allSat, Looking for solution 19
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (define-fun s48 () Bool (distinct s1 s32))
+[GOOD] (assert s48)
+Fast allSat, Looking for solution 20
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (define-fun s49 () Bool (distinct s1 s30))
+[GOOD] (assert s49)
+Fast allSat, Looking for solution 21
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (define-fun s50 () Bool (distinct s1 s28))
+[GOOD] (assert s50)
+Fast allSat, Looking for solution 22
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (define-fun s51 () Bool (distinct s1 s26))
+[GOOD] (assert s51)
+Fast allSat, Looking for solution 23
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (define-fun s52 () Bool (distinct s1 s24))
+[GOOD] (assert s52)
+Fast allSat, Looking for solution 24
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (define-fun s53 () Bool (distinct s1 s22))
+[GOOD] (assert s53)
+Fast allSat, Looking for solution 25
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (define-fun s54 () Bool (distinct s1 s20))
+[GOOD] (assert s54)
+Fast allSat, Looking for solution 26
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (define-fun s55 () Bool (distinct s1 s18))
+[GOOD] (assert s55)
+Fast allSat, Looking for solution 27
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (define-fun s56 () Bool (distinct s1 s16))
+[GOOD] (assert s56)
+Fast allSat, Looking for solution 28
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (define-fun s57 () Bool (distinct s1 s3))
+[GOOD] (assert s57)
+Fast allSat, Looking for solution 29
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (define-fun s58 () Bool (distinct s2 s16))
+[GOOD] (assert s58)
+[GOOD] (define-fun s59 () Bool (= s1 s3))
+[GOOD] (assert s59)
+Fast allSat, Looking for solution 29
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (define-fun s60 () Bool (distinct s2 s18))
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 30
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (define-fun s61 () Bool (distinct s2 s20))
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 31
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (define-fun s62 () Bool (distinct s2 s22))
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 32
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (define-fun s63 () Bool (distinct s2 s24))
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 33
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (define-fun s64 () Bool (distinct s2 s26))
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 34
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (define-fun s65 () Bool (distinct s2 s28))
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 35
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (define-fun s66 () Bool (distinct s2 s30))
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 36
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (define-fun s67 () Bool (distinct s2 s32))
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 37
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (define-fun s68 () Bool (distinct s2 s34))
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 38
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (define-fun s69 () Bool (distinct s2 s36))
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 39
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (define-fun s70 () Bool (distinct s2 s38))
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 40
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (define-fun s71 () Bool (distinct s2 s40))
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 41
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (define-fun s72 () Bool (distinct s2 s3))
+[GOOD] (assert s72)
+[GOOD] (define-fun s73 () Bool (= s1 s16))
+[GOOD] (assert s73)
+Fast allSat, Looking for solution 41
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 42
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 43
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 44
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 45
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 46
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 47
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 48
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 49
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 50
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 51
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 52
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 53
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s58)
+[GOOD] (define-fun s74 () Bool (= s1 s18))
+[GOOD] (assert s74)
+Fast allSat, Looking for solution 53
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 54
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 55
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 56
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 57
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 58
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 59
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 60
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 61
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 62
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 63
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 64
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 65
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s60)
+[GOOD] (define-fun s75 () Bool (= s1 s20))
+[GOOD] (assert s75)
+Fast allSat, Looking for solution 65
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 66
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 67
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 68
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 69
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 70
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 71
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 72
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 73
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 74
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 75
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 76
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 77
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s61)
+[GOOD] (define-fun s76 () Bool (= s1 s22))
+[GOOD] (assert s76)
+Fast allSat, Looking for solution 77
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 78
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 79
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 80
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 81
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 82
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 83
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 84
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 85
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 86
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 87
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 88
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 89
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s62)
+[GOOD] (define-fun s77 () Bool (= s1 s24))
+[GOOD] (assert s77)
+Fast allSat, Looking for solution 89
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 90
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 91
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 92
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 93
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 94
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 95
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 96
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 97
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 98
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 99
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 100
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 101
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s63)
+[GOOD] (define-fun s78 () Bool (= s1 s26))
+[GOOD] (assert s78)
+Fast allSat, Looking for solution 101
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 102
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 103
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 104
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 105
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 106
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 107
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 108
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 109
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 110
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 111
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 112
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 113
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s64)
+[GOOD] (define-fun s79 () Bool (= s1 s28))
+[GOOD] (assert s79)
+Fast allSat, Looking for solution 113
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 114
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 115
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 116
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 117
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 118
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 119
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 120
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 121
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 122
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 123
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 124
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 125
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s65)
+[GOOD] (define-fun s80 () Bool (= s1 s30))
+[GOOD] (assert s80)
+Fast allSat, Looking for solution 125
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 126
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 127
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 128
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 129
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 130
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 131
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 132
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 133
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 134
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 135
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 136
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 137
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s66)
+[GOOD] (define-fun s81 () Bool (= s1 s32))
+[GOOD] (assert s81)
+Fast allSat, Looking for solution 137
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 138
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 139
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 140
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 141
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 142
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 143
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 144
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 145
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 146
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 147
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 148
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 149
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s67)
+[GOOD] (define-fun s82 () Bool (= s1 s34))
+[GOOD] (assert s82)
+Fast allSat, Looking for solution 149
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 150
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 151
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 152
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 153
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 154
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 155
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 156
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 157
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 158
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 159
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 160
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 161
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s68)
+[GOOD] (define-fun s83 () Bool (= s1 s36))
+[GOOD] (assert s83)
+Fast allSat, Looking for solution 161
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 162
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 163
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 164
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 165
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 166
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 167
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 168
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 169
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 170
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 171
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 172
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 173
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s69)
+[GOOD] (define-fun s84 () Bool (= s1 s38))
+[GOOD] (assert s84)
+Fast allSat, Looking for solution 173
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 174
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 175
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 176
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 177
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 178
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 179
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 180
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 181
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 182
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 183
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 184
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 185
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s70)
+[GOOD] (assert s44)
+[GOOD] (define-fun s85 () Bool (= s1 s40))
+[GOOD] (assert s85)
+Fast allSat, Looking for solution 185
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 186
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 187
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 188
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 189
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 190
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 191
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 192
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 193
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 194
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 195
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 196
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 15))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 197
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (define-fun s86 () Bool (distinct s1 s5))
+[GOOD] (assert s86)
+[GOOD] (define-fun s87 () Bool (= s0 s40))
+[GOOD] (assert s87)
+Fast allSat, Looking for solution 197
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s45)
+Fast allSat, Looking for solution 198
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s46)
+Fast allSat, Looking for solution 199
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s47)
+Fast allSat, Looking for solution 200
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s48)
+Fast allSat, Looking for solution 201
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s49)
+Fast allSat, Looking for solution 202
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s50)
+Fast allSat, Looking for solution 203
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s51)
+Fast allSat, Looking for solution 204
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s52)
+Fast allSat, Looking for solution 205
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s53)
+Fast allSat, Looking for solution 206
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s54)
+Fast allSat, Looking for solution 207
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s55)
+Fast allSat, Looking for solution 208
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s56)
+Fast allSat, Looking for solution 209
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s57)
+Fast allSat, Looking for solution 210
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s58)
+[GOOD] (assert s59)
+Fast allSat, Looking for solution 210
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 211
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 212
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 213
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 214
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 215
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 216
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 217
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 218
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 219
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 220
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 221
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (define-fun s88 () Bool (distinct s2 s5))
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 222
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s72)
+[GOOD] (assert s73)
+Fast allSat, Looking for solution 222
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 223
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 224
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 225
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 226
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 227
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 228
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 229
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 230
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 231
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 232
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 233
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 234
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s58)
+[GOOD] (assert s74)
+Fast allSat, Looking for solution 234
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 235
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 236
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 237
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 238
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 239
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 240
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 241
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 242
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 243
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 244
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 245
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 246
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s60)
+[GOOD] (assert s75)
+Fast allSat, Looking for solution 246
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 247
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 248
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 249
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 250
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 251
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 252
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 253
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 254
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 255
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 256
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 257
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 258
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s61)
+[GOOD] (assert s76)
+Fast allSat, Looking for solution 258
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 259
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 260
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 261
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 262
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 263
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 264
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 265
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 266
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 267
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 268
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 269
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 270
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s62)
+[GOOD] (assert s77)
+Fast allSat, Looking for solution 270
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 271
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 272
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 273
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 274
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 275
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 276
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 277
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 278
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 279
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 280
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 281
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 282
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s63)
+[GOOD] (assert s78)
+Fast allSat, Looking for solution 282
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 283
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 284
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 285
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 286
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 287
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 288
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 289
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 290
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 291
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 292
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 293
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 294
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s64)
+[GOOD] (assert s79)
+Fast allSat, Looking for solution 294
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 295
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 296
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 297
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 298
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 299
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 300
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 301
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 302
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 303
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 304
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 305
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 306
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s65)
+[GOOD] (assert s80)
+Fast allSat, Looking for solution 306
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 307
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 308
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 309
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 310
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 311
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 312
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 313
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 314
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 315
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 316
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 317
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 318
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s66)
+[GOOD] (assert s81)
+Fast allSat, Looking for solution 318
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 319
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 320
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 321
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 322
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 323
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 324
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 325
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 326
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 327
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 328
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 329
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 330
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s67)
+[GOOD] (assert s82)
+Fast allSat, Looking for solution 330
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 331
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 332
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 333
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 334
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 335
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 336
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 337
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 338
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 339
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 340
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 341
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 342
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s68)
+[GOOD] (assert s83)
+Fast allSat, Looking for solution 342
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 343
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 344
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 345
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 346
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 347
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 348
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 349
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 350
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 351
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 352
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 353
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 354
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s69)
+[GOOD] (assert s84)
+Fast allSat, Looking for solution 354
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 355
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 356
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 357
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 358
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 359
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 360
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 361
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 362
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 363
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 364
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 365
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 366
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s70)
+[GOOD] (assert s87)
+[GOOD] (define-fun s89 () Bool (= s1 s5))
+[GOOD] (assert s89)
+Fast allSat, Looking for solution 366
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 367
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 368
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 369
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 370
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 371
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 372
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 373
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 374
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 375
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 376
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 377
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 14))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 378
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s43)
+[GOOD] (define-fun s90 () Bool (= s0 s38))
+[GOOD] (assert s90)
+Fast allSat, Looking for solution 378
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s86)
+Fast allSat, Looking for solution 379
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s46)
+Fast allSat, Looking for solution 380
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s47)
+Fast allSat, Looking for solution 381
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s48)
+Fast allSat, Looking for solution 382
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s49)
+Fast allSat, Looking for solution 383
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s50)
+Fast allSat, Looking for solution 384
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s51)
+Fast allSat, Looking for solution 385
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s52)
+Fast allSat, Looking for solution 386
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s53)
+Fast allSat, Looking for solution 387
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s54)
+Fast allSat, Looking for solution 388
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s55)
+Fast allSat, Looking for solution 389
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s56)
+Fast allSat, Looking for solution 390
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s57)
+Fast allSat, Looking for solution 391
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s59)
+Fast allSat, Looking for solution 391
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 392
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 393
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 394
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 395
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 396
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 397
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 398
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 399
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 400
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 401
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 402
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 403
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s72)
+[GOOD] (assert s73)
+Fast allSat, Looking for solution 403
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 404
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 405
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 406
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 407
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 408
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 409
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 410
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 411
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 412
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 413
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 414
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 415
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s58)
+[GOOD] (assert s74)
+Fast allSat, Looking for solution 415
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 416
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 417
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 418
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 419
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 420
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 421
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 422
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 423
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 424
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 425
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 426
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 427
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s60)
+[GOOD] (assert s75)
+Fast allSat, Looking for solution 427
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 428
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 429
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 430
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 431
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 432
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 433
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 434
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 435
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 436
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 437
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 438
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 439
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s61)
+[GOOD] (assert s76)
+Fast allSat, Looking for solution 439
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 440
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 441
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 442
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 443
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 444
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 445
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 446
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 447
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 448
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 449
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 450
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 451
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s62)
+[GOOD] (assert s77)
+Fast allSat, Looking for solution 451
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 452
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 453
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 454
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 455
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 456
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 457
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 458
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 459
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 460
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 461
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 462
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 463
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s63)
+[GOOD] (assert s78)
+Fast allSat, Looking for solution 463
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 464
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 465
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 466
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 467
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 468
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 469
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 470
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 471
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 472
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 473
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 474
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 475
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s63)
+[GOOD] (assert s79)
+Fast allSat, Looking for solution 475
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 476
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 477
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 478
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 479
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 480
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 481
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 482
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 483
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 484
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 485
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 486
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 487
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s63)
+[GOOD] (assert s80)
+Fast allSat, Looking for solution 487
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 488
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 489
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 490
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 491
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 492
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 493
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 494
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 495
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 496
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 497
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 498
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 499
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s63)
+[GOOD] (assert s81)
+Fast allSat, Looking for solution 499
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 500
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 501
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 502
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 503
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 504
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 505
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 506
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 507
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 508
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 509
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 510
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 511
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s63)
+[GOOD] (assert s82)
+Fast allSat, Looking for solution 511
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 512
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 513
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 514
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 515
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 516
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 517
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 518
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 519
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 520
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 521
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 522
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 523
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s63)
+[GOOD] (assert s83)
+Fast allSat, Looking for solution 523
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 524
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 525
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 526
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 527
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 528
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 529
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 530
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 531
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 532
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 533
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 534
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 535
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s63)
+[GOOD] (assert s89)
+Fast allSat, Looking for solution 535
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 536
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 537
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 538
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 539
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 540
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 541
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 542
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 543
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 544
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 545
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 546
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 547
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s88)
+[GOOD] (assert s90)
+[GOOD] (assert s85)
+Fast allSat, Looking for solution 547
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 548
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 549
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 550
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 551
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 552
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 553
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 554
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 555
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 556
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 557
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 558
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 13))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 559
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s45)
+[GOOD] (define-fun s91 () Bool (= s0 s36))
+[GOOD] (assert s91)
+Fast allSat, Looking for solution 559
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s43)
+Fast allSat, Looking for solution 560
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s86)
+Fast allSat, Looking for solution 561
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s47)
+Fast allSat, Looking for solution 562
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s48)
+Fast allSat, Looking for solution 563
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s49)
+Fast allSat, Looking for solution 564
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s50)
+Fast allSat, Looking for solution 565
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s51)
+Fast allSat, Looking for solution 566
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s52)
+Fast allSat, Looking for solution 567
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s53)
+Fast allSat, Looking for solution 568
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s54)
+Fast allSat, Looking for solution 569
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s55)
+Fast allSat, Looking for solution 570
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s56)
+Fast allSat, Looking for solution 571
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s57)
+Fast allSat, Looking for solution 572
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s58)
+[GOOD] (assert s59)
+Fast allSat, Looking for solution 572
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 573
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 574
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 575
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 576
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 577
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 578
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 579
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 580
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 581
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 582
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 583
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 584
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s72)
+[GOOD] (assert s73)
+Fast allSat, Looking for solution 584
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 585
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 586
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 587
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 588
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 589
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 590
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 591
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 592
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 593
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 594
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 595
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 596
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s58)
+[GOOD] (assert s74)
+Fast allSat, Looking for solution 596
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 597
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 598
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 599
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 600
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 601
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 602
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 603
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 604
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 605
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 606
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 607
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 608
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s60)
+[GOOD] (assert s75)
+Fast allSat, Looking for solution 608
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 609
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 610
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 611
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 612
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 613
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 614
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 615
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 616
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 617
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 618
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 619
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 620
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s61)
+[GOOD] (assert s76)
+Fast allSat, Looking for solution 620
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 621
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 622
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 623
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 624
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 625
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 626
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 627
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 628
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 629
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 630
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 631
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 632
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s62)
+[GOOD] (assert s77)
+Fast allSat, Looking for solution 632
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 633
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 634
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 635
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 636
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 637
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 638
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 639
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 640
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 641
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 642
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 643
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 644
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s63)
+[GOOD] (assert s78)
+Fast allSat, Looking for solution 644
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 645
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 646
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 647
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 648
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 649
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 650
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 651
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 652
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 653
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 654
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 655
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 656
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s64)
+[GOOD] (assert s79)
+Fast allSat, Looking for solution 656
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 657
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 658
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 659
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 660
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 661
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 662
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 663
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 664
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 665
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 666
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 667
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 668
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s65)
+[GOOD] (assert s80)
+Fast allSat, Looking for solution 668
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 669
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 670
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 671
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 672
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 673
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 674
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 675
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 676
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 677
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 678
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 679
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 680
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s66)
+[GOOD] (assert s81)
+Fast allSat, Looking for solution 680
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 681
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 682
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 683
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 684
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 685
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 686
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 687
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 688
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 689
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 690
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 691
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 692
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s67)
+[GOOD] (assert s82)
+Fast allSat, Looking for solution 692
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 693
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 694
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 695
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 696
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 697
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 698
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 699
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 700
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 701
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 702
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 703
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 704
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s68)
+[GOOD] (assert s89)
+Fast allSat, Looking for solution 704
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 705
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 706
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 707
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 708
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 709
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 710
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 711
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 712
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 713
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 714
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 715
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 716
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s68)
+[GOOD] (assert s85)
+Fast allSat, Looking for solution 716
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 717
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 718
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 719
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 720
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 721
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 722
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 723
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 724
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 725
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 726
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 727
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 728
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s91)
+[GOOD] (assert s84)
+Fast allSat, Looking for solution 728
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 729
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 730
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 731
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 732
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 733
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 734
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 735
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 736
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 737
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 738
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 739
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 12))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 740
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s46)
+[GOOD] (define-fun s92 () Bool (= s0 s34))
+[GOOD] (assert s92)
+Fast allSat, Looking for solution 740
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s45)
+Fast allSat, Looking for solution 741
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s43)
+Fast allSat, Looking for solution 742
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s48)
+Fast allSat, Looking for solution 743
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s49)
+Fast allSat, Looking for solution 744
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s50)
+Fast allSat, Looking for solution 745
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s51)
+Fast allSat, Looking for solution 746
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s52)
+Fast allSat, Looking for solution 747
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s53)
+Fast allSat, Looking for solution 748
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s54)
+Fast allSat, Looking for solution 749
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s55)
+Fast allSat, Looking for solution 750
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s56)
+Fast allSat, Looking for solution 751
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s57)
+Fast allSat, Looking for solution 752
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s86)
+Fast allSat, Looking for solution 753
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s89)
+Fast allSat, Looking for solution 753
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 754
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 755
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 756
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 757
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 758
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 759
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 760
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 761
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 762
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 763
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 764
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 765
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s69)
+[GOOD] (assert s59)
+Fast allSat, Looking for solution 765
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 766
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 767
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 768
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 769
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 770
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 771
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 772
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 773
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 774
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 775
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 776
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 777
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s69)
+[GOOD] (assert s73)
+Fast allSat, Looking for solution 777
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 778
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 779
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 780
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 781
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 782
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 783
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 784
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 785
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 786
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 787
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 788
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 789
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s69)
+[GOOD] (assert s74)
+Fast allSat, Looking for solution 789
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 790
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 791
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 792
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 793
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 794
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 795
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 796
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 797
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 798
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 799
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 800
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 801
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s69)
+[GOOD] (assert s75)
+Fast allSat, Looking for solution 801
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 802
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 803
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 804
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 805
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 806
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 807
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 808
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 809
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 810
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 811
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 812
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 813
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s69)
+[GOOD] (assert s76)
+Fast allSat, Looking for solution 813
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 814
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 815
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 816
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 817
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 818
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 819
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 820
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 821
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 822
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 823
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 824
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 825
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s69)
+[GOOD] (assert s77)
+Fast allSat, Looking for solution 825
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 826
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 827
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 828
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 829
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 830
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 831
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 832
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 833
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 834
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 835
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 836
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 837
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s69)
+[GOOD] (assert s78)
+Fast allSat, Looking for solution 837
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 838
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 839
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 840
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 841
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 842
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 843
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 844
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 845
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 846
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 847
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 848
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 849
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s69)
+[GOOD] (assert s79)
+Fast allSat, Looking for solution 849
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 850
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 851
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 852
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 853
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 854
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 855
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 856
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 857
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 858
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 859
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 860
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 861
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s69)
+[GOOD] (assert s80)
+Fast allSat, Looking for solution 861
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 862
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 863
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 864
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 865
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 866
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 867
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 868
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 869
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 870
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 871
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 872
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 873
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s69)
+[GOOD] (assert s81)
+Fast allSat, Looking for solution 873
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 874
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 875
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 876
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 877
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 878
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 879
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 880
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 881
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 882
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 883
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 884
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 885
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s88)
+[GOOD] (assert s85)
+Fast allSat, Looking for solution 885
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 886
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 887
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 888
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 889
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 890
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 891
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 892
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 893
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 894
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 895
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 896
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 897
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s84)
+Fast allSat, Looking for solution 897
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 898
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 899
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 900
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 901
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 902
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 903
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 904
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 905
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 906
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 907
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 908
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 909
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s70)
+[GOOD] (assert s92)
+[GOOD] (assert s83)
+Fast allSat, Looking for solution 909
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 910
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 911
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 912
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 913
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 914
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 915
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 916
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 917
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 918
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 919
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 920
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 11))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 921
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s47)
+[GOOD] (define-fun s93 () Bool (= s0 s32))
+[GOOD] (assert s93)
+Fast allSat, Looking for solution 921
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s46)
+Fast allSat, Looking for solution 922
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s45)
+Fast allSat, Looking for solution 923
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s43)
+Fast allSat, Looking for solution 924
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s49)
+Fast allSat, Looking for solution 925
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s50)
+Fast allSat, Looking for solution 926
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s51)
+Fast allSat, Looking for solution 927
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s52)
+Fast allSat, Looking for solution 928
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s53)
+Fast allSat, Looking for solution 929
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s54)
+Fast allSat, Looking for solution 930
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s55)
+Fast allSat, Looking for solution 931
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s56)
+Fast allSat, Looking for solution 932
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s57)
+Fast allSat, Looking for solution 933
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s86)
+Fast allSat, Looking for solution 934
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s89)
+Fast allSat, Looking for solution 934
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 935
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 936
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 937
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 938
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 939
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 940
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 941
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 942
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 943
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 944
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 945
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 946
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s68)
+[GOOD] (assert s59)
+Fast allSat, Looking for solution 946
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 947
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 948
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 949
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 950
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 951
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 952
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 953
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 954
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 955
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 956
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 957
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 958
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s68)
+[GOOD] (assert s73)
+Fast allSat, Looking for solution 958
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 959
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 960
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 961
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 962
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 963
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 964
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 965
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 966
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 967
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 968
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 969
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 970
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s68)
+[GOOD] (assert s74)
+Fast allSat, Looking for solution 970
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 971
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 972
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 973
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 974
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 975
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 976
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 977
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 978
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 979
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 980
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 981
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 982
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s68)
+[GOOD] (assert s75)
+Fast allSat, Looking for solution 982
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 983
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 984
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 985
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 986
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 987
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 988
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 989
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 990
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 991
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 992
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 993
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 994
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s68)
+[GOOD] (assert s76)
+Fast allSat, Looking for solution 994
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 995
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 996
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 997
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 998
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 999
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1000
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1001
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1002
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1003
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1004
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1005
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1006
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s68)
+[GOOD] (assert s77)
+Fast allSat, Looking for solution 1006
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1007
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1008
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1009
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1010
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1011
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1012
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1013
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1014
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1015
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1016
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1017
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1018
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s68)
+[GOOD] (assert s78)
+Fast allSat, Looking for solution 1018
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1019
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1020
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1021
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1022
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1023
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1024
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1025
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1026
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1027
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1028
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1029
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1030
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s68)
+[GOOD] (assert s79)
+Fast allSat, Looking for solution 1030
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1031
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1032
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1033
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1034
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1035
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1036
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1037
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1038
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1039
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1040
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1041
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1042
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s68)
+[GOOD] (assert s80)
+Fast allSat, Looking for solution 1042
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1043
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1044
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1045
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1046
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1047
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1048
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1049
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1050
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1051
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1052
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1053
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1054
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s88)
+[GOOD] (assert s85)
+Fast allSat, Looking for solution 1054
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1055
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1056
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1057
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1058
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1059
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1060
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1061
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1062
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1063
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1064
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1065
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1066
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s84)
+Fast allSat, Looking for solution 1066
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1067
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1068
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1069
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1070
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1071
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1072
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1073
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1074
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1075
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1076
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1077
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1078
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s70)
+[GOOD] (assert s83)
+Fast allSat, Looking for solution 1078
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1079
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1080
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1081
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1082
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1083
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1084
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1085
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1086
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1087
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1088
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1089
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1090
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s69)
+[GOOD] (assert s93)
+[GOOD] (assert s82)
+Fast allSat, Looking for solution 1090
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1091
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1092
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1093
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1094
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1095
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1096
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1097
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1098
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1099
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1100
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1101
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 10))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1102
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s48)
+[GOOD] (define-fun s94 () Bool (= s0 s30))
+[GOOD] (assert s94)
+Fast allSat, Looking for solution 1102
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s47)
+Fast allSat, Looking for solution 1103
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s46)
+Fast allSat, Looking for solution 1104
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s45)
+Fast allSat, Looking for solution 1105
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s43)
+Fast allSat, Looking for solution 1106
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s50)
+Fast allSat, Looking for solution 1107
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s51)
+Fast allSat, Looking for solution 1108
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s52)
+Fast allSat, Looking for solution 1109
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s53)
+Fast allSat, Looking for solution 1110
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s54)
+Fast allSat, Looking for solution 1111
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s55)
+Fast allSat, Looking for solution 1112
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s56)
+Fast allSat, Looking for solution 1113
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s57)
+Fast allSat, Looking for solution 1114
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s86)
+Fast allSat, Looking for solution 1115
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s89)
+Fast allSat, Looking for solution 1115
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1116
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1117
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1118
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1119
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1120
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1121
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1122
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1123
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1124
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1125
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1126
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1127
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s67)
+[GOOD] (assert s59)
+Fast allSat, Looking for solution 1127
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1128
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1129
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1130
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1131
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1132
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1133
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1134
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1135
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1136
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1137
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1138
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1139
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s67)
+[GOOD] (assert s73)
+Fast allSat, Looking for solution 1139
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1140
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1141
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1142
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1143
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1144
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1145
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1146
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1147
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1148
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1149
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1150
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1151
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s67)
+[GOOD] (assert s74)
+Fast allSat, Looking for solution 1151
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1152
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1153
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1154
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1155
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1156
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1157
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1158
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1159
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1160
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1161
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1162
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1163
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s67)
+[GOOD] (assert s75)
+Fast allSat, Looking for solution 1163
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1164
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1165
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1166
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1167
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1168
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1169
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1170
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1171
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1172
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1173
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1174
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1175
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s67)
+[GOOD] (assert s76)
+Fast allSat, Looking for solution 1175
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1176
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1177
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1178
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1179
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1180
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1181
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1182
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1183
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1184
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1185
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1186
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1187
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s67)
+[GOOD] (assert s77)
+Fast allSat, Looking for solution 1187
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1188
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1189
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1190
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1191
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1192
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1193
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1194
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1195
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1196
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1197
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1198
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1199
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s67)
+[GOOD] (assert s78)
+Fast allSat, Looking for solution 1199
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1200
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1201
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1202
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1203
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1204
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1205
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1206
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1207
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1208
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1209
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1210
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1211
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s67)
+[GOOD] (assert s79)
+Fast allSat, Looking for solution 1211
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1212
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1213
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1214
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1215
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1216
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1217
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1218
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1219
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1220
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1221
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1222
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1223
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s88)
+[GOOD] (assert s85)
+Fast allSat, Looking for solution 1223
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1224
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1225
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1226
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1227
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1228
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1229
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1230
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1231
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1232
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1233
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1234
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1235
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s84)
+Fast allSat, Looking for solution 1235
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1236
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1237
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1238
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1239
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1240
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1241
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1242
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1243
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1244
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1245
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1246
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1247
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s83)
+Fast allSat, Looking for solution 1247
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1248
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1249
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1250
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1251
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1252
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1253
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1254
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1255
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1256
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1257
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1258
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1259
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s82)
+Fast allSat, Looking for solution 1259
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1260
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1261
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1262
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1263
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1264
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1265
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1266
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1267
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1268
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1269
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1270
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1271
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s68)
+[GOOD] (assert s94)
+[GOOD] (assert s81)
+Fast allSat, Looking for solution 1271
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1272
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1273
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1274
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1275
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1276
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1277
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1278
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1279
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1280
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1281
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1282
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1283
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s49)
+[GOOD] (define-fun s95 () Bool (= s0 s28))
+[GOOD] (assert s95)
+Fast allSat, Looking for solution 1283
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s48)
+Fast allSat, Looking for solution 1284
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s47)
+Fast allSat, Looking for solution 1285
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s46)
+Fast allSat, Looking for solution 1286
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s45)
+Fast allSat, Looking for solution 1287
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s43)
+Fast allSat, Looking for solution 1288
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s86)
+Fast allSat, Looking for solution 1289
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s51)
+Fast allSat, Looking for solution 1290
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s52)
+Fast allSat, Looking for solution 1291
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s53)
+Fast allSat, Looking for solution 1292
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s54)
+Fast allSat, Looking for solution 1293
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s55)
+Fast allSat, Looking for solution 1294
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s56)
+Fast allSat, Looking for solution 1295
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s57)
+Fast allSat, Looking for solution 1296
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s58)
+[GOOD] (assert s59)
+Fast allSat, Looking for solution 1296
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1297
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1298
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1299
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1300
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1301
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1302
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1303
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1304
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1305
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1306
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1307
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1308
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s72)
+[GOOD] (assert s73)
+Fast allSat, Looking for solution 1308
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1309
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1310
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1311
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1312
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1313
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1314
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1315
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1316
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1317
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1318
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1319
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1320
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s58)
+[GOOD] (assert s74)
+Fast allSat, Looking for solution 1320
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1321
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1322
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1323
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1324
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1325
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1326
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1327
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1328
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1329
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1330
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1331
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1332
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s60)
+[GOOD] (assert s75)
+Fast allSat, Looking for solution 1332
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1333
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1334
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1335
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1336
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1337
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1338
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1339
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1340
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1341
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1342
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1343
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1344
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s61)
+[GOOD] (assert s76)
+Fast allSat, Looking for solution 1344
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1345
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1346
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1347
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1348
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1349
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1350
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1351
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1352
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1353
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1354
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1355
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1356
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s62)
+[GOOD] (assert s77)
+Fast allSat, Looking for solution 1356
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1357
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1358
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1359
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1360
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1361
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1362
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1363
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1364
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1365
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1366
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1367
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1368
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s63)
+[GOOD] (assert s78)
+Fast allSat, Looking for solution 1368
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1369
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1370
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1371
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1372
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1373
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1374
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1375
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1376
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1377
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1378
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1379
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1380
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s89)
+Fast allSat, Looking for solution 1380
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1381
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1382
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1383
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1384
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1385
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1386
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1387
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1388
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1389
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1390
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1391
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1392
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s88)
+[GOOD] (assert s85)
+Fast allSat, Looking for solution 1392
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1393
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1394
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1395
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1396
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1397
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1398
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1399
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1400
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1401
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1402
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1403
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1404
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s84)
+Fast allSat, Looking for solution 1404
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1405
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1406
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1407
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1408
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1409
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1410
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1411
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1412
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1413
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1414
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1415
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1416
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s70)
+[GOOD] (assert s83)
+Fast allSat, Looking for solution 1416
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1417
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1418
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1419
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1420
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1421
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1422
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1423
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1424
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1425
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1426
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1427
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1428
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s69)
+[GOOD] (assert s82)
+Fast allSat, Looking for solution 1428
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1429
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1430
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1431
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1432
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1433
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1434
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1435
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1436
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1437
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1438
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1439
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1440
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s68)
+[GOOD] (assert s81)
+Fast allSat, Looking for solution 1440
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1441
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1442
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1443
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1444
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1445
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1446
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1447
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1448
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1449
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1450
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1451
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1452
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s67)
+[GOOD] (assert s95)
+[GOOD] (assert s80)
+Fast allSat, Looking for solution 1452
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1453
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1454
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1455
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1456
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1457
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1458
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1459
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1460
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1461
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1462
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1463
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 8))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1464
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s50)
+[GOOD] (define-fun s96 () Bool (= s0 s26))
+[GOOD] (assert s96)
+Fast allSat, Looking for solution 1464
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s49)
+Fast allSat, Looking for solution 1465
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s48)
+Fast allSat, Looking for solution 1466
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s47)
+Fast allSat, Looking for solution 1467
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s46)
+Fast allSat, Looking for solution 1468
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s45)
+Fast allSat, Looking for solution 1469
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s43)
+Fast allSat, Looking for solution 1470
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s52)
+Fast allSat, Looking for solution 1471
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s53)
+Fast allSat, Looking for solution 1472
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s54)
+Fast allSat, Looking for solution 1473
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s55)
+Fast allSat, Looking for solution 1474
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s56)
+Fast allSat, Looking for solution 1475
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s57)
+Fast allSat, Looking for solution 1476
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s86)
+Fast allSat, Looking for solution 1477
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s89)
+Fast allSat, Looking for solution 1477
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1478
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1479
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1480
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1481
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1482
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1483
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1484
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1485
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1486
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1487
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1488
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1489
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s65)
+[GOOD] (assert s59)
+Fast allSat, Looking for solution 1489
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1490
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1491
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1492
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1493
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1494
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1495
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1496
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1497
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1498
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1499
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1500
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1501
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s65)
+[GOOD] (assert s73)
+Fast allSat, Looking for solution 1501
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1502
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1503
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1504
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1505
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1506
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1507
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1508
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1509
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1510
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1511
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1512
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1513
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s65)
+[GOOD] (assert s74)
+Fast allSat, Looking for solution 1513
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1514
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1515
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1516
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1517
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1518
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1519
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1520
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1521
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1522
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1523
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1524
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1525
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s65)
+[GOOD] (assert s75)
+Fast allSat, Looking for solution 1525
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1526
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1527
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1528
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1529
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1530
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1531
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1532
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1533
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1534
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1535
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1536
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1537
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s65)
+[GOOD] (assert s76)
+Fast allSat, Looking for solution 1537
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1538
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1539
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1540
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1541
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1542
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1543
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1544
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1545
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1546
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1547
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1548
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1549
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s65)
+[GOOD] (assert s77)
+Fast allSat, Looking for solution 1549
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1550
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1551
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1552
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1553
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1554
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1555
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1556
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1557
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1558
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1559
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1560
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1561
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s88)
+[GOOD] (assert s85)
+Fast allSat, Looking for solution 1561
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1562
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1563
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1564
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1565
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1566
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1567
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1568
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1569
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1570
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1571
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1572
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1573
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s84)
+Fast allSat, Looking for solution 1573
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1574
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1575
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1576
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1577
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1578
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1579
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1580
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1581
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1582
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1583
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1584
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1585
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s70)
+[GOOD] (assert s83)
+Fast allSat, Looking for solution 1585
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1586
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1587
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1588
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1589
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1590
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1591
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1592
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1593
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1594
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1595
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1596
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1597
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s69)
+[GOOD] (assert s82)
+Fast allSat, Looking for solution 1597
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1598
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1599
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1600
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1601
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1602
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1603
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1604
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1605
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1606
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1607
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1608
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1609
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s68)
+[GOOD] (assert s81)
+Fast allSat, Looking for solution 1609
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1610
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1611
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1612
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1613
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1614
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1615
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1616
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1617
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1618
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1619
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1620
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1621
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s67)
+[GOOD] (assert s80)
+Fast allSat, Looking for solution 1621
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1622
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1623
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1624
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1625
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1626
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1627
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1628
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1629
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1630
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1631
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1632
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1633
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s66)
+[GOOD] (assert s96)
+[GOOD] (assert s79)
+Fast allSat, Looking for solution 1633
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1634
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1635
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1636
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1637
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1638
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1639
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1640
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1641
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1642
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1643
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1644
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 7))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1645
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s51)
+[GOOD] (define-fun s97 () Bool (= s0 s24))
+[GOOD] (assert s97)
+Fast allSat, Looking for solution 1645
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s50)
+Fast allSat, Looking for solution 1646
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s49)
+Fast allSat, Looking for solution 1647
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s53)
+Fast allSat, Looking for solution 1648
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s48)
+Fast allSat, Looking for solution 1649
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s54)
+Fast allSat, Looking for solution 1650
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s47)
+Fast allSat, Looking for solution 1651
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s55)
+Fast allSat, Looking for solution 1652
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s46)
+Fast allSat, Looking for solution 1653
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s56)
+Fast allSat, Looking for solution 1654
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s45)
+Fast allSat, Looking for solution 1655
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s57)
+Fast allSat, Looking for solution 1656
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s43)
+Fast allSat, Looking for solution 1657
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s86)
+Fast allSat, Looking for solution 1658
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s89)
+Fast allSat, Looking for solution 1658
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1659
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1660
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1661
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1662
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1663
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1664
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1665
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1666
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1667
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1668
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1669
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1670
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s88)
+[GOOD] (assert s85)
+Fast allSat, Looking for solution 1670
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1671
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1672
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1673
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1674
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1675
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1676
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1677
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1678
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1679
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1680
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1681
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1682
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s64)
+[GOOD] (assert s59)
+Fast allSat, Looking for solution 1682
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1683
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1684
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1685
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1686
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1687
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1688
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1689
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1690
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1691
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1692
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1693
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1694
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s84)
+Fast allSat, Looking for solution 1694
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1695
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1696
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1697
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1698
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1699
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1700
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1701
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1702
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1703
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1704
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1705
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1706
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s64)
+[GOOD] (assert s73)
+Fast allSat, Looking for solution 1706
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1707
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1708
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1709
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1710
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1711
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1712
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1713
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1714
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1715
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1716
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1717
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1718
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s70)
+[GOOD] (assert s83)
+Fast allSat, Looking for solution 1718
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1719
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1720
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1721
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1722
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1723
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1724
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1725
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1726
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1727
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1728
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1729
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1730
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s64)
+[GOOD] (assert s74)
+Fast allSat, Looking for solution 1730
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1731
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1732
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1733
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1734
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1735
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1736
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1737
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1738
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1739
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1740
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1741
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1742
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s69)
+[GOOD] (assert s82)
+Fast allSat, Looking for solution 1742
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1743
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1744
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1745
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1746
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1747
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1748
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1749
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1750
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1751
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1752
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1753
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1754
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s64)
+[GOOD] (assert s75)
+Fast allSat, Looking for solution 1754
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1755
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1756
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1757
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1758
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1759
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1760
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1761
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1762
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1763
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1764
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1765
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1766
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s68)
+[GOOD] (assert s81)
+Fast allSat, Looking for solution 1766
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1767
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1768
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1769
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1770
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1771
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1772
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1773
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1774
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1775
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1776
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1777
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1778
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s64)
+[GOOD] (assert s76)
+Fast allSat, Looking for solution 1778
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1779
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1780
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1781
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1782
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1783
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1784
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1785
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1786
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1787
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1788
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1789
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1790
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s67)
+[GOOD] (assert s80)
+Fast allSat, Looking for solution 1790
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1791
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1792
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1793
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1794
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1795
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1796
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1797
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1798
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1799
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1800
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1801
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1802
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s66)
+[GOOD] (assert s79)
+Fast allSat, Looking for solution 1802
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1803
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1804
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1805
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1806
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1807
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1808
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1809
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1810
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1811
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1812
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1813
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1814
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s65)
+[GOOD] (assert s97)
+[GOOD] (assert s78)
+Fast allSat, Looking for solution 1814
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1815
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1816
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1817
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1818
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1819
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1820
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1821
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 1822
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1823
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1824
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1825
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1826
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s52)
+[GOOD] (define-fun s98 () Bool (= s0 s22))
+[GOOD] (assert s98)
+Fast allSat, Looking for solution 1826
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s51)
+Fast allSat, Looking for solution 1827
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s50)
+Fast allSat, Looking for solution 1828
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s49)
+Fast allSat, Looking for solution 1829
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s48)
+Fast allSat, Looking for solution 1830
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s47)
+Fast allSat, Looking for solution 1831
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s46)
+Fast allSat, Looking for solution 1832
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s45)
+Fast allSat, Looking for solution 1833
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s43)
+Fast allSat, Looking for solution 1834
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s86)
+Fast allSat, Looking for solution 1835
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s54)
+Fast allSat, Looking for solution 1836
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s55)
+Fast allSat, Looking for solution 1837
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s56)
+Fast allSat, Looking for solution 1838
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s57)
+Fast allSat, Looking for solution 1839
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s58)
+[GOOD] (assert s59)
+Fast allSat, Looking for solution 1839
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1840
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1841
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1842
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1843
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1844
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1845
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1846
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1847
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1848
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1849
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1850
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1851
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s72)
+[GOOD] (assert s73)
+Fast allSat, Looking for solution 1851
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1852
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1853
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1854
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1855
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1856
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1857
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1858
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1859
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1860
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1861
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1862
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1863
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s58)
+[GOOD] (assert s74)
+Fast allSat, Looking for solution 1863
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1864
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1865
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1866
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1867
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1868
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1869
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1870
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1871
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1872
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1873
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1874
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1875
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s60)
+[GOOD] (assert s75)
+Fast allSat, Looking for solution 1875
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 1876
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1877
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1878
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1879
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1880
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1881
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1882
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1883
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1884
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1885
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1886
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1887
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s89)
+Fast allSat, Looking for solution 1887
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1888
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1889
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1890
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1891
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1892
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1893
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1894
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1895
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1896
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1897
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1898
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1899
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s88)
+[GOOD] (assert s85)
+Fast allSat, Looking for solution 1899
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1900
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1901
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1902
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1903
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1904
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1905
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1906
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1907
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1908
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1909
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1910
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1911
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s84)
+Fast allSat, Looking for solution 1911
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1912
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1913
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1914
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1915
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1916
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1917
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1918
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1919
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1920
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1921
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1922
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1923
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s83)
+Fast allSat, Looking for solution 1923
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1924
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1925
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1926
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1927
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1928
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1929
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1930
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1931
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1932
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1933
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1934
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1935
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s82)
+Fast allSat, Looking for solution 1935
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1936
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1937
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1938
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1939
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1940
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1941
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1942
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1943
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1944
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1945
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1946
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1947
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s81)
+Fast allSat, Looking for solution 1947
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1948
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1949
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1950
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1951
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1952
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1953
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1954
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1955
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1956
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1957
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1958
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1959
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s80)
+Fast allSat, Looking for solution 1959
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1960
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1961
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1962
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1963
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1964
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1965
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1966
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1967
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1968
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1969
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1970
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1971
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s79)
+Fast allSat, Looking for solution 1971
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1972
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1973
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1974
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1975
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1976
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1977
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 1978
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1979
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1980
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1981
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1982
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1983
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s78)
+Fast allSat, Looking for solution 1983
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1984
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1985
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1986
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1987
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 1988
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 1989
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 1990
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 1991
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 1992
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 1993
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 1994
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 1995
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s64)
+[GOOD] (assert s98)
+[GOOD] (assert s77)
+Fast allSat, Looking for solution 1995
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 1996
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 1997
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 1998
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 1999
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2000
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2001
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 2002
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2003
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2004
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2005
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2006
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2007
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s53)
+[GOOD] (define-fun s99 () Bool (= s0 s20))
+[GOOD] (assert s99)
+Fast allSat, Looking for solution 2007
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s52)
+Fast allSat, Looking for solution 2008
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s51)
+Fast allSat, Looking for solution 2009
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s50)
+Fast allSat, Looking for solution 2010
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s49)
+Fast allSat, Looking for solution 2011
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s48)
+Fast allSat, Looking for solution 2012
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s47)
+Fast allSat, Looking for solution 2013
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s46)
+Fast allSat, Looking for solution 2014
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s45)
+Fast allSat, Looking for solution 2015
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s43)
+Fast allSat, Looking for solution 2016
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s86)
+Fast allSat, Looking for solution 2017
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s55)
+Fast allSat, Looking for solution 2018
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s56)
+Fast allSat, Looking for solution 2019
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s57)
+Fast allSat, Looking for solution 2020
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s58)
+[GOOD] (assert s59)
+Fast allSat, Looking for solution 2020
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2021
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2022
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2023
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2024
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2025
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2026
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2027
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2028
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2029
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2030
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 2031
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2032
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s72)
+[GOOD] (assert s73)
+Fast allSat, Looking for solution 2032
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2033
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2034
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2035
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2036
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2037
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2038
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2039
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2040
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2041
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 2042
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2043
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2044
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s58)
+[GOOD] (assert s74)
+Fast allSat, Looking for solution 2044
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2045
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2046
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2047
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2048
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2049
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2050
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2051
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2052
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2053
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 2054
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2055
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2056
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s89)
+Fast allSat, Looking for solution 2056
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2057
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2058
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2059
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2060
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2061
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2062
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2063
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2064
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2065
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2066
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2067
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2068
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s88)
+[GOOD] (assert s85)
+Fast allSat, Looking for solution 2068
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2069
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2070
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2071
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2072
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2073
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2074
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2075
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2076
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2077
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2078
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2079
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2080
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s84)
+Fast allSat, Looking for solution 2080
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2081
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2082
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2083
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2084
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2085
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2086
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2087
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2088
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2089
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2090
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2091
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2092
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s83)
+Fast allSat, Looking for solution 2092
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2093
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2094
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2095
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2096
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2097
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2098
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2099
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2100
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2101
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2102
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2103
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2104
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s82)
+Fast allSat, Looking for solution 2104
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2105
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2106
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2107
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2108
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2109
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2110
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2111
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2112
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2113
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2114
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2115
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2116
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s81)
+Fast allSat, Looking for solution 2116
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2117
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2118
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2119
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2120
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2121
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2122
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2123
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2124
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2125
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2126
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2127
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2128
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s80)
+Fast allSat, Looking for solution 2128
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2129
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2130
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2131
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2132
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2133
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2134
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2135
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2136
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2137
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2138
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2139
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2140
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s79)
+Fast allSat, Looking for solution 2140
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2141
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2142
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2143
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2144
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2145
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2146
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2147
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2148
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2149
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2150
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2151
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2152
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s78)
+Fast allSat, Looking for solution 2152
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2153
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2154
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2155
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2156
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2157
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2158
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2159
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2160
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2161
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2162
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2163
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2164
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s77)
+Fast allSat, Looking for solution 2164
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2165
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2166
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2167
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2168
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2169
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2170
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2171
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2172
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2173
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2174
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2175
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2176
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s63)
+[GOOD] (assert s99)
+[GOOD] (assert s76)
+Fast allSat, Looking for solution 2176
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2177
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2178
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2179
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2180
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2181
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2182
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2183
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 2184
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2185
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2186
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2187
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2188
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s54)
+[GOOD] (define-fun s100 () Bool (= s0 s18))
+[GOOD] (assert s100)
+Fast allSat, Looking for solution 2188
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s53)
+Fast allSat, Looking for solution 2189
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s52)
+Fast allSat, Looking for solution 2190
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s51)
+Fast allSat, Looking for solution 2191
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s50)
+Fast allSat, Looking for solution 2192
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s49)
+Fast allSat, Looking for solution 2193
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s48)
+Fast allSat, Looking for solution 2194
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s47)
+Fast allSat, Looking for solution 2195
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s46)
+Fast allSat, Looking for solution 2196
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s45)
+Fast allSat, Looking for solution 2197
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s43)
+Fast allSat, Looking for solution 2198
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s86)
+Fast allSat, Looking for solution 2199
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s56)
+Fast allSat, Looking for solution 2200
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s57)
+Fast allSat, Looking for solution 2201
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s58)
+[GOOD] (assert s59)
+Fast allSat, Looking for solution 2201
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2202
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2203
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2204
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2205
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2206
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2207
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2208
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2209
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2210
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2211
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 2212
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2213
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s72)
+[GOOD] (assert s73)
+Fast allSat, Looking for solution 2213
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2214
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2215
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2216
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2217
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2218
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2219
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2220
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2221
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2222
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2223
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 2224
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2225
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s89)
+Fast allSat, Looking for solution 2225
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2226
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2227
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2228
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2229
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2230
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2231
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2232
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2233
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2234
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2235
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2236
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2237
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s88)
+[GOOD] (assert s85)
+Fast allSat, Looking for solution 2237
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2238
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2239
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2240
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2241
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2242
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2243
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2244
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2245
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2246
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2247
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2248
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2249
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s84)
+Fast allSat, Looking for solution 2249
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2250
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2251
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2252
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2253
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2254
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2255
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2256
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2257
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2258
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2259
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2260
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2261
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s70)
+[GOOD] (assert s83)
+Fast allSat, Looking for solution 2261
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 2262
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2263
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2264
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2265
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2266
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2267
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2268
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2269
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2270
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2271
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2272
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2273
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s69)
+[GOOD] (assert s82)
+Fast allSat, Looking for solution 2273
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2274
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 2275
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2276
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2277
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2278
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2279
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2280
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2281
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2282
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2283
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2284
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2285
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s68)
+[GOOD] (assert s81)
+Fast allSat, Looking for solution 2285
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 2286
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2287
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2288
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2289
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2290
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2291
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2292
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2293
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2294
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2295
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2296
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2297
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s68)
+[GOOD] (assert s80)
+Fast allSat, Looking for solution 2297
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2298
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2299
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 2300
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2301
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2302
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2303
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2304
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2305
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2306
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2307
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2308
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2309
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s68)
+[GOOD] (assert s79)
+Fast allSat, Looking for solution 2309
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2310
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2311
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 2312
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2313
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2314
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2315
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2316
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2317
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2318
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2319
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2320
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2321
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s68)
+[GOOD] (assert s78)
+Fast allSat, Looking for solution 2321
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2322
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2323
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2324
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2325
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2326
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 2327
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2328
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2329
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2330
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2331
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2332
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2333
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s68)
+[GOOD] (assert s77)
+Fast allSat, Looking for solution 2333
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2334
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2335
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2336
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2337
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2338
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2339
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 2340
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2341
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2342
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2343
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2344
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2345
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s68)
+[GOOD] (assert s76)
+Fast allSat, Looking for solution 2345
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2346
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2347
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2348
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2349
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2350
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2351
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2352
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 2353
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2354
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2355
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2356
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2357
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s62)
+[GOOD] (assert s100)
+[GOOD] (assert s75)
+Fast allSat, Looking for solution 2357
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2358
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2359
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2360
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2361
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2362
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2363
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2364
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2365
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 2366
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2367
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2368
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2369
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s55)
+[GOOD] (define-fun s101 () Bool (= s0 s16))
+[GOOD] (assert s101)
+Fast allSat, Looking for solution 2369
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s57)
+Fast allSat, Looking for solution 2370
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s54)
+Fast allSat, Looking for solution 2371
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s53)
+Fast allSat, Looking for solution 2372
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s52)
+Fast allSat, Looking for solution 2373
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s51)
+Fast allSat, Looking for solution 2374
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s50)
+Fast allSat, Looking for solution 2375
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s49)
+Fast allSat, Looking for solution 2376
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s48)
+Fast allSat, Looking for solution 2377
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s47)
+Fast allSat, Looking for solution 2378
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s46)
+Fast allSat, Looking for solution 2379
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s45)
+Fast allSat, Looking for solution 2380
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s43)
+Fast allSat, Looking for solution 2381
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s86)
+Fast allSat, Looking for solution 2382
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s89)
+Fast allSat, Looking for solution 2382
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2383
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2384
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2385
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2386
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2387
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2388
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2389
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2390
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2391
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2392
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2393
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2394
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s88)
+[GOOD] (assert s85)
+Fast allSat, Looking for solution 2394
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2395
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2396
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2397
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2398
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2399
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2400
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2401
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2402
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2403
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2404
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2405
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2406
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s84)
+Fast allSat, Looking for solution 2406
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2407
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2408
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2409
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2410
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2411
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2412
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2413
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2414
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2415
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2416
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2417
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2418
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s70)
+[GOOD] (assert s83)
+Fast allSat, Looking for solution 2418
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 2419
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2420
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2421
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2422
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2423
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2424
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2425
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2426
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2427
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2428
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2429
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2430
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s69)
+[GOOD] (assert s82)
+Fast allSat, Looking for solution 2430
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2431
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 2432
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2433
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2434
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2435
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2436
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2437
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2438
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2439
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2440
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2441
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2442
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s68)
+[GOOD] (assert s81)
+Fast allSat, Looking for solution 2442
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 2443
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2444
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2445
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2446
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2447
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2448
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2449
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2450
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2451
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2452
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2453
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2454
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s67)
+[GOOD] (assert s80)
+Fast allSat, Looking for solution 2454
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2455
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2456
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2457
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 2458
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2459
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2460
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2461
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2462
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2463
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2464
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2465
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2466
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s67)
+[GOOD] (assert s79)
+Fast allSat, Looking for solution 2466
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2467
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2468
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2469
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 2470
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2471
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2472
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2473
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2474
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2475
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2476
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2477
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2478
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s67)
+[GOOD] (assert s78)
+Fast allSat, Looking for solution 2478
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2479
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2480
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2481
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2482
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2483
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 2484
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2485
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2486
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2487
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2488
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2489
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2490
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s67)
+[GOOD] (assert s77)
+Fast allSat, Looking for solution 2490
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2491
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2492
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2493
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2494
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2495
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2496
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 2497
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2498
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2499
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2500
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2501
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2502
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s67)
+[GOOD] (assert s76)
+Fast allSat, Looking for solution 2502
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2503
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2504
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2505
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 2506
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2507
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2508
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2509
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2510
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2511
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2512
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2513
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2514
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s67)
+[GOOD] (assert s75)
+Fast allSat, Looking for solution 2514
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2515
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2516
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2517
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2518
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2519
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2520
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2521
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2522
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 2523
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2524
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2525
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2526
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s67)
+[GOOD] (assert s59)
+Fast allSat, Looking for solution 2526
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2527
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2528
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2529
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2530
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2531
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2532
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 2533
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2534
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2535
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2536
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2537
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2538
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s61)
+[GOOD] (assert s101)
+[GOOD] (assert s74)
+Fast allSat, Looking for solution 2538
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2539
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2540
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2541
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2542
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2543
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2544
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2545
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2546
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2547
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
+Fast allSat, Looking for solution 2548
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2549
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[GOOD] (push 1)
+[GOOD] (assert s72)
+Fast allSat, Looking for solution 2550
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s56)
+[GOOD] (define-fun s102 () Bool (= s0 s3))
+[GOOD] (assert s102)
+Fast allSat, Looking for solution 2550
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s55)
+Fast allSat, Looking for solution 2551
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s54)
+Fast allSat, Looking for solution 2552
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s53)
+Fast allSat, Looking for solution 2553
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s52)
+Fast allSat, Looking for solution 2554
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s51)
+Fast allSat, Looking for solution 2555
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s50)
+Fast allSat, Looking for solution 2556
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s49)
+Fast allSat, Looking for solution 2557
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s48)
+Fast allSat, Looking for solution 2558
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s47)
+Fast allSat, Looking for solution 2559
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s46)
+Fast allSat, Looking for solution 2560
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s45)
+Fast allSat, Looking for solution 2561
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s43)
+Fast allSat, Looking for solution 2562
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s86)
+Fast allSat, Looking for solution 2563
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s89)
+Fast allSat, Looking for solution 2563
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2564
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2565
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2566
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2567
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2568
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2569
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2570
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2571
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2572
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2573
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2574
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 15))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2575
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s88)
+[GOOD] (assert s85)
+Fast allSat, Looking for solution 2575
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2576
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2577
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2578
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2579
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2580
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2581
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2582
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2583
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2584
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2585
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2586
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 14))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2587
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s84)
+Fast allSat, Looking for solution 2587
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2588
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2589
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2590
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2591
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2592
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2593
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2594
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2595
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2596
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2597
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2598
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 13))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2599
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s83)
+Fast allSat, Looking for solution 2599
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2600
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2601
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2602
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2603
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2604
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2605
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2606
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2607
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2608
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2609
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2610
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 12))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2611
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s82)
+Fast allSat, Looking for solution 2611
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2612
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2613
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2614
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2615
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2616
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2617
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2618
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2619
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2620
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2621
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2622
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 11))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2623
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s81)
+Fast allSat, Looking for solution 2623
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2624
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2625
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2626
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2627
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2628
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2629
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2630
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2631
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2632
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2633
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2634
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 10))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2635
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s80)
+Fast allSat, Looking for solution 2635
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2636
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2637
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2638
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2639
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2640
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2641
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2642
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2643
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2644
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2645
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2646
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 9))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2647
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s79)
+Fast allSat, Looking for solution 2647
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2648
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2649
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2650
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2651
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2652
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2653
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2654
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2655
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2656
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2657
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2658
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 8))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2659
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s78)
+Fast allSat, Looking for solution 2659
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2660
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2661
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2662
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2663
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2664
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2665
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2666
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2667
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2668
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2669
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2670
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2671
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s77)
+Fast allSat, Looking for solution 2671
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2672
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2673
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2674
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2675
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2676
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2677
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2678
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2679
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2680
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2681
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2682
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 6))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2683
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s76)
+Fast allSat, Looking for solution 2683
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2684
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2685
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2686
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2687
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2688
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2689
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2690
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2691
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2692
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2693
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2694
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 5))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2695
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s75)
+Fast allSat, Looking for solution 2695
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2696
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2697
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2698
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2699
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2700
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2701
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2702
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2703
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2704
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2705
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 3))
+[GOOD] (push 1)
+[GOOD] (assert s60)
+Fast allSat, Looking for solution 2706
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 4))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2707
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s71)
+[GOOD] (assert s74)
+Fast allSat, Looking for solution 2707
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2708
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2709
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2710
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2711
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2712
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2713
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2714
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2715
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2716
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2717
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 15))
+[GOOD] (push 1)
+[GOOD] (assert s88)
+Fast allSat, Looking for solution 2718
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 3))
+[SEND] (get-value (s2))
+[RECV] ((s2 2))
+[GOOD] (push 1)
+[GOOD] (assert s58)
+Fast allSat, Looking for solution 2719
+[SEND] (check-sat)
+[RECV] unsat
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (pop 1)
+[GOOD] (push 1)
+[GOOD] (assert s60)
+[GOOD] (assert s102)
+[GOOD] (assert s73)
+Fast allSat, Looking for solution 2719
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 4))
+[GOOD] (push 1)
+[GOOD] (assert s61)
+Fast allSat, Looking for solution 2720
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 5))
+[GOOD] (push 1)
+[GOOD] (assert s62)
+Fast allSat, Looking for solution 2721
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 6))
+[GOOD] (push 1)
+[GOOD] (assert s63)
+Fast allSat, Looking for solution 2722
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 7))
+[GOOD] (push 1)
+[GOOD] (assert s64)
+Fast allSat, Looking for solution 2723
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 8))
+[GOOD] (push 1)
+[GOOD] (assert s65)
+Fast allSat, Looking for solution 2724
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 9))
+[GOOD] (push 1)
+[GOOD] (assert s66)
+Fast allSat, Looking for solution 2725
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 10))
+[GOOD] (push 1)
+[GOOD] (assert s67)
+Fast allSat, Looking for solution 2726
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 11))
+[GOOD] (push 1)
+[GOOD] (assert s68)
+Fast allSat, Looking for solution 2727
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 12))
+[GOOD] (push 1)
+[GOOD] (assert s69)
+Fast allSat, Looking for solution 2728
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 13))
+[GOOD] (push 1)
+[GOOD] (assert s70)
+Fast allSat, Looking for solution 2729
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s2))
+[RECV] ((s2 14))
+[GOOD] (push 1)
+[GOOD] (assert s71)
 Fast allSat, Looking for solution 2730
 [SEND] (check-sat)
 [RECV] sat
diff --git a/SBVTestSuite/GoldFiles/allSat8.gold b/SBVTestSuite/GoldFiles/allSat8.gold
--- a/SBVTestSuite/GoldFiles/allSat8.gold
+++ b/SBVTestSuite/GoldFiles/allSat8.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/arrayGetValTest1.gold b/SBVTestSuite/GoldFiles/arrayGetValTest1.gold
--- a/SBVTestSuite/GoldFiles/arrayGetValTest1.gold
+++ b/SBVTestSuite/GoldFiles/arrayGetValTest1.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/array_caching_01.gold b/SBVTestSuite/GoldFiles/array_caching_01.gold
--- a/SBVTestSuite/GoldFiles/array_caching_01.gold
+++ b/SBVTestSuite/GoldFiles/array_caching_01.gold
@@ -9,13 +9,12 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
 [GOOD] (define-fun s1 () Int 0)
-[GOOD] (define-fun s4 () Int 2)
-[GOOD] (define-fun s6 () Int 1)
+[GOOD] (define-fun s3 () (Array Int Int) (store ((as const (Array Int Int)) 0) 0 2))
+[GOOD] (define-fun s4 () Int 1)
 [GOOD] ; --- top level inputs ---
 [GOOD] (declare-fun s0 () Int) ; tracks user variable "x"
 [GOOD] ; --- constant tables ---
@@ -24,20 +23,17 @@
 [GOOD] ; --- user defined functions ---
 [GOOD] ; --- assignments ---
 [GOOD] (define-fun s2 () Bool (= s0 s1))
-[GOOD] (define-fun s3 () (Array Int Int) (lambda ((l1_s0 Int))
-         0))
-[GOOD] (define-fun s5 () (Array Int Int) (store s3 s1 s4))
-[GOOD] (define-fun s7 () Int (+ s0 s6))
-[GOOD] (define-fun s8 () Int (select s5 s7))
-[GOOD] (define-fun s9 () (Array Int Int) (store s5 s1 s8))
+[GOOD] (define-fun s5 () Int (+ s0 s4))
+[GOOD] (define-fun s6 () Int (select s3 s5))
+[GOOD] (define-fun s7 () (Array Int Int) (store s3 s1 s6))
+[GOOD] (define-fun s8 () Int (select s7 s1))
+[GOOD] (define-fun s9 () (Array Int Int) (store s3 s5 s4))
 [GOOD] (define-fun s10 () Int (select s9 s1))
-[GOOD] (define-fun s11 () (Array Int Int) (store s5 s7 s6))
-[GOOD] (define-fun s12 () Int (select s11 s1))
-[GOOD] (define-fun s13 () Int (ite s2 s10 s12))
-[GOOD] (define-fun s14 () Bool (= s6 s13))
+[GOOD] (define-fun s11 () Int (ite s2 s8 s10))
+[GOOD] (define-fun s12 () Bool (= s4 s11))
 [GOOD] ; --- delayedEqualities ---
 [GOOD] ; --- formula ---
-[GOOD] (assert s14)
+[GOOD] (assert s12)
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
diff --git a/SBVTestSuite/GoldFiles/array_caching_02.gold b/SBVTestSuite/GoldFiles/array_caching_02.gold
--- a/SBVTestSuite/GoldFiles/array_caching_02.gold
+++ b/SBVTestSuite/GoldFiles/array_caching_02.gold
@@ -9,13 +9,12 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
 [GOOD] (define-fun s1 () Int 0)
-[GOOD] (define-fun s4 () Int 2)
-[GOOD] (define-fun s6 () Int 1)
+[GOOD] (define-fun s3 () (Array Int Int) (store ((as const (Array Int Int)) 0) 0 2))
+[GOOD] (define-fun s4 () Int 1)
 [GOOD] ; --- top level inputs ---
 [GOOD] (declare-fun s0 () Int) ; tracks user variable "x"
 [GOOD] ; --- constant tables ---
@@ -24,20 +23,17 @@
 [GOOD] ; --- user defined functions ---
 [GOOD] ; --- assignments ---
 [GOOD] (define-fun s2 () Bool (distinct s0 s1))
-[GOOD] (define-fun s3 () (Array Int Int) (lambda ((l1_s0 Int))
-         0))
-[GOOD] (define-fun s5 () (Array Int Int) (store s3 s1 s4))
-[GOOD] (define-fun s7 () Int (+ s0 s6))
-[GOOD] (define-fun s8 () (Array Int Int) (store s5 s7 s6))
-[GOOD] (define-fun s9 () Int (select s8 s1))
-[GOOD] (define-fun s10 () Int (select s5 s7))
-[GOOD] (define-fun s11 () (Array Int Int) (store s5 s1 s10))
-[GOOD] (define-fun s12 () Int (select s11 s1))
-[GOOD] (define-fun s13 () Int (ite s2 s9 s12))
-[GOOD] (define-fun s14 () Bool (= s6 s13))
+[GOOD] (define-fun s5 () Int (+ s0 s4))
+[GOOD] (define-fun s6 () (Array Int Int) (store s3 s5 s4))
+[GOOD] (define-fun s7 () Int (select s6 s1))
+[GOOD] (define-fun s8 () Int (select s3 s5))
+[GOOD] (define-fun s9 () (Array Int Int) (store s3 s1 s8))
+[GOOD] (define-fun s10 () Int (select s9 s1))
+[GOOD] (define-fun s11 () Int (ite s2 s7 s10))
+[GOOD] (define-fun s12 () Bool (= s4 s11))
 [GOOD] ; --- delayedEqualities ---
 [GOOD] ; --- formula ---
-[GOOD] (assert s14)
+[GOOD] (assert s12)
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
diff --git a/SBVTestSuite/GoldFiles/array_misc_1.gold b/SBVTestSuite/GoldFiles/array_misc_1.gold
--- a/SBVTestSuite/GoldFiles/array_misc_1.gold
+++ b/SBVTestSuite/GoldFiles/array_misc_1.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/array_misc_11.gold b/SBVTestSuite/GoldFiles/array_misc_11.gold
--- a/SBVTestSuite/GoldFiles/array_misc_11.gold
+++ b/SBVTestSuite/GoldFiles/array_misc_11.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/array_misc_12.gold b/SBVTestSuite/GoldFiles/array_misc_12.gold
--- a/SBVTestSuite/GoldFiles/array_misc_12.gold
+++ b/SBVTestSuite/GoldFiles/array_misc_12.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/array_misc_13.gold b/SBVTestSuite/GoldFiles/array_misc_13.gold
--- a/SBVTestSuite/GoldFiles/array_misc_13.gold
+++ b/SBVTestSuite/GoldFiles/array_misc_13.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/array_misc_14.gold b/SBVTestSuite/GoldFiles/array_misc_14.gold
--- a/SBVTestSuite/GoldFiles/array_misc_14.gold
+++ b/SBVTestSuite/GoldFiles/array_misc_14.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/array_misc_15.gold b/SBVTestSuite/GoldFiles/array_misc_15.gold
--- a/SBVTestSuite/GoldFiles/array_misc_15.gold
+++ b/SBVTestSuite/GoldFiles/array_misc_15.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/array_misc_16.gold b/SBVTestSuite/GoldFiles/array_misc_16.gold
--- a/SBVTestSuite/GoldFiles/array_misc_16.gold
+++ b/SBVTestSuite/GoldFiles/array_misc_16.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/array_misc_17.gold b/SBVTestSuite/GoldFiles/array_misc_17.gold
--- a/SBVTestSuite/GoldFiles/array_misc_17.gold
+++ b/SBVTestSuite/GoldFiles/array_misc_17.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/array_misc_18.gold b/SBVTestSuite/GoldFiles/array_misc_18.gold
--- a/SBVTestSuite/GoldFiles/array_misc_18.gold
+++ b/SBVTestSuite/GoldFiles/array_misc_18.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/array_misc_19.gold b/SBVTestSuite/GoldFiles/array_misc_19.gold
--- a/SBVTestSuite/GoldFiles/array_misc_19.gold
+++ b/SBVTestSuite/GoldFiles/array_misc_19.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/array_misc_2.gold b/SBVTestSuite/GoldFiles/array_misc_2.gold
--- a/SBVTestSuite/GoldFiles/array_misc_2.gold
+++ b/SBVTestSuite/GoldFiles/array_misc_2.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
@@ -40,7 +39,7 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (store (store ((as const (Array Int Int)) 4) 6 12) 3 5)))
+[RECV] ((s0 (store (store ((as const (Array Int Int)) 5) 2 4) 6 12)))
 [SEND] (get-value (s1))
 [RECV] ((s1 2))
 [SEND] (get-value (s2))
@@ -52,7 +51,7 @@
 
 FINAL OUTPUT:
 Satisfiable. Model:
-  s0 = ([(3,5),(6,12)], 4) :: Array Integer Integer
+  s0 = ([(6,12),(2,4)], 5) :: Array Integer Integer
   s1 =                   2 :: Integer
   s2 =                   3 :: Integer
   s3 =                   6 :: Integer
diff --git a/SBVTestSuite/GoldFiles/array_misc_20.gold b/SBVTestSuite/GoldFiles/array_misc_20.gold
--- a/SBVTestSuite/GoldFiles/array_misc_20.gold
+++ b/SBVTestSuite/GoldFiles/array_misc_20.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/array_misc_21.gold b/SBVTestSuite/GoldFiles/array_misc_21.gold
--- a/SBVTestSuite/GoldFiles/array_misc_21.gold
+++ b/SBVTestSuite/GoldFiles/array_misc_21.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/array_misc_22.gold b/SBVTestSuite/GoldFiles/array_misc_22.gold
--- a/SBVTestSuite/GoldFiles/array_misc_22.gold
+++ b/SBVTestSuite/GoldFiles/array_misc_22.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/array_misc_23.gold b/SBVTestSuite/GoldFiles/array_misc_23.gold
--- a/SBVTestSuite/GoldFiles/array_misc_23.gold
+++ b/SBVTestSuite/GoldFiles/array_misc_23.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/array_misc_24.gold b/SBVTestSuite/GoldFiles/array_misc_24.gold
--- a/SBVTestSuite/GoldFiles/array_misc_24.gold
+++ b/SBVTestSuite/GoldFiles/array_misc_24.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/array_misc_25.gold b/SBVTestSuite/GoldFiles/array_misc_25.gold
--- a/SBVTestSuite/GoldFiles/array_misc_25.gold
+++ b/SBVTestSuite/GoldFiles/array_misc_25.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/array_misc_26.gold b/SBVTestSuite/GoldFiles/array_misc_26.gold
--- a/SBVTestSuite/GoldFiles/array_misc_26.gold
+++ b/SBVTestSuite/GoldFiles/array_misc_26.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/array_misc_27.gold b/SBVTestSuite/GoldFiles/array_misc_27.gold
--- a/SBVTestSuite/GoldFiles/array_misc_27.gold
+++ b/SBVTestSuite/GoldFiles/array_misc_27.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/array_misc_28.gold b/SBVTestSuite/GoldFiles/array_misc_28.gold
--- a/SBVTestSuite/GoldFiles/array_misc_28.gold
+++ b/SBVTestSuite/GoldFiles/array_misc_28.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/array_misc_29.gold b/SBVTestSuite/GoldFiles/array_misc_29.gold
--- a/SBVTestSuite/GoldFiles/array_misc_29.gold
+++ b/SBVTestSuite/GoldFiles/array_misc_29.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/array_misc_3.gold b/SBVTestSuite/GoldFiles/array_misc_3.gold
--- a/SBVTestSuite/GoldFiles/array_misc_3.gold
+++ b/SBVTestSuite/GoldFiles/array_misc_3.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_BV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/array_misc_30.gold b/SBVTestSuite/GoldFiles/array_misc_30.gold
--- a/SBVTestSuite/GoldFiles/array_misc_30.gold
+++ b/SBVTestSuite/GoldFiles/array_misc_30.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/array_misc_31.gold b/SBVTestSuite/GoldFiles/array_misc_31.gold
--- a/SBVTestSuite/GoldFiles/array_misc_31.gold
+++ b/SBVTestSuite/GoldFiles/array_misc_31.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_BV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/array_misc_5.gold b/SBVTestSuite/GoldFiles/array_misc_5.gold
--- a/SBVTestSuite/GoldFiles/array_misc_5.gold
+++ b/SBVTestSuite/GoldFiles/array_misc_5.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; NB. User specified.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/array_misc_7.gold b/SBVTestSuite/GoldFiles/array_misc_7.gold
--- a/SBVTestSuite/GoldFiles/array_misc_7.gold
+++ b/SBVTestSuite/GoldFiles/array_misc_7.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_BV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/array_misc_9.gold b/SBVTestSuite/GoldFiles/array_misc_9.gold
--- a/SBVTestSuite/GoldFiles/array_misc_9.gold
+++ b/SBVTestSuite/GoldFiles/array_misc_9.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_BV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int16_Word16.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int16_Word16.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int16_Word16.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int16_Word16.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int16_Word32.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int16_Word32.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int16_Word32.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int16_Word32.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int16_Word64.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int16_Word64.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int16_Word64.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int16_Word64.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int16_Word8.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int16_Word8.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int16_Word8.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int16_Word8.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int32_Word16.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int32_Word16.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int32_Word16.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int32_Word16.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int32_Word32.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int32_Word32.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int32_Word32.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int32_Word32.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int32_Word64.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int32_Word64.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int32_Word64.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int32_Word64.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int32_Word8.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int32_Word8.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int32_Word8.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int32_Word8.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int64_Word16.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int64_Word16.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int64_Word16.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int64_Word16.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int64_Word32.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int64_Word32.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int64_Word32.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int64_Word32.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int64_Word64.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int64_Word64.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int64_Word64.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int64_Word64.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int64_Word8.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int64_Word8.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int64_Word8.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int64_Word8.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int8_Word16.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int8_Word16.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int8_Word16.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int8_Word16.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int8_Word32.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int8_Word32.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int8_Word32.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int8_Word32.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int8_Word64.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int8_Word64.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int8_Word64.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int8_Word64.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int8_Word8.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int8_Word8.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Int8_Word8.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Int8_Word8.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word16_Word16.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word16_Word16.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word16_Word16.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word16_Word16.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word16_Word32.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word16_Word32.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word16_Word32.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word16_Word32.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word16_Word64.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word16_Word64.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word16_Word64.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word16_Word64.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word16_Word8.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word16_Word8.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word16_Word8.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word16_Word8.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word32_Word16.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word32_Word16.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word32_Word16.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word32_Word16.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word32_Word32.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word32_Word32.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word32_Word32.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word32_Word32.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word32_Word64.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word32_Word64.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word32_Word64.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word32_Word64.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word32_Word8.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word32_Word8.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word32_Word8.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word32_Word8.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word64_Word16.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word64_Word16.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word64_Word16.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word64_Word16.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word64_Word32.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word64_Word32.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word64_Word32.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word64_Word32.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word64_Word64.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word64_Word64.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word64_Word64.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word64_Word64.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word64_Word8.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word64_Word8.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word64_Word8.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word64_Word8.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word8_Word16.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word8_Word16.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word8_Word16.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word8_Word16.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word8_Word32.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word8_Word32.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word8_Word32.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word8_Word32.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word8_Word64.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word8_Word64.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word8_Word64.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word8_Word64.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word8_Word8.gold b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word8_Word8.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Left_Word8_Word8.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Left_Word8_Word8.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int16_Word16.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int16_Word16.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int16_Word16.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int16_Word16.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int16_Word32.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int16_Word32.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int16_Word32.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int16_Word32.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int16_Word64.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int16_Word64.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int16_Word64.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int16_Word64.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int16_Word8.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int16_Word8.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int16_Word8.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int16_Word8.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int32_Word16.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int32_Word16.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int32_Word16.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int32_Word16.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int32_Word32.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int32_Word32.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int32_Word32.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int32_Word32.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int32_Word64.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int32_Word64.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int32_Word64.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int32_Word64.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int32_Word8.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int32_Word8.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int32_Word8.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int32_Word8.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int64_Word16.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int64_Word16.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int64_Word16.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int64_Word16.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int64_Word32.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int64_Word32.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int64_Word32.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int64_Word32.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int64_Word64.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int64_Word64.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int64_Word64.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int64_Word64.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int64_Word8.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int64_Word8.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int64_Word8.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int64_Word8.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int8_Word16.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int8_Word16.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int8_Word16.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int8_Word16.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int8_Word32.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int8_Word32.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int8_Word32.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int8_Word32.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int8_Word64.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int8_Word64.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int8_Word64.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int8_Word64.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int8_Word8.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int8_Word8.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Int8_Word8.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Int8_Word8.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word16_Word16.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word16_Word16.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word16_Word16.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word16_Word16.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word16_Word32.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word16_Word32.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word16_Word32.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word16_Word32.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word16_Word64.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word16_Word64.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word16_Word64.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word16_Word64.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word16_Word8.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word16_Word8.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word16_Word8.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word16_Word8.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word32_Word16.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word32_Word16.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word32_Word16.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word32_Word16.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word32_Word32.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word32_Word32.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word32_Word32.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word32_Word32.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word32_Word64.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word32_Word64.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word32_Word64.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word32_Word64.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word32_Word8.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word32_Word8.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word32_Word8.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word32_Word8.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word64_Word16.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word64_Word16.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word64_Word16.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word64_Word16.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word64_Word32.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word64_Word32.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word64_Word32.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word64_Word32.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word64_Word64.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word64_Word64.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word64_Word64.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word64_Word64.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word64_Word8.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word64_Word8.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word64_Word8.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word64_Word8.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word8_Word16.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word8_Word16.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word8_Word16.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word8_Word16.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word8_Word32.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word8_Word32.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word8_Word32.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word8_Word32.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word8_Word64.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word8_Word64.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word8_Word64.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word8_Word64.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word8_Word8.gold b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word8_Word8.gold
--- a/SBVTestSuite/GoldFiles/barrelRotate_Right_Word8_Word8.gold
+++ b/SBVTestSuite/GoldFiles/barrelRotate_Right_Word8_Word8.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/cgUninterpret.gold b/SBVTestSuite/GoldFiles/cgUninterpret.gold
--- a/SBVTestSuite/GoldFiles/cgUninterpret.gold
+++ b/SBVTestSuite/GoldFiles/cgUninterpret.gold
@@ -12,11 +12,11 @@
 tstShiftLeft.o: tstShiftLeft.c tstShiftLeft.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
-tstShiftLeft_driver.o: tstShiftLeft_driver.c
+tstShiftLeft_driver.o: tstShiftLeft_driver.c tstShiftLeft.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
 tstShiftLeft_driver: tstShiftLeft.o tstShiftLeft_driver.o
-	${CC} ${CCFLAGS} $^ -o $@
+	${CC} ${CCFLAGS} $^ -o $@ ${LDFLAGS}
 
 clean:
 	rm -f *.o
@@ -27,9 +27,10 @@
 == BEGIN: "tstShiftLeft.h" ================
 /* Header file for tstShiftLeft. Automatically generated by SBV. Do not edit! */
 
-#ifndef __tstShiftLeft__HEADER_INCLUDED__
-#define __tstShiftLeft__HEADER_INCLUDED__
+#ifndef SBV_GENERATED_tstShiftLeft_HEADER_INCLUDED
+#define SBV_GENERATED_tstShiftLeft_HEADER_INCLUDED
 
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <inttypes.h>
@@ -38,6 +39,13 @@
 #include <string.h>
 #include <math.h>
 
+/* Floating-point calling convention:
+ * Enter generated code in FE_TONEAREST (round-to-nearest, ties-to-even).
+ * Callbacks must preserve this mode before returning or re-entering.
+ * Generated code does not check or change the hardware rounding mode.
+ * Custom builds must disable implicit FP contraction, including at LTO link time.
+ */
+
 /* The boolean type */
 typedef bool SBool;
 
@@ -62,7 +70,7 @@
 /* Entry point prototype: */
 SWord32 tstShiftLeft(const SWord32 *vs);
 
-#endif /* __tstShiftLeft__HEADER_INCLUDED__ */
+#endif /* SBV_GENERATED_tstShiftLeft_HEADER_INCLUDED */
 == END: "tstShiftLeft.h" ==================
 == BEGIN: "tstShiftLeft_driver.c" ================
 /* Example driver program for tstShiftLeft. */
@@ -73,19 +81,22 @@
 
 int main(void)
 {
-  const SWord32 vs[3] = {
+  const SWord32 sbv_driver_input_0[3] = {
       0x00000001UL, 0x00000002UL, 0x00000003UL
   };
 
   printf("Contents of input array vs:\n");
-  int vs_ctr;
-  for(vs_ctr = 0; vs_ctr < 3 ; ++vs_ctr)
-    printf("  vs[%1d] = 0x%08"PRIx32"UL\n", vs_ctr ,vs[vs_ctr]);
+  int sbv_driver_input_0_ctr;
+  for(sbv_driver_input_0_ctr = 0; sbv_driver_input_0_ctr < 3 ; ++sbv_driver_input_0_ctr)
+  { printf("  vs[%1d] = ", sbv_driver_input_0_ctr);
+    printf("0x%08"PRIx32"UL", sbv_driver_input_0[sbv_driver_input_0_ctr]);
+    printf("\n");
+  }
 
 
-  const SWord32 __result = tstShiftLeft(vs);
+  const SWord32 sbv_result = tstShiftLeft(sbv_driver_input_0);
 
-  printf("tstShiftLeft(vs) = 0x%08"PRIx32"UL\n", __result);
+  printf("tstShiftLeft(vs) = 0x%08"PRIx32"UL\n", sbv_result);
 
   return 0;
 }
@@ -98,16 +109,33 @@
 /* User specified custom code for "SBV_SHIFTLEFT" */
 #define SBV_SHIFTLEFT(x, y) ((x) << (y))
 
-SWord32 tstShiftLeft(const SWord32 *vs)
+/* Exact bit-vector runtime. All arithmetic is modulo the declared width. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static inline SBV_CGEN_UNUSED SWord32 sbv_bv_u32_add(SWord32 a, SWord32 b)
 {
-  const SWord32 s0 = vs[0];
-  const SWord32 s1 = vs[1];
-  const SWord32 s2 = vs[2];
-  const SWord32 s3 = /* Uninterpreted function */ SBV_SHIFTLEFT(s0,
-                                                                s2);
-  const SWord32 s4 = /* Uninterpreted function */ SBV_SHIFTLEFT(s1,
-                                                                s2);
-  const SWord32 s5 = s3 + s4;
+  const SWord32 bits = (SWord32) ((((uint64_t) (SWord32) a) + ((uint64_t) (SWord32) b)) & UINT64_C(0x00000000ffffffff));
+  return (SWord32) bits;
+}
+
+
+SWord32 tstShiftLeft(const SWord32 *sbv_input_0)
+{
+  const SWord32 s0 = sbv_input_0[0];
+  const SWord32 s1 = sbv_input_0[1];
+  const SWord32 s2 = sbv_input_0[2];
+        SWord32 s3;
+        SWord32 s4;
+        SWord32 s5;
+  s3 = /* Uninterpreted function */ SBV_SHIFTLEFT(s0, s2);
+  s4 = /* Uninterpreted function */ SBV_SHIFTLEFT(s1, s2);
+  s5 = sbv_bv_u32_add(s3, s4);
 
   return s5;
 }
diff --git a/SBVTestSuite/GoldFiles/charConstr00.gold b/SBVTestSuite/GoldFiles/charConstr00.gold
--- a/SBVTestSuite/GoldFiles/charConstr00.gold
+++ b/SBVTestSuite/GoldFiles/charConstr00.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has chars, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/charConstr01.gold b/SBVTestSuite/GoldFiles/charConstr01.gold
--- a/SBVTestSuite/GoldFiles/charConstr01.gold
+++ b/SBVTestSuite/GoldFiles/charConstr01.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/charConstr02.gold b/SBVTestSuite/GoldFiles/charConstr02.gold
--- a/SBVTestSuite/GoldFiles/charConstr02.gold
+++ b/SBVTestSuite/GoldFiles/charConstr02.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple3 3)) ((par (T1 T2 T3)
                                            ((mkSBVTuple3 (proj_1_SBVTuple3 T1)
diff --git a/SBVTestSuite/GoldFiles/charConstr03.gold b/SBVTestSuite/GoldFiles/charConstr03.gold
--- a/SBVTestSuite/GoldFiles/charConstr03.gold
+++ b/SBVTestSuite/GoldFiles/charConstr03.gold
@@ -8,19 +8,21 @@
 [GOOD] (set-option :pp.max_depth      4294967295)
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
-[GOOD] (set-logic ALL) ; has either type, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] (set-logic ALL) ; has user-defined data-types, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
-[GOOD] (declare-datatypes ((SBVEither 2)) ((par (T1 T2)
-                                           ((left_SBVEither  (get_left_SBVEither  T1))
-                                            (right_SBVEither (get_right_SBVEither T2))))))
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Either
+[GOOD] (declare-datatype Either (par (a b) (
+           (Left (getLeft_1 a))
+           (Right (getRight_1 b))
+       )))
 [GOOD] ; --- literal constants ---
-[GOOD] (define-fun s1 () (SBVEither String String) ((as left_SBVEither (SBVEither String String)) (_ char #x41)))
+[GOOD] (define-fun s1 () (Either String String) ((as Left (Either String String)) (_ char #x41)))
 [GOOD] ; --- top level inputs ---
-[GOOD] (declare-fun s0 () (SBVEither String String)) ; tracks user variable "x"
-[GOOD] (assert (and (=> ((_ is (left_SBVEither (String) (SBVEither String String))) s0) (= 1 (str.len (get_left_SBVEither s0))))
-                    (=> ((_ is (right_SBVEither (String) (SBVEither String String))) s0) (= 1 (str.len (get_right_SBVEither s0))))
+[GOOD] (declare-fun s0 () (Either String String)) ; tracks user variable "x"
+[GOOD] (assert (and (= 1 (str.len (getLeft_1 s0)))
+                    (= 1 (str.len (getRight_1 s0)))
                ))
 [GOOD] ; --- constant tables ---
 [GOOD] ; --- non-constant tables ---
@@ -34,7 +36,7 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (left_SBVEither "B")))
+[RECV] ((s0 (Left "B")))
 
 MODEL: SMTModel {modelObjectives = [], modelBindings = Nothing, modelAssocs = [("x",Left 'B' :: Either Char Char)], modelUIFuns = []}
 DONE.*** Solver   : Z3
diff --git a/SBVTestSuite/GoldFiles/charConstr04.gold b/SBVTestSuite/GoldFiles/charConstr04.gold
--- a/SBVTestSuite/GoldFiles/charConstr04.gold
+++ b/SBVTestSuite/GoldFiles/charConstr04.gold
@@ -9,17 +9,19 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
-[GOOD] (declare-datatypes ((SBVEither 2)) ((par (T1 T2)
-                                           ((left_SBVEither  (get_left_SBVEither  T1))
-                                            (right_SBVEither (get_right_SBVEither T2))))))
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Either
+[GOOD] (declare-datatype Either (par (a b) (
+           (Left (getLeft_1 a))
+           (Right (getRight_1 b))
+       )))
 [GOOD] ; --- literal constants ---
-[GOOD] (define-fun s1 () (SBVEither Int String) ((as right_SBVEither (SBVEither Int String)) (_ char #x41)))
+[GOOD] (define-fun s1 () (Either Int String) ((as Right (Either Int String)) (_ char #x41)))
 [GOOD] ; --- top level inputs ---
-[GOOD] (declare-fun s0 () (SBVEither Int String)) ; tracks user variable "x"
-[GOOD] (assert (=> ((_ is (right_SBVEither (String) (SBVEither Int String))) s0) (= 1 (str.len (get_right_SBVEither s0)))))
+[GOOD] (declare-fun s0 () (Either Int String)) ; tracks user variable "x"
+[GOOD] (assert (= 1 (str.len (getRight_1 s0))))
 [GOOD] ; --- constant tables ---
 [GOOD] ; --- non-constant tables ---
 [GOOD] ; --- uninterpreted constants ---
@@ -32,7 +34,7 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (left_SBVEither 2)))
+[RECV] ((s0 (Left 2)))
 
 MODEL: SMTModel {modelObjectives = [], modelBindings = Nothing, modelAssocs = [("x",Left 2 :: Either Integer Char)], modelUIFuns = []}
 DONE.*** Solver   : Z3
diff --git a/SBVTestSuite/GoldFiles/charConstr05.gold b/SBVTestSuite/GoldFiles/charConstr05.gold
--- a/SBVTestSuite/GoldFiles/charConstr05.gold
+++ b/SBVTestSuite/GoldFiles/charConstr05.gold
@@ -9,17 +9,19 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
-[GOOD] (declare-datatypes ((SBVEither 2)) ((par (T1 T2)
-                                           ((left_SBVEither  (get_left_SBVEither  T1))
-                                            (right_SBVEither (get_right_SBVEither T2))))))
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Either
+[GOOD] (declare-datatype Either (par (a b) (
+           (Left (getLeft_1 a))
+           (Right (getRight_1 b))
+       )))
 [GOOD] ; --- literal constants ---
-[GOOD] (define-fun s1 () (SBVEither String Int) ((as left_SBVEither (SBVEither String Int)) (_ char #x41)))
+[GOOD] (define-fun s1 () (Either String Int) ((as Left (Either String Int)) (_ char #x41)))
 [GOOD] ; --- top level inputs ---
-[GOOD] (declare-fun s0 () (SBVEither String Int)) ; tracks user variable "x"
-[GOOD] (assert (=> ((_ is (left_SBVEither (String) (SBVEither String Int))) s0) (= 1 (str.len (get_left_SBVEither s0)))))
+[GOOD] (declare-fun s0 () (Either String Int)) ; tracks user variable "x"
+[GOOD] (assert (= 1 (str.len (getLeft_1 s0))))
 [GOOD] ; --- constant tables ---
 [GOOD] ; --- non-constant tables ---
 [GOOD] ; --- uninterpreted constants ---
@@ -32,8 +34,8 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (right_SBVEither 2)))
+[RECV] ((s0 (Left "B")))
 
-MODEL: SMTModel {modelObjectives = [], modelBindings = Nothing, modelAssocs = [("x",Right 2 :: Either Char Integer)], modelUIFuns = []}
+MODEL: SMTModel {modelObjectives = [], modelBindings = Nothing, modelAssocs = [("x",Left 'B' :: Either Char Integer)], modelUIFuns = []}
 DONE.*** Solver   : Z3
 *** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/charConstr06.gold b/SBVTestSuite/GoldFiles/charConstr06.gold
--- a/SBVTestSuite/GoldFiles/charConstr06.gold
+++ b/SBVTestSuite/GoldFiles/charConstr06.gold
@@ -9,18 +9,20 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
-[GOOD] (declare-datatypes ((SBVEither 2)) ((par (T1 T2)
-                                           ((left_SBVEither  (get_left_SBVEither  T1))
-                                            (right_SBVEither (get_right_SBVEither T2))))))
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Either
+[GOOD] (declare-datatype Either (par (a b) (
+           (Left (getLeft_1 a))
+           (Right (getRight_1 b))
+       )))
 [GOOD] ; --- literal constants ---
-[GOOD] (define-fun s1 () (SBVEither String (SBVEither String Int)) ((as left_SBVEither (SBVEither String (SBVEither String Int))) (_ char #x41)))
+[GOOD] (define-fun s1 () (Either String (Either String Int)) ((as Left (Either String (Either String Int))) (_ char #x41)))
 [GOOD] ; --- top level inputs ---
-[GOOD] (declare-fun s0 () (SBVEither String (SBVEither String Int))) ; tracks user variable "x"
-[GOOD] (assert (and (=> ((_ is (left_SBVEither (String) (SBVEither String (SBVEither String Int)))) s0) (= 1 (str.len (get_left_SBVEither s0))))
-                    (=> ((_ is (right_SBVEither ((SBVEither String Int)) (SBVEither String (SBVEither String Int)))) s0) (=> ((_ is (left_SBVEither (String) (SBVEither String Int))) (get_right_SBVEither s0)) (= 1 (str.len (get_left_SBVEither (get_right_SBVEither s0))))))
+[GOOD] (declare-fun s0 () (Either String (Either String Int))) ; tracks user variable "x"
+[GOOD] (assert (and (= 1 (str.len (getLeft_1 s0)))
+                    (= 1 (str.len (getLeft_1 (getRight_1 s0))))
                ))
 [GOOD] ; --- constant tables ---
 [GOOD] ; --- non-constant tables ---
@@ -34,7 +36,7 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 ((as left_SBVEither (SBVEither String (SBVEither String Int))) "B")))
+[RECV] ((s0 ((as Left (Either String (Either String Int))) "B")))
 
 MODEL: SMTModel {modelObjectives = [], modelBindings = Nothing, modelAssocs = [("x",Left 'B' :: Either Char (Either Char Integer))], modelUIFuns = []}
 DONE.*** Solver   : Z3
diff --git a/SBVTestSuite/GoldFiles/charConstr07.gold b/SBVTestSuite/GoldFiles/charConstr07.gold
--- a/SBVTestSuite/GoldFiles/charConstr07.gold
+++ b/SBVTestSuite/GoldFiles/charConstr07.gold
@@ -8,34 +8,35 @@
 [GOOD] (set-option :pp.max_depth      4294967295)
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
-[GOOD] (set-logic ALL) ; has maybe type, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] (set-logic ALL) ; has user-defined data-types, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
-[GOOD] (declare-datatypes ((SBVMaybe 1)) ((par (T)
-                                           ((nothing_SBVMaybe)
-                                            (just_SBVMaybe (get_just_SBVMaybe T))))))
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Maybe
+[GOOD] (declare-datatype Maybe (par (a) (
+           (Nothing)
+           (Just (getJust_1 a))
+       )))
 [GOOD] ; --- literal constants ---
-[GOOD] (define-fun s3 () (SBVMaybe String) ((as just_SBVMaybe (SBVMaybe String)) (_ char #x41)))
+[GOOD] (define-fun s2 () (Maybe String) ((as Just (Maybe String)) (_ char #x41)))
 [GOOD] ; --- top level inputs ---
-[GOOD] (declare-fun s0 () (SBVMaybe String)) ; tracks user variable "x"
-[GOOD] (assert (=> ((_ is (just_SBVMaybe (String) (SBVMaybe String))) s0) (= 1 (str.len (get_just_SBVMaybe s0)))))
+[GOOD] (declare-fun s0 () (Maybe String)) ; tracks user variable "x"
+[GOOD] (assert (= 1 (str.len (getJust_1 s0))))
 [GOOD] ; --- constant tables ---
 [GOOD] ; --- non-constant tables ---
 [GOOD] ; --- uninterpreted constants ---
 [GOOD] ; --- user defined functions ---
 [GOOD] ; --- assignments ---
-[GOOD] (define-fun s1 () Bool ((_ is (nothing_SBVMaybe () (SBVMaybe String))) s0))
-[GOOD] (define-fun s2 () Bool (ite s1 false true))
-[GOOD] (define-fun s4 () Bool (distinct s0 s3))
-[GOOD] (define-fun s5 () Bool (and s2 s4))
+[GOOD] (define-fun s1 () Bool ((as is-Just Bool) s0))
+[GOOD] (define-fun s3 () Bool (distinct s0 s2))
+[GOOD] (define-fun s4 () Bool (and s1 s3))
 [GOOD] ; --- delayedEqualities ---
 [GOOD] ; --- formula ---
-[GOOD] (assert s5)
+[GOOD] (assert s4)
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (just_SBVMaybe "B")))
+[RECV] ((s0 (Just "B")))
 
 MODEL: SMTModel {modelObjectives = [], modelBindings = Nothing, modelAssocs = [("x",Just 'B' :: Maybe Char)], modelUIFuns = []}
 DONE.*** Solver   : Z3
diff --git a/SBVTestSuite/GoldFiles/charConstr08.gold b/SBVTestSuite/GoldFiles/charConstr08.gold
--- a/SBVTestSuite/GoldFiles/charConstr08.gold
+++ b/SBVTestSuite/GoldFiles/charConstr08.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has sets, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/charConstr09.gold b/SBVTestSuite/GoldFiles/charConstr09.gold
--- a/SBVTestSuite/GoldFiles/charConstr09.gold
+++ b/SBVTestSuite/GoldFiles/charConstr09.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/charConstr10.gold b/SBVTestSuite/GoldFiles/charConstr10.gold
--- a/SBVTestSuite/GoldFiles/charConstr10.gold
+++ b/SBVTestSuite/GoldFiles/charConstr10.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/charConstr11.gold b/SBVTestSuite/GoldFiles/charConstr11.gold
--- a/SBVTestSuite/GoldFiles/charConstr11.gold
+++ b/SBVTestSuite/GoldFiles/charConstr11.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/check1.gold b/SBVTestSuite/GoldFiles/check1.gold
--- a/SBVTestSuite/GoldFiles/check1.gold
+++ b/SBVTestSuite/GoldFiles/check1.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_BV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/check2.gold b/SBVTestSuite/GoldFiles/check2.gold
--- a/SBVTestSuite/GoldFiles/check2.gold
+++ b/SBVTestSuite/GoldFiles/check2.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_BV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/codeGen1.gold b/SBVTestSuite/GoldFiles/codeGen1.gold
--- a/SBVTestSuite/GoldFiles/codeGen1.gold
+++ b/SBVTestSuite/GoldFiles/codeGen1.gold
@@ -12,11 +12,11 @@
 foo.o: foo.c foo.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
-foo_driver.o: foo_driver.c
+foo_driver.o: foo_driver.c foo.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
 foo_driver: foo.o foo_driver.o
-	${CC} ${CCFLAGS} $^ -o $@
+	${CC} ${CCFLAGS} $^ -o $@ ${LDFLAGS}
 
 clean:
 	rm -f *.o
@@ -27,9 +27,10 @@
 == BEGIN: "foo.h" ================
 /* Header file for foo. Automatically generated by SBV. Do not edit! */
 
-#ifndef __foo__HEADER_INCLUDED__
-#define __foo__HEADER_INCLUDED__
+#ifndef SBV_GENERATED_foo_HEADER_INCLUDED
+#define SBV_GENERATED_foo_HEADER_INCLUDED
 
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <inttypes.h>
@@ -38,6 +39,13 @@
 #include <string.h>
 #include <math.h>
 
+/* Floating-point calling convention:
+ * Enter generated code in FE_TONEAREST (round-to-nearest, ties-to-even).
+ * Callbacks must preserve this mode before returning or re-entering.
+ * Generated code does not check or change the hardware rounding mode.
+ * Custom builds must disable implicit FP contraction, including at LTO link time.
+ */
+
 /* The boolean type */
 typedef bool SBool;
 
@@ -63,7 +71,7 @@
 SInt16 foo(const SInt16 x, const SInt64 *xArr, SWord16 *z,
            SInt16 *zArr, SInt64 *yArr);
 
-#endif /* __foo__HEADER_INCLUDED__ */
+#endif /* SBV_GENERATED_foo_HEADER_INCLUDED */
 == END: "foo.h" ==================
 == BEGIN: "foo_driver.c" ================
 /* Example driver program for foo. */
@@ -74,7 +82,7 @@
 
 int main(void)
 {
-  const SInt64 xArr[45] = {
+  const SInt64 sbv_driver_input_1[45] = {
       0x0000000000000000LL, 0x0000000000000000LL, 0x0000000000000000LL,
       0x0000000000000000LL, 0x0000000000000000LL, 0x0000000000000000LL,
       0x0000000000000000LL, 0x0000000000000000LL, 0x0000000000000000LL,
@@ -93,24 +101,34 @@
   };
 
   printf("Contents of input array xArr:\n");
-  int xArr_ctr;
-  for(xArr_ctr = 0; xArr_ctr < 45 ; ++xArr_ctr)
-    printf("  xArr[%2d] = %"PRId64"LL\n", xArr_ctr ,xArr[xArr_ctr]);
+  int sbv_driver_input_1_ctr;
+  for(sbv_driver_input_1_ctr = 0; sbv_driver_input_1_ctr < 45 ; ++sbv_driver_input_1_ctr)
+  { printf("  xArr[%2d] = ", sbv_driver_input_1_ctr);
+    printf("%"PRId64"LL", sbv_driver_input_1[sbv_driver_input_1_ctr]);
+    printf("\n");
+  }
 
-  SWord16 z;
-  SInt16 zArr[7];
-  SInt64 yArr[45];
+  SWord16 sbv_driver_output_0;
+  SInt16 sbv_driver_output_1[7];
+  SInt64 sbv_driver_output_2[45];
 
-  const SInt16 __result = foo(0x0000, xArr, &z, zArr, yArr);
+  const SInt16 sbv_result = foo(0x0000, sbv_driver_input_1,
+                                &sbv_driver_output_0, sbv_driver_output_1, sbv_driver_output_2);
 
-  printf("foo(0x0000, xArr, &z, zArr, yArr) = %"PRId16"\n", __result);
-  printf("  z = 0x%04"PRIx16"U\n", z);
-  int zArr_ctr;
-  for(zArr_ctr = 0; zArr_ctr < 7 ; ++zArr_ctr)
-    printf("  zArr[%1d] = %"PRId16"\n", zArr_ctr ,zArr[zArr_ctr]);
-  int yArr_ctr;
-  for(yArr_ctr = 0; yArr_ctr < 45 ; ++yArr_ctr)
-    printf("  yArr[%2d] = %"PRId64"LL\n", yArr_ctr ,yArr[yArr_ctr]);
+  printf("foo(0x0000, xArr, &z, zArr, yArr) = %"PRId16"\n", sbv_result);
+  printf("  z = 0x%04"PRIx16"U\n", sbv_driver_output_0);
+  int sbv_driver_output_1_ctr;
+  for(sbv_driver_output_1_ctr = 0; sbv_driver_output_1_ctr < 7 ; ++sbv_driver_output_1_ctr)
+  { printf("  zArr[%1d] = ", sbv_driver_output_1_ctr);
+    printf("%"PRId16"", sbv_driver_output_1[sbv_driver_output_1_ctr]);
+    printf("\n");
+  }
+  int sbv_driver_output_2_ctr;
+  for(sbv_driver_output_2_ctr = 0; sbv_driver_output_2_ctr < 45 ; ++sbv_driver_output_2_ctr)
+  { printf("  yArr[%2d] = ", sbv_driver_output_2_ctr);
+    printf("%"PRId64"LL", sbv_driver_output_2[sbv_driver_output_2_ctr]);
+    printf("\n");
+  }
 
   return 0;
 }
@@ -120,111 +138,133 @@
 
 #include "foo.h"
 
-SInt16 foo(const SInt16 x, const SInt64 *xArr, SWord16 *z,
-           SInt16 *zArr, SInt64 *yArr)
+/* Exact bit-vector runtime. All arithmetic is modulo the declared width. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static inline SBV_CGEN_UNUSED SInt16 sbv_bv_s16_add(SInt16 a, SInt16 b)
 {
-  const SInt16 s0 = x;
-  const SInt64 s1 = xArr[0];
-  const SInt64 s2 = xArr[1];
-  const SInt64 s3 = xArr[2];
-  const SInt64 s4 = xArr[3];
-  const SInt64 s5 = xArr[4];
-  const SInt64 s6 = xArr[5];
-  const SInt64 s7 = xArr[6];
-  const SInt64 s8 = xArr[7];
-  const SInt64 s9 = xArr[8];
-  const SInt64 s10 = xArr[9];
-  const SInt64 s11 = xArr[10];
-  const SInt64 s12 = xArr[11];
-  const SInt64 s13 = xArr[12];
-  const SInt64 s14 = xArr[13];
-  const SInt64 s15 = xArr[14];
-  const SInt64 s16 = xArr[15];
-  const SInt64 s17 = xArr[16];
-  const SInt64 s18 = xArr[17];
-  const SInt64 s19 = xArr[18];
-  const SInt64 s20 = xArr[19];
-  const SInt64 s21 = xArr[20];
-  const SInt64 s22 = xArr[21];
-  const SInt64 s23 = xArr[22];
-  const SInt64 s24 = xArr[23];
-  const SInt64 s25 = xArr[24];
-  const SInt64 s26 = xArr[25];
-  const SInt64 s27 = xArr[26];
-  const SInt64 s28 = xArr[27];
-  const SInt64 s29 = xArr[28];
-  const SInt64 s30 = xArr[29];
-  const SInt64 s31 = xArr[30];
-  const SInt64 s32 = xArr[31];
-  const SInt64 s33 = xArr[32];
-  const SInt64 s34 = xArr[33];
-  const SInt64 s35 = xArr[34];
-  const SInt64 s36 = xArr[35];
-  const SInt64 s37 = xArr[36];
-  const SInt64 s38 = xArr[37];
-  const SInt64 s39 = xArr[38];
-  const SInt64 s40 = xArr[39];
-  const SInt64 s41 = xArr[40];
-  const SInt64 s42 = xArr[41];
-  const SInt64 s43 = xArr[42];
-  const SInt64 s44 = xArr[43];
-  const SInt64 s45 = xArr[44];
-  const SInt16 s48 = s0 + 0x0001;
-  const SInt16 s50 = s0 * 0x0002;
+  const SWord16 bits = (SWord16) ((((uint64_t) (SWord16) a) + ((uint64_t) (SWord16) b)) & UINT64_C(0x000000000000ffff));
+  SInt16 result; memcpy(&result, &bits, sizeof result); return result;
+}
 
-  *z = 0x0005U;
-  zArr[0] = s48;
-  zArr[1] = s48;
-  zArr[2] = s48;
-  zArr[3] = s48;
-  zArr[4] = s48;
-  zArr[5] = s48;
-  zArr[6] = s48;
-  yArr[0] = s1;
-  yArr[1] = s2;
-  yArr[2] = s3;
-  yArr[3] = s4;
-  yArr[4] = s5;
-  yArr[5] = s6;
-  yArr[6] = s7;
-  yArr[7] = s8;
-  yArr[8] = s9;
-  yArr[9] = s10;
-  yArr[10] = s11;
-  yArr[11] = s12;
-  yArr[12] = s13;
-  yArr[13] = s14;
-  yArr[14] = s15;
-  yArr[15] = s16;
-  yArr[16] = s17;
-  yArr[17] = s18;
-  yArr[18] = s19;
-  yArr[19] = s20;
-  yArr[20] = s21;
-  yArr[21] = s22;
-  yArr[22] = s23;
-  yArr[23] = s24;
-  yArr[24] = s25;
-  yArr[25] = s26;
-  yArr[26] = s27;
-  yArr[27] = s28;
-  yArr[28] = s29;
-  yArr[29] = s30;
-  yArr[30] = s31;
-  yArr[31] = s32;
-  yArr[32] = s33;
-  yArr[33] = s34;
-  yArr[34] = s35;
-  yArr[35] = s36;
-  yArr[36] = s37;
-  yArr[37] = s38;
-  yArr[38] = s39;
-  yArr[39] = s40;
-  yArr[40] = s41;
-  yArr[41] = s42;
-  yArr[42] = s43;
-  yArr[43] = s44;
-  yArr[44] = s45;
+static inline SBV_CGEN_UNUSED SInt16 sbv_bv_s16_mul(SInt16 a, SInt16 b)
+{
+  const SWord16 bits = (SWord16) ((((uint64_t) (SWord16) a) * ((uint64_t) (SWord16) b)) & UINT64_C(0x000000000000ffff));
+  SInt16 result; memcpy(&result, &bits, sizeof result); return result;
+}
+
+
+SInt16 foo(const SInt16 sbv_input_0, const SInt64 *sbv_input_1,
+           SWord16 *sbv_output_0, SInt16 *sbv_output_1, SInt64 *sbv_output_2)
+{
+  const SInt16 s0 = sbv_input_0;
+  const SInt64 s1 = sbv_input_1[0];
+  const SInt64 s2 = sbv_input_1[1];
+  const SInt64 s3 = sbv_input_1[2];
+  const SInt64 s4 = sbv_input_1[3];
+  const SInt64 s5 = sbv_input_1[4];
+  const SInt64 s6 = sbv_input_1[5];
+  const SInt64 s7 = sbv_input_1[6];
+  const SInt64 s8 = sbv_input_1[7];
+  const SInt64 s9 = sbv_input_1[8];
+  const SInt64 s10 = sbv_input_1[9];
+  const SInt64 s11 = sbv_input_1[10];
+  const SInt64 s12 = sbv_input_1[11];
+  const SInt64 s13 = sbv_input_1[12];
+  const SInt64 s14 = sbv_input_1[13];
+  const SInt64 s15 = sbv_input_1[14];
+  const SInt64 s16 = sbv_input_1[15];
+  const SInt64 s17 = sbv_input_1[16];
+  const SInt64 s18 = sbv_input_1[17];
+  const SInt64 s19 = sbv_input_1[18];
+  const SInt64 s20 = sbv_input_1[19];
+  const SInt64 s21 = sbv_input_1[20];
+  const SInt64 s22 = sbv_input_1[21];
+  const SInt64 s23 = sbv_input_1[22];
+  const SInt64 s24 = sbv_input_1[23];
+  const SInt64 s25 = sbv_input_1[24];
+  const SInt64 s26 = sbv_input_1[25];
+  const SInt64 s27 = sbv_input_1[26];
+  const SInt64 s28 = sbv_input_1[27];
+  const SInt64 s29 = sbv_input_1[28];
+  const SInt64 s30 = sbv_input_1[29];
+  const SInt64 s31 = sbv_input_1[30];
+  const SInt64 s32 = sbv_input_1[31];
+  const SInt64 s33 = sbv_input_1[32];
+  const SInt64 s34 = sbv_input_1[33];
+  const SInt64 s35 = sbv_input_1[34];
+  const SInt64 s36 = sbv_input_1[35];
+  const SInt64 s37 = sbv_input_1[36];
+  const SInt64 s38 = sbv_input_1[37];
+  const SInt64 s39 = sbv_input_1[38];
+  const SInt64 s40 = sbv_input_1[39];
+  const SInt64 s41 = sbv_input_1[40];
+  const SInt64 s42 = sbv_input_1[41];
+  const SInt64 s43 = sbv_input_1[42];
+  const SInt64 s44 = sbv_input_1[43];
+  const SInt64 s45 = sbv_input_1[44];
+  const SInt16 s48 = sbv_bv_s16_add(s0, 0x0001);
+  const SInt16 s50 = sbv_bv_s16_mul(s0, 0x0002);
+
+  *sbv_output_0 = 0x0005U;
+  sbv_output_1[0] = s48;
+  sbv_output_1[1] = s48;
+  sbv_output_1[2] = s48;
+  sbv_output_1[3] = s48;
+  sbv_output_1[4] = s48;
+  sbv_output_1[5] = s48;
+  sbv_output_1[6] = s48;
+  sbv_output_2[0] = s1;
+  sbv_output_2[1] = s2;
+  sbv_output_2[2] = s3;
+  sbv_output_2[3] = s4;
+  sbv_output_2[4] = s5;
+  sbv_output_2[5] = s6;
+  sbv_output_2[6] = s7;
+  sbv_output_2[7] = s8;
+  sbv_output_2[8] = s9;
+  sbv_output_2[9] = s10;
+  sbv_output_2[10] = s11;
+  sbv_output_2[11] = s12;
+  sbv_output_2[12] = s13;
+  sbv_output_2[13] = s14;
+  sbv_output_2[14] = s15;
+  sbv_output_2[15] = s16;
+  sbv_output_2[16] = s17;
+  sbv_output_2[17] = s18;
+  sbv_output_2[18] = s19;
+  sbv_output_2[19] = s20;
+  sbv_output_2[20] = s21;
+  sbv_output_2[21] = s22;
+  sbv_output_2[22] = s23;
+  sbv_output_2[23] = s24;
+  sbv_output_2[24] = s25;
+  sbv_output_2[25] = s26;
+  sbv_output_2[26] = s27;
+  sbv_output_2[27] = s28;
+  sbv_output_2[28] = s29;
+  sbv_output_2[29] = s30;
+  sbv_output_2[30] = s31;
+  sbv_output_2[31] = s32;
+  sbv_output_2[32] = s33;
+  sbv_output_2[33] = s34;
+  sbv_output_2[34] = s35;
+  sbv_output_2[35] = s36;
+  sbv_output_2[36] = s37;
+  sbv_output_2[37] = s38;
+  sbv_output_2[38] = s39;
+  sbv_output_2[39] = s40;
+  sbv_output_2[40] = s41;
+  sbv_output_2[41] = s42;
+  sbv_output_2[42] = s43;
+  sbv_output_2[43] = s44;
+  sbv_output_2[44] = s45;
   return s50;
 }
 == END: "foo.c" ==================
diff --git a/SBVTestSuite/GoldFiles/constArr2_SArray.gold b/SBVTestSuite/GoldFiles/constArr2_SArray.gold
--- a/SBVTestSuite/GoldFiles/constArr2_SArray.gold
+++ b/SBVTestSuite/GoldFiles/constArr2_SArray.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/constArr_SArray.gold b/SBVTestSuite/GoldFiles/constArr_SArray.gold
--- a/SBVTestSuite/GoldFiles/constArr_SArray.gold
+++ b/SBVTestSuite/GoldFiles/constArr_SArray.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/crcUSB5_1.gold b/SBVTestSuite/GoldFiles/crcUSB5_1.gold
--- a/SBVTestSuite/GoldFiles/crcUSB5_1.gold
+++ b/SBVTestSuite/GoldFiles/crcUSB5_1.gold
@@ -12,11 +12,11 @@
 crcUSB5.o: crcUSB5.c crcUSB5.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
-crcUSB5_driver.o: crcUSB5_driver.c
+crcUSB5_driver.o: crcUSB5_driver.c crcUSB5.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
 crcUSB5_driver: crcUSB5.o crcUSB5_driver.o
-	${CC} ${CCFLAGS} $^ -o $@
+	${CC} ${CCFLAGS} $^ -o $@ ${LDFLAGS}
 
 clean:
 	rm -f *.o
@@ -27,9 +27,10 @@
 == BEGIN: "crcUSB5.h" ================
 /* Header file for crcUSB5. Automatically generated by SBV. Do not edit! */
 
-#ifndef __crcUSB5__HEADER_INCLUDED__
-#define __crcUSB5__HEADER_INCLUDED__
+#ifndef SBV_GENERATED_crcUSB5_HEADER_INCLUDED
+#define SBV_GENERATED_crcUSB5_HEADER_INCLUDED
 
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <inttypes.h>
@@ -38,6 +39,13 @@
 #include <string.h>
 #include <math.h>
 
+/* Floating-point calling convention:
+ * Enter generated code in FE_TONEAREST (round-to-nearest, ties-to-even).
+ * Callbacks must preserve this mode before returning or re-entering.
+ * Generated code does not check or change the hardware rounding mode.
+ * Custom builds must disable implicit FP contraction, including at LTO link time.
+ */
+
 /* The boolean type */
 typedef bool SBool;
 
@@ -62,7 +70,7 @@
 /* Entry point prototype: */
 SWord16 crcUSB5(const SWord16 msg);
 
-#endif /* __crcUSB5__HEADER_INCLUDED__ */
+#endif /* SBV_GENERATED_crcUSB5_HEADER_INCLUDED */
 == END: "crcUSB5.h" ==================
 == BEGIN: "crcUSB5_driver.c" ================
 /* Example driver program for crcUSB5. */
@@ -73,9 +81,9 @@
 
 int main(void)
 {
-  const SWord16 __result = crcUSB5(0xfedcU);
+  const SWord16 sbv_result = crcUSB5(0xfedcU);
 
-  printf("crcUSB5(0xfedcU) = 0x%04"PRIx16"U\n", __result);
+  printf("crcUSB5(0xfedcU) = 0x%04"PRIx16"U\n", sbv_result);
 
   return 0;
 }
@@ -85,30 +93,128 @@
 
 #include "crcUSB5.h"
 
-SWord16 crcUSB5(const SWord16 msg)
+/* Exact bit-vector runtime. All arithmetic is modulo the declared width. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static inline SBV_CGEN_UNUSED SBool sbv_bv_extract_u16_10_10_u1(SWord16 a)
 {
-  const SWord16 s0 = msg;
-  const SBool   s1 = (SBool) ((s0 >> 10) & 1);
+  SBool r = (SBool) 0;
+  uint64_t i;
+  for (i = 0; i < 1; ++i) { r = (SBool) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 10)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SBool sbv_bv_extract_u16_9_9_u1(SWord16 a)
+{
+  SBool r = (SBool) 0;
+  uint64_t i;
+  for (i = 0; i < 1; ++i) { r = (SBool) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 9)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SBool sbv_bv_extract_u16_8_8_u1(SWord16 a)
+{
+  SBool r = (SBool) 0;
+  uint64_t i;
+  for (i = 0; i < 1; ++i) { r = (SBool) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 8)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SBool sbv_bv_extract_u16_7_7_u1(SWord16 a)
+{
+  SBool r = (SBool) 0;
+  uint64_t i;
+  for (i = 0; i < 1; ++i) { r = (SBool) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 7)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SBool sbv_bv_extract_u16_6_6_u1(SWord16 a)
+{
+  SBool r = (SBool) 0;
+  uint64_t i;
+  for (i = 0; i < 1; ++i) { r = (SBool) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 6)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SBool sbv_bv_extract_u16_5_5_u1(SWord16 a)
+{
+  SBool r = (SBool) 0;
+  uint64_t i;
+  for (i = 0; i < 1; ++i) { r = (SBool) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 5)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SBool sbv_bv_extract_u16_4_4_u1(SWord16 a)
+{
+  SBool r = (SBool) 0;
+  uint64_t i;
+  for (i = 0; i < 1; ++i) { r = (SBool) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 4)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SBool sbv_bv_extract_u16_3_3_u1(SWord16 a)
+{
+  SBool r = (SBool) 0;
+  uint64_t i;
+  for (i = 0; i < 1; ++i) { r = (SBool) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 3)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SBool sbv_bv_extract_u16_2_2_u1(SWord16 a)
+{
+  SBool r = (SBool) 0;
+  uint64_t i;
+  for (i = 0; i < 1; ++i) { r = (SBool) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 2)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SBool sbv_bv_extract_u16_1_1_u1(SWord16 a)
+{
+  SBool r = (SBool) 0;
+  uint64_t i;
+  for (i = 0; i < 1; ++i) { r = (SBool) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 1)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SBool sbv_bv_extract_u16_0_0_u1(SWord16 a)
+{
+  SBool r = (SBool) 0;
+  uint64_t i;
+  for (i = 0; i < 1; ++i) { r = (SBool) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+
+SWord16 crcUSB5(const SWord16 sbv_input_0)
+{
+  const SWord16 s0 = sbv_input_0;
+  const SBool   s1 = sbv_bv_extract_u16_10_10_u1(s0);
   const SBool   s3 = s1 != false;
-  const SBool   s4 = (SBool) ((s0 >> 9) & 1);
+  const SBool   s4 = sbv_bv_extract_u16_9_9_u1(s0);
   const SBool   s5 = false != s4;
-  const SBool   s6 = (SBool) ((s0 >> 8) & 1);
+  const SBool   s6 = sbv_bv_extract_u16_8_8_u1(s0);
   const SBool   s7 = false != s6;
-  const SBool   s8 = (SBool) ((s0 >> 7) & 1);
+  const SBool   s8 = sbv_bv_extract_u16_7_7_u1(s0);
   const SBool   s9 = false != s8;
-  const SBool   s10 = (SBool) ((s0 >> 6) & 1);
+  const SBool   s10 = sbv_bv_extract_u16_6_6_u1(s0);
   const SBool   s11 = false != s10;
-  const SBool   s12 = (SBool) ((s0 >> 5) & 1);
+  const SBool   s12 = sbv_bv_extract_u16_5_5_u1(s0);
   const SBool   s13 = false != s12;
-  const SBool   s14 = (SBool) ((s0 >> 4) & 1);
+  const SBool   s14 = sbv_bv_extract_u16_4_4_u1(s0);
   const SBool   s15 = false != s14;
-  const SBool   s16 = (SBool) ((s0 >> 3) & 1);
+  const SBool   s16 = sbv_bv_extract_u16_3_3_u1(s0);
   const SBool   s17 = false != s16;
-  const SBool   s18 = (SBool) ((s0 >> 2) & 1);
+  const SBool   s18 = sbv_bv_extract_u16_2_2_u1(s0);
   const SBool   s19 = false != s18;
-  const SBool   s20 = (SBool) ((s0 >> 1) & 1);
+  const SBool   s20 = sbv_bv_extract_u16_1_1_u1(s0);
   const SBool   s21 = false != s20;
-  const SBool   s22 = (SBool) (s0 & 1);
+  const SBool   s22 = sbv_bv_extract_u16_0_0_u1(s0);
   const SBool   s23 = false != s22;
   const SBool   s24 = !s9;
   const SBool   s25 = s3 ? s24 : s9;
diff --git a/SBVTestSuite/GoldFiles/crcUSB5_2.gold b/SBVTestSuite/GoldFiles/crcUSB5_2.gold
--- a/SBVTestSuite/GoldFiles/crcUSB5_2.gold
+++ b/SBVTestSuite/GoldFiles/crcUSB5_2.gold
@@ -12,11 +12,11 @@
 crcUSB5.o: crcUSB5.c crcUSB5.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
-crcUSB5_driver.o: crcUSB5_driver.c
+crcUSB5_driver.o: crcUSB5_driver.c crcUSB5.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
 crcUSB5_driver: crcUSB5.o crcUSB5_driver.o
-	${CC} ${CCFLAGS} $^ -o $@
+	${CC} ${CCFLAGS} $^ -o $@ ${LDFLAGS}
 
 clean:
 	rm -f *.o
@@ -27,9 +27,10 @@
 == BEGIN: "crcUSB5.h" ================
 /* Header file for crcUSB5. Automatically generated by SBV. Do not edit! */
 
-#ifndef __crcUSB5__HEADER_INCLUDED__
-#define __crcUSB5__HEADER_INCLUDED__
+#ifndef SBV_GENERATED_crcUSB5_HEADER_INCLUDED
+#define SBV_GENERATED_crcUSB5_HEADER_INCLUDED
 
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <inttypes.h>
@@ -38,6 +39,13 @@
 #include <string.h>
 #include <math.h>
 
+/* Floating-point calling convention:
+ * Enter generated code in FE_TONEAREST (round-to-nearest, ties-to-even).
+ * Callbacks must preserve this mode before returning or re-entering.
+ * Generated code does not check or change the hardware rounding mode.
+ * Custom builds must disable implicit FP contraction, including at LTO link time.
+ */
+
 /* The boolean type */
 typedef bool SBool;
 
@@ -62,7 +70,7 @@
 /* Entry point prototype: */
 SWord16 crcUSB5(const SWord16 msg);
 
-#endif /* __crcUSB5__HEADER_INCLUDED__ */
+#endif /* SBV_GENERATED_crcUSB5_HEADER_INCLUDED */
 == END: "crcUSB5.h" ==================
 == BEGIN: "crcUSB5_driver.c" ================
 /* Example driver program for crcUSB5. */
@@ -73,9 +81,9 @@
 
 int main(void)
 {
-  const SWord16 __result = crcUSB5(0xfedcU);
+  const SWord16 sbv_result = crcUSB5(0xfedcU);
 
-  printf("crcUSB5(0xfedcU) = 0x%04"PRIx16"U\n", __result);
+  printf("crcUSB5(0xfedcU) = 0x%04"PRIx16"U\n", sbv_result);
 
   return 0;
 }
@@ -85,55 +93,206 @@
 
 #include "crcUSB5.h"
 
-SWord16 crcUSB5(const SWord16 msg)
+/* Exact bit-vector runtime. All arithmetic is modulo the declared width. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static inline SBV_CGEN_UNUSED SWord16 sbv_bv_u16_shl(SWord16 a, SWord16 amount)
 {
-  const SWord16 s0 = msg;
-  const SWord16 s2 = s0 << 5;
-  const SBool   s3 = (SBool) ((s2 >> 15) & 1);
+  const uint64_t n = (uint64_t) (SWord16) amount;
+  const SWord16 result = n >= 16 ? (SWord16) 0 : (SWord16) ((uint64_t) (SWord16) a << n);
+  return result;
+}
+
+static inline SBV_CGEN_UNUSED SWord16 sbv_bv_u16_lshr(SWord16 a, SWord16 amount)
+{
+  const uint64_t n = (uint64_t) (SWord16) amount;
+  return n >= 16 ? (SWord16) 0 : (SWord16) ((uint64_t) (SWord16) a >> n);
+}
+
+static inline SBV_CGEN_UNUSED SBool sbv_bv_extract_u16_15_15_u1(SWord16 a)
+{
+  SBool r = (SBool) 0;
+  uint64_t i;
+  for (i = 0; i < 1; ++i) { r = (SBool) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 15)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SBool sbv_bv_extract_u16_14_14_u1(SWord16 a)
+{
+  SBool r = (SBool) 0;
+  uint64_t i;
+  for (i = 0; i < 1; ++i) { r = (SBool) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 14)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SBool sbv_bv_extract_u16_13_13_u1(SWord16 a)
+{
+  SBool r = (SBool) 0;
+  uint64_t i;
+  for (i = 0; i < 1; ++i) { r = (SBool) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 13)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SBool sbv_bv_extract_u16_12_12_u1(SWord16 a)
+{
+  SBool r = (SBool) 0;
+  uint64_t i;
+  for (i = 0; i < 1; ++i) { r = (SBool) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 12)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SBool sbv_bv_extract_u16_11_11_u1(SWord16 a)
+{
+  SBool r = (SBool) 0;
+  uint64_t i;
+  for (i = 0; i < 1; ++i) { r = (SBool) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 11)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SBool sbv_bv_extract_u16_10_10_u1(SWord16 a)
+{
+  SBool r = (SBool) 0;
+  uint64_t i;
+  for (i = 0; i < 1; ++i) { r = (SBool) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 10)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SBool sbv_bv_extract_u16_9_9_u1(SWord16 a)
+{
+  SBool r = (SBool) 0;
+  uint64_t i;
+  for (i = 0; i < 1; ++i) { r = (SBool) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 9)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SBool sbv_bv_extract_u16_8_8_u1(SWord16 a)
+{
+  SBool r = (SBool) 0;
+  uint64_t i;
+  for (i = 0; i < 1; ++i) { r = (SBool) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 8)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SBool sbv_bv_extract_u16_7_7_u1(SWord16 a)
+{
+  SBool r = (SBool) 0;
+  uint64_t i;
+  for (i = 0; i < 1; ++i) { r = (SBool) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 7)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SBool sbv_bv_extract_u16_6_6_u1(SWord16 a)
+{
+  SBool r = (SBool) 0;
+  uint64_t i;
+  for (i = 0; i < 1; ++i) { r = (SBool) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 6)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SBool sbv_bv_extract_u16_5_5_u1(SWord16 a)
+{
+  SBool r = (SBool) 0;
+  uint64_t i;
+  for (i = 0; i < 1; ++i) { r = (SBool) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 5)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SBool sbv_bv_extract_u16_4_4_u1(SWord16 a)
+{
+  SBool r = (SBool) 0;
+  uint64_t i;
+  for (i = 0; i < 1; ++i) { r = (SBool) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 4)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SBool sbv_bv_extract_u16_3_3_u1(SWord16 a)
+{
+  SBool r = (SBool) 0;
+  uint64_t i;
+  for (i = 0; i < 1; ++i) { r = (SBool) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 3)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SBool sbv_bv_extract_u16_2_2_u1(SWord16 a)
+{
+  SBool r = (SBool) 0;
+  uint64_t i;
+  for (i = 0; i < 1; ++i) { r = (SBool) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 2)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SBool sbv_bv_extract_u16_1_1_u1(SWord16 a)
+{
+  SBool r = (SBool) 0;
+  uint64_t i;
+  for (i = 0; i < 1; ++i) { r = (SBool) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 1)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SBool sbv_bv_extract_u16_0_0_u1(SWord16 a)
+{
+  SBool r = (SBool) 0;
+  uint64_t i;
+  for (i = 0; i < 1; ++i) { r = (SBool) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+
+SWord16 crcUSB5(const SWord16 sbv_input_0)
+{
+  const SWord16 s0 = sbv_input_0;
+  const SWord16 s2 = sbv_bv_u16_shl(s0, 0x0005U);
+  const SBool   s3 = sbv_bv_extract_u16_15_15_u1(s2);
   const SBool   s5 = s3 != false;
-  const SBool   s6 = (SBool) ((s2 >> 14) & 1);
+  const SBool   s6 = sbv_bv_extract_u16_14_14_u1(s2);
   const SBool   s7 = false != s6;
-  const SBool   s8 = (SBool) ((s2 >> 13) & 1);
+  const SBool   s8 = sbv_bv_extract_u16_13_13_u1(s2);
   const SBool   s9 = false != s8;
-  const SBool   s10 = (SBool) ((s2 >> 12) & 1);
+  const SBool   s10 = sbv_bv_extract_u16_12_12_u1(s2);
   const SBool   s11 = false != s10;
   const SBool   s12 = !s11;
   const SBool   s13 = s5 ? s12 : s11;
-  const SBool   s14 = (SBool) ((s2 >> 11) & 1);
+  const SBool   s14 = sbv_bv_extract_u16_11_11_u1(s2);
   const SBool   s15 = false != s14;
   const SBool   s16 = !s15;
   const SBool   s17 = s7 ? s16 : s15;
-  const SBool   s18 = (SBool) ((s2 >> 10) & 1);
+  const SBool   s18 = sbv_bv_extract_u16_10_10_u1(s2);
   const SBool   s19 = false != s18;
   const SBool   s20 = !s19;
   const SBool   s21 = s5 ? s20 : s19;
   const SBool   s22 = !s21;
   const SBool   s23 = s9 ? s22 : s21;
-  const SBool   s24 = (SBool) ((s2 >> 9) & 1);
+  const SBool   s24 = sbv_bv_extract_u16_9_9_u1(s2);
   const SBool   s25 = false != s24;
   const SBool   s26 = !s25;
   const SBool   s27 = s7 ? s26 : s25;
   const SBool   s28 = !s27;
   const SBool   s29 = s13 ? s28 : s27;
-  const SBool   s30 = (SBool) ((s2 >> 8) & 1);
+  const SBool   s30 = sbv_bv_extract_u16_8_8_u1(s2);
   const SBool   s31 = false != s30;
   const SBool   s32 = !s31;
   const SBool   s33 = s9 ? s32 : s31;
   const SBool   s34 = !s33;
   const SBool   s35 = s17 ? s34 : s33;
-  const SBool   s36 = (SBool) ((s2 >> 7) & 1);
+  const SBool   s36 = sbv_bv_extract_u16_7_7_u1(s2);
   const SBool   s37 = false != s36;
   const SBool   s38 = !s37;
   const SBool   s39 = s13 ? s38 : s37;
   const SBool   s40 = !s39;
   const SBool   s41 = s23 ? s40 : s39;
-  const SBool   s42 = (SBool) ((s2 >> 6) & 1);
+  const SBool   s42 = sbv_bv_extract_u16_6_6_u1(s2);
   const SBool   s43 = false != s42;
   const SBool   s44 = !s43;
   const SBool   s45 = s17 ? s44 : s43;
   const SBool   s46 = !s45;
   const SBool   s47 = s29 ? s46 : s45;
-  const SBool   s48 = (SBool) ((s2 >> 5) & 1);
+  const SBool   s48 = sbv_bv_extract_u16_5_5_u1(s2);
   const SBool   s49 = false != s48;
   const SBool   s50 = !s49;
   const SBool   s51 = s23 ? s50 : s49;
@@ -161,29 +320,29 @@
   const SBool   s73 = s47 ? s72 : s47;
   const SBool   s74 = !s53;
   const SBool   s75 = s53 ? s74 : s53;
-  const SBool   s76 = (SBool) ((s2 >> 4) & 1);
+  const SBool   s76 = sbv_bv_extract_u16_4_4_u1(s2);
   const SBool   s77 = false != s76;
   const SBool   s78 = !s77;
   const SBool   s79 = s29 ? s78 : s77;
   const SBool   s80 = !s79;
   const SBool   s81 = s41 ? s80 : s79;
-  const SBool   s82 = (SBool) ((s2 >> 3) & 1);
+  const SBool   s82 = sbv_bv_extract_u16_3_3_u1(s2);
   const SBool   s83 = false != s82;
   const SBool   s84 = !s83;
   const SBool   s85 = s35 ? s84 : s83;
   const SBool   s86 = !s85;
   const SBool   s87 = s47 ? s86 : s85;
-  const SBool   s88 = (SBool) ((s2 >> 2) & 1);
+  const SBool   s88 = sbv_bv_extract_u16_2_2_u1(s2);
   const SBool   s89 = false != s88;
   const SBool   s90 = !s89;
   const SBool   s91 = s41 ? s90 : s89;
   const SBool   s92 = !s91;
   const SBool   s93 = s53 ? s92 : s91;
-  const SBool   s94 = (SBool) ((s2 >> 1) & 1);
+  const SBool   s94 = sbv_bv_extract_u16_1_1_u1(s2);
   const SBool   s95 = false != s94;
   const SBool   s96 = !s95;
   const SBool   s97 = s47 ? s96 : s95;
-  const SBool   s98 = (SBool) (s2 & 1);
+  const SBool   s98 = sbv_bv_extract_u16_0_0_u1(s2);
   const SBool   s99 = false != s98;
   const SBool   s100 = !s99;
   const SBool   s101 = s53 ? s100 : s99;
diff --git a/SBVTestSuite/GoldFiles/doctest_sanity.gold b/SBVTestSuite/GoldFiles/doctest_sanity.gold
--- a/SBVTestSuite/GoldFiles/doctest_sanity.gold
+++ b/SBVTestSuite/GoldFiles/doctest_sanity.gold
@@ -1,3 +1,3 @@
-Total:      1020; Tried: 1020; Skipped:    0; Success: 1020; Errors:    0; Failures    0
-Examples:    910; Tried:  910; Skipped:    0; Success:  910; Errors:    0; Failures    0
-Setup:       110; Tried:  110; Skipped:    0; Success:  110; Errors:    0; Failures    0
+Total:      1268; Tried: 1268; Skipped:    0; Success: 1268; Errors:    0; Failures    0
+Examples:   1113; Tried: 1113; Skipped:    0; Success: 1113; Errors:    0; Failures    0
+Setup:       155; Tried:  155; Skipped:    0; Success:  155; Errors:    0; Failures    0
diff --git a/SBVTestSuite/GoldFiles/dsat01.gold b/SBVTestSuite/GoldFiles/dsat01.gold
--- a/SBVTestSuite/GoldFiles/dsat01.gold
+++ b/SBVTestSuite/GoldFiles/dsat01.gold
@@ -6,7 +6,6 @@
 [ISSUE] (set-option :smtlib2_compliant true)
 [ISSUE] (set-option :produce-models true)
 [ISSUE] (set-logic ALL) ; has unbounded values, using catch-all.
-[ISSUE] ; --- uninterpreted sorts ---
 [ISSUE] ; --- tuples ---
 [ISSUE] ; --- sums ---
 [ISSUE] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/exceptionLocal1.gold b/SBVTestSuite/GoldFiles/exceptionLocal1.gold
--- a/SBVTestSuite/GoldFiles/exceptionLocal1.gold
+++ b/SBVTestSuite/GoldFiles/exceptionLocal1.gold
@@ -4,7 +4,6 @@
 [GOOD] (set-option :global-declarations true)
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
@@ -49,17 +48,11 @@
 [GOOD] (define-fun s31 () (_ BitVec 32) (bvmul s30 s30))
 [GOOD] (define-fun s32 () (_ BitVec 32) (bvmul s31 s31))
 [GOOD] (define-fun s33 () (_ BitVec 32) (bvmul s32 s32))
-[FAIL] (define-fun s34 () (_ BitVec 32) (bvmul s33 s33))
 CAUGHT SMT EXCEPTION
-*** Data.SBV: Unexpected non-success response from Yices:
+*** Data.SBV: Unexpected solver error:
 ***
 ***    Sent      : (define-fun s34 () (_ BitVec 32) (bvmul s33 s33))
-***    Expected  : success
-***    Received  : (error "at line 40, column 35: in bvmul: maximal polynomial degree exceeded")
 ***
-***    Exit code : ExitSuccess
-***    Executable: /usr/local/bin/yices-smt2
+***    Stderr    : at line 40, column 35: in bvmul: maximal polynomial degree exceeded
+***    Executable: /Users/lerkok/Projects/Solvers/bin/yices-smt2
 ***    Options   : --incremental
-***
-***    Reason    : Check solver response for further information. If your code is correct,
-***                please report this as an issue either with SBV or the solver itself!
diff --git a/SBVTestSuite/GoldFiles/exceptionLocal2.gold b/SBVTestSuite/GoldFiles/exceptionLocal2.gold
--- a/SBVTestSuite/GoldFiles/exceptionLocal2.gold
+++ b/SBVTestSuite/GoldFiles/exceptionLocal2.gold
@@ -6,23 +6,16 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_LIA) ; NB. User specified.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
 [GOOD] (define-fun s1 () Real (/ 2.0 1.0))
 [GOOD] ; --- top level inputs ---
-[FAIL] (declare-fun s0 () Real) ; tracks user variable "x"
 CAUGHT SMT EXCEPTION
-*** Data.SBV: Unexpected non-success response from Z3:
+*** Data.SBV: Unexpected solver error:
 ***
 ***    Sent      : (declare-fun s0 () Real) ; tracks user variable "x"
-***    Expected  : success
-***    Received  : (error "line 8 column 23: logic does not support reals")
 ***
-***    Exit code : ExitFailure (-15)
-***    Executable: /usr/local/bin/z3
+***    Stderr    : line 8 column 23: logic does not support reals
+***    Executable: /Users/lerkok/Projects/Solvers/bin/z3
 ***    Options   : -nw -in -smt2
-***
-***    Reason    : Check solver response for further information. If your code is correct,
-***                please report this as an issue either with SBV or the solver itself!
diff --git a/SBVTestSuite/GoldFiles/exceptionRemote1.gold b/SBVTestSuite/GoldFiles/exceptionRemote1.gold
--- a/SBVTestSuite/GoldFiles/exceptionRemote1.gold
+++ b/SBVTestSuite/GoldFiles/exceptionRemote1.gold
@@ -1,3 +1,3 @@
 
-FINAL: "OK, we got: Unexpected response from the solver, context: assert"
+FINAL: "OK, we got: Unexpected solver error"
 DONE!
diff --git a/SBVTestSuite/GoldFiles/fib1.gold b/SBVTestSuite/GoldFiles/fib1.gold
--- a/SBVTestSuite/GoldFiles/fib1.gold
+++ b/SBVTestSuite/GoldFiles/fib1.gold
@@ -12,11 +12,11 @@
 fib1.o: fib1.c fib1.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
-fib1_driver.o: fib1_driver.c
+fib1_driver.o: fib1_driver.c fib1.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
 fib1_driver: fib1.o fib1_driver.o
-	${CC} ${CCFLAGS} $^ -o $@
+	${CC} ${CCFLAGS} $^ -o $@ ${LDFLAGS}
 
 clean:
 	rm -f *.o
@@ -27,9 +27,10 @@
 == BEGIN: "fib1.h" ================
 /* Header file for fib1. Automatically generated by SBV. Do not edit! */
 
-#ifndef __fib1__HEADER_INCLUDED__
-#define __fib1__HEADER_INCLUDED__
+#ifndef SBV_GENERATED_fib1_HEADER_INCLUDED
+#define SBV_GENERATED_fib1_HEADER_INCLUDED
 
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <inttypes.h>
@@ -38,6 +39,13 @@
 #include <string.h>
 #include <math.h>
 
+/* Floating-point calling convention:
+ * Enter generated code in FE_TONEAREST (round-to-nearest, ties-to-even).
+ * Callbacks must preserve this mode before returning or re-entering.
+ * Generated code does not check or change the hardware rounding mode.
+ * Custom builds must disable implicit FP contraction, including at LTO link time.
+ */
+
 /* The boolean type */
 typedef bool SBool;
 
@@ -62,7 +70,7 @@
 /* Entry point prototype: */
 SWord64 fib1(const SWord64 n);
 
-#endif /* __fib1__HEADER_INCLUDED__ */
+#endif /* SBV_GENERATED_fib1_HEADER_INCLUDED */
 == END: "fib1.h" ==================
 == BEGIN: "fib1_driver.c" ================
 /* Example driver program for fib1. */
@@ -73,9 +81,9 @@
 
 int main(void)
 {
-  const SWord64 __result = fib1(0x000000000000000cULL);
+  const SWord64 sbv_result = fib1(0x000000000000000cULL);
 
-  printf("fib1(0x000000000000000cULL) = 0x%016"PRIx64"ULL\n", __result);
+  printf("fib1(0x000000000000000cULL) = 0x%016"PRIx64"ULL\n", sbv_result);
 
   return 0;
 }
@@ -85,9 +93,9 @@
 
 #include "fib1.h"
 
-SWord64 fib1(const SWord64 n)
+SWord64 fib1(const SWord64 sbv_input_0)
 {
-  const SWord64 s0 = n;
+  const SWord64 s0 = sbv_input_0;
   const SBool   s2 = s0 == 0x0000000000000000ULL;
   const SBool   s4 = s0 == 0x0000000000000001ULL;
   const SBool   s6 = s0 == 0x0000000000000002ULL;
diff --git a/SBVTestSuite/GoldFiles/fib2.gold b/SBVTestSuite/GoldFiles/fib2.gold
--- a/SBVTestSuite/GoldFiles/fib2.gold
+++ b/SBVTestSuite/GoldFiles/fib2.gold
@@ -12,11 +12,11 @@
 fib2.o: fib2.c fib2.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
-fib2_driver.o: fib2_driver.c
+fib2_driver.o: fib2_driver.c fib2.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
 fib2_driver: fib2.o fib2_driver.o
-	${CC} ${CCFLAGS} $^ -o $@
+	${CC} ${CCFLAGS} $^ -o $@ ${LDFLAGS}
 
 clean:
 	rm -f *.o
@@ -27,9 +27,10 @@
 == BEGIN: "fib2.h" ================
 /* Header file for fib2. Automatically generated by SBV. Do not edit! */
 
-#ifndef __fib2__HEADER_INCLUDED__
-#define __fib2__HEADER_INCLUDED__
+#ifndef SBV_GENERATED_fib2_HEADER_INCLUDED
+#define SBV_GENERATED_fib2_HEADER_INCLUDED
 
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <inttypes.h>
@@ -38,6 +39,13 @@
 #include <string.h>
 #include <math.h>
 
+/* Floating-point calling convention:
+ * Enter generated code in FE_TONEAREST (round-to-nearest, ties-to-even).
+ * Callbacks must preserve this mode before returning or re-entering.
+ * Generated code does not check or change the hardware rounding mode.
+ * Custom builds must disable implicit FP contraction, including at LTO link time.
+ */
+
 /* The boolean type */
 typedef bool SBool;
 
@@ -62,7 +70,7 @@
 /* Entry point prototype: */
 SWord64 fib2(const SWord64 n);
 
-#endif /* __fib2__HEADER_INCLUDED__ */
+#endif /* SBV_GENERATED_fib2_HEADER_INCLUDED */
 == END: "fib2.h" ==================
 == BEGIN: "fib2_driver.c" ================
 /* Example driver program for fib2. */
@@ -73,9 +81,9 @@
 
 int main(void)
 {
-  const SWord64 __result = fib2(0x0000000000000014ULL);
+  const SWord64 sbv_result = fib2(0x0000000000000014ULL);
 
-  printf("fib2(0x0000000000000014ULL) = 0x%016"PRIx64"ULL\n", __result);
+  printf("fib2(0x0000000000000014ULL) = 0x%016"PRIx64"ULL\n", sbv_result);
 
   return 0;
 }
@@ -85,9 +93,10 @@
 
 #include "fib2.h"
 
-SWord64 fib2(const SWord64 n)
+SWord64 fib2(const SWord64 sbv_input_0)
 {
-  const SWord64 s0 = n;
+  const SWord64 s0 = sbv_input_0;
+        SWord64 s65;
   static const SWord64 table0[] = {
       0x0000000000000000ULL, 0x0000000000000001ULL,
       0x0000000000000001ULL, 0x0000000000000002ULL,
@@ -122,7 +131,7 @@
       0x000001686c8312d0ULL, 0x000002472d96a909ULL,
       0x000003af9a19bbd9ULL, 0x000005f6c7b064e2ULL, 0x000009a661ca20bbULL
   };
-  const SWord64 s65 = s0 >= 65 ? 0x0000000000000000ULL : table0[s0];
+  s65 = s0 >= 65 ? 0x0000000000000000ULL : table0[s0];
 
   return s65;
 }
diff --git a/SBVTestSuite/GoldFiles/floats_cgen.gold b/SBVTestSuite/GoldFiles/floats_cgen.gold
--- a/SBVTestSuite/GoldFiles/floats_cgen.gold
+++ b/SBVTestSuite/GoldFiles/floats_cgen.gold
@@ -2,2787 +2,5195 @@
 /* File: "toFP_Int8_ToFloat.c". Automatically generated by SBV. Do not edit! */
 
 #include "floatCodeGen.h"
-
-SFloat toFP_Int8_ToFloat(const SInt8 a)
-{
-  const SInt8  s0 = a;
-  const SFloat s2 = (SFloat) s0;
-
-  return s2;
-}
-== END: "toFP_Int8_ToFloat.c" ==================
-== BEGIN: "toFP_Int16_ToFloat.c" ================
-/* File: "toFP_Int16_ToFloat.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SFloat toFP_Int16_ToFloat(const SInt16 a)
-{
-  const SInt16 s0 = a;
-  const SFloat s2 = (SFloat) s0;
-
-  return s2;
-}
-== END: "toFP_Int16_ToFloat.c" ==================
-== BEGIN: "toFP_Int32_ToFloat.c" ================
-/* File: "toFP_Int32_ToFloat.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SFloat toFP_Int32_ToFloat(const SInt32 a)
-{
-  const SInt32 s0 = a;
-  const SFloat s2 = (SFloat) s0;
-
-  return s2;
-}
-== END: "toFP_Int32_ToFloat.c" ==================
-== BEGIN: "toFP_Int64_ToFloat.c" ================
-/* File: "toFP_Int64_ToFloat.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SFloat toFP_Int64_ToFloat(const SInt64 a)
-{
-  const SInt64 s0 = a;
-  const SFloat s2 = (SFloat) s0;
-
-  return s2;
-}
-== END: "toFP_Int64_ToFloat.c" ==================
-== BEGIN: "toFP_Word8_ToFloat.c" ================
-/* File: "toFP_Word8_ToFloat.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SFloat toFP_Word8_ToFloat(const SWord8 a)
-{
-  const SWord8 s0 = a;
-  const SFloat s2 = (SFloat) s0;
-
-  return s2;
-}
-== END: "toFP_Word8_ToFloat.c" ==================
-== BEGIN: "toFP_Word16_ToFloat.c" ================
-/* File: "toFP_Word16_ToFloat.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SFloat toFP_Word16_ToFloat(const SWord16 a)
-{
-  const SWord16 s0 = a;
-  const SFloat  s2 = (SFloat) s0;
-
-  return s2;
-}
-== END: "toFP_Word16_ToFloat.c" ==================
-== BEGIN: "toFP_Word32_ToFloat.c" ================
-/* File: "toFP_Word32_ToFloat.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SFloat toFP_Word32_ToFloat(const SWord32 a)
-{
-  const SWord32 s0 = a;
-  const SFloat  s2 = (SFloat) s0;
-
-  return s2;
-}
-== END: "toFP_Word32_ToFloat.c" ==================
-== BEGIN: "toFP_Word64_ToFloat.c" ================
-/* File: "toFP_Word64_ToFloat.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SFloat toFP_Word64_ToFloat(const SWord64 a)
-{
-  const SWord64 s0 = a;
-  const SFloat  s2 = (SFloat) s0;
-
-  return s2;
-}
-== END: "toFP_Word64_ToFloat.c" ==================
-== BEGIN: "toFP_Float_ToFloat.c" ================
-/* File: "toFP_Float_ToFloat.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SFloat toFP_Float_ToFloat(const SFloat a)
-{
-  const SFloat s0 = a;
-  return s0;
-}
-== END: "toFP_Float_ToFloat.c" ==================
-== BEGIN: "toFP_Double_ToFloat.c" ================
-/* File: "toFP_Double_ToFloat.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SFloat toFP_Double_ToFloat(const SDouble a)
-{
-  const SDouble s0 = a;
-  const SFloat  s2 = (SFloat) s0;
-
-  return s2;
-}
-== END: "toFP_Double_ToFloat.c" ==================
-== BEGIN: "toFP_Integer_ToFloat.c" ================
-/* File: "toFP_Integer_ToFloat.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SFloat toFP_Integer_ToFloat(const SInteger a)
-{
-  const SInteger s0 = a;
-  const SFloat   s2 = (SFloat) s0;
-
-  return s2;
-}
-== END: "toFP_Integer_ToFloat.c" ==================
-== BEGIN: "toFP_Real_ToFloat.c" ================
-/* File: "toFP_Real_ToFloat.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SFloat toFP_Real_ToFloat(const SReal a)
-{
-  const SReal  s0 = a;
-  const SFloat s2 = (SFloat) s0;
-
-  return s2;
-}
-== END: "toFP_Real_ToFloat.c" ==================
-== BEGIN: "toFP_Int8_ToDouble.c" ================
-/* File: "toFP_Int8_ToDouble.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SDouble toFP_Int8_ToDouble(const SInt8 a)
-{
-  const SInt8   s0 = a;
-  const SDouble s2 = (SDouble) s0;
-
-  return s2;
-}
-== END: "toFP_Int8_ToDouble.c" ==================
-== BEGIN: "toFP_Int16_ToDouble.c" ================
-/* File: "toFP_Int16_ToDouble.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SDouble toFP_Int16_ToDouble(const SInt16 a)
-{
-  const SInt16  s0 = a;
-  const SDouble s2 = (SDouble) s0;
-
-  return s2;
-}
-== END: "toFP_Int16_ToDouble.c" ==================
-== BEGIN: "toFP_Int32_ToDouble.c" ================
-/* File: "toFP_Int32_ToDouble.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SDouble toFP_Int32_ToDouble(const SInt32 a)
-{
-  const SInt32  s0 = a;
-  const SDouble s2 = (SDouble) s0;
-
-  return s2;
-}
-== END: "toFP_Int32_ToDouble.c" ==================
-== BEGIN: "toFP_Int64_ToDouble.c" ================
-/* File: "toFP_Int64_ToDouble.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SDouble toFP_Int64_ToDouble(const SInt64 a)
-{
-  const SInt64  s0 = a;
-  const SDouble s2 = (SDouble) s0;
-
-  return s2;
-}
-== END: "toFP_Int64_ToDouble.c" ==================
-== BEGIN: "toFP_Word8_ToDouble.c" ================
-/* File: "toFP_Word8_ToDouble.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SDouble toFP_Word8_ToDouble(const SWord8 a)
-{
-  const SWord8  s0 = a;
-  const SDouble s2 = (SDouble) s0;
-
-  return s2;
-}
-== END: "toFP_Word8_ToDouble.c" ==================
-== BEGIN: "toFP_Word16_ToDouble.c" ================
-/* File: "toFP_Word16_ToDouble.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SDouble toFP_Word16_ToDouble(const SWord16 a)
-{
-  const SWord16 s0 = a;
-  const SDouble s2 = (SDouble) s0;
-
-  return s2;
-}
-== END: "toFP_Word16_ToDouble.c" ==================
-== BEGIN: "toFP_Word32_ToDouble.c" ================
-/* File: "toFP_Word32_ToDouble.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SDouble toFP_Word32_ToDouble(const SWord32 a)
-{
-  const SWord32 s0 = a;
-  const SDouble s2 = (SDouble) s0;
-
-  return s2;
-}
-== END: "toFP_Word32_ToDouble.c" ==================
-== BEGIN: "toFP_Word64_ToDouble.c" ================
-/* File: "toFP_Word64_ToDouble.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SDouble toFP_Word64_ToDouble(const SWord64 a)
-{
-  const SWord64 s0 = a;
-  const SDouble s2 = (SDouble) s0;
-
-  return s2;
-}
-== END: "toFP_Word64_ToDouble.c" ==================
-== BEGIN: "toFP_Float_ToDouble.c" ================
-/* File: "toFP_Float_ToDouble.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SDouble toFP_Float_ToDouble(const SFloat a)
-{
-  const SFloat  s0 = a;
-  const SDouble s2 = (SDouble) s0;
-
-  return s2;
-}
-== END: "toFP_Float_ToDouble.c" ==================
-== BEGIN: "toFP_Double_ToDouble.c" ================
-/* File: "toFP_Double_ToDouble.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SDouble toFP_Double_ToDouble(const SDouble a)
-{
-  const SDouble s0 = a;
-  return s0;
-}
-== END: "toFP_Double_ToDouble.c" ==================
-== BEGIN: "toFP_Integer_ToDouble.c" ================
-/* File: "toFP_Integer_ToDouble.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SDouble toFP_Integer_ToDouble(const SInteger a)
-{
-  const SInteger s0 = a;
-  const SDouble  s2 = (SDouble) s0;
-
-  return s2;
-}
-== END: "toFP_Integer_ToDouble.c" ==================
-== BEGIN: "toFP_Real_ToDouble.c" ================
-/* File: "toFP_Real_ToDouble.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SDouble toFP_Real_ToDouble(const SReal a)
-{
-  const SReal   s0 = a;
-  const SDouble s2 = (SDouble) s0;
-
-  return s2;
-}
-== END: "toFP_Real_ToDouble.c" ==================
-== BEGIN: "fromFP_Float_ToInt8.c" ================
-/* File: "fromFP_Float_ToInt8.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SInt8 fromFP_Float_ToInt8(const SFloat a)
-{
-  const SFloat s0 = a;
-  const SInt8  s2 = (SInt8) rintf(s0);
-
-  return s2;
-}
-== END: "fromFP_Float_ToInt8.c" ==================
-== BEGIN: "fromFP_Float_ToInt16.c" ================
-/* File: "fromFP_Float_ToInt16.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SInt16 fromFP_Float_ToInt16(const SFloat a)
-{
-  const SFloat s0 = a;
-  const SInt16 s2 = (SInt16) rintf(s0);
-
-  return s2;
-}
-== END: "fromFP_Float_ToInt16.c" ==================
-== BEGIN: "fromFP_Float_ToInt32.c" ================
-/* File: "fromFP_Float_ToInt32.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SInt32 fromFP_Float_ToInt32(const SFloat a)
-{
-  const SFloat s0 = a;
-  const SInt32 s2 = (SInt32) rintf(s0);
-
-  return s2;
-}
-== END: "fromFP_Float_ToInt32.c" ==================
-== BEGIN: "fromFP_Float_ToInt64.c" ================
-/* File: "fromFP_Float_ToInt64.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SInt64 fromFP_Float_ToInt64(const SFloat a)
-{
-  const SFloat s0 = a;
-  const SInt64 s2 = (SInt64) rintf(s0);
-
-  return s2;
-}
-== END: "fromFP_Float_ToInt64.c" ==================
-== BEGIN: "fromFP_Float_ToWord8.c" ================
-/* File: "fromFP_Float_ToWord8.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SWord8 fromFP_Float_ToWord8(const SFloat a)
-{
-  const SFloat s0 = a;
-  const SWord8 s2 = (SWord8) rintf(s0);
-
-  return s2;
-}
-== END: "fromFP_Float_ToWord8.c" ==================
-== BEGIN: "fromFP_Float_ToWord16.c" ================
-/* File: "fromFP_Float_ToWord16.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SWord16 fromFP_Float_ToWord16(const SFloat a)
-{
-  const SFloat  s0 = a;
-  const SWord16 s2 = (SWord16) rintf(s0);
-
-  return s2;
-}
-== END: "fromFP_Float_ToWord16.c" ==================
-== BEGIN: "fromFP_Float_ToWord32.c" ================
-/* File: "fromFP_Float_ToWord32.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SWord32 fromFP_Float_ToWord32(const SFloat a)
-{
-  const SFloat  s0 = a;
-  const SWord32 s2 = (SWord32) rintf(s0);
-
-  return s2;
-}
-== END: "fromFP_Float_ToWord32.c" ==================
-== BEGIN: "fromFP_Float_ToWord64.c" ================
-/* File: "fromFP_Float_ToWord64.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SWord64 fromFP_Float_ToWord64(const SFloat a)
-{
-  const SFloat  s0 = a;
-  const SWord64 s2 = (SWord64) rintf(s0);
-
-  return s2;
-}
-== END: "fromFP_Float_ToWord64.c" ==================
-== BEGIN: "fromFP_Float_ToFloat.c" ================
-/* File: "fromFP_Float_ToFloat.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SFloat fromFP_Float_ToFloat(const SFloat a)
-{
-  const SFloat s0 = a;
-  return s0;
-}
-== END: "fromFP_Float_ToFloat.c" ==================
-== BEGIN: "fromFP_Float_ToDouble.c" ================
-/* File: "fromFP_Float_ToDouble.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SDouble fromFP_Float_ToDouble(const SFloat a)
-{
-  const SFloat  s0 = a;
-  const SDouble s2 = (SDouble) s0;
-
-  return s2;
-}
-== END: "fromFP_Float_ToDouble.c" ==================
-== BEGIN: "fromFP_Float_ToInteger.c" ================
-/* File: "fromFP_Float_ToInteger.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SInteger fromFP_Float_ToInteger(const SFloat a)
-{
-  const SFloat   s0 = a;
-  const SInteger s2 = (SInteger) rintf(s0);
-
-  return s2;
-}
-== END: "fromFP_Float_ToInteger.c" ==================
-== BEGIN: "fromFP_Float_ToReal.c" ================
-/* File: "fromFP_Float_ToReal.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SReal fromFP_Float_ToReal(const SFloat a)
-{
-  const SFloat s0 = a;
-  const SReal  s2 = (SReal) s0;
-
-  return s2;
-}
-== END: "fromFP_Float_ToReal.c" ==================
-== BEGIN: "fromFP_DoubleTo_Int8.c" ================
-/* File: "fromFP_DoubleTo_Int8.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SInt8 fromFP_DoubleTo_Int8(const SDouble a)
-{
-  const SDouble s0 = a;
-  const SInt8   s2 = (SInt8) rint(s0);
-
-  return s2;
-}
-== END: "fromFP_DoubleTo_Int8.c" ==================
-== BEGIN: "fromFP_DoubleTo_Int16.c" ================
-/* File: "fromFP_DoubleTo_Int16.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SInt16 fromFP_DoubleTo_Int16(const SDouble a)
-{
-  const SDouble s0 = a;
-  const SInt16  s2 = (SInt16) rint(s0);
-
-  return s2;
-}
-== END: "fromFP_DoubleTo_Int16.c" ==================
-== BEGIN: "fromFP_DoubleTo_Int32.c" ================
-/* File: "fromFP_DoubleTo_Int32.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SInt32 fromFP_DoubleTo_Int32(const SDouble a)
-{
-  const SDouble s0 = a;
-  const SInt32  s2 = (SInt32) rint(s0);
-
-  return s2;
-}
-== END: "fromFP_DoubleTo_Int32.c" ==================
-== BEGIN: "fromFP_DoubleTo_Int64.c" ================
-/* File: "fromFP_DoubleTo_Int64.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SInt64 fromFP_DoubleTo_Int64(const SDouble a)
-{
-  const SDouble s0 = a;
-  const SInt64  s2 = (SInt64) rint(s0);
-
-  return s2;
-}
-== END: "fromFP_DoubleTo_Int64.c" ==================
-== BEGIN: "fromFP_DoubleTo_Word8.c" ================
-/* File: "fromFP_DoubleTo_Word8.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SWord8 fromFP_DoubleTo_Word8(const SDouble a)
-{
-  const SDouble s0 = a;
-  const SWord8  s2 = (SWord8) rint(s0);
-
-  return s2;
-}
-== END: "fromFP_DoubleTo_Word8.c" ==================
-== BEGIN: "fromFP_DoubleTo_Word16.c" ================
-/* File: "fromFP_DoubleTo_Word16.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SWord16 fromFP_DoubleTo_Word16(const SDouble a)
-{
-  const SDouble s0 = a;
-  const SWord16 s2 = (SWord16) rint(s0);
-
-  return s2;
-}
-== END: "fromFP_DoubleTo_Word16.c" ==================
-== BEGIN: "fromFP_DoubleTo_Word32.c" ================
-/* File: "fromFP_DoubleTo_Word32.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SWord32 fromFP_DoubleTo_Word32(const SDouble a)
-{
-  const SDouble s0 = a;
-  const SWord32 s2 = (SWord32) rint(s0);
-
-  return s2;
-}
-== END: "fromFP_DoubleTo_Word32.c" ==================
-== BEGIN: "fromFP_DoubleTo_Word64.c" ================
-/* File: "fromFP_DoubleTo_Word64.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SWord64 fromFP_DoubleTo_Word64(const SDouble a)
-{
-  const SDouble s0 = a;
-  const SWord64 s2 = (SWord64) rint(s0);
-
-  return s2;
-}
-== END: "fromFP_DoubleTo_Word64.c" ==================
-== BEGIN: "fromFP_DoubleTo_Float.c" ================
-/* File: "fromFP_DoubleTo_Float.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SFloat fromFP_DoubleTo_Float(const SDouble a)
-{
-  const SDouble s0 = a;
-  const SFloat  s2 = (SFloat) s0;
-
-  return s2;
-}
-== END: "fromFP_DoubleTo_Float.c" ==================
-== BEGIN: "fromFP_DoubleTo_Double.c" ================
-/* File: "fromFP_DoubleTo_Double.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SDouble fromFP_DoubleTo_Double(const SDouble a)
-{
-  const SDouble s0 = a;
-  return s0;
-}
-== END: "fromFP_DoubleTo_Double.c" ==================
-== BEGIN: "fromFP_DoubleTo_Integer.c" ================
-/* File: "fromFP_DoubleTo_Integer.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SInteger fromFP_DoubleTo_Integer(const SDouble a)
-{
-  const SDouble  s0 = a;
-  const SInteger s2 = (SInteger) rint(s0);
-
-  return s2;
-}
-== END: "fromFP_DoubleTo_Integer.c" ==================
-== BEGIN: "fromFP_DoubleTo_Real.c" ================
-/* File: "fromFP_DoubleTo_Real.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SReal fromFP_DoubleTo_Real(const SDouble a)
-{
-  const SDouble s0 = a;
-  const SReal   s2 = (SReal) s0;
-
-  return s2;
-}
-== END: "fromFP_DoubleTo_Real.c" ==================
-== BEGIN: "fromFP_SWord32_SFloat.c" ================
-/* File: "fromFP_SWord32_SFloat.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SFloat fromFP_SWord32_SFloat(const SWord32 a)
-{
-  const SWord32 s0 = a;
-        SFloat  s1; memcpy(&s1, &s0, sizeof(SFloat));
-
-  return s1;
-}
-== END: "fromFP_SWord32_SFloat.c" ==================
-== BEGIN: "fromFP_SWord64_SDouble.c" ================
-/* File: "fromFP_SWord64_SDouble.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SDouble fromFP_SWord64_SDouble(const SWord64 a)
-{
-  const SWord64 s0 = a;
-        SDouble s1; memcpy(&s1, &s0, sizeof(SDouble));
-
-  return s1;
-}
-== END: "fromFP_SWord64_SDouble.c" ==================
-== BEGIN: "fromFP_SFloat_SWord32.c" ================
-/* File: "fromFP_SFloat_SWord32.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SWord32 fromFP_SFloat_SWord32(const SFloat a)
-{
-  const SFloat  s0 = a;
-        SWord32 s1; memcpy(&s1, &s0, sizeof(SWord32));
-
-  return s1;
-}
-== END: "fromFP_SFloat_SWord32.c" ==================
-== BEGIN: "fromFP_SDouble_SWord64.c" ================
-/* File: "fromFP_SDouble_SWord64.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SWord64 fromFP_SDouble_SWord64(const SDouble a)
-{
-  const SDouble s0 = a;
-        SWord64 s1; memcpy(&s1, &s0, sizeof(SWord64));
-
-  return s1;
-}
-== END: "fromFP_SDouble_SWord64.c" ==================
-== BEGIN: "f_FP_Abs.c" ================
-/* File: "f_FP_Abs.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SFloat f_FP_Abs(const SFloat a)
-{
-  const SFloat s0 = a;
-  const SFloat s1 = fabsf(s0);
-
-  return s1;
-}
-== END: "f_FP_Abs.c" ==================
-== BEGIN: "d_FP_Abs.c" ================
-/* File: "d_FP_Abs.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SDouble d_FP_Abs(const SDouble a)
-{
-  const SDouble s0 = a;
-  const SDouble s1 = fabs(s0);
-
-  return s1;
-}
-== END: "d_FP_Abs.c" ==================
-== BEGIN: "f_FP_Neg.c" ================
-/* File: "f_FP_Neg.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SFloat f_FP_Neg(const SFloat a)
-{
-  const SFloat s0 = a;
-  const SFloat s1 = (- s0);
-
-  return s1;
-}
-== END: "f_FP_Neg.c" ==================
-== BEGIN: "d_FP_Neg.c" ================
-/* File: "d_FP_Neg.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SDouble d_FP_Neg(const SDouble a)
-{
-  const SDouble s0 = a;
-  const SDouble s1 = (- s0);
-
-  return s1;
-}
-== END: "d_FP_Neg.c" ==================
-== BEGIN: "f_FP_Add.c" ================
-/* File: "f_FP_Add.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SFloat f_FP_Add(const SFloat a, const SFloat b)
-{
-  const SFloat s0 = a;
-  const SFloat s1 = b;
-  const SFloat s3 = s0 + s1;
-
-  return s3;
-}
-== END: "f_FP_Add.c" ==================
-== BEGIN: "d_FP_Add.c" ================
-/* File: "d_FP_Add.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SDouble d_FP_Add(const SDouble a, const SDouble b)
-{
-  const SDouble s0 = a;
-  const SDouble s1 = b;
-  const SDouble s3 = s0 + s1;
-
-  return s3;
-}
-== END: "d_FP_Add.c" ==================
-== BEGIN: "f_FP_Sub.c" ================
-/* File: "f_FP_Sub.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SFloat f_FP_Sub(const SFloat a, const SFloat b)
-{
-  const SFloat s0 = a;
-  const SFloat s1 = b;
-  const SFloat s3 = s0 - s1;
-
-  return s3;
-}
-== END: "f_FP_Sub.c" ==================
-== BEGIN: "d_FP_Sub.c" ================
-/* File: "d_FP_Sub.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SDouble d_FP_Sub(const SDouble a, const SDouble b)
-{
-  const SDouble s0 = a;
-  const SDouble s1 = b;
-  const SDouble s3 = s0 - s1;
-
-  return s3;
-}
-== END: "d_FP_Sub.c" ==================
-== BEGIN: "f_FP_Mul.c" ================
-/* File: "f_FP_Mul.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SFloat f_FP_Mul(const SFloat a, const SFloat b)
-{
-  const SFloat s0 = a;
-  const SFloat s1 = b;
-  const SFloat s3 = s0 * s1;
-
-  return s3;
-}
-== END: "f_FP_Mul.c" ==================
-== BEGIN: "d_FP_Mul.c" ================
-/* File: "d_FP_Mul.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SDouble d_FP_Mul(const SDouble a, const SDouble b)
-{
-  const SDouble s0 = a;
-  const SDouble s1 = b;
-  const SDouble s3 = s0 * s1;
-
-  return s3;
-}
-== END: "d_FP_Mul.c" ==================
-== BEGIN: "f_FP_Div.c" ================
-/* File: "f_FP_Div.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SFloat f_FP_Div(const SFloat a, const SFloat b)
-{
-  const SFloat s0 = a;
-  const SFloat s1 = b;
-  const SFloat s3 = s0 / s1;
-
-  return s3;
-}
-== END: "f_FP_Div.c" ==================
-== BEGIN: "d_FP_Div.c" ================
-/* File: "d_FP_Div.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SDouble d_FP_Div(const SDouble a, const SDouble b)
-{
-  const SDouble s0 = a;
-  const SDouble s1 = b;
-  const SDouble s3 = s0 / s1;
-
-  return s3;
-}
-== END: "d_FP_Div.c" ==================
-== BEGIN: "f_FP_FMA.c" ================
-/* File: "f_FP_FMA.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SFloat f_FP_FMA(const SFloat a, const SFloat b, const SFloat c)
-{
-  const SFloat s0 = a;
-  const SFloat s1 = b;
-  const SFloat s2 = c;
-  const SFloat s4 = fmaf(s0, s1, s2);
-
-  return s4;
-}
-== END: "f_FP_FMA.c" ==================
-== BEGIN: "d_FP_FMA.c" ================
-/* File: "d_FP_FMA.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SDouble d_FP_FMA(const SDouble a, const SDouble b, const SDouble c)
-{
-  const SDouble s0 = a;
-  const SDouble s1 = b;
-  const SDouble s2 = c;
-  const SDouble s4 = fma(s0, s1, s2);
-
-  return s4;
-}
-== END: "d_FP_FMA.c" ==================
-== BEGIN: "f_FP_Sqrt.c" ================
-/* File: "f_FP_Sqrt.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SFloat f_FP_Sqrt(const SFloat a)
-{
-  const SFloat s0 = a;
-  const SFloat s2 = sqrtf(s0);
-
-  return s2;
-}
-== END: "f_FP_Sqrt.c" ==================
-== BEGIN: "d_FP_Sqrt.c" ================
-/* File: "d_FP_Sqrt.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SDouble d_FP_Sqrt(const SDouble a)
-{
-  const SDouble s0 = a;
-  const SDouble s2 = sqrt(s0);
-
-  return s2;
-}
-== END: "d_FP_Sqrt.c" ==================
-== BEGIN: "f_FP_Rem.c" ================
-/* File: "f_FP_Rem.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SFloat f_FP_Rem(const SFloat a, const SFloat b)
-{
-  const SFloat s0 = a;
-  const SFloat s1 = b;
-  const SFloat s2 = fmodf(s0, s1);
-
-  return s2;
-}
-== END: "f_FP_Rem.c" ==================
-== BEGIN: "d_FP_Rem.c" ================
-/* File: "d_FP_Rem.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SDouble d_FP_Rem(const SDouble a, const SDouble b)
-{
-  const SDouble s0 = a;
-  const SDouble s1 = b;
-  const SDouble s2 = fmod(s0, s1);
-
-  return s2;
-}
-== END: "d_FP_Rem.c" ==================
-== BEGIN: "f_FP_RoundToIntegral.c" ================
-/* File: "f_FP_RoundToIntegral.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SFloat f_FP_RoundToIntegral(const SFloat a)
-{
-  const SFloat s0 = a;
-  const SFloat s2 = rintf(s0);
-
-  return s2;
-}
-== END: "f_FP_RoundToIntegral.c" ==================
-== BEGIN: "d_FP_RoundToIntegral.c" ================
-/* File: "d_FP_RoundToIntegral.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SDouble d_FP_RoundToIntegral(const SDouble a)
-{
-  const SDouble s0 = a;
-  const SDouble s2 = rint(s0);
-
-  return s2;
-}
-== END: "d_FP_RoundToIntegral.c" ==================
-== BEGIN: "f_FP_Min.c" ================
-/* File: "f_FP_Min.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SFloat f_FP_Min(const SFloat a, const SFloat b)
-{
-  const SFloat s0 = a;
-  const SFloat s1 = b;
-  const SFloat s2 = ((FP_ZERO == fpclassify(s0)) && (FP_ZERO == fpclassify(s1)) && (signbit(s0) != signbit(s1))) ? 0x0p+0F /* 0.0F */ : fminf(s0,
-                                                                                                                                              s1);
-
-  return s2;
-}
-== END: "f_FP_Min.c" ==================
-== BEGIN: "d_FP_Min.c" ================
-/* File: "d_FP_Min.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SDouble d_FP_Min(const SDouble a, const SDouble b)
-{
-  const SDouble s0 = a;
-  const SDouble s1 = b;
-  const SDouble s2 = ((FP_ZERO == fpclassify(s0)) && (FP_ZERO == fpclassify(s1)) && (signbit(s0) != signbit(s1))) ? 0x0p+0 /* 0.0 */ : fmin(s0,
-                                                                                                                                            s1);
-
-  return s2;
-}
-== END: "d_FP_Min.c" ==================
-== BEGIN: "f_FP_Max.c" ================
-/* File: "f_FP_Max.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SFloat f_FP_Max(const SFloat a, const SFloat b)
-{
-  const SFloat s0 = a;
-  const SFloat s1 = b;
-  const SFloat s2 = ((FP_ZERO == fpclassify(s0)) && (FP_ZERO == fpclassify(s1)) && (signbit(s0) != signbit(s1))) ? 0x0p+0F /* 0.0F */ : fmaxf(s0,
-                                                                                                                                              s1);
-
-  return s2;
-}
-== END: "f_FP_Max.c" ==================
-== BEGIN: "d_FP_Max.c" ================
-/* File: "d_FP_Max.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SDouble d_FP_Max(const SDouble a, const SDouble b)
-{
-  const SDouble s0 = a;
-  const SDouble s1 = b;
-  const SDouble s2 = ((FP_ZERO == fpclassify(s0)) && (FP_ZERO == fpclassify(s1)) && (signbit(s0) != signbit(s1))) ? 0x0p+0 /* 0.0 */ : fmax(s0,
-                                                                                                                                            s1);
-
-  return s2;
-}
-== END: "d_FP_Max.c" ==================
-== BEGIN: "f_FP_IsEqualObject.c" ================
-/* File: "f_FP_IsEqualObject.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SBool f_FP_IsEqualObject(const SFloat a, const SFloat b)
-{
-  const SFloat s0 = a;
-  const SFloat s1 = b;
-  const SBool  s2 = isnan(s0) ? isnan(s1) : (signbit(s0) && (s0 == 0)) ? (signbit(s1) && (s1 == 0)) : (signbit(s1) && (s1 == 0)) ? (signbit(s0) && (s0 == 0)) : (s0 == s1);
-
-  return s2;
-}
-== END: "f_FP_IsEqualObject.c" ==================
-== BEGIN: "d_FP_IsEqualObject.c" ================
-/* File: "d_FP_IsEqualObject.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SBool d_FP_IsEqualObject(const SDouble a, const SDouble b)
-{
-  const SDouble s0 = a;
-  const SDouble s1 = b;
-  const SBool   s2 = isnan(s0) ? isnan(s1) : (signbit(s0) && (s0 == 0)) ? (signbit(s1) && (s1 == 0)) : (signbit(s1) && (s1 == 0)) ? (signbit(s0) && (s0 == 0)) : (s0 == s1);
-
-  return s2;
-}
-== END: "d_FP_IsEqualObject.c" ==================
-== BEGIN: "f_FP_IsNormal.c" ================
-/* File: "f_FP_IsNormal.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SBool f_FP_IsNormal(const SFloat a)
-{
-  const SFloat s0 = a;
-  const SBool  s1 = isnormal(s0);
-
-  return s1;
-}
-== END: "f_FP_IsNormal.c" ==================
-== BEGIN: "d_FP_IsNormal.c" ================
-/* File: "d_FP_IsNormal.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SBool d_FP_IsNormal(const SDouble a)
-{
-  const SDouble s0 = a;
-  const SBool   s1 = isnormal(s0);
-
-  return s1;
-}
-== END: "d_FP_IsNormal.c" ==================
-== BEGIN: "f_FP_IsZero.c" ================
-/* File: "f_FP_IsZero.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SBool f_FP_IsZero(const SFloat a)
-{
-  const SFloat s0 = a;
-  const SBool  s1 = FP_ZERO == fpclassify(s0);
-
-  return s1;
-}
-== END: "f_FP_IsZero.c" ==================
-== BEGIN: "d_FP_IsZero.c" ================
-/* File: "d_FP_IsZero.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SBool d_FP_IsZero(const SDouble a)
-{
-  const SDouble s0 = a;
-  const SBool   s1 = FP_ZERO == fpclassify(s0);
-
-  return s1;
-}
-== END: "d_FP_IsZero.c" ==================
-== BEGIN: "f_FP_IsSubnormal.c" ================
-/* File: "f_FP_IsSubnormal.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SBool f_FP_IsSubnormal(const SFloat a)
-{
-  const SFloat s0 = a;
-  const SBool  s1 = FP_SUBNORMAL == fpclassify(s0);
-
-  return s1;
-}
-== END: "f_FP_IsSubnormal.c" ==================
-== BEGIN: "d_FP_IsSubnormal.c" ================
-/* File: "d_FP_IsSubnormal.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SBool d_FP_IsSubnormal(const SDouble a)
-{
-  const SDouble s0 = a;
-  const SBool   s1 = FP_SUBNORMAL == fpclassify(s0);
-
-  return s1;
-}
-== END: "d_FP_IsSubnormal.c" ==================
-== BEGIN: "f_FP_IsInfinite.c" ================
-/* File: "f_FP_IsInfinite.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SBool f_FP_IsInfinite(const SFloat a)
-{
-  const SFloat s0 = a;
-  const SBool  s1 = isinf(s0);
-
-  return s1;
-}
-== END: "f_FP_IsInfinite.c" ==================
-== BEGIN: "d_FP_IsInfinite.c" ================
-/* File: "d_FP_IsInfinite.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SBool d_FP_IsInfinite(const SDouble a)
-{
-  const SDouble s0 = a;
-  const SBool   s1 = isinf(s0);
-
-  return s1;
-}
-== END: "d_FP_IsInfinite.c" ==================
-== BEGIN: "f_FP_IsNaN.c" ================
-/* File: "f_FP_IsNaN.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SBool f_FP_IsNaN(const SFloat a)
-{
-  const SFloat s0 = a;
-  const SBool  s1 = isnan(s0);
-
-  return s1;
-}
-== END: "f_FP_IsNaN.c" ==================
-== BEGIN: "d_FP_IsNaN.c" ================
-/* File: "d_FP_IsNaN.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SBool d_FP_IsNaN(const SDouble a)
-{
-  const SDouble s0 = a;
-  const SBool   s1 = isnan(s0);
-
-  return s1;
-}
-== END: "d_FP_IsNaN.c" ==================
-== BEGIN: "f_FP_IsNegative.c" ================
-/* File: "f_FP_IsNegative.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SBool f_FP_IsNegative(const SFloat a)
-{
-  const SFloat s0 = a;
-  const SBool  s1 = !isnan(s0) && signbit(s0);
-
-  return s1;
-}
-== END: "f_FP_IsNegative.c" ==================
-== BEGIN: "d_FP_IsNegative.c" ================
-/* File: "d_FP_IsNegative.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SBool d_FP_IsNegative(const SDouble a)
-{
-  const SDouble s0 = a;
-  const SBool   s1 = !isnan(s0) && signbit(s0);
-
-  return s1;
-}
-== END: "d_FP_IsNegative.c" ==================
-== BEGIN: "f_FP_IsPositive.c" ================
-/* File: "f_FP_IsPositive.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SBool f_FP_IsPositive(const SFloat a)
-{
-  const SFloat s0 = a;
-  const SBool  s1 = !isnan(s0) && !signbit(s0);
-
-  return s1;
-}
-== END: "f_FP_IsPositive.c" ==================
-== BEGIN: "d_FP_IsPositive.c" ================
-/* File: "d_FP_IsPositive.c". Automatically generated by SBV. Do not edit! */
-
-#include "floatCodeGen.h"
-
-SBool d_FP_IsPositive(const SDouble a)
-{
-  const SDouble s0 = a;
-  const SBool   s1 = !isnan(s0) && !signbit(s0);
-
-  return s1;
-}
-== END: "d_FP_IsPositive.c" ==================
-== BEGIN: "floatCodeGen.h" ================
-/* Header file for floatCodeGen. Automatically generated by SBV. Do not edit! */
-
-#ifndef __floatCodeGen__HEADER_INCLUDED__
-#define __floatCodeGen__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;
-
-/* User requested mapping for SInteger.                                 */
-/* NB. Loss of precision: Target type is subject to modular arithmetic. */
-typedef SInt64 SInteger;
-
-/* User requested mapping for SReal.                          */
-/* NB. Loss of precision: Target type is subject to rounding. */
-typedef long double SReal;
-
-/* Entry point prototypes: */
-SFloat toFP_Int8_ToFloat(const SInt8 a);
-SFloat toFP_Int16_ToFloat(const SInt16 a);
-SFloat toFP_Int32_ToFloat(const SInt32 a);
-SFloat toFP_Int64_ToFloat(const SInt64 a);
-SFloat toFP_Word8_ToFloat(const SWord8 a);
-SFloat toFP_Word16_ToFloat(const SWord16 a);
-SFloat toFP_Word32_ToFloat(const SWord32 a);
-SFloat toFP_Word64_ToFloat(const SWord64 a);
-SFloat toFP_Float_ToFloat(const SFloat a);
-SFloat toFP_Double_ToFloat(const SDouble a);
-SFloat toFP_Integer_ToFloat(const SInteger a);
-SFloat toFP_Real_ToFloat(const SReal a);
-SDouble toFP_Int8_ToDouble(const SInt8 a);
-SDouble toFP_Int16_ToDouble(const SInt16 a);
-SDouble toFP_Int32_ToDouble(const SInt32 a);
-SDouble toFP_Int64_ToDouble(const SInt64 a);
-SDouble toFP_Word8_ToDouble(const SWord8 a);
-SDouble toFP_Word16_ToDouble(const SWord16 a);
-SDouble toFP_Word32_ToDouble(const SWord32 a);
-SDouble toFP_Word64_ToDouble(const SWord64 a);
-SDouble toFP_Float_ToDouble(const SFloat a);
-SDouble toFP_Double_ToDouble(const SDouble a);
-SDouble toFP_Integer_ToDouble(const SInteger a);
-SDouble toFP_Real_ToDouble(const SReal a);
-SInt8 fromFP_Float_ToInt8(const SFloat a);
-SInt16 fromFP_Float_ToInt16(const SFloat a);
-SInt32 fromFP_Float_ToInt32(const SFloat a);
-SInt64 fromFP_Float_ToInt64(const SFloat a);
-SWord8 fromFP_Float_ToWord8(const SFloat a);
-SWord16 fromFP_Float_ToWord16(const SFloat a);
-SWord32 fromFP_Float_ToWord32(const SFloat a);
-SWord64 fromFP_Float_ToWord64(const SFloat a);
-SFloat fromFP_Float_ToFloat(const SFloat a);
-SDouble fromFP_Float_ToDouble(const SFloat a);
-SInteger fromFP_Float_ToInteger(const SFloat a);
-SReal fromFP_Float_ToReal(const SFloat a);
-SInt8 fromFP_DoubleTo_Int8(const SDouble a);
-SInt16 fromFP_DoubleTo_Int16(const SDouble a);
-SInt32 fromFP_DoubleTo_Int32(const SDouble a);
-SInt64 fromFP_DoubleTo_Int64(const SDouble a);
-SWord8 fromFP_DoubleTo_Word8(const SDouble a);
-SWord16 fromFP_DoubleTo_Word16(const SDouble a);
-SWord32 fromFP_DoubleTo_Word32(const SDouble a);
-SWord64 fromFP_DoubleTo_Word64(const SDouble a);
-SFloat fromFP_DoubleTo_Float(const SDouble a);
-SDouble fromFP_DoubleTo_Double(const SDouble a);
-SInteger fromFP_DoubleTo_Integer(const SDouble a);
-SReal fromFP_DoubleTo_Real(const SDouble a);
-SFloat fromFP_SWord32_SFloat(const SWord32 a);
-SDouble fromFP_SWord64_SDouble(const SWord64 a);
-SWord32 fromFP_SFloat_SWord32(const SFloat a);
-SWord64 fromFP_SDouble_SWord64(const SDouble a);
-SFloat f_FP_Abs(const SFloat a);
-SDouble d_FP_Abs(const SDouble a);
-SFloat f_FP_Neg(const SFloat a);
-SDouble d_FP_Neg(const SDouble a);
-SFloat f_FP_Add(const SFloat a, const SFloat b);
-SDouble d_FP_Add(const SDouble a, const SDouble b);
-SFloat f_FP_Sub(const SFloat a, const SFloat b);
-SDouble d_FP_Sub(const SDouble a, const SDouble b);
-SFloat f_FP_Mul(const SFloat a, const SFloat b);
-SDouble d_FP_Mul(const SDouble a, const SDouble b);
-SFloat f_FP_Div(const SFloat a, const SFloat b);
-SDouble d_FP_Div(const SDouble a, const SDouble b);
-SFloat f_FP_FMA(const SFloat a, const SFloat b, const SFloat c);
-SDouble d_FP_FMA(const SDouble a, const SDouble b,
-                 const SDouble c);
-SFloat f_FP_Sqrt(const SFloat a);
-SDouble d_FP_Sqrt(const SDouble a);
-SFloat f_FP_Rem(const SFloat a, const SFloat b);
-SDouble d_FP_Rem(const SDouble a, const SDouble b);
-SFloat f_FP_RoundToIntegral(const SFloat a);
-SDouble d_FP_RoundToIntegral(const SDouble a);
-SFloat f_FP_Min(const SFloat a, const SFloat b);
-SDouble d_FP_Min(const SDouble a, const SDouble b);
-SFloat f_FP_Max(const SFloat a, const SFloat b);
-SDouble d_FP_Max(const SDouble a, const SDouble b);
-SBool f_FP_IsEqualObject(const SFloat a, const SFloat b);
-SBool d_FP_IsEqualObject(const SDouble a, const SDouble b);
-SBool f_FP_IsNormal(const SFloat a);
-SBool d_FP_IsNormal(const SDouble a);
-SBool f_FP_IsZero(const SFloat a);
-SBool d_FP_IsZero(const SDouble a);
-SBool f_FP_IsSubnormal(const SFloat a);
-SBool d_FP_IsSubnormal(const SDouble a);
-SBool f_FP_IsInfinite(const SFloat a);
-SBool d_FP_IsInfinite(const SDouble a);
-SBool f_FP_IsNaN(const SFloat a);
-SBool d_FP_IsNaN(const SDouble a);
-SBool f_FP_IsNegative(const SFloat a);
-SBool d_FP_IsNegative(const SDouble a);
-SBool f_FP_IsPositive(const SFloat a);
-SBool d_FP_IsPositive(const SDouble a);
-
-#endif /* __floatCodeGen__HEADER_INCLUDED__ */
-== END: "floatCodeGen.h" ==================
-== BEGIN: "floatCodeGen_driver.c" ================
-/* Example driver program for floatCodeGen. */
-/* Automatically generated by SBV. Edit as you see fit! */
-
-#include <stdio.h>
-#include "floatCodeGen.h"
-
-void toFP_Int8_ToFloat_driver(void)
-{
-  const SFloat __result = toFP_Int8_ToFloat(42);
-
-  printf("toFP_Int8_ToFloat(42) = %a\n", __result);
-}
-
-void toFP_Int16_ToFloat_driver(void)
-{
-  const SFloat __result = toFP_Int16_ToFloat(0x002a);
-
-  printf("toFP_Int16_ToFloat(0x002a) = %a\n", __result);
-}
-
-void toFP_Int32_ToFloat_driver(void)
-{
-  const SFloat __result = toFP_Int32_ToFloat(0x0000002aL);
-
-  printf("toFP_Int32_ToFloat(0x0000002aL) = %a\n", __result);
-}
-
-void toFP_Int64_ToFloat_driver(void)
-{
-  const SFloat __result = toFP_Int64_ToFloat(0x000000000000002aLL);
-
-  printf("toFP_Int64_ToFloat(0x000000000000002aLL) = %a\n", __result);
-}
-
-void toFP_Word8_ToFloat_driver(void)
-{
-  const SFloat __result = toFP_Word8_ToFloat(42);
-
-  printf("toFP_Word8_ToFloat(42) = %a\n", __result);
-}
-
-void toFP_Word16_ToFloat_driver(void)
-{
-  const SFloat __result = toFP_Word16_ToFloat(0x002aU);
-
-  printf("toFP_Word16_ToFloat(0x002aU) = %a\n", __result);
-}
-
-void toFP_Word32_ToFloat_driver(void)
-{
-  const SFloat __result = toFP_Word32_ToFloat(0x0000002aUL);
-
-  printf("toFP_Word32_ToFloat(0x0000002aUL) = %a\n", __result);
-}
-
-void toFP_Word64_ToFloat_driver(void)
-{
-  const SFloat __result = toFP_Word64_ToFloat(0x000000000000002aULL);
-
-  printf("toFP_Word64_ToFloat(0x000000000000002aULL) = %a\n", __result);
-}
-
-void toFP_Float_ToFloat_driver(void)
-{
-  const SFloat __result = toFP_Float_ToFloat(0x1.5p5F /* 42.0F */);
-
-  printf("toFP_Float_ToFloat(0x1.5p5F /* 42.0F */) = %a\n", __result);
-}
-
-void toFP_Double_ToFloat_driver(void)
-{
-  const SFloat __result = toFP_Double_ToFloat(0x1.5p5 /* 42.0 */);
-
-  printf("toFP_Double_ToFloat(0x1.5p5 /* 42.0 */) = %a\n", __result);
-}
-
-void toFP_Integer_ToFloat_driver(void)
-{
-  const SFloat __result = toFP_Integer_ToFloat(0x000000000000002aLL);
-
-  printf("toFP_Integer_ToFloat(0x000000000000002aLL) = %a\n", __result);
-}
-
-void toFP_Real_ToFloat_driver(void)
-{
-  const SFloat __result = toFP_Real_ToFloat(42.0L);
-
-  printf("toFP_Real_ToFloat(42.0L) = %a\n", __result);
-}
-
-void toFP_Int8_ToDouble_driver(void)
-{
-  const SDouble __result = toFP_Int8_ToDouble(42);
-
-  printf("toFP_Int8_ToDouble(42) = %a\n", __result);
-}
-
-void toFP_Int16_ToDouble_driver(void)
-{
-  const SDouble __result = toFP_Int16_ToDouble(0x002a);
-
-  printf("toFP_Int16_ToDouble(0x002a) = %a\n", __result);
-}
-
-void toFP_Int32_ToDouble_driver(void)
-{
-  const SDouble __result = toFP_Int32_ToDouble(0x0000002aL);
-
-  printf("toFP_Int32_ToDouble(0x0000002aL) = %a\n", __result);
-}
-
-void toFP_Int64_ToDouble_driver(void)
-{
-  const SDouble __result = toFP_Int64_ToDouble(0x000000000000002aLL);
-
-  printf("toFP_Int64_ToDouble(0x000000000000002aLL) = %a\n", __result);
-}
-
-void toFP_Word8_ToDouble_driver(void)
-{
-  const SDouble __result = toFP_Word8_ToDouble(42);
-
-  printf("toFP_Word8_ToDouble(42) = %a\n", __result);
-}
-
-void toFP_Word16_ToDouble_driver(void)
-{
-  const SDouble __result = toFP_Word16_ToDouble(0x002aU);
-
-  printf("toFP_Word16_ToDouble(0x002aU) = %a\n", __result);
-}
-
-void toFP_Word32_ToDouble_driver(void)
-{
-  const SDouble __result = toFP_Word32_ToDouble(0x0000002aUL);
-
-  printf("toFP_Word32_ToDouble(0x0000002aUL) = %a\n", __result);
-}
-
-void toFP_Word64_ToDouble_driver(void)
-{
-  const SDouble __result = toFP_Word64_ToDouble(0x000000000000002aULL);
-
-  printf("toFP_Word64_ToDouble(0x000000000000002aULL) = %a\n", __result);
-}
-
-void toFP_Float_ToDouble_driver(void)
-{
-  const SDouble __result = toFP_Float_ToDouble(0x1.5p5F /* 42.0F */);
-
-  printf("toFP_Float_ToDouble(0x1.5p5F /* 42.0F */) = %a\n", __result);
-}
-
-void toFP_Double_ToDouble_driver(void)
-{
-  const SDouble __result = toFP_Double_ToDouble(0x1.5p5 /* 42.0 */);
-
-  printf("toFP_Double_ToDouble(0x1.5p5 /* 42.0 */) = %a\n", __result);
-}
-
-void toFP_Integer_ToDouble_driver(void)
-{
-  const SDouble __result = toFP_Integer_ToDouble(0x000000000000002aLL);
-
-  printf("toFP_Integer_ToDouble(0x000000000000002aLL) = %a\n", __result);
-}
-
-void toFP_Real_ToDouble_driver(void)
-{
-  const SDouble __result = toFP_Real_ToDouble(42.0L);
-
-  printf("toFP_Real_ToDouble(42.0L) = %a\n", __result);
-}
-
-void fromFP_Float_ToInt8_driver(void)
-{
-  const SInt8 __result = fromFP_Float_ToInt8(0x1.5p5F /* 42.0F */);
-
-  printf("fromFP_Float_ToInt8(0x1.5p5F /* 42.0F */) = %"PRId8"\n", __result);
-}
-
-void fromFP_Float_ToInt16_driver(void)
-{
-  const SInt16 __result = fromFP_Float_ToInt16(0x1.5p5F /* 42.0F */);
-
-  printf("fromFP_Float_ToInt16(0x1.5p5F /* 42.0F */) = %"PRId16"\n", __result);
-}
-
-void fromFP_Float_ToInt32_driver(void)
-{
-  const SInt32 __result = fromFP_Float_ToInt32(0x1.5p5F /* 42.0F */);
-
-  printf("fromFP_Float_ToInt32(0x1.5p5F /* 42.0F */) = %"PRId32"L\n", __result);
-}
-
-void fromFP_Float_ToInt64_driver(void)
-{
-  const SInt64 __result = fromFP_Float_ToInt64(0x1.5p5F /* 42.0F */);
-
-  printf("fromFP_Float_ToInt64(0x1.5p5F /* 42.0F */) = %"PRId64"LL\n", __result);
-}
-
-void fromFP_Float_ToWord8_driver(void)
-{
-  const SWord8 __result = fromFP_Float_ToWord8(0x1.5p5F /* 42.0F */);
-
-  printf("fromFP_Float_ToWord8(0x1.5p5F /* 42.0F */) = %"PRIu8"\n", __result);
-}
-
-void fromFP_Float_ToWord16_driver(void)
-{
-  const SWord16 __result = fromFP_Float_ToWord16(0x1.5p5F /* 42.0F */);
-
-  printf("fromFP_Float_ToWord16(0x1.5p5F /* 42.0F */) = 0x%04"PRIx16"U\n", __result);
-}
-
-void fromFP_Float_ToWord32_driver(void)
-{
-  const SWord32 __result = fromFP_Float_ToWord32(0x1.5p5F /* 42.0F */);
-
-  printf("fromFP_Float_ToWord32(0x1.5p5F /* 42.0F */) = 0x%08"PRIx32"UL\n", __result);
-}
-
-void fromFP_Float_ToWord64_driver(void)
-{
-  const SWord64 __result = fromFP_Float_ToWord64(0x1.5p5F /* 42.0F */);
-
-  printf("fromFP_Float_ToWord64(0x1.5p5F /* 42.0F */) = 0x%016"PRIx64"ULL\n", __result);
-}
-
-void fromFP_Float_ToFloat_driver(void)
-{
-  const SFloat __result = fromFP_Float_ToFloat(0x1.5p5F /* 42.0F */);
-
-  printf("fromFP_Float_ToFloat(0x1.5p5F /* 42.0F */) = %a\n", __result);
-}
-
-void fromFP_Float_ToDouble_driver(void)
-{
-  const SDouble __result = fromFP_Float_ToDouble(0x1.5p5F /* 42.0F */);
-
-  printf("fromFP_Float_ToDouble(0x1.5p5F /* 42.0F */) = %a\n", __result);
-}
-
-void fromFP_Float_ToInteger_driver(void)
-{
-  const SInteger __result = fromFP_Float_ToInteger(0x1.5p5F /* 42.0F */);
-
-  printf("fromFP_Float_ToInteger(0x1.5p5F /* 42.0F */) = %"PRId64"LL\n", __result);
-}
-
-void fromFP_Float_ToReal_driver(void)
-{
-  const SReal __result = fromFP_Float_ToReal(0x1.5p5F /* 42.0F */);
-
-  printf("fromFP_Float_ToReal(0x1.5p5F /* 42.0F */) = %Lf\n", __result);
-}
-
-void fromFP_DoubleTo_Int8_driver(void)
-{
-  const SInt8 __result = fromFP_DoubleTo_Int8(0x1.5p5 /* 42.0 */);
-
-  printf("fromFP_DoubleTo_Int8(0x1.5p5 /* 42.0 */) = %"PRId8"\n", __result);
-}
-
-void fromFP_DoubleTo_Int16_driver(void)
-{
-  const SInt16 __result = fromFP_DoubleTo_Int16(0x1.5p5 /* 42.0 */);
-
-  printf("fromFP_DoubleTo_Int16(0x1.5p5 /* 42.0 */) = %"PRId16"\n", __result);
-}
-
-void fromFP_DoubleTo_Int32_driver(void)
-{
-  const SInt32 __result = fromFP_DoubleTo_Int32(0x1.5p5 /* 42.0 */);
-
-  printf("fromFP_DoubleTo_Int32(0x1.5p5 /* 42.0 */) = %"PRId32"L\n", __result);
-}
-
-void fromFP_DoubleTo_Int64_driver(void)
-{
-  const SInt64 __result = fromFP_DoubleTo_Int64(0x1.5p5 /* 42.0 */);
-
-  printf("fromFP_DoubleTo_Int64(0x1.5p5 /* 42.0 */) = %"PRId64"LL\n", __result);
-}
-
-void fromFP_DoubleTo_Word8_driver(void)
-{
-  const SWord8 __result = fromFP_DoubleTo_Word8(0x1.5p5 /* 42.0 */);
-
-  printf("fromFP_DoubleTo_Word8(0x1.5p5 /* 42.0 */) = %"PRIu8"\n", __result);
-}
-
-void fromFP_DoubleTo_Word16_driver(void)
-{
-  const SWord16 __result = fromFP_DoubleTo_Word16(0x1.5p5 /* 42.0 */);
-
-  printf("fromFP_DoubleTo_Word16(0x1.5p5 /* 42.0 */) = 0x%04"PRIx16"U\n", __result);
-}
-
-void fromFP_DoubleTo_Word32_driver(void)
-{
-  const SWord32 __result = fromFP_DoubleTo_Word32(0x1.5p5 /* 42.0 */);
-
-  printf("fromFP_DoubleTo_Word32(0x1.5p5 /* 42.0 */) = 0x%08"PRIx32"UL\n", __result);
-}
-
-void fromFP_DoubleTo_Word64_driver(void)
-{
-  const SWord64 __result = fromFP_DoubleTo_Word64(0x1.5p5 /* 42.0 */);
-
-  printf("fromFP_DoubleTo_Word64(0x1.5p5 /* 42.0 */) = 0x%016"PRIx64"ULL\n", __result);
-}
-
-void fromFP_DoubleTo_Float_driver(void)
-{
-  const SFloat __result = fromFP_DoubleTo_Float(0x1.5p5 /* 42.0 */);
-
-  printf("fromFP_DoubleTo_Float(0x1.5p5 /* 42.0 */) = %a\n", __result);
-}
-
-void fromFP_DoubleTo_Double_driver(void)
-{
-  const SDouble __result = fromFP_DoubleTo_Double(0x1.5p5 /* 42.0 */);
-
-  printf("fromFP_DoubleTo_Double(0x1.5p5 /* 42.0 */) = %a\n", __result);
-}
-
-void fromFP_DoubleTo_Integer_driver(void)
-{
-  const SInteger __result = fromFP_DoubleTo_Integer(0x1.5p5 /* 42.0 */);
-
-  printf("fromFP_DoubleTo_Integer(0x1.5p5 /* 42.0 */) = %"PRId64"LL\n", __result);
-}
-
-void fromFP_DoubleTo_Real_driver(void)
-{
-  const SReal __result = fromFP_DoubleTo_Real(0x1.5p5 /* 42.0 */);
-
-  printf("fromFP_DoubleTo_Real(0x1.5p5 /* 42.0 */) = %Lf\n", __result);
-}
-
-void fromFP_SWord32_SFloat_driver(void)
-{
-  const SFloat __result = fromFP_SWord32_SFloat(0x0000002aUL);
-
-  printf("fromFP_SWord32_SFloat(0x0000002aUL) = %a\n", __result);
-}
-
-void fromFP_SWord64_SDouble_driver(void)
-{
-  const SDouble __result = fromFP_SWord64_SDouble(0x000000000000002aULL);
-
-  printf("fromFP_SWord64_SDouble(0x000000000000002aULL) = %a\n", __result);
-}
-
-void fromFP_SFloat_SWord32_driver(void)
-{
-  const SWord32 __result = fromFP_SFloat_SWord32(0x1.5p5F /* 42.0F */);
-
-  printf("fromFP_SFloat_SWord32(0x1.5p5F /* 42.0F */) = 0x%08"PRIx32"UL\n", __result);
-}
-
-void fromFP_SDouble_SWord64_driver(void)
-{
-  const SWord64 __result = fromFP_SDouble_SWord64(0x1.5p5 /* 42.0 */);
-
-  printf("fromFP_SDouble_SWord64(0x1.5p5 /* 42.0 */) = 0x%016"PRIx64"ULL\n", __result);
-}
-
-void f_FP_Abs_driver(void)
-{
-  const SFloat __result = f_FP_Abs(0x1.5p5F /* 42.0F */);
-
-  printf("f_FP_Abs(0x1.5p5F /* 42.0F */) = %a\n", __result);
-}
-
-void d_FP_Abs_driver(void)
-{
-  const SDouble __result = d_FP_Abs(0x1.5p5 /* 42.0 */);
-
-  printf("d_FP_Abs(0x1.5p5 /* 42.0 */) = %a\n", __result);
-}
-
-void f_FP_Neg_driver(void)
-{
-  const SFloat __result = f_FP_Neg(0x1.5p5F /* 42.0F */);
-
-  printf("f_FP_Neg(0x1.5p5F /* 42.0F */) = %a\n", __result);
-}
-
-void d_FP_Neg_driver(void)
-{
-  const SDouble __result = d_FP_Neg(0x1.5p5 /* 42.0 */);
-
-  printf("d_FP_Neg(0x1.5p5 /* 42.0 */) = %a\n", __result);
-}
-
-void f_FP_Add_driver(void)
-{
-  const SFloat __result = f_FP_Add(0x1.5p5F /* 42.0F */,
-                                   0x1.58p5F /* 43.0F */);
-
-  printf("f_FP_Add(0x1.5p5F /* 42.0F */, 0x1.58p5F /* 43.0F */) = %a\n", __result);
-}
-
-void d_FP_Add_driver(void)
-{
-  const SDouble __result = d_FP_Add(0x1.5p5 /* 42.0 */,
-                                    0x1.58p5 /* 43.0 */);
-
-  printf("d_FP_Add(0x1.5p5 /* 42.0 */, 0x1.58p5 /* 43.0 */) = %a\n", __result);
-}
-
-void f_FP_Sub_driver(void)
-{
-  const SFloat __result = f_FP_Sub(0x1.5p5F /* 42.0F */,
-                                   0x1.58p5F /* 43.0F */);
-
-  printf("f_FP_Sub(0x1.5p5F /* 42.0F */, 0x1.58p5F /* 43.0F */) = %a\n", __result);
-}
-
-void d_FP_Sub_driver(void)
-{
-  const SDouble __result = d_FP_Sub(0x1.5p5 /* 42.0 */,
-                                    0x1.58p5 /* 43.0 */);
-
-  printf("d_FP_Sub(0x1.5p5 /* 42.0 */, 0x1.58p5 /* 43.0 */) = %a\n", __result);
-}
-
-void f_FP_Mul_driver(void)
-{
-  const SFloat __result = f_FP_Mul(0x1.5p5F /* 42.0F */,
-                                   0x1.58p5F /* 43.0F */);
-
-  printf("f_FP_Mul(0x1.5p5F /* 42.0F */, 0x1.58p5F /* 43.0F */) = %a\n", __result);
-}
-
-void d_FP_Mul_driver(void)
-{
-  const SDouble __result = d_FP_Mul(0x1.5p5 /* 42.0 */,
-                                    0x1.58p5 /* 43.0 */);
-
-  printf("d_FP_Mul(0x1.5p5 /* 42.0 */, 0x1.58p5 /* 43.0 */) = %a\n", __result);
-}
-
-void f_FP_Div_driver(void)
-{
-  const SFloat __result = f_FP_Div(0x1.5p5F /* 42.0F */,
-                                   0x1.58p5F /* 43.0F */);
-
-  printf("f_FP_Div(0x1.5p5F /* 42.0F */, 0x1.58p5F /* 43.0F */) = %a\n", __result);
-}
-
-void d_FP_Div_driver(void)
-{
-  const SDouble __result = d_FP_Div(0x1.5p5 /* 42.0 */,
-                                    0x1.58p5 /* 43.0 */);
-
-  printf("d_FP_Div(0x1.5p5 /* 42.0 */, 0x1.58p5 /* 43.0 */) = %a\n", __result);
-}
-
-void f_FP_FMA_driver(void)
-{
-  const SFloat __result = f_FP_FMA(0x1.5p5F /* 42.0F */,
-                                   0x1.58p5F /* 43.0F */, 0x1.6p5F /* 44.0F */);
-
-  printf("f_FP_FMA(0x1.5p5F /* 42.0F */, 0x1.58p5F /* 43.0F */, 0x1.6p5F /* 44.0F */) = %a\n", __result);
-}
-
-void d_FP_FMA_driver(void)
-{
-  const SDouble __result = d_FP_FMA(0x1.5p5 /* 42.0 */,
-                                    0x1.58p5 /* 43.0 */, 0x1.6p5 /* 44.0 */);
-
-  printf("d_FP_FMA(0x1.5p5 /* 42.0 */, 0x1.58p5 /* 43.0 */, 0x1.6p5 /* 44.0 */) = %a\n", __result);
-}
-
-void f_FP_Sqrt_driver(void)
-{
-  const SFloat __result = f_FP_Sqrt(0x1.5p5F /* 42.0F */);
-
-  printf("f_FP_Sqrt(0x1.5p5F /* 42.0F */) = %a\n", __result);
-}
-
-void d_FP_Sqrt_driver(void)
-{
-  const SDouble __result = d_FP_Sqrt(0x1.5p5 /* 42.0 */);
-
-  printf("d_FP_Sqrt(0x1.5p5 /* 42.0 */) = %a\n", __result);
-}
-
-void f_FP_Rem_driver(void)
-{
-  const SFloat __result = f_FP_Rem(0x1.5p5F /* 42.0F */,
-                                   0x1.58p5F /* 43.0F */);
-
-  printf("f_FP_Rem(0x1.5p5F /* 42.0F */, 0x1.58p5F /* 43.0F */) = %a\n", __result);
-}
-
-void d_FP_Rem_driver(void)
-{
-  const SDouble __result = d_FP_Rem(0x1.5p5 /* 42.0 */,
-                                    0x1.58p5 /* 43.0 */);
-
-  printf("d_FP_Rem(0x1.5p5 /* 42.0 */, 0x1.58p5 /* 43.0 */) = %a\n", __result);
-}
-
-void f_FP_RoundToIntegral_driver(void)
-{
-  const SFloat __result = f_FP_RoundToIntegral(0x1.5p5F /* 42.0F */);
-
-  printf("f_FP_RoundToIntegral(0x1.5p5F /* 42.0F */) = %a\n", __result);
-}
-
-void d_FP_RoundToIntegral_driver(void)
-{
-  const SDouble __result = d_FP_RoundToIntegral(0x1.5p5 /* 42.0 */);
-
-  printf("d_FP_RoundToIntegral(0x1.5p5 /* 42.0 */) = %a\n", __result);
-}
-
-void f_FP_Min_driver(void)
-{
-  const SFloat __result = f_FP_Min(0x1.5p5F /* 42.0F */,
-                                   0x1.58p5F /* 43.0F */);
-
-  printf("f_FP_Min(0x1.5p5F /* 42.0F */, 0x1.58p5F /* 43.0F */) = %a\n", __result);
-}
-
-void d_FP_Min_driver(void)
-{
-  const SDouble __result = d_FP_Min(0x1.5p5 /* 42.0 */,
-                                    0x1.58p5 /* 43.0 */);
-
-  printf("d_FP_Min(0x1.5p5 /* 42.0 */, 0x1.58p5 /* 43.0 */) = %a\n", __result);
-}
-
-void f_FP_Max_driver(void)
-{
-  const SFloat __result = f_FP_Max(0x1.5p5F /* 42.0F */,
-                                   0x1.58p5F /* 43.0F */);
-
-  printf("f_FP_Max(0x1.5p5F /* 42.0F */, 0x1.58p5F /* 43.0F */) = %a\n", __result);
-}
-
-void d_FP_Max_driver(void)
-{
-  const SDouble __result = d_FP_Max(0x1.5p5 /* 42.0 */,
-                                    0x1.58p5 /* 43.0 */);
-
-  printf("d_FP_Max(0x1.5p5 /* 42.0 */, 0x1.58p5 /* 43.0 */) = %a\n", __result);
-}
-
-void f_FP_IsEqualObject_driver(void)
-{
-  const SBool __result = f_FP_IsEqualObject(0x1.5p5F /* 42.0F */,
-                                            0x1.58p5F /* 43.0F */);
-
-  printf("f_FP_IsEqualObject(0x1.5p5F /* 42.0F */, 0x1.58p5F /* 43.0F */) = %d\n", __result);
-}
-
-void d_FP_IsEqualObject_driver(void)
-{
-  const SBool __result = d_FP_IsEqualObject(0x1.5p5 /* 42.0 */,
-                                            0x1.58p5 /* 43.0 */);
-
-  printf("d_FP_IsEqualObject(0x1.5p5 /* 42.0 */, 0x1.58p5 /* 43.0 */) = %d\n", __result);
-}
-
-void f_FP_IsNormal_driver(void)
-{
-  const SBool __result = f_FP_IsNormal(0x1.5p5F /* 42.0F */);
-
-  printf("f_FP_IsNormal(0x1.5p5F /* 42.0F */) = %d\n", __result);
-}
-
-void d_FP_IsNormal_driver(void)
-{
-  const SBool __result = d_FP_IsNormal(0x1.5p5 /* 42.0 */);
-
-  printf("d_FP_IsNormal(0x1.5p5 /* 42.0 */) = %d\n", __result);
-}
-
-void f_FP_IsZero_driver(void)
-{
-  const SBool __result = f_FP_IsZero(0x1.5p5F /* 42.0F */);
-
-  printf("f_FP_IsZero(0x1.5p5F /* 42.0F */) = %d\n", __result);
-}
-
-void d_FP_IsZero_driver(void)
-{
-  const SBool __result = d_FP_IsZero(0x1.5p5 /* 42.0 */);
-
-  printf("d_FP_IsZero(0x1.5p5 /* 42.0 */) = %d\n", __result);
-}
-
-void f_FP_IsSubnormal_driver(void)
-{
-  const SBool __result = f_FP_IsSubnormal(0x1.5p5F /* 42.0F */);
-
-  printf("f_FP_IsSubnormal(0x1.5p5F /* 42.0F */) = %d\n", __result);
-}
-
-void d_FP_IsSubnormal_driver(void)
-{
-  const SBool __result = d_FP_IsSubnormal(0x1.5p5 /* 42.0 */);
-
-  printf("d_FP_IsSubnormal(0x1.5p5 /* 42.0 */) = %d\n", __result);
-}
-
-void f_FP_IsInfinite_driver(void)
-{
-  const SBool __result = f_FP_IsInfinite(0x1.5p5F /* 42.0F */);
-
-  printf("f_FP_IsInfinite(0x1.5p5F /* 42.0F */) = %d\n", __result);
-}
-
-void d_FP_IsInfinite_driver(void)
-{
-  const SBool __result = d_FP_IsInfinite(0x1.5p5 /* 42.0 */);
-
-  printf("d_FP_IsInfinite(0x1.5p5 /* 42.0 */) = %d\n", __result);
-}
-
-void f_FP_IsNaN_driver(void)
-{
-  const SBool __result = f_FP_IsNaN(0x1.5p5F /* 42.0F */);
-
-  printf("f_FP_IsNaN(0x1.5p5F /* 42.0F */) = %d\n", __result);
-}
-
-void d_FP_IsNaN_driver(void)
-{
-  const SBool __result = d_FP_IsNaN(0x1.5p5 /* 42.0 */);
-
-  printf("d_FP_IsNaN(0x1.5p5 /* 42.0 */) = %d\n", __result);
-}
-
-void f_FP_IsNegative_driver(void)
-{
-  const SBool __result = f_FP_IsNegative(0x1.5p5F /* 42.0F */);
-
-  printf("f_FP_IsNegative(0x1.5p5F /* 42.0F */) = %d\n", __result);
-}
-
-void d_FP_IsNegative_driver(void)
-{
-  const SBool __result = d_FP_IsNegative(0x1.5p5 /* 42.0 */);
-
-  printf("d_FP_IsNegative(0x1.5p5 /* 42.0 */) = %d\n", __result);
-}
-
-void f_FP_IsPositive_driver(void)
-{
-  const SBool __result = f_FP_IsPositive(0x1.5p5F /* 42.0F */);
-
-  printf("f_FP_IsPositive(0x1.5p5F /* 42.0F */) = %d\n", __result);
-}
-
-void d_FP_IsPositive_driver(void)
-{
-  const SBool __result = d_FP_IsPositive(0x1.5p5 /* 42.0 */);
-
-  printf("d_FP_IsPositive(0x1.5p5 /* 42.0 */) = %d\n", __result);
-}
-
-int main(void)
-{
-  printf("====================================\n");
-  printf("** Driver run for toFP_Int8_ToFloat:\n");
-  printf("====================================\n");
-  toFP_Int8_ToFloat_driver();
-
-  printf("=====================================\n");
-  printf("** Driver run for toFP_Int16_ToFloat:\n");
-  printf("=====================================\n");
-  toFP_Int16_ToFloat_driver();
-
-  printf("=====================================\n");
-  printf("** Driver run for toFP_Int32_ToFloat:\n");
-  printf("=====================================\n");
-  toFP_Int32_ToFloat_driver();
-
-  printf("=====================================\n");
-  printf("** Driver run for toFP_Int64_ToFloat:\n");
-  printf("=====================================\n");
-  toFP_Int64_ToFloat_driver();
-
-  printf("=====================================\n");
-  printf("** Driver run for toFP_Word8_ToFloat:\n");
-  printf("=====================================\n");
-  toFP_Word8_ToFloat_driver();
-
-  printf("======================================\n");
-  printf("** Driver run for toFP_Word16_ToFloat:\n");
-  printf("======================================\n");
-  toFP_Word16_ToFloat_driver();
-
-  printf("======================================\n");
-  printf("** Driver run for toFP_Word32_ToFloat:\n");
-  printf("======================================\n");
-  toFP_Word32_ToFloat_driver();
-
-  printf("======================================\n");
-  printf("** Driver run for toFP_Word64_ToFloat:\n");
-  printf("======================================\n");
-  toFP_Word64_ToFloat_driver();
-
-  printf("=====================================\n");
-  printf("** Driver run for toFP_Float_ToFloat:\n");
-  printf("=====================================\n");
-  toFP_Float_ToFloat_driver();
-
-  printf("======================================\n");
-  printf("** Driver run for toFP_Double_ToFloat:\n");
-  printf("======================================\n");
-  toFP_Double_ToFloat_driver();
-
-  printf("=======================================\n");
-  printf("** Driver run for toFP_Integer_ToFloat:\n");
-  printf("=======================================\n");
-  toFP_Integer_ToFloat_driver();
-
-  printf("====================================\n");
-  printf("** Driver run for toFP_Real_ToFloat:\n");
-  printf("====================================\n");
-  toFP_Real_ToFloat_driver();
-
-  printf("=====================================\n");
-  printf("** Driver run for toFP_Int8_ToDouble:\n");
-  printf("=====================================\n");
-  toFP_Int8_ToDouble_driver();
-
-  printf("======================================\n");
-  printf("** Driver run for toFP_Int16_ToDouble:\n");
-  printf("======================================\n");
-  toFP_Int16_ToDouble_driver();
-
-  printf("======================================\n");
-  printf("** Driver run for toFP_Int32_ToDouble:\n");
-  printf("======================================\n");
-  toFP_Int32_ToDouble_driver();
-
-  printf("======================================\n");
-  printf("** Driver run for toFP_Int64_ToDouble:\n");
-  printf("======================================\n");
-  toFP_Int64_ToDouble_driver();
-
-  printf("======================================\n");
-  printf("** Driver run for toFP_Word8_ToDouble:\n");
-  printf("======================================\n");
-  toFP_Word8_ToDouble_driver();
-
-  printf("=======================================\n");
-  printf("** Driver run for toFP_Word16_ToDouble:\n");
-  printf("=======================================\n");
-  toFP_Word16_ToDouble_driver();
-
-  printf("=======================================\n");
-  printf("** Driver run for toFP_Word32_ToDouble:\n");
-  printf("=======================================\n");
-  toFP_Word32_ToDouble_driver();
-
-  printf("=======================================\n");
-  printf("** Driver run for toFP_Word64_ToDouble:\n");
-  printf("=======================================\n");
-  toFP_Word64_ToDouble_driver();
-
-  printf("======================================\n");
-  printf("** Driver run for toFP_Float_ToDouble:\n");
-  printf("======================================\n");
-  toFP_Float_ToDouble_driver();
-
-  printf("=======================================\n");
-  printf("** Driver run for toFP_Double_ToDouble:\n");
-  printf("=======================================\n");
-  toFP_Double_ToDouble_driver();
-
-  printf("========================================\n");
-  printf("** Driver run for toFP_Integer_ToDouble:\n");
-  printf("========================================\n");
-  toFP_Integer_ToDouble_driver();
-
-  printf("=====================================\n");
-  printf("** Driver run for toFP_Real_ToDouble:\n");
-  printf("=====================================\n");
-  toFP_Real_ToDouble_driver();
-
-  printf("======================================\n");
-  printf("** Driver run for fromFP_Float_ToInt8:\n");
-  printf("======================================\n");
-  fromFP_Float_ToInt8_driver();
-
-  printf("=======================================\n");
-  printf("** Driver run for fromFP_Float_ToInt16:\n");
-  printf("=======================================\n");
-  fromFP_Float_ToInt16_driver();
-
-  printf("=======================================\n");
-  printf("** Driver run for fromFP_Float_ToInt32:\n");
-  printf("=======================================\n");
-  fromFP_Float_ToInt32_driver();
-
-  printf("=======================================\n");
-  printf("** Driver run for fromFP_Float_ToInt64:\n");
-  printf("=======================================\n");
-  fromFP_Float_ToInt64_driver();
-
-  printf("=======================================\n");
-  printf("** Driver run for fromFP_Float_ToWord8:\n");
-  printf("=======================================\n");
-  fromFP_Float_ToWord8_driver();
-
-  printf("========================================\n");
-  printf("** Driver run for fromFP_Float_ToWord16:\n");
-  printf("========================================\n");
-  fromFP_Float_ToWord16_driver();
-
-  printf("========================================\n");
-  printf("** Driver run for fromFP_Float_ToWord32:\n");
-  printf("========================================\n");
-  fromFP_Float_ToWord32_driver();
-
-  printf("========================================\n");
-  printf("** Driver run for fromFP_Float_ToWord64:\n");
-  printf("========================================\n");
-  fromFP_Float_ToWord64_driver();
-
-  printf("=======================================\n");
-  printf("** Driver run for fromFP_Float_ToFloat:\n");
-  printf("=======================================\n");
-  fromFP_Float_ToFloat_driver();
-
-  printf("========================================\n");
-  printf("** Driver run for fromFP_Float_ToDouble:\n");
-  printf("========================================\n");
-  fromFP_Float_ToDouble_driver();
-
-  printf("=========================================\n");
-  printf("** Driver run for fromFP_Float_ToInteger:\n");
-  printf("=========================================\n");
-  fromFP_Float_ToInteger_driver();
-
-  printf("======================================\n");
-  printf("** Driver run for fromFP_Float_ToReal:\n");
-  printf("======================================\n");
-  fromFP_Float_ToReal_driver();
-
-  printf("=======================================\n");
-  printf("** Driver run for fromFP_DoubleTo_Int8:\n");
-  printf("=======================================\n");
-  fromFP_DoubleTo_Int8_driver();
-
-  printf("========================================\n");
-  printf("** Driver run for fromFP_DoubleTo_Int16:\n");
-  printf("========================================\n");
-  fromFP_DoubleTo_Int16_driver();
-
-  printf("========================================\n");
-  printf("** Driver run for fromFP_DoubleTo_Int32:\n");
-  printf("========================================\n");
-  fromFP_DoubleTo_Int32_driver();
-
-  printf("========================================\n");
-  printf("** Driver run for fromFP_DoubleTo_Int64:\n");
-  printf("========================================\n");
-  fromFP_DoubleTo_Int64_driver();
-
-  printf("========================================\n");
-  printf("** Driver run for fromFP_DoubleTo_Word8:\n");
-  printf("========================================\n");
-  fromFP_DoubleTo_Word8_driver();
-
-  printf("=========================================\n");
-  printf("** Driver run for fromFP_DoubleTo_Word16:\n");
-  printf("=========================================\n");
-  fromFP_DoubleTo_Word16_driver();
-
-  printf("=========================================\n");
-  printf("** Driver run for fromFP_DoubleTo_Word32:\n");
-  printf("=========================================\n");
-  fromFP_DoubleTo_Word32_driver();
-
-  printf("=========================================\n");
-  printf("** Driver run for fromFP_DoubleTo_Word64:\n");
-  printf("=========================================\n");
-  fromFP_DoubleTo_Word64_driver();
-
-  printf("========================================\n");
-  printf("** Driver run for fromFP_DoubleTo_Float:\n");
-  printf("========================================\n");
-  fromFP_DoubleTo_Float_driver();
-
-  printf("=========================================\n");
-  printf("** Driver run for fromFP_DoubleTo_Double:\n");
-  printf("=========================================\n");
-  fromFP_DoubleTo_Double_driver();
-
-  printf("==========================================\n");
-  printf("** Driver run for fromFP_DoubleTo_Integer:\n");
-  printf("==========================================\n");
-  fromFP_DoubleTo_Integer_driver();
-
-  printf("=======================================\n");
-  printf("** Driver run for fromFP_DoubleTo_Real:\n");
-  printf("=======================================\n");
-  fromFP_DoubleTo_Real_driver();
-
-  printf("========================================\n");
-  printf("** Driver run for fromFP_SWord32_SFloat:\n");
-  printf("========================================\n");
-  fromFP_SWord32_SFloat_driver();
-
-  printf("=========================================\n");
-  printf("** Driver run for fromFP_SWord64_SDouble:\n");
-  printf("=========================================\n");
-  fromFP_SWord64_SDouble_driver();
-
-  printf("========================================\n");
-  printf("** Driver run for fromFP_SFloat_SWord32:\n");
-  printf("========================================\n");
-  fromFP_SFloat_SWord32_driver();
-
-  printf("=========================================\n");
-  printf("** Driver run for fromFP_SDouble_SWord64:\n");
-  printf("=========================================\n");
-  fromFP_SDouble_SWord64_driver();
-
-  printf("===========================\n");
-  printf("** Driver run for f_FP_Abs:\n");
-  printf("===========================\n");
-  f_FP_Abs_driver();
-
-  printf("===========================\n");
-  printf("** Driver run for d_FP_Abs:\n");
-  printf("===========================\n");
-  d_FP_Abs_driver();
-
-  printf("===========================\n");
-  printf("** Driver run for f_FP_Neg:\n");
-  printf("===========================\n");
-  f_FP_Neg_driver();
-
-  printf("===========================\n");
-  printf("** Driver run for d_FP_Neg:\n");
-  printf("===========================\n");
-  d_FP_Neg_driver();
-
-  printf("===========================\n");
-  printf("** Driver run for f_FP_Add:\n");
-  printf("===========================\n");
-  f_FP_Add_driver();
-
-  printf("===========================\n");
-  printf("** Driver run for d_FP_Add:\n");
-  printf("===========================\n");
-  d_FP_Add_driver();
-
-  printf("===========================\n");
-  printf("** Driver run for f_FP_Sub:\n");
-  printf("===========================\n");
-  f_FP_Sub_driver();
-
-  printf("===========================\n");
-  printf("** Driver run for d_FP_Sub:\n");
-  printf("===========================\n");
-  d_FP_Sub_driver();
-
-  printf("===========================\n");
-  printf("** Driver run for f_FP_Mul:\n");
-  printf("===========================\n");
-  f_FP_Mul_driver();
-
-  printf("===========================\n");
-  printf("** Driver run for d_FP_Mul:\n");
-  printf("===========================\n");
-  d_FP_Mul_driver();
-
-  printf("===========================\n");
-  printf("** Driver run for f_FP_Div:\n");
-  printf("===========================\n");
-  f_FP_Div_driver();
-
-  printf("===========================\n");
-  printf("** Driver run for d_FP_Div:\n");
-  printf("===========================\n");
-  d_FP_Div_driver();
-
-  printf("===========================\n");
-  printf("** Driver run for f_FP_FMA:\n");
-  printf("===========================\n");
-  f_FP_FMA_driver();
-
-  printf("===========================\n");
-  printf("** Driver run for d_FP_FMA:\n");
-  printf("===========================\n");
-  d_FP_FMA_driver();
-
-  printf("============================\n");
-  printf("** Driver run for f_FP_Sqrt:\n");
-  printf("============================\n");
-  f_FP_Sqrt_driver();
-
-  printf("============================\n");
-  printf("** Driver run for d_FP_Sqrt:\n");
-  printf("============================\n");
-  d_FP_Sqrt_driver();
-
-  printf("===========================\n");
-  printf("** Driver run for f_FP_Rem:\n");
-  printf("===========================\n");
-  f_FP_Rem_driver();
-
-  printf("===========================\n");
-  printf("** Driver run for d_FP_Rem:\n");
-  printf("===========================\n");
-  d_FP_Rem_driver();
-
-  printf("=======================================\n");
-  printf("** Driver run for f_FP_RoundToIntegral:\n");
-  printf("=======================================\n");
-  f_FP_RoundToIntegral_driver();
-
-  printf("=======================================\n");
-  printf("** Driver run for d_FP_RoundToIntegral:\n");
-  printf("=======================================\n");
-  d_FP_RoundToIntegral_driver();
-
-  printf("===========================\n");
-  printf("** Driver run for f_FP_Min:\n");
-  printf("===========================\n");
-  f_FP_Min_driver();
-
-  printf("===========================\n");
-  printf("** Driver run for d_FP_Min:\n");
-  printf("===========================\n");
-  d_FP_Min_driver();
-
-  printf("===========================\n");
-  printf("** Driver run for f_FP_Max:\n");
-  printf("===========================\n");
-  f_FP_Max_driver();
-
-  printf("===========================\n");
-  printf("** Driver run for d_FP_Max:\n");
-  printf("===========================\n");
-  d_FP_Max_driver();
-
-  printf("=====================================\n");
-  printf("** Driver run for f_FP_IsEqualObject:\n");
-  printf("=====================================\n");
-  f_FP_IsEqualObject_driver();
-
-  printf("=====================================\n");
-  printf("** Driver run for d_FP_IsEqualObject:\n");
-  printf("=====================================\n");
-  d_FP_IsEqualObject_driver();
-
-  printf("================================\n");
-  printf("** Driver run for f_FP_IsNormal:\n");
-  printf("================================\n");
-  f_FP_IsNormal_driver();
-
-  printf("================================\n");
-  printf("** Driver run for d_FP_IsNormal:\n");
-  printf("================================\n");
-  d_FP_IsNormal_driver();
-
-  printf("==============================\n");
-  printf("** Driver run for f_FP_IsZero:\n");
-  printf("==============================\n");
-  f_FP_IsZero_driver();
-
-  printf("==============================\n");
-  printf("** Driver run for d_FP_IsZero:\n");
-  printf("==============================\n");
-  d_FP_IsZero_driver();
-
-  printf("===================================\n");
-  printf("** Driver run for f_FP_IsSubnormal:\n");
-  printf("===================================\n");
-  f_FP_IsSubnormal_driver();
-
-  printf("===================================\n");
-  printf("** Driver run for d_FP_IsSubnormal:\n");
-  printf("===================================\n");
-  d_FP_IsSubnormal_driver();
-
-  printf("==================================\n");
-  printf("** Driver run for f_FP_IsInfinite:\n");
-  printf("==================================\n");
-  f_FP_IsInfinite_driver();
-
-  printf("==================================\n");
-  printf("** Driver run for d_FP_IsInfinite:\n");
-  printf("==================================\n");
-  d_FP_IsInfinite_driver();
-
-  printf("=============================\n");
-  printf("** Driver run for f_FP_IsNaN:\n");
-  printf("=============================\n");
-  f_FP_IsNaN_driver();
-
-  printf("=============================\n");
-  printf("** Driver run for d_FP_IsNaN:\n");
-  printf("=============================\n");
-  d_FP_IsNaN_driver();
-
-  printf("==================================\n");
-  printf("** Driver run for f_FP_IsNegative:\n");
-  printf("==================================\n");
-  f_FP_IsNegative_driver();
-
-  printf("==================================\n");
-  printf("** Driver run for d_FP_IsNegative:\n");
-  printf("==================================\n");
-  d_FP_IsNegative_driver();
-
-  printf("==================================\n");
-  printf("** Driver run for f_FP_IsPositive:\n");
-  printf("==================================\n");
-  f_FP_IsPositive_driver();
-
-  printf("==================================\n");
-  printf("** Driver run for d_FP_IsPositive:\n");
-  printf("==================================\n");
-  d_FP_IsPositive_driver();
-
-  return 0;
-}
-== END: "floatCodeGen_driver.c" ==================
-== BEGIN: "Makefile" ================
-# Makefile for floatCodeGen. 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
-LDFLAGS?=-lm
-AR?=ar
-ARFLAGS?=cr
-
-all: floatCodeGen.a floatCodeGen_driver
-
-floatCodeGen.a: toFP_Int8_ToFloat.o toFP_Int16_ToFloat.o toFP_Int32_ToFloat.o toFP_Int64_ToFloat.o toFP_Word8_ToFloat.o toFP_Word16_ToFloat.o toFP_Word32_ToFloat.o toFP_Word64_ToFloat.o toFP_Float_ToFloat.o toFP_Double_ToFloat.o toFP_Integer_ToFloat.o toFP_Real_ToFloat.o toFP_Int8_ToDouble.o toFP_Int16_ToDouble.o toFP_Int32_ToDouble.o toFP_Int64_ToDouble.o toFP_Word8_ToDouble.o toFP_Word16_ToDouble.o toFP_Word32_ToDouble.o toFP_Word64_ToDouble.o toFP_Float_ToDouble.o toFP_Double_ToDouble.o toFP_Integer_ToDouble.o toFP_Real_ToDouble.o fromFP_Float_ToInt8.o fromFP_Float_ToInt16.o fromFP_Float_ToInt32.o fromFP_Float_ToInt64.o fromFP_Float_ToWord8.o fromFP_Float_ToWord16.o fromFP_Float_ToWord32.o fromFP_Float_ToWord64.o fromFP_Float_ToFloat.o fromFP_Float_ToDouble.o fromFP_Float_ToInteger.o fromFP_Float_ToReal.o fromFP_DoubleTo_Int8.o fromFP_DoubleTo_Int16.o fromFP_DoubleTo_Int32.o fromFP_DoubleTo_Int64.o fromFP_DoubleTo_Word8.o fromFP_DoubleTo_Word16.o fromFP_DoubleTo_Word32.o fromFP_DoubleTo_Word64.o fromFP_DoubleTo_Float.o fromFP_DoubleTo_Double.o fromFP_DoubleTo_Integer.o fromFP_DoubleTo_Real.o fromFP_SWord32_SFloat.o fromFP_SWord64_SDouble.o fromFP_SFloat_SWord32.o fromFP_SDouble_SWord64.o f_FP_Abs.o d_FP_Abs.o f_FP_Neg.o d_FP_Neg.o f_FP_Add.o d_FP_Add.o f_FP_Sub.o d_FP_Sub.o f_FP_Mul.o d_FP_Mul.o f_FP_Div.o d_FP_Div.o f_FP_FMA.o d_FP_FMA.o f_FP_Sqrt.o d_FP_Sqrt.o f_FP_Rem.o d_FP_Rem.o f_FP_RoundToIntegral.o d_FP_RoundToIntegral.o f_FP_Min.o d_FP_Min.o f_FP_Max.o d_FP_Max.o f_FP_IsEqualObject.o d_FP_IsEqualObject.o f_FP_IsNormal.o d_FP_IsNormal.o f_FP_IsZero.o d_FP_IsZero.o f_FP_IsSubnormal.o d_FP_IsSubnormal.o f_FP_IsInfinite.o d_FP_IsInfinite.o f_FP_IsNaN.o d_FP_IsNaN.o f_FP_IsNegative.o d_FP_IsNegative.o f_FP_IsPositive.o d_FP_IsPositive.o
-	${AR} ${ARFLAGS} $@ $^
-
-floatCodeGen_driver: floatCodeGen_driver.c floatCodeGen.h
-	${CC} ${CCFLAGS} $< -o $@ floatCodeGen.a ${LDFLAGS}
-
-toFP_Int8_ToFloat.o: toFP_Int8_ToFloat.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-toFP_Int16_ToFloat.o: toFP_Int16_ToFloat.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-toFP_Int32_ToFloat.o: toFP_Int32_ToFloat.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-toFP_Int64_ToFloat.o: toFP_Int64_ToFloat.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-toFP_Word8_ToFloat.o: toFP_Word8_ToFloat.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-toFP_Word16_ToFloat.o: toFP_Word16_ToFloat.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-toFP_Word32_ToFloat.o: toFP_Word32_ToFloat.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-toFP_Word64_ToFloat.o: toFP_Word64_ToFloat.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-toFP_Float_ToFloat.o: toFP_Float_ToFloat.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-toFP_Double_ToFloat.o: toFP_Double_ToFloat.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-toFP_Integer_ToFloat.o: toFP_Integer_ToFloat.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-toFP_Real_ToFloat.o: toFP_Real_ToFloat.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-toFP_Int8_ToDouble.o: toFP_Int8_ToDouble.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-toFP_Int16_ToDouble.o: toFP_Int16_ToDouble.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-toFP_Int32_ToDouble.o: toFP_Int32_ToDouble.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-toFP_Int64_ToDouble.o: toFP_Int64_ToDouble.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-toFP_Word8_ToDouble.o: toFP_Word8_ToDouble.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-toFP_Word16_ToDouble.o: toFP_Word16_ToDouble.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-toFP_Word32_ToDouble.o: toFP_Word32_ToDouble.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-toFP_Word64_ToDouble.o: toFP_Word64_ToDouble.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-toFP_Float_ToDouble.o: toFP_Float_ToDouble.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-toFP_Double_ToDouble.o: toFP_Double_ToDouble.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-toFP_Integer_ToDouble.o: toFP_Integer_ToDouble.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-toFP_Real_ToDouble.o: toFP_Real_ToDouble.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-fromFP_Float_ToInt8.o: fromFP_Float_ToInt8.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-fromFP_Float_ToInt16.o: fromFP_Float_ToInt16.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-fromFP_Float_ToInt32.o: fromFP_Float_ToInt32.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-fromFP_Float_ToInt64.o: fromFP_Float_ToInt64.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-fromFP_Float_ToWord8.o: fromFP_Float_ToWord8.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-fromFP_Float_ToWord16.o: fromFP_Float_ToWord16.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-fromFP_Float_ToWord32.o: fromFP_Float_ToWord32.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-fromFP_Float_ToWord64.o: fromFP_Float_ToWord64.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-fromFP_Float_ToFloat.o: fromFP_Float_ToFloat.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-fromFP_Float_ToDouble.o: fromFP_Float_ToDouble.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-fromFP_Float_ToInteger.o: fromFP_Float_ToInteger.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-fromFP_Float_ToReal.o: fromFP_Float_ToReal.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-fromFP_DoubleTo_Int8.o: fromFP_DoubleTo_Int8.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-fromFP_DoubleTo_Int16.o: fromFP_DoubleTo_Int16.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-fromFP_DoubleTo_Int32.o: fromFP_DoubleTo_Int32.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-fromFP_DoubleTo_Int64.o: fromFP_DoubleTo_Int64.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-fromFP_DoubleTo_Word8.o: fromFP_DoubleTo_Word8.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-fromFP_DoubleTo_Word16.o: fromFP_DoubleTo_Word16.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-fromFP_DoubleTo_Word32.o: fromFP_DoubleTo_Word32.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-fromFP_DoubleTo_Word64.o: fromFP_DoubleTo_Word64.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-fromFP_DoubleTo_Float.o: fromFP_DoubleTo_Float.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-fromFP_DoubleTo_Double.o: fromFP_DoubleTo_Double.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-fromFP_DoubleTo_Integer.o: fromFP_DoubleTo_Integer.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-fromFP_DoubleTo_Real.o: fromFP_DoubleTo_Real.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-fromFP_SWord32_SFloat.o: fromFP_SWord32_SFloat.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-fromFP_SWord64_SDouble.o: fromFP_SWord64_SDouble.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-fromFP_SFloat_SWord32.o: fromFP_SFloat_SWord32.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-fromFP_SDouble_SWord64.o: fromFP_SDouble_SWord64.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-f_FP_Abs.o: f_FP_Abs.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-d_FP_Abs.o: d_FP_Abs.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-f_FP_Neg.o: f_FP_Neg.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-d_FP_Neg.o: d_FP_Neg.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-f_FP_Add.o: f_FP_Add.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-d_FP_Add.o: d_FP_Add.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-f_FP_Sub.o: f_FP_Sub.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-d_FP_Sub.o: d_FP_Sub.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-f_FP_Mul.o: f_FP_Mul.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-d_FP_Mul.o: d_FP_Mul.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-f_FP_Div.o: f_FP_Div.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-d_FP_Div.o: d_FP_Div.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-f_FP_FMA.o: f_FP_FMA.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-d_FP_FMA.o: d_FP_FMA.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-f_FP_Sqrt.o: f_FP_Sqrt.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-d_FP_Sqrt.o: d_FP_Sqrt.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-f_FP_Rem.o: f_FP_Rem.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-d_FP_Rem.o: d_FP_Rem.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-f_FP_RoundToIntegral.o: f_FP_RoundToIntegral.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-d_FP_RoundToIntegral.o: d_FP_RoundToIntegral.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-f_FP_Min.o: f_FP_Min.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-d_FP_Min.o: d_FP_Min.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-f_FP_Max.o: f_FP_Max.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-d_FP_Max.o: d_FP_Max.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-f_FP_IsEqualObject.o: f_FP_IsEqualObject.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-d_FP_IsEqualObject.o: d_FP_IsEqualObject.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-f_FP_IsNormal.o: f_FP_IsNormal.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-d_FP_IsNormal.o: d_FP_IsNormal.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-f_FP_IsZero.o: f_FP_IsZero.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-d_FP_IsZero.o: d_FP_IsZero.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-f_FP_IsSubnormal.o: f_FP_IsSubnormal.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-d_FP_IsSubnormal.o: d_FP_IsSubnormal.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-f_FP_IsInfinite.o: f_FP_IsInfinite.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-d_FP_IsInfinite.o: d_FP_IsInfinite.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-f_FP_IsNaN.o: f_FP_IsNaN.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-d_FP_IsNaN.o: d_FP_IsNaN.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-f_FP_IsNegative.o: f_FP_IsNegative.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-d_FP_IsNegative.o: d_FP_IsNegative.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-f_FP_IsPositive.o: f_FP_IsPositive.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-d_FP_IsPositive.o: d_FP_IsPositive.c floatCodeGen.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-clean:
-	rm -f *.o
-
-veryclean: clean
-	rm -f floatCodeGen.a floatCodeGen_driver
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SFloat toFP_Int8_ToFloat(const SInt8 sbv_input_0)
+{
+  const SInt8  s0 = sbv_input_0;
+        SFloat s2;
+  s2 = (SFloat) s0;
+
+  return s2;
+}
+== END: "toFP_Int8_ToFloat.c" ==================
+== BEGIN: "toFP_Int16_ToFloat.c" ================
+/* File: "toFP_Int16_ToFloat.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SFloat toFP_Int16_ToFloat(const SInt16 sbv_input_0)
+{
+  const SInt16 s0 = sbv_input_0;
+        SFloat s2;
+  s2 = (SFloat) s0;
+
+  return s2;
+}
+== END: "toFP_Int16_ToFloat.c" ==================
+== BEGIN: "toFP_Int32_ToFloat.c" ================
+/* File: "toFP_Int32_ToFloat.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+static SBV_CGEN_UNUSED inline SFloat sbv_fp_cast_s32_float(SInt32 a, bf_rnd_t rnd)
+{
+  uint64_t words[1]; uint64_t carry = 1; size_t i; limb_t j;
+  const bool negative = ((((uint64_t) a) >> (31)) & UINT64_C(1)) != 0;
+  bf_context_t ctx; bf_t x, chunk; double result;
+  for (i = 0; i < 1; ++i) {
+    words[i] = 0;
+    for (j = 0; j < 64 && i * 64 + j < 32; ++j)
+      if (((((uint64_t) a) >> ((i * 64 + j))) & UINT64_C(1)) != 0) words[i] |= UINT64_C(1) << j;
+  }
+  if (negative) for (i = 0; i < 1; ++i) {
+    const uint64_t next = ~words[i] + carry; carry = carry && next == 0; words[i] = next;
+  }
+  words[0] &= UINT64_C(0x00000000ffffffff);
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_init(&ctx, &chunk); bf_set_ui(&x, 0);
+  for (i = 1; i-- > 0;) {
+    bf_mul_2exp(&x, i == 0 ? 32 : 64, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);
+    bf_set_ui(&chunk, words[i]); bf_add(&x, &x, &chunk, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);
+  }
+  if (negative) bf_neg(&x);
+  bf_round(&x, 24, BF_FLAG_SUBNORMAL | bf_set_exp_bits(8) | (bf_flags_t) rnd); bf_get_float64(&x, &result, rnd);
+  bf_delete(&chunk); bf_delete(&x); bf_context_end(&ctx); return (SFloat) result;
+}
+
+
+SFloat toFP_Int32_ToFloat(const SInt32 sbv_input_0)
+{
+  const SInt32 s0 = sbv_input_0;
+        SFloat s2;
+  s2 = sbv_fp_cast_s32_float(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "toFP_Int32_ToFloat.c" ==================
+== BEGIN: "toFP_Int64_ToFloat.c" ================
+/* File: "toFP_Int64_ToFloat.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+static SBV_CGEN_UNUSED inline SFloat sbv_fp_cast_s64_float(SInt64 a, bf_rnd_t rnd)
+{
+  uint64_t words[1]; uint64_t carry = 1; size_t i; limb_t j;
+  const bool negative = ((((uint64_t) a) >> (63)) & UINT64_C(1)) != 0;
+  bf_context_t ctx; bf_t x, chunk; double result;
+  for (i = 0; i < 1; ++i) {
+    words[i] = 0;
+    for (j = 0; j < 64 && i * 64 + j < 64; ++j)
+      if (((((uint64_t) a) >> ((i * 64 + j))) & UINT64_C(1)) != 0) words[i] |= UINT64_C(1) << j;
+  }
+  if (negative) for (i = 0; i < 1; ++i) {
+    const uint64_t next = ~words[i] + carry; carry = carry && next == 0; words[i] = next;
+  }
+  words[0] &= UINT64_C(0xffffffffffffffff);
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_init(&ctx, &chunk); bf_set_ui(&x, 0);
+  for (i = 1; i-- > 0;) {
+    bf_mul_2exp(&x, i == 0 ? 64 : 64, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);
+    bf_set_ui(&chunk, words[i]); bf_add(&x, &x, &chunk, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);
+  }
+  if (negative) bf_neg(&x);
+  bf_round(&x, 24, BF_FLAG_SUBNORMAL | bf_set_exp_bits(8) | (bf_flags_t) rnd); bf_get_float64(&x, &result, rnd);
+  bf_delete(&chunk); bf_delete(&x); bf_context_end(&ctx); return (SFloat) result;
+}
+
+
+SFloat toFP_Int64_ToFloat(const SInt64 sbv_input_0)
+{
+  const SInt64 s0 = sbv_input_0;
+        SFloat s2;
+  s2 = sbv_fp_cast_s64_float(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "toFP_Int64_ToFloat.c" ==================
+== BEGIN: "toFP_Word8_ToFloat.c" ================
+/* File: "toFP_Word8_ToFloat.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SFloat toFP_Word8_ToFloat(const SWord8 sbv_input_0)
+{
+  const SWord8 s0 = sbv_input_0;
+        SFloat s2;
+  s2 = (SFloat) s0;
+
+  return s2;
+}
+== END: "toFP_Word8_ToFloat.c" ==================
+== BEGIN: "toFP_Word16_ToFloat.c" ================
+/* File: "toFP_Word16_ToFloat.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SFloat toFP_Word16_ToFloat(const SWord16 sbv_input_0)
+{
+  const SWord16 s0 = sbv_input_0;
+        SFloat  s2;
+  s2 = (SFloat) s0;
+
+  return s2;
+}
+== END: "toFP_Word16_ToFloat.c" ==================
+== BEGIN: "toFP_Word32_ToFloat.c" ================
+/* File: "toFP_Word32_ToFloat.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+static SBV_CGEN_UNUSED inline SFloat sbv_fp_cast_u32_float(SWord32 a, bf_rnd_t rnd)
+{
+  uint64_t words[1]; uint64_t carry = 1; size_t i; limb_t j;
+  const bool negative = false;
+  bf_context_t ctx; bf_t x, chunk; double result;
+  for (i = 0; i < 1; ++i) {
+    words[i] = 0;
+    for (j = 0; j < 64 && i * 64 + j < 32; ++j)
+      if (((((uint64_t) a) >> ((i * 64 + j))) & UINT64_C(1)) != 0) words[i] |= UINT64_C(1) << j;
+  }
+  if (negative) for (i = 0; i < 1; ++i) {
+    const uint64_t next = ~words[i] + carry; carry = carry && next == 0; words[i] = next;
+  }
+  words[0] &= UINT64_C(0x00000000ffffffff);
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_init(&ctx, &chunk); bf_set_ui(&x, 0);
+  for (i = 1; i-- > 0;) {
+    bf_mul_2exp(&x, i == 0 ? 32 : 64, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);
+    bf_set_ui(&chunk, words[i]); bf_add(&x, &x, &chunk, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);
+  }
+  if (negative) bf_neg(&x);
+  bf_round(&x, 24, BF_FLAG_SUBNORMAL | bf_set_exp_bits(8) | (bf_flags_t) rnd); bf_get_float64(&x, &result, rnd);
+  bf_delete(&chunk); bf_delete(&x); bf_context_end(&ctx); return (SFloat) result;
+}
+
+
+SFloat toFP_Word32_ToFloat(const SWord32 sbv_input_0)
+{
+  const SWord32 s0 = sbv_input_0;
+        SFloat  s2;
+  s2 = sbv_fp_cast_u32_float(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "toFP_Word32_ToFloat.c" ==================
+== BEGIN: "toFP_Word64_ToFloat.c" ================
+/* File: "toFP_Word64_ToFloat.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+static SBV_CGEN_UNUSED inline SFloat sbv_fp_cast_u64_float(SWord64 a, bf_rnd_t rnd)
+{
+  uint64_t words[1]; uint64_t carry = 1; size_t i; limb_t j;
+  const bool negative = false;
+  bf_context_t ctx; bf_t x, chunk; double result;
+  for (i = 0; i < 1; ++i) {
+    words[i] = 0;
+    for (j = 0; j < 64 && i * 64 + j < 64; ++j)
+      if (((((uint64_t) a) >> ((i * 64 + j))) & UINT64_C(1)) != 0) words[i] |= UINT64_C(1) << j;
+  }
+  if (negative) for (i = 0; i < 1; ++i) {
+    const uint64_t next = ~words[i] + carry; carry = carry && next == 0; words[i] = next;
+  }
+  words[0] &= UINT64_C(0xffffffffffffffff);
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_init(&ctx, &chunk); bf_set_ui(&x, 0);
+  for (i = 1; i-- > 0;) {
+    bf_mul_2exp(&x, i == 0 ? 64 : 64, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);
+    bf_set_ui(&chunk, words[i]); bf_add(&x, &x, &chunk, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);
+  }
+  if (negative) bf_neg(&x);
+  bf_round(&x, 24, BF_FLAG_SUBNORMAL | bf_set_exp_bits(8) | (bf_flags_t) rnd); bf_get_float64(&x, &result, rnd);
+  bf_delete(&chunk); bf_delete(&x); bf_context_end(&ctx); return (SFloat) result;
+}
+
+
+SFloat toFP_Word64_ToFloat(const SWord64 sbv_input_0)
+{
+  const SWord64 s0 = sbv_input_0;
+        SFloat  s2;
+  s2 = sbv_fp_cast_u64_float(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "toFP_Word64_ToFloat.c" ==================
+== BEGIN: "toFP_Float_ToFloat.c" ================
+/* File: "toFP_Float_ToFloat.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SFloat toFP_Float_ToFloat(const SFloat sbv_input_0)
+{
+  const SFloat s0 = sbv_input_0;
+  return s0;
+}
+== END: "toFP_Float_ToFloat.c" ==================
+== BEGIN: "toFP_Double_ToFloat.c" ================
+/* File: "toFP_Double_ToFloat.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+static SBV_CGEN_UNUSED inline SFloat sbv_fp_cast_double_float(SDouble a, bf_rnd_t rnd)
+{
+  bf_context_t ctx; bf_t x; double result;
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_set_float64(&x, (double) a);
+  bf_round(&x, 24, BF_FLAG_SUBNORMAL | bf_set_exp_bits(8) | (bf_flags_t) rnd); bf_get_float64(&x, &result, rnd);
+  bf_delete(&x); bf_context_end(&ctx); return (SFloat) result;
+}
+
+
+SFloat toFP_Double_ToFloat(const SDouble sbv_input_0)
+{
+  const SDouble s0 = sbv_input_0;
+        SFloat  s2;
+  s2 = sbv_fp_cast_double_float(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "toFP_Double_ToFloat.c" ==================
+== BEGIN: "toFP_Integer_ToFloat.c" ================
+/* File: "toFP_Integer_ToFloat.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+static SBV_CGEN_UNUSED inline SFloat sbv_fp_cast_integer_float(SInt64 a, bf_rnd_t rnd)
+{
+  uint64_t words[1]; uint64_t carry = 1; size_t i; limb_t j;
+  const bool negative = ((((uint64_t) a) >> (63)) & UINT64_C(1)) != 0;
+  bf_context_t ctx; bf_t x, chunk; double result;
+  for (i = 0; i < 1; ++i) {
+    words[i] = 0;
+    for (j = 0; j < 64 && i * 64 + j < 64; ++j)
+      if (((((uint64_t) a) >> ((i * 64 + j))) & UINT64_C(1)) != 0) words[i] |= UINT64_C(1) << j;
+  }
+  if (negative) for (i = 0; i < 1; ++i) {
+    const uint64_t next = ~words[i] + carry; carry = carry && next == 0; words[i] = next;
+  }
+  words[0] &= UINT64_C(0xffffffffffffffff);
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_init(&ctx, &chunk); bf_set_ui(&x, 0);
+  for (i = 1; i-- > 0;) {
+    bf_mul_2exp(&x, i == 0 ? 64 : 64, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);
+    bf_set_ui(&chunk, words[i]); bf_add(&x, &x, &chunk, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);
+  }
+  if (negative) bf_neg(&x);
+  bf_round(&x, 24, BF_FLAG_SUBNORMAL | bf_set_exp_bits(8) | (bf_flags_t) rnd); bf_get_float64(&x, &result, rnd);
+  bf_delete(&chunk); bf_delete(&x); bf_context_end(&ctx); return (SFloat) result;
+}
+
+
+SFloat toFP_Integer_ToFloat(const SInteger sbv_input_0)
+{
+  const SInteger s0 = sbv_input_0;
+        SFloat   s2;
+  s2 = sbv_fp_cast_integer_float(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "toFP_Integer_ToFloat.c" ==================
+== BEGIN: "toFP_Real_ToFloat.c" ================
+/* File: "toFP_Real_ToFloat.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+#include <float.h>
+#if FLT_RADIX == 2 && LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 && LDBL_MIN_EXP == -1021
+#define SBV_LDBL_EXP_BITS 11
+#elif FLT_RADIX == 2 && (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 && LDBL_MIN_EXP == -16381
+#define SBV_LDBL_EXP_BITS 15
+#else
+#error SBV C long-double conversions require binary64, x87 extended, or binary128 long double
+#endif
+#if BF_EXP_BITS_MAX < SBV_LDBL_EXP_BITS
+#error SBV C long-double conversions exceed the LibBF exponent range
+#endif
+
+static SBV_CGEN_UNUSED bf_flags_t sbv_bf_long_double_flags(bf_rnd_t rnd)
+{
+  return BF_FLAG_SUBNORMAL | bf_set_exp_bits(SBV_LDBL_EXP_BITS) | (bf_flags_t) rnd;
+}
+
+static SBV_CGEN_UNUSED void sbv_bf_set_long_double(bf_t *result, long double value)
+{
+  int exponent, shift = 0, status = 0; bf_t chunk;
+  if (isnan(value)) { bf_set_nan(result); return; }
+  if (isinf(value)) { bf_set_inf(result, signbit(value) != 0); return; }
+  if (value == 0) { bf_set_zero(result, signbit(value) != 0); return; }
+  long double fraction = frexpl(fabsl(value), &exponent);
+  bf_init(result->ctx, &chunk); bf_set_zero(result, 0);
+  while (fraction != 0) {
+    fraction = ldexpl(fraction, 32);
+    const uint32_t bits = (uint32_t) fraction; fraction -= (long double) bits;
+    status |= bf_mul_2exp(result, 32, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);
+    status |= bf_set_ui(&chunk, bits);
+    status |= bf_add(result, result, &chunk, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ); shift += 32;
+  }
+  status |= bf_mul_2exp(result, exponent - shift, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);
+  bf_delete(&chunk); if (status & BF_ST_MEM_ERROR) abort();
+  if (signbit(value)) bf_neg(result);
+}
+
+static SBV_CGEN_UNUSED long double sbv_bf_get_long_double(bf_t *value, bf_rnd_t rnd)
+{
+  if (bf_round(value, LDBL_MANT_DIG, sbv_bf_long_double_flags(rnd)) & BF_ST_MEM_ERROR) abort();
+  if (bf_is_nan(value)) return nanl("");
+  if (!bf_is_finite(value)) return value->sign ? -HUGE_VALL : HUGE_VALL;
+  if (bf_is_zero(value)) return value->sign ? -0.0L : 0.0L;
+  long double significand = 0;
+  const slimb_t base = (slimb_t) value->len * LIMB_BITS;
+  for (int i = 0; i < LDBL_MANT_DIG; ++i) {
+    const slimb_t bit = base - 1 - i;
+    const unsigned digit = bit < 0 ? 0 : (unsigned) ((value->tab[bit / LIMB_BITS] >> (bit % LIMB_BITS)) & 1);
+    significand = significand * 2 + digit;
+  }
+  const long double result = ldexpl(significand, (int) value->expn - LDBL_MANT_DIG);
+  return value->sign ? -result : result;
+}
+
+static SBV_CGEN_UNUSED inline SFloat sbv_fp_cast_real_float(SReal a, bf_rnd_t rnd)
+{
+  bf_context_t ctx; bf_t x; double result;
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); sbv_bf_set_long_double(&x, a);
+  bf_round(&x, 24, BF_FLAG_SUBNORMAL | bf_set_exp_bits(8) | (bf_flags_t) rnd); bf_get_float64(&x, &result, rnd);
+  bf_delete(&x); bf_context_end(&ctx); return (SFloat) result;
+}
+
+
+SFloat toFP_Real_ToFloat(const SReal sbv_input_0)
+{
+  const SReal  s0 = sbv_input_0;
+        SFloat s2;
+  s2 = sbv_fp_cast_real_float(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "toFP_Real_ToFloat.c" ==================
+== BEGIN: "toFP_Int8_ToDouble.c" ================
+/* File: "toFP_Int8_ToDouble.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SDouble toFP_Int8_ToDouble(const SInt8 sbv_input_0)
+{
+  const SInt8   s0 = sbv_input_0;
+        SDouble s2;
+  s2 = (SDouble) s0;
+
+  return s2;
+}
+== END: "toFP_Int8_ToDouble.c" ==================
+== BEGIN: "toFP_Int16_ToDouble.c" ================
+/* File: "toFP_Int16_ToDouble.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SDouble toFP_Int16_ToDouble(const SInt16 sbv_input_0)
+{
+  const SInt16  s0 = sbv_input_0;
+        SDouble s2;
+  s2 = (SDouble) s0;
+
+  return s2;
+}
+== END: "toFP_Int16_ToDouble.c" ==================
+== BEGIN: "toFP_Int32_ToDouble.c" ================
+/* File: "toFP_Int32_ToDouble.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SDouble toFP_Int32_ToDouble(const SInt32 sbv_input_0)
+{
+  const SInt32  s0 = sbv_input_0;
+        SDouble s2;
+  s2 = (SDouble) s0;
+
+  return s2;
+}
+== END: "toFP_Int32_ToDouble.c" ==================
+== BEGIN: "toFP_Int64_ToDouble.c" ================
+/* File: "toFP_Int64_ToDouble.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+static SBV_CGEN_UNUSED inline SDouble sbv_fp_cast_s64_double(SInt64 a, bf_rnd_t rnd)
+{
+  uint64_t words[1]; uint64_t carry = 1; size_t i; limb_t j;
+  const bool negative = ((((uint64_t) a) >> (63)) & UINT64_C(1)) != 0;
+  bf_context_t ctx; bf_t x, chunk; double result;
+  for (i = 0; i < 1; ++i) {
+    words[i] = 0;
+    for (j = 0; j < 64 && i * 64 + j < 64; ++j)
+      if (((((uint64_t) a) >> ((i * 64 + j))) & UINT64_C(1)) != 0) words[i] |= UINT64_C(1) << j;
+  }
+  if (negative) for (i = 0; i < 1; ++i) {
+    const uint64_t next = ~words[i] + carry; carry = carry && next == 0; words[i] = next;
+  }
+  words[0] &= UINT64_C(0xffffffffffffffff);
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_init(&ctx, &chunk); bf_set_ui(&x, 0);
+  for (i = 1; i-- > 0;) {
+    bf_mul_2exp(&x, i == 0 ? 64 : 64, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);
+    bf_set_ui(&chunk, words[i]); bf_add(&x, &x, &chunk, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);
+  }
+  if (negative) bf_neg(&x);
+  bf_round(&x, 53, BF_FLAG_SUBNORMAL | bf_set_exp_bits(11) | (bf_flags_t) rnd); bf_get_float64(&x, &result, rnd);
+  bf_delete(&chunk); bf_delete(&x); bf_context_end(&ctx); return (SDouble) result;
+}
+
+
+SDouble toFP_Int64_ToDouble(const SInt64 sbv_input_0)
+{
+  const SInt64  s0 = sbv_input_0;
+        SDouble s2;
+  s2 = sbv_fp_cast_s64_double(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "toFP_Int64_ToDouble.c" ==================
+== BEGIN: "toFP_Word8_ToDouble.c" ================
+/* File: "toFP_Word8_ToDouble.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SDouble toFP_Word8_ToDouble(const SWord8 sbv_input_0)
+{
+  const SWord8  s0 = sbv_input_0;
+        SDouble s2;
+  s2 = (SDouble) s0;
+
+  return s2;
+}
+== END: "toFP_Word8_ToDouble.c" ==================
+== BEGIN: "toFP_Word16_ToDouble.c" ================
+/* File: "toFP_Word16_ToDouble.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SDouble toFP_Word16_ToDouble(const SWord16 sbv_input_0)
+{
+  const SWord16 s0 = sbv_input_0;
+        SDouble s2;
+  s2 = (SDouble) s0;
+
+  return s2;
+}
+== END: "toFP_Word16_ToDouble.c" ==================
+== BEGIN: "toFP_Word32_ToDouble.c" ================
+/* File: "toFP_Word32_ToDouble.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SDouble toFP_Word32_ToDouble(const SWord32 sbv_input_0)
+{
+  const SWord32 s0 = sbv_input_0;
+        SDouble s2;
+  s2 = (SDouble) s0;
+
+  return s2;
+}
+== END: "toFP_Word32_ToDouble.c" ==================
+== BEGIN: "toFP_Word64_ToDouble.c" ================
+/* File: "toFP_Word64_ToDouble.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+static SBV_CGEN_UNUSED inline SDouble sbv_fp_cast_u64_double(SWord64 a, bf_rnd_t rnd)
+{
+  uint64_t words[1]; uint64_t carry = 1; size_t i; limb_t j;
+  const bool negative = false;
+  bf_context_t ctx; bf_t x, chunk; double result;
+  for (i = 0; i < 1; ++i) {
+    words[i] = 0;
+    for (j = 0; j < 64 && i * 64 + j < 64; ++j)
+      if (((((uint64_t) a) >> ((i * 64 + j))) & UINT64_C(1)) != 0) words[i] |= UINT64_C(1) << j;
+  }
+  if (negative) for (i = 0; i < 1; ++i) {
+    const uint64_t next = ~words[i] + carry; carry = carry && next == 0; words[i] = next;
+  }
+  words[0] &= UINT64_C(0xffffffffffffffff);
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_init(&ctx, &chunk); bf_set_ui(&x, 0);
+  for (i = 1; i-- > 0;) {
+    bf_mul_2exp(&x, i == 0 ? 64 : 64, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);
+    bf_set_ui(&chunk, words[i]); bf_add(&x, &x, &chunk, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);
+  }
+  if (negative) bf_neg(&x);
+  bf_round(&x, 53, BF_FLAG_SUBNORMAL | bf_set_exp_bits(11) | (bf_flags_t) rnd); bf_get_float64(&x, &result, rnd);
+  bf_delete(&chunk); bf_delete(&x); bf_context_end(&ctx); return (SDouble) result;
+}
+
+
+SDouble toFP_Word64_ToDouble(const SWord64 sbv_input_0)
+{
+  const SWord64 s0 = sbv_input_0;
+        SDouble s2;
+  s2 = sbv_fp_cast_u64_double(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "toFP_Word64_ToDouble.c" ==================
+== BEGIN: "toFP_Float_ToDouble.c" ================
+/* File: "toFP_Float_ToDouble.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SDouble toFP_Float_ToDouble(const SFloat sbv_input_0)
+{
+  const SFloat  s0 = sbv_input_0;
+        SDouble s2;
+  s2 = (SDouble) s0;
+
+  return s2;
+}
+== END: "toFP_Float_ToDouble.c" ==================
+== BEGIN: "toFP_Double_ToDouble.c" ================
+/* File: "toFP_Double_ToDouble.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SDouble toFP_Double_ToDouble(const SDouble sbv_input_0)
+{
+  const SDouble s0 = sbv_input_0;
+  return s0;
+}
+== END: "toFP_Double_ToDouble.c" ==================
+== BEGIN: "toFP_Integer_ToDouble.c" ================
+/* File: "toFP_Integer_ToDouble.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+static SBV_CGEN_UNUSED inline SDouble sbv_fp_cast_integer_double(SInt64 a, bf_rnd_t rnd)
+{
+  uint64_t words[1]; uint64_t carry = 1; size_t i; limb_t j;
+  const bool negative = ((((uint64_t) a) >> (63)) & UINT64_C(1)) != 0;
+  bf_context_t ctx; bf_t x, chunk; double result;
+  for (i = 0; i < 1; ++i) {
+    words[i] = 0;
+    for (j = 0; j < 64 && i * 64 + j < 64; ++j)
+      if (((((uint64_t) a) >> ((i * 64 + j))) & UINT64_C(1)) != 0) words[i] |= UINT64_C(1) << j;
+  }
+  if (negative) for (i = 0; i < 1; ++i) {
+    const uint64_t next = ~words[i] + carry; carry = carry && next == 0; words[i] = next;
+  }
+  words[0] &= UINT64_C(0xffffffffffffffff);
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_init(&ctx, &chunk); bf_set_ui(&x, 0);
+  for (i = 1; i-- > 0;) {
+    bf_mul_2exp(&x, i == 0 ? 64 : 64, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);
+    bf_set_ui(&chunk, words[i]); bf_add(&x, &x, &chunk, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);
+  }
+  if (negative) bf_neg(&x);
+  bf_round(&x, 53, BF_FLAG_SUBNORMAL | bf_set_exp_bits(11) | (bf_flags_t) rnd); bf_get_float64(&x, &result, rnd);
+  bf_delete(&chunk); bf_delete(&x); bf_context_end(&ctx); return (SDouble) result;
+}
+
+
+SDouble toFP_Integer_ToDouble(const SInteger sbv_input_0)
+{
+  const SInteger s0 = sbv_input_0;
+        SDouble  s2;
+  s2 = sbv_fp_cast_integer_double(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "toFP_Integer_ToDouble.c" ==================
+== BEGIN: "toFP_Real_ToDouble.c" ================
+/* File: "toFP_Real_ToDouble.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+#include <float.h>
+#if FLT_RADIX == 2 && LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 && LDBL_MIN_EXP == -1021
+#define SBV_LDBL_EXP_BITS 11
+#elif FLT_RADIX == 2 && (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 && LDBL_MIN_EXP == -16381
+#define SBV_LDBL_EXP_BITS 15
+#else
+#error SBV C long-double conversions require binary64, x87 extended, or binary128 long double
+#endif
+#if BF_EXP_BITS_MAX < SBV_LDBL_EXP_BITS
+#error SBV C long-double conversions exceed the LibBF exponent range
+#endif
+
+static SBV_CGEN_UNUSED bf_flags_t sbv_bf_long_double_flags(bf_rnd_t rnd)
+{
+  return BF_FLAG_SUBNORMAL | bf_set_exp_bits(SBV_LDBL_EXP_BITS) | (bf_flags_t) rnd;
+}
+
+static SBV_CGEN_UNUSED void sbv_bf_set_long_double(bf_t *result, long double value)
+{
+  int exponent, shift = 0, status = 0; bf_t chunk;
+  if (isnan(value)) { bf_set_nan(result); return; }
+  if (isinf(value)) { bf_set_inf(result, signbit(value) != 0); return; }
+  if (value == 0) { bf_set_zero(result, signbit(value) != 0); return; }
+  long double fraction = frexpl(fabsl(value), &exponent);
+  bf_init(result->ctx, &chunk); bf_set_zero(result, 0);
+  while (fraction != 0) {
+    fraction = ldexpl(fraction, 32);
+    const uint32_t bits = (uint32_t) fraction; fraction -= (long double) bits;
+    status |= bf_mul_2exp(result, 32, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);
+    status |= bf_set_ui(&chunk, bits);
+    status |= bf_add(result, result, &chunk, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ); shift += 32;
+  }
+  status |= bf_mul_2exp(result, exponent - shift, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);
+  bf_delete(&chunk); if (status & BF_ST_MEM_ERROR) abort();
+  if (signbit(value)) bf_neg(result);
+}
+
+static SBV_CGEN_UNUSED long double sbv_bf_get_long_double(bf_t *value, bf_rnd_t rnd)
+{
+  if (bf_round(value, LDBL_MANT_DIG, sbv_bf_long_double_flags(rnd)) & BF_ST_MEM_ERROR) abort();
+  if (bf_is_nan(value)) return nanl("");
+  if (!bf_is_finite(value)) return value->sign ? -HUGE_VALL : HUGE_VALL;
+  if (bf_is_zero(value)) return value->sign ? -0.0L : 0.0L;
+  long double significand = 0;
+  const slimb_t base = (slimb_t) value->len * LIMB_BITS;
+  for (int i = 0; i < LDBL_MANT_DIG; ++i) {
+    const slimb_t bit = base - 1 - i;
+    const unsigned digit = bit < 0 ? 0 : (unsigned) ((value->tab[bit / LIMB_BITS] >> (bit % LIMB_BITS)) & 1);
+    significand = significand * 2 + digit;
+  }
+  const long double result = ldexpl(significand, (int) value->expn - LDBL_MANT_DIG);
+  return value->sign ? -result : result;
+}
+
+static SBV_CGEN_UNUSED inline SDouble sbv_fp_cast_real_double(SReal a, bf_rnd_t rnd)
+{
+  bf_context_t ctx; bf_t x; double result;
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); sbv_bf_set_long_double(&x, a);
+  bf_round(&x, 53, BF_FLAG_SUBNORMAL | bf_set_exp_bits(11) | (bf_flags_t) rnd); bf_get_float64(&x, &result, rnd);
+  bf_delete(&x); bf_context_end(&ctx); return (SDouble) result;
+}
+
+
+SDouble toFP_Real_ToDouble(const SReal sbv_input_0)
+{
+  const SReal   s0 = sbv_input_0;
+        SDouble s2;
+  s2 = sbv_fp_cast_real_double(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "toFP_Real_ToDouble.c" ==================
+== BEGIN: "fromFP_Float_ToInt8.c" ================
+/* File: "fromFP_Float_ToInt8.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+static SBV_CGEN_UNUSED inline SInt8 sbv_fp_cast_float_s8(SFloat a, bf_rnd_t rnd)
+{
+  bf_context_t ctx; bf_t x; SWord8 raw = (SWord8) 0; limb_t i;
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_set_float64(&x, (double) a); bf_rint(&x, rnd);
+  if (bf_is_finite(&x) && !bf_is_zero(&x)) {
+    const slimb_t base = (slimb_t) x.len * LIMB_BITS;
+    for (i = 0; i < 8; ++i) {
+      const slimb_t bit = (slimb_t) i - x.expn + base;
+      if (bit >= 0 && bit < base) { raw = (SWord8) ((uint64_t) raw | ((uint64_t) (((x.tab[bit / LIMB_BITS] >> (bit % LIMB_BITS)) & 1) != 0) << (i))); }
+    }
+    if (x.sign) raw = (SWord8) (~(uint64_t) raw + UINT64_C(1));
+  }
+  bf_delete(&x); bf_context_end(&ctx);
+  SInt8 result; memcpy(&result, &raw, sizeof result); return result;
+}
+
+
+SInt8 fromFP_Float_ToInt8(const SFloat sbv_input_0)
+{
+  const SFloat s0 = sbv_input_0;
+        SInt8  s2;
+  s2 = sbv_fp_cast_float_s8(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "fromFP_Float_ToInt8.c" ==================
+== BEGIN: "fromFP_Float_ToInt16.c" ================
+/* File: "fromFP_Float_ToInt16.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+static SBV_CGEN_UNUSED inline SInt16 sbv_fp_cast_float_s16(SFloat a, bf_rnd_t rnd)
+{
+  bf_context_t ctx; bf_t x; SWord16 raw = (SWord16) 0; limb_t i;
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_set_float64(&x, (double) a); bf_rint(&x, rnd);
+  if (bf_is_finite(&x) && !bf_is_zero(&x)) {
+    const slimb_t base = (slimb_t) x.len * LIMB_BITS;
+    for (i = 0; i < 16; ++i) {
+      const slimb_t bit = (slimb_t) i - x.expn + base;
+      if (bit >= 0 && bit < base) { raw = (SWord16) ((uint64_t) raw | ((uint64_t) (((x.tab[bit / LIMB_BITS] >> (bit % LIMB_BITS)) & 1) != 0) << (i))); }
+    }
+    if (x.sign) raw = (SWord16) (~(uint64_t) raw + UINT64_C(1));
+  }
+  bf_delete(&x); bf_context_end(&ctx);
+  SInt16 result; memcpy(&result, &raw, sizeof result); return result;
+}
+
+
+SInt16 fromFP_Float_ToInt16(const SFloat sbv_input_0)
+{
+  const SFloat s0 = sbv_input_0;
+        SInt16 s2;
+  s2 = sbv_fp_cast_float_s16(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "fromFP_Float_ToInt16.c" ==================
+== BEGIN: "fromFP_Float_ToInt32.c" ================
+/* File: "fromFP_Float_ToInt32.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+static SBV_CGEN_UNUSED inline SInt32 sbv_fp_cast_float_s32(SFloat a, bf_rnd_t rnd)
+{
+  bf_context_t ctx; bf_t x; SWord32 raw = (SWord32) 0; limb_t i;
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_set_float64(&x, (double) a); bf_rint(&x, rnd);
+  if (bf_is_finite(&x) && !bf_is_zero(&x)) {
+    const slimb_t base = (slimb_t) x.len * LIMB_BITS;
+    for (i = 0; i < 32; ++i) {
+      const slimb_t bit = (slimb_t) i - x.expn + base;
+      if (bit >= 0 && bit < base) { raw = (SWord32) ((uint64_t) raw | ((uint64_t) (((x.tab[bit / LIMB_BITS] >> (bit % LIMB_BITS)) & 1) != 0) << (i))); }
+    }
+    if (x.sign) raw = (SWord32) (~(uint64_t) raw + UINT64_C(1));
+  }
+  bf_delete(&x); bf_context_end(&ctx);
+  SInt32 result; memcpy(&result, &raw, sizeof result); return result;
+}
+
+
+SInt32 fromFP_Float_ToInt32(const SFloat sbv_input_0)
+{
+  const SFloat s0 = sbv_input_0;
+        SInt32 s2;
+  s2 = sbv_fp_cast_float_s32(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "fromFP_Float_ToInt32.c" ==================
+== BEGIN: "fromFP_Float_ToInt64.c" ================
+/* File: "fromFP_Float_ToInt64.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+static SBV_CGEN_UNUSED inline SInt64 sbv_fp_cast_float_s64(SFloat a, bf_rnd_t rnd)
+{
+  bf_context_t ctx; bf_t x; SWord64 raw = (SWord64) 0; limb_t i;
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_set_float64(&x, (double) a); bf_rint(&x, rnd);
+  if (bf_is_finite(&x) && !bf_is_zero(&x)) {
+    const slimb_t base = (slimb_t) x.len * LIMB_BITS;
+    for (i = 0; i < 64; ++i) {
+      const slimb_t bit = (slimb_t) i - x.expn + base;
+      if (bit >= 0 && bit < base) { raw = (SWord64) ((uint64_t) raw | ((uint64_t) (((x.tab[bit / LIMB_BITS] >> (bit % LIMB_BITS)) & 1) != 0) << (i))); }
+    }
+    if (x.sign) raw = (SWord64) (~(uint64_t) raw + UINT64_C(1));
+  }
+  bf_delete(&x); bf_context_end(&ctx);
+  SInt64 result; memcpy(&result, &raw, sizeof result); return result;
+}
+
+
+SInt64 fromFP_Float_ToInt64(const SFloat sbv_input_0)
+{
+  const SFloat s0 = sbv_input_0;
+        SInt64 s2;
+  s2 = sbv_fp_cast_float_s64(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "fromFP_Float_ToInt64.c" ==================
+== BEGIN: "fromFP_Float_ToWord8.c" ================
+/* File: "fromFP_Float_ToWord8.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+static SBV_CGEN_UNUSED inline SWord8 sbv_fp_cast_float_u8(SFloat a, bf_rnd_t rnd)
+{
+  bf_context_t ctx; bf_t x; SWord8 raw = (SWord8) 0; limb_t i;
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_set_float64(&x, (double) a); bf_rint(&x, rnd);
+  if (bf_is_finite(&x) && !bf_is_zero(&x)) {
+    const slimb_t base = (slimb_t) x.len * LIMB_BITS;
+    for (i = 0; i < 8; ++i) {
+      const slimb_t bit = (slimb_t) i - x.expn + base;
+      if (bit >= 0 && bit < base) { raw = (SWord8) ((uint64_t) raw | ((uint64_t) (((x.tab[bit / LIMB_BITS] >> (bit % LIMB_BITS)) & 1) != 0) << (i))); }
+    }
+    if (x.sign) raw = (SWord8) (~(uint64_t) raw + UINT64_C(1));
+  }
+  bf_delete(&x); bf_context_end(&ctx);
+  return raw;
+}
+
+
+SWord8 fromFP_Float_ToWord8(const SFloat sbv_input_0)
+{
+  const SFloat s0 = sbv_input_0;
+        SWord8 s2;
+  s2 = sbv_fp_cast_float_u8(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "fromFP_Float_ToWord8.c" ==================
+== BEGIN: "fromFP_Float_ToWord16.c" ================
+/* File: "fromFP_Float_ToWord16.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+static SBV_CGEN_UNUSED inline SWord16 sbv_fp_cast_float_u16(SFloat a, bf_rnd_t rnd)
+{
+  bf_context_t ctx; bf_t x; SWord16 raw = (SWord16) 0; limb_t i;
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_set_float64(&x, (double) a); bf_rint(&x, rnd);
+  if (bf_is_finite(&x) && !bf_is_zero(&x)) {
+    const slimb_t base = (slimb_t) x.len * LIMB_BITS;
+    for (i = 0; i < 16; ++i) {
+      const slimb_t bit = (slimb_t) i - x.expn + base;
+      if (bit >= 0 && bit < base) { raw = (SWord16) ((uint64_t) raw | ((uint64_t) (((x.tab[bit / LIMB_BITS] >> (bit % LIMB_BITS)) & 1) != 0) << (i))); }
+    }
+    if (x.sign) raw = (SWord16) (~(uint64_t) raw + UINT64_C(1));
+  }
+  bf_delete(&x); bf_context_end(&ctx);
+  return raw;
+}
+
+
+SWord16 fromFP_Float_ToWord16(const SFloat sbv_input_0)
+{
+  const SFloat  s0 = sbv_input_0;
+        SWord16 s2;
+  s2 = sbv_fp_cast_float_u16(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "fromFP_Float_ToWord16.c" ==================
+== BEGIN: "fromFP_Float_ToWord32.c" ================
+/* File: "fromFP_Float_ToWord32.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+static SBV_CGEN_UNUSED inline SWord32 sbv_fp_cast_float_u32(SFloat a, bf_rnd_t rnd)
+{
+  bf_context_t ctx; bf_t x; SWord32 raw = (SWord32) 0; limb_t i;
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_set_float64(&x, (double) a); bf_rint(&x, rnd);
+  if (bf_is_finite(&x) && !bf_is_zero(&x)) {
+    const slimb_t base = (slimb_t) x.len * LIMB_BITS;
+    for (i = 0; i < 32; ++i) {
+      const slimb_t bit = (slimb_t) i - x.expn + base;
+      if (bit >= 0 && bit < base) { raw = (SWord32) ((uint64_t) raw | ((uint64_t) (((x.tab[bit / LIMB_BITS] >> (bit % LIMB_BITS)) & 1) != 0) << (i))); }
+    }
+    if (x.sign) raw = (SWord32) (~(uint64_t) raw + UINT64_C(1));
+  }
+  bf_delete(&x); bf_context_end(&ctx);
+  return raw;
+}
+
+
+SWord32 fromFP_Float_ToWord32(const SFloat sbv_input_0)
+{
+  const SFloat  s0 = sbv_input_0;
+        SWord32 s2;
+  s2 = sbv_fp_cast_float_u32(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "fromFP_Float_ToWord32.c" ==================
+== BEGIN: "fromFP_Float_ToWord64.c" ================
+/* File: "fromFP_Float_ToWord64.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+static SBV_CGEN_UNUSED inline SWord64 sbv_fp_cast_float_u64(SFloat a, bf_rnd_t rnd)
+{
+  bf_context_t ctx; bf_t x; SWord64 raw = (SWord64) 0; limb_t i;
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_set_float64(&x, (double) a); bf_rint(&x, rnd);
+  if (bf_is_finite(&x) && !bf_is_zero(&x)) {
+    const slimb_t base = (slimb_t) x.len * LIMB_BITS;
+    for (i = 0; i < 64; ++i) {
+      const slimb_t bit = (slimb_t) i - x.expn + base;
+      if (bit >= 0 && bit < base) { raw = (SWord64) ((uint64_t) raw | ((uint64_t) (((x.tab[bit / LIMB_BITS] >> (bit % LIMB_BITS)) & 1) != 0) << (i))); }
+    }
+    if (x.sign) raw = (SWord64) (~(uint64_t) raw + UINT64_C(1));
+  }
+  bf_delete(&x); bf_context_end(&ctx);
+  return raw;
+}
+
+
+SWord64 fromFP_Float_ToWord64(const SFloat sbv_input_0)
+{
+  const SFloat  s0 = sbv_input_0;
+        SWord64 s2;
+  s2 = sbv_fp_cast_float_u64(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "fromFP_Float_ToWord64.c" ==================
+== BEGIN: "fromFP_Float_ToFloat.c" ================
+/* File: "fromFP_Float_ToFloat.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SFloat fromFP_Float_ToFloat(const SFloat sbv_input_0)
+{
+  const SFloat s0 = sbv_input_0;
+  return s0;
+}
+== END: "fromFP_Float_ToFloat.c" ==================
+== BEGIN: "fromFP_Float_ToDouble.c" ================
+/* File: "fromFP_Float_ToDouble.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SDouble fromFP_Float_ToDouble(const SFloat sbv_input_0)
+{
+  const SFloat  s0 = sbv_input_0;
+        SDouble s2;
+  s2 = (SDouble) s0;
+
+  return s2;
+}
+== END: "fromFP_Float_ToDouble.c" ==================
+== BEGIN: "fromFP_Float_ToInteger.c" ================
+/* File: "fromFP_Float_ToInteger.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+static SBV_CGEN_UNUSED inline SInt64 sbv_fp_cast_float_integer(SFloat a, bf_rnd_t rnd)
+{
+  bf_context_t ctx; bf_t x; SWord64 raw = (SWord64) 0; limb_t i;
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_set_float64(&x, (double) a); bf_rint(&x, rnd);
+  if (bf_is_finite(&x) && !bf_is_zero(&x)) {
+    const slimb_t base = (slimb_t) x.len * LIMB_BITS;
+    for (i = 0; i < 64; ++i) {
+      const slimb_t bit = (slimb_t) i - x.expn + base;
+      if (bit >= 0 && bit < base) { raw = (SWord64) ((uint64_t) raw | ((uint64_t) (((x.tab[bit / LIMB_BITS] >> (bit % LIMB_BITS)) & 1) != 0) << (i))); }
+    }
+    if (x.sign) raw = (SWord64) (~(uint64_t) raw + UINT64_C(1));
+  }
+  bf_delete(&x); bf_context_end(&ctx);
+  SInt64 result; memcpy(&result, &raw, sizeof result); return result;
+}
+
+
+SInteger fromFP_Float_ToInteger(const SFloat sbv_input_0)
+{
+  const SFloat   s0 = sbv_input_0;
+        SInteger s2;
+  s2 = sbv_fp_cast_float_integer(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "fromFP_Float_ToInteger.c" ==================
+== BEGIN: "fromFP_Float_ToReal.c" ================
+/* File: "fromFP_Float_ToReal.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+#include <float.h>
+#if FLT_RADIX == 2 && LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 && LDBL_MIN_EXP == -1021
+#define SBV_LDBL_EXP_BITS 11
+#elif FLT_RADIX == 2 && (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 && LDBL_MIN_EXP == -16381
+#define SBV_LDBL_EXP_BITS 15
+#else
+#error SBV C long-double conversions require binary64, x87 extended, or binary128 long double
+#endif
+#if BF_EXP_BITS_MAX < SBV_LDBL_EXP_BITS
+#error SBV C long-double conversions exceed the LibBF exponent range
+#endif
+
+static SBV_CGEN_UNUSED bf_flags_t sbv_bf_long_double_flags(bf_rnd_t rnd)
+{
+  return BF_FLAG_SUBNORMAL | bf_set_exp_bits(SBV_LDBL_EXP_BITS) | (bf_flags_t) rnd;
+}
+
+static SBV_CGEN_UNUSED void sbv_bf_set_long_double(bf_t *result, long double value)
+{
+  int exponent, shift = 0, status = 0; bf_t chunk;
+  if (isnan(value)) { bf_set_nan(result); return; }
+  if (isinf(value)) { bf_set_inf(result, signbit(value) != 0); return; }
+  if (value == 0) { bf_set_zero(result, signbit(value) != 0); return; }
+  long double fraction = frexpl(fabsl(value), &exponent);
+  bf_init(result->ctx, &chunk); bf_set_zero(result, 0);
+  while (fraction != 0) {
+    fraction = ldexpl(fraction, 32);
+    const uint32_t bits = (uint32_t) fraction; fraction -= (long double) bits;
+    status |= bf_mul_2exp(result, 32, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);
+    status |= bf_set_ui(&chunk, bits);
+    status |= bf_add(result, result, &chunk, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ); shift += 32;
+  }
+  status |= bf_mul_2exp(result, exponent - shift, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);
+  bf_delete(&chunk); if (status & BF_ST_MEM_ERROR) abort();
+  if (signbit(value)) bf_neg(result);
+}
+
+static SBV_CGEN_UNUSED long double sbv_bf_get_long_double(bf_t *value, bf_rnd_t rnd)
+{
+  if (bf_round(value, LDBL_MANT_DIG, sbv_bf_long_double_flags(rnd)) & BF_ST_MEM_ERROR) abort();
+  if (bf_is_nan(value)) return nanl("");
+  if (!bf_is_finite(value)) return value->sign ? -HUGE_VALL : HUGE_VALL;
+  if (bf_is_zero(value)) return value->sign ? -0.0L : 0.0L;
+  long double significand = 0;
+  const slimb_t base = (slimb_t) value->len * LIMB_BITS;
+  for (int i = 0; i < LDBL_MANT_DIG; ++i) {
+    const slimb_t bit = base - 1 - i;
+    const unsigned digit = bit < 0 ? 0 : (unsigned) ((value->tab[bit / LIMB_BITS] >> (bit % LIMB_BITS)) & 1);
+    significand = significand * 2 + digit;
+  }
+  const long double result = ldexpl(significand, (int) value->expn - LDBL_MANT_DIG);
+  return value->sign ? -result : result;
+}
+
+static SBV_CGEN_UNUSED inline SReal sbv_fp_cast_float_real(SFloat a, bf_rnd_t rnd)
+{
+  bf_context_t ctx; bf_t x; long double result;
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_set_float64(&x, (double) a);
+  bf_round(&x, LDBL_MANT_DIG, sbv_bf_long_double_flags(rnd)); result = sbv_bf_get_long_double(&x, rnd);
+  bf_delete(&x); bf_context_end(&ctx); return (SReal) result;
+}
+
+
+SReal fromFP_Float_ToReal(const SFloat sbv_input_0)
+{
+  const SFloat s0 = sbv_input_0;
+        SReal  s2;
+  s2 = sbv_fp_cast_float_real(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "fromFP_Float_ToReal.c" ==================
+== BEGIN: "fromFP_DoubleTo_Int8.c" ================
+/* File: "fromFP_DoubleTo_Int8.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+static SBV_CGEN_UNUSED inline SInt8 sbv_fp_cast_double_s8(SDouble a, bf_rnd_t rnd)
+{
+  bf_context_t ctx; bf_t x; SWord8 raw = (SWord8) 0; limb_t i;
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_set_float64(&x, (double) a); bf_rint(&x, rnd);
+  if (bf_is_finite(&x) && !bf_is_zero(&x)) {
+    const slimb_t base = (slimb_t) x.len * LIMB_BITS;
+    for (i = 0; i < 8; ++i) {
+      const slimb_t bit = (slimb_t) i - x.expn + base;
+      if (bit >= 0 && bit < base) { raw = (SWord8) ((uint64_t) raw | ((uint64_t) (((x.tab[bit / LIMB_BITS] >> (bit % LIMB_BITS)) & 1) != 0) << (i))); }
+    }
+    if (x.sign) raw = (SWord8) (~(uint64_t) raw + UINT64_C(1));
+  }
+  bf_delete(&x); bf_context_end(&ctx);
+  SInt8 result; memcpy(&result, &raw, sizeof result); return result;
+}
+
+
+SInt8 fromFP_DoubleTo_Int8(const SDouble sbv_input_0)
+{
+  const SDouble s0 = sbv_input_0;
+        SInt8   s2;
+  s2 = sbv_fp_cast_double_s8(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "fromFP_DoubleTo_Int8.c" ==================
+== BEGIN: "fromFP_DoubleTo_Int16.c" ================
+/* File: "fromFP_DoubleTo_Int16.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+static SBV_CGEN_UNUSED inline SInt16 sbv_fp_cast_double_s16(SDouble a, bf_rnd_t rnd)
+{
+  bf_context_t ctx; bf_t x; SWord16 raw = (SWord16) 0; limb_t i;
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_set_float64(&x, (double) a); bf_rint(&x, rnd);
+  if (bf_is_finite(&x) && !bf_is_zero(&x)) {
+    const slimb_t base = (slimb_t) x.len * LIMB_BITS;
+    for (i = 0; i < 16; ++i) {
+      const slimb_t bit = (slimb_t) i - x.expn + base;
+      if (bit >= 0 && bit < base) { raw = (SWord16) ((uint64_t) raw | ((uint64_t) (((x.tab[bit / LIMB_BITS] >> (bit % LIMB_BITS)) & 1) != 0) << (i))); }
+    }
+    if (x.sign) raw = (SWord16) (~(uint64_t) raw + UINT64_C(1));
+  }
+  bf_delete(&x); bf_context_end(&ctx);
+  SInt16 result; memcpy(&result, &raw, sizeof result); return result;
+}
+
+
+SInt16 fromFP_DoubleTo_Int16(const SDouble sbv_input_0)
+{
+  const SDouble s0 = sbv_input_0;
+        SInt16  s2;
+  s2 = sbv_fp_cast_double_s16(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "fromFP_DoubleTo_Int16.c" ==================
+== BEGIN: "fromFP_DoubleTo_Int32.c" ================
+/* File: "fromFP_DoubleTo_Int32.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+static SBV_CGEN_UNUSED inline SInt32 sbv_fp_cast_double_s32(SDouble a, bf_rnd_t rnd)
+{
+  bf_context_t ctx; bf_t x; SWord32 raw = (SWord32) 0; limb_t i;
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_set_float64(&x, (double) a); bf_rint(&x, rnd);
+  if (bf_is_finite(&x) && !bf_is_zero(&x)) {
+    const slimb_t base = (slimb_t) x.len * LIMB_BITS;
+    for (i = 0; i < 32; ++i) {
+      const slimb_t bit = (slimb_t) i - x.expn + base;
+      if (bit >= 0 && bit < base) { raw = (SWord32) ((uint64_t) raw | ((uint64_t) (((x.tab[bit / LIMB_BITS] >> (bit % LIMB_BITS)) & 1) != 0) << (i))); }
+    }
+    if (x.sign) raw = (SWord32) (~(uint64_t) raw + UINT64_C(1));
+  }
+  bf_delete(&x); bf_context_end(&ctx);
+  SInt32 result; memcpy(&result, &raw, sizeof result); return result;
+}
+
+
+SInt32 fromFP_DoubleTo_Int32(const SDouble sbv_input_0)
+{
+  const SDouble s0 = sbv_input_0;
+        SInt32  s2;
+  s2 = sbv_fp_cast_double_s32(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "fromFP_DoubleTo_Int32.c" ==================
+== BEGIN: "fromFP_DoubleTo_Int64.c" ================
+/* File: "fromFP_DoubleTo_Int64.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+static SBV_CGEN_UNUSED inline SInt64 sbv_fp_cast_double_s64(SDouble a, bf_rnd_t rnd)
+{
+  bf_context_t ctx; bf_t x; SWord64 raw = (SWord64) 0; limb_t i;
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_set_float64(&x, (double) a); bf_rint(&x, rnd);
+  if (bf_is_finite(&x) && !bf_is_zero(&x)) {
+    const slimb_t base = (slimb_t) x.len * LIMB_BITS;
+    for (i = 0; i < 64; ++i) {
+      const slimb_t bit = (slimb_t) i - x.expn + base;
+      if (bit >= 0 && bit < base) { raw = (SWord64) ((uint64_t) raw | ((uint64_t) (((x.tab[bit / LIMB_BITS] >> (bit % LIMB_BITS)) & 1) != 0) << (i))); }
+    }
+    if (x.sign) raw = (SWord64) (~(uint64_t) raw + UINT64_C(1));
+  }
+  bf_delete(&x); bf_context_end(&ctx);
+  SInt64 result; memcpy(&result, &raw, sizeof result); return result;
+}
+
+
+SInt64 fromFP_DoubleTo_Int64(const SDouble sbv_input_0)
+{
+  const SDouble s0 = sbv_input_0;
+        SInt64  s2;
+  s2 = sbv_fp_cast_double_s64(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "fromFP_DoubleTo_Int64.c" ==================
+== BEGIN: "fromFP_DoubleTo_Word8.c" ================
+/* File: "fromFP_DoubleTo_Word8.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+static SBV_CGEN_UNUSED inline SWord8 sbv_fp_cast_double_u8(SDouble a, bf_rnd_t rnd)
+{
+  bf_context_t ctx; bf_t x; SWord8 raw = (SWord8) 0; limb_t i;
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_set_float64(&x, (double) a); bf_rint(&x, rnd);
+  if (bf_is_finite(&x) && !bf_is_zero(&x)) {
+    const slimb_t base = (slimb_t) x.len * LIMB_BITS;
+    for (i = 0; i < 8; ++i) {
+      const slimb_t bit = (slimb_t) i - x.expn + base;
+      if (bit >= 0 && bit < base) { raw = (SWord8) ((uint64_t) raw | ((uint64_t) (((x.tab[bit / LIMB_BITS] >> (bit % LIMB_BITS)) & 1) != 0) << (i))); }
+    }
+    if (x.sign) raw = (SWord8) (~(uint64_t) raw + UINT64_C(1));
+  }
+  bf_delete(&x); bf_context_end(&ctx);
+  return raw;
+}
+
+
+SWord8 fromFP_DoubleTo_Word8(const SDouble sbv_input_0)
+{
+  const SDouble s0 = sbv_input_0;
+        SWord8  s2;
+  s2 = sbv_fp_cast_double_u8(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "fromFP_DoubleTo_Word8.c" ==================
+== BEGIN: "fromFP_DoubleTo_Word16.c" ================
+/* File: "fromFP_DoubleTo_Word16.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+static SBV_CGEN_UNUSED inline SWord16 sbv_fp_cast_double_u16(SDouble a, bf_rnd_t rnd)
+{
+  bf_context_t ctx; bf_t x; SWord16 raw = (SWord16) 0; limb_t i;
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_set_float64(&x, (double) a); bf_rint(&x, rnd);
+  if (bf_is_finite(&x) && !bf_is_zero(&x)) {
+    const slimb_t base = (slimb_t) x.len * LIMB_BITS;
+    for (i = 0; i < 16; ++i) {
+      const slimb_t bit = (slimb_t) i - x.expn + base;
+      if (bit >= 0 && bit < base) { raw = (SWord16) ((uint64_t) raw | ((uint64_t) (((x.tab[bit / LIMB_BITS] >> (bit % LIMB_BITS)) & 1) != 0) << (i))); }
+    }
+    if (x.sign) raw = (SWord16) (~(uint64_t) raw + UINT64_C(1));
+  }
+  bf_delete(&x); bf_context_end(&ctx);
+  return raw;
+}
+
+
+SWord16 fromFP_DoubleTo_Word16(const SDouble sbv_input_0)
+{
+  const SDouble s0 = sbv_input_0;
+        SWord16 s2;
+  s2 = sbv_fp_cast_double_u16(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "fromFP_DoubleTo_Word16.c" ==================
+== BEGIN: "fromFP_DoubleTo_Word32.c" ================
+/* File: "fromFP_DoubleTo_Word32.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+static SBV_CGEN_UNUSED inline SWord32 sbv_fp_cast_double_u32(SDouble a, bf_rnd_t rnd)
+{
+  bf_context_t ctx; bf_t x; SWord32 raw = (SWord32) 0; limb_t i;
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_set_float64(&x, (double) a); bf_rint(&x, rnd);
+  if (bf_is_finite(&x) && !bf_is_zero(&x)) {
+    const slimb_t base = (slimb_t) x.len * LIMB_BITS;
+    for (i = 0; i < 32; ++i) {
+      const slimb_t bit = (slimb_t) i - x.expn + base;
+      if (bit >= 0 && bit < base) { raw = (SWord32) ((uint64_t) raw | ((uint64_t) (((x.tab[bit / LIMB_BITS] >> (bit % LIMB_BITS)) & 1) != 0) << (i))); }
+    }
+    if (x.sign) raw = (SWord32) (~(uint64_t) raw + UINT64_C(1));
+  }
+  bf_delete(&x); bf_context_end(&ctx);
+  return raw;
+}
+
+
+SWord32 fromFP_DoubleTo_Word32(const SDouble sbv_input_0)
+{
+  const SDouble s0 = sbv_input_0;
+        SWord32 s2;
+  s2 = sbv_fp_cast_double_u32(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "fromFP_DoubleTo_Word32.c" ==================
+== BEGIN: "fromFP_DoubleTo_Word64.c" ================
+/* File: "fromFP_DoubleTo_Word64.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+static SBV_CGEN_UNUSED inline SWord64 sbv_fp_cast_double_u64(SDouble a, bf_rnd_t rnd)
+{
+  bf_context_t ctx; bf_t x; SWord64 raw = (SWord64) 0; limb_t i;
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_set_float64(&x, (double) a); bf_rint(&x, rnd);
+  if (bf_is_finite(&x) && !bf_is_zero(&x)) {
+    const slimb_t base = (slimb_t) x.len * LIMB_BITS;
+    for (i = 0; i < 64; ++i) {
+      const slimb_t bit = (slimb_t) i - x.expn + base;
+      if (bit >= 0 && bit < base) { raw = (SWord64) ((uint64_t) raw | ((uint64_t) (((x.tab[bit / LIMB_BITS] >> (bit % LIMB_BITS)) & 1) != 0) << (i))); }
+    }
+    if (x.sign) raw = (SWord64) (~(uint64_t) raw + UINT64_C(1));
+  }
+  bf_delete(&x); bf_context_end(&ctx);
+  return raw;
+}
+
+
+SWord64 fromFP_DoubleTo_Word64(const SDouble sbv_input_0)
+{
+  const SDouble s0 = sbv_input_0;
+        SWord64 s2;
+  s2 = sbv_fp_cast_double_u64(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "fromFP_DoubleTo_Word64.c" ==================
+== BEGIN: "fromFP_DoubleTo_Float.c" ================
+/* File: "fromFP_DoubleTo_Float.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+static SBV_CGEN_UNUSED inline SFloat sbv_fp_cast_double_float(SDouble a, bf_rnd_t rnd)
+{
+  bf_context_t ctx; bf_t x; double result;
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_set_float64(&x, (double) a);
+  bf_round(&x, 24, BF_FLAG_SUBNORMAL | bf_set_exp_bits(8) | (bf_flags_t) rnd); bf_get_float64(&x, &result, rnd);
+  bf_delete(&x); bf_context_end(&ctx); return (SFloat) result;
+}
+
+
+SFloat fromFP_DoubleTo_Float(const SDouble sbv_input_0)
+{
+  const SDouble s0 = sbv_input_0;
+        SFloat  s2;
+  s2 = sbv_fp_cast_double_float(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "fromFP_DoubleTo_Float.c" ==================
+== BEGIN: "fromFP_DoubleTo_Double.c" ================
+/* File: "fromFP_DoubleTo_Double.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SDouble fromFP_DoubleTo_Double(const SDouble sbv_input_0)
+{
+  const SDouble s0 = sbv_input_0;
+  return s0;
+}
+== END: "fromFP_DoubleTo_Double.c" ==================
+== BEGIN: "fromFP_DoubleTo_Integer.c" ================
+/* File: "fromFP_DoubleTo_Integer.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+static SBV_CGEN_UNUSED inline SInt64 sbv_fp_cast_double_integer(SDouble a, bf_rnd_t rnd)
+{
+  bf_context_t ctx; bf_t x; SWord64 raw = (SWord64) 0; limb_t i;
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_set_float64(&x, (double) a); bf_rint(&x, rnd);
+  if (bf_is_finite(&x) && !bf_is_zero(&x)) {
+    const slimb_t base = (slimb_t) x.len * LIMB_BITS;
+    for (i = 0; i < 64; ++i) {
+      const slimb_t bit = (slimb_t) i - x.expn + base;
+      if (bit >= 0 && bit < base) { raw = (SWord64) ((uint64_t) raw | ((uint64_t) (((x.tab[bit / LIMB_BITS] >> (bit % LIMB_BITS)) & 1) != 0) << (i))); }
+    }
+    if (x.sign) raw = (SWord64) (~(uint64_t) raw + UINT64_C(1));
+  }
+  bf_delete(&x); bf_context_end(&ctx);
+  SInt64 result; memcpy(&result, &raw, sizeof result); return result;
+}
+
+
+SInteger fromFP_DoubleTo_Integer(const SDouble sbv_input_0)
+{
+  const SDouble  s0 = sbv_input_0;
+        SInteger s2;
+  s2 = sbv_fp_cast_double_integer(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "fromFP_DoubleTo_Integer.c" ==================
+== BEGIN: "fromFP_DoubleTo_Real.c" ================
+/* File: "fromFP_DoubleTo_Real.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+/* LibBF-backed arbitrary floating-point runtime. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static SBV_CGEN_UNUSED inline bf_rnd_t sbv_bf_rounding_mode(int mode)
+{
+  switch (mode) {
+    case 0: return BF_RNDN;
+    case 1: return BF_RNDNA;
+    case 2: return BF_RNDU;
+    case 3: return BF_RNDD;
+    case 4: return BF_RNDZ;
+    default: abort();
+  }
+}
+
+static SBV_CGEN_UNUSED void *sbv_bf_realloc(void *opaque, void *ptr, size_t size)
+{
+  (void) opaque;
+  return realloc(ptr, size);
+}
+
+#include <float.h>
+#if FLT_RADIX == 2 && LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 && LDBL_MIN_EXP == -1021
+#define SBV_LDBL_EXP_BITS 11
+#elif FLT_RADIX == 2 && (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 && LDBL_MIN_EXP == -16381
+#define SBV_LDBL_EXP_BITS 15
+#else
+#error SBV C long-double conversions require binary64, x87 extended, or binary128 long double
+#endif
+#if BF_EXP_BITS_MAX < SBV_LDBL_EXP_BITS
+#error SBV C long-double conversions exceed the LibBF exponent range
+#endif
+
+static SBV_CGEN_UNUSED bf_flags_t sbv_bf_long_double_flags(bf_rnd_t rnd)
+{
+  return BF_FLAG_SUBNORMAL | bf_set_exp_bits(SBV_LDBL_EXP_BITS) | (bf_flags_t) rnd;
+}
+
+static SBV_CGEN_UNUSED void sbv_bf_set_long_double(bf_t *result, long double value)
+{
+  int exponent, shift = 0, status = 0; bf_t chunk;
+  if (isnan(value)) { bf_set_nan(result); return; }
+  if (isinf(value)) { bf_set_inf(result, signbit(value) != 0); return; }
+  if (value == 0) { bf_set_zero(result, signbit(value) != 0); return; }
+  long double fraction = frexpl(fabsl(value), &exponent);
+  bf_init(result->ctx, &chunk); bf_set_zero(result, 0);
+  while (fraction != 0) {
+    fraction = ldexpl(fraction, 32);
+    const uint32_t bits = (uint32_t) fraction; fraction -= (long double) bits;
+    status |= bf_mul_2exp(result, 32, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);
+    status |= bf_set_ui(&chunk, bits);
+    status |= bf_add(result, result, &chunk, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ); shift += 32;
+  }
+  status |= bf_mul_2exp(result, exponent - shift, BF_PREC_INF, BF_FLAG_EXT_EXP | BF_RNDZ);
+  bf_delete(&chunk); if (status & BF_ST_MEM_ERROR) abort();
+  if (signbit(value)) bf_neg(result);
+}
+
+static SBV_CGEN_UNUSED long double sbv_bf_get_long_double(bf_t *value, bf_rnd_t rnd)
+{
+  if (bf_round(value, LDBL_MANT_DIG, sbv_bf_long_double_flags(rnd)) & BF_ST_MEM_ERROR) abort();
+  if (bf_is_nan(value)) return nanl("");
+  if (!bf_is_finite(value)) return value->sign ? -HUGE_VALL : HUGE_VALL;
+  if (bf_is_zero(value)) return value->sign ? -0.0L : 0.0L;
+  long double significand = 0;
+  const slimb_t base = (slimb_t) value->len * LIMB_BITS;
+  for (int i = 0; i < LDBL_MANT_DIG; ++i) {
+    const slimb_t bit = base - 1 - i;
+    const unsigned digit = bit < 0 ? 0 : (unsigned) ((value->tab[bit / LIMB_BITS] >> (bit % LIMB_BITS)) & 1);
+    significand = significand * 2 + digit;
+  }
+  const long double result = ldexpl(significand, (int) value->expn - LDBL_MANT_DIG);
+  return value->sign ? -result : result;
+}
+
+static SBV_CGEN_UNUSED inline SReal sbv_fp_cast_double_real(SDouble a, bf_rnd_t rnd)
+{
+  bf_context_t ctx; bf_t x; long double result;
+  bf_context_init(&ctx, sbv_bf_realloc, NULL); bf_init(&ctx, &x); bf_set_float64(&x, (double) a);
+  bf_round(&x, LDBL_MANT_DIG, sbv_bf_long_double_flags(rnd)); result = sbv_bf_get_long_double(&x, rnd);
+  bf_delete(&x); bf_context_end(&ctx); return (SReal) result;
+}
+
+
+SReal fromFP_DoubleTo_Real(const SDouble sbv_input_0)
+{
+  const SDouble s0 = sbv_input_0;
+        SReal   s2;
+  s2 = sbv_fp_cast_double_real(s0, BF_RNDN);
+
+  return s2;
+}
+== END: "fromFP_DoubleTo_Real.c" ==================
+== BEGIN: "fromFP_SWord32_SFloat.c" ================
+/* File: "fromFP_SWord32_SFloat.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SFloat fromFP_SWord32_SFloat(const SWord32 sbv_input_0)
+{
+  const SWord32 s0 = sbv_input_0;
+        SFloat  s1;
+  memcpy(&s1, &s0, sizeof(SFloat));
+
+  return s1;
+}
+== END: "fromFP_SWord32_SFloat.c" ==================
+== BEGIN: "fromFP_SWord64_SDouble.c" ================
+/* File: "fromFP_SWord64_SDouble.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SDouble fromFP_SWord64_SDouble(const SWord64 sbv_input_0)
+{
+  const SWord64 s0 = sbv_input_0;
+        SDouble s1;
+  memcpy(&s1, &s0, sizeof(SDouble));
+
+  return s1;
+}
+== END: "fromFP_SWord64_SDouble.c" ==================
+== BEGIN: "fromFP_SFloat_SWord32.c" ================
+/* File: "fromFP_SFloat_SWord32.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SWord32 fromFP_SFloat_SWord32(const SFloat sbv_input_0)
+{
+  const SFloat  s0 = sbv_input_0;
+        SWord32 s1;
+  memcpy(&s1, &s0, sizeof(SWord32));
+
+  return s1;
+}
+== END: "fromFP_SFloat_SWord32.c" ==================
+== BEGIN: "fromFP_SDouble_SWord64.c" ================
+/* File: "fromFP_SDouble_SWord64.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SWord64 fromFP_SDouble_SWord64(const SDouble sbv_input_0)
+{
+  const SDouble s0 = sbv_input_0;
+        SWord64 s1;
+  memcpy(&s1, &s0, sizeof(SWord64));
+
+  return s1;
+}
+== END: "fromFP_SDouble_SWord64.c" ==================
+== BEGIN: "f_FP_Abs.c" ================
+/* File: "f_FP_Abs.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SFloat f_FP_Abs(const SFloat sbv_input_0)
+{
+  const SFloat s0 = sbv_input_0;
+        SFloat s1;
+  s1 = fabsf(s0);
+
+  return s1;
+}
+== END: "f_FP_Abs.c" ==================
+== BEGIN: "d_FP_Abs.c" ================
+/* File: "d_FP_Abs.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SDouble d_FP_Abs(const SDouble sbv_input_0)
+{
+  const SDouble s0 = sbv_input_0;
+        SDouble s1;
+  s1 = fabs(s0);
+
+  return s1;
+}
+== END: "d_FP_Abs.c" ==================
+== BEGIN: "f_FP_Neg.c" ================
+/* File: "f_FP_Neg.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SFloat f_FP_Neg(const SFloat sbv_input_0)
+{
+  const SFloat s0 = sbv_input_0;
+        SFloat s1;
+  s1 = (- s0);
+
+  return s1;
+}
+== END: "f_FP_Neg.c" ==================
+== BEGIN: "d_FP_Neg.c" ================
+/* File: "d_FP_Neg.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SDouble d_FP_Neg(const SDouble sbv_input_0)
+{
+  const SDouble s0 = sbv_input_0;
+        SDouble s1;
+  s1 = (- s0);
+
+  return s1;
+}
+== END: "d_FP_Neg.c" ==================
+== BEGIN: "f_FP_Add.c" ================
+/* File: "f_FP_Add.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SFloat f_FP_Add(const SFloat sbv_input_0, const SFloat sbv_input_1)
+{
+  const SFloat s0 = sbv_input_0;
+  const SFloat s1 = sbv_input_1;
+        SFloat s3;
+  s3 = s0 + s1;
+
+  return s3;
+}
+== END: "f_FP_Add.c" ==================
+== BEGIN: "d_FP_Add.c" ================
+/* File: "d_FP_Add.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SDouble d_FP_Add(const SDouble sbv_input_0,
+                 const SDouble sbv_input_1)
+{
+  const SDouble s0 = sbv_input_0;
+  const SDouble s1 = sbv_input_1;
+        SDouble s3;
+  s3 = s0 + s1;
+
+  return s3;
+}
+== END: "d_FP_Add.c" ==================
+== BEGIN: "f_FP_Sub.c" ================
+/* File: "f_FP_Sub.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SFloat f_FP_Sub(const SFloat sbv_input_0, const SFloat sbv_input_1)
+{
+  const SFloat s0 = sbv_input_0;
+  const SFloat s1 = sbv_input_1;
+        SFloat s3;
+  s3 = s0 - s1;
+
+  return s3;
+}
+== END: "f_FP_Sub.c" ==================
+== BEGIN: "d_FP_Sub.c" ================
+/* File: "d_FP_Sub.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SDouble d_FP_Sub(const SDouble sbv_input_0,
+                 const SDouble sbv_input_1)
+{
+  const SDouble s0 = sbv_input_0;
+  const SDouble s1 = sbv_input_1;
+        SDouble s3;
+  s3 = s0 - s1;
+
+  return s3;
+}
+== END: "d_FP_Sub.c" ==================
+== BEGIN: "f_FP_Mul.c" ================
+/* File: "f_FP_Mul.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SFloat f_FP_Mul(const SFloat sbv_input_0, const SFloat sbv_input_1)
+{
+  const SFloat s0 = sbv_input_0;
+  const SFloat s1 = sbv_input_1;
+        SFloat s3;
+  s3 = s0 * s1;
+
+  return s3;
+}
+== END: "f_FP_Mul.c" ==================
+== BEGIN: "d_FP_Mul.c" ================
+/* File: "d_FP_Mul.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SDouble d_FP_Mul(const SDouble sbv_input_0,
+                 const SDouble sbv_input_1)
+{
+  const SDouble s0 = sbv_input_0;
+  const SDouble s1 = sbv_input_1;
+        SDouble s3;
+  s3 = s0 * s1;
+
+  return s3;
+}
+== END: "d_FP_Mul.c" ==================
+== BEGIN: "f_FP_Div.c" ================
+/* File: "f_FP_Div.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SFloat f_FP_Div(const SFloat sbv_input_0, const SFloat sbv_input_1)
+{
+  const SFloat s0 = sbv_input_0;
+  const SFloat s1 = sbv_input_1;
+        SFloat s3;
+  s3 = s0 / s1;
+
+  return s3;
+}
+== END: "f_FP_Div.c" ==================
+== BEGIN: "d_FP_Div.c" ================
+/* File: "d_FP_Div.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SDouble d_FP_Div(const SDouble sbv_input_0,
+                 const SDouble sbv_input_1)
+{
+  const SDouble s0 = sbv_input_0;
+  const SDouble s1 = sbv_input_1;
+        SDouble s3;
+  s3 = s0 / s1;
+
+  return s3;
+}
+== END: "d_FP_Div.c" ==================
+== BEGIN: "f_FP_FMA.c" ================
+/* File: "f_FP_FMA.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SFloat f_FP_FMA(const SFloat sbv_input_0, const SFloat sbv_input_1,
+                const SFloat sbv_input_2)
+{
+  const SFloat s0 = sbv_input_0;
+  const SFloat s1 = sbv_input_1;
+  const SFloat s2 = sbv_input_2;
+        SFloat s4;
+  s4 = fmaf(s0, s1, s2);
+
+  return s4;
+}
+== END: "f_FP_FMA.c" ==================
+== BEGIN: "d_FP_FMA.c" ================
+/* File: "d_FP_FMA.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SDouble d_FP_FMA(const SDouble sbv_input_0,
+                 const SDouble sbv_input_1, const SDouble sbv_input_2)
+{
+  const SDouble s0 = sbv_input_0;
+  const SDouble s1 = sbv_input_1;
+  const SDouble s2 = sbv_input_2;
+        SDouble s4;
+  s4 = fma(s0, s1, s2);
+
+  return s4;
+}
+== END: "d_FP_FMA.c" ==================
+== BEGIN: "f_FP_Sqrt.c" ================
+/* File: "f_FP_Sqrt.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SFloat f_FP_Sqrt(const SFloat sbv_input_0)
+{
+  const SFloat s0 = sbv_input_0;
+        SFloat s2;
+  s2 = sqrtf(s0);
+
+  return s2;
+}
+== END: "f_FP_Sqrt.c" ==================
+== BEGIN: "d_FP_Sqrt.c" ================
+/* File: "d_FP_Sqrt.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SDouble d_FP_Sqrt(const SDouble sbv_input_0)
+{
+  const SDouble s0 = sbv_input_0;
+        SDouble s2;
+  s2 = sqrt(s0);
+
+  return s2;
+}
+== END: "d_FP_Sqrt.c" ==================
+== BEGIN: "f_FP_Rem.c" ================
+/* File: "f_FP_Rem.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SFloat f_FP_Rem(const SFloat sbv_input_0, const SFloat sbv_input_1)
+{
+  const SFloat s0 = sbv_input_0;
+  const SFloat s1 = sbv_input_1;
+        SFloat s2;
+  s2 = remainderf(s0, s1);
+
+  return s2;
+}
+== END: "f_FP_Rem.c" ==================
+== BEGIN: "d_FP_Rem.c" ================
+/* File: "d_FP_Rem.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SDouble d_FP_Rem(const SDouble sbv_input_0,
+                 const SDouble sbv_input_1)
+{
+  const SDouble s0 = sbv_input_0;
+  const SDouble s1 = sbv_input_1;
+        SDouble s2;
+  s2 = remainder(s0, s1);
+
+  return s2;
+}
+== END: "d_FP_Rem.c" ==================
+== BEGIN: "f_FP_RoundToIntegral.c" ================
+/* File: "f_FP_RoundToIntegral.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SFloat f_FP_RoundToIntegral(const SFloat sbv_input_0)
+{
+  const SFloat s0 = sbv_input_0;
+        SFloat s2;
+  s2 = rintf(s0);
+
+  return s2;
+}
+== END: "f_FP_RoundToIntegral.c" ==================
+== BEGIN: "d_FP_RoundToIntegral.c" ================
+/* File: "d_FP_RoundToIntegral.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SDouble d_FP_RoundToIntegral(const SDouble sbv_input_0)
+{
+  const SDouble s0 = sbv_input_0;
+        SDouble s2;
+  s2 = rint(s0);
+
+  return s2;
+}
+== END: "d_FP_RoundToIntegral.c" ==================
+== BEGIN: "f_FP_Min.c" ================
+/* File: "f_FP_Min.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SFloat f_FP_Min(const SFloat sbv_input_0, const SFloat sbv_input_1)
+{
+  const SFloat s0 = sbv_input_0;
+  const SFloat s1 = sbv_input_1;
+        SFloat s2;
+  s2 = ((FP_ZERO == fpclassify(s0)) && (FP_ZERO == fpclassify(s1)) && (signbit(s0) != signbit(s1))) ? 0x0p+0F /* 0.0F */ : fminf(s0,
+                                                                                                                                 s1);
+
+  return s2;
+}
+== END: "f_FP_Min.c" ==================
+== BEGIN: "d_FP_Min.c" ================
+/* File: "d_FP_Min.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SDouble d_FP_Min(const SDouble sbv_input_0,
+                 const SDouble sbv_input_1)
+{
+  const SDouble s0 = sbv_input_0;
+  const SDouble s1 = sbv_input_1;
+        SDouble s2;
+  s2 = ((FP_ZERO == fpclassify(s0)) && (FP_ZERO == fpclassify(s1)) && (signbit(s0) != signbit(s1))) ? 0x0p+0 /* 0.0 */ : fmin(s0,
+                                                                                                                              s1);
+
+  return s2;
+}
+== END: "d_FP_Min.c" ==================
+== BEGIN: "f_FP_Max.c" ================
+/* File: "f_FP_Max.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SFloat f_FP_Max(const SFloat sbv_input_0, const SFloat sbv_input_1)
+{
+  const SFloat s0 = sbv_input_0;
+  const SFloat s1 = sbv_input_1;
+        SFloat s2;
+  s2 = ((FP_ZERO == fpclassify(s0)) && (FP_ZERO == fpclassify(s1)) && (signbit(s0) != signbit(s1))) ? 0x0p+0F /* 0.0F */ : fmaxf(s0,
+                                                                                                                                 s1);
+
+  return s2;
+}
+== END: "f_FP_Max.c" ==================
+== BEGIN: "d_FP_Max.c" ================
+/* File: "d_FP_Max.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SDouble d_FP_Max(const SDouble sbv_input_0,
+                 const SDouble sbv_input_1)
+{
+  const SDouble s0 = sbv_input_0;
+  const SDouble s1 = sbv_input_1;
+        SDouble s2;
+  s2 = ((FP_ZERO == fpclassify(s0)) && (FP_ZERO == fpclassify(s1)) && (signbit(s0) != signbit(s1))) ? 0x0p+0 /* 0.0 */ : fmax(s0,
+                                                                                                                              s1);
+
+  return s2;
+}
+== END: "d_FP_Max.c" ==================
+== BEGIN: "f_FP_IsEqualObject.c" ================
+/* File: "f_FP_IsEqualObject.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SBool f_FP_IsEqualObject(const SFloat sbv_input_0,
+                         const SFloat sbv_input_1)
+{
+  const SFloat s0 = sbv_input_0;
+  const SFloat s1 = sbv_input_1;
+        SBool  s2;
+  s2 = isnan(s0) ? isnan(s1) : (signbit(s0) && (s0 == 0)) ? (signbit(s1) && (s1 == 0)) : (signbit(s1) && (s1 == 0)) ? (signbit(s0) && (s0 == 0)) : (s0 == s1);
+
+  return s2;
+}
+== END: "f_FP_IsEqualObject.c" ==================
+== BEGIN: "d_FP_IsEqualObject.c" ================
+/* File: "d_FP_IsEqualObject.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SBool d_FP_IsEqualObject(const SDouble sbv_input_0,
+                         const SDouble sbv_input_1)
+{
+  const SDouble s0 = sbv_input_0;
+  const SDouble s1 = sbv_input_1;
+        SBool   s2;
+  s2 = isnan(s0) ? isnan(s1) : (signbit(s0) && (s0 == 0)) ? (signbit(s1) && (s1 == 0)) : (signbit(s1) && (s1 == 0)) ? (signbit(s0) && (s0 == 0)) : (s0 == s1);
+
+  return s2;
+}
+== END: "d_FP_IsEqualObject.c" ==================
+== BEGIN: "f_FP_IsNormal.c" ================
+/* File: "f_FP_IsNormal.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SBool f_FP_IsNormal(const SFloat sbv_input_0)
+{
+  const SFloat s0 = sbv_input_0;
+        SBool  s1;
+  s1 = isnormal(s0);
+
+  return s1;
+}
+== END: "f_FP_IsNormal.c" ==================
+== BEGIN: "d_FP_IsNormal.c" ================
+/* File: "d_FP_IsNormal.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SBool d_FP_IsNormal(const SDouble sbv_input_0)
+{
+  const SDouble s0 = sbv_input_0;
+        SBool   s1;
+  s1 = isnormal(s0);
+
+  return s1;
+}
+== END: "d_FP_IsNormal.c" ==================
+== BEGIN: "f_FP_IsZero.c" ================
+/* File: "f_FP_IsZero.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SBool f_FP_IsZero(const SFloat sbv_input_0)
+{
+  const SFloat s0 = sbv_input_0;
+        SBool  s1;
+  s1 = FP_ZERO == fpclassify(s0);
+
+  return s1;
+}
+== END: "f_FP_IsZero.c" ==================
+== BEGIN: "d_FP_IsZero.c" ================
+/* File: "d_FP_IsZero.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SBool d_FP_IsZero(const SDouble sbv_input_0)
+{
+  const SDouble s0 = sbv_input_0;
+        SBool   s1;
+  s1 = FP_ZERO == fpclassify(s0);
+
+  return s1;
+}
+== END: "d_FP_IsZero.c" ==================
+== BEGIN: "f_FP_IsSubnormal.c" ================
+/* File: "f_FP_IsSubnormal.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SBool f_FP_IsSubnormal(const SFloat sbv_input_0)
+{
+  const SFloat s0 = sbv_input_0;
+        SBool  s1;
+  s1 = FP_SUBNORMAL == fpclassify(s0);
+
+  return s1;
+}
+== END: "f_FP_IsSubnormal.c" ==================
+== BEGIN: "d_FP_IsSubnormal.c" ================
+/* File: "d_FP_IsSubnormal.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SBool d_FP_IsSubnormal(const SDouble sbv_input_0)
+{
+  const SDouble s0 = sbv_input_0;
+        SBool   s1;
+  s1 = FP_SUBNORMAL == fpclassify(s0);
+
+  return s1;
+}
+== END: "d_FP_IsSubnormal.c" ==================
+== BEGIN: "f_FP_IsInfinite.c" ================
+/* File: "f_FP_IsInfinite.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SBool f_FP_IsInfinite(const SFloat sbv_input_0)
+{
+  const SFloat s0 = sbv_input_0;
+        SBool  s1;
+  s1 = isinf(s0);
+
+  return s1;
+}
+== END: "f_FP_IsInfinite.c" ==================
+== BEGIN: "d_FP_IsInfinite.c" ================
+/* File: "d_FP_IsInfinite.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SBool d_FP_IsInfinite(const SDouble sbv_input_0)
+{
+  const SDouble s0 = sbv_input_0;
+        SBool   s1;
+  s1 = isinf(s0);
+
+  return s1;
+}
+== END: "d_FP_IsInfinite.c" ==================
+== BEGIN: "f_FP_IsNaN.c" ================
+/* File: "f_FP_IsNaN.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SBool f_FP_IsNaN(const SFloat sbv_input_0)
+{
+  const SFloat s0 = sbv_input_0;
+        SBool  s1;
+  s1 = isnan(s0);
+
+  return s1;
+}
+== END: "f_FP_IsNaN.c" ==================
+== BEGIN: "d_FP_IsNaN.c" ================
+/* File: "d_FP_IsNaN.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SBool d_FP_IsNaN(const SDouble sbv_input_0)
+{
+  const SDouble s0 = sbv_input_0;
+        SBool   s1;
+  s1 = isnan(s0);
+
+  return s1;
+}
+== END: "d_FP_IsNaN.c" ==================
+== BEGIN: "f_FP_IsNegative.c" ================
+/* File: "f_FP_IsNegative.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SBool f_FP_IsNegative(const SFloat sbv_input_0)
+{
+  const SFloat s0 = sbv_input_0;
+        SBool  s1;
+  s1 = !isnan(s0) && signbit(s0);
+
+  return s1;
+}
+== END: "f_FP_IsNegative.c" ==================
+== BEGIN: "d_FP_IsNegative.c" ================
+/* File: "d_FP_IsNegative.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SBool d_FP_IsNegative(const SDouble sbv_input_0)
+{
+  const SDouble s0 = sbv_input_0;
+        SBool   s1;
+  s1 = !isnan(s0) && signbit(s0);
+
+  return s1;
+}
+== END: "d_FP_IsNegative.c" ==================
+== BEGIN: "f_FP_IsPositive.c" ================
+/* File: "f_FP_IsPositive.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SBool f_FP_IsPositive(const SFloat sbv_input_0)
+{
+  const SFloat s0 = sbv_input_0;
+        SBool  s1;
+  s1 = !isnan(s0) && !signbit(s0);
+
+  return s1;
+}
+== END: "f_FP_IsPositive.c" ==================
+== BEGIN: "d_FP_IsPositive.c" ================
+/* File: "d_FP_IsPositive.c". Automatically generated by SBV. Do not edit! */
+
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+/* Preserve separate SBV rounding steps; explicit fma calls remain fused. */
+#if defined(__clang__)
+#pragma STDC FP_CONTRACT OFF
+#endif
+
+
+SBool d_FP_IsPositive(const SDouble sbv_input_0)
+{
+  const SDouble s0 = sbv_input_0;
+        SBool   s1;
+  s1 = !isnan(s0) && !signbit(s0);
+
+  return s1;
+}
+== END: "d_FP_IsPositive.c" ==================
+== BEGIN: "floatCodeGen.h" ================
+/* Header file for floatCodeGen. Automatically generated by SBV. Do not edit! */
+
+#ifndef SBV_GENERATED_floatCodeGen_HEADER_INCLUDED
+#define SBV_GENERATED_floatCodeGen_HEADER_INCLUDED
+
+#if defined(__FAST_MATH__) || (defined(__FINITE_MATH_ONLY__) && __FINITE_MATH_ONLY__ > 0)
+#error "SBV-generated C requires IEEE floating-point semantics; disable fast-math and finite-math-only."
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <math.h>
+#include <float.h>
+#if FLT_EVAL_METHOD != 0
+#error "SBV-generated C requires FLT_EVAL_METHOD == 0; indeterminate or excess-precision floating evaluation is unsupported."
+#endif
+
+/* Floating-point calling convention:
+ * Enter generated code in FE_TONEAREST (round-to-nearest, ties-to-even).
+ * Callbacks must preserve this mode before returning or re-entering.
+ * Generated code does not check or change the hardware rounding mode.
+ * Custom builds must disable implicit FP contraction, including at LTO link time.
+ */
+
+/* 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;
+
+/* User requested mapping for SInteger.                                 */
+/* NB. Loss of precision: Target type is subject to modular arithmetic. */
+typedef SInt64 SInteger;
+
+/* User requested mapping for SReal.                          */
+/* NB. Loss of precision: Target type is subject to rounding. */
+typedef long double SReal;
+
+/* IEEE-754 rounding modes. */
+#ifndef SBV_ROUNDING_MODE_DEFINED
+#define SBV_ROUNDING_MODE_DEFINED
+typedef enum { SBV_RM_RNE = 0, SBV_RM_RNA = 1, SBV_RM_RTP = 2, SBV_RM_RTN = 3, SBV_RM_RTZ = 4 } RoundingMode;
+#endif
+
+
+/* Entry point prototypes: */
+SFloat toFP_Int8_ToFloat(const SInt8 a);
+SFloat toFP_Int16_ToFloat(const SInt16 a);
+SFloat toFP_Int32_ToFloat(const SInt32 a);
+SFloat toFP_Int64_ToFloat(const SInt64 a);
+SFloat toFP_Word8_ToFloat(const SWord8 a);
+SFloat toFP_Word16_ToFloat(const SWord16 a);
+SFloat toFP_Word32_ToFloat(const SWord32 a);
+SFloat toFP_Word64_ToFloat(const SWord64 a);
+SFloat toFP_Float_ToFloat(const SFloat a);
+SFloat toFP_Double_ToFloat(const SDouble a);
+SFloat toFP_Integer_ToFloat(const SInteger a);
+SFloat toFP_Real_ToFloat(const SReal a);
+SDouble toFP_Int8_ToDouble(const SInt8 a);
+SDouble toFP_Int16_ToDouble(const SInt16 a);
+SDouble toFP_Int32_ToDouble(const SInt32 a);
+SDouble toFP_Int64_ToDouble(const SInt64 a);
+SDouble toFP_Word8_ToDouble(const SWord8 a);
+SDouble toFP_Word16_ToDouble(const SWord16 a);
+SDouble toFP_Word32_ToDouble(const SWord32 a);
+SDouble toFP_Word64_ToDouble(const SWord64 a);
+SDouble toFP_Float_ToDouble(const SFloat a);
+SDouble toFP_Double_ToDouble(const SDouble a);
+SDouble toFP_Integer_ToDouble(const SInteger a);
+SDouble toFP_Real_ToDouble(const SReal a);
+SInt8 fromFP_Float_ToInt8(const SFloat a);
+SInt16 fromFP_Float_ToInt16(const SFloat a);
+SInt32 fromFP_Float_ToInt32(const SFloat a);
+SInt64 fromFP_Float_ToInt64(const SFloat a);
+SWord8 fromFP_Float_ToWord8(const SFloat a);
+SWord16 fromFP_Float_ToWord16(const SFloat a);
+SWord32 fromFP_Float_ToWord32(const SFloat a);
+SWord64 fromFP_Float_ToWord64(const SFloat a);
+SFloat fromFP_Float_ToFloat(const SFloat a);
+SDouble fromFP_Float_ToDouble(const SFloat a);
+SInteger fromFP_Float_ToInteger(const SFloat a);
+SReal fromFP_Float_ToReal(const SFloat a);
+SInt8 fromFP_DoubleTo_Int8(const SDouble a);
+SInt16 fromFP_DoubleTo_Int16(const SDouble a);
+SInt32 fromFP_DoubleTo_Int32(const SDouble a);
+SInt64 fromFP_DoubleTo_Int64(const SDouble a);
+SWord8 fromFP_DoubleTo_Word8(const SDouble a);
+SWord16 fromFP_DoubleTo_Word16(const SDouble a);
+SWord32 fromFP_DoubleTo_Word32(const SDouble a);
+SWord64 fromFP_DoubleTo_Word64(const SDouble a);
+SFloat fromFP_DoubleTo_Float(const SDouble a);
+SDouble fromFP_DoubleTo_Double(const SDouble a);
+SInteger fromFP_DoubleTo_Integer(const SDouble a);
+SReal fromFP_DoubleTo_Real(const SDouble a);
+SFloat fromFP_SWord32_SFloat(const SWord32 a);
+SDouble fromFP_SWord64_SDouble(const SWord64 a);
+SWord32 fromFP_SFloat_SWord32(const SFloat a);
+SWord64 fromFP_SDouble_SWord64(const SDouble a);
+SFloat f_FP_Abs(const SFloat a);
+SDouble d_FP_Abs(const SDouble a);
+SFloat f_FP_Neg(const SFloat a);
+SDouble d_FP_Neg(const SDouble a);
+SFloat f_FP_Add(const SFloat a, const SFloat b);
+SDouble d_FP_Add(const SDouble a, const SDouble b);
+SFloat f_FP_Sub(const SFloat a, const SFloat b);
+SDouble d_FP_Sub(const SDouble a, const SDouble b);
+SFloat f_FP_Mul(const SFloat a, const SFloat b);
+SDouble d_FP_Mul(const SDouble a, const SDouble b);
+SFloat f_FP_Div(const SFloat a, const SFloat b);
+SDouble d_FP_Div(const SDouble a, const SDouble b);
+SFloat f_FP_FMA(const SFloat a, const SFloat b, const SFloat c);
+SDouble d_FP_FMA(const SDouble a, const SDouble b,
+                 const SDouble c);
+SFloat f_FP_Sqrt(const SFloat a);
+SDouble d_FP_Sqrt(const SDouble a);
+SFloat f_FP_Rem(const SFloat a, const SFloat b);
+SDouble d_FP_Rem(const SDouble a, const SDouble b);
+SFloat f_FP_RoundToIntegral(const SFloat a);
+SDouble d_FP_RoundToIntegral(const SDouble a);
+SFloat f_FP_Min(const SFloat a, const SFloat b);
+SDouble d_FP_Min(const SDouble a, const SDouble b);
+SFloat f_FP_Max(const SFloat a, const SFloat b);
+SDouble d_FP_Max(const SDouble a, const SDouble b);
+SBool f_FP_IsEqualObject(const SFloat a, const SFloat b);
+SBool d_FP_IsEqualObject(const SDouble a, const SDouble b);
+SBool f_FP_IsNormal(const SFloat a);
+SBool d_FP_IsNormal(const SDouble a);
+SBool f_FP_IsZero(const SFloat a);
+SBool d_FP_IsZero(const SDouble a);
+SBool f_FP_IsSubnormal(const SFloat a);
+SBool d_FP_IsSubnormal(const SDouble a);
+SBool f_FP_IsInfinite(const SFloat a);
+SBool d_FP_IsInfinite(const SDouble a);
+SBool f_FP_IsNaN(const SFloat a);
+SBool d_FP_IsNaN(const SDouble a);
+SBool f_FP_IsNegative(const SFloat a);
+SBool d_FP_IsNegative(const SDouble a);
+SBool f_FP_IsPositive(const SFloat a);
+SBool d_FP_IsPositive(const SDouble a);
+
+#endif /* SBV_GENERATED_floatCodeGen_HEADER_INCLUDED */
+== END: "floatCodeGen.h" ==================
+== BEGIN: "floatCodeGen_driver.c" ================
+/* Example driver program for floatCodeGen. */
+/* Automatically generated by SBV. Edit as you see fit! */
+
+#include <stdio.h>
+#include "floatCodeGen.h"
+#include <libbf.h>
+
+void toFP_Int8_ToFloat_driver(void)
+{
+  const SFloat sbv_result = toFP_Int8_ToFloat(42);
+
+  printf("toFP_Int8_ToFloat(42) = %a\n", sbv_result);
+}
+
+void toFP_Int16_ToFloat_driver(void)
+{
+  const SFloat sbv_result = toFP_Int16_ToFloat(0x002a);
+
+  printf("toFP_Int16_ToFloat(0x002a) = %a\n", sbv_result);
+}
+
+void toFP_Int32_ToFloat_driver(void)
+{
+  const SFloat sbv_result = toFP_Int32_ToFloat(0x0000002aL);
+
+  printf("toFP_Int32_ToFloat(0x0000002aL) = %a\n", sbv_result);
+}
+
+void toFP_Int64_ToFloat_driver(void)
+{
+  const SFloat sbv_result = toFP_Int64_ToFloat(0x000000000000002aLL);
+
+  printf("toFP_Int64_ToFloat(0x000000000000002aLL) = %a\n", sbv_result);
+}
+
+void toFP_Word8_ToFloat_driver(void)
+{
+  const SFloat sbv_result = toFP_Word8_ToFloat(42);
+
+  printf("toFP_Word8_ToFloat(42) = %a\n", sbv_result);
+}
+
+void toFP_Word16_ToFloat_driver(void)
+{
+  const SFloat sbv_result = toFP_Word16_ToFloat(0x002aU);
+
+  printf("toFP_Word16_ToFloat(0x002aU) = %a\n", sbv_result);
+}
+
+void toFP_Word32_ToFloat_driver(void)
+{
+  const SFloat sbv_result = toFP_Word32_ToFloat(0x0000002aUL);
+
+  printf("toFP_Word32_ToFloat(0x0000002aUL) = %a\n", sbv_result);
+}
+
+void toFP_Word64_ToFloat_driver(void)
+{
+  const SFloat sbv_result = toFP_Word64_ToFloat(0x000000000000002aULL);
+
+  printf("toFP_Word64_ToFloat(0x000000000000002aULL) = %a\n", sbv_result);
+}
+
+void toFP_Float_ToFloat_driver(void)
+{
+  const SFloat sbv_result = toFP_Float_ToFloat(0x1.5p5F /* 42.0F */);
+
+  printf("toFP_Float_ToFloat(0x1.5p5F /* 42.0F */) = %a\n", sbv_result);
+}
+
+void toFP_Double_ToFloat_driver(void)
+{
+  const SFloat sbv_result = toFP_Double_ToFloat(0x1.5p5 /* 42.0 */);
+
+  printf("toFP_Double_ToFloat(0x1.5p5 /* 42.0 */) = %a\n", sbv_result);
+}
+
+void toFP_Integer_ToFloat_driver(void)
+{
+  const SFloat sbv_result = toFP_Integer_ToFloat(0x000000000000002aLL);
+
+  printf("toFP_Integer_ToFloat(0x000000000000002aLL) = %a\n", sbv_result);
+}
+
+void toFP_Real_ToFloat_driver(void)
+{
+  const SFloat sbv_result = toFP_Real_ToFloat(42.0L);
+
+  printf("toFP_Real_ToFloat(42.0L) = %a\n", sbv_result);
+}
+
+void toFP_Int8_ToDouble_driver(void)
+{
+  const SDouble sbv_result = toFP_Int8_ToDouble(42);
+
+  printf("toFP_Int8_ToDouble(42) = %a\n", sbv_result);
+}
+
+void toFP_Int16_ToDouble_driver(void)
+{
+  const SDouble sbv_result = toFP_Int16_ToDouble(0x002a);
+
+  printf("toFP_Int16_ToDouble(0x002a) = %a\n", sbv_result);
+}
+
+void toFP_Int32_ToDouble_driver(void)
+{
+  const SDouble sbv_result = toFP_Int32_ToDouble(0x0000002aL);
+
+  printf("toFP_Int32_ToDouble(0x0000002aL) = %a\n", sbv_result);
+}
+
+void toFP_Int64_ToDouble_driver(void)
+{
+  const SDouble sbv_result = toFP_Int64_ToDouble(0x000000000000002aLL);
+
+  printf("toFP_Int64_ToDouble(0x000000000000002aLL) = %a\n", sbv_result);
+}
+
+void toFP_Word8_ToDouble_driver(void)
+{
+  const SDouble sbv_result = toFP_Word8_ToDouble(42);
+
+  printf("toFP_Word8_ToDouble(42) = %a\n", sbv_result);
+}
+
+void toFP_Word16_ToDouble_driver(void)
+{
+  const SDouble sbv_result = toFP_Word16_ToDouble(0x002aU);
+
+  printf("toFP_Word16_ToDouble(0x002aU) = %a\n", sbv_result);
+}
+
+void toFP_Word32_ToDouble_driver(void)
+{
+  const SDouble sbv_result = toFP_Word32_ToDouble(0x0000002aUL);
+
+  printf("toFP_Word32_ToDouble(0x0000002aUL) = %a\n", sbv_result);
+}
+
+void toFP_Word64_ToDouble_driver(void)
+{
+  const SDouble sbv_result = toFP_Word64_ToDouble(0x000000000000002aULL);
+
+  printf("toFP_Word64_ToDouble(0x000000000000002aULL) = %a\n", sbv_result);
+}
+
+void toFP_Float_ToDouble_driver(void)
+{
+  const SDouble sbv_result = toFP_Float_ToDouble(0x1.5p5F /* 42.0F */);
+
+  printf("toFP_Float_ToDouble(0x1.5p5F /* 42.0F */) = %a\n", sbv_result);
+}
+
+void toFP_Double_ToDouble_driver(void)
+{
+  const SDouble sbv_result = toFP_Double_ToDouble(0x1.5p5 /* 42.0 */);
+
+  printf("toFP_Double_ToDouble(0x1.5p5 /* 42.0 */) = %a\n", sbv_result);
+}
+
+void toFP_Integer_ToDouble_driver(void)
+{
+  const SDouble sbv_result = toFP_Integer_ToDouble(0x000000000000002aLL);
+
+  printf("toFP_Integer_ToDouble(0x000000000000002aLL) = %a\n", sbv_result);
+}
+
+void toFP_Real_ToDouble_driver(void)
+{
+  const SDouble sbv_result = toFP_Real_ToDouble(42.0L);
+
+  printf("toFP_Real_ToDouble(42.0L) = %a\n", sbv_result);
+}
+
+void fromFP_Float_ToInt8_driver(void)
+{
+  const SInt8 sbv_result = fromFP_Float_ToInt8(0x1.5p5F /* 42.0F */);
+
+  printf("fromFP_Float_ToInt8(0x1.5p5F /* 42.0F */) = %"PRId8"\n", sbv_result);
+}
+
+void fromFP_Float_ToInt16_driver(void)
+{
+  const SInt16 sbv_result = fromFP_Float_ToInt16(0x1.5p5F /* 42.0F */);
+
+  printf("fromFP_Float_ToInt16(0x1.5p5F /* 42.0F */) = %"PRId16"\n", sbv_result);
+}
+
+void fromFP_Float_ToInt32_driver(void)
+{
+  const SInt32 sbv_result = fromFP_Float_ToInt32(0x1.5p5F /* 42.0F */);
+
+  printf("fromFP_Float_ToInt32(0x1.5p5F /* 42.0F */) = %"PRId32"L\n", sbv_result);
+}
+
+void fromFP_Float_ToInt64_driver(void)
+{
+  const SInt64 sbv_result = fromFP_Float_ToInt64(0x1.5p5F /* 42.0F */);
+
+  printf("fromFP_Float_ToInt64(0x1.5p5F /* 42.0F */) = %"PRId64"LL\n", sbv_result);
+}
+
+void fromFP_Float_ToWord8_driver(void)
+{
+  const SWord8 sbv_result = fromFP_Float_ToWord8(0x1.5p5F /* 42.0F */);
+
+  printf("fromFP_Float_ToWord8(0x1.5p5F /* 42.0F */) = %"PRIu8"\n", sbv_result);
+}
+
+void fromFP_Float_ToWord16_driver(void)
+{
+  const SWord16 sbv_result = fromFP_Float_ToWord16(0x1.5p5F /* 42.0F */);
+
+  printf("fromFP_Float_ToWord16(0x1.5p5F /* 42.0F */) = 0x%04"PRIx16"U\n", sbv_result);
+}
+
+void fromFP_Float_ToWord32_driver(void)
+{
+  const SWord32 sbv_result = fromFP_Float_ToWord32(0x1.5p5F /* 42.0F */);
+
+  printf("fromFP_Float_ToWord32(0x1.5p5F /* 42.0F */) = 0x%08"PRIx32"UL\n", sbv_result);
+}
+
+void fromFP_Float_ToWord64_driver(void)
+{
+  const SWord64 sbv_result = fromFP_Float_ToWord64(0x1.5p5F /* 42.0F */);
+
+  printf("fromFP_Float_ToWord64(0x1.5p5F /* 42.0F */) = 0x%016"PRIx64"ULL\n", sbv_result);
+}
+
+void fromFP_Float_ToFloat_driver(void)
+{
+  const SFloat sbv_result = fromFP_Float_ToFloat(0x1.5p5F /* 42.0F */);
+
+  printf("fromFP_Float_ToFloat(0x1.5p5F /* 42.0F */) = %a\n", sbv_result);
+}
+
+void fromFP_Float_ToDouble_driver(void)
+{
+  const SDouble sbv_result = fromFP_Float_ToDouble(0x1.5p5F /* 42.0F */);
+
+  printf("fromFP_Float_ToDouble(0x1.5p5F /* 42.0F */) = %a\n", sbv_result);
+}
+
+void fromFP_Float_ToInteger_driver(void)
+{
+  const SInteger sbv_result = fromFP_Float_ToInteger(0x1.5p5F /* 42.0F */);
+
+  printf("fromFP_Float_ToInteger(0x1.5p5F /* 42.0F */) = %"PRId64"LL\n", sbv_result);
+}
+
+void fromFP_Float_ToReal_driver(void)
+{
+  const SReal sbv_result = fromFP_Float_ToReal(0x1.5p5F /* 42.0F */);
+
+  printf("fromFP_Float_ToReal(0x1.5p5F /* 42.0F */) = %Lf\n", sbv_result);
+}
+
+void fromFP_DoubleTo_Int8_driver(void)
+{
+  const SInt8 sbv_result = fromFP_DoubleTo_Int8(0x1.5p5 /* 42.0 */);
+
+  printf("fromFP_DoubleTo_Int8(0x1.5p5 /* 42.0 */) = %"PRId8"\n", sbv_result);
+}
+
+void fromFP_DoubleTo_Int16_driver(void)
+{
+  const SInt16 sbv_result = fromFP_DoubleTo_Int16(0x1.5p5 /* 42.0 */);
+
+  printf("fromFP_DoubleTo_Int16(0x1.5p5 /* 42.0 */) = %"PRId16"\n", sbv_result);
+}
+
+void fromFP_DoubleTo_Int32_driver(void)
+{
+  const SInt32 sbv_result = fromFP_DoubleTo_Int32(0x1.5p5 /* 42.0 */);
+
+  printf("fromFP_DoubleTo_Int32(0x1.5p5 /* 42.0 */) = %"PRId32"L\n", sbv_result);
+}
+
+void fromFP_DoubleTo_Int64_driver(void)
+{
+  const SInt64 sbv_result = fromFP_DoubleTo_Int64(0x1.5p5 /* 42.0 */);
+
+  printf("fromFP_DoubleTo_Int64(0x1.5p5 /* 42.0 */) = %"PRId64"LL\n", sbv_result);
+}
+
+void fromFP_DoubleTo_Word8_driver(void)
+{
+  const SWord8 sbv_result = fromFP_DoubleTo_Word8(0x1.5p5 /* 42.0 */);
+
+  printf("fromFP_DoubleTo_Word8(0x1.5p5 /* 42.0 */) = %"PRIu8"\n", sbv_result);
+}
+
+void fromFP_DoubleTo_Word16_driver(void)
+{
+  const SWord16 sbv_result = fromFP_DoubleTo_Word16(0x1.5p5 /* 42.0 */);
+
+  printf("fromFP_DoubleTo_Word16(0x1.5p5 /* 42.0 */) = 0x%04"PRIx16"U\n", sbv_result);
+}
+
+void fromFP_DoubleTo_Word32_driver(void)
+{
+  const SWord32 sbv_result = fromFP_DoubleTo_Word32(0x1.5p5 /* 42.0 */);
+
+  printf("fromFP_DoubleTo_Word32(0x1.5p5 /* 42.0 */) = 0x%08"PRIx32"UL\n", sbv_result);
+}
+
+void fromFP_DoubleTo_Word64_driver(void)
+{
+  const SWord64 sbv_result = fromFP_DoubleTo_Word64(0x1.5p5 /* 42.0 */);
+
+  printf("fromFP_DoubleTo_Word64(0x1.5p5 /* 42.0 */) = 0x%016"PRIx64"ULL\n", sbv_result);
+}
+
+void fromFP_DoubleTo_Float_driver(void)
+{
+  const SFloat sbv_result = fromFP_DoubleTo_Float(0x1.5p5 /* 42.0 */);
+
+  printf("fromFP_DoubleTo_Float(0x1.5p5 /* 42.0 */) = %a\n", sbv_result);
+}
+
+void fromFP_DoubleTo_Double_driver(void)
+{
+  const SDouble sbv_result = fromFP_DoubleTo_Double(0x1.5p5 /* 42.0 */);
+
+  printf("fromFP_DoubleTo_Double(0x1.5p5 /* 42.0 */) = %a\n", sbv_result);
+}
+
+void fromFP_DoubleTo_Integer_driver(void)
+{
+  const SInteger sbv_result = fromFP_DoubleTo_Integer(0x1.5p5 /* 42.0 */);
+
+  printf("fromFP_DoubleTo_Integer(0x1.5p5 /* 42.0 */) = %"PRId64"LL\n", sbv_result);
+}
+
+void fromFP_DoubleTo_Real_driver(void)
+{
+  const SReal sbv_result = fromFP_DoubleTo_Real(0x1.5p5 /* 42.0 */);
+
+  printf("fromFP_DoubleTo_Real(0x1.5p5 /* 42.0 */) = %Lf\n", sbv_result);
+}
+
+void fromFP_SWord32_SFloat_driver(void)
+{
+  const SFloat sbv_result = fromFP_SWord32_SFloat(0x0000002aUL);
+
+  printf("fromFP_SWord32_SFloat(0x0000002aUL) = %a\n", sbv_result);
+}
+
+void fromFP_SWord64_SDouble_driver(void)
+{
+  const SDouble sbv_result = fromFP_SWord64_SDouble(0x000000000000002aULL);
+
+  printf("fromFP_SWord64_SDouble(0x000000000000002aULL) = %a\n", sbv_result);
+}
+
+void fromFP_SFloat_SWord32_driver(void)
+{
+  const SWord32 sbv_result = fromFP_SFloat_SWord32(0x1.5p5F /* 42.0F */);
+
+  printf("fromFP_SFloat_SWord32(0x1.5p5F /* 42.0F */) = 0x%08"PRIx32"UL\n", sbv_result);
+}
+
+void fromFP_SDouble_SWord64_driver(void)
+{
+  const SWord64 sbv_result = fromFP_SDouble_SWord64(0x1.5p5 /* 42.0 */);
+
+  printf("fromFP_SDouble_SWord64(0x1.5p5 /* 42.0 */) = 0x%016"PRIx64"ULL\n", sbv_result);
+}
+
+void f_FP_Abs_driver(void)
+{
+  const SFloat sbv_result = f_FP_Abs(0x1.5p5F /* 42.0F */);
+
+  printf("f_FP_Abs(0x1.5p5F /* 42.0F */) = %a\n", sbv_result);
+}
+
+void d_FP_Abs_driver(void)
+{
+  const SDouble sbv_result = d_FP_Abs(0x1.5p5 /* 42.0 */);
+
+  printf("d_FP_Abs(0x1.5p5 /* 42.0 */) = %a\n", sbv_result);
+}
+
+void f_FP_Neg_driver(void)
+{
+  const SFloat sbv_result = f_FP_Neg(0x1.5p5F /* 42.0F */);
+
+  printf("f_FP_Neg(0x1.5p5F /* 42.0F */) = %a\n", sbv_result);
+}
+
+void d_FP_Neg_driver(void)
+{
+  const SDouble sbv_result = d_FP_Neg(0x1.5p5 /* 42.0 */);
+
+  printf("d_FP_Neg(0x1.5p5 /* 42.0 */) = %a\n", sbv_result);
+}
+
+void f_FP_Add_driver(void)
+{
+  const SFloat sbv_result = f_FP_Add(0x1.5p5F /* 42.0F */,
+                                     0x1.58p5F /* 43.0F */);
+
+  printf("f_FP_Add(0x1.5p5F /* 42.0F */, 0x1.58p5F /* 43.0F */) = %a\n", sbv_result);
+}
+
+void d_FP_Add_driver(void)
+{
+  const SDouble sbv_result = d_FP_Add(0x1.5p5 /* 42.0 */,
+                                      0x1.58p5 /* 43.0 */);
+
+  printf("d_FP_Add(0x1.5p5 /* 42.0 */, 0x1.58p5 /* 43.0 */) = %a\n", sbv_result);
+}
+
+void f_FP_Sub_driver(void)
+{
+  const SFloat sbv_result = f_FP_Sub(0x1.5p5F /* 42.0F */,
+                                     0x1.58p5F /* 43.0F */);
+
+  printf("f_FP_Sub(0x1.5p5F /* 42.0F */, 0x1.58p5F /* 43.0F */) = %a\n", sbv_result);
+}
+
+void d_FP_Sub_driver(void)
+{
+  const SDouble sbv_result = d_FP_Sub(0x1.5p5 /* 42.0 */,
+                                      0x1.58p5 /* 43.0 */);
+
+  printf("d_FP_Sub(0x1.5p5 /* 42.0 */, 0x1.58p5 /* 43.0 */) = %a\n", sbv_result);
+}
+
+void f_FP_Mul_driver(void)
+{
+  const SFloat sbv_result = f_FP_Mul(0x1.5p5F /* 42.0F */,
+                                     0x1.58p5F /* 43.0F */);
+
+  printf("f_FP_Mul(0x1.5p5F /* 42.0F */, 0x1.58p5F /* 43.0F */) = %a\n", sbv_result);
+}
+
+void d_FP_Mul_driver(void)
+{
+  const SDouble sbv_result = d_FP_Mul(0x1.5p5 /* 42.0 */,
+                                      0x1.58p5 /* 43.0 */);
+
+  printf("d_FP_Mul(0x1.5p5 /* 42.0 */, 0x1.58p5 /* 43.0 */) = %a\n", sbv_result);
+}
+
+void f_FP_Div_driver(void)
+{
+  const SFloat sbv_result = f_FP_Div(0x1.5p5F /* 42.0F */,
+                                     0x1.58p5F /* 43.0F */);
+
+  printf("f_FP_Div(0x1.5p5F /* 42.0F */, 0x1.58p5F /* 43.0F */) = %a\n", sbv_result);
+}
+
+void d_FP_Div_driver(void)
+{
+  const SDouble sbv_result = d_FP_Div(0x1.5p5 /* 42.0 */,
+                                      0x1.58p5 /* 43.0 */);
+
+  printf("d_FP_Div(0x1.5p5 /* 42.0 */, 0x1.58p5 /* 43.0 */) = %a\n", sbv_result);
+}
+
+void f_FP_FMA_driver(void)
+{
+  const SFloat sbv_result = f_FP_FMA(0x1.5p5F /* 42.0F */,
+                                     0x1.58p5F /* 43.0F */, 0x1.6p5F /* 44.0F */);
+
+  printf("f_FP_FMA(0x1.5p5F /* 42.0F */, 0x1.58p5F /* 43.0F */, 0x1.6p5F /* 44.0F */) = %a\n", sbv_result);
+}
+
+void d_FP_FMA_driver(void)
+{
+  const SDouble sbv_result = d_FP_FMA(0x1.5p5 /* 42.0 */,
+                                      0x1.58p5 /* 43.0 */, 0x1.6p5 /* 44.0 */);
+
+  printf("d_FP_FMA(0x1.5p5 /* 42.0 */, 0x1.58p5 /* 43.0 */, 0x1.6p5 /* 44.0 */) = %a\n", sbv_result);
+}
+
+void f_FP_Sqrt_driver(void)
+{
+  const SFloat sbv_result = f_FP_Sqrt(0x1.5p5F /* 42.0F */);
+
+  printf("f_FP_Sqrt(0x1.5p5F /* 42.0F */) = %a\n", sbv_result);
+}
+
+void d_FP_Sqrt_driver(void)
+{
+  const SDouble sbv_result = d_FP_Sqrt(0x1.5p5 /* 42.0 */);
+
+  printf("d_FP_Sqrt(0x1.5p5 /* 42.0 */) = %a\n", sbv_result);
+}
+
+void f_FP_Rem_driver(void)
+{
+  const SFloat sbv_result = f_FP_Rem(0x1.5p5F /* 42.0F */,
+                                     0x1.58p5F /* 43.0F */);
+
+  printf("f_FP_Rem(0x1.5p5F /* 42.0F */, 0x1.58p5F /* 43.0F */) = %a\n", sbv_result);
+}
+
+void d_FP_Rem_driver(void)
+{
+  const SDouble sbv_result = d_FP_Rem(0x1.5p5 /* 42.0 */,
+                                      0x1.58p5 /* 43.0 */);
+
+  printf("d_FP_Rem(0x1.5p5 /* 42.0 */, 0x1.58p5 /* 43.0 */) = %a\n", sbv_result);
+}
+
+void f_FP_RoundToIntegral_driver(void)
+{
+  const SFloat sbv_result = f_FP_RoundToIntegral(0x1.5p5F /* 42.0F */);
+
+  printf("f_FP_RoundToIntegral(0x1.5p5F /* 42.0F */) = %a\n", sbv_result);
+}
+
+void d_FP_RoundToIntegral_driver(void)
+{
+  const SDouble sbv_result = d_FP_RoundToIntegral(0x1.5p5 /* 42.0 */);
+
+  printf("d_FP_RoundToIntegral(0x1.5p5 /* 42.0 */) = %a\n", sbv_result);
+}
+
+void f_FP_Min_driver(void)
+{
+  const SFloat sbv_result = f_FP_Min(0x1.5p5F /* 42.0F */,
+                                     0x1.58p5F /* 43.0F */);
+
+  printf("f_FP_Min(0x1.5p5F /* 42.0F */, 0x1.58p5F /* 43.0F */) = %a\n", sbv_result);
+}
+
+void d_FP_Min_driver(void)
+{
+  const SDouble sbv_result = d_FP_Min(0x1.5p5 /* 42.0 */,
+                                      0x1.58p5 /* 43.0 */);
+
+  printf("d_FP_Min(0x1.5p5 /* 42.0 */, 0x1.58p5 /* 43.0 */) = %a\n", sbv_result);
+}
+
+void f_FP_Max_driver(void)
+{
+  const SFloat sbv_result = f_FP_Max(0x1.5p5F /* 42.0F */,
+                                     0x1.58p5F /* 43.0F */);
+
+  printf("f_FP_Max(0x1.5p5F /* 42.0F */, 0x1.58p5F /* 43.0F */) = %a\n", sbv_result);
+}
+
+void d_FP_Max_driver(void)
+{
+  const SDouble sbv_result = d_FP_Max(0x1.5p5 /* 42.0 */,
+                                      0x1.58p5 /* 43.0 */);
+
+  printf("d_FP_Max(0x1.5p5 /* 42.0 */, 0x1.58p5 /* 43.0 */) = %a\n", sbv_result);
+}
+
+void f_FP_IsEqualObject_driver(void)
+{
+  const SBool sbv_result = f_FP_IsEqualObject(0x1.5p5F /* 42.0F */,
+                                              0x1.58p5F /* 43.0F */);
+
+  printf("f_FP_IsEqualObject(0x1.5p5F /* 42.0F */, 0x1.58p5F /* 43.0F */) = %d\n", sbv_result);
+}
+
+void d_FP_IsEqualObject_driver(void)
+{
+  const SBool sbv_result = d_FP_IsEqualObject(0x1.5p5 /* 42.0 */,
+                                              0x1.58p5 /* 43.0 */);
+
+  printf("d_FP_IsEqualObject(0x1.5p5 /* 42.0 */, 0x1.58p5 /* 43.0 */) = %d\n", sbv_result);
+}
+
+void f_FP_IsNormal_driver(void)
+{
+  const SBool sbv_result = f_FP_IsNormal(0x1.5p5F /* 42.0F */);
+
+  printf("f_FP_IsNormal(0x1.5p5F /* 42.0F */) = %d\n", sbv_result);
+}
+
+void d_FP_IsNormal_driver(void)
+{
+  const SBool sbv_result = d_FP_IsNormal(0x1.5p5 /* 42.0 */);
+
+  printf("d_FP_IsNormal(0x1.5p5 /* 42.0 */) = %d\n", sbv_result);
+}
+
+void f_FP_IsZero_driver(void)
+{
+  const SBool sbv_result = f_FP_IsZero(0x1.5p5F /* 42.0F */);
+
+  printf("f_FP_IsZero(0x1.5p5F /* 42.0F */) = %d\n", sbv_result);
+}
+
+void d_FP_IsZero_driver(void)
+{
+  const SBool sbv_result = d_FP_IsZero(0x1.5p5 /* 42.0 */);
+
+  printf("d_FP_IsZero(0x1.5p5 /* 42.0 */) = %d\n", sbv_result);
+}
+
+void f_FP_IsSubnormal_driver(void)
+{
+  const SBool sbv_result = f_FP_IsSubnormal(0x1.5p5F /* 42.0F */);
+
+  printf("f_FP_IsSubnormal(0x1.5p5F /* 42.0F */) = %d\n", sbv_result);
+}
+
+void d_FP_IsSubnormal_driver(void)
+{
+  const SBool sbv_result = d_FP_IsSubnormal(0x1.5p5 /* 42.0 */);
+
+  printf("d_FP_IsSubnormal(0x1.5p5 /* 42.0 */) = %d\n", sbv_result);
+}
+
+void f_FP_IsInfinite_driver(void)
+{
+  const SBool sbv_result = f_FP_IsInfinite(0x1.5p5F /* 42.0F */);
+
+  printf("f_FP_IsInfinite(0x1.5p5F /* 42.0F */) = %d\n", sbv_result);
+}
+
+void d_FP_IsInfinite_driver(void)
+{
+  const SBool sbv_result = d_FP_IsInfinite(0x1.5p5 /* 42.0 */);
+
+  printf("d_FP_IsInfinite(0x1.5p5 /* 42.0 */) = %d\n", sbv_result);
+}
+
+void f_FP_IsNaN_driver(void)
+{
+  const SBool sbv_result = f_FP_IsNaN(0x1.5p5F /* 42.0F */);
+
+  printf("f_FP_IsNaN(0x1.5p5F /* 42.0F */) = %d\n", sbv_result);
+}
+
+void d_FP_IsNaN_driver(void)
+{
+  const SBool sbv_result = d_FP_IsNaN(0x1.5p5 /* 42.0 */);
+
+  printf("d_FP_IsNaN(0x1.5p5 /* 42.0 */) = %d\n", sbv_result);
+}
+
+void f_FP_IsNegative_driver(void)
+{
+  const SBool sbv_result = f_FP_IsNegative(0x1.5p5F /* 42.0F */);
+
+  printf("f_FP_IsNegative(0x1.5p5F /* 42.0F */) = %d\n", sbv_result);
+}
+
+void d_FP_IsNegative_driver(void)
+{
+  const SBool sbv_result = d_FP_IsNegative(0x1.5p5 /* 42.0 */);
+
+  printf("d_FP_IsNegative(0x1.5p5 /* 42.0 */) = %d\n", sbv_result);
+}
+
+void f_FP_IsPositive_driver(void)
+{
+  const SBool sbv_result = f_FP_IsPositive(0x1.5p5F /* 42.0F */);
+
+  printf("f_FP_IsPositive(0x1.5p5F /* 42.0F */) = %d\n", sbv_result);
+}
+
+void d_FP_IsPositive_driver(void)
+{
+  const SBool sbv_result = d_FP_IsPositive(0x1.5p5 /* 42.0 */);
+
+  printf("d_FP_IsPositive(0x1.5p5 /* 42.0 */) = %d\n", sbv_result);
+}
+
+int main(void)
+{
+  printf("====================================\n");
+  printf("** Driver run for toFP_Int8_ToFloat:\n");
+  printf("====================================\n");
+  toFP_Int8_ToFloat_driver();
+
+  printf("=====================================\n");
+  printf("** Driver run for toFP_Int16_ToFloat:\n");
+  printf("=====================================\n");
+  toFP_Int16_ToFloat_driver();
+
+  printf("=====================================\n");
+  printf("** Driver run for toFP_Int32_ToFloat:\n");
+  printf("=====================================\n");
+  toFP_Int32_ToFloat_driver();
+
+  printf("=====================================\n");
+  printf("** Driver run for toFP_Int64_ToFloat:\n");
+  printf("=====================================\n");
+  toFP_Int64_ToFloat_driver();
+
+  printf("=====================================\n");
+  printf("** Driver run for toFP_Word8_ToFloat:\n");
+  printf("=====================================\n");
+  toFP_Word8_ToFloat_driver();
+
+  printf("======================================\n");
+  printf("** Driver run for toFP_Word16_ToFloat:\n");
+  printf("======================================\n");
+  toFP_Word16_ToFloat_driver();
+
+  printf("======================================\n");
+  printf("** Driver run for toFP_Word32_ToFloat:\n");
+  printf("======================================\n");
+  toFP_Word32_ToFloat_driver();
+
+  printf("======================================\n");
+  printf("** Driver run for toFP_Word64_ToFloat:\n");
+  printf("======================================\n");
+  toFP_Word64_ToFloat_driver();
+
+  printf("=====================================\n");
+  printf("** Driver run for toFP_Float_ToFloat:\n");
+  printf("=====================================\n");
+  toFP_Float_ToFloat_driver();
+
+  printf("======================================\n");
+  printf("** Driver run for toFP_Double_ToFloat:\n");
+  printf("======================================\n");
+  toFP_Double_ToFloat_driver();
+
+  printf("=======================================\n");
+  printf("** Driver run for toFP_Integer_ToFloat:\n");
+  printf("=======================================\n");
+  toFP_Integer_ToFloat_driver();
+
+  printf("====================================\n");
+  printf("** Driver run for toFP_Real_ToFloat:\n");
+  printf("====================================\n");
+  toFP_Real_ToFloat_driver();
+
+  printf("=====================================\n");
+  printf("** Driver run for toFP_Int8_ToDouble:\n");
+  printf("=====================================\n");
+  toFP_Int8_ToDouble_driver();
+
+  printf("======================================\n");
+  printf("** Driver run for toFP_Int16_ToDouble:\n");
+  printf("======================================\n");
+  toFP_Int16_ToDouble_driver();
+
+  printf("======================================\n");
+  printf("** Driver run for toFP_Int32_ToDouble:\n");
+  printf("======================================\n");
+  toFP_Int32_ToDouble_driver();
+
+  printf("======================================\n");
+  printf("** Driver run for toFP_Int64_ToDouble:\n");
+  printf("======================================\n");
+  toFP_Int64_ToDouble_driver();
+
+  printf("======================================\n");
+  printf("** Driver run for toFP_Word8_ToDouble:\n");
+  printf("======================================\n");
+  toFP_Word8_ToDouble_driver();
+
+  printf("=======================================\n");
+  printf("** Driver run for toFP_Word16_ToDouble:\n");
+  printf("=======================================\n");
+  toFP_Word16_ToDouble_driver();
+
+  printf("=======================================\n");
+  printf("** Driver run for toFP_Word32_ToDouble:\n");
+  printf("=======================================\n");
+  toFP_Word32_ToDouble_driver();
+
+  printf("=======================================\n");
+  printf("** Driver run for toFP_Word64_ToDouble:\n");
+  printf("=======================================\n");
+  toFP_Word64_ToDouble_driver();
+
+  printf("======================================\n");
+  printf("** Driver run for toFP_Float_ToDouble:\n");
+  printf("======================================\n");
+  toFP_Float_ToDouble_driver();
+
+  printf("=======================================\n");
+  printf("** Driver run for toFP_Double_ToDouble:\n");
+  printf("=======================================\n");
+  toFP_Double_ToDouble_driver();
+
+  printf("========================================\n");
+  printf("** Driver run for toFP_Integer_ToDouble:\n");
+  printf("========================================\n");
+  toFP_Integer_ToDouble_driver();
+
+  printf("=====================================\n");
+  printf("** Driver run for toFP_Real_ToDouble:\n");
+  printf("=====================================\n");
+  toFP_Real_ToDouble_driver();
+
+  printf("======================================\n");
+  printf("** Driver run for fromFP_Float_ToInt8:\n");
+  printf("======================================\n");
+  fromFP_Float_ToInt8_driver();
+
+  printf("=======================================\n");
+  printf("** Driver run for fromFP_Float_ToInt16:\n");
+  printf("=======================================\n");
+  fromFP_Float_ToInt16_driver();
+
+  printf("=======================================\n");
+  printf("** Driver run for fromFP_Float_ToInt32:\n");
+  printf("=======================================\n");
+  fromFP_Float_ToInt32_driver();
+
+  printf("=======================================\n");
+  printf("** Driver run for fromFP_Float_ToInt64:\n");
+  printf("=======================================\n");
+  fromFP_Float_ToInt64_driver();
+
+  printf("=======================================\n");
+  printf("** Driver run for fromFP_Float_ToWord8:\n");
+  printf("=======================================\n");
+  fromFP_Float_ToWord8_driver();
+
+  printf("========================================\n");
+  printf("** Driver run for fromFP_Float_ToWord16:\n");
+  printf("========================================\n");
+  fromFP_Float_ToWord16_driver();
+
+  printf("========================================\n");
+  printf("** Driver run for fromFP_Float_ToWord32:\n");
+  printf("========================================\n");
+  fromFP_Float_ToWord32_driver();
+
+  printf("========================================\n");
+  printf("** Driver run for fromFP_Float_ToWord64:\n");
+  printf("========================================\n");
+  fromFP_Float_ToWord64_driver();
+
+  printf("=======================================\n");
+  printf("** Driver run for fromFP_Float_ToFloat:\n");
+  printf("=======================================\n");
+  fromFP_Float_ToFloat_driver();
+
+  printf("========================================\n");
+  printf("** Driver run for fromFP_Float_ToDouble:\n");
+  printf("========================================\n");
+  fromFP_Float_ToDouble_driver();
+
+  printf("=========================================\n");
+  printf("** Driver run for fromFP_Float_ToInteger:\n");
+  printf("=========================================\n");
+  fromFP_Float_ToInteger_driver();
+
+  printf("======================================\n");
+  printf("** Driver run for fromFP_Float_ToReal:\n");
+  printf("======================================\n");
+  fromFP_Float_ToReal_driver();
+
+  printf("=======================================\n");
+  printf("** Driver run for fromFP_DoubleTo_Int8:\n");
+  printf("=======================================\n");
+  fromFP_DoubleTo_Int8_driver();
+
+  printf("========================================\n");
+  printf("** Driver run for fromFP_DoubleTo_Int16:\n");
+  printf("========================================\n");
+  fromFP_DoubleTo_Int16_driver();
+
+  printf("========================================\n");
+  printf("** Driver run for fromFP_DoubleTo_Int32:\n");
+  printf("========================================\n");
+  fromFP_DoubleTo_Int32_driver();
+
+  printf("========================================\n");
+  printf("** Driver run for fromFP_DoubleTo_Int64:\n");
+  printf("========================================\n");
+  fromFP_DoubleTo_Int64_driver();
+
+  printf("========================================\n");
+  printf("** Driver run for fromFP_DoubleTo_Word8:\n");
+  printf("========================================\n");
+  fromFP_DoubleTo_Word8_driver();
+
+  printf("=========================================\n");
+  printf("** Driver run for fromFP_DoubleTo_Word16:\n");
+  printf("=========================================\n");
+  fromFP_DoubleTo_Word16_driver();
+
+  printf("=========================================\n");
+  printf("** Driver run for fromFP_DoubleTo_Word32:\n");
+  printf("=========================================\n");
+  fromFP_DoubleTo_Word32_driver();
+
+  printf("=========================================\n");
+  printf("** Driver run for fromFP_DoubleTo_Word64:\n");
+  printf("=========================================\n");
+  fromFP_DoubleTo_Word64_driver();
+
+  printf("========================================\n");
+  printf("** Driver run for fromFP_DoubleTo_Float:\n");
+  printf("========================================\n");
+  fromFP_DoubleTo_Float_driver();
+
+  printf("=========================================\n");
+  printf("** Driver run for fromFP_DoubleTo_Double:\n");
+  printf("=========================================\n");
+  fromFP_DoubleTo_Double_driver();
+
+  printf("==========================================\n");
+  printf("** Driver run for fromFP_DoubleTo_Integer:\n");
+  printf("==========================================\n");
+  fromFP_DoubleTo_Integer_driver();
+
+  printf("=======================================\n");
+  printf("** Driver run for fromFP_DoubleTo_Real:\n");
+  printf("=======================================\n");
+  fromFP_DoubleTo_Real_driver();
+
+  printf("========================================\n");
+  printf("** Driver run for fromFP_SWord32_SFloat:\n");
+  printf("========================================\n");
+  fromFP_SWord32_SFloat_driver();
+
+  printf("=========================================\n");
+  printf("** Driver run for fromFP_SWord64_SDouble:\n");
+  printf("=========================================\n");
+  fromFP_SWord64_SDouble_driver();
+
+  printf("========================================\n");
+  printf("** Driver run for fromFP_SFloat_SWord32:\n");
+  printf("========================================\n");
+  fromFP_SFloat_SWord32_driver();
+
+  printf("=========================================\n");
+  printf("** Driver run for fromFP_SDouble_SWord64:\n");
+  printf("=========================================\n");
+  fromFP_SDouble_SWord64_driver();
+
+  printf("===========================\n");
+  printf("** Driver run for f_FP_Abs:\n");
+  printf("===========================\n");
+  f_FP_Abs_driver();
+
+  printf("===========================\n");
+  printf("** Driver run for d_FP_Abs:\n");
+  printf("===========================\n");
+  d_FP_Abs_driver();
+
+  printf("===========================\n");
+  printf("** Driver run for f_FP_Neg:\n");
+  printf("===========================\n");
+  f_FP_Neg_driver();
+
+  printf("===========================\n");
+  printf("** Driver run for d_FP_Neg:\n");
+  printf("===========================\n");
+  d_FP_Neg_driver();
+
+  printf("===========================\n");
+  printf("** Driver run for f_FP_Add:\n");
+  printf("===========================\n");
+  f_FP_Add_driver();
+
+  printf("===========================\n");
+  printf("** Driver run for d_FP_Add:\n");
+  printf("===========================\n");
+  d_FP_Add_driver();
+
+  printf("===========================\n");
+  printf("** Driver run for f_FP_Sub:\n");
+  printf("===========================\n");
+  f_FP_Sub_driver();
+
+  printf("===========================\n");
+  printf("** Driver run for d_FP_Sub:\n");
+  printf("===========================\n");
+  d_FP_Sub_driver();
+
+  printf("===========================\n");
+  printf("** Driver run for f_FP_Mul:\n");
+  printf("===========================\n");
+  f_FP_Mul_driver();
+
+  printf("===========================\n");
+  printf("** Driver run for d_FP_Mul:\n");
+  printf("===========================\n");
+  d_FP_Mul_driver();
+
+  printf("===========================\n");
+  printf("** Driver run for f_FP_Div:\n");
+  printf("===========================\n");
+  f_FP_Div_driver();
+
+  printf("===========================\n");
+  printf("** Driver run for d_FP_Div:\n");
+  printf("===========================\n");
+  d_FP_Div_driver();
+
+  printf("===========================\n");
+  printf("** Driver run for f_FP_FMA:\n");
+  printf("===========================\n");
+  f_FP_FMA_driver();
+
+  printf("===========================\n");
+  printf("** Driver run for d_FP_FMA:\n");
+  printf("===========================\n");
+  d_FP_FMA_driver();
+
+  printf("============================\n");
+  printf("** Driver run for f_FP_Sqrt:\n");
+  printf("============================\n");
+  f_FP_Sqrt_driver();
+
+  printf("============================\n");
+  printf("** Driver run for d_FP_Sqrt:\n");
+  printf("============================\n");
+  d_FP_Sqrt_driver();
+
+  printf("===========================\n");
+  printf("** Driver run for f_FP_Rem:\n");
+  printf("===========================\n");
+  f_FP_Rem_driver();
+
+  printf("===========================\n");
+  printf("** Driver run for d_FP_Rem:\n");
+  printf("===========================\n");
+  d_FP_Rem_driver();
+
+  printf("=======================================\n");
+  printf("** Driver run for f_FP_RoundToIntegral:\n");
+  printf("=======================================\n");
+  f_FP_RoundToIntegral_driver();
+
+  printf("=======================================\n");
+  printf("** Driver run for d_FP_RoundToIntegral:\n");
+  printf("=======================================\n");
+  d_FP_RoundToIntegral_driver();
+
+  printf("===========================\n");
+  printf("** Driver run for f_FP_Min:\n");
+  printf("===========================\n");
+  f_FP_Min_driver();
+
+  printf("===========================\n");
+  printf("** Driver run for d_FP_Min:\n");
+  printf("===========================\n");
+  d_FP_Min_driver();
+
+  printf("===========================\n");
+  printf("** Driver run for f_FP_Max:\n");
+  printf("===========================\n");
+  f_FP_Max_driver();
+
+  printf("===========================\n");
+  printf("** Driver run for d_FP_Max:\n");
+  printf("===========================\n");
+  d_FP_Max_driver();
+
+  printf("=====================================\n");
+  printf("** Driver run for f_FP_IsEqualObject:\n");
+  printf("=====================================\n");
+  f_FP_IsEqualObject_driver();
+
+  printf("=====================================\n");
+  printf("** Driver run for d_FP_IsEqualObject:\n");
+  printf("=====================================\n");
+  d_FP_IsEqualObject_driver();
+
+  printf("================================\n");
+  printf("** Driver run for f_FP_IsNormal:\n");
+  printf("================================\n");
+  f_FP_IsNormal_driver();
+
+  printf("================================\n");
+  printf("** Driver run for d_FP_IsNormal:\n");
+  printf("================================\n");
+  d_FP_IsNormal_driver();
+
+  printf("==============================\n");
+  printf("** Driver run for f_FP_IsZero:\n");
+  printf("==============================\n");
+  f_FP_IsZero_driver();
+
+  printf("==============================\n");
+  printf("** Driver run for d_FP_IsZero:\n");
+  printf("==============================\n");
+  d_FP_IsZero_driver();
+
+  printf("===================================\n");
+  printf("** Driver run for f_FP_IsSubnormal:\n");
+  printf("===================================\n");
+  f_FP_IsSubnormal_driver();
+
+  printf("===================================\n");
+  printf("** Driver run for d_FP_IsSubnormal:\n");
+  printf("===================================\n");
+  d_FP_IsSubnormal_driver();
+
+  printf("==================================\n");
+  printf("** Driver run for f_FP_IsInfinite:\n");
+  printf("==================================\n");
+  f_FP_IsInfinite_driver();
+
+  printf("==================================\n");
+  printf("** Driver run for d_FP_IsInfinite:\n");
+  printf("==================================\n");
+  d_FP_IsInfinite_driver();
+
+  printf("=============================\n");
+  printf("** Driver run for f_FP_IsNaN:\n");
+  printf("=============================\n");
+  f_FP_IsNaN_driver();
+
+  printf("=============================\n");
+  printf("** Driver run for d_FP_IsNaN:\n");
+  printf("=============================\n");
+  d_FP_IsNaN_driver();
+
+  printf("==================================\n");
+  printf("** Driver run for f_FP_IsNegative:\n");
+  printf("==================================\n");
+  f_FP_IsNegative_driver();
+
+  printf("==================================\n");
+  printf("** Driver run for d_FP_IsNegative:\n");
+  printf("==================================\n");
+  d_FP_IsNegative_driver();
+
+  printf("==================================\n");
+  printf("** Driver run for f_FP_IsPositive:\n");
+  printf("==================================\n");
+  f_FP_IsPositive_driver();
+
+  printf("==================================\n");
+  printf("** Driver run for d_FP_IsPositive:\n");
+  printf("==================================\n");
+  d_FP_IsPositive_driver();
+
+  return 0;
+}
+== END: "floatCodeGen_driver.c" ==================
+== BEGIN: "Makefile" ================
+# Makefile for floatCodeGen. 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
+SBV_LIBS?=-lm -lbf
+AR?=ar
+ARFLAGS?=cr
+
+all: floatCodeGen.a floatCodeGen_driver
+
+floatCodeGen.a: toFP_Int8_ToFloat.o toFP_Int16_ToFloat.o toFP_Int32_ToFloat.o toFP_Int64_ToFloat.o toFP_Word8_ToFloat.o toFP_Word16_ToFloat.o toFP_Word32_ToFloat.o toFP_Word64_ToFloat.o toFP_Float_ToFloat.o toFP_Double_ToFloat.o toFP_Integer_ToFloat.o toFP_Real_ToFloat.o toFP_Int8_ToDouble.o toFP_Int16_ToDouble.o toFP_Int32_ToDouble.o toFP_Int64_ToDouble.o toFP_Word8_ToDouble.o toFP_Word16_ToDouble.o toFP_Word32_ToDouble.o toFP_Word64_ToDouble.o toFP_Float_ToDouble.o toFP_Double_ToDouble.o toFP_Integer_ToDouble.o toFP_Real_ToDouble.o fromFP_Float_ToInt8.o fromFP_Float_ToInt16.o fromFP_Float_ToInt32.o fromFP_Float_ToInt64.o fromFP_Float_ToWord8.o fromFP_Float_ToWord16.o fromFP_Float_ToWord32.o fromFP_Float_ToWord64.o fromFP_Float_ToFloat.o fromFP_Float_ToDouble.o fromFP_Float_ToInteger.o fromFP_Float_ToReal.o fromFP_DoubleTo_Int8.o fromFP_DoubleTo_Int16.o fromFP_DoubleTo_Int32.o fromFP_DoubleTo_Int64.o fromFP_DoubleTo_Word8.o fromFP_DoubleTo_Word16.o fromFP_DoubleTo_Word32.o fromFP_DoubleTo_Word64.o fromFP_DoubleTo_Float.o fromFP_DoubleTo_Double.o fromFP_DoubleTo_Integer.o fromFP_DoubleTo_Real.o fromFP_SWord32_SFloat.o fromFP_SWord64_SDouble.o fromFP_SFloat_SWord32.o fromFP_SDouble_SWord64.o f_FP_Abs.o d_FP_Abs.o f_FP_Neg.o d_FP_Neg.o f_FP_Add.o d_FP_Add.o f_FP_Sub.o d_FP_Sub.o f_FP_Mul.o d_FP_Mul.o f_FP_Div.o d_FP_Div.o f_FP_FMA.o d_FP_FMA.o f_FP_Sqrt.o d_FP_Sqrt.o f_FP_Rem.o d_FP_Rem.o f_FP_RoundToIntegral.o d_FP_RoundToIntegral.o f_FP_Min.o d_FP_Min.o f_FP_Max.o d_FP_Max.o f_FP_IsEqualObject.o d_FP_IsEqualObject.o f_FP_IsNormal.o d_FP_IsNormal.o f_FP_IsZero.o d_FP_IsZero.o f_FP_IsSubnormal.o d_FP_IsSubnormal.o f_FP_IsInfinite.o d_FP_IsInfinite.o f_FP_IsNaN.o d_FP_IsNaN.o f_FP_IsNegative.o d_FP_IsNegative.o f_FP_IsPositive.o d_FP_IsPositive.o
+	rm -f $@.tmp
+	${AR} ${ARFLAGS} $@.tmp $^
+	mv -f $@.tmp $@
+
+floatCodeGen_driver: floatCodeGen_driver.c floatCodeGen.h floatCodeGen.a
+	${CC} ${CCFLAGS} -ffp-contract=off $< -o $@ floatCodeGen.a ${LDFLAGS} ${SBV_LIBS}
+
+toFP_Int8_ToFloat.o: toFP_Int8_ToFloat.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+toFP_Int16_ToFloat.o: toFP_Int16_ToFloat.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+toFP_Int32_ToFloat.o: toFP_Int32_ToFloat.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+toFP_Int64_ToFloat.o: toFP_Int64_ToFloat.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+toFP_Word8_ToFloat.o: toFP_Word8_ToFloat.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+toFP_Word16_ToFloat.o: toFP_Word16_ToFloat.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+toFP_Word32_ToFloat.o: toFP_Word32_ToFloat.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+toFP_Word64_ToFloat.o: toFP_Word64_ToFloat.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+toFP_Float_ToFloat.o: toFP_Float_ToFloat.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+toFP_Double_ToFloat.o: toFP_Double_ToFloat.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+toFP_Integer_ToFloat.o: toFP_Integer_ToFloat.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+toFP_Real_ToFloat.o: toFP_Real_ToFloat.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+toFP_Int8_ToDouble.o: toFP_Int8_ToDouble.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+toFP_Int16_ToDouble.o: toFP_Int16_ToDouble.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+toFP_Int32_ToDouble.o: toFP_Int32_ToDouble.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+toFP_Int64_ToDouble.o: toFP_Int64_ToDouble.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+toFP_Word8_ToDouble.o: toFP_Word8_ToDouble.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+toFP_Word16_ToDouble.o: toFP_Word16_ToDouble.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+toFP_Word32_ToDouble.o: toFP_Word32_ToDouble.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+toFP_Word64_ToDouble.o: toFP_Word64_ToDouble.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+toFP_Float_ToDouble.o: toFP_Float_ToDouble.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+toFP_Double_ToDouble.o: toFP_Double_ToDouble.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+toFP_Integer_ToDouble.o: toFP_Integer_ToDouble.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+toFP_Real_ToDouble.o: toFP_Real_ToDouble.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+fromFP_Float_ToInt8.o: fromFP_Float_ToInt8.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+fromFP_Float_ToInt16.o: fromFP_Float_ToInt16.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+fromFP_Float_ToInt32.o: fromFP_Float_ToInt32.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+fromFP_Float_ToInt64.o: fromFP_Float_ToInt64.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+fromFP_Float_ToWord8.o: fromFP_Float_ToWord8.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+fromFP_Float_ToWord16.o: fromFP_Float_ToWord16.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+fromFP_Float_ToWord32.o: fromFP_Float_ToWord32.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+fromFP_Float_ToWord64.o: fromFP_Float_ToWord64.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+fromFP_Float_ToFloat.o: fromFP_Float_ToFloat.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+fromFP_Float_ToDouble.o: fromFP_Float_ToDouble.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+fromFP_Float_ToInteger.o: fromFP_Float_ToInteger.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+fromFP_Float_ToReal.o: fromFP_Float_ToReal.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+fromFP_DoubleTo_Int8.o: fromFP_DoubleTo_Int8.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+fromFP_DoubleTo_Int16.o: fromFP_DoubleTo_Int16.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+fromFP_DoubleTo_Int32.o: fromFP_DoubleTo_Int32.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+fromFP_DoubleTo_Int64.o: fromFP_DoubleTo_Int64.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+fromFP_DoubleTo_Word8.o: fromFP_DoubleTo_Word8.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+fromFP_DoubleTo_Word16.o: fromFP_DoubleTo_Word16.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+fromFP_DoubleTo_Word32.o: fromFP_DoubleTo_Word32.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+fromFP_DoubleTo_Word64.o: fromFP_DoubleTo_Word64.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+fromFP_DoubleTo_Float.o: fromFP_DoubleTo_Float.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+fromFP_DoubleTo_Double.o: fromFP_DoubleTo_Double.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+fromFP_DoubleTo_Integer.o: fromFP_DoubleTo_Integer.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+fromFP_DoubleTo_Real.o: fromFP_DoubleTo_Real.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+fromFP_SWord32_SFloat.o: fromFP_SWord32_SFloat.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+fromFP_SWord64_SDouble.o: fromFP_SWord64_SDouble.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+fromFP_SFloat_SWord32.o: fromFP_SFloat_SWord32.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+fromFP_SDouble_SWord64.o: fromFP_SDouble_SWord64.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+f_FP_Abs.o: f_FP_Abs.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+d_FP_Abs.o: d_FP_Abs.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+f_FP_Neg.o: f_FP_Neg.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+d_FP_Neg.o: d_FP_Neg.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+f_FP_Add.o: f_FP_Add.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+d_FP_Add.o: d_FP_Add.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+f_FP_Sub.o: f_FP_Sub.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+d_FP_Sub.o: d_FP_Sub.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+f_FP_Mul.o: f_FP_Mul.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+d_FP_Mul.o: d_FP_Mul.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+f_FP_Div.o: f_FP_Div.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+d_FP_Div.o: d_FP_Div.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+f_FP_FMA.o: f_FP_FMA.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+d_FP_FMA.o: d_FP_FMA.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+f_FP_Sqrt.o: f_FP_Sqrt.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+d_FP_Sqrt.o: d_FP_Sqrt.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+f_FP_Rem.o: f_FP_Rem.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+d_FP_Rem.o: d_FP_Rem.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+f_FP_RoundToIntegral.o: f_FP_RoundToIntegral.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+d_FP_RoundToIntegral.o: d_FP_RoundToIntegral.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+f_FP_Min.o: f_FP_Min.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+d_FP_Min.o: d_FP_Min.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+f_FP_Max.o: f_FP_Max.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+d_FP_Max.o: d_FP_Max.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+f_FP_IsEqualObject.o: f_FP_IsEqualObject.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+d_FP_IsEqualObject.o: d_FP_IsEqualObject.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+f_FP_IsNormal.o: f_FP_IsNormal.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+d_FP_IsNormal.o: d_FP_IsNormal.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+f_FP_IsZero.o: f_FP_IsZero.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+d_FP_IsZero.o: d_FP_IsZero.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+f_FP_IsSubnormal.o: f_FP_IsSubnormal.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+d_FP_IsSubnormal.o: d_FP_IsSubnormal.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+f_FP_IsInfinite.o: f_FP_IsInfinite.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+d_FP_IsInfinite.o: d_FP_IsInfinite.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+f_FP_IsNaN.o: f_FP_IsNaN.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+d_FP_IsNaN.o: d_FP_IsNaN.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+f_FP_IsNegative.o: f_FP_IsNegative.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+d_FP_IsNegative.o: d_FP_IsNegative.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+f_FP_IsPositive.o: f_FP_IsPositive.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+d_FP_IsPositive.o: d_FP_IsPositive.c floatCodeGen.h
+	${CC} ${CCFLAGS} -ffp-contract=off -c $< -o $@
+
+clean:
+	rm -f *.o
+
+veryclean: clean
+	rm -f floatCodeGen.a floatCodeGen_driver floatCodeGen.a.tmp
 == END: "Makefile" ==================
diff --git a/SBVTestSuite/GoldFiles/freshVars.gold b/SBVTestSuite/GoldFiles/freshVars.gold
--- a/SBVTestSuite/GoldFiles/freshVars.gold
+++ b/SBVTestSuite/GoldFiles/freshVars.gold
@@ -8,7 +8,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
@@ -37,10 +36,15 @@
 [GOOD] (declare-fun s13 () (_ FloatingPoint 11 53))
 [GOOD] (declare-fun s14 () Real)
 [GOOD] (declare-fun s15 () Int)
-[GOOD] (declare-datatypes ((BinOp 0)) (((Plus) (Minus) (Times))))
-[GOOD] (define-fun BinOp_constrIndex ((x BinOp)) Int
-          (ite (= x Plus) 0 (ite (= x Minus) 1 2))
-       )
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] ; User defined ADT: BinOp
+[GOOD] (declare-datatype BinOp (
+           (Plus)
+           (Minus)
+           (Times)
+       ))
 [GOOD] (declare-fun s16 () BinOp)
 [GOOD] (declare-fun s17 () (_ FloatingPoint 15 113))
 [GOOD] (declare-fun s18 () (_ FloatingPoint 15 113))
@@ -69,10 +73,10 @@
 [GOOD] (define-fun s33 () (_ BitVec 64) #x0000000000000008)
 [GOOD] (define-fun s34 () Bool (= s11 s33))
 [GOOD] (assert s34)
-[GOOD] (define-fun s35 () (_ FloatingPoint  8 24) ((_ to_fp 8 24) roundNearestTiesToEven (/ 9.0 1.0)))
+[GOOD] (define-fun s35 () (_ FloatingPoint  8 24) (fp #b0 #b10000010 #b00100000000000000000000))
 [GOOD] (define-fun s36 () Bool (fp.eq s12 s35))
 [GOOD] (assert s36)
-[GOOD] (define-fun s37 () (_ FloatingPoint 11 53) ((_ to_fp 11 53) roundNearestTiesToEven (/ 10.0 1.0)))
+[GOOD] (define-fun s37 () (_ FloatingPoint 11 53) (fp #b0 #b10000000010 #b0100000000000000000000000000000000000000000000000000))
 [GOOD] (define-fun s38 () Bool (fp.eq s13 s37))
 [GOOD] (assert s38)
 [GOOD] (define-fun s39 () Real (/ 11.0 1.0))
@@ -81,7 +85,7 @@
 [GOOD] (define-fun s41 () Int 12)
 [GOOD] (define-fun s42 () Bool (= s15 s41))
 [GOOD] (assert s42)
-[GOOD] (define-fun s43 () BinOp Plus)
+[GOOD] (define-fun s43 () BinOp (as Plus BinOp))
 [GOOD] (define-fun s44 () Bool (= s16 s43))
 [GOOD] (assert s44)
 [GOOD] (define-fun s45 () Bool (fp.eq s17 s18))
@@ -99,49 +103,46 @@
 [GOOD] (define-fun s54 () Bool (= s52 s53))
 [GOOD] (assert s54)
 [GOOD] (declare-fun s55 () Int)
-[GOOD] (define-fun s57 () Int 96)
-[GOOD] (define-fun s56 () (Array Int Int) (lambda ((l1_s0 Int))
-         42))
-[GOOD] (define-fun s58 () Int (select s56 s57))
-[GOOD] (define-fun s59 () Bool (= s55 s58))
+[GOOD] (define-fun s56 () Int 42)
+[GOOD] (define-fun s57 () Bool (= s55 s56))
+[GOOD] (assert s57)
+[GOOD] (define-fun s58 () Int 1)
+[GOOD] (define-fun s59 () Bool (= s50 s58))
 [GOOD] (assert s59)
-[GOOD] (define-fun s60 () Int 1)
-[GOOD] (define-fun s61 () Bool (= s50 s60))
-[GOOD] (assert s61)
-[GOOD] (define-fun s62 () Bool (not s51))
-[GOOD] (assert s62)
-[GOOD] (declare-fun s63 () String)
+[GOOD] (define-fun s60 () Bool (not s51))
+[GOOD] (assert s60)
+[GOOD] (declare-fun s61 () String)
 [GOOD] (set-option :pp.max_depth      4294967295)
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
-[GOOD] (declare-fun s64 () (Seq Int))
+[GOOD] (declare-fun s62 () (Seq Int))
 [GOOD] (set-option :pp.max_depth      4294967295)
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
-[GOOD] (declare-fun s65 () (Seq (Seq Int)))
+[GOOD] (declare-fun s63 () (Seq (Seq Int)))
 [GOOD] (set-option :pp.max_depth      4294967295)
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
-[GOOD] (declare-fun s66 () (Seq (_ BitVec 8)))
+[GOOD] (declare-fun s64 () (Seq (_ BitVec 8)))
 [GOOD] (set-option :pp.max_depth      4294967295)
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
-[GOOD] (declare-fun s67 () (Seq (Seq (_ BitVec 16))))
-[GOOD] (define-fun s68 () String "hello")
-[GOOD] (define-fun s69 () Bool (= s63 s68))
+[GOOD] (declare-fun s65 () (Seq (Seq (_ BitVec 16))))
+[GOOD] (define-fun s66 () String "hello")
+[GOOD] (define-fun s67 () Bool (= s61 s66))
+[GOOD] (assert s67)
+[GOOD] (define-fun s68 () (Seq Int) (seq.++ (seq.unit 1) (seq.unit 2) (seq.unit 3) (seq.unit 4)))
+[GOOD] (define-fun s69 () Bool (= s62 s68))
 [GOOD] (assert s69)
-[GOOD] (define-fun s70 () (Seq Int) (seq.++ (seq.unit 1) (seq.unit 2) (seq.unit 3) (seq.unit 4)))
-[GOOD] (define-fun s71 () Bool (= s64 s70))
+[GOOD] (define-fun s70 () (Seq (Seq Int)) (seq.++ (seq.unit (seq.++ (seq.unit 1) (seq.unit 2) (seq.unit 3))) (seq.unit (seq.++ (seq.unit 4) (seq.unit 5) (seq.unit 6) (seq.unit 7)))))
+[GOOD] (define-fun s71 () Bool (= s63 s70))
 [GOOD] (assert s71)
-[GOOD] (define-fun s72 () (Seq (Seq Int)) (seq.++ (seq.unit (seq.++ (seq.unit 1) (seq.unit 2) (seq.unit 3))) (seq.unit (seq.++ (seq.unit 4) (seq.unit 5) (seq.unit 6) (seq.unit 7)))))
-[GOOD] (define-fun s73 () Bool (= s65 s72))
+[GOOD] (define-fun s72 () (Seq (_ BitVec 8)) (seq.++ (seq.unit #x01) (seq.unit #x02)))
+[GOOD] (define-fun s73 () Bool (= s64 s72))
 [GOOD] (assert s73)
-[GOOD] (define-fun s74 () (Seq (_ BitVec 8)) (seq.++ (seq.unit #x01) (seq.unit #x02)))
-[GOOD] (define-fun s75 () Bool (= s66 s74))
+[GOOD] (define-fun s74 () (Seq (Seq (_ BitVec 16))) (seq.++ (seq.unit (seq.++ (seq.unit #x0001) (seq.unit #x0002) (seq.unit #x0003))) (seq.unit (as seq.empty (Seq (_ BitVec 16)))) (seq.unit (seq.++ (seq.unit #x0004) (seq.unit #x0005) (seq.unit #x0006)))))
+[GOOD] (define-fun s75 () Bool (= s65 s74))
 [GOOD] (assert s75)
-[GOOD] (define-fun s76 () (Seq (Seq (_ BitVec 16))) (seq.++ (seq.unit (seq.++ (seq.unit #x0001) (seq.unit #x0002) (seq.unit #x0003))) (seq.unit (as seq.empty (Seq (_ BitVec 16)))) (seq.unit (seq.++ (seq.unit #x0004) (seq.unit #x0005) (seq.unit #x0006)))))
-[GOOD] (define-fun s77 () Bool (= s67 s76))
-[GOOD] (assert s77)
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
@@ -187,17 +188,17 @@
 [RECV] ((s51 false))
 [SEND] (get-value (s55))
 [RECV] ((s55 42))
+[SEND] (get-value (s61))
+[RECV] ((s61 "hello"))
+[SEND] (get-value (s62))
+[RECV] ((s62 (seq.++ (seq.unit 1) (seq.unit 2) (seq.unit 3) (seq.unit 4))))
 [SEND] (get-value (s63))
-[RECV] ((s63 "hello"))
+[RECV] ((s63 (seq.++ (seq.unit (seq.++ (seq.unit 1) (seq.unit 2) (seq.unit 3)))
+               (seq.unit (seq.++ (seq.unit 4) (seq.unit 5) (seq.unit 6) (seq.unit 7))))))
 [SEND] (get-value (s64))
-[RECV] ((s64 (seq.++ (seq.unit 1) (seq.unit 2) (seq.unit 3) (seq.unit 4))))
+[RECV] ((s64 (seq.++ (seq.unit #x01) (seq.unit #x02))))
 [SEND] (get-value (s65))
-[RECV] ((s65 (seq.++ (seq.unit (seq.++ (seq.unit 1) (seq.unit 2) (seq.unit 3)))
-               (seq.unit (seq.++ (seq.unit 4) (seq.unit 5) (seq.unit 6) (seq.unit 7))))))
-[SEND] (get-value (s66))
-[RECV] ((s66 (seq.++ (seq.unit #x01) (seq.unit #x02))))
-[SEND] (get-value (s67))
-[RECV] ((s67 (seq.++ (seq.unit (seq.++ (seq.unit #x0001) (seq.unit #x0002) (seq.unit #x0003)))
+[RECV] ((s65 (seq.++ (seq.unit (seq.++ (seq.unit #x0001) (seq.unit #x0002) (seq.unit #x0003)))
                (seq.unit (as seq.empty (Seq (_ BitVec 16))))
                (seq.unit (seq.++ (seq.unit #x0004) (seq.unit #x0005) (seq.unit #x0006))))))
 [SEND] (get-value (s17))
diff --git a/SBVTestSuite/GoldFiles/gcd.gold b/SBVTestSuite/GoldFiles/gcd.gold
--- a/SBVTestSuite/GoldFiles/gcd.gold
+++ b/SBVTestSuite/GoldFiles/gcd.gold
@@ -12,11 +12,11 @@
 sgcd.o: sgcd.c sgcd.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
-sgcd_driver.o: sgcd_driver.c
+sgcd_driver.o: sgcd_driver.c sgcd.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
 sgcd_driver: sgcd.o sgcd_driver.o
-	${CC} ${CCFLAGS} $^ -o $@
+	${CC} ${CCFLAGS} $^ -o $@ ${LDFLAGS}
 
 clean:
 	rm -f *.o
@@ -27,9 +27,10 @@
 == BEGIN: "sgcd.h" ================
 /* Header file for sgcd. Automatically generated by SBV. Do not edit! */
 
-#ifndef __sgcd__HEADER_INCLUDED__
-#define __sgcd__HEADER_INCLUDED__
+#ifndef SBV_GENERATED_sgcd_HEADER_INCLUDED
+#define SBV_GENERATED_sgcd_HEADER_INCLUDED
 
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <inttypes.h>
@@ -38,6 +39,13 @@
 #include <string.h>
 #include <math.h>
 
+/* Floating-point calling convention:
+ * Enter generated code in FE_TONEAREST (round-to-nearest, ties-to-even).
+ * Callbacks must preserve this mode before returning or re-entering.
+ * Generated code does not check or change the hardware rounding mode.
+ * Custom builds must disable implicit FP contraction, including at LTO link time.
+ */
+
 /* The boolean type */
 typedef bool SBool;
 
@@ -62,7 +70,7 @@
 /* Entry point prototype: */
 SWord8 sgcd(const SWord8 x, const SWord8 y);
 
-#endif /* __sgcd__HEADER_INCLUDED__ */
+#endif /* SBV_GENERATED_sgcd_HEADER_INCLUDED */
 == END: "sgcd.h" ==================
 == BEGIN: "sgcd_driver.c" ================
 /* Example driver program for sgcd. */
@@ -73,9 +81,9 @@
 
 int main(void)
 {
-  const SWord8 __result = sgcd(55, 154);
+  const SWord8 sbv_result = sgcd(55, 154);
 
-  printf("sgcd(55, 154) = %"PRIu8"\n", __result);
+  printf("sgcd(55, 154) = %"PRIu8"\n", sbv_result);
 
   return 0;
 }
@@ -85,42 +93,58 @@
 
 #include "sgcd.h"
 
-SWord8 sgcd(const SWord8 x, const SWord8 y)
+/* Exact bit-vector runtime. All arithmetic is modulo the declared width. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_u8_rem(SWord8 a, SWord8 b)
 {
-  const SWord8 s0 = x;
-  const SWord8 s1 = y;
+  if (b == (SWord8) 0) return a;
+  return (SWord8) (a % b);
+}
+
+
+SWord8 sgcd(const SWord8 sbv_input_0, const SWord8 sbv_input_1)
+{
+  const SWord8 s0 = sbv_input_0;
+  const SWord8 s1 = sbv_input_1;
   const SBool  s3 = s1 == 0;
-  const SWord8 s4 = (s1 == 0) ? s0 : (s0 % s1);
+  const SWord8 s4 = sbv_bv_u8_rem(s0, s1);
   const SWord8 s5 = s3 ? s0 : s4;
   const SBool  s6 = 0 == s5;
-  const SWord8 s7 = (s5 == 0) ? s1 : (s1 % s5);
+  const SWord8 s7 = sbv_bv_u8_rem(s1, s5);
   const SWord8 s8 = s6 ? s1 : s7;
   const SBool  s9 = 0 == s8;
-  const SWord8 s10 = (s8 == 0) ? s5 : (s5 % s8);
+  const SWord8 s10 = sbv_bv_u8_rem(s5, s8);
   const SWord8 s11 = s9 ? s5 : s10;
   const SBool  s12 = 0 == s11;
-  const SWord8 s13 = (s11 == 0) ? s8 : (s8 % s11);
+  const SWord8 s13 = sbv_bv_u8_rem(s8, s11);
   const SWord8 s14 = s12 ? s8 : s13;
   const SBool  s15 = 0 == s14;
-  const SWord8 s16 = (s14 == 0) ? s11 : (s11 % s14);
+  const SWord8 s16 = sbv_bv_u8_rem(s11, s14);
   const SWord8 s17 = s15 ? s11 : s16;
   const SBool  s18 = 0 == s17;
-  const SWord8 s19 = (s17 == 0) ? s14 : (s14 % s17);
+  const SWord8 s19 = sbv_bv_u8_rem(s14, s17);
   const SWord8 s20 = s18 ? s14 : s19;
   const SBool  s21 = 0 == s20;
-  const SWord8 s22 = (s20 == 0) ? s17 : (s17 % s20);
+  const SWord8 s22 = sbv_bv_u8_rem(s17, s20);
   const SWord8 s23 = s21 ? s17 : s22;
   const SBool  s24 = 0 == s23;
-  const SWord8 s25 = (s23 == 0) ? s20 : (s20 % s23);
+  const SWord8 s25 = sbv_bv_u8_rem(s20, s23);
   const SWord8 s26 = s24 ? s20 : s25;
   const SBool  s27 = 0 == s26;
-  const SWord8 s28 = (s26 == 0) ? s23 : (s23 % s26);
+  const SWord8 s28 = sbv_bv_u8_rem(s23, s26);
   const SWord8 s29 = s27 ? s23 : s28;
   const SBool  s30 = 0 == s29;
-  const SWord8 s31 = (s29 == 0) ? s26 : (s26 % s29);
+  const SWord8 s31 = sbv_bv_u8_rem(s26, s29);
   const SWord8 s32 = s30 ? s26 : s31;
   const SBool  s33 = 0 == s32;
-  const SWord8 s34 = (s32 == 0) ? s29 : (s29 % s32);
+  const SWord8 s34 = sbv_bv_u8_rem(s29, s32);
   const SWord8 s35 = s33 ? s29 : s34;
   const SBool  s36 = 0 == s35;
   const SWord8 s37 = s36 ? s32 : s35;
diff --git a/SBVTestSuite/GoldFiles/genBenchMark1.gold b/SBVTestSuite/GoldFiles/genBenchMark1.gold
--- a/SBVTestSuite/GoldFiles/genBenchMark1.gold
+++ b/SBVTestSuite/GoldFiles/genBenchMark1.gold
@@ -2,7 +2,6 @@
 (set-option :diagnostic-output-channel "stdout")
 (set-option :produce-models true)
 (set-logic QF_BV)
-; --- uninterpreted sorts ---
 ; --- tuples ---
 ; --- sums ---
 ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/genBenchMark2.gold b/SBVTestSuite/GoldFiles/genBenchMark2.gold
--- a/SBVTestSuite/GoldFiles/genBenchMark2.gold
+++ b/SBVTestSuite/GoldFiles/genBenchMark2.gold
@@ -2,7 +2,6 @@
 (set-option :diagnostic-output-channel "stdout")
 (set-option :produce-models true)
 (set-logic QF_BV)
-; --- uninterpreted sorts ---
 ; --- tuples ---
 ; --- sums ---
 ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda04.gold b/SBVTestSuite/GoldFiles/lambda04.gold
--- a/SBVTestSuite/GoldFiles/lambda04.gold
+++ b/SBVTestSuite/GoldFiles/lambda04.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.map @(SBV Integer -> SBV Bool)_96a983e094 @(SBV [Integer] -> SBV [Bool])
+[MEASURE] Checking: sbv.map @(SBV Integer -> SBV Bool)_96a983e094 @(SBV [Integer] -> SBV [Bool])
+[MEASURE] sbv.map @(SBV Integer -> SBV Bool)_96a983e094 @(SBV [Integer] -> SBV [Bool]): barified = "|sbv.map @(SBV Integer -> SBV Bool)_96a983e094 @(SBV [Integer] -> SBV [Bool])|"
+[MEASURE] sbv.map @(SBV Integer -> SBV Bool)_96a983e094 @(SBV [Integer] -> SBV [Bool]): Uninterpreted ops in DAG: [("|sbv.map @(SBV Integer -> SBV Bool)_96a983e094 @(SBV [Integer] -> SBV [Bool])|",1)]
+[MEASURE] sbv.map @(SBV Integer -> SBV Bool)_96a983e094 @(SBV [Integer] -> SBV [Bool]): recursive calls found = 1
+[MEASURE] sbv.map @(SBV Integer -> SBV Bool)_96a983e094 @(SBV [Integer] -> SBV [Bool]): trying length arg1
+[MEASURE] replayDAG {sbv.map @(SBV Integer -> SBV Bool)_96a983e094 @(SBV [Integer] -> SBV [Bool])}: replaying 8 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,10 +16,95 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq Bool) (as seq.empty (Seq Bool)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s9 () (Seq Bool)) ; tracks user variable "__internal_sbv_s9"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () (Seq Bool) (seq.unit false))
+[GOOD] (define-fun s7 () Int (- s4 s2))
+[GOOD] (define-fun s8 () (Seq Int) (seq.extract s0 s2 s7))
+[GOOD] (define-fun s10 () (Seq Bool) (seq.++ s6 s9))
+[GOOD] (define-fun s11 () (Seq Bool) (ite s5 s3 s10))
+[GOOD] (define-fun s12 () Bool (>= s4 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.map @(SBV Integer -> SBV Bool)_96a983e094 @(SBV [Integer] -> SBV [Bool])}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq Bool) (as seq.empty (Seq Bool)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s9 () (Seq Bool)) ; tracks user variable "__internal_sbv_s9"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () (Seq Bool) (seq.unit false))
+[GOOD] (define-fun s7 () Int (- s4 s2))
+[GOOD] (define-fun s8 () (Seq Int) (seq.extract s0 s2 s7))
+[GOOD] (define-fun s10 () (Seq Bool) (seq.++ s6 s9))
+[GOOD] (define-fun s11 () (Seq Bool) (ite s5 s3 s10))
+[GOOD] (define-fun s12 () Int (seq.len s8))
+[GOOD] (define-fun s13 () Bool (not s5))
+[GOOD] (define-fun s14 () Bool (> s4 s12))
+[GOOD] (define-fun s15 () Bool (=> s13 s14))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s15))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.map @(SBV Integer -> SBV Bool)_96a983e094 @(SBV [Integer] -> SBV [Bool]): length arg1 -> OK
+[MEASURE] Passed (terminating): sbv.map @(SBV Integer -> SBV Bool)_96a983e094 @(SBV [Integer] -> SBV [Bool])
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
 [GOOD] (define-fun s2 () (Seq Int) (seq.++ (seq.unit 1) (seq.unit 2) (seq.unit 3)))
 [GOOD] ; --- top level inputs ---
 [GOOD] (declare-fun s0 () (Seq Int))
@@ -25,10 +117,10 @@
 [GOOD] (define-fun-rec |sbv.map @(SBV Integer -> SBV Bool)_96a983e094 @(SBV [Integer] -> SBV [Bool])| ((l1_s0 (Seq Int))) (Seq Bool)
                                  (let ((l1_s2 0))
                                  (let ((l1_s4 (as seq.empty (Seq Bool))))
-                                 (let ((l1_s5 (seq.unit false)))
                                  (let ((l1_s6 1))
                                  (let ((l1_s1 (seq.len l1_s0)))
                                  (let ((l1_s3 (= l1_s1 l1_s2)))
+                                 (let ((l1_s5 (seq.unit false)))
                                  (let ((l1_s7 (- l1_s1 l1_s6)))
                                  (let ((l1_s8 (seq.extract l1_s0 l1_s6 l1_s7)))
                                  (let ((l1_s9 (|sbv.map @(SBV Integer -> SBV Bool)_96a983e094 @(SBV [Integer] -> SBV [Bool])| l1_s8)))
diff --git a/SBVTestSuite/GoldFiles/lambda05.gold b/SBVTestSuite/GoldFiles/lambda05.gold
--- a/SBVTestSuite/GoldFiles/lambda05.gold
+++ b/SBVTestSuite/GoldFiles/lambda05.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.map @(SBV Integer -> SBV Integer)_6e8bf9627c @(SBV [Integer] -> SBV [Integer]), sbv.map @(SBV Integer -> SBV Integer)_aaa4562f59 @(SBV [Integer] -> SBV [Integer])
+[MEASURE] Checking: sbv.map @(SBV Integer -> SBV Integer)_6e8bf9627c @(SBV [Integer] -> SBV [Integer])
+[MEASURE] sbv.map @(SBV Integer -> SBV Integer)_6e8bf9627c @(SBV [Integer] -> SBV [Integer]): barified = "|sbv.map @(SBV Integer -> SBV Integer)_6e8bf9627c @(SBV [Integer] -> SBV [Integer])|"
+[MEASURE] sbv.map @(SBV Integer -> SBV Integer)_6e8bf9627c @(SBV [Integer] -> SBV [Integer]): Uninterpreted ops in DAG: [("|sbv.map @(SBV Integer -> SBV Integer)_6e8bf9627c @(SBV [Integer] -> SBV [Integer])|",1)]
+[MEASURE] sbv.map @(SBV Integer -> SBV Integer)_6e8bf9627c @(SBV [Integer] -> SBV [Integer]): recursive calls found = 1
+[MEASURE] sbv.map @(SBV Integer -> SBV Integer)_6e8bf9627c @(SBV [Integer] -> SBV [Integer]): trying length arg1
+[MEASURE] replayDAG {sbv.map @(SBV Integer -> SBV Integer)_6e8bf9627c @(SBV [Integer] -> SBV [Integer])}: replaying 10 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +16,194 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] (define-fun s4 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s12 () (Seq Int)) ; tracks user variable "__internal_sbv_s12"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s5 () Int (seq.len s0))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () Int (seq.nth s0 s1))
+[GOOD] (define-fun s8 () Int (+ s3 s7))
+[GOOD] (define-fun s9 () (Seq Int) (seq.unit s8))
+[GOOD] (define-fun s10 () Int (- s5 s2))
+[GOOD] (define-fun s11 () (Seq Int) (seq.extract s0 s2 s10))
+[GOOD] (define-fun s13 () (Seq Int) (seq.++ s9 s12))
+[GOOD] (define-fun s14 () (Seq Int) (ite s6 s4 s13))
+[GOOD] (define-fun s15 () Bool (>= s5 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s15))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.map @(SBV Integer -> SBV Integer)_6e8bf9627c @(SBV [Integer] -> SBV [Integer])}: replaying 10 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] (define-fun s4 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s12 () (Seq Int)) ; tracks user variable "__internal_sbv_s12"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s5 () Int (seq.len s0))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () Int (seq.nth s0 s1))
+[GOOD] (define-fun s8 () Int (+ s3 s7))
+[GOOD] (define-fun s9 () (Seq Int) (seq.unit s8))
+[GOOD] (define-fun s10 () Int (- s5 s2))
+[GOOD] (define-fun s11 () (Seq Int) (seq.extract s0 s2 s10))
+[GOOD] (define-fun s13 () (Seq Int) (seq.++ s9 s12))
+[GOOD] (define-fun s14 () (Seq Int) (ite s6 s4 s13))
+[GOOD] (define-fun s15 () Int (seq.len s11))
+[GOOD] (define-fun s16 () Bool (not s6))
+[GOOD] (define-fun s17 () Bool (> s5 s15))
+[GOOD] (define-fun s18 () Bool (=> s16 s17))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s18))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.map @(SBV Integer -> SBV Integer)_6e8bf9627c @(SBV [Integer] -> SBV [Integer]): length arg1 -> OK
+[MEASURE] Passed (terminating): sbv.map @(SBV Integer -> SBV Integer)_6e8bf9627c @(SBV [Integer] -> SBV [Integer])
+[MEASURE] Checking: sbv.map @(SBV Integer -> SBV Integer)_aaa4562f59 @(SBV [Integer] -> SBV [Integer])
+[MEASURE] sbv.map @(SBV Integer -> SBV Integer)_aaa4562f59 @(SBV [Integer] -> SBV [Integer]): barified = "|sbv.map @(SBV Integer -> SBV Integer)_aaa4562f59 @(SBV [Integer] -> SBV [Integer])|"
+[MEASURE] sbv.map @(SBV Integer -> SBV Integer)_aaa4562f59 @(SBV [Integer] -> SBV [Integer]): Uninterpreted ops in DAG: [("|sbv.map @(SBV Integer -> SBV Integer)_aaa4562f59 @(SBV [Integer] -> SBV [Integer])|",1)]
+[MEASURE] sbv.map @(SBV Integer -> SBV Integer)_aaa4562f59 @(SBV [Integer] -> SBV [Integer]): recursive calls found = 1
+[MEASURE] sbv.map @(SBV Integer -> SBV Integer)_aaa4562f59 @(SBV [Integer] -> SBV [Integer]): trying length arg1
+[MEASURE] replayDAG {sbv.map @(SBV Integer -> SBV Integer)_aaa4562f59 @(SBV [Integer] -> SBV [Integer])}: replaying 10 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () (Seq Int)) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (seq.nth s0 s1))
+[GOOD] (define-fun s7 () Int (+ s2 s6))
+[GOOD] (define-fun s8 () (Seq Int) (seq.unit s7))
+[GOOD] (define-fun s9 () Int (- s4 s2))
+[GOOD] (define-fun s10 () (Seq Int) (seq.extract s0 s2 s9))
+[GOOD] (define-fun s12 () (Seq Int) (seq.++ s8 s11))
+[GOOD] (define-fun s13 () (Seq Int) (ite s5 s3 s12))
+[GOOD] (define-fun s14 () Bool (>= s4 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.map @(SBV Integer -> SBV Integer)_aaa4562f59 @(SBV [Integer] -> SBV [Integer])}: replaying 10 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () (Seq Int)) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (seq.nth s0 s1))
+[GOOD] (define-fun s7 () Int (+ s2 s6))
+[GOOD] (define-fun s8 () (Seq Int) (seq.unit s7))
+[GOOD] (define-fun s9 () Int (- s4 s2))
+[GOOD] (define-fun s10 () (Seq Int) (seq.extract s0 s2 s9))
+[GOOD] (define-fun s12 () (Seq Int) (seq.++ s8 s11))
+[GOOD] (define-fun s13 () (Seq Int) (ite s5 s3 s12))
+[GOOD] (define-fun s14 () Int (seq.len s10))
+[GOOD] (define-fun s15 () Bool (not s5))
+[GOOD] (define-fun s16 () Bool (> s4 s14))
+[GOOD] (define-fun s17 () Bool (=> s15 s16))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.map @(SBV Integer -> SBV Integer)_aaa4562f59 @(SBV [Integer] -> SBV [Integer]): length arg1 -> OK
+[MEASURE] Passed (terminating): sbv.map @(SBV Integer -> SBV Integer)_aaa4562f59 @(SBV [Integer] -> SBV [Integer])
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda06.gold b/SBVTestSuite/GoldFiles/lambda06.gold
--- a/SBVTestSuite/GoldFiles/lambda06.gold
+++ b/SBVTestSuite/GoldFiles/lambda06.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.map @(SBV Integer -> SBV Integer)_b01b78a2e9 @(SBV [Integer] -> SBV [Integer])
+[MEASURE] Checking: sbv.map @(SBV Integer -> SBV Integer)_b01b78a2e9 @(SBV [Integer] -> SBV [Integer])
+[MEASURE] sbv.map @(SBV Integer -> SBV Integer)_b01b78a2e9 @(SBV [Integer] -> SBV [Integer]): barified = "|sbv.map @(SBV Integer -> SBV Integer)_b01b78a2e9 @(SBV [Integer] -> SBV [Integer])|"
+[MEASURE] sbv.map @(SBV Integer -> SBV Integer)_b01b78a2e9 @(SBV [Integer] -> SBV [Integer]): Uninterpreted ops in DAG: [("|sbv.map @(SBV Integer -> SBV Integer)_b01b78a2e9 @(SBV [Integer] -> SBV [Integer])|",1)]
+[MEASURE] sbv.map @(SBV Integer -> SBV Integer)_b01b78a2e9 @(SBV [Integer] -> SBV [Integer]): recursive calls found = 1
+[MEASURE] sbv.map @(SBV Integer -> SBV Integer)_b01b78a2e9 @(SBV [Integer] -> SBV [Integer]): trying length arg1
+[MEASURE] replayDAG {sbv.map @(SBV Integer -> SBV Integer)_b01b78a2e9 @(SBV [Integer] -> SBV [Integer])}: replaying 27 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +16,130 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s28 () (Seq Int)) ; tracks user variable "__internal_sbv_s28"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (seq.nth s0 s1))
+[GOOD] (define-fun s7 () Int (* s6 s6))
+[GOOD] (define-fun s8 () Int (+ s6 s7))
+[GOOD] (define-fun s9 () Int (* s6 s7))
+[GOOD] (define-fun s10 () Int (+ s8 s9))
+[GOOD] (define-fun s11 () Int (* s7 s7))
+[GOOD] (define-fun s12 () Int (+ s10 s11))
+[GOOD] (define-fun s13 () Int (* s6 s11))
+[GOOD] (define-fun s14 () Int (+ s12 s13))
+[GOOD] (define-fun s15 () Int (* s7 s11))
+[GOOD] (define-fun s16 () Int (+ s14 s15))
+[GOOD] (define-fun s17 () Int (* s6 s15))
+[GOOD] (define-fun s18 () Int (+ s16 s17))
+[GOOD] (define-fun s19 () Int (* s11 s11))
+[GOOD] (define-fun s20 () Int (+ s18 s19))
+[GOOD] (define-fun s21 () Int (* s6 s19))
+[GOOD] (define-fun s22 () Int (+ s20 s21))
+[GOOD] (define-fun s23 () Int (* s7 s19))
+[GOOD] (define-fun s24 () Int (+ s22 s23))
+[GOOD] (define-fun s25 () (Seq Int) (seq.unit s24))
+[GOOD] (define-fun s26 () Int (- s4 s2))
+[GOOD] (define-fun s27 () (Seq Int) (seq.extract s0 s2 s26))
+[GOOD] (define-fun s29 () (Seq Int) (seq.++ s25 s28))
+[GOOD] (define-fun s30 () (Seq Int) (ite s5 s3 s29))
+[GOOD] (define-fun s31 () Bool (>= s4 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s31))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.map @(SBV Integer -> SBV Integer)_b01b78a2e9 @(SBV [Integer] -> SBV [Integer])}: replaying 27 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s28 () (Seq Int)) ; tracks user variable "__internal_sbv_s28"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (seq.nth s0 s1))
+[GOOD] (define-fun s7 () Int (* s6 s6))
+[GOOD] (define-fun s8 () Int (+ s6 s7))
+[GOOD] (define-fun s9 () Int (* s6 s7))
+[GOOD] (define-fun s10 () Int (+ s8 s9))
+[GOOD] (define-fun s11 () Int (* s7 s7))
+[GOOD] (define-fun s12 () Int (+ s10 s11))
+[GOOD] (define-fun s13 () Int (* s6 s11))
+[GOOD] (define-fun s14 () Int (+ s12 s13))
+[GOOD] (define-fun s15 () Int (* s7 s11))
+[GOOD] (define-fun s16 () Int (+ s14 s15))
+[GOOD] (define-fun s17 () Int (* s6 s15))
+[GOOD] (define-fun s18 () Int (+ s16 s17))
+[GOOD] (define-fun s19 () Int (* s11 s11))
+[GOOD] (define-fun s20 () Int (+ s18 s19))
+[GOOD] (define-fun s21 () Int (* s6 s19))
+[GOOD] (define-fun s22 () Int (+ s20 s21))
+[GOOD] (define-fun s23 () Int (* s7 s19))
+[GOOD] (define-fun s24 () Int (+ s22 s23))
+[GOOD] (define-fun s25 () (Seq Int) (seq.unit s24))
+[GOOD] (define-fun s26 () Int (- s4 s2))
+[GOOD] (define-fun s27 () (Seq Int) (seq.extract s0 s2 s26))
+[GOOD] (define-fun s29 () (Seq Int) (seq.++ s25 s28))
+[GOOD] (define-fun s30 () (Seq Int) (ite s5 s3 s29))
+[GOOD] (define-fun s31 () Int (seq.len s27))
+[GOOD] (define-fun s32 () Bool (not s5))
+[GOOD] (define-fun s33 () Bool (> s4 s31))
+[GOOD] (define-fun s34 () Bool (=> s32 s33))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s34))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.map @(SBV Integer -> SBV Integer)_b01b78a2e9 @(SBV [Integer] -> SBV [Integer]): length arg1 -> OK
+[MEASURE] Passed (terminating): sbv.map @(SBV Integer -> SBV Integer)_b01b78a2e9 @(SBV [Integer] -> SBV [Integer])
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda07.gold b/SBVTestSuite/GoldFiles/lambda07.gold
--- a/SBVTestSuite/GoldFiles/lambda07.gold
+++ b/SBVTestSuite/GoldFiles/lambda07.gold
@@ -1,3 +1,13 @@
+[MEASURE] Verifying termination measures for: sbv.map @(SBV [Integer] -> SBV Integer)_1b9bf3f573 @(SBV [[Integer]] -> SBV [Integer]), sbv.map @(SBV [Integer] -> SBV Integer)_1b9bf3f573 @(SBV [[Integer]] -> SBV [Integer]), sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_b97075844e @(SBV (Integer,[Integer]) -> SBV Integer), sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)
+[MEASURE] Checking: sbv.map @(SBV [Integer] -> SBV Integer)_1b9bf3f573 @(SBV [[Integer]] -> SBV [Integer])
+[MEASURE] sbv.map @(SBV [Integer] -> SBV Integer)_1b9bf3f573 @(SBV [[Integer]] -> SBV [Integer]): not in a multi-member cycle, skipping mutual check
+[MEASURE] Passed (terminating): sbv.map @(SBV [Integer] -> SBV Integer)_1b9bf3f573 @(SBV [[Integer]] -> SBV [Integer])
+[MEASURE] Checking: sbv.map @(SBV [Integer] -> SBV Integer)_1b9bf3f573 @(SBV [[Integer]] -> SBV [Integer])
+[MEASURE] sbv.map @(SBV [Integer] -> SBV Integer)_1b9bf3f573 @(SBV [[Integer]] -> SBV [Integer]): barified = "|sbv.map @(SBV [Integer] -> SBV Integer)_1b9bf3f573 @(SBV [[Integer]] -> SBV [Integer])|"
+[MEASURE] sbv.map @(SBV [Integer] -> SBV Integer)_1b9bf3f573 @(SBV [[Integer]] -> SBV [Integer]): Uninterpreted ops in DAG: [("|sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)|",1),("|sbv.map @(SBV [Integer] -> SBV Integer)_1b9bf3f573 @(SBV [[Integer]] -> SBV [Integer])|",1)]
+[MEASURE] sbv.map @(SBV [Integer] -> SBV Integer)_1b9bf3f573 @(SBV [[Integer]] -> SBV [Integer]): recursive calls found = 1
+[MEASURE] sbv.map @(SBV [Integer] -> SBV Integer)_1b9bf3f573 @(SBV [[Integer]] -> SBV [Integer]): trying length arg1
+[MEASURE] replayDAG {sbv.map @(SBV [Integer] -> SBV Integer)_1b9bf3f573 @(SBV [[Integer]] -> SBV [Integer])}: replaying 11 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +19,322 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] (declare-fun s12 () (Seq Int)) ; tracks user variable "__internal_sbv_s12"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () (Seq Int) (seq.nth s0 s1))
+[GOOD] (define-fun s7 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s1 s6))
+[GOOD] (define-fun s9 () (Seq Int) (seq.unit s8))
+[GOOD] (define-fun s10 () Int (- s4 s2))
+[GOOD] (define-fun s11 () (Seq (Seq Int)) (seq.extract s0 s2 s10))
+[GOOD] (define-fun s13 () (Seq Int) (seq.++ s9 s12))
+[GOOD] (define-fun s14 () (Seq Int) (ite s5 s3 s13))
+[GOOD] (define-fun s15 () Bool (>= s4 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s15))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.map @(SBV [Integer] -> SBV Integer)_1b9bf3f573 @(SBV [[Integer]] -> SBV [Integer])}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] (declare-fun s12 () (Seq Int)) ; tracks user variable "__internal_sbv_s12"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () (Seq Int) (seq.nth s0 s1))
+[GOOD] (define-fun s7 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s1 s6))
+[GOOD] (define-fun s9 () (Seq Int) (seq.unit s8))
+[GOOD] (define-fun s10 () Int (- s4 s2))
+[GOOD] (define-fun s11 () (Seq (Seq Int)) (seq.extract s0 s2 s10))
+[GOOD] (define-fun s13 () (Seq Int) (seq.++ s9 s12))
+[GOOD] (define-fun s14 () (Seq Int) (ite s5 s3 s13))
+[GOOD] (define-fun s15 () Int (seq.len s11))
+[GOOD] (define-fun s16 () Bool (not s5))
+[GOOD] (define-fun s17 () Bool (> s4 s15))
+[GOOD] (define-fun s18 () Bool (=> s16 s17))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s18))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.map @(SBV [Integer] -> SBV Integer)_1b9bf3f573 @(SBV [[Integer]] -> SBV [Integer]): length arg1 -> OK
+[MEASURE] Passed (terminating): sbv.map @(SBV [Integer] -> SBV Integer)_1b9bf3f573 @(SBV [[Integer]] -> SBV [Integer])
+[MEASURE] Checking: sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_b97075844e @(SBV (Integer,[Integer]) -> SBV Integer)
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_b97075844e @(SBV (Integer,[Integer]) -> SBV Integer): not in a multi-member cycle, skipping mutual check
+[MEASURE] Passed (terminating): sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_b97075844e @(SBV (Integer,[Integer]) -> SBV Integer)
+[MEASURE] Checking: sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): barified = "|sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)|"
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): Uninterpreted ops in DAG: [("|sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)|",1)]
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): recursive calls found = 1
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): trying abs arg1._1
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (- s4 s2))
+[GOOD] (define-fun s9 () (Seq Int) (seq.extract s3 s2 s8))
+[GOOD] (define-fun s10 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s6 s9))
+[GOOD] (define-fun s12 () Int (+ s7 s11))
+[GOOD] (define-fun s13 () Int (ite s5 s6 s12))
+[GOOD] (define-fun s14 () Int (abs s6))
+[GOOD] (define-fun s15 () Bool (>= s14 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s15))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (- s4 s2))
+[GOOD] (define-fun s9 () (Seq Int) (seq.extract s3 s2 s8))
+[GOOD] (define-fun s10 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s6 s9))
+[GOOD] (define-fun s12 () Int (+ s7 s11))
+[GOOD] (define-fun s13 () Int (ite s5 s6 s12))
+[GOOD] (define-fun s14 () Int (abs s6))
+[GOOD] (define-fun s15 () Int (proj_1_SBVTuple2 s10))
+[GOOD] (define-fun s16 () Int (abs s15))
+[GOOD] (define-fun s17 () Bool (not s5))
+[GOOD] (define-fun s18 () Bool (> s14 s16))
+[GOOD] (define-fun s19 () Bool (=> s17 s18))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s19))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s14))
+[RECV] ((s14 0))
+[SEND] (get-value (s16))
+[RECV] ((s16 0))
+[SEND] (get-value (s0))
+[RECV] ((s0 (mkSBVTuple2 0 (seq.unit 4))))
+[SEND] (get-value (s11))
+[RECV] ((s11 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): abs arg1._1 failed strict decrease: Falsifiable. Counter-example:
+  arg    = (0,[4]) :: (Integer, [Integer])
+  before =       0 :: Integer
+  then   =       0 :: Integer
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): trying next candidate..
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): trying length arg1._2
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (- s4 s2))
+[GOOD] (define-fun s9 () (Seq Int) (seq.extract s3 s2 s8))
+[GOOD] (define-fun s10 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s6 s9))
+[GOOD] (define-fun s12 () Int (+ s7 s11))
+[GOOD] (define-fun s13 () Int (ite s5 s6 s12))
+[GOOD] (define-fun s14 () Bool (>= s4 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (- s4 s2))
+[GOOD] (define-fun s9 () (Seq Int) (seq.extract s3 s2 s8))
+[GOOD] (define-fun s10 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s6 s9))
+[GOOD] (define-fun s12 () Int (+ s7 s11))
+[GOOD] (define-fun s13 () Int (ite s5 s6 s12))
+[GOOD] (define-fun s14 () (Seq Int) (proj_2_SBVTuple2 s10))
+[GOOD] (define-fun s15 () Int (seq.len s14))
+[GOOD] (define-fun s16 () Bool (not s5))
+[GOOD] (define-fun s17 () Bool (> s4 s15))
+[GOOD] (define-fun s18 () Bool (=> s16 s17))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s18))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): length arg1._2 -> OK
+[MEASURE] Passed (terminating): sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/lambda08.gold b/SBVTestSuite/GoldFiles/lambda08.gold
--- a/SBVTestSuite/GoldFiles/lambda08.gold
+++ b/SBVTestSuite/GoldFiles/lambda08.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.map @(SBV Int64 -> SBV Int64)_bc2a222730 @(SBV [Int64] -> SBV [Int64])
+[MEASURE] Checking: sbv.map @(SBV Int64 -> SBV Int64)_bc2a222730 @(SBV [Int64] -> SBV [Int64])
+[MEASURE] sbv.map @(SBV Int64 -> SBV Int64)_bc2a222730 @(SBV [Int64] -> SBV [Int64]): barified = "|sbv.map @(SBV Int64 -> SBV Int64)_bc2a222730 @(SBV [Int64] -> SBV [Int64])|"
+[MEASURE] sbv.map @(SBV Int64 -> SBV Int64)_bc2a222730 @(SBV [Int64] -> SBV [Int64]): Uninterpreted ops in DAG: [("|sbv.map @(SBV Int64 -> SBV Int64)_bc2a222730 @(SBV [Int64] -> SBV [Int64])|",1)]
+[MEASURE] sbv.map @(SBV Int64 -> SBV Int64)_bc2a222730 @(SBV [Int64] -> SBV [Int64]): recursive calls found = 1
+[MEASURE] sbv.map @(SBV Int64 -> SBV Int64)_bc2a222730 @(SBV [Int64] -> SBV [Int64]): trying length arg1
+[MEASURE] replayDAG {sbv.map @(SBV Int64 -> SBV Int64)_bc2a222730 @(SBV [Int64] -> SBV [Int64])}: replaying 10 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +16,98 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (_ BitVec 64) #x0000000000000001)
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] (define-fun s4 () (Seq (_ BitVec 64)) (as seq.empty (Seq (_ BitVec 64))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (_ BitVec 64))) ; tracks user variable "arg"
+[GOOD] (declare-fun s12 () (Seq (_ BitVec 64))) ; tracks user variable "__internal_sbv_s12"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s5 () Int (seq.len s0))
+[GOOD] (define-fun s6 () Bool (= s2 s5))
+[GOOD] (define-fun s7 () (_ BitVec 64) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () (_ BitVec 64) (bvadd s1 s7))
+[GOOD] (define-fun s9 () (Seq (_ BitVec 64)) (seq.unit s8))
+[GOOD] (define-fun s10 () Int (- s5 s3))
+[GOOD] (define-fun s11 () (Seq (_ BitVec 64)) (seq.extract s0 s3 s10))
+[GOOD] (define-fun s13 () (Seq (_ BitVec 64)) (seq.++ s9 s12))
+[GOOD] (define-fun s14 () (Seq (_ BitVec 64)) (ite s6 s4 s13))
+[GOOD] (define-fun s15 () Bool (>= s5 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s15))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.map @(SBV Int64 -> SBV Int64)_bc2a222730 @(SBV [Int64] -> SBV [Int64])}: replaying 10 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (_ BitVec 64) #x0000000000000001)
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] (define-fun s4 () (Seq (_ BitVec 64)) (as seq.empty (Seq (_ BitVec 64))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (_ BitVec 64))) ; tracks user variable "arg"
+[GOOD] (declare-fun s12 () (Seq (_ BitVec 64))) ; tracks user variable "__internal_sbv_s12"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s5 () Int (seq.len s0))
+[GOOD] (define-fun s6 () Bool (= s2 s5))
+[GOOD] (define-fun s7 () (_ BitVec 64) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () (_ BitVec 64) (bvadd s1 s7))
+[GOOD] (define-fun s9 () (Seq (_ BitVec 64)) (seq.unit s8))
+[GOOD] (define-fun s10 () Int (- s5 s3))
+[GOOD] (define-fun s11 () (Seq (_ BitVec 64)) (seq.extract s0 s3 s10))
+[GOOD] (define-fun s13 () (Seq (_ BitVec 64)) (seq.++ s9 s12))
+[GOOD] (define-fun s14 () (Seq (_ BitVec 64)) (ite s6 s4 s13))
+[GOOD] (define-fun s15 () Int (seq.len s11))
+[GOOD] (define-fun s16 () Bool (not s6))
+[GOOD] (define-fun s17 () Bool (> s5 s15))
+[GOOD] (define-fun s18 () Bool (=> s16 s17))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s18))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.map @(SBV Int64 -> SBV Int64)_bc2a222730 @(SBV [Int64] -> SBV [Int64]): length arg1 -> OK
+[MEASURE] Passed (terminating): sbv.map @(SBV Int64 -> SBV Int64)_bc2a222730 @(SBV [Int64] -> SBV [Int64])
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda09.gold b/SBVTestSuite/GoldFiles/lambda09.gold
--- a/SBVTestSuite/GoldFiles/lambda09.gold
+++ b/SBVTestSuite/GoldFiles/lambda09.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.map @(SBV Int8 -> SBV Int8)_5111aac2ea @(SBV [Int8] -> SBV [Int8])
+[MEASURE] Checking: sbv.map @(SBV Int8 -> SBV Int8)_5111aac2ea @(SBV [Int8] -> SBV [Int8])
+[MEASURE] sbv.map @(SBV Int8 -> SBV Int8)_5111aac2ea @(SBV [Int8] -> SBV [Int8]): barified = "|sbv.map @(SBV Int8 -> SBV Int8)_5111aac2ea @(SBV [Int8] -> SBV [Int8])|"
+[MEASURE] sbv.map @(SBV Int8 -> SBV Int8)_5111aac2ea @(SBV [Int8] -> SBV [Int8]): Uninterpreted ops in DAG: [("|sbv.map @(SBV Int8 -> SBV Int8)_5111aac2ea @(SBV [Int8] -> SBV [Int8])|",1)]
+[MEASURE] sbv.map @(SBV Int8 -> SBV Int8)_5111aac2ea @(SBV [Int8] -> SBV [Int8]): recursive calls found = 1
+[MEASURE] sbv.map @(SBV Int8 -> SBV Int8)_5111aac2ea @(SBV [Int8] -> SBV [Int8]): trying length arg1
+[MEASURE] replayDAG {sbv.map @(SBV Int8 -> SBV Int8)_5111aac2ea @(SBV [Int8] -> SBV [Int8])}: replaying 10 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +16,98 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (_ BitVec 8) #x01)
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] (define-fun s4 () (Seq (_ BitVec 8)) (as seq.empty (Seq (_ BitVec 8))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (_ BitVec 8))) ; tracks user variable "arg"
+[GOOD] (declare-fun s12 () (Seq (_ BitVec 8))) ; tracks user variable "__internal_sbv_s12"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s5 () Int (seq.len s0))
+[GOOD] (define-fun s6 () Bool (= s2 s5))
+[GOOD] (define-fun s7 () (_ BitVec 8) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () (_ BitVec 8) (bvadd s1 s7))
+[GOOD] (define-fun s9 () (Seq (_ BitVec 8)) (seq.unit s8))
+[GOOD] (define-fun s10 () Int (- s5 s3))
+[GOOD] (define-fun s11 () (Seq (_ BitVec 8)) (seq.extract s0 s3 s10))
+[GOOD] (define-fun s13 () (Seq (_ BitVec 8)) (seq.++ s9 s12))
+[GOOD] (define-fun s14 () (Seq (_ BitVec 8)) (ite s6 s4 s13))
+[GOOD] (define-fun s15 () Bool (>= s5 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s15))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.map @(SBV Int8 -> SBV Int8)_5111aac2ea @(SBV [Int8] -> SBV [Int8])}: replaying 10 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (_ BitVec 8) #x01)
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] (define-fun s4 () (Seq (_ BitVec 8)) (as seq.empty (Seq (_ BitVec 8))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (_ BitVec 8))) ; tracks user variable "arg"
+[GOOD] (declare-fun s12 () (Seq (_ BitVec 8))) ; tracks user variable "__internal_sbv_s12"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s5 () Int (seq.len s0))
+[GOOD] (define-fun s6 () Bool (= s2 s5))
+[GOOD] (define-fun s7 () (_ BitVec 8) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () (_ BitVec 8) (bvadd s1 s7))
+[GOOD] (define-fun s9 () (Seq (_ BitVec 8)) (seq.unit s8))
+[GOOD] (define-fun s10 () Int (- s5 s3))
+[GOOD] (define-fun s11 () (Seq (_ BitVec 8)) (seq.extract s0 s3 s10))
+[GOOD] (define-fun s13 () (Seq (_ BitVec 8)) (seq.++ s9 s12))
+[GOOD] (define-fun s14 () (Seq (_ BitVec 8)) (ite s6 s4 s13))
+[GOOD] (define-fun s15 () Int (seq.len s11))
+[GOOD] (define-fun s16 () Bool (not s6))
+[GOOD] (define-fun s17 () Bool (> s5 s15))
+[GOOD] (define-fun s18 () Bool (=> s16 s17))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s18))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.map @(SBV Int8 -> SBV Int8)_5111aac2ea @(SBV [Int8] -> SBV [Int8]): length arg1 -> OK
+[MEASURE] Passed (terminating): sbv.map @(SBV Int8 -> SBV Int8)_5111aac2ea @(SBV [Int8] -> SBV [Int8])
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda10.gold b/SBVTestSuite/GoldFiles/lambda10.gold
--- a/SBVTestSuite/GoldFiles/lambda10.gold
+++ b/SBVTestSuite/GoldFiles/lambda10.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.map @(SBV Integer -> SBV Integer)_aaa4562f59 @(SBV [Integer] -> SBV [Integer])
+[MEASURE] Checking: sbv.map @(SBV Integer -> SBV Integer)_aaa4562f59 @(SBV [Integer] -> SBV [Integer])
+[MEASURE] sbv.map @(SBV Integer -> SBV Integer)_aaa4562f59 @(SBV [Integer] -> SBV [Integer]): barified = "|sbv.map @(SBV Integer -> SBV Integer)_aaa4562f59 @(SBV [Integer] -> SBV [Integer])|"
+[MEASURE] sbv.map @(SBV Integer -> SBV Integer)_aaa4562f59 @(SBV [Integer] -> SBV [Integer]): Uninterpreted ops in DAG: [("|sbv.map @(SBV Integer -> SBV Integer)_aaa4562f59 @(SBV [Integer] -> SBV [Integer])|",1)]
+[MEASURE] sbv.map @(SBV Integer -> SBV Integer)_aaa4562f59 @(SBV [Integer] -> SBV [Integer]): recursive calls found = 1
+[MEASURE] sbv.map @(SBV Integer -> SBV Integer)_aaa4562f59 @(SBV [Integer] -> SBV [Integer]): trying length arg1
+[MEASURE] replayDAG {sbv.map @(SBV Integer -> SBV Integer)_aaa4562f59 @(SBV [Integer] -> SBV [Integer])}: replaying 10 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +16,96 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () (Seq Int)) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (seq.nth s0 s1))
+[GOOD] (define-fun s7 () Int (+ s2 s6))
+[GOOD] (define-fun s8 () (Seq Int) (seq.unit s7))
+[GOOD] (define-fun s9 () Int (- s4 s2))
+[GOOD] (define-fun s10 () (Seq Int) (seq.extract s0 s2 s9))
+[GOOD] (define-fun s12 () (Seq Int) (seq.++ s8 s11))
+[GOOD] (define-fun s13 () (Seq Int) (ite s5 s3 s12))
+[GOOD] (define-fun s14 () Bool (>= s4 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.map @(SBV Integer -> SBV Integer)_aaa4562f59 @(SBV [Integer] -> SBV [Integer])}: replaying 10 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () (Seq Int)) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (seq.nth s0 s1))
+[GOOD] (define-fun s7 () Int (+ s2 s6))
+[GOOD] (define-fun s8 () (Seq Int) (seq.unit s7))
+[GOOD] (define-fun s9 () Int (- s4 s2))
+[GOOD] (define-fun s10 () (Seq Int) (seq.extract s0 s2 s9))
+[GOOD] (define-fun s12 () (Seq Int) (seq.++ s8 s11))
+[GOOD] (define-fun s13 () (Seq Int) (ite s5 s3 s12))
+[GOOD] (define-fun s14 () Int (seq.len s10))
+[GOOD] (define-fun s15 () Bool (not s5))
+[GOOD] (define-fun s16 () Bool (> s4 s14))
+[GOOD] (define-fun s17 () Bool (=> s15 s16))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.map @(SBV Integer -> SBV Integer)_aaa4562f59 @(SBV [Integer] -> SBV [Integer]): length arg1 -> OK
+[MEASURE] Passed (terminating): sbv.map @(SBV Integer -> SBV Integer)_aaa4562f59 @(SBV [Integer] -> SBV [Integer])
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda11.gold b/SBVTestSuite/GoldFiles/lambda11.gold
--- a/SBVTestSuite/GoldFiles/lambda11.gold
+++ b/SBVTestSuite/GoldFiles/lambda11.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.map @(SBV Word8 -> SBV Word8)_5111aac2ea @(SBV [Word8] -> SBV [Word8])
+[MEASURE] Checking: sbv.map @(SBV Word8 -> SBV Word8)_5111aac2ea @(SBV [Word8] -> SBV [Word8])
+[MEASURE] sbv.map @(SBV Word8 -> SBV Word8)_5111aac2ea @(SBV [Word8] -> SBV [Word8]): barified = "|sbv.map @(SBV Word8 -> SBV Word8)_5111aac2ea @(SBV [Word8] -> SBV [Word8])|"
+[MEASURE] sbv.map @(SBV Word8 -> SBV Word8)_5111aac2ea @(SBV [Word8] -> SBV [Word8]): Uninterpreted ops in DAG: [("|sbv.map @(SBV Word8 -> SBV Word8)_5111aac2ea @(SBV [Word8] -> SBV [Word8])|",1)]
+[MEASURE] sbv.map @(SBV Word8 -> SBV Word8)_5111aac2ea @(SBV [Word8] -> SBV [Word8]): recursive calls found = 1
+[MEASURE] sbv.map @(SBV Word8 -> SBV Word8)_5111aac2ea @(SBV [Word8] -> SBV [Word8]): trying length arg1
+[MEASURE] replayDAG {sbv.map @(SBV Word8 -> SBV Word8)_5111aac2ea @(SBV [Word8] -> SBV [Word8])}: replaying 10 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +16,98 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (_ BitVec 8) #x01)
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] (define-fun s4 () (Seq (_ BitVec 8)) (as seq.empty (Seq (_ BitVec 8))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (_ BitVec 8))) ; tracks user variable "arg"
+[GOOD] (declare-fun s12 () (Seq (_ BitVec 8))) ; tracks user variable "__internal_sbv_s12"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s5 () Int (seq.len s0))
+[GOOD] (define-fun s6 () Bool (= s2 s5))
+[GOOD] (define-fun s7 () (_ BitVec 8) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () (_ BitVec 8) (bvadd s1 s7))
+[GOOD] (define-fun s9 () (Seq (_ BitVec 8)) (seq.unit s8))
+[GOOD] (define-fun s10 () Int (- s5 s3))
+[GOOD] (define-fun s11 () (Seq (_ BitVec 8)) (seq.extract s0 s3 s10))
+[GOOD] (define-fun s13 () (Seq (_ BitVec 8)) (seq.++ s9 s12))
+[GOOD] (define-fun s14 () (Seq (_ BitVec 8)) (ite s6 s4 s13))
+[GOOD] (define-fun s15 () Bool (>= s5 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s15))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.map @(SBV Word8 -> SBV Word8)_5111aac2ea @(SBV [Word8] -> SBV [Word8])}: replaying 10 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (_ BitVec 8) #x01)
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] (define-fun s4 () (Seq (_ BitVec 8)) (as seq.empty (Seq (_ BitVec 8))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (_ BitVec 8))) ; tracks user variable "arg"
+[GOOD] (declare-fun s12 () (Seq (_ BitVec 8))) ; tracks user variable "__internal_sbv_s12"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s5 () Int (seq.len s0))
+[GOOD] (define-fun s6 () Bool (= s2 s5))
+[GOOD] (define-fun s7 () (_ BitVec 8) (seq.nth s0 s2))
+[GOOD] (define-fun s8 () (_ BitVec 8) (bvadd s1 s7))
+[GOOD] (define-fun s9 () (Seq (_ BitVec 8)) (seq.unit s8))
+[GOOD] (define-fun s10 () Int (- s5 s3))
+[GOOD] (define-fun s11 () (Seq (_ BitVec 8)) (seq.extract s0 s3 s10))
+[GOOD] (define-fun s13 () (Seq (_ BitVec 8)) (seq.++ s9 s12))
+[GOOD] (define-fun s14 () (Seq (_ BitVec 8)) (ite s6 s4 s13))
+[GOOD] (define-fun s15 () Int (seq.len s11))
+[GOOD] (define-fun s16 () Bool (not s6))
+[GOOD] (define-fun s17 () Bool (> s5 s15))
+[GOOD] (define-fun s18 () Bool (=> s16 s17))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s18))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.map @(SBV Word8 -> SBV Word8)_5111aac2ea @(SBV [Word8] -> SBV [Word8]): length arg1 -> OK
+[MEASURE] Passed (terminating): sbv.map @(SBV Word8 -> SBV Word8)_5111aac2ea @(SBV [Word8] -> SBV [Word8])
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda12.gold b/SBVTestSuite/GoldFiles/lambda12.gold
--- a/SBVTestSuite/GoldFiles/lambda12.gold
+++ b/SBVTestSuite/GoldFiles/lambda12.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.map @(SBV Integer -> SBV [Integer])_661d2aaa20 @(SBV [Integer] -> SBV [[Integer]])
+[MEASURE] Checking: sbv.map @(SBV Integer -> SBV [Integer])_661d2aaa20 @(SBV [Integer] -> SBV [[Integer]])
+[MEASURE] sbv.map @(SBV Integer -> SBV [Integer])_661d2aaa20 @(SBV [Integer] -> SBV [[Integer]]): barified = "|sbv.map @(SBV Integer -> SBV [Integer])_661d2aaa20 @(SBV [Integer] -> SBV [[Integer]])|"
+[MEASURE] sbv.map @(SBV Integer -> SBV [Integer])_661d2aaa20 @(SBV [Integer] -> SBV [[Integer]]): Uninterpreted ops in DAG: [("|sbv.map @(SBV Integer -> SBV [Integer])_661d2aaa20 @(SBV [Integer] -> SBV [[Integer]])|",1)]
+[MEASURE] sbv.map @(SBV Integer -> SBV [Integer])_661d2aaa20 @(SBV [Integer] -> SBV [[Integer]]): recursive calls found = 1
+[MEASURE] sbv.map @(SBV Integer -> SBV [Integer])_661d2aaa20 @(SBV [Integer] -> SBV [[Integer]]): trying length arg1
+[MEASURE] replayDAG {sbv.map @(SBV Integer -> SBV [Integer])_661d2aaa20 @(SBV [Integer] -> SBV [[Integer]])}: replaying 10 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +16,96 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq (Seq Int)) (as seq.empty (Seq (Seq Int))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () (Seq (Seq Int))) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (seq.nth s0 s1))
+[GOOD] (define-fun s7 () (Seq Int) (seq.unit s6))
+[GOOD] (define-fun s8 () (Seq (Seq Int)) (seq.unit s7))
+[GOOD] (define-fun s9 () Int (- s4 s2))
+[GOOD] (define-fun s10 () (Seq Int) (seq.extract s0 s2 s9))
+[GOOD] (define-fun s12 () (Seq (Seq Int)) (seq.++ s8 s11))
+[GOOD] (define-fun s13 () (Seq (Seq Int)) (ite s5 s3 s12))
+[GOOD] (define-fun s14 () Bool (>= s4 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.map @(SBV Integer -> SBV [Integer])_661d2aaa20 @(SBV [Integer] -> SBV [[Integer]])}: replaying 10 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq (Seq Int)) (as seq.empty (Seq (Seq Int))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () (Seq (Seq Int))) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (seq.nth s0 s1))
+[GOOD] (define-fun s7 () (Seq Int) (seq.unit s6))
+[GOOD] (define-fun s8 () (Seq (Seq Int)) (seq.unit s7))
+[GOOD] (define-fun s9 () Int (- s4 s2))
+[GOOD] (define-fun s10 () (Seq Int) (seq.extract s0 s2 s9))
+[GOOD] (define-fun s12 () (Seq (Seq Int)) (seq.++ s8 s11))
+[GOOD] (define-fun s13 () (Seq (Seq Int)) (ite s5 s3 s12))
+[GOOD] (define-fun s14 () Int (seq.len s10))
+[GOOD] (define-fun s15 () Bool (not s5))
+[GOOD] (define-fun s16 () Bool (> s4 s14))
+[GOOD] (define-fun s17 () Bool (=> s15 s16))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.map @(SBV Integer -> SBV [Integer])_661d2aaa20 @(SBV [Integer] -> SBV [[Integer]]): length arg1 -> OK
+[MEASURE] Passed (terminating): sbv.map @(SBV Integer -> SBV [Integer])_661d2aaa20 @(SBV [Integer] -> SBV [[Integer]])
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda13.gold b/SBVTestSuite/GoldFiles/lambda13.gold
--- a/SBVTestSuite/GoldFiles/lambda13.gold
+++ b/SBVTestSuite/GoldFiles/lambda13.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.map @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV [(Integer,Integer)] -> SBV [Integer])
+[MEASURE] Checking: sbv.map @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV [(Integer,Integer)] -> SBV [Integer])
+[MEASURE] sbv.map @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV [(Integer,Integer)] -> SBV [Integer]): barified = "|sbv.map @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV [(Integer,Integer)] -> SBV [Integer])|"
+[MEASURE] sbv.map @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV [(Integer,Integer)] -> SBV [Integer]): Uninterpreted ops in DAG: [("|sbv.map @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV [(Integer,Integer)] -> SBV [Integer])|",1)]
+[MEASURE] sbv.map @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV [(Integer,Integer)] -> SBV [Integer]): recursive calls found = 1
+[MEASURE] sbv.map @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV [(Integer,Integer)] -> SBV [Integer]): trying length arg1
+[MEASURE] replayDAG {sbv.map @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV [(Integer,Integer)] -> SBV [Integer])}: replaying 12 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +16,106 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 Int Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s13 () (Seq Int)) ; tracks user variable "__internal_sbv_s13"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () (SBVTuple2 Int Int) (seq.nth s0 s1))
+[GOOD] (define-fun s7 () Int (proj_1_SBVTuple2 s6))
+[GOOD] (define-fun s8 () Int (proj_2_SBVTuple2 s6))
+[GOOD] (define-fun s9 () Int (+ s7 s8))
+[GOOD] (define-fun s10 () (Seq Int) (seq.unit s9))
+[GOOD] (define-fun s11 () Int (- s4 s2))
+[GOOD] (define-fun s12 () (Seq (SBVTuple2 Int Int)) (seq.extract s0 s2 s11))
+[GOOD] (define-fun s14 () (Seq Int) (seq.++ s10 s13))
+[GOOD] (define-fun s15 () (Seq Int) (ite s5 s3 s14))
+[GOOD] (define-fun s16 () Bool (>= s4 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s16))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.map @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV [(Integer,Integer)] -> SBV [Integer])}: replaying 12 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 Int Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s13 () (Seq Int)) ; tracks user variable "__internal_sbv_s13"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () (SBVTuple2 Int Int) (seq.nth s0 s1))
+[GOOD] (define-fun s7 () Int (proj_1_SBVTuple2 s6))
+[GOOD] (define-fun s8 () Int (proj_2_SBVTuple2 s6))
+[GOOD] (define-fun s9 () Int (+ s7 s8))
+[GOOD] (define-fun s10 () (Seq Int) (seq.unit s9))
+[GOOD] (define-fun s11 () Int (- s4 s2))
+[GOOD] (define-fun s12 () (Seq (SBVTuple2 Int Int)) (seq.extract s0 s2 s11))
+[GOOD] (define-fun s14 () (Seq Int) (seq.++ s10 s13))
+[GOOD] (define-fun s15 () (Seq Int) (ite s5 s3 s14))
+[GOOD] (define-fun s16 () Int (seq.len s12))
+[GOOD] (define-fun s17 () Bool (not s5))
+[GOOD] (define-fun s18 () Bool (> s4 s16))
+[GOOD] (define-fun s19 () Bool (=> s17 s18))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s19))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.map @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV [(Integer,Integer)] -> SBV [Integer]): length arg1 -> OK
+[MEASURE] Passed (terminating): sbv.map @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV [(Integer,Integer)] -> SBV [Integer])
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/lambda14.gold b/SBVTestSuite/GoldFiles/lambda14.gold
--- a/SBVTestSuite/GoldFiles/lambda14.gold
+++ b/SBVTestSuite/GoldFiles/lambda14.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])
+[MEASURE] Checking: sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])
+[MEASURE] sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer]): barified = "|sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])|"
+[MEASURE] sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer]): Uninterpreted ops in DAG: [("|sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])|",1)]
+[MEASURE] sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer]): recursive calls found = 1
+[MEASURE] sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer]): trying length arg1._1
+[MEASURE] replayDAG {sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])}: replaying 19 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,13 +16,129 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
                                                          (proj_2_SBVTuple2 T2))))))
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 (Seq Int) (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s19 () (Seq Int)) ; tracks user variable "__internal_sbv_s19"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () (Seq Int) (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s5 () Int (seq.len s4))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s8 () Int (seq.len s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Int (seq.nth s4 s1))
+[GOOD] (define-fun s11 () Int (seq.nth s7 s1))
+[GOOD] (define-fun s12 () Int (+ s10 s11))
+[GOOD] (define-fun s13 () (Seq Int) (seq.unit s12))
+[GOOD] (define-fun s14 () Int (- s5 s2))
+[GOOD] (define-fun s15 () (Seq Int) (seq.extract s4 s2 s14))
+[GOOD] (define-fun s16 () Int (- s8 s2))
+[GOOD] (define-fun s17 () (Seq Int) (seq.extract s7 s2 s16))
+[GOOD] (define-fun s18 () (SBVTuple2 (Seq Int) (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq Int))) s15 s17))
+[GOOD] (define-fun s20 () (Seq Int) (seq.++ s13 s19))
+[GOOD] (define-fun s21 () (Seq Int) (ite s9 s3 s20))
+[GOOD] (define-fun s22 () (Seq Int) (ite s6 s3 s21))
+[GOOD] (define-fun s23 () Bool (>= s5 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s23))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])}: replaying 19 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 (Seq Int) (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s19 () (Seq Int)) ; tracks user variable "__internal_sbv_s19"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () (Seq Int) (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s5 () Int (seq.len s4))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s8 () Int (seq.len s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Int (seq.nth s4 s1))
+[GOOD] (define-fun s11 () Int (seq.nth s7 s1))
+[GOOD] (define-fun s12 () Int (+ s10 s11))
+[GOOD] (define-fun s13 () (Seq Int) (seq.unit s12))
+[GOOD] (define-fun s14 () Int (- s5 s2))
+[GOOD] (define-fun s15 () (Seq Int) (seq.extract s4 s2 s14))
+[GOOD] (define-fun s16 () Int (- s8 s2))
+[GOOD] (define-fun s17 () (Seq Int) (seq.extract s7 s2 s16))
+[GOOD] (define-fun s18 () (SBVTuple2 (Seq Int) (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq Int))) s15 s17))
+[GOOD] (define-fun s20 () (Seq Int) (seq.++ s13 s19))
+[GOOD] (define-fun s21 () (Seq Int) (ite s9 s3 s20))
+[GOOD] (define-fun s22 () (Seq Int) (ite s6 s3 s21))
+[GOOD] (define-fun s23 () (Seq Int) (proj_1_SBVTuple2 s18))
+[GOOD] (define-fun s24 () Int (seq.len s23))
+[GOOD] (define-fun s25 () Bool (not s9))
+[GOOD] (define-fun s26 () Bool (not s6))
+[GOOD] (define-fun s27 () Bool (and s25 s26))
+[GOOD] (define-fun s28 () Bool (> s5 s24))
+[GOOD] (define-fun s29 () Bool (=> s27 s28))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s29))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer]): length arg1._1 -> OK
+[MEASURE] Passed (terminating): sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
 [GOOD] (define-fun s2 () (Seq Int) (seq.++ (seq.unit 1) (seq.unit 2) (seq.unit 3) (seq.unit 4) (seq.unit 5)))
 [GOOD] (define-fun s4 () (Seq Int) (seq.++ (seq.unit 10) (seq.unit 11) (seq.unit 12) (seq.unit 13) (seq.unit 14) (seq.unit 15)))
 [GOOD] ; --- top level inputs ---
@@ -28,27 +151,27 @@
 [GOOD] ; |sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])| :: ([SInteger], [SInteger]) -> [SInteger] [Recursive]
 [GOOD] (define-fun-rec |sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])| ((l1_s0 (SBVTuple2 (Seq Int) (Seq Int)))) (Seq Int)
                                  (let ((l1_s3 0))
-                                 (let ((l1_s9 (as seq.empty (Seq Int))))
-                                 (let ((l1_s14 1))
+                                 (let ((l1_s5 (as seq.empty (Seq Int))))
+                                 (let ((l1_s13 1))
                                  (let ((l1_s1 (proj_1_SBVTuple2 l1_s0)))
                                  (let ((l1_s2 (seq.len l1_s1)))
                                  (let ((l1_s4 (= l1_s2 l1_s3)))
-                                 (let ((l1_s5 (proj_2_SBVTuple2 l1_s0)))
-                                 (let ((l1_s6 (seq.len l1_s5)))
-                                 (let ((l1_s7 (= l1_s3 l1_s6)))
-                                 (let ((l1_s8 (or l1_s4 l1_s7)))
-                                 (let ((l1_s10 (seq.nth l1_s1 l1_s3)))
-                                 (let ((l1_s11 (seq.nth l1_s5 l1_s3)))
-                                 (let ((l1_s12 (+ l1_s10 l1_s11)))
-                                 (let ((l1_s13 (seq.unit l1_s12)))
-                                 (let ((l1_s15 (- l1_s2 l1_s14)))
-                                 (let ((l1_s16 (seq.extract l1_s1 l1_s14 l1_s15)))
-                                 (let ((l1_s17 (- l1_s6 l1_s14)))
-                                 (let ((l1_s18 (seq.extract l1_s5 l1_s14 l1_s17)))
-                                 (let ((l1_s19 ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq Int))) l1_s16 l1_s18)))
-                                 (let ((l1_s20 (|sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])| l1_s19)))
-                                 (let ((l1_s21 (seq.++ l1_s13 l1_s20)))
-                                 (let ((l1_s22 (ite l1_s8 l1_s9 l1_s21)))
+                                 (let ((l1_s6 (proj_2_SBVTuple2 l1_s0)))
+                                 (let ((l1_s7 (seq.len l1_s6)))
+                                 (let ((l1_s8 (= l1_s3 l1_s7)))
+                                 (let ((l1_s9 (seq.nth l1_s1 l1_s3)))
+                                 (let ((l1_s10 (seq.nth l1_s6 l1_s3)))
+                                 (let ((l1_s11 (+ l1_s9 l1_s10)))
+                                 (let ((l1_s12 (seq.unit l1_s11)))
+                                 (let ((l1_s14 (- l1_s2 l1_s13)))
+                                 (let ((l1_s15 (seq.extract l1_s1 l1_s13 l1_s14)))
+                                 (let ((l1_s16 (- l1_s7 l1_s13)))
+                                 (let ((l1_s17 (seq.extract l1_s6 l1_s13 l1_s16)))
+                                 (let ((l1_s18 ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq Int))) l1_s15 l1_s17)))
+                                 (let ((l1_s19 (|sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])| l1_s18)))
+                                 (let ((l1_s20 (seq.++ l1_s12 l1_s19)))
+                                 (let ((l1_s21 (ite l1_s8 l1_s5 l1_s20)))
+                                 (let ((l1_s22 (ite l1_s4 l1_s5 l1_s21)))
                                  l1_s22)))))))))))))))))))))))
 [GOOD] ; --- assignments ---
 [GOOD] (define-fun s3 () Bool (= s0 s2))
diff --git a/SBVTestSuite/GoldFiles/lambda15.gold b/SBVTestSuite/GoldFiles/lambda15.gold
--- a/SBVTestSuite/GoldFiles/lambda15.gold
+++ b/SBVTestSuite/GoldFiles/lambda15.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)
+[MEASURE] Checking: sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)
+[MEASURE] sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): barified = "|sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)|"
+[MEASURE] sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): Uninterpreted ops in DAG: [("|sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)|",1)]
+[MEASURE] sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): recursive calls found = 1
+[MEASURE] sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): trying abs arg1._1
+[MEASURE] replayDAG {sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)}: replaying 11 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +16,215 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s12 () Int) ; tracks user variable "__internal_sbv_s12"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (+ s6 s7))
+[GOOD] (define-fun s9 () Int (- s4 s2))
+[GOOD] (define-fun s10 () (Seq Int) (seq.extract s3 s2 s9))
+[GOOD] (define-fun s11 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s8 s10))
+[GOOD] (define-fun s13 () Int (ite s5 s6 s12))
+[GOOD] (define-fun s14 () Int (abs s6))
+[GOOD] (define-fun s15 () Bool (>= s14 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s15))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s12 () Int) ; tracks user variable "__internal_sbv_s12"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (+ s6 s7))
+[GOOD] (define-fun s9 () Int (- s4 s2))
+[GOOD] (define-fun s10 () (Seq Int) (seq.extract s3 s2 s9))
+[GOOD] (define-fun s11 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s8 s10))
+[GOOD] (define-fun s13 () Int (ite s5 s6 s12))
+[GOOD] (define-fun s14 () Int (abs s6))
+[GOOD] (define-fun s15 () Int (proj_1_SBVTuple2 s11))
+[GOOD] (define-fun s16 () Int (abs s15))
+[GOOD] (define-fun s17 () Bool (not s5))
+[GOOD] (define-fun s18 () Bool (> s14 s16))
+[GOOD] (define-fun s19 () Bool (=> s17 s18))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s19))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s14))
+[RECV] ((s14 8946))
+[SEND] (get-value (s16))
+[RECV] ((s16 8946))
+[SEND] (get-value (s0))
+[RECV] ((s0 (mkSBVTuple2 8946 (seq.unit 0))))
+[SEND] (get-value (s12))
+[RECV] ((s12 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): abs arg1._1 failed strict decrease: Falsifiable. Counter-example:
+  arg    = (8946,[0]) :: (Integer, [Integer])
+  before =       8946 :: Integer
+  then   =       8946 :: Integer
+[MEASURE] sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): trying next candidate..
+[MEASURE] sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): trying length arg1._2
+[MEASURE] replayDAG {sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s12 () Int) ; tracks user variable "__internal_sbv_s12"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (+ s6 s7))
+[GOOD] (define-fun s9 () Int (- s4 s2))
+[GOOD] (define-fun s10 () (Seq Int) (seq.extract s3 s2 s9))
+[GOOD] (define-fun s11 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s8 s10))
+[GOOD] (define-fun s13 () Int (ite s5 s6 s12))
+[GOOD] (define-fun s14 () Bool (>= s4 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s12 () Int) ; tracks user variable "__internal_sbv_s12"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (+ s6 s7))
+[GOOD] (define-fun s9 () Int (- s4 s2))
+[GOOD] (define-fun s10 () (Seq Int) (seq.extract s3 s2 s9))
+[GOOD] (define-fun s11 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s8 s10))
+[GOOD] (define-fun s13 () Int (ite s5 s6 s12))
+[GOOD] (define-fun s14 () (Seq Int) (proj_2_SBVTuple2 s11))
+[GOOD] (define-fun s15 () Int (seq.len s14))
+[GOOD] (define-fun s16 () Bool (not s5))
+[GOOD] (define-fun s17 () Bool (> s4 s15))
+[GOOD] (define-fun s18 () Bool (=> s16 s17))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s18))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): length arg1._2 -> OK
+[MEASURE] Passed (terminating): sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/lambda16.gold b/SBVTestSuite/GoldFiles/lambda16.gold
--- a/SBVTestSuite/GoldFiles/lambda16.gold
+++ b/SBVTestSuite/GoldFiles/lambda16.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer)
+[MEASURE] Checking: sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer)
+[MEASURE] sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer): barified = "|sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer)|"
+[MEASURE] sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer): Uninterpreted ops in DAG: [("|sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer)|",1)]
+[MEASURE] sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer): recursive calls found = 1
+[MEASURE] sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer): trying abs arg1._1
+[MEASURE] replayDAG {sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer)}: replaying 11 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +16,215 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s12 () Int) ; tracks user variable "__internal_sbv_s12"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (* s6 s7))
+[GOOD] (define-fun s9 () Int (- s4 s2))
+[GOOD] (define-fun s10 () (Seq Int) (seq.extract s3 s2 s9))
+[GOOD] (define-fun s11 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s8 s10))
+[GOOD] (define-fun s13 () Int (ite s5 s6 s12))
+[GOOD] (define-fun s14 () Int (abs s6))
+[GOOD] (define-fun s15 () Bool (>= s14 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s15))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer)}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s12 () Int) ; tracks user variable "__internal_sbv_s12"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (* s6 s7))
+[GOOD] (define-fun s9 () Int (- s4 s2))
+[GOOD] (define-fun s10 () (Seq Int) (seq.extract s3 s2 s9))
+[GOOD] (define-fun s11 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s8 s10))
+[GOOD] (define-fun s13 () Int (ite s5 s6 s12))
+[GOOD] (define-fun s14 () Int (abs s6))
+[GOOD] (define-fun s15 () Int (proj_1_SBVTuple2 s11))
+[GOOD] (define-fun s16 () Int (abs s15))
+[GOOD] (define-fun s17 () Bool (not s5))
+[GOOD] (define-fun s18 () Bool (> s14 s16))
+[GOOD] (define-fun s19 () Bool (=> s17 s18))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s19))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s14))
+[RECV] ((s14 1))
+[SEND] (get-value (s16))
+[RECV] ((s16 1))
+[SEND] (get-value (s0))
+[RECV] ((s0 (mkSBVTuple2 1 (seq.unit (- 1)))))
+[SEND] (get-value (s12))
+[RECV] ((s12 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer): abs arg1._1 failed strict decrease: Falsifiable. Counter-example:
+  arg    = (1,[-1]) :: (Integer, [Integer])
+  before =        1 :: Integer
+  then   =        1 :: Integer
+[MEASURE] sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer): trying next candidate..
+[MEASURE] sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer): trying length arg1._2
+[MEASURE] replayDAG {sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer)}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s12 () Int) ; tracks user variable "__internal_sbv_s12"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (* s6 s7))
+[GOOD] (define-fun s9 () Int (- s4 s2))
+[GOOD] (define-fun s10 () (Seq Int) (seq.extract s3 s2 s9))
+[GOOD] (define-fun s11 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s8 s10))
+[GOOD] (define-fun s13 () Int (ite s5 s6 s12))
+[GOOD] (define-fun s14 () Bool (>= s4 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer)}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s12 () Int) ; tracks user variable "__internal_sbv_s12"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (* s6 s7))
+[GOOD] (define-fun s9 () Int (- s4 s2))
+[GOOD] (define-fun s10 () (Seq Int) (seq.extract s3 s2 s9))
+[GOOD] (define-fun s11 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s8 s10))
+[GOOD] (define-fun s13 () Int (ite s5 s6 s12))
+[GOOD] (define-fun s14 () (Seq Int) (proj_2_SBVTuple2 s11))
+[GOOD] (define-fun s15 () Int (seq.len s14))
+[GOOD] (define-fun s16 () Bool (not s5))
+[GOOD] (define-fun s17 () Bool (> s4 s15))
+[GOOD] (define-fun s18 () Bool (=> s16 s17))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s18))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer): length arg1._2 -> OK
+[MEASURE] Passed (terminating): sbv.foldl @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/lambda17.gold b/SBVTestSuite/GoldFiles/lambda17.gold
--- a/SBVTestSuite/GoldFiles/lambda17.gold
+++ b/SBVTestSuite/GoldFiles/lambda17.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.foldl @(SBV ([Integer],Integer) -> SBV [Integer])_2d6951daf1 @(SBV ([Integer],[Integer]) -> SBV [Integer])
+[MEASURE] Checking: sbv.foldl @(SBV ([Integer],Integer) -> SBV [Integer])_2d6951daf1 @(SBV ([Integer],[Integer]) -> SBV [Integer])
+[MEASURE] sbv.foldl @(SBV ([Integer],Integer) -> SBV [Integer])_2d6951daf1 @(SBV ([Integer],[Integer]) -> SBV [Integer]): barified = "|sbv.foldl @(SBV ([Integer],Integer) -> SBV [Integer])_2d6951daf1 @(SBV ([Integer],[Integer]) -> SBV [Integer])|"
+[MEASURE] sbv.foldl @(SBV ([Integer],Integer) -> SBV [Integer])_2d6951daf1 @(SBV ([Integer],[Integer]) -> SBV [Integer]): Uninterpreted ops in DAG: [("|sbv.foldl @(SBV ([Integer],Integer) -> SBV [Integer])_2d6951daf1 @(SBV ([Integer],[Integer]) -> SBV [Integer])|",1)]
+[MEASURE] sbv.foldl @(SBV ([Integer],Integer) -> SBV [Integer])_2d6951daf1 @(SBV ([Integer],[Integer]) -> SBV [Integer]): recursive calls found = 1
+[MEASURE] sbv.foldl @(SBV ([Integer],Integer) -> SBV [Integer])_2d6951daf1 @(SBV ([Integer],[Integer]) -> SBV [Integer]): trying length arg1._1
+[MEASURE] replayDAG {sbv.foldl @(SBV ([Integer],Integer) -> SBV [Integer])_2d6951daf1 @(SBV ([Integer],[Integer]) -> SBV [Integer])}: replaying 12 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +16,219 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 (Seq Int) (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s13 () (Seq Int)) ; tracks user variable "__internal_sbv_s13"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () (Seq Int) (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () (Seq Int) (seq.unit s7))
+[GOOD] (define-fun s9 () (Seq Int) (seq.++ s8 s6))
+[GOOD] (define-fun s10 () Int (- s4 s2))
+[GOOD] (define-fun s11 () (Seq Int) (seq.extract s3 s2 s10))
+[GOOD] (define-fun s12 () (SBVTuple2 (Seq Int) (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq Int))) s9 s11))
+[GOOD] (define-fun s14 () (Seq Int) (ite s5 s6 s13))
+[GOOD] (define-fun s15 () Int (seq.len s6))
+[GOOD] (define-fun s16 () Bool (>= s15 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s16))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.foldl @(SBV ([Integer],Integer) -> SBV [Integer])_2d6951daf1 @(SBV ([Integer],[Integer]) -> SBV [Integer])}: replaying 12 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 (Seq Int) (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s13 () (Seq Int)) ; tracks user variable "__internal_sbv_s13"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () (Seq Int) (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () (Seq Int) (seq.unit s7))
+[GOOD] (define-fun s9 () (Seq Int) (seq.++ s8 s6))
+[GOOD] (define-fun s10 () Int (- s4 s2))
+[GOOD] (define-fun s11 () (Seq Int) (seq.extract s3 s2 s10))
+[GOOD] (define-fun s12 () (SBVTuple2 (Seq Int) (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq Int))) s9 s11))
+[GOOD] (define-fun s14 () (Seq Int) (ite s5 s6 s13))
+[GOOD] (define-fun s15 () Int (seq.len s6))
+[GOOD] (define-fun s16 () (Seq Int) (proj_1_SBVTuple2 s12))
+[GOOD] (define-fun s17 () Int (seq.len s16))
+[GOOD] (define-fun s18 () Bool (not s5))
+[GOOD] (define-fun s19 () Bool (> s15 s17))
+[GOOD] (define-fun s20 () Bool (=> s18 s19))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s20))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s15))
+[RECV] ((s15 0))
+[SEND] (get-value (s17))
+[RECV] ((s17 1))
+[SEND] (get-value (s0))
+[RECV] ((s0 (mkSBVTuple2 (as seq.empty (Seq Int)) (seq.unit 4))))
+[SEND] (get-value (s13))
+[RECV] ((s13 (as seq.empty (Seq Int))))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.foldl @(SBV ([Integer],Integer) -> SBV [Integer])_2d6951daf1 @(SBV ([Integer],[Integer]) -> SBV [Integer]): length arg1._1 failed strict decrease: Falsifiable. Counter-example:
+  arg    = ([],[4]) :: ([Integer], [Integer])
+  before =        0 :: Integer
+  then   =        1 :: Integer
+[MEASURE] sbv.foldl @(SBV ([Integer],Integer) -> SBV [Integer])_2d6951daf1 @(SBV ([Integer],[Integer]) -> SBV [Integer]): trying next candidate..
+[MEASURE] sbv.foldl @(SBV ([Integer],Integer) -> SBV [Integer])_2d6951daf1 @(SBV ([Integer],[Integer]) -> SBV [Integer]): trying length arg1._2
+[MEASURE] replayDAG {sbv.foldl @(SBV ([Integer],Integer) -> SBV [Integer])_2d6951daf1 @(SBV ([Integer],[Integer]) -> SBV [Integer])}: replaying 12 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 (Seq Int) (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s13 () (Seq Int)) ; tracks user variable "__internal_sbv_s13"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () (Seq Int) (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () (Seq Int) (seq.unit s7))
+[GOOD] (define-fun s9 () (Seq Int) (seq.++ s8 s6))
+[GOOD] (define-fun s10 () Int (- s4 s2))
+[GOOD] (define-fun s11 () (Seq Int) (seq.extract s3 s2 s10))
+[GOOD] (define-fun s12 () (SBVTuple2 (Seq Int) (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq Int))) s9 s11))
+[GOOD] (define-fun s14 () (Seq Int) (ite s5 s6 s13))
+[GOOD] (define-fun s15 () Bool (>= s4 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s15))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.foldl @(SBV ([Integer],Integer) -> SBV [Integer])_2d6951daf1 @(SBV ([Integer],[Integer]) -> SBV [Integer])}: replaying 12 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 (Seq Int) (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s13 () (Seq Int)) ; tracks user variable "__internal_sbv_s13"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () (Seq Int) (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () (Seq Int) (seq.unit s7))
+[GOOD] (define-fun s9 () (Seq Int) (seq.++ s8 s6))
+[GOOD] (define-fun s10 () Int (- s4 s2))
+[GOOD] (define-fun s11 () (Seq Int) (seq.extract s3 s2 s10))
+[GOOD] (define-fun s12 () (SBVTuple2 (Seq Int) (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq Int))) s9 s11))
+[GOOD] (define-fun s14 () (Seq Int) (ite s5 s6 s13))
+[GOOD] (define-fun s15 () (Seq Int) (proj_2_SBVTuple2 s12))
+[GOOD] (define-fun s16 () Int (seq.len s15))
+[GOOD] (define-fun s17 () Bool (not s5))
+[GOOD] (define-fun s18 () Bool (> s4 s16))
+[GOOD] (define-fun s19 () Bool (=> s17 s18))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s19))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.foldl @(SBV ([Integer],Integer) -> SBV [Integer])_2d6951daf1 @(SBV ([Integer],[Integer]) -> SBV [Integer]): length arg1._2 -> OK
+[MEASURE] Passed (terminating): sbv.foldl @(SBV ([Integer],Integer) -> SBV [Integer])_2d6951daf1 @(SBV ([Integer],[Integer]) -> SBV [Integer])
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/lambda18.gold b/SBVTestSuite/GoldFiles/lambda18.gold
--- a/SBVTestSuite/GoldFiles/lambda18.gold
+++ b/SBVTestSuite/GoldFiles/lambda18.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)]), sbv.foldl @(SBV (Integer,(Integer,Integer)) -> SBV Integer)_f29a298542 @(SBV (Integer,[(Integer,Integer)]) -> SBV Integer)
+[MEASURE] Checking: sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])
+[MEASURE] sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)]): barified = "|sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])|"
+[MEASURE] sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)]): Uninterpreted ops in DAG: [("|sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])|",2)]
+[MEASURE] sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)]): recursive calls found = 1
+[MEASURE] sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)]): trying length arg1
+[MEASURE] replayDAG {sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])}: replaying 16 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,13 +16,351 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
                                                          (proj_2_SBVTuple2 T2))))))
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] (define-fun s4 () (Seq (SBVTuple2 Int Int)) (as seq.empty (Seq (SBVTuple2 Int Int))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () (Seq Int)) ; tracks user variable "arg1"
+[GOOD] (declare-fun s17 () (Seq (SBVTuple2 Int Int))) ; tracks user variable "__internal_sbv_s17"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s5 () Int (seq.len s0))
+[GOOD] (define-fun s6 () Bool (= s2 s5))
+[GOOD] (define-fun s7 () Int (seq.len s1))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s9 () Int (seq.nth s0 s2))
+[GOOD] (define-fun s10 () Int (seq.nth s1 s2))
+[GOOD] (define-fun s11 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s9 s10))
+[GOOD] (define-fun s12 () (Seq (SBVTuple2 Int Int)) (seq.unit s11))
+[GOOD] (define-fun s13 () Int (- s5 s3))
+[GOOD] (define-fun s14 () (Seq Int) (seq.extract s0 s3 s13))
+[GOOD] (define-fun s15 () Int (- s7 s3))
+[GOOD] (define-fun s16 () (Seq Int) (seq.extract s1 s3 s15))
+[GOOD] (define-fun s18 () (Seq (SBVTuple2 Int Int)) (seq.++ s12 s17))
+[GOOD] (define-fun s19 () (Seq (SBVTuple2 Int Int)) (ite s8 s4 s18))
+[GOOD] (define-fun s20 () (Seq (SBVTuple2 Int Int)) (ite s6 s4 s19))
+[GOOD] (define-fun s21 () Bool (>= s5 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])}: replaying 16 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] (define-fun s4 () (Seq (SBVTuple2 Int Int)) (as seq.empty (Seq (SBVTuple2 Int Int))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () (Seq Int)) ; tracks user variable "arg1"
+[GOOD] (declare-fun s17 () (Seq (SBVTuple2 Int Int))) ; tracks user variable "__internal_sbv_s17"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s5 () Int (seq.len s0))
+[GOOD] (define-fun s6 () Bool (= s2 s5))
+[GOOD] (define-fun s7 () Int (seq.len s1))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s9 () Int (seq.nth s0 s2))
+[GOOD] (define-fun s10 () Int (seq.nth s1 s2))
+[GOOD] (define-fun s11 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s9 s10))
+[GOOD] (define-fun s12 () (Seq (SBVTuple2 Int Int)) (seq.unit s11))
+[GOOD] (define-fun s13 () Int (- s5 s3))
+[GOOD] (define-fun s14 () (Seq Int) (seq.extract s0 s3 s13))
+[GOOD] (define-fun s15 () Int (- s7 s3))
+[GOOD] (define-fun s16 () (Seq Int) (seq.extract s1 s3 s15))
+[GOOD] (define-fun s18 () (Seq (SBVTuple2 Int Int)) (seq.++ s12 s17))
+[GOOD] (define-fun s19 () (Seq (SBVTuple2 Int Int)) (ite s8 s4 s18))
+[GOOD] (define-fun s20 () (Seq (SBVTuple2 Int Int)) (ite s6 s4 s19))
+[GOOD] (define-fun s21 () Int (seq.len s14))
+[GOOD] (define-fun s22 () Bool (not s8))
+[GOOD] (define-fun s23 () Bool (not s6))
+[GOOD] (define-fun s24 () Bool (and s22 s23))
+[GOOD] (define-fun s25 () Bool (> s5 s21))
+[GOOD] (define-fun s26 () Bool (=> s24 s25))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s26))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)]): length arg1 -> OK
+[MEASURE] Passed (terminating): sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])
+[MEASURE] Checking: sbv.foldl @(SBV (Integer,(Integer,Integer)) -> SBV Integer)_f29a298542 @(SBV (Integer,[(Integer,Integer)]) -> SBV Integer)
+[MEASURE] sbv.foldl @(SBV (Integer,(Integer,Integer)) -> SBV Integer)_f29a298542 @(SBV (Integer,[(Integer,Integer)]) -> SBV Integer): barified = "|sbv.foldl @(SBV (Integer,(Integer,Integer)) -> SBV Integer)_f29a298542 @(SBV (Integer,[(Integer,Integer)]) -> SBV Integer)|"
+[MEASURE] sbv.foldl @(SBV (Integer,(Integer,Integer)) -> SBV Integer)_f29a298542 @(SBV (Integer,[(Integer,Integer)]) -> SBV Integer): Uninterpreted ops in DAG: [("|sbv.foldl @(SBV (Integer,(Integer,Integer)) -> SBV Integer)_f29a298542 @(SBV (Integer,[(Integer,Integer)]) -> SBV Integer)|",1)]
+[MEASURE] sbv.foldl @(SBV (Integer,(Integer,Integer)) -> SBV Integer)_f29a298542 @(SBV (Integer,[(Integer,Integer)]) -> SBV Integer): recursive calls found = 1
+[MEASURE] sbv.foldl @(SBV (Integer,(Integer,Integer)) -> SBV Integer)_f29a298542 @(SBV (Integer,[(Integer,Integer)]) -> SBV Integer): trying abs arg1._1
+[MEASURE] replayDAG {sbv.foldl @(SBV (Integer,(Integer,Integer)) -> SBV Integer)_f29a298542 @(SBV (Integer,[(Integer,Integer)]) -> SBV Integer)}: replaying 14 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq (SBVTuple2 Int Int)))) ; tracks user variable "arg"
+[GOOD] (declare-fun s15 () Int) ; tracks user variable "__internal_sbv_s15"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq (SBVTuple2 Int Int)) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () (SBVTuple2 Int Int) (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s11 () Int (+ s9 s10))
+[GOOD] (define-fun s12 () Int (- s4 s2))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 Int Int)) (seq.extract s3 s2 s12))
+[GOOD] (define-fun s14 () (SBVTuple2 Int (Seq (SBVTuple2 Int Int))) ((as mkSBVTuple2 (SBVTuple2 Int (Seq (SBVTuple2 Int Int)))) s11 s13))
+[GOOD] (define-fun s16 () Int (ite s5 s6 s15))
+[GOOD] (define-fun s17 () Int (abs s6))
+[GOOD] (define-fun s18 () Bool (>= s17 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s18))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.foldl @(SBV (Integer,(Integer,Integer)) -> SBV Integer)_f29a298542 @(SBV (Integer,[(Integer,Integer)]) -> SBV Integer)}: replaying 14 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq (SBVTuple2 Int Int)))) ; tracks user variable "arg"
+[GOOD] (declare-fun s15 () Int) ; tracks user variable "__internal_sbv_s15"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq (SBVTuple2 Int Int)) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () (SBVTuple2 Int Int) (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s11 () Int (+ s9 s10))
+[GOOD] (define-fun s12 () Int (- s4 s2))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 Int Int)) (seq.extract s3 s2 s12))
+[GOOD] (define-fun s14 () (SBVTuple2 Int (Seq (SBVTuple2 Int Int))) ((as mkSBVTuple2 (SBVTuple2 Int (Seq (SBVTuple2 Int Int)))) s11 s13))
+[GOOD] (define-fun s16 () Int (ite s5 s6 s15))
+[GOOD] (define-fun s17 () Int (abs s6))
+[GOOD] (define-fun s18 () Int (proj_1_SBVTuple2 s14))
+[GOOD] (define-fun s19 () Int (abs s18))
+[GOOD] (define-fun s20 () Bool (not s5))
+[GOOD] (define-fun s21 () Bool (> s17 s19))
+[GOOD] (define-fun s22 () Bool (=> s20 s21))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s22))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s17))
+[RECV] ((s17 0))
+[SEND] (get-value (s19))
+[RECV] ((s19 0))
+[SEND] (get-value (s0))
+[RECV] ((s0 (mkSBVTuple2 0 (seq.unit (mkSBVTuple2 0 0)))))
+[SEND] (get-value (s15))
+[RECV] ((s15 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.foldl @(SBV (Integer,(Integer,Integer)) -> SBV Integer)_f29a298542 @(SBV (Integer,[(Integer,Integer)]) -> SBV Integer): abs arg1._1 failed strict decrease: Falsifiable. Counter-example:
+  arg    = (0,[(0,0)]) :: (Integer, [(Integer, Integer)])
+  before =           0 :: Integer
+  then   =           0 :: Integer
+[MEASURE] sbv.foldl @(SBV (Integer,(Integer,Integer)) -> SBV Integer)_f29a298542 @(SBV (Integer,[(Integer,Integer)]) -> SBV Integer): trying next candidate..
+[MEASURE] sbv.foldl @(SBV (Integer,(Integer,Integer)) -> SBV Integer)_f29a298542 @(SBV (Integer,[(Integer,Integer)]) -> SBV Integer): trying length arg1._2
+[MEASURE] replayDAG {sbv.foldl @(SBV (Integer,(Integer,Integer)) -> SBV Integer)_f29a298542 @(SBV (Integer,[(Integer,Integer)]) -> SBV Integer)}: replaying 14 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq (SBVTuple2 Int Int)))) ; tracks user variable "arg"
+[GOOD] (declare-fun s15 () Int) ; tracks user variable "__internal_sbv_s15"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq (SBVTuple2 Int Int)) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () (SBVTuple2 Int Int) (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s11 () Int (+ s9 s10))
+[GOOD] (define-fun s12 () Int (- s4 s2))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 Int Int)) (seq.extract s3 s2 s12))
+[GOOD] (define-fun s14 () (SBVTuple2 Int (Seq (SBVTuple2 Int Int))) ((as mkSBVTuple2 (SBVTuple2 Int (Seq (SBVTuple2 Int Int)))) s11 s13))
+[GOOD] (define-fun s16 () Int (ite s5 s6 s15))
+[GOOD] (define-fun s17 () Bool (>= s4 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.foldl @(SBV (Integer,(Integer,Integer)) -> SBV Integer)_f29a298542 @(SBV (Integer,[(Integer,Integer)]) -> SBV Integer)}: replaying 14 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq (SBVTuple2 Int Int)))) ; tracks user variable "arg"
+[GOOD] (declare-fun s15 () Int) ; tracks user variable "__internal_sbv_s15"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq (SBVTuple2 Int Int)) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () (SBVTuple2 Int Int) (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (proj_1_SBVTuple2 s7))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (proj_2_SBVTuple2 s7))
+[GOOD] (define-fun s11 () Int (+ s9 s10))
+[GOOD] (define-fun s12 () Int (- s4 s2))
+[GOOD] (define-fun s13 () (Seq (SBVTuple2 Int Int)) (seq.extract s3 s2 s12))
+[GOOD] (define-fun s14 () (SBVTuple2 Int (Seq (SBVTuple2 Int Int))) ((as mkSBVTuple2 (SBVTuple2 Int (Seq (SBVTuple2 Int Int)))) s11 s13))
+[GOOD] (define-fun s16 () Int (ite s5 s6 s15))
+[GOOD] (define-fun s17 () (Seq (SBVTuple2 Int Int)) (proj_2_SBVTuple2 s14))
+[GOOD] (define-fun s18 () Int (seq.len s17))
+[GOOD] (define-fun s19 () Bool (not s5))
+[GOOD] (define-fun s20 () Bool (> s4 s18))
+[GOOD] (define-fun s21 () Bool (=> s19 s20))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.foldl @(SBV (Integer,(Integer,Integer)) -> SBV Integer)_f29a298542 @(SBV (Integer,[(Integer,Integer)]) -> SBV Integer): length arg1._2 -> OK
+[MEASURE] Passed (terminating): sbv.foldl @(SBV (Integer,(Integer,Integer)) -> SBV Integer)_f29a298542 @(SBV (Integer,[(Integer,Integer)]) -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
 [GOOD] (define-fun s2 () (Seq Int) (seq.++ (seq.unit 1) (seq.unit 2) (seq.unit 3) (seq.unit 4) (seq.unit 5)))
 [GOOD] (define-fun s4 () Int 0)
 [GOOD] (define-fun s5 () (Seq Int) (seq.++ (seq.unit 10) (seq.unit 11) (seq.unit 12) (seq.unit 13) (seq.unit 14) (seq.unit 15)))
@@ -29,24 +374,24 @@
 [GOOD] ; |sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])| :: [SInteger] -> [SInteger] -> [(SInteger, SInteger)] [Recursive]
 [GOOD] (define-fun-rec |sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])| ((l1_s0 (Seq Int)) (l1_s1 (Seq Int))) (Seq (SBVTuple2 Int Int))
                                  (let ((l1_s3 0))
-                                 (let ((l1_s8 (as seq.empty (Seq (SBVTuple2 Int Int)))))
-                                 (let ((l1_s13 1))
+                                 (let ((l1_s5 (as seq.empty (Seq (SBVTuple2 Int Int)))))
+                                 (let ((l1_s12 1))
                                  (let ((l1_s2 (seq.len l1_s0)))
                                  (let ((l1_s4 (= l1_s2 l1_s3)))
-                                 (let ((l1_s5 (seq.len l1_s1)))
-                                 (let ((l1_s6 (= l1_s3 l1_s5)))
-                                 (let ((l1_s7 (or l1_s4 l1_s6)))
-                                 (let ((l1_s9 (seq.nth l1_s0 l1_s3)))
-                                 (let ((l1_s10 (seq.nth l1_s1 l1_s3)))
-                                 (let ((l1_s11 ((as mkSBVTuple2 (SBVTuple2 Int Int)) l1_s9 l1_s10)))
-                                 (let ((l1_s12 (seq.unit l1_s11)))
-                                 (let ((l1_s14 (- l1_s2 l1_s13)))
-                                 (let ((l1_s15 (seq.extract l1_s0 l1_s13 l1_s14)))
-                                 (let ((l1_s16 (- l1_s5 l1_s13)))
-                                 (let ((l1_s17 (seq.extract l1_s1 l1_s13 l1_s16)))
-                                 (let ((l1_s18 (|sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])| l1_s15 l1_s17)))
-                                 (let ((l1_s19 (seq.++ l1_s12 l1_s18)))
-                                 (let ((l1_s20 (ite l1_s7 l1_s8 l1_s19)))
+                                 (let ((l1_s6 (seq.len l1_s1)))
+                                 (let ((l1_s7 (= l1_s3 l1_s6)))
+                                 (let ((l1_s8 (seq.nth l1_s0 l1_s3)))
+                                 (let ((l1_s9 (seq.nth l1_s1 l1_s3)))
+                                 (let ((l1_s10 ((as mkSBVTuple2 (SBVTuple2 Int Int)) l1_s8 l1_s9)))
+                                 (let ((l1_s11 (seq.unit l1_s10)))
+                                 (let ((l1_s13 (- l1_s2 l1_s12)))
+                                 (let ((l1_s14 (seq.extract l1_s0 l1_s12 l1_s13)))
+                                 (let ((l1_s15 (- l1_s6 l1_s12)))
+                                 (let ((l1_s16 (seq.extract l1_s1 l1_s12 l1_s15)))
+                                 (let ((l1_s17 (|sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])| l1_s14 l1_s16)))
+                                 (let ((l1_s18 (seq.++ l1_s11 l1_s17)))
+                                 (let ((l1_s19 (ite l1_s7 l1_s5 l1_s18)))
+                                 (let ((l1_s20 (ite l1_s4 l1_s5 l1_s19)))
                                  l1_s20))))))))))))))))))))
 [GOOD] ; |sbv.foldl @(SBV (Integer,(Integer,Integer)) -> SBV Integer)_f29a298542 @(SBV (Integer,[(Integer,Integer)]) -> SBV Integer)| :: (SInteger, [(SInteger, SInteger)]) -> SInteger [Recursive]
 [GOOD] (define-fun-rec |sbv.foldl @(SBV (Integer,(Integer,Integer)) -> SBV Integer)_f29a298542 @(SBV (Integer,[(Integer,Integer)]) -> SBV Integer)| ((l1_s0 (SBVTuple2 Int (Seq (SBVTuple2 Int Int))))) Int
diff --git a/SBVTestSuite/GoldFiles/lambda19.gold b/SBVTestSuite/GoldFiles/lambda19.gold
--- a/SBVTestSuite/GoldFiles/lambda19.gold
+++ b/SBVTestSuite/GoldFiles/lambda19.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)
+[MEASURE] Checking: sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): barified = "|sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)|"
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): Uninterpreted ops in DAG: [("|sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)|",1)]
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): recursive calls found = 1
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): trying abs arg1._1
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)}: replaying 11 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +16,215 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (- s4 s2))
+[GOOD] (define-fun s9 () (Seq Int) (seq.extract s3 s2 s8))
+[GOOD] (define-fun s10 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s6 s9))
+[GOOD] (define-fun s12 () Int (+ s7 s11))
+[GOOD] (define-fun s13 () Int (ite s5 s6 s12))
+[GOOD] (define-fun s14 () Int (abs s6))
+[GOOD] (define-fun s15 () Bool (>= s14 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s15))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (- s4 s2))
+[GOOD] (define-fun s9 () (Seq Int) (seq.extract s3 s2 s8))
+[GOOD] (define-fun s10 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s6 s9))
+[GOOD] (define-fun s12 () Int (+ s7 s11))
+[GOOD] (define-fun s13 () Int (ite s5 s6 s12))
+[GOOD] (define-fun s14 () Int (abs s6))
+[GOOD] (define-fun s15 () Int (proj_1_SBVTuple2 s10))
+[GOOD] (define-fun s16 () Int (abs s15))
+[GOOD] (define-fun s17 () Bool (not s5))
+[GOOD] (define-fun s18 () Bool (> s14 s16))
+[GOOD] (define-fun s19 () Bool (=> s17 s18))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s19))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s14))
+[RECV] ((s14 0))
+[SEND] (get-value (s16))
+[RECV] ((s16 0))
+[SEND] (get-value (s0))
+[RECV] ((s0 (mkSBVTuple2 0 (seq.unit 4))))
+[SEND] (get-value (s11))
+[RECV] ((s11 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): abs arg1._1 failed strict decrease: Falsifiable. Counter-example:
+  arg    = (0,[4]) :: (Integer, [Integer])
+  before =       0 :: Integer
+  then   =       0 :: Integer
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): trying next candidate..
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): trying length arg1._2
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (- s4 s2))
+[GOOD] (define-fun s9 () (Seq Int) (seq.extract s3 s2 s8))
+[GOOD] (define-fun s10 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s6 s9))
+[GOOD] (define-fun s12 () Int (+ s7 s11))
+[GOOD] (define-fun s13 () Int (ite s5 s6 s12))
+[GOOD] (define-fun s14 () Bool (>= s4 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (- s4 s2))
+[GOOD] (define-fun s9 () (Seq Int) (seq.extract s3 s2 s8))
+[GOOD] (define-fun s10 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s6 s9))
+[GOOD] (define-fun s12 () Int (+ s7 s11))
+[GOOD] (define-fun s13 () Int (ite s5 s6 s12))
+[GOOD] (define-fun s14 () (Seq Int) (proj_2_SBVTuple2 s10))
+[GOOD] (define-fun s15 () Int (seq.len s14))
+[GOOD] (define-fun s16 () Bool (not s5))
+[GOOD] (define-fun s17 () Bool (> s4 s15))
+[GOOD] (define-fun s18 () Bool (=> s16 s17))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s18))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): length arg1._2 -> OK
+[MEASURE] Passed (terminating): sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/lambda20.gold b/SBVTestSuite/GoldFiles/lambda20.gold
--- a/SBVTestSuite/GoldFiles/lambda20.gold
+++ b/SBVTestSuite/GoldFiles/lambda20.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer)
+[MEASURE] Checking: sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer)
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer): barified = "|sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer)|"
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer): Uninterpreted ops in DAG: [("|sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer)|",1)]
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer): recursive calls found = 1
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer): trying abs arg1._1
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer)}: replaying 11 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +16,215 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (- s4 s2))
+[GOOD] (define-fun s9 () (Seq Int) (seq.extract s3 s2 s8))
+[GOOD] (define-fun s10 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s6 s9))
+[GOOD] (define-fun s12 () Int (* s7 s11))
+[GOOD] (define-fun s13 () Int (ite s5 s6 s12))
+[GOOD] (define-fun s14 () Int (abs s6))
+[GOOD] (define-fun s15 () Bool (>= s14 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s15))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer)}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (- s4 s2))
+[GOOD] (define-fun s9 () (Seq Int) (seq.extract s3 s2 s8))
+[GOOD] (define-fun s10 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s6 s9))
+[GOOD] (define-fun s12 () Int (* s7 s11))
+[GOOD] (define-fun s13 () Int (ite s5 s6 s12))
+[GOOD] (define-fun s14 () Int (abs s6))
+[GOOD] (define-fun s15 () Int (proj_1_SBVTuple2 s10))
+[GOOD] (define-fun s16 () Int (abs s15))
+[GOOD] (define-fun s17 () Bool (not s5))
+[GOOD] (define-fun s18 () Bool (> s14 s16))
+[GOOD] (define-fun s19 () Bool (=> s17 s18))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s19))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s14))
+[RECV] ((s14 0))
+[SEND] (get-value (s16))
+[RECV] ((s16 0))
+[SEND] (get-value (s0))
+[RECV] ((s0 (mkSBVTuple2 0 (seq.unit 4))))
+[SEND] (get-value (s11))
+[RECV] ((s11 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer): abs arg1._1 failed strict decrease: Falsifiable. Counter-example:
+  arg    = (0,[4]) :: (Integer, [Integer])
+  before =       0 :: Integer
+  then   =       0 :: Integer
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer): trying next candidate..
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer): trying length arg1._2
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer)}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (- s4 s2))
+[GOOD] (define-fun s9 () (Seq Int) (seq.extract s3 s2 s8))
+[GOOD] (define-fun s10 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s6 s9))
+[GOOD] (define-fun s12 () Int (* s7 s11))
+[GOOD] (define-fun s13 () Int (ite s5 s6 s12))
+[GOOD] (define-fun s14 () Bool (>= s4 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer)}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (- s4 s2))
+[GOOD] (define-fun s9 () (Seq Int) (seq.extract s3 s2 s8))
+[GOOD] (define-fun s10 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s6 s9))
+[GOOD] (define-fun s12 () Int (* s7 s11))
+[GOOD] (define-fun s13 () Int (ite s5 s6 s12))
+[GOOD] (define-fun s14 () (Seq Int) (proj_2_SBVTuple2 s10))
+[GOOD] (define-fun s15 () Int (seq.len s14))
+[GOOD] (define-fun s16 () Bool (not s5))
+[GOOD] (define-fun s17 () Bool (> s4 s15))
+[GOOD] (define-fun s18 () Bool (=> s16 s17))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s18))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer): length arg1._2 -> OK
+[MEASURE] Passed (terminating): sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_dd270bb7de @(SBV (Integer,[Integer]) -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/lambda21.gold b/SBVTestSuite/GoldFiles/lambda21.gold
--- a/SBVTestSuite/GoldFiles/lambda21.gold
+++ b/SBVTestSuite/GoldFiles/lambda21.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.foldr @(SBV (Integer,[Integer]) -> SBV [Integer])_5c3e05abf3 @(SBV ([Integer],[Integer]) -> SBV [Integer])
+[MEASURE] Checking: sbv.foldr @(SBV (Integer,[Integer]) -> SBV [Integer])_5c3e05abf3 @(SBV ([Integer],[Integer]) -> SBV [Integer])
+[MEASURE] sbv.foldr @(SBV (Integer,[Integer]) -> SBV [Integer])_5c3e05abf3 @(SBV ([Integer],[Integer]) -> SBV [Integer]): barified = "|sbv.foldr @(SBV (Integer,[Integer]) -> SBV [Integer])_5c3e05abf3 @(SBV ([Integer],[Integer]) -> SBV [Integer])|"
+[MEASURE] sbv.foldr @(SBV (Integer,[Integer]) -> SBV [Integer])_5c3e05abf3 @(SBV ([Integer],[Integer]) -> SBV [Integer]): Uninterpreted ops in DAG: [("|sbv.foldr @(SBV (Integer,[Integer]) -> SBV [Integer])_5c3e05abf3 @(SBV ([Integer],[Integer]) -> SBV [Integer])|",1)]
+[MEASURE] sbv.foldr @(SBV (Integer,[Integer]) -> SBV [Integer])_5c3e05abf3 @(SBV ([Integer],[Integer]) -> SBV [Integer]): recursive calls found = 1
+[MEASURE] sbv.foldr @(SBV (Integer,[Integer]) -> SBV [Integer])_5c3e05abf3 @(SBV ([Integer],[Integer]) -> SBV [Integer]): trying length arg1._1
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,[Integer]) -> SBV [Integer])_5c3e05abf3 @(SBV ([Integer],[Integer]) -> SBV [Integer])}: replaying 12 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +16,219 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 (Seq Int) (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s10 () (Seq Int)) ; tracks user variable "__internal_sbv_s10"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () (Seq Int) (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (- s4 s2))
+[GOOD] (define-fun s8 () (Seq Int) (seq.extract s3 s2 s7))
+[GOOD] (define-fun s9 () (SBVTuple2 (Seq Int) (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq Int))) s6 s8))
+[GOOD] (define-fun s11 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s12 () (Seq Int) (seq.unit s11))
+[GOOD] (define-fun s13 () (Seq Int) (seq.++ s10 s12))
+[GOOD] (define-fun s14 () (Seq Int) (ite s5 s6 s13))
+[GOOD] (define-fun s15 () Int (seq.len s6))
+[GOOD] (define-fun s16 () Bool (>= s15 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s16))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,[Integer]) -> SBV [Integer])_5c3e05abf3 @(SBV ([Integer],[Integer]) -> SBV [Integer])}: replaying 12 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 (Seq Int) (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s10 () (Seq Int)) ; tracks user variable "__internal_sbv_s10"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () (Seq Int) (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (- s4 s2))
+[GOOD] (define-fun s8 () (Seq Int) (seq.extract s3 s2 s7))
+[GOOD] (define-fun s9 () (SBVTuple2 (Seq Int) (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq Int))) s6 s8))
+[GOOD] (define-fun s11 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s12 () (Seq Int) (seq.unit s11))
+[GOOD] (define-fun s13 () (Seq Int) (seq.++ s10 s12))
+[GOOD] (define-fun s14 () (Seq Int) (ite s5 s6 s13))
+[GOOD] (define-fun s15 () Int (seq.len s6))
+[GOOD] (define-fun s16 () (Seq Int) (proj_1_SBVTuple2 s9))
+[GOOD] (define-fun s17 () Int (seq.len s16))
+[GOOD] (define-fun s18 () Bool (not s5))
+[GOOD] (define-fun s19 () Bool (> s15 s17))
+[GOOD] (define-fun s20 () Bool (=> s18 s19))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s20))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s15))
+[RECV] ((s15 0))
+[SEND] (get-value (s17))
+[RECV] ((s17 0))
+[SEND] (get-value (s0))
+[RECV] ((s0 (mkSBVTuple2 (as seq.empty (Seq Int)) (seq.unit 4))))
+[SEND] (get-value (s10))
+[RECV] ((s10 (as seq.empty (Seq Int))))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.foldr @(SBV (Integer,[Integer]) -> SBV [Integer])_5c3e05abf3 @(SBV ([Integer],[Integer]) -> SBV [Integer]): length arg1._1 failed strict decrease: Falsifiable. Counter-example:
+  arg    = ([],[4]) :: ([Integer], [Integer])
+  before =        0 :: Integer
+  then   =        0 :: Integer
+[MEASURE] sbv.foldr @(SBV (Integer,[Integer]) -> SBV [Integer])_5c3e05abf3 @(SBV ([Integer],[Integer]) -> SBV [Integer]): trying next candidate..
+[MEASURE] sbv.foldr @(SBV (Integer,[Integer]) -> SBV [Integer])_5c3e05abf3 @(SBV ([Integer],[Integer]) -> SBV [Integer]): trying length arg1._2
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,[Integer]) -> SBV [Integer])_5c3e05abf3 @(SBV ([Integer],[Integer]) -> SBV [Integer])}: replaying 12 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 (Seq Int) (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s10 () (Seq Int)) ; tracks user variable "__internal_sbv_s10"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () (Seq Int) (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (- s4 s2))
+[GOOD] (define-fun s8 () (Seq Int) (seq.extract s3 s2 s7))
+[GOOD] (define-fun s9 () (SBVTuple2 (Seq Int) (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq Int))) s6 s8))
+[GOOD] (define-fun s11 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s12 () (Seq Int) (seq.unit s11))
+[GOOD] (define-fun s13 () (Seq Int) (seq.++ s10 s12))
+[GOOD] (define-fun s14 () (Seq Int) (ite s5 s6 s13))
+[GOOD] (define-fun s15 () Bool (>= s4 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s15))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,[Integer]) -> SBV [Integer])_5c3e05abf3 @(SBV ([Integer],[Integer]) -> SBV [Integer])}: replaying 12 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 (Seq Int) (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s10 () (Seq Int)) ; tracks user variable "__internal_sbv_s10"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () (Seq Int) (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (- s4 s2))
+[GOOD] (define-fun s8 () (Seq Int) (seq.extract s3 s2 s7))
+[GOOD] (define-fun s9 () (SBVTuple2 (Seq Int) (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq Int))) s6 s8))
+[GOOD] (define-fun s11 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s12 () (Seq Int) (seq.unit s11))
+[GOOD] (define-fun s13 () (Seq Int) (seq.++ s10 s12))
+[GOOD] (define-fun s14 () (Seq Int) (ite s5 s6 s13))
+[GOOD] (define-fun s15 () (Seq Int) (proj_2_SBVTuple2 s9))
+[GOOD] (define-fun s16 () Int (seq.len s15))
+[GOOD] (define-fun s17 () Bool (not s5))
+[GOOD] (define-fun s18 () Bool (> s4 s16))
+[GOOD] (define-fun s19 () Bool (=> s17 s18))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s19))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.foldr @(SBV (Integer,[Integer]) -> SBV [Integer])_5c3e05abf3 @(SBV ([Integer],[Integer]) -> SBV [Integer]): length arg1._2 -> OK
+[MEASURE] Passed (terminating): sbv.foldr @(SBV (Integer,[Integer]) -> SBV [Integer])_5c3e05abf3 @(SBV ([Integer],[Integer]) -> SBV [Integer])
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/lambda22.gold b/SBVTestSuite/GoldFiles/lambda22.gold
--- a/SBVTestSuite/GoldFiles/lambda22.gold
+++ b/SBVTestSuite/GoldFiles/lambda22.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])
+[MEASURE] Checking: sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])
+[MEASURE] sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)]): barified = "|sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])|"
+[MEASURE] sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)]): Uninterpreted ops in DAG: [("|sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])|",2)]
+[MEASURE] sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)]): recursive calls found = 1
+[MEASURE] sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)]): trying length arg1
+[MEASURE] replayDAG {sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])}: replaying 16 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,13 +16,124 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
                                                          (proj_2_SBVTuple2 T2))))))
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] (define-fun s4 () (Seq (SBVTuple2 Int Int)) (as seq.empty (Seq (SBVTuple2 Int Int))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () (Seq Int)) ; tracks user variable "arg1"
+[GOOD] (declare-fun s17 () (Seq (SBVTuple2 Int Int))) ; tracks user variable "__internal_sbv_s17"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s5 () Int (seq.len s0))
+[GOOD] (define-fun s6 () Bool (= s2 s5))
+[GOOD] (define-fun s7 () Int (seq.len s1))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s9 () Int (seq.nth s0 s2))
+[GOOD] (define-fun s10 () Int (seq.nth s1 s2))
+[GOOD] (define-fun s11 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s9 s10))
+[GOOD] (define-fun s12 () (Seq (SBVTuple2 Int Int)) (seq.unit s11))
+[GOOD] (define-fun s13 () Int (- s5 s3))
+[GOOD] (define-fun s14 () (Seq Int) (seq.extract s0 s3 s13))
+[GOOD] (define-fun s15 () Int (- s7 s3))
+[GOOD] (define-fun s16 () (Seq Int) (seq.extract s1 s3 s15))
+[GOOD] (define-fun s18 () (Seq (SBVTuple2 Int Int)) (seq.++ s12 s17))
+[GOOD] (define-fun s19 () (Seq (SBVTuple2 Int Int)) (ite s8 s4 s18))
+[GOOD] (define-fun s20 () (Seq (SBVTuple2 Int Int)) (ite s6 s4 s19))
+[GOOD] (define-fun s21 () Bool (>= s5 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])}: replaying 16 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] (define-fun s4 () (Seq (SBVTuple2 Int Int)) (as seq.empty (Seq (SBVTuple2 Int Int))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () (Seq Int)) ; tracks user variable "arg1"
+[GOOD] (declare-fun s17 () (Seq (SBVTuple2 Int Int))) ; tracks user variable "__internal_sbv_s17"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s5 () Int (seq.len s0))
+[GOOD] (define-fun s6 () Bool (= s2 s5))
+[GOOD] (define-fun s7 () Int (seq.len s1))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s9 () Int (seq.nth s0 s2))
+[GOOD] (define-fun s10 () Int (seq.nth s1 s2))
+[GOOD] (define-fun s11 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s9 s10))
+[GOOD] (define-fun s12 () (Seq (SBVTuple2 Int Int)) (seq.unit s11))
+[GOOD] (define-fun s13 () Int (- s5 s3))
+[GOOD] (define-fun s14 () (Seq Int) (seq.extract s0 s3 s13))
+[GOOD] (define-fun s15 () Int (- s7 s3))
+[GOOD] (define-fun s16 () (Seq Int) (seq.extract s1 s3 s15))
+[GOOD] (define-fun s18 () (Seq (SBVTuple2 Int Int)) (seq.++ s12 s17))
+[GOOD] (define-fun s19 () (Seq (SBVTuple2 Int Int)) (ite s8 s4 s18))
+[GOOD] (define-fun s20 () (Seq (SBVTuple2 Int Int)) (ite s6 s4 s19))
+[GOOD] (define-fun s21 () Int (seq.len s14))
+[GOOD] (define-fun s22 () Bool (not s8))
+[GOOD] (define-fun s23 () Bool (not s6))
+[GOOD] (define-fun s24 () Bool (and s22 s23))
+[GOOD] (define-fun s25 () Bool (> s5 s21))
+[GOOD] (define-fun s26 () Bool (=> s24 s25))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s26))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)]): length arg1 -> OK
+[MEASURE] Passed (terminating): sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
 [GOOD] (define-fun s3 () (Seq Int) (seq.++ (seq.unit 1) (seq.unit 2) (seq.unit 3) (seq.unit 4) (seq.unit 5) (seq.unit 6) (seq.unit 7) (seq.unit 8) (seq.unit 9) (seq.unit 10)))
 [GOOD] (define-fun s5 () (Seq Int) (seq.++ (seq.unit 11) (seq.unit 12) (seq.unit 13) (seq.unit 14) (seq.unit 15) (seq.unit 16) (seq.unit 17) (seq.unit 18) (seq.unit 19) (seq.unit 20)))
 [GOOD] ; --- top level inputs ---
@@ -29,24 +147,24 @@
 [GOOD] ; |sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])| :: [SInteger] -> [SInteger] -> [(SInteger, SInteger)] [Recursive]
 [GOOD] (define-fun-rec |sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])| ((l1_s0 (Seq Int)) (l1_s1 (Seq Int))) (Seq (SBVTuple2 Int Int))
                                  (let ((l1_s3 0))
-                                 (let ((l1_s8 (as seq.empty (Seq (SBVTuple2 Int Int)))))
-                                 (let ((l1_s13 1))
+                                 (let ((l1_s5 (as seq.empty (Seq (SBVTuple2 Int Int)))))
+                                 (let ((l1_s12 1))
                                  (let ((l1_s2 (seq.len l1_s0)))
                                  (let ((l1_s4 (= l1_s2 l1_s3)))
-                                 (let ((l1_s5 (seq.len l1_s1)))
-                                 (let ((l1_s6 (= l1_s3 l1_s5)))
-                                 (let ((l1_s7 (or l1_s4 l1_s6)))
-                                 (let ((l1_s9 (seq.nth l1_s0 l1_s3)))
-                                 (let ((l1_s10 (seq.nth l1_s1 l1_s3)))
-                                 (let ((l1_s11 ((as mkSBVTuple2 (SBVTuple2 Int Int)) l1_s9 l1_s10)))
-                                 (let ((l1_s12 (seq.unit l1_s11)))
-                                 (let ((l1_s14 (- l1_s2 l1_s13)))
-                                 (let ((l1_s15 (seq.extract l1_s0 l1_s13 l1_s14)))
-                                 (let ((l1_s16 (- l1_s5 l1_s13)))
-                                 (let ((l1_s17 (seq.extract l1_s1 l1_s13 l1_s16)))
-                                 (let ((l1_s18 (|sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])| l1_s15 l1_s17)))
-                                 (let ((l1_s19 (seq.++ l1_s12 l1_s18)))
-                                 (let ((l1_s20 (ite l1_s7 l1_s8 l1_s19)))
+                                 (let ((l1_s6 (seq.len l1_s1)))
+                                 (let ((l1_s7 (= l1_s3 l1_s6)))
+                                 (let ((l1_s8 (seq.nth l1_s0 l1_s3)))
+                                 (let ((l1_s9 (seq.nth l1_s1 l1_s3)))
+                                 (let ((l1_s10 ((as mkSBVTuple2 (SBVTuple2 Int Int)) l1_s8 l1_s9)))
+                                 (let ((l1_s11 (seq.unit l1_s10)))
+                                 (let ((l1_s13 (- l1_s2 l1_s12)))
+                                 (let ((l1_s14 (seq.extract l1_s0 l1_s12 l1_s13)))
+                                 (let ((l1_s15 (- l1_s6 l1_s12)))
+                                 (let ((l1_s16 (seq.extract l1_s1 l1_s12 l1_s15)))
+                                 (let ((l1_s17 (|sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])| l1_s14 l1_s16)))
+                                 (let ((l1_s18 (seq.++ l1_s11 l1_s17)))
+                                 (let ((l1_s19 (ite l1_s7 l1_s5 l1_s18)))
+                                 (let ((l1_s20 (ite l1_s4 l1_s5 l1_s19)))
                                  l1_s20))))))))))))))))))))
 [GOOD] ; --- assignments ---
 [GOOD] (define-fun s4 () Bool (= s0 s3))
diff --git a/SBVTestSuite/GoldFiles/lambda23.gold b/SBVTestSuite/GoldFiles/lambda23.gold
--- a/SBVTestSuite/GoldFiles/lambda23.gold
+++ b/SBVTestSuite/GoldFiles/lambda23.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)]), sbv.map @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV [(Integer,Integer)] -> SBV [Integer]), sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)
+[MEASURE] Checking: sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])
+[MEASURE] sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)]): barified = "|sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])|"
+[MEASURE] sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)]): Uninterpreted ops in DAG: [("|sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])|",2)]
+[MEASURE] sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)]): recursive calls found = 1
+[MEASURE] sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)]): trying length arg1
+[MEASURE] replayDAG {sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])}: replaying 16 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,13 +16,445 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
                                                          (proj_2_SBVTuple2 T2))))))
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] (define-fun s4 () (Seq (SBVTuple2 Int Int)) (as seq.empty (Seq (SBVTuple2 Int Int))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () (Seq Int)) ; tracks user variable "arg1"
+[GOOD] (declare-fun s17 () (Seq (SBVTuple2 Int Int))) ; tracks user variable "__internal_sbv_s17"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s5 () Int (seq.len s0))
+[GOOD] (define-fun s6 () Bool (= s2 s5))
+[GOOD] (define-fun s7 () Int (seq.len s1))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s9 () Int (seq.nth s0 s2))
+[GOOD] (define-fun s10 () Int (seq.nth s1 s2))
+[GOOD] (define-fun s11 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s9 s10))
+[GOOD] (define-fun s12 () (Seq (SBVTuple2 Int Int)) (seq.unit s11))
+[GOOD] (define-fun s13 () Int (- s5 s3))
+[GOOD] (define-fun s14 () (Seq Int) (seq.extract s0 s3 s13))
+[GOOD] (define-fun s15 () Int (- s7 s3))
+[GOOD] (define-fun s16 () (Seq Int) (seq.extract s1 s3 s15))
+[GOOD] (define-fun s18 () (Seq (SBVTuple2 Int Int)) (seq.++ s12 s17))
+[GOOD] (define-fun s19 () (Seq (SBVTuple2 Int Int)) (ite s8 s4 s18))
+[GOOD] (define-fun s20 () (Seq (SBVTuple2 Int Int)) (ite s6 s4 s19))
+[GOOD] (define-fun s21 () Bool (>= s5 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])}: replaying 16 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] (define-fun s4 () (Seq (SBVTuple2 Int Int)) (as seq.empty (Seq (SBVTuple2 Int Int))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () (Seq Int)) ; tracks user variable "arg1"
+[GOOD] (declare-fun s17 () (Seq (SBVTuple2 Int Int))) ; tracks user variable "__internal_sbv_s17"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s5 () Int (seq.len s0))
+[GOOD] (define-fun s6 () Bool (= s2 s5))
+[GOOD] (define-fun s7 () Int (seq.len s1))
+[GOOD] (define-fun s8 () Bool (= s2 s7))
+[GOOD] (define-fun s9 () Int (seq.nth s0 s2))
+[GOOD] (define-fun s10 () Int (seq.nth s1 s2))
+[GOOD] (define-fun s11 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s9 s10))
+[GOOD] (define-fun s12 () (Seq (SBVTuple2 Int Int)) (seq.unit s11))
+[GOOD] (define-fun s13 () Int (- s5 s3))
+[GOOD] (define-fun s14 () (Seq Int) (seq.extract s0 s3 s13))
+[GOOD] (define-fun s15 () Int (- s7 s3))
+[GOOD] (define-fun s16 () (Seq Int) (seq.extract s1 s3 s15))
+[GOOD] (define-fun s18 () (Seq (SBVTuple2 Int Int)) (seq.++ s12 s17))
+[GOOD] (define-fun s19 () (Seq (SBVTuple2 Int Int)) (ite s8 s4 s18))
+[GOOD] (define-fun s20 () (Seq (SBVTuple2 Int Int)) (ite s6 s4 s19))
+[GOOD] (define-fun s21 () Int (seq.len s14))
+[GOOD] (define-fun s22 () Bool (not s8))
+[GOOD] (define-fun s23 () Bool (not s6))
+[GOOD] (define-fun s24 () Bool (and s22 s23))
+[GOOD] (define-fun s25 () Bool (> s5 s21))
+[GOOD] (define-fun s26 () Bool (=> s24 s25))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s26))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)]): length arg1 -> OK
+[MEASURE] Passed (terminating): sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])
+[MEASURE] Checking: sbv.map @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV [(Integer,Integer)] -> SBV [Integer])
+[MEASURE] sbv.map @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV [(Integer,Integer)] -> SBV [Integer]): barified = "|sbv.map @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV [(Integer,Integer)] -> SBV [Integer])|"
+[MEASURE] sbv.map @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV [(Integer,Integer)] -> SBV [Integer]): Uninterpreted ops in DAG: [("|sbv.map @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV [(Integer,Integer)] -> SBV [Integer])|",1)]
+[MEASURE] sbv.map @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV [(Integer,Integer)] -> SBV [Integer]): recursive calls found = 1
+[MEASURE] sbv.map @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV [(Integer,Integer)] -> SBV [Integer]): trying length arg1
+[MEASURE] replayDAG {sbv.map @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV [(Integer,Integer)] -> SBV [Integer])}: replaying 12 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 Int Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s13 () (Seq Int)) ; tracks user variable "__internal_sbv_s13"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () (SBVTuple2 Int Int) (seq.nth s0 s1))
+[GOOD] (define-fun s7 () Int (proj_1_SBVTuple2 s6))
+[GOOD] (define-fun s8 () Int (proj_2_SBVTuple2 s6))
+[GOOD] (define-fun s9 () Int (+ s7 s8))
+[GOOD] (define-fun s10 () (Seq Int) (seq.unit s9))
+[GOOD] (define-fun s11 () Int (- s4 s2))
+[GOOD] (define-fun s12 () (Seq (SBVTuple2 Int Int)) (seq.extract s0 s2 s11))
+[GOOD] (define-fun s14 () (Seq Int) (seq.++ s10 s13))
+[GOOD] (define-fun s15 () (Seq Int) (ite s5 s3 s14))
+[GOOD] (define-fun s16 () Bool (>= s4 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s16))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.map @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV [(Integer,Integer)] -> SBV [Integer])}: replaying 12 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (SBVTuple2 Int Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s13 () (Seq Int)) ; tracks user variable "__internal_sbv_s13"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () (SBVTuple2 Int Int) (seq.nth s0 s1))
+[GOOD] (define-fun s7 () Int (proj_1_SBVTuple2 s6))
+[GOOD] (define-fun s8 () Int (proj_2_SBVTuple2 s6))
+[GOOD] (define-fun s9 () Int (+ s7 s8))
+[GOOD] (define-fun s10 () (Seq Int) (seq.unit s9))
+[GOOD] (define-fun s11 () Int (- s4 s2))
+[GOOD] (define-fun s12 () (Seq (SBVTuple2 Int Int)) (seq.extract s0 s2 s11))
+[GOOD] (define-fun s14 () (Seq Int) (seq.++ s10 s13))
+[GOOD] (define-fun s15 () (Seq Int) (ite s5 s3 s14))
+[GOOD] (define-fun s16 () Int (seq.len s12))
+[GOOD] (define-fun s17 () Bool (not s5))
+[GOOD] (define-fun s18 () Bool (> s4 s16))
+[GOOD] (define-fun s19 () Bool (=> s17 s18))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s19))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.map @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV [(Integer,Integer)] -> SBV [Integer]): length arg1 -> OK
+[MEASURE] Passed (terminating): sbv.map @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV [(Integer,Integer)] -> SBV [Integer])
+[MEASURE] Checking: sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): barified = "|sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)|"
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): Uninterpreted ops in DAG: [("|sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)|",1)]
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): recursive calls found = 1
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): trying abs arg1._1
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (- s4 s2))
+[GOOD] (define-fun s9 () (Seq Int) (seq.extract s3 s2 s8))
+[GOOD] (define-fun s10 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s6 s9))
+[GOOD] (define-fun s12 () Int (+ s7 s11))
+[GOOD] (define-fun s13 () Int (ite s5 s6 s12))
+[GOOD] (define-fun s14 () Int (abs s6))
+[GOOD] (define-fun s15 () Bool (>= s14 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s15))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (- s4 s2))
+[GOOD] (define-fun s9 () (Seq Int) (seq.extract s3 s2 s8))
+[GOOD] (define-fun s10 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s6 s9))
+[GOOD] (define-fun s12 () Int (+ s7 s11))
+[GOOD] (define-fun s13 () Int (ite s5 s6 s12))
+[GOOD] (define-fun s14 () Int (abs s6))
+[GOOD] (define-fun s15 () Int (proj_1_SBVTuple2 s10))
+[GOOD] (define-fun s16 () Int (abs s15))
+[GOOD] (define-fun s17 () Bool (not s5))
+[GOOD] (define-fun s18 () Bool (> s14 s16))
+[GOOD] (define-fun s19 () Bool (=> s17 s18))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s19))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s14))
+[RECV] ((s14 0))
+[SEND] (get-value (s16))
+[RECV] ((s16 0))
+[SEND] (get-value (s0))
+[RECV] ((s0 (mkSBVTuple2 0 (seq.unit 4))))
+[SEND] (get-value (s11))
+[RECV] ((s11 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): abs arg1._1 failed strict decrease: Falsifiable. Counter-example:
+  arg    = (0,[4]) :: (Integer, [Integer])
+  before =       0 :: Integer
+  then   =       0 :: Integer
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): trying next candidate..
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): trying length arg1._2
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (- s4 s2))
+[GOOD] (define-fun s9 () (Seq Int) (seq.extract s3 s2 s8))
+[GOOD] (define-fun s10 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s6 s9))
+[GOOD] (define-fun s12 () Int (+ s7 s11))
+[GOOD] (define-fun s13 () Int (ite s5 s6 s12))
+[GOOD] (define-fun s14 () Bool (>= s4 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (- s4 s2))
+[GOOD] (define-fun s9 () (Seq Int) (seq.extract s3 s2 s8))
+[GOOD] (define-fun s10 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s6 s9))
+[GOOD] (define-fun s12 () Int (+ s7 s11))
+[GOOD] (define-fun s13 () Int (ite s5 s6 s12))
+[GOOD] (define-fun s14 () (Seq Int) (proj_2_SBVTuple2 s10))
+[GOOD] (define-fun s15 () Int (seq.len s14))
+[GOOD] (define-fun s16 () Bool (not s5))
+[GOOD] (define-fun s17 () Bool (> s4 s15))
+[GOOD] (define-fun s18 () Bool (=> s16 s17))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s18))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): length arg1._2 -> OK
+[MEASURE] Passed (terminating): sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
 [GOOD] (define-fun s3 () (Seq Int) (seq.++ (seq.unit 1) (seq.unit 2) (seq.unit 3) (seq.unit 4) (seq.unit 5) (seq.unit 6) (seq.unit 7) (seq.unit 8) (seq.unit 9) (seq.unit 10)))
 [GOOD] (define-fun s5 () (Seq Int) (seq.++ (seq.unit 10) (seq.unit 9) (seq.unit 8) (seq.unit 7) (seq.unit 6) (seq.unit 5) (seq.unit 4) (seq.unit 3) (seq.unit 2) (seq.unit 1)))
 [GOOD] (define-fun s7 () Int 0)
@@ -30,24 +469,24 @@
 [GOOD] ; |sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])| :: [SInteger] -> [SInteger] -> [(SInteger, SInteger)] [Recursive]
 [GOOD] (define-fun-rec |sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])| ((l1_s0 (Seq Int)) (l1_s1 (Seq Int))) (Seq (SBVTuple2 Int Int))
                                  (let ((l1_s3 0))
-                                 (let ((l1_s8 (as seq.empty (Seq (SBVTuple2 Int Int)))))
-                                 (let ((l1_s13 1))
+                                 (let ((l1_s5 (as seq.empty (Seq (SBVTuple2 Int Int)))))
+                                 (let ((l1_s12 1))
                                  (let ((l1_s2 (seq.len l1_s0)))
                                  (let ((l1_s4 (= l1_s2 l1_s3)))
-                                 (let ((l1_s5 (seq.len l1_s1)))
-                                 (let ((l1_s6 (= l1_s3 l1_s5)))
-                                 (let ((l1_s7 (or l1_s4 l1_s6)))
-                                 (let ((l1_s9 (seq.nth l1_s0 l1_s3)))
-                                 (let ((l1_s10 (seq.nth l1_s1 l1_s3)))
-                                 (let ((l1_s11 ((as mkSBVTuple2 (SBVTuple2 Int Int)) l1_s9 l1_s10)))
-                                 (let ((l1_s12 (seq.unit l1_s11)))
-                                 (let ((l1_s14 (- l1_s2 l1_s13)))
-                                 (let ((l1_s15 (seq.extract l1_s0 l1_s13 l1_s14)))
-                                 (let ((l1_s16 (- l1_s5 l1_s13)))
-                                 (let ((l1_s17 (seq.extract l1_s1 l1_s13 l1_s16)))
-                                 (let ((l1_s18 (|sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])| l1_s15 l1_s17)))
-                                 (let ((l1_s19 (seq.++ l1_s12 l1_s18)))
-                                 (let ((l1_s20 (ite l1_s7 l1_s8 l1_s19)))
+                                 (let ((l1_s6 (seq.len l1_s1)))
+                                 (let ((l1_s7 (= l1_s3 l1_s6)))
+                                 (let ((l1_s8 (seq.nth l1_s0 l1_s3)))
+                                 (let ((l1_s9 (seq.nth l1_s1 l1_s3)))
+                                 (let ((l1_s10 ((as mkSBVTuple2 (SBVTuple2 Int Int)) l1_s8 l1_s9)))
+                                 (let ((l1_s11 (seq.unit l1_s10)))
+                                 (let ((l1_s13 (- l1_s2 l1_s12)))
+                                 (let ((l1_s14 (seq.extract l1_s0 l1_s12 l1_s13)))
+                                 (let ((l1_s15 (- l1_s6 l1_s12)))
+                                 (let ((l1_s16 (seq.extract l1_s1 l1_s12 l1_s15)))
+                                 (let ((l1_s17 (|sbv.zip @(SBV [Integer] -> SBV [Integer] -> SBV [(Integer,Integer)])| l1_s14 l1_s16)))
+                                 (let ((l1_s18 (seq.++ l1_s11 l1_s17)))
+                                 (let ((l1_s19 (ite l1_s7 l1_s5 l1_s18)))
+                                 (let ((l1_s20 (ite l1_s4 l1_s5 l1_s19)))
                                  l1_s20))))))))))))))))))))
 [GOOD] ; |sbv.map @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV [(Integer,Integer)] -> SBV [Integer])| :: [(SInteger, SInteger)] -> [SInteger] [Recursive]
 [GOOD] (define-fun-rec |sbv.map @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV [(Integer,Integer)] -> SBV [Integer])| ((l1_s0 (Seq (SBVTuple2 Int Int)))) (Seq Int)
diff --git a/SBVTestSuite/GoldFiles/lambda24.gold b/SBVTestSuite/GoldFiles/lambda24.gold
--- a/SBVTestSuite/GoldFiles/lambda24.gold
+++ b/SBVTestSuite/GoldFiles/lambda24.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])
+[MEASURE] Checking: sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])
+[MEASURE] sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer]): barified = "|sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])|"
+[MEASURE] sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer]): Uninterpreted ops in DAG: [("|sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])|",1)]
+[MEASURE] sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer]): recursive calls found = 1
+[MEASURE] sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer]): trying length arg1._1
+[MEASURE] replayDAG {sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])}: replaying 19 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,13 +16,129 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
                                                          (proj_2_SBVTuple2 T2))))))
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 (Seq Int) (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s19 () (Seq Int)) ; tracks user variable "__internal_sbv_s19"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () (Seq Int) (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s5 () Int (seq.len s4))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s8 () Int (seq.len s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Int (seq.nth s4 s1))
+[GOOD] (define-fun s11 () Int (seq.nth s7 s1))
+[GOOD] (define-fun s12 () Int (+ s10 s11))
+[GOOD] (define-fun s13 () (Seq Int) (seq.unit s12))
+[GOOD] (define-fun s14 () Int (- s5 s2))
+[GOOD] (define-fun s15 () (Seq Int) (seq.extract s4 s2 s14))
+[GOOD] (define-fun s16 () Int (- s8 s2))
+[GOOD] (define-fun s17 () (Seq Int) (seq.extract s7 s2 s16))
+[GOOD] (define-fun s18 () (SBVTuple2 (Seq Int) (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq Int))) s15 s17))
+[GOOD] (define-fun s20 () (Seq Int) (seq.++ s13 s19))
+[GOOD] (define-fun s21 () (Seq Int) (ite s9 s3 s20))
+[GOOD] (define-fun s22 () (Seq Int) (ite s6 s3 s21))
+[GOOD] (define-fun s23 () Bool (>= s5 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s23))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])}: replaying 19 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 (Seq Int) (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s19 () (Seq Int)) ; tracks user variable "__internal_sbv_s19"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () (Seq Int) (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s5 () Int (seq.len s4))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s8 () Int (seq.len s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Int (seq.nth s4 s1))
+[GOOD] (define-fun s11 () Int (seq.nth s7 s1))
+[GOOD] (define-fun s12 () Int (+ s10 s11))
+[GOOD] (define-fun s13 () (Seq Int) (seq.unit s12))
+[GOOD] (define-fun s14 () Int (- s5 s2))
+[GOOD] (define-fun s15 () (Seq Int) (seq.extract s4 s2 s14))
+[GOOD] (define-fun s16 () Int (- s8 s2))
+[GOOD] (define-fun s17 () (Seq Int) (seq.extract s7 s2 s16))
+[GOOD] (define-fun s18 () (SBVTuple2 (Seq Int) (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq Int))) s15 s17))
+[GOOD] (define-fun s20 () (Seq Int) (seq.++ s13 s19))
+[GOOD] (define-fun s21 () (Seq Int) (ite s9 s3 s20))
+[GOOD] (define-fun s22 () (Seq Int) (ite s6 s3 s21))
+[GOOD] (define-fun s23 () (Seq Int) (proj_1_SBVTuple2 s18))
+[GOOD] (define-fun s24 () Int (seq.len s23))
+[GOOD] (define-fun s25 () Bool (not s9))
+[GOOD] (define-fun s26 () Bool (not s6))
+[GOOD] (define-fun s27 () Bool (and s25 s26))
+[GOOD] (define-fun s28 () Bool (> s5 s24))
+[GOOD] (define-fun s29 () Bool (=> s27 s28))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s29))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer]): length arg1._1 -> OK
+[MEASURE] Passed (terminating): sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
 [GOOD] (define-fun s3 () (Seq Int) (seq.++ (seq.unit 1) (seq.unit 2) (seq.unit 3) (seq.unit 4) (seq.unit 5) (seq.unit 6) (seq.unit 7) (seq.unit 8) (seq.unit 9) (seq.unit 10)))
 [GOOD] (define-fun s5 () (Seq Int) (seq.++ (seq.unit 11) (seq.unit 12) (seq.unit 13) (seq.unit 14) (seq.unit 15) (seq.unit 16) (seq.unit 17) (seq.unit 18) (seq.unit 19) (seq.unit 20)))
 [GOOD] ; --- top level inputs ---
@@ -29,27 +152,27 @@
 [GOOD] ; |sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])| :: ([SInteger], [SInteger]) -> [SInteger] [Recursive]
 [GOOD] (define-fun-rec |sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])| ((l1_s0 (SBVTuple2 (Seq Int) (Seq Int)))) (Seq Int)
                                  (let ((l1_s3 0))
-                                 (let ((l1_s9 (as seq.empty (Seq Int))))
-                                 (let ((l1_s14 1))
+                                 (let ((l1_s5 (as seq.empty (Seq Int))))
+                                 (let ((l1_s13 1))
                                  (let ((l1_s1 (proj_1_SBVTuple2 l1_s0)))
                                  (let ((l1_s2 (seq.len l1_s1)))
                                  (let ((l1_s4 (= l1_s2 l1_s3)))
-                                 (let ((l1_s5 (proj_2_SBVTuple2 l1_s0)))
-                                 (let ((l1_s6 (seq.len l1_s5)))
-                                 (let ((l1_s7 (= l1_s3 l1_s6)))
-                                 (let ((l1_s8 (or l1_s4 l1_s7)))
-                                 (let ((l1_s10 (seq.nth l1_s1 l1_s3)))
-                                 (let ((l1_s11 (seq.nth l1_s5 l1_s3)))
-                                 (let ((l1_s12 (+ l1_s10 l1_s11)))
-                                 (let ((l1_s13 (seq.unit l1_s12)))
-                                 (let ((l1_s15 (- l1_s2 l1_s14)))
-                                 (let ((l1_s16 (seq.extract l1_s1 l1_s14 l1_s15)))
-                                 (let ((l1_s17 (- l1_s6 l1_s14)))
-                                 (let ((l1_s18 (seq.extract l1_s5 l1_s14 l1_s17)))
-                                 (let ((l1_s19 ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq Int))) l1_s16 l1_s18)))
-                                 (let ((l1_s20 (|sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])| l1_s19)))
-                                 (let ((l1_s21 (seq.++ l1_s13 l1_s20)))
-                                 (let ((l1_s22 (ite l1_s8 l1_s9 l1_s21)))
+                                 (let ((l1_s6 (proj_2_SBVTuple2 l1_s0)))
+                                 (let ((l1_s7 (seq.len l1_s6)))
+                                 (let ((l1_s8 (= l1_s3 l1_s7)))
+                                 (let ((l1_s9 (seq.nth l1_s1 l1_s3)))
+                                 (let ((l1_s10 (seq.nth l1_s6 l1_s3)))
+                                 (let ((l1_s11 (+ l1_s9 l1_s10)))
+                                 (let ((l1_s12 (seq.unit l1_s11)))
+                                 (let ((l1_s14 (- l1_s2 l1_s13)))
+                                 (let ((l1_s15 (seq.extract l1_s1 l1_s13 l1_s14)))
+                                 (let ((l1_s16 (- l1_s7 l1_s13)))
+                                 (let ((l1_s17 (seq.extract l1_s6 l1_s13 l1_s16)))
+                                 (let ((l1_s18 ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq Int))) l1_s15 l1_s17)))
+                                 (let ((l1_s19 (|sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])| l1_s18)))
+                                 (let ((l1_s20 (seq.++ l1_s12 l1_s19)))
+                                 (let ((l1_s21 (ite l1_s8 l1_s5 l1_s20)))
+                                 (let ((l1_s22 (ite l1_s4 l1_s5 l1_s21)))
                                  l1_s22)))))))))))))))))))))))
 [GOOD] ; --- assignments ---
 [GOOD] (define-fun s4 () Bool (= s0 s3))
diff --git a/SBVTestSuite/GoldFiles/lambda25.gold b/SBVTestSuite/GoldFiles/lambda25.gold
--- a/SBVTestSuite/GoldFiles/lambda25.gold
+++ b/SBVTestSuite/GoldFiles/lambda25.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer]), sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)
+[MEASURE] Checking: sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])
+[MEASURE] sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer]): barified = "|sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])|"
+[MEASURE] sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer]): Uninterpreted ops in DAG: [("|sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])|",1)]
+[MEASURE] sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer]): recursive calls found = 1
+[MEASURE] sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer]): trying length arg1._1
+[MEASURE] replayDAG {sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])}: replaying 19 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,13 +16,344 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
                                                          (proj_2_SBVTuple2 T2))))))
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 (Seq Int) (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s19 () (Seq Int)) ; tracks user variable "__internal_sbv_s19"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () (Seq Int) (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s5 () Int (seq.len s4))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s8 () Int (seq.len s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Int (seq.nth s4 s1))
+[GOOD] (define-fun s11 () Int (seq.nth s7 s1))
+[GOOD] (define-fun s12 () Int (+ s10 s11))
+[GOOD] (define-fun s13 () (Seq Int) (seq.unit s12))
+[GOOD] (define-fun s14 () Int (- s5 s2))
+[GOOD] (define-fun s15 () (Seq Int) (seq.extract s4 s2 s14))
+[GOOD] (define-fun s16 () Int (- s8 s2))
+[GOOD] (define-fun s17 () (Seq Int) (seq.extract s7 s2 s16))
+[GOOD] (define-fun s18 () (SBVTuple2 (Seq Int) (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq Int))) s15 s17))
+[GOOD] (define-fun s20 () (Seq Int) (seq.++ s13 s19))
+[GOOD] (define-fun s21 () (Seq Int) (ite s9 s3 s20))
+[GOOD] (define-fun s22 () (Seq Int) (ite s6 s3 s21))
+[GOOD] (define-fun s23 () Bool (>= s5 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s23))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])}: replaying 19 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 (Seq Int) (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s19 () (Seq Int)) ; tracks user variable "__internal_sbv_s19"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () (Seq Int) (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s5 () Int (seq.len s4))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s8 () Int (seq.len s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Int (seq.nth s4 s1))
+[GOOD] (define-fun s11 () Int (seq.nth s7 s1))
+[GOOD] (define-fun s12 () Int (+ s10 s11))
+[GOOD] (define-fun s13 () (Seq Int) (seq.unit s12))
+[GOOD] (define-fun s14 () Int (- s5 s2))
+[GOOD] (define-fun s15 () (Seq Int) (seq.extract s4 s2 s14))
+[GOOD] (define-fun s16 () Int (- s8 s2))
+[GOOD] (define-fun s17 () (Seq Int) (seq.extract s7 s2 s16))
+[GOOD] (define-fun s18 () (SBVTuple2 (Seq Int) (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq Int))) s15 s17))
+[GOOD] (define-fun s20 () (Seq Int) (seq.++ s13 s19))
+[GOOD] (define-fun s21 () (Seq Int) (ite s9 s3 s20))
+[GOOD] (define-fun s22 () (Seq Int) (ite s6 s3 s21))
+[GOOD] (define-fun s23 () (Seq Int) (proj_1_SBVTuple2 s18))
+[GOOD] (define-fun s24 () Int (seq.len s23))
+[GOOD] (define-fun s25 () Bool (not s9))
+[GOOD] (define-fun s26 () Bool (not s6))
+[GOOD] (define-fun s27 () Bool (and s25 s26))
+[GOOD] (define-fun s28 () Bool (> s5 s24))
+[GOOD] (define-fun s29 () Bool (=> s27 s28))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s29))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer]): length arg1._1 -> OK
+[MEASURE] Passed (terminating): sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])
+[MEASURE] Checking: sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): barified = "|sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)|"
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): Uninterpreted ops in DAG: [("|sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)|",1)]
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): recursive calls found = 1
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): trying abs arg1._1
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (- s4 s2))
+[GOOD] (define-fun s9 () (Seq Int) (seq.extract s3 s2 s8))
+[GOOD] (define-fun s10 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s6 s9))
+[GOOD] (define-fun s12 () Int (+ s7 s11))
+[GOOD] (define-fun s13 () Int (ite s5 s6 s12))
+[GOOD] (define-fun s14 () Int (abs s6))
+[GOOD] (define-fun s15 () Bool (>= s14 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s15))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (- s4 s2))
+[GOOD] (define-fun s9 () (Seq Int) (seq.extract s3 s2 s8))
+[GOOD] (define-fun s10 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s6 s9))
+[GOOD] (define-fun s12 () Int (+ s7 s11))
+[GOOD] (define-fun s13 () Int (ite s5 s6 s12))
+[GOOD] (define-fun s14 () Int (abs s6))
+[GOOD] (define-fun s15 () Int (proj_1_SBVTuple2 s10))
+[GOOD] (define-fun s16 () Int (abs s15))
+[GOOD] (define-fun s17 () Bool (not s5))
+[GOOD] (define-fun s18 () Bool (> s14 s16))
+[GOOD] (define-fun s19 () Bool (=> s17 s18))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s19))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s14))
+[RECV] ((s14 0))
+[SEND] (get-value (s16))
+[RECV] ((s16 0))
+[SEND] (get-value (s0))
+[RECV] ((s0 (mkSBVTuple2 0 (seq.unit 4))))
+[SEND] (get-value (s11))
+[RECV] ((s11 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): abs arg1._1 failed strict decrease: Falsifiable. Counter-example:
+  arg    = (0,[4]) :: (Integer, [Integer])
+  before =       0 :: Integer
+  then   =       0 :: Integer
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): trying next candidate..
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): trying length arg1._2
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (- s4 s2))
+[GOOD] (define-fun s9 () (Seq Int) (seq.extract s3 s2 s8))
+[GOOD] (define-fun s10 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s6 s9))
+[GOOD] (define-fun s12 () Int (+ s7 s11))
+[GOOD] (define-fun s13 () Int (ite s5 s6 s12))
+[GOOD] (define-fun s14 () Bool (>= s4 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () Int (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (- s4 s2))
+[GOOD] (define-fun s9 () (Seq Int) (seq.extract s3 s2 s8))
+[GOOD] (define-fun s10 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s6 s9))
+[GOOD] (define-fun s12 () Int (+ s7 s11))
+[GOOD] (define-fun s13 () Int (ite s5 s6 s12))
+[GOOD] (define-fun s14 () (Seq Int) (proj_2_SBVTuple2 s10))
+[GOOD] (define-fun s15 () Int (seq.len s14))
+[GOOD] (define-fun s16 () Bool (not s5))
+[GOOD] (define-fun s17 () Bool (> s4 s15))
+[GOOD] (define-fun s18 () Bool (=> s16 s17))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s18))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer): length arg1._2 -> OK
+[MEASURE] Passed (terminating): sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
 [GOOD] (define-fun s3 () (Seq Int) (seq.++ (seq.unit 1) (seq.unit 2) (seq.unit 3) (seq.unit 4) (seq.unit 5) (seq.unit 6) (seq.unit 7) (seq.unit 8) (seq.unit 9) (seq.unit 10)))
 [GOOD] (define-fun s5 () (Seq Int) (seq.++ (seq.unit 10) (seq.unit 9) (seq.unit 8) (seq.unit 7) (seq.unit 6) (seq.unit 5) (seq.unit 4) (seq.unit 3) (seq.unit 2) (seq.unit 1)))
 [GOOD] (define-fun s7 () Int 0)
@@ -30,27 +368,27 @@
 [GOOD] ; |sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])| :: ([SInteger], [SInteger]) -> [SInteger] [Recursive]
 [GOOD] (define-fun-rec |sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])| ((l1_s0 (SBVTuple2 (Seq Int) (Seq Int)))) (Seq Int)
                                  (let ((l1_s3 0))
-                                 (let ((l1_s9 (as seq.empty (Seq Int))))
-                                 (let ((l1_s14 1))
+                                 (let ((l1_s5 (as seq.empty (Seq Int))))
+                                 (let ((l1_s13 1))
                                  (let ((l1_s1 (proj_1_SBVTuple2 l1_s0)))
                                  (let ((l1_s2 (seq.len l1_s1)))
                                  (let ((l1_s4 (= l1_s2 l1_s3)))
-                                 (let ((l1_s5 (proj_2_SBVTuple2 l1_s0)))
-                                 (let ((l1_s6 (seq.len l1_s5)))
-                                 (let ((l1_s7 (= l1_s3 l1_s6)))
-                                 (let ((l1_s8 (or l1_s4 l1_s7)))
-                                 (let ((l1_s10 (seq.nth l1_s1 l1_s3)))
-                                 (let ((l1_s11 (seq.nth l1_s5 l1_s3)))
-                                 (let ((l1_s12 (+ l1_s10 l1_s11)))
-                                 (let ((l1_s13 (seq.unit l1_s12)))
-                                 (let ((l1_s15 (- l1_s2 l1_s14)))
-                                 (let ((l1_s16 (seq.extract l1_s1 l1_s14 l1_s15)))
-                                 (let ((l1_s17 (- l1_s6 l1_s14)))
-                                 (let ((l1_s18 (seq.extract l1_s5 l1_s14 l1_s17)))
-                                 (let ((l1_s19 ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq Int))) l1_s16 l1_s18)))
-                                 (let ((l1_s20 (|sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])| l1_s19)))
-                                 (let ((l1_s21 (seq.++ l1_s13 l1_s20)))
-                                 (let ((l1_s22 (ite l1_s8 l1_s9 l1_s21)))
+                                 (let ((l1_s6 (proj_2_SBVTuple2 l1_s0)))
+                                 (let ((l1_s7 (seq.len l1_s6)))
+                                 (let ((l1_s8 (= l1_s3 l1_s7)))
+                                 (let ((l1_s9 (seq.nth l1_s1 l1_s3)))
+                                 (let ((l1_s10 (seq.nth l1_s6 l1_s3)))
+                                 (let ((l1_s11 (+ l1_s9 l1_s10)))
+                                 (let ((l1_s12 (seq.unit l1_s11)))
+                                 (let ((l1_s14 (- l1_s2 l1_s13)))
+                                 (let ((l1_s15 (seq.extract l1_s1 l1_s13 l1_s14)))
+                                 (let ((l1_s16 (- l1_s7 l1_s13)))
+                                 (let ((l1_s17 (seq.extract l1_s6 l1_s13 l1_s16)))
+                                 (let ((l1_s18 ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq Int))) l1_s15 l1_s17)))
+                                 (let ((l1_s19 (|sbv.zipWith @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV ([Integer],[Integer]) -> SBV [Integer])| l1_s18)))
+                                 (let ((l1_s20 (seq.++ l1_s12 l1_s19)))
+                                 (let ((l1_s21 (ite l1_s8 l1_s5 l1_s20)))
+                                 (let ((l1_s22 (ite l1_s4 l1_s5 l1_s21)))
                                  l1_s22)))))))))))))))))))))))
 [GOOD] ; |sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)| :: (SInteger, [SInteger]) -> SInteger [Recursive]
 [GOOD] (define-fun-rec |sbv.foldr @(SBV (Integer,Integer) -> SBV Integer)_1fd06f7602 @(SBV (Integer,[Integer]) -> SBV Integer)| ((l1_s0 (SBVTuple2 Int (Seq Int)))) Int
diff --git a/SBVTestSuite/GoldFiles/lambda26.gold b/SBVTestSuite/GoldFiles/lambda26.gold
--- a/SBVTestSuite/GoldFiles/lambda26.gold
+++ b/SBVTestSuite/GoldFiles/lambda26.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.foldr @(SBV ([Integer],[Integer]) -> SBV [Integer])_44d71053fc @(SBV ([Integer],[[Integer]]) -> SBV [Integer])
+[MEASURE] Checking: sbv.foldr @(SBV ([Integer],[Integer]) -> SBV [Integer])_44d71053fc @(SBV ([Integer],[[Integer]]) -> SBV [Integer])
+[MEASURE] sbv.foldr @(SBV ([Integer],[Integer]) -> SBV [Integer])_44d71053fc @(SBV ([Integer],[[Integer]]) -> SBV [Integer]): barified = "|sbv.foldr @(SBV ([Integer],[Integer]) -> SBV [Integer])_44d71053fc @(SBV ([Integer],[[Integer]]) -> SBV [Integer])|"
+[MEASURE] sbv.foldr @(SBV ([Integer],[Integer]) -> SBV [Integer])_44d71053fc @(SBV ([Integer],[[Integer]]) -> SBV [Integer]): Uninterpreted ops in DAG: [("|sbv.foldr @(SBV ([Integer],[Integer]) -> SBV [Integer])_44d71053fc @(SBV ([Integer],[[Integer]]) -> SBV [Integer])|",1)]
+[MEASURE] sbv.foldr @(SBV ([Integer],[Integer]) -> SBV [Integer])_44d71053fc @(SBV ([Integer],[[Integer]]) -> SBV [Integer]): recursive calls found = 1
+[MEASURE] sbv.foldr @(SBV ([Integer],[Integer]) -> SBV [Integer])_44d71053fc @(SBV ([Integer],[[Integer]]) -> SBV [Integer]): trying length arg1._1
+[MEASURE] replayDAG {sbv.foldr @(SBV ([Integer],[Integer]) -> SBV [Integer])_44d71053fc @(SBV ([Integer],[[Integer]]) -> SBV [Integer])}: replaying 11 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +16,215 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 (Seq Int) (Seq (Seq Int)))) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () (Seq Int)) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq (Seq Int)) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () (Seq Int) (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () (Seq Int) (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (- s4 s2))
+[GOOD] (define-fun s9 () (Seq (Seq Int)) (seq.extract s3 s2 s8))
+[GOOD] (define-fun s10 () (SBVTuple2 (Seq Int) (Seq (Seq Int))) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq (Seq Int)))) s6 s9))
+[GOOD] (define-fun s12 () (Seq Int) (seq.++ s7 s11))
+[GOOD] (define-fun s13 () (Seq Int) (ite s5 s6 s12))
+[GOOD] (define-fun s14 () Int (seq.len s6))
+[GOOD] (define-fun s15 () Bool (>= s14 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s15))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.foldr @(SBV ([Integer],[Integer]) -> SBV [Integer])_44d71053fc @(SBV ([Integer],[[Integer]]) -> SBV [Integer])}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 (Seq Int) (Seq (Seq Int)))) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () (Seq Int)) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq (Seq Int)) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () (Seq Int) (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () (Seq Int) (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (- s4 s2))
+[GOOD] (define-fun s9 () (Seq (Seq Int)) (seq.extract s3 s2 s8))
+[GOOD] (define-fun s10 () (SBVTuple2 (Seq Int) (Seq (Seq Int))) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq (Seq Int)))) s6 s9))
+[GOOD] (define-fun s12 () (Seq Int) (seq.++ s7 s11))
+[GOOD] (define-fun s13 () (Seq Int) (ite s5 s6 s12))
+[GOOD] (define-fun s14 () Int (seq.len s6))
+[GOOD] (define-fun s15 () (Seq Int) (proj_1_SBVTuple2 s10))
+[GOOD] (define-fun s16 () Int (seq.len s15))
+[GOOD] (define-fun s17 () Bool (not s5))
+[GOOD] (define-fun s18 () Bool (> s14 s16))
+[GOOD] (define-fun s19 () Bool (=> s17 s18))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s19))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s14))
+[RECV] ((s14 0))
+[SEND] (get-value (s16))
+[RECV] ((s16 0))
+[SEND] (get-value (s0))
+[RECV] ((s0 (mkSBVTuple2 (as seq.empty (Seq Int)) (seq.unit (seq.unit 2)))))
+[SEND] (get-value (s11))
+[RECV] ((s11 (as seq.empty (Seq Int))))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.foldr @(SBV ([Integer],[Integer]) -> SBV [Integer])_44d71053fc @(SBV ([Integer],[[Integer]]) -> SBV [Integer]): length arg1._1 failed strict decrease: Falsifiable. Counter-example:
+  arg    = ([],[[2]]) :: ([Integer], [[Integer]])
+  before =          0 :: Integer
+  then   =          0 :: Integer
+[MEASURE] sbv.foldr @(SBV ([Integer],[Integer]) -> SBV [Integer])_44d71053fc @(SBV ([Integer],[[Integer]]) -> SBV [Integer]): trying next candidate..
+[MEASURE] sbv.foldr @(SBV ([Integer],[Integer]) -> SBV [Integer])_44d71053fc @(SBV ([Integer],[[Integer]]) -> SBV [Integer]): trying length arg1._2
+[MEASURE] replayDAG {sbv.foldr @(SBV ([Integer],[Integer]) -> SBV [Integer])_44d71053fc @(SBV ([Integer],[[Integer]]) -> SBV [Integer])}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 (Seq Int) (Seq (Seq Int)))) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () (Seq Int)) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq (Seq Int)) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () (Seq Int) (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () (Seq Int) (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (- s4 s2))
+[GOOD] (define-fun s9 () (Seq (Seq Int)) (seq.extract s3 s2 s8))
+[GOOD] (define-fun s10 () (SBVTuple2 (Seq Int) (Seq (Seq Int))) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq (Seq Int)))) s6 s9))
+[GOOD] (define-fun s12 () (Seq Int) (seq.++ s7 s11))
+[GOOD] (define-fun s13 () (Seq Int) (ite s5 s6 s12))
+[GOOD] (define-fun s14 () Bool (>= s4 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.foldr @(SBV ([Integer],[Integer]) -> SBV [Integer])_44d71053fc @(SBV ([Integer],[[Integer]]) -> SBV [Integer])}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 (Seq Int) (Seq (Seq Int)))) ; tracks user variable "arg"
+[GOOD] (declare-fun s11 () (Seq Int)) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq (Seq Int)) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () (Seq Int) (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s7 () (Seq Int) (seq.nth s3 s1))
+[GOOD] (define-fun s8 () Int (- s4 s2))
+[GOOD] (define-fun s9 () (Seq (Seq Int)) (seq.extract s3 s2 s8))
+[GOOD] (define-fun s10 () (SBVTuple2 (Seq Int) (Seq (Seq Int))) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq (Seq Int)))) s6 s9))
+[GOOD] (define-fun s12 () (Seq Int) (seq.++ s7 s11))
+[GOOD] (define-fun s13 () (Seq Int) (ite s5 s6 s12))
+[GOOD] (define-fun s14 () (Seq (Seq Int)) (proj_2_SBVTuple2 s10))
+[GOOD] (define-fun s15 () Int (seq.len s14))
+[GOOD] (define-fun s16 () Bool (not s5))
+[GOOD] (define-fun s17 () Bool (> s4 s15))
+[GOOD] (define-fun s18 () Bool (=> s16 s17))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s18))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.foldr @(SBV ([Integer],[Integer]) -> SBV [Integer])_44d71053fc @(SBV ([Integer],[[Integer]]) -> SBV [Integer]): length arg1._2 -> OK
+[MEASURE] Passed (terminating): sbv.foldr @(SBV ([Integer],[Integer]) -> SBV [Integer])_44d71053fc @(SBV ([Integer],[[Integer]]) -> SBV [Integer])
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/lambda27.gold b/SBVTestSuite/GoldFiles/lambda27.gold
--- a/SBVTestSuite/GoldFiles/lambda27.gold
+++ b/SBVTestSuite/GoldFiles/lambda27.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_574b56f8c4 @(SBV (Bool,[Integer]) -> SBV Bool)
+[MEASURE] Checking: sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_574b56f8c4 @(SBV (Bool,[Integer]) -> SBV Bool)
+[MEASURE] sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_574b56f8c4 @(SBV (Bool,[Integer]) -> SBV Bool): barified = "|sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_574b56f8c4 @(SBV (Bool,[Integer]) -> SBV Bool)|"
+[MEASURE] sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_574b56f8c4 @(SBV (Bool,[Integer]) -> SBV Bool): Uninterpreted ops in DAG: [("|sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_574b56f8c4 @(SBV (Bool,[Integer]) -> SBV Bool)|",1)]
+[MEASURE] sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_574b56f8c4 @(SBV (Bool,[Integer]) -> SBV Bool): recursive calls found = 1
+[MEASURE] sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_574b56f8c4 @(SBV (Bool,[Integer]) -> SBV Bool): trying length arg1._2
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_574b56f8c4 @(SBV (Bool,[Integer]) -> SBV Bool)}: replaying 13 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +16,110 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Bool (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s14 () Bool) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s5 () Int (seq.len s4))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () Bool (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s8 () Int (seq.nth s4 s1))
+[GOOD] (define-fun s9 () Int (mod s8 s3))
+[GOOD] (define-fun s10 () Bool (= s1 s9))
+[GOOD] (define-fun s11 () Int (- s5 s2))
+[GOOD] (define-fun s12 () (Seq Int) (seq.extract s4 s2 s11))
+[GOOD] (define-fun s13 () (SBVTuple2 Bool (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Bool (Seq Int))) s7 s12))
+[GOOD] (define-fun s15 () Bool (and s10 s14))
+[GOOD] (define-fun s16 () Bool (ite s6 s7 s15))
+[GOOD] (define-fun s17 () Bool (>= s5 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_574b56f8c4 @(SBV (Bool,[Integer]) -> SBV Bool)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Bool (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s14 () Bool) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s5 () Int (seq.len s4))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () Bool (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s8 () Int (seq.nth s4 s1))
+[GOOD] (define-fun s9 () Int (mod s8 s3))
+[GOOD] (define-fun s10 () Bool (= s1 s9))
+[GOOD] (define-fun s11 () Int (- s5 s2))
+[GOOD] (define-fun s12 () (Seq Int) (seq.extract s4 s2 s11))
+[GOOD] (define-fun s13 () (SBVTuple2 Bool (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Bool (Seq Int))) s7 s12))
+[GOOD] (define-fun s15 () Bool (and s10 s14))
+[GOOD] (define-fun s16 () Bool (ite s6 s7 s15))
+[GOOD] (define-fun s17 () (Seq Int) (proj_2_SBVTuple2 s13))
+[GOOD] (define-fun s18 () Int (seq.len s17))
+[GOOD] (define-fun s19 () Bool (not s6))
+[GOOD] (define-fun s20 () Bool (and s10 s19))
+[GOOD] (define-fun s21 () Bool (> s5 s18))
+[GOOD] (define-fun s22 () Bool (=> s20 s21))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s22))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_574b56f8c4 @(SBV (Bool,[Integer]) -> SBV Bool): length arg1._2 -> OK
+[MEASURE] Passed (terminating): sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_574b56f8c4 @(SBV (Bool,[Integer]) -> SBV Bool)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/lambda28.gold b/SBVTestSuite/GoldFiles/lambda28.gold
--- a/SBVTestSuite/GoldFiles/lambda28.gold
+++ b/SBVTestSuite/GoldFiles/lambda28.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_574b56f8c4 @(SBV (Bool,[Integer]) -> SBV Bool)
+[MEASURE] Checking: sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_574b56f8c4 @(SBV (Bool,[Integer]) -> SBV Bool)
+[MEASURE] sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_574b56f8c4 @(SBV (Bool,[Integer]) -> SBV Bool): barified = "|sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_574b56f8c4 @(SBV (Bool,[Integer]) -> SBV Bool)|"
+[MEASURE] sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_574b56f8c4 @(SBV (Bool,[Integer]) -> SBV Bool): Uninterpreted ops in DAG: [("|sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_574b56f8c4 @(SBV (Bool,[Integer]) -> SBV Bool)|",1)]
+[MEASURE] sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_574b56f8c4 @(SBV (Bool,[Integer]) -> SBV Bool): recursive calls found = 1
+[MEASURE] sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_574b56f8c4 @(SBV (Bool,[Integer]) -> SBV Bool): trying length arg1._2
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_574b56f8c4 @(SBV (Bool,[Integer]) -> SBV Bool)}: replaying 13 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +16,110 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Bool (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s14 () Bool) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s5 () Int (seq.len s4))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () Bool (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s8 () Int (seq.nth s4 s1))
+[GOOD] (define-fun s9 () Int (mod s8 s3))
+[GOOD] (define-fun s10 () Bool (= s1 s9))
+[GOOD] (define-fun s11 () Int (- s5 s2))
+[GOOD] (define-fun s12 () (Seq Int) (seq.extract s4 s2 s11))
+[GOOD] (define-fun s13 () (SBVTuple2 Bool (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Bool (Seq Int))) s7 s12))
+[GOOD] (define-fun s15 () Bool (and s10 s14))
+[GOOD] (define-fun s16 () Bool (ite s6 s7 s15))
+[GOOD] (define-fun s17 () Bool (>= s5 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_574b56f8c4 @(SBV (Bool,[Integer]) -> SBV Bool)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Bool (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s14 () Bool) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s5 () Int (seq.len s4))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () Bool (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s8 () Int (seq.nth s4 s1))
+[GOOD] (define-fun s9 () Int (mod s8 s3))
+[GOOD] (define-fun s10 () Bool (= s1 s9))
+[GOOD] (define-fun s11 () Int (- s5 s2))
+[GOOD] (define-fun s12 () (Seq Int) (seq.extract s4 s2 s11))
+[GOOD] (define-fun s13 () (SBVTuple2 Bool (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Bool (Seq Int))) s7 s12))
+[GOOD] (define-fun s15 () Bool (and s10 s14))
+[GOOD] (define-fun s16 () Bool (ite s6 s7 s15))
+[GOOD] (define-fun s17 () (Seq Int) (proj_2_SBVTuple2 s13))
+[GOOD] (define-fun s18 () Int (seq.len s17))
+[GOOD] (define-fun s19 () Bool (not s6))
+[GOOD] (define-fun s20 () Bool (and s10 s19))
+[GOOD] (define-fun s21 () Bool (> s5 s18))
+[GOOD] (define-fun s22 () Bool (=> s20 s21))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s22))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_574b56f8c4 @(SBV (Bool,[Integer]) -> SBV Bool): length arg1._2 -> OK
+[MEASURE] Passed (terminating): sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_574b56f8c4 @(SBV (Bool,[Integer]) -> SBV Bool)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/lambda29.gold b/SBVTestSuite/GoldFiles/lambda29.gold
--- a/SBVTestSuite/GoldFiles/lambda29.gold
+++ b/SBVTestSuite/GoldFiles/lambda29.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_01257e6724 @(SBV (Bool,[Integer]) -> SBV Bool)
+[MEASURE] Checking: sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_01257e6724 @(SBV (Bool,[Integer]) -> SBV Bool)
+[MEASURE] sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_01257e6724 @(SBV (Bool,[Integer]) -> SBV Bool): barified = "|sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_01257e6724 @(SBV (Bool,[Integer]) -> SBV Bool)|"
+[MEASURE] sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_01257e6724 @(SBV (Bool,[Integer]) -> SBV Bool): Uninterpreted ops in DAG: [("|sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_01257e6724 @(SBV (Bool,[Integer]) -> SBV Bool)|",1)]
+[MEASURE] sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_01257e6724 @(SBV (Bool,[Integer]) -> SBV Bool): recursive calls found = 1
+[MEASURE] sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_01257e6724 @(SBV (Bool,[Integer]) -> SBV Bool): trying length arg1._2
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_01257e6724 @(SBV (Bool,[Integer]) -> SBV Bool)}: replaying 13 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +16,111 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Bool (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s14 () Bool) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s5 () Int (seq.len s4))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () Bool (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s8 () Int (seq.nth s4 s1))
+[GOOD] (define-fun s9 () Int (mod s8 s3))
+[GOOD] (define-fun s10 () Bool (distinct s1 s9))
+[GOOD] (define-fun s11 () Int (- s5 s2))
+[GOOD] (define-fun s12 () (Seq Int) (seq.extract s4 s2 s11))
+[GOOD] (define-fun s13 () (SBVTuple2 Bool (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Bool (Seq Int))) s7 s12))
+[GOOD] (define-fun s15 () Bool (or s10 s14))
+[GOOD] (define-fun s16 () Bool (ite s6 s7 s15))
+[GOOD] (define-fun s17 () Bool (>= s5 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_01257e6724 @(SBV (Bool,[Integer]) -> SBV Bool)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Bool (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s14 () Bool) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s5 () Int (seq.len s4))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () Bool (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s8 () Int (seq.nth s4 s1))
+[GOOD] (define-fun s9 () Int (mod s8 s3))
+[GOOD] (define-fun s10 () Bool (distinct s1 s9))
+[GOOD] (define-fun s11 () Int (- s5 s2))
+[GOOD] (define-fun s12 () (Seq Int) (seq.extract s4 s2 s11))
+[GOOD] (define-fun s13 () (SBVTuple2 Bool (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Bool (Seq Int))) s7 s12))
+[GOOD] (define-fun s15 () Bool (or s10 s14))
+[GOOD] (define-fun s16 () Bool (ite s6 s7 s15))
+[GOOD] (define-fun s17 () (Seq Int) (proj_2_SBVTuple2 s13))
+[GOOD] (define-fun s18 () Int (seq.len s17))
+[GOOD] (define-fun s19 () Bool (not s10))
+[GOOD] (define-fun s20 () Bool (not s6))
+[GOOD] (define-fun s21 () Bool (and s19 s20))
+[GOOD] (define-fun s22 () Bool (> s5 s18))
+[GOOD] (define-fun s23 () Bool (=> s21 s22))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s23))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_01257e6724 @(SBV (Bool,[Integer]) -> SBV Bool): length arg1._2 -> OK
+[MEASURE] Passed (terminating): sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_01257e6724 @(SBV (Bool,[Integer]) -> SBV Bool)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/lambda30.gold b/SBVTestSuite/GoldFiles/lambda30.gold
--- a/SBVTestSuite/GoldFiles/lambda30.gold
+++ b/SBVTestSuite/GoldFiles/lambda30.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_7182762f14 @(SBV (Bool,[Integer]) -> SBV Bool)
+[MEASURE] Checking: sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_7182762f14 @(SBV (Bool,[Integer]) -> SBV Bool)
+[MEASURE] sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_7182762f14 @(SBV (Bool,[Integer]) -> SBV Bool): barified = "|sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_7182762f14 @(SBV (Bool,[Integer]) -> SBV Bool)|"
+[MEASURE] sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_7182762f14 @(SBV (Bool,[Integer]) -> SBV Bool): Uninterpreted ops in DAG: [("|sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_7182762f14 @(SBV (Bool,[Integer]) -> SBV Bool)|",1)]
+[MEASURE] sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_7182762f14 @(SBV (Bool,[Integer]) -> SBV Bool): recursive calls found = 1
+[MEASURE] sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_7182762f14 @(SBV (Bool,[Integer]) -> SBV Bool): trying length arg1._2
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_7182762f14 @(SBV (Bool,[Integer]) -> SBV Bool)}: replaying 13 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +16,111 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Bool (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s14 () Bool) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s5 () Int (seq.len s4))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () Bool (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s8 () Int (seq.nth s4 s1))
+[GOOD] (define-fun s9 () Int (mod s8 s3))
+[GOOD] (define-fun s10 () Bool (= s1 s9))
+[GOOD] (define-fun s11 () Int (- s5 s2))
+[GOOD] (define-fun s12 () (Seq Int) (seq.extract s4 s2 s11))
+[GOOD] (define-fun s13 () (SBVTuple2 Bool (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Bool (Seq Int))) s7 s12))
+[GOOD] (define-fun s15 () Bool (or s10 s14))
+[GOOD] (define-fun s16 () Bool (ite s6 s7 s15))
+[GOOD] (define-fun s17 () Bool (>= s5 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_7182762f14 @(SBV (Bool,[Integer]) -> SBV Bool)}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Bool (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s14 () Bool) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s5 () Int (seq.len s4))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () Bool (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s8 () Int (seq.nth s4 s1))
+[GOOD] (define-fun s9 () Int (mod s8 s3))
+[GOOD] (define-fun s10 () Bool (= s1 s9))
+[GOOD] (define-fun s11 () Int (- s5 s2))
+[GOOD] (define-fun s12 () (Seq Int) (seq.extract s4 s2 s11))
+[GOOD] (define-fun s13 () (SBVTuple2 Bool (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Bool (Seq Int))) s7 s12))
+[GOOD] (define-fun s15 () Bool (or s10 s14))
+[GOOD] (define-fun s16 () Bool (ite s6 s7 s15))
+[GOOD] (define-fun s17 () (Seq Int) (proj_2_SBVTuple2 s13))
+[GOOD] (define-fun s18 () Int (seq.len s17))
+[GOOD] (define-fun s19 () Bool (not s10))
+[GOOD] (define-fun s20 () Bool (not s6))
+[GOOD] (define-fun s21 () Bool (and s19 s20))
+[GOOD] (define-fun s22 () Bool (> s5 s18))
+[GOOD] (define-fun s23 () Bool (=> s21 s22))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s23))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_7182762f14 @(SBV (Bool,[Integer]) -> SBV Bool): length arg1._2 -> OK
+[MEASURE] Passed (terminating): sbv.foldr @(SBV (Integer,Bool) -> SBV Bool)_7182762f14 @(SBV (Bool,[Integer]) -> SBV Bool)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/lambda31.gold b/SBVTestSuite/GoldFiles/lambda31.gold
--- a/SBVTestSuite/GoldFiles/lambda31.gold
+++ b/SBVTestSuite/GoldFiles/lambda31.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.filter @(SBV Integer -> SBV Bool)_72b7bf5d4c @(SBV [Integer] -> SBV [Integer])
+[MEASURE] Checking: sbv.filter @(SBV Integer -> SBV Bool)_72b7bf5d4c @(SBV [Integer] -> SBV [Integer])
+[MEASURE] sbv.filter @(SBV Integer -> SBV Bool)_72b7bf5d4c @(SBV [Integer] -> SBV [Integer]): barified = "|sbv.filter @(SBV Integer -> SBV Bool)_72b7bf5d4c @(SBV [Integer] -> SBV [Integer])|"
+[MEASURE] sbv.filter @(SBV Integer -> SBV Bool)_72b7bf5d4c @(SBV [Integer] -> SBV [Integer]): Uninterpreted ops in DAG: [("|sbv.filter @(SBV Integer -> SBV Bool)_72b7bf5d4c @(SBV [Integer] -> SBV [Integer])|",1)]
+[MEASURE] sbv.filter @(SBV Integer -> SBV Bool)_72b7bf5d4c @(SBV [Integer] -> SBV [Integer]): recursive calls found = 1
+[MEASURE] sbv.filter @(SBV Integer -> SBV Bool)_72b7bf5d4c @(SBV [Integer] -> SBV [Integer]): trying length arg1
+[MEASURE] replayDAG {sbv.filter @(SBV Integer -> SBV Bool)_72b7bf5d4c @(SBV [Integer] -> SBV [Integer])}: replaying 12 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +16,104 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] (define-fun s4 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s13 () (Seq Int)) ; tracks user variable "__internal_sbv_s13"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s5 () Int (seq.len s0))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () Int (seq.nth s0 s1))
+[GOOD] (define-fun s8 () Int (mod s7 s3))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () (Seq Int) (seq.unit s7))
+[GOOD] (define-fun s11 () Int (- s5 s2))
+[GOOD] (define-fun s12 () (Seq Int) (seq.extract s0 s2 s11))
+[GOOD] (define-fun s14 () (Seq Int) (seq.++ s10 s13))
+[GOOD] (define-fun s15 () (Seq Int) (ite s9 s14 s13))
+[GOOD] (define-fun s16 () (Seq Int) (ite s6 s4 s15))
+[GOOD] (define-fun s17 () Bool (>= s5 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.filter @(SBV Integer -> SBV Bool)_72b7bf5d4c @(SBV [Integer] -> SBV [Integer])}: replaying 12 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] (define-fun s4 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s13 () (Seq Int)) ; tracks user variable "__internal_sbv_s13"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s5 () Int (seq.len s0))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () Int (seq.nth s0 s1))
+[GOOD] (define-fun s8 () Int (mod s7 s3))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () (Seq Int) (seq.unit s7))
+[GOOD] (define-fun s11 () Int (- s5 s2))
+[GOOD] (define-fun s12 () (Seq Int) (seq.extract s0 s2 s11))
+[GOOD] (define-fun s14 () (Seq Int) (seq.++ s10 s13))
+[GOOD] (define-fun s15 () (Seq Int) (ite s9 s14 s13))
+[GOOD] (define-fun s16 () (Seq Int) (ite s6 s4 s15))
+[GOOD] (define-fun s17 () Int (seq.len s12))
+[GOOD] (define-fun s18 () Bool (not s9))
+[GOOD] (define-fun s19 () Bool (not s6))
+[GOOD] (define-fun s20 () Bool (and s18 s19))
+[GOOD] (define-fun s21 () Bool (> s5 s17))
+[GOOD] (define-fun s22 () Bool (=> s20 s21))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s22))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.filter @(SBV Integer -> SBV Bool)_72b7bf5d4c @(SBV [Integer] -> SBV [Integer]): length arg1 -> OK
+[MEASURE] Passed (terminating): sbv.filter @(SBV Integer -> SBV Bool)_72b7bf5d4c @(SBV [Integer] -> SBV [Integer])
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda32.gold b/SBVTestSuite/GoldFiles/lambda32.gold
--- a/SBVTestSuite/GoldFiles/lambda32.gold
+++ b/SBVTestSuite/GoldFiles/lambda32.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.filter @(SBV Integer -> SBV Bool)_cb04f986c4 @(SBV [Integer] -> SBV [Integer])
+[MEASURE] Checking: sbv.filter @(SBV Integer -> SBV Bool)_cb04f986c4 @(SBV [Integer] -> SBV [Integer])
+[MEASURE] sbv.filter @(SBV Integer -> SBV Bool)_cb04f986c4 @(SBV [Integer] -> SBV [Integer]): barified = "|sbv.filter @(SBV Integer -> SBV Bool)_cb04f986c4 @(SBV [Integer] -> SBV [Integer])|"
+[MEASURE] sbv.filter @(SBV Integer -> SBV Bool)_cb04f986c4 @(SBV [Integer] -> SBV [Integer]): Uninterpreted ops in DAG: [("|sbv.filter @(SBV Integer -> SBV Bool)_cb04f986c4 @(SBV [Integer] -> SBV [Integer])|",1)]
+[MEASURE] sbv.filter @(SBV Integer -> SBV Bool)_cb04f986c4 @(SBV [Integer] -> SBV [Integer]): recursive calls found = 1
+[MEASURE] sbv.filter @(SBV Integer -> SBV Bool)_cb04f986c4 @(SBV [Integer] -> SBV [Integer]): trying length arg1
+[MEASURE] replayDAG {sbv.filter @(SBV Integer -> SBV Bool)_cb04f986c4 @(SBV [Integer] -> SBV [Integer])}: replaying 12 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +16,104 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] (define-fun s4 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s13 () (Seq Int)) ; tracks user variable "__internal_sbv_s13"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s5 () Int (seq.len s0))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () Int (seq.nth s0 s1))
+[GOOD] (define-fun s8 () Int (mod s7 s3))
+[GOOD] (define-fun s9 () Bool (distinct s1 s8))
+[GOOD] (define-fun s10 () (Seq Int) (seq.unit s7))
+[GOOD] (define-fun s11 () Int (- s5 s2))
+[GOOD] (define-fun s12 () (Seq Int) (seq.extract s0 s2 s11))
+[GOOD] (define-fun s14 () (Seq Int) (seq.++ s10 s13))
+[GOOD] (define-fun s15 () (Seq Int) (ite s9 s14 s13))
+[GOOD] (define-fun s16 () (Seq Int) (ite s6 s4 s15))
+[GOOD] (define-fun s17 () Bool (>= s5 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.filter @(SBV Integer -> SBV Bool)_cb04f986c4 @(SBV [Integer] -> SBV [Integer])}: replaying 12 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] (define-fun s4 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s13 () (Seq Int)) ; tracks user variable "__internal_sbv_s13"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s5 () Int (seq.len s0))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () Int (seq.nth s0 s1))
+[GOOD] (define-fun s8 () Int (mod s7 s3))
+[GOOD] (define-fun s9 () Bool (distinct s1 s8))
+[GOOD] (define-fun s10 () (Seq Int) (seq.unit s7))
+[GOOD] (define-fun s11 () Int (- s5 s2))
+[GOOD] (define-fun s12 () (Seq Int) (seq.extract s0 s2 s11))
+[GOOD] (define-fun s14 () (Seq Int) (seq.++ s10 s13))
+[GOOD] (define-fun s15 () (Seq Int) (ite s9 s14 s13))
+[GOOD] (define-fun s16 () (Seq Int) (ite s6 s4 s15))
+[GOOD] (define-fun s17 () Int (seq.len s12))
+[GOOD] (define-fun s18 () Bool (not s9))
+[GOOD] (define-fun s19 () Bool (not s6))
+[GOOD] (define-fun s20 () Bool (and s18 s19))
+[GOOD] (define-fun s21 () Bool (> s5 s17))
+[GOOD] (define-fun s22 () Bool (=> s20 s21))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s22))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.filter @(SBV Integer -> SBV Bool)_cb04f986c4 @(SBV [Integer] -> SBV [Integer]): length arg1 -> OK
+[MEASURE] Passed (terminating): sbv.filter @(SBV Integer -> SBV Bool)_cb04f986c4 @(SBV [Integer] -> SBV [Integer])
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda46.gold b/SBVTestSuite/GoldFiles/lambda46.gold
--- a/SBVTestSuite/GoldFiles/lambda46.gold
+++ b/SBVTestSuite/GoldFiles/lambda46.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda47.gold b/SBVTestSuite/GoldFiles/lambda47.gold
--- a/SBVTestSuite/GoldFiles/lambda47.gold
+++ b/SBVTestSuite/GoldFiles/lambda47.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sumToN @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: sumToN @(SBV Integer -> SBV Integer)
+[MEASURE] sumToN @(SBV Integer -> SBV Integer): barified = "|sumToN @(SBV Integer -> SBV Integer)|"
+[MEASURE] sumToN @(SBV Integer -> SBV Integer): Uninterpreted ops in DAG: [("|sumToN @(SBV Integer -> SBV Integer)|",1)]
+[MEASURE] sumToN @(SBV Integer -> SBV Integer): recursive calls found = 1
+[MEASURE] sumToN @(SBV Integer -> SBV Integer): trying abs arg1
+[MEASURE] replayDAG {sumToN @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -6,7 +13,80 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s0 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (>= s8 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s9))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sumToN @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s0 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Int (abs s4))
+[GOOD] (define-fun s10 () Bool (not s3))
+[GOOD] (define-fun s11 () Bool (> s8 s9))
+[GOOD] (define-fun s12 () Bool (=> s10 s11))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sumToN @(SBV Integer -> SBV Integer): abs arg1 -> OK
+[MEASURE] Passed (terminating): sumToN @(SBV Integer -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda47_c.gold b/SBVTestSuite/GoldFiles/lambda47_c.gold
--- a/SBVTestSuite/GoldFiles/lambda47_c.gold
+++ b/SBVTestSuite/GoldFiles/lambda47_c.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda48.gold b/SBVTestSuite/GoldFiles/lambda48.gold
--- a/SBVTestSuite/GoldFiles/lambda48.gold
+++ b/SBVTestSuite/GoldFiles/lambda48.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: list_length @(SBV [Integer] -> SBV Integer)
+[MEASURE] Checking: list_length @(SBV [Integer] -> SBV Integer)
+[MEASURE] list_length @(SBV [Integer] -> SBV Integer): barified = "|list_length @(SBV [Integer] -> SBV Integer)|"
+[MEASURE] list_length @(SBV [Integer] -> SBV Integer): Uninterpreted ops in DAG: [("|list_length @(SBV [Integer] -> SBV Integer)|",1)]
+[MEASURE] list_length @(SBV [Integer] -> SBV Integer): recursive calls found = 1
+[MEASURE] list_length @(SBV [Integer] -> SBV Integer): trying length arg1
+[MEASURE] replayDAG {list_length @(SBV [Integer] -> SBV Integer)}: replaying 7 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +16,88 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s7 () Int) ; tracks user variable "__internal_sbv_s7"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Int (seq.len s0))
+[GOOD] (define-fun s4 () Bool (= s1 s3))
+[GOOD] (define-fun s5 () Int (- s3 s2))
+[GOOD] (define-fun s6 () (Seq Int) (seq.extract s0 s2 s5))
+[GOOD] (define-fun s8 () Int (+ s2 s7))
+[GOOD] (define-fun s9 () Int (ite s4 s1 s8))
+[GOOD] (define-fun s10 () Bool (>= s3 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s10))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {list_length @(SBV [Integer] -> SBV Integer)}: replaying 7 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s7 () Int) ; tracks user variable "__internal_sbv_s7"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Int (seq.len s0))
+[GOOD] (define-fun s4 () Bool (= s1 s3))
+[GOOD] (define-fun s5 () Int (- s3 s2))
+[GOOD] (define-fun s6 () (Seq Int) (seq.extract s0 s2 s5))
+[GOOD] (define-fun s8 () Int (+ s2 s7))
+[GOOD] (define-fun s9 () Int (ite s4 s1 s8))
+[GOOD] (define-fun s10 () Int (seq.len s6))
+[GOOD] (define-fun s11 () Bool (not s4))
+[GOOD] (define-fun s12 () Bool (> s3 s10))
+[GOOD] (define-fun s13 () Bool (=> s11 s12))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s13))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] list_length @(SBV [Integer] -> SBV Integer): length arg1 -> OK
+[MEASURE] Passed (terminating): list_length @(SBV [Integer] -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda48_c.gold b/SBVTestSuite/GoldFiles/lambda48_c.gold
--- a/SBVTestSuite/GoldFiles/lambda48_c.gold
+++ b/SBVTestSuite/GoldFiles/lambda48_c.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda49.gold b/SBVTestSuite/GoldFiles/lambda49.gold
--- a/SBVTestSuite/GoldFiles/lambda49.gold
+++ b/SBVTestSuite/GoldFiles/lambda49.gold
@@ -1,3 +1,8 @@
+[MEASURE] Verifying termination measures for: isEvenOdd @(SBV Integer -> SBV (Bool,Bool))
+[MEASURE] Checking: isEvenOdd @(SBV Integer -> SBV (Bool,Bool))
+[MEASURE] isEvenOdd @(SBV Integer -> SBV (Bool,Bool)): verifying with 0 helper(s)
+[MEASURE] isEvenOdd @(SBV Integer -> SBV (Bool,Bool)): 0 helper axiom(s) collected, checking measure
+[MEASURE] replayDAG {isEvenOdd @(SBV Integer -> SBV (Bool,Bool))}: replaying 11 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +14,139 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (SBVTuple2 Bool Bool) (mkSBVTuple2 true false))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () (SBVTuple2 Bool Bool)) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s9 () (SBVTuple2 Bool Bool)) ; tracks user variable "__internal_sbv_s9"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (< s0 s1))
+[GOOD] (define-fun s5 () Int (- s0))
+[GOOD] (define-fun s7 () Bool (= s0 s1))
+[GOOD] (define-fun s8 () Int (- s0 s2))
+[GOOD] (define-fun s10 () Bool (proj_2_SBVTuple2 s9))
+[GOOD] (define-fun s11 () Bool (proj_1_SBVTuple2 s9))
+[GOOD] (define-fun s12 () (SBVTuple2 Bool Bool) ((as mkSBVTuple2 (SBVTuple2 Bool Bool)) s10 s11))
+[GOOD] (define-fun s13 () (SBVTuple2 Bool Bool) (ite s7 s3 s12))
+[GOOD] (define-fun s14 () (SBVTuple2 Bool Bool) (ite s4 s6 s13))
+[GOOD] (define-fun s15 () Int (abs s0))
+[GOOD] (define-fun s16 () Int (ite s4 s2 s1))
+[GOOD] (define-fun s17 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s15 s16))
+[GOOD] (define-fun s18 () Int (proj_1_SBVTuple2 s17))
+[GOOD] (define-fun s19 () Bool (>= s18 s1))
+[GOOD] (define-fun s20 () Int (proj_2_SBVTuple2 s17))
+[GOOD] (define-fun s21 () Bool (>= s20 s1))
+[GOOD] (define-fun s22 () Bool (and s19 s21))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s22))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {isEvenOdd @(SBV Integer -> SBV (Bool,Bool))}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (SBVTuple2 Bool Bool) (mkSBVTuple2 true false))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () (SBVTuple2 Bool Bool)) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s9 () (SBVTuple2 Bool Bool)) ; tracks user variable "__internal_sbv_s9"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (< s0 s1))
+[GOOD] (define-fun s5 () Int (- s0))
+[GOOD] (define-fun s7 () Bool (= s0 s1))
+[GOOD] (define-fun s8 () Int (- s0 s2))
+[GOOD] (define-fun s10 () Bool (proj_2_SBVTuple2 s9))
+[GOOD] (define-fun s11 () Bool (proj_1_SBVTuple2 s9))
+[GOOD] (define-fun s12 () (SBVTuple2 Bool Bool) ((as mkSBVTuple2 (SBVTuple2 Bool Bool)) s10 s11))
+[GOOD] (define-fun s13 () (SBVTuple2 Bool Bool) (ite s7 s3 s12))
+[GOOD] (define-fun s14 () (SBVTuple2 Bool Bool) (ite s4 s6 s13))
+[GOOD] (define-fun s15 () Int (abs s0))
+[GOOD] (define-fun s16 () Int (ite s4 s2 s1))
+[GOOD] (define-fun s17 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s15 s16))
+[GOOD] (define-fun s18 () Int (abs s5))
+[GOOD] (define-fun s19 () Bool (< s5 s1))
+[GOOD] (define-fun s20 () Int (ite s19 s2 s1))
+[GOOD] (define-fun s21 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s18 s20))
+[GOOD] (define-fun s22 () Int (abs s8))
+[GOOD] (define-fun s23 () Bool (< s8 s1))
+[GOOD] (define-fun s24 () Int (ite s23 s2 s1))
+[GOOD] (define-fun s25 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s22 s24))
+[GOOD] (define-fun s26 () Int (proj_1_SBVTuple2 s21))
+[GOOD] (define-fun s27 () Int (proj_1_SBVTuple2 s17))
+[GOOD] (define-fun s28 () Bool (< s26 s27))
+[GOOD] (define-fun s29 () Bool (= s26 s27))
+[GOOD] (define-fun s30 () Int (proj_2_SBVTuple2 s21))
+[GOOD] (define-fun s31 () Int (proj_2_SBVTuple2 s17))
+[GOOD] (define-fun s32 () Bool (< s30 s31))
+[GOOD] (define-fun s33 () Bool (and s29 s32))
+[GOOD] (define-fun s34 () Bool (or s28 s33))
+[GOOD] (define-fun s35 () Bool (=> s4 s34))
+[GOOD] (define-fun s36 () Bool (not s7))
+[GOOD] (define-fun s37 () Bool (not s4))
+[GOOD] (define-fun s38 () Bool (and s36 s37))
+[GOOD] (define-fun s39 () Int (proj_1_SBVTuple2 s25))
+[GOOD] (define-fun s40 () Bool (< s39 s27))
+[GOOD] (define-fun s41 () Bool (= s27 s39))
+[GOOD] (define-fun s42 () Int (proj_2_SBVTuple2 s25))
+[GOOD] (define-fun s43 () Bool (< s42 s31))
+[GOOD] (define-fun s44 () Bool (and s41 s43))
+[GOOD] (define-fun s45 () Bool (or s40 s44))
+[GOOD] (define-fun s46 () Bool (=> s38 s45))
+[GOOD] (define-fun s47 () Bool (and s35 s46))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s47))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Passed (terminating): isEvenOdd @(SBV Integer -> SBV (Bool,Bool))
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/lambda49_c.gold b/SBVTestSuite/GoldFiles/lambda49_c.gold
--- a/SBVTestSuite/GoldFiles/lambda49_c.gold
+++ b/SBVTestSuite/GoldFiles/lambda49_c.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda50.gold b/SBVTestSuite/GoldFiles/lambda50.gold
--- a/SBVTestSuite/GoldFiles/lambda50.gold
+++ b/SBVTestSuite/GoldFiles/lambda50.gold
@@ -1,3 +1,8 @@
+[MEASURE] Verifying termination measures for: isEvenOdd @(SBV Integer -> SBV (Bool,Bool))
+[MEASURE] Checking: isEvenOdd @(SBV Integer -> SBV (Bool,Bool))
+[MEASURE] isEvenOdd @(SBV Integer -> SBV (Bool,Bool)): verifying with 0 helper(s)
+[MEASURE] isEvenOdd @(SBV Integer -> SBV (Bool,Bool)): 0 helper axiom(s) collected, checking measure
+[MEASURE] replayDAG {isEvenOdd @(SBV Integer -> SBV (Bool,Bool))}: replaying 11 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +14,139 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (SBVTuple2 Bool Bool) (mkSBVTuple2 true false))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () (SBVTuple2 Bool Bool)) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s9 () (SBVTuple2 Bool Bool)) ; tracks user variable "__internal_sbv_s9"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (< s0 s1))
+[GOOD] (define-fun s5 () Int (- s0))
+[GOOD] (define-fun s7 () Bool (= s0 s1))
+[GOOD] (define-fun s8 () Int (- s0 s2))
+[GOOD] (define-fun s10 () Bool (proj_2_SBVTuple2 s9))
+[GOOD] (define-fun s11 () Bool (proj_1_SBVTuple2 s9))
+[GOOD] (define-fun s12 () (SBVTuple2 Bool Bool) ((as mkSBVTuple2 (SBVTuple2 Bool Bool)) s10 s11))
+[GOOD] (define-fun s13 () (SBVTuple2 Bool Bool) (ite s7 s3 s12))
+[GOOD] (define-fun s14 () (SBVTuple2 Bool Bool) (ite s4 s6 s13))
+[GOOD] (define-fun s15 () Int (abs s0))
+[GOOD] (define-fun s16 () Int (ite s4 s2 s1))
+[GOOD] (define-fun s17 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s15 s16))
+[GOOD] (define-fun s18 () Int (proj_1_SBVTuple2 s17))
+[GOOD] (define-fun s19 () Bool (>= s18 s1))
+[GOOD] (define-fun s20 () Int (proj_2_SBVTuple2 s17))
+[GOOD] (define-fun s21 () Bool (>= s20 s1))
+[GOOD] (define-fun s22 () Bool (and s19 s21))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s22))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {isEvenOdd @(SBV Integer -> SBV (Bool,Bool))}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (SBVTuple2 Bool Bool) (mkSBVTuple2 true false))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () (SBVTuple2 Bool Bool)) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s9 () (SBVTuple2 Bool Bool)) ; tracks user variable "__internal_sbv_s9"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (< s0 s1))
+[GOOD] (define-fun s5 () Int (- s0))
+[GOOD] (define-fun s7 () Bool (= s0 s1))
+[GOOD] (define-fun s8 () Int (- s0 s2))
+[GOOD] (define-fun s10 () Bool (proj_2_SBVTuple2 s9))
+[GOOD] (define-fun s11 () Bool (proj_1_SBVTuple2 s9))
+[GOOD] (define-fun s12 () (SBVTuple2 Bool Bool) ((as mkSBVTuple2 (SBVTuple2 Bool Bool)) s10 s11))
+[GOOD] (define-fun s13 () (SBVTuple2 Bool Bool) (ite s7 s3 s12))
+[GOOD] (define-fun s14 () (SBVTuple2 Bool Bool) (ite s4 s6 s13))
+[GOOD] (define-fun s15 () Int (abs s0))
+[GOOD] (define-fun s16 () Int (ite s4 s2 s1))
+[GOOD] (define-fun s17 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s15 s16))
+[GOOD] (define-fun s18 () Int (abs s5))
+[GOOD] (define-fun s19 () Bool (< s5 s1))
+[GOOD] (define-fun s20 () Int (ite s19 s2 s1))
+[GOOD] (define-fun s21 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s18 s20))
+[GOOD] (define-fun s22 () Int (abs s8))
+[GOOD] (define-fun s23 () Bool (< s8 s1))
+[GOOD] (define-fun s24 () Int (ite s23 s2 s1))
+[GOOD] (define-fun s25 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s22 s24))
+[GOOD] (define-fun s26 () Int (proj_1_SBVTuple2 s21))
+[GOOD] (define-fun s27 () Int (proj_1_SBVTuple2 s17))
+[GOOD] (define-fun s28 () Bool (< s26 s27))
+[GOOD] (define-fun s29 () Bool (= s26 s27))
+[GOOD] (define-fun s30 () Int (proj_2_SBVTuple2 s21))
+[GOOD] (define-fun s31 () Int (proj_2_SBVTuple2 s17))
+[GOOD] (define-fun s32 () Bool (< s30 s31))
+[GOOD] (define-fun s33 () Bool (and s29 s32))
+[GOOD] (define-fun s34 () Bool (or s28 s33))
+[GOOD] (define-fun s35 () Bool (=> s4 s34))
+[GOOD] (define-fun s36 () Bool (not s7))
+[GOOD] (define-fun s37 () Bool (not s4))
+[GOOD] (define-fun s38 () Bool (and s36 s37))
+[GOOD] (define-fun s39 () Int (proj_1_SBVTuple2 s25))
+[GOOD] (define-fun s40 () Bool (< s39 s27))
+[GOOD] (define-fun s41 () Bool (= s27 s39))
+[GOOD] (define-fun s42 () Int (proj_2_SBVTuple2 s25))
+[GOOD] (define-fun s43 () Bool (< s42 s31))
+[GOOD] (define-fun s44 () Bool (and s41 s43))
+[GOOD] (define-fun s45 () Bool (or s40 s44))
+[GOOD] (define-fun s46 () Bool (=> s38 s45))
+[GOOD] (define-fun s47 () Bool (and s35 s46))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s47))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Passed (terminating): isEvenOdd @(SBV Integer -> SBV (Bool,Bool))
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/lambda50_c.gold b/SBVTestSuite/GoldFiles/lambda50_c.gold
--- a/SBVTestSuite/GoldFiles/lambda50_c.gold
+++ b/SBVTestSuite/GoldFiles/lambda50_c.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda51.gold b/SBVTestSuite/GoldFiles/lambda51.gold
--- a/SBVTestSuite/GoldFiles/lambda51.gold
+++ b/SBVTestSuite/GoldFiles/lambda51.gold
@@ -1,3 +1,8 @@
+[MEASURE] Verifying termination measures for: isEvenOdd @(SBV Integer -> SBV (Bool,Bool))
+[MEASURE] Checking: isEvenOdd @(SBV Integer -> SBV (Bool,Bool))
+[MEASURE] isEvenOdd @(SBV Integer -> SBV (Bool,Bool)): verifying with 0 helper(s)
+[MEASURE] isEvenOdd @(SBV Integer -> SBV (Bool,Bool)): 0 helper axiom(s) collected, checking measure
+[MEASURE] replayDAG {isEvenOdd @(SBV Integer -> SBV (Bool,Bool))}: replaying 11 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +14,139 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (SBVTuple2 Bool Bool) (mkSBVTuple2 true false))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () (SBVTuple2 Bool Bool)) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s9 () (SBVTuple2 Bool Bool)) ; tracks user variable "__internal_sbv_s9"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (< s0 s1))
+[GOOD] (define-fun s5 () Int (- s0))
+[GOOD] (define-fun s7 () Bool (= s0 s1))
+[GOOD] (define-fun s8 () Int (- s0 s2))
+[GOOD] (define-fun s10 () Bool (proj_2_SBVTuple2 s9))
+[GOOD] (define-fun s11 () Bool (proj_1_SBVTuple2 s9))
+[GOOD] (define-fun s12 () (SBVTuple2 Bool Bool) ((as mkSBVTuple2 (SBVTuple2 Bool Bool)) s10 s11))
+[GOOD] (define-fun s13 () (SBVTuple2 Bool Bool) (ite s7 s3 s12))
+[GOOD] (define-fun s14 () (SBVTuple2 Bool Bool) (ite s4 s6 s13))
+[GOOD] (define-fun s15 () Int (abs s0))
+[GOOD] (define-fun s16 () Int (ite s4 s2 s1))
+[GOOD] (define-fun s17 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s15 s16))
+[GOOD] (define-fun s18 () Int (proj_1_SBVTuple2 s17))
+[GOOD] (define-fun s19 () Bool (>= s18 s1))
+[GOOD] (define-fun s20 () Int (proj_2_SBVTuple2 s17))
+[GOOD] (define-fun s21 () Bool (>= s20 s1))
+[GOOD] (define-fun s22 () Bool (and s19 s21))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s22))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {isEvenOdd @(SBV Integer -> SBV (Bool,Bool))}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (SBVTuple2 Bool Bool) (mkSBVTuple2 true false))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () (SBVTuple2 Bool Bool)) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s9 () (SBVTuple2 Bool Bool)) ; tracks user variable "__internal_sbv_s9"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (< s0 s1))
+[GOOD] (define-fun s5 () Int (- s0))
+[GOOD] (define-fun s7 () Bool (= s0 s1))
+[GOOD] (define-fun s8 () Int (- s0 s2))
+[GOOD] (define-fun s10 () Bool (proj_2_SBVTuple2 s9))
+[GOOD] (define-fun s11 () Bool (proj_1_SBVTuple2 s9))
+[GOOD] (define-fun s12 () (SBVTuple2 Bool Bool) ((as mkSBVTuple2 (SBVTuple2 Bool Bool)) s10 s11))
+[GOOD] (define-fun s13 () (SBVTuple2 Bool Bool) (ite s7 s3 s12))
+[GOOD] (define-fun s14 () (SBVTuple2 Bool Bool) (ite s4 s6 s13))
+[GOOD] (define-fun s15 () Int (abs s0))
+[GOOD] (define-fun s16 () Int (ite s4 s2 s1))
+[GOOD] (define-fun s17 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s15 s16))
+[GOOD] (define-fun s18 () Int (abs s5))
+[GOOD] (define-fun s19 () Bool (< s5 s1))
+[GOOD] (define-fun s20 () Int (ite s19 s2 s1))
+[GOOD] (define-fun s21 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s18 s20))
+[GOOD] (define-fun s22 () Int (abs s8))
+[GOOD] (define-fun s23 () Bool (< s8 s1))
+[GOOD] (define-fun s24 () Int (ite s23 s2 s1))
+[GOOD] (define-fun s25 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s22 s24))
+[GOOD] (define-fun s26 () Int (proj_1_SBVTuple2 s21))
+[GOOD] (define-fun s27 () Int (proj_1_SBVTuple2 s17))
+[GOOD] (define-fun s28 () Bool (< s26 s27))
+[GOOD] (define-fun s29 () Bool (= s26 s27))
+[GOOD] (define-fun s30 () Int (proj_2_SBVTuple2 s21))
+[GOOD] (define-fun s31 () Int (proj_2_SBVTuple2 s17))
+[GOOD] (define-fun s32 () Bool (< s30 s31))
+[GOOD] (define-fun s33 () Bool (and s29 s32))
+[GOOD] (define-fun s34 () Bool (or s28 s33))
+[GOOD] (define-fun s35 () Bool (=> s4 s34))
+[GOOD] (define-fun s36 () Bool (not s7))
+[GOOD] (define-fun s37 () Bool (not s4))
+[GOOD] (define-fun s38 () Bool (and s36 s37))
+[GOOD] (define-fun s39 () Int (proj_1_SBVTuple2 s25))
+[GOOD] (define-fun s40 () Bool (< s39 s27))
+[GOOD] (define-fun s41 () Bool (= s27 s39))
+[GOOD] (define-fun s42 () Int (proj_2_SBVTuple2 s25))
+[GOOD] (define-fun s43 () Bool (< s42 s31))
+[GOOD] (define-fun s44 () Bool (and s41 s43))
+[GOOD] (define-fun s45 () Bool (or s40 s44))
+[GOOD] (define-fun s46 () Bool (=> s38 s45))
+[GOOD] (define-fun s47 () Bool (and s35 s46))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s47))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Passed (terminating): isEvenOdd @(SBV Integer -> SBV (Bool,Bool))
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/lambda51_c.gold b/SBVTestSuite/GoldFiles/lambda51_c.gold
--- a/SBVTestSuite/GoldFiles/lambda51_c.gold
+++ b/SBVTestSuite/GoldFiles/lambda51_c.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda52.gold b/SBVTestSuite/GoldFiles/lambda52.gold
--- a/SBVTestSuite/GoldFiles/lambda52.gold
+++ b/SBVTestSuite/GoldFiles/lambda52.gold
@@ -1,3 +1,8 @@
+[MEASURE] Verifying termination measures for: isEvenOdd @(SBV Integer -> SBV (Bool,Bool))
+[MEASURE] Checking: isEvenOdd @(SBV Integer -> SBV (Bool,Bool))
+[MEASURE] isEvenOdd @(SBV Integer -> SBV (Bool,Bool)): verifying with 0 helper(s)
+[MEASURE] isEvenOdd @(SBV Integer -> SBV (Bool,Bool)): 0 helper axiom(s) collected, checking measure
+[MEASURE] replayDAG {isEvenOdd @(SBV Integer -> SBV (Bool,Bool))}: replaying 11 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +14,139 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (SBVTuple2 Bool Bool) (mkSBVTuple2 true false))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () (SBVTuple2 Bool Bool)) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s9 () (SBVTuple2 Bool Bool)) ; tracks user variable "__internal_sbv_s9"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (< s0 s1))
+[GOOD] (define-fun s5 () Int (- s0))
+[GOOD] (define-fun s7 () Bool (= s0 s1))
+[GOOD] (define-fun s8 () Int (- s0 s2))
+[GOOD] (define-fun s10 () Bool (proj_2_SBVTuple2 s9))
+[GOOD] (define-fun s11 () Bool (proj_1_SBVTuple2 s9))
+[GOOD] (define-fun s12 () (SBVTuple2 Bool Bool) ((as mkSBVTuple2 (SBVTuple2 Bool Bool)) s10 s11))
+[GOOD] (define-fun s13 () (SBVTuple2 Bool Bool) (ite s7 s3 s12))
+[GOOD] (define-fun s14 () (SBVTuple2 Bool Bool) (ite s4 s6 s13))
+[GOOD] (define-fun s15 () Int (abs s0))
+[GOOD] (define-fun s16 () Int (ite s4 s2 s1))
+[GOOD] (define-fun s17 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s15 s16))
+[GOOD] (define-fun s18 () Int (proj_1_SBVTuple2 s17))
+[GOOD] (define-fun s19 () Bool (>= s18 s1))
+[GOOD] (define-fun s20 () Int (proj_2_SBVTuple2 s17))
+[GOOD] (define-fun s21 () Bool (>= s20 s1))
+[GOOD] (define-fun s22 () Bool (and s19 s21))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s22))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {isEvenOdd @(SBV Integer -> SBV (Bool,Bool))}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (SBVTuple2 Bool Bool) (mkSBVTuple2 true false))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () (SBVTuple2 Bool Bool)) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s9 () (SBVTuple2 Bool Bool)) ; tracks user variable "__internal_sbv_s9"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (< s0 s1))
+[GOOD] (define-fun s5 () Int (- s0))
+[GOOD] (define-fun s7 () Bool (= s0 s1))
+[GOOD] (define-fun s8 () Int (- s0 s2))
+[GOOD] (define-fun s10 () Bool (proj_2_SBVTuple2 s9))
+[GOOD] (define-fun s11 () Bool (proj_1_SBVTuple2 s9))
+[GOOD] (define-fun s12 () (SBVTuple2 Bool Bool) ((as mkSBVTuple2 (SBVTuple2 Bool Bool)) s10 s11))
+[GOOD] (define-fun s13 () (SBVTuple2 Bool Bool) (ite s7 s3 s12))
+[GOOD] (define-fun s14 () (SBVTuple2 Bool Bool) (ite s4 s6 s13))
+[GOOD] (define-fun s15 () Int (abs s0))
+[GOOD] (define-fun s16 () Int (ite s4 s2 s1))
+[GOOD] (define-fun s17 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s15 s16))
+[GOOD] (define-fun s18 () Int (abs s5))
+[GOOD] (define-fun s19 () Bool (< s5 s1))
+[GOOD] (define-fun s20 () Int (ite s19 s2 s1))
+[GOOD] (define-fun s21 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s18 s20))
+[GOOD] (define-fun s22 () Int (abs s8))
+[GOOD] (define-fun s23 () Bool (< s8 s1))
+[GOOD] (define-fun s24 () Int (ite s23 s2 s1))
+[GOOD] (define-fun s25 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s22 s24))
+[GOOD] (define-fun s26 () Int (proj_1_SBVTuple2 s21))
+[GOOD] (define-fun s27 () Int (proj_1_SBVTuple2 s17))
+[GOOD] (define-fun s28 () Bool (< s26 s27))
+[GOOD] (define-fun s29 () Bool (= s26 s27))
+[GOOD] (define-fun s30 () Int (proj_2_SBVTuple2 s21))
+[GOOD] (define-fun s31 () Int (proj_2_SBVTuple2 s17))
+[GOOD] (define-fun s32 () Bool (< s30 s31))
+[GOOD] (define-fun s33 () Bool (and s29 s32))
+[GOOD] (define-fun s34 () Bool (or s28 s33))
+[GOOD] (define-fun s35 () Bool (=> s4 s34))
+[GOOD] (define-fun s36 () Bool (not s7))
+[GOOD] (define-fun s37 () Bool (not s4))
+[GOOD] (define-fun s38 () Bool (and s36 s37))
+[GOOD] (define-fun s39 () Int (proj_1_SBVTuple2 s25))
+[GOOD] (define-fun s40 () Bool (< s39 s27))
+[GOOD] (define-fun s41 () Bool (= s27 s39))
+[GOOD] (define-fun s42 () Int (proj_2_SBVTuple2 s25))
+[GOOD] (define-fun s43 () Bool (< s42 s31))
+[GOOD] (define-fun s44 () Bool (and s41 s43))
+[GOOD] (define-fun s45 () Bool (or s40 s44))
+[GOOD] (define-fun s46 () Bool (=> s38 s45))
+[GOOD] (define-fun s47 () Bool (and s35 s46))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s47))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Passed (terminating): isEvenOdd @(SBV Integer -> SBV (Bool,Bool))
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/lambda52_c.gold b/SBVTestSuite/GoldFiles/lambda52_c.gold
--- a/SBVTestSuite/GoldFiles/lambda52_c.gold
+++ b/SBVTestSuite/GoldFiles/lambda52_c.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda53.gold b/SBVTestSuite/GoldFiles/lambda53.gold
--- a/SBVTestSuite/GoldFiles/lambda53.gold
+++ b/SBVTestSuite/GoldFiles/lambda53.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
@@ -25,19 +24,13 @@
 [GOOD] ; --- delayedEqualities ---
 [GOOD] ; --- formula ---
 [GOOD] (assert s2)
-[GOOD] (declare-fun s3 () Int)
-[GOOD] (define-fun s4 () Int (|foo @(SBV Integer -> SBV Integer)| s3))
-[GOOD] (define-fun s5 () Bool (= s3 s4))
-[GOOD] (assert s5)
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
 [RECV] ((s0 0))
-[SEND] (get-value (s3))
-[RECV] ((s3 0))
 *** Solver   : Z3
 *** Exit code: ExitSuccess
 
 RESULT:
+Satisfiable. Model:
   s0 = 0 :: Integer
-  s3 = 0 :: Integer
diff --git a/SBVTestSuite/GoldFiles/lambda54.gold b/SBVTestSuite/GoldFiles/lambda54.gold
--- a/SBVTestSuite/GoldFiles/lambda54.gold
+++ b/SBVTestSuite/GoldFiles/lambda54.gold
@@ -1,3 +1,7 @@
+[MEASURE] Verifying termination measures for: foo @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: foo @(SBV Integer -> SBV Integer)
+[MEASURE] foo @(SBV Integer -> SBV Integer): not in a multi-member cycle, skipping mutual check
+[MEASURE] Passed (terminating): foo @(SBV Integer -> SBV Integer)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -6,7 +10,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda55.gold b/SBVTestSuite/GoldFiles/lambda55.gold
--- a/SBVTestSuite/GoldFiles/lambda55.gold
+++ b/SBVTestSuite/GoldFiles/lambda55.gold
@@ -1,3 +1,7 @@
+[MEASURE] Verifying termination measures for: foo @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: foo @(SBV Integer -> SBV Integer)
+[MEASURE] foo @(SBV Integer -> SBV Integer): not in a multi-member cycle, skipping mutual check
+[MEASURE] Passed (terminating): foo @(SBV Integer -> SBV Integer)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -6,7 +10,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda56.gold b/SBVTestSuite/GoldFiles/lambda56.gold
--- a/SBVTestSuite/GoldFiles/lambda56.gold
+++ b/SBVTestSuite/GoldFiles/lambda56.gold
@@ -1,3 +1,8 @@
+[MEASURE] Verifying termination measures for: foo @(SBV Integer -> SBV Integer), bar @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: foo @(SBV Integer -> SBV Integer)
+[MEASURE] Checking mutual recursion group: {bar :: SBV Integer -> SBV Integer, foo :: SBV Integer -> SBV Integer}
+[MEASURE] Mutual group: trying measure abs arg1 for all members
+[MEASURE] replayDAG {bar @(SBV Integer -> SBV Integer), foo @(SBV Integer -> SBV Integer)}: replaying 2 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -6,48 +11,448 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 1)
+[GOOD] (define-fun s5 () Int 0)
 [GOOD] ; --- top level inputs ---
-[GOOD] (declare-fun s0 () Int)
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s2 () Int) ; tracks user variable "__internal_sbv_s2"
 [GOOD] ; --- constant tables ---
 [GOOD] ; --- non-constant tables ---
 [GOOD] ; --- uninterpreted constants ---
 [GOOD] ; --- user defined functions ---
-[GOOD] ; |bar @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger, |foo @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger
-[GOOD] (define-funs-rec
-         ((|bar @(SBV Integer -> SBV Integer)| ((l2_s0 Int)) Int)
-          (|foo @(SBV Integer -> SBV Integer)| ((l1_s0 Int)) Int))
-         (; Definition of: |bar @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |foo @(SBV Integer -> SBV Integer)|]
-                                                  (let ((l2_s2 1))
-                                                  (let ((l2_s1 (|foo @(SBV Integer -> SBV Integer)| l2_s0)))
-                                                  (let ((l2_s3 (+ l2_s1 l2_s2)))
-                                                  l2_s3)))
-          ; Definition of: |foo @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |bar @(SBV Integer -> SBV Integer)|]
-                                  (let ((l1_s2 1))
-                                  (let ((l1_s1 (|bar @(SBV Integer -> SBV Integer)| l1_s0)))
-                                  (let ((l1_s3 (+ l1_s1 l1_s2)))
-                                  l1_s3)))))
 [GOOD] ; --- assignments ---
-[GOOD] (define-fun s1 () Int (|foo @(SBV Integer -> SBV Integer)| s0))
-[GOOD] (define-fun s2 () Int (|bar @(SBV Integer -> SBV Integer)| s0))
 [GOOD] (define-fun s3 () Int (+ s1 s2))
-[GOOD] (define-fun s4 () Bool (= s0 s3))
+[GOOD] (define-fun s4 () Int (abs s0))
+[GOOD] (define-fun s6 () Bool (>= s4 s5))
 [GOOD] ; --- delayedEqualities ---
 [GOOD] ; --- formula ---
-[GOOD] (assert s4)
-[GOOD] (declare-fun s5 () Int)
-[GOOD] (define-fun s6 () Int (|foo @(SBV Integer -> SBV Integer)| s5))
-[GOOD] (define-fun s7 () Int (|bar @(SBV Integer -> SBV Integer)| s5))
-[GOOD] (define-fun s8 () Int (+ s6 s7))
-[GOOD] (define-fun s9 () Bool (= s5 s8))
-[GOOD] (assert s9)
+[GOOD] (assert (not s6))
 [SEND] (check-sat)
 [RECV] unsat
 *** Solver   : Z3
 *** Exit code: ExitSuccess
+[MEASURE] replayDAG {bar @(SBV Integer -> SBV Integer), foo @(SBV Integer -> SBV Integer)}: replaying 2 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s2 () Int) ; tracks user variable "__internal_sbv_s2"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Int (+ s1 s2))
+[GOOD] (define-fun s4 () Int (abs s0))
+[GOOD] (define-fun s5 () Bool (=> true false))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s5))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s4))
+[RECV] ((s4 0))
+[SEND] (get-value (s4))
+[RECV] ((s4 0))
+[SEND] (get-value (s0))
+[RECV] ((s0 0))
+[SEND] (get-value (s2))
+[RECV] ((s2 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease failed for bar @(SBV Integer -> SBV Integer): Falsifiable. Counter-example:
+  arg    = 0 :: Integer
+  before = 0 :: Integer
+  then   = 0 :: Integer
+[MEASURE] Mutual group: measure abs arg1 failed, trying next
+[MEASURE] Mutual group: trying measure smax 0 arg1 for all members
+[MEASURE] replayDAG {bar @(SBV Integer -> SBV Integer), foo @(SBV Integer -> SBV Integer)}: replaying 2 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 1)
+[GOOD] (define-fun s4 () Int 0)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s2 () Int) ; tracks user variable "__internal_sbv_s2"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Int (+ s1 s2))
+[GOOD] (define-fun s5 () Bool (<= s4 s0))
+[GOOD] (define-fun s6 () Int (ite s5 s0 s4))
+[GOOD] (define-fun s7 () Bool (>= s6 s4))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s7))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {bar @(SBV Integer -> SBV Integer), foo @(SBV Integer -> SBV Integer)}: replaying 2 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 1)
+[GOOD] (define-fun s4 () Int 0)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s2 () Int) ; tracks user variable "__internal_sbv_s2"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Int (+ s1 s2))
+[GOOD] (define-fun s5 () Bool (<= s4 s0))
+[GOOD] (define-fun s6 () Int (ite s5 s0 s4))
+[GOOD] (define-fun s7 () Bool (=> true false))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s7))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s6))
+[RECV] ((s6 0))
+[SEND] (get-value (s6))
+[RECV] ((s6 0))
+[SEND] (get-value (s0))
+[RECV] ((s0 0))
+[SEND] (get-value (s2))
+[RECV] ((s2 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease failed for bar @(SBV Integer -> SBV Integer): Falsifiable. Counter-example:
+  arg    = 0 :: Integer
+  before = 0 :: Integer
+  then   = 0 :: Integer
+[MEASURE] Mutual group: measure smax 0 arg1 failed, trying next
+[MEASURE] Mutual group: trying measure abs arg1 + smax 0 arg1 for all members
+[MEASURE] replayDAG {bar @(SBV Integer -> SBV Integer), foo @(SBV Integer -> SBV Integer)}: replaying 2 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 1)
+[GOOD] (define-fun s5 () Int 0)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s2 () Int) ; tracks user variable "__internal_sbv_s2"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Int (+ s1 s2))
+[GOOD] (define-fun s4 () Int (abs s0))
+[GOOD] (define-fun s6 () Bool (<= s5 s0))
+[GOOD] (define-fun s7 () Int (ite s6 s0 s5))
+[GOOD] (define-fun s8 () Int (+ s4 s7))
+[GOOD] (define-fun s9 () Bool (>= s8 s5))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s9))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {bar @(SBV Integer -> SBV Integer), foo @(SBV Integer -> SBV Integer)}: replaying 2 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 1)
+[GOOD] (define-fun s5 () Int 0)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s2 () Int) ; tracks user variable "__internal_sbv_s2"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Int (+ s1 s2))
+[GOOD] (define-fun s4 () Int (abs s0))
+[GOOD] (define-fun s6 () Bool (<= s5 s0))
+[GOOD] (define-fun s7 () Int (ite s6 s0 s5))
+[GOOD] (define-fun s8 () Int (+ s4 s7))
+[GOOD] (define-fun s9 () Bool (=> true false))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s9))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s8))
+[RECV] ((s8 0))
+[SEND] (get-value (s8))
+[RECV] ((s8 0))
+[SEND] (get-value (s0))
+[RECV] ((s0 0))
+[SEND] (get-value (s2))
+[RECV] ((s2 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease failed for bar @(SBV Integer -> SBV Integer): Falsifiable. Counter-example:
+  arg    = 0 :: Integer
+  before = 0 :: Integer
+  then   = 0 :: Integer
+[MEASURE] Mutual group: measure abs arg1 + smax 0 arg1 failed, trying next
+[MEASURE] Mutual group: trying measure (abs arg1, smax 0 arg1) for all members
+[MEASURE] replayDAG {bar @(SBV Integer -> SBV Integer), foo @(SBV Integer -> SBV Integer)}: replaying 2 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 1)
+[GOOD] (define-fun s5 () Int 0)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s2 () Int) ; tracks user variable "__internal_sbv_s2"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Int (+ s1 s2))
+[GOOD] (define-fun s4 () Int (abs s0))
+[GOOD] (define-fun s6 () Bool (<= s5 s0))
+[GOOD] (define-fun s7 () Int (ite s6 s0 s5))
+[GOOD] (define-fun s8 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s4 s7))
+[GOOD] (define-fun s9 () Int (proj_1_SBVTuple2 s8))
+[GOOD] (define-fun s10 () Bool (>= s9 s5))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s8))
+[GOOD] (define-fun s12 () Bool (>= s11 s5))
+[GOOD] (define-fun s13 () Bool (and s10 s12))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s13))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {bar @(SBV Integer -> SBV Integer), foo @(SBV Integer -> SBV Integer)}: replaying 2 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 1)
+[GOOD] (define-fun s5 () Int 0)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s2 () Int) ; tracks user variable "__internal_sbv_s2"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Int (+ s1 s2))
+[GOOD] (define-fun s4 () Int (abs s0))
+[GOOD] (define-fun s6 () Bool (<= s5 s0))
+[GOOD] (define-fun s7 () Int (ite s6 s0 s5))
+[GOOD] (define-fun s8 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s4 s7))
+[GOOD] (define-fun s9 () Int (proj_1_SBVTuple2 s8))
+[GOOD] (define-fun s10 () Int (proj_2_SBVTuple2 s8))
+[GOOD] (define-fun s11 () Bool (=> true false))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s11))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s8))
+[RECV] ((s8 (mkSBVTuple2 0 0)))
+[SEND] (get-value (s8))
+[RECV] ((s8 (mkSBVTuple2 0 0)))
+[SEND] (get-value (s0))
+[RECV] ((s0 0))
+[SEND] (get-value (s2))
+[RECV] ((s2 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease failed for bar @(SBV Integer -> SBV Integer): Falsifiable. Counter-example:
+  arg    =     0 :: Integer
+  before = (0,0) :: (Integer, Integer)
+  then   = (0,0) :: (Integer, Integer)
+[MEASURE] Mutual group: measure (abs arg1, smax 0 arg1) failed, trying next
+[MEASURE] Mutual group: trying measure (smax 0 arg1, abs arg1) for all members
+[MEASURE] replayDAG {bar @(SBV Integer -> SBV Integer), foo @(SBV Integer -> SBV Integer)}: replaying 2 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 1)
+[GOOD] (define-fun s4 () Int 0)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s2 () Int) ; tracks user variable "__internal_sbv_s2"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Int (+ s1 s2))
+[GOOD] (define-fun s5 () Bool (<= s4 s0))
+[GOOD] (define-fun s6 () Int (ite s5 s0 s4))
+[GOOD] (define-fun s7 () Int (abs s0))
+[GOOD] (define-fun s8 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s6 s7))
+[GOOD] (define-fun s9 () Int (proj_1_SBVTuple2 s8))
+[GOOD] (define-fun s10 () Bool (>= s9 s4))
+[GOOD] (define-fun s11 () Int (proj_2_SBVTuple2 s8))
+[GOOD] (define-fun s12 () Bool (>= s11 s4))
+[GOOD] (define-fun s13 () Bool (and s10 s12))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s13))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {bar @(SBV Integer -> SBV Integer), foo @(SBV Integer -> SBV Integer)}: replaying 2 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 1)
+[GOOD] (define-fun s4 () Int 0)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s2 () Int) ; tracks user variable "__internal_sbv_s2"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Int (+ s1 s2))
+[GOOD] (define-fun s5 () Bool (<= s4 s0))
+[GOOD] (define-fun s6 () Int (ite s5 s0 s4))
+[GOOD] (define-fun s7 () Int (abs s0))
+[GOOD] (define-fun s8 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s6 s7))
+[GOOD] (define-fun s9 () Int (proj_1_SBVTuple2 s8))
+[GOOD] (define-fun s10 () Int (proj_2_SBVTuple2 s8))
+[GOOD] (define-fun s11 () Bool (=> true false))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s11))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s8))
+[RECV] ((s8 (mkSBVTuple2 0 0)))
+[SEND] (get-value (s8))
+[RECV] ((s8 (mkSBVTuple2 0 0)))
+[SEND] (get-value (s0))
+[RECV] ((s0 0))
+[SEND] (get-value (s2))
+[RECV] ((s2 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease failed for bar @(SBV Integer -> SBV Integer): Falsifiable. Counter-example:
+  arg    =     0 :: Integer
+  before = (0,0) :: (Integer, Integer)
+  then   = (0,0) :: (Integer, Integer)
+[MEASURE] Mutual group: measure (smax 0 arg1, abs arg1) failed, trying next
 
-RESULT:
-All good, expecting: Unsat
+EXCEPTION CAUGHT:
+
+*** Data.SBV: Cannot determine a termination measure for mutual recursion group.
+***
+***     bar  :: SBV Integer -> SBV Integer
+***     foo  :: SBV Integer -> SBV Integer
+***
+*** Please use 'smtFunctionWithMeasure' to provide explicit measures.
+
diff --git a/SBVTestSuite/GoldFiles/lambda57.gold b/SBVTestSuite/GoldFiles/lambda57.gold
--- a/SBVTestSuite/GoldFiles/lambda57.gold
+++ b/SBVTestSuite/GoldFiles/lambda57.gold
@@ -1,3 +1,8 @@
+[MEASURE] Verifying termination measures for: f1 @(SBV Word8 -> SBV Word8), f1 @(SBV Word8 -> SBV Word8), f2 @(SBV Word8 -> SBV Word8), f2 @(SBV Word8 -> SBV Word8), f3 @(SBV Word8 -> SBV Word8), f3 @(SBV Word8 -> SBV Word8), f4 @(SBV Word8 -> SBV Word8), f4 @(SBV Word8 -> SBV Word8)
+[MEASURE] Checking: f1 @(SBV Word8 -> SBV Word8)
+[MEASURE] Checking mutual recursion group: {f1 :: SBV Word8 -> SBV Word8, f2 :: SBV Word8 -> SBV Word8, f3 :: SBV Word8 -> SBV Word8, f4 :: SBV Word8 -> SBV Word8}
+[MEASURE] Mutual group: trying measure arg1 for all members
+[MEASURE] replayDAG {f1 @(SBV Word8 -> SBV Word8), f2 @(SBV Word8 -> SBV Word8), f3 @(SBV Word8 -> SBV Word8), f4 @(SBV Word8 -> SBV Word8)}: replaying 8 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -5,94 +10,111 @@
 [GOOD] (set-option :smtlib2_compliant true)
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
-[GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (_ BitVec 8) #x00)
+[GOOD] (define-fun s2 () (_ BitVec 8) #x01)
+[GOOD] (define-fun s3 () (_ BitVec 8) #x02)
+[GOOD] (define-fun s13 () Int 0)
 [GOOD] ; --- top level inputs ---
-[GOOD] (declare-fun s0 () (_ BitVec 8))
+[GOOD] (declare-fun s0 () (_ BitVec 8)) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () (_ BitVec 8)) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () (_ BitVec 8)) ; tracks user variable "__internal_sbv_s8"
 [GOOD] ; --- constant tables ---
 [GOOD] ; --- non-constant tables ---
 [GOOD] ; --- uninterpreted constants ---
 [GOOD] ; --- user defined functions ---
-[GOOD] ; |f1 @(SBV Word8 -> SBV Word8)| :: SWord8 -> SWord8, |f2 @(SBV Word8 -> SBV Word8)| :: SWord8 -> SWord8, |f3 @(SBV Word8 -> SBV Word8)| :: SWord8 -> SWord8, |f4 @(SBV Word8 -> SBV Word8)| :: SWord8 -> SWord8
-[GOOD] (define-funs-rec
-         ((|f1 @(SBV Word8 -> SBV Word8)| ((l1_s0 (_ BitVec 8))) (_ BitVec 8))
-          (|f2 @(SBV Word8 -> SBV Word8)| ((l2_s0 (_ BitVec 8))) (_ BitVec 8))
-          (|f3 @(SBV Word8 -> SBV Word8)| ((l3_s0 (_ BitVec 8))) (_ BitVec 8))
-          (|f4 @(SBV Word8 -> SBV Word8)| ((l4_s0 (_ BitVec 8))) (_ BitVec 8)))
-         (; Definition of: |f1 @(SBV Word8 -> SBV Word8)| :: SWord8 -> SWord8. [Refers to: |f1 @(SBV Word8 -> SBV Word8)|, |f2 @(SBV Word8 -> SBV Word8)|]
-                                  (let ((l1_s1 #x00))
-                                  (let ((l1_s3 #x01))
-                                  (let ((l1_s6 #x02))
-                                  (let ((l1_s2 (= l1_s0 l1_s1)))
-                                  (let ((l1_s4 (bvsub l1_s0 l1_s3)))
-                                  (let ((l1_s5 (|f1 @(SBV Word8 -> SBV Word8)| l1_s4)))
-                                  (let ((l1_s7 (bvsub l1_s0 l1_s6)))
-                                  (let ((l1_s8 (|f2 @(SBV Word8 -> SBV Word8)| l1_s7)))
-                                  (let ((l1_s9 (bvadd l1_s5 l1_s8)))
-                                  (let ((l1_s10 (bvadd l1_s3 l1_s9)))
-                                  (let ((l1_s11 (ite l1_s2 l1_s1 l1_s10)))
-                                  l1_s11)))))))))))
-          ; Definition of: |f2 @(SBV Word8 -> SBV Word8)| :: SWord8 -> SWord8. [Refers to: |f2 @(SBV Word8 -> SBV Word8)|, |f3 @(SBV Word8 -> SBV Word8)|]
-                                                  (let ((l2_s1 #x00))
-                                                  (let ((l2_s3 #x01))
-                                                  (let ((l2_s6 #x02))
-                                                  (let ((l2_s2 (= l2_s0 l2_s1)))
-                                                  (let ((l2_s4 (bvsub l2_s0 l2_s3)))
-                                                  (let ((l2_s5 (|f2 @(SBV Word8 -> SBV Word8)| l2_s4)))
-                                                  (let ((l2_s7 (bvsub l2_s0 l2_s6)))
-                                                  (let ((l2_s8 (|f3 @(SBV Word8 -> SBV Word8)| l2_s7)))
-                                                  (let ((l2_s9 (bvadd l2_s5 l2_s8)))
-                                                  (let ((l2_s10 (bvadd l2_s3 l2_s9)))
-                                                  (let ((l2_s11 (ite l2_s2 l2_s1 l2_s10)))
-                                                  l2_s11)))))))))))
-          ; Definition of: |f3 @(SBV Word8 -> SBV Word8)| :: SWord8 -> SWord8. [Refers to: |f3 @(SBV Word8 -> SBV Word8)|, |f4 @(SBV Word8 -> SBV Word8)|]
-                                                                  (let ((l3_s1 #x00))
-                                                                  (let ((l3_s3 #x01))
-                                                                  (let ((l3_s6 #x02))
-                                                                  (let ((l3_s2 (= l3_s0 l3_s1)))
-                                                                  (let ((l3_s4 (bvsub l3_s0 l3_s3)))
-                                                                  (let ((l3_s5 (|f3 @(SBV Word8 -> SBV Word8)| l3_s4)))
-                                                                  (let ((l3_s7 (bvsub l3_s0 l3_s6)))
-                                                                  (let ((l3_s8 (|f4 @(SBV Word8 -> SBV Word8)| l3_s7)))
-                                                                  (let ((l3_s9 (bvadd l3_s5 l3_s8)))
-                                                                  (let ((l3_s10 (bvadd l3_s3 l3_s9)))
-                                                                  (let ((l3_s11 (ite l3_s2 l3_s1 l3_s10)))
-                                                                  l3_s11)))))))))))
-          ; Definition of: |f4 @(SBV Word8 -> SBV Word8)| :: SWord8 -> SWord8. [Refers to: |f1 @(SBV Word8 -> SBV Word8)|, |f4 @(SBV Word8 -> SBV Word8)|]
-                                                                                  (let ((l4_s1 #x00))
-                                                                                  (let ((l4_s3 #x01))
-                                                                                  (let ((l4_s6 #x02))
-                                                                                  (let ((l4_s2 (= l4_s0 l4_s1)))
-                                                                                  (let ((l4_s4 (bvsub l4_s0 l4_s3)))
-                                                                                  (let ((l4_s5 (|f4 @(SBV Word8 -> SBV Word8)| l4_s4)))
-                                                                                  (let ((l4_s7 (bvsub l4_s0 l4_s6)))
-                                                                                  (let ((l4_s8 (|f1 @(SBV Word8 -> SBV Word8)| l4_s7)))
-                                                                                  (let ((l4_s9 (bvadd l4_s5 l4_s8)))
-                                                                                  (let ((l4_s10 (bvadd l4_s3 l4_s9)))
-                                                                                  (let ((l4_s11 (ite l4_s2 l4_s1 l4_s10)))
-                                                                                  l4_s11)))))))))))))
 [GOOD] ; --- assignments ---
-[GOOD] (define-fun s1 () (_ BitVec 8) (|f1 @(SBV Word8 -> SBV Word8)| s0))
-[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s4 () Bool (= s0 s1))
+[GOOD] (define-fun s5 () (_ BitVec 8) (bvsub s0 s2))
+[GOOD] (define-fun s7 () (_ BitVec 8) (bvsub s0 s3))
+[GOOD] (define-fun s9 () (_ BitVec 8) (bvadd s6 s8))
+[GOOD] (define-fun s10 () (_ BitVec 8) (bvadd s2 s9))
+[GOOD] (define-fun s11 () (_ BitVec 8) (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Int (ubv_to_int s0))
+[GOOD] (define-fun s14 () Bool (>= s12 s13))
 [GOOD] ; --- delayedEqualities ---
 [GOOD] ; --- formula ---
-[GOOD] (assert s2)
-[GOOD] (declare-fun s3 () (_ BitVec 8))
-[GOOD] (define-fun s4 () (_ BitVec 8) (|f1 @(SBV Word8 -> SBV Word8)| s3))
-[GOOD] (define-fun s5 () Bool (= s3 s4))
-[GOOD] (assert s5)
+[GOOD] (assert (not s14))
 [SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {f1 @(SBV Word8 -> SBV Word8), f2 @(SBV Word8 -> SBV Word8), f3 @(SBV Word8 -> SBV Word8), f4 @(SBV Word8 -> SBV Word8)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (_ BitVec 8) #x00)
+[GOOD] (define-fun s2 () (_ BitVec 8) #x01)
+[GOOD] (define-fun s3 () (_ BitVec 8) #x02)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (_ BitVec 8)) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () (_ BitVec 8)) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () (_ BitVec 8)) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (= s0 s1))
+[GOOD] (define-fun s5 () (_ BitVec 8) (bvsub s0 s2))
+[GOOD] (define-fun s7 () (_ BitVec 8) (bvsub s0 s3))
+[GOOD] (define-fun s9 () (_ BitVec 8) (bvadd s6 s8))
+[GOOD] (define-fun s10 () (_ BitVec 8) (bvadd s2 s9))
+[GOOD] (define-fun s11 () (_ BitVec 8) (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Int (ubv_to_int s0))
+[GOOD] (define-fun s13 () Int (ubv_to_int s5))
+[GOOD] (define-fun s14 () Int (ubv_to_int s7))
+[GOOD] (define-fun s15 () Bool (not s4))
+[GOOD] (define-fun s16 () Bool (> s12 s13))
+[GOOD] (define-fun s17 () Bool (=> s15 s16))
+[GOOD] (define-fun s18 () Bool (> s12 s14))
+[GOOD] (define-fun s19 () Bool (=> s15 s18))
+[GOOD] (define-fun s20 () Bool (and s17 s19))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s20))
+[SEND] (check-sat)
 [RECV] sat
+[SEND] (get-value (s12))
+[RECV] ((s12 1))
+[SEND] (get-value (s13))
+[RECV] ((s13 0))
+[SEND] (get-value (s14))
+[RECV] ((s14 255))
 [SEND] (get-value (s0))
-[RECV] ((s0 #x00))
-[SEND] (get-value (s3))
-[RECV] ((s3 #x00))
+[RECV] ((s0 #x01))
+[SEND] (get-value (s6))
+[RECV] ((s6 #x00))
+[SEND] (get-value (s8))
+[RECV] ((s8 #x00))
 *** Solver   : Z3
 *** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease failed for f1 @(SBV Word8 -> SBV Word8): Falsifiable. Counter-example:
+  arg     =   1 :: Word8
+  before  =   1 :: Integer
+  then[1] =   0 :: Integer
+  then[2] = 255 :: Integer
+[MEASURE] Mutual group: measure arg1 failed, trying next
 
-RESULT:
-  s0 = 0 :: Word8
-  s3 = 0 :: Word8
+EXCEPTION CAUGHT:
+
+*** Data.SBV: Cannot determine a termination measure for mutual recursion group.
+***
+***     f1  :: SBV Word8 -> SBV Word8
+***     f2  :: SBV Word8 -> SBV Word8
+***     f3  :: SBV Word8 -> SBV Word8
+***     f4  :: SBV Word8 -> SBV Word8
+***
+*** Please use 'smtFunctionWithMeasure' to provide explicit measures.
+
diff --git a/SBVTestSuite/GoldFiles/lambda57a.gold b/SBVTestSuite/GoldFiles/lambda57a.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/lambda57a.gold
@@ -0,0 +1,928 @@
+[MEASURE] Verifying termination measures for: f1i @(SBV Integer -> SBV Integer), f1i @(SBV Integer -> SBV Integer), f2i @(SBV Integer -> SBV Integer), f2i @(SBV Integer -> SBV Integer), f3i @(SBV Integer -> SBV Integer), f3i @(SBV Integer -> SBV Integer), f4i @(SBV Integer -> SBV Integer), f4i @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: f1i @(SBV Integer -> SBV Integer)
+[MEASURE] Checking mutual recursion group: {f1i :: SBV Integer -> SBV Integer, f2i :: SBV Integer -> SBV Integer, f3i :: SBV Integer -> SBV Integer, f4i :: SBV Integer -> SBV Integer}
+[MEASURE] Mutual group: trying measure abs arg1 for all members
+[MEASURE] replayDAG {f1i @(SBV Integer -> SBV Integer), f2i @(SBV Integer -> SBV Integer), f3i @(SBV Integer -> SBV Integer), f4i @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Int (abs s0))
+[GOOD] (define-fun s13 () Bool (>= s12 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s13))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {f1i @(SBV Integer -> SBV Integer), f2i @(SBV Integer -> SBV Integer), f3i @(SBV Integer -> SBV Integer), f4i @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Int (abs s0))
+[GOOD] (define-fun s13 () Int (abs s5))
+[GOOD] (define-fun s14 () Int (abs s7))
+[GOOD] (define-fun s15 () Bool (not s4))
+[GOOD] (define-fun s16 () Bool (> s12 s13))
+[GOOD] (define-fun s17 () Bool (=> s15 s16))
+[GOOD] (define-fun s18 () Bool (> s12 s14))
+[GOOD] (define-fun s19 () Bool (=> s15 s18))
+[GOOD] (define-fun s20 () Bool (and s17 s19))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s20))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s12))
+[RECV] ((s12 1))
+[SEND] (get-value (s13))
+[RECV] ((s13 0))
+[SEND] (get-value (s14))
+[RECV] ((s14 1))
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s6))
+[RECV] ((s6 0))
+[SEND] (get-value (s8))
+[RECV] ((s8 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease failed for f1i @(SBV Integer -> SBV Integer): Falsifiable. Counter-example:
+  arg     = 1 :: Integer
+  before  = 1 :: Integer
+  then[1] = 0 :: Integer
+  then[2] = 1 :: Integer
+[MEASURE] Mutual group: measure abs arg1 failed, trying next
+[MEASURE] Mutual group: trying measure smax 0 arg1 for all members
+[MEASURE] replayDAG {f1i @(SBV Integer -> SBV Integer), f2i @(SBV Integer -> SBV Integer), f3i @(SBV Integer -> SBV Integer), f4i @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Bool (<= s1 s0))
+[GOOD] (define-fun s13 () Int (ite s12 s0 s1))
+[GOOD] (define-fun s14 () Bool (>= s13 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {f1i @(SBV Integer -> SBV Integer), f2i @(SBV Integer -> SBV Integer), f3i @(SBV Integer -> SBV Integer), f4i @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Bool (<= s1 s0))
+[GOOD] (define-fun s13 () Int (ite s12 s0 s1))
+[GOOD] (define-fun s14 () Bool (<= s1 s5))
+[GOOD] (define-fun s15 () Int (ite s14 s5 s1))
+[GOOD] (define-fun s16 () Bool (<= s1 s7))
+[GOOD] (define-fun s17 () Int (ite s16 s7 s1))
+[GOOD] (define-fun s18 () Bool (not s4))
+[GOOD] (define-fun s19 () Bool (> s13 s15))
+[GOOD] (define-fun s20 () Bool (=> s18 s19))
+[GOOD] (define-fun s21 () Bool (> s13 s17))
+[GOOD] (define-fun s22 () Bool (=> s18 s21))
+[GOOD] (define-fun s23 () Bool (and s20 s22))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s23))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for f1i @(SBV Integer -> SBV Integer)
+[MEASURE] replayDAG {f1i @(SBV Integer -> SBV Integer), f2i @(SBV Integer -> SBV Integer), f3i @(SBV Integer -> SBV Integer), f4i @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Bool (<= s1 s0))
+[GOOD] (define-fun s13 () Int (ite s12 s0 s1))
+[GOOD] (define-fun s14 () Bool (>= s13 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {f1i @(SBV Integer -> SBV Integer), f2i @(SBV Integer -> SBV Integer), f3i @(SBV Integer -> SBV Integer), f4i @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Bool (<= s1 s0))
+[GOOD] (define-fun s13 () Int (ite s12 s0 s1))
+[GOOD] (define-fun s14 () Bool (<= s1 s5))
+[GOOD] (define-fun s15 () Int (ite s14 s5 s1))
+[GOOD] (define-fun s16 () Bool (<= s1 s7))
+[GOOD] (define-fun s17 () Int (ite s16 s7 s1))
+[GOOD] (define-fun s18 () Bool (not s4))
+[GOOD] (define-fun s19 () Bool (> s13 s15))
+[GOOD] (define-fun s20 () Bool (=> s18 s19))
+[GOOD] (define-fun s21 () Bool (> s13 s17))
+[GOOD] (define-fun s22 () Bool (=> s18 s21))
+[GOOD] (define-fun s23 () Bool (and s20 s22))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s23))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for f2i @(SBV Integer -> SBV Integer)
+[MEASURE] replayDAG {f1i @(SBV Integer -> SBV Integer), f2i @(SBV Integer -> SBV Integer), f3i @(SBV Integer -> SBV Integer), f4i @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Bool (<= s1 s0))
+[GOOD] (define-fun s13 () Int (ite s12 s0 s1))
+[GOOD] (define-fun s14 () Bool (>= s13 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {f1i @(SBV Integer -> SBV Integer), f2i @(SBV Integer -> SBV Integer), f3i @(SBV Integer -> SBV Integer), f4i @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Bool (<= s1 s0))
+[GOOD] (define-fun s13 () Int (ite s12 s0 s1))
+[GOOD] (define-fun s14 () Bool (<= s1 s5))
+[GOOD] (define-fun s15 () Int (ite s14 s5 s1))
+[GOOD] (define-fun s16 () Bool (<= s1 s7))
+[GOOD] (define-fun s17 () Int (ite s16 s7 s1))
+[GOOD] (define-fun s18 () Bool (not s4))
+[GOOD] (define-fun s19 () Bool (> s13 s15))
+[GOOD] (define-fun s20 () Bool (=> s18 s19))
+[GOOD] (define-fun s21 () Bool (> s13 s17))
+[GOOD] (define-fun s22 () Bool (=> s18 s21))
+[GOOD] (define-fun s23 () Bool (and s20 s22))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s23))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for f3i @(SBV Integer -> SBV Integer)
+[MEASURE] replayDAG {f1i @(SBV Integer -> SBV Integer), f2i @(SBV Integer -> SBV Integer), f3i @(SBV Integer -> SBV Integer), f4i @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Bool (<= s1 s0))
+[GOOD] (define-fun s13 () Int (ite s12 s0 s1))
+[GOOD] (define-fun s14 () Bool (>= s13 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {f1i @(SBV Integer -> SBV Integer), f2i @(SBV Integer -> SBV Integer), f3i @(SBV Integer -> SBV Integer), f4i @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Bool (<= s1 s0))
+[GOOD] (define-fun s13 () Int (ite s12 s0 s1))
+[GOOD] (define-fun s14 () Bool (<= s1 s5))
+[GOOD] (define-fun s15 () Int (ite s14 s5 s1))
+[GOOD] (define-fun s16 () Bool (<= s1 s7))
+[GOOD] (define-fun s17 () Int (ite s16 s7 s1))
+[GOOD] (define-fun s18 () Bool (not s4))
+[GOOD] (define-fun s19 () Bool (> s13 s15))
+[GOOD] (define-fun s20 () Bool (=> s18 s19))
+[GOOD] (define-fun s21 () Bool (> s13 s17))
+[GOOD] (define-fun s22 () Bool (=> s18 s21))
+[GOOD] (define-fun s23 () Bool (and s20 s22))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s23))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for f4i @(SBV Integer -> SBV Integer)
+[MEASURE] Mutual group: measure smax 0 arg1 works for all members
+[MEASURE] Passed (terminating): f1i @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: f1i @(SBV Integer -> SBV Integer)
+[MEASURE] f1i @(SBV Integer -> SBV Integer): barified = "|f1i @(SBV Integer -> SBV Integer)|"
+[MEASURE] f1i @(SBV Integer -> SBV Integer): Uninterpreted ops in DAG: [("|f1i @(SBV Integer -> SBV Integer)|",1),("|f2i @(SBV Integer -> SBV Integer)|",1)]
+[MEASURE] f1i @(SBV Integer -> SBV Integer): recursive calls found = 1
+[MEASURE] f1i @(SBV Integer -> SBV Integer): trying abs arg1
+[MEASURE] replayDAG {f1i @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Int (abs s0))
+[GOOD] (define-fun s13 () Bool (>= s12 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s13))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {f1i @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Int (abs s0))
+[GOOD] (define-fun s13 () Int (abs s5))
+[GOOD] (define-fun s14 () Bool (not s4))
+[GOOD] (define-fun s15 () Bool (> s12 s13))
+[GOOD] (define-fun s16 () Bool (=> s14 s15))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s16))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] f1i @(SBV Integer -> SBV Integer): abs arg1 -> OK
+[MEASURE] Passed (terminating): f1i @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: f2i @(SBV Integer -> SBV Integer)
+[MEASURE] f2i @(SBV Integer -> SBV Integer): mutual group already verified, skipping
+[MEASURE] Passed (terminating): f2i @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: f2i @(SBV Integer -> SBV Integer)
+[MEASURE] f2i @(SBV Integer -> SBV Integer): barified = "|f2i @(SBV Integer -> SBV Integer)|"
+[MEASURE] f2i @(SBV Integer -> SBV Integer): Uninterpreted ops in DAG: [("|f2i @(SBV Integer -> SBV Integer)|",1),("|f3i @(SBV Integer -> SBV Integer)|",1)]
+[MEASURE] f2i @(SBV Integer -> SBV Integer): recursive calls found = 1
+[MEASURE] f2i @(SBV Integer -> SBV Integer): trying abs arg1
+[MEASURE] replayDAG {f2i @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Int (abs s0))
+[GOOD] (define-fun s13 () Bool (>= s12 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s13))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {f2i @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Int (abs s0))
+[GOOD] (define-fun s13 () Int (abs s5))
+[GOOD] (define-fun s14 () Bool (not s4))
+[GOOD] (define-fun s15 () Bool (> s12 s13))
+[GOOD] (define-fun s16 () Bool (=> s14 s15))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s16))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] f2i @(SBV Integer -> SBV Integer): abs arg1 -> OK
+[MEASURE] Passed (terminating): f2i @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: f3i @(SBV Integer -> SBV Integer)
+[MEASURE] f3i @(SBV Integer -> SBV Integer): mutual group already verified, skipping
+[MEASURE] Passed (terminating): f3i @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: f3i @(SBV Integer -> SBV Integer)
+[MEASURE] f3i @(SBV Integer -> SBV Integer): barified = "|f3i @(SBV Integer -> SBV Integer)|"
+[MEASURE] f3i @(SBV Integer -> SBV Integer): Uninterpreted ops in DAG: [("|f3i @(SBV Integer -> SBV Integer)|",1),("|f4i @(SBV Integer -> SBV Integer)|",1)]
+[MEASURE] f3i @(SBV Integer -> SBV Integer): recursive calls found = 1
+[MEASURE] f3i @(SBV Integer -> SBV Integer): trying abs arg1
+[MEASURE] replayDAG {f3i @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Int (abs s0))
+[GOOD] (define-fun s13 () Bool (>= s12 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s13))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {f3i @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Int (abs s0))
+[GOOD] (define-fun s13 () Int (abs s5))
+[GOOD] (define-fun s14 () Bool (not s4))
+[GOOD] (define-fun s15 () Bool (> s12 s13))
+[GOOD] (define-fun s16 () Bool (=> s14 s15))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s16))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] f3i @(SBV Integer -> SBV Integer): abs arg1 -> OK
+[MEASURE] Passed (terminating): f3i @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: f4i @(SBV Integer -> SBV Integer)
+[MEASURE] f4i @(SBV Integer -> SBV Integer): mutual group already verified, skipping
+[MEASURE] Passed (terminating): f4i @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: f4i @(SBV Integer -> SBV Integer)
+[MEASURE] f4i @(SBV Integer -> SBV Integer): barified = "|f4i @(SBV Integer -> SBV Integer)|"
+[MEASURE] f4i @(SBV Integer -> SBV Integer): Uninterpreted ops in DAG: [("|f4i @(SBV Integer -> SBV Integer)|",1),("|f1i @(SBV Integer -> SBV Integer)|",1)]
+[MEASURE] f4i @(SBV Integer -> SBV Integer): recursive calls found = 1
+[MEASURE] f4i @(SBV Integer -> SBV Integer): trying abs arg1
+[MEASURE] replayDAG {f4i @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Int (abs s0))
+[GOOD] (define-fun s13 () Bool (>= s12 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s13))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {f4i @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Int (abs s0))
+[GOOD] (define-fun s13 () Int (abs s5))
+[GOOD] (define-fun s14 () Bool (not s4))
+[GOOD] (define-fun s15 () Bool (> s12 s13))
+[GOOD] (define-fun s16 () Bool (=> s14 s15))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s16))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] f4i @(SBV Integer -> SBV Integer): abs arg1 -> OK
+[MEASURE] Passed (terminating): f4i @(SBV Integer -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |f1i @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger, |f2i @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger, |f3i @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger, |f4i @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger
+[GOOD] (define-funs-rec
+         ((|f1i @(SBV Integer -> SBV Integer)| ((l1_s0 Int)) Int)
+          (|f2i @(SBV Integer -> SBV Integer)| ((l2_s0 Int)) Int)
+          (|f3i @(SBV Integer -> SBV Integer)| ((l3_s0 Int)) Int)
+          (|f4i @(SBV Integer -> SBV Integer)| ((l4_s0 Int)) Int))
+         (; Definition of: |f1i @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |f1i @(SBV Integer -> SBV Integer)|, |f2i @(SBV Integer -> SBV Integer)|]
+                                  (let ((l1_s1 0))
+                                  (let ((l1_s3 1))
+                                  (let ((l1_s6 2))
+                                  (let ((l1_s2 (<= l1_s0 l1_s1)))
+                                  (let ((l1_s4 (- l1_s0 l1_s3)))
+                                  (let ((l1_s5 (|f1i @(SBV Integer -> SBV Integer)| l1_s4)))
+                                  (let ((l1_s7 (- l1_s0 l1_s6)))
+                                  (let ((l1_s8 (|f2i @(SBV Integer -> SBV Integer)| l1_s7)))
+                                  (let ((l1_s9 (+ l1_s5 l1_s8)))
+                                  (let ((l1_s10 (+ l1_s3 l1_s9)))
+                                  (let ((l1_s11 (ite l1_s2 l1_s1 l1_s10)))
+                                  l1_s11)))))))))))
+          ; Definition of: |f2i @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |f2i @(SBV Integer -> SBV Integer)|, |f3i @(SBV Integer -> SBV Integer)|]
+                                                  (let ((l2_s1 0))
+                                                  (let ((l2_s3 1))
+                                                  (let ((l2_s6 2))
+                                                  (let ((l2_s2 (<= l2_s0 l2_s1)))
+                                                  (let ((l2_s4 (- l2_s0 l2_s3)))
+                                                  (let ((l2_s5 (|f2i @(SBV Integer -> SBV Integer)| l2_s4)))
+                                                  (let ((l2_s7 (- l2_s0 l2_s6)))
+                                                  (let ((l2_s8 (|f3i @(SBV Integer -> SBV Integer)| l2_s7)))
+                                                  (let ((l2_s9 (+ l2_s5 l2_s8)))
+                                                  (let ((l2_s10 (+ l2_s3 l2_s9)))
+                                                  (let ((l2_s11 (ite l2_s2 l2_s1 l2_s10)))
+                                                  l2_s11)))))))))))
+          ; Definition of: |f3i @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |f3i @(SBV Integer -> SBV Integer)|, |f4i @(SBV Integer -> SBV Integer)|]
+                                                                  (let ((l3_s1 0))
+                                                                  (let ((l3_s3 1))
+                                                                  (let ((l3_s6 2))
+                                                                  (let ((l3_s2 (<= l3_s0 l3_s1)))
+                                                                  (let ((l3_s4 (- l3_s0 l3_s3)))
+                                                                  (let ((l3_s5 (|f3i @(SBV Integer -> SBV Integer)| l3_s4)))
+                                                                  (let ((l3_s7 (- l3_s0 l3_s6)))
+                                                                  (let ((l3_s8 (|f4i @(SBV Integer -> SBV Integer)| l3_s7)))
+                                                                  (let ((l3_s9 (+ l3_s5 l3_s8)))
+                                                                  (let ((l3_s10 (+ l3_s3 l3_s9)))
+                                                                  (let ((l3_s11 (ite l3_s2 l3_s1 l3_s10)))
+                                                                  l3_s11)))))))))))
+          ; Definition of: |f4i @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |f1i @(SBV Integer -> SBV Integer)|, |f4i @(SBV Integer -> SBV Integer)|]
+                                                                                  (let ((l4_s1 0))
+                                                                                  (let ((l4_s3 1))
+                                                                                  (let ((l4_s6 2))
+                                                                                  (let ((l4_s2 (<= l4_s0 l4_s1)))
+                                                                                  (let ((l4_s4 (- l4_s0 l4_s3)))
+                                                                                  (let ((l4_s5 (|f4i @(SBV Integer -> SBV Integer)| l4_s4)))
+                                                                                  (let ((l4_s7 (- l4_s0 l4_s6)))
+                                                                                  (let ((l4_s8 (|f1i @(SBV Integer -> SBV Integer)| l4_s7)))
+                                                                                  (let ((l4_s9 (+ l4_s5 l4_s8)))
+                                                                                  (let ((l4_s10 (+ l4_s3 l4_s9)))
+                                                                                  (let ((l4_s11 (ite l4_s2 l4_s1 l4_s10)))
+                                                                                  l4_s11)))))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Int (|f1i @(SBV Integer -> SBV Integer)| s0))
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (declare-fun s3 () Int)
+[GOOD] (define-fun s4 () Int (|f1i @(SBV Integer -> SBV Integer)| s3))
+[GOOD] (define-fun s5 () Bool (= s3 s4))
+[GOOD] (assert s5)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 0))
+[SEND] (get-value (s3))
+[RECV] ((s3 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+
+RESULT:
+  s0 = 0 :: Integer
+  s3 = 0 :: Integer
diff --git a/SBVTestSuite/GoldFiles/lambda57b.gold b/SBVTestSuite/GoldFiles/lambda57b.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/lambda57b.gold
@@ -0,0 +1,824 @@
+[MEASURE] Verifying termination measures for: f1m @(SBV Integer -> SBV Integer), f1m @(SBV Integer -> SBV Integer), f2m @(SBV Integer -> SBV Integer), f2m @(SBV Integer -> SBV Integer), f3m @(SBV Integer -> SBV Integer), f3m @(SBV Integer -> SBV Integer), f4m @(SBV Integer -> SBV Integer), f4m @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: f1m @(SBV Integer -> SBV Integer)
+[MEASURE] Checking mutual recursion group: {f1m :: SBV Integer -> SBV Integer, f2m :: SBV Integer -> SBV Integer, f3m :: SBV Integer -> SBV Integer, f4m :: SBV Integer -> SBV Integer}
+[MEASURE] Mutual group: trying user-provided measure for all members
+[MEASURE] replayDAG {f1m @(SBV Integer -> SBV Integer), f2m @(SBV Integer -> SBV Integer), f3m @(SBV Integer -> SBV Integer), f4m @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Bool (<= s1 s0))
+[GOOD] (define-fun s13 () Int (ite s12 s0 s1))
+[GOOD] (define-fun s14 () Bool (>= s13 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {f1m @(SBV Integer -> SBV Integer), f2m @(SBV Integer -> SBV Integer), f3m @(SBV Integer -> SBV Integer), f4m @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Bool (<= s1 s0))
+[GOOD] (define-fun s13 () Int (ite s12 s0 s1))
+[GOOD] (define-fun s14 () Bool (<= s1 s5))
+[GOOD] (define-fun s15 () Int (ite s14 s5 s1))
+[GOOD] (define-fun s16 () Bool (<= s1 s7))
+[GOOD] (define-fun s17 () Int (ite s16 s7 s1))
+[GOOD] (define-fun s18 () Bool (not s4))
+[GOOD] (define-fun s19 () Bool (> s13 s15))
+[GOOD] (define-fun s20 () Bool (=> s18 s19))
+[GOOD] (define-fun s21 () Bool (> s13 s17))
+[GOOD] (define-fun s22 () Bool (=> s18 s21))
+[GOOD] (define-fun s23 () Bool (and s20 s22))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s23))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for f1m @(SBV Integer -> SBV Integer)
+[MEASURE] replayDAG {f1m @(SBV Integer -> SBV Integer), f2m @(SBV Integer -> SBV Integer), f3m @(SBV Integer -> SBV Integer), f4m @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Bool (<= s1 s0))
+[GOOD] (define-fun s13 () Int (ite s12 s0 s1))
+[GOOD] (define-fun s14 () Bool (>= s13 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {f1m @(SBV Integer -> SBV Integer), f2m @(SBV Integer -> SBV Integer), f3m @(SBV Integer -> SBV Integer), f4m @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Bool (<= s1 s0))
+[GOOD] (define-fun s13 () Int (ite s12 s0 s1))
+[GOOD] (define-fun s14 () Bool (<= s1 s5))
+[GOOD] (define-fun s15 () Int (ite s14 s5 s1))
+[GOOD] (define-fun s16 () Bool (<= s1 s7))
+[GOOD] (define-fun s17 () Int (ite s16 s7 s1))
+[GOOD] (define-fun s18 () Bool (not s4))
+[GOOD] (define-fun s19 () Bool (> s13 s15))
+[GOOD] (define-fun s20 () Bool (=> s18 s19))
+[GOOD] (define-fun s21 () Bool (> s13 s17))
+[GOOD] (define-fun s22 () Bool (=> s18 s21))
+[GOOD] (define-fun s23 () Bool (and s20 s22))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s23))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for f2m @(SBV Integer -> SBV Integer)
+[MEASURE] replayDAG {f1m @(SBV Integer -> SBV Integer), f2m @(SBV Integer -> SBV Integer), f3m @(SBV Integer -> SBV Integer), f4m @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Bool (<= s1 s0))
+[GOOD] (define-fun s13 () Int (ite s12 s0 s1))
+[GOOD] (define-fun s14 () Bool (>= s13 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {f1m @(SBV Integer -> SBV Integer), f2m @(SBV Integer -> SBV Integer), f3m @(SBV Integer -> SBV Integer), f4m @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Bool (<= s1 s0))
+[GOOD] (define-fun s13 () Int (ite s12 s0 s1))
+[GOOD] (define-fun s14 () Bool (<= s1 s5))
+[GOOD] (define-fun s15 () Int (ite s14 s5 s1))
+[GOOD] (define-fun s16 () Bool (<= s1 s7))
+[GOOD] (define-fun s17 () Int (ite s16 s7 s1))
+[GOOD] (define-fun s18 () Bool (not s4))
+[GOOD] (define-fun s19 () Bool (> s13 s15))
+[GOOD] (define-fun s20 () Bool (=> s18 s19))
+[GOOD] (define-fun s21 () Bool (> s13 s17))
+[GOOD] (define-fun s22 () Bool (=> s18 s21))
+[GOOD] (define-fun s23 () Bool (and s20 s22))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s23))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for f3m @(SBV Integer -> SBV Integer)
+[MEASURE] replayDAG {f1m @(SBV Integer -> SBV Integer), f2m @(SBV Integer -> SBV Integer), f3m @(SBV Integer -> SBV Integer), f4m @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Bool (<= s1 s0))
+[GOOD] (define-fun s13 () Int (ite s12 s0 s1))
+[GOOD] (define-fun s14 () Bool (>= s13 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {f1m @(SBV Integer -> SBV Integer), f2m @(SBV Integer -> SBV Integer), f3m @(SBV Integer -> SBV Integer), f4m @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Bool (<= s1 s0))
+[GOOD] (define-fun s13 () Int (ite s12 s0 s1))
+[GOOD] (define-fun s14 () Bool (<= s1 s5))
+[GOOD] (define-fun s15 () Int (ite s14 s5 s1))
+[GOOD] (define-fun s16 () Bool (<= s1 s7))
+[GOOD] (define-fun s17 () Int (ite s16 s7 s1))
+[GOOD] (define-fun s18 () Bool (not s4))
+[GOOD] (define-fun s19 () Bool (> s13 s15))
+[GOOD] (define-fun s20 () Bool (=> s18 s19))
+[GOOD] (define-fun s21 () Bool (> s13 s17))
+[GOOD] (define-fun s22 () Bool (=> s18 s21))
+[GOOD] (define-fun s23 () Bool (and s20 s22))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s23))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for f4m @(SBV Integer -> SBV Integer)
+[MEASURE] Mutual group: user-provided measure works for all members
+[MEASURE] Passed (terminating): f1m @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: f1m @(SBV Integer -> SBV Integer)
+[MEASURE] f1m @(SBV Integer -> SBV Integer): verifying with 0 helper(s)
+[MEASURE] f1m @(SBV Integer -> SBV Integer): 0 helper axiom(s) collected, checking measure
+[MEASURE] replayDAG {f1m @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Bool (<= s1 s0))
+[GOOD] (define-fun s13 () Int (ite s12 s0 s1))
+[GOOD] (define-fun s14 () Bool (>= s13 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {f1m @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Bool (<= s1 s0))
+[GOOD] (define-fun s13 () Int (ite s12 s0 s1))
+[GOOD] (define-fun s14 () Bool (<= s1 s5))
+[GOOD] (define-fun s15 () Int (ite s14 s5 s1))
+[GOOD] (define-fun s16 () Bool (not s4))
+[GOOD] (define-fun s17 () Bool (> s13 s15))
+[GOOD] (define-fun s18 () Bool (=> s16 s17))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s18))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Passed (terminating): f1m @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: f2m @(SBV Integer -> SBV Integer)
+[MEASURE] f2m @(SBV Integer -> SBV Integer): mutual group already verified, skipping
+[MEASURE] Passed (terminating): f2m @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: f2m @(SBV Integer -> SBV Integer)
+[MEASURE] f2m @(SBV Integer -> SBV Integer): verifying with 0 helper(s)
+[MEASURE] f2m @(SBV Integer -> SBV Integer): 0 helper axiom(s) collected, checking measure
+[MEASURE] replayDAG {f2m @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Bool (<= s1 s0))
+[GOOD] (define-fun s13 () Int (ite s12 s0 s1))
+[GOOD] (define-fun s14 () Bool (>= s13 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {f2m @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Bool (<= s1 s0))
+[GOOD] (define-fun s13 () Int (ite s12 s0 s1))
+[GOOD] (define-fun s14 () Bool (<= s1 s5))
+[GOOD] (define-fun s15 () Int (ite s14 s5 s1))
+[GOOD] (define-fun s16 () Bool (not s4))
+[GOOD] (define-fun s17 () Bool (> s13 s15))
+[GOOD] (define-fun s18 () Bool (=> s16 s17))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s18))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Passed (terminating): f2m @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: f3m @(SBV Integer -> SBV Integer)
+[MEASURE] f3m @(SBV Integer -> SBV Integer): mutual group already verified, skipping
+[MEASURE] Passed (terminating): f3m @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: f3m @(SBV Integer -> SBV Integer)
+[MEASURE] f3m @(SBV Integer -> SBV Integer): verifying with 0 helper(s)
+[MEASURE] f3m @(SBV Integer -> SBV Integer): 0 helper axiom(s) collected, checking measure
+[MEASURE] replayDAG {f3m @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Bool (<= s1 s0))
+[GOOD] (define-fun s13 () Int (ite s12 s0 s1))
+[GOOD] (define-fun s14 () Bool (>= s13 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {f3m @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Bool (<= s1 s0))
+[GOOD] (define-fun s13 () Int (ite s12 s0 s1))
+[GOOD] (define-fun s14 () Bool (<= s1 s5))
+[GOOD] (define-fun s15 () Int (ite s14 s5 s1))
+[GOOD] (define-fun s16 () Bool (not s4))
+[GOOD] (define-fun s17 () Bool (> s13 s15))
+[GOOD] (define-fun s18 () Bool (=> s16 s17))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s18))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Passed (terminating): f3m @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: f4m @(SBV Integer -> SBV Integer)
+[MEASURE] f4m @(SBV Integer -> SBV Integer): mutual group already verified, skipping
+[MEASURE] Passed (terminating): f4m @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: f4m @(SBV Integer -> SBV Integer)
+[MEASURE] f4m @(SBV Integer -> SBV Integer): verifying with 0 helper(s)
+[MEASURE] f4m @(SBV Integer -> SBV Integer): 0 helper axiom(s) collected, checking measure
+[MEASURE] replayDAG {f4m @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Bool (<= s1 s0))
+[GOOD] (define-fun s13 () Int (ite s12 s0 s1))
+[GOOD] (define-fun s14 () Bool (>= s13 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {f4m @(SBV Integer -> SBV Integer)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s1))
+[GOOD] (define-fun s5 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (+ s6 s8))
+[GOOD] (define-fun s10 () Int (+ s2 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Bool (<= s1 s0))
+[GOOD] (define-fun s13 () Int (ite s12 s0 s1))
+[GOOD] (define-fun s14 () Bool (<= s1 s5))
+[GOOD] (define-fun s15 () Int (ite s14 s5 s1))
+[GOOD] (define-fun s16 () Bool (not s4))
+[GOOD] (define-fun s17 () Bool (> s13 s15))
+[GOOD] (define-fun s18 () Bool (=> s16 s17))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s18))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Passed (terminating): f4m @(SBV Integer -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |f1m @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger, |f2m @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger, |f3m @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger, |f4m @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger
+[GOOD] (define-funs-rec
+         ((|f1m @(SBV Integer -> SBV Integer)| ((l1_s0 Int)) Int)
+          (|f2m @(SBV Integer -> SBV Integer)| ((l2_s0 Int)) Int)
+          (|f3m @(SBV Integer -> SBV Integer)| ((l3_s0 Int)) Int)
+          (|f4m @(SBV Integer -> SBV Integer)| ((l4_s0 Int)) Int))
+         (; Definition of: |f1m @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |f1m @(SBV Integer -> SBV Integer)|, |f2m @(SBV Integer -> SBV Integer)|]
+                                  (let ((l1_s1 0))
+                                  (let ((l1_s3 1))
+                                  (let ((l1_s6 2))
+                                  (let ((l1_s2 (<= l1_s0 l1_s1)))
+                                  (let ((l1_s4 (- l1_s0 l1_s3)))
+                                  (let ((l1_s5 (|f1m @(SBV Integer -> SBV Integer)| l1_s4)))
+                                  (let ((l1_s7 (- l1_s0 l1_s6)))
+                                  (let ((l1_s8 (|f2m @(SBV Integer -> SBV Integer)| l1_s7)))
+                                  (let ((l1_s9 (+ l1_s5 l1_s8)))
+                                  (let ((l1_s10 (+ l1_s3 l1_s9)))
+                                  (let ((l1_s11 (ite l1_s2 l1_s1 l1_s10)))
+                                  l1_s11)))))))))))
+          ; Definition of: |f2m @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |f2m @(SBV Integer -> SBV Integer)|, |f3m @(SBV Integer -> SBV Integer)|]
+                                                  (let ((l2_s1 0))
+                                                  (let ((l2_s3 1))
+                                                  (let ((l2_s6 2))
+                                                  (let ((l2_s2 (<= l2_s0 l2_s1)))
+                                                  (let ((l2_s4 (- l2_s0 l2_s3)))
+                                                  (let ((l2_s5 (|f2m @(SBV Integer -> SBV Integer)| l2_s4)))
+                                                  (let ((l2_s7 (- l2_s0 l2_s6)))
+                                                  (let ((l2_s8 (|f3m @(SBV Integer -> SBV Integer)| l2_s7)))
+                                                  (let ((l2_s9 (+ l2_s5 l2_s8)))
+                                                  (let ((l2_s10 (+ l2_s3 l2_s9)))
+                                                  (let ((l2_s11 (ite l2_s2 l2_s1 l2_s10)))
+                                                  l2_s11)))))))))))
+          ; Definition of: |f3m @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |f3m @(SBV Integer -> SBV Integer)|, |f4m @(SBV Integer -> SBV Integer)|]
+                                                                  (let ((l3_s1 0))
+                                                                  (let ((l3_s3 1))
+                                                                  (let ((l3_s6 2))
+                                                                  (let ((l3_s2 (<= l3_s0 l3_s1)))
+                                                                  (let ((l3_s4 (- l3_s0 l3_s3)))
+                                                                  (let ((l3_s5 (|f3m @(SBV Integer -> SBV Integer)| l3_s4)))
+                                                                  (let ((l3_s7 (- l3_s0 l3_s6)))
+                                                                  (let ((l3_s8 (|f4m @(SBV Integer -> SBV Integer)| l3_s7)))
+                                                                  (let ((l3_s9 (+ l3_s5 l3_s8)))
+                                                                  (let ((l3_s10 (+ l3_s3 l3_s9)))
+                                                                  (let ((l3_s11 (ite l3_s2 l3_s1 l3_s10)))
+                                                                  l3_s11)))))))))))
+          ; Definition of: |f4m @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |f1m @(SBV Integer -> SBV Integer)|, |f4m @(SBV Integer -> SBV Integer)|]
+                                                                                  (let ((l4_s1 0))
+                                                                                  (let ((l4_s3 1))
+                                                                                  (let ((l4_s6 2))
+                                                                                  (let ((l4_s2 (<= l4_s0 l4_s1)))
+                                                                                  (let ((l4_s4 (- l4_s0 l4_s3)))
+                                                                                  (let ((l4_s5 (|f4m @(SBV Integer -> SBV Integer)| l4_s4)))
+                                                                                  (let ((l4_s7 (- l4_s0 l4_s6)))
+                                                                                  (let ((l4_s8 (|f1m @(SBV Integer -> SBV Integer)| l4_s7)))
+                                                                                  (let ((l4_s9 (+ l4_s5 l4_s8)))
+                                                                                  (let ((l4_s10 (+ l4_s3 l4_s9)))
+                                                                                  (let ((l4_s11 (ite l4_s2 l4_s1 l4_s10)))
+                                                                                  l4_s11)))))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Int (|f1m @(SBV Integer -> SBV Integer)| s0))
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (declare-fun s3 () Int)
+[GOOD] (define-fun s4 () Int (|f1m @(SBV Integer -> SBV Integer)| s3))
+[GOOD] (define-fun s5 () Bool (= s3 s4))
+[GOOD] (assert s5)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 0))
+[SEND] (get-value (s3))
+[RECV] ((s3 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+
+RESULT:
+  s0 = 0 :: Integer
+  s3 = 0 :: Integer
diff --git a/SBVTestSuite/GoldFiles/lambda57c.gold b/SBVTestSuite/GoldFiles/lambda57c.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/lambda57c.gold
@@ -0,0 +1,225 @@
+[MEASURE] Verifying termination measures for: f1w @(SBV Word8 -> SBV Word8), f1w @(SBV Word8 -> SBV Word8), f2w @(SBV Word8 -> SBV Word8), f2w @(SBV Word8 -> SBV Word8), f3w @(SBV Word8 -> SBV Word8), f3w @(SBV Word8 -> SBV Word8), f4w @(SBV Word8 -> SBV Word8), f4w @(SBV Word8 -> SBV Word8)
+[MEASURE] Checking: f1w @(SBV Word8 -> SBV Word8)
+[MEASURE] Checking mutual recursion group: {f1w :: SBV Word8 -> SBV Word8, f2w :: SBV Word8 -> SBV Word8, f3w :: SBV Word8 -> SBV Word8, f4w :: SBV Word8 -> SBV Word8}
+[MEASURE] Mutual group: trying user-provided measure for all members
+[MEASURE] replayDAG {f1w @(SBV Word8 -> SBV Word8), f2w @(SBV Word8 -> SBV Word8), f3w @(SBV Word8 -> SBV Word8), f4w @(SBV Word8 -> SBV Word8)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (_ BitVec 8) #x00)
+[GOOD] (define-fun s2 () (_ BitVec 8) #x01)
+[GOOD] (define-fun s3 () (_ BitVec 8) #x02)
+[GOOD] (define-fun s13 () Int 0)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (_ BitVec 8)) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () (_ BitVec 8)) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () (_ BitVec 8)) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (= s0 s1))
+[GOOD] (define-fun s5 () (_ BitVec 8) (bvsub s0 s2))
+[GOOD] (define-fun s7 () (_ BitVec 8) (bvsub s0 s3))
+[GOOD] (define-fun s9 () (_ BitVec 8) (bvadd s6 s8))
+[GOOD] (define-fun s10 () (_ BitVec 8) (bvadd s2 s9))
+[GOOD] (define-fun s11 () (_ BitVec 8) (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Int (ubv_to_int s0))
+[GOOD] (define-fun s14 () Bool (>= s12 s13))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {f1w @(SBV Word8 -> SBV Word8), f2w @(SBV Word8 -> SBV Word8), f3w @(SBV Word8 -> SBV Word8), f4w @(SBV Word8 -> SBV Word8)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (_ BitVec 8) #x00)
+[GOOD] (define-fun s2 () (_ BitVec 8) #x01)
+[GOOD] (define-fun s3 () (_ BitVec 8) #x02)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (_ BitVec 8)) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () (_ BitVec 8)) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () (_ BitVec 8)) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (= s0 s1))
+[GOOD] (define-fun s5 () (_ BitVec 8) (bvsub s0 s2))
+[GOOD] (define-fun s7 () (_ BitVec 8) (bvsub s0 s3))
+[GOOD] (define-fun s9 () (_ BitVec 8) (bvadd s6 s8))
+[GOOD] (define-fun s10 () (_ BitVec 8) (bvadd s2 s9))
+[GOOD] (define-fun s11 () (_ BitVec 8) (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Int (ubv_to_int s0))
+[GOOD] (define-fun s13 () Int (ubv_to_int s5))
+[GOOD] (define-fun s14 () Int (ubv_to_int s7))
+[GOOD] (define-fun s15 () Bool (not s4))
+[GOOD] (define-fun s16 () Bool (> s12 s13))
+[GOOD] (define-fun s17 () Bool (=> s15 s16))
+[GOOD] (define-fun s18 () Bool (> s12 s14))
+[GOOD] (define-fun s19 () Bool (=> s15 s18))
+[GOOD] (define-fun s20 () Bool (and s17 s19))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s20))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s12))
+[RECV] ((s12 1))
+[SEND] (get-value (s13))
+[RECV] ((s13 0))
+[SEND] (get-value (s14))
+[RECV] ((s14 255))
+[SEND] (get-value (s0))
+[RECV] ((s0 #x01))
+[SEND] (get-value (s6))
+[RECV] ((s6 #x00))
+[SEND] (get-value (s8))
+[RECV] ((s8 #x00))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease failed for f1w @(SBV Word8 -> SBV Word8): Falsifiable. Counter-example:
+  arg     =   1 :: Word8
+  before  =   1 :: Integer
+  then[1] =   0 :: Integer
+  then[2] = 255 :: Integer
+[MEASURE] Mutual group: user-provided measure failed, falling back to auto-guess
+[MEASURE] Mutual group: trying measure arg1 for all members
+[MEASURE] replayDAG {f1w @(SBV Word8 -> SBV Word8), f2w @(SBV Word8 -> SBV Word8), f3w @(SBV Word8 -> SBV Word8), f4w @(SBV Word8 -> SBV Word8)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (_ BitVec 8) #x00)
+[GOOD] (define-fun s2 () (_ BitVec 8) #x01)
+[GOOD] (define-fun s3 () (_ BitVec 8) #x02)
+[GOOD] (define-fun s13 () Int 0)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (_ BitVec 8)) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () (_ BitVec 8)) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () (_ BitVec 8)) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (= s0 s1))
+[GOOD] (define-fun s5 () (_ BitVec 8) (bvsub s0 s2))
+[GOOD] (define-fun s7 () (_ BitVec 8) (bvsub s0 s3))
+[GOOD] (define-fun s9 () (_ BitVec 8) (bvadd s6 s8))
+[GOOD] (define-fun s10 () (_ BitVec 8) (bvadd s2 s9))
+[GOOD] (define-fun s11 () (_ BitVec 8) (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Int (ubv_to_int s0))
+[GOOD] (define-fun s14 () Bool (>= s12 s13))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {f1w @(SBV Word8 -> SBV Word8), f2w @(SBV Word8 -> SBV Word8), f3w @(SBV Word8 -> SBV Word8), f4w @(SBV Word8 -> SBV Word8)}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () (_ BitVec 8) #x00)
+[GOOD] (define-fun s2 () (_ BitVec 8) #x01)
+[GOOD] (define-fun s3 () (_ BitVec 8) #x02)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (_ BitVec 8)) ; tracks user variable "arg"
+[GOOD] (declare-fun s6 () (_ BitVec 8)) ; tracks user variable "__internal_sbv_s6"
+[GOOD] (declare-fun s8 () (_ BitVec 8)) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (= s0 s1))
+[GOOD] (define-fun s5 () (_ BitVec 8) (bvsub s0 s2))
+[GOOD] (define-fun s7 () (_ BitVec 8) (bvsub s0 s3))
+[GOOD] (define-fun s9 () (_ BitVec 8) (bvadd s6 s8))
+[GOOD] (define-fun s10 () (_ BitVec 8) (bvadd s2 s9))
+[GOOD] (define-fun s11 () (_ BitVec 8) (ite s4 s1 s10))
+[GOOD] (define-fun s12 () Int (ubv_to_int s0))
+[GOOD] (define-fun s13 () Int (ubv_to_int s5))
+[GOOD] (define-fun s14 () Int (ubv_to_int s7))
+[GOOD] (define-fun s15 () Bool (not s4))
+[GOOD] (define-fun s16 () Bool (> s12 s13))
+[GOOD] (define-fun s17 () Bool (=> s15 s16))
+[GOOD] (define-fun s18 () Bool (> s12 s14))
+[GOOD] (define-fun s19 () Bool (=> s15 s18))
+[GOOD] (define-fun s20 () Bool (and s17 s19))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s20))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s12))
+[RECV] ((s12 1))
+[SEND] (get-value (s13))
+[RECV] ((s13 0))
+[SEND] (get-value (s14))
+[RECV] ((s14 255))
+[SEND] (get-value (s0))
+[RECV] ((s0 #x01))
+[SEND] (get-value (s6))
+[RECV] ((s6 #x00))
+[SEND] (get-value (s8))
+[RECV] ((s8 #x00))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease failed for f1w @(SBV Word8 -> SBV Word8): Falsifiable. Counter-example:
+  arg     =   1 :: Word8
+  before  =   1 :: Integer
+  then[1] =   0 :: Integer
+  then[2] = 255 :: Integer
+[MEASURE] Mutual group: measure arg1 failed, trying next
+
+EXCEPTION CAUGHT:
+
+*** Data.SBV: Cannot determine a termination measure for mutual recursion group.
+***
+***     f1w  :: SBV Word8 -> SBV Word8
+***     f2w  :: SBV Word8 -> SBV Word8
+***     f3w  :: SBV Word8 -> SBV Word8
+***     f4w  :: SBV Word8 -> SBV Word8
+***
+*** The user-provided measure did not work, and auto-guessing also failed.
+
diff --git a/SBVTestSuite/GoldFiles/lambda60.gold b/SBVTestSuite/GoldFiles/lambda60.gold
--- a/SBVTestSuite/GoldFiles/lambda60.gold
+++ b/SBVTestSuite/GoldFiles/lambda60.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda61.gold b/SBVTestSuite/GoldFiles/lambda61.gold
--- a/SBVTestSuite/GoldFiles/lambda61.gold
+++ b/SBVTestSuite/GoldFiles/lambda61.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda62.gold b/SBVTestSuite/GoldFiles/lambda62.gold
--- a/SBVTestSuite/GoldFiles/lambda62.gold
+++ b/SBVTestSuite/GoldFiles/lambda62.gold
@@ -5,12 +5,11 @@
 [GOOD] (set-option :smtlib2_compliant true)
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
-[GOOD] (set-logic ALL) ; has user-defined sorts, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
-[GOOD] (declare-sort P 0)  ; N.B. Uninterpreted sort.
-[GOOD] (declare-fun P_witness () P)
+[GOOD] (set-logic ALL) ; has user-defined data-types, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] (declare-sort P 0) ; N.B. Uninterpreted sort.
 [GOOD] ; --- literal constants ---
 [GOOD] ; --- top level inputs ---
 [GOOD] ; --- constant tables ---
diff --git a/SBVTestSuite/GoldFiles/lambda63.gold b/SBVTestSuite/GoldFiles/lambda63.gold
--- a/SBVTestSuite/GoldFiles/lambda63.gold
+++ b/SBVTestSuite/GoldFiles/lambda63.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda64.gold b/SBVTestSuite/GoldFiles/lambda64.gold
--- a/SBVTestSuite/GoldFiles/lambda64.gold
+++ b/SBVTestSuite/GoldFiles/lambda64.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] ; has special relations, no logic set.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda65.gold b/SBVTestSuite/GoldFiles/lambda65.gold
--- a/SBVTestSuite/GoldFiles/lambda65.gold
+++ b/SBVTestSuite/GoldFiles/lambda65.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] ; has special relations, no logic set.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda66.gold b/SBVTestSuite/GoldFiles/lambda66.gold
--- a/SBVTestSuite/GoldFiles/lambda66.gold
+++ b/SBVTestSuite/GoldFiles/lambda66.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] ; has special relations, no logic set.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda67.gold b/SBVTestSuite/GoldFiles/lambda67.gold
--- a/SBVTestSuite/GoldFiles/lambda67.gold
+++ b/SBVTestSuite/GoldFiles/lambda67.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] ; has special relations, no logic set.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda68.gold b/SBVTestSuite/GoldFiles/lambda68.gold
--- a/SBVTestSuite/GoldFiles/lambda68.gold
+++ b/SBVTestSuite/GoldFiles/lambda68.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda69.gold b/SBVTestSuite/GoldFiles/lambda69.gold
--- a/SBVTestSuite/GoldFiles/lambda69.gold
+++ b/SBVTestSuite/GoldFiles/lambda69.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
@@ -35,11 +34,11 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [SEND] (get-value (F))
-[RECV] ((F (lambda ((x!1 Int) (x!2 Int)) (+ 3 (* 2 x!1) (* (- 1) x!2)))))
+[RECV] ((F (lambda ((x!1 Int) (x!2 Int)) (+ 3 (* (- 1) x!2) (* 2 x!1)))))
 *** Solver   : Z3
 *** Exit code: ExitSuccess
 
 RESULT:
 Satisfiable. Model:
   F :: Integer -> Integer -> Integer
-  F x y = 3 + 2 * x + (-y)
+  F x y = 3 + (-y) + 2 * x
diff --git a/SBVTestSuite/GoldFiles/lambda70.gold b/SBVTestSuite/GoldFiles/lambda70.gold
--- a/SBVTestSuite/GoldFiles/lambda70.gold
+++ b/SBVTestSuite/GoldFiles/lambda70.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
@@ -47,16 +46,18 @@
 [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 Int Int)) 0)))
+[RECV] ((x_eu1 (store ((as const (Array Int Int)) 1) 1 0)))
 [SEND] (get-value (x_eu2))
-[RECV] ((x_eu2 ((as const (Array Int Int)) 1)))
+[RECV] ((x_eu2 (store ((as const (Array Int Int)) 0) 1 1)))
 *** Solver   : Z3
 *** Exit code: ExitSuccess
 
 RESULT:
 Satisfiable. Model:
   x_eu1 :: Integer -> Integer
-  x_eu1 _ = 0
+  x_eu1 1 = 0
+  x_eu1 _ = 1
 
   x_eu2 :: Integer -> Integer
-  x_eu2 _ = 1
+  x_eu2 1 = 1
+  x_eu2 _ = 0
diff --git a/SBVTestSuite/GoldFiles/lambda81.gold b/SBVTestSuite/GoldFiles/lambda81.gold
--- a/SBVTestSuite/GoldFiles/lambda81.gold
+++ b/SBVTestSuite/GoldFiles/lambda81.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.filter @(SBV Integer -> SBV Bool)_f7406d70a9 @(SBV [Integer] -> SBV [Integer]), sbv.filter @(SBV Integer -> SBV Bool)_2611d6a22d @(SBV [Integer] -> SBV [Integer])
+[MEASURE] Checking: sbv.filter @(SBV Integer -> SBV Bool)_f7406d70a9 @(SBV [Integer] -> SBV [Integer])
+[MEASURE] sbv.filter @(SBV Integer -> SBV Bool)_f7406d70a9 @(SBV [Integer] -> SBV [Integer]): barified = "|sbv.filter @(SBV Integer -> SBV Bool)_f7406d70a9 @(SBV [Integer] -> SBV [Integer])|"
+[MEASURE] sbv.filter @(SBV Integer -> SBV Bool)_f7406d70a9 @(SBV [Integer] -> SBV [Integer]): Uninterpreted ops in DAG: [("|sbv.filter @(SBV Integer -> SBV Bool)_f7406d70a9 @(SBV [Integer] -> SBV [Integer])|",1)]
+[MEASURE] sbv.filter @(SBV Integer -> SBV Bool)_f7406d70a9 @(SBV [Integer] -> SBV [Integer]): recursive calls found = 1
+[MEASURE] sbv.filter @(SBV Integer -> SBV Bool)_f7406d70a9 @(SBV [Integer] -> SBV [Integer]): trying length arg1
+[MEASURE] replayDAG {sbv.filter @(SBV Integer -> SBV Bool)_f7406d70a9 @(SBV [Integer] -> SBV [Integer])}: replaying 11 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +16,206 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 4)
+[GOOD] (define-fun s4 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s12 () (Seq Int)) ; tracks user variable "__internal_sbv_s12"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s5 () Int (seq.len s0))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () Int (seq.nth s0 s1))
+[GOOD] (define-fun s8 () Bool (> s7 s3))
+[GOOD] (define-fun s9 () (Seq Int) (seq.unit s7))
+[GOOD] (define-fun s10 () Int (- s5 s2))
+[GOOD] (define-fun s11 () (Seq Int) (seq.extract s0 s2 s10))
+[GOOD] (define-fun s13 () (Seq Int) (seq.++ s9 s12))
+[GOOD] (define-fun s14 () (Seq Int) (ite s8 s13 s12))
+[GOOD] (define-fun s15 () (Seq Int) (ite s6 s4 s14))
+[GOOD] (define-fun s16 () Bool (>= s5 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s16))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.filter @(SBV Integer -> SBV Bool)_f7406d70a9 @(SBV [Integer] -> SBV [Integer])}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 4)
+[GOOD] (define-fun s4 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s12 () (Seq Int)) ; tracks user variable "__internal_sbv_s12"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s5 () Int (seq.len s0))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () Int (seq.nth s0 s1))
+[GOOD] (define-fun s8 () Bool (> s7 s3))
+[GOOD] (define-fun s9 () (Seq Int) (seq.unit s7))
+[GOOD] (define-fun s10 () Int (- s5 s2))
+[GOOD] (define-fun s11 () (Seq Int) (seq.extract s0 s2 s10))
+[GOOD] (define-fun s13 () (Seq Int) (seq.++ s9 s12))
+[GOOD] (define-fun s14 () (Seq Int) (ite s8 s13 s12))
+[GOOD] (define-fun s15 () (Seq Int) (ite s6 s4 s14))
+[GOOD] (define-fun s16 () Int (seq.len s11))
+[GOOD] (define-fun s17 () Bool (not s8))
+[GOOD] (define-fun s18 () Bool (not s6))
+[GOOD] (define-fun s19 () Bool (and s17 s18))
+[GOOD] (define-fun s20 () Bool (> s5 s16))
+[GOOD] (define-fun s21 () Bool (=> s19 s20))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.filter @(SBV Integer -> SBV Bool)_f7406d70a9 @(SBV [Integer] -> SBV [Integer]): length arg1 -> OK
+[MEASURE] Passed (terminating): sbv.filter @(SBV Integer -> SBV Bool)_f7406d70a9 @(SBV [Integer] -> SBV [Integer])
+[MEASURE] Checking: sbv.filter @(SBV Integer -> SBV Bool)_2611d6a22d @(SBV [Integer] -> SBV [Integer])
+[MEASURE] sbv.filter @(SBV Integer -> SBV Bool)_2611d6a22d @(SBV [Integer] -> SBV [Integer]): barified = "|sbv.filter @(SBV Integer -> SBV Bool)_2611d6a22d @(SBV [Integer] -> SBV [Integer])|"
+[MEASURE] sbv.filter @(SBV Integer -> SBV Bool)_2611d6a22d @(SBV [Integer] -> SBV [Integer]): Uninterpreted ops in DAG: [("|sbv.filter @(SBV Integer -> SBV Bool)_2611d6a22d @(SBV [Integer] -> SBV [Integer])|",1)]
+[MEASURE] sbv.filter @(SBV Integer -> SBV Bool)_2611d6a22d @(SBV [Integer] -> SBV [Integer]): recursive calls found = 1
+[MEASURE] sbv.filter @(SBV Integer -> SBV Bool)_2611d6a22d @(SBV [Integer] -> SBV [Integer]): trying length arg1
+[MEASURE] replayDAG {sbv.filter @(SBV Integer -> SBV Bool)_2611d6a22d @(SBV [Integer] -> SBV [Integer])}: replaying 12 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s7 () (Seq Int)) ; tracks user variable "__internal_sbv_s7"
+[GOOD] (declare-fun s13 () (Seq Int)) ; tracks user variable "__internal_sbv_s13"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (seq.nth s0 s1))
+[GOOD] (define-fun s8 () Int (seq.nth s7 s1))
+[GOOD] (define-fun s9 () Bool (> s6 s8))
+[GOOD] (define-fun s10 () (Seq Int) (seq.unit s6))
+[GOOD] (define-fun s11 () Int (- s4 s2))
+[GOOD] (define-fun s12 () (Seq Int) (seq.extract s0 s2 s11))
+[GOOD] (define-fun s14 () (Seq Int) (seq.++ s10 s13))
+[GOOD] (define-fun s15 () (Seq Int) (ite s9 s14 s13))
+[GOOD] (define-fun s16 () (Seq Int) (ite s5 s3 s15))
+[GOOD] (define-fun s17 () Bool (>= s4 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.filter @(SBV Integer -> SBV Bool)_2611d6a22d @(SBV [Integer] -> SBV [Integer])}: replaying 12 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s7 () (Seq Int)) ; tracks user variable "__internal_sbv_s7"
+[GOOD] (declare-fun s13 () (Seq Int)) ; tracks user variable "__internal_sbv_s13"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (seq.nth s0 s1))
+[GOOD] (define-fun s8 () Int (seq.nth s7 s1))
+[GOOD] (define-fun s9 () Bool (> s6 s8))
+[GOOD] (define-fun s10 () (Seq Int) (seq.unit s6))
+[GOOD] (define-fun s11 () Int (- s4 s2))
+[GOOD] (define-fun s12 () (Seq Int) (seq.extract s0 s2 s11))
+[GOOD] (define-fun s14 () (Seq Int) (seq.++ s10 s13))
+[GOOD] (define-fun s15 () (Seq Int) (ite s9 s14 s13))
+[GOOD] (define-fun s16 () (Seq Int) (ite s5 s3 s15))
+[GOOD] (define-fun s17 () Int (seq.len s12))
+[GOOD] (define-fun s18 () Bool (not s9))
+[GOOD] (define-fun s19 () Bool (not s5))
+[GOOD] (define-fun s20 () Bool (and s18 s19))
+[GOOD] (define-fun s21 () Bool (> s4 s17))
+[GOOD] (define-fun s22 () Bool (=> s20 s21))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s22))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.filter @(SBV Integer -> SBV Bool)_2611d6a22d @(SBV [Integer] -> SBV [Integer]): length arg1 -> OK
+[MEASURE] Passed (terminating): sbv.filter @(SBV Integer -> SBV Bool)_2611d6a22d @(SBV [Integer] -> SBV [Integer])
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda82.gold b/SBVTestSuite/GoldFiles/lambda82.gold
--- a/SBVTestSuite/GoldFiles/lambda82.gold
+++ b/SBVTestSuite/GoldFiles/lambda82.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.map @(SBV Integer -> SBV [Integer])_136c80b6a3 @(SBV [Integer] -> SBV [[Integer]])
+[MEASURE] Checking: sbv.map @(SBV Integer -> SBV [Integer])_136c80b6a3 @(SBV [Integer] -> SBV [[Integer]])
+[MEASURE] sbv.map @(SBV Integer -> SBV [Integer])_136c80b6a3 @(SBV [Integer] -> SBV [[Integer]]): barified = "|sbv.map @(SBV Integer -> SBV [Integer])_136c80b6a3 @(SBV [Integer] -> SBV [[Integer]])|"
+[MEASURE] sbv.map @(SBV Integer -> SBV [Integer])_136c80b6a3 @(SBV [Integer] -> SBV [[Integer]]): Uninterpreted ops in DAG: [("|sbv.map @(SBV Integer -> SBV [Integer])_136c80b6a3 @(SBV [Integer] -> SBV [[Integer]])|",1)]
+[MEASURE] sbv.map @(SBV Integer -> SBV [Integer])_136c80b6a3 @(SBV [Integer] -> SBV [[Integer]]): recursive calls found = 1
+[MEASURE] sbv.map @(SBV Integer -> SBV [Integer])_136c80b6a3 @(SBV [Integer] -> SBV [[Integer]]): trying length arg1
+[MEASURE] replayDAG {sbv.map @(SBV Integer -> SBV [Integer])_136c80b6a3 @(SBV [Integer] -> SBV [[Integer]])}: replaying 18 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +16,120 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 4)
+[GOOD] (define-fun s4 () Int 5)
+[GOOD] (define-fun s5 () Int 6)
+[GOOD] (define-fun s6 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] (define-fun s7 () (Seq (Seq Int)) (as seq.empty (Seq (Seq Int))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s23 () (Seq (Seq Int))) ; tracks user variable "__internal_sbv_s23"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s8 () Int (seq.len s0))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Int (seq.nth s0 s1))
+[GOOD] (define-fun s11 () Int (+ s3 s10))
+[GOOD] (define-fun s12 () (Seq Int) (seq.unit s11))
+[GOOD] (define-fun s13 () Int (+ s4 s10))
+[GOOD] (define-fun s14 () (Seq Int) (seq.unit s13))
+[GOOD] (define-fun s15 () Int (+ s5 s10))
+[GOOD] (define-fun s16 () (Seq Int) (seq.unit s15))
+[GOOD] (define-fun s17 () (Seq Int) (seq.++ s16 s6))
+[GOOD] (define-fun s18 () (Seq Int) (seq.++ s14 s17))
+[GOOD] (define-fun s19 () (Seq Int) (seq.++ s12 s18))
+[GOOD] (define-fun s20 () (Seq (Seq Int)) (seq.unit s19))
+[GOOD] (define-fun s21 () Int (- s8 s2))
+[GOOD] (define-fun s22 () (Seq Int) (seq.extract s0 s2 s21))
+[GOOD] (define-fun s24 () (Seq (Seq Int)) (seq.++ s20 s23))
+[GOOD] (define-fun s25 () (Seq (Seq Int)) (ite s9 s7 s24))
+[GOOD] (define-fun s26 () Bool (>= s8 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s26))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.map @(SBV Integer -> SBV [Integer])_136c80b6a3 @(SBV [Integer] -> SBV [[Integer]])}: replaying 18 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 4)
+[GOOD] (define-fun s4 () Int 5)
+[GOOD] (define-fun s5 () Int 6)
+[GOOD] (define-fun s6 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] (define-fun s7 () (Seq (Seq Int)) (as seq.empty (Seq (Seq Int))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s23 () (Seq (Seq Int))) ; tracks user variable "__internal_sbv_s23"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s8 () Int (seq.len s0))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Int (seq.nth s0 s1))
+[GOOD] (define-fun s11 () Int (+ s3 s10))
+[GOOD] (define-fun s12 () (Seq Int) (seq.unit s11))
+[GOOD] (define-fun s13 () Int (+ s4 s10))
+[GOOD] (define-fun s14 () (Seq Int) (seq.unit s13))
+[GOOD] (define-fun s15 () Int (+ s5 s10))
+[GOOD] (define-fun s16 () (Seq Int) (seq.unit s15))
+[GOOD] (define-fun s17 () (Seq Int) (seq.++ s16 s6))
+[GOOD] (define-fun s18 () (Seq Int) (seq.++ s14 s17))
+[GOOD] (define-fun s19 () (Seq Int) (seq.++ s12 s18))
+[GOOD] (define-fun s20 () (Seq (Seq Int)) (seq.unit s19))
+[GOOD] (define-fun s21 () Int (- s8 s2))
+[GOOD] (define-fun s22 () (Seq Int) (seq.extract s0 s2 s21))
+[GOOD] (define-fun s24 () (Seq (Seq Int)) (seq.++ s20 s23))
+[GOOD] (define-fun s25 () (Seq (Seq Int)) (ite s9 s7 s24))
+[GOOD] (define-fun s26 () Int (seq.len s22))
+[GOOD] (define-fun s27 () Bool (not s9))
+[GOOD] (define-fun s28 () Bool (> s8 s26))
+[GOOD] (define-fun s29 () Bool (=> s27 s28))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s29))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.map @(SBV Integer -> SBV [Integer])_136c80b6a3 @(SBV [Integer] -> SBV [[Integer]]): length arg1 -> OK
+[MEASURE] Passed (terminating): sbv.map @(SBV Integer -> SBV [Integer])_136c80b6a3 @(SBV [Integer] -> SBV [[Integer]])
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/lambda85.gold b/SBVTestSuite/GoldFiles/lambda85.gold
--- a/SBVTestSuite/GoldFiles/lambda85.gold
+++ b/SBVTestSuite/GoldFiles/lambda85.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.partition @(SBV Integer -> SBV Bool)_72b7bf5d4c @(SBV [Integer] -> SBV ([Integer],[Integer]))
+[MEASURE] Checking: sbv.partition @(SBV Integer -> SBV Bool)_72b7bf5d4c @(SBV [Integer] -> SBV ([Integer],[Integer]))
+[MEASURE] sbv.partition @(SBV Integer -> SBV Bool)_72b7bf5d4c @(SBV [Integer] -> SBV ([Integer],[Integer])): barified = "|sbv.partition @(SBV Integer -> SBV Bool)_72b7bf5d4c @(SBV [Integer] -> SBV ([Integer],[Integer]))|"
+[MEASURE] sbv.partition @(SBV Integer -> SBV Bool)_72b7bf5d4c @(SBV [Integer] -> SBV ([Integer],[Integer])): Uninterpreted ops in DAG: [("|sbv.partition @(SBV Integer -> SBV Bool)_72b7bf5d4c @(SBV [Integer] -> SBV ([Integer],[Integer]))|",1)]
+[MEASURE] sbv.partition @(SBV Integer -> SBV Bool)_72b7bf5d4c @(SBV [Integer] -> SBV ([Integer],[Integer])): recursive calls found = 1
+[MEASURE] sbv.partition @(SBV Integer -> SBV Bool)_72b7bf5d4c @(SBV [Integer] -> SBV ([Integer],[Integer])): trying length arg1
+[MEASURE] replayDAG {sbv.partition @(SBV Integer -> SBV Bool)_72b7bf5d4c @(SBV [Integer] -> SBV ([Integer],[Integer]))}: replaying 17 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +16,120 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] (define-fun s4 () (SBVTuple2 (Seq Int) (Seq Int)) (mkSBVTuple2 (as seq.empty (Seq Int)) (as seq.empty (Seq Int))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s13 () (SBVTuple2 (Seq Int) (Seq Int))) ; tracks user variable "__internal_sbv_s13"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s5 () Int (seq.len s0))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () Int (seq.nth s0 s1))
+[GOOD] (define-fun s8 () Int (mod s7 s3))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () (Seq Int) (seq.unit s7))
+[GOOD] (define-fun s11 () Int (- s5 s2))
+[GOOD] (define-fun s12 () (Seq Int) (seq.extract s0 s2 s11))
+[GOOD] (define-fun s14 () (Seq Int) (proj_1_SBVTuple2 s13))
+[GOOD] (define-fun s15 () (Seq Int) (seq.++ s10 s14))
+[GOOD] (define-fun s16 () (Seq Int) (proj_2_SBVTuple2 s13))
+[GOOD] (define-fun s17 () (SBVTuple2 (Seq Int) (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq Int))) s15 s16))
+[GOOD] (define-fun s18 () (Seq Int) (seq.++ s10 s16))
+[GOOD] (define-fun s19 () (SBVTuple2 (Seq Int) (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq Int))) s14 s18))
+[GOOD] (define-fun s20 () (SBVTuple2 (Seq Int) (Seq Int)) (ite s9 s17 s19))
+[GOOD] (define-fun s21 () (SBVTuple2 (Seq Int) (Seq Int)) (ite s6 s4 s20))
+[GOOD] (define-fun s22 () Bool (>= s5 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s22))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.partition @(SBV Integer -> SBV Bool)_72b7bf5d4c @(SBV [Integer] -> SBV ([Integer],[Integer]))}: replaying 17 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] (define-fun s4 () (SBVTuple2 (Seq Int) (Seq Int)) (mkSBVTuple2 (as seq.empty (Seq Int)) (as seq.empty (Seq Int))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s13 () (SBVTuple2 (Seq Int) (Seq Int))) ; tracks user variable "__internal_sbv_s13"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s5 () Int (seq.len s0))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () Int (seq.nth s0 s1))
+[GOOD] (define-fun s8 () Int (mod s7 s3))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () (Seq Int) (seq.unit s7))
+[GOOD] (define-fun s11 () Int (- s5 s2))
+[GOOD] (define-fun s12 () (Seq Int) (seq.extract s0 s2 s11))
+[GOOD] (define-fun s14 () (Seq Int) (proj_1_SBVTuple2 s13))
+[GOOD] (define-fun s15 () (Seq Int) (seq.++ s10 s14))
+[GOOD] (define-fun s16 () (Seq Int) (proj_2_SBVTuple2 s13))
+[GOOD] (define-fun s17 () (SBVTuple2 (Seq Int) (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq Int))) s15 s16))
+[GOOD] (define-fun s18 () (Seq Int) (seq.++ s10 s16))
+[GOOD] (define-fun s19 () (SBVTuple2 (Seq Int) (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq Int))) s14 s18))
+[GOOD] (define-fun s20 () (SBVTuple2 (Seq Int) (Seq Int)) (ite s9 s17 s19))
+[GOOD] (define-fun s21 () (SBVTuple2 (Seq Int) (Seq Int)) (ite s6 s4 s20))
+[GOOD] (define-fun s22 () Int (seq.len s12))
+[GOOD] (define-fun s23 () Bool (not s9))
+[GOOD] (define-fun s24 () Bool (not s6))
+[GOOD] (define-fun s25 () Bool (and s23 s24))
+[GOOD] (define-fun s26 () Bool (> s5 s22))
+[GOOD] (define-fun s27 () Bool (=> s25 s26))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s27))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.partition @(SBV Integer -> SBV Bool)_72b7bf5d4c @(SBV [Integer] -> SBV ([Integer],[Integer])): length arg1 -> OK
+[MEASURE] Passed (terminating): sbv.partition @(SBV Integer -> SBV Bool)_72b7bf5d4c @(SBV [Integer] -> SBV ([Integer],[Integer]))
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/lambda86.gold b/SBVTestSuite/GoldFiles/lambda86.gold
--- a/SBVTestSuite/GoldFiles/lambda86.gold
+++ b/SBVTestSuite/GoldFiles/lambda86.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.partition @(SBV Integer -> SBV Bool)_cb04f986c4 @(SBV [Integer] -> SBV ([Integer],[Integer]))
+[MEASURE] Checking: sbv.partition @(SBV Integer -> SBV Bool)_cb04f986c4 @(SBV [Integer] -> SBV ([Integer],[Integer]))
+[MEASURE] sbv.partition @(SBV Integer -> SBV Bool)_cb04f986c4 @(SBV [Integer] -> SBV ([Integer],[Integer])): barified = "|sbv.partition @(SBV Integer -> SBV Bool)_cb04f986c4 @(SBV [Integer] -> SBV ([Integer],[Integer]))|"
+[MEASURE] sbv.partition @(SBV Integer -> SBV Bool)_cb04f986c4 @(SBV [Integer] -> SBV ([Integer],[Integer])): Uninterpreted ops in DAG: [("|sbv.partition @(SBV Integer -> SBV Bool)_cb04f986c4 @(SBV [Integer] -> SBV ([Integer],[Integer]))|",1)]
+[MEASURE] sbv.partition @(SBV Integer -> SBV Bool)_cb04f986c4 @(SBV [Integer] -> SBV ([Integer],[Integer])): recursive calls found = 1
+[MEASURE] sbv.partition @(SBV Integer -> SBV Bool)_cb04f986c4 @(SBV [Integer] -> SBV ([Integer],[Integer])): trying length arg1
+[MEASURE] replayDAG {sbv.partition @(SBV Integer -> SBV Bool)_cb04f986c4 @(SBV [Integer] -> SBV ([Integer],[Integer]))}: replaying 17 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +16,120 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] (define-fun s4 () (SBVTuple2 (Seq Int) (Seq Int)) (mkSBVTuple2 (as seq.empty (Seq Int)) (as seq.empty (Seq Int))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s13 () (SBVTuple2 (Seq Int) (Seq Int))) ; tracks user variable "__internal_sbv_s13"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s5 () Int (seq.len s0))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () Int (seq.nth s0 s1))
+[GOOD] (define-fun s8 () Int (mod s7 s3))
+[GOOD] (define-fun s9 () Bool (distinct s1 s8))
+[GOOD] (define-fun s10 () (Seq Int) (seq.unit s7))
+[GOOD] (define-fun s11 () Int (- s5 s2))
+[GOOD] (define-fun s12 () (Seq Int) (seq.extract s0 s2 s11))
+[GOOD] (define-fun s14 () (Seq Int) (proj_1_SBVTuple2 s13))
+[GOOD] (define-fun s15 () (Seq Int) (seq.++ s10 s14))
+[GOOD] (define-fun s16 () (Seq Int) (proj_2_SBVTuple2 s13))
+[GOOD] (define-fun s17 () (SBVTuple2 (Seq Int) (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq Int))) s15 s16))
+[GOOD] (define-fun s18 () (Seq Int) (seq.++ s10 s16))
+[GOOD] (define-fun s19 () (SBVTuple2 (Seq Int) (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq Int))) s14 s18))
+[GOOD] (define-fun s20 () (SBVTuple2 (Seq Int) (Seq Int)) (ite s9 s17 s19))
+[GOOD] (define-fun s21 () (SBVTuple2 (Seq Int) (Seq Int)) (ite s6 s4 s20))
+[GOOD] (define-fun s22 () Bool (>= s5 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s22))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.partition @(SBV Integer -> SBV Bool)_cb04f986c4 @(SBV [Integer] -> SBV ([Integer],[Integer]))}: replaying 17 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 2)
+[GOOD] (define-fun s4 () (SBVTuple2 (Seq Int) (Seq Int)) (mkSBVTuple2 (as seq.empty (Seq Int)) (as seq.empty (Seq Int))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s13 () (SBVTuple2 (Seq Int) (Seq Int))) ; tracks user variable "__internal_sbv_s13"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s5 () Int (seq.len s0))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () Int (seq.nth s0 s1))
+[GOOD] (define-fun s8 () Int (mod s7 s3))
+[GOOD] (define-fun s9 () Bool (distinct s1 s8))
+[GOOD] (define-fun s10 () (Seq Int) (seq.unit s7))
+[GOOD] (define-fun s11 () Int (- s5 s2))
+[GOOD] (define-fun s12 () (Seq Int) (seq.extract s0 s2 s11))
+[GOOD] (define-fun s14 () (Seq Int) (proj_1_SBVTuple2 s13))
+[GOOD] (define-fun s15 () (Seq Int) (seq.++ s10 s14))
+[GOOD] (define-fun s16 () (Seq Int) (proj_2_SBVTuple2 s13))
+[GOOD] (define-fun s17 () (SBVTuple2 (Seq Int) (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq Int))) s15 s16))
+[GOOD] (define-fun s18 () (Seq Int) (seq.++ s10 s16))
+[GOOD] (define-fun s19 () (SBVTuple2 (Seq Int) (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq Int))) s14 s18))
+[GOOD] (define-fun s20 () (SBVTuple2 (Seq Int) (Seq Int)) (ite s9 s17 s19))
+[GOOD] (define-fun s21 () (SBVTuple2 (Seq Int) (Seq Int)) (ite s6 s4 s20))
+[GOOD] (define-fun s22 () Int (seq.len s12))
+[GOOD] (define-fun s23 () Bool (not s9))
+[GOOD] (define-fun s24 () Bool (not s6))
+[GOOD] (define-fun s25 () Bool (and s23 s24))
+[GOOD] (define-fun s26 () Bool (> s5 s22))
+[GOOD] (define-fun s27 () Bool (=> s25 s26))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s27))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.partition @(SBV Integer -> SBV Bool)_cb04f986c4 @(SBV [Integer] -> SBV ([Integer],[Integer])): length arg1 -> OK
+[MEASURE] Passed (terminating): sbv.partition @(SBV Integer -> SBV Bool)_cb04f986c4 @(SBV [Integer] -> SBV ([Integer],[Integer]))
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/lambda87.gold b/SBVTestSuite/GoldFiles/lambda87.gold
--- a/SBVTestSuite/GoldFiles/lambda87.gold
+++ b/SBVTestSuite/GoldFiles/lambda87.gold
@@ -1,3 +1,13 @@
+[MEASURE] Verifying termination measures for: sbv.map @(SBV Integer -> SBV [Integer])_8a19cac1b3 @(SBV [Integer] -> SBV [[Integer]]), sbv.map @(SBV Integer -> SBV [Integer])_8a19cac1b3 @(SBV [Integer] -> SBV [[Integer]]), sbv.closureMap @(SBV Integer -> SBV Integer -> SBV Integer)_3339bda50c @(SBV (Integer,[Integer]) -> SBV [Integer]), sbv.closureMap @(SBV Integer -> SBV Integer -> SBV Integer)_d8dc9e6fbd @(SBV (Integer,[Integer]) -> SBV [Integer])
+[MEASURE] Checking: sbv.map @(SBV Integer -> SBV [Integer])_8a19cac1b3 @(SBV [Integer] -> SBV [[Integer]])
+[MEASURE] sbv.map @(SBV Integer -> SBV [Integer])_8a19cac1b3 @(SBV [Integer] -> SBV [[Integer]]): not in a multi-member cycle, skipping mutual check
+[MEASURE] Passed (terminating): sbv.map @(SBV Integer -> SBV [Integer])_8a19cac1b3 @(SBV [Integer] -> SBV [[Integer]])
+[MEASURE] Checking: sbv.map @(SBV Integer -> SBV [Integer])_8a19cac1b3 @(SBV [Integer] -> SBV [[Integer]])
+[MEASURE] sbv.map @(SBV Integer -> SBV [Integer])_8a19cac1b3 @(SBV [Integer] -> SBV [[Integer]]): barified = "|sbv.map @(SBV Integer -> SBV [Integer])_8a19cac1b3 @(SBV [Integer] -> SBV [[Integer]])|"
+[MEASURE] sbv.map @(SBV Integer -> SBV [Integer])_8a19cac1b3 @(SBV [Integer] -> SBV [[Integer]]): Uninterpreted ops in DAG: [("|sbv.closureMap @(SBV Integer -> SBV Integer -> SBV Integer)_d8dc9e6fbd @(SBV (Integer,[Integer]) -> SBV [Integer])|",1),("|sbv.map @(SBV Integer -> SBV [Integer])_8a19cac1b3 @(SBV [Integer] -> SBV [[Integer]])|",1)]
+[MEASURE] sbv.map @(SBV Integer -> SBV [Integer])_8a19cac1b3 @(SBV [Integer] -> SBV [[Integer]]): recursive calls found = 1
+[MEASURE] sbv.map @(SBV Integer -> SBV [Integer])_8a19cac1b3 @(SBV [Integer] -> SBV [[Integer]]): trying length arg1
+[MEASURE] replayDAG {sbv.map @(SBV Integer -> SBV [Integer])_8a19cac1b3 @(SBV [Integer] -> SBV [[Integer]])}: replaying 11 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +19,336 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq (Seq Int)) (as seq.empty (Seq (Seq Int))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s7 () (Seq Int)) ; tracks user variable "__internal_sbv_s7"
+[GOOD] (declare-fun s9 () (Seq Int)) ; tracks user variable "__internal_sbv_s9"
+[GOOD] (declare-fun s13 () (Seq (Seq Int))) ; tracks user variable "__internal_sbv_s13"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (seq.nth s0 s1))
+[GOOD] (define-fun s8 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s6 s7))
+[GOOD] (define-fun s10 () (Seq (Seq Int)) (seq.unit s9))
+[GOOD] (define-fun s11 () Int (- s4 s2))
+[GOOD] (define-fun s12 () (Seq Int) (seq.extract s0 s2 s11))
+[GOOD] (define-fun s14 () (Seq (Seq Int)) (seq.++ s10 s13))
+[GOOD] (define-fun s15 () (Seq (Seq Int)) (ite s5 s3 s14))
+[GOOD] (define-fun s16 () Bool (>= s4 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s16))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.map @(SBV Integer -> SBV [Integer])_8a19cac1b3 @(SBV [Integer] -> SBV [[Integer]])}: replaying 11 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq (Seq Int)) (as seq.empty (Seq (Seq Int))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq Int)) ; tracks user variable "arg"
+[GOOD] (declare-fun s7 () (Seq Int)) ; tracks user variable "__internal_sbv_s7"
+[GOOD] (declare-fun s9 () (Seq Int)) ; tracks user variable "__internal_sbv_s9"
+[GOOD] (declare-fun s13 () (Seq (Seq Int))) ; tracks user variable "__internal_sbv_s13"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s1 s4))
+[GOOD] (define-fun s6 () Int (seq.nth s0 s1))
+[GOOD] (define-fun s8 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s6 s7))
+[GOOD] (define-fun s10 () (Seq (Seq Int)) (seq.unit s9))
+[GOOD] (define-fun s11 () Int (- s4 s2))
+[GOOD] (define-fun s12 () (Seq Int) (seq.extract s0 s2 s11))
+[GOOD] (define-fun s14 () (Seq (Seq Int)) (seq.++ s10 s13))
+[GOOD] (define-fun s15 () (Seq (Seq Int)) (ite s5 s3 s14))
+[GOOD] (define-fun s16 () Int (seq.len s12))
+[GOOD] (define-fun s17 () Bool (not s5))
+[GOOD] (define-fun s18 () Bool (> s4 s16))
+[GOOD] (define-fun s19 () Bool (=> s17 s18))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s19))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.map @(SBV Integer -> SBV [Integer])_8a19cac1b3 @(SBV [Integer] -> SBV [[Integer]]): length arg1 -> OK
+[MEASURE] Passed (terminating): sbv.map @(SBV Integer -> SBV [Integer])_8a19cac1b3 @(SBV [Integer] -> SBV [[Integer]])
+[MEASURE] Checking: sbv.closureMap @(SBV Integer -> SBV Integer -> SBV Integer)_3339bda50c @(SBV (Integer,[Integer]) -> SBV [Integer])
+[MEASURE] sbv.closureMap @(SBV Integer -> SBV Integer -> SBV Integer)_3339bda50c @(SBV (Integer,[Integer]) -> SBV [Integer]): not in a multi-member cycle, skipping mutual check
+[MEASURE] Passed (terminating): sbv.closureMap @(SBV Integer -> SBV Integer -> SBV Integer)_3339bda50c @(SBV (Integer,[Integer]) -> SBV [Integer])
+[MEASURE] Checking: sbv.closureMap @(SBV Integer -> SBV Integer -> SBV Integer)_d8dc9e6fbd @(SBV (Integer,[Integer]) -> SBV [Integer])
+[MEASURE] sbv.closureMap @(SBV Integer -> SBV Integer -> SBV Integer)_d8dc9e6fbd @(SBV (Integer,[Integer]) -> SBV [Integer]): barified = "|sbv.closureMap @(SBV Integer -> SBV Integer -> SBV Integer)_d8dc9e6fbd @(SBV (Integer,[Integer]) -> SBV [Integer])|"
+[MEASURE] sbv.closureMap @(SBV Integer -> SBV Integer -> SBV Integer)_d8dc9e6fbd @(SBV (Integer,[Integer]) -> SBV [Integer]): Uninterpreted ops in DAG: [("|sbv.closureMap @(SBV Integer -> SBV Integer -> SBV Integer)_d8dc9e6fbd @(SBV (Integer,[Integer]) -> SBV [Integer])|",1)]
+[MEASURE] sbv.closureMap @(SBV Integer -> SBV Integer -> SBV Integer)_d8dc9e6fbd @(SBV (Integer,[Integer]) -> SBV [Integer]): recursive calls found = 1
+[MEASURE] sbv.closureMap @(SBV Integer -> SBV Integer -> SBV Integer)_d8dc9e6fbd @(SBV (Integer,[Integer]) -> SBV [Integer]): trying abs arg1._1
+[MEASURE] replayDAG {sbv.closureMap @(SBV Integer -> SBV Integer -> SBV Integer)_d8dc9e6fbd @(SBV (Integer,[Integer]) -> SBV [Integer])}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s14 () (Seq Int)) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s5 () Int (seq.len s4))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s8 () Int (seq.nth s4 s1))
+[GOOD] (define-fun s9 () Int (+ s7 s8))
+[GOOD] (define-fun s10 () (Seq Int) (seq.unit s9))
+[GOOD] (define-fun s11 () Int (- s5 s2))
+[GOOD] (define-fun s12 () (Seq Int) (seq.extract s4 s2 s11))
+[GOOD] (define-fun s13 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s7 s12))
+[GOOD] (define-fun s15 () (Seq Int) (seq.++ s10 s14))
+[GOOD] (define-fun s16 () (Seq Int) (ite s6 s3 s15))
+[GOOD] (define-fun s17 () Int (abs s7))
+[GOOD] (define-fun s18 () Bool (>= s17 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s18))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.closureMap @(SBV Integer -> SBV Integer -> SBV Integer)_d8dc9e6fbd @(SBV (Integer,[Integer]) -> SBV [Integer])}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s14 () (Seq Int)) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s5 () Int (seq.len s4))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s8 () Int (seq.nth s4 s1))
+[GOOD] (define-fun s9 () Int (+ s7 s8))
+[GOOD] (define-fun s10 () (Seq Int) (seq.unit s9))
+[GOOD] (define-fun s11 () Int (- s5 s2))
+[GOOD] (define-fun s12 () (Seq Int) (seq.extract s4 s2 s11))
+[GOOD] (define-fun s13 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s7 s12))
+[GOOD] (define-fun s15 () (Seq Int) (seq.++ s10 s14))
+[GOOD] (define-fun s16 () (Seq Int) (ite s6 s3 s15))
+[GOOD] (define-fun s17 () Int (abs s7))
+[GOOD] (define-fun s18 () Int (proj_1_SBVTuple2 s13))
+[GOOD] (define-fun s19 () Int (abs s18))
+[GOOD] (define-fun s20 () Bool (not s6))
+[GOOD] (define-fun s21 () Bool (> s17 s19))
+[GOOD] (define-fun s22 () Bool (=> s20 s21))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s22))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s17))
+[RECV] ((s17 0))
+[SEND] (get-value (s19))
+[RECV] ((s19 0))
+[SEND] (get-value (s0))
+[RECV] ((s0 (mkSBVTuple2 0 (seq.unit 4))))
+[SEND] (get-value (s14))
+[RECV] ((s14 (as seq.empty (Seq Int))))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.closureMap @(SBV Integer -> SBV Integer -> SBV Integer)_d8dc9e6fbd @(SBV (Integer,[Integer]) -> SBV [Integer]): abs arg1._1 failed strict decrease: Falsifiable. Counter-example:
+  arg    = (0,[4]) :: (Integer, [Integer])
+  before =       0 :: Integer
+  then   =       0 :: Integer
+[MEASURE] sbv.closureMap @(SBV Integer -> SBV Integer -> SBV Integer)_d8dc9e6fbd @(SBV (Integer,[Integer]) -> SBV [Integer]): trying next candidate..
+[MEASURE] sbv.closureMap @(SBV Integer -> SBV Integer -> SBV Integer)_d8dc9e6fbd @(SBV (Integer,[Integer]) -> SBV [Integer]): trying length arg1._2
+[MEASURE] replayDAG {sbv.closureMap @(SBV Integer -> SBV Integer -> SBV Integer)_d8dc9e6fbd @(SBV (Integer,[Integer]) -> SBV [Integer])}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s14 () (Seq Int)) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s5 () Int (seq.len s4))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s8 () Int (seq.nth s4 s1))
+[GOOD] (define-fun s9 () Int (+ s7 s8))
+[GOOD] (define-fun s10 () (Seq Int) (seq.unit s9))
+[GOOD] (define-fun s11 () Int (- s5 s2))
+[GOOD] (define-fun s12 () (Seq Int) (seq.extract s4 s2 s11))
+[GOOD] (define-fun s13 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s7 s12))
+[GOOD] (define-fun s15 () (Seq Int) (seq.++ s10 s14))
+[GOOD] (define-fun s16 () (Seq Int) (ite s6 s3 s15))
+[GOOD] (define-fun s17 () Bool (>= s5 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.closureMap @(SBV Integer -> SBV Integer -> SBV Integer)_d8dc9e6fbd @(SBV (Integer,[Integer]) -> SBV [Integer])}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 Int (Seq Int))) ; tracks user variable "arg"
+[GOOD] (declare-fun s14 () (Seq Int)) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () (Seq Int) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s5 () Int (seq.len s4))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () Int (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s8 () Int (seq.nth s4 s1))
+[GOOD] (define-fun s9 () Int (+ s7 s8))
+[GOOD] (define-fun s10 () (Seq Int) (seq.unit s9))
+[GOOD] (define-fun s11 () Int (- s5 s2))
+[GOOD] (define-fun s12 () (Seq Int) (seq.extract s4 s2 s11))
+[GOOD] (define-fun s13 () (SBVTuple2 Int (Seq Int)) ((as mkSBVTuple2 (SBVTuple2 Int (Seq Int))) s7 s12))
+[GOOD] (define-fun s15 () (Seq Int) (seq.++ s10 s14))
+[GOOD] (define-fun s16 () (Seq Int) (ite s6 s3 s15))
+[GOOD] (define-fun s17 () (Seq Int) (proj_2_SBVTuple2 s13))
+[GOOD] (define-fun s18 () Int (seq.len s17))
+[GOOD] (define-fun s19 () Bool (not s6))
+[GOOD] (define-fun s20 () Bool (> s5 s18))
+[GOOD] (define-fun s21 () Bool (=> s19 s20))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.closureMap @(SBV Integer -> SBV Integer -> SBV Integer)_d8dc9e6fbd @(SBV (Integer,[Integer]) -> SBV [Integer]): length arg1._2 -> OK
+[MEASURE] Passed (terminating): sbv.closureMap @(SBV Integer -> SBV Integer -> SBV Integer)_d8dc9e6fbd @(SBV (Integer,[Integer]) -> SBV [Integer])
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/lambda88.gold b/SBVTestSuite/GoldFiles/lambda88.gold
--- a/SBVTestSuite/GoldFiles/lambda88.gold
+++ b/SBVTestSuite/GoldFiles/lambda88.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: sbv.closureMap @(SBV [Integer] -> SBV [Integer] -> SBV [Integer])_24b5487d7f @(SBV ([Integer],[[Integer]]) -> SBV [[Integer]])
+[MEASURE] Checking: sbv.closureMap @(SBV [Integer] -> SBV [Integer] -> SBV [Integer])_24b5487d7f @(SBV ([Integer],[[Integer]]) -> SBV [[Integer]])
+[MEASURE] sbv.closureMap @(SBV [Integer] -> SBV [Integer] -> SBV [Integer])_24b5487d7f @(SBV ([Integer],[[Integer]]) -> SBV [[Integer]]): barified = "|sbv.closureMap @(SBV [Integer] -> SBV [Integer] -> SBV [Integer])_24b5487d7f @(SBV ([Integer],[[Integer]]) -> SBV [[Integer]])|"
+[MEASURE] sbv.closureMap @(SBV [Integer] -> SBV [Integer] -> SBV [Integer])_24b5487d7f @(SBV ([Integer],[[Integer]]) -> SBV [[Integer]]): Uninterpreted ops in DAG: [("|sbv.closureMap @(SBV [Integer] -> SBV [Integer] -> SBV [Integer])_24b5487d7f @(SBV ([Integer],[[Integer]]) -> SBV [[Integer]])|",1)]
+[MEASURE] sbv.closureMap @(SBV [Integer] -> SBV [Integer] -> SBV [Integer])_24b5487d7f @(SBV ([Integer],[[Integer]]) -> SBV [[Integer]]): recursive calls found = 1
+[MEASURE] sbv.closureMap @(SBV [Integer] -> SBV [Integer] -> SBV [Integer])_24b5487d7f @(SBV ([Integer],[[Integer]]) -> SBV [[Integer]]): trying length arg1._1
+[MEASURE] replayDAG {sbv.closureMap @(SBV [Integer] -> SBV [Integer] -> SBV [Integer])_24b5487d7f @(SBV ([Integer],[[Integer]]) -> SBV [[Integer]])}: replaying 13 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,7 +16,227 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq (Seq Int)) (as seq.empty (Seq (Seq Int))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 (Seq Int) (Seq (Seq Int)))) ; tracks user variable "arg"
+[GOOD] (declare-fun s14 () (Seq (Seq Int))) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () (Seq (Seq Int)) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s5 () Int (seq.len s4))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () (Seq Int) (seq.nth s4 s1))
+[GOOD] (define-fun s8 () (Seq Int) (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s9 () (Seq Int) (seq.++ s7 s8))
+[GOOD] (define-fun s10 () (Seq (Seq Int)) (seq.unit s9))
+[GOOD] (define-fun s11 () Int (- s5 s2))
+[GOOD] (define-fun s12 () (Seq (Seq Int)) (seq.extract s4 s2 s11))
+[GOOD] (define-fun s13 () (SBVTuple2 (Seq Int) (Seq (Seq Int))) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq (Seq Int)))) s8 s12))
+[GOOD] (define-fun s15 () (Seq (Seq Int)) (seq.++ s10 s14))
+[GOOD] (define-fun s16 () (Seq (Seq Int)) (ite s6 s3 s15))
+[GOOD] (define-fun s17 () Int (seq.len s8))
+[GOOD] (define-fun s18 () Bool (>= s17 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s18))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.closureMap @(SBV [Integer] -> SBV [Integer] -> SBV [Integer])_24b5487d7f @(SBV ([Integer],[[Integer]]) -> SBV [[Integer]])}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq (Seq Int)) (as seq.empty (Seq (Seq Int))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 (Seq Int) (Seq (Seq Int)))) ; tracks user variable "arg"
+[GOOD] (declare-fun s14 () (Seq (Seq Int))) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () (Seq (Seq Int)) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s5 () Int (seq.len s4))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () (Seq Int) (seq.nth s4 s1))
+[GOOD] (define-fun s8 () (Seq Int) (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s9 () (Seq Int) (seq.++ s7 s8))
+[GOOD] (define-fun s10 () (Seq (Seq Int)) (seq.unit s9))
+[GOOD] (define-fun s11 () Int (- s5 s2))
+[GOOD] (define-fun s12 () (Seq (Seq Int)) (seq.extract s4 s2 s11))
+[GOOD] (define-fun s13 () (SBVTuple2 (Seq Int) (Seq (Seq Int))) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq (Seq Int)))) s8 s12))
+[GOOD] (define-fun s15 () (Seq (Seq Int)) (seq.++ s10 s14))
+[GOOD] (define-fun s16 () (Seq (Seq Int)) (ite s6 s3 s15))
+[GOOD] (define-fun s17 () Int (seq.len s8))
+[GOOD] (define-fun s18 () (Seq Int) (proj_1_SBVTuple2 s13))
+[GOOD] (define-fun s19 () Int (seq.len s18))
+[GOOD] (define-fun s20 () Bool (not s6))
+[GOOD] (define-fun s21 () Bool (> s17 s19))
+[GOOD] (define-fun s22 () Bool (=> s20 s21))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s22))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s17))
+[RECV] ((s17 0))
+[SEND] (get-value (s19))
+[RECV] ((s19 0))
+[SEND] (get-value (s0))
+[RECV] ((s0 (mkSBVTuple2 (as seq.empty (Seq Int)) (seq.unit (seq.unit 2)))))
+[SEND] (get-value (s14))
+[RECV] ((s14 (as seq.empty (Seq (Seq Int)))))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.closureMap @(SBV [Integer] -> SBV [Integer] -> SBV [Integer])_24b5487d7f @(SBV ([Integer],[[Integer]]) -> SBV [[Integer]]): length arg1._1 failed strict decrease: Falsifiable. Counter-example:
+  arg    = ([],[[2]]) :: ([Integer], [[Integer]])
+  before =          0 :: Integer
+  then   =          0 :: Integer
+[MEASURE] sbv.closureMap @(SBV [Integer] -> SBV [Integer] -> SBV [Integer])_24b5487d7f @(SBV ([Integer],[[Integer]]) -> SBV [[Integer]]): trying next candidate..
+[MEASURE] sbv.closureMap @(SBV [Integer] -> SBV [Integer] -> SBV [Integer])_24b5487d7f @(SBV ([Integer],[[Integer]]) -> SBV [[Integer]]): trying length arg1._2
+[MEASURE] replayDAG {sbv.closureMap @(SBV [Integer] -> SBV [Integer] -> SBV [Integer])_24b5487d7f @(SBV ([Integer],[[Integer]]) -> SBV [[Integer]])}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq (Seq Int)) (as seq.empty (Seq (Seq Int))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 (Seq Int) (Seq (Seq Int)))) ; tracks user variable "arg"
+[GOOD] (declare-fun s14 () (Seq (Seq Int))) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () (Seq (Seq Int)) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s5 () Int (seq.len s4))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () (Seq Int) (seq.nth s4 s1))
+[GOOD] (define-fun s8 () (Seq Int) (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s9 () (Seq Int) (seq.++ s7 s8))
+[GOOD] (define-fun s10 () (Seq (Seq Int)) (seq.unit s9))
+[GOOD] (define-fun s11 () Int (- s5 s2))
+[GOOD] (define-fun s12 () (Seq (Seq Int)) (seq.extract s4 s2 s11))
+[GOOD] (define-fun s13 () (SBVTuple2 (Seq Int) (Seq (Seq Int))) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq (Seq Int)))) s8 s12))
+[GOOD] (define-fun s15 () (Seq (Seq Int)) (seq.++ s10 s14))
+[GOOD] (define-fun s16 () (Seq (Seq Int)) (ite s6 s3 s15))
+[GOOD] (define-fun s17 () Bool (>= s5 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s17))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sbv.closureMap @(SBV [Integer] -> SBV [Integer] -> SBV [Integer])_24b5487d7f @(SBV ([Integer],[[Integer]]) -> SBV [[Integer]])}: replaying 13 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () (Seq (Seq Int)) (as seq.empty (Seq (Seq Int))))
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (SBVTuple2 (Seq Int) (Seq (Seq Int)))) ; tracks user variable "arg"
+[GOOD] (declare-fun s14 () (Seq (Seq Int))) ; tracks user variable "__internal_sbv_s14"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () (Seq (Seq Int)) (proj_2_SBVTuple2 s0))
+[GOOD] (define-fun s5 () Int (seq.len s4))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () (Seq Int) (seq.nth s4 s1))
+[GOOD] (define-fun s8 () (Seq Int) (proj_1_SBVTuple2 s0))
+[GOOD] (define-fun s9 () (Seq Int) (seq.++ s7 s8))
+[GOOD] (define-fun s10 () (Seq (Seq Int)) (seq.unit s9))
+[GOOD] (define-fun s11 () Int (- s5 s2))
+[GOOD] (define-fun s12 () (Seq (Seq Int)) (seq.extract s4 s2 s11))
+[GOOD] (define-fun s13 () (SBVTuple2 (Seq Int) (Seq (Seq Int))) ((as mkSBVTuple2 (SBVTuple2 (Seq Int) (Seq (Seq Int)))) s8 s12))
+[GOOD] (define-fun s15 () (Seq (Seq Int)) (seq.++ s10 s14))
+[GOOD] (define-fun s16 () (Seq (Seq Int)) (ite s6 s3 s15))
+[GOOD] (define-fun s17 () (Seq (Seq Int)) (proj_2_SBVTuple2 s13))
+[GOOD] (define-fun s18 () Int (seq.len s17))
+[GOOD] (define-fun s19 () Bool (not s6))
+[GOOD] (define-fun s20 () Bool (> s5 s18))
+[GOOD] (define-fun s21 () Bool (=> s19 s20))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sbv.closureMap @(SBV [Integer] -> SBV [Integer] -> SBV [Integer])_24b5487d7f @(SBV ([Integer],[[Integer]]) -> SBV [[Integer]]): length arg1._2 -> OK
+[MEASURE] Passed (terminating): sbv.closureMap @(SBV [Integer] -> SBV [Integer] -> SBV [Integer])_24b5487d7f @(SBV ([Integer],[[Integer]]) -> SBV [[Integer]])
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/legato_c.gold b/SBVTestSuite/GoldFiles/legato_c.gold
--- a/SBVTestSuite/GoldFiles/legato_c.gold
+++ b/SBVTestSuite/GoldFiles/legato_c.gold
@@ -12,6414 +12,6460 @@
 legatoMult.o: legatoMult.c legatoMult.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
-legatoMult_driver.o: legatoMult_driver.c
-	${CC} ${CCFLAGS} -c $< -o $@
-
-legatoMult_driver: legatoMult.o legatoMult_driver.o
-	${CC} ${CCFLAGS} $^ -o $@
-
-clean:
-	rm -f *.o
-
-veryclean: clean
-	rm -f legatoMult_driver
-== END: "Makefile" ==================
-== BEGIN: "legatoMult.h" ================
-/* Header file for legatoMult. Automatically generated by SBV. Do not edit! */
-
-#ifndef __legatoMult__HEADER_INCLUDED__
-#define __legatoMult__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 prototype: */
-void legatoMult(const SWord8 x, const SWord8 y, SWord8 *hi,
-                SWord8 *lo);
-
-#endif /* __legatoMult__HEADER_INCLUDED__ */
-== END: "legatoMult.h" ==================
-== BEGIN: "legatoMult_driver.c" ================
-/* Example driver program for legatoMult. */
-/* Automatically generated by SBV. Edit as you see fit! */
-
-#include <stdio.h>
-#include "legatoMult.h"
-
-int main(void)
-{
-  SWord8 hi;
-  SWord8 lo;
-
-  legatoMult(87, 92, &hi, &lo);
-
-  printf("legatoMult(87, 92, &hi, &lo) ->\n");
-  printf("  hi = %"PRIu8"\n", hi);
-  printf("  lo = %"PRIu8"\n", lo);
-
-  return 0;
-}
-== END: "legatoMult_driver.c" ==================
-== BEGIN: "legatoMult.c" ================
-/* File: "legatoMult.c". Automatically generated by SBV. Do not edit! */
-
-#include "legatoMult.h"
-
-void legatoMult(const SWord8 x, const SWord8 y, SWord8 *hi,
-                SWord8 *lo)
-{
-  const SWord8 s0 = x;
-  const SWord8 s1 = y;
-  const SBool  s2 = (SBool) (s0 & 1);
-  const SBool  s4 = s2 != false;
-  const SBool  s5 = !s4;
-  const SWord8 s6 = (s0 >> 1) | (s0 << 7);
-  const SWord8 s8 = s6 & 127;
-  const SBool  s9 = (SBool) (s8 & 1);
-  const SBool  s10 = false != s9;
-  const SBool  s11 = !s10;
-  const SWord8 s12 = (s8 >> 1) | (s8 << 7);
-  const SWord8 s13 = 127 & s12;
-  const SBool  s14 = (SBool) (s13 & 1);
-  const SBool  s15 = false != s14;
-  const SBool  s16 = !s15;
-  const SWord8 s17 = (s13 >> 1) | (s13 << 7);
-  const SWord8 s18 = 127 & s17;
-  const SBool  s19 = (SBool) (s18 & 1);
-  const SBool  s20 = false != s19;
-  const SBool  s21 = !s20;
-  const SWord8 s24 = s4 ? 128 : 0;
-  const SBool  s25 = (SBool) (s24 & 1);
-  const SBool  s26 = false != s25;
-  const SWord8 s27 = s26 ? 128 : 0;
-  const SBool  s28 = (SBool) (s27 & 1);
-  const SBool  s29 = false != s28;
-  const SWord8 s30 = (s18 >> 1) | (s18 << 7);
-  const SWord8 s31 = 128 | s30;
-  const SWord8 s32 = 127 & s30;
-  const SWord8 s33 = s29 ? s31 : s32;
-  const SBool  s34 = (SBool) (s33 & 1);
-  const SBool  s35 = false != s34;
-  const SBool  s36 = !s35;
-  const SWord8 s37 = (s24 >> 1) | (s24 << 7);
-  const SWord8 s38 = 128 | s37;
-  const SWord8 s39 = 127 & s37;
-  const SWord8 s40 = s10 ? s38 : s39;
-  const SBool  s41 = (SBool) (s40 & 1);
-  const SBool  s42 = false != s41;
-  const SWord8 s43 = (s27 >> 1) | (s27 << 7);
-  const SWord8 s44 = 128 | s43;
-  const SWord8 s45 = 127 & s43;
-  const SWord8 s46 = s42 ? s44 : s45;
-  const SBool  s47 = (SBool) (s46 & 1);
-  const SBool  s48 = false != s47;
-  const SWord8 s49 = (s33 >> 1) | (s33 << 7);
-  const SWord8 s50 = 128 | s49;
-  const SWord8 s51 = 127 & s49;
-  const SWord8 s52 = s48 ? s50 : s51;
-  const SBool  s53 = (SBool) (s52 & 1);
-  const SBool  s54 = false != s53;
-  const SBool  s55 = !s54;
-  const SWord8 s56 = (s40 >> 1) | (s40 << 7);
-  const SWord8 s57 = 128 | s56;
-  const SWord8 s58 = 127 & s56;
-  const SWord8 s59 = s15 ? s57 : s58;
-  const SBool  s60 = (SBool) (s59 & 1);
-  const SBool  s61 = false != s60;
-  const SWord8 s62 = (s46 >> 1) | (s46 << 7);
-  const SWord8 s63 = 128 | s62;
-  const SWord8 s64 = 127 & s62;
-  const SWord8 s65 = s61 ? s63 : s64;
-  const SBool  s66 = (SBool) (s65 & 1);
-  const SBool  s67 = false != s66;
-  const SWord8 s68 = (s52 >> 1) | (s52 << 7);
-  const SWord8 s69 = 128 | s68;
-  const SWord8 s70 = 127 & s68;
-  const SWord8 s71 = s67 ? s69 : s70;
-  const SBool  s72 = (SBool) (s71 & 1);
-  const SBool  s73 = false != s72;
-  const SBool  s74 = !s73;
-  const SWord8 s75 = (s59 >> 1) | (s59 << 7);
-  const SWord8 s76 = 128 | s75;
-  const SWord8 s77 = 127 & s75;
-  const SWord8 s78 = s20 ? s76 : s77;
-  const SBool  s79 = (SBool) (s78 & 1);
-  const SBool  s80 = false != s79;
-  const SWord8 s81 = (s65 >> 1) | (s65 << 7);
-  const SWord8 s82 = 128 | s81;
-  const SWord8 s83 = 127 & s81;
-  const SWord8 s84 = s80 ? s82 : s83;
-  const SBool  s85 = (SBool) (s84 & 1);
-  const SBool  s86 = false != s85;
-  const SWord8 s87 = (s71 >> 1) | (s71 << 7);
-  const SWord8 s88 = 128 | s87;
-  const SWord8 s89 = 127 & s87;
-  const SWord8 s90 = s86 ? s88 : s89;
-  const SBool  s91 = (SBool) (s90 & 1);
-  const SBool  s92 = false != s91;
-  const SBool  s93 = !s92;
-  const SWord8 s94 = (s78 >> 1) | (s78 << 7);
-  const SWord8 s95 = 128 | s94;
-  const SWord8 s96 = 127 & s94;
-  const SWord8 s97 = s35 ? s95 : s96;
-  const SWord8 s98 = (s97 >> 1) | (s97 << 7);
-  const SWord8 s99 = 128 | s98;
-  const SWord8 s100 = 127 & s98;
-  const SWord8 s101 = s54 ? s99 : s100;
-  const SWord8 s102 = (s101 >> 1) | (s101 << 7);
-  const SWord8 s103 = 128 | s102;
-  const SWord8 s104 = 127 & s102;
-  const SWord8 s105 = s73 ? s103 : s104;
-  const SWord8 s106 = (s105 >> 1) | (s105 << 7);
-  const SWord8 s107 = 128 | s106;
-  const SWord8 s108 = 127 & s106;
-  const SWord8 s109 = s92 ? s107 : s108;
-  const SWord8 s110 = s1 + s105;
-  const SBool  s111 = s110 < s1;
-  const SBool  s112 = s110 < s105;
-  const SBool  s113 = s111 || s112;
-  const SWord8 s114 = (s110 >> 1) | (s110 << 7);
-  const SWord8 s115 = 128 | s114;
-  const SWord8 s116 = 127 & s114;
-  const SWord8 s117 = s113 ? s115 : s116;
-  const SWord8 s118 = s93 ? s109 : s117;
-  const SWord8 s119 = s1 + s101;
-  const SBool  s120 = s119 < s1;
-  const SBool  s121 = s119 < s101;
-  const SBool  s122 = s120 || s121;
-  const SWord8 s123 = (s119 >> 1) | (s119 << 7);
-  const SWord8 s124 = 128 | s123;
-  const SWord8 s125 = 127 & s123;
-  const SWord8 s126 = s122 ? s124 : s125;
-  const SWord8 s127 = (s126 >> 1) | (s126 << 7);
-  const SWord8 s128 = 128 | s127;
-  const SWord8 s129 = 127 & s127;
-  const SWord8 s130 = s92 ? s128 : s129;
-  const SWord8 s131 = s1 + s126;
-  const SBool  s132 = s131 < s1;
-  const SBool  s133 = s131 < s126;
-  const SBool  s134 = s132 || s133;
-  const SWord8 s135 = (s131 >> 1) | (s131 << 7);
-  const SWord8 s136 = 128 | s135;
-  const SWord8 s137 = 127 & s135;
-  const SWord8 s138 = s134 ? s136 : s137;
-  const SWord8 s139 = s93 ? s130 : s138;
-  const SWord8 s140 = s74 ? s118 : s139;
-  const SWord8 s141 = s1 + s97;
-  const SBool  s142 = s141 < s1;
-  const SBool  s143 = s141 < s97;
-  const SBool  s144 = s142 || s143;
-  const SWord8 s145 = (s141 >> 1) | (s141 << 7);
-  const SWord8 s146 = 128 | s145;
-  const SWord8 s147 = 127 & s145;
-  const SWord8 s148 = s144 ? s146 : s147;
-  const SWord8 s149 = (s148 >> 1) | (s148 << 7);
-  const SWord8 s150 = 128 | s149;
-  const SWord8 s151 = 127 & s149;
-  const SWord8 s152 = s73 ? s150 : s151;
-  const SWord8 s153 = (s152 >> 1) | (s152 << 7);
-  const SWord8 s154 = 128 | s153;
-  const SWord8 s155 = 127 & s153;
-  const SWord8 s156 = s92 ? s154 : s155;
-  const SWord8 s157 = s1 + s152;
-  const SBool  s158 = s157 < s1;
-  const SBool  s159 = s157 < s152;
-  const SBool  s160 = s158 || s159;
-  const SWord8 s161 = (s157 >> 1) | (s157 << 7);
-  const SWord8 s162 = 128 | s161;
-  const SWord8 s163 = 127 & s161;
-  const SWord8 s164 = s160 ? s162 : s163;
-  const SWord8 s165 = s93 ? s156 : s164;
-  const SWord8 s166 = s1 + s148;
-  const SBool  s167 = s166 < s1;
-  const SBool  s168 = s166 < s148;
-  const SBool  s169 = s167 || s168;
-  const SWord8 s170 = (s166 >> 1) | (s166 << 7);
-  const SWord8 s171 = 128 | s170;
-  const SWord8 s172 = 127 & s170;
-  const SWord8 s173 = s169 ? s171 : s172;
-  const SWord8 s174 = (s173 >> 1) | (s173 << 7);
-  const SWord8 s175 = 128 | s174;
-  const SWord8 s176 = 127 & s174;
-  const SWord8 s177 = s92 ? s175 : s176;
-  const SWord8 s178 = s1 + s173;
-  const SBool  s179 = s178 < s1;
-  const SBool  s180 = s178 < s173;
-  const SBool  s181 = s179 || s180;
-  const SWord8 s182 = (s178 >> 1) | (s178 << 7);
-  const SWord8 s183 = 128 | s182;
-  const SWord8 s184 = 127 & s182;
-  const SWord8 s185 = s181 ? s183 : s184;
-  const SWord8 s186 = s93 ? s177 : s185;
-  const SWord8 s187 = s74 ? s165 : s186;
-  const SWord8 s188 = s55 ? s140 : s187;
-  const SWord8 s189 = s1 + s78;
-  const SBool  s190 = (SBool) (s189 & 1);
-  const SBool  s191 = false != s190;
-  const SWord8 s192 = s191 ? s82 : s83;
-  const SBool  s193 = (SBool) (s192 & 1);
-  const SBool  s194 = false != s193;
-  const SWord8 s195 = s194 ? s88 : s89;
-  const SBool  s196 = (SBool) (s195 & 1);
-  const SBool  s197 = false != s196;
-  const SBool  s198 = !s197;
-  const SBool  s199 = s189 < s1;
-  const SBool  s200 = s189 < s78;
-  const SBool  s201 = s199 || s200;
-  const SWord8 s202 = (s189 >> 1) | (s189 << 7);
-  const SWord8 s203 = 128 | s202;
-  const SWord8 s204 = 127 & s202;
-  const SWord8 s205 = s201 ? s203 : s204;
-  const SWord8 s206 = (s205 >> 1) | (s205 << 7);
-  const SWord8 s207 = 128 | s206;
-  const SWord8 s208 = 127 & s206;
-  const SWord8 s209 = s54 ? s207 : s208;
-  const SWord8 s210 = (s209 >> 1) | (s209 << 7);
-  const SWord8 s211 = 128 | s210;
-  const SWord8 s212 = 127 & s210;
-  const SWord8 s213 = s73 ? s211 : s212;
-  const SWord8 s214 = (s213 >> 1) | (s213 << 7);
-  const SWord8 s215 = 128 | s214;
-  const SWord8 s216 = 127 & s214;
-  const SWord8 s217 = s197 ? s215 : s216;
-  const SWord8 s218 = s1 + s213;
-  const SBool  s219 = s218 < s1;
-  const SBool  s220 = s218 < s213;
-  const SBool  s221 = s219 || s220;
-  const SWord8 s222 = (s218 >> 1) | (s218 << 7);
-  const SWord8 s223 = 128 | s222;
-  const SWord8 s224 = 127 & s222;
-  const SWord8 s225 = s221 ? s223 : s224;
-  const SWord8 s226 = s198 ? s217 : s225;
-  const SWord8 s227 = s1 + s209;
-  const SBool  s228 = s227 < s1;
-  const SBool  s229 = s227 < s209;
-  const SBool  s230 = s228 || s229;
-  const SWord8 s231 = (s227 >> 1) | (s227 << 7);
-  const SWord8 s232 = 128 | s231;
-  const SWord8 s233 = 127 & s231;
-  const SWord8 s234 = s230 ? s232 : s233;
-  const SWord8 s235 = (s234 >> 1) | (s234 << 7);
-  const SWord8 s236 = 128 | s235;
-  const SWord8 s237 = 127 & s235;
-  const SWord8 s238 = s197 ? s236 : s237;
-  const SWord8 s239 = s1 + s234;
-  const SBool  s240 = s239 < s1;
-  const SBool  s241 = s239 < s234;
-  const SBool  s242 = s240 || s241;
-  const SWord8 s243 = (s239 >> 1) | (s239 << 7);
-  const SWord8 s244 = 128 | s243;
-  const SWord8 s245 = 127 & s243;
-  const SWord8 s246 = s242 ? s244 : s245;
-  const SWord8 s247 = s198 ? s238 : s246;
-  const SWord8 s248 = s74 ? s226 : s247;
-  const SWord8 s249 = s1 + s205;
-  const SBool  s250 = s249 < s1;
-  const SBool  s251 = s249 < s205;
-  const SBool  s252 = s250 || s251;
-  const SWord8 s253 = (s249 >> 1) | (s249 << 7);
-  const SWord8 s254 = 128 | s253;
-  const SWord8 s255 = 127 & s253;
-  const SWord8 s256 = s252 ? s254 : s255;
-  const SWord8 s257 = (s256 >> 1) | (s256 << 7);
-  const SWord8 s258 = 128 | s257;
-  const SWord8 s259 = 127 & s257;
-  const SWord8 s260 = s73 ? s258 : s259;
-  const SWord8 s261 = (s260 >> 1) | (s260 << 7);
-  const SWord8 s262 = 128 | s261;
-  const SWord8 s263 = 127 & s261;
-  const SWord8 s264 = s197 ? s262 : s263;
-  const SWord8 s265 = s1 + s260;
-  const SBool  s266 = s265 < s1;
-  const SBool  s267 = s265 < s260;
-  const SBool  s268 = s266 || s267;
-  const SWord8 s269 = (s265 >> 1) | (s265 << 7);
-  const SWord8 s270 = 128 | s269;
-  const SWord8 s271 = 127 & s269;
-  const SWord8 s272 = s268 ? s270 : s271;
-  const SWord8 s273 = s198 ? s264 : s272;
-  const SWord8 s274 = s1 + s256;
-  const SBool  s275 = s274 < s1;
-  const SBool  s276 = s274 < s256;
-  const SBool  s277 = s275 || s276;
-  const SWord8 s278 = (s274 >> 1) | (s274 << 7);
-  const SWord8 s279 = 128 | s278;
-  const SWord8 s280 = 127 & s278;
-  const SWord8 s281 = s277 ? s279 : s280;
-  const SWord8 s282 = (s281 >> 1) | (s281 << 7);
-  const SWord8 s283 = 128 | s282;
-  const SWord8 s284 = 127 & s282;
-  const SWord8 s285 = s197 ? s283 : s284;
-  const SWord8 s286 = s1 + s281;
-  const SBool  s287 = s286 < s1;
-  const SBool  s288 = s286 < s281;
-  const SBool  s289 = s287 || s288;
-  const SWord8 s290 = (s286 >> 1) | (s286 << 7);
-  const SWord8 s291 = 128 | s290;
-  const SWord8 s292 = 127 & s290;
-  const SWord8 s293 = s289 ? s291 : s292;
-  const SWord8 s294 = s198 ? s285 : s293;
-  const SWord8 s295 = s74 ? s273 : s294;
-  const SWord8 s296 = s55 ? s248 : s295;
-  const SWord8 s297 = s36 ? s188 : s296;
-  const SWord8 s298 = s1 + s59;
-  const SBool  s299 = (SBool) (s298 & 1);
-  const SBool  s300 = false != s299;
-  const SWord8 s301 = s300 ? s63 : s64;
-  const SBool  s302 = (SBool) (s301 & 1);
-  const SBool  s303 = false != s302;
-  const SWord8 s304 = s303 ? s69 : s70;
-  const SBool  s305 = (SBool) (s304 & 1);
-  const SBool  s306 = false != s305;
-  const SBool  s307 = !s306;
-  const SBool  s308 = s298 < s1;
-  const SBool  s309 = s298 < s59;
-  const SBool  s310 = s308 || s309;
-  const SWord8 s311 = (s298 >> 1) | (s298 << 7);
-  const SWord8 s312 = 128 | s311;
-  const SWord8 s313 = 127 & s311;
-  const SWord8 s314 = s310 ? s312 : s313;
-  const SBool  s315 = (SBool) (s314 & 1);
-  const SBool  s316 = false != s315;
-  const SWord8 s317 = (s301 >> 1) | (s301 << 7);
-  const SWord8 s318 = 128 | s317;
-  const SWord8 s319 = 127 & s317;
-  const SWord8 s320 = s316 ? s318 : s319;
-  const SBool  s321 = (SBool) (s320 & 1);
-  const SBool  s322 = false != s321;
-  const SWord8 s323 = (s304 >> 1) | (s304 << 7);
-  const SWord8 s324 = 128 | s323;
-  const SWord8 s325 = 127 & s323;
-  const SWord8 s326 = s322 ? s324 : s325;
-  const SBool  s327 = (SBool) (s326 & 1);
-  const SBool  s328 = false != s327;
-  const SBool  s329 = !s328;
-  const SWord8 s330 = (s314 >> 1) | (s314 << 7);
-  const SWord8 s331 = 128 | s330;
-  const SWord8 s332 = 127 & s330;
-  const SWord8 s333 = s35 ? s331 : s332;
-  const SWord8 s334 = (s333 >> 1) | (s333 << 7);
-  const SWord8 s335 = 128 | s334;
-  const SWord8 s336 = 127 & s334;
-  const SWord8 s337 = s54 ? s335 : s336;
-  const SWord8 s338 = (s337 >> 1) | (s337 << 7);
-  const SWord8 s339 = 128 | s338;
-  const SWord8 s340 = 127 & s338;
-  const SWord8 s341 = s306 ? s339 : s340;
-  const SWord8 s342 = (s341 >> 1) | (s341 << 7);
-  const SWord8 s343 = 128 | s342;
-  const SWord8 s344 = 127 & s342;
-  const SWord8 s345 = s328 ? s343 : s344;
-  const SWord8 s346 = s1 + s341;
-  const SBool  s347 = s346 < s1;
-  const SBool  s348 = s346 < s341;
-  const SBool  s349 = s347 || s348;
-  const SWord8 s350 = (s346 >> 1) | (s346 << 7);
-  const SWord8 s351 = 128 | s350;
-  const SWord8 s352 = 127 & s350;
-  const SWord8 s353 = s349 ? s351 : s352;
-  const SWord8 s354 = s329 ? s345 : s353;
-  const SWord8 s355 = s1 + s337;
-  const SBool  s356 = s355 < s1;
-  const SBool  s357 = s355 < s337;
-  const SBool  s358 = s356 || s357;
-  const SWord8 s359 = (s355 >> 1) | (s355 << 7);
-  const SWord8 s360 = 128 | s359;
-  const SWord8 s361 = 127 & s359;
-  const SWord8 s362 = s358 ? s360 : s361;
-  const SWord8 s363 = (s362 >> 1) | (s362 << 7);
-  const SWord8 s364 = 128 | s363;
-  const SWord8 s365 = 127 & s363;
-  const SWord8 s366 = s328 ? s364 : s365;
-  const SWord8 s367 = s1 + s362;
-  const SBool  s368 = s367 < s1;
-  const SBool  s369 = s367 < s362;
-  const SBool  s370 = s368 || s369;
-  const SWord8 s371 = (s367 >> 1) | (s367 << 7);
-  const SWord8 s372 = 128 | s371;
-  const SWord8 s373 = 127 & s371;
-  const SWord8 s374 = s370 ? s372 : s373;
-  const SWord8 s375 = s329 ? s366 : s374;
-  const SWord8 s376 = s307 ? s354 : s375;
-  const SWord8 s377 = s1 + s333;
-  const SBool  s378 = s377 < s1;
-  const SBool  s379 = s377 < s333;
-  const SBool  s380 = s378 || s379;
-  const SWord8 s381 = (s377 >> 1) | (s377 << 7);
-  const SWord8 s382 = 128 | s381;
-  const SWord8 s383 = 127 & s381;
-  const SWord8 s384 = s380 ? s382 : s383;
-  const SWord8 s385 = (s384 >> 1) | (s384 << 7);
-  const SWord8 s386 = 128 | s385;
-  const SWord8 s387 = 127 & s385;
-  const SWord8 s388 = s306 ? s386 : s387;
-  const SWord8 s389 = (s388 >> 1) | (s388 << 7);
-  const SWord8 s390 = 128 | s389;
-  const SWord8 s391 = 127 & s389;
-  const SWord8 s392 = s328 ? s390 : s391;
-  const SWord8 s393 = s1 + s388;
-  const SBool  s394 = s393 < s1;
-  const SBool  s395 = s393 < s388;
-  const SBool  s396 = s394 || s395;
-  const SWord8 s397 = (s393 >> 1) | (s393 << 7);
-  const SWord8 s398 = 128 | s397;
-  const SWord8 s399 = 127 & s397;
-  const SWord8 s400 = s396 ? s398 : s399;
-  const SWord8 s401 = s329 ? s392 : s400;
-  const SWord8 s402 = s1 + s384;
-  const SBool  s403 = s402 < s1;
-  const SBool  s404 = s402 < s384;
-  const SBool  s405 = s403 || s404;
-  const SWord8 s406 = (s402 >> 1) | (s402 << 7);
-  const SWord8 s407 = 128 | s406;
-  const SWord8 s408 = 127 & s406;
-  const SWord8 s409 = s405 ? s407 : s408;
-  const SWord8 s410 = (s409 >> 1) | (s409 << 7);
-  const SWord8 s411 = 128 | s410;
-  const SWord8 s412 = 127 & s410;
-  const SWord8 s413 = s328 ? s411 : s412;
-  const SWord8 s414 = s1 + s409;
-  const SBool  s415 = s414 < s1;
-  const SBool  s416 = s414 < s409;
-  const SBool  s417 = s415 || s416;
-  const SWord8 s418 = (s414 >> 1) | (s414 << 7);
-  const SWord8 s419 = 128 | s418;
-  const SWord8 s420 = 127 & s418;
-  const SWord8 s421 = s417 ? s419 : s420;
-  const SWord8 s422 = s329 ? s413 : s421;
-  const SWord8 s423 = s307 ? s401 : s422;
-  const SWord8 s424 = s55 ? s376 : s423;
-  const SWord8 s425 = s1 + s314;
-  const SBool  s426 = (SBool) (s425 & 1);
-  const SBool  s427 = false != s426;
-  const SWord8 s428 = s427 ? s318 : s319;
-  const SBool  s429 = (SBool) (s428 & 1);
-  const SBool  s430 = false != s429;
-  const SWord8 s431 = s430 ? s324 : s325;
-  const SBool  s432 = (SBool) (s431 & 1);
-  const SBool  s433 = false != s432;
-  const SBool  s434 = !s433;
-  const SBool  s435 = s425 < s1;
-  const SBool  s436 = s425 < s314;
-  const SBool  s437 = s435 || s436;
-  const SWord8 s438 = (s425 >> 1) | (s425 << 7);
-  const SWord8 s439 = 128 | s438;
-  const SWord8 s440 = 127 & s438;
-  const SWord8 s441 = s437 ? s439 : s440;
-  const SWord8 s442 = (s441 >> 1) | (s441 << 7);
-  const SWord8 s443 = 128 | s442;
-  const SWord8 s444 = 127 & s442;
-  const SWord8 s445 = s54 ? s443 : s444;
-  const SWord8 s446 = (s445 >> 1) | (s445 << 7);
-  const SWord8 s447 = 128 | s446;
-  const SWord8 s448 = 127 & s446;
-  const SWord8 s449 = s306 ? s447 : s448;
-  const SWord8 s450 = (s449 >> 1) | (s449 << 7);
-  const SWord8 s451 = 128 | s450;
-  const SWord8 s452 = 127 & s450;
-  const SWord8 s453 = s433 ? s451 : s452;
-  const SWord8 s454 = s1 + s449;
-  const SBool  s455 = s454 < s1;
-  const SBool  s456 = s454 < s449;
-  const SBool  s457 = s455 || s456;
-  const SWord8 s458 = (s454 >> 1) | (s454 << 7);
-  const SWord8 s459 = 128 | s458;
-  const SWord8 s460 = 127 & s458;
-  const SWord8 s461 = s457 ? s459 : s460;
-  const SWord8 s462 = s434 ? s453 : s461;
-  const SWord8 s463 = s1 + s445;
-  const SBool  s464 = s463 < s1;
-  const SBool  s465 = s463 < s445;
-  const SBool  s466 = s464 || s465;
-  const SWord8 s467 = (s463 >> 1) | (s463 << 7);
-  const SWord8 s468 = 128 | s467;
-  const SWord8 s469 = 127 & s467;
-  const SWord8 s470 = s466 ? s468 : s469;
-  const SWord8 s471 = (s470 >> 1) | (s470 << 7);
-  const SWord8 s472 = 128 | s471;
-  const SWord8 s473 = 127 & s471;
-  const SWord8 s474 = s433 ? s472 : s473;
-  const SWord8 s475 = s1 + s470;
-  const SBool  s476 = s475 < s1;
-  const SBool  s477 = s475 < s470;
-  const SBool  s478 = s476 || s477;
-  const SWord8 s479 = (s475 >> 1) | (s475 << 7);
-  const SWord8 s480 = 128 | s479;
-  const SWord8 s481 = 127 & s479;
-  const SWord8 s482 = s478 ? s480 : s481;
-  const SWord8 s483 = s434 ? s474 : s482;
-  const SWord8 s484 = s307 ? s462 : s483;
-  const SWord8 s485 = s1 + s441;
-  const SBool  s486 = s485 < s1;
-  const SBool  s487 = s485 < s441;
-  const SBool  s488 = s486 || s487;
-  const SWord8 s489 = (s485 >> 1) | (s485 << 7);
-  const SWord8 s490 = 128 | s489;
-  const SWord8 s491 = 127 & s489;
-  const SWord8 s492 = s488 ? s490 : s491;
-  const SWord8 s493 = (s492 >> 1) | (s492 << 7);
-  const SWord8 s494 = 128 | s493;
-  const SWord8 s495 = 127 & s493;
-  const SWord8 s496 = s306 ? s494 : s495;
-  const SWord8 s497 = (s496 >> 1) | (s496 << 7);
-  const SWord8 s498 = 128 | s497;
-  const SWord8 s499 = 127 & s497;
-  const SWord8 s500 = s433 ? s498 : s499;
-  const SWord8 s501 = s1 + s496;
-  const SBool  s502 = s501 < s1;
-  const SBool  s503 = s501 < s496;
-  const SBool  s504 = s502 || s503;
-  const SWord8 s505 = (s501 >> 1) | (s501 << 7);
-  const SWord8 s506 = 128 | s505;
-  const SWord8 s507 = 127 & s505;
-  const SWord8 s508 = s504 ? s506 : s507;
-  const SWord8 s509 = s434 ? s500 : s508;
-  const SWord8 s510 = s1 + s492;
-  const SBool  s511 = s510 < s1;
-  const SBool  s512 = s510 < s492;
-  const SBool  s513 = s511 || s512;
-  const SWord8 s514 = (s510 >> 1) | (s510 << 7);
-  const SWord8 s515 = 128 | s514;
-  const SWord8 s516 = 127 & s514;
-  const SWord8 s517 = s513 ? s515 : s516;
-  const SWord8 s518 = (s517 >> 1) | (s517 << 7);
-  const SWord8 s519 = 128 | s518;
-  const SWord8 s520 = 127 & s518;
-  const SWord8 s521 = s433 ? s519 : s520;
-  const SWord8 s522 = s1 + s517;
-  const SBool  s523 = s522 < s1;
-  const SBool  s524 = s522 < s517;
-  const SBool  s525 = s523 || s524;
-  const SWord8 s526 = (s522 >> 1) | (s522 << 7);
-  const SWord8 s527 = 128 | s526;
-  const SWord8 s528 = 127 & s526;
-  const SWord8 s529 = s525 ? s527 : s528;
-  const SWord8 s530 = s434 ? s521 : s529;
-  const SWord8 s531 = s307 ? s509 : s530;
-  const SWord8 s532 = s55 ? s484 : s531;
-  const SWord8 s533 = s36 ? s424 : s532;
-  const SWord8 s534 = s21 ? s297 : s533;
-  const SWord8 s535 = s1 + s40;
-  const SBool  s536 = (SBool) (s535 & 1);
-  const SBool  s537 = false != s536;
-  const SWord8 s538 = s537 ? s44 : s45;
-  const SBool  s539 = (SBool) (s538 & 1);
-  const SBool  s540 = false != s539;
-  const SWord8 s541 = s540 ? s50 : s51;
-  const SBool  s542 = (SBool) (s541 & 1);
-  const SBool  s543 = false != s542;
-  const SBool  s544 = !s543;
-  const SBool  s545 = s535 < s1;
-  const SBool  s546 = s535 < s40;
-  const SBool  s547 = s545 || s546;
-  const SWord8 s548 = (s535 >> 1) | (s535 << 7);
-  const SWord8 s549 = 128 | s548;
-  const SWord8 s550 = 127 & s548;
-  const SWord8 s551 = s547 ? s549 : s550;
-  const SBool  s552 = (SBool) (s551 & 1);
-  const SBool  s553 = false != s552;
-  const SWord8 s554 = (s538 >> 1) | (s538 << 7);
-  const SWord8 s555 = 128 | s554;
-  const SWord8 s556 = 127 & s554;
-  const SWord8 s557 = s553 ? s555 : s556;
-  const SBool  s558 = (SBool) (s557 & 1);
-  const SBool  s559 = false != s558;
-  const SWord8 s560 = (s541 >> 1) | (s541 << 7);
-  const SWord8 s561 = 128 | s560;
-  const SWord8 s562 = 127 & s560;
-  const SWord8 s563 = s559 ? s561 : s562;
-  const SBool  s564 = (SBool) (s563 & 1);
-  const SBool  s565 = false != s564;
-  const SBool  s566 = !s565;
-  const SWord8 s567 = (s551 >> 1) | (s551 << 7);
-  const SWord8 s568 = 128 | s567;
-  const SWord8 s569 = 127 & s567;
-  const SWord8 s570 = s20 ? s568 : s569;
-  const SBool  s571 = (SBool) (s570 & 1);
-  const SBool  s572 = false != s571;
-  const SWord8 s573 = (s557 >> 1) | (s557 << 7);
-  const SWord8 s574 = 128 | s573;
-  const SWord8 s575 = 127 & s573;
-  const SWord8 s576 = s572 ? s574 : s575;
-  const SBool  s577 = (SBool) (s576 & 1);
-  const SBool  s578 = false != s577;
-  const SWord8 s579 = (s563 >> 1) | (s563 << 7);
-  const SWord8 s580 = 128 | s579;
-  const SWord8 s581 = 127 & s579;
-  const SWord8 s582 = s578 ? s580 : s581;
-  const SBool  s583 = (SBool) (s582 & 1);
-  const SBool  s584 = false != s583;
-  const SBool  s585 = !s584;
-  const SWord8 s586 = (s570 >> 1) | (s570 << 7);
-  const SWord8 s587 = 128 | s586;
-  const SWord8 s588 = 127 & s586;
-  const SWord8 s589 = s35 ? s587 : s588;
-  const SWord8 s590 = (s589 >> 1) | (s589 << 7);
-  const SWord8 s591 = 128 | s590;
-  const SWord8 s592 = 127 & s590;
-  const SWord8 s593 = s543 ? s591 : s592;
-  const SWord8 s594 = (s593 >> 1) | (s593 << 7);
-  const SWord8 s595 = 128 | s594;
-  const SWord8 s596 = 127 & s594;
-  const SWord8 s597 = s565 ? s595 : s596;
-  const SWord8 s598 = (s597 >> 1) | (s597 << 7);
-  const SWord8 s599 = 128 | s598;
-  const SWord8 s600 = 127 & s598;
-  const SWord8 s601 = s584 ? s599 : s600;
-  const SWord8 s602 = s1 + s597;
-  const SBool  s603 = s602 < s1;
-  const SBool  s604 = s602 < s597;
-  const SBool  s605 = s603 || s604;
-  const SWord8 s606 = (s602 >> 1) | (s602 << 7);
-  const SWord8 s607 = 128 | s606;
-  const SWord8 s608 = 127 & s606;
-  const SWord8 s609 = s605 ? s607 : s608;
-  const SWord8 s610 = s585 ? s601 : s609;
-  const SWord8 s611 = s1 + s593;
-  const SBool  s612 = s611 < s1;
-  const SBool  s613 = s611 < s593;
-  const SBool  s614 = s612 || s613;
-  const SWord8 s615 = (s611 >> 1) | (s611 << 7);
-  const SWord8 s616 = 128 | s615;
-  const SWord8 s617 = 127 & s615;
-  const SWord8 s618 = s614 ? s616 : s617;
-  const SWord8 s619 = (s618 >> 1) | (s618 << 7);
-  const SWord8 s620 = 128 | s619;
-  const SWord8 s621 = 127 & s619;
-  const SWord8 s622 = s584 ? s620 : s621;
-  const SWord8 s623 = s1 + s618;
-  const SBool  s624 = s623 < s1;
-  const SBool  s625 = s623 < s618;
-  const SBool  s626 = s624 || s625;
-  const SWord8 s627 = (s623 >> 1) | (s623 << 7);
-  const SWord8 s628 = 128 | s627;
-  const SWord8 s629 = 127 & s627;
-  const SWord8 s630 = s626 ? s628 : s629;
-  const SWord8 s631 = s585 ? s622 : s630;
-  const SWord8 s632 = s566 ? s610 : s631;
-  const SWord8 s633 = s1 + s589;
-  const SBool  s634 = s633 < s1;
-  const SBool  s635 = s633 < s589;
-  const SBool  s636 = s634 || s635;
-  const SWord8 s637 = (s633 >> 1) | (s633 << 7);
-  const SWord8 s638 = 128 | s637;
-  const SWord8 s639 = 127 & s637;
-  const SWord8 s640 = s636 ? s638 : s639;
-  const SWord8 s641 = (s640 >> 1) | (s640 << 7);
-  const SWord8 s642 = 128 | s641;
-  const SWord8 s643 = 127 & s641;
-  const SWord8 s644 = s565 ? s642 : s643;
-  const SWord8 s645 = (s644 >> 1) | (s644 << 7);
-  const SWord8 s646 = 128 | s645;
-  const SWord8 s647 = 127 & s645;
-  const SWord8 s648 = s584 ? s646 : s647;
-  const SWord8 s649 = s1 + s644;
-  const SBool  s650 = s649 < s1;
-  const SBool  s651 = s649 < s644;
-  const SBool  s652 = s650 || s651;
-  const SWord8 s653 = (s649 >> 1) | (s649 << 7);
-  const SWord8 s654 = 128 | s653;
-  const SWord8 s655 = 127 & s653;
-  const SWord8 s656 = s652 ? s654 : s655;
-  const SWord8 s657 = s585 ? s648 : s656;
-  const SWord8 s658 = s1 + s640;
-  const SBool  s659 = s658 < s1;
-  const SBool  s660 = s658 < s640;
-  const SBool  s661 = s659 || s660;
-  const SWord8 s662 = (s658 >> 1) | (s658 << 7);
-  const SWord8 s663 = 128 | s662;
-  const SWord8 s664 = 127 & s662;
-  const SWord8 s665 = s661 ? s663 : s664;
-  const SWord8 s666 = (s665 >> 1) | (s665 << 7);
-  const SWord8 s667 = 128 | s666;
-  const SWord8 s668 = 127 & s666;
-  const SWord8 s669 = s584 ? s667 : s668;
-  const SWord8 s670 = s1 + s665;
-  const SBool  s671 = s670 < s1;
-  const SBool  s672 = s670 < s665;
-  const SBool  s673 = s671 || s672;
-  const SWord8 s674 = (s670 >> 1) | (s670 << 7);
-  const SWord8 s675 = 128 | s674;
-  const SWord8 s676 = 127 & s674;
-  const SWord8 s677 = s673 ? s675 : s676;
-  const SWord8 s678 = s585 ? s669 : s677;
-  const SWord8 s679 = s566 ? s657 : s678;
-  const SWord8 s680 = s544 ? s632 : s679;
-  const SWord8 s681 = s1 + s570;
-  const SBool  s682 = (SBool) (s681 & 1);
-  const SBool  s683 = false != s682;
-  const SWord8 s684 = s683 ? s574 : s575;
-  const SBool  s685 = (SBool) (s684 & 1);
-  const SBool  s686 = false != s685;
-  const SWord8 s687 = s686 ? s580 : s581;
-  const SBool  s688 = (SBool) (s687 & 1);
-  const SBool  s689 = false != s688;
-  const SBool  s690 = !s689;
-  const SBool  s691 = s681 < s1;
-  const SBool  s692 = s681 < s570;
-  const SBool  s693 = s691 || s692;
-  const SWord8 s694 = (s681 >> 1) | (s681 << 7);
-  const SWord8 s695 = 128 | s694;
-  const SWord8 s696 = 127 & s694;
-  const SWord8 s697 = s693 ? s695 : s696;
-  const SWord8 s698 = (s697 >> 1) | (s697 << 7);
-  const SWord8 s699 = 128 | s698;
-  const SWord8 s700 = 127 & s698;
-  const SWord8 s701 = s543 ? s699 : s700;
-  const SWord8 s702 = (s701 >> 1) | (s701 << 7);
-  const SWord8 s703 = 128 | s702;
-  const SWord8 s704 = 127 & s702;
-  const SWord8 s705 = s565 ? s703 : s704;
-  const SWord8 s706 = (s705 >> 1) | (s705 << 7);
-  const SWord8 s707 = 128 | s706;
-  const SWord8 s708 = 127 & s706;
-  const SWord8 s709 = s689 ? s707 : s708;
-  const SWord8 s710 = s1 + s705;
-  const SBool  s711 = s710 < s1;
-  const SBool  s712 = s710 < s705;
-  const SBool  s713 = s711 || s712;
-  const SWord8 s714 = (s710 >> 1) | (s710 << 7);
-  const SWord8 s715 = 128 | s714;
-  const SWord8 s716 = 127 & s714;
-  const SWord8 s717 = s713 ? s715 : s716;
-  const SWord8 s718 = s690 ? s709 : s717;
-  const SWord8 s719 = s1 + s701;
-  const SBool  s720 = s719 < s1;
-  const SBool  s721 = s719 < s701;
-  const SBool  s722 = s720 || s721;
-  const SWord8 s723 = (s719 >> 1) | (s719 << 7);
-  const SWord8 s724 = 128 | s723;
-  const SWord8 s725 = 127 & s723;
-  const SWord8 s726 = s722 ? s724 : s725;
-  const SWord8 s727 = (s726 >> 1) | (s726 << 7);
-  const SWord8 s728 = 128 | s727;
-  const SWord8 s729 = 127 & s727;
-  const SWord8 s730 = s689 ? s728 : s729;
-  const SWord8 s731 = s1 + s726;
-  const SBool  s732 = s731 < s1;
-  const SBool  s733 = s731 < s726;
-  const SBool  s734 = s732 || s733;
-  const SWord8 s735 = (s731 >> 1) | (s731 << 7);
-  const SWord8 s736 = 128 | s735;
-  const SWord8 s737 = 127 & s735;
-  const SWord8 s738 = s734 ? s736 : s737;
-  const SWord8 s739 = s690 ? s730 : s738;
-  const SWord8 s740 = s566 ? s718 : s739;
-  const SWord8 s741 = s1 + s697;
-  const SBool  s742 = s741 < s1;
-  const SBool  s743 = s741 < s697;
-  const SBool  s744 = s742 || s743;
-  const SWord8 s745 = (s741 >> 1) | (s741 << 7);
-  const SWord8 s746 = 128 | s745;
-  const SWord8 s747 = 127 & s745;
-  const SWord8 s748 = s744 ? s746 : s747;
-  const SWord8 s749 = (s748 >> 1) | (s748 << 7);
-  const SWord8 s750 = 128 | s749;
-  const SWord8 s751 = 127 & s749;
-  const SWord8 s752 = s565 ? s750 : s751;
-  const SWord8 s753 = (s752 >> 1) | (s752 << 7);
-  const SWord8 s754 = 128 | s753;
-  const SWord8 s755 = 127 & s753;
-  const SWord8 s756 = s689 ? s754 : s755;
-  const SWord8 s757 = s1 + s752;
-  const SBool  s758 = s757 < s1;
-  const SBool  s759 = s757 < s752;
-  const SBool  s760 = s758 || s759;
-  const SWord8 s761 = (s757 >> 1) | (s757 << 7);
-  const SWord8 s762 = 128 | s761;
-  const SWord8 s763 = 127 & s761;
-  const SWord8 s764 = s760 ? s762 : s763;
-  const SWord8 s765 = s690 ? s756 : s764;
-  const SWord8 s766 = s1 + s748;
-  const SBool  s767 = s766 < s1;
-  const SBool  s768 = s766 < s748;
-  const SBool  s769 = s767 || s768;
-  const SWord8 s770 = (s766 >> 1) | (s766 << 7);
-  const SWord8 s771 = 128 | s770;
-  const SWord8 s772 = 127 & s770;
-  const SWord8 s773 = s769 ? s771 : s772;
-  const SWord8 s774 = (s773 >> 1) | (s773 << 7);
-  const SWord8 s775 = 128 | s774;
-  const SWord8 s776 = 127 & s774;
-  const SWord8 s777 = s689 ? s775 : s776;
-  const SWord8 s778 = s1 + s773;
-  const SBool  s779 = s778 < s1;
-  const SBool  s780 = s778 < s773;
-  const SBool  s781 = s779 || s780;
-  const SWord8 s782 = (s778 >> 1) | (s778 << 7);
-  const SWord8 s783 = 128 | s782;
-  const SWord8 s784 = 127 & s782;
-  const SWord8 s785 = s781 ? s783 : s784;
-  const SWord8 s786 = s690 ? s777 : s785;
-  const SWord8 s787 = s566 ? s765 : s786;
-  const SWord8 s788 = s544 ? s740 : s787;
-  const SWord8 s789 = s36 ? s680 : s788;
-  const SWord8 s790 = s1 + s551;
-  const SBool  s791 = (SBool) (s790 & 1);
-  const SBool  s792 = false != s791;
-  const SWord8 s793 = s792 ? s555 : s556;
-  const SBool  s794 = (SBool) (s793 & 1);
-  const SBool  s795 = false != s794;
-  const SWord8 s796 = s795 ? s561 : s562;
-  const SBool  s797 = (SBool) (s796 & 1);
-  const SBool  s798 = false != s797;
-  const SBool  s799 = !s798;
-  const SBool  s800 = s790 < s1;
-  const SBool  s801 = s790 < s551;
-  const SBool  s802 = s800 || s801;
-  const SWord8 s803 = (s790 >> 1) | (s790 << 7);
-  const SWord8 s804 = 128 | s803;
-  const SWord8 s805 = 127 & s803;
-  const SWord8 s806 = s802 ? s804 : s805;
-  const SBool  s807 = (SBool) (s806 & 1);
-  const SBool  s808 = false != s807;
-  const SWord8 s809 = (s793 >> 1) | (s793 << 7);
-  const SWord8 s810 = 128 | s809;
-  const SWord8 s811 = 127 & s809;
-  const SWord8 s812 = s808 ? s810 : s811;
-  const SBool  s813 = (SBool) (s812 & 1);
-  const SBool  s814 = false != s813;
-  const SWord8 s815 = (s796 >> 1) | (s796 << 7);
-  const SWord8 s816 = 128 | s815;
-  const SWord8 s817 = 127 & s815;
-  const SWord8 s818 = s814 ? s816 : s817;
-  const SBool  s819 = (SBool) (s818 & 1);
-  const SBool  s820 = false != s819;
-  const SBool  s821 = !s820;
-  const SWord8 s822 = (s806 >> 1) | (s806 << 7);
-  const SWord8 s823 = 128 | s822;
-  const SWord8 s824 = 127 & s822;
-  const SWord8 s825 = s35 ? s823 : s824;
-  const SWord8 s826 = (s825 >> 1) | (s825 << 7);
-  const SWord8 s827 = 128 | s826;
-  const SWord8 s828 = 127 & s826;
-  const SWord8 s829 = s543 ? s827 : s828;
-  const SWord8 s830 = (s829 >> 1) | (s829 << 7);
-  const SWord8 s831 = 128 | s830;
-  const SWord8 s832 = 127 & s830;
-  const SWord8 s833 = s798 ? s831 : s832;
-  const SWord8 s834 = (s833 >> 1) | (s833 << 7);
-  const SWord8 s835 = 128 | s834;
-  const SWord8 s836 = 127 & s834;
-  const SWord8 s837 = s820 ? s835 : s836;
-  const SWord8 s838 = s1 + s833;
-  const SBool  s839 = s838 < s1;
-  const SBool  s840 = s838 < s833;
-  const SBool  s841 = s839 || s840;
-  const SWord8 s842 = (s838 >> 1) | (s838 << 7);
-  const SWord8 s843 = 128 | s842;
-  const SWord8 s844 = 127 & s842;
-  const SWord8 s845 = s841 ? s843 : s844;
-  const SWord8 s846 = s821 ? s837 : s845;
-  const SWord8 s847 = s1 + s829;
-  const SBool  s848 = s847 < s1;
-  const SBool  s849 = s847 < s829;
-  const SBool  s850 = s848 || s849;
-  const SWord8 s851 = (s847 >> 1) | (s847 << 7);
-  const SWord8 s852 = 128 | s851;
-  const SWord8 s853 = 127 & s851;
-  const SWord8 s854 = s850 ? s852 : s853;
-  const SWord8 s855 = (s854 >> 1) | (s854 << 7);
-  const SWord8 s856 = 128 | s855;
-  const SWord8 s857 = 127 & s855;
-  const SWord8 s858 = s820 ? s856 : s857;
-  const SWord8 s859 = s1 + s854;
-  const SBool  s860 = s859 < s1;
-  const SBool  s861 = s859 < s854;
-  const SBool  s862 = s860 || s861;
-  const SWord8 s863 = (s859 >> 1) | (s859 << 7);
-  const SWord8 s864 = 128 | s863;
-  const SWord8 s865 = 127 & s863;
-  const SWord8 s866 = s862 ? s864 : s865;
-  const SWord8 s867 = s821 ? s858 : s866;
-  const SWord8 s868 = s799 ? s846 : s867;
-  const SWord8 s869 = s1 + s825;
-  const SBool  s870 = s869 < s1;
-  const SBool  s871 = s869 < s825;
-  const SBool  s872 = s870 || s871;
-  const SWord8 s873 = (s869 >> 1) | (s869 << 7);
-  const SWord8 s874 = 128 | s873;
-  const SWord8 s875 = 127 & s873;
-  const SWord8 s876 = s872 ? s874 : s875;
-  const SWord8 s877 = (s876 >> 1) | (s876 << 7);
-  const SWord8 s878 = 128 | s877;
-  const SWord8 s879 = 127 & s877;
-  const SWord8 s880 = s798 ? s878 : s879;
-  const SWord8 s881 = (s880 >> 1) | (s880 << 7);
-  const SWord8 s882 = 128 | s881;
-  const SWord8 s883 = 127 & s881;
-  const SWord8 s884 = s820 ? s882 : s883;
-  const SWord8 s885 = s1 + s880;
-  const SBool  s886 = s885 < s1;
-  const SBool  s887 = s885 < s880;
-  const SBool  s888 = s886 || s887;
-  const SWord8 s889 = (s885 >> 1) | (s885 << 7);
-  const SWord8 s890 = 128 | s889;
-  const SWord8 s891 = 127 & s889;
-  const SWord8 s892 = s888 ? s890 : s891;
-  const SWord8 s893 = s821 ? s884 : s892;
-  const SWord8 s894 = s1 + s876;
-  const SBool  s895 = s894 < s1;
-  const SBool  s896 = s894 < s876;
-  const SBool  s897 = s895 || s896;
-  const SWord8 s898 = (s894 >> 1) | (s894 << 7);
-  const SWord8 s899 = 128 | s898;
-  const SWord8 s900 = 127 & s898;
-  const SWord8 s901 = s897 ? s899 : s900;
-  const SWord8 s902 = (s901 >> 1) | (s901 << 7);
-  const SWord8 s903 = 128 | s902;
-  const SWord8 s904 = 127 & s902;
-  const SWord8 s905 = s820 ? s903 : s904;
-  const SWord8 s906 = s1 + s901;
-  const SBool  s907 = s906 < s1;
-  const SBool  s908 = s906 < s901;
-  const SBool  s909 = s907 || s908;
-  const SWord8 s910 = (s906 >> 1) | (s906 << 7);
-  const SWord8 s911 = 128 | s910;
-  const SWord8 s912 = 127 & s910;
-  const SWord8 s913 = s909 ? s911 : s912;
-  const SWord8 s914 = s821 ? s905 : s913;
-  const SWord8 s915 = s799 ? s893 : s914;
-  const SWord8 s916 = s544 ? s868 : s915;
-  const SWord8 s917 = s1 + s806;
-  const SBool  s918 = (SBool) (s917 & 1);
-  const SBool  s919 = false != s918;
-  const SWord8 s920 = s919 ? s810 : s811;
-  const SBool  s921 = (SBool) (s920 & 1);
-  const SBool  s922 = false != s921;
-  const SWord8 s923 = s922 ? s816 : s817;
-  const SBool  s924 = (SBool) (s923 & 1);
-  const SBool  s925 = false != s924;
-  const SBool  s926 = !s925;
-  const SBool  s927 = s917 < s1;
-  const SBool  s928 = s917 < s806;
-  const SBool  s929 = s927 || s928;
-  const SWord8 s930 = (s917 >> 1) | (s917 << 7);
-  const SWord8 s931 = 128 | s930;
-  const SWord8 s932 = 127 & s930;
-  const SWord8 s933 = s929 ? s931 : s932;
-  const SWord8 s934 = (s933 >> 1) | (s933 << 7);
-  const SWord8 s935 = 128 | s934;
-  const SWord8 s936 = 127 & s934;
-  const SWord8 s937 = s543 ? s935 : s936;
-  const SWord8 s938 = (s937 >> 1) | (s937 << 7);
-  const SWord8 s939 = 128 | s938;
-  const SWord8 s940 = 127 & s938;
-  const SWord8 s941 = s798 ? s939 : s940;
-  const SWord8 s942 = (s941 >> 1) | (s941 << 7);
-  const SWord8 s943 = 128 | s942;
-  const SWord8 s944 = 127 & s942;
-  const SWord8 s945 = s925 ? s943 : s944;
-  const SWord8 s946 = s1 + s941;
-  const SBool  s947 = s946 < s1;
-  const SBool  s948 = s946 < s941;
-  const SBool  s949 = s947 || s948;
-  const SWord8 s950 = (s946 >> 1) | (s946 << 7);
-  const SWord8 s951 = 128 | s950;
-  const SWord8 s952 = 127 & s950;
-  const SWord8 s953 = s949 ? s951 : s952;
-  const SWord8 s954 = s926 ? s945 : s953;
-  const SWord8 s955 = s1 + s937;
-  const SBool  s956 = s955 < s1;
-  const SBool  s957 = s955 < s937;
-  const SBool  s958 = s956 || s957;
-  const SWord8 s959 = (s955 >> 1) | (s955 << 7);
-  const SWord8 s960 = 128 | s959;
-  const SWord8 s961 = 127 & s959;
-  const SWord8 s962 = s958 ? s960 : s961;
-  const SWord8 s963 = (s962 >> 1) | (s962 << 7);
-  const SWord8 s964 = 128 | s963;
-  const SWord8 s965 = 127 & s963;
-  const SWord8 s966 = s925 ? s964 : s965;
-  const SWord8 s967 = s1 + s962;
-  const SBool  s968 = s967 < s1;
-  const SBool  s969 = s967 < s962;
-  const SBool  s970 = s968 || s969;
-  const SWord8 s971 = (s967 >> 1) | (s967 << 7);
-  const SWord8 s972 = 128 | s971;
-  const SWord8 s973 = 127 & s971;
-  const SWord8 s974 = s970 ? s972 : s973;
-  const SWord8 s975 = s926 ? s966 : s974;
-  const SWord8 s976 = s799 ? s954 : s975;
-  const SWord8 s977 = s1 + s933;
-  const SBool  s978 = s977 < s1;
-  const SBool  s979 = s977 < s933;
-  const SBool  s980 = s978 || s979;
-  const SWord8 s981 = (s977 >> 1) | (s977 << 7);
-  const SWord8 s982 = 128 | s981;
-  const SWord8 s983 = 127 & s981;
-  const SWord8 s984 = s980 ? s982 : s983;
-  const SWord8 s985 = (s984 >> 1) | (s984 << 7);
-  const SWord8 s986 = 128 | s985;
-  const SWord8 s987 = 127 & s985;
-  const SWord8 s988 = s798 ? s986 : s987;
-  const SWord8 s989 = (s988 >> 1) | (s988 << 7);
-  const SWord8 s990 = 128 | s989;
-  const SWord8 s991 = 127 & s989;
-  const SWord8 s992 = s925 ? s990 : s991;
-  const SWord8 s993 = s1 + s988;
-  const SBool  s994 = s993 < s1;
-  const SBool  s995 = s993 < s988;
-  const SBool  s996 = s994 || s995;
-  const SWord8 s997 = (s993 >> 1) | (s993 << 7);
-  const SWord8 s998 = 128 | s997;
-  const SWord8 s999 = 127 & s997;
-  const SWord8 s1000 = s996 ? s998 : s999;
-  const SWord8 s1001 = s926 ? s992 : s1000;
-  const SWord8 s1002 = s1 + s984;
-  const SBool  s1003 = s1002 < s1;
-  const SBool  s1004 = s1002 < s984;
-  const SBool  s1005 = s1003 || s1004;
-  const SWord8 s1006 = (s1002 >> 1) | (s1002 << 7);
-  const SWord8 s1007 = 128 | s1006;
-  const SWord8 s1008 = 127 & s1006;
-  const SWord8 s1009 = s1005 ? s1007 : s1008;
-  const SWord8 s1010 = (s1009 >> 1) | (s1009 << 7);
-  const SWord8 s1011 = 128 | s1010;
-  const SWord8 s1012 = 127 & s1010;
-  const SWord8 s1013 = s925 ? s1011 : s1012;
-  const SWord8 s1014 = s1 + s1009;
-  const SBool  s1015 = s1014 < s1;
-  const SBool  s1016 = s1014 < s1009;
-  const SBool  s1017 = s1015 || s1016;
-  const SWord8 s1018 = (s1014 >> 1) | (s1014 << 7);
-  const SWord8 s1019 = 128 | s1018;
-  const SWord8 s1020 = 127 & s1018;
-  const SWord8 s1021 = s1017 ? s1019 : s1020;
-  const SWord8 s1022 = s926 ? s1013 : s1021;
-  const SWord8 s1023 = s799 ? s1001 : s1022;
-  const SWord8 s1024 = s544 ? s976 : s1023;
-  const SWord8 s1025 = s36 ? s916 : s1024;
-  const SWord8 s1026 = s21 ? s789 : s1025;
-  const SWord8 s1027 = s16 ? s534 : s1026;
-  const SWord8 s1028 = s1 + s24;
-  const SBool  s1029 = (SBool) (s1028 & 1);
-  const SBool  s1030 = false != s1029;
-  const SWord8 s1031 = s1030 ? 128 : 0;
-  const SBool  s1032 = (SBool) (s1031 & 1);
-  const SBool  s1033 = false != s1032;
-  const SWord8 s1034 = s1033 ? s31 : s32;
-  const SBool  s1035 = (SBool) (s1034 & 1);
-  const SBool  s1036 = false != s1035;
-  const SBool  s1037 = !s1036;
-  const SBool  s1038 = s1028 < s1;
-  const SBool  s1039 = s1028 < s24;
-  const SBool  s1040 = s1038 || s1039;
-  const SWord8 s1041 = (s1028 >> 1) | (s1028 << 7);
-  const SWord8 s1042 = 128 | s1041;
-  const SWord8 s1043 = 127 & s1041;
-  const SWord8 s1044 = s1040 ? s1042 : s1043;
-  const SBool  s1045 = (SBool) (s1044 & 1);
-  const SBool  s1046 = false != s1045;
-  const SWord8 s1047 = (s1031 >> 1) | (s1031 << 7);
-  const SWord8 s1048 = 128 | s1047;
-  const SWord8 s1049 = 127 & s1047;
-  const SWord8 s1050 = s1046 ? s1048 : s1049;
-  const SBool  s1051 = (SBool) (s1050 & 1);
-  const SBool  s1052 = false != s1051;
-  const SWord8 s1053 = (s1034 >> 1) | (s1034 << 7);
-  const SWord8 s1054 = 128 | s1053;
-  const SWord8 s1055 = 127 & s1053;
-  const SWord8 s1056 = s1052 ? s1054 : s1055;
-  const SBool  s1057 = (SBool) (s1056 & 1);
-  const SBool  s1058 = false != s1057;
-  const SBool  s1059 = !s1058;
-  const SWord8 s1060 = (s1044 >> 1) | (s1044 << 7);
-  const SWord8 s1061 = 128 | s1060;
-  const SWord8 s1062 = 127 & s1060;
-  const SWord8 s1063 = s15 ? s1061 : s1062;
-  const SBool  s1064 = (SBool) (s1063 & 1);
-  const SBool  s1065 = false != s1064;
-  const SWord8 s1066 = (s1050 >> 1) | (s1050 << 7);
-  const SWord8 s1067 = 128 | s1066;
-  const SWord8 s1068 = 127 & s1066;
-  const SWord8 s1069 = s1065 ? s1067 : s1068;
-  const SBool  s1070 = (SBool) (s1069 & 1);
-  const SBool  s1071 = false != s1070;
-  const SWord8 s1072 = (s1056 >> 1) | (s1056 << 7);
-  const SWord8 s1073 = 128 | s1072;
-  const SWord8 s1074 = 127 & s1072;
-  const SWord8 s1075 = s1071 ? s1073 : s1074;
-  const SBool  s1076 = (SBool) (s1075 & 1);
-  const SBool  s1077 = false != s1076;
-  const SBool  s1078 = !s1077;
-  const SWord8 s1079 = (s1063 >> 1) | (s1063 << 7);
-  const SWord8 s1080 = 128 | s1079;
-  const SWord8 s1081 = 127 & s1079;
-  const SWord8 s1082 = s20 ? s1080 : s1081;
-  const SBool  s1083 = (SBool) (s1082 & 1);
-  const SBool  s1084 = false != s1083;
-  const SWord8 s1085 = (s1069 >> 1) | (s1069 << 7);
-  const SWord8 s1086 = 128 | s1085;
-  const SWord8 s1087 = 127 & s1085;
-  const SWord8 s1088 = s1084 ? s1086 : s1087;
-  const SBool  s1089 = (SBool) (s1088 & 1);
-  const SBool  s1090 = false != s1089;
-  const SWord8 s1091 = (s1075 >> 1) | (s1075 << 7);
-  const SWord8 s1092 = 128 | s1091;
-  const SWord8 s1093 = 127 & s1091;
-  const SWord8 s1094 = s1090 ? s1092 : s1093;
-  const SBool  s1095 = (SBool) (s1094 & 1);
-  const SBool  s1096 = false != s1095;
-  const SBool  s1097 = !s1096;
-  const SWord8 s1098 = (s1082 >> 1) | (s1082 << 7);
-  const SWord8 s1099 = 128 | s1098;
-  const SWord8 s1100 = 127 & s1098;
-  const SWord8 s1101 = s1036 ? s1099 : s1100;
-  const SWord8 s1102 = (s1101 >> 1) | (s1101 << 7);
-  const SWord8 s1103 = 128 | s1102;
-  const SWord8 s1104 = 127 & s1102;
-  const SWord8 s1105 = s1058 ? s1103 : s1104;
-  const SWord8 s1106 = (s1105 >> 1) | (s1105 << 7);
-  const SWord8 s1107 = 128 | s1106;
-  const SWord8 s1108 = 127 & s1106;
-  const SWord8 s1109 = s1077 ? s1107 : s1108;
-  const SWord8 s1110 = (s1109 >> 1) | (s1109 << 7);
-  const SWord8 s1111 = 128 | s1110;
-  const SWord8 s1112 = 127 & s1110;
-  const SWord8 s1113 = s1096 ? s1111 : s1112;
-  const SWord8 s1114 = s1 + s1109;
-  const SBool  s1115 = s1114 < s1;
-  const SBool  s1116 = s1114 < s1109;
-  const SBool  s1117 = s1115 || s1116;
-  const SWord8 s1118 = (s1114 >> 1) | (s1114 << 7);
-  const SWord8 s1119 = 128 | s1118;
-  const SWord8 s1120 = 127 & s1118;
-  const SWord8 s1121 = s1117 ? s1119 : s1120;
-  const SWord8 s1122 = s1097 ? s1113 : s1121;
-  const SWord8 s1123 = s1 + s1105;
-  const SBool  s1124 = s1123 < s1;
-  const SBool  s1125 = s1123 < s1105;
-  const SBool  s1126 = s1124 || s1125;
-  const SWord8 s1127 = (s1123 >> 1) | (s1123 << 7);
-  const SWord8 s1128 = 128 | s1127;
-  const SWord8 s1129 = 127 & s1127;
-  const SWord8 s1130 = s1126 ? s1128 : s1129;
-  const SWord8 s1131 = (s1130 >> 1) | (s1130 << 7);
-  const SWord8 s1132 = 128 | s1131;
-  const SWord8 s1133 = 127 & s1131;
-  const SWord8 s1134 = s1096 ? s1132 : s1133;
-  const SWord8 s1135 = s1 + s1130;
-  const SBool  s1136 = s1135 < s1;
-  const SBool  s1137 = s1135 < s1130;
-  const SBool  s1138 = s1136 || s1137;
-  const SWord8 s1139 = (s1135 >> 1) | (s1135 << 7);
-  const SWord8 s1140 = 128 | s1139;
-  const SWord8 s1141 = 127 & s1139;
-  const SWord8 s1142 = s1138 ? s1140 : s1141;
-  const SWord8 s1143 = s1097 ? s1134 : s1142;
-  const SWord8 s1144 = s1078 ? s1122 : s1143;
-  const SWord8 s1145 = s1 + s1101;
-  const SBool  s1146 = s1145 < s1;
-  const SBool  s1147 = s1145 < s1101;
-  const SBool  s1148 = s1146 || s1147;
-  const SWord8 s1149 = (s1145 >> 1) | (s1145 << 7);
-  const SWord8 s1150 = 128 | s1149;
-  const SWord8 s1151 = 127 & s1149;
-  const SWord8 s1152 = s1148 ? s1150 : s1151;
-  const SWord8 s1153 = (s1152 >> 1) | (s1152 << 7);
-  const SWord8 s1154 = 128 | s1153;
-  const SWord8 s1155 = 127 & s1153;
-  const SWord8 s1156 = s1077 ? s1154 : s1155;
-  const SWord8 s1157 = (s1156 >> 1) | (s1156 << 7);
-  const SWord8 s1158 = 128 | s1157;
-  const SWord8 s1159 = 127 & s1157;
-  const SWord8 s1160 = s1096 ? s1158 : s1159;
-  const SWord8 s1161 = s1 + s1156;
-  const SBool  s1162 = s1161 < s1;
-  const SBool  s1163 = s1161 < s1156;
-  const SBool  s1164 = s1162 || s1163;
-  const SWord8 s1165 = (s1161 >> 1) | (s1161 << 7);
-  const SWord8 s1166 = 128 | s1165;
-  const SWord8 s1167 = 127 & s1165;
-  const SWord8 s1168 = s1164 ? s1166 : s1167;
-  const SWord8 s1169 = s1097 ? s1160 : s1168;
-  const SWord8 s1170 = s1 + s1152;
-  const SBool  s1171 = s1170 < s1;
-  const SBool  s1172 = s1170 < s1152;
-  const SBool  s1173 = s1171 || s1172;
-  const SWord8 s1174 = (s1170 >> 1) | (s1170 << 7);
-  const SWord8 s1175 = 128 | s1174;
-  const SWord8 s1176 = 127 & s1174;
-  const SWord8 s1177 = s1173 ? s1175 : s1176;
-  const SWord8 s1178 = (s1177 >> 1) | (s1177 << 7);
-  const SWord8 s1179 = 128 | s1178;
-  const SWord8 s1180 = 127 & s1178;
-  const SWord8 s1181 = s1096 ? s1179 : s1180;
-  const SWord8 s1182 = s1 + s1177;
-  const SBool  s1183 = s1182 < s1;
-  const SBool  s1184 = s1182 < s1177;
-  const SBool  s1185 = s1183 || s1184;
-  const SWord8 s1186 = (s1182 >> 1) | (s1182 << 7);
-  const SWord8 s1187 = 128 | s1186;
-  const SWord8 s1188 = 127 & s1186;
-  const SWord8 s1189 = s1185 ? s1187 : s1188;
-  const SWord8 s1190 = s1097 ? s1181 : s1189;
-  const SWord8 s1191 = s1078 ? s1169 : s1190;
-  const SWord8 s1192 = s1059 ? s1144 : s1191;
-  const SWord8 s1193 = s1 + s1082;
-  const SBool  s1194 = (SBool) (s1193 & 1);
-  const SBool  s1195 = false != s1194;
-  const SWord8 s1196 = s1195 ? s1086 : s1087;
-  const SBool  s1197 = (SBool) (s1196 & 1);
-  const SBool  s1198 = false != s1197;
-  const SWord8 s1199 = s1198 ? s1092 : s1093;
-  const SBool  s1200 = (SBool) (s1199 & 1);
-  const SBool  s1201 = false != s1200;
-  const SBool  s1202 = !s1201;
-  const SBool  s1203 = s1193 < s1;
-  const SBool  s1204 = s1193 < s1082;
-  const SBool  s1205 = s1203 || s1204;
-  const SWord8 s1206 = (s1193 >> 1) | (s1193 << 7);
-  const SWord8 s1207 = 128 | s1206;
-  const SWord8 s1208 = 127 & s1206;
-  const SWord8 s1209 = s1205 ? s1207 : s1208;
-  const SWord8 s1210 = (s1209 >> 1) | (s1209 << 7);
-  const SWord8 s1211 = 128 | s1210;
-  const SWord8 s1212 = 127 & s1210;
-  const SWord8 s1213 = s1058 ? s1211 : s1212;
-  const SWord8 s1214 = (s1213 >> 1) | (s1213 << 7);
-  const SWord8 s1215 = 128 | s1214;
-  const SWord8 s1216 = 127 & s1214;
-  const SWord8 s1217 = s1077 ? s1215 : s1216;
-  const SWord8 s1218 = (s1217 >> 1) | (s1217 << 7);
-  const SWord8 s1219 = 128 | s1218;
-  const SWord8 s1220 = 127 & s1218;
-  const SWord8 s1221 = s1201 ? s1219 : s1220;
-  const SWord8 s1222 = s1 + s1217;
-  const SBool  s1223 = s1222 < s1;
-  const SBool  s1224 = s1222 < s1217;
-  const SBool  s1225 = s1223 || s1224;
-  const SWord8 s1226 = (s1222 >> 1) | (s1222 << 7);
-  const SWord8 s1227 = 128 | s1226;
-  const SWord8 s1228 = 127 & s1226;
-  const SWord8 s1229 = s1225 ? s1227 : s1228;
-  const SWord8 s1230 = s1202 ? s1221 : s1229;
-  const SWord8 s1231 = s1 + s1213;
-  const SBool  s1232 = s1231 < s1;
-  const SBool  s1233 = s1231 < s1213;
-  const SBool  s1234 = s1232 || s1233;
-  const SWord8 s1235 = (s1231 >> 1) | (s1231 << 7);
-  const SWord8 s1236 = 128 | s1235;
-  const SWord8 s1237 = 127 & s1235;
-  const SWord8 s1238 = s1234 ? s1236 : s1237;
-  const SWord8 s1239 = (s1238 >> 1) | (s1238 << 7);
-  const SWord8 s1240 = 128 | s1239;
-  const SWord8 s1241 = 127 & s1239;
-  const SWord8 s1242 = s1201 ? s1240 : s1241;
-  const SWord8 s1243 = s1 + s1238;
-  const SBool  s1244 = s1243 < s1;
-  const SBool  s1245 = s1243 < s1238;
-  const SBool  s1246 = s1244 || s1245;
-  const SWord8 s1247 = (s1243 >> 1) | (s1243 << 7);
-  const SWord8 s1248 = 128 | s1247;
-  const SWord8 s1249 = 127 & s1247;
-  const SWord8 s1250 = s1246 ? s1248 : s1249;
-  const SWord8 s1251 = s1202 ? s1242 : s1250;
-  const SWord8 s1252 = s1078 ? s1230 : s1251;
-  const SWord8 s1253 = s1 + s1209;
-  const SBool  s1254 = s1253 < s1;
-  const SBool  s1255 = s1253 < s1209;
-  const SBool  s1256 = s1254 || s1255;
-  const SWord8 s1257 = (s1253 >> 1) | (s1253 << 7);
-  const SWord8 s1258 = 128 | s1257;
-  const SWord8 s1259 = 127 & s1257;
-  const SWord8 s1260 = s1256 ? s1258 : s1259;
-  const SWord8 s1261 = (s1260 >> 1) | (s1260 << 7);
-  const SWord8 s1262 = 128 | s1261;
-  const SWord8 s1263 = 127 & s1261;
-  const SWord8 s1264 = s1077 ? s1262 : s1263;
-  const SWord8 s1265 = (s1264 >> 1) | (s1264 << 7);
-  const SWord8 s1266 = 128 | s1265;
-  const SWord8 s1267 = 127 & s1265;
-  const SWord8 s1268 = s1201 ? s1266 : s1267;
-  const SWord8 s1269 = s1 + s1264;
-  const SBool  s1270 = s1269 < s1;
-  const SBool  s1271 = s1269 < s1264;
-  const SBool  s1272 = s1270 || s1271;
-  const SWord8 s1273 = (s1269 >> 1) | (s1269 << 7);
-  const SWord8 s1274 = 128 | s1273;
-  const SWord8 s1275 = 127 & s1273;
-  const SWord8 s1276 = s1272 ? s1274 : s1275;
-  const SWord8 s1277 = s1202 ? s1268 : s1276;
-  const SWord8 s1278 = s1 + s1260;
-  const SBool  s1279 = s1278 < s1;
-  const SBool  s1280 = s1278 < s1260;
-  const SBool  s1281 = s1279 || s1280;
-  const SWord8 s1282 = (s1278 >> 1) | (s1278 << 7);
-  const SWord8 s1283 = 128 | s1282;
-  const SWord8 s1284 = 127 & s1282;
-  const SWord8 s1285 = s1281 ? s1283 : s1284;
-  const SWord8 s1286 = (s1285 >> 1) | (s1285 << 7);
-  const SWord8 s1287 = 128 | s1286;
-  const SWord8 s1288 = 127 & s1286;
-  const SWord8 s1289 = s1201 ? s1287 : s1288;
-  const SWord8 s1290 = s1 + s1285;
-  const SBool  s1291 = s1290 < s1;
-  const SBool  s1292 = s1290 < s1285;
-  const SBool  s1293 = s1291 || s1292;
-  const SWord8 s1294 = (s1290 >> 1) | (s1290 << 7);
-  const SWord8 s1295 = 128 | s1294;
-  const SWord8 s1296 = 127 & s1294;
-  const SWord8 s1297 = s1293 ? s1295 : s1296;
-  const SWord8 s1298 = s1202 ? s1289 : s1297;
-  const SWord8 s1299 = s1078 ? s1277 : s1298;
-  const SWord8 s1300 = s1059 ? s1252 : s1299;
-  const SWord8 s1301 = s1037 ? s1192 : s1300;
-  const SWord8 s1302 = s1 + s1063;
-  const SBool  s1303 = (SBool) (s1302 & 1);
-  const SBool  s1304 = false != s1303;
-  const SWord8 s1305 = s1304 ? s1067 : s1068;
-  const SBool  s1306 = (SBool) (s1305 & 1);
-  const SBool  s1307 = false != s1306;
-  const SWord8 s1308 = s1307 ? s1073 : s1074;
-  const SBool  s1309 = (SBool) (s1308 & 1);
-  const SBool  s1310 = false != s1309;
-  const SBool  s1311 = !s1310;
-  const SBool  s1312 = s1302 < s1;
-  const SBool  s1313 = s1302 < s1063;
-  const SBool  s1314 = s1312 || s1313;
-  const SWord8 s1315 = (s1302 >> 1) | (s1302 << 7);
-  const SWord8 s1316 = 128 | s1315;
-  const SWord8 s1317 = 127 & s1315;
-  const SWord8 s1318 = s1314 ? s1316 : s1317;
-  const SBool  s1319 = (SBool) (s1318 & 1);
-  const SBool  s1320 = false != s1319;
-  const SWord8 s1321 = (s1305 >> 1) | (s1305 << 7);
-  const SWord8 s1322 = 128 | s1321;
-  const SWord8 s1323 = 127 & s1321;
-  const SWord8 s1324 = s1320 ? s1322 : s1323;
-  const SBool  s1325 = (SBool) (s1324 & 1);
-  const SBool  s1326 = false != s1325;
-  const SWord8 s1327 = (s1308 >> 1) | (s1308 << 7);
-  const SWord8 s1328 = 128 | s1327;
-  const SWord8 s1329 = 127 & s1327;
-  const SWord8 s1330 = s1326 ? s1328 : s1329;
-  const SBool  s1331 = (SBool) (s1330 & 1);
-  const SBool  s1332 = false != s1331;
-  const SBool  s1333 = !s1332;
-  const SWord8 s1334 = (s1318 >> 1) | (s1318 << 7);
-  const SWord8 s1335 = 128 | s1334;
-  const SWord8 s1336 = 127 & s1334;
-  const SWord8 s1337 = s1036 ? s1335 : s1336;
-  const SWord8 s1338 = (s1337 >> 1) | (s1337 << 7);
-  const SWord8 s1339 = 128 | s1338;
-  const SWord8 s1340 = 127 & s1338;
-  const SWord8 s1341 = s1058 ? s1339 : s1340;
-  const SWord8 s1342 = (s1341 >> 1) | (s1341 << 7);
-  const SWord8 s1343 = 128 | s1342;
-  const SWord8 s1344 = 127 & s1342;
-  const SWord8 s1345 = s1310 ? s1343 : s1344;
-  const SWord8 s1346 = (s1345 >> 1) | (s1345 << 7);
-  const SWord8 s1347 = 128 | s1346;
-  const SWord8 s1348 = 127 & s1346;
-  const SWord8 s1349 = s1332 ? s1347 : s1348;
-  const SWord8 s1350 = s1 + s1345;
-  const SBool  s1351 = s1350 < s1;
-  const SBool  s1352 = s1350 < s1345;
-  const SBool  s1353 = s1351 || s1352;
-  const SWord8 s1354 = (s1350 >> 1) | (s1350 << 7);
-  const SWord8 s1355 = 128 | s1354;
-  const SWord8 s1356 = 127 & s1354;
-  const SWord8 s1357 = s1353 ? s1355 : s1356;
-  const SWord8 s1358 = s1333 ? s1349 : s1357;
-  const SWord8 s1359 = s1 + s1341;
-  const SBool  s1360 = s1359 < s1;
-  const SBool  s1361 = s1359 < s1341;
-  const SBool  s1362 = s1360 || s1361;
-  const SWord8 s1363 = (s1359 >> 1) | (s1359 << 7);
-  const SWord8 s1364 = 128 | s1363;
-  const SWord8 s1365 = 127 & s1363;
-  const SWord8 s1366 = s1362 ? s1364 : s1365;
-  const SWord8 s1367 = (s1366 >> 1) | (s1366 << 7);
-  const SWord8 s1368 = 128 | s1367;
-  const SWord8 s1369 = 127 & s1367;
-  const SWord8 s1370 = s1332 ? s1368 : s1369;
-  const SWord8 s1371 = s1 + s1366;
-  const SBool  s1372 = s1371 < s1;
-  const SBool  s1373 = s1371 < s1366;
-  const SBool  s1374 = s1372 || s1373;
-  const SWord8 s1375 = (s1371 >> 1) | (s1371 << 7);
-  const SWord8 s1376 = 128 | s1375;
-  const SWord8 s1377 = 127 & s1375;
-  const SWord8 s1378 = s1374 ? s1376 : s1377;
-  const SWord8 s1379 = s1333 ? s1370 : s1378;
-  const SWord8 s1380 = s1311 ? s1358 : s1379;
-  const SWord8 s1381 = s1 + s1337;
-  const SBool  s1382 = s1381 < s1;
-  const SBool  s1383 = s1381 < s1337;
-  const SBool  s1384 = s1382 || s1383;
-  const SWord8 s1385 = (s1381 >> 1) | (s1381 << 7);
-  const SWord8 s1386 = 128 | s1385;
-  const SWord8 s1387 = 127 & s1385;
-  const SWord8 s1388 = s1384 ? s1386 : s1387;
-  const SWord8 s1389 = (s1388 >> 1) | (s1388 << 7);
-  const SWord8 s1390 = 128 | s1389;
-  const SWord8 s1391 = 127 & s1389;
-  const SWord8 s1392 = s1310 ? s1390 : s1391;
-  const SWord8 s1393 = (s1392 >> 1) | (s1392 << 7);
-  const SWord8 s1394 = 128 | s1393;
-  const SWord8 s1395 = 127 & s1393;
-  const SWord8 s1396 = s1332 ? s1394 : s1395;
-  const SWord8 s1397 = s1 + s1392;
-  const SBool  s1398 = s1397 < s1;
-  const SBool  s1399 = s1397 < s1392;
-  const SBool  s1400 = s1398 || s1399;
-  const SWord8 s1401 = (s1397 >> 1) | (s1397 << 7);
-  const SWord8 s1402 = 128 | s1401;
-  const SWord8 s1403 = 127 & s1401;
-  const SWord8 s1404 = s1400 ? s1402 : s1403;
-  const SWord8 s1405 = s1333 ? s1396 : s1404;
-  const SWord8 s1406 = s1 + s1388;
-  const SBool  s1407 = s1406 < s1;
-  const SBool  s1408 = s1406 < s1388;
-  const SBool  s1409 = s1407 || s1408;
-  const SWord8 s1410 = (s1406 >> 1) | (s1406 << 7);
-  const SWord8 s1411 = 128 | s1410;
-  const SWord8 s1412 = 127 & s1410;
-  const SWord8 s1413 = s1409 ? s1411 : s1412;
-  const SWord8 s1414 = (s1413 >> 1) | (s1413 << 7);
-  const SWord8 s1415 = 128 | s1414;
-  const SWord8 s1416 = 127 & s1414;
-  const SWord8 s1417 = s1332 ? s1415 : s1416;
-  const SWord8 s1418 = s1 + s1413;
-  const SBool  s1419 = s1418 < s1;
-  const SBool  s1420 = s1418 < s1413;
-  const SBool  s1421 = s1419 || s1420;
-  const SWord8 s1422 = (s1418 >> 1) | (s1418 << 7);
-  const SWord8 s1423 = 128 | s1422;
-  const SWord8 s1424 = 127 & s1422;
-  const SWord8 s1425 = s1421 ? s1423 : s1424;
-  const SWord8 s1426 = s1333 ? s1417 : s1425;
-  const SWord8 s1427 = s1311 ? s1405 : s1426;
-  const SWord8 s1428 = s1059 ? s1380 : s1427;
-  const SWord8 s1429 = s1 + s1318;
-  const SBool  s1430 = (SBool) (s1429 & 1);
-  const SBool  s1431 = false != s1430;
-  const SWord8 s1432 = s1431 ? s1322 : s1323;
-  const SBool  s1433 = (SBool) (s1432 & 1);
-  const SBool  s1434 = false != s1433;
-  const SWord8 s1435 = s1434 ? s1328 : s1329;
-  const SBool  s1436 = (SBool) (s1435 & 1);
-  const SBool  s1437 = false != s1436;
-  const SBool  s1438 = !s1437;
-  const SBool  s1439 = s1429 < s1;
-  const SBool  s1440 = s1429 < s1318;
-  const SBool  s1441 = s1439 || s1440;
-  const SWord8 s1442 = (s1429 >> 1) | (s1429 << 7);
-  const SWord8 s1443 = 128 | s1442;
-  const SWord8 s1444 = 127 & s1442;
-  const SWord8 s1445 = s1441 ? s1443 : s1444;
-  const SWord8 s1446 = (s1445 >> 1) | (s1445 << 7);
-  const SWord8 s1447 = 128 | s1446;
-  const SWord8 s1448 = 127 & s1446;
-  const SWord8 s1449 = s1058 ? s1447 : s1448;
-  const SWord8 s1450 = (s1449 >> 1) | (s1449 << 7);
-  const SWord8 s1451 = 128 | s1450;
-  const SWord8 s1452 = 127 & s1450;
-  const SWord8 s1453 = s1310 ? s1451 : s1452;
-  const SWord8 s1454 = (s1453 >> 1) | (s1453 << 7);
-  const SWord8 s1455 = 128 | s1454;
-  const SWord8 s1456 = 127 & s1454;
-  const SWord8 s1457 = s1437 ? s1455 : s1456;
-  const SWord8 s1458 = s1 + s1453;
-  const SBool  s1459 = s1458 < s1;
-  const SBool  s1460 = s1458 < s1453;
-  const SBool  s1461 = s1459 || s1460;
-  const SWord8 s1462 = (s1458 >> 1) | (s1458 << 7);
-  const SWord8 s1463 = 128 | s1462;
-  const SWord8 s1464 = 127 & s1462;
-  const SWord8 s1465 = s1461 ? s1463 : s1464;
-  const SWord8 s1466 = s1438 ? s1457 : s1465;
-  const SWord8 s1467 = s1 + s1449;
-  const SBool  s1468 = s1467 < s1;
-  const SBool  s1469 = s1467 < s1449;
-  const SBool  s1470 = s1468 || s1469;
-  const SWord8 s1471 = (s1467 >> 1) | (s1467 << 7);
-  const SWord8 s1472 = 128 | s1471;
-  const SWord8 s1473 = 127 & s1471;
-  const SWord8 s1474 = s1470 ? s1472 : s1473;
-  const SWord8 s1475 = (s1474 >> 1) | (s1474 << 7);
-  const SWord8 s1476 = 128 | s1475;
-  const SWord8 s1477 = 127 & s1475;
-  const SWord8 s1478 = s1437 ? s1476 : s1477;
-  const SWord8 s1479 = s1 + s1474;
-  const SBool  s1480 = s1479 < s1;
-  const SBool  s1481 = s1479 < s1474;
-  const SBool  s1482 = s1480 || s1481;
-  const SWord8 s1483 = (s1479 >> 1) | (s1479 << 7);
-  const SWord8 s1484 = 128 | s1483;
-  const SWord8 s1485 = 127 & s1483;
-  const SWord8 s1486 = s1482 ? s1484 : s1485;
-  const SWord8 s1487 = s1438 ? s1478 : s1486;
-  const SWord8 s1488 = s1311 ? s1466 : s1487;
-  const SWord8 s1489 = s1 + s1445;
-  const SBool  s1490 = s1489 < s1;
-  const SBool  s1491 = s1489 < s1445;
-  const SBool  s1492 = s1490 || s1491;
-  const SWord8 s1493 = (s1489 >> 1) | (s1489 << 7);
-  const SWord8 s1494 = 128 | s1493;
-  const SWord8 s1495 = 127 & s1493;
-  const SWord8 s1496 = s1492 ? s1494 : s1495;
-  const SWord8 s1497 = (s1496 >> 1) | (s1496 << 7);
-  const SWord8 s1498 = 128 | s1497;
-  const SWord8 s1499 = 127 & s1497;
-  const SWord8 s1500 = s1310 ? s1498 : s1499;
-  const SWord8 s1501 = (s1500 >> 1) | (s1500 << 7);
-  const SWord8 s1502 = 128 | s1501;
-  const SWord8 s1503 = 127 & s1501;
-  const SWord8 s1504 = s1437 ? s1502 : s1503;
-  const SWord8 s1505 = s1 + s1500;
-  const SBool  s1506 = s1505 < s1;
-  const SBool  s1507 = s1505 < s1500;
-  const SBool  s1508 = s1506 || s1507;
-  const SWord8 s1509 = (s1505 >> 1) | (s1505 << 7);
-  const SWord8 s1510 = 128 | s1509;
-  const SWord8 s1511 = 127 & s1509;
-  const SWord8 s1512 = s1508 ? s1510 : s1511;
-  const SWord8 s1513 = s1438 ? s1504 : s1512;
-  const SWord8 s1514 = s1 + s1496;
-  const SBool  s1515 = s1514 < s1;
-  const SBool  s1516 = s1514 < s1496;
-  const SBool  s1517 = s1515 || s1516;
-  const SWord8 s1518 = (s1514 >> 1) | (s1514 << 7);
-  const SWord8 s1519 = 128 | s1518;
-  const SWord8 s1520 = 127 & s1518;
-  const SWord8 s1521 = s1517 ? s1519 : s1520;
-  const SWord8 s1522 = (s1521 >> 1) | (s1521 << 7);
-  const SWord8 s1523 = 128 | s1522;
-  const SWord8 s1524 = 127 & s1522;
-  const SWord8 s1525 = s1437 ? s1523 : s1524;
-  const SWord8 s1526 = s1 + s1521;
-  const SBool  s1527 = s1526 < s1;
-  const SBool  s1528 = s1526 < s1521;
-  const SBool  s1529 = s1527 || s1528;
-  const SWord8 s1530 = (s1526 >> 1) | (s1526 << 7);
-  const SWord8 s1531 = 128 | s1530;
-  const SWord8 s1532 = 127 & s1530;
-  const SWord8 s1533 = s1529 ? s1531 : s1532;
-  const SWord8 s1534 = s1438 ? s1525 : s1533;
-  const SWord8 s1535 = s1311 ? s1513 : s1534;
-  const SWord8 s1536 = s1059 ? s1488 : s1535;
-  const SWord8 s1537 = s1037 ? s1428 : s1536;
-  const SWord8 s1538 = s21 ? s1301 : s1537;
-  const SWord8 s1539 = s1 + s1044;
-  const SBool  s1540 = (SBool) (s1539 & 1);
-  const SBool  s1541 = false != s1540;
-  const SWord8 s1542 = s1541 ? s1048 : s1049;
-  const SBool  s1543 = (SBool) (s1542 & 1);
-  const SBool  s1544 = false != s1543;
-  const SWord8 s1545 = s1544 ? s1054 : s1055;
-  const SBool  s1546 = (SBool) (s1545 & 1);
-  const SBool  s1547 = false != s1546;
-  const SBool  s1548 = !s1547;
-  const SBool  s1549 = s1539 < s1;
-  const SBool  s1550 = s1539 < s1044;
-  const SBool  s1551 = s1549 || s1550;
-  const SWord8 s1552 = (s1539 >> 1) | (s1539 << 7);
-  const SWord8 s1553 = 128 | s1552;
-  const SWord8 s1554 = 127 & s1552;
-  const SWord8 s1555 = s1551 ? s1553 : s1554;
-  const SBool  s1556 = (SBool) (s1555 & 1);
-  const SBool  s1557 = false != s1556;
-  const SWord8 s1558 = (s1542 >> 1) | (s1542 << 7);
-  const SWord8 s1559 = 128 | s1558;
-  const SWord8 s1560 = 127 & s1558;
-  const SWord8 s1561 = s1557 ? s1559 : s1560;
-  const SBool  s1562 = (SBool) (s1561 & 1);
-  const SBool  s1563 = false != s1562;
-  const SWord8 s1564 = (s1545 >> 1) | (s1545 << 7);
-  const SWord8 s1565 = 128 | s1564;
-  const SWord8 s1566 = 127 & s1564;
-  const SWord8 s1567 = s1563 ? s1565 : s1566;
-  const SBool  s1568 = (SBool) (s1567 & 1);
-  const SBool  s1569 = false != s1568;
-  const SBool  s1570 = !s1569;
-  const SWord8 s1571 = (s1555 >> 1) | (s1555 << 7);
-  const SWord8 s1572 = 128 | s1571;
-  const SWord8 s1573 = 127 & s1571;
-  const SWord8 s1574 = s20 ? s1572 : s1573;
-  const SBool  s1575 = (SBool) (s1574 & 1);
-  const SBool  s1576 = false != s1575;
-  const SWord8 s1577 = (s1561 >> 1) | (s1561 << 7);
-  const SWord8 s1578 = 128 | s1577;
-  const SWord8 s1579 = 127 & s1577;
-  const SWord8 s1580 = s1576 ? s1578 : s1579;
-  const SBool  s1581 = (SBool) (s1580 & 1);
-  const SBool  s1582 = false != s1581;
-  const SWord8 s1583 = (s1567 >> 1) | (s1567 << 7);
-  const SWord8 s1584 = 128 | s1583;
-  const SWord8 s1585 = 127 & s1583;
-  const SWord8 s1586 = s1582 ? s1584 : s1585;
-  const SBool  s1587 = (SBool) (s1586 & 1);
-  const SBool  s1588 = false != s1587;
-  const SBool  s1589 = !s1588;
-  const SWord8 s1590 = (s1574 >> 1) | (s1574 << 7);
-  const SWord8 s1591 = 128 | s1590;
-  const SWord8 s1592 = 127 & s1590;
-  const SWord8 s1593 = s1036 ? s1591 : s1592;
-  const SWord8 s1594 = (s1593 >> 1) | (s1593 << 7);
-  const SWord8 s1595 = 128 | s1594;
-  const SWord8 s1596 = 127 & s1594;
-  const SWord8 s1597 = s1547 ? s1595 : s1596;
-  const SWord8 s1598 = (s1597 >> 1) | (s1597 << 7);
-  const SWord8 s1599 = 128 | s1598;
-  const SWord8 s1600 = 127 & s1598;
-  const SWord8 s1601 = s1569 ? s1599 : s1600;
-  const SWord8 s1602 = (s1601 >> 1) | (s1601 << 7);
-  const SWord8 s1603 = 128 | s1602;
-  const SWord8 s1604 = 127 & s1602;
-  const SWord8 s1605 = s1588 ? s1603 : s1604;
-  const SWord8 s1606 = s1 + s1601;
-  const SBool  s1607 = s1606 < s1;
-  const SBool  s1608 = s1606 < s1601;
-  const SBool  s1609 = s1607 || s1608;
-  const SWord8 s1610 = (s1606 >> 1) | (s1606 << 7);
-  const SWord8 s1611 = 128 | s1610;
-  const SWord8 s1612 = 127 & s1610;
-  const SWord8 s1613 = s1609 ? s1611 : s1612;
-  const SWord8 s1614 = s1589 ? s1605 : s1613;
-  const SWord8 s1615 = s1 + s1597;
-  const SBool  s1616 = s1615 < s1;
-  const SBool  s1617 = s1615 < s1597;
-  const SBool  s1618 = s1616 || s1617;
-  const SWord8 s1619 = (s1615 >> 1) | (s1615 << 7);
-  const SWord8 s1620 = 128 | s1619;
-  const SWord8 s1621 = 127 & s1619;
-  const SWord8 s1622 = s1618 ? s1620 : s1621;
-  const SWord8 s1623 = (s1622 >> 1) | (s1622 << 7);
-  const SWord8 s1624 = 128 | s1623;
-  const SWord8 s1625 = 127 & s1623;
-  const SWord8 s1626 = s1588 ? s1624 : s1625;
-  const SWord8 s1627 = s1 + s1622;
-  const SBool  s1628 = s1627 < s1;
-  const SBool  s1629 = s1627 < s1622;
-  const SBool  s1630 = s1628 || s1629;
-  const SWord8 s1631 = (s1627 >> 1) | (s1627 << 7);
-  const SWord8 s1632 = 128 | s1631;
-  const SWord8 s1633 = 127 & s1631;
-  const SWord8 s1634 = s1630 ? s1632 : s1633;
-  const SWord8 s1635 = s1589 ? s1626 : s1634;
-  const SWord8 s1636 = s1570 ? s1614 : s1635;
-  const SWord8 s1637 = s1 + s1593;
-  const SBool  s1638 = s1637 < s1;
-  const SBool  s1639 = s1637 < s1593;
-  const SBool  s1640 = s1638 || s1639;
-  const SWord8 s1641 = (s1637 >> 1) | (s1637 << 7);
-  const SWord8 s1642 = 128 | s1641;
-  const SWord8 s1643 = 127 & s1641;
-  const SWord8 s1644 = s1640 ? s1642 : s1643;
-  const SWord8 s1645 = (s1644 >> 1) | (s1644 << 7);
-  const SWord8 s1646 = 128 | s1645;
-  const SWord8 s1647 = 127 & s1645;
-  const SWord8 s1648 = s1569 ? s1646 : s1647;
-  const SWord8 s1649 = (s1648 >> 1) | (s1648 << 7);
-  const SWord8 s1650 = 128 | s1649;
-  const SWord8 s1651 = 127 & s1649;
-  const SWord8 s1652 = s1588 ? s1650 : s1651;
-  const SWord8 s1653 = s1 + s1648;
-  const SBool  s1654 = s1653 < s1;
-  const SBool  s1655 = s1653 < s1648;
-  const SBool  s1656 = s1654 || s1655;
-  const SWord8 s1657 = (s1653 >> 1) | (s1653 << 7);
-  const SWord8 s1658 = 128 | s1657;
-  const SWord8 s1659 = 127 & s1657;
-  const SWord8 s1660 = s1656 ? s1658 : s1659;
-  const SWord8 s1661 = s1589 ? s1652 : s1660;
-  const SWord8 s1662 = s1 + s1644;
-  const SBool  s1663 = s1662 < s1;
-  const SBool  s1664 = s1662 < s1644;
-  const SBool  s1665 = s1663 || s1664;
-  const SWord8 s1666 = (s1662 >> 1) | (s1662 << 7);
-  const SWord8 s1667 = 128 | s1666;
-  const SWord8 s1668 = 127 & s1666;
-  const SWord8 s1669 = s1665 ? s1667 : s1668;
-  const SWord8 s1670 = (s1669 >> 1) | (s1669 << 7);
-  const SWord8 s1671 = 128 | s1670;
-  const SWord8 s1672 = 127 & s1670;
-  const SWord8 s1673 = s1588 ? s1671 : s1672;
-  const SWord8 s1674 = s1 + s1669;
-  const SBool  s1675 = s1674 < s1;
-  const SBool  s1676 = s1674 < s1669;
-  const SBool  s1677 = s1675 || s1676;
-  const SWord8 s1678 = (s1674 >> 1) | (s1674 << 7);
-  const SWord8 s1679 = 128 | s1678;
-  const SWord8 s1680 = 127 & s1678;
-  const SWord8 s1681 = s1677 ? s1679 : s1680;
-  const SWord8 s1682 = s1589 ? s1673 : s1681;
-  const SWord8 s1683 = s1570 ? s1661 : s1682;
-  const SWord8 s1684 = s1548 ? s1636 : s1683;
-  const SWord8 s1685 = s1 + s1574;
-  const SBool  s1686 = (SBool) (s1685 & 1);
-  const SBool  s1687 = false != s1686;
-  const SWord8 s1688 = s1687 ? s1578 : s1579;
-  const SBool  s1689 = (SBool) (s1688 & 1);
-  const SBool  s1690 = false != s1689;
-  const SWord8 s1691 = s1690 ? s1584 : s1585;
-  const SBool  s1692 = (SBool) (s1691 & 1);
-  const SBool  s1693 = false != s1692;
-  const SBool  s1694 = !s1693;
-  const SBool  s1695 = s1685 < s1;
-  const SBool  s1696 = s1685 < s1574;
-  const SBool  s1697 = s1695 || s1696;
-  const SWord8 s1698 = (s1685 >> 1) | (s1685 << 7);
-  const SWord8 s1699 = 128 | s1698;
-  const SWord8 s1700 = 127 & s1698;
-  const SWord8 s1701 = s1697 ? s1699 : s1700;
-  const SWord8 s1702 = (s1701 >> 1) | (s1701 << 7);
-  const SWord8 s1703 = 128 | s1702;
-  const SWord8 s1704 = 127 & s1702;
-  const SWord8 s1705 = s1547 ? s1703 : s1704;
-  const SWord8 s1706 = (s1705 >> 1) | (s1705 << 7);
-  const SWord8 s1707 = 128 | s1706;
-  const SWord8 s1708 = 127 & s1706;
-  const SWord8 s1709 = s1569 ? s1707 : s1708;
-  const SWord8 s1710 = (s1709 >> 1) | (s1709 << 7);
-  const SWord8 s1711 = 128 | s1710;
-  const SWord8 s1712 = 127 & s1710;
-  const SWord8 s1713 = s1693 ? s1711 : s1712;
-  const SWord8 s1714 = s1 + s1709;
-  const SBool  s1715 = s1714 < s1;
-  const SBool  s1716 = s1714 < s1709;
-  const SBool  s1717 = s1715 || s1716;
-  const SWord8 s1718 = (s1714 >> 1) | (s1714 << 7);
-  const SWord8 s1719 = 128 | s1718;
-  const SWord8 s1720 = 127 & s1718;
-  const SWord8 s1721 = s1717 ? s1719 : s1720;
-  const SWord8 s1722 = s1694 ? s1713 : s1721;
-  const SWord8 s1723 = s1 + s1705;
-  const SBool  s1724 = s1723 < s1;
-  const SBool  s1725 = s1723 < s1705;
-  const SBool  s1726 = s1724 || s1725;
-  const SWord8 s1727 = (s1723 >> 1) | (s1723 << 7);
-  const SWord8 s1728 = 128 | s1727;
-  const SWord8 s1729 = 127 & s1727;
-  const SWord8 s1730 = s1726 ? s1728 : s1729;
-  const SWord8 s1731 = (s1730 >> 1) | (s1730 << 7);
-  const SWord8 s1732 = 128 | s1731;
-  const SWord8 s1733 = 127 & s1731;
-  const SWord8 s1734 = s1693 ? s1732 : s1733;
-  const SWord8 s1735 = s1 + s1730;
-  const SBool  s1736 = s1735 < s1;
-  const SBool  s1737 = s1735 < s1730;
-  const SBool  s1738 = s1736 || s1737;
-  const SWord8 s1739 = (s1735 >> 1) | (s1735 << 7);
-  const SWord8 s1740 = 128 | s1739;
-  const SWord8 s1741 = 127 & s1739;
-  const SWord8 s1742 = s1738 ? s1740 : s1741;
-  const SWord8 s1743 = s1694 ? s1734 : s1742;
-  const SWord8 s1744 = s1570 ? s1722 : s1743;
-  const SWord8 s1745 = s1 + s1701;
-  const SBool  s1746 = s1745 < s1;
-  const SBool  s1747 = s1745 < s1701;
-  const SBool  s1748 = s1746 || s1747;
-  const SWord8 s1749 = (s1745 >> 1) | (s1745 << 7);
-  const SWord8 s1750 = 128 | s1749;
-  const SWord8 s1751 = 127 & s1749;
-  const SWord8 s1752 = s1748 ? s1750 : s1751;
-  const SWord8 s1753 = (s1752 >> 1) | (s1752 << 7);
-  const SWord8 s1754 = 128 | s1753;
-  const SWord8 s1755 = 127 & s1753;
-  const SWord8 s1756 = s1569 ? s1754 : s1755;
-  const SWord8 s1757 = (s1756 >> 1) | (s1756 << 7);
-  const SWord8 s1758 = 128 | s1757;
-  const SWord8 s1759 = 127 & s1757;
-  const SWord8 s1760 = s1693 ? s1758 : s1759;
-  const SWord8 s1761 = s1 + s1756;
-  const SBool  s1762 = s1761 < s1;
-  const SBool  s1763 = s1761 < s1756;
-  const SBool  s1764 = s1762 || s1763;
-  const SWord8 s1765 = (s1761 >> 1) | (s1761 << 7);
-  const SWord8 s1766 = 128 | s1765;
-  const SWord8 s1767 = 127 & s1765;
-  const SWord8 s1768 = s1764 ? s1766 : s1767;
-  const SWord8 s1769 = s1694 ? s1760 : s1768;
-  const SWord8 s1770 = s1 + s1752;
-  const SBool  s1771 = s1770 < s1;
-  const SBool  s1772 = s1770 < s1752;
-  const SBool  s1773 = s1771 || s1772;
-  const SWord8 s1774 = (s1770 >> 1) | (s1770 << 7);
-  const SWord8 s1775 = 128 | s1774;
-  const SWord8 s1776 = 127 & s1774;
-  const SWord8 s1777 = s1773 ? s1775 : s1776;
-  const SWord8 s1778 = (s1777 >> 1) | (s1777 << 7);
-  const SWord8 s1779 = 128 | s1778;
-  const SWord8 s1780 = 127 & s1778;
-  const SWord8 s1781 = s1693 ? s1779 : s1780;
-  const SWord8 s1782 = s1 + s1777;
-  const SBool  s1783 = s1782 < s1;
-  const SBool  s1784 = s1782 < s1777;
-  const SBool  s1785 = s1783 || s1784;
-  const SWord8 s1786 = (s1782 >> 1) | (s1782 << 7);
-  const SWord8 s1787 = 128 | s1786;
-  const SWord8 s1788 = 127 & s1786;
-  const SWord8 s1789 = s1785 ? s1787 : s1788;
-  const SWord8 s1790 = s1694 ? s1781 : s1789;
-  const SWord8 s1791 = s1570 ? s1769 : s1790;
-  const SWord8 s1792 = s1548 ? s1744 : s1791;
-  const SWord8 s1793 = s1037 ? s1684 : s1792;
-  const SWord8 s1794 = s1 + s1555;
-  const SBool  s1795 = (SBool) (s1794 & 1);
-  const SBool  s1796 = false != s1795;
-  const SWord8 s1797 = s1796 ? s1559 : s1560;
-  const SBool  s1798 = (SBool) (s1797 & 1);
-  const SBool  s1799 = false != s1798;
-  const SWord8 s1800 = s1799 ? s1565 : s1566;
-  const SBool  s1801 = (SBool) (s1800 & 1);
-  const SBool  s1802 = false != s1801;
-  const SBool  s1803 = !s1802;
-  const SBool  s1804 = s1794 < s1;
-  const SBool  s1805 = s1794 < s1555;
-  const SBool  s1806 = s1804 || s1805;
-  const SWord8 s1807 = (s1794 >> 1) | (s1794 << 7);
-  const SWord8 s1808 = 128 | s1807;
-  const SWord8 s1809 = 127 & s1807;
-  const SWord8 s1810 = s1806 ? s1808 : s1809;
-  const SBool  s1811 = (SBool) (s1810 & 1);
-  const SBool  s1812 = false != s1811;
-  const SWord8 s1813 = (s1797 >> 1) | (s1797 << 7);
-  const SWord8 s1814 = 128 | s1813;
-  const SWord8 s1815 = 127 & s1813;
-  const SWord8 s1816 = s1812 ? s1814 : s1815;
-  const SBool  s1817 = (SBool) (s1816 & 1);
-  const SBool  s1818 = false != s1817;
-  const SWord8 s1819 = (s1800 >> 1) | (s1800 << 7);
-  const SWord8 s1820 = 128 | s1819;
-  const SWord8 s1821 = 127 & s1819;
-  const SWord8 s1822 = s1818 ? s1820 : s1821;
-  const SBool  s1823 = (SBool) (s1822 & 1);
-  const SBool  s1824 = false != s1823;
-  const SBool  s1825 = !s1824;
-  const SWord8 s1826 = (s1810 >> 1) | (s1810 << 7);
-  const SWord8 s1827 = 128 | s1826;
-  const SWord8 s1828 = 127 & s1826;
-  const SWord8 s1829 = s1036 ? s1827 : s1828;
-  const SWord8 s1830 = (s1829 >> 1) | (s1829 << 7);
-  const SWord8 s1831 = 128 | s1830;
-  const SWord8 s1832 = 127 & s1830;
-  const SWord8 s1833 = s1547 ? s1831 : s1832;
-  const SWord8 s1834 = (s1833 >> 1) | (s1833 << 7);
-  const SWord8 s1835 = 128 | s1834;
-  const SWord8 s1836 = 127 & s1834;
-  const SWord8 s1837 = s1802 ? s1835 : s1836;
-  const SWord8 s1838 = (s1837 >> 1) | (s1837 << 7);
-  const SWord8 s1839 = 128 | s1838;
-  const SWord8 s1840 = 127 & s1838;
-  const SWord8 s1841 = s1824 ? s1839 : s1840;
-  const SWord8 s1842 = s1 + s1837;
-  const SBool  s1843 = s1842 < s1;
-  const SBool  s1844 = s1842 < s1837;
-  const SBool  s1845 = s1843 || s1844;
-  const SWord8 s1846 = (s1842 >> 1) | (s1842 << 7);
-  const SWord8 s1847 = 128 | s1846;
-  const SWord8 s1848 = 127 & s1846;
-  const SWord8 s1849 = s1845 ? s1847 : s1848;
-  const SWord8 s1850 = s1825 ? s1841 : s1849;
-  const SWord8 s1851 = s1 + s1833;
-  const SBool  s1852 = s1851 < s1;
-  const SBool  s1853 = s1851 < s1833;
-  const SBool  s1854 = s1852 || s1853;
-  const SWord8 s1855 = (s1851 >> 1) | (s1851 << 7);
-  const SWord8 s1856 = 128 | s1855;
-  const SWord8 s1857 = 127 & s1855;
-  const SWord8 s1858 = s1854 ? s1856 : s1857;
-  const SWord8 s1859 = (s1858 >> 1) | (s1858 << 7);
-  const SWord8 s1860 = 128 | s1859;
-  const SWord8 s1861 = 127 & s1859;
-  const SWord8 s1862 = s1824 ? s1860 : s1861;
-  const SWord8 s1863 = s1 + s1858;
-  const SBool  s1864 = s1863 < s1;
-  const SBool  s1865 = s1863 < s1858;
-  const SBool  s1866 = s1864 || s1865;
-  const SWord8 s1867 = (s1863 >> 1) | (s1863 << 7);
-  const SWord8 s1868 = 128 | s1867;
-  const SWord8 s1869 = 127 & s1867;
-  const SWord8 s1870 = s1866 ? s1868 : s1869;
-  const SWord8 s1871 = s1825 ? s1862 : s1870;
-  const SWord8 s1872 = s1803 ? s1850 : s1871;
-  const SWord8 s1873 = s1 + s1829;
-  const SBool  s1874 = s1873 < s1;
-  const SBool  s1875 = s1873 < s1829;
-  const SBool  s1876 = s1874 || s1875;
-  const SWord8 s1877 = (s1873 >> 1) | (s1873 << 7);
-  const SWord8 s1878 = 128 | s1877;
-  const SWord8 s1879 = 127 & s1877;
-  const SWord8 s1880 = s1876 ? s1878 : s1879;
-  const SWord8 s1881 = (s1880 >> 1) | (s1880 << 7);
-  const SWord8 s1882 = 128 | s1881;
-  const SWord8 s1883 = 127 & s1881;
-  const SWord8 s1884 = s1802 ? s1882 : s1883;
-  const SWord8 s1885 = (s1884 >> 1) | (s1884 << 7);
-  const SWord8 s1886 = 128 | s1885;
-  const SWord8 s1887 = 127 & s1885;
-  const SWord8 s1888 = s1824 ? s1886 : s1887;
-  const SWord8 s1889 = s1 + s1884;
-  const SBool  s1890 = s1889 < s1;
-  const SBool  s1891 = s1889 < s1884;
-  const SBool  s1892 = s1890 || s1891;
-  const SWord8 s1893 = (s1889 >> 1) | (s1889 << 7);
-  const SWord8 s1894 = 128 | s1893;
-  const SWord8 s1895 = 127 & s1893;
-  const SWord8 s1896 = s1892 ? s1894 : s1895;
-  const SWord8 s1897 = s1825 ? s1888 : s1896;
-  const SWord8 s1898 = s1 + s1880;
-  const SBool  s1899 = s1898 < s1;
-  const SBool  s1900 = s1898 < s1880;
-  const SBool  s1901 = s1899 || s1900;
-  const SWord8 s1902 = (s1898 >> 1) | (s1898 << 7);
-  const SWord8 s1903 = 128 | s1902;
-  const SWord8 s1904 = 127 & s1902;
-  const SWord8 s1905 = s1901 ? s1903 : s1904;
-  const SWord8 s1906 = (s1905 >> 1) | (s1905 << 7);
-  const SWord8 s1907 = 128 | s1906;
-  const SWord8 s1908 = 127 & s1906;
-  const SWord8 s1909 = s1824 ? s1907 : s1908;
-  const SWord8 s1910 = s1 + s1905;
-  const SBool  s1911 = s1910 < s1;
-  const SBool  s1912 = s1910 < s1905;
-  const SBool  s1913 = s1911 || s1912;
-  const SWord8 s1914 = (s1910 >> 1) | (s1910 << 7);
-  const SWord8 s1915 = 128 | s1914;
-  const SWord8 s1916 = 127 & s1914;
-  const SWord8 s1917 = s1913 ? s1915 : s1916;
-  const SWord8 s1918 = s1825 ? s1909 : s1917;
-  const SWord8 s1919 = s1803 ? s1897 : s1918;
-  const SWord8 s1920 = s1548 ? s1872 : s1919;
-  const SWord8 s1921 = s1 + s1810;
-  const SBool  s1922 = (SBool) (s1921 & 1);
-  const SBool  s1923 = false != s1922;
-  const SWord8 s1924 = s1923 ? s1814 : s1815;
-  const SBool  s1925 = (SBool) (s1924 & 1);
-  const SBool  s1926 = false != s1925;
-  const SWord8 s1927 = s1926 ? s1820 : s1821;
-  const SBool  s1928 = (SBool) (s1927 & 1);
-  const SBool  s1929 = false != s1928;
-  const SBool  s1930 = !s1929;
-  const SBool  s1931 = s1921 < s1;
-  const SBool  s1932 = s1921 < s1810;
-  const SBool  s1933 = s1931 || s1932;
-  const SWord8 s1934 = (s1921 >> 1) | (s1921 << 7);
-  const SWord8 s1935 = 128 | s1934;
-  const SWord8 s1936 = 127 & s1934;
-  const SWord8 s1937 = s1933 ? s1935 : s1936;
-  const SWord8 s1938 = (s1937 >> 1) | (s1937 << 7);
-  const SWord8 s1939 = 128 | s1938;
-  const SWord8 s1940 = 127 & s1938;
-  const SWord8 s1941 = s1547 ? s1939 : s1940;
-  const SWord8 s1942 = (s1941 >> 1) | (s1941 << 7);
-  const SWord8 s1943 = 128 | s1942;
-  const SWord8 s1944 = 127 & s1942;
-  const SWord8 s1945 = s1802 ? s1943 : s1944;
-  const SWord8 s1946 = (s1945 >> 1) | (s1945 << 7);
-  const SWord8 s1947 = 128 | s1946;
-  const SWord8 s1948 = 127 & s1946;
-  const SWord8 s1949 = s1929 ? s1947 : s1948;
-  const SWord8 s1950 = s1 + s1945;
-  const SBool  s1951 = s1950 < s1;
-  const SBool  s1952 = s1950 < s1945;
-  const SBool  s1953 = s1951 || s1952;
-  const SWord8 s1954 = (s1950 >> 1) | (s1950 << 7);
-  const SWord8 s1955 = 128 | s1954;
-  const SWord8 s1956 = 127 & s1954;
-  const SWord8 s1957 = s1953 ? s1955 : s1956;
-  const SWord8 s1958 = s1930 ? s1949 : s1957;
-  const SWord8 s1959 = s1 + s1941;
-  const SBool  s1960 = s1959 < s1;
-  const SBool  s1961 = s1959 < s1941;
-  const SBool  s1962 = s1960 || s1961;
-  const SWord8 s1963 = (s1959 >> 1) | (s1959 << 7);
-  const SWord8 s1964 = 128 | s1963;
-  const SWord8 s1965 = 127 & s1963;
-  const SWord8 s1966 = s1962 ? s1964 : s1965;
-  const SWord8 s1967 = (s1966 >> 1) | (s1966 << 7);
-  const SWord8 s1968 = 128 | s1967;
-  const SWord8 s1969 = 127 & s1967;
-  const SWord8 s1970 = s1929 ? s1968 : s1969;
-  const SWord8 s1971 = s1 + s1966;
-  const SBool  s1972 = s1971 < s1;
-  const SBool  s1973 = s1971 < s1966;
-  const SBool  s1974 = s1972 || s1973;
-  const SWord8 s1975 = (s1971 >> 1) | (s1971 << 7);
-  const SWord8 s1976 = 128 | s1975;
-  const SWord8 s1977 = 127 & s1975;
-  const SWord8 s1978 = s1974 ? s1976 : s1977;
-  const SWord8 s1979 = s1930 ? s1970 : s1978;
-  const SWord8 s1980 = s1803 ? s1958 : s1979;
-  const SWord8 s1981 = s1 + s1937;
-  const SBool  s1982 = s1981 < s1;
-  const SBool  s1983 = s1981 < s1937;
-  const SBool  s1984 = s1982 || s1983;
-  const SWord8 s1985 = (s1981 >> 1) | (s1981 << 7);
-  const SWord8 s1986 = 128 | s1985;
-  const SWord8 s1987 = 127 & s1985;
-  const SWord8 s1988 = s1984 ? s1986 : s1987;
-  const SWord8 s1989 = (s1988 >> 1) | (s1988 << 7);
-  const SWord8 s1990 = 128 | s1989;
-  const SWord8 s1991 = 127 & s1989;
-  const SWord8 s1992 = s1802 ? s1990 : s1991;
-  const SWord8 s1993 = (s1992 >> 1) | (s1992 << 7);
-  const SWord8 s1994 = 128 | s1993;
-  const SWord8 s1995 = 127 & s1993;
-  const SWord8 s1996 = s1929 ? s1994 : s1995;
-  const SWord8 s1997 = s1 + s1992;
-  const SBool  s1998 = s1997 < s1;
-  const SBool  s1999 = s1997 < s1992;
-  const SBool  s2000 = s1998 || s1999;
-  const SWord8 s2001 = (s1997 >> 1) | (s1997 << 7);
-  const SWord8 s2002 = 128 | s2001;
-  const SWord8 s2003 = 127 & s2001;
-  const SWord8 s2004 = s2000 ? s2002 : s2003;
-  const SWord8 s2005 = s1930 ? s1996 : s2004;
-  const SWord8 s2006 = s1 + s1988;
-  const SBool  s2007 = s2006 < s1;
-  const SBool  s2008 = s2006 < s1988;
-  const SBool  s2009 = s2007 || s2008;
-  const SWord8 s2010 = (s2006 >> 1) | (s2006 << 7);
-  const SWord8 s2011 = 128 | s2010;
-  const SWord8 s2012 = 127 & s2010;
-  const SWord8 s2013 = s2009 ? s2011 : s2012;
-  const SWord8 s2014 = (s2013 >> 1) | (s2013 << 7);
-  const SWord8 s2015 = 128 | s2014;
-  const SWord8 s2016 = 127 & s2014;
-  const SWord8 s2017 = s1929 ? s2015 : s2016;
-  const SWord8 s2018 = s1 + s2013;
-  const SBool  s2019 = s2018 < s1;
-  const SBool  s2020 = s2018 < s2013;
-  const SBool  s2021 = s2019 || s2020;
-  const SWord8 s2022 = (s2018 >> 1) | (s2018 << 7);
-  const SWord8 s2023 = 128 | s2022;
-  const SWord8 s2024 = 127 & s2022;
-  const SWord8 s2025 = s2021 ? s2023 : s2024;
-  const SWord8 s2026 = s1930 ? s2017 : s2025;
-  const SWord8 s2027 = s1803 ? s2005 : s2026;
-  const SWord8 s2028 = s1548 ? s1980 : s2027;
-  const SWord8 s2029 = s1037 ? s1920 : s2028;
-  const SWord8 s2030 = s21 ? s1793 : s2029;
-  const SWord8 s2031 = s16 ? s1538 : s2030;
-  const SWord8 s2032 = s11 ? s1027 : s2031;
-  const SBool  s2033 = (SBool) (s1 & 1);
-  const SBool  s2034 = false != s2033;
-  const SWord8 s2035 = s2034 ? 128 : 0;
-  const SBool  s2036 = (SBool) (s2035 & 1);
-  const SBool  s2037 = false != s2036;
-  const SWord8 s2038 = s17 | 128;
-  const SWord8 s2039 = s2037 ? s2038 : s18;
-  const SBool  s2040 = (SBool) (s2039 & 1);
-  const SBool  s2041 = false != s2040;
-  const SBool  s2042 = !s2041;
-  const SWord8 s2043 = (s1 >> 1) | (s1 << 7);
-  const SWord8 s2044 = 127 & s2043;
-  const SBool  s2045 = (SBool) (s2044 & 1);
-  const SBool  s2046 = false != s2045;
-  const SWord8 s2047 = (s2035 >> 1) | (s2035 << 7);
-  const SWord8 s2048 = 128 | s2047;
-  const SWord8 s2049 = 127 & s2047;
-  const SWord8 s2050 = s2046 ? s2048 : s2049;
-  const SBool  s2051 = (SBool) (s2050 & 1);
-  const SBool  s2052 = false != s2051;
-  const SWord8 s2053 = (s2039 >> 1) | (s2039 << 7);
-  const SWord8 s2054 = 128 | s2053;
-  const SWord8 s2055 = 127 & s2053;
-  const SWord8 s2056 = s2052 ? s2054 : s2055;
-  const SBool  s2057 = (SBool) (s2056 & 1);
-  const SBool  s2058 = false != s2057;
-  const SBool  s2059 = !s2058;
-  const SWord8 s2060 = (s2044 >> 1) | (s2044 << 7);
-  const SWord8 s2061 = 128 | s2060;
-  const SWord8 s2062 = 127 & s2060;
-  const SWord8 s2063 = s10 ? s2061 : s2062;
-  const SBool  s2064 = (SBool) (s2063 & 1);
-  const SBool  s2065 = false != s2064;
-  const SWord8 s2066 = (s2050 >> 1) | (s2050 << 7);
-  const SWord8 s2067 = 128 | s2066;
-  const SWord8 s2068 = 127 & s2066;
-  const SWord8 s2069 = s2065 ? s2067 : s2068;
-  const SBool  s2070 = (SBool) (s2069 & 1);
-  const SBool  s2071 = false != s2070;
-  const SWord8 s2072 = (s2056 >> 1) | (s2056 << 7);
-  const SWord8 s2073 = 128 | s2072;
-  const SWord8 s2074 = 127 & s2072;
-  const SWord8 s2075 = s2071 ? s2073 : s2074;
-  const SBool  s2076 = (SBool) (s2075 & 1);
-  const SBool  s2077 = false != s2076;
-  const SBool  s2078 = !s2077;
-  const SWord8 s2079 = (s2063 >> 1) | (s2063 << 7);
-  const SWord8 s2080 = 128 | s2079;
-  const SWord8 s2081 = 127 & s2079;
-  const SWord8 s2082 = s15 ? s2080 : s2081;
-  const SBool  s2083 = (SBool) (s2082 & 1);
-  const SBool  s2084 = false != s2083;
-  const SWord8 s2085 = (s2069 >> 1) | (s2069 << 7);
-  const SWord8 s2086 = 128 | s2085;
-  const SWord8 s2087 = 127 & s2085;
-  const SWord8 s2088 = s2084 ? s2086 : s2087;
-  const SBool  s2089 = (SBool) (s2088 & 1);
-  const SBool  s2090 = false != s2089;
-  const SWord8 s2091 = (s2075 >> 1) | (s2075 << 7);
-  const SWord8 s2092 = 128 | s2091;
-  const SWord8 s2093 = 127 & s2091;
-  const SWord8 s2094 = s2090 ? s2092 : s2093;
-  const SBool  s2095 = (SBool) (s2094 & 1);
-  const SBool  s2096 = false != s2095;
-  const SBool  s2097 = !s2096;
-  const SWord8 s2098 = (s2082 >> 1) | (s2082 << 7);
-  const SWord8 s2099 = 128 | s2098;
-  const SWord8 s2100 = 127 & s2098;
-  const SWord8 s2101 = s2041 ? s2099 : s2100;
-  const SBool  s2102 = (SBool) (s2101 & 1);
-  const SBool  s2103 = false != s2102;
-  const SWord8 s2104 = (s2088 >> 1) | (s2088 << 7);
-  const SWord8 s2105 = 128 | s2104;
-  const SWord8 s2106 = 127 & s2104;
-  const SWord8 s2107 = s2103 ? s2105 : s2106;
-  const SBool  s2108 = (SBool) (s2107 & 1);
-  const SBool  s2109 = false != s2108;
-  const SWord8 s2110 = (s2094 >> 1) | (s2094 << 7);
-  const SWord8 s2111 = 128 | s2110;
-  const SWord8 s2112 = 127 & s2110;
-  const SWord8 s2113 = s2109 ? s2111 : s2112;
-  const SBool  s2114 = (SBool) (s2113 & 1);
-  const SBool  s2115 = false != s2114;
-  const SBool  s2116 = !s2115;
-  const SWord8 s2117 = (s2101 >> 1) | (s2101 << 7);
-  const SWord8 s2118 = 128 | s2117;
-  const SWord8 s2119 = 127 & s2117;
-  const SWord8 s2120 = s2058 ? s2118 : s2119;
-  const SWord8 s2121 = (s2120 >> 1) | (s2120 << 7);
-  const SWord8 s2122 = 128 | s2121;
-  const SWord8 s2123 = 127 & s2121;
-  const SWord8 s2124 = s2077 ? s2122 : s2123;
-  const SWord8 s2125 = (s2124 >> 1) | (s2124 << 7);
-  const SWord8 s2126 = 128 | s2125;
-  const SWord8 s2127 = 127 & s2125;
-  const SWord8 s2128 = s2096 ? s2126 : s2127;
-  const SWord8 s2129 = (s2128 >> 1) | (s2128 << 7);
-  const SWord8 s2130 = 128 | s2129;
-  const SWord8 s2131 = 127 & s2129;
-  const SWord8 s2132 = s2115 ? s2130 : s2131;
-  const SWord8 s2133 = s1 + s2128;
-  const SBool  s2134 = s2133 < s1;
-  const SBool  s2135 = s2133 < s2128;
-  const SBool  s2136 = s2134 || s2135;
-  const SWord8 s2137 = (s2133 >> 1) | (s2133 << 7);
-  const SWord8 s2138 = 128 | s2137;
-  const SWord8 s2139 = 127 & s2137;
-  const SWord8 s2140 = s2136 ? s2138 : s2139;
-  const SWord8 s2141 = s2116 ? s2132 : s2140;
-  const SWord8 s2142 = s1 + s2124;
-  const SBool  s2143 = s2142 < s1;
-  const SBool  s2144 = s2142 < s2124;
-  const SBool  s2145 = s2143 || s2144;
-  const SWord8 s2146 = (s2142 >> 1) | (s2142 << 7);
-  const SWord8 s2147 = 128 | s2146;
-  const SWord8 s2148 = 127 & s2146;
-  const SWord8 s2149 = s2145 ? s2147 : s2148;
-  const SWord8 s2150 = (s2149 >> 1) | (s2149 << 7);
-  const SWord8 s2151 = 128 | s2150;
-  const SWord8 s2152 = 127 & s2150;
-  const SWord8 s2153 = s2115 ? s2151 : s2152;
-  const SWord8 s2154 = s1 + s2149;
-  const SBool  s2155 = s2154 < s1;
-  const SBool  s2156 = s2154 < s2149;
-  const SBool  s2157 = s2155 || s2156;
-  const SWord8 s2158 = (s2154 >> 1) | (s2154 << 7);
-  const SWord8 s2159 = 128 | s2158;
-  const SWord8 s2160 = 127 & s2158;
-  const SWord8 s2161 = s2157 ? s2159 : s2160;
-  const SWord8 s2162 = s2116 ? s2153 : s2161;
-  const SWord8 s2163 = s2097 ? s2141 : s2162;
-  const SWord8 s2164 = s1 + s2120;
-  const SBool  s2165 = s2164 < s1;
-  const SBool  s2166 = s2164 < s2120;
-  const SBool  s2167 = s2165 || s2166;
-  const SWord8 s2168 = (s2164 >> 1) | (s2164 << 7);
-  const SWord8 s2169 = 128 | s2168;
-  const SWord8 s2170 = 127 & s2168;
-  const SWord8 s2171 = s2167 ? s2169 : s2170;
-  const SWord8 s2172 = (s2171 >> 1) | (s2171 << 7);
-  const SWord8 s2173 = 128 | s2172;
-  const SWord8 s2174 = 127 & s2172;
-  const SWord8 s2175 = s2096 ? s2173 : s2174;
-  const SWord8 s2176 = (s2175 >> 1) | (s2175 << 7);
-  const SWord8 s2177 = 128 | s2176;
-  const SWord8 s2178 = 127 & s2176;
-  const SWord8 s2179 = s2115 ? s2177 : s2178;
-  const SWord8 s2180 = s1 + s2175;
-  const SBool  s2181 = s2180 < s1;
-  const SBool  s2182 = s2180 < s2175;
-  const SBool  s2183 = s2181 || s2182;
-  const SWord8 s2184 = (s2180 >> 1) | (s2180 << 7);
-  const SWord8 s2185 = 128 | s2184;
-  const SWord8 s2186 = 127 & s2184;
-  const SWord8 s2187 = s2183 ? s2185 : s2186;
-  const SWord8 s2188 = s2116 ? s2179 : s2187;
-  const SWord8 s2189 = s1 + s2171;
-  const SBool  s2190 = s2189 < s1;
-  const SBool  s2191 = s2189 < s2171;
-  const SBool  s2192 = s2190 || s2191;
-  const SWord8 s2193 = (s2189 >> 1) | (s2189 << 7);
-  const SWord8 s2194 = 128 | s2193;
-  const SWord8 s2195 = 127 & s2193;
-  const SWord8 s2196 = s2192 ? s2194 : s2195;
-  const SWord8 s2197 = (s2196 >> 1) | (s2196 << 7);
-  const SWord8 s2198 = 128 | s2197;
-  const SWord8 s2199 = 127 & s2197;
-  const SWord8 s2200 = s2115 ? s2198 : s2199;
-  const SWord8 s2201 = s1 + s2196;
-  const SBool  s2202 = s2201 < s1;
-  const SBool  s2203 = s2201 < s2196;
-  const SBool  s2204 = s2202 || s2203;
-  const SWord8 s2205 = (s2201 >> 1) | (s2201 << 7);
-  const SWord8 s2206 = 128 | s2205;
-  const SWord8 s2207 = 127 & s2205;
-  const SWord8 s2208 = s2204 ? s2206 : s2207;
-  const SWord8 s2209 = s2116 ? s2200 : s2208;
-  const SWord8 s2210 = s2097 ? s2188 : s2209;
-  const SWord8 s2211 = s2078 ? s2163 : s2210;
-  const SWord8 s2212 = s1 + s2101;
-  const SBool  s2213 = (SBool) (s2212 & 1);
-  const SBool  s2214 = false != s2213;
-  const SWord8 s2215 = s2214 ? s2105 : s2106;
-  const SBool  s2216 = (SBool) (s2215 & 1);
-  const SBool  s2217 = false != s2216;
-  const SWord8 s2218 = s2217 ? s2111 : s2112;
-  const SBool  s2219 = (SBool) (s2218 & 1);
-  const SBool  s2220 = false != s2219;
-  const SBool  s2221 = !s2220;
-  const SBool  s2222 = s2212 < s1;
-  const SBool  s2223 = s2212 < s2101;
-  const SBool  s2224 = s2222 || s2223;
-  const SWord8 s2225 = (s2212 >> 1) | (s2212 << 7);
-  const SWord8 s2226 = 128 | s2225;
-  const SWord8 s2227 = 127 & s2225;
-  const SWord8 s2228 = s2224 ? s2226 : s2227;
-  const SWord8 s2229 = (s2228 >> 1) | (s2228 << 7);
-  const SWord8 s2230 = 128 | s2229;
-  const SWord8 s2231 = 127 & s2229;
-  const SWord8 s2232 = s2077 ? s2230 : s2231;
-  const SWord8 s2233 = (s2232 >> 1) | (s2232 << 7);
-  const SWord8 s2234 = 128 | s2233;
-  const SWord8 s2235 = 127 & s2233;
-  const SWord8 s2236 = s2096 ? s2234 : s2235;
-  const SWord8 s2237 = (s2236 >> 1) | (s2236 << 7);
-  const SWord8 s2238 = 128 | s2237;
-  const SWord8 s2239 = 127 & s2237;
-  const SWord8 s2240 = s2220 ? s2238 : s2239;
-  const SWord8 s2241 = s1 + s2236;
-  const SBool  s2242 = s2241 < s1;
-  const SBool  s2243 = s2241 < s2236;
-  const SBool  s2244 = s2242 || s2243;
-  const SWord8 s2245 = (s2241 >> 1) | (s2241 << 7);
-  const SWord8 s2246 = 128 | s2245;
-  const SWord8 s2247 = 127 & s2245;
-  const SWord8 s2248 = s2244 ? s2246 : s2247;
-  const SWord8 s2249 = s2221 ? s2240 : s2248;
-  const SWord8 s2250 = s1 + s2232;
-  const SBool  s2251 = s2250 < s1;
-  const SBool  s2252 = s2250 < s2232;
-  const SBool  s2253 = s2251 || s2252;
-  const SWord8 s2254 = (s2250 >> 1) | (s2250 << 7);
-  const SWord8 s2255 = 128 | s2254;
-  const SWord8 s2256 = 127 & s2254;
-  const SWord8 s2257 = s2253 ? s2255 : s2256;
-  const SWord8 s2258 = (s2257 >> 1) | (s2257 << 7);
-  const SWord8 s2259 = 128 | s2258;
-  const SWord8 s2260 = 127 & s2258;
-  const SWord8 s2261 = s2220 ? s2259 : s2260;
-  const SWord8 s2262 = s1 + s2257;
-  const SBool  s2263 = s2262 < s1;
-  const SBool  s2264 = s2262 < s2257;
-  const SBool  s2265 = s2263 || s2264;
-  const SWord8 s2266 = (s2262 >> 1) | (s2262 << 7);
-  const SWord8 s2267 = 128 | s2266;
-  const SWord8 s2268 = 127 & s2266;
-  const SWord8 s2269 = s2265 ? s2267 : s2268;
-  const SWord8 s2270 = s2221 ? s2261 : s2269;
-  const SWord8 s2271 = s2097 ? s2249 : s2270;
-  const SWord8 s2272 = s1 + s2228;
-  const SBool  s2273 = s2272 < s1;
-  const SBool  s2274 = s2272 < s2228;
-  const SBool  s2275 = s2273 || s2274;
-  const SWord8 s2276 = (s2272 >> 1) | (s2272 << 7);
-  const SWord8 s2277 = 128 | s2276;
-  const SWord8 s2278 = 127 & s2276;
-  const SWord8 s2279 = s2275 ? s2277 : s2278;
-  const SWord8 s2280 = (s2279 >> 1) | (s2279 << 7);
-  const SWord8 s2281 = 128 | s2280;
-  const SWord8 s2282 = 127 & s2280;
-  const SWord8 s2283 = s2096 ? s2281 : s2282;
-  const SWord8 s2284 = (s2283 >> 1) | (s2283 << 7);
-  const SWord8 s2285 = 128 | s2284;
-  const SWord8 s2286 = 127 & s2284;
-  const SWord8 s2287 = s2220 ? s2285 : s2286;
-  const SWord8 s2288 = s1 + s2283;
-  const SBool  s2289 = s2288 < s1;
-  const SBool  s2290 = s2288 < s2283;
-  const SBool  s2291 = s2289 || s2290;
-  const SWord8 s2292 = (s2288 >> 1) | (s2288 << 7);
-  const SWord8 s2293 = 128 | s2292;
-  const SWord8 s2294 = 127 & s2292;
-  const SWord8 s2295 = s2291 ? s2293 : s2294;
-  const SWord8 s2296 = s2221 ? s2287 : s2295;
-  const SWord8 s2297 = s1 + s2279;
-  const SBool  s2298 = s2297 < s1;
-  const SBool  s2299 = s2297 < s2279;
-  const SBool  s2300 = s2298 || s2299;
-  const SWord8 s2301 = (s2297 >> 1) | (s2297 << 7);
-  const SWord8 s2302 = 128 | s2301;
-  const SWord8 s2303 = 127 & s2301;
-  const SWord8 s2304 = s2300 ? s2302 : s2303;
-  const SWord8 s2305 = (s2304 >> 1) | (s2304 << 7);
-  const SWord8 s2306 = 128 | s2305;
-  const SWord8 s2307 = 127 & s2305;
-  const SWord8 s2308 = s2220 ? s2306 : s2307;
-  const SWord8 s2309 = s1 + s2304;
-  const SBool  s2310 = s2309 < s1;
-  const SBool  s2311 = s2309 < s2304;
-  const SBool  s2312 = s2310 || s2311;
-  const SWord8 s2313 = (s2309 >> 1) | (s2309 << 7);
-  const SWord8 s2314 = 128 | s2313;
-  const SWord8 s2315 = 127 & s2313;
-  const SWord8 s2316 = s2312 ? s2314 : s2315;
-  const SWord8 s2317 = s2221 ? s2308 : s2316;
-  const SWord8 s2318 = s2097 ? s2296 : s2317;
-  const SWord8 s2319 = s2078 ? s2271 : s2318;
-  const SWord8 s2320 = s2059 ? s2211 : s2319;
-  const SWord8 s2321 = s1 + s2082;
-  const SBool  s2322 = (SBool) (s2321 & 1);
-  const SBool  s2323 = false != s2322;
-  const SWord8 s2324 = s2323 ? s2086 : s2087;
-  const SBool  s2325 = (SBool) (s2324 & 1);
-  const SBool  s2326 = false != s2325;
-  const SWord8 s2327 = s2326 ? s2092 : s2093;
-  const SBool  s2328 = (SBool) (s2327 & 1);
-  const SBool  s2329 = false != s2328;
-  const SBool  s2330 = !s2329;
-  const SBool  s2331 = s2321 < s1;
-  const SBool  s2332 = s2321 < s2082;
-  const SBool  s2333 = s2331 || s2332;
-  const SWord8 s2334 = (s2321 >> 1) | (s2321 << 7);
-  const SWord8 s2335 = 128 | s2334;
-  const SWord8 s2336 = 127 & s2334;
-  const SWord8 s2337 = s2333 ? s2335 : s2336;
-  const SBool  s2338 = (SBool) (s2337 & 1);
-  const SBool  s2339 = false != s2338;
-  const SWord8 s2340 = (s2324 >> 1) | (s2324 << 7);
-  const SWord8 s2341 = 128 | s2340;
-  const SWord8 s2342 = 127 & s2340;
-  const SWord8 s2343 = s2339 ? s2341 : s2342;
-  const SBool  s2344 = (SBool) (s2343 & 1);
-  const SBool  s2345 = false != s2344;
-  const SWord8 s2346 = (s2327 >> 1) | (s2327 << 7);
-  const SWord8 s2347 = 128 | s2346;
-  const SWord8 s2348 = 127 & s2346;
-  const SWord8 s2349 = s2345 ? s2347 : s2348;
-  const SBool  s2350 = (SBool) (s2349 & 1);
-  const SBool  s2351 = false != s2350;
-  const SBool  s2352 = !s2351;
-  const SWord8 s2353 = (s2337 >> 1) | (s2337 << 7);
-  const SWord8 s2354 = 128 | s2353;
-  const SWord8 s2355 = 127 & s2353;
-  const SWord8 s2356 = s2058 ? s2354 : s2355;
-  const SWord8 s2357 = (s2356 >> 1) | (s2356 << 7);
-  const SWord8 s2358 = 128 | s2357;
-  const SWord8 s2359 = 127 & s2357;
-  const SWord8 s2360 = s2077 ? s2358 : s2359;
-  const SWord8 s2361 = (s2360 >> 1) | (s2360 << 7);
-  const SWord8 s2362 = 128 | s2361;
-  const SWord8 s2363 = 127 & s2361;
-  const SWord8 s2364 = s2329 ? s2362 : s2363;
-  const SWord8 s2365 = (s2364 >> 1) | (s2364 << 7);
-  const SWord8 s2366 = 128 | s2365;
-  const SWord8 s2367 = 127 & s2365;
-  const SWord8 s2368 = s2351 ? s2366 : s2367;
-  const SWord8 s2369 = s1 + s2364;
-  const SBool  s2370 = s2369 < s1;
-  const SBool  s2371 = s2369 < s2364;
-  const SBool  s2372 = s2370 || s2371;
-  const SWord8 s2373 = (s2369 >> 1) | (s2369 << 7);
-  const SWord8 s2374 = 128 | s2373;
-  const SWord8 s2375 = 127 & s2373;
-  const SWord8 s2376 = s2372 ? s2374 : s2375;
-  const SWord8 s2377 = s2352 ? s2368 : s2376;
-  const SWord8 s2378 = s1 + s2360;
-  const SBool  s2379 = s2378 < s1;
-  const SBool  s2380 = s2378 < s2360;
-  const SBool  s2381 = s2379 || s2380;
-  const SWord8 s2382 = (s2378 >> 1) | (s2378 << 7);
-  const SWord8 s2383 = 128 | s2382;
-  const SWord8 s2384 = 127 & s2382;
-  const SWord8 s2385 = s2381 ? s2383 : s2384;
-  const SWord8 s2386 = (s2385 >> 1) | (s2385 << 7);
-  const SWord8 s2387 = 128 | s2386;
-  const SWord8 s2388 = 127 & s2386;
-  const SWord8 s2389 = s2351 ? s2387 : s2388;
-  const SWord8 s2390 = s1 + s2385;
-  const SBool  s2391 = s2390 < s1;
-  const SBool  s2392 = s2390 < s2385;
-  const SBool  s2393 = s2391 || s2392;
-  const SWord8 s2394 = (s2390 >> 1) | (s2390 << 7);
-  const SWord8 s2395 = 128 | s2394;
-  const SWord8 s2396 = 127 & s2394;
-  const SWord8 s2397 = s2393 ? s2395 : s2396;
-  const SWord8 s2398 = s2352 ? s2389 : s2397;
-  const SWord8 s2399 = s2330 ? s2377 : s2398;
-  const SWord8 s2400 = s1 + s2356;
-  const SBool  s2401 = s2400 < s1;
-  const SBool  s2402 = s2400 < s2356;
-  const SBool  s2403 = s2401 || s2402;
-  const SWord8 s2404 = (s2400 >> 1) | (s2400 << 7);
-  const SWord8 s2405 = 128 | s2404;
-  const SWord8 s2406 = 127 & s2404;
-  const SWord8 s2407 = s2403 ? s2405 : s2406;
-  const SWord8 s2408 = (s2407 >> 1) | (s2407 << 7);
-  const SWord8 s2409 = 128 | s2408;
-  const SWord8 s2410 = 127 & s2408;
-  const SWord8 s2411 = s2329 ? s2409 : s2410;
-  const SWord8 s2412 = (s2411 >> 1) | (s2411 << 7);
-  const SWord8 s2413 = 128 | s2412;
-  const SWord8 s2414 = 127 & s2412;
-  const SWord8 s2415 = s2351 ? s2413 : s2414;
-  const SWord8 s2416 = s1 + s2411;
-  const SBool  s2417 = s2416 < s1;
-  const SBool  s2418 = s2416 < s2411;
-  const SBool  s2419 = s2417 || s2418;
-  const SWord8 s2420 = (s2416 >> 1) | (s2416 << 7);
-  const SWord8 s2421 = 128 | s2420;
-  const SWord8 s2422 = 127 & s2420;
-  const SWord8 s2423 = s2419 ? s2421 : s2422;
-  const SWord8 s2424 = s2352 ? s2415 : s2423;
-  const SWord8 s2425 = s1 + s2407;
-  const SBool  s2426 = s2425 < s1;
-  const SBool  s2427 = s2425 < s2407;
-  const SBool  s2428 = s2426 || s2427;
-  const SWord8 s2429 = (s2425 >> 1) | (s2425 << 7);
-  const SWord8 s2430 = 128 | s2429;
-  const SWord8 s2431 = 127 & s2429;
-  const SWord8 s2432 = s2428 ? s2430 : s2431;
-  const SWord8 s2433 = (s2432 >> 1) | (s2432 << 7);
-  const SWord8 s2434 = 128 | s2433;
-  const SWord8 s2435 = 127 & s2433;
-  const SWord8 s2436 = s2351 ? s2434 : s2435;
-  const SWord8 s2437 = s1 + s2432;
-  const SBool  s2438 = s2437 < s1;
-  const SBool  s2439 = s2437 < s2432;
-  const SBool  s2440 = s2438 || s2439;
-  const SWord8 s2441 = (s2437 >> 1) | (s2437 << 7);
-  const SWord8 s2442 = 128 | s2441;
-  const SWord8 s2443 = 127 & s2441;
-  const SWord8 s2444 = s2440 ? s2442 : s2443;
-  const SWord8 s2445 = s2352 ? s2436 : s2444;
-  const SWord8 s2446 = s2330 ? s2424 : s2445;
-  const SWord8 s2447 = s2078 ? s2399 : s2446;
-  const SWord8 s2448 = s1 + s2337;
-  const SBool  s2449 = (SBool) (s2448 & 1);
-  const SBool  s2450 = false != s2449;
-  const SWord8 s2451 = s2450 ? s2341 : s2342;
-  const SBool  s2452 = (SBool) (s2451 & 1);
-  const SBool  s2453 = false != s2452;
-  const SWord8 s2454 = s2453 ? s2347 : s2348;
-  const SBool  s2455 = (SBool) (s2454 & 1);
-  const SBool  s2456 = false != s2455;
-  const SBool  s2457 = !s2456;
-  const SBool  s2458 = s2448 < s1;
-  const SBool  s2459 = s2448 < s2337;
-  const SBool  s2460 = s2458 || s2459;
-  const SWord8 s2461 = (s2448 >> 1) | (s2448 << 7);
-  const SWord8 s2462 = 128 | s2461;
-  const SWord8 s2463 = 127 & s2461;
-  const SWord8 s2464 = s2460 ? s2462 : s2463;
-  const SWord8 s2465 = (s2464 >> 1) | (s2464 << 7);
-  const SWord8 s2466 = 128 | s2465;
-  const SWord8 s2467 = 127 & s2465;
-  const SWord8 s2468 = s2077 ? s2466 : s2467;
-  const SWord8 s2469 = (s2468 >> 1) | (s2468 << 7);
-  const SWord8 s2470 = 128 | s2469;
-  const SWord8 s2471 = 127 & s2469;
-  const SWord8 s2472 = s2329 ? s2470 : s2471;
-  const SWord8 s2473 = (s2472 >> 1) | (s2472 << 7);
-  const SWord8 s2474 = 128 | s2473;
-  const SWord8 s2475 = 127 & s2473;
-  const SWord8 s2476 = s2456 ? s2474 : s2475;
-  const SWord8 s2477 = s1 + s2472;
-  const SBool  s2478 = s2477 < s1;
-  const SBool  s2479 = s2477 < s2472;
-  const SBool  s2480 = s2478 || s2479;
-  const SWord8 s2481 = (s2477 >> 1) | (s2477 << 7);
-  const SWord8 s2482 = 128 | s2481;
-  const SWord8 s2483 = 127 & s2481;
-  const SWord8 s2484 = s2480 ? s2482 : s2483;
-  const SWord8 s2485 = s2457 ? s2476 : s2484;
-  const SWord8 s2486 = s1 + s2468;
-  const SBool  s2487 = s2486 < s1;
-  const SBool  s2488 = s2486 < s2468;
-  const SBool  s2489 = s2487 || s2488;
-  const SWord8 s2490 = (s2486 >> 1) | (s2486 << 7);
-  const SWord8 s2491 = 128 | s2490;
-  const SWord8 s2492 = 127 & s2490;
-  const SWord8 s2493 = s2489 ? s2491 : s2492;
-  const SWord8 s2494 = (s2493 >> 1) | (s2493 << 7);
-  const SWord8 s2495 = 128 | s2494;
-  const SWord8 s2496 = 127 & s2494;
-  const SWord8 s2497 = s2456 ? s2495 : s2496;
-  const SWord8 s2498 = s1 + s2493;
-  const SBool  s2499 = s2498 < s1;
-  const SBool  s2500 = s2498 < s2493;
-  const SBool  s2501 = s2499 || s2500;
-  const SWord8 s2502 = (s2498 >> 1) | (s2498 << 7);
-  const SWord8 s2503 = 128 | s2502;
-  const SWord8 s2504 = 127 & s2502;
-  const SWord8 s2505 = s2501 ? s2503 : s2504;
-  const SWord8 s2506 = s2457 ? s2497 : s2505;
-  const SWord8 s2507 = s2330 ? s2485 : s2506;
-  const SWord8 s2508 = s1 + s2464;
-  const SBool  s2509 = s2508 < s1;
-  const SBool  s2510 = s2508 < s2464;
-  const SBool  s2511 = s2509 || s2510;
-  const SWord8 s2512 = (s2508 >> 1) | (s2508 << 7);
-  const SWord8 s2513 = 128 | s2512;
-  const SWord8 s2514 = 127 & s2512;
-  const SWord8 s2515 = s2511 ? s2513 : s2514;
-  const SWord8 s2516 = (s2515 >> 1) | (s2515 << 7);
-  const SWord8 s2517 = 128 | s2516;
-  const SWord8 s2518 = 127 & s2516;
-  const SWord8 s2519 = s2329 ? s2517 : s2518;
-  const SWord8 s2520 = (s2519 >> 1) | (s2519 << 7);
-  const SWord8 s2521 = 128 | s2520;
-  const SWord8 s2522 = 127 & s2520;
-  const SWord8 s2523 = s2456 ? s2521 : s2522;
-  const SWord8 s2524 = s1 + s2519;
-  const SBool  s2525 = s2524 < s1;
-  const SBool  s2526 = s2524 < s2519;
-  const SBool  s2527 = s2525 || s2526;
-  const SWord8 s2528 = (s2524 >> 1) | (s2524 << 7);
-  const SWord8 s2529 = 128 | s2528;
-  const SWord8 s2530 = 127 & s2528;
-  const SWord8 s2531 = s2527 ? s2529 : s2530;
-  const SWord8 s2532 = s2457 ? s2523 : s2531;
-  const SWord8 s2533 = s1 + s2515;
-  const SBool  s2534 = s2533 < s1;
-  const SBool  s2535 = s2533 < s2515;
-  const SBool  s2536 = s2534 || s2535;
-  const SWord8 s2537 = (s2533 >> 1) | (s2533 << 7);
-  const SWord8 s2538 = 128 | s2537;
-  const SWord8 s2539 = 127 & s2537;
-  const SWord8 s2540 = s2536 ? s2538 : s2539;
-  const SWord8 s2541 = (s2540 >> 1) | (s2540 << 7);
-  const SWord8 s2542 = 128 | s2541;
-  const SWord8 s2543 = 127 & s2541;
-  const SWord8 s2544 = s2456 ? s2542 : s2543;
-  const SWord8 s2545 = s1 + s2540;
-  const SBool  s2546 = s2545 < s1;
-  const SBool  s2547 = s2545 < s2540;
-  const SBool  s2548 = s2546 || s2547;
-  const SWord8 s2549 = (s2545 >> 1) | (s2545 << 7);
-  const SWord8 s2550 = 128 | s2549;
-  const SWord8 s2551 = 127 & s2549;
-  const SWord8 s2552 = s2548 ? s2550 : s2551;
-  const SWord8 s2553 = s2457 ? s2544 : s2552;
-  const SWord8 s2554 = s2330 ? s2532 : s2553;
-  const SWord8 s2555 = s2078 ? s2507 : s2554;
-  const SWord8 s2556 = s2059 ? s2447 : s2555;
-  const SWord8 s2557 = s2042 ? s2320 : s2556;
-  const SWord8 s2558 = s1 + s2063;
-  const SBool  s2559 = (SBool) (s2558 & 1);
-  const SBool  s2560 = false != s2559;
-  const SWord8 s2561 = s2560 ? s2067 : s2068;
-  const SBool  s2562 = (SBool) (s2561 & 1);
-  const SBool  s2563 = false != s2562;
-  const SWord8 s2564 = s2563 ? s2073 : s2074;
-  const SBool  s2565 = (SBool) (s2564 & 1);
-  const SBool  s2566 = false != s2565;
-  const SBool  s2567 = !s2566;
-  const SBool  s2568 = s2558 < s1;
-  const SBool  s2569 = s2558 < s2063;
-  const SBool  s2570 = s2568 || s2569;
-  const SWord8 s2571 = (s2558 >> 1) | (s2558 << 7);
-  const SWord8 s2572 = 128 | s2571;
-  const SWord8 s2573 = 127 & s2571;
-  const SWord8 s2574 = s2570 ? s2572 : s2573;
-  const SBool  s2575 = (SBool) (s2574 & 1);
-  const SBool  s2576 = false != s2575;
-  const SWord8 s2577 = (s2561 >> 1) | (s2561 << 7);
-  const SWord8 s2578 = 128 | s2577;
-  const SWord8 s2579 = 127 & s2577;
-  const SWord8 s2580 = s2576 ? s2578 : s2579;
-  const SBool  s2581 = (SBool) (s2580 & 1);
-  const SBool  s2582 = false != s2581;
-  const SWord8 s2583 = (s2564 >> 1) | (s2564 << 7);
-  const SWord8 s2584 = 128 | s2583;
-  const SWord8 s2585 = 127 & s2583;
-  const SWord8 s2586 = s2582 ? s2584 : s2585;
-  const SBool  s2587 = (SBool) (s2586 & 1);
-  const SBool  s2588 = false != s2587;
-  const SBool  s2589 = !s2588;
-  const SWord8 s2590 = (s2574 >> 1) | (s2574 << 7);
-  const SWord8 s2591 = 128 | s2590;
-  const SWord8 s2592 = 127 & s2590;
-  const SWord8 s2593 = s2041 ? s2591 : s2592;
-  const SBool  s2594 = (SBool) (s2593 & 1);
-  const SBool  s2595 = false != s2594;
-  const SWord8 s2596 = (s2580 >> 1) | (s2580 << 7);
-  const SWord8 s2597 = 128 | s2596;
-  const SWord8 s2598 = 127 & s2596;
-  const SWord8 s2599 = s2595 ? s2597 : s2598;
-  const SBool  s2600 = (SBool) (s2599 & 1);
-  const SBool  s2601 = false != s2600;
-  const SWord8 s2602 = (s2586 >> 1) | (s2586 << 7);
-  const SWord8 s2603 = 128 | s2602;
-  const SWord8 s2604 = 127 & s2602;
-  const SWord8 s2605 = s2601 ? s2603 : s2604;
-  const SBool  s2606 = (SBool) (s2605 & 1);
-  const SBool  s2607 = false != s2606;
-  const SBool  s2608 = !s2607;
-  const SWord8 s2609 = (s2593 >> 1) | (s2593 << 7);
-  const SWord8 s2610 = 128 | s2609;
-  const SWord8 s2611 = 127 & s2609;
-  const SWord8 s2612 = s2058 ? s2610 : s2611;
-  const SWord8 s2613 = (s2612 >> 1) | (s2612 << 7);
-  const SWord8 s2614 = 128 | s2613;
-  const SWord8 s2615 = 127 & s2613;
-  const SWord8 s2616 = s2566 ? s2614 : s2615;
-  const SWord8 s2617 = (s2616 >> 1) | (s2616 << 7);
-  const SWord8 s2618 = 128 | s2617;
-  const SWord8 s2619 = 127 & s2617;
-  const SWord8 s2620 = s2588 ? s2618 : s2619;
-  const SWord8 s2621 = (s2620 >> 1) | (s2620 << 7);
-  const SWord8 s2622 = 128 | s2621;
-  const SWord8 s2623 = 127 & s2621;
-  const SWord8 s2624 = s2607 ? s2622 : s2623;
-  const SWord8 s2625 = s1 + s2620;
-  const SBool  s2626 = s2625 < s1;
-  const SBool  s2627 = s2625 < s2620;
-  const SBool  s2628 = s2626 || s2627;
-  const SWord8 s2629 = (s2625 >> 1) | (s2625 << 7);
-  const SWord8 s2630 = 128 | s2629;
-  const SWord8 s2631 = 127 & s2629;
-  const SWord8 s2632 = s2628 ? s2630 : s2631;
-  const SWord8 s2633 = s2608 ? s2624 : s2632;
-  const SWord8 s2634 = s1 + s2616;
-  const SBool  s2635 = s2634 < s1;
-  const SBool  s2636 = s2634 < s2616;
-  const SBool  s2637 = s2635 || s2636;
-  const SWord8 s2638 = (s2634 >> 1) | (s2634 << 7);
-  const SWord8 s2639 = 128 | s2638;
-  const SWord8 s2640 = 127 & s2638;
-  const SWord8 s2641 = s2637 ? s2639 : s2640;
-  const SWord8 s2642 = (s2641 >> 1) | (s2641 << 7);
-  const SWord8 s2643 = 128 | s2642;
-  const SWord8 s2644 = 127 & s2642;
-  const SWord8 s2645 = s2607 ? s2643 : s2644;
-  const SWord8 s2646 = s1 + s2641;
-  const SBool  s2647 = s2646 < s1;
-  const SBool  s2648 = s2646 < s2641;
-  const SBool  s2649 = s2647 || s2648;
-  const SWord8 s2650 = (s2646 >> 1) | (s2646 << 7);
-  const SWord8 s2651 = 128 | s2650;
-  const SWord8 s2652 = 127 & s2650;
-  const SWord8 s2653 = s2649 ? s2651 : s2652;
-  const SWord8 s2654 = s2608 ? s2645 : s2653;
-  const SWord8 s2655 = s2589 ? s2633 : s2654;
-  const SWord8 s2656 = s1 + s2612;
-  const SBool  s2657 = s2656 < s1;
-  const SBool  s2658 = s2656 < s2612;
-  const SBool  s2659 = s2657 || s2658;
-  const SWord8 s2660 = (s2656 >> 1) | (s2656 << 7);
-  const SWord8 s2661 = 128 | s2660;
-  const SWord8 s2662 = 127 & s2660;
-  const SWord8 s2663 = s2659 ? s2661 : s2662;
-  const SWord8 s2664 = (s2663 >> 1) | (s2663 << 7);
-  const SWord8 s2665 = 128 | s2664;
-  const SWord8 s2666 = 127 & s2664;
-  const SWord8 s2667 = s2588 ? s2665 : s2666;
-  const SWord8 s2668 = (s2667 >> 1) | (s2667 << 7);
-  const SWord8 s2669 = 128 | s2668;
-  const SWord8 s2670 = 127 & s2668;
-  const SWord8 s2671 = s2607 ? s2669 : s2670;
-  const SWord8 s2672 = s1 + s2667;
-  const SBool  s2673 = s2672 < s1;
-  const SBool  s2674 = s2672 < s2667;
-  const SBool  s2675 = s2673 || s2674;
-  const SWord8 s2676 = (s2672 >> 1) | (s2672 << 7);
-  const SWord8 s2677 = 128 | s2676;
-  const SWord8 s2678 = 127 & s2676;
-  const SWord8 s2679 = s2675 ? s2677 : s2678;
-  const SWord8 s2680 = s2608 ? s2671 : s2679;
-  const SWord8 s2681 = s1 + s2663;
-  const SBool  s2682 = s2681 < s1;
-  const SBool  s2683 = s2681 < s2663;
-  const SBool  s2684 = s2682 || s2683;
-  const SWord8 s2685 = (s2681 >> 1) | (s2681 << 7);
-  const SWord8 s2686 = 128 | s2685;
-  const SWord8 s2687 = 127 & s2685;
-  const SWord8 s2688 = s2684 ? s2686 : s2687;
-  const SWord8 s2689 = (s2688 >> 1) | (s2688 << 7);
-  const SWord8 s2690 = 128 | s2689;
-  const SWord8 s2691 = 127 & s2689;
-  const SWord8 s2692 = s2607 ? s2690 : s2691;
-  const SWord8 s2693 = s1 + s2688;
-  const SBool  s2694 = s2693 < s1;
-  const SBool  s2695 = s2693 < s2688;
-  const SBool  s2696 = s2694 || s2695;
-  const SWord8 s2697 = (s2693 >> 1) | (s2693 << 7);
-  const SWord8 s2698 = 128 | s2697;
-  const SWord8 s2699 = 127 & s2697;
-  const SWord8 s2700 = s2696 ? s2698 : s2699;
-  const SWord8 s2701 = s2608 ? s2692 : s2700;
-  const SWord8 s2702 = s2589 ? s2680 : s2701;
-  const SWord8 s2703 = s2567 ? s2655 : s2702;
-  const SWord8 s2704 = s1 + s2593;
-  const SBool  s2705 = (SBool) (s2704 & 1);
-  const SBool  s2706 = false != s2705;
-  const SWord8 s2707 = s2706 ? s2597 : s2598;
-  const SBool  s2708 = (SBool) (s2707 & 1);
-  const SBool  s2709 = false != s2708;
-  const SWord8 s2710 = s2709 ? s2603 : s2604;
-  const SBool  s2711 = (SBool) (s2710 & 1);
-  const SBool  s2712 = false != s2711;
-  const SBool  s2713 = !s2712;
-  const SBool  s2714 = s2704 < s1;
-  const SBool  s2715 = s2704 < s2593;
-  const SBool  s2716 = s2714 || s2715;
-  const SWord8 s2717 = (s2704 >> 1) | (s2704 << 7);
-  const SWord8 s2718 = 128 | s2717;
-  const SWord8 s2719 = 127 & s2717;
-  const SWord8 s2720 = s2716 ? s2718 : s2719;
-  const SWord8 s2721 = (s2720 >> 1) | (s2720 << 7);
-  const SWord8 s2722 = 128 | s2721;
-  const SWord8 s2723 = 127 & s2721;
-  const SWord8 s2724 = s2566 ? s2722 : s2723;
-  const SWord8 s2725 = (s2724 >> 1) | (s2724 << 7);
-  const SWord8 s2726 = 128 | s2725;
-  const SWord8 s2727 = 127 & s2725;
-  const SWord8 s2728 = s2588 ? s2726 : s2727;
-  const SWord8 s2729 = (s2728 >> 1) | (s2728 << 7);
-  const SWord8 s2730 = 128 | s2729;
-  const SWord8 s2731 = 127 & s2729;
-  const SWord8 s2732 = s2712 ? s2730 : s2731;
-  const SWord8 s2733 = s1 + s2728;
-  const SBool  s2734 = s2733 < s1;
-  const SBool  s2735 = s2733 < s2728;
-  const SBool  s2736 = s2734 || s2735;
-  const SWord8 s2737 = (s2733 >> 1) | (s2733 << 7);
-  const SWord8 s2738 = 128 | s2737;
-  const SWord8 s2739 = 127 & s2737;
-  const SWord8 s2740 = s2736 ? s2738 : s2739;
-  const SWord8 s2741 = s2713 ? s2732 : s2740;
-  const SWord8 s2742 = s1 + s2724;
-  const SBool  s2743 = s2742 < s1;
-  const SBool  s2744 = s2742 < s2724;
-  const SBool  s2745 = s2743 || s2744;
-  const SWord8 s2746 = (s2742 >> 1) | (s2742 << 7);
-  const SWord8 s2747 = 128 | s2746;
-  const SWord8 s2748 = 127 & s2746;
-  const SWord8 s2749 = s2745 ? s2747 : s2748;
-  const SWord8 s2750 = (s2749 >> 1) | (s2749 << 7);
-  const SWord8 s2751 = 128 | s2750;
-  const SWord8 s2752 = 127 & s2750;
-  const SWord8 s2753 = s2712 ? s2751 : s2752;
-  const SWord8 s2754 = s1 + s2749;
-  const SBool  s2755 = s2754 < s1;
-  const SBool  s2756 = s2754 < s2749;
-  const SBool  s2757 = s2755 || s2756;
-  const SWord8 s2758 = (s2754 >> 1) | (s2754 << 7);
-  const SWord8 s2759 = 128 | s2758;
-  const SWord8 s2760 = 127 & s2758;
-  const SWord8 s2761 = s2757 ? s2759 : s2760;
-  const SWord8 s2762 = s2713 ? s2753 : s2761;
-  const SWord8 s2763 = s2589 ? s2741 : s2762;
-  const SWord8 s2764 = s1 + s2720;
-  const SBool  s2765 = s2764 < s1;
-  const SBool  s2766 = s2764 < s2720;
-  const SBool  s2767 = s2765 || s2766;
-  const SWord8 s2768 = (s2764 >> 1) | (s2764 << 7);
-  const SWord8 s2769 = 128 | s2768;
-  const SWord8 s2770 = 127 & s2768;
-  const SWord8 s2771 = s2767 ? s2769 : s2770;
-  const SWord8 s2772 = (s2771 >> 1) | (s2771 << 7);
-  const SWord8 s2773 = 128 | s2772;
-  const SWord8 s2774 = 127 & s2772;
-  const SWord8 s2775 = s2588 ? s2773 : s2774;
-  const SWord8 s2776 = (s2775 >> 1) | (s2775 << 7);
-  const SWord8 s2777 = 128 | s2776;
-  const SWord8 s2778 = 127 & s2776;
-  const SWord8 s2779 = s2712 ? s2777 : s2778;
-  const SWord8 s2780 = s1 + s2775;
-  const SBool  s2781 = s2780 < s1;
-  const SBool  s2782 = s2780 < s2775;
-  const SBool  s2783 = s2781 || s2782;
-  const SWord8 s2784 = (s2780 >> 1) | (s2780 << 7);
-  const SWord8 s2785 = 128 | s2784;
-  const SWord8 s2786 = 127 & s2784;
-  const SWord8 s2787 = s2783 ? s2785 : s2786;
-  const SWord8 s2788 = s2713 ? s2779 : s2787;
-  const SWord8 s2789 = s1 + s2771;
-  const SBool  s2790 = s2789 < s1;
-  const SBool  s2791 = s2789 < s2771;
-  const SBool  s2792 = s2790 || s2791;
-  const SWord8 s2793 = (s2789 >> 1) | (s2789 << 7);
-  const SWord8 s2794 = 128 | s2793;
-  const SWord8 s2795 = 127 & s2793;
-  const SWord8 s2796 = s2792 ? s2794 : s2795;
-  const SWord8 s2797 = (s2796 >> 1) | (s2796 << 7);
-  const SWord8 s2798 = 128 | s2797;
-  const SWord8 s2799 = 127 & s2797;
-  const SWord8 s2800 = s2712 ? s2798 : s2799;
-  const SWord8 s2801 = s1 + s2796;
-  const SBool  s2802 = s2801 < s1;
-  const SBool  s2803 = s2801 < s2796;
-  const SBool  s2804 = s2802 || s2803;
-  const SWord8 s2805 = (s2801 >> 1) | (s2801 << 7);
-  const SWord8 s2806 = 128 | s2805;
-  const SWord8 s2807 = 127 & s2805;
-  const SWord8 s2808 = s2804 ? s2806 : s2807;
-  const SWord8 s2809 = s2713 ? s2800 : s2808;
-  const SWord8 s2810 = s2589 ? s2788 : s2809;
-  const SWord8 s2811 = s2567 ? s2763 : s2810;
-  const SWord8 s2812 = s2059 ? s2703 : s2811;
-  const SWord8 s2813 = s1 + s2574;
-  const SBool  s2814 = (SBool) (s2813 & 1);
-  const SBool  s2815 = false != s2814;
-  const SWord8 s2816 = s2815 ? s2578 : s2579;
-  const SBool  s2817 = (SBool) (s2816 & 1);
-  const SBool  s2818 = false != s2817;
-  const SWord8 s2819 = s2818 ? s2584 : s2585;
-  const SBool  s2820 = (SBool) (s2819 & 1);
-  const SBool  s2821 = false != s2820;
-  const SBool  s2822 = !s2821;
-  const SBool  s2823 = s2813 < s1;
-  const SBool  s2824 = s2813 < s2574;
-  const SBool  s2825 = s2823 || s2824;
-  const SWord8 s2826 = (s2813 >> 1) | (s2813 << 7);
-  const SWord8 s2827 = 128 | s2826;
-  const SWord8 s2828 = 127 & s2826;
-  const SWord8 s2829 = s2825 ? s2827 : s2828;
-  const SBool  s2830 = (SBool) (s2829 & 1);
-  const SBool  s2831 = false != s2830;
-  const SWord8 s2832 = (s2816 >> 1) | (s2816 << 7);
-  const SWord8 s2833 = 128 | s2832;
-  const SWord8 s2834 = 127 & s2832;
-  const SWord8 s2835 = s2831 ? s2833 : s2834;
-  const SBool  s2836 = (SBool) (s2835 & 1);
-  const SBool  s2837 = false != s2836;
-  const SWord8 s2838 = (s2819 >> 1) | (s2819 << 7);
-  const SWord8 s2839 = 128 | s2838;
-  const SWord8 s2840 = 127 & s2838;
-  const SWord8 s2841 = s2837 ? s2839 : s2840;
-  const SBool  s2842 = (SBool) (s2841 & 1);
-  const SBool  s2843 = false != s2842;
-  const SBool  s2844 = !s2843;
-  const SWord8 s2845 = (s2829 >> 1) | (s2829 << 7);
-  const SWord8 s2846 = 128 | s2845;
-  const SWord8 s2847 = 127 & s2845;
-  const SWord8 s2848 = s2058 ? s2846 : s2847;
-  const SWord8 s2849 = (s2848 >> 1) | (s2848 << 7);
-  const SWord8 s2850 = 128 | s2849;
-  const SWord8 s2851 = 127 & s2849;
-  const SWord8 s2852 = s2566 ? s2850 : s2851;
-  const SWord8 s2853 = (s2852 >> 1) | (s2852 << 7);
-  const SWord8 s2854 = 128 | s2853;
-  const SWord8 s2855 = 127 & s2853;
-  const SWord8 s2856 = s2821 ? s2854 : s2855;
-  const SWord8 s2857 = (s2856 >> 1) | (s2856 << 7);
-  const SWord8 s2858 = 128 | s2857;
-  const SWord8 s2859 = 127 & s2857;
-  const SWord8 s2860 = s2843 ? s2858 : s2859;
-  const SWord8 s2861 = s1 + s2856;
-  const SBool  s2862 = s2861 < s1;
-  const SBool  s2863 = s2861 < s2856;
-  const SBool  s2864 = s2862 || s2863;
-  const SWord8 s2865 = (s2861 >> 1) | (s2861 << 7);
-  const SWord8 s2866 = 128 | s2865;
-  const SWord8 s2867 = 127 & s2865;
-  const SWord8 s2868 = s2864 ? s2866 : s2867;
-  const SWord8 s2869 = s2844 ? s2860 : s2868;
-  const SWord8 s2870 = s1 + s2852;
-  const SBool  s2871 = s2870 < s1;
-  const SBool  s2872 = s2870 < s2852;
-  const SBool  s2873 = s2871 || s2872;
-  const SWord8 s2874 = (s2870 >> 1) | (s2870 << 7);
-  const SWord8 s2875 = 128 | s2874;
-  const SWord8 s2876 = 127 & s2874;
-  const SWord8 s2877 = s2873 ? s2875 : s2876;
-  const SWord8 s2878 = (s2877 >> 1) | (s2877 << 7);
-  const SWord8 s2879 = 128 | s2878;
-  const SWord8 s2880 = 127 & s2878;
-  const SWord8 s2881 = s2843 ? s2879 : s2880;
-  const SWord8 s2882 = s1 + s2877;
-  const SBool  s2883 = s2882 < s1;
-  const SBool  s2884 = s2882 < s2877;
-  const SBool  s2885 = s2883 || s2884;
-  const SWord8 s2886 = (s2882 >> 1) | (s2882 << 7);
-  const SWord8 s2887 = 128 | s2886;
-  const SWord8 s2888 = 127 & s2886;
-  const SWord8 s2889 = s2885 ? s2887 : s2888;
-  const SWord8 s2890 = s2844 ? s2881 : s2889;
-  const SWord8 s2891 = s2822 ? s2869 : s2890;
-  const SWord8 s2892 = s1 + s2848;
-  const SBool  s2893 = s2892 < s1;
-  const SBool  s2894 = s2892 < s2848;
-  const SBool  s2895 = s2893 || s2894;
-  const SWord8 s2896 = (s2892 >> 1) | (s2892 << 7);
-  const SWord8 s2897 = 128 | s2896;
-  const SWord8 s2898 = 127 & s2896;
-  const SWord8 s2899 = s2895 ? s2897 : s2898;
-  const SWord8 s2900 = (s2899 >> 1) | (s2899 << 7);
-  const SWord8 s2901 = 128 | s2900;
-  const SWord8 s2902 = 127 & s2900;
-  const SWord8 s2903 = s2821 ? s2901 : s2902;
-  const SWord8 s2904 = (s2903 >> 1) | (s2903 << 7);
-  const SWord8 s2905 = 128 | s2904;
-  const SWord8 s2906 = 127 & s2904;
-  const SWord8 s2907 = s2843 ? s2905 : s2906;
-  const SWord8 s2908 = s1 + s2903;
-  const SBool  s2909 = s2908 < s1;
-  const SBool  s2910 = s2908 < s2903;
-  const SBool  s2911 = s2909 || s2910;
-  const SWord8 s2912 = (s2908 >> 1) | (s2908 << 7);
-  const SWord8 s2913 = 128 | s2912;
-  const SWord8 s2914 = 127 & s2912;
-  const SWord8 s2915 = s2911 ? s2913 : s2914;
-  const SWord8 s2916 = s2844 ? s2907 : s2915;
-  const SWord8 s2917 = s1 + s2899;
-  const SBool  s2918 = s2917 < s1;
-  const SBool  s2919 = s2917 < s2899;
-  const SBool  s2920 = s2918 || s2919;
-  const SWord8 s2921 = (s2917 >> 1) | (s2917 << 7);
-  const SWord8 s2922 = 128 | s2921;
-  const SWord8 s2923 = 127 & s2921;
-  const SWord8 s2924 = s2920 ? s2922 : s2923;
-  const SWord8 s2925 = (s2924 >> 1) | (s2924 << 7);
-  const SWord8 s2926 = 128 | s2925;
-  const SWord8 s2927 = 127 & s2925;
-  const SWord8 s2928 = s2843 ? s2926 : s2927;
-  const SWord8 s2929 = s1 + s2924;
-  const SBool  s2930 = s2929 < s1;
-  const SBool  s2931 = s2929 < s2924;
-  const SBool  s2932 = s2930 || s2931;
-  const SWord8 s2933 = (s2929 >> 1) | (s2929 << 7);
-  const SWord8 s2934 = 128 | s2933;
-  const SWord8 s2935 = 127 & s2933;
-  const SWord8 s2936 = s2932 ? s2934 : s2935;
-  const SWord8 s2937 = s2844 ? s2928 : s2936;
-  const SWord8 s2938 = s2822 ? s2916 : s2937;
-  const SWord8 s2939 = s2567 ? s2891 : s2938;
-  const SWord8 s2940 = s1 + s2829;
-  const SBool  s2941 = (SBool) (s2940 & 1);
-  const SBool  s2942 = false != s2941;
-  const SWord8 s2943 = s2942 ? s2833 : s2834;
-  const SBool  s2944 = (SBool) (s2943 & 1);
-  const SBool  s2945 = false != s2944;
-  const SWord8 s2946 = s2945 ? s2839 : s2840;
-  const SBool  s2947 = (SBool) (s2946 & 1);
-  const SBool  s2948 = false != s2947;
-  const SBool  s2949 = !s2948;
-  const SBool  s2950 = s2940 < s1;
-  const SBool  s2951 = s2940 < s2829;
-  const SBool  s2952 = s2950 || s2951;
-  const SWord8 s2953 = (s2940 >> 1) | (s2940 << 7);
-  const SWord8 s2954 = 128 | s2953;
-  const SWord8 s2955 = 127 & s2953;
-  const SWord8 s2956 = s2952 ? s2954 : s2955;
-  const SWord8 s2957 = (s2956 >> 1) | (s2956 << 7);
-  const SWord8 s2958 = 128 | s2957;
-  const SWord8 s2959 = 127 & s2957;
-  const SWord8 s2960 = s2566 ? s2958 : s2959;
-  const SWord8 s2961 = (s2960 >> 1) | (s2960 << 7);
-  const SWord8 s2962 = 128 | s2961;
-  const SWord8 s2963 = 127 & s2961;
-  const SWord8 s2964 = s2821 ? s2962 : s2963;
-  const SWord8 s2965 = (s2964 >> 1) | (s2964 << 7);
-  const SWord8 s2966 = 128 | s2965;
-  const SWord8 s2967 = 127 & s2965;
-  const SWord8 s2968 = s2948 ? s2966 : s2967;
-  const SWord8 s2969 = s1 + s2964;
-  const SBool  s2970 = s2969 < s1;
-  const SBool  s2971 = s2969 < s2964;
-  const SBool  s2972 = s2970 || s2971;
-  const SWord8 s2973 = (s2969 >> 1) | (s2969 << 7);
-  const SWord8 s2974 = 128 | s2973;
-  const SWord8 s2975 = 127 & s2973;
-  const SWord8 s2976 = s2972 ? s2974 : s2975;
-  const SWord8 s2977 = s2949 ? s2968 : s2976;
-  const SWord8 s2978 = s1 + s2960;
-  const SBool  s2979 = s2978 < s1;
-  const SBool  s2980 = s2978 < s2960;
-  const SBool  s2981 = s2979 || s2980;
-  const SWord8 s2982 = (s2978 >> 1) | (s2978 << 7);
-  const SWord8 s2983 = 128 | s2982;
-  const SWord8 s2984 = 127 & s2982;
-  const SWord8 s2985 = s2981 ? s2983 : s2984;
-  const SWord8 s2986 = (s2985 >> 1) | (s2985 << 7);
-  const SWord8 s2987 = 128 | s2986;
-  const SWord8 s2988 = 127 & s2986;
-  const SWord8 s2989 = s2948 ? s2987 : s2988;
-  const SWord8 s2990 = s1 + s2985;
-  const SBool  s2991 = s2990 < s1;
-  const SBool  s2992 = s2990 < s2985;
-  const SBool  s2993 = s2991 || s2992;
-  const SWord8 s2994 = (s2990 >> 1) | (s2990 << 7);
-  const SWord8 s2995 = 128 | s2994;
-  const SWord8 s2996 = 127 & s2994;
-  const SWord8 s2997 = s2993 ? s2995 : s2996;
-  const SWord8 s2998 = s2949 ? s2989 : s2997;
-  const SWord8 s2999 = s2822 ? s2977 : s2998;
-  const SWord8 s3000 = s1 + s2956;
-  const SBool  s3001 = s3000 < s1;
-  const SBool  s3002 = s3000 < s2956;
-  const SBool  s3003 = s3001 || s3002;
-  const SWord8 s3004 = (s3000 >> 1) | (s3000 << 7);
-  const SWord8 s3005 = 128 | s3004;
-  const SWord8 s3006 = 127 & s3004;
-  const SWord8 s3007 = s3003 ? s3005 : s3006;
-  const SWord8 s3008 = (s3007 >> 1) | (s3007 << 7);
-  const SWord8 s3009 = 128 | s3008;
-  const SWord8 s3010 = 127 & s3008;
-  const SWord8 s3011 = s2821 ? s3009 : s3010;
-  const SWord8 s3012 = (s3011 >> 1) | (s3011 << 7);
-  const SWord8 s3013 = 128 | s3012;
-  const SWord8 s3014 = 127 & s3012;
-  const SWord8 s3015 = s2948 ? s3013 : s3014;
-  const SWord8 s3016 = s1 + s3011;
-  const SBool  s3017 = s3016 < s1;
-  const SBool  s3018 = s3016 < s3011;
-  const SBool  s3019 = s3017 || s3018;
-  const SWord8 s3020 = (s3016 >> 1) | (s3016 << 7);
-  const SWord8 s3021 = 128 | s3020;
-  const SWord8 s3022 = 127 & s3020;
-  const SWord8 s3023 = s3019 ? s3021 : s3022;
-  const SWord8 s3024 = s2949 ? s3015 : s3023;
-  const SWord8 s3025 = s1 + s3007;
-  const SBool  s3026 = s3025 < s1;
-  const SBool  s3027 = s3025 < s3007;
-  const SBool  s3028 = s3026 || s3027;
-  const SWord8 s3029 = (s3025 >> 1) | (s3025 << 7);
-  const SWord8 s3030 = 128 | s3029;
-  const SWord8 s3031 = 127 & s3029;
-  const SWord8 s3032 = s3028 ? s3030 : s3031;
-  const SWord8 s3033 = (s3032 >> 1) | (s3032 << 7);
-  const SWord8 s3034 = 128 | s3033;
-  const SWord8 s3035 = 127 & s3033;
-  const SWord8 s3036 = s2948 ? s3034 : s3035;
-  const SWord8 s3037 = s1 + s3032;
-  const SBool  s3038 = s3037 < s1;
-  const SBool  s3039 = s3037 < s3032;
-  const SBool  s3040 = s3038 || s3039;
-  const SWord8 s3041 = (s3037 >> 1) | (s3037 << 7);
-  const SWord8 s3042 = 128 | s3041;
-  const SWord8 s3043 = 127 & s3041;
-  const SWord8 s3044 = s3040 ? s3042 : s3043;
-  const SWord8 s3045 = s2949 ? s3036 : s3044;
-  const SWord8 s3046 = s2822 ? s3024 : s3045;
-  const SWord8 s3047 = s2567 ? s2999 : s3046;
-  const SWord8 s3048 = s2059 ? s2939 : s3047;
-  const SWord8 s3049 = s2042 ? s2812 : s3048;
-  const SWord8 s3050 = s16 ? s2557 : s3049;
-  const SWord8 s3051 = s1 + s2044;
-  const SBool  s3052 = (SBool) (s3051 & 1);
-  const SBool  s3053 = false != s3052;
-  const SWord8 s3054 = s3053 ? s2048 : s2049;
-  const SBool  s3055 = (SBool) (s3054 & 1);
-  const SBool  s3056 = false != s3055;
-  const SWord8 s3057 = s3056 ? s2054 : s2055;
-  const SBool  s3058 = (SBool) (s3057 & 1);
-  const SBool  s3059 = false != s3058;
-  const SBool  s3060 = !s3059;
-  const SBool  s3061 = s3051 < s1;
-  const SBool  s3062 = s3051 < s2044;
-  const SBool  s3063 = s3061 || s3062;
-  const SWord8 s3064 = (s3051 >> 1) | (s3051 << 7);
-  const SWord8 s3065 = 128 | s3064;
-  const SWord8 s3066 = 127 & s3064;
-  const SWord8 s3067 = s3063 ? s3065 : s3066;
-  const SBool  s3068 = (SBool) (s3067 & 1);
-  const SBool  s3069 = false != s3068;
-  const SWord8 s3070 = (s3054 >> 1) | (s3054 << 7);
-  const SWord8 s3071 = 128 | s3070;
-  const SWord8 s3072 = 127 & s3070;
-  const SWord8 s3073 = s3069 ? s3071 : s3072;
-  const SBool  s3074 = (SBool) (s3073 & 1);
-  const SBool  s3075 = false != s3074;
-  const SWord8 s3076 = (s3057 >> 1) | (s3057 << 7);
-  const SWord8 s3077 = 128 | s3076;
-  const SWord8 s3078 = 127 & s3076;
-  const SWord8 s3079 = s3075 ? s3077 : s3078;
-  const SBool  s3080 = (SBool) (s3079 & 1);
-  const SBool  s3081 = false != s3080;
-  const SBool  s3082 = !s3081;
-  const SWord8 s3083 = (s3067 >> 1) | (s3067 << 7);
-  const SWord8 s3084 = 128 | s3083;
-  const SWord8 s3085 = 127 & s3083;
-  const SWord8 s3086 = s15 ? s3084 : s3085;
-  const SBool  s3087 = (SBool) (s3086 & 1);
-  const SBool  s3088 = false != s3087;
-  const SWord8 s3089 = (s3073 >> 1) | (s3073 << 7);
-  const SWord8 s3090 = 128 | s3089;
-  const SWord8 s3091 = 127 & s3089;
-  const SWord8 s3092 = s3088 ? s3090 : s3091;
-  const SBool  s3093 = (SBool) (s3092 & 1);
-  const SBool  s3094 = false != s3093;
-  const SWord8 s3095 = (s3079 >> 1) | (s3079 << 7);
-  const SWord8 s3096 = 128 | s3095;
-  const SWord8 s3097 = 127 & s3095;
-  const SWord8 s3098 = s3094 ? s3096 : s3097;
-  const SBool  s3099 = (SBool) (s3098 & 1);
-  const SBool  s3100 = false != s3099;
-  const SBool  s3101 = !s3100;
-  const SWord8 s3102 = (s3086 >> 1) | (s3086 << 7);
-  const SWord8 s3103 = 128 | s3102;
-  const SWord8 s3104 = 127 & s3102;
-  const SWord8 s3105 = s2041 ? s3103 : s3104;
-  const SBool  s3106 = (SBool) (s3105 & 1);
-  const SBool  s3107 = false != s3106;
-  const SWord8 s3108 = (s3092 >> 1) | (s3092 << 7);
-  const SWord8 s3109 = 128 | s3108;
-  const SWord8 s3110 = 127 & s3108;
-  const SWord8 s3111 = s3107 ? s3109 : s3110;
-  const SBool  s3112 = (SBool) (s3111 & 1);
-  const SBool  s3113 = false != s3112;
-  const SWord8 s3114 = (s3098 >> 1) | (s3098 << 7);
-  const SWord8 s3115 = 128 | s3114;
-  const SWord8 s3116 = 127 & s3114;
-  const SWord8 s3117 = s3113 ? s3115 : s3116;
-  const SBool  s3118 = (SBool) (s3117 & 1);
-  const SBool  s3119 = false != s3118;
-  const SBool  s3120 = !s3119;
-  const SWord8 s3121 = (s3105 >> 1) | (s3105 << 7);
-  const SWord8 s3122 = 128 | s3121;
-  const SWord8 s3123 = 127 & s3121;
-  const SWord8 s3124 = s3059 ? s3122 : s3123;
-  const SWord8 s3125 = (s3124 >> 1) | (s3124 << 7);
-  const SWord8 s3126 = 128 | s3125;
-  const SWord8 s3127 = 127 & s3125;
-  const SWord8 s3128 = s3081 ? s3126 : s3127;
-  const SWord8 s3129 = (s3128 >> 1) | (s3128 << 7);
-  const SWord8 s3130 = 128 | s3129;
-  const SWord8 s3131 = 127 & s3129;
-  const SWord8 s3132 = s3100 ? s3130 : s3131;
-  const SWord8 s3133 = (s3132 >> 1) | (s3132 << 7);
-  const SWord8 s3134 = 128 | s3133;
-  const SWord8 s3135 = 127 & s3133;
-  const SWord8 s3136 = s3119 ? s3134 : s3135;
-  const SWord8 s3137 = s1 + s3132;
-  const SBool  s3138 = s3137 < s1;
-  const SBool  s3139 = s3137 < s3132;
-  const SBool  s3140 = s3138 || s3139;
-  const SWord8 s3141 = (s3137 >> 1) | (s3137 << 7);
-  const SWord8 s3142 = 128 | s3141;
-  const SWord8 s3143 = 127 & s3141;
-  const SWord8 s3144 = s3140 ? s3142 : s3143;
-  const SWord8 s3145 = s3120 ? s3136 : s3144;
-  const SWord8 s3146 = s1 + s3128;
-  const SBool  s3147 = s3146 < s1;
-  const SBool  s3148 = s3146 < s3128;
-  const SBool  s3149 = s3147 || s3148;
-  const SWord8 s3150 = (s3146 >> 1) | (s3146 << 7);
-  const SWord8 s3151 = 128 | s3150;
-  const SWord8 s3152 = 127 & s3150;
-  const SWord8 s3153 = s3149 ? s3151 : s3152;
-  const SWord8 s3154 = (s3153 >> 1) | (s3153 << 7);
-  const SWord8 s3155 = 128 | s3154;
-  const SWord8 s3156 = 127 & s3154;
-  const SWord8 s3157 = s3119 ? s3155 : s3156;
-  const SWord8 s3158 = s1 + s3153;
-  const SBool  s3159 = s3158 < s1;
-  const SBool  s3160 = s3158 < s3153;
-  const SBool  s3161 = s3159 || s3160;
-  const SWord8 s3162 = (s3158 >> 1) | (s3158 << 7);
-  const SWord8 s3163 = 128 | s3162;
-  const SWord8 s3164 = 127 & s3162;
-  const SWord8 s3165 = s3161 ? s3163 : s3164;
-  const SWord8 s3166 = s3120 ? s3157 : s3165;
-  const SWord8 s3167 = s3101 ? s3145 : s3166;
-  const SWord8 s3168 = s1 + s3124;
-  const SBool  s3169 = s3168 < s1;
-  const SBool  s3170 = s3168 < s3124;
-  const SBool  s3171 = s3169 || s3170;
-  const SWord8 s3172 = (s3168 >> 1) | (s3168 << 7);
-  const SWord8 s3173 = 128 | s3172;
-  const SWord8 s3174 = 127 & s3172;
-  const SWord8 s3175 = s3171 ? s3173 : s3174;
-  const SWord8 s3176 = (s3175 >> 1) | (s3175 << 7);
-  const SWord8 s3177 = 128 | s3176;
-  const SWord8 s3178 = 127 & s3176;
-  const SWord8 s3179 = s3100 ? s3177 : s3178;
-  const SWord8 s3180 = (s3179 >> 1) | (s3179 << 7);
-  const SWord8 s3181 = 128 | s3180;
-  const SWord8 s3182 = 127 & s3180;
-  const SWord8 s3183 = s3119 ? s3181 : s3182;
-  const SWord8 s3184 = s1 + s3179;
-  const SBool  s3185 = s3184 < s1;
-  const SBool  s3186 = s3184 < s3179;
-  const SBool  s3187 = s3185 || s3186;
-  const SWord8 s3188 = (s3184 >> 1) | (s3184 << 7);
-  const SWord8 s3189 = 128 | s3188;
-  const SWord8 s3190 = 127 & s3188;
-  const SWord8 s3191 = s3187 ? s3189 : s3190;
-  const SWord8 s3192 = s3120 ? s3183 : s3191;
-  const SWord8 s3193 = s1 + s3175;
-  const SBool  s3194 = s3193 < s1;
-  const SBool  s3195 = s3193 < s3175;
-  const SBool  s3196 = s3194 || s3195;
-  const SWord8 s3197 = (s3193 >> 1) | (s3193 << 7);
-  const SWord8 s3198 = 128 | s3197;
-  const SWord8 s3199 = 127 & s3197;
-  const SWord8 s3200 = s3196 ? s3198 : s3199;
-  const SWord8 s3201 = (s3200 >> 1) | (s3200 << 7);
-  const SWord8 s3202 = 128 | s3201;
-  const SWord8 s3203 = 127 & s3201;
-  const SWord8 s3204 = s3119 ? s3202 : s3203;
-  const SWord8 s3205 = s1 + s3200;
-  const SBool  s3206 = s3205 < s1;
-  const SBool  s3207 = s3205 < s3200;
-  const SBool  s3208 = s3206 || s3207;
-  const SWord8 s3209 = (s3205 >> 1) | (s3205 << 7);
-  const SWord8 s3210 = 128 | s3209;
-  const SWord8 s3211 = 127 & s3209;
-  const SWord8 s3212 = s3208 ? s3210 : s3211;
-  const SWord8 s3213 = s3120 ? s3204 : s3212;
-  const SWord8 s3214 = s3101 ? s3192 : s3213;
-  const SWord8 s3215 = s3082 ? s3167 : s3214;
-  const SWord8 s3216 = s1 + s3105;
-  const SBool  s3217 = (SBool) (s3216 & 1);
-  const SBool  s3218 = false != s3217;
-  const SWord8 s3219 = s3218 ? s3109 : s3110;
-  const SBool  s3220 = (SBool) (s3219 & 1);
-  const SBool  s3221 = false != s3220;
-  const SWord8 s3222 = s3221 ? s3115 : s3116;
-  const SBool  s3223 = (SBool) (s3222 & 1);
-  const SBool  s3224 = false != s3223;
-  const SBool  s3225 = !s3224;
-  const SBool  s3226 = s3216 < s1;
-  const SBool  s3227 = s3216 < s3105;
-  const SBool  s3228 = s3226 || s3227;
-  const SWord8 s3229 = (s3216 >> 1) | (s3216 << 7);
-  const SWord8 s3230 = 128 | s3229;
-  const SWord8 s3231 = 127 & s3229;
-  const SWord8 s3232 = s3228 ? s3230 : s3231;
-  const SWord8 s3233 = (s3232 >> 1) | (s3232 << 7);
-  const SWord8 s3234 = 128 | s3233;
-  const SWord8 s3235 = 127 & s3233;
-  const SWord8 s3236 = s3081 ? s3234 : s3235;
-  const SWord8 s3237 = (s3236 >> 1) | (s3236 << 7);
-  const SWord8 s3238 = 128 | s3237;
-  const SWord8 s3239 = 127 & s3237;
-  const SWord8 s3240 = s3100 ? s3238 : s3239;
-  const SWord8 s3241 = (s3240 >> 1) | (s3240 << 7);
-  const SWord8 s3242 = 128 | s3241;
-  const SWord8 s3243 = 127 & s3241;
-  const SWord8 s3244 = s3224 ? s3242 : s3243;
-  const SWord8 s3245 = s1 + s3240;
-  const SBool  s3246 = s3245 < s1;
-  const SBool  s3247 = s3245 < s3240;
-  const SBool  s3248 = s3246 || s3247;
-  const SWord8 s3249 = (s3245 >> 1) | (s3245 << 7);
-  const SWord8 s3250 = 128 | s3249;
-  const SWord8 s3251 = 127 & s3249;
-  const SWord8 s3252 = s3248 ? s3250 : s3251;
-  const SWord8 s3253 = s3225 ? s3244 : s3252;
-  const SWord8 s3254 = s1 + s3236;
-  const SBool  s3255 = s3254 < s1;
-  const SBool  s3256 = s3254 < s3236;
-  const SBool  s3257 = s3255 || s3256;
-  const SWord8 s3258 = (s3254 >> 1) | (s3254 << 7);
-  const SWord8 s3259 = 128 | s3258;
-  const SWord8 s3260 = 127 & s3258;
-  const SWord8 s3261 = s3257 ? s3259 : s3260;
-  const SWord8 s3262 = (s3261 >> 1) | (s3261 << 7);
-  const SWord8 s3263 = 128 | s3262;
-  const SWord8 s3264 = 127 & s3262;
-  const SWord8 s3265 = s3224 ? s3263 : s3264;
-  const SWord8 s3266 = s1 + s3261;
-  const SBool  s3267 = s3266 < s1;
-  const SBool  s3268 = s3266 < s3261;
-  const SBool  s3269 = s3267 || s3268;
-  const SWord8 s3270 = (s3266 >> 1) | (s3266 << 7);
-  const SWord8 s3271 = 128 | s3270;
-  const SWord8 s3272 = 127 & s3270;
-  const SWord8 s3273 = s3269 ? s3271 : s3272;
-  const SWord8 s3274 = s3225 ? s3265 : s3273;
-  const SWord8 s3275 = s3101 ? s3253 : s3274;
-  const SWord8 s3276 = s1 + s3232;
-  const SBool  s3277 = s3276 < s1;
-  const SBool  s3278 = s3276 < s3232;
-  const SBool  s3279 = s3277 || s3278;
-  const SWord8 s3280 = (s3276 >> 1) | (s3276 << 7);
-  const SWord8 s3281 = 128 | s3280;
-  const SWord8 s3282 = 127 & s3280;
-  const SWord8 s3283 = s3279 ? s3281 : s3282;
-  const SWord8 s3284 = (s3283 >> 1) | (s3283 << 7);
-  const SWord8 s3285 = 128 | s3284;
-  const SWord8 s3286 = 127 & s3284;
-  const SWord8 s3287 = s3100 ? s3285 : s3286;
-  const SWord8 s3288 = (s3287 >> 1) | (s3287 << 7);
-  const SWord8 s3289 = 128 | s3288;
-  const SWord8 s3290 = 127 & s3288;
-  const SWord8 s3291 = s3224 ? s3289 : s3290;
-  const SWord8 s3292 = s1 + s3287;
-  const SBool  s3293 = s3292 < s1;
-  const SBool  s3294 = s3292 < s3287;
-  const SBool  s3295 = s3293 || s3294;
-  const SWord8 s3296 = (s3292 >> 1) | (s3292 << 7);
-  const SWord8 s3297 = 128 | s3296;
-  const SWord8 s3298 = 127 & s3296;
-  const SWord8 s3299 = s3295 ? s3297 : s3298;
-  const SWord8 s3300 = s3225 ? s3291 : s3299;
-  const SWord8 s3301 = s1 + s3283;
-  const SBool  s3302 = s3301 < s1;
-  const SBool  s3303 = s3301 < s3283;
-  const SBool  s3304 = s3302 || s3303;
-  const SWord8 s3305 = (s3301 >> 1) | (s3301 << 7);
-  const SWord8 s3306 = 128 | s3305;
-  const SWord8 s3307 = 127 & s3305;
-  const SWord8 s3308 = s3304 ? s3306 : s3307;
-  const SWord8 s3309 = (s3308 >> 1) | (s3308 << 7);
-  const SWord8 s3310 = 128 | s3309;
-  const SWord8 s3311 = 127 & s3309;
-  const SWord8 s3312 = s3224 ? s3310 : s3311;
-  const SWord8 s3313 = s1 + s3308;
-  const SBool  s3314 = s3313 < s1;
-  const SBool  s3315 = s3313 < s3308;
-  const SBool  s3316 = s3314 || s3315;
-  const SWord8 s3317 = (s3313 >> 1) | (s3313 << 7);
-  const SWord8 s3318 = 128 | s3317;
-  const SWord8 s3319 = 127 & s3317;
-  const SWord8 s3320 = s3316 ? s3318 : s3319;
-  const SWord8 s3321 = s3225 ? s3312 : s3320;
-  const SWord8 s3322 = s3101 ? s3300 : s3321;
-  const SWord8 s3323 = s3082 ? s3275 : s3322;
-  const SWord8 s3324 = s3060 ? s3215 : s3323;
-  const SWord8 s3325 = s1 + s3086;
-  const SBool  s3326 = (SBool) (s3325 & 1);
-  const SBool  s3327 = false != s3326;
-  const SWord8 s3328 = s3327 ? s3090 : s3091;
-  const SBool  s3329 = (SBool) (s3328 & 1);
-  const SBool  s3330 = false != s3329;
-  const SWord8 s3331 = s3330 ? s3096 : s3097;
-  const SBool  s3332 = (SBool) (s3331 & 1);
-  const SBool  s3333 = false != s3332;
-  const SBool  s3334 = !s3333;
-  const SBool  s3335 = s3325 < s1;
-  const SBool  s3336 = s3325 < s3086;
-  const SBool  s3337 = s3335 || s3336;
-  const SWord8 s3338 = (s3325 >> 1) | (s3325 << 7);
-  const SWord8 s3339 = 128 | s3338;
-  const SWord8 s3340 = 127 & s3338;
-  const SWord8 s3341 = s3337 ? s3339 : s3340;
-  const SBool  s3342 = (SBool) (s3341 & 1);
-  const SBool  s3343 = false != s3342;
-  const SWord8 s3344 = (s3328 >> 1) | (s3328 << 7);
-  const SWord8 s3345 = 128 | s3344;
-  const SWord8 s3346 = 127 & s3344;
-  const SWord8 s3347 = s3343 ? s3345 : s3346;
-  const SBool  s3348 = (SBool) (s3347 & 1);
-  const SBool  s3349 = false != s3348;
-  const SWord8 s3350 = (s3331 >> 1) | (s3331 << 7);
-  const SWord8 s3351 = 128 | s3350;
-  const SWord8 s3352 = 127 & s3350;
-  const SWord8 s3353 = s3349 ? s3351 : s3352;
-  const SBool  s3354 = (SBool) (s3353 & 1);
-  const SBool  s3355 = false != s3354;
-  const SBool  s3356 = !s3355;
-  const SWord8 s3357 = (s3341 >> 1) | (s3341 << 7);
-  const SWord8 s3358 = 128 | s3357;
-  const SWord8 s3359 = 127 & s3357;
-  const SWord8 s3360 = s3059 ? s3358 : s3359;
-  const SWord8 s3361 = (s3360 >> 1) | (s3360 << 7);
-  const SWord8 s3362 = 128 | s3361;
-  const SWord8 s3363 = 127 & s3361;
-  const SWord8 s3364 = s3081 ? s3362 : s3363;
-  const SWord8 s3365 = (s3364 >> 1) | (s3364 << 7);
-  const SWord8 s3366 = 128 | s3365;
-  const SWord8 s3367 = 127 & s3365;
-  const SWord8 s3368 = s3333 ? s3366 : s3367;
-  const SWord8 s3369 = (s3368 >> 1) | (s3368 << 7);
-  const SWord8 s3370 = 128 | s3369;
-  const SWord8 s3371 = 127 & s3369;
-  const SWord8 s3372 = s3355 ? s3370 : s3371;
-  const SWord8 s3373 = s1 + s3368;
-  const SBool  s3374 = s3373 < s1;
-  const SBool  s3375 = s3373 < s3368;
-  const SBool  s3376 = s3374 || s3375;
-  const SWord8 s3377 = (s3373 >> 1) | (s3373 << 7);
-  const SWord8 s3378 = 128 | s3377;
-  const SWord8 s3379 = 127 & s3377;
-  const SWord8 s3380 = s3376 ? s3378 : s3379;
-  const SWord8 s3381 = s3356 ? s3372 : s3380;
-  const SWord8 s3382 = s1 + s3364;
-  const SBool  s3383 = s3382 < s1;
-  const SBool  s3384 = s3382 < s3364;
-  const SBool  s3385 = s3383 || s3384;
-  const SWord8 s3386 = (s3382 >> 1) | (s3382 << 7);
-  const SWord8 s3387 = 128 | s3386;
-  const SWord8 s3388 = 127 & s3386;
-  const SWord8 s3389 = s3385 ? s3387 : s3388;
-  const SWord8 s3390 = (s3389 >> 1) | (s3389 << 7);
-  const SWord8 s3391 = 128 | s3390;
-  const SWord8 s3392 = 127 & s3390;
-  const SWord8 s3393 = s3355 ? s3391 : s3392;
-  const SWord8 s3394 = s1 + s3389;
-  const SBool  s3395 = s3394 < s1;
-  const SBool  s3396 = s3394 < s3389;
-  const SBool  s3397 = s3395 || s3396;
-  const SWord8 s3398 = (s3394 >> 1) | (s3394 << 7);
-  const SWord8 s3399 = 128 | s3398;
-  const SWord8 s3400 = 127 & s3398;
-  const SWord8 s3401 = s3397 ? s3399 : s3400;
-  const SWord8 s3402 = s3356 ? s3393 : s3401;
-  const SWord8 s3403 = s3334 ? s3381 : s3402;
-  const SWord8 s3404 = s1 + s3360;
-  const SBool  s3405 = s3404 < s1;
-  const SBool  s3406 = s3404 < s3360;
-  const SBool  s3407 = s3405 || s3406;
-  const SWord8 s3408 = (s3404 >> 1) | (s3404 << 7);
-  const SWord8 s3409 = 128 | s3408;
-  const SWord8 s3410 = 127 & s3408;
-  const SWord8 s3411 = s3407 ? s3409 : s3410;
-  const SWord8 s3412 = (s3411 >> 1) | (s3411 << 7);
-  const SWord8 s3413 = 128 | s3412;
-  const SWord8 s3414 = 127 & s3412;
-  const SWord8 s3415 = s3333 ? s3413 : s3414;
-  const SWord8 s3416 = (s3415 >> 1) | (s3415 << 7);
-  const SWord8 s3417 = 128 | s3416;
-  const SWord8 s3418 = 127 & s3416;
-  const SWord8 s3419 = s3355 ? s3417 : s3418;
-  const SWord8 s3420 = s1 + s3415;
-  const SBool  s3421 = s3420 < s1;
-  const SBool  s3422 = s3420 < s3415;
-  const SBool  s3423 = s3421 || s3422;
-  const SWord8 s3424 = (s3420 >> 1) | (s3420 << 7);
-  const SWord8 s3425 = 128 | s3424;
-  const SWord8 s3426 = 127 & s3424;
-  const SWord8 s3427 = s3423 ? s3425 : s3426;
-  const SWord8 s3428 = s3356 ? s3419 : s3427;
-  const SWord8 s3429 = s1 + s3411;
-  const SBool  s3430 = s3429 < s1;
-  const SBool  s3431 = s3429 < s3411;
-  const SBool  s3432 = s3430 || s3431;
-  const SWord8 s3433 = (s3429 >> 1) | (s3429 << 7);
-  const SWord8 s3434 = 128 | s3433;
-  const SWord8 s3435 = 127 & s3433;
-  const SWord8 s3436 = s3432 ? s3434 : s3435;
-  const SWord8 s3437 = (s3436 >> 1) | (s3436 << 7);
-  const SWord8 s3438 = 128 | s3437;
-  const SWord8 s3439 = 127 & s3437;
-  const SWord8 s3440 = s3355 ? s3438 : s3439;
-  const SWord8 s3441 = s1 + s3436;
-  const SBool  s3442 = s3441 < s1;
-  const SBool  s3443 = s3441 < s3436;
-  const SBool  s3444 = s3442 || s3443;
-  const SWord8 s3445 = (s3441 >> 1) | (s3441 << 7);
-  const SWord8 s3446 = 128 | s3445;
-  const SWord8 s3447 = 127 & s3445;
-  const SWord8 s3448 = s3444 ? s3446 : s3447;
-  const SWord8 s3449 = s3356 ? s3440 : s3448;
-  const SWord8 s3450 = s3334 ? s3428 : s3449;
-  const SWord8 s3451 = s3082 ? s3403 : s3450;
-  const SWord8 s3452 = s1 + s3341;
-  const SBool  s3453 = (SBool) (s3452 & 1);
-  const SBool  s3454 = false != s3453;
-  const SWord8 s3455 = s3454 ? s3345 : s3346;
-  const SBool  s3456 = (SBool) (s3455 & 1);
-  const SBool  s3457 = false != s3456;
-  const SWord8 s3458 = s3457 ? s3351 : s3352;
-  const SBool  s3459 = (SBool) (s3458 & 1);
-  const SBool  s3460 = false != s3459;
-  const SBool  s3461 = !s3460;
-  const SBool  s3462 = s3452 < s1;
-  const SBool  s3463 = s3452 < s3341;
-  const SBool  s3464 = s3462 || s3463;
-  const SWord8 s3465 = (s3452 >> 1) | (s3452 << 7);
-  const SWord8 s3466 = 128 | s3465;
-  const SWord8 s3467 = 127 & s3465;
-  const SWord8 s3468 = s3464 ? s3466 : s3467;
-  const SWord8 s3469 = (s3468 >> 1) | (s3468 << 7);
-  const SWord8 s3470 = 128 | s3469;
-  const SWord8 s3471 = 127 & s3469;
-  const SWord8 s3472 = s3081 ? s3470 : s3471;
-  const SWord8 s3473 = (s3472 >> 1) | (s3472 << 7);
-  const SWord8 s3474 = 128 | s3473;
-  const SWord8 s3475 = 127 & s3473;
-  const SWord8 s3476 = s3333 ? s3474 : s3475;
-  const SWord8 s3477 = (s3476 >> 1) | (s3476 << 7);
-  const SWord8 s3478 = 128 | s3477;
-  const SWord8 s3479 = 127 & s3477;
-  const SWord8 s3480 = s3460 ? s3478 : s3479;
-  const SWord8 s3481 = s1 + s3476;
-  const SBool  s3482 = s3481 < s1;
-  const SBool  s3483 = s3481 < s3476;
-  const SBool  s3484 = s3482 || s3483;
-  const SWord8 s3485 = (s3481 >> 1) | (s3481 << 7);
-  const SWord8 s3486 = 128 | s3485;
-  const SWord8 s3487 = 127 & s3485;
-  const SWord8 s3488 = s3484 ? s3486 : s3487;
-  const SWord8 s3489 = s3461 ? s3480 : s3488;
-  const SWord8 s3490 = s1 + s3472;
-  const SBool  s3491 = s3490 < s1;
-  const SBool  s3492 = s3490 < s3472;
-  const SBool  s3493 = s3491 || s3492;
-  const SWord8 s3494 = (s3490 >> 1) | (s3490 << 7);
-  const SWord8 s3495 = 128 | s3494;
-  const SWord8 s3496 = 127 & s3494;
-  const SWord8 s3497 = s3493 ? s3495 : s3496;
-  const SWord8 s3498 = (s3497 >> 1) | (s3497 << 7);
-  const SWord8 s3499 = 128 | s3498;
-  const SWord8 s3500 = 127 & s3498;
-  const SWord8 s3501 = s3460 ? s3499 : s3500;
-  const SWord8 s3502 = s1 + s3497;
-  const SBool  s3503 = s3502 < s1;
-  const SBool  s3504 = s3502 < s3497;
-  const SBool  s3505 = s3503 || s3504;
-  const SWord8 s3506 = (s3502 >> 1) | (s3502 << 7);
-  const SWord8 s3507 = 128 | s3506;
-  const SWord8 s3508 = 127 & s3506;
-  const SWord8 s3509 = s3505 ? s3507 : s3508;
-  const SWord8 s3510 = s3461 ? s3501 : s3509;
-  const SWord8 s3511 = s3334 ? s3489 : s3510;
-  const SWord8 s3512 = s1 + s3468;
-  const SBool  s3513 = s3512 < s1;
-  const SBool  s3514 = s3512 < s3468;
-  const SBool  s3515 = s3513 || s3514;
-  const SWord8 s3516 = (s3512 >> 1) | (s3512 << 7);
-  const SWord8 s3517 = 128 | s3516;
-  const SWord8 s3518 = 127 & s3516;
-  const SWord8 s3519 = s3515 ? s3517 : s3518;
-  const SWord8 s3520 = (s3519 >> 1) | (s3519 << 7);
-  const SWord8 s3521 = 128 | s3520;
-  const SWord8 s3522 = 127 & s3520;
-  const SWord8 s3523 = s3333 ? s3521 : s3522;
-  const SWord8 s3524 = (s3523 >> 1) | (s3523 << 7);
-  const SWord8 s3525 = 128 | s3524;
-  const SWord8 s3526 = 127 & s3524;
-  const SWord8 s3527 = s3460 ? s3525 : s3526;
-  const SWord8 s3528 = s1 + s3523;
-  const SBool  s3529 = s3528 < s1;
-  const SBool  s3530 = s3528 < s3523;
-  const SBool  s3531 = s3529 || s3530;
-  const SWord8 s3532 = (s3528 >> 1) | (s3528 << 7);
-  const SWord8 s3533 = 128 | s3532;
-  const SWord8 s3534 = 127 & s3532;
-  const SWord8 s3535 = s3531 ? s3533 : s3534;
-  const SWord8 s3536 = s3461 ? s3527 : s3535;
-  const SWord8 s3537 = s1 + s3519;
-  const SBool  s3538 = s3537 < s1;
-  const SBool  s3539 = s3537 < s3519;
-  const SBool  s3540 = s3538 || s3539;
-  const SWord8 s3541 = (s3537 >> 1) | (s3537 << 7);
-  const SWord8 s3542 = 128 | s3541;
-  const SWord8 s3543 = 127 & s3541;
-  const SWord8 s3544 = s3540 ? s3542 : s3543;
-  const SWord8 s3545 = (s3544 >> 1) | (s3544 << 7);
-  const SWord8 s3546 = 128 | s3545;
-  const SWord8 s3547 = 127 & s3545;
-  const SWord8 s3548 = s3460 ? s3546 : s3547;
-  const SWord8 s3549 = s1 + s3544;
-  const SBool  s3550 = s3549 < s1;
-  const SBool  s3551 = s3549 < s3544;
-  const SBool  s3552 = s3550 || s3551;
-  const SWord8 s3553 = (s3549 >> 1) | (s3549 << 7);
-  const SWord8 s3554 = 128 | s3553;
-  const SWord8 s3555 = 127 & s3553;
-  const SWord8 s3556 = s3552 ? s3554 : s3555;
-  const SWord8 s3557 = s3461 ? s3548 : s3556;
-  const SWord8 s3558 = s3334 ? s3536 : s3557;
-  const SWord8 s3559 = s3082 ? s3511 : s3558;
-  const SWord8 s3560 = s3060 ? s3451 : s3559;
-  const SWord8 s3561 = s2042 ? s3324 : s3560;
-  const SWord8 s3562 = s1 + s3067;
-  const SBool  s3563 = (SBool) (s3562 & 1);
-  const SBool  s3564 = false != s3563;
-  const SWord8 s3565 = s3564 ? s3071 : s3072;
-  const SBool  s3566 = (SBool) (s3565 & 1);
-  const SBool  s3567 = false != s3566;
-  const SWord8 s3568 = s3567 ? s3077 : s3078;
-  const SBool  s3569 = (SBool) (s3568 & 1);
-  const SBool  s3570 = false != s3569;
-  const SBool  s3571 = !s3570;
-  const SBool  s3572 = s3562 < s1;
-  const SBool  s3573 = s3562 < s3067;
-  const SBool  s3574 = s3572 || s3573;
-  const SWord8 s3575 = (s3562 >> 1) | (s3562 << 7);
-  const SWord8 s3576 = 128 | s3575;
-  const SWord8 s3577 = 127 & s3575;
-  const SWord8 s3578 = s3574 ? s3576 : s3577;
-  const SBool  s3579 = (SBool) (s3578 & 1);
-  const SBool  s3580 = false != s3579;
-  const SWord8 s3581 = (s3565 >> 1) | (s3565 << 7);
-  const SWord8 s3582 = 128 | s3581;
-  const SWord8 s3583 = 127 & s3581;
-  const SWord8 s3584 = s3580 ? s3582 : s3583;
-  const SBool  s3585 = (SBool) (s3584 & 1);
-  const SBool  s3586 = false != s3585;
-  const SWord8 s3587 = (s3568 >> 1) | (s3568 << 7);
-  const SWord8 s3588 = 128 | s3587;
-  const SWord8 s3589 = 127 & s3587;
-  const SWord8 s3590 = s3586 ? s3588 : s3589;
-  const SBool  s3591 = (SBool) (s3590 & 1);
-  const SBool  s3592 = false != s3591;
-  const SBool  s3593 = !s3592;
-  const SWord8 s3594 = (s3578 >> 1) | (s3578 << 7);
-  const SWord8 s3595 = 128 | s3594;
-  const SWord8 s3596 = 127 & s3594;
-  const SWord8 s3597 = s2041 ? s3595 : s3596;
-  const SBool  s3598 = (SBool) (s3597 & 1);
-  const SBool  s3599 = false != s3598;
-  const SWord8 s3600 = (s3584 >> 1) | (s3584 << 7);
-  const SWord8 s3601 = 128 | s3600;
-  const SWord8 s3602 = 127 & s3600;
-  const SWord8 s3603 = s3599 ? s3601 : s3602;
-  const SBool  s3604 = (SBool) (s3603 & 1);
-  const SBool  s3605 = false != s3604;
-  const SWord8 s3606 = (s3590 >> 1) | (s3590 << 7);
-  const SWord8 s3607 = 128 | s3606;
-  const SWord8 s3608 = 127 & s3606;
-  const SWord8 s3609 = s3605 ? s3607 : s3608;
-  const SBool  s3610 = (SBool) (s3609 & 1);
-  const SBool  s3611 = false != s3610;
-  const SBool  s3612 = !s3611;
-  const SWord8 s3613 = (s3597 >> 1) | (s3597 << 7);
-  const SWord8 s3614 = 128 | s3613;
-  const SWord8 s3615 = 127 & s3613;
-  const SWord8 s3616 = s3059 ? s3614 : s3615;
-  const SWord8 s3617 = (s3616 >> 1) | (s3616 << 7);
-  const SWord8 s3618 = 128 | s3617;
-  const SWord8 s3619 = 127 & s3617;
-  const SWord8 s3620 = s3570 ? s3618 : s3619;
-  const SWord8 s3621 = (s3620 >> 1) | (s3620 << 7);
-  const SWord8 s3622 = 128 | s3621;
-  const SWord8 s3623 = 127 & s3621;
-  const SWord8 s3624 = s3592 ? s3622 : s3623;
-  const SWord8 s3625 = (s3624 >> 1) | (s3624 << 7);
-  const SWord8 s3626 = 128 | s3625;
-  const SWord8 s3627 = 127 & s3625;
-  const SWord8 s3628 = s3611 ? s3626 : s3627;
-  const SWord8 s3629 = s1 + s3624;
-  const SBool  s3630 = s3629 < s1;
-  const SBool  s3631 = s3629 < s3624;
-  const SBool  s3632 = s3630 || s3631;
-  const SWord8 s3633 = (s3629 >> 1) | (s3629 << 7);
-  const SWord8 s3634 = 128 | s3633;
-  const SWord8 s3635 = 127 & s3633;
-  const SWord8 s3636 = s3632 ? s3634 : s3635;
-  const SWord8 s3637 = s3612 ? s3628 : s3636;
-  const SWord8 s3638 = s1 + s3620;
-  const SBool  s3639 = s3638 < s1;
-  const SBool  s3640 = s3638 < s3620;
-  const SBool  s3641 = s3639 || s3640;
-  const SWord8 s3642 = (s3638 >> 1) | (s3638 << 7);
-  const SWord8 s3643 = 128 | s3642;
-  const SWord8 s3644 = 127 & s3642;
-  const SWord8 s3645 = s3641 ? s3643 : s3644;
-  const SWord8 s3646 = (s3645 >> 1) | (s3645 << 7);
-  const SWord8 s3647 = 128 | s3646;
-  const SWord8 s3648 = 127 & s3646;
-  const SWord8 s3649 = s3611 ? s3647 : s3648;
-  const SWord8 s3650 = s1 + s3645;
-  const SBool  s3651 = s3650 < s1;
-  const SBool  s3652 = s3650 < s3645;
-  const SBool  s3653 = s3651 || s3652;
-  const SWord8 s3654 = (s3650 >> 1) | (s3650 << 7);
-  const SWord8 s3655 = 128 | s3654;
-  const SWord8 s3656 = 127 & s3654;
-  const SWord8 s3657 = s3653 ? s3655 : s3656;
-  const SWord8 s3658 = s3612 ? s3649 : s3657;
-  const SWord8 s3659 = s3593 ? s3637 : s3658;
-  const SWord8 s3660 = s1 + s3616;
-  const SBool  s3661 = s3660 < s1;
-  const SBool  s3662 = s3660 < s3616;
-  const SBool  s3663 = s3661 || s3662;
-  const SWord8 s3664 = (s3660 >> 1) | (s3660 << 7);
-  const SWord8 s3665 = 128 | s3664;
-  const SWord8 s3666 = 127 & s3664;
-  const SWord8 s3667 = s3663 ? s3665 : s3666;
-  const SWord8 s3668 = (s3667 >> 1) | (s3667 << 7);
-  const SWord8 s3669 = 128 | s3668;
-  const SWord8 s3670 = 127 & s3668;
-  const SWord8 s3671 = s3592 ? s3669 : s3670;
-  const SWord8 s3672 = (s3671 >> 1) | (s3671 << 7);
-  const SWord8 s3673 = 128 | s3672;
-  const SWord8 s3674 = 127 & s3672;
-  const SWord8 s3675 = s3611 ? s3673 : s3674;
-  const SWord8 s3676 = s1 + s3671;
-  const SBool  s3677 = s3676 < s1;
-  const SBool  s3678 = s3676 < s3671;
-  const SBool  s3679 = s3677 || s3678;
-  const SWord8 s3680 = (s3676 >> 1) | (s3676 << 7);
-  const SWord8 s3681 = 128 | s3680;
-  const SWord8 s3682 = 127 & s3680;
-  const SWord8 s3683 = s3679 ? s3681 : s3682;
-  const SWord8 s3684 = s3612 ? s3675 : s3683;
-  const SWord8 s3685 = s1 + s3667;
-  const SBool  s3686 = s3685 < s1;
-  const SBool  s3687 = s3685 < s3667;
-  const SBool  s3688 = s3686 || s3687;
-  const SWord8 s3689 = (s3685 >> 1) | (s3685 << 7);
-  const SWord8 s3690 = 128 | s3689;
-  const SWord8 s3691 = 127 & s3689;
-  const SWord8 s3692 = s3688 ? s3690 : s3691;
-  const SWord8 s3693 = (s3692 >> 1) | (s3692 << 7);
-  const SWord8 s3694 = 128 | s3693;
-  const SWord8 s3695 = 127 & s3693;
-  const SWord8 s3696 = s3611 ? s3694 : s3695;
-  const SWord8 s3697 = s1 + s3692;
-  const SBool  s3698 = s3697 < s1;
-  const SBool  s3699 = s3697 < s3692;
-  const SBool  s3700 = s3698 || s3699;
-  const SWord8 s3701 = (s3697 >> 1) | (s3697 << 7);
-  const SWord8 s3702 = 128 | s3701;
-  const SWord8 s3703 = 127 & s3701;
-  const SWord8 s3704 = s3700 ? s3702 : s3703;
-  const SWord8 s3705 = s3612 ? s3696 : s3704;
-  const SWord8 s3706 = s3593 ? s3684 : s3705;
-  const SWord8 s3707 = s3571 ? s3659 : s3706;
-  const SWord8 s3708 = s1 + s3597;
-  const SBool  s3709 = (SBool) (s3708 & 1);
-  const SBool  s3710 = false != s3709;
-  const SWord8 s3711 = s3710 ? s3601 : s3602;
-  const SBool  s3712 = (SBool) (s3711 & 1);
-  const SBool  s3713 = false != s3712;
-  const SWord8 s3714 = s3713 ? s3607 : s3608;
-  const SBool  s3715 = (SBool) (s3714 & 1);
-  const SBool  s3716 = false != s3715;
-  const SBool  s3717 = !s3716;
-  const SBool  s3718 = s3708 < s1;
-  const SBool  s3719 = s3708 < s3597;
-  const SBool  s3720 = s3718 || s3719;
-  const SWord8 s3721 = (s3708 >> 1) | (s3708 << 7);
-  const SWord8 s3722 = 128 | s3721;
-  const SWord8 s3723 = 127 & s3721;
-  const SWord8 s3724 = s3720 ? s3722 : s3723;
-  const SWord8 s3725 = (s3724 >> 1) | (s3724 << 7);
-  const SWord8 s3726 = 128 | s3725;
-  const SWord8 s3727 = 127 & s3725;
-  const SWord8 s3728 = s3570 ? s3726 : s3727;
-  const SWord8 s3729 = (s3728 >> 1) | (s3728 << 7);
-  const SWord8 s3730 = 128 | s3729;
-  const SWord8 s3731 = 127 & s3729;
-  const SWord8 s3732 = s3592 ? s3730 : s3731;
-  const SWord8 s3733 = (s3732 >> 1) | (s3732 << 7);
-  const SWord8 s3734 = 128 | s3733;
-  const SWord8 s3735 = 127 & s3733;
-  const SWord8 s3736 = s3716 ? s3734 : s3735;
-  const SWord8 s3737 = s1 + s3732;
-  const SBool  s3738 = s3737 < s1;
-  const SBool  s3739 = s3737 < s3732;
-  const SBool  s3740 = s3738 || s3739;
-  const SWord8 s3741 = (s3737 >> 1) | (s3737 << 7);
-  const SWord8 s3742 = 128 | s3741;
-  const SWord8 s3743 = 127 & s3741;
-  const SWord8 s3744 = s3740 ? s3742 : s3743;
-  const SWord8 s3745 = s3717 ? s3736 : s3744;
-  const SWord8 s3746 = s1 + s3728;
-  const SBool  s3747 = s3746 < s1;
-  const SBool  s3748 = s3746 < s3728;
-  const SBool  s3749 = s3747 || s3748;
-  const SWord8 s3750 = (s3746 >> 1) | (s3746 << 7);
-  const SWord8 s3751 = 128 | s3750;
-  const SWord8 s3752 = 127 & s3750;
-  const SWord8 s3753 = s3749 ? s3751 : s3752;
-  const SWord8 s3754 = (s3753 >> 1) | (s3753 << 7);
-  const SWord8 s3755 = 128 | s3754;
-  const SWord8 s3756 = 127 & s3754;
-  const SWord8 s3757 = s3716 ? s3755 : s3756;
-  const SWord8 s3758 = s1 + s3753;
-  const SBool  s3759 = s3758 < s1;
-  const SBool  s3760 = s3758 < s3753;
-  const SBool  s3761 = s3759 || s3760;
-  const SWord8 s3762 = (s3758 >> 1) | (s3758 << 7);
-  const SWord8 s3763 = 128 | s3762;
-  const SWord8 s3764 = 127 & s3762;
-  const SWord8 s3765 = s3761 ? s3763 : s3764;
-  const SWord8 s3766 = s3717 ? s3757 : s3765;
-  const SWord8 s3767 = s3593 ? s3745 : s3766;
-  const SWord8 s3768 = s1 + s3724;
-  const SBool  s3769 = s3768 < s1;
-  const SBool  s3770 = s3768 < s3724;
-  const SBool  s3771 = s3769 || s3770;
-  const SWord8 s3772 = (s3768 >> 1) | (s3768 << 7);
-  const SWord8 s3773 = 128 | s3772;
-  const SWord8 s3774 = 127 & s3772;
-  const SWord8 s3775 = s3771 ? s3773 : s3774;
-  const SWord8 s3776 = (s3775 >> 1) | (s3775 << 7);
-  const SWord8 s3777 = 128 | s3776;
-  const SWord8 s3778 = 127 & s3776;
-  const SWord8 s3779 = s3592 ? s3777 : s3778;
-  const SWord8 s3780 = (s3779 >> 1) | (s3779 << 7);
-  const SWord8 s3781 = 128 | s3780;
-  const SWord8 s3782 = 127 & s3780;
-  const SWord8 s3783 = s3716 ? s3781 : s3782;
-  const SWord8 s3784 = s1 + s3779;
-  const SBool  s3785 = s3784 < s1;
-  const SBool  s3786 = s3784 < s3779;
-  const SBool  s3787 = s3785 || s3786;
-  const SWord8 s3788 = (s3784 >> 1) | (s3784 << 7);
-  const SWord8 s3789 = 128 | s3788;
-  const SWord8 s3790 = 127 & s3788;
-  const SWord8 s3791 = s3787 ? s3789 : s3790;
-  const SWord8 s3792 = s3717 ? s3783 : s3791;
-  const SWord8 s3793 = s1 + s3775;
-  const SBool  s3794 = s3793 < s1;
-  const SBool  s3795 = s3793 < s3775;
-  const SBool  s3796 = s3794 || s3795;
-  const SWord8 s3797 = (s3793 >> 1) | (s3793 << 7);
-  const SWord8 s3798 = 128 | s3797;
-  const SWord8 s3799 = 127 & s3797;
-  const SWord8 s3800 = s3796 ? s3798 : s3799;
-  const SWord8 s3801 = (s3800 >> 1) | (s3800 << 7);
-  const SWord8 s3802 = 128 | s3801;
-  const SWord8 s3803 = 127 & s3801;
-  const SWord8 s3804 = s3716 ? s3802 : s3803;
-  const SWord8 s3805 = s1 + s3800;
-  const SBool  s3806 = s3805 < s1;
-  const SBool  s3807 = s3805 < s3800;
-  const SBool  s3808 = s3806 || s3807;
-  const SWord8 s3809 = (s3805 >> 1) | (s3805 << 7);
-  const SWord8 s3810 = 128 | s3809;
-  const SWord8 s3811 = 127 & s3809;
-  const SWord8 s3812 = s3808 ? s3810 : s3811;
-  const SWord8 s3813 = s3717 ? s3804 : s3812;
-  const SWord8 s3814 = s3593 ? s3792 : s3813;
-  const SWord8 s3815 = s3571 ? s3767 : s3814;
-  const SWord8 s3816 = s3060 ? s3707 : s3815;
-  const SWord8 s3817 = s1 + s3578;
-  const SBool  s3818 = (SBool) (s3817 & 1);
-  const SBool  s3819 = false != s3818;
-  const SWord8 s3820 = s3819 ? s3582 : s3583;
-  const SBool  s3821 = (SBool) (s3820 & 1);
-  const SBool  s3822 = false != s3821;
-  const SWord8 s3823 = s3822 ? s3588 : s3589;
-  const SBool  s3824 = (SBool) (s3823 & 1);
-  const SBool  s3825 = false != s3824;
-  const SBool  s3826 = !s3825;
-  const SBool  s3827 = s3817 < s1;
-  const SBool  s3828 = s3817 < s3578;
-  const SBool  s3829 = s3827 || s3828;
-  const SWord8 s3830 = (s3817 >> 1) | (s3817 << 7);
-  const SWord8 s3831 = 128 | s3830;
-  const SWord8 s3832 = 127 & s3830;
-  const SWord8 s3833 = s3829 ? s3831 : s3832;
-  const SBool  s3834 = (SBool) (s3833 & 1);
-  const SBool  s3835 = false != s3834;
-  const SWord8 s3836 = (s3820 >> 1) | (s3820 << 7);
-  const SWord8 s3837 = 128 | s3836;
-  const SWord8 s3838 = 127 & s3836;
-  const SWord8 s3839 = s3835 ? s3837 : s3838;
-  const SBool  s3840 = (SBool) (s3839 & 1);
-  const SBool  s3841 = false != s3840;
-  const SWord8 s3842 = (s3823 >> 1) | (s3823 << 7);
-  const SWord8 s3843 = 128 | s3842;
-  const SWord8 s3844 = 127 & s3842;
-  const SWord8 s3845 = s3841 ? s3843 : s3844;
-  const SBool  s3846 = (SBool) (s3845 & 1);
-  const SBool  s3847 = false != s3846;
-  const SBool  s3848 = !s3847;
-  const SWord8 s3849 = (s3833 >> 1) | (s3833 << 7);
-  const SWord8 s3850 = 128 | s3849;
-  const SWord8 s3851 = 127 & s3849;
-  const SWord8 s3852 = s3059 ? s3850 : s3851;
-  const SWord8 s3853 = (s3852 >> 1) | (s3852 << 7);
-  const SWord8 s3854 = 128 | s3853;
-  const SWord8 s3855 = 127 & s3853;
-  const SWord8 s3856 = s3570 ? s3854 : s3855;
-  const SWord8 s3857 = (s3856 >> 1) | (s3856 << 7);
-  const SWord8 s3858 = 128 | s3857;
-  const SWord8 s3859 = 127 & s3857;
-  const SWord8 s3860 = s3825 ? s3858 : s3859;
-  const SWord8 s3861 = (s3860 >> 1) | (s3860 << 7);
-  const SWord8 s3862 = 128 | s3861;
-  const SWord8 s3863 = 127 & s3861;
-  const SWord8 s3864 = s3847 ? s3862 : s3863;
-  const SWord8 s3865 = s1 + s3860;
-  const SBool  s3866 = s3865 < s1;
-  const SBool  s3867 = s3865 < s3860;
-  const SBool  s3868 = s3866 || s3867;
-  const SWord8 s3869 = (s3865 >> 1) | (s3865 << 7);
-  const SWord8 s3870 = 128 | s3869;
-  const SWord8 s3871 = 127 & s3869;
-  const SWord8 s3872 = s3868 ? s3870 : s3871;
-  const SWord8 s3873 = s3848 ? s3864 : s3872;
-  const SWord8 s3874 = s1 + s3856;
-  const SBool  s3875 = s3874 < s1;
-  const SBool  s3876 = s3874 < s3856;
-  const SBool  s3877 = s3875 || s3876;
-  const SWord8 s3878 = (s3874 >> 1) | (s3874 << 7);
-  const SWord8 s3879 = 128 | s3878;
-  const SWord8 s3880 = 127 & s3878;
-  const SWord8 s3881 = s3877 ? s3879 : s3880;
-  const SWord8 s3882 = (s3881 >> 1) | (s3881 << 7);
-  const SWord8 s3883 = 128 | s3882;
-  const SWord8 s3884 = 127 & s3882;
-  const SWord8 s3885 = s3847 ? s3883 : s3884;
-  const SWord8 s3886 = s1 + s3881;
-  const SBool  s3887 = s3886 < s1;
-  const SBool  s3888 = s3886 < s3881;
-  const SBool  s3889 = s3887 || s3888;
-  const SWord8 s3890 = (s3886 >> 1) | (s3886 << 7);
-  const SWord8 s3891 = 128 | s3890;
-  const SWord8 s3892 = 127 & s3890;
-  const SWord8 s3893 = s3889 ? s3891 : s3892;
-  const SWord8 s3894 = s3848 ? s3885 : s3893;
-  const SWord8 s3895 = s3826 ? s3873 : s3894;
-  const SWord8 s3896 = s1 + s3852;
-  const SBool  s3897 = s3896 < s1;
-  const SBool  s3898 = s3896 < s3852;
-  const SBool  s3899 = s3897 || s3898;
-  const SWord8 s3900 = (s3896 >> 1) | (s3896 << 7);
-  const SWord8 s3901 = 128 | s3900;
-  const SWord8 s3902 = 127 & s3900;
-  const SWord8 s3903 = s3899 ? s3901 : s3902;
-  const SWord8 s3904 = (s3903 >> 1) | (s3903 << 7);
-  const SWord8 s3905 = 128 | s3904;
-  const SWord8 s3906 = 127 & s3904;
-  const SWord8 s3907 = s3825 ? s3905 : s3906;
-  const SWord8 s3908 = (s3907 >> 1) | (s3907 << 7);
-  const SWord8 s3909 = 128 | s3908;
-  const SWord8 s3910 = 127 & s3908;
-  const SWord8 s3911 = s3847 ? s3909 : s3910;
-  const SWord8 s3912 = s1 + s3907;
-  const SBool  s3913 = s3912 < s1;
-  const SBool  s3914 = s3912 < s3907;
-  const SBool  s3915 = s3913 || s3914;
-  const SWord8 s3916 = (s3912 >> 1) | (s3912 << 7);
-  const SWord8 s3917 = 128 | s3916;
-  const SWord8 s3918 = 127 & s3916;
-  const SWord8 s3919 = s3915 ? s3917 : s3918;
-  const SWord8 s3920 = s3848 ? s3911 : s3919;
-  const SWord8 s3921 = s1 + s3903;
-  const SBool  s3922 = s3921 < s1;
-  const SBool  s3923 = s3921 < s3903;
-  const SBool  s3924 = s3922 || s3923;
-  const SWord8 s3925 = (s3921 >> 1) | (s3921 << 7);
-  const SWord8 s3926 = 128 | s3925;
-  const SWord8 s3927 = 127 & s3925;
-  const SWord8 s3928 = s3924 ? s3926 : s3927;
-  const SWord8 s3929 = (s3928 >> 1) | (s3928 << 7);
-  const SWord8 s3930 = 128 | s3929;
-  const SWord8 s3931 = 127 & s3929;
-  const SWord8 s3932 = s3847 ? s3930 : s3931;
-  const SWord8 s3933 = s1 + s3928;
-  const SBool  s3934 = s3933 < s1;
-  const SBool  s3935 = s3933 < s3928;
-  const SBool  s3936 = s3934 || s3935;
-  const SWord8 s3937 = (s3933 >> 1) | (s3933 << 7);
-  const SWord8 s3938 = 128 | s3937;
-  const SWord8 s3939 = 127 & s3937;
-  const SWord8 s3940 = s3936 ? s3938 : s3939;
-  const SWord8 s3941 = s3848 ? s3932 : s3940;
-  const SWord8 s3942 = s3826 ? s3920 : s3941;
-  const SWord8 s3943 = s3571 ? s3895 : s3942;
-  const SWord8 s3944 = s1 + s3833;
-  const SBool  s3945 = (SBool) (s3944 & 1);
-  const SBool  s3946 = false != s3945;
-  const SWord8 s3947 = s3946 ? s3837 : s3838;
-  const SBool  s3948 = (SBool) (s3947 & 1);
-  const SBool  s3949 = false != s3948;
-  const SWord8 s3950 = s3949 ? s3843 : s3844;
-  const SBool  s3951 = (SBool) (s3950 & 1);
-  const SBool  s3952 = false != s3951;
-  const SBool  s3953 = !s3952;
-  const SBool  s3954 = s3944 < s1;
-  const SBool  s3955 = s3944 < s3833;
-  const SBool  s3956 = s3954 || s3955;
-  const SWord8 s3957 = (s3944 >> 1) | (s3944 << 7);
-  const SWord8 s3958 = 128 | s3957;
-  const SWord8 s3959 = 127 & s3957;
-  const SWord8 s3960 = s3956 ? s3958 : s3959;
-  const SWord8 s3961 = (s3960 >> 1) | (s3960 << 7);
-  const SWord8 s3962 = 128 | s3961;
-  const SWord8 s3963 = 127 & s3961;
-  const SWord8 s3964 = s3570 ? s3962 : s3963;
-  const SWord8 s3965 = (s3964 >> 1) | (s3964 << 7);
-  const SWord8 s3966 = 128 | s3965;
-  const SWord8 s3967 = 127 & s3965;
-  const SWord8 s3968 = s3825 ? s3966 : s3967;
-  const SWord8 s3969 = (s3968 >> 1) | (s3968 << 7);
-  const SWord8 s3970 = 128 | s3969;
-  const SWord8 s3971 = 127 & s3969;
-  const SWord8 s3972 = s3952 ? s3970 : s3971;
-  const SWord8 s3973 = s1 + s3968;
-  const SBool  s3974 = s3973 < s1;
-  const SBool  s3975 = s3973 < s3968;
-  const SBool  s3976 = s3974 || s3975;
-  const SWord8 s3977 = (s3973 >> 1) | (s3973 << 7);
-  const SWord8 s3978 = 128 | s3977;
-  const SWord8 s3979 = 127 & s3977;
-  const SWord8 s3980 = s3976 ? s3978 : s3979;
-  const SWord8 s3981 = s3953 ? s3972 : s3980;
-  const SWord8 s3982 = s1 + s3964;
-  const SBool  s3983 = s3982 < s1;
-  const SBool  s3984 = s3982 < s3964;
-  const SBool  s3985 = s3983 || s3984;
-  const SWord8 s3986 = (s3982 >> 1) | (s3982 << 7);
-  const SWord8 s3987 = 128 | s3986;
-  const SWord8 s3988 = 127 & s3986;
-  const SWord8 s3989 = s3985 ? s3987 : s3988;
-  const SWord8 s3990 = (s3989 >> 1) | (s3989 << 7);
-  const SWord8 s3991 = 128 | s3990;
-  const SWord8 s3992 = 127 & s3990;
-  const SWord8 s3993 = s3952 ? s3991 : s3992;
-  const SWord8 s3994 = s1 + s3989;
-  const SBool  s3995 = s3994 < s1;
-  const SBool  s3996 = s3994 < s3989;
-  const SBool  s3997 = s3995 || s3996;
-  const SWord8 s3998 = (s3994 >> 1) | (s3994 << 7);
-  const SWord8 s3999 = 128 | s3998;
-  const SWord8 s4000 = 127 & s3998;
-  const SWord8 s4001 = s3997 ? s3999 : s4000;
-  const SWord8 s4002 = s3953 ? s3993 : s4001;
-  const SWord8 s4003 = s3826 ? s3981 : s4002;
-  const SWord8 s4004 = s1 + s3960;
-  const SBool  s4005 = s4004 < s1;
-  const SBool  s4006 = s4004 < s3960;
-  const SBool  s4007 = s4005 || s4006;
-  const SWord8 s4008 = (s4004 >> 1) | (s4004 << 7);
-  const SWord8 s4009 = 128 | s4008;
-  const SWord8 s4010 = 127 & s4008;
-  const SWord8 s4011 = s4007 ? s4009 : s4010;
-  const SWord8 s4012 = (s4011 >> 1) | (s4011 << 7);
-  const SWord8 s4013 = 128 | s4012;
-  const SWord8 s4014 = 127 & s4012;
-  const SWord8 s4015 = s3825 ? s4013 : s4014;
-  const SWord8 s4016 = (s4015 >> 1) | (s4015 << 7);
-  const SWord8 s4017 = 128 | s4016;
-  const SWord8 s4018 = 127 & s4016;
-  const SWord8 s4019 = s3952 ? s4017 : s4018;
-  const SWord8 s4020 = s1 + s4015;
-  const SBool  s4021 = s4020 < s1;
-  const SBool  s4022 = s4020 < s4015;
-  const SBool  s4023 = s4021 || s4022;
-  const SWord8 s4024 = (s4020 >> 1) | (s4020 << 7);
-  const SWord8 s4025 = 128 | s4024;
-  const SWord8 s4026 = 127 & s4024;
-  const SWord8 s4027 = s4023 ? s4025 : s4026;
-  const SWord8 s4028 = s3953 ? s4019 : s4027;
-  const SWord8 s4029 = s1 + s4011;
-  const SBool  s4030 = s4029 < s1;
-  const SBool  s4031 = s4029 < s4011;
-  const SBool  s4032 = s4030 || s4031;
-  const SWord8 s4033 = (s4029 >> 1) | (s4029 << 7);
-  const SWord8 s4034 = 128 | s4033;
-  const SWord8 s4035 = 127 & s4033;
-  const SWord8 s4036 = s4032 ? s4034 : s4035;
-  const SWord8 s4037 = (s4036 >> 1) | (s4036 << 7);
-  const SWord8 s4038 = 128 | s4037;
-  const SWord8 s4039 = 127 & s4037;
-  const SWord8 s4040 = s3952 ? s4038 : s4039;
-  const SWord8 s4041 = s1 + s4036;
-  const SBool  s4042 = s4041 < s1;
-  const SBool  s4043 = s4041 < s4036;
-  const SBool  s4044 = s4042 || s4043;
-  const SWord8 s4045 = (s4041 >> 1) | (s4041 << 7);
-  const SWord8 s4046 = 128 | s4045;
-  const SWord8 s4047 = 127 & s4045;
-  const SWord8 s4048 = s4044 ? s4046 : s4047;
-  const SWord8 s4049 = s3953 ? s4040 : s4048;
-  const SWord8 s4050 = s3826 ? s4028 : s4049;
-  const SWord8 s4051 = s3571 ? s4003 : s4050;
-  const SWord8 s4052 = s3060 ? s3943 : s4051;
-  const SWord8 s4053 = s2042 ? s3816 : s4052;
-  const SWord8 s4054 = s16 ? s3561 : s4053;
-  const SWord8 s4055 = s11 ? s3050 : s4054;
-  const SWord8 s4056 = s5 ? s2032 : s4055;
-  const SBool  s4057 = (SBool) (s105 & 1);
-  const SBool  s4058 = false != s4057;
-  const SBool  s4059 = (SBool) (s101 & 1);
-  const SBool  s4060 = false != s4059;
-  const SBool  s4061 = (SBool) (s97 & 1);
-  const SBool  s4062 = false != s4061;
-  const SWord8 s4063 = (s84 >> 1) | (s84 << 7);
-  const SWord8 s4064 = 128 | s4063;
-  const SWord8 s4065 = 127 & s4063;
-  const SWord8 s4066 = s4062 ? s4064 : s4065;
-  const SWord8 s4067 = (s4066 >> 1) | (s4066 << 7);
-  const SWord8 s4068 = 128 | s4067;
-  const SWord8 s4069 = 127 & s4067;
-  const SWord8 s4070 = s4060 ? s4068 : s4069;
-  const SWord8 s4071 = (s4070 >> 1) | (s4070 << 7);
-  const SWord8 s4072 = 128 | s4071;
-  const SWord8 s4073 = 127 & s4071;
-  const SWord8 s4074 = s4058 ? s4072 : s4073;
-  const SBool  s4075 = (SBool) (s110 & 1);
-  const SBool  s4076 = false != s4075;
-  const SWord8 s4077 = s4076 ? s4072 : s4073;
-  const SWord8 s4078 = s93 ? s4074 : s4077;
-  const SBool  s4079 = (SBool) (s126 & 1);
-  const SBool  s4080 = false != s4079;
-  const SBool  s4081 = (SBool) (s119 & 1);
-  const SBool  s4082 = false != s4081;
-  const SWord8 s4083 = s4082 ? s4068 : s4069;
-  const SWord8 s4084 = (s4083 >> 1) | (s4083 << 7);
-  const SWord8 s4085 = 128 | s4084;
-  const SWord8 s4086 = 127 & s4084;
-  const SWord8 s4087 = s4080 ? s4085 : s4086;
-  const SBool  s4088 = (SBool) (s131 & 1);
-  const SBool  s4089 = false != s4088;
-  const SWord8 s4090 = s4089 ? s4085 : s4086;
-  const SWord8 s4091 = s93 ? s4087 : s4090;
-  const SWord8 s4092 = s74 ? s4078 : s4091;
-  const SBool  s4093 = (SBool) (s152 & 1);
-  const SBool  s4094 = false != s4093;
-  const SBool  s4095 = (SBool) (s148 & 1);
-  const SBool  s4096 = false != s4095;
-  const SBool  s4097 = (SBool) (s141 & 1);
-  const SBool  s4098 = false != s4097;
-  const SWord8 s4099 = s4098 ? s4064 : s4065;
-  const SWord8 s4100 = (s4099 >> 1) | (s4099 << 7);
-  const SWord8 s4101 = 128 | s4100;
-  const SWord8 s4102 = 127 & s4100;
-  const SWord8 s4103 = s4096 ? s4101 : s4102;
-  const SWord8 s4104 = (s4103 >> 1) | (s4103 << 7);
-  const SWord8 s4105 = 128 | s4104;
-  const SWord8 s4106 = 127 & s4104;
-  const SWord8 s4107 = s4094 ? s4105 : s4106;
-  const SBool  s4108 = (SBool) (s157 & 1);
-  const SBool  s4109 = false != s4108;
-  const SWord8 s4110 = s4109 ? s4105 : s4106;
-  const SWord8 s4111 = s93 ? s4107 : s4110;
-  const SBool  s4112 = (SBool) (s173 & 1);
-  const SBool  s4113 = false != s4112;
-  const SBool  s4114 = (SBool) (s166 & 1);
-  const SBool  s4115 = false != s4114;
-  const SWord8 s4116 = s4115 ? s4101 : s4102;
-  const SWord8 s4117 = (s4116 >> 1) | (s4116 << 7);
-  const SWord8 s4118 = 128 | s4117;
-  const SWord8 s4119 = 127 & s4117;
-  const SWord8 s4120 = s4113 ? s4118 : s4119;
-  const SBool  s4121 = (SBool) (s178 & 1);
-  const SBool  s4122 = false != s4121;
-  const SWord8 s4123 = s4122 ? s4118 : s4119;
-  const SWord8 s4124 = s93 ? s4120 : s4123;
-  const SWord8 s4125 = s74 ? s4111 : s4124;
-  const SWord8 s4126 = s55 ? s4092 : s4125;
-  const SBool  s4127 = (SBool) (s213 & 1);
-  const SBool  s4128 = false != s4127;
-  const SBool  s4129 = (SBool) (s209 & 1);
-  const SBool  s4130 = false != s4129;
-  const SBool  s4131 = (SBool) (s205 & 1);
-  const SBool  s4132 = false != s4131;
-  const SWord8 s4133 = (s192 >> 1) | (s192 << 7);
-  const SWord8 s4134 = 128 | s4133;
-  const SWord8 s4135 = 127 & s4133;
-  const SWord8 s4136 = s4132 ? s4134 : s4135;
-  const SWord8 s4137 = (s4136 >> 1) | (s4136 << 7);
-  const SWord8 s4138 = 128 | s4137;
-  const SWord8 s4139 = 127 & s4137;
-  const SWord8 s4140 = s4130 ? s4138 : s4139;
-  const SWord8 s4141 = (s4140 >> 1) | (s4140 << 7);
-  const SWord8 s4142 = 128 | s4141;
-  const SWord8 s4143 = 127 & s4141;
-  const SWord8 s4144 = s4128 ? s4142 : s4143;
-  const SBool  s4145 = (SBool) (s218 & 1);
-  const SBool  s4146 = false != s4145;
-  const SWord8 s4147 = s4146 ? s4142 : s4143;
-  const SWord8 s4148 = s198 ? s4144 : s4147;
-  const SBool  s4149 = (SBool) (s234 & 1);
-  const SBool  s4150 = false != s4149;
-  const SBool  s4151 = (SBool) (s227 & 1);
-  const SBool  s4152 = false != s4151;
-  const SWord8 s4153 = s4152 ? s4138 : s4139;
-  const SWord8 s4154 = (s4153 >> 1) | (s4153 << 7);
-  const SWord8 s4155 = 128 | s4154;
-  const SWord8 s4156 = 127 & s4154;
-  const SWord8 s4157 = s4150 ? s4155 : s4156;
-  const SBool  s4158 = (SBool) (s239 & 1);
-  const SBool  s4159 = false != s4158;
-  const SWord8 s4160 = s4159 ? s4155 : s4156;
-  const SWord8 s4161 = s198 ? s4157 : s4160;
-  const SWord8 s4162 = s74 ? s4148 : s4161;
-  const SBool  s4163 = (SBool) (s260 & 1);
-  const SBool  s4164 = false != s4163;
-  const SBool  s4165 = (SBool) (s256 & 1);
-  const SBool  s4166 = false != s4165;
-  const SBool  s4167 = (SBool) (s249 & 1);
-  const SBool  s4168 = false != s4167;
-  const SWord8 s4169 = s4168 ? s4134 : s4135;
-  const SWord8 s4170 = (s4169 >> 1) | (s4169 << 7);
-  const SWord8 s4171 = 128 | s4170;
-  const SWord8 s4172 = 127 & s4170;
-  const SWord8 s4173 = s4166 ? s4171 : s4172;
-  const SWord8 s4174 = (s4173 >> 1) | (s4173 << 7);
-  const SWord8 s4175 = 128 | s4174;
-  const SWord8 s4176 = 127 & s4174;
-  const SWord8 s4177 = s4164 ? s4175 : s4176;
-  const SBool  s4178 = (SBool) (s265 & 1);
-  const SBool  s4179 = false != s4178;
-  const SWord8 s4180 = s4179 ? s4175 : s4176;
-  const SWord8 s4181 = s198 ? s4177 : s4180;
-  const SBool  s4182 = (SBool) (s281 & 1);
-  const SBool  s4183 = false != s4182;
-  const SBool  s4184 = (SBool) (s274 & 1);
-  const SBool  s4185 = false != s4184;
-  const SWord8 s4186 = s4185 ? s4171 : s4172;
-  const SWord8 s4187 = (s4186 >> 1) | (s4186 << 7);
-  const SWord8 s4188 = 128 | s4187;
-  const SWord8 s4189 = 127 & s4187;
-  const SWord8 s4190 = s4183 ? s4188 : s4189;
-  const SBool  s4191 = (SBool) (s286 & 1);
-  const SBool  s4192 = false != s4191;
-  const SWord8 s4193 = s4192 ? s4188 : s4189;
-  const SWord8 s4194 = s198 ? s4190 : s4193;
-  const SWord8 s4195 = s74 ? s4181 : s4194;
-  const SWord8 s4196 = s55 ? s4162 : s4195;
-  const SWord8 s4197 = s36 ? s4126 : s4196;
-  const SBool  s4198 = (SBool) (s341 & 1);
-  const SBool  s4199 = false != s4198;
-  const SBool  s4200 = (SBool) (s337 & 1);
-  const SBool  s4201 = false != s4200;
-  const SBool  s4202 = (SBool) (s333 & 1);
-  const SBool  s4203 = false != s4202;
-  const SWord8 s4204 = (s320 >> 1) | (s320 << 7);
-  const SWord8 s4205 = 128 | s4204;
-  const SWord8 s4206 = 127 & s4204;
-  const SWord8 s4207 = s4203 ? s4205 : s4206;
-  const SWord8 s4208 = (s4207 >> 1) | (s4207 << 7);
-  const SWord8 s4209 = 128 | s4208;
-  const SWord8 s4210 = 127 & s4208;
-  const SWord8 s4211 = s4201 ? s4209 : s4210;
-  const SWord8 s4212 = (s4211 >> 1) | (s4211 << 7);
-  const SWord8 s4213 = 128 | s4212;
-  const SWord8 s4214 = 127 & s4212;
-  const SWord8 s4215 = s4199 ? s4213 : s4214;
-  const SBool  s4216 = (SBool) (s346 & 1);
-  const SBool  s4217 = false != s4216;
-  const SWord8 s4218 = s4217 ? s4213 : s4214;
-  const SWord8 s4219 = s329 ? s4215 : s4218;
-  const SBool  s4220 = (SBool) (s362 & 1);
-  const SBool  s4221 = false != s4220;
-  const SBool  s4222 = (SBool) (s355 & 1);
-  const SBool  s4223 = false != s4222;
-  const SWord8 s4224 = s4223 ? s4209 : s4210;
-  const SWord8 s4225 = (s4224 >> 1) | (s4224 << 7);
-  const SWord8 s4226 = 128 | s4225;
-  const SWord8 s4227 = 127 & s4225;
-  const SWord8 s4228 = s4221 ? s4226 : s4227;
-  const SBool  s4229 = (SBool) (s367 & 1);
-  const SBool  s4230 = false != s4229;
-  const SWord8 s4231 = s4230 ? s4226 : s4227;
-  const SWord8 s4232 = s329 ? s4228 : s4231;
-  const SWord8 s4233 = s307 ? s4219 : s4232;
-  const SBool  s4234 = (SBool) (s388 & 1);
-  const SBool  s4235 = false != s4234;
-  const SBool  s4236 = (SBool) (s384 & 1);
-  const SBool  s4237 = false != s4236;
-  const SBool  s4238 = (SBool) (s377 & 1);
-  const SBool  s4239 = false != s4238;
-  const SWord8 s4240 = s4239 ? s4205 : s4206;
-  const SWord8 s4241 = (s4240 >> 1) | (s4240 << 7);
-  const SWord8 s4242 = 128 | s4241;
-  const SWord8 s4243 = 127 & s4241;
-  const SWord8 s4244 = s4237 ? s4242 : s4243;
-  const SWord8 s4245 = (s4244 >> 1) | (s4244 << 7);
-  const SWord8 s4246 = 128 | s4245;
-  const SWord8 s4247 = 127 & s4245;
-  const SWord8 s4248 = s4235 ? s4246 : s4247;
-  const SBool  s4249 = (SBool) (s393 & 1);
-  const SBool  s4250 = false != s4249;
-  const SWord8 s4251 = s4250 ? s4246 : s4247;
-  const SWord8 s4252 = s329 ? s4248 : s4251;
-  const SBool  s4253 = (SBool) (s409 & 1);
-  const SBool  s4254 = false != s4253;
-  const SBool  s4255 = (SBool) (s402 & 1);
-  const SBool  s4256 = false != s4255;
-  const SWord8 s4257 = s4256 ? s4242 : s4243;
-  const SWord8 s4258 = (s4257 >> 1) | (s4257 << 7);
-  const SWord8 s4259 = 128 | s4258;
-  const SWord8 s4260 = 127 & s4258;
-  const SWord8 s4261 = s4254 ? s4259 : s4260;
-  const SBool  s4262 = (SBool) (s414 & 1);
-  const SBool  s4263 = false != s4262;
-  const SWord8 s4264 = s4263 ? s4259 : s4260;
-  const SWord8 s4265 = s329 ? s4261 : s4264;
-  const SWord8 s4266 = s307 ? s4252 : s4265;
-  const SWord8 s4267 = s55 ? s4233 : s4266;
-  const SBool  s4268 = (SBool) (s449 & 1);
-  const SBool  s4269 = false != s4268;
-  const SBool  s4270 = (SBool) (s445 & 1);
-  const SBool  s4271 = false != s4270;
-  const SBool  s4272 = (SBool) (s441 & 1);
-  const SBool  s4273 = false != s4272;
-  const SWord8 s4274 = (s428 >> 1) | (s428 << 7);
-  const SWord8 s4275 = 128 | s4274;
-  const SWord8 s4276 = 127 & s4274;
-  const SWord8 s4277 = s4273 ? s4275 : s4276;
-  const SWord8 s4278 = (s4277 >> 1) | (s4277 << 7);
-  const SWord8 s4279 = 128 | s4278;
-  const SWord8 s4280 = 127 & s4278;
-  const SWord8 s4281 = s4271 ? s4279 : s4280;
-  const SWord8 s4282 = (s4281 >> 1) | (s4281 << 7);
-  const SWord8 s4283 = 128 | s4282;
-  const SWord8 s4284 = 127 & s4282;
-  const SWord8 s4285 = s4269 ? s4283 : s4284;
-  const SBool  s4286 = (SBool) (s454 & 1);
-  const SBool  s4287 = false != s4286;
-  const SWord8 s4288 = s4287 ? s4283 : s4284;
-  const SWord8 s4289 = s434 ? s4285 : s4288;
-  const SBool  s4290 = (SBool) (s470 & 1);
-  const SBool  s4291 = false != s4290;
-  const SBool  s4292 = (SBool) (s463 & 1);
-  const SBool  s4293 = false != s4292;
-  const SWord8 s4294 = s4293 ? s4279 : s4280;
-  const SWord8 s4295 = (s4294 >> 1) | (s4294 << 7);
-  const SWord8 s4296 = 128 | s4295;
-  const SWord8 s4297 = 127 & s4295;
-  const SWord8 s4298 = s4291 ? s4296 : s4297;
-  const SBool  s4299 = (SBool) (s475 & 1);
-  const SBool  s4300 = false != s4299;
-  const SWord8 s4301 = s4300 ? s4296 : s4297;
-  const SWord8 s4302 = s434 ? s4298 : s4301;
-  const SWord8 s4303 = s307 ? s4289 : s4302;
-  const SBool  s4304 = (SBool) (s496 & 1);
-  const SBool  s4305 = false != s4304;
-  const SBool  s4306 = (SBool) (s492 & 1);
-  const SBool  s4307 = false != s4306;
-  const SBool  s4308 = (SBool) (s485 & 1);
-  const SBool  s4309 = false != s4308;
-  const SWord8 s4310 = s4309 ? s4275 : s4276;
-  const SWord8 s4311 = (s4310 >> 1) | (s4310 << 7);
-  const SWord8 s4312 = 128 | s4311;
-  const SWord8 s4313 = 127 & s4311;
-  const SWord8 s4314 = s4307 ? s4312 : s4313;
-  const SWord8 s4315 = (s4314 >> 1) | (s4314 << 7);
-  const SWord8 s4316 = 128 | s4315;
-  const SWord8 s4317 = 127 & s4315;
-  const SWord8 s4318 = s4305 ? s4316 : s4317;
-  const SBool  s4319 = (SBool) (s501 & 1);
-  const SBool  s4320 = false != s4319;
-  const SWord8 s4321 = s4320 ? s4316 : s4317;
-  const SWord8 s4322 = s434 ? s4318 : s4321;
-  const SBool  s4323 = (SBool) (s517 & 1);
-  const SBool  s4324 = false != s4323;
-  const SBool  s4325 = (SBool) (s510 & 1);
-  const SBool  s4326 = false != s4325;
-  const SWord8 s4327 = s4326 ? s4312 : s4313;
-  const SWord8 s4328 = (s4327 >> 1) | (s4327 << 7);
-  const SWord8 s4329 = 128 | s4328;
-  const SWord8 s4330 = 127 & s4328;
-  const SWord8 s4331 = s4324 ? s4329 : s4330;
-  const SBool  s4332 = (SBool) (s522 & 1);
-  const SBool  s4333 = false != s4332;
-  const SWord8 s4334 = s4333 ? s4329 : s4330;
-  const SWord8 s4335 = s434 ? s4331 : s4334;
-  const SWord8 s4336 = s307 ? s4322 : s4335;
-  const SWord8 s4337 = s55 ? s4303 : s4336;
-  const SWord8 s4338 = s36 ? s4267 : s4337;
-  const SWord8 s4339 = s21 ? s4197 : s4338;
-  const SBool  s4340 = (SBool) (s597 & 1);
-  const SBool  s4341 = false != s4340;
-  const SBool  s4342 = (SBool) (s593 & 1);
-  const SBool  s4343 = false != s4342;
-  const SBool  s4344 = (SBool) (s589 & 1);
-  const SBool  s4345 = false != s4344;
-  const SWord8 s4346 = (s576 >> 1) | (s576 << 7);
-  const SWord8 s4347 = 128 | s4346;
-  const SWord8 s4348 = 127 & s4346;
-  const SWord8 s4349 = s4345 ? s4347 : s4348;
-  const SWord8 s4350 = (s4349 >> 1) | (s4349 << 7);
-  const SWord8 s4351 = 128 | s4350;
-  const SWord8 s4352 = 127 & s4350;
-  const SWord8 s4353 = s4343 ? s4351 : s4352;
-  const SWord8 s4354 = (s4353 >> 1) | (s4353 << 7);
-  const SWord8 s4355 = 128 | s4354;
-  const SWord8 s4356 = 127 & s4354;
-  const SWord8 s4357 = s4341 ? s4355 : s4356;
-  const SBool  s4358 = (SBool) (s602 & 1);
-  const SBool  s4359 = false != s4358;
-  const SWord8 s4360 = s4359 ? s4355 : s4356;
-  const SWord8 s4361 = s585 ? s4357 : s4360;
-  const SBool  s4362 = (SBool) (s618 & 1);
-  const SBool  s4363 = false != s4362;
-  const SBool  s4364 = (SBool) (s611 & 1);
-  const SBool  s4365 = false != s4364;
-  const SWord8 s4366 = s4365 ? s4351 : s4352;
-  const SWord8 s4367 = (s4366 >> 1) | (s4366 << 7);
-  const SWord8 s4368 = 128 | s4367;
-  const SWord8 s4369 = 127 & s4367;
-  const SWord8 s4370 = s4363 ? s4368 : s4369;
-  const SBool  s4371 = (SBool) (s623 & 1);
-  const SBool  s4372 = false != s4371;
-  const SWord8 s4373 = s4372 ? s4368 : s4369;
-  const SWord8 s4374 = s585 ? s4370 : s4373;
-  const SWord8 s4375 = s566 ? s4361 : s4374;
-  const SBool  s4376 = (SBool) (s644 & 1);
-  const SBool  s4377 = false != s4376;
-  const SBool  s4378 = (SBool) (s640 & 1);
-  const SBool  s4379 = false != s4378;
-  const SBool  s4380 = (SBool) (s633 & 1);
-  const SBool  s4381 = false != s4380;
-  const SWord8 s4382 = s4381 ? s4347 : s4348;
-  const SWord8 s4383 = (s4382 >> 1) | (s4382 << 7);
-  const SWord8 s4384 = 128 | s4383;
-  const SWord8 s4385 = 127 & s4383;
-  const SWord8 s4386 = s4379 ? s4384 : s4385;
-  const SWord8 s4387 = (s4386 >> 1) | (s4386 << 7);
-  const SWord8 s4388 = 128 | s4387;
-  const SWord8 s4389 = 127 & s4387;
-  const SWord8 s4390 = s4377 ? s4388 : s4389;
-  const SBool  s4391 = (SBool) (s649 & 1);
-  const SBool  s4392 = false != s4391;
-  const SWord8 s4393 = s4392 ? s4388 : s4389;
-  const SWord8 s4394 = s585 ? s4390 : s4393;
-  const SBool  s4395 = (SBool) (s665 & 1);
-  const SBool  s4396 = false != s4395;
-  const SBool  s4397 = (SBool) (s658 & 1);
-  const SBool  s4398 = false != s4397;
-  const SWord8 s4399 = s4398 ? s4384 : s4385;
-  const SWord8 s4400 = (s4399 >> 1) | (s4399 << 7);
-  const SWord8 s4401 = 128 | s4400;
-  const SWord8 s4402 = 127 & s4400;
-  const SWord8 s4403 = s4396 ? s4401 : s4402;
-  const SBool  s4404 = (SBool) (s670 & 1);
-  const SBool  s4405 = false != s4404;
-  const SWord8 s4406 = s4405 ? s4401 : s4402;
-  const SWord8 s4407 = s585 ? s4403 : s4406;
-  const SWord8 s4408 = s566 ? s4394 : s4407;
-  const SWord8 s4409 = s544 ? s4375 : s4408;
-  const SBool  s4410 = (SBool) (s705 & 1);
-  const SBool  s4411 = false != s4410;
-  const SBool  s4412 = (SBool) (s701 & 1);
-  const SBool  s4413 = false != s4412;
-  const SBool  s4414 = (SBool) (s697 & 1);
-  const SBool  s4415 = false != s4414;
-  const SWord8 s4416 = (s684 >> 1) | (s684 << 7);
-  const SWord8 s4417 = 128 | s4416;
-  const SWord8 s4418 = 127 & s4416;
-  const SWord8 s4419 = s4415 ? s4417 : s4418;
-  const SWord8 s4420 = (s4419 >> 1) | (s4419 << 7);
-  const SWord8 s4421 = 128 | s4420;
-  const SWord8 s4422 = 127 & s4420;
-  const SWord8 s4423 = s4413 ? s4421 : s4422;
-  const SWord8 s4424 = (s4423 >> 1) | (s4423 << 7);
-  const SWord8 s4425 = 128 | s4424;
-  const SWord8 s4426 = 127 & s4424;
-  const SWord8 s4427 = s4411 ? s4425 : s4426;
-  const SBool  s4428 = (SBool) (s710 & 1);
-  const SBool  s4429 = false != s4428;
-  const SWord8 s4430 = s4429 ? s4425 : s4426;
-  const SWord8 s4431 = s690 ? s4427 : s4430;
-  const SBool  s4432 = (SBool) (s726 & 1);
-  const SBool  s4433 = false != s4432;
-  const SBool  s4434 = (SBool) (s719 & 1);
-  const SBool  s4435 = false != s4434;
-  const SWord8 s4436 = s4435 ? s4421 : s4422;
-  const SWord8 s4437 = (s4436 >> 1) | (s4436 << 7);
-  const SWord8 s4438 = 128 | s4437;
-  const SWord8 s4439 = 127 & s4437;
-  const SWord8 s4440 = s4433 ? s4438 : s4439;
-  const SBool  s4441 = (SBool) (s731 & 1);
-  const SBool  s4442 = false != s4441;
-  const SWord8 s4443 = s4442 ? s4438 : s4439;
-  const SWord8 s4444 = s690 ? s4440 : s4443;
-  const SWord8 s4445 = s566 ? s4431 : s4444;
-  const SBool  s4446 = (SBool) (s752 & 1);
-  const SBool  s4447 = false != s4446;
-  const SBool  s4448 = (SBool) (s748 & 1);
-  const SBool  s4449 = false != s4448;
-  const SBool  s4450 = (SBool) (s741 & 1);
-  const SBool  s4451 = false != s4450;
-  const SWord8 s4452 = s4451 ? s4417 : s4418;
-  const SWord8 s4453 = (s4452 >> 1) | (s4452 << 7);
-  const SWord8 s4454 = 128 | s4453;
-  const SWord8 s4455 = 127 & s4453;
-  const SWord8 s4456 = s4449 ? s4454 : s4455;
-  const SWord8 s4457 = (s4456 >> 1) | (s4456 << 7);
-  const SWord8 s4458 = 128 | s4457;
-  const SWord8 s4459 = 127 & s4457;
-  const SWord8 s4460 = s4447 ? s4458 : s4459;
-  const SBool  s4461 = (SBool) (s757 & 1);
-  const SBool  s4462 = false != s4461;
-  const SWord8 s4463 = s4462 ? s4458 : s4459;
-  const SWord8 s4464 = s690 ? s4460 : s4463;
-  const SBool  s4465 = (SBool) (s773 & 1);
-  const SBool  s4466 = false != s4465;
-  const SBool  s4467 = (SBool) (s766 & 1);
-  const SBool  s4468 = false != s4467;
-  const SWord8 s4469 = s4468 ? s4454 : s4455;
-  const SWord8 s4470 = (s4469 >> 1) | (s4469 << 7);
-  const SWord8 s4471 = 128 | s4470;
-  const SWord8 s4472 = 127 & s4470;
-  const SWord8 s4473 = s4466 ? s4471 : s4472;
-  const SBool  s4474 = (SBool) (s778 & 1);
-  const SBool  s4475 = false != s4474;
-  const SWord8 s4476 = s4475 ? s4471 : s4472;
-  const SWord8 s4477 = s690 ? s4473 : s4476;
-  const SWord8 s4478 = s566 ? s4464 : s4477;
-  const SWord8 s4479 = s544 ? s4445 : s4478;
-  const SWord8 s4480 = s36 ? s4409 : s4479;
-  const SBool  s4481 = (SBool) (s833 & 1);
-  const SBool  s4482 = false != s4481;
-  const SBool  s4483 = (SBool) (s829 & 1);
-  const SBool  s4484 = false != s4483;
-  const SBool  s4485 = (SBool) (s825 & 1);
-  const SBool  s4486 = false != s4485;
-  const SWord8 s4487 = (s812 >> 1) | (s812 << 7);
-  const SWord8 s4488 = 128 | s4487;
-  const SWord8 s4489 = 127 & s4487;
-  const SWord8 s4490 = s4486 ? s4488 : s4489;
-  const SWord8 s4491 = (s4490 >> 1) | (s4490 << 7);
-  const SWord8 s4492 = 128 | s4491;
-  const SWord8 s4493 = 127 & s4491;
-  const SWord8 s4494 = s4484 ? s4492 : s4493;
-  const SWord8 s4495 = (s4494 >> 1) | (s4494 << 7);
-  const SWord8 s4496 = 128 | s4495;
-  const SWord8 s4497 = 127 & s4495;
-  const SWord8 s4498 = s4482 ? s4496 : s4497;
-  const SBool  s4499 = (SBool) (s838 & 1);
-  const SBool  s4500 = false != s4499;
-  const SWord8 s4501 = s4500 ? s4496 : s4497;
-  const SWord8 s4502 = s821 ? s4498 : s4501;
-  const SBool  s4503 = (SBool) (s854 & 1);
-  const SBool  s4504 = false != s4503;
-  const SBool  s4505 = (SBool) (s847 & 1);
-  const SBool  s4506 = false != s4505;
-  const SWord8 s4507 = s4506 ? s4492 : s4493;
-  const SWord8 s4508 = (s4507 >> 1) | (s4507 << 7);
-  const SWord8 s4509 = 128 | s4508;
-  const SWord8 s4510 = 127 & s4508;
-  const SWord8 s4511 = s4504 ? s4509 : s4510;
-  const SBool  s4512 = (SBool) (s859 & 1);
-  const SBool  s4513 = false != s4512;
-  const SWord8 s4514 = s4513 ? s4509 : s4510;
-  const SWord8 s4515 = s821 ? s4511 : s4514;
-  const SWord8 s4516 = s799 ? s4502 : s4515;
-  const SBool  s4517 = (SBool) (s880 & 1);
-  const SBool  s4518 = false != s4517;
-  const SBool  s4519 = (SBool) (s876 & 1);
-  const SBool  s4520 = false != s4519;
-  const SBool  s4521 = (SBool) (s869 & 1);
-  const SBool  s4522 = false != s4521;
-  const SWord8 s4523 = s4522 ? s4488 : s4489;
-  const SWord8 s4524 = (s4523 >> 1) | (s4523 << 7);
-  const SWord8 s4525 = 128 | s4524;
-  const SWord8 s4526 = 127 & s4524;
-  const SWord8 s4527 = s4520 ? s4525 : s4526;
-  const SWord8 s4528 = (s4527 >> 1) | (s4527 << 7);
-  const SWord8 s4529 = 128 | s4528;
-  const SWord8 s4530 = 127 & s4528;
-  const SWord8 s4531 = s4518 ? s4529 : s4530;
-  const SBool  s4532 = (SBool) (s885 & 1);
-  const SBool  s4533 = false != s4532;
-  const SWord8 s4534 = s4533 ? s4529 : s4530;
-  const SWord8 s4535 = s821 ? s4531 : s4534;
-  const SBool  s4536 = (SBool) (s901 & 1);
-  const SBool  s4537 = false != s4536;
-  const SBool  s4538 = (SBool) (s894 & 1);
-  const SBool  s4539 = false != s4538;
-  const SWord8 s4540 = s4539 ? s4525 : s4526;
-  const SWord8 s4541 = (s4540 >> 1) | (s4540 << 7);
-  const SWord8 s4542 = 128 | s4541;
-  const SWord8 s4543 = 127 & s4541;
-  const SWord8 s4544 = s4537 ? s4542 : s4543;
-  const SBool  s4545 = (SBool) (s906 & 1);
-  const SBool  s4546 = false != s4545;
-  const SWord8 s4547 = s4546 ? s4542 : s4543;
-  const SWord8 s4548 = s821 ? s4544 : s4547;
-  const SWord8 s4549 = s799 ? s4535 : s4548;
-  const SWord8 s4550 = s544 ? s4516 : s4549;
-  const SBool  s4551 = (SBool) (s941 & 1);
-  const SBool  s4552 = false != s4551;
-  const SBool  s4553 = (SBool) (s937 & 1);
-  const SBool  s4554 = false != s4553;
-  const SBool  s4555 = (SBool) (s933 & 1);
-  const SBool  s4556 = false != s4555;
-  const SWord8 s4557 = (s920 >> 1) | (s920 << 7);
-  const SWord8 s4558 = 128 | s4557;
-  const SWord8 s4559 = 127 & s4557;
-  const SWord8 s4560 = s4556 ? s4558 : s4559;
-  const SWord8 s4561 = (s4560 >> 1) | (s4560 << 7);
-  const SWord8 s4562 = 128 | s4561;
-  const SWord8 s4563 = 127 & s4561;
-  const SWord8 s4564 = s4554 ? s4562 : s4563;
-  const SWord8 s4565 = (s4564 >> 1) | (s4564 << 7);
-  const SWord8 s4566 = 128 | s4565;
-  const SWord8 s4567 = 127 & s4565;
-  const SWord8 s4568 = s4552 ? s4566 : s4567;
-  const SBool  s4569 = (SBool) (s946 & 1);
-  const SBool  s4570 = false != s4569;
-  const SWord8 s4571 = s4570 ? s4566 : s4567;
-  const SWord8 s4572 = s926 ? s4568 : s4571;
-  const SBool  s4573 = (SBool) (s962 & 1);
-  const SBool  s4574 = false != s4573;
-  const SBool  s4575 = (SBool) (s955 & 1);
-  const SBool  s4576 = false != s4575;
-  const SWord8 s4577 = s4576 ? s4562 : s4563;
-  const SWord8 s4578 = (s4577 >> 1) | (s4577 << 7);
-  const SWord8 s4579 = 128 | s4578;
-  const SWord8 s4580 = 127 & s4578;
-  const SWord8 s4581 = s4574 ? s4579 : s4580;
-  const SBool  s4582 = (SBool) (s967 & 1);
-  const SBool  s4583 = false != s4582;
-  const SWord8 s4584 = s4583 ? s4579 : s4580;
-  const SWord8 s4585 = s926 ? s4581 : s4584;
-  const SWord8 s4586 = s799 ? s4572 : s4585;
-  const SBool  s4587 = (SBool) (s988 & 1);
-  const SBool  s4588 = false != s4587;
-  const SBool  s4589 = (SBool) (s984 & 1);
-  const SBool  s4590 = false != s4589;
-  const SBool  s4591 = (SBool) (s977 & 1);
-  const SBool  s4592 = false != s4591;
-  const SWord8 s4593 = s4592 ? s4558 : s4559;
-  const SWord8 s4594 = (s4593 >> 1) | (s4593 << 7);
-  const SWord8 s4595 = 128 | s4594;
-  const SWord8 s4596 = 127 & s4594;
-  const SWord8 s4597 = s4590 ? s4595 : s4596;
-  const SWord8 s4598 = (s4597 >> 1) | (s4597 << 7);
-  const SWord8 s4599 = 128 | s4598;
-  const SWord8 s4600 = 127 & s4598;
-  const SWord8 s4601 = s4588 ? s4599 : s4600;
-  const SBool  s4602 = (SBool) (s993 & 1);
-  const SBool  s4603 = false != s4602;
-  const SWord8 s4604 = s4603 ? s4599 : s4600;
-  const SWord8 s4605 = s926 ? s4601 : s4604;
-  const SBool  s4606 = (SBool) (s1009 & 1);
-  const SBool  s4607 = false != s4606;
-  const SBool  s4608 = (SBool) (s1002 & 1);
-  const SBool  s4609 = false != s4608;
-  const SWord8 s4610 = s4609 ? s4595 : s4596;
-  const SWord8 s4611 = (s4610 >> 1) | (s4610 << 7);
-  const SWord8 s4612 = 128 | s4611;
-  const SWord8 s4613 = 127 & s4611;
-  const SWord8 s4614 = s4607 ? s4612 : s4613;
-  const SBool  s4615 = (SBool) (s1014 & 1);
-  const SBool  s4616 = false != s4615;
-  const SWord8 s4617 = s4616 ? s4612 : s4613;
-  const SWord8 s4618 = s926 ? s4614 : s4617;
-  const SWord8 s4619 = s799 ? s4605 : s4618;
-  const SWord8 s4620 = s544 ? s4586 : s4619;
-  const SWord8 s4621 = s36 ? s4550 : s4620;
-  const SWord8 s4622 = s21 ? s4480 : s4621;
-  const SWord8 s4623 = s16 ? s4339 : s4622;
-  const SBool  s4624 = (SBool) (s1109 & 1);
-  const SBool  s4625 = false != s4624;
-  const SBool  s4626 = (SBool) (s1105 & 1);
-  const SBool  s4627 = false != s4626;
-  const SBool  s4628 = (SBool) (s1101 & 1);
-  const SBool  s4629 = false != s4628;
-  const SWord8 s4630 = (s1088 >> 1) | (s1088 << 7);
-  const SWord8 s4631 = 128 | s4630;
-  const SWord8 s4632 = 127 & s4630;
-  const SWord8 s4633 = s4629 ? s4631 : s4632;
-  const SWord8 s4634 = (s4633 >> 1) | (s4633 << 7);
-  const SWord8 s4635 = 128 | s4634;
-  const SWord8 s4636 = 127 & s4634;
-  const SWord8 s4637 = s4627 ? s4635 : s4636;
-  const SWord8 s4638 = (s4637 >> 1) | (s4637 << 7);
-  const SWord8 s4639 = 128 | s4638;
-  const SWord8 s4640 = 127 & s4638;
-  const SWord8 s4641 = s4625 ? s4639 : s4640;
-  const SBool  s4642 = (SBool) (s1114 & 1);
-  const SBool  s4643 = false != s4642;
-  const SWord8 s4644 = s4643 ? s4639 : s4640;
-  const SWord8 s4645 = s1097 ? s4641 : s4644;
-  const SBool  s4646 = (SBool) (s1130 & 1);
-  const SBool  s4647 = false != s4646;
-  const SBool  s4648 = (SBool) (s1123 & 1);
-  const SBool  s4649 = false != s4648;
-  const SWord8 s4650 = s4649 ? s4635 : s4636;
-  const SWord8 s4651 = (s4650 >> 1) | (s4650 << 7);
-  const SWord8 s4652 = 128 | s4651;
-  const SWord8 s4653 = 127 & s4651;
-  const SWord8 s4654 = s4647 ? s4652 : s4653;
-  const SBool  s4655 = (SBool) (s1135 & 1);
-  const SBool  s4656 = false != s4655;
-  const SWord8 s4657 = s4656 ? s4652 : s4653;
-  const SWord8 s4658 = s1097 ? s4654 : s4657;
-  const SWord8 s4659 = s1078 ? s4645 : s4658;
-  const SBool  s4660 = (SBool) (s1156 & 1);
-  const SBool  s4661 = false != s4660;
-  const SBool  s4662 = (SBool) (s1152 & 1);
-  const SBool  s4663 = false != s4662;
-  const SBool  s4664 = (SBool) (s1145 & 1);
-  const SBool  s4665 = false != s4664;
-  const SWord8 s4666 = s4665 ? s4631 : s4632;
-  const SWord8 s4667 = (s4666 >> 1) | (s4666 << 7);
-  const SWord8 s4668 = 128 | s4667;
-  const SWord8 s4669 = 127 & s4667;
-  const SWord8 s4670 = s4663 ? s4668 : s4669;
-  const SWord8 s4671 = (s4670 >> 1) | (s4670 << 7);
-  const SWord8 s4672 = 128 | s4671;
-  const SWord8 s4673 = 127 & s4671;
-  const SWord8 s4674 = s4661 ? s4672 : s4673;
-  const SBool  s4675 = (SBool) (s1161 & 1);
-  const SBool  s4676 = false != s4675;
-  const SWord8 s4677 = s4676 ? s4672 : s4673;
-  const SWord8 s4678 = s1097 ? s4674 : s4677;
-  const SBool  s4679 = (SBool) (s1177 & 1);
-  const SBool  s4680 = false != s4679;
-  const SBool  s4681 = (SBool) (s1170 & 1);
-  const SBool  s4682 = false != s4681;
-  const SWord8 s4683 = s4682 ? s4668 : s4669;
-  const SWord8 s4684 = (s4683 >> 1) | (s4683 << 7);
-  const SWord8 s4685 = 128 | s4684;
-  const SWord8 s4686 = 127 & s4684;
-  const SWord8 s4687 = s4680 ? s4685 : s4686;
-  const SBool  s4688 = (SBool) (s1182 & 1);
-  const SBool  s4689 = false != s4688;
-  const SWord8 s4690 = s4689 ? s4685 : s4686;
-  const SWord8 s4691 = s1097 ? s4687 : s4690;
-  const SWord8 s4692 = s1078 ? s4678 : s4691;
-  const SWord8 s4693 = s1059 ? s4659 : s4692;
-  const SBool  s4694 = (SBool) (s1217 & 1);
-  const SBool  s4695 = false != s4694;
-  const SBool  s4696 = (SBool) (s1213 & 1);
-  const SBool  s4697 = false != s4696;
-  const SBool  s4698 = (SBool) (s1209 & 1);
-  const SBool  s4699 = false != s4698;
-  const SWord8 s4700 = (s1196 >> 1) | (s1196 << 7);
-  const SWord8 s4701 = 128 | s4700;
-  const SWord8 s4702 = 127 & s4700;
-  const SWord8 s4703 = s4699 ? s4701 : s4702;
-  const SWord8 s4704 = (s4703 >> 1) | (s4703 << 7);
-  const SWord8 s4705 = 128 | s4704;
-  const SWord8 s4706 = 127 & s4704;
-  const SWord8 s4707 = s4697 ? s4705 : s4706;
-  const SWord8 s4708 = (s4707 >> 1) | (s4707 << 7);
-  const SWord8 s4709 = 128 | s4708;
-  const SWord8 s4710 = 127 & s4708;
-  const SWord8 s4711 = s4695 ? s4709 : s4710;
-  const SBool  s4712 = (SBool) (s1222 & 1);
-  const SBool  s4713 = false != s4712;
-  const SWord8 s4714 = s4713 ? s4709 : s4710;
-  const SWord8 s4715 = s1202 ? s4711 : s4714;
-  const SBool  s4716 = (SBool) (s1238 & 1);
-  const SBool  s4717 = false != s4716;
-  const SBool  s4718 = (SBool) (s1231 & 1);
-  const SBool  s4719 = false != s4718;
-  const SWord8 s4720 = s4719 ? s4705 : s4706;
-  const SWord8 s4721 = (s4720 >> 1) | (s4720 << 7);
-  const SWord8 s4722 = 128 | s4721;
-  const SWord8 s4723 = 127 & s4721;
-  const SWord8 s4724 = s4717 ? s4722 : s4723;
-  const SBool  s4725 = (SBool) (s1243 & 1);
-  const SBool  s4726 = false != s4725;
-  const SWord8 s4727 = s4726 ? s4722 : s4723;
-  const SWord8 s4728 = s1202 ? s4724 : s4727;
-  const SWord8 s4729 = s1078 ? s4715 : s4728;
-  const SBool  s4730 = (SBool) (s1264 & 1);
-  const SBool  s4731 = false != s4730;
-  const SBool  s4732 = (SBool) (s1260 & 1);
-  const SBool  s4733 = false != s4732;
-  const SBool  s4734 = (SBool) (s1253 & 1);
-  const SBool  s4735 = false != s4734;
-  const SWord8 s4736 = s4735 ? s4701 : s4702;
-  const SWord8 s4737 = (s4736 >> 1) | (s4736 << 7);
-  const SWord8 s4738 = 128 | s4737;
-  const SWord8 s4739 = 127 & s4737;
-  const SWord8 s4740 = s4733 ? s4738 : s4739;
-  const SWord8 s4741 = (s4740 >> 1) | (s4740 << 7);
-  const SWord8 s4742 = 128 | s4741;
-  const SWord8 s4743 = 127 & s4741;
-  const SWord8 s4744 = s4731 ? s4742 : s4743;
-  const SBool  s4745 = (SBool) (s1269 & 1);
-  const SBool  s4746 = false != s4745;
-  const SWord8 s4747 = s4746 ? s4742 : s4743;
-  const SWord8 s4748 = s1202 ? s4744 : s4747;
-  const SBool  s4749 = (SBool) (s1285 & 1);
-  const SBool  s4750 = false != s4749;
-  const SBool  s4751 = (SBool) (s1278 & 1);
-  const SBool  s4752 = false != s4751;
-  const SWord8 s4753 = s4752 ? s4738 : s4739;
-  const SWord8 s4754 = (s4753 >> 1) | (s4753 << 7);
-  const SWord8 s4755 = 128 | s4754;
-  const SWord8 s4756 = 127 & s4754;
-  const SWord8 s4757 = s4750 ? s4755 : s4756;
-  const SBool  s4758 = (SBool) (s1290 & 1);
-  const SBool  s4759 = false != s4758;
-  const SWord8 s4760 = s4759 ? s4755 : s4756;
-  const SWord8 s4761 = s1202 ? s4757 : s4760;
-  const SWord8 s4762 = s1078 ? s4748 : s4761;
-  const SWord8 s4763 = s1059 ? s4729 : s4762;
-  const SWord8 s4764 = s1037 ? s4693 : s4763;
-  const SBool  s4765 = (SBool) (s1345 & 1);
-  const SBool  s4766 = false != s4765;
-  const SBool  s4767 = (SBool) (s1341 & 1);
-  const SBool  s4768 = false != s4767;
-  const SBool  s4769 = (SBool) (s1337 & 1);
-  const SBool  s4770 = false != s4769;
-  const SWord8 s4771 = (s1324 >> 1) | (s1324 << 7);
-  const SWord8 s4772 = 128 | s4771;
-  const SWord8 s4773 = 127 & s4771;
-  const SWord8 s4774 = s4770 ? s4772 : s4773;
-  const SWord8 s4775 = (s4774 >> 1) | (s4774 << 7);
-  const SWord8 s4776 = 128 | s4775;
-  const SWord8 s4777 = 127 & s4775;
-  const SWord8 s4778 = s4768 ? s4776 : s4777;
-  const SWord8 s4779 = (s4778 >> 1) | (s4778 << 7);
-  const SWord8 s4780 = 128 | s4779;
-  const SWord8 s4781 = 127 & s4779;
-  const SWord8 s4782 = s4766 ? s4780 : s4781;
-  const SBool  s4783 = (SBool) (s1350 & 1);
-  const SBool  s4784 = false != s4783;
-  const SWord8 s4785 = s4784 ? s4780 : s4781;
-  const SWord8 s4786 = s1333 ? s4782 : s4785;
-  const SBool  s4787 = (SBool) (s1366 & 1);
-  const SBool  s4788 = false != s4787;
-  const SBool  s4789 = (SBool) (s1359 & 1);
-  const SBool  s4790 = false != s4789;
-  const SWord8 s4791 = s4790 ? s4776 : s4777;
-  const SWord8 s4792 = (s4791 >> 1) | (s4791 << 7);
-  const SWord8 s4793 = 128 | s4792;
-  const SWord8 s4794 = 127 & s4792;
-  const SWord8 s4795 = s4788 ? s4793 : s4794;
-  const SBool  s4796 = (SBool) (s1371 & 1);
-  const SBool  s4797 = false != s4796;
-  const SWord8 s4798 = s4797 ? s4793 : s4794;
-  const SWord8 s4799 = s1333 ? s4795 : s4798;
-  const SWord8 s4800 = s1311 ? s4786 : s4799;
-  const SBool  s4801 = (SBool) (s1392 & 1);
-  const SBool  s4802 = false != s4801;
-  const SBool  s4803 = (SBool) (s1388 & 1);
-  const SBool  s4804 = false != s4803;
-  const SBool  s4805 = (SBool) (s1381 & 1);
-  const SBool  s4806 = false != s4805;
-  const SWord8 s4807 = s4806 ? s4772 : s4773;
-  const SWord8 s4808 = (s4807 >> 1) | (s4807 << 7);
-  const SWord8 s4809 = 128 | s4808;
-  const SWord8 s4810 = 127 & s4808;
-  const SWord8 s4811 = s4804 ? s4809 : s4810;
-  const SWord8 s4812 = (s4811 >> 1) | (s4811 << 7);
-  const SWord8 s4813 = 128 | s4812;
-  const SWord8 s4814 = 127 & s4812;
-  const SWord8 s4815 = s4802 ? s4813 : s4814;
-  const SBool  s4816 = (SBool) (s1397 & 1);
-  const SBool  s4817 = false != s4816;
-  const SWord8 s4818 = s4817 ? s4813 : s4814;
-  const SWord8 s4819 = s1333 ? s4815 : s4818;
-  const SBool  s4820 = (SBool) (s1413 & 1);
-  const SBool  s4821 = false != s4820;
-  const SBool  s4822 = (SBool) (s1406 & 1);
-  const SBool  s4823 = false != s4822;
-  const SWord8 s4824 = s4823 ? s4809 : s4810;
-  const SWord8 s4825 = (s4824 >> 1) | (s4824 << 7);
-  const SWord8 s4826 = 128 | s4825;
-  const SWord8 s4827 = 127 & s4825;
-  const SWord8 s4828 = s4821 ? s4826 : s4827;
-  const SBool  s4829 = (SBool) (s1418 & 1);
-  const SBool  s4830 = false != s4829;
-  const SWord8 s4831 = s4830 ? s4826 : s4827;
-  const SWord8 s4832 = s1333 ? s4828 : s4831;
-  const SWord8 s4833 = s1311 ? s4819 : s4832;
-  const SWord8 s4834 = s1059 ? s4800 : s4833;
-  const SBool  s4835 = (SBool) (s1453 & 1);
-  const SBool  s4836 = false != s4835;
-  const SBool  s4837 = (SBool) (s1449 & 1);
-  const SBool  s4838 = false != s4837;
-  const SBool  s4839 = (SBool) (s1445 & 1);
-  const SBool  s4840 = false != s4839;
-  const SWord8 s4841 = (s1432 >> 1) | (s1432 << 7);
-  const SWord8 s4842 = 128 | s4841;
-  const SWord8 s4843 = 127 & s4841;
-  const SWord8 s4844 = s4840 ? s4842 : s4843;
-  const SWord8 s4845 = (s4844 >> 1) | (s4844 << 7);
-  const SWord8 s4846 = 128 | s4845;
-  const SWord8 s4847 = 127 & s4845;
-  const SWord8 s4848 = s4838 ? s4846 : s4847;
-  const SWord8 s4849 = (s4848 >> 1) | (s4848 << 7);
-  const SWord8 s4850 = 128 | s4849;
-  const SWord8 s4851 = 127 & s4849;
-  const SWord8 s4852 = s4836 ? s4850 : s4851;
-  const SBool  s4853 = (SBool) (s1458 & 1);
-  const SBool  s4854 = false != s4853;
-  const SWord8 s4855 = s4854 ? s4850 : s4851;
-  const SWord8 s4856 = s1438 ? s4852 : s4855;
-  const SBool  s4857 = (SBool) (s1474 & 1);
-  const SBool  s4858 = false != s4857;
-  const SBool  s4859 = (SBool) (s1467 & 1);
-  const SBool  s4860 = false != s4859;
-  const SWord8 s4861 = s4860 ? s4846 : s4847;
-  const SWord8 s4862 = (s4861 >> 1) | (s4861 << 7);
-  const SWord8 s4863 = 128 | s4862;
-  const SWord8 s4864 = 127 & s4862;
-  const SWord8 s4865 = s4858 ? s4863 : s4864;
-  const SBool  s4866 = (SBool) (s1479 & 1);
-  const SBool  s4867 = false != s4866;
-  const SWord8 s4868 = s4867 ? s4863 : s4864;
-  const SWord8 s4869 = s1438 ? s4865 : s4868;
-  const SWord8 s4870 = s1311 ? s4856 : s4869;
-  const SBool  s4871 = (SBool) (s1500 & 1);
-  const SBool  s4872 = false != s4871;
-  const SBool  s4873 = (SBool) (s1496 & 1);
-  const SBool  s4874 = false != s4873;
-  const SBool  s4875 = (SBool) (s1489 & 1);
-  const SBool  s4876 = false != s4875;
-  const SWord8 s4877 = s4876 ? s4842 : s4843;
-  const SWord8 s4878 = (s4877 >> 1) | (s4877 << 7);
-  const SWord8 s4879 = 128 | s4878;
-  const SWord8 s4880 = 127 & s4878;
-  const SWord8 s4881 = s4874 ? s4879 : s4880;
-  const SWord8 s4882 = (s4881 >> 1) | (s4881 << 7);
-  const SWord8 s4883 = 128 | s4882;
-  const SWord8 s4884 = 127 & s4882;
-  const SWord8 s4885 = s4872 ? s4883 : s4884;
-  const SBool  s4886 = (SBool) (s1505 & 1);
-  const SBool  s4887 = false != s4886;
-  const SWord8 s4888 = s4887 ? s4883 : s4884;
-  const SWord8 s4889 = s1438 ? s4885 : s4888;
-  const SBool  s4890 = (SBool) (s1521 & 1);
-  const SBool  s4891 = false != s4890;
-  const SBool  s4892 = (SBool) (s1514 & 1);
-  const SBool  s4893 = false != s4892;
-  const SWord8 s4894 = s4893 ? s4879 : s4880;
-  const SWord8 s4895 = (s4894 >> 1) | (s4894 << 7);
-  const SWord8 s4896 = 128 | s4895;
-  const SWord8 s4897 = 127 & s4895;
-  const SWord8 s4898 = s4891 ? s4896 : s4897;
-  const SBool  s4899 = (SBool) (s1526 & 1);
-  const SBool  s4900 = false != s4899;
-  const SWord8 s4901 = s4900 ? s4896 : s4897;
-  const SWord8 s4902 = s1438 ? s4898 : s4901;
-  const SWord8 s4903 = s1311 ? s4889 : s4902;
-  const SWord8 s4904 = s1059 ? s4870 : s4903;
-  const SWord8 s4905 = s1037 ? s4834 : s4904;
-  const SWord8 s4906 = s21 ? s4764 : s4905;
-  const SBool  s4907 = (SBool) (s1601 & 1);
-  const SBool  s4908 = false != s4907;
-  const SBool  s4909 = (SBool) (s1597 & 1);
-  const SBool  s4910 = false != s4909;
-  const SBool  s4911 = (SBool) (s1593 & 1);
-  const SBool  s4912 = false != s4911;
-  const SWord8 s4913 = (s1580 >> 1) | (s1580 << 7);
-  const SWord8 s4914 = 128 | s4913;
-  const SWord8 s4915 = 127 & s4913;
-  const SWord8 s4916 = s4912 ? s4914 : s4915;
-  const SWord8 s4917 = (s4916 >> 1) | (s4916 << 7);
-  const SWord8 s4918 = 128 | s4917;
-  const SWord8 s4919 = 127 & s4917;
-  const SWord8 s4920 = s4910 ? s4918 : s4919;
-  const SWord8 s4921 = (s4920 >> 1) | (s4920 << 7);
-  const SWord8 s4922 = 128 | s4921;
-  const SWord8 s4923 = 127 & s4921;
-  const SWord8 s4924 = s4908 ? s4922 : s4923;
-  const SBool  s4925 = (SBool) (s1606 & 1);
-  const SBool  s4926 = false != s4925;
-  const SWord8 s4927 = s4926 ? s4922 : s4923;
-  const SWord8 s4928 = s1589 ? s4924 : s4927;
-  const SBool  s4929 = (SBool) (s1622 & 1);
-  const SBool  s4930 = false != s4929;
-  const SBool  s4931 = (SBool) (s1615 & 1);
-  const SBool  s4932 = false != s4931;
-  const SWord8 s4933 = s4932 ? s4918 : s4919;
-  const SWord8 s4934 = (s4933 >> 1) | (s4933 << 7);
-  const SWord8 s4935 = 128 | s4934;
-  const SWord8 s4936 = 127 & s4934;
-  const SWord8 s4937 = s4930 ? s4935 : s4936;
-  const SBool  s4938 = (SBool) (s1627 & 1);
-  const SBool  s4939 = false != s4938;
-  const SWord8 s4940 = s4939 ? s4935 : s4936;
-  const SWord8 s4941 = s1589 ? s4937 : s4940;
-  const SWord8 s4942 = s1570 ? s4928 : s4941;
-  const SBool  s4943 = (SBool) (s1648 & 1);
-  const SBool  s4944 = false != s4943;
-  const SBool  s4945 = (SBool) (s1644 & 1);
-  const SBool  s4946 = false != s4945;
-  const SBool  s4947 = (SBool) (s1637 & 1);
-  const SBool  s4948 = false != s4947;
-  const SWord8 s4949 = s4948 ? s4914 : s4915;
-  const SWord8 s4950 = (s4949 >> 1) | (s4949 << 7);
-  const SWord8 s4951 = 128 | s4950;
-  const SWord8 s4952 = 127 & s4950;
-  const SWord8 s4953 = s4946 ? s4951 : s4952;
-  const SWord8 s4954 = (s4953 >> 1) | (s4953 << 7);
-  const SWord8 s4955 = 128 | s4954;
-  const SWord8 s4956 = 127 & s4954;
-  const SWord8 s4957 = s4944 ? s4955 : s4956;
-  const SBool  s4958 = (SBool) (s1653 & 1);
-  const SBool  s4959 = false != s4958;
-  const SWord8 s4960 = s4959 ? s4955 : s4956;
-  const SWord8 s4961 = s1589 ? s4957 : s4960;
-  const SBool  s4962 = (SBool) (s1669 & 1);
-  const SBool  s4963 = false != s4962;
-  const SBool  s4964 = (SBool) (s1662 & 1);
-  const SBool  s4965 = false != s4964;
-  const SWord8 s4966 = s4965 ? s4951 : s4952;
-  const SWord8 s4967 = (s4966 >> 1) | (s4966 << 7);
-  const SWord8 s4968 = 128 | s4967;
-  const SWord8 s4969 = 127 & s4967;
-  const SWord8 s4970 = s4963 ? s4968 : s4969;
-  const SBool  s4971 = (SBool) (s1674 & 1);
-  const SBool  s4972 = false != s4971;
-  const SWord8 s4973 = s4972 ? s4968 : s4969;
-  const SWord8 s4974 = s1589 ? s4970 : s4973;
-  const SWord8 s4975 = s1570 ? s4961 : s4974;
-  const SWord8 s4976 = s1548 ? s4942 : s4975;
-  const SBool  s4977 = (SBool) (s1709 & 1);
-  const SBool  s4978 = false != s4977;
-  const SBool  s4979 = (SBool) (s1705 & 1);
-  const SBool  s4980 = false != s4979;
-  const SBool  s4981 = (SBool) (s1701 & 1);
-  const SBool  s4982 = false != s4981;
-  const SWord8 s4983 = (s1688 >> 1) | (s1688 << 7);
-  const SWord8 s4984 = 128 | s4983;
-  const SWord8 s4985 = 127 & s4983;
-  const SWord8 s4986 = s4982 ? s4984 : s4985;
-  const SWord8 s4987 = (s4986 >> 1) | (s4986 << 7);
-  const SWord8 s4988 = 128 | s4987;
-  const SWord8 s4989 = 127 & s4987;
-  const SWord8 s4990 = s4980 ? s4988 : s4989;
-  const SWord8 s4991 = (s4990 >> 1) | (s4990 << 7);
-  const SWord8 s4992 = 128 | s4991;
-  const SWord8 s4993 = 127 & s4991;
-  const SWord8 s4994 = s4978 ? s4992 : s4993;
-  const SBool  s4995 = (SBool) (s1714 & 1);
-  const SBool  s4996 = false != s4995;
-  const SWord8 s4997 = s4996 ? s4992 : s4993;
-  const SWord8 s4998 = s1694 ? s4994 : s4997;
-  const SBool  s4999 = (SBool) (s1730 & 1);
-  const SBool  s5000 = false != s4999;
-  const SBool  s5001 = (SBool) (s1723 & 1);
-  const SBool  s5002 = false != s5001;
-  const SWord8 s5003 = s5002 ? s4988 : s4989;
-  const SWord8 s5004 = (s5003 >> 1) | (s5003 << 7);
-  const SWord8 s5005 = 128 | s5004;
-  const SWord8 s5006 = 127 & s5004;
-  const SWord8 s5007 = s5000 ? s5005 : s5006;
-  const SBool  s5008 = (SBool) (s1735 & 1);
-  const SBool  s5009 = false != s5008;
-  const SWord8 s5010 = s5009 ? s5005 : s5006;
-  const SWord8 s5011 = s1694 ? s5007 : s5010;
-  const SWord8 s5012 = s1570 ? s4998 : s5011;
-  const SBool  s5013 = (SBool) (s1756 & 1);
-  const SBool  s5014 = false != s5013;
-  const SBool  s5015 = (SBool) (s1752 & 1);
-  const SBool  s5016 = false != s5015;
-  const SBool  s5017 = (SBool) (s1745 & 1);
-  const SBool  s5018 = false != s5017;
-  const SWord8 s5019 = s5018 ? s4984 : s4985;
-  const SWord8 s5020 = (s5019 >> 1) | (s5019 << 7);
-  const SWord8 s5021 = 128 | s5020;
-  const SWord8 s5022 = 127 & s5020;
-  const SWord8 s5023 = s5016 ? s5021 : s5022;
-  const SWord8 s5024 = (s5023 >> 1) | (s5023 << 7);
-  const SWord8 s5025 = 128 | s5024;
-  const SWord8 s5026 = 127 & s5024;
-  const SWord8 s5027 = s5014 ? s5025 : s5026;
-  const SBool  s5028 = (SBool) (s1761 & 1);
-  const SBool  s5029 = false != s5028;
-  const SWord8 s5030 = s5029 ? s5025 : s5026;
-  const SWord8 s5031 = s1694 ? s5027 : s5030;
-  const SBool  s5032 = (SBool) (s1777 & 1);
-  const SBool  s5033 = false != s5032;
-  const SBool  s5034 = (SBool) (s1770 & 1);
-  const SBool  s5035 = false != s5034;
-  const SWord8 s5036 = s5035 ? s5021 : s5022;
-  const SWord8 s5037 = (s5036 >> 1) | (s5036 << 7);
-  const SWord8 s5038 = 128 | s5037;
-  const SWord8 s5039 = 127 & s5037;
-  const SWord8 s5040 = s5033 ? s5038 : s5039;
-  const SBool  s5041 = (SBool) (s1782 & 1);
-  const SBool  s5042 = false != s5041;
-  const SWord8 s5043 = s5042 ? s5038 : s5039;
-  const SWord8 s5044 = s1694 ? s5040 : s5043;
-  const SWord8 s5045 = s1570 ? s5031 : s5044;
-  const SWord8 s5046 = s1548 ? s5012 : s5045;
-  const SWord8 s5047 = s1037 ? s4976 : s5046;
-  const SBool  s5048 = (SBool) (s1837 & 1);
-  const SBool  s5049 = false != s5048;
-  const SBool  s5050 = (SBool) (s1833 & 1);
-  const SBool  s5051 = false != s5050;
-  const SBool  s5052 = (SBool) (s1829 & 1);
-  const SBool  s5053 = false != s5052;
-  const SWord8 s5054 = (s1816 >> 1) | (s1816 << 7);
-  const SWord8 s5055 = 128 | s5054;
-  const SWord8 s5056 = 127 & s5054;
-  const SWord8 s5057 = s5053 ? s5055 : s5056;
-  const SWord8 s5058 = (s5057 >> 1) | (s5057 << 7);
-  const SWord8 s5059 = 128 | s5058;
-  const SWord8 s5060 = 127 & s5058;
-  const SWord8 s5061 = s5051 ? s5059 : s5060;
-  const SWord8 s5062 = (s5061 >> 1) | (s5061 << 7);
-  const SWord8 s5063 = 128 | s5062;
-  const SWord8 s5064 = 127 & s5062;
-  const SWord8 s5065 = s5049 ? s5063 : s5064;
-  const SBool  s5066 = (SBool) (s1842 & 1);
-  const SBool  s5067 = false != s5066;
-  const SWord8 s5068 = s5067 ? s5063 : s5064;
-  const SWord8 s5069 = s1825 ? s5065 : s5068;
-  const SBool  s5070 = (SBool) (s1858 & 1);
-  const SBool  s5071 = false != s5070;
-  const SBool  s5072 = (SBool) (s1851 & 1);
-  const SBool  s5073 = false != s5072;
-  const SWord8 s5074 = s5073 ? s5059 : s5060;
-  const SWord8 s5075 = (s5074 >> 1) | (s5074 << 7);
-  const SWord8 s5076 = 128 | s5075;
-  const SWord8 s5077 = 127 & s5075;
-  const SWord8 s5078 = s5071 ? s5076 : s5077;
-  const SBool  s5079 = (SBool) (s1863 & 1);
-  const SBool  s5080 = false != s5079;
-  const SWord8 s5081 = s5080 ? s5076 : s5077;
-  const SWord8 s5082 = s1825 ? s5078 : s5081;
-  const SWord8 s5083 = s1803 ? s5069 : s5082;
-  const SBool  s5084 = (SBool) (s1884 & 1);
-  const SBool  s5085 = false != s5084;
-  const SBool  s5086 = (SBool) (s1880 & 1);
-  const SBool  s5087 = false != s5086;
-  const SBool  s5088 = (SBool) (s1873 & 1);
-  const SBool  s5089 = false != s5088;
-  const SWord8 s5090 = s5089 ? s5055 : s5056;
-  const SWord8 s5091 = (s5090 >> 1) | (s5090 << 7);
-  const SWord8 s5092 = 128 | s5091;
-  const SWord8 s5093 = 127 & s5091;
-  const SWord8 s5094 = s5087 ? s5092 : s5093;
-  const SWord8 s5095 = (s5094 >> 1) | (s5094 << 7);
-  const SWord8 s5096 = 128 | s5095;
-  const SWord8 s5097 = 127 & s5095;
-  const SWord8 s5098 = s5085 ? s5096 : s5097;
-  const SBool  s5099 = (SBool) (s1889 & 1);
-  const SBool  s5100 = false != s5099;
-  const SWord8 s5101 = s5100 ? s5096 : s5097;
-  const SWord8 s5102 = s1825 ? s5098 : s5101;
-  const SBool  s5103 = (SBool) (s1905 & 1);
-  const SBool  s5104 = false != s5103;
-  const SBool  s5105 = (SBool) (s1898 & 1);
-  const SBool  s5106 = false != s5105;
-  const SWord8 s5107 = s5106 ? s5092 : s5093;
-  const SWord8 s5108 = (s5107 >> 1) | (s5107 << 7);
-  const SWord8 s5109 = 128 | s5108;
-  const SWord8 s5110 = 127 & s5108;
-  const SWord8 s5111 = s5104 ? s5109 : s5110;
-  const SBool  s5112 = (SBool) (s1910 & 1);
-  const SBool  s5113 = false != s5112;
-  const SWord8 s5114 = s5113 ? s5109 : s5110;
-  const SWord8 s5115 = s1825 ? s5111 : s5114;
-  const SWord8 s5116 = s1803 ? s5102 : s5115;
-  const SWord8 s5117 = s1548 ? s5083 : s5116;
-  const SBool  s5118 = (SBool) (s1945 & 1);
-  const SBool  s5119 = false != s5118;
-  const SBool  s5120 = (SBool) (s1941 & 1);
-  const SBool  s5121 = false != s5120;
-  const SBool  s5122 = (SBool) (s1937 & 1);
-  const SBool  s5123 = false != s5122;
-  const SWord8 s5124 = (s1924 >> 1) | (s1924 << 7);
-  const SWord8 s5125 = 128 | s5124;
-  const SWord8 s5126 = 127 & s5124;
-  const SWord8 s5127 = s5123 ? s5125 : s5126;
-  const SWord8 s5128 = (s5127 >> 1) | (s5127 << 7);
-  const SWord8 s5129 = 128 | s5128;
-  const SWord8 s5130 = 127 & s5128;
-  const SWord8 s5131 = s5121 ? s5129 : s5130;
-  const SWord8 s5132 = (s5131 >> 1) | (s5131 << 7);
-  const SWord8 s5133 = 128 | s5132;
-  const SWord8 s5134 = 127 & s5132;
-  const SWord8 s5135 = s5119 ? s5133 : s5134;
-  const SBool  s5136 = (SBool) (s1950 & 1);
-  const SBool  s5137 = false != s5136;
-  const SWord8 s5138 = s5137 ? s5133 : s5134;
-  const SWord8 s5139 = s1930 ? s5135 : s5138;
-  const SBool  s5140 = (SBool) (s1966 & 1);
-  const SBool  s5141 = false != s5140;
-  const SBool  s5142 = (SBool) (s1959 & 1);
-  const SBool  s5143 = false != s5142;
-  const SWord8 s5144 = s5143 ? s5129 : s5130;
-  const SWord8 s5145 = (s5144 >> 1) | (s5144 << 7);
-  const SWord8 s5146 = 128 | s5145;
-  const SWord8 s5147 = 127 & s5145;
-  const SWord8 s5148 = s5141 ? s5146 : s5147;
-  const SBool  s5149 = (SBool) (s1971 & 1);
-  const SBool  s5150 = false != s5149;
-  const SWord8 s5151 = s5150 ? s5146 : s5147;
-  const SWord8 s5152 = s1930 ? s5148 : s5151;
-  const SWord8 s5153 = s1803 ? s5139 : s5152;
-  const SBool  s5154 = (SBool) (s1992 & 1);
-  const SBool  s5155 = false != s5154;
-  const SBool  s5156 = (SBool) (s1988 & 1);
-  const SBool  s5157 = false != s5156;
-  const SBool  s5158 = (SBool) (s1981 & 1);
-  const SBool  s5159 = false != s5158;
-  const SWord8 s5160 = s5159 ? s5125 : s5126;
-  const SWord8 s5161 = (s5160 >> 1) | (s5160 << 7);
-  const SWord8 s5162 = 128 | s5161;
-  const SWord8 s5163 = 127 & s5161;
-  const SWord8 s5164 = s5157 ? s5162 : s5163;
-  const SWord8 s5165 = (s5164 >> 1) | (s5164 << 7);
-  const SWord8 s5166 = 128 | s5165;
-  const SWord8 s5167 = 127 & s5165;
-  const SWord8 s5168 = s5155 ? s5166 : s5167;
-  const SBool  s5169 = (SBool) (s1997 & 1);
-  const SBool  s5170 = false != s5169;
-  const SWord8 s5171 = s5170 ? s5166 : s5167;
-  const SWord8 s5172 = s1930 ? s5168 : s5171;
-  const SBool  s5173 = (SBool) (s2013 & 1);
-  const SBool  s5174 = false != s5173;
-  const SBool  s5175 = (SBool) (s2006 & 1);
-  const SBool  s5176 = false != s5175;
-  const SWord8 s5177 = s5176 ? s5162 : s5163;
-  const SWord8 s5178 = (s5177 >> 1) | (s5177 << 7);
-  const SWord8 s5179 = 128 | s5178;
-  const SWord8 s5180 = 127 & s5178;
-  const SWord8 s5181 = s5174 ? s5179 : s5180;
-  const SBool  s5182 = (SBool) (s2018 & 1);
-  const SBool  s5183 = false != s5182;
-  const SWord8 s5184 = s5183 ? s5179 : s5180;
-  const SWord8 s5185 = s1930 ? s5181 : s5184;
-  const SWord8 s5186 = s1803 ? s5172 : s5185;
-  const SWord8 s5187 = s1548 ? s5153 : s5186;
-  const SWord8 s5188 = s1037 ? s5117 : s5187;
-  const SWord8 s5189 = s21 ? s5047 : s5188;
-  const SWord8 s5190 = s16 ? s4906 : s5189;
-  const SWord8 s5191 = s11 ? s4623 : s5190;
-  const SBool  s5192 = (SBool) (s2128 & 1);
-  const SBool  s5193 = false != s5192;
-  const SBool  s5194 = (SBool) (s2124 & 1);
-  const SBool  s5195 = false != s5194;
-  const SBool  s5196 = (SBool) (s2120 & 1);
-  const SBool  s5197 = false != s5196;
-  const SWord8 s5198 = (s2107 >> 1) | (s2107 << 7);
-  const SWord8 s5199 = 128 | s5198;
-  const SWord8 s5200 = 127 & s5198;
-  const SWord8 s5201 = s5197 ? s5199 : s5200;
-  const SWord8 s5202 = (s5201 >> 1) | (s5201 << 7);
-  const SWord8 s5203 = 128 | s5202;
-  const SWord8 s5204 = 127 & s5202;
-  const SWord8 s5205 = s5195 ? s5203 : s5204;
-  const SWord8 s5206 = (s5205 >> 1) | (s5205 << 7);
-  const SWord8 s5207 = 128 | s5206;
-  const SWord8 s5208 = 127 & s5206;
-  const SWord8 s5209 = s5193 ? s5207 : s5208;
-  const SBool  s5210 = (SBool) (s2133 & 1);
-  const SBool  s5211 = false != s5210;
-  const SWord8 s5212 = s5211 ? s5207 : s5208;
-  const SWord8 s5213 = s2116 ? s5209 : s5212;
-  const SBool  s5214 = (SBool) (s2149 & 1);
-  const SBool  s5215 = false != s5214;
-  const SBool  s5216 = (SBool) (s2142 & 1);
-  const SBool  s5217 = false != s5216;
-  const SWord8 s5218 = s5217 ? s5203 : s5204;
-  const SWord8 s5219 = (s5218 >> 1) | (s5218 << 7);
-  const SWord8 s5220 = 128 | s5219;
-  const SWord8 s5221 = 127 & s5219;
-  const SWord8 s5222 = s5215 ? s5220 : s5221;
-  const SBool  s5223 = (SBool) (s2154 & 1);
-  const SBool  s5224 = false != s5223;
-  const SWord8 s5225 = s5224 ? s5220 : s5221;
-  const SWord8 s5226 = s2116 ? s5222 : s5225;
-  const SWord8 s5227 = s2097 ? s5213 : s5226;
-  const SBool  s5228 = (SBool) (s2175 & 1);
-  const SBool  s5229 = false != s5228;
-  const SBool  s5230 = (SBool) (s2171 & 1);
-  const SBool  s5231 = false != s5230;
-  const SBool  s5232 = (SBool) (s2164 & 1);
-  const SBool  s5233 = false != s5232;
-  const SWord8 s5234 = s5233 ? s5199 : s5200;
-  const SWord8 s5235 = (s5234 >> 1) | (s5234 << 7);
-  const SWord8 s5236 = 128 | s5235;
-  const SWord8 s5237 = 127 & s5235;
-  const SWord8 s5238 = s5231 ? s5236 : s5237;
-  const SWord8 s5239 = (s5238 >> 1) | (s5238 << 7);
-  const SWord8 s5240 = 128 | s5239;
-  const SWord8 s5241 = 127 & s5239;
-  const SWord8 s5242 = s5229 ? s5240 : s5241;
-  const SBool  s5243 = (SBool) (s2180 & 1);
-  const SBool  s5244 = false != s5243;
-  const SWord8 s5245 = s5244 ? s5240 : s5241;
-  const SWord8 s5246 = s2116 ? s5242 : s5245;
-  const SBool  s5247 = (SBool) (s2196 & 1);
-  const SBool  s5248 = false != s5247;
-  const SBool  s5249 = (SBool) (s2189 & 1);
-  const SBool  s5250 = false != s5249;
-  const SWord8 s5251 = s5250 ? s5236 : s5237;
-  const SWord8 s5252 = (s5251 >> 1) | (s5251 << 7);
-  const SWord8 s5253 = 128 | s5252;
-  const SWord8 s5254 = 127 & s5252;
-  const SWord8 s5255 = s5248 ? s5253 : s5254;
-  const SBool  s5256 = (SBool) (s2201 & 1);
-  const SBool  s5257 = false != s5256;
-  const SWord8 s5258 = s5257 ? s5253 : s5254;
-  const SWord8 s5259 = s2116 ? s5255 : s5258;
-  const SWord8 s5260 = s2097 ? s5246 : s5259;
-  const SWord8 s5261 = s2078 ? s5227 : s5260;
-  const SBool  s5262 = (SBool) (s2236 & 1);
-  const SBool  s5263 = false != s5262;
-  const SBool  s5264 = (SBool) (s2232 & 1);
-  const SBool  s5265 = false != s5264;
-  const SBool  s5266 = (SBool) (s2228 & 1);
-  const SBool  s5267 = false != s5266;
-  const SWord8 s5268 = (s2215 >> 1) | (s2215 << 7);
-  const SWord8 s5269 = 128 | s5268;
-  const SWord8 s5270 = 127 & s5268;
-  const SWord8 s5271 = s5267 ? s5269 : s5270;
-  const SWord8 s5272 = (s5271 >> 1) | (s5271 << 7);
-  const SWord8 s5273 = 128 | s5272;
-  const SWord8 s5274 = 127 & s5272;
-  const SWord8 s5275 = s5265 ? s5273 : s5274;
-  const SWord8 s5276 = (s5275 >> 1) | (s5275 << 7);
-  const SWord8 s5277 = 128 | s5276;
-  const SWord8 s5278 = 127 & s5276;
-  const SWord8 s5279 = s5263 ? s5277 : s5278;
-  const SBool  s5280 = (SBool) (s2241 & 1);
-  const SBool  s5281 = false != s5280;
-  const SWord8 s5282 = s5281 ? s5277 : s5278;
-  const SWord8 s5283 = s2221 ? s5279 : s5282;
-  const SBool  s5284 = (SBool) (s2257 & 1);
-  const SBool  s5285 = false != s5284;
-  const SBool  s5286 = (SBool) (s2250 & 1);
-  const SBool  s5287 = false != s5286;
-  const SWord8 s5288 = s5287 ? s5273 : s5274;
-  const SWord8 s5289 = (s5288 >> 1) | (s5288 << 7);
-  const SWord8 s5290 = 128 | s5289;
-  const SWord8 s5291 = 127 & s5289;
-  const SWord8 s5292 = s5285 ? s5290 : s5291;
-  const SBool  s5293 = (SBool) (s2262 & 1);
-  const SBool  s5294 = false != s5293;
-  const SWord8 s5295 = s5294 ? s5290 : s5291;
-  const SWord8 s5296 = s2221 ? s5292 : s5295;
-  const SWord8 s5297 = s2097 ? s5283 : s5296;
-  const SBool  s5298 = (SBool) (s2283 & 1);
-  const SBool  s5299 = false != s5298;
-  const SBool  s5300 = (SBool) (s2279 & 1);
-  const SBool  s5301 = false != s5300;
-  const SBool  s5302 = (SBool) (s2272 & 1);
-  const SBool  s5303 = false != s5302;
-  const SWord8 s5304 = s5303 ? s5269 : s5270;
-  const SWord8 s5305 = (s5304 >> 1) | (s5304 << 7);
-  const SWord8 s5306 = 128 | s5305;
-  const SWord8 s5307 = 127 & s5305;
-  const SWord8 s5308 = s5301 ? s5306 : s5307;
-  const SWord8 s5309 = (s5308 >> 1) | (s5308 << 7);
-  const SWord8 s5310 = 128 | s5309;
-  const SWord8 s5311 = 127 & s5309;
-  const SWord8 s5312 = s5299 ? s5310 : s5311;
-  const SBool  s5313 = (SBool) (s2288 & 1);
-  const SBool  s5314 = false != s5313;
-  const SWord8 s5315 = s5314 ? s5310 : s5311;
-  const SWord8 s5316 = s2221 ? s5312 : s5315;
-  const SBool  s5317 = (SBool) (s2304 & 1);
-  const SBool  s5318 = false != s5317;
-  const SBool  s5319 = (SBool) (s2297 & 1);
-  const SBool  s5320 = false != s5319;
-  const SWord8 s5321 = s5320 ? s5306 : s5307;
-  const SWord8 s5322 = (s5321 >> 1) | (s5321 << 7);
-  const SWord8 s5323 = 128 | s5322;
-  const SWord8 s5324 = 127 & s5322;
-  const SWord8 s5325 = s5318 ? s5323 : s5324;
-  const SBool  s5326 = (SBool) (s2309 & 1);
-  const SBool  s5327 = false != s5326;
-  const SWord8 s5328 = s5327 ? s5323 : s5324;
-  const SWord8 s5329 = s2221 ? s5325 : s5328;
-  const SWord8 s5330 = s2097 ? s5316 : s5329;
-  const SWord8 s5331 = s2078 ? s5297 : s5330;
-  const SWord8 s5332 = s2059 ? s5261 : s5331;
-  const SBool  s5333 = (SBool) (s2364 & 1);
-  const SBool  s5334 = false != s5333;
-  const SBool  s5335 = (SBool) (s2360 & 1);
-  const SBool  s5336 = false != s5335;
-  const SBool  s5337 = (SBool) (s2356 & 1);
-  const SBool  s5338 = false != s5337;
-  const SWord8 s5339 = (s2343 >> 1) | (s2343 << 7);
-  const SWord8 s5340 = 128 | s5339;
-  const SWord8 s5341 = 127 & s5339;
-  const SWord8 s5342 = s5338 ? s5340 : s5341;
-  const SWord8 s5343 = (s5342 >> 1) | (s5342 << 7);
-  const SWord8 s5344 = 128 | s5343;
-  const SWord8 s5345 = 127 & s5343;
-  const SWord8 s5346 = s5336 ? s5344 : s5345;
-  const SWord8 s5347 = (s5346 >> 1) | (s5346 << 7);
-  const SWord8 s5348 = 128 | s5347;
-  const SWord8 s5349 = 127 & s5347;
-  const SWord8 s5350 = s5334 ? s5348 : s5349;
-  const SBool  s5351 = (SBool) (s2369 & 1);
-  const SBool  s5352 = false != s5351;
-  const SWord8 s5353 = s5352 ? s5348 : s5349;
-  const SWord8 s5354 = s2352 ? s5350 : s5353;
-  const SBool  s5355 = (SBool) (s2385 & 1);
-  const SBool  s5356 = false != s5355;
-  const SBool  s5357 = (SBool) (s2378 & 1);
-  const SBool  s5358 = false != s5357;
-  const SWord8 s5359 = s5358 ? s5344 : s5345;
-  const SWord8 s5360 = (s5359 >> 1) | (s5359 << 7);
-  const SWord8 s5361 = 128 | s5360;
-  const SWord8 s5362 = 127 & s5360;
-  const SWord8 s5363 = s5356 ? s5361 : s5362;
-  const SBool  s5364 = (SBool) (s2390 & 1);
-  const SBool  s5365 = false != s5364;
-  const SWord8 s5366 = s5365 ? s5361 : s5362;
-  const SWord8 s5367 = s2352 ? s5363 : s5366;
-  const SWord8 s5368 = s2330 ? s5354 : s5367;
-  const SBool  s5369 = (SBool) (s2411 & 1);
-  const SBool  s5370 = false != s5369;
-  const SBool  s5371 = (SBool) (s2407 & 1);
-  const SBool  s5372 = false != s5371;
-  const SBool  s5373 = (SBool) (s2400 & 1);
-  const SBool  s5374 = false != s5373;
-  const SWord8 s5375 = s5374 ? s5340 : s5341;
-  const SWord8 s5376 = (s5375 >> 1) | (s5375 << 7);
-  const SWord8 s5377 = 128 | s5376;
-  const SWord8 s5378 = 127 & s5376;
-  const SWord8 s5379 = s5372 ? s5377 : s5378;
-  const SWord8 s5380 = (s5379 >> 1) | (s5379 << 7);
-  const SWord8 s5381 = 128 | s5380;
-  const SWord8 s5382 = 127 & s5380;
-  const SWord8 s5383 = s5370 ? s5381 : s5382;
-  const SBool  s5384 = (SBool) (s2416 & 1);
-  const SBool  s5385 = false != s5384;
-  const SWord8 s5386 = s5385 ? s5381 : s5382;
-  const SWord8 s5387 = s2352 ? s5383 : s5386;
-  const SBool  s5388 = (SBool) (s2432 & 1);
-  const SBool  s5389 = false != s5388;
-  const SBool  s5390 = (SBool) (s2425 & 1);
-  const SBool  s5391 = false != s5390;
-  const SWord8 s5392 = s5391 ? s5377 : s5378;
-  const SWord8 s5393 = (s5392 >> 1) | (s5392 << 7);
-  const SWord8 s5394 = 128 | s5393;
-  const SWord8 s5395 = 127 & s5393;
-  const SWord8 s5396 = s5389 ? s5394 : s5395;
-  const SBool  s5397 = (SBool) (s2437 & 1);
-  const SBool  s5398 = false != s5397;
-  const SWord8 s5399 = s5398 ? s5394 : s5395;
-  const SWord8 s5400 = s2352 ? s5396 : s5399;
-  const SWord8 s5401 = s2330 ? s5387 : s5400;
-  const SWord8 s5402 = s2078 ? s5368 : s5401;
-  const SBool  s5403 = (SBool) (s2472 & 1);
-  const SBool  s5404 = false != s5403;
-  const SBool  s5405 = (SBool) (s2468 & 1);
-  const SBool  s5406 = false != s5405;
-  const SBool  s5407 = (SBool) (s2464 & 1);
-  const SBool  s5408 = false != s5407;
-  const SWord8 s5409 = (s2451 >> 1) | (s2451 << 7);
-  const SWord8 s5410 = 128 | s5409;
-  const SWord8 s5411 = 127 & s5409;
-  const SWord8 s5412 = s5408 ? s5410 : s5411;
-  const SWord8 s5413 = (s5412 >> 1) | (s5412 << 7);
-  const SWord8 s5414 = 128 | s5413;
-  const SWord8 s5415 = 127 & s5413;
-  const SWord8 s5416 = s5406 ? s5414 : s5415;
-  const SWord8 s5417 = (s5416 >> 1) | (s5416 << 7);
-  const SWord8 s5418 = 128 | s5417;
-  const SWord8 s5419 = 127 & s5417;
-  const SWord8 s5420 = s5404 ? s5418 : s5419;
-  const SBool  s5421 = (SBool) (s2477 & 1);
-  const SBool  s5422 = false != s5421;
-  const SWord8 s5423 = s5422 ? s5418 : s5419;
-  const SWord8 s5424 = s2457 ? s5420 : s5423;
-  const SBool  s5425 = (SBool) (s2493 & 1);
-  const SBool  s5426 = false != s5425;
-  const SBool  s5427 = (SBool) (s2486 & 1);
-  const SBool  s5428 = false != s5427;
-  const SWord8 s5429 = s5428 ? s5414 : s5415;
-  const SWord8 s5430 = (s5429 >> 1) | (s5429 << 7);
-  const SWord8 s5431 = 128 | s5430;
-  const SWord8 s5432 = 127 & s5430;
-  const SWord8 s5433 = s5426 ? s5431 : s5432;
-  const SBool  s5434 = (SBool) (s2498 & 1);
-  const SBool  s5435 = false != s5434;
-  const SWord8 s5436 = s5435 ? s5431 : s5432;
-  const SWord8 s5437 = s2457 ? s5433 : s5436;
-  const SWord8 s5438 = s2330 ? s5424 : s5437;
-  const SBool  s5439 = (SBool) (s2519 & 1);
-  const SBool  s5440 = false != s5439;
-  const SBool  s5441 = (SBool) (s2515 & 1);
-  const SBool  s5442 = false != s5441;
-  const SBool  s5443 = (SBool) (s2508 & 1);
-  const SBool  s5444 = false != s5443;
-  const SWord8 s5445 = s5444 ? s5410 : s5411;
-  const SWord8 s5446 = (s5445 >> 1) | (s5445 << 7);
-  const SWord8 s5447 = 128 | s5446;
-  const SWord8 s5448 = 127 & s5446;
-  const SWord8 s5449 = s5442 ? s5447 : s5448;
-  const SWord8 s5450 = (s5449 >> 1) | (s5449 << 7);
-  const SWord8 s5451 = 128 | s5450;
-  const SWord8 s5452 = 127 & s5450;
-  const SWord8 s5453 = s5440 ? s5451 : s5452;
-  const SBool  s5454 = (SBool) (s2524 & 1);
-  const SBool  s5455 = false != s5454;
-  const SWord8 s5456 = s5455 ? s5451 : s5452;
-  const SWord8 s5457 = s2457 ? s5453 : s5456;
-  const SBool  s5458 = (SBool) (s2540 & 1);
-  const SBool  s5459 = false != s5458;
-  const SBool  s5460 = (SBool) (s2533 & 1);
-  const SBool  s5461 = false != s5460;
-  const SWord8 s5462 = s5461 ? s5447 : s5448;
-  const SWord8 s5463 = (s5462 >> 1) | (s5462 << 7);
-  const SWord8 s5464 = 128 | s5463;
-  const SWord8 s5465 = 127 & s5463;
-  const SWord8 s5466 = s5459 ? s5464 : s5465;
-  const SBool  s5467 = (SBool) (s2545 & 1);
-  const SBool  s5468 = false != s5467;
-  const SWord8 s5469 = s5468 ? s5464 : s5465;
-  const SWord8 s5470 = s2457 ? s5466 : s5469;
-  const SWord8 s5471 = s2330 ? s5457 : s5470;
-  const SWord8 s5472 = s2078 ? s5438 : s5471;
-  const SWord8 s5473 = s2059 ? s5402 : s5472;
-  const SWord8 s5474 = s2042 ? s5332 : s5473;
-  const SBool  s5475 = (SBool) (s2620 & 1);
-  const SBool  s5476 = false != s5475;
-  const SBool  s5477 = (SBool) (s2616 & 1);
-  const SBool  s5478 = false != s5477;
-  const SBool  s5479 = (SBool) (s2612 & 1);
-  const SBool  s5480 = false != s5479;
-  const SWord8 s5481 = (s2599 >> 1) | (s2599 << 7);
-  const SWord8 s5482 = 128 | s5481;
-  const SWord8 s5483 = 127 & s5481;
-  const SWord8 s5484 = s5480 ? s5482 : s5483;
-  const SWord8 s5485 = (s5484 >> 1) | (s5484 << 7);
-  const SWord8 s5486 = 128 | s5485;
-  const SWord8 s5487 = 127 & s5485;
-  const SWord8 s5488 = s5478 ? s5486 : s5487;
-  const SWord8 s5489 = (s5488 >> 1) | (s5488 << 7);
-  const SWord8 s5490 = 128 | s5489;
-  const SWord8 s5491 = 127 & s5489;
-  const SWord8 s5492 = s5476 ? s5490 : s5491;
-  const SBool  s5493 = (SBool) (s2625 & 1);
-  const SBool  s5494 = false != s5493;
-  const SWord8 s5495 = s5494 ? s5490 : s5491;
-  const SWord8 s5496 = s2608 ? s5492 : s5495;
-  const SBool  s5497 = (SBool) (s2641 & 1);
-  const SBool  s5498 = false != s5497;
-  const SBool  s5499 = (SBool) (s2634 & 1);
-  const SBool  s5500 = false != s5499;
-  const SWord8 s5501 = s5500 ? s5486 : s5487;
-  const SWord8 s5502 = (s5501 >> 1) | (s5501 << 7);
-  const SWord8 s5503 = 128 | s5502;
-  const SWord8 s5504 = 127 & s5502;
-  const SWord8 s5505 = s5498 ? s5503 : s5504;
-  const SBool  s5506 = (SBool) (s2646 & 1);
-  const SBool  s5507 = false != s5506;
-  const SWord8 s5508 = s5507 ? s5503 : s5504;
-  const SWord8 s5509 = s2608 ? s5505 : s5508;
-  const SWord8 s5510 = s2589 ? s5496 : s5509;
-  const SBool  s5511 = (SBool) (s2667 & 1);
-  const SBool  s5512 = false != s5511;
-  const SBool  s5513 = (SBool) (s2663 & 1);
-  const SBool  s5514 = false != s5513;
-  const SBool  s5515 = (SBool) (s2656 & 1);
-  const SBool  s5516 = false != s5515;
-  const SWord8 s5517 = s5516 ? s5482 : s5483;
-  const SWord8 s5518 = (s5517 >> 1) | (s5517 << 7);
-  const SWord8 s5519 = 128 | s5518;
-  const SWord8 s5520 = 127 & s5518;
-  const SWord8 s5521 = s5514 ? s5519 : s5520;
-  const SWord8 s5522 = (s5521 >> 1) | (s5521 << 7);
-  const SWord8 s5523 = 128 | s5522;
-  const SWord8 s5524 = 127 & s5522;
-  const SWord8 s5525 = s5512 ? s5523 : s5524;
-  const SBool  s5526 = (SBool) (s2672 & 1);
-  const SBool  s5527 = false != s5526;
-  const SWord8 s5528 = s5527 ? s5523 : s5524;
-  const SWord8 s5529 = s2608 ? s5525 : s5528;
-  const SBool  s5530 = (SBool) (s2688 & 1);
-  const SBool  s5531 = false != s5530;
-  const SBool  s5532 = (SBool) (s2681 & 1);
-  const SBool  s5533 = false != s5532;
-  const SWord8 s5534 = s5533 ? s5519 : s5520;
-  const SWord8 s5535 = (s5534 >> 1) | (s5534 << 7);
-  const SWord8 s5536 = 128 | s5535;
-  const SWord8 s5537 = 127 & s5535;
-  const SWord8 s5538 = s5531 ? s5536 : s5537;
-  const SBool  s5539 = (SBool) (s2693 & 1);
-  const SBool  s5540 = false != s5539;
-  const SWord8 s5541 = s5540 ? s5536 : s5537;
-  const SWord8 s5542 = s2608 ? s5538 : s5541;
-  const SWord8 s5543 = s2589 ? s5529 : s5542;
-  const SWord8 s5544 = s2567 ? s5510 : s5543;
-  const SBool  s5545 = (SBool) (s2728 & 1);
-  const SBool  s5546 = false != s5545;
-  const SBool  s5547 = (SBool) (s2724 & 1);
-  const SBool  s5548 = false != s5547;
-  const SBool  s5549 = (SBool) (s2720 & 1);
-  const SBool  s5550 = false != s5549;
-  const SWord8 s5551 = (s2707 >> 1) | (s2707 << 7);
-  const SWord8 s5552 = 128 | s5551;
-  const SWord8 s5553 = 127 & s5551;
-  const SWord8 s5554 = s5550 ? s5552 : s5553;
-  const SWord8 s5555 = (s5554 >> 1) | (s5554 << 7);
-  const SWord8 s5556 = 128 | s5555;
-  const SWord8 s5557 = 127 & s5555;
-  const SWord8 s5558 = s5548 ? s5556 : s5557;
-  const SWord8 s5559 = (s5558 >> 1) | (s5558 << 7);
-  const SWord8 s5560 = 128 | s5559;
-  const SWord8 s5561 = 127 & s5559;
-  const SWord8 s5562 = s5546 ? s5560 : s5561;
-  const SBool  s5563 = (SBool) (s2733 & 1);
-  const SBool  s5564 = false != s5563;
-  const SWord8 s5565 = s5564 ? s5560 : s5561;
-  const SWord8 s5566 = s2713 ? s5562 : s5565;
-  const SBool  s5567 = (SBool) (s2749 & 1);
-  const SBool  s5568 = false != s5567;
-  const SBool  s5569 = (SBool) (s2742 & 1);
-  const SBool  s5570 = false != s5569;
-  const SWord8 s5571 = s5570 ? s5556 : s5557;
-  const SWord8 s5572 = (s5571 >> 1) | (s5571 << 7);
-  const SWord8 s5573 = 128 | s5572;
-  const SWord8 s5574 = 127 & s5572;
-  const SWord8 s5575 = s5568 ? s5573 : s5574;
-  const SBool  s5576 = (SBool) (s2754 & 1);
-  const SBool  s5577 = false != s5576;
-  const SWord8 s5578 = s5577 ? s5573 : s5574;
-  const SWord8 s5579 = s2713 ? s5575 : s5578;
-  const SWord8 s5580 = s2589 ? s5566 : s5579;
-  const SBool  s5581 = (SBool) (s2775 & 1);
-  const SBool  s5582 = false != s5581;
-  const SBool  s5583 = (SBool) (s2771 & 1);
-  const SBool  s5584 = false != s5583;
-  const SBool  s5585 = (SBool) (s2764 & 1);
-  const SBool  s5586 = false != s5585;
-  const SWord8 s5587 = s5586 ? s5552 : s5553;
-  const SWord8 s5588 = (s5587 >> 1) | (s5587 << 7);
-  const SWord8 s5589 = 128 | s5588;
-  const SWord8 s5590 = 127 & s5588;
-  const SWord8 s5591 = s5584 ? s5589 : s5590;
-  const SWord8 s5592 = (s5591 >> 1) | (s5591 << 7);
-  const SWord8 s5593 = 128 | s5592;
-  const SWord8 s5594 = 127 & s5592;
-  const SWord8 s5595 = s5582 ? s5593 : s5594;
-  const SBool  s5596 = (SBool) (s2780 & 1);
-  const SBool  s5597 = false != s5596;
-  const SWord8 s5598 = s5597 ? s5593 : s5594;
-  const SWord8 s5599 = s2713 ? s5595 : s5598;
-  const SBool  s5600 = (SBool) (s2796 & 1);
-  const SBool  s5601 = false != s5600;
-  const SBool  s5602 = (SBool) (s2789 & 1);
-  const SBool  s5603 = false != s5602;
-  const SWord8 s5604 = s5603 ? s5589 : s5590;
-  const SWord8 s5605 = (s5604 >> 1) | (s5604 << 7);
-  const SWord8 s5606 = 128 | s5605;
-  const SWord8 s5607 = 127 & s5605;
-  const SWord8 s5608 = s5601 ? s5606 : s5607;
-  const SBool  s5609 = (SBool) (s2801 & 1);
-  const SBool  s5610 = false != s5609;
-  const SWord8 s5611 = s5610 ? s5606 : s5607;
-  const SWord8 s5612 = s2713 ? s5608 : s5611;
-  const SWord8 s5613 = s2589 ? s5599 : s5612;
-  const SWord8 s5614 = s2567 ? s5580 : s5613;
-  const SWord8 s5615 = s2059 ? s5544 : s5614;
-  const SBool  s5616 = (SBool) (s2856 & 1);
-  const SBool  s5617 = false != s5616;
-  const SBool  s5618 = (SBool) (s2852 & 1);
-  const SBool  s5619 = false != s5618;
-  const SBool  s5620 = (SBool) (s2848 & 1);
-  const SBool  s5621 = false != s5620;
-  const SWord8 s5622 = (s2835 >> 1) | (s2835 << 7);
-  const SWord8 s5623 = 128 | s5622;
-  const SWord8 s5624 = 127 & s5622;
-  const SWord8 s5625 = s5621 ? s5623 : s5624;
-  const SWord8 s5626 = (s5625 >> 1) | (s5625 << 7);
-  const SWord8 s5627 = 128 | s5626;
-  const SWord8 s5628 = 127 & s5626;
-  const SWord8 s5629 = s5619 ? s5627 : s5628;
-  const SWord8 s5630 = (s5629 >> 1) | (s5629 << 7);
-  const SWord8 s5631 = 128 | s5630;
-  const SWord8 s5632 = 127 & s5630;
-  const SWord8 s5633 = s5617 ? s5631 : s5632;
-  const SBool  s5634 = (SBool) (s2861 & 1);
-  const SBool  s5635 = false != s5634;
-  const SWord8 s5636 = s5635 ? s5631 : s5632;
-  const SWord8 s5637 = s2844 ? s5633 : s5636;
-  const SBool  s5638 = (SBool) (s2877 & 1);
-  const SBool  s5639 = false != s5638;
-  const SBool  s5640 = (SBool) (s2870 & 1);
-  const SBool  s5641 = false != s5640;
-  const SWord8 s5642 = s5641 ? s5627 : s5628;
-  const SWord8 s5643 = (s5642 >> 1) | (s5642 << 7);
-  const SWord8 s5644 = 128 | s5643;
-  const SWord8 s5645 = 127 & s5643;
-  const SWord8 s5646 = s5639 ? s5644 : s5645;
-  const SBool  s5647 = (SBool) (s2882 & 1);
-  const SBool  s5648 = false != s5647;
-  const SWord8 s5649 = s5648 ? s5644 : s5645;
-  const SWord8 s5650 = s2844 ? s5646 : s5649;
-  const SWord8 s5651 = s2822 ? s5637 : s5650;
-  const SBool  s5652 = (SBool) (s2903 & 1);
-  const SBool  s5653 = false != s5652;
-  const SBool  s5654 = (SBool) (s2899 & 1);
-  const SBool  s5655 = false != s5654;
-  const SBool  s5656 = (SBool) (s2892 & 1);
-  const SBool  s5657 = false != s5656;
-  const SWord8 s5658 = s5657 ? s5623 : s5624;
-  const SWord8 s5659 = (s5658 >> 1) | (s5658 << 7);
-  const SWord8 s5660 = 128 | s5659;
-  const SWord8 s5661 = 127 & s5659;
-  const SWord8 s5662 = s5655 ? s5660 : s5661;
-  const SWord8 s5663 = (s5662 >> 1) | (s5662 << 7);
-  const SWord8 s5664 = 128 | s5663;
-  const SWord8 s5665 = 127 & s5663;
-  const SWord8 s5666 = s5653 ? s5664 : s5665;
-  const SBool  s5667 = (SBool) (s2908 & 1);
-  const SBool  s5668 = false != s5667;
-  const SWord8 s5669 = s5668 ? s5664 : s5665;
-  const SWord8 s5670 = s2844 ? s5666 : s5669;
-  const SBool  s5671 = (SBool) (s2924 & 1);
-  const SBool  s5672 = false != s5671;
-  const SBool  s5673 = (SBool) (s2917 & 1);
-  const SBool  s5674 = false != s5673;
-  const SWord8 s5675 = s5674 ? s5660 : s5661;
-  const SWord8 s5676 = (s5675 >> 1) | (s5675 << 7);
-  const SWord8 s5677 = 128 | s5676;
-  const SWord8 s5678 = 127 & s5676;
-  const SWord8 s5679 = s5672 ? s5677 : s5678;
-  const SBool  s5680 = (SBool) (s2929 & 1);
-  const SBool  s5681 = false != s5680;
-  const SWord8 s5682 = s5681 ? s5677 : s5678;
-  const SWord8 s5683 = s2844 ? s5679 : s5682;
-  const SWord8 s5684 = s2822 ? s5670 : s5683;
-  const SWord8 s5685 = s2567 ? s5651 : s5684;
-  const SBool  s5686 = (SBool) (s2964 & 1);
-  const SBool  s5687 = false != s5686;
-  const SBool  s5688 = (SBool) (s2960 & 1);
-  const SBool  s5689 = false != s5688;
-  const SBool  s5690 = (SBool) (s2956 & 1);
-  const SBool  s5691 = false != s5690;
-  const SWord8 s5692 = (s2943 >> 1) | (s2943 << 7);
-  const SWord8 s5693 = 128 | s5692;
-  const SWord8 s5694 = 127 & s5692;
-  const SWord8 s5695 = s5691 ? s5693 : s5694;
-  const SWord8 s5696 = (s5695 >> 1) | (s5695 << 7);
-  const SWord8 s5697 = 128 | s5696;
-  const SWord8 s5698 = 127 & s5696;
-  const SWord8 s5699 = s5689 ? s5697 : s5698;
-  const SWord8 s5700 = (s5699 >> 1) | (s5699 << 7);
-  const SWord8 s5701 = 128 | s5700;
-  const SWord8 s5702 = 127 & s5700;
-  const SWord8 s5703 = s5687 ? s5701 : s5702;
-  const SBool  s5704 = (SBool) (s2969 & 1);
-  const SBool  s5705 = false != s5704;
-  const SWord8 s5706 = s5705 ? s5701 : s5702;
-  const SWord8 s5707 = s2949 ? s5703 : s5706;
-  const SBool  s5708 = (SBool) (s2985 & 1);
-  const SBool  s5709 = false != s5708;
-  const SBool  s5710 = (SBool) (s2978 & 1);
-  const SBool  s5711 = false != s5710;
-  const SWord8 s5712 = s5711 ? s5697 : s5698;
-  const SWord8 s5713 = (s5712 >> 1) | (s5712 << 7);
-  const SWord8 s5714 = 128 | s5713;
-  const SWord8 s5715 = 127 & s5713;
-  const SWord8 s5716 = s5709 ? s5714 : s5715;
-  const SBool  s5717 = (SBool) (s2990 & 1);
-  const SBool  s5718 = false != s5717;
-  const SWord8 s5719 = s5718 ? s5714 : s5715;
-  const SWord8 s5720 = s2949 ? s5716 : s5719;
-  const SWord8 s5721 = s2822 ? s5707 : s5720;
-  const SBool  s5722 = (SBool) (s3011 & 1);
-  const SBool  s5723 = false != s5722;
-  const SBool  s5724 = (SBool) (s3007 & 1);
-  const SBool  s5725 = false != s5724;
-  const SBool  s5726 = (SBool) (s3000 & 1);
-  const SBool  s5727 = false != s5726;
-  const SWord8 s5728 = s5727 ? s5693 : s5694;
-  const SWord8 s5729 = (s5728 >> 1) | (s5728 << 7);
-  const SWord8 s5730 = 128 | s5729;
-  const SWord8 s5731 = 127 & s5729;
-  const SWord8 s5732 = s5725 ? s5730 : s5731;
-  const SWord8 s5733 = (s5732 >> 1) | (s5732 << 7);
-  const SWord8 s5734 = 128 | s5733;
-  const SWord8 s5735 = 127 & s5733;
-  const SWord8 s5736 = s5723 ? s5734 : s5735;
-  const SBool  s5737 = (SBool) (s3016 & 1);
-  const SBool  s5738 = false != s5737;
-  const SWord8 s5739 = s5738 ? s5734 : s5735;
-  const SWord8 s5740 = s2949 ? s5736 : s5739;
-  const SBool  s5741 = (SBool) (s3032 & 1);
-  const SBool  s5742 = false != s5741;
-  const SBool  s5743 = (SBool) (s3025 & 1);
-  const SBool  s5744 = false != s5743;
-  const SWord8 s5745 = s5744 ? s5730 : s5731;
-  const SWord8 s5746 = (s5745 >> 1) | (s5745 << 7);
-  const SWord8 s5747 = 128 | s5746;
-  const SWord8 s5748 = 127 & s5746;
-  const SWord8 s5749 = s5742 ? s5747 : s5748;
-  const SBool  s5750 = (SBool) (s3037 & 1);
-  const SBool  s5751 = false != s5750;
-  const SWord8 s5752 = s5751 ? s5747 : s5748;
-  const SWord8 s5753 = s2949 ? s5749 : s5752;
-  const SWord8 s5754 = s2822 ? s5740 : s5753;
-  const SWord8 s5755 = s2567 ? s5721 : s5754;
-  const SWord8 s5756 = s2059 ? s5685 : s5755;
-  const SWord8 s5757 = s2042 ? s5615 : s5756;
-  const SWord8 s5758 = s16 ? s5474 : s5757;
-  const SBool  s5759 = (SBool) (s3132 & 1);
-  const SBool  s5760 = false != s5759;
-  const SBool  s5761 = (SBool) (s3128 & 1);
-  const SBool  s5762 = false != s5761;
-  const SBool  s5763 = (SBool) (s3124 & 1);
-  const SBool  s5764 = false != s5763;
-  const SWord8 s5765 = (s3111 >> 1) | (s3111 << 7);
-  const SWord8 s5766 = 128 | s5765;
-  const SWord8 s5767 = 127 & s5765;
-  const SWord8 s5768 = s5764 ? s5766 : s5767;
-  const SWord8 s5769 = (s5768 >> 1) | (s5768 << 7);
-  const SWord8 s5770 = 128 | s5769;
-  const SWord8 s5771 = 127 & s5769;
-  const SWord8 s5772 = s5762 ? s5770 : s5771;
-  const SWord8 s5773 = (s5772 >> 1) | (s5772 << 7);
-  const SWord8 s5774 = 128 | s5773;
-  const SWord8 s5775 = 127 & s5773;
-  const SWord8 s5776 = s5760 ? s5774 : s5775;
-  const SBool  s5777 = (SBool) (s3137 & 1);
-  const SBool  s5778 = false != s5777;
-  const SWord8 s5779 = s5778 ? s5774 : s5775;
-  const SWord8 s5780 = s3120 ? s5776 : s5779;
-  const SBool  s5781 = (SBool) (s3153 & 1);
-  const SBool  s5782 = false != s5781;
-  const SBool  s5783 = (SBool) (s3146 & 1);
-  const SBool  s5784 = false != s5783;
-  const SWord8 s5785 = s5784 ? s5770 : s5771;
-  const SWord8 s5786 = (s5785 >> 1) | (s5785 << 7);
-  const SWord8 s5787 = 128 | s5786;
-  const SWord8 s5788 = 127 & s5786;
-  const SWord8 s5789 = s5782 ? s5787 : s5788;
-  const SBool  s5790 = (SBool) (s3158 & 1);
-  const SBool  s5791 = false != s5790;
-  const SWord8 s5792 = s5791 ? s5787 : s5788;
-  const SWord8 s5793 = s3120 ? s5789 : s5792;
-  const SWord8 s5794 = s3101 ? s5780 : s5793;
-  const SBool  s5795 = (SBool) (s3179 & 1);
-  const SBool  s5796 = false != s5795;
-  const SBool  s5797 = (SBool) (s3175 & 1);
-  const SBool  s5798 = false != s5797;
-  const SBool  s5799 = (SBool) (s3168 & 1);
-  const SBool  s5800 = false != s5799;
-  const SWord8 s5801 = s5800 ? s5766 : s5767;
-  const SWord8 s5802 = (s5801 >> 1) | (s5801 << 7);
-  const SWord8 s5803 = 128 | s5802;
-  const SWord8 s5804 = 127 & s5802;
-  const SWord8 s5805 = s5798 ? s5803 : s5804;
-  const SWord8 s5806 = (s5805 >> 1) | (s5805 << 7);
-  const SWord8 s5807 = 128 | s5806;
-  const SWord8 s5808 = 127 & s5806;
-  const SWord8 s5809 = s5796 ? s5807 : s5808;
-  const SBool  s5810 = (SBool) (s3184 & 1);
-  const SBool  s5811 = false != s5810;
-  const SWord8 s5812 = s5811 ? s5807 : s5808;
-  const SWord8 s5813 = s3120 ? s5809 : s5812;
-  const SBool  s5814 = (SBool) (s3200 & 1);
-  const SBool  s5815 = false != s5814;
-  const SBool  s5816 = (SBool) (s3193 & 1);
-  const SBool  s5817 = false != s5816;
-  const SWord8 s5818 = s5817 ? s5803 : s5804;
-  const SWord8 s5819 = (s5818 >> 1) | (s5818 << 7);
-  const SWord8 s5820 = 128 | s5819;
-  const SWord8 s5821 = 127 & s5819;
-  const SWord8 s5822 = s5815 ? s5820 : s5821;
-  const SBool  s5823 = (SBool) (s3205 & 1);
-  const SBool  s5824 = false != s5823;
-  const SWord8 s5825 = s5824 ? s5820 : s5821;
-  const SWord8 s5826 = s3120 ? s5822 : s5825;
-  const SWord8 s5827 = s3101 ? s5813 : s5826;
-  const SWord8 s5828 = s3082 ? s5794 : s5827;
-  const SBool  s5829 = (SBool) (s3240 & 1);
-  const SBool  s5830 = false != s5829;
-  const SBool  s5831 = (SBool) (s3236 & 1);
-  const SBool  s5832 = false != s5831;
-  const SBool  s5833 = (SBool) (s3232 & 1);
-  const SBool  s5834 = false != s5833;
-  const SWord8 s5835 = (s3219 >> 1) | (s3219 << 7);
-  const SWord8 s5836 = 128 | s5835;
-  const SWord8 s5837 = 127 & s5835;
-  const SWord8 s5838 = s5834 ? s5836 : s5837;
-  const SWord8 s5839 = (s5838 >> 1) | (s5838 << 7);
-  const SWord8 s5840 = 128 | s5839;
-  const SWord8 s5841 = 127 & s5839;
-  const SWord8 s5842 = s5832 ? s5840 : s5841;
-  const SWord8 s5843 = (s5842 >> 1) | (s5842 << 7);
-  const SWord8 s5844 = 128 | s5843;
-  const SWord8 s5845 = 127 & s5843;
-  const SWord8 s5846 = s5830 ? s5844 : s5845;
-  const SBool  s5847 = (SBool) (s3245 & 1);
-  const SBool  s5848 = false != s5847;
-  const SWord8 s5849 = s5848 ? s5844 : s5845;
-  const SWord8 s5850 = s3225 ? s5846 : s5849;
-  const SBool  s5851 = (SBool) (s3261 & 1);
-  const SBool  s5852 = false != s5851;
-  const SBool  s5853 = (SBool) (s3254 & 1);
-  const SBool  s5854 = false != s5853;
-  const SWord8 s5855 = s5854 ? s5840 : s5841;
-  const SWord8 s5856 = (s5855 >> 1) | (s5855 << 7);
-  const SWord8 s5857 = 128 | s5856;
-  const SWord8 s5858 = 127 & s5856;
-  const SWord8 s5859 = s5852 ? s5857 : s5858;
-  const SBool  s5860 = (SBool) (s3266 & 1);
-  const SBool  s5861 = false != s5860;
-  const SWord8 s5862 = s5861 ? s5857 : s5858;
-  const SWord8 s5863 = s3225 ? s5859 : s5862;
-  const SWord8 s5864 = s3101 ? s5850 : s5863;
-  const SBool  s5865 = (SBool) (s3287 & 1);
-  const SBool  s5866 = false != s5865;
-  const SBool  s5867 = (SBool) (s3283 & 1);
-  const SBool  s5868 = false != s5867;
-  const SBool  s5869 = (SBool) (s3276 & 1);
-  const SBool  s5870 = false != s5869;
-  const SWord8 s5871 = s5870 ? s5836 : s5837;
-  const SWord8 s5872 = (s5871 >> 1) | (s5871 << 7);
-  const SWord8 s5873 = 128 | s5872;
-  const SWord8 s5874 = 127 & s5872;
-  const SWord8 s5875 = s5868 ? s5873 : s5874;
-  const SWord8 s5876 = (s5875 >> 1) | (s5875 << 7);
-  const SWord8 s5877 = 128 | s5876;
-  const SWord8 s5878 = 127 & s5876;
-  const SWord8 s5879 = s5866 ? s5877 : s5878;
-  const SBool  s5880 = (SBool) (s3292 & 1);
-  const SBool  s5881 = false != s5880;
-  const SWord8 s5882 = s5881 ? s5877 : s5878;
-  const SWord8 s5883 = s3225 ? s5879 : s5882;
-  const SBool  s5884 = (SBool) (s3308 & 1);
-  const SBool  s5885 = false != s5884;
-  const SBool  s5886 = (SBool) (s3301 & 1);
-  const SBool  s5887 = false != s5886;
-  const SWord8 s5888 = s5887 ? s5873 : s5874;
-  const SWord8 s5889 = (s5888 >> 1) | (s5888 << 7);
-  const SWord8 s5890 = 128 | s5889;
-  const SWord8 s5891 = 127 & s5889;
-  const SWord8 s5892 = s5885 ? s5890 : s5891;
-  const SBool  s5893 = (SBool) (s3313 & 1);
-  const SBool  s5894 = false != s5893;
-  const SWord8 s5895 = s5894 ? s5890 : s5891;
-  const SWord8 s5896 = s3225 ? s5892 : s5895;
-  const SWord8 s5897 = s3101 ? s5883 : s5896;
-  const SWord8 s5898 = s3082 ? s5864 : s5897;
-  const SWord8 s5899 = s3060 ? s5828 : s5898;
-  const SBool  s5900 = (SBool) (s3368 & 1);
-  const SBool  s5901 = false != s5900;
-  const SBool  s5902 = (SBool) (s3364 & 1);
-  const SBool  s5903 = false != s5902;
-  const SBool  s5904 = (SBool) (s3360 & 1);
-  const SBool  s5905 = false != s5904;
-  const SWord8 s5906 = (s3347 >> 1) | (s3347 << 7);
-  const SWord8 s5907 = 128 | s5906;
-  const SWord8 s5908 = 127 & s5906;
-  const SWord8 s5909 = s5905 ? s5907 : s5908;
-  const SWord8 s5910 = (s5909 >> 1) | (s5909 << 7);
-  const SWord8 s5911 = 128 | s5910;
-  const SWord8 s5912 = 127 & s5910;
-  const SWord8 s5913 = s5903 ? s5911 : s5912;
-  const SWord8 s5914 = (s5913 >> 1) | (s5913 << 7);
-  const SWord8 s5915 = 128 | s5914;
-  const SWord8 s5916 = 127 & s5914;
-  const SWord8 s5917 = s5901 ? s5915 : s5916;
-  const SBool  s5918 = (SBool) (s3373 & 1);
-  const SBool  s5919 = false != s5918;
-  const SWord8 s5920 = s5919 ? s5915 : s5916;
-  const SWord8 s5921 = s3356 ? s5917 : s5920;
-  const SBool  s5922 = (SBool) (s3389 & 1);
-  const SBool  s5923 = false != s5922;
-  const SBool  s5924 = (SBool) (s3382 & 1);
-  const SBool  s5925 = false != s5924;
-  const SWord8 s5926 = s5925 ? s5911 : s5912;
-  const SWord8 s5927 = (s5926 >> 1) | (s5926 << 7);
-  const SWord8 s5928 = 128 | s5927;
-  const SWord8 s5929 = 127 & s5927;
-  const SWord8 s5930 = s5923 ? s5928 : s5929;
-  const SBool  s5931 = (SBool) (s3394 & 1);
-  const SBool  s5932 = false != s5931;
-  const SWord8 s5933 = s5932 ? s5928 : s5929;
-  const SWord8 s5934 = s3356 ? s5930 : s5933;
-  const SWord8 s5935 = s3334 ? s5921 : s5934;
-  const SBool  s5936 = (SBool) (s3415 & 1);
-  const SBool  s5937 = false != s5936;
-  const SBool  s5938 = (SBool) (s3411 & 1);
-  const SBool  s5939 = false != s5938;
-  const SBool  s5940 = (SBool) (s3404 & 1);
-  const SBool  s5941 = false != s5940;
-  const SWord8 s5942 = s5941 ? s5907 : s5908;
-  const SWord8 s5943 = (s5942 >> 1) | (s5942 << 7);
-  const SWord8 s5944 = 128 | s5943;
-  const SWord8 s5945 = 127 & s5943;
-  const SWord8 s5946 = s5939 ? s5944 : s5945;
-  const SWord8 s5947 = (s5946 >> 1) | (s5946 << 7);
-  const SWord8 s5948 = 128 | s5947;
-  const SWord8 s5949 = 127 & s5947;
-  const SWord8 s5950 = s5937 ? s5948 : s5949;
-  const SBool  s5951 = (SBool) (s3420 & 1);
-  const SBool  s5952 = false != s5951;
-  const SWord8 s5953 = s5952 ? s5948 : s5949;
-  const SWord8 s5954 = s3356 ? s5950 : s5953;
-  const SBool  s5955 = (SBool) (s3436 & 1);
-  const SBool  s5956 = false != s5955;
-  const SBool  s5957 = (SBool) (s3429 & 1);
-  const SBool  s5958 = false != s5957;
-  const SWord8 s5959 = s5958 ? s5944 : s5945;
-  const SWord8 s5960 = (s5959 >> 1) | (s5959 << 7);
-  const SWord8 s5961 = 128 | s5960;
-  const SWord8 s5962 = 127 & s5960;
-  const SWord8 s5963 = s5956 ? s5961 : s5962;
-  const SBool  s5964 = (SBool) (s3441 & 1);
-  const SBool  s5965 = false != s5964;
-  const SWord8 s5966 = s5965 ? s5961 : s5962;
-  const SWord8 s5967 = s3356 ? s5963 : s5966;
-  const SWord8 s5968 = s3334 ? s5954 : s5967;
-  const SWord8 s5969 = s3082 ? s5935 : s5968;
-  const SBool  s5970 = (SBool) (s3476 & 1);
-  const SBool  s5971 = false != s5970;
-  const SBool  s5972 = (SBool) (s3472 & 1);
-  const SBool  s5973 = false != s5972;
-  const SBool  s5974 = (SBool) (s3468 & 1);
-  const SBool  s5975 = false != s5974;
-  const SWord8 s5976 = (s3455 >> 1) | (s3455 << 7);
-  const SWord8 s5977 = 128 | s5976;
-  const SWord8 s5978 = 127 & s5976;
-  const SWord8 s5979 = s5975 ? s5977 : s5978;
-  const SWord8 s5980 = (s5979 >> 1) | (s5979 << 7);
-  const SWord8 s5981 = 128 | s5980;
-  const SWord8 s5982 = 127 & s5980;
-  const SWord8 s5983 = s5973 ? s5981 : s5982;
-  const SWord8 s5984 = (s5983 >> 1) | (s5983 << 7);
-  const SWord8 s5985 = 128 | s5984;
-  const SWord8 s5986 = 127 & s5984;
-  const SWord8 s5987 = s5971 ? s5985 : s5986;
-  const SBool  s5988 = (SBool) (s3481 & 1);
-  const SBool  s5989 = false != s5988;
-  const SWord8 s5990 = s5989 ? s5985 : s5986;
-  const SWord8 s5991 = s3461 ? s5987 : s5990;
-  const SBool  s5992 = (SBool) (s3497 & 1);
-  const SBool  s5993 = false != s5992;
-  const SBool  s5994 = (SBool) (s3490 & 1);
-  const SBool  s5995 = false != s5994;
-  const SWord8 s5996 = s5995 ? s5981 : s5982;
-  const SWord8 s5997 = (s5996 >> 1) | (s5996 << 7);
-  const SWord8 s5998 = 128 | s5997;
-  const SWord8 s5999 = 127 & s5997;
-  const SWord8 s6000 = s5993 ? s5998 : s5999;
-  const SBool  s6001 = (SBool) (s3502 & 1);
-  const SBool  s6002 = false != s6001;
-  const SWord8 s6003 = s6002 ? s5998 : s5999;
-  const SWord8 s6004 = s3461 ? s6000 : s6003;
-  const SWord8 s6005 = s3334 ? s5991 : s6004;
-  const SBool  s6006 = (SBool) (s3523 & 1);
-  const SBool  s6007 = false != s6006;
-  const SBool  s6008 = (SBool) (s3519 & 1);
-  const SBool  s6009 = false != s6008;
-  const SBool  s6010 = (SBool) (s3512 & 1);
-  const SBool  s6011 = false != s6010;
-  const SWord8 s6012 = s6011 ? s5977 : s5978;
-  const SWord8 s6013 = (s6012 >> 1) | (s6012 << 7);
-  const SWord8 s6014 = 128 | s6013;
-  const SWord8 s6015 = 127 & s6013;
-  const SWord8 s6016 = s6009 ? s6014 : s6015;
-  const SWord8 s6017 = (s6016 >> 1) | (s6016 << 7);
-  const SWord8 s6018 = 128 | s6017;
-  const SWord8 s6019 = 127 & s6017;
-  const SWord8 s6020 = s6007 ? s6018 : s6019;
-  const SBool  s6021 = (SBool) (s3528 & 1);
-  const SBool  s6022 = false != s6021;
-  const SWord8 s6023 = s6022 ? s6018 : s6019;
-  const SWord8 s6024 = s3461 ? s6020 : s6023;
-  const SBool  s6025 = (SBool) (s3544 & 1);
-  const SBool  s6026 = false != s6025;
-  const SBool  s6027 = (SBool) (s3537 & 1);
-  const SBool  s6028 = false != s6027;
-  const SWord8 s6029 = s6028 ? s6014 : s6015;
-  const SWord8 s6030 = (s6029 >> 1) | (s6029 << 7);
-  const SWord8 s6031 = 128 | s6030;
-  const SWord8 s6032 = 127 & s6030;
-  const SWord8 s6033 = s6026 ? s6031 : s6032;
-  const SBool  s6034 = (SBool) (s3549 & 1);
-  const SBool  s6035 = false != s6034;
-  const SWord8 s6036 = s6035 ? s6031 : s6032;
-  const SWord8 s6037 = s3461 ? s6033 : s6036;
-  const SWord8 s6038 = s3334 ? s6024 : s6037;
-  const SWord8 s6039 = s3082 ? s6005 : s6038;
-  const SWord8 s6040 = s3060 ? s5969 : s6039;
-  const SWord8 s6041 = s2042 ? s5899 : s6040;
-  const SBool  s6042 = (SBool) (s3624 & 1);
-  const SBool  s6043 = false != s6042;
-  const SBool  s6044 = (SBool) (s3620 & 1);
-  const SBool  s6045 = false != s6044;
-  const SBool  s6046 = (SBool) (s3616 & 1);
-  const SBool  s6047 = false != s6046;
-  const SWord8 s6048 = (s3603 >> 1) | (s3603 << 7);
-  const SWord8 s6049 = 128 | s6048;
-  const SWord8 s6050 = 127 & s6048;
-  const SWord8 s6051 = s6047 ? s6049 : s6050;
-  const SWord8 s6052 = (s6051 >> 1) | (s6051 << 7);
-  const SWord8 s6053 = 128 | s6052;
-  const SWord8 s6054 = 127 & s6052;
-  const SWord8 s6055 = s6045 ? s6053 : s6054;
-  const SWord8 s6056 = (s6055 >> 1) | (s6055 << 7);
-  const SWord8 s6057 = 128 | s6056;
-  const SWord8 s6058 = 127 & s6056;
-  const SWord8 s6059 = s6043 ? s6057 : s6058;
-  const SBool  s6060 = (SBool) (s3629 & 1);
-  const SBool  s6061 = false != s6060;
-  const SWord8 s6062 = s6061 ? s6057 : s6058;
-  const SWord8 s6063 = s3612 ? s6059 : s6062;
-  const SBool  s6064 = (SBool) (s3645 & 1);
-  const SBool  s6065 = false != s6064;
-  const SBool  s6066 = (SBool) (s3638 & 1);
-  const SBool  s6067 = false != s6066;
-  const SWord8 s6068 = s6067 ? s6053 : s6054;
-  const SWord8 s6069 = (s6068 >> 1) | (s6068 << 7);
-  const SWord8 s6070 = 128 | s6069;
-  const SWord8 s6071 = 127 & s6069;
-  const SWord8 s6072 = s6065 ? s6070 : s6071;
-  const SBool  s6073 = (SBool) (s3650 & 1);
-  const SBool  s6074 = false != s6073;
-  const SWord8 s6075 = s6074 ? s6070 : s6071;
-  const SWord8 s6076 = s3612 ? s6072 : s6075;
-  const SWord8 s6077 = s3593 ? s6063 : s6076;
-  const SBool  s6078 = (SBool) (s3671 & 1);
-  const SBool  s6079 = false != s6078;
-  const SBool  s6080 = (SBool) (s3667 & 1);
-  const SBool  s6081 = false != s6080;
-  const SBool  s6082 = (SBool) (s3660 & 1);
-  const SBool  s6083 = false != s6082;
-  const SWord8 s6084 = s6083 ? s6049 : s6050;
-  const SWord8 s6085 = (s6084 >> 1) | (s6084 << 7);
-  const SWord8 s6086 = 128 | s6085;
-  const SWord8 s6087 = 127 & s6085;
-  const SWord8 s6088 = s6081 ? s6086 : s6087;
-  const SWord8 s6089 = (s6088 >> 1) | (s6088 << 7);
-  const SWord8 s6090 = 128 | s6089;
-  const SWord8 s6091 = 127 & s6089;
-  const SWord8 s6092 = s6079 ? s6090 : s6091;
-  const SBool  s6093 = (SBool) (s3676 & 1);
-  const SBool  s6094 = false != s6093;
-  const SWord8 s6095 = s6094 ? s6090 : s6091;
-  const SWord8 s6096 = s3612 ? s6092 : s6095;
-  const SBool  s6097 = (SBool) (s3692 & 1);
-  const SBool  s6098 = false != s6097;
-  const SBool  s6099 = (SBool) (s3685 & 1);
-  const SBool  s6100 = false != s6099;
-  const SWord8 s6101 = s6100 ? s6086 : s6087;
-  const SWord8 s6102 = (s6101 >> 1) | (s6101 << 7);
-  const SWord8 s6103 = 128 | s6102;
-  const SWord8 s6104 = 127 & s6102;
-  const SWord8 s6105 = s6098 ? s6103 : s6104;
-  const SBool  s6106 = (SBool) (s3697 & 1);
-  const SBool  s6107 = false != s6106;
-  const SWord8 s6108 = s6107 ? s6103 : s6104;
-  const SWord8 s6109 = s3612 ? s6105 : s6108;
-  const SWord8 s6110 = s3593 ? s6096 : s6109;
-  const SWord8 s6111 = s3571 ? s6077 : s6110;
-  const SBool  s6112 = (SBool) (s3732 & 1);
-  const SBool  s6113 = false != s6112;
-  const SBool  s6114 = (SBool) (s3728 & 1);
-  const SBool  s6115 = false != s6114;
-  const SBool  s6116 = (SBool) (s3724 & 1);
-  const SBool  s6117 = false != s6116;
-  const SWord8 s6118 = (s3711 >> 1) | (s3711 << 7);
-  const SWord8 s6119 = 128 | s6118;
-  const SWord8 s6120 = 127 & s6118;
-  const SWord8 s6121 = s6117 ? s6119 : s6120;
-  const SWord8 s6122 = (s6121 >> 1) | (s6121 << 7);
-  const SWord8 s6123 = 128 | s6122;
-  const SWord8 s6124 = 127 & s6122;
-  const SWord8 s6125 = s6115 ? s6123 : s6124;
-  const SWord8 s6126 = (s6125 >> 1) | (s6125 << 7);
-  const SWord8 s6127 = 128 | s6126;
-  const SWord8 s6128 = 127 & s6126;
-  const SWord8 s6129 = s6113 ? s6127 : s6128;
-  const SBool  s6130 = (SBool) (s3737 & 1);
-  const SBool  s6131 = false != s6130;
-  const SWord8 s6132 = s6131 ? s6127 : s6128;
-  const SWord8 s6133 = s3717 ? s6129 : s6132;
-  const SBool  s6134 = (SBool) (s3753 & 1);
-  const SBool  s6135 = false != s6134;
-  const SBool  s6136 = (SBool) (s3746 & 1);
-  const SBool  s6137 = false != s6136;
-  const SWord8 s6138 = s6137 ? s6123 : s6124;
-  const SWord8 s6139 = (s6138 >> 1) | (s6138 << 7);
-  const SWord8 s6140 = 128 | s6139;
-  const SWord8 s6141 = 127 & s6139;
-  const SWord8 s6142 = s6135 ? s6140 : s6141;
-  const SBool  s6143 = (SBool) (s3758 & 1);
-  const SBool  s6144 = false != s6143;
-  const SWord8 s6145 = s6144 ? s6140 : s6141;
-  const SWord8 s6146 = s3717 ? s6142 : s6145;
-  const SWord8 s6147 = s3593 ? s6133 : s6146;
-  const SBool  s6148 = (SBool) (s3779 & 1);
-  const SBool  s6149 = false != s6148;
-  const SBool  s6150 = (SBool) (s3775 & 1);
-  const SBool  s6151 = false != s6150;
-  const SBool  s6152 = (SBool) (s3768 & 1);
-  const SBool  s6153 = false != s6152;
-  const SWord8 s6154 = s6153 ? s6119 : s6120;
-  const SWord8 s6155 = (s6154 >> 1) | (s6154 << 7);
-  const SWord8 s6156 = 128 | s6155;
-  const SWord8 s6157 = 127 & s6155;
-  const SWord8 s6158 = s6151 ? s6156 : s6157;
-  const SWord8 s6159 = (s6158 >> 1) | (s6158 << 7);
-  const SWord8 s6160 = 128 | s6159;
-  const SWord8 s6161 = 127 & s6159;
-  const SWord8 s6162 = s6149 ? s6160 : s6161;
-  const SBool  s6163 = (SBool) (s3784 & 1);
-  const SBool  s6164 = false != s6163;
-  const SWord8 s6165 = s6164 ? s6160 : s6161;
-  const SWord8 s6166 = s3717 ? s6162 : s6165;
-  const SBool  s6167 = (SBool) (s3800 & 1);
-  const SBool  s6168 = false != s6167;
-  const SBool  s6169 = (SBool) (s3793 & 1);
-  const SBool  s6170 = false != s6169;
-  const SWord8 s6171 = s6170 ? s6156 : s6157;
-  const SWord8 s6172 = (s6171 >> 1) | (s6171 << 7);
-  const SWord8 s6173 = 128 | s6172;
-  const SWord8 s6174 = 127 & s6172;
-  const SWord8 s6175 = s6168 ? s6173 : s6174;
-  const SBool  s6176 = (SBool) (s3805 & 1);
-  const SBool  s6177 = false != s6176;
-  const SWord8 s6178 = s6177 ? s6173 : s6174;
-  const SWord8 s6179 = s3717 ? s6175 : s6178;
-  const SWord8 s6180 = s3593 ? s6166 : s6179;
-  const SWord8 s6181 = s3571 ? s6147 : s6180;
-  const SWord8 s6182 = s3060 ? s6111 : s6181;
-  const SBool  s6183 = (SBool) (s3860 & 1);
-  const SBool  s6184 = false != s6183;
-  const SBool  s6185 = (SBool) (s3856 & 1);
-  const SBool  s6186 = false != s6185;
-  const SBool  s6187 = (SBool) (s3852 & 1);
-  const SBool  s6188 = false != s6187;
-  const SWord8 s6189 = (s3839 >> 1) | (s3839 << 7);
-  const SWord8 s6190 = 128 | s6189;
-  const SWord8 s6191 = 127 & s6189;
-  const SWord8 s6192 = s6188 ? s6190 : s6191;
-  const SWord8 s6193 = (s6192 >> 1) | (s6192 << 7);
-  const SWord8 s6194 = 128 | s6193;
-  const SWord8 s6195 = 127 & s6193;
-  const SWord8 s6196 = s6186 ? s6194 : s6195;
-  const SWord8 s6197 = (s6196 >> 1) | (s6196 << 7);
-  const SWord8 s6198 = 128 | s6197;
-  const SWord8 s6199 = 127 & s6197;
-  const SWord8 s6200 = s6184 ? s6198 : s6199;
-  const SBool  s6201 = (SBool) (s3865 & 1);
-  const SBool  s6202 = false != s6201;
-  const SWord8 s6203 = s6202 ? s6198 : s6199;
-  const SWord8 s6204 = s3848 ? s6200 : s6203;
-  const SBool  s6205 = (SBool) (s3881 & 1);
-  const SBool  s6206 = false != s6205;
-  const SBool  s6207 = (SBool) (s3874 & 1);
-  const SBool  s6208 = false != s6207;
-  const SWord8 s6209 = s6208 ? s6194 : s6195;
-  const SWord8 s6210 = (s6209 >> 1) | (s6209 << 7);
-  const SWord8 s6211 = 128 | s6210;
-  const SWord8 s6212 = 127 & s6210;
-  const SWord8 s6213 = s6206 ? s6211 : s6212;
-  const SBool  s6214 = (SBool) (s3886 & 1);
-  const SBool  s6215 = false != s6214;
-  const SWord8 s6216 = s6215 ? s6211 : s6212;
-  const SWord8 s6217 = s3848 ? s6213 : s6216;
-  const SWord8 s6218 = s3826 ? s6204 : s6217;
-  const SBool  s6219 = (SBool) (s3907 & 1);
-  const SBool  s6220 = false != s6219;
-  const SBool  s6221 = (SBool) (s3903 & 1);
-  const SBool  s6222 = false != s6221;
-  const SBool  s6223 = (SBool) (s3896 & 1);
-  const SBool  s6224 = false != s6223;
-  const SWord8 s6225 = s6224 ? s6190 : s6191;
-  const SWord8 s6226 = (s6225 >> 1) | (s6225 << 7);
-  const SWord8 s6227 = 128 | s6226;
-  const SWord8 s6228 = 127 & s6226;
-  const SWord8 s6229 = s6222 ? s6227 : s6228;
-  const SWord8 s6230 = (s6229 >> 1) | (s6229 << 7);
-  const SWord8 s6231 = 128 | s6230;
-  const SWord8 s6232 = 127 & s6230;
-  const SWord8 s6233 = s6220 ? s6231 : s6232;
-  const SBool  s6234 = (SBool) (s3912 & 1);
-  const SBool  s6235 = false != s6234;
-  const SWord8 s6236 = s6235 ? s6231 : s6232;
-  const SWord8 s6237 = s3848 ? s6233 : s6236;
-  const SBool  s6238 = (SBool) (s3928 & 1);
-  const SBool  s6239 = false != s6238;
-  const SBool  s6240 = (SBool) (s3921 & 1);
-  const SBool  s6241 = false != s6240;
-  const SWord8 s6242 = s6241 ? s6227 : s6228;
-  const SWord8 s6243 = (s6242 >> 1) | (s6242 << 7);
-  const SWord8 s6244 = 128 | s6243;
-  const SWord8 s6245 = 127 & s6243;
-  const SWord8 s6246 = s6239 ? s6244 : s6245;
-  const SBool  s6247 = (SBool) (s3933 & 1);
-  const SBool  s6248 = false != s6247;
-  const SWord8 s6249 = s6248 ? s6244 : s6245;
-  const SWord8 s6250 = s3848 ? s6246 : s6249;
-  const SWord8 s6251 = s3826 ? s6237 : s6250;
-  const SWord8 s6252 = s3571 ? s6218 : s6251;
-  const SBool  s6253 = (SBool) (s3968 & 1);
-  const SBool  s6254 = false != s6253;
-  const SBool  s6255 = (SBool) (s3964 & 1);
-  const SBool  s6256 = false != s6255;
-  const SBool  s6257 = (SBool) (s3960 & 1);
-  const SBool  s6258 = false != s6257;
-  const SWord8 s6259 = (s3947 >> 1) | (s3947 << 7);
-  const SWord8 s6260 = 128 | s6259;
-  const SWord8 s6261 = 127 & s6259;
-  const SWord8 s6262 = s6258 ? s6260 : s6261;
-  const SWord8 s6263 = (s6262 >> 1) | (s6262 << 7);
-  const SWord8 s6264 = 128 | s6263;
-  const SWord8 s6265 = 127 & s6263;
-  const SWord8 s6266 = s6256 ? s6264 : s6265;
-  const SWord8 s6267 = (s6266 >> 1) | (s6266 << 7);
-  const SWord8 s6268 = 128 | s6267;
-  const SWord8 s6269 = 127 & s6267;
-  const SWord8 s6270 = s6254 ? s6268 : s6269;
-  const SBool  s6271 = (SBool) (s3973 & 1);
-  const SBool  s6272 = false != s6271;
-  const SWord8 s6273 = s6272 ? s6268 : s6269;
-  const SWord8 s6274 = s3953 ? s6270 : s6273;
-  const SBool  s6275 = (SBool) (s3989 & 1);
-  const SBool  s6276 = false != s6275;
-  const SBool  s6277 = (SBool) (s3982 & 1);
-  const SBool  s6278 = false != s6277;
-  const SWord8 s6279 = s6278 ? s6264 : s6265;
-  const SWord8 s6280 = (s6279 >> 1) | (s6279 << 7);
-  const SWord8 s6281 = 128 | s6280;
-  const SWord8 s6282 = 127 & s6280;
-  const SWord8 s6283 = s6276 ? s6281 : s6282;
-  const SBool  s6284 = (SBool) (s3994 & 1);
-  const SBool  s6285 = false != s6284;
-  const SWord8 s6286 = s6285 ? s6281 : s6282;
-  const SWord8 s6287 = s3953 ? s6283 : s6286;
-  const SWord8 s6288 = s3826 ? s6274 : s6287;
-  const SBool  s6289 = (SBool) (s4015 & 1);
-  const SBool  s6290 = false != s6289;
-  const SBool  s6291 = (SBool) (s4011 & 1);
-  const SBool  s6292 = false != s6291;
-  const SBool  s6293 = (SBool) (s4004 & 1);
-  const SBool  s6294 = false != s6293;
-  const SWord8 s6295 = s6294 ? s6260 : s6261;
-  const SWord8 s6296 = (s6295 >> 1) | (s6295 << 7);
-  const SWord8 s6297 = 128 | s6296;
-  const SWord8 s6298 = 127 & s6296;
-  const SWord8 s6299 = s6292 ? s6297 : s6298;
-  const SWord8 s6300 = (s6299 >> 1) | (s6299 << 7);
-  const SWord8 s6301 = 128 | s6300;
-  const SWord8 s6302 = 127 & s6300;
-  const SWord8 s6303 = s6290 ? s6301 : s6302;
-  const SBool  s6304 = (SBool) (s4020 & 1);
-  const SBool  s6305 = false != s6304;
-  const SWord8 s6306 = s6305 ? s6301 : s6302;
-  const SWord8 s6307 = s3953 ? s6303 : s6306;
-  const SBool  s6308 = (SBool) (s4036 & 1);
-  const SBool  s6309 = false != s6308;
-  const SBool  s6310 = (SBool) (s4029 & 1);
-  const SBool  s6311 = false != s6310;
-  const SWord8 s6312 = s6311 ? s6297 : s6298;
-  const SWord8 s6313 = (s6312 >> 1) | (s6312 << 7);
-  const SWord8 s6314 = 128 | s6313;
-  const SWord8 s6315 = 127 & s6313;
-  const SWord8 s6316 = s6309 ? s6314 : s6315;
-  const SBool  s6317 = (SBool) (s4041 & 1);
-  const SBool  s6318 = false != s6317;
-  const SWord8 s6319 = s6318 ? s6314 : s6315;
-  const SWord8 s6320 = s3953 ? s6316 : s6319;
-  const SWord8 s6321 = s3826 ? s6307 : s6320;
-  const SWord8 s6322 = s3571 ? s6288 : s6321;
-  const SWord8 s6323 = s3060 ? s6252 : s6322;
-  const SWord8 s6324 = s2042 ? s6182 : s6323;
-  const SWord8 s6325 = s16 ? s6041 : s6324;
-  const SWord8 s6326 = s11 ? s5758 : s6325;
-  const SWord8 s6327 = s5 ? s5191 : s6326;
-
-  *hi = s4056;
-  *lo = s6327;
+legatoMult_driver.o: legatoMult_driver.c legatoMult.h
+	${CC} ${CCFLAGS} -c $< -o $@
+
+legatoMult_driver: legatoMult.o legatoMult_driver.o
+	${CC} ${CCFLAGS} $^ -o $@ ${LDFLAGS}
+
+clean:
+	rm -f *.o
+
+veryclean: clean
+	rm -f legatoMult_driver
+== END: "Makefile" ==================
+== BEGIN: "legatoMult.h" ================
+/* Header file for legatoMult. Automatically generated by SBV. Do not edit! */
+
+#ifndef SBV_GENERATED_legatoMult_HEADER_INCLUDED
+#define SBV_GENERATED_legatoMult_HEADER_INCLUDED
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <math.h>
+
+/* Floating-point calling convention:
+ * Enter generated code in FE_TONEAREST (round-to-nearest, ties-to-even).
+ * Callbacks must preserve this mode before returning or re-entering.
+ * Generated code does not check or change the hardware rounding mode.
+ * Custom builds must disable implicit FP contraction, including at LTO link time.
+ */
+
+/* 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 prototype: */
+void legatoMult(const SWord8 x, const SWord8 y, SWord8 *hi,
+                SWord8 *lo);
+
+#endif /* SBV_GENERATED_legatoMult_HEADER_INCLUDED */
+== END: "legatoMult.h" ==================
+== BEGIN: "legatoMult_driver.c" ================
+/* Example driver program for legatoMult. */
+/* Automatically generated by SBV. Edit as you see fit! */
+
+#include <stdio.h>
+#include "legatoMult.h"
+
+int main(void)
+{
+  SWord8 sbv_driver_output_0;
+  SWord8 sbv_driver_output_1;
+
+  legatoMult(87, 92, &sbv_driver_output_0, &sbv_driver_output_1);
+
+  printf("legatoMult(87, 92, &hi, &lo) ->\n");
+  printf("  hi = %"PRIu8"\n", sbv_driver_output_0);
+  printf("  lo = %"PRIu8"\n", sbv_driver_output_1);
+
+  return 0;
+}
+== END: "legatoMult_driver.c" ==================
+== BEGIN: "legatoMult.c" ================
+/* File: "legatoMult.c". Automatically generated by SBV. Do not edit! */
+
+#include "legatoMult.h"
+
+/* Exact bit-vector runtime. All arithmetic is modulo the declared width. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static inline SBV_CGEN_UNUSED SBool sbv_bv_extract_u8_0_0_u1(SWord8 a)
+{
+  SBool r = (SBool) 0;
+  uint64_t i;
+  for (i = 0; i < 1; ++i) { r = (SBool) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_u8_rotl(SWord8 a, uint64_t amount)
+{
+  amount %= 8;
+  if (amount == 0) return a;
+  return (SWord8) ((((uint64_t) (SWord8) a) << amount) | (((uint64_t) (SWord8) a) >> (8 - amount)));
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_u8_rotr(SWord8 a, uint64_t amount)
+{
+  amount %= 8;
+  if (amount == 0) return a;
+  return (SWord8) ((((uint64_t) (SWord8) a) >> amount) | (((uint64_t) (SWord8) a) << (8 - amount)));
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_u8_add(SWord8 a, SWord8 b)
+{
+  const SWord8 bits = (SWord8) ((((uint64_t) (SWord8) a) + ((uint64_t) (SWord8) b)) & UINT64_C(0x00000000000000ff));
+  return (SWord8) bits;
+}
+
+
+void legatoMult(const SWord8 sbv_input_0, const SWord8 sbv_input_1,
+                SWord8 *sbv_output_0, SWord8 *sbv_output_1)
+{
+  const SWord8 s0 = sbv_input_0;
+  const SWord8 s1 = sbv_input_1;
+  const SBool  s2 = sbv_bv_extract_u8_0_0_u1(s0);
+  const SBool  s4 = s2 != false;
+  const SBool  s5 = !s4;
+  const SWord8 s6 = sbv_bv_u8_rotr(s0, 1);
+  const SWord8 s8 = s6 & 127;
+  const SBool  s9 = sbv_bv_extract_u8_0_0_u1(s8);
+  const SBool  s10 = false != s9;
+  const SBool  s11 = !s10;
+  const SWord8 s12 = sbv_bv_u8_rotr(s8, 1);
+  const SWord8 s13 = 127 & s12;
+  const SBool  s14 = sbv_bv_extract_u8_0_0_u1(s13);
+  const SBool  s15 = false != s14;
+  const SBool  s16 = !s15;
+  const SWord8 s17 = sbv_bv_u8_rotr(s13, 1);
+  const SWord8 s18 = 127 & s17;
+  const SBool  s19 = sbv_bv_extract_u8_0_0_u1(s18);
+  const SBool  s20 = false != s19;
+  const SBool  s21 = !s20;
+  const SWord8 s24 = s4 ? 128 : 0;
+  const SBool  s25 = sbv_bv_extract_u8_0_0_u1(s24);
+  const SBool  s26 = false != s25;
+  const SWord8 s27 = s26 ? 128 : 0;
+  const SBool  s28 = sbv_bv_extract_u8_0_0_u1(s27);
+  const SBool  s29 = false != s28;
+  const SWord8 s30 = sbv_bv_u8_rotr(s18, 1);
+  const SWord8 s31 = 128 | s30;
+  const SWord8 s32 = 127 & s30;
+  const SWord8 s33 = s29 ? s31 : s32;
+  const SBool  s34 = sbv_bv_extract_u8_0_0_u1(s33);
+  const SBool  s35 = false != s34;
+  const SBool  s36 = !s35;
+  const SWord8 s37 = sbv_bv_u8_rotr(s24, 1);
+  const SWord8 s38 = 128 | s37;
+  const SWord8 s39 = 127 & s37;
+  const SWord8 s40 = s10 ? s38 : s39;
+  const SBool  s41 = sbv_bv_extract_u8_0_0_u1(s40);
+  const SBool  s42 = false != s41;
+  const SWord8 s43 = sbv_bv_u8_rotr(s27, 1);
+  const SWord8 s44 = 128 | s43;
+  const SWord8 s45 = 127 & s43;
+  const SWord8 s46 = s42 ? s44 : s45;
+  const SBool  s47 = sbv_bv_extract_u8_0_0_u1(s46);
+  const SBool  s48 = false != s47;
+  const SWord8 s49 = sbv_bv_u8_rotr(s33, 1);
+  const SWord8 s50 = 128 | s49;
+  const SWord8 s51 = 127 & s49;
+  const SWord8 s52 = s48 ? s50 : s51;
+  const SBool  s53 = sbv_bv_extract_u8_0_0_u1(s52);
+  const SBool  s54 = false != s53;
+  const SBool  s55 = !s54;
+  const SWord8 s56 = sbv_bv_u8_rotr(s40, 1);
+  const SWord8 s57 = 128 | s56;
+  const SWord8 s58 = 127 & s56;
+  const SWord8 s59 = s15 ? s57 : s58;
+  const SBool  s60 = sbv_bv_extract_u8_0_0_u1(s59);
+  const SBool  s61 = false != s60;
+  const SWord8 s62 = sbv_bv_u8_rotr(s46, 1);
+  const SWord8 s63 = 128 | s62;
+  const SWord8 s64 = 127 & s62;
+  const SWord8 s65 = s61 ? s63 : s64;
+  const SBool  s66 = sbv_bv_extract_u8_0_0_u1(s65);
+  const SBool  s67 = false != s66;
+  const SWord8 s68 = sbv_bv_u8_rotr(s52, 1);
+  const SWord8 s69 = 128 | s68;
+  const SWord8 s70 = 127 & s68;
+  const SWord8 s71 = s67 ? s69 : s70;
+  const SBool  s72 = sbv_bv_extract_u8_0_0_u1(s71);
+  const SBool  s73 = false != s72;
+  const SBool  s74 = !s73;
+  const SWord8 s75 = sbv_bv_u8_rotr(s59, 1);
+  const SWord8 s76 = 128 | s75;
+  const SWord8 s77 = 127 & s75;
+  const SWord8 s78 = s20 ? s76 : s77;
+  const SBool  s79 = sbv_bv_extract_u8_0_0_u1(s78);
+  const SBool  s80 = false != s79;
+  const SWord8 s81 = sbv_bv_u8_rotr(s65, 1);
+  const SWord8 s82 = 128 | s81;
+  const SWord8 s83 = 127 & s81;
+  const SWord8 s84 = s80 ? s82 : s83;
+  const SBool  s85 = sbv_bv_extract_u8_0_0_u1(s84);
+  const SBool  s86 = false != s85;
+  const SWord8 s87 = sbv_bv_u8_rotr(s71, 1);
+  const SWord8 s88 = 128 | s87;
+  const SWord8 s89 = 127 & s87;
+  const SWord8 s90 = s86 ? s88 : s89;
+  const SBool  s91 = sbv_bv_extract_u8_0_0_u1(s90);
+  const SBool  s92 = false != s91;
+  const SBool  s93 = !s92;
+  const SWord8 s94 = sbv_bv_u8_rotr(s78, 1);
+  const SWord8 s95 = 128 | s94;
+  const SWord8 s96 = 127 & s94;
+  const SWord8 s97 = s35 ? s95 : s96;
+  const SWord8 s98 = sbv_bv_u8_rotr(s97, 1);
+  const SWord8 s99 = 128 | s98;
+  const SWord8 s100 = 127 & s98;
+  const SWord8 s101 = s54 ? s99 : s100;
+  const SWord8 s102 = sbv_bv_u8_rotr(s101, 1);
+  const SWord8 s103 = 128 | s102;
+  const SWord8 s104 = 127 & s102;
+  const SWord8 s105 = s73 ? s103 : s104;
+  const SWord8 s106 = sbv_bv_u8_rotr(s105, 1);
+  const SWord8 s107 = 128 | s106;
+  const SWord8 s108 = 127 & s106;
+  const SWord8 s109 = s92 ? s107 : s108;
+  const SWord8 s110 = sbv_bv_u8_add(s1, s105);
+  const SBool  s111 = s110 < s1;
+  const SBool  s112 = s110 < s105;
+  const SBool  s113 = s111 || s112;
+  const SWord8 s114 = sbv_bv_u8_rotr(s110, 1);
+  const SWord8 s115 = 128 | s114;
+  const SWord8 s116 = 127 & s114;
+  const SWord8 s117 = s113 ? s115 : s116;
+  const SWord8 s118 = s93 ? s109 : s117;
+  const SWord8 s119 = sbv_bv_u8_add(s1, s101);
+  const SBool  s120 = s119 < s1;
+  const SBool  s121 = s119 < s101;
+  const SBool  s122 = s120 || s121;
+  const SWord8 s123 = sbv_bv_u8_rotr(s119, 1);
+  const SWord8 s124 = 128 | s123;
+  const SWord8 s125 = 127 & s123;
+  const SWord8 s126 = s122 ? s124 : s125;
+  const SWord8 s127 = sbv_bv_u8_rotr(s126, 1);
+  const SWord8 s128 = 128 | s127;
+  const SWord8 s129 = 127 & s127;
+  const SWord8 s130 = s92 ? s128 : s129;
+  const SWord8 s131 = sbv_bv_u8_add(s1, s126);
+  const SBool  s132 = s131 < s1;
+  const SBool  s133 = s131 < s126;
+  const SBool  s134 = s132 || s133;
+  const SWord8 s135 = sbv_bv_u8_rotr(s131, 1);
+  const SWord8 s136 = 128 | s135;
+  const SWord8 s137 = 127 & s135;
+  const SWord8 s138 = s134 ? s136 : s137;
+  const SWord8 s139 = s93 ? s130 : s138;
+  const SWord8 s140 = s74 ? s118 : s139;
+  const SWord8 s141 = sbv_bv_u8_add(s1, s97);
+  const SBool  s142 = s141 < s1;
+  const SBool  s143 = s141 < s97;
+  const SBool  s144 = s142 || s143;
+  const SWord8 s145 = sbv_bv_u8_rotr(s141, 1);
+  const SWord8 s146 = 128 | s145;
+  const SWord8 s147 = 127 & s145;
+  const SWord8 s148 = s144 ? s146 : s147;
+  const SWord8 s149 = sbv_bv_u8_rotr(s148, 1);
+  const SWord8 s150 = 128 | s149;
+  const SWord8 s151 = 127 & s149;
+  const SWord8 s152 = s73 ? s150 : s151;
+  const SWord8 s153 = sbv_bv_u8_rotr(s152, 1);
+  const SWord8 s154 = 128 | s153;
+  const SWord8 s155 = 127 & s153;
+  const SWord8 s156 = s92 ? s154 : s155;
+  const SWord8 s157 = sbv_bv_u8_add(s1, s152);
+  const SBool  s158 = s157 < s1;
+  const SBool  s159 = s157 < s152;
+  const SBool  s160 = s158 || s159;
+  const SWord8 s161 = sbv_bv_u8_rotr(s157, 1);
+  const SWord8 s162 = 128 | s161;
+  const SWord8 s163 = 127 & s161;
+  const SWord8 s164 = s160 ? s162 : s163;
+  const SWord8 s165 = s93 ? s156 : s164;
+  const SWord8 s166 = sbv_bv_u8_add(s1, s148);
+  const SBool  s167 = s166 < s1;
+  const SBool  s168 = s166 < s148;
+  const SBool  s169 = s167 || s168;
+  const SWord8 s170 = sbv_bv_u8_rotr(s166, 1);
+  const SWord8 s171 = 128 | s170;
+  const SWord8 s172 = 127 & s170;
+  const SWord8 s173 = s169 ? s171 : s172;
+  const SWord8 s174 = sbv_bv_u8_rotr(s173, 1);
+  const SWord8 s175 = 128 | s174;
+  const SWord8 s176 = 127 & s174;
+  const SWord8 s177 = s92 ? s175 : s176;
+  const SWord8 s178 = sbv_bv_u8_add(s1, s173);
+  const SBool  s179 = s178 < s1;
+  const SBool  s180 = s178 < s173;
+  const SBool  s181 = s179 || s180;
+  const SWord8 s182 = sbv_bv_u8_rotr(s178, 1);
+  const SWord8 s183 = 128 | s182;
+  const SWord8 s184 = 127 & s182;
+  const SWord8 s185 = s181 ? s183 : s184;
+  const SWord8 s186 = s93 ? s177 : s185;
+  const SWord8 s187 = s74 ? s165 : s186;
+  const SWord8 s188 = s55 ? s140 : s187;
+  const SWord8 s189 = sbv_bv_u8_add(s1, s78);
+  const SBool  s190 = sbv_bv_extract_u8_0_0_u1(s189);
+  const SBool  s191 = false != s190;
+  const SWord8 s192 = s191 ? s82 : s83;
+  const SBool  s193 = sbv_bv_extract_u8_0_0_u1(s192);
+  const SBool  s194 = false != s193;
+  const SWord8 s195 = s194 ? s88 : s89;
+  const SBool  s196 = sbv_bv_extract_u8_0_0_u1(s195);
+  const SBool  s197 = false != s196;
+  const SBool  s198 = !s197;
+  const SBool  s199 = s189 < s1;
+  const SBool  s200 = s189 < s78;
+  const SBool  s201 = s199 || s200;
+  const SWord8 s202 = sbv_bv_u8_rotr(s189, 1);
+  const SWord8 s203 = 128 | s202;
+  const SWord8 s204 = 127 & s202;
+  const SWord8 s205 = s201 ? s203 : s204;
+  const SWord8 s206 = sbv_bv_u8_rotr(s205, 1);
+  const SWord8 s207 = 128 | s206;
+  const SWord8 s208 = 127 & s206;
+  const SWord8 s209 = s54 ? s207 : s208;
+  const SWord8 s210 = sbv_bv_u8_rotr(s209, 1);
+  const SWord8 s211 = 128 | s210;
+  const SWord8 s212 = 127 & s210;
+  const SWord8 s213 = s73 ? s211 : s212;
+  const SWord8 s214 = sbv_bv_u8_rotr(s213, 1);
+  const SWord8 s215 = 128 | s214;
+  const SWord8 s216 = 127 & s214;
+  const SWord8 s217 = s197 ? s215 : s216;
+  const SWord8 s218 = sbv_bv_u8_add(s1, s213);
+  const SBool  s219 = s218 < s1;
+  const SBool  s220 = s218 < s213;
+  const SBool  s221 = s219 || s220;
+  const SWord8 s222 = sbv_bv_u8_rotr(s218, 1);
+  const SWord8 s223 = 128 | s222;
+  const SWord8 s224 = 127 & s222;
+  const SWord8 s225 = s221 ? s223 : s224;
+  const SWord8 s226 = s198 ? s217 : s225;
+  const SWord8 s227 = sbv_bv_u8_add(s1, s209);
+  const SBool  s228 = s227 < s1;
+  const SBool  s229 = s227 < s209;
+  const SBool  s230 = s228 || s229;
+  const SWord8 s231 = sbv_bv_u8_rotr(s227, 1);
+  const SWord8 s232 = 128 | s231;
+  const SWord8 s233 = 127 & s231;
+  const SWord8 s234 = s230 ? s232 : s233;
+  const SWord8 s235 = sbv_bv_u8_rotr(s234, 1);
+  const SWord8 s236 = 128 | s235;
+  const SWord8 s237 = 127 & s235;
+  const SWord8 s238 = s197 ? s236 : s237;
+  const SWord8 s239 = sbv_bv_u8_add(s1, s234);
+  const SBool  s240 = s239 < s1;
+  const SBool  s241 = s239 < s234;
+  const SBool  s242 = s240 || s241;
+  const SWord8 s243 = sbv_bv_u8_rotr(s239, 1);
+  const SWord8 s244 = 128 | s243;
+  const SWord8 s245 = 127 & s243;
+  const SWord8 s246 = s242 ? s244 : s245;
+  const SWord8 s247 = s198 ? s238 : s246;
+  const SWord8 s248 = s74 ? s226 : s247;
+  const SWord8 s249 = sbv_bv_u8_add(s1, s205);
+  const SBool  s250 = s249 < s1;
+  const SBool  s251 = s249 < s205;
+  const SBool  s252 = s250 || s251;
+  const SWord8 s253 = sbv_bv_u8_rotr(s249, 1);
+  const SWord8 s254 = 128 | s253;
+  const SWord8 s255 = 127 & s253;
+  const SWord8 s256 = s252 ? s254 : s255;
+  const SWord8 s257 = sbv_bv_u8_rotr(s256, 1);
+  const SWord8 s258 = 128 | s257;
+  const SWord8 s259 = 127 & s257;
+  const SWord8 s260 = s73 ? s258 : s259;
+  const SWord8 s261 = sbv_bv_u8_rotr(s260, 1);
+  const SWord8 s262 = 128 | s261;
+  const SWord8 s263 = 127 & s261;
+  const SWord8 s264 = s197 ? s262 : s263;
+  const SWord8 s265 = sbv_bv_u8_add(s1, s260);
+  const SBool  s266 = s265 < s1;
+  const SBool  s267 = s265 < s260;
+  const SBool  s268 = s266 || s267;
+  const SWord8 s269 = sbv_bv_u8_rotr(s265, 1);
+  const SWord8 s270 = 128 | s269;
+  const SWord8 s271 = 127 & s269;
+  const SWord8 s272 = s268 ? s270 : s271;
+  const SWord8 s273 = s198 ? s264 : s272;
+  const SWord8 s274 = sbv_bv_u8_add(s1, s256);
+  const SBool  s275 = s274 < s1;
+  const SBool  s276 = s274 < s256;
+  const SBool  s277 = s275 || s276;
+  const SWord8 s278 = sbv_bv_u8_rotr(s274, 1);
+  const SWord8 s279 = 128 | s278;
+  const SWord8 s280 = 127 & s278;
+  const SWord8 s281 = s277 ? s279 : s280;
+  const SWord8 s282 = sbv_bv_u8_rotr(s281, 1);
+  const SWord8 s283 = 128 | s282;
+  const SWord8 s284 = 127 & s282;
+  const SWord8 s285 = s197 ? s283 : s284;
+  const SWord8 s286 = sbv_bv_u8_add(s1, s281);
+  const SBool  s287 = s286 < s1;
+  const SBool  s288 = s286 < s281;
+  const SBool  s289 = s287 || s288;
+  const SWord8 s290 = sbv_bv_u8_rotr(s286, 1);
+  const SWord8 s291 = 128 | s290;
+  const SWord8 s292 = 127 & s290;
+  const SWord8 s293 = s289 ? s291 : s292;
+  const SWord8 s294 = s198 ? s285 : s293;
+  const SWord8 s295 = s74 ? s273 : s294;
+  const SWord8 s296 = s55 ? s248 : s295;
+  const SWord8 s297 = s36 ? s188 : s296;
+  const SWord8 s298 = sbv_bv_u8_add(s1, s59);
+  const SBool  s299 = sbv_bv_extract_u8_0_0_u1(s298);
+  const SBool  s300 = false != s299;
+  const SWord8 s301 = s300 ? s63 : s64;
+  const SBool  s302 = sbv_bv_extract_u8_0_0_u1(s301);
+  const SBool  s303 = false != s302;
+  const SWord8 s304 = s303 ? s69 : s70;
+  const SBool  s305 = sbv_bv_extract_u8_0_0_u1(s304);
+  const SBool  s306 = false != s305;
+  const SBool  s307 = !s306;
+  const SBool  s308 = s298 < s1;
+  const SBool  s309 = s298 < s59;
+  const SBool  s310 = s308 || s309;
+  const SWord8 s311 = sbv_bv_u8_rotr(s298, 1);
+  const SWord8 s312 = 128 | s311;
+  const SWord8 s313 = 127 & s311;
+  const SWord8 s314 = s310 ? s312 : s313;
+  const SBool  s315 = sbv_bv_extract_u8_0_0_u1(s314);
+  const SBool  s316 = false != s315;
+  const SWord8 s317 = sbv_bv_u8_rotr(s301, 1);
+  const SWord8 s318 = 128 | s317;
+  const SWord8 s319 = 127 & s317;
+  const SWord8 s320 = s316 ? s318 : s319;
+  const SBool  s321 = sbv_bv_extract_u8_0_0_u1(s320);
+  const SBool  s322 = false != s321;
+  const SWord8 s323 = sbv_bv_u8_rotr(s304, 1);
+  const SWord8 s324 = 128 | s323;
+  const SWord8 s325 = 127 & s323;
+  const SWord8 s326 = s322 ? s324 : s325;
+  const SBool  s327 = sbv_bv_extract_u8_0_0_u1(s326);
+  const SBool  s328 = false != s327;
+  const SBool  s329 = !s328;
+  const SWord8 s330 = sbv_bv_u8_rotr(s314, 1);
+  const SWord8 s331 = 128 | s330;
+  const SWord8 s332 = 127 & s330;
+  const SWord8 s333 = s35 ? s331 : s332;
+  const SWord8 s334 = sbv_bv_u8_rotr(s333, 1);
+  const SWord8 s335 = 128 | s334;
+  const SWord8 s336 = 127 & s334;
+  const SWord8 s337 = s54 ? s335 : s336;
+  const SWord8 s338 = sbv_bv_u8_rotr(s337, 1);
+  const SWord8 s339 = 128 | s338;
+  const SWord8 s340 = 127 & s338;
+  const SWord8 s341 = s306 ? s339 : s340;
+  const SWord8 s342 = sbv_bv_u8_rotr(s341, 1);
+  const SWord8 s343 = 128 | s342;
+  const SWord8 s344 = 127 & s342;
+  const SWord8 s345 = s328 ? s343 : s344;
+  const SWord8 s346 = sbv_bv_u8_add(s1, s341);
+  const SBool  s347 = s346 < s1;
+  const SBool  s348 = s346 < s341;
+  const SBool  s349 = s347 || s348;
+  const SWord8 s350 = sbv_bv_u8_rotr(s346, 1);
+  const SWord8 s351 = 128 | s350;
+  const SWord8 s352 = 127 & s350;
+  const SWord8 s353 = s349 ? s351 : s352;
+  const SWord8 s354 = s329 ? s345 : s353;
+  const SWord8 s355 = sbv_bv_u8_add(s1, s337);
+  const SBool  s356 = s355 < s1;
+  const SBool  s357 = s355 < s337;
+  const SBool  s358 = s356 || s357;
+  const SWord8 s359 = sbv_bv_u8_rotr(s355, 1);
+  const SWord8 s360 = 128 | s359;
+  const SWord8 s361 = 127 & s359;
+  const SWord8 s362 = s358 ? s360 : s361;
+  const SWord8 s363 = sbv_bv_u8_rotr(s362, 1);
+  const SWord8 s364 = 128 | s363;
+  const SWord8 s365 = 127 & s363;
+  const SWord8 s366 = s328 ? s364 : s365;
+  const SWord8 s367 = sbv_bv_u8_add(s1, s362);
+  const SBool  s368 = s367 < s1;
+  const SBool  s369 = s367 < s362;
+  const SBool  s370 = s368 || s369;
+  const SWord8 s371 = sbv_bv_u8_rotr(s367, 1);
+  const SWord8 s372 = 128 | s371;
+  const SWord8 s373 = 127 & s371;
+  const SWord8 s374 = s370 ? s372 : s373;
+  const SWord8 s375 = s329 ? s366 : s374;
+  const SWord8 s376 = s307 ? s354 : s375;
+  const SWord8 s377 = sbv_bv_u8_add(s1, s333);
+  const SBool  s378 = s377 < s1;
+  const SBool  s379 = s377 < s333;
+  const SBool  s380 = s378 || s379;
+  const SWord8 s381 = sbv_bv_u8_rotr(s377, 1);
+  const SWord8 s382 = 128 | s381;
+  const SWord8 s383 = 127 & s381;
+  const SWord8 s384 = s380 ? s382 : s383;
+  const SWord8 s385 = sbv_bv_u8_rotr(s384, 1);
+  const SWord8 s386 = 128 | s385;
+  const SWord8 s387 = 127 & s385;
+  const SWord8 s388 = s306 ? s386 : s387;
+  const SWord8 s389 = sbv_bv_u8_rotr(s388, 1);
+  const SWord8 s390 = 128 | s389;
+  const SWord8 s391 = 127 & s389;
+  const SWord8 s392 = s328 ? s390 : s391;
+  const SWord8 s393 = sbv_bv_u8_add(s1, s388);
+  const SBool  s394 = s393 < s1;
+  const SBool  s395 = s393 < s388;
+  const SBool  s396 = s394 || s395;
+  const SWord8 s397 = sbv_bv_u8_rotr(s393, 1);
+  const SWord8 s398 = 128 | s397;
+  const SWord8 s399 = 127 & s397;
+  const SWord8 s400 = s396 ? s398 : s399;
+  const SWord8 s401 = s329 ? s392 : s400;
+  const SWord8 s402 = sbv_bv_u8_add(s1, s384);
+  const SBool  s403 = s402 < s1;
+  const SBool  s404 = s402 < s384;
+  const SBool  s405 = s403 || s404;
+  const SWord8 s406 = sbv_bv_u8_rotr(s402, 1);
+  const SWord8 s407 = 128 | s406;
+  const SWord8 s408 = 127 & s406;
+  const SWord8 s409 = s405 ? s407 : s408;
+  const SWord8 s410 = sbv_bv_u8_rotr(s409, 1);
+  const SWord8 s411 = 128 | s410;
+  const SWord8 s412 = 127 & s410;
+  const SWord8 s413 = s328 ? s411 : s412;
+  const SWord8 s414 = sbv_bv_u8_add(s1, s409);
+  const SBool  s415 = s414 < s1;
+  const SBool  s416 = s414 < s409;
+  const SBool  s417 = s415 || s416;
+  const SWord8 s418 = sbv_bv_u8_rotr(s414, 1);
+  const SWord8 s419 = 128 | s418;
+  const SWord8 s420 = 127 & s418;
+  const SWord8 s421 = s417 ? s419 : s420;
+  const SWord8 s422 = s329 ? s413 : s421;
+  const SWord8 s423 = s307 ? s401 : s422;
+  const SWord8 s424 = s55 ? s376 : s423;
+  const SWord8 s425 = sbv_bv_u8_add(s1, s314);
+  const SBool  s426 = sbv_bv_extract_u8_0_0_u1(s425);
+  const SBool  s427 = false != s426;
+  const SWord8 s428 = s427 ? s318 : s319;
+  const SBool  s429 = sbv_bv_extract_u8_0_0_u1(s428);
+  const SBool  s430 = false != s429;
+  const SWord8 s431 = s430 ? s324 : s325;
+  const SBool  s432 = sbv_bv_extract_u8_0_0_u1(s431);
+  const SBool  s433 = false != s432;
+  const SBool  s434 = !s433;
+  const SBool  s435 = s425 < s1;
+  const SBool  s436 = s425 < s314;
+  const SBool  s437 = s435 || s436;
+  const SWord8 s438 = sbv_bv_u8_rotr(s425, 1);
+  const SWord8 s439 = 128 | s438;
+  const SWord8 s440 = 127 & s438;
+  const SWord8 s441 = s437 ? s439 : s440;
+  const SWord8 s442 = sbv_bv_u8_rotr(s441, 1);
+  const SWord8 s443 = 128 | s442;
+  const SWord8 s444 = 127 & s442;
+  const SWord8 s445 = s54 ? s443 : s444;
+  const SWord8 s446 = sbv_bv_u8_rotr(s445, 1);
+  const SWord8 s447 = 128 | s446;
+  const SWord8 s448 = 127 & s446;
+  const SWord8 s449 = s306 ? s447 : s448;
+  const SWord8 s450 = sbv_bv_u8_rotr(s449, 1);
+  const SWord8 s451 = 128 | s450;
+  const SWord8 s452 = 127 & s450;
+  const SWord8 s453 = s433 ? s451 : s452;
+  const SWord8 s454 = sbv_bv_u8_add(s1, s449);
+  const SBool  s455 = s454 < s1;
+  const SBool  s456 = s454 < s449;
+  const SBool  s457 = s455 || s456;
+  const SWord8 s458 = sbv_bv_u8_rotr(s454, 1);
+  const SWord8 s459 = 128 | s458;
+  const SWord8 s460 = 127 & s458;
+  const SWord8 s461 = s457 ? s459 : s460;
+  const SWord8 s462 = s434 ? s453 : s461;
+  const SWord8 s463 = sbv_bv_u8_add(s1, s445);
+  const SBool  s464 = s463 < s1;
+  const SBool  s465 = s463 < s445;
+  const SBool  s466 = s464 || s465;
+  const SWord8 s467 = sbv_bv_u8_rotr(s463, 1);
+  const SWord8 s468 = 128 | s467;
+  const SWord8 s469 = 127 & s467;
+  const SWord8 s470 = s466 ? s468 : s469;
+  const SWord8 s471 = sbv_bv_u8_rotr(s470, 1);
+  const SWord8 s472 = 128 | s471;
+  const SWord8 s473 = 127 & s471;
+  const SWord8 s474 = s433 ? s472 : s473;
+  const SWord8 s475 = sbv_bv_u8_add(s1, s470);
+  const SBool  s476 = s475 < s1;
+  const SBool  s477 = s475 < s470;
+  const SBool  s478 = s476 || s477;
+  const SWord8 s479 = sbv_bv_u8_rotr(s475, 1);
+  const SWord8 s480 = 128 | s479;
+  const SWord8 s481 = 127 & s479;
+  const SWord8 s482 = s478 ? s480 : s481;
+  const SWord8 s483 = s434 ? s474 : s482;
+  const SWord8 s484 = s307 ? s462 : s483;
+  const SWord8 s485 = sbv_bv_u8_add(s1, s441);
+  const SBool  s486 = s485 < s1;
+  const SBool  s487 = s485 < s441;
+  const SBool  s488 = s486 || s487;
+  const SWord8 s489 = sbv_bv_u8_rotr(s485, 1);
+  const SWord8 s490 = 128 | s489;
+  const SWord8 s491 = 127 & s489;
+  const SWord8 s492 = s488 ? s490 : s491;
+  const SWord8 s493 = sbv_bv_u8_rotr(s492, 1);
+  const SWord8 s494 = 128 | s493;
+  const SWord8 s495 = 127 & s493;
+  const SWord8 s496 = s306 ? s494 : s495;
+  const SWord8 s497 = sbv_bv_u8_rotr(s496, 1);
+  const SWord8 s498 = 128 | s497;
+  const SWord8 s499 = 127 & s497;
+  const SWord8 s500 = s433 ? s498 : s499;
+  const SWord8 s501 = sbv_bv_u8_add(s1, s496);
+  const SBool  s502 = s501 < s1;
+  const SBool  s503 = s501 < s496;
+  const SBool  s504 = s502 || s503;
+  const SWord8 s505 = sbv_bv_u8_rotr(s501, 1);
+  const SWord8 s506 = 128 | s505;
+  const SWord8 s507 = 127 & s505;
+  const SWord8 s508 = s504 ? s506 : s507;
+  const SWord8 s509 = s434 ? s500 : s508;
+  const SWord8 s510 = sbv_bv_u8_add(s1, s492);
+  const SBool  s511 = s510 < s1;
+  const SBool  s512 = s510 < s492;
+  const SBool  s513 = s511 || s512;
+  const SWord8 s514 = sbv_bv_u8_rotr(s510, 1);
+  const SWord8 s515 = 128 | s514;
+  const SWord8 s516 = 127 & s514;
+  const SWord8 s517 = s513 ? s515 : s516;
+  const SWord8 s518 = sbv_bv_u8_rotr(s517, 1);
+  const SWord8 s519 = 128 | s518;
+  const SWord8 s520 = 127 & s518;
+  const SWord8 s521 = s433 ? s519 : s520;
+  const SWord8 s522 = sbv_bv_u8_add(s1, s517);
+  const SBool  s523 = s522 < s1;
+  const SBool  s524 = s522 < s517;
+  const SBool  s525 = s523 || s524;
+  const SWord8 s526 = sbv_bv_u8_rotr(s522, 1);
+  const SWord8 s527 = 128 | s526;
+  const SWord8 s528 = 127 & s526;
+  const SWord8 s529 = s525 ? s527 : s528;
+  const SWord8 s530 = s434 ? s521 : s529;
+  const SWord8 s531 = s307 ? s509 : s530;
+  const SWord8 s532 = s55 ? s484 : s531;
+  const SWord8 s533 = s36 ? s424 : s532;
+  const SWord8 s534 = s21 ? s297 : s533;
+  const SWord8 s535 = sbv_bv_u8_add(s1, s40);
+  const SBool  s536 = sbv_bv_extract_u8_0_0_u1(s535);
+  const SBool  s537 = false != s536;
+  const SWord8 s538 = s537 ? s44 : s45;
+  const SBool  s539 = sbv_bv_extract_u8_0_0_u1(s538);
+  const SBool  s540 = false != s539;
+  const SWord8 s541 = s540 ? s50 : s51;
+  const SBool  s542 = sbv_bv_extract_u8_0_0_u1(s541);
+  const SBool  s543 = false != s542;
+  const SBool  s544 = !s543;
+  const SBool  s545 = s535 < s1;
+  const SBool  s546 = s535 < s40;
+  const SBool  s547 = s545 || s546;
+  const SWord8 s548 = sbv_bv_u8_rotr(s535, 1);
+  const SWord8 s549 = 128 | s548;
+  const SWord8 s550 = 127 & s548;
+  const SWord8 s551 = s547 ? s549 : s550;
+  const SBool  s552 = sbv_bv_extract_u8_0_0_u1(s551);
+  const SBool  s553 = false != s552;
+  const SWord8 s554 = sbv_bv_u8_rotr(s538, 1);
+  const SWord8 s555 = 128 | s554;
+  const SWord8 s556 = 127 & s554;
+  const SWord8 s557 = s553 ? s555 : s556;
+  const SBool  s558 = sbv_bv_extract_u8_0_0_u1(s557);
+  const SBool  s559 = false != s558;
+  const SWord8 s560 = sbv_bv_u8_rotr(s541, 1);
+  const SWord8 s561 = 128 | s560;
+  const SWord8 s562 = 127 & s560;
+  const SWord8 s563 = s559 ? s561 : s562;
+  const SBool  s564 = sbv_bv_extract_u8_0_0_u1(s563);
+  const SBool  s565 = false != s564;
+  const SBool  s566 = !s565;
+  const SWord8 s567 = sbv_bv_u8_rotr(s551, 1);
+  const SWord8 s568 = 128 | s567;
+  const SWord8 s569 = 127 & s567;
+  const SWord8 s570 = s20 ? s568 : s569;
+  const SBool  s571 = sbv_bv_extract_u8_0_0_u1(s570);
+  const SBool  s572 = false != s571;
+  const SWord8 s573 = sbv_bv_u8_rotr(s557, 1);
+  const SWord8 s574 = 128 | s573;
+  const SWord8 s575 = 127 & s573;
+  const SWord8 s576 = s572 ? s574 : s575;
+  const SBool  s577 = sbv_bv_extract_u8_0_0_u1(s576);
+  const SBool  s578 = false != s577;
+  const SWord8 s579 = sbv_bv_u8_rotr(s563, 1);
+  const SWord8 s580 = 128 | s579;
+  const SWord8 s581 = 127 & s579;
+  const SWord8 s582 = s578 ? s580 : s581;
+  const SBool  s583 = sbv_bv_extract_u8_0_0_u1(s582);
+  const SBool  s584 = false != s583;
+  const SBool  s585 = !s584;
+  const SWord8 s586 = sbv_bv_u8_rotr(s570, 1);
+  const SWord8 s587 = 128 | s586;
+  const SWord8 s588 = 127 & s586;
+  const SWord8 s589 = s35 ? s587 : s588;
+  const SWord8 s590 = sbv_bv_u8_rotr(s589, 1);
+  const SWord8 s591 = 128 | s590;
+  const SWord8 s592 = 127 & s590;
+  const SWord8 s593 = s543 ? s591 : s592;
+  const SWord8 s594 = sbv_bv_u8_rotr(s593, 1);
+  const SWord8 s595 = 128 | s594;
+  const SWord8 s596 = 127 & s594;
+  const SWord8 s597 = s565 ? s595 : s596;
+  const SWord8 s598 = sbv_bv_u8_rotr(s597, 1);
+  const SWord8 s599 = 128 | s598;
+  const SWord8 s600 = 127 & s598;
+  const SWord8 s601 = s584 ? s599 : s600;
+  const SWord8 s602 = sbv_bv_u8_add(s1, s597);
+  const SBool  s603 = s602 < s1;
+  const SBool  s604 = s602 < s597;
+  const SBool  s605 = s603 || s604;
+  const SWord8 s606 = sbv_bv_u8_rotr(s602, 1);
+  const SWord8 s607 = 128 | s606;
+  const SWord8 s608 = 127 & s606;
+  const SWord8 s609 = s605 ? s607 : s608;
+  const SWord8 s610 = s585 ? s601 : s609;
+  const SWord8 s611 = sbv_bv_u8_add(s1, s593);
+  const SBool  s612 = s611 < s1;
+  const SBool  s613 = s611 < s593;
+  const SBool  s614 = s612 || s613;
+  const SWord8 s615 = sbv_bv_u8_rotr(s611, 1);
+  const SWord8 s616 = 128 | s615;
+  const SWord8 s617 = 127 & s615;
+  const SWord8 s618 = s614 ? s616 : s617;
+  const SWord8 s619 = sbv_bv_u8_rotr(s618, 1);
+  const SWord8 s620 = 128 | s619;
+  const SWord8 s621 = 127 & s619;
+  const SWord8 s622 = s584 ? s620 : s621;
+  const SWord8 s623 = sbv_bv_u8_add(s1, s618);
+  const SBool  s624 = s623 < s1;
+  const SBool  s625 = s623 < s618;
+  const SBool  s626 = s624 || s625;
+  const SWord8 s627 = sbv_bv_u8_rotr(s623, 1);
+  const SWord8 s628 = 128 | s627;
+  const SWord8 s629 = 127 & s627;
+  const SWord8 s630 = s626 ? s628 : s629;
+  const SWord8 s631 = s585 ? s622 : s630;
+  const SWord8 s632 = s566 ? s610 : s631;
+  const SWord8 s633 = sbv_bv_u8_add(s1, s589);
+  const SBool  s634 = s633 < s1;
+  const SBool  s635 = s633 < s589;
+  const SBool  s636 = s634 || s635;
+  const SWord8 s637 = sbv_bv_u8_rotr(s633, 1);
+  const SWord8 s638 = 128 | s637;
+  const SWord8 s639 = 127 & s637;
+  const SWord8 s640 = s636 ? s638 : s639;
+  const SWord8 s641 = sbv_bv_u8_rotr(s640, 1);
+  const SWord8 s642 = 128 | s641;
+  const SWord8 s643 = 127 & s641;
+  const SWord8 s644 = s565 ? s642 : s643;
+  const SWord8 s645 = sbv_bv_u8_rotr(s644, 1);
+  const SWord8 s646 = 128 | s645;
+  const SWord8 s647 = 127 & s645;
+  const SWord8 s648 = s584 ? s646 : s647;
+  const SWord8 s649 = sbv_bv_u8_add(s1, s644);
+  const SBool  s650 = s649 < s1;
+  const SBool  s651 = s649 < s644;
+  const SBool  s652 = s650 || s651;
+  const SWord8 s653 = sbv_bv_u8_rotr(s649, 1);
+  const SWord8 s654 = 128 | s653;
+  const SWord8 s655 = 127 & s653;
+  const SWord8 s656 = s652 ? s654 : s655;
+  const SWord8 s657 = s585 ? s648 : s656;
+  const SWord8 s658 = sbv_bv_u8_add(s1, s640);
+  const SBool  s659 = s658 < s1;
+  const SBool  s660 = s658 < s640;
+  const SBool  s661 = s659 || s660;
+  const SWord8 s662 = sbv_bv_u8_rotr(s658, 1);
+  const SWord8 s663 = 128 | s662;
+  const SWord8 s664 = 127 & s662;
+  const SWord8 s665 = s661 ? s663 : s664;
+  const SWord8 s666 = sbv_bv_u8_rotr(s665, 1);
+  const SWord8 s667 = 128 | s666;
+  const SWord8 s668 = 127 & s666;
+  const SWord8 s669 = s584 ? s667 : s668;
+  const SWord8 s670 = sbv_bv_u8_add(s1, s665);
+  const SBool  s671 = s670 < s1;
+  const SBool  s672 = s670 < s665;
+  const SBool  s673 = s671 || s672;
+  const SWord8 s674 = sbv_bv_u8_rotr(s670, 1);
+  const SWord8 s675 = 128 | s674;
+  const SWord8 s676 = 127 & s674;
+  const SWord8 s677 = s673 ? s675 : s676;
+  const SWord8 s678 = s585 ? s669 : s677;
+  const SWord8 s679 = s566 ? s657 : s678;
+  const SWord8 s680 = s544 ? s632 : s679;
+  const SWord8 s681 = sbv_bv_u8_add(s1, s570);
+  const SBool  s682 = sbv_bv_extract_u8_0_0_u1(s681);
+  const SBool  s683 = false != s682;
+  const SWord8 s684 = s683 ? s574 : s575;
+  const SBool  s685 = sbv_bv_extract_u8_0_0_u1(s684);
+  const SBool  s686 = false != s685;
+  const SWord8 s687 = s686 ? s580 : s581;
+  const SBool  s688 = sbv_bv_extract_u8_0_0_u1(s687);
+  const SBool  s689 = false != s688;
+  const SBool  s690 = !s689;
+  const SBool  s691 = s681 < s1;
+  const SBool  s692 = s681 < s570;
+  const SBool  s693 = s691 || s692;
+  const SWord8 s694 = sbv_bv_u8_rotr(s681, 1);
+  const SWord8 s695 = 128 | s694;
+  const SWord8 s696 = 127 & s694;
+  const SWord8 s697 = s693 ? s695 : s696;
+  const SWord8 s698 = sbv_bv_u8_rotr(s697, 1);
+  const SWord8 s699 = 128 | s698;
+  const SWord8 s700 = 127 & s698;
+  const SWord8 s701 = s543 ? s699 : s700;
+  const SWord8 s702 = sbv_bv_u8_rotr(s701, 1);
+  const SWord8 s703 = 128 | s702;
+  const SWord8 s704 = 127 & s702;
+  const SWord8 s705 = s565 ? s703 : s704;
+  const SWord8 s706 = sbv_bv_u8_rotr(s705, 1);
+  const SWord8 s707 = 128 | s706;
+  const SWord8 s708 = 127 & s706;
+  const SWord8 s709 = s689 ? s707 : s708;
+  const SWord8 s710 = sbv_bv_u8_add(s1, s705);
+  const SBool  s711 = s710 < s1;
+  const SBool  s712 = s710 < s705;
+  const SBool  s713 = s711 || s712;
+  const SWord8 s714 = sbv_bv_u8_rotr(s710, 1);
+  const SWord8 s715 = 128 | s714;
+  const SWord8 s716 = 127 & s714;
+  const SWord8 s717 = s713 ? s715 : s716;
+  const SWord8 s718 = s690 ? s709 : s717;
+  const SWord8 s719 = sbv_bv_u8_add(s1, s701);
+  const SBool  s720 = s719 < s1;
+  const SBool  s721 = s719 < s701;
+  const SBool  s722 = s720 || s721;
+  const SWord8 s723 = sbv_bv_u8_rotr(s719, 1);
+  const SWord8 s724 = 128 | s723;
+  const SWord8 s725 = 127 & s723;
+  const SWord8 s726 = s722 ? s724 : s725;
+  const SWord8 s727 = sbv_bv_u8_rotr(s726, 1);
+  const SWord8 s728 = 128 | s727;
+  const SWord8 s729 = 127 & s727;
+  const SWord8 s730 = s689 ? s728 : s729;
+  const SWord8 s731 = sbv_bv_u8_add(s1, s726);
+  const SBool  s732 = s731 < s1;
+  const SBool  s733 = s731 < s726;
+  const SBool  s734 = s732 || s733;
+  const SWord8 s735 = sbv_bv_u8_rotr(s731, 1);
+  const SWord8 s736 = 128 | s735;
+  const SWord8 s737 = 127 & s735;
+  const SWord8 s738 = s734 ? s736 : s737;
+  const SWord8 s739 = s690 ? s730 : s738;
+  const SWord8 s740 = s566 ? s718 : s739;
+  const SWord8 s741 = sbv_bv_u8_add(s1, s697);
+  const SBool  s742 = s741 < s1;
+  const SBool  s743 = s741 < s697;
+  const SBool  s744 = s742 || s743;
+  const SWord8 s745 = sbv_bv_u8_rotr(s741, 1);
+  const SWord8 s746 = 128 | s745;
+  const SWord8 s747 = 127 & s745;
+  const SWord8 s748 = s744 ? s746 : s747;
+  const SWord8 s749 = sbv_bv_u8_rotr(s748, 1);
+  const SWord8 s750 = 128 | s749;
+  const SWord8 s751 = 127 & s749;
+  const SWord8 s752 = s565 ? s750 : s751;
+  const SWord8 s753 = sbv_bv_u8_rotr(s752, 1);
+  const SWord8 s754 = 128 | s753;
+  const SWord8 s755 = 127 & s753;
+  const SWord8 s756 = s689 ? s754 : s755;
+  const SWord8 s757 = sbv_bv_u8_add(s1, s752);
+  const SBool  s758 = s757 < s1;
+  const SBool  s759 = s757 < s752;
+  const SBool  s760 = s758 || s759;
+  const SWord8 s761 = sbv_bv_u8_rotr(s757, 1);
+  const SWord8 s762 = 128 | s761;
+  const SWord8 s763 = 127 & s761;
+  const SWord8 s764 = s760 ? s762 : s763;
+  const SWord8 s765 = s690 ? s756 : s764;
+  const SWord8 s766 = sbv_bv_u8_add(s1, s748);
+  const SBool  s767 = s766 < s1;
+  const SBool  s768 = s766 < s748;
+  const SBool  s769 = s767 || s768;
+  const SWord8 s770 = sbv_bv_u8_rotr(s766, 1);
+  const SWord8 s771 = 128 | s770;
+  const SWord8 s772 = 127 & s770;
+  const SWord8 s773 = s769 ? s771 : s772;
+  const SWord8 s774 = sbv_bv_u8_rotr(s773, 1);
+  const SWord8 s775 = 128 | s774;
+  const SWord8 s776 = 127 & s774;
+  const SWord8 s777 = s689 ? s775 : s776;
+  const SWord8 s778 = sbv_bv_u8_add(s1, s773);
+  const SBool  s779 = s778 < s1;
+  const SBool  s780 = s778 < s773;
+  const SBool  s781 = s779 || s780;
+  const SWord8 s782 = sbv_bv_u8_rotr(s778, 1);
+  const SWord8 s783 = 128 | s782;
+  const SWord8 s784 = 127 & s782;
+  const SWord8 s785 = s781 ? s783 : s784;
+  const SWord8 s786 = s690 ? s777 : s785;
+  const SWord8 s787 = s566 ? s765 : s786;
+  const SWord8 s788 = s544 ? s740 : s787;
+  const SWord8 s789 = s36 ? s680 : s788;
+  const SWord8 s790 = sbv_bv_u8_add(s1, s551);
+  const SBool  s791 = sbv_bv_extract_u8_0_0_u1(s790);
+  const SBool  s792 = false != s791;
+  const SWord8 s793 = s792 ? s555 : s556;
+  const SBool  s794 = sbv_bv_extract_u8_0_0_u1(s793);
+  const SBool  s795 = false != s794;
+  const SWord8 s796 = s795 ? s561 : s562;
+  const SBool  s797 = sbv_bv_extract_u8_0_0_u1(s796);
+  const SBool  s798 = false != s797;
+  const SBool  s799 = !s798;
+  const SBool  s800 = s790 < s1;
+  const SBool  s801 = s790 < s551;
+  const SBool  s802 = s800 || s801;
+  const SWord8 s803 = sbv_bv_u8_rotr(s790, 1);
+  const SWord8 s804 = 128 | s803;
+  const SWord8 s805 = 127 & s803;
+  const SWord8 s806 = s802 ? s804 : s805;
+  const SBool  s807 = sbv_bv_extract_u8_0_0_u1(s806);
+  const SBool  s808 = false != s807;
+  const SWord8 s809 = sbv_bv_u8_rotr(s793, 1);
+  const SWord8 s810 = 128 | s809;
+  const SWord8 s811 = 127 & s809;
+  const SWord8 s812 = s808 ? s810 : s811;
+  const SBool  s813 = sbv_bv_extract_u8_0_0_u1(s812);
+  const SBool  s814 = false != s813;
+  const SWord8 s815 = sbv_bv_u8_rotr(s796, 1);
+  const SWord8 s816 = 128 | s815;
+  const SWord8 s817 = 127 & s815;
+  const SWord8 s818 = s814 ? s816 : s817;
+  const SBool  s819 = sbv_bv_extract_u8_0_0_u1(s818);
+  const SBool  s820 = false != s819;
+  const SBool  s821 = !s820;
+  const SWord8 s822 = sbv_bv_u8_rotr(s806, 1);
+  const SWord8 s823 = 128 | s822;
+  const SWord8 s824 = 127 & s822;
+  const SWord8 s825 = s35 ? s823 : s824;
+  const SWord8 s826 = sbv_bv_u8_rotr(s825, 1);
+  const SWord8 s827 = 128 | s826;
+  const SWord8 s828 = 127 & s826;
+  const SWord8 s829 = s543 ? s827 : s828;
+  const SWord8 s830 = sbv_bv_u8_rotr(s829, 1);
+  const SWord8 s831 = 128 | s830;
+  const SWord8 s832 = 127 & s830;
+  const SWord8 s833 = s798 ? s831 : s832;
+  const SWord8 s834 = sbv_bv_u8_rotr(s833, 1);
+  const SWord8 s835 = 128 | s834;
+  const SWord8 s836 = 127 & s834;
+  const SWord8 s837 = s820 ? s835 : s836;
+  const SWord8 s838 = sbv_bv_u8_add(s1, s833);
+  const SBool  s839 = s838 < s1;
+  const SBool  s840 = s838 < s833;
+  const SBool  s841 = s839 || s840;
+  const SWord8 s842 = sbv_bv_u8_rotr(s838, 1);
+  const SWord8 s843 = 128 | s842;
+  const SWord8 s844 = 127 & s842;
+  const SWord8 s845 = s841 ? s843 : s844;
+  const SWord8 s846 = s821 ? s837 : s845;
+  const SWord8 s847 = sbv_bv_u8_add(s1, s829);
+  const SBool  s848 = s847 < s1;
+  const SBool  s849 = s847 < s829;
+  const SBool  s850 = s848 || s849;
+  const SWord8 s851 = sbv_bv_u8_rotr(s847, 1);
+  const SWord8 s852 = 128 | s851;
+  const SWord8 s853 = 127 & s851;
+  const SWord8 s854 = s850 ? s852 : s853;
+  const SWord8 s855 = sbv_bv_u8_rotr(s854, 1);
+  const SWord8 s856 = 128 | s855;
+  const SWord8 s857 = 127 & s855;
+  const SWord8 s858 = s820 ? s856 : s857;
+  const SWord8 s859 = sbv_bv_u8_add(s1, s854);
+  const SBool  s860 = s859 < s1;
+  const SBool  s861 = s859 < s854;
+  const SBool  s862 = s860 || s861;
+  const SWord8 s863 = sbv_bv_u8_rotr(s859, 1);
+  const SWord8 s864 = 128 | s863;
+  const SWord8 s865 = 127 & s863;
+  const SWord8 s866 = s862 ? s864 : s865;
+  const SWord8 s867 = s821 ? s858 : s866;
+  const SWord8 s868 = s799 ? s846 : s867;
+  const SWord8 s869 = sbv_bv_u8_add(s1, s825);
+  const SBool  s870 = s869 < s1;
+  const SBool  s871 = s869 < s825;
+  const SBool  s872 = s870 || s871;
+  const SWord8 s873 = sbv_bv_u8_rotr(s869, 1);
+  const SWord8 s874 = 128 | s873;
+  const SWord8 s875 = 127 & s873;
+  const SWord8 s876 = s872 ? s874 : s875;
+  const SWord8 s877 = sbv_bv_u8_rotr(s876, 1);
+  const SWord8 s878 = 128 | s877;
+  const SWord8 s879 = 127 & s877;
+  const SWord8 s880 = s798 ? s878 : s879;
+  const SWord8 s881 = sbv_bv_u8_rotr(s880, 1);
+  const SWord8 s882 = 128 | s881;
+  const SWord8 s883 = 127 & s881;
+  const SWord8 s884 = s820 ? s882 : s883;
+  const SWord8 s885 = sbv_bv_u8_add(s1, s880);
+  const SBool  s886 = s885 < s1;
+  const SBool  s887 = s885 < s880;
+  const SBool  s888 = s886 || s887;
+  const SWord8 s889 = sbv_bv_u8_rotr(s885, 1);
+  const SWord8 s890 = 128 | s889;
+  const SWord8 s891 = 127 & s889;
+  const SWord8 s892 = s888 ? s890 : s891;
+  const SWord8 s893 = s821 ? s884 : s892;
+  const SWord8 s894 = sbv_bv_u8_add(s1, s876);
+  const SBool  s895 = s894 < s1;
+  const SBool  s896 = s894 < s876;
+  const SBool  s897 = s895 || s896;
+  const SWord8 s898 = sbv_bv_u8_rotr(s894, 1);
+  const SWord8 s899 = 128 | s898;
+  const SWord8 s900 = 127 & s898;
+  const SWord8 s901 = s897 ? s899 : s900;
+  const SWord8 s902 = sbv_bv_u8_rotr(s901, 1);
+  const SWord8 s903 = 128 | s902;
+  const SWord8 s904 = 127 & s902;
+  const SWord8 s905 = s820 ? s903 : s904;
+  const SWord8 s906 = sbv_bv_u8_add(s1, s901);
+  const SBool  s907 = s906 < s1;
+  const SBool  s908 = s906 < s901;
+  const SBool  s909 = s907 || s908;
+  const SWord8 s910 = sbv_bv_u8_rotr(s906, 1);
+  const SWord8 s911 = 128 | s910;
+  const SWord8 s912 = 127 & s910;
+  const SWord8 s913 = s909 ? s911 : s912;
+  const SWord8 s914 = s821 ? s905 : s913;
+  const SWord8 s915 = s799 ? s893 : s914;
+  const SWord8 s916 = s544 ? s868 : s915;
+  const SWord8 s917 = sbv_bv_u8_add(s1, s806);
+  const SBool  s918 = sbv_bv_extract_u8_0_0_u1(s917);
+  const SBool  s919 = false != s918;
+  const SWord8 s920 = s919 ? s810 : s811;
+  const SBool  s921 = sbv_bv_extract_u8_0_0_u1(s920);
+  const SBool  s922 = false != s921;
+  const SWord8 s923 = s922 ? s816 : s817;
+  const SBool  s924 = sbv_bv_extract_u8_0_0_u1(s923);
+  const SBool  s925 = false != s924;
+  const SBool  s926 = !s925;
+  const SBool  s927 = s917 < s1;
+  const SBool  s928 = s917 < s806;
+  const SBool  s929 = s927 || s928;
+  const SWord8 s930 = sbv_bv_u8_rotr(s917, 1);
+  const SWord8 s931 = 128 | s930;
+  const SWord8 s932 = 127 & s930;
+  const SWord8 s933 = s929 ? s931 : s932;
+  const SWord8 s934 = sbv_bv_u8_rotr(s933, 1);
+  const SWord8 s935 = 128 | s934;
+  const SWord8 s936 = 127 & s934;
+  const SWord8 s937 = s543 ? s935 : s936;
+  const SWord8 s938 = sbv_bv_u8_rotr(s937, 1);
+  const SWord8 s939 = 128 | s938;
+  const SWord8 s940 = 127 & s938;
+  const SWord8 s941 = s798 ? s939 : s940;
+  const SWord8 s942 = sbv_bv_u8_rotr(s941, 1);
+  const SWord8 s943 = 128 | s942;
+  const SWord8 s944 = 127 & s942;
+  const SWord8 s945 = s925 ? s943 : s944;
+  const SWord8 s946 = sbv_bv_u8_add(s1, s941);
+  const SBool  s947 = s946 < s1;
+  const SBool  s948 = s946 < s941;
+  const SBool  s949 = s947 || s948;
+  const SWord8 s950 = sbv_bv_u8_rotr(s946, 1);
+  const SWord8 s951 = 128 | s950;
+  const SWord8 s952 = 127 & s950;
+  const SWord8 s953 = s949 ? s951 : s952;
+  const SWord8 s954 = s926 ? s945 : s953;
+  const SWord8 s955 = sbv_bv_u8_add(s1, s937);
+  const SBool  s956 = s955 < s1;
+  const SBool  s957 = s955 < s937;
+  const SBool  s958 = s956 || s957;
+  const SWord8 s959 = sbv_bv_u8_rotr(s955, 1);
+  const SWord8 s960 = 128 | s959;
+  const SWord8 s961 = 127 & s959;
+  const SWord8 s962 = s958 ? s960 : s961;
+  const SWord8 s963 = sbv_bv_u8_rotr(s962, 1);
+  const SWord8 s964 = 128 | s963;
+  const SWord8 s965 = 127 & s963;
+  const SWord8 s966 = s925 ? s964 : s965;
+  const SWord8 s967 = sbv_bv_u8_add(s1, s962);
+  const SBool  s968 = s967 < s1;
+  const SBool  s969 = s967 < s962;
+  const SBool  s970 = s968 || s969;
+  const SWord8 s971 = sbv_bv_u8_rotr(s967, 1);
+  const SWord8 s972 = 128 | s971;
+  const SWord8 s973 = 127 & s971;
+  const SWord8 s974 = s970 ? s972 : s973;
+  const SWord8 s975 = s926 ? s966 : s974;
+  const SWord8 s976 = s799 ? s954 : s975;
+  const SWord8 s977 = sbv_bv_u8_add(s1, s933);
+  const SBool  s978 = s977 < s1;
+  const SBool  s979 = s977 < s933;
+  const SBool  s980 = s978 || s979;
+  const SWord8 s981 = sbv_bv_u8_rotr(s977, 1);
+  const SWord8 s982 = 128 | s981;
+  const SWord8 s983 = 127 & s981;
+  const SWord8 s984 = s980 ? s982 : s983;
+  const SWord8 s985 = sbv_bv_u8_rotr(s984, 1);
+  const SWord8 s986 = 128 | s985;
+  const SWord8 s987 = 127 & s985;
+  const SWord8 s988 = s798 ? s986 : s987;
+  const SWord8 s989 = sbv_bv_u8_rotr(s988, 1);
+  const SWord8 s990 = 128 | s989;
+  const SWord8 s991 = 127 & s989;
+  const SWord8 s992 = s925 ? s990 : s991;
+  const SWord8 s993 = sbv_bv_u8_add(s1, s988);
+  const SBool  s994 = s993 < s1;
+  const SBool  s995 = s993 < s988;
+  const SBool  s996 = s994 || s995;
+  const SWord8 s997 = sbv_bv_u8_rotr(s993, 1);
+  const SWord8 s998 = 128 | s997;
+  const SWord8 s999 = 127 & s997;
+  const SWord8 s1000 = s996 ? s998 : s999;
+  const SWord8 s1001 = s926 ? s992 : s1000;
+  const SWord8 s1002 = sbv_bv_u8_add(s1, s984);
+  const SBool  s1003 = s1002 < s1;
+  const SBool  s1004 = s1002 < s984;
+  const SBool  s1005 = s1003 || s1004;
+  const SWord8 s1006 = sbv_bv_u8_rotr(s1002, 1);
+  const SWord8 s1007 = 128 | s1006;
+  const SWord8 s1008 = 127 & s1006;
+  const SWord8 s1009 = s1005 ? s1007 : s1008;
+  const SWord8 s1010 = sbv_bv_u8_rotr(s1009, 1);
+  const SWord8 s1011 = 128 | s1010;
+  const SWord8 s1012 = 127 & s1010;
+  const SWord8 s1013 = s925 ? s1011 : s1012;
+  const SWord8 s1014 = sbv_bv_u8_add(s1, s1009);
+  const SBool  s1015 = s1014 < s1;
+  const SBool  s1016 = s1014 < s1009;
+  const SBool  s1017 = s1015 || s1016;
+  const SWord8 s1018 = sbv_bv_u8_rotr(s1014, 1);
+  const SWord8 s1019 = 128 | s1018;
+  const SWord8 s1020 = 127 & s1018;
+  const SWord8 s1021 = s1017 ? s1019 : s1020;
+  const SWord8 s1022 = s926 ? s1013 : s1021;
+  const SWord8 s1023 = s799 ? s1001 : s1022;
+  const SWord8 s1024 = s544 ? s976 : s1023;
+  const SWord8 s1025 = s36 ? s916 : s1024;
+  const SWord8 s1026 = s21 ? s789 : s1025;
+  const SWord8 s1027 = s16 ? s534 : s1026;
+  const SWord8 s1028 = sbv_bv_u8_add(s1, s24);
+  const SBool  s1029 = sbv_bv_extract_u8_0_0_u1(s1028);
+  const SBool  s1030 = false != s1029;
+  const SWord8 s1031 = s1030 ? 128 : 0;
+  const SBool  s1032 = sbv_bv_extract_u8_0_0_u1(s1031);
+  const SBool  s1033 = false != s1032;
+  const SWord8 s1034 = s1033 ? s31 : s32;
+  const SBool  s1035 = sbv_bv_extract_u8_0_0_u1(s1034);
+  const SBool  s1036 = false != s1035;
+  const SBool  s1037 = !s1036;
+  const SBool  s1038 = s1028 < s1;
+  const SBool  s1039 = s1028 < s24;
+  const SBool  s1040 = s1038 || s1039;
+  const SWord8 s1041 = sbv_bv_u8_rotr(s1028, 1);
+  const SWord8 s1042 = 128 | s1041;
+  const SWord8 s1043 = 127 & s1041;
+  const SWord8 s1044 = s1040 ? s1042 : s1043;
+  const SBool  s1045 = sbv_bv_extract_u8_0_0_u1(s1044);
+  const SBool  s1046 = false != s1045;
+  const SWord8 s1047 = sbv_bv_u8_rotr(s1031, 1);
+  const SWord8 s1048 = 128 | s1047;
+  const SWord8 s1049 = 127 & s1047;
+  const SWord8 s1050 = s1046 ? s1048 : s1049;
+  const SBool  s1051 = sbv_bv_extract_u8_0_0_u1(s1050);
+  const SBool  s1052 = false != s1051;
+  const SWord8 s1053 = sbv_bv_u8_rotr(s1034, 1);
+  const SWord8 s1054 = 128 | s1053;
+  const SWord8 s1055 = 127 & s1053;
+  const SWord8 s1056 = s1052 ? s1054 : s1055;
+  const SBool  s1057 = sbv_bv_extract_u8_0_0_u1(s1056);
+  const SBool  s1058 = false != s1057;
+  const SBool  s1059 = !s1058;
+  const SWord8 s1060 = sbv_bv_u8_rotr(s1044, 1);
+  const SWord8 s1061 = 128 | s1060;
+  const SWord8 s1062 = 127 & s1060;
+  const SWord8 s1063 = s15 ? s1061 : s1062;
+  const SBool  s1064 = sbv_bv_extract_u8_0_0_u1(s1063);
+  const SBool  s1065 = false != s1064;
+  const SWord8 s1066 = sbv_bv_u8_rotr(s1050, 1);
+  const SWord8 s1067 = 128 | s1066;
+  const SWord8 s1068 = 127 & s1066;
+  const SWord8 s1069 = s1065 ? s1067 : s1068;
+  const SBool  s1070 = sbv_bv_extract_u8_0_0_u1(s1069);
+  const SBool  s1071 = false != s1070;
+  const SWord8 s1072 = sbv_bv_u8_rotr(s1056, 1);
+  const SWord8 s1073 = 128 | s1072;
+  const SWord8 s1074 = 127 & s1072;
+  const SWord8 s1075 = s1071 ? s1073 : s1074;
+  const SBool  s1076 = sbv_bv_extract_u8_0_0_u1(s1075);
+  const SBool  s1077 = false != s1076;
+  const SBool  s1078 = !s1077;
+  const SWord8 s1079 = sbv_bv_u8_rotr(s1063, 1);
+  const SWord8 s1080 = 128 | s1079;
+  const SWord8 s1081 = 127 & s1079;
+  const SWord8 s1082 = s20 ? s1080 : s1081;
+  const SBool  s1083 = sbv_bv_extract_u8_0_0_u1(s1082);
+  const SBool  s1084 = false != s1083;
+  const SWord8 s1085 = sbv_bv_u8_rotr(s1069, 1);
+  const SWord8 s1086 = 128 | s1085;
+  const SWord8 s1087 = 127 & s1085;
+  const SWord8 s1088 = s1084 ? s1086 : s1087;
+  const SBool  s1089 = sbv_bv_extract_u8_0_0_u1(s1088);
+  const SBool  s1090 = false != s1089;
+  const SWord8 s1091 = sbv_bv_u8_rotr(s1075, 1);
+  const SWord8 s1092 = 128 | s1091;
+  const SWord8 s1093 = 127 & s1091;
+  const SWord8 s1094 = s1090 ? s1092 : s1093;
+  const SBool  s1095 = sbv_bv_extract_u8_0_0_u1(s1094);
+  const SBool  s1096 = false != s1095;
+  const SBool  s1097 = !s1096;
+  const SWord8 s1098 = sbv_bv_u8_rotr(s1082, 1);
+  const SWord8 s1099 = 128 | s1098;
+  const SWord8 s1100 = 127 & s1098;
+  const SWord8 s1101 = s1036 ? s1099 : s1100;
+  const SWord8 s1102 = sbv_bv_u8_rotr(s1101, 1);
+  const SWord8 s1103 = 128 | s1102;
+  const SWord8 s1104 = 127 & s1102;
+  const SWord8 s1105 = s1058 ? s1103 : s1104;
+  const SWord8 s1106 = sbv_bv_u8_rotr(s1105, 1);
+  const SWord8 s1107 = 128 | s1106;
+  const SWord8 s1108 = 127 & s1106;
+  const SWord8 s1109 = s1077 ? s1107 : s1108;
+  const SWord8 s1110 = sbv_bv_u8_rotr(s1109, 1);
+  const SWord8 s1111 = 128 | s1110;
+  const SWord8 s1112 = 127 & s1110;
+  const SWord8 s1113 = s1096 ? s1111 : s1112;
+  const SWord8 s1114 = sbv_bv_u8_add(s1, s1109);
+  const SBool  s1115 = s1114 < s1;
+  const SBool  s1116 = s1114 < s1109;
+  const SBool  s1117 = s1115 || s1116;
+  const SWord8 s1118 = sbv_bv_u8_rotr(s1114, 1);
+  const SWord8 s1119 = 128 | s1118;
+  const SWord8 s1120 = 127 & s1118;
+  const SWord8 s1121 = s1117 ? s1119 : s1120;
+  const SWord8 s1122 = s1097 ? s1113 : s1121;
+  const SWord8 s1123 = sbv_bv_u8_add(s1, s1105);
+  const SBool  s1124 = s1123 < s1;
+  const SBool  s1125 = s1123 < s1105;
+  const SBool  s1126 = s1124 || s1125;
+  const SWord8 s1127 = sbv_bv_u8_rotr(s1123, 1);
+  const SWord8 s1128 = 128 | s1127;
+  const SWord8 s1129 = 127 & s1127;
+  const SWord8 s1130 = s1126 ? s1128 : s1129;
+  const SWord8 s1131 = sbv_bv_u8_rotr(s1130, 1);
+  const SWord8 s1132 = 128 | s1131;
+  const SWord8 s1133 = 127 & s1131;
+  const SWord8 s1134 = s1096 ? s1132 : s1133;
+  const SWord8 s1135 = sbv_bv_u8_add(s1, s1130);
+  const SBool  s1136 = s1135 < s1;
+  const SBool  s1137 = s1135 < s1130;
+  const SBool  s1138 = s1136 || s1137;
+  const SWord8 s1139 = sbv_bv_u8_rotr(s1135, 1);
+  const SWord8 s1140 = 128 | s1139;
+  const SWord8 s1141 = 127 & s1139;
+  const SWord8 s1142 = s1138 ? s1140 : s1141;
+  const SWord8 s1143 = s1097 ? s1134 : s1142;
+  const SWord8 s1144 = s1078 ? s1122 : s1143;
+  const SWord8 s1145 = sbv_bv_u8_add(s1, s1101);
+  const SBool  s1146 = s1145 < s1;
+  const SBool  s1147 = s1145 < s1101;
+  const SBool  s1148 = s1146 || s1147;
+  const SWord8 s1149 = sbv_bv_u8_rotr(s1145, 1);
+  const SWord8 s1150 = 128 | s1149;
+  const SWord8 s1151 = 127 & s1149;
+  const SWord8 s1152 = s1148 ? s1150 : s1151;
+  const SWord8 s1153 = sbv_bv_u8_rotr(s1152, 1);
+  const SWord8 s1154 = 128 | s1153;
+  const SWord8 s1155 = 127 & s1153;
+  const SWord8 s1156 = s1077 ? s1154 : s1155;
+  const SWord8 s1157 = sbv_bv_u8_rotr(s1156, 1);
+  const SWord8 s1158 = 128 | s1157;
+  const SWord8 s1159 = 127 & s1157;
+  const SWord8 s1160 = s1096 ? s1158 : s1159;
+  const SWord8 s1161 = sbv_bv_u8_add(s1, s1156);
+  const SBool  s1162 = s1161 < s1;
+  const SBool  s1163 = s1161 < s1156;
+  const SBool  s1164 = s1162 || s1163;
+  const SWord8 s1165 = sbv_bv_u8_rotr(s1161, 1);
+  const SWord8 s1166 = 128 | s1165;
+  const SWord8 s1167 = 127 & s1165;
+  const SWord8 s1168 = s1164 ? s1166 : s1167;
+  const SWord8 s1169 = s1097 ? s1160 : s1168;
+  const SWord8 s1170 = sbv_bv_u8_add(s1, s1152);
+  const SBool  s1171 = s1170 < s1;
+  const SBool  s1172 = s1170 < s1152;
+  const SBool  s1173 = s1171 || s1172;
+  const SWord8 s1174 = sbv_bv_u8_rotr(s1170, 1);
+  const SWord8 s1175 = 128 | s1174;
+  const SWord8 s1176 = 127 & s1174;
+  const SWord8 s1177 = s1173 ? s1175 : s1176;
+  const SWord8 s1178 = sbv_bv_u8_rotr(s1177, 1);
+  const SWord8 s1179 = 128 | s1178;
+  const SWord8 s1180 = 127 & s1178;
+  const SWord8 s1181 = s1096 ? s1179 : s1180;
+  const SWord8 s1182 = sbv_bv_u8_add(s1, s1177);
+  const SBool  s1183 = s1182 < s1;
+  const SBool  s1184 = s1182 < s1177;
+  const SBool  s1185 = s1183 || s1184;
+  const SWord8 s1186 = sbv_bv_u8_rotr(s1182, 1);
+  const SWord8 s1187 = 128 | s1186;
+  const SWord8 s1188 = 127 & s1186;
+  const SWord8 s1189 = s1185 ? s1187 : s1188;
+  const SWord8 s1190 = s1097 ? s1181 : s1189;
+  const SWord8 s1191 = s1078 ? s1169 : s1190;
+  const SWord8 s1192 = s1059 ? s1144 : s1191;
+  const SWord8 s1193 = sbv_bv_u8_add(s1, s1082);
+  const SBool  s1194 = sbv_bv_extract_u8_0_0_u1(s1193);
+  const SBool  s1195 = false != s1194;
+  const SWord8 s1196 = s1195 ? s1086 : s1087;
+  const SBool  s1197 = sbv_bv_extract_u8_0_0_u1(s1196);
+  const SBool  s1198 = false != s1197;
+  const SWord8 s1199 = s1198 ? s1092 : s1093;
+  const SBool  s1200 = sbv_bv_extract_u8_0_0_u1(s1199);
+  const SBool  s1201 = false != s1200;
+  const SBool  s1202 = !s1201;
+  const SBool  s1203 = s1193 < s1;
+  const SBool  s1204 = s1193 < s1082;
+  const SBool  s1205 = s1203 || s1204;
+  const SWord8 s1206 = sbv_bv_u8_rotr(s1193, 1);
+  const SWord8 s1207 = 128 | s1206;
+  const SWord8 s1208 = 127 & s1206;
+  const SWord8 s1209 = s1205 ? s1207 : s1208;
+  const SWord8 s1210 = sbv_bv_u8_rotr(s1209, 1);
+  const SWord8 s1211 = 128 | s1210;
+  const SWord8 s1212 = 127 & s1210;
+  const SWord8 s1213 = s1058 ? s1211 : s1212;
+  const SWord8 s1214 = sbv_bv_u8_rotr(s1213, 1);
+  const SWord8 s1215 = 128 | s1214;
+  const SWord8 s1216 = 127 & s1214;
+  const SWord8 s1217 = s1077 ? s1215 : s1216;
+  const SWord8 s1218 = sbv_bv_u8_rotr(s1217, 1);
+  const SWord8 s1219 = 128 | s1218;
+  const SWord8 s1220 = 127 & s1218;
+  const SWord8 s1221 = s1201 ? s1219 : s1220;
+  const SWord8 s1222 = sbv_bv_u8_add(s1, s1217);
+  const SBool  s1223 = s1222 < s1;
+  const SBool  s1224 = s1222 < s1217;
+  const SBool  s1225 = s1223 || s1224;
+  const SWord8 s1226 = sbv_bv_u8_rotr(s1222, 1);
+  const SWord8 s1227 = 128 | s1226;
+  const SWord8 s1228 = 127 & s1226;
+  const SWord8 s1229 = s1225 ? s1227 : s1228;
+  const SWord8 s1230 = s1202 ? s1221 : s1229;
+  const SWord8 s1231 = sbv_bv_u8_add(s1, s1213);
+  const SBool  s1232 = s1231 < s1;
+  const SBool  s1233 = s1231 < s1213;
+  const SBool  s1234 = s1232 || s1233;
+  const SWord8 s1235 = sbv_bv_u8_rotr(s1231, 1);
+  const SWord8 s1236 = 128 | s1235;
+  const SWord8 s1237 = 127 & s1235;
+  const SWord8 s1238 = s1234 ? s1236 : s1237;
+  const SWord8 s1239 = sbv_bv_u8_rotr(s1238, 1);
+  const SWord8 s1240 = 128 | s1239;
+  const SWord8 s1241 = 127 & s1239;
+  const SWord8 s1242 = s1201 ? s1240 : s1241;
+  const SWord8 s1243 = sbv_bv_u8_add(s1, s1238);
+  const SBool  s1244 = s1243 < s1;
+  const SBool  s1245 = s1243 < s1238;
+  const SBool  s1246 = s1244 || s1245;
+  const SWord8 s1247 = sbv_bv_u8_rotr(s1243, 1);
+  const SWord8 s1248 = 128 | s1247;
+  const SWord8 s1249 = 127 & s1247;
+  const SWord8 s1250 = s1246 ? s1248 : s1249;
+  const SWord8 s1251 = s1202 ? s1242 : s1250;
+  const SWord8 s1252 = s1078 ? s1230 : s1251;
+  const SWord8 s1253 = sbv_bv_u8_add(s1, s1209);
+  const SBool  s1254 = s1253 < s1;
+  const SBool  s1255 = s1253 < s1209;
+  const SBool  s1256 = s1254 || s1255;
+  const SWord8 s1257 = sbv_bv_u8_rotr(s1253, 1);
+  const SWord8 s1258 = 128 | s1257;
+  const SWord8 s1259 = 127 & s1257;
+  const SWord8 s1260 = s1256 ? s1258 : s1259;
+  const SWord8 s1261 = sbv_bv_u8_rotr(s1260, 1);
+  const SWord8 s1262 = 128 | s1261;
+  const SWord8 s1263 = 127 & s1261;
+  const SWord8 s1264 = s1077 ? s1262 : s1263;
+  const SWord8 s1265 = sbv_bv_u8_rotr(s1264, 1);
+  const SWord8 s1266 = 128 | s1265;
+  const SWord8 s1267 = 127 & s1265;
+  const SWord8 s1268 = s1201 ? s1266 : s1267;
+  const SWord8 s1269 = sbv_bv_u8_add(s1, s1264);
+  const SBool  s1270 = s1269 < s1;
+  const SBool  s1271 = s1269 < s1264;
+  const SBool  s1272 = s1270 || s1271;
+  const SWord8 s1273 = sbv_bv_u8_rotr(s1269, 1);
+  const SWord8 s1274 = 128 | s1273;
+  const SWord8 s1275 = 127 & s1273;
+  const SWord8 s1276 = s1272 ? s1274 : s1275;
+  const SWord8 s1277 = s1202 ? s1268 : s1276;
+  const SWord8 s1278 = sbv_bv_u8_add(s1, s1260);
+  const SBool  s1279 = s1278 < s1;
+  const SBool  s1280 = s1278 < s1260;
+  const SBool  s1281 = s1279 || s1280;
+  const SWord8 s1282 = sbv_bv_u8_rotr(s1278, 1);
+  const SWord8 s1283 = 128 | s1282;
+  const SWord8 s1284 = 127 & s1282;
+  const SWord8 s1285 = s1281 ? s1283 : s1284;
+  const SWord8 s1286 = sbv_bv_u8_rotr(s1285, 1);
+  const SWord8 s1287 = 128 | s1286;
+  const SWord8 s1288 = 127 & s1286;
+  const SWord8 s1289 = s1201 ? s1287 : s1288;
+  const SWord8 s1290 = sbv_bv_u8_add(s1, s1285);
+  const SBool  s1291 = s1290 < s1;
+  const SBool  s1292 = s1290 < s1285;
+  const SBool  s1293 = s1291 || s1292;
+  const SWord8 s1294 = sbv_bv_u8_rotr(s1290, 1);
+  const SWord8 s1295 = 128 | s1294;
+  const SWord8 s1296 = 127 & s1294;
+  const SWord8 s1297 = s1293 ? s1295 : s1296;
+  const SWord8 s1298 = s1202 ? s1289 : s1297;
+  const SWord8 s1299 = s1078 ? s1277 : s1298;
+  const SWord8 s1300 = s1059 ? s1252 : s1299;
+  const SWord8 s1301 = s1037 ? s1192 : s1300;
+  const SWord8 s1302 = sbv_bv_u8_add(s1, s1063);
+  const SBool  s1303 = sbv_bv_extract_u8_0_0_u1(s1302);
+  const SBool  s1304 = false != s1303;
+  const SWord8 s1305 = s1304 ? s1067 : s1068;
+  const SBool  s1306 = sbv_bv_extract_u8_0_0_u1(s1305);
+  const SBool  s1307 = false != s1306;
+  const SWord8 s1308 = s1307 ? s1073 : s1074;
+  const SBool  s1309 = sbv_bv_extract_u8_0_0_u1(s1308);
+  const SBool  s1310 = false != s1309;
+  const SBool  s1311 = !s1310;
+  const SBool  s1312 = s1302 < s1;
+  const SBool  s1313 = s1302 < s1063;
+  const SBool  s1314 = s1312 || s1313;
+  const SWord8 s1315 = sbv_bv_u8_rotr(s1302, 1);
+  const SWord8 s1316 = 128 | s1315;
+  const SWord8 s1317 = 127 & s1315;
+  const SWord8 s1318 = s1314 ? s1316 : s1317;
+  const SBool  s1319 = sbv_bv_extract_u8_0_0_u1(s1318);
+  const SBool  s1320 = false != s1319;
+  const SWord8 s1321 = sbv_bv_u8_rotr(s1305, 1);
+  const SWord8 s1322 = 128 | s1321;
+  const SWord8 s1323 = 127 & s1321;
+  const SWord8 s1324 = s1320 ? s1322 : s1323;
+  const SBool  s1325 = sbv_bv_extract_u8_0_0_u1(s1324);
+  const SBool  s1326 = false != s1325;
+  const SWord8 s1327 = sbv_bv_u8_rotr(s1308, 1);
+  const SWord8 s1328 = 128 | s1327;
+  const SWord8 s1329 = 127 & s1327;
+  const SWord8 s1330 = s1326 ? s1328 : s1329;
+  const SBool  s1331 = sbv_bv_extract_u8_0_0_u1(s1330);
+  const SBool  s1332 = false != s1331;
+  const SBool  s1333 = !s1332;
+  const SWord8 s1334 = sbv_bv_u8_rotr(s1318, 1);
+  const SWord8 s1335 = 128 | s1334;
+  const SWord8 s1336 = 127 & s1334;
+  const SWord8 s1337 = s1036 ? s1335 : s1336;
+  const SWord8 s1338 = sbv_bv_u8_rotr(s1337, 1);
+  const SWord8 s1339 = 128 | s1338;
+  const SWord8 s1340 = 127 & s1338;
+  const SWord8 s1341 = s1058 ? s1339 : s1340;
+  const SWord8 s1342 = sbv_bv_u8_rotr(s1341, 1);
+  const SWord8 s1343 = 128 | s1342;
+  const SWord8 s1344 = 127 & s1342;
+  const SWord8 s1345 = s1310 ? s1343 : s1344;
+  const SWord8 s1346 = sbv_bv_u8_rotr(s1345, 1);
+  const SWord8 s1347 = 128 | s1346;
+  const SWord8 s1348 = 127 & s1346;
+  const SWord8 s1349 = s1332 ? s1347 : s1348;
+  const SWord8 s1350 = sbv_bv_u8_add(s1, s1345);
+  const SBool  s1351 = s1350 < s1;
+  const SBool  s1352 = s1350 < s1345;
+  const SBool  s1353 = s1351 || s1352;
+  const SWord8 s1354 = sbv_bv_u8_rotr(s1350, 1);
+  const SWord8 s1355 = 128 | s1354;
+  const SWord8 s1356 = 127 & s1354;
+  const SWord8 s1357 = s1353 ? s1355 : s1356;
+  const SWord8 s1358 = s1333 ? s1349 : s1357;
+  const SWord8 s1359 = sbv_bv_u8_add(s1, s1341);
+  const SBool  s1360 = s1359 < s1;
+  const SBool  s1361 = s1359 < s1341;
+  const SBool  s1362 = s1360 || s1361;
+  const SWord8 s1363 = sbv_bv_u8_rotr(s1359, 1);
+  const SWord8 s1364 = 128 | s1363;
+  const SWord8 s1365 = 127 & s1363;
+  const SWord8 s1366 = s1362 ? s1364 : s1365;
+  const SWord8 s1367 = sbv_bv_u8_rotr(s1366, 1);
+  const SWord8 s1368 = 128 | s1367;
+  const SWord8 s1369 = 127 & s1367;
+  const SWord8 s1370 = s1332 ? s1368 : s1369;
+  const SWord8 s1371 = sbv_bv_u8_add(s1, s1366);
+  const SBool  s1372 = s1371 < s1;
+  const SBool  s1373 = s1371 < s1366;
+  const SBool  s1374 = s1372 || s1373;
+  const SWord8 s1375 = sbv_bv_u8_rotr(s1371, 1);
+  const SWord8 s1376 = 128 | s1375;
+  const SWord8 s1377 = 127 & s1375;
+  const SWord8 s1378 = s1374 ? s1376 : s1377;
+  const SWord8 s1379 = s1333 ? s1370 : s1378;
+  const SWord8 s1380 = s1311 ? s1358 : s1379;
+  const SWord8 s1381 = sbv_bv_u8_add(s1, s1337);
+  const SBool  s1382 = s1381 < s1;
+  const SBool  s1383 = s1381 < s1337;
+  const SBool  s1384 = s1382 || s1383;
+  const SWord8 s1385 = sbv_bv_u8_rotr(s1381, 1);
+  const SWord8 s1386 = 128 | s1385;
+  const SWord8 s1387 = 127 & s1385;
+  const SWord8 s1388 = s1384 ? s1386 : s1387;
+  const SWord8 s1389 = sbv_bv_u8_rotr(s1388, 1);
+  const SWord8 s1390 = 128 | s1389;
+  const SWord8 s1391 = 127 & s1389;
+  const SWord8 s1392 = s1310 ? s1390 : s1391;
+  const SWord8 s1393 = sbv_bv_u8_rotr(s1392, 1);
+  const SWord8 s1394 = 128 | s1393;
+  const SWord8 s1395 = 127 & s1393;
+  const SWord8 s1396 = s1332 ? s1394 : s1395;
+  const SWord8 s1397 = sbv_bv_u8_add(s1, s1392);
+  const SBool  s1398 = s1397 < s1;
+  const SBool  s1399 = s1397 < s1392;
+  const SBool  s1400 = s1398 || s1399;
+  const SWord8 s1401 = sbv_bv_u8_rotr(s1397, 1);
+  const SWord8 s1402 = 128 | s1401;
+  const SWord8 s1403 = 127 & s1401;
+  const SWord8 s1404 = s1400 ? s1402 : s1403;
+  const SWord8 s1405 = s1333 ? s1396 : s1404;
+  const SWord8 s1406 = sbv_bv_u8_add(s1, s1388);
+  const SBool  s1407 = s1406 < s1;
+  const SBool  s1408 = s1406 < s1388;
+  const SBool  s1409 = s1407 || s1408;
+  const SWord8 s1410 = sbv_bv_u8_rotr(s1406, 1);
+  const SWord8 s1411 = 128 | s1410;
+  const SWord8 s1412 = 127 & s1410;
+  const SWord8 s1413 = s1409 ? s1411 : s1412;
+  const SWord8 s1414 = sbv_bv_u8_rotr(s1413, 1);
+  const SWord8 s1415 = 128 | s1414;
+  const SWord8 s1416 = 127 & s1414;
+  const SWord8 s1417 = s1332 ? s1415 : s1416;
+  const SWord8 s1418 = sbv_bv_u8_add(s1, s1413);
+  const SBool  s1419 = s1418 < s1;
+  const SBool  s1420 = s1418 < s1413;
+  const SBool  s1421 = s1419 || s1420;
+  const SWord8 s1422 = sbv_bv_u8_rotr(s1418, 1);
+  const SWord8 s1423 = 128 | s1422;
+  const SWord8 s1424 = 127 & s1422;
+  const SWord8 s1425 = s1421 ? s1423 : s1424;
+  const SWord8 s1426 = s1333 ? s1417 : s1425;
+  const SWord8 s1427 = s1311 ? s1405 : s1426;
+  const SWord8 s1428 = s1059 ? s1380 : s1427;
+  const SWord8 s1429 = sbv_bv_u8_add(s1, s1318);
+  const SBool  s1430 = sbv_bv_extract_u8_0_0_u1(s1429);
+  const SBool  s1431 = false != s1430;
+  const SWord8 s1432 = s1431 ? s1322 : s1323;
+  const SBool  s1433 = sbv_bv_extract_u8_0_0_u1(s1432);
+  const SBool  s1434 = false != s1433;
+  const SWord8 s1435 = s1434 ? s1328 : s1329;
+  const SBool  s1436 = sbv_bv_extract_u8_0_0_u1(s1435);
+  const SBool  s1437 = false != s1436;
+  const SBool  s1438 = !s1437;
+  const SBool  s1439 = s1429 < s1;
+  const SBool  s1440 = s1429 < s1318;
+  const SBool  s1441 = s1439 || s1440;
+  const SWord8 s1442 = sbv_bv_u8_rotr(s1429, 1);
+  const SWord8 s1443 = 128 | s1442;
+  const SWord8 s1444 = 127 & s1442;
+  const SWord8 s1445 = s1441 ? s1443 : s1444;
+  const SWord8 s1446 = sbv_bv_u8_rotr(s1445, 1);
+  const SWord8 s1447 = 128 | s1446;
+  const SWord8 s1448 = 127 & s1446;
+  const SWord8 s1449 = s1058 ? s1447 : s1448;
+  const SWord8 s1450 = sbv_bv_u8_rotr(s1449, 1);
+  const SWord8 s1451 = 128 | s1450;
+  const SWord8 s1452 = 127 & s1450;
+  const SWord8 s1453 = s1310 ? s1451 : s1452;
+  const SWord8 s1454 = sbv_bv_u8_rotr(s1453, 1);
+  const SWord8 s1455 = 128 | s1454;
+  const SWord8 s1456 = 127 & s1454;
+  const SWord8 s1457 = s1437 ? s1455 : s1456;
+  const SWord8 s1458 = sbv_bv_u8_add(s1, s1453);
+  const SBool  s1459 = s1458 < s1;
+  const SBool  s1460 = s1458 < s1453;
+  const SBool  s1461 = s1459 || s1460;
+  const SWord8 s1462 = sbv_bv_u8_rotr(s1458, 1);
+  const SWord8 s1463 = 128 | s1462;
+  const SWord8 s1464 = 127 & s1462;
+  const SWord8 s1465 = s1461 ? s1463 : s1464;
+  const SWord8 s1466 = s1438 ? s1457 : s1465;
+  const SWord8 s1467 = sbv_bv_u8_add(s1, s1449);
+  const SBool  s1468 = s1467 < s1;
+  const SBool  s1469 = s1467 < s1449;
+  const SBool  s1470 = s1468 || s1469;
+  const SWord8 s1471 = sbv_bv_u8_rotr(s1467, 1);
+  const SWord8 s1472 = 128 | s1471;
+  const SWord8 s1473 = 127 & s1471;
+  const SWord8 s1474 = s1470 ? s1472 : s1473;
+  const SWord8 s1475 = sbv_bv_u8_rotr(s1474, 1);
+  const SWord8 s1476 = 128 | s1475;
+  const SWord8 s1477 = 127 & s1475;
+  const SWord8 s1478 = s1437 ? s1476 : s1477;
+  const SWord8 s1479 = sbv_bv_u8_add(s1, s1474);
+  const SBool  s1480 = s1479 < s1;
+  const SBool  s1481 = s1479 < s1474;
+  const SBool  s1482 = s1480 || s1481;
+  const SWord8 s1483 = sbv_bv_u8_rotr(s1479, 1);
+  const SWord8 s1484 = 128 | s1483;
+  const SWord8 s1485 = 127 & s1483;
+  const SWord8 s1486 = s1482 ? s1484 : s1485;
+  const SWord8 s1487 = s1438 ? s1478 : s1486;
+  const SWord8 s1488 = s1311 ? s1466 : s1487;
+  const SWord8 s1489 = sbv_bv_u8_add(s1, s1445);
+  const SBool  s1490 = s1489 < s1;
+  const SBool  s1491 = s1489 < s1445;
+  const SBool  s1492 = s1490 || s1491;
+  const SWord8 s1493 = sbv_bv_u8_rotr(s1489, 1);
+  const SWord8 s1494 = 128 | s1493;
+  const SWord8 s1495 = 127 & s1493;
+  const SWord8 s1496 = s1492 ? s1494 : s1495;
+  const SWord8 s1497 = sbv_bv_u8_rotr(s1496, 1);
+  const SWord8 s1498 = 128 | s1497;
+  const SWord8 s1499 = 127 & s1497;
+  const SWord8 s1500 = s1310 ? s1498 : s1499;
+  const SWord8 s1501 = sbv_bv_u8_rotr(s1500, 1);
+  const SWord8 s1502 = 128 | s1501;
+  const SWord8 s1503 = 127 & s1501;
+  const SWord8 s1504 = s1437 ? s1502 : s1503;
+  const SWord8 s1505 = sbv_bv_u8_add(s1, s1500);
+  const SBool  s1506 = s1505 < s1;
+  const SBool  s1507 = s1505 < s1500;
+  const SBool  s1508 = s1506 || s1507;
+  const SWord8 s1509 = sbv_bv_u8_rotr(s1505, 1);
+  const SWord8 s1510 = 128 | s1509;
+  const SWord8 s1511 = 127 & s1509;
+  const SWord8 s1512 = s1508 ? s1510 : s1511;
+  const SWord8 s1513 = s1438 ? s1504 : s1512;
+  const SWord8 s1514 = sbv_bv_u8_add(s1, s1496);
+  const SBool  s1515 = s1514 < s1;
+  const SBool  s1516 = s1514 < s1496;
+  const SBool  s1517 = s1515 || s1516;
+  const SWord8 s1518 = sbv_bv_u8_rotr(s1514, 1);
+  const SWord8 s1519 = 128 | s1518;
+  const SWord8 s1520 = 127 & s1518;
+  const SWord8 s1521 = s1517 ? s1519 : s1520;
+  const SWord8 s1522 = sbv_bv_u8_rotr(s1521, 1);
+  const SWord8 s1523 = 128 | s1522;
+  const SWord8 s1524 = 127 & s1522;
+  const SWord8 s1525 = s1437 ? s1523 : s1524;
+  const SWord8 s1526 = sbv_bv_u8_add(s1, s1521);
+  const SBool  s1527 = s1526 < s1;
+  const SBool  s1528 = s1526 < s1521;
+  const SBool  s1529 = s1527 || s1528;
+  const SWord8 s1530 = sbv_bv_u8_rotr(s1526, 1);
+  const SWord8 s1531 = 128 | s1530;
+  const SWord8 s1532 = 127 & s1530;
+  const SWord8 s1533 = s1529 ? s1531 : s1532;
+  const SWord8 s1534 = s1438 ? s1525 : s1533;
+  const SWord8 s1535 = s1311 ? s1513 : s1534;
+  const SWord8 s1536 = s1059 ? s1488 : s1535;
+  const SWord8 s1537 = s1037 ? s1428 : s1536;
+  const SWord8 s1538 = s21 ? s1301 : s1537;
+  const SWord8 s1539 = sbv_bv_u8_add(s1, s1044);
+  const SBool  s1540 = sbv_bv_extract_u8_0_0_u1(s1539);
+  const SBool  s1541 = false != s1540;
+  const SWord8 s1542 = s1541 ? s1048 : s1049;
+  const SBool  s1543 = sbv_bv_extract_u8_0_0_u1(s1542);
+  const SBool  s1544 = false != s1543;
+  const SWord8 s1545 = s1544 ? s1054 : s1055;
+  const SBool  s1546 = sbv_bv_extract_u8_0_0_u1(s1545);
+  const SBool  s1547 = false != s1546;
+  const SBool  s1548 = !s1547;
+  const SBool  s1549 = s1539 < s1;
+  const SBool  s1550 = s1539 < s1044;
+  const SBool  s1551 = s1549 || s1550;
+  const SWord8 s1552 = sbv_bv_u8_rotr(s1539, 1);
+  const SWord8 s1553 = 128 | s1552;
+  const SWord8 s1554 = 127 & s1552;
+  const SWord8 s1555 = s1551 ? s1553 : s1554;
+  const SBool  s1556 = sbv_bv_extract_u8_0_0_u1(s1555);
+  const SBool  s1557 = false != s1556;
+  const SWord8 s1558 = sbv_bv_u8_rotr(s1542, 1);
+  const SWord8 s1559 = 128 | s1558;
+  const SWord8 s1560 = 127 & s1558;
+  const SWord8 s1561 = s1557 ? s1559 : s1560;
+  const SBool  s1562 = sbv_bv_extract_u8_0_0_u1(s1561);
+  const SBool  s1563 = false != s1562;
+  const SWord8 s1564 = sbv_bv_u8_rotr(s1545, 1);
+  const SWord8 s1565 = 128 | s1564;
+  const SWord8 s1566 = 127 & s1564;
+  const SWord8 s1567 = s1563 ? s1565 : s1566;
+  const SBool  s1568 = sbv_bv_extract_u8_0_0_u1(s1567);
+  const SBool  s1569 = false != s1568;
+  const SBool  s1570 = !s1569;
+  const SWord8 s1571 = sbv_bv_u8_rotr(s1555, 1);
+  const SWord8 s1572 = 128 | s1571;
+  const SWord8 s1573 = 127 & s1571;
+  const SWord8 s1574 = s20 ? s1572 : s1573;
+  const SBool  s1575 = sbv_bv_extract_u8_0_0_u1(s1574);
+  const SBool  s1576 = false != s1575;
+  const SWord8 s1577 = sbv_bv_u8_rotr(s1561, 1);
+  const SWord8 s1578 = 128 | s1577;
+  const SWord8 s1579 = 127 & s1577;
+  const SWord8 s1580 = s1576 ? s1578 : s1579;
+  const SBool  s1581 = sbv_bv_extract_u8_0_0_u1(s1580);
+  const SBool  s1582 = false != s1581;
+  const SWord8 s1583 = sbv_bv_u8_rotr(s1567, 1);
+  const SWord8 s1584 = 128 | s1583;
+  const SWord8 s1585 = 127 & s1583;
+  const SWord8 s1586 = s1582 ? s1584 : s1585;
+  const SBool  s1587 = sbv_bv_extract_u8_0_0_u1(s1586);
+  const SBool  s1588 = false != s1587;
+  const SBool  s1589 = !s1588;
+  const SWord8 s1590 = sbv_bv_u8_rotr(s1574, 1);
+  const SWord8 s1591 = 128 | s1590;
+  const SWord8 s1592 = 127 & s1590;
+  const SWord8 s1593 = s1036 ? s1591 : s1592;
+  const SWord8 s1594 = sbv_bv_u8_rotr(s1593, 1);
+  const SWord8 s1595 = 128 | s1594;
+  const SWord8 s1596 = 127 & s1594;
+  const SWord8 s1597 = s1547 ? s1595 : s1596;
+  const SWord8 s1598 = sbv_bv_u8_rotr(s1597, 1);
+  const SWord8 s1599 = 128 | s1598;
+  const SWord8 s1600 = 127 & s1598;
+  const SWord8 s1601 = s1569 ? s1599 : s1600;
+  const SWord8 s1602 = sbv_bv_u8_rotr(s1601, 1);
+  const SWord8 s1603 = 128 | s1602;
+  const SWord8 s1604 = 127 & s1602;
+  const SWord8 s1605 = s1588 ? s1603 : s1604;
+  const SWord8 s1606 = sbv_bv_u8_add(s1, s1601);
+  const SBool  s1607 = s1606 < s1;
+  const SBool  s1608 = s1606 < s1601;
+  const SBool  s1609 = s1607 || s1608;
+  const SWord8 s1610 = sbv_bv_u8_rotr(s1606, 1);
+  const SWord8 s1611 = 128 | s1610;
+  const SWord8 s1612 = 127 & s1610;
+  const SWord8 s1613 = s1609 ? s1611 : s1612;
+  const SWord8 s1614 = s1589 ? s1605 : s1613;
+  const SWord8 s1615 = sbv_bv_u8_add(s1, s1597);
+  const SBool  s1616 = s1615 < s1;
+  const SBool  s1617 = s1615 < s1597;
+  const SBool  s1618 = s1616 || s1617;
+  const SWord8 s1619 = sbv_bv_u8_rotr(s1615, 1);
+  const SWord8 s1620 = 128 | s1619;
+  const SWord8 s1621 = 127 & s1619;
+  const SWord8 s1622 = s1618 ? s1620 : s1621;
+  const SWord8 s1623 = sbv_bv_u8_rotr(s1622, 1);
+  const SWord8 s1624 = 128 | s1623;
+  const SWord8 s1625 = 127 & s1623;
+  const SWord8 s1626 = s1588 ? s1624 : s1625;
+  const SWord8 s1627 = sbv_bv_u8_add(s1, s1622);
+  const SBool  s1628 = s1627 < s1;
+  const SBool  s1629 = s1627 < s1622;
+  const SBool  s1630 = s1628 || s1629;
+  const SWord8 s1631 = sbv_bv_u8_rotr(s1627, 1);
+  const SWord8 s1632 = 128 | s1631;
+  const SWord8 s1633 = 127 & s1631;
+  const SWord8 s1634 = s1630 ? s1632 : s1633;
+  const SWord8 s1635 = s1589 ? s1626 : s1634;
+  const SWord8 s1636 = s1570 ? s1614 : s1635;
+  const SWord8 s1637 = sbv_bv_u8_add(s1, s1593);
+  const SBool  s1638 = s1637 < s1;
+  const SBool  s1639 = s1637 < s1593;
+  const SBool  s1640 = s1638 || s1639;
+  const SWord8 s1641 = sbv_bv_u8_rotr(s1637, 1);
+  const SWord8 s1642 = 128 | s1641;
+  const SWord8 s1643 = 127 & s1641;
+  const SWord8 s1644 = s1640 ? s1642 : s1643;
+  const SWord8 s1645 = sbv_bv_u8_rotr(s1644, 1);
+  const SWord8 s1646 = 128 | s1645;
+  const SWord8 s1647 = 127 & s1645;
+  const SWord8 s1648 = s1569 ? s1646 : s1647;
+  const SWord8 s1649 = sbv_bv_u8_rotr(s1648, 1);
+  const SWord8 s1650 = 128 | s1649;
+  const SWord8 s1651 = 127 & s1649;
+  const SWord8 s1652 = s1588 ? s1650 : s1651;
+  const SWord8 s1653 = sbv_bv_u8_add(s1, s1648);
+  const SBool  s1654 = s1653 < s1;
+  const SBool  s1655 = s1653 < s1648;
+  const SBool  s1656 = s1654 || s1655;
+  const SWord8 s1657 = sbv_bv_u8_rotr(s1653, 1);
+  const SWord8 s1658 = 128 | s1657;
+  const SWord8 s1659 = 127 & s1657;
+  const SWord8 s1660 = s1656 ? s1658 : s1659;
+  const SWord8 s1661 = s1589 ? s1652 : s1660;
+  const SWord8 s1662 = sbv_bv_u8_add(s1, s1644);
+  const SBool  s1663 = s1662 < s1;
+  const SBool  s1664 = s1662 < s1644;
+  const SBool  s1665 = s1663 || s1664;
+  const SWord8 s1666 = sbv_bv_u8_rotr(s1662, 1);
+  const SWord8 s1667 = 128 | s1666;
+  const SWord8 s1668 = 127 & s1666;
+  const SWord8 s1669 = s1665 ? s1667 : s1668;
+  const SWord8 s1670 = sbv_bv_u8_rotr(s1669, 1);
+  const SWord8 s1671 = 128 | s1670;
+  const SWord8 s1672 = 127 & s1670;
+  const SWord8 s1673 = s1588 ? s1671 : s1672;
+  const SWord8 s1674 = sbv_bv_u8_add(s1, s1669);
+  const SBool  s1675 = s1674 < s1;
+  const SBool  s1676 = s1674 < s1669;
+  const SBool  s1677 = s1675 || s1676;
+  const SWord8 s1678 = sbv_bv_u8_rotr(s1674, 1);
+  const SWord8 s1679 = 128 | s1678;
+  const SWord8 s1680 = 127 & s1678;
+  const SWord8 s1681 = s1677 ? s1679 : s1680;
+  const SWord8 s1682 = s1589 ? s1673 : s1681;
+  const SWord8 s1683 = s1570 ? s1661 : s1682;
+  const SWord8 s1684 = s1548 ? s1636 : s1683;
+  const SWord8 s1685 = sbv_bv_u8_add(s1, s1574);
+  const SBool  s1686 = sbv_bv_extract_u8_0_0_u1(s1685);
+  const SBool  s1687 = false != s1686;
+  const SWord8 s1688 = s1687 ? s1578 : s1579;
+  const SBool  s1689 = sbv_bv_extract_u8_0_0_u1(s1688);
+  const SBool  s1690 = false != s1689;
+  const SWord8 s1691 = s1690 ? s1584 : s1585;
+  const SBool  s1692 = sbv_bv_extract_u8_0_0_u1(s1691);
+  const SBool  s1693 = false != s1692;
+  const SBool  s1694 = !s1693;
+  const SBool  s1695 = s1685 < s1;
+  const SBool  s1696 = s1685 < s1574;
+  const SBool  s1697 = s1695 || s1696;
+  const SWord8 s1698 = sbv_bv_u8_rotr(s1685, 1);
+  const SWord8 s1699 = 128 | s1698;
+  const SWord8 s1700 = 127 & s1698;
+  const SWord8 s1701 = s1697 ? s1699 : s1700;
+  const SWord8 s1702 = sbv_bv_u8_rotr(s1701, 1);
+  const SWord8 s1703 = 128 | s1702;
+  const SWord8 s1704 = 127 & s1702;
+  const SWord8 s1705 = s1547 ? s1703 : s1704;
+  const SWord8 s1706 = sbv_bv_u8_rotr(s1705, 1);
+  const SWord8 s1707 = 128 | s1706;
+  const SWord8 s1708 = 127 & s1706;
+  const SWord8 s1709 = s1569 ? s1707 : s1708;
+  const SWord8 s1710 = sbv_bv_u8_rotr(s1709, 1);
+  const SWord8 s1711 = 128 | s1710;
+  const SWord8 s1712 = 127 & s1710;
+  const SWord8 s1713 = s1693 ? s1711 : s1712;
+  const SWord8 s1714 = sbv_bv_u8_add(s1, s1709);
+  const SBool  s1715 = s1714 < s1;
+  const SBool  s1716 = s1714 < s1709;
+  const SBool  s1717 = s1715 || s1716;
+  const SWord8 s1718 = sbv_bv_u8_rotr(s1714, 1);
+  const SWord8 s1719 = 128 | s1718;
+  const SWord8 s1720 = 127 & s1718;
+  const SWord8 s1721 = s1717 ? s1719 : s1720;
+  const SWord8 s1722 = s1694 ? s1713 : s1721;
+  const SWord8 s1723 = sbv_bv_u8_add(s1, s1705);
+  const SBool  s1724 = s1723 < s1;
+  const SBool  s1725 = s1723 < s1705;
+  const SBool  s1726 = s1724 || s1725;
+  const SWord8 s1727 = sbv_bv_u8_rotr(s1723, 1);
+  const SWord8 s1728 = 128 | s1727;
+  const SWord8 s1729 = 127 & s1727;
+  const SWord8 s1730 = s1726 ? s1728 : s1729;
+  const SWord8 s1731 = sbv_bv_u8_rotr(s1730, 1);
+  const SWord8 s1732 = 128 | s1731;
+  const SWord8 s1733 = 127 & s1731;
+  const SWord8 s1734 = s1693 ? s1732 : s1733;
+  const SWord8 s1735 = sbv_bv_u8_add(s1, s1730);
+  const SBool  s1736 = s1735 < s1;
+  const SBool  s1737 = s1735 < s1730;
+  const SBool  s1738 = s1736 || s1737;
+  const SWord8 s1739 = sbv_bv_u8_rotr(s1735, 1);
+  const SWord8 s1740 = 128 | s1739;
+  const SWord8 s1741 = 127 & s1739;
+  const SWord8 s1742 = s1738 ? s1740 : s1741;
+  const SWord8 s1743 = s1694 ? s1734 : s1742;
+  const SWord8 s1744 = s1570 ? s1722 : s1743;
+  const SWord8 s1745 = sbv_bv_u8_add(s1, s1701);
+  const SBool  s1746 = s1745 < s1;
+  const SBool  s1747 = s1745 < s1701;
+  const SBool  s1748 = s1746 || s1747;
+  const SWord8 s1749 = sbv_bv_u8_rotr(s1745, 1);
+  const SWord8 s1750 = 128 | s1749;
+  const SWord8 s1751 = 127 & s1749;
+  const SWord8 s1752 = s1748 ? s1750 : s1751;
+  const SWord8 s1753 = sbv_bv_u8_rotr(s1752, 1);
+  const SWord8 s1754 = 128 | s1753;
+  const SWord8 s1755 = 127 & s1753;
+  const SWord8 s1756 = s1569 ? s1754 : s1755;
+  const SWord8 s1757 = sbv_bv_u8_rotr(s1756, 1);
+  const SWord8 s1758 = 128 | s1757;
+  const SWord8 s1759 = 127 & s1757;
+  const SWord8 s1760 = s1693 ? s1758 : s1759;
+  const SWord8 s1761 = sbv_bv_u8_add(s1, s1756);
+  const SBool  s1762 = s1761 < s1;
+  const SBool  s1763 = s1761 < s1756;
+  const SBool  s1764 = s1762 || s1763;
+  const SWord8 s1765 = sbv_bv_u8_rotr(s1761, 1);
+  const SWord8 s1766 = 128 | s1765;
+  const SWord8 s1767 = 127 & s1765;
+  const SWord8 s1768 = s1764 ? s1766 : s1767;
+  const SWord8 s1769 = s1694 ? s1760 : s1768;
+  const SWord8 s1770 = sbv_bv_u8_add(s1, s1752);
+  const SBool  s1771 = s1770 < s1;
+  const SBool  s1772 = s1770 < s1752;
+  const SBool  s1773 = s1771 || s1772;
+  const SWord8 s1774 = sbv_bv_u8_rotr(s1770, 1);
+  const SWord8 s1775 = 128 | s1774;
+  const SWord8 s1776 = 127 & s1774;
+  const SWord8 s1777 = s1773 ? s1775 : s1776;
+  const SWord8 s1778 = sbv_bv_u8_rotr(s1777, 1);
+  const SWord8 s1779 = 128 | s1778;
+  const SWord8 s1780 = 127 & s1778;
+  const SWord8 s1781 = s1693 ? s1779 : s1780;
+  const SWord8 s1782 = sbv_bv_u8_add(s1, s1777);
+  const SBool  s1783 = s1782 < s1;
+  const SBool  s1784 = s1782 < s1777;
+  const SBool  s1785 = s1783 || s1784;
+  const SWord8 s1786 = sbv_bv_u8_rotr(s1782, 1);
+  const SWord8 s1787 = 128 | s1786;
+  const SWord8 s1788 = 127 & s1786;
+  const SWord8 s1789 = s1785 ? s1787 : s1788;
+  const SWord8 s1790 = s1694 ? s1781 : s1789;
+  const SWord8 s1791 = s1570 ? s1769 : s1790;
+  const SWord8 s1792 = s1548 ? s1744 : s1791;
+  const SWord8 s1793 = s1037 ? s1684 : s1792;
+  const SWord8 s1794 = sbv_bv_u8_add(s1, s1555);
+  const SBool  s1795 = sbv_bv_extract_u8_0_0_u1(s1794);
+  const SBool  s1796 = false != s1795;
+  const SWord8 s1797 = s1796 ? s1559 : s1560;
+  const SBool  s1798 = sbv_bv_extract_u8_0_0_u1(s1797);
+  const SBool  s1799 = false != s1798;
+  const SWord8 s1800 = s1799 ? s1565 : s1566;
+  const SBool  s1801 = sbv_bv_extract_u8_0_0_u1(s1800);
+  const SBool  s1802 = false != s1801;
+  const SBool  s1803 = !s1802;
+  const SBool  s1804 = s1794 < s1;
+  const SBool  s1805 = s1794 < s1555;
+  const SBool  s1806 = s1804 || s1805;
+  const SWord8 s1807 = sbv_bv_u8_rotr(s1794, 1);
+  const SWord8 s1808 = 128 | s1807;
+  const SWord8 s1809 = 127 & s1807;
+  const SWord8 s1810 = s1806 ? s1808 : s1809;
+  const SBool  s1811 = sbv_bv_extract_u8_0_0_u1(s1810);
+  const SBool  s1812 = false != s1811;
+  const SWord8 s1813 = sbv_bv_u8_rotr(s1797, 1);
+  const SWord8 s1814 = 128 | s1813;
+  const SWord8 s1815 = 127 & s1813;
+  const SWord8 s1816 = s1812 ? s1814 : s1815;
+  const SBool  s1817 = sbv_bv_extract_u8_0_0_u1(s1816);
+  const SBool  s1818 = false != s1817;
+  const SWord8 s1819 = sbv_bv_u8_rotr(s1800, 1);
+  const SWord8 s1820 = 128 | s1819;
+  const SWord8 s1821 = 127 & s1819;
+  const SWord8 s1822 = s1818 ? s1820 : s1821;
+  const SBool  s1823 = sbv_bv_extract_u8_0_0_u1(s1822);
+  const SBool  s1824 = false != s1823;
+  const SBool  s1825 = !s1824;
+  const SWord8 s1826 = sbv_bv_u8_rotr(s1810, 1);
+  const SWord8 s1827 = 128 | s1826;
+  const SWord8 s1828 = 127 & s1826;
+  const SWord8 s1829 = s1036 ? s1827 : s1828;
+  const SWord8 s1830 = sbv_bv_u8_rotr(s1829, 1);
+  const SWord8 s1831 = 128 | s1830;
+  const SWord8 s1832 = 127 & s1830;
+  const SWord8 s1833 = s1547 ? s1831 : s1832;
+  const SWord8 s1834 = sbv_bv_u8_rotr(s1833, 1);
+  const SWord8 s1835 = 128 | s1834;
+  const SWord8 s1836 = 127 & s1834;
+  const SWord8 s1837 = s1802 ? s1835 : s1836;
+  const SWord8 s1838 = sbv_bv_u8_rotr(s1837, 1);
+  const SWord8 s1839 = 128 | s1838;
+  const SWord8 s1840 = 127 & s1838;
+  const SWord8 s1841 = s1824 ? s1839 : s1840;
+  const SWord8 s1842 = sbv_bv_u8_add(s1, s1837);
+  const SBool  s1843 = s1842 < s1;
+  const SBool  s1844 = s1842 < s1837;
+  const SBool  s1845 = s1843 || s1844;
+  const SWord8 s1846 = sbv_bv_u8_rotr(s1842, 1);
+  const SWord8 s1847 = 128 | s1846;
+  const SWord8 s1848 = 127 & s1846;
+  const SWord8 s1849 = s1845 ? s1847 : s1848;
+  const SWord8 s1850 = s1825 ? s1841 : s1849;
+  const SWord8 s1851 = sbv_bv_u8_add(s1, s1833);
+  const SBool  s1852 = s1851 < s1;
+  const SBool  s1853 = s1851 < s1833;
+  const SBool  s1854 = s1852 || s1853;
+  const SWord8 s1855 = sbv_bv_u8_rotr(s1851, 1);
+  const SWord8 s1856 = 128 | s1855;
+  const SWord8 s1857 = 127 & s1855;
+  const SWord8 s1858 = s1854 ? s1856 : s1857;
+  const SWord8 s1859 = sbv_bv_u8_rotr(s1858, 1);
+  const SWord8 s1860 = 128 | s1859;
+  const SWord8 s1861 = 127 & s1859;
+  const SWord8 s1862 = s1824 ? s1860 : s1861;
+  const SWord8 s1863 = sbv_bv_u8_add(s1, s1858);
+  const SBool  s1864 = s1863 < s1;
+  const SBool  s1865 = s1863 < s1858;
+  const SBool  s1866 = s1864 || s1865;
+  const SWord8 s1867 = sbv_bv_u8_rotr(s1863, 1);
+  const SWord8 s1868 = 128 | s1867;
+  const SWord8 s1869 = 127 & s1867;
+  const SWord8 s1870 = s1866 ? s1868 : s1869;
+  const SWord8 s1871 = s1825 ? s1862 : s1870;
+  const SWord8 s1872 = s1803 ? s1850 : s1871;
+  const SWord8 s1873 = sbv_bv_u8_add(s1, s1829);
+  const SBool  s1874 = s1873 < s1;
+  const SBool  s1875 = s1873 < s1829;
+  const SBool  s1876 = s1874 || s1875;
+  const SWord8 s1877 = sbv_bv_u8_rotr(s1873, 1);
+  const SWord8 s1878 = 128 | s1877;
+  const SWord8 s1879 = 127 & s1877;
+  const SWord8 s1880 = s1876 ? s1878 : s1879;
+  const SWord8 s1881 = sbv_bv_u8_rotr(s1880, 1);
+  const SWord8 s1882 = 128 | s1881;
+  const SWord8 s1883 = 127 & s1881;
+  const SWord8 s1884 = s1802 ? s1882 : s1883;
+  const SWord8 s1885 = sbv_bv_u8_rotr(s1884, 1);
+  const SWord8 s1886 = 128 | s1885;
+  const SWord8 s1887 = 127 & s1885;
+  const SWord8 s1888 = s1824 ? s1886 : s1887;
+  const SWord8 s1889 = sbv_bv_u8_add(s1, s1884);
+  const SBool  s1890 = s1889 < s1;
+  const SBool  s1891 = s1889 < s1884;
+  const SBool  s1892 = s1890 || s1891;
+  const SWord8 s1893 = sbv_bv_u8_rotr(s1889, 1);
+  const SWord8 s1894 = 128 | s1893;
+  const SWord8 s1895 = 127 & s1893;
+  const SWord8 s1896 = s1892 ? s1894 : s1895;
+  const SWord8 s1897 = s1825 ? s1888 : s1896;
+  const SWord8 s1898 = sbv_bv_u8_add(s1, s1880);
+  const SBool  s1899 = s1898 < s1;
+  const SBool  s1900 = s1898 < s1880;
+  const SBool  s1901 = s1899 || s1900;
+  const SWord8 s1902 = sbv_bv_u8_rotr(s1898, 1);
+  const SWord8 s1903 = 128 | s1902;
+  const SWord8 s1904 = 127 & s1902;
+  const SWord8 s1905 = s1901 ? s1903 : s1904;
+  const SWord8 s1906 = sbv_bv_u8_rotr(s1905, 1);
+  const SWord8 s1907 = 128 | s1906;
+  const SWord8 s1908 = 127 & s1906;
+  const SWord8 s1909 = s1824 ? s1907 : s1908;
+  const SWord8 s1910 = sbv_bv_u8_add(s1, s1905);
+  const SBool  s1911 = s1910 < s1;
+  const SBool  s1912 = s1910 < s1905;
+  const SBool  s1913 = s1911 || s1912;
+  const SWord8 s1914 = sbv_bv_u8_rotr(s1910, 1);
+  const SWord8 s1915 = 128 | s1914;
+  const SWord8 s1916 = 127 & s1914;
+  const SWord8 s1917 = s1913 ? s1915 : s1916;
+  const SWord8 s1918 = s1825 ? s1909 : s1917;
+  const SWord8 s1919 = s1803 ? s1897 : s1918;
+  const SWord8 s1920 = s1548 ? s1872 : s1919;
+  const SWord8 s1921 = sbv_bv_u8_add(s1, s1810);
+  const SBool  s1922 = sbv_bv_extract_u8_0_0_u1(s1921);
+  const SBool  s1923 = false != s1922;
+  const SWord8 s1924 = s1923 ? s1814 : s1815;
+  const SBool  s1925 = sbv_bv_extract_u8_0_0_u1(s1924);
+  const SBool  s1926 = false != s1925;
+  const SWord8 s1927 = s1926 ? s1820 : s1821;
+  const SBool  s1928 = sbv_bv_extract_u8_0_0_u1(s1927);
+  const SBool  s1929 = false != s1928;
+  const SBool  s1930 = !s1929;
+  const SBool  s1931 = s1921 < s1;
+  const SBool  s1932 = s1921 < s1810;
+  const SBool  s1933 = s1931 || s1932;
+  const SWord8 s1934 = sbv_bv_u8_rotr(s1921, 1);
+  const SWord8 s1935 = 128 | s1934;
+  const SWord8 s1936 = 127 & s1934;
+  const SWord8 s1937 = s1933 ? s1935 : s1936;
+  const SWord8 s1938 = sbv_bv_u8_rotr(s1937, 1);
+  const SWord8 s1939 = 128 | s1938;
+  const SWord8 s1940 = 127 & s1938;
+  const SWord8 s1941 = s1547 ? s1939 : s1940;
+  const SWord8 s1942 = sbv_bv_u8_rotr(s1941, 1);
+  const SWord8 s1943 = 128 | s1942;
+  const SWord8 s1944 = 127 & s1942;
+  const SWord8 s1945 = s1802 ? s1943 : s1944;
+  const SWord8 s1946 = sbv_bv_u8_rotr(s1945, 1);
+  const SWord8 s1947 = 128 | s1946;
+  const SWord8 s1948 = 127 & s1946;
+  const SWord8 s1949 = s1929 ? s1947 : s1948;
+  const SWord8 s1950 = sbv_bv_u8_add(s1, s1945);
+  const SBool  s1951 = s1950 < s1;
+  const SBool  s1952 = s1950 < s1945;
+  const SBool  s1953 = s1951 || s1952;
+  const SWord8 s1954 = sbv_bv_u8_rotr(s1950, 1);
+  const SWord8 s1955 = 128 | s1954;
+  const SWord8 s1956 = 127 & s1954;
+  const SWord8 s1957 = s1953 ? s1955 : s1956;
+  const SWord8 s1958 = s1930 ? s1949 : s1957;
+  const SWord8 s1959 = sbv_bv_u8_add(s1, s1941);
+  const SBool  s1960 = s1959 < s1;
+  const SBool  s1961 = s1959 < s1941;
+  const SBool  s1962 = s1960 || s1961;
+  const SWord8 s1963 = sbv_bv_u8_rotr(s1959, 1);
+  const SWord8 s1964 = 128 | s1963;
+  const SWord8 s1965 = 127 & s1963;
+  const SWord8 s1966 = s1962 ? s1964 : s1965;
+  const SWord8 s1967 = sbv_bv_u8_rotr(s1966, 1);
+  const SWord8 s1968 = 128 | s1967;
+  const SWord8 s1969 = 127 & s1967;
+  const SWord8 s1970 = s1929 ? s1968 : s1969;
+  const SWord8 s1971 = sbv_bv_u8_add(s1, s1966);
+  const SBool  s1972 = s1971 < s1;
+  const SBool  s1973 = s1971 < s1966;
+  const SBool  s1974 = s1972 || s1973;
+  const SWord8 s1975 = sbv_bv_u8_rotr(s1971, 1);
+  const SWord8 s1976 = 128 | s1975;
+  const SWord8 s1977 = 127 & s1975;
+  const SWord8 s1978 = s1974 ? s1976 : s1977;
+  const SWord8 s1979 = s1930 ? s1970 : s1978;
+  const SWord8 s1980 = s1803 ? s1958 : s1979;
+  const SWord8 s1981 = sbv_bv_u8_add(s1, s1937);
+  const SBool  s1982 = s1981 < s1;
+  const SBool  s1983 = s1981 < s1937;
+  const SBool  s1984 = s1982 || s1983;
+  const SWord8 s1985 = sbv_bv_u8_rotr(s1981, 1);
+  const SWord8 s1986 = 128 | s1985;
+  const SWord8 s1987 = 127 & s1985;
+  const SWord8 s1988 = s1984 ? s1986 : s1987;
+  const SWord8 s1989 = sbv_bv_u8_rotr(s1988, 1);
+  const SWord8 s1990 = 128 | s1989;
+  const SWord8 s1991 = 127 & s1989;
+  const SWord8 s1992 = s1802 ? s1990 : s1991;
+  const SWord8 s1993 = sbv_bv_u8_rotr(s1992, 1);
+  const SWord8 s1994 = 128 | s1993;
+  const SWord8 s1995 = 127 & s1993;
+  const SWord8 s1996 = s1929 ? s1994 : s1995;
+  const SWord8 s1997 = sbv_bv_u8_add(s1, s1992);
+  const SBool  s1998 = s1997 < s1;
+  const SBool  s1999 = s1997 < s1992;
+  const SBool  s2000 = s1998 || s1999;
+  const SWord8 s2001 = sbv_bv_u8_rotr(s1997, 1);
+  const SWord8 s2002 = 128 | s2001;
+  const SWord8 s2003 = 127 & s2001;
+  const SWord8 s2004 = s2000 ? s2002 : s2003;
+  const SWord8 s2005 = s1930 ? s1996 : s2004;
+  const SWord8 s2006 = sbv_bv_u8_add(s1, s1988);
+  const SBool  s2007 = s2006 < s1;
+  const SBool  s2008 = s2006 < s1988;
+  const SBool  s2009 = s2007 || s2008;
+  const SWord8 s2010 = sbv_bv_u8_rotr(s2006, 1);
+  const SWord8 s2011 = 128 | s2010;
+  const SWord8 s2012 = 127 & s2010;
+  const SWord8 s2013 = s2009 ? s2011 : s2012;
+  const SWord8 s2014 = sbv_bv_u8_rotr(s2013, 1);
+  const SWord8 s2015 = 128 | s2014;
+  const SWord8 s2016 = 127 & s2014;
+  const SWord8 s2017 = s1929 ? s2015 : s2016;
+  const SWord8 s2018 = sbv_bv_u8_add(s1, s2013);
+  const SBool  s2019 = s2018 < s1;
+  const SBool  s2020 = s2018 < s2013;
+  const SBool  s2021 = s2019 || s2020;
+  const SWord8 s2022 = sbv_bv_u8_rotr(s2018, 1);
+  const SWord8 s2023 = 128 | s2022;
+  const SWord8 s2024 = 127 & s2022;
+  const SWord8 s2025 = s2021 ? s2023 : s2024;
+  const SWord8 s2026 = s1930 ? s2017 : s2025;
+  const SWord8 s2027 = s1803 ? s2005 : s2026;
+  const SWord8 s2028 = s1548 ? s1980 : s2027;
+  const SWord8 s2029 = s1037 ? s1920 : s2028;
+  const SWord8 s2030 = s21 ? s1793 : s2029;
+  const SWord8 s2031 = s16 ? s1538 : s2030;
+  const SWord8 s2032 = s11 ? s1027 : s2031;
+  const SBool  s2033 = sbv_bv_extract_u8_0_0_u1(s1);
+  const SBool  s2034 = false != s2033;
+  const SWord8 s2035 = s2034 ? 128 : 0;
+  const SBool  s2036 = sbv_bv_extract_u8_0_0_u1(s2035);
+  const SBool  s2037 = false != s2036;
+  const SWord8 s2038 = s17 | 128;
+  const SWord8 s2039 = s2037 ? s2038 : s18;
+  const SBool  s2040 = sbv_bv_extract_u8_0_0_u1(s2039);
+  const SBool  s2041 = false != s2040;
+  const SBool  s2042 = !s2041;
+  const SWord8 s2043 = sbv_bv_u8_rotr(s1, 1);
+  const SWord8 s2044 = 127 & s2043;
+  const SBool  s2045 = sbv_bv_extract_u8_0_0_u1(s2044);
+  const SBool  s2046 = false != s2045;
+  const SWord8 s2047 = sbv_bv_u8_rotr(s2035, 1);
+  const SWord8 s2048 = 128 | s2047;
+  const SWord8 s2049 = 127 & s2047;
+  const SWord8 s2050 = s2046 ? s2048 : s2049;
+  const SBool  s2051 = sbv_bv_extract_u8_0_0_u1(s2050);
+  const SBool  s2052 = false != s2051;
+  const SWord8 s2053 = sbv_bv_u8_rotr(s2039, 1);
+  const SWord8 s2054 = 128 | s2053;
+  const SWord8 s2055 = 127 & s2053;
+  const SWord8 s2056 = s2052 ? s2054 : s2055;
+  const SBool  s2057 = sbv_bv_extract_u8_0_0_u1(s2056);
+  const SBool  s2058 = false != s2057;
+  const SBool  s2059 = !s2058;
+  const SWord8 s2060 = sbv_bv_u8_rotr(s2044, 1);
+  const SWord8 s2061 = 128 | s2060;
+  const SWord8 s2062 = 127 & s2060;
+  const SWord8 s2063 = s10 ? s2061 : s2062;
+  const SBool  s2064 = sbv_bv_extract_u8_0_0_u1(s2063);
+  const SBool  s2065 = false != s2064;
+  const SWord8 s2066 = sbv_bv_u8_rotr(s2050, 1);
+  const SWord8 s2067 = 128 | s2066;
+  const SWord8 s2068 = 127 & s2066;
+  const SWord8 s2069 = s2065 ? s2067 : s2068;
+  const SBool  s2070 = sbv_bv_extract_u8_0_0_u1(s2069);
+  const SBool  s2071 = false != s2070;
+  const SWord8 s2072 = sbv_bv_u8_rotr(s2056, 1);
+  const SWord8 s2073 = 128 | s2072;
+  const SWord8 s2074 = 127 & s2072;
+  const SWord8 s2075 = s2071 ? s2073 : s2074;
+  const SBool  s2076 = sbv_bv_extract_u8_0_0_u1(s2075);
+  const SBool  s2077 = false != s2076;
+  const SBool  s2078 = !s2077;
+  const SWord8 s2079 = sbv_bv_u8_rotr(s2063, 1);
+  const SWord8 s2080 = 128 | s2079;
+  const SWord8 s2081 = 127 & s2079;
+  const SWord8 s2082 = s15 ? s2080 : s2081;
+  const SBool  s2083 = sbv_bv_extract_u8_0_0_u1(s2082);
+  const SBool  s2084 = false != s2083;
+  const SWord8 s2085 = sbv_bv_u8_rotr(s2069, 1);
+  const SWord8 s2086 = 128 | s2085;
+  const SWord8 s2087 = 127 & s2085;
+  const SWord8 s2088 = s2084 ? s2086 : s2087;
+  const SBool  s2089 = sbv_bv_extract_u8_0_0_u1(s2088);
+  const SBool  s2090 = false != s2089;
+  const SWord8 s2091 = sbv_bv_u8_rotr(s2075, 1);
+  const SWord8 s2092 = 128 | s2091;
+  const SWord8 s2093 = 127 & s2091;
+  const SWord8 s2094 = s2090 ? s2092 : s2093;
+  const SBool  s2095 = sbv_bv_extract_u8_0_0_u1(s2094);
+  const SBool  s2096 = false != s2095;
+  const SBool  s2097 = !s2096;
+  const SWord8 s2098 = sbv_bv_u8_rotr(s2082, 1);
+  const SWord8 s2099 = 128 | s2098;
+  const SWord8 s2100 = 127 & s2098;
+  const SWord8 s2101 = s2041 ? s2099 : s2100;
+  const SBool  s2102 = sbv_bv_extract_u8_0_0_u1(s2101);
+  const SBool  s2103 = false != s2102;
+  const SWord8 s2104 = sbv_bv_u8_rotr(s2088, 1);
+  const SWord8 s2105 = 128 | s2104;
+  const SWord8 s2106 = 127 & s2104;
+  const SWord8 s2107 = s2103 ? s2105 : s2106;
+  const SBool  s2108 = sbv_bv_extract_u8_0_0_u1(s2107);
+  const SBool  s2109 = false != s2108;
+  const SWord8 s2110 = sbv_bv_u8_rotr(s2094, 1);
+  const SWord8 s2111 = 128 | s2110;
+  const SWord8 s2112 = 127 & s2110;
+  const SWord8 s2113 = s2109 ? s2111 : s2112;
+  const SBool  s2114 = sbv_bv_extract_u8_0_0_u1(s2113);
+  const SBool  s2115 = false != s2114;
+  const SBool  s2116 = !s2115;
+  const SWord8 s2117 = sbv_bv_u8_rotr(s2101, 1);
+  const SWord8 s2118 = 128 | s2117;
+  const SWord8 s2119 = 127 & s2117;
+  const SWord8 s2120 = s2058 ? s2118 : s2119;
+  const SWord8 s2121 = sbv_bv_u8_rotr(s2120, 1);
+  const SWord8 s2122 = 128 | s2121;
+  const SWord8 s2123 = 127 & s2121;
+  const SWord8 s2124 = s2077 ? s2122 : s2123;
+  const SWord8 s2125 = sbv_bv_u8_rotr(s2124, 1);
+  const SWord8 s2126 = 128 | s2125;
+  const SWord8 s2127 = 127 & s2125;
+  const SWord8 s2128 = s2096 ? s2126 : s2127;
+  const SWord8 s2129 = sbv_bv_u8_rotr(s2128, 1);
+  const SWord8 s2130 = 128 | s2129;
+  const SWord8 s2131 = 127 & s2129;
+  const SWord8 s2132 = s2115 ? s2130 : s2131;
+  const SWord8 s2133 = sbv_bv_u8_add(s1, s2128);
+  const SBool  s2134 = s2133 < s1;
+  const SBool  s2135 = s2133 < s2128;
+  const SBool  s2136 = s2134 || s2135;
+  const SWord8 s2137 = sbv_bv_u8_rotr(s2133, 1);
+  const SWord8 s2138 = 128 | s2137;
+  const SWord8 s2139 = 127 & s2137;
+  const SWord8 s2140 = s2136 ? s2138 : s2139;
+  const SWord8 s2141 = s2116 ? s2132 : s2140;
+  const SWord8 s2142 = sbv_bv_u8_add(s1, s2124);
+  const SBool  s2143 = s2142 < s1;
+  const SBool  s2144 = s2142 < s2124;
+  const SBool  s2145 = s2143 || s2144;
+  const SWord8 s2146 = sbv_bv_u8_rotr(s2142, 1);
+  const SWord8 s2147 = 128 | s2146;
+  const SWord8 s2148 = 127 & s2146;
+  const SWord8 s2149 = s2145 ? s2147 : s2148;
+  const SWord8 s2150 = sbv_bv_u8_rotr(s2149, 1);
+  const SWord8 s2151 = 128 | s2150;
+  const SWord8 s2152 = 127 & s2150;
+  const SWord8 s2153 = s2115 ? s2151 : s2152;
+  const SWord8 s2154 = sbv_bv_u8_add(s1, s2149);
+  const SBool  s2155 = s2154 < s1;
+  const SBool  s2156 = s2154 < s2149;
+  const SBool  s2157 = s2155 || s2156;
+  const SWord8 s2158 = sbv_bv_u8_rotr(s2154, 1);
+  const SWord8 s2159 = 128 | s2158;
+  const SWord8 s2160 = 127 & s2158;
+  const SWord8 s2161 = s2157 ? s2159 : s2160;
+  const SWord8 s2162 = s2116 ? s2153 : s2161;
+  const SWord8 s2163 = s2097 ? s2141 : s2162;
+  const SWord8 s2164 = sbv_bv_u8_add(s1, s2120);
+  const SBool  s2165 = s2164 < s1;
+  const SBool  s2166 = s2164 < s2120;
+  const SBool  s2167 = s2165 || s2166;
+  const SWord8 s2168 = sbv_bv_u8_rotr(s2164, 1);
+  const SWord8 s2169 = 128 | s2168;
+  const SWord8 s2170 = 127 & s2168;
+  const SWord8 s2171 = s2167 ? s2169 : s2170;
+  const SWord8 s2172 = sbv_bv_u8_rotr(s2171, 1);
+  const SWord8 s2173 = 128 | s2172;
+  const SWord8 s2174 = 127 & s2172;
+  const SWord8 s2175 = s2096 ? s2173 : s2174;
+  const SWord8 s2176 = sbv_bv_u8_rotr(s2175, 1);
+  const SWord8 s2177 = 128 | s2176;
+  const SWord8 s2178 = 127 & s2176;
+  const SWord8 s2179 = s2115 ? s2177 : s2178;
+  const SWord8 s2180 = sbv_bv_u8_add(s1, s2175);
+  const SBool  s2181 = s2180 < s1;
+  const SBool  s2182 = s2180 < s2175;
+  const SBool  s2183 = s2181 || s2182;
+  const SWord8 s2184 = sbv_bv_u8_rotr(s2180, 1);
+  const SWord8 s2185 = 128 | s2184;
+  const SWord8 s2186 = 127 & s2184;
+  const SWord8 s2187 = s2183 ? s2185 : s2186;
+  const SWord8 s2188 = s2116 ? s2179 : s2187;
+  const SWord8 s2189 = sbv_bv_u8_add(s1, s2171);
+  const SBool  s2190 = s2189 < s1;
+  const SBool  s2191 = s2189 < s2171;
+  const SBool  s2192 = s2190 || s2191;
+  const SWord8 s2193 = sbv_bv_u8_rotr(s2189, 1);
+  const SWord8 s2194 = 128 | s2193;
+  const SWord8 s2195 = 127 & s2193;
+  const SWord8 s2196 = s2192 ? s2194 : s2195;
+  const SWord8 s2197 = sbv_bv_u8_rotr(s2196, 1);
+  const SWord8 s2198 = 128 | s2197;
+  const SWord8 s2199 = 127 & s2197;
+  const SWord8 s2200 = s2115 ? s2198 : s2199;
+  const SWord8 s2201 = sbv_bv_u8_add(s1, s2196);
+  const SBool  s2202 = s2201 < s1;
+  const SBool  s2203 = s2201 < s2196;
+  const SBool  s2204 = s2202 || s2203;
+  const SWord8 s2205 = sbv_bv_u8_rotr(s2201, 1);
+  const SWord8 s2206 = 128 | s2205;
+  const SWord8 s2207 = 127 & s2205;
+  const SWord8 s2208 = s2204 ? s2206 : s2207;
+  const SWord8 s2209 = s2116 ? s2200 : s2208;
+  const SWord8 s2210 = s2097 ? s2188 : s2209;
+  const SWord8 s2211 = s2078 ? s2163 : s2210;
+  const SWord8 s2212 = sbv_bv_u8_add(s1, s2101);
+  const SBool  s2213 = sbv_bv_extract_u8_0_0_u1(s2212);
+  const SBool  s2214 = false != s2213;
+  const SWord8 s2215 = s2214 ? s2105 : s2106;
+  const SBool  s2216 = sbv_bv_extract_u8_0_0_u1(s2215);
+  const SBool  s2217 = false != s2216;
+  const SWord8 s2218 = s2217 ? s2111 : s2112;
+  const SBool  s2219 = sbv_bv_extract_u8_0_0_u1(s2218);
+  const SBool  s2220 = false != s2219;
+  const SBool  s2221 = !s2220;
+  const SBool  s2222 = s2212 < s1;
+  const SBool  s2223 = s2212 < s2101;
+  const SBool  s2224 = s2222 || s2223;
+  const SWord8 s2225 = sbv_bv_u8_rotr(s2212, 1);
+  const SWord8 s2226 = 128 | s2225;
+  const SWord8 s2227 = 127 & s2225;
+  const SWord8 s2228 = s2224 ? s2226 : s2227;
+  const SWord8 s2229 = sbv_bv_u8_rotr(s2228, 1);
+  const SWord8 s2230 = 128 | s2229;
+  const SWord8 s2231 = 127 & s2229;
+  const SWord8 s2232 = s2077 ? s2230 : s2231;
+  const SWord8 s2233 = sbv_bv_u8_rotr(s2232, 1);
+  const SWord8 s2234 = 128 | s2233;
+  const SWord8 s2235 = 127 & s2233;
+  const SWord8 s2236 = s2096 ? s2234 : s2235;
+  const SWord8 s2237 = sbv_bv_u8_rotr(s2236, 1);
+  const SWord8 s2238 = 128 | s2237;
+  const SWord8 s2239 = 127 & s2237;
+  const SWord8 s2240 = s2220 ? s2238 : s2239;
+  const SWord8 s2241 = sbv_bv_u8_add(s1, s2236);
+  const SBool  s2242 = s2241 < s1;
+  const SBool  s2243 = s2241 < s2236;
+  const SBool  s2244 = s2242 || s2243;
+  const SWord8 s2245 = sbv_bv_u8_rotr(s2241, 1);
+  const SWord8 s2246 = 128 | s2245;
+  const SWord8 s2247 = 127 & s2245;
+  const SWord8 s2248 = s2244 ? s2246 : s2247;
+  const SWord8 s2249 = s2221 ? s2240 : s2248;
+  const SWord8 s2250 = sbv_bv_u8_add(s1, s2232);
+  const SBool  s2251 = s2250 < s1;
+  const SBool  s2252 = s2250 < s2232;
+  const SBool  s2253 = s2251 || s2252;
+  const SWord8 s2254 = sbv_bv_u8_rotr(s2250, 1);
+  const SWord8 s2255 = 128 | s2254;
+  const SWord8 s2256 = 127 & s2254;
+  const SWord8 s2257 = s2253 ? s2255 : s2256;
+  const SWord8 s2258 = sbv_bv_u8_rotr(s2257, 1);
+  const SWord8 s2259 = 128 | s2258;
+  const SWord8 s2260 = 127 & s2258;
+  const SWord8 s2261 = s2220 ? s2259 : s2260;
+  const SWord8 s2262 = sbv_bv_u8_add(s1, s2257);
+  const SBool  s2263 = s2262 < s1;
+  const SBool  s2264 = s2262 < s2257;
+  const SBool  s2265 = s2263 || s2264;
+  const SWord8 s2266 = sbv_bv_u8_rotr(s2262, 1);
+  const SWord8 s2267 = 128 | s2266;
+  const SWord8 s2268 = 127 & s2266;
+  const SWord8 s2269 = s2265 ? s2267 : s2268;
+  const SWord8 s2270 = s2221 ? s2261 : s2269;
+  const SWord8 s2271 = s2097 ? s2249 : s2270;
+  const SWord8 s2272 = sbv_bv_u8_add(s1, s2228);
+  const SBool  s2273 = s2272 < s1;
+  const SBool  s2274 = s2272 < s2228;
+  const SBool  s2275 = s2273 || s2274;
+  const SWord8 s2276 = sbv_bv_u8_rotr(s2272, 1);
+  const SWord8 s2277 = 128 | s2276;
+  const SWord8 s2278 = 127 & s2276;
+  const SWord8 s2279 = s2275 ? s2277 : s2278;
+  const SWord8 s2280 = sbv_bv_u8_rotr(s2279, 1);
+  const SWord8 s2281 = 128 | s2280;
+  const SWord8 s2282 = 127 & s2280;
+  const SWord8 s2283 = s2096 ? s2281 : s2282;
+  const SWord8 s2284 = sbv_bv_u8_rotr(s2283, 1);
+  const SWord8 s2285 = 128 | s2284;
+  const SWord8 s2286 = 127 & s2284;
+  const SWord8 s2287 = s2220 ? s2285 : s2286;
+  const SWord8 s2288 = sbv_bv_u8_add(s1, s2283);
+  const SBool  s2289 = s2288 < s1;
+  const SBool  s2290 = s2288 < s2283;
+  const SBool  s2291 = s2289 || s2290;
+  const SWord8 s2292 = sbv_bv_u8_rotr(s2288, 1);
+  const SWord8 s2293 = 128 | s2292;
+  const SWord8 s2294 = 127 & s2292;
+  const SWord8 s2295 = s2291 ? s2293 : s2294;
+  const SWord8 s2296 = s2221 ? s2287 : s2295;
+  const SWord8 s2297 = sbv_bv_u8_add(s1, s2279);
+  const SBool  s2298 = s2297 < s1;
+  const SBool  s2299 = s2297 < s2279;
+  const SBool  s2300 = s2298 || s2299;
+  const SWord8 s2301 = sbv_bv_u8_rotr(s2297, 1);
+  const SWord8 s2302 = 128 | s2301;
+  const SWord8 s2303 = 127 & s2301;
+  const SWord8 s2304 = s2300 ? s2302 : s2303;
+  const SWord8 s2305 = sbv_bv_u8_rotr(s2304, 1);
+  const SWord8 s2306 = 128 | s2305;
+  const SWord8 s2307 = 127 & s2305;
+  const SWord8 s2308 = s2220 ? s2306 : s2307;
+  const SWord8 s2309 = sbv_bv_u8_add(s1, s2304);
+  const SBool  s2310 = s2309 < s1;
+  const SBool  s2311 = s2309 < s2304;
+  const SBool  s2312 = s2310 || s2311;
+  const SWord8 s2313 = sbv_bv_u8_rotr(s2309, 1);
+  const SWord8 s2314 = 128 | s2313;
+  const SWord8 s2315 = 127 & s2313;
+  const SWord8 s2316 = s2312 ? s2314 : s2315;
+  const SWord8 s2317 = s2221 ? s2308 : s2316;
+  const SWord8 s2318 = s2097 ? s2296 : s2317;
+  const SWord8 s2319 = s2078 ? s2271 : s2318;
+  const SWord8 s2320 = s2059 ? s2211 : s2319;
+  const SWord8 s2321 = sbv_bv_u8_add(s1, s2082);
+  const SBool  s2322 = sbv_bv_extract_u8_0_0_u1(s2321);
+  const SBool  s2323 = false != s2322;
+  const SWord8 s2324 = s2323 ? s2086 : s2087;
+  const SBool  s2325 = sbv_bv_extract_u8_0_0_u1(s2324);
+  const SBool  s2326 = false != s2325;
+  const SWord8 s2327 = s2326 ? s2092 : s2093;
+  const SBool  s2328 = sbv_bv_extract_u8_0_0_u1(s2327);
+  const SBool  s2329 = false != s2328;
+  const SBool  s2330 = !s2329;
+  const SBool  s2331 = s2321 < s1;
+  const SBool  s2332 = s2321 < s2082;
+  const SBool  s2333 = s2331 || s2332;
+  const SWord8 s2334 = sbv_bv_u8_rotr(s2321, 1);
+  const SWord8 s2335 = 128 | s2334;
+  const SWord8 s2336 = 127 & s2334;
+  const SWord8 s2337 = s2333 ? s2335 : s2336;
+  const SBool  s2338 = sbv_bv_extract_u8_0_0_u1(s2337);
+  const SBool  s2339 = false != s2338;
+  const SWord8 s2340 = sbv_bv_u8_rotr(s2324, 1);
+  const SWord8 s2341 = 128 | s2340;
+  const SWord8 s2342 = 127 & s2340;
+  const SWord8 s2343 = s2339 ? s2341 : s2342;
+  const SBool  s2344 = sbv_bv_extract_u8_0_0_u1(s2343);
+  const SBool  s2345 = false != s2344;
+  const SWord8 s2346 = sbv_bv_u8_rotr(s2327, 1);
+  const SWord8 s2347 = 128 | s2346;
+  const SWord8 s2348 = 127 & s2346;
+  const SWord8 s2349 = s2345 ? s2347 : s2348;
+  const SBool  s2350 = sbv_bv_extract_u8_0_0_u1(s2349);
+  const SBool  s2351 = false != s2350;
+  const SBool  s2352 = !s2351;
+  const SWord8 s2353 = sbv_bv_u8_rotr(s2337, 1);
+  const SWord8 s2354 = 128 | s2353;
+  const SWord8 s2355 = 127 & s2353;
+  const SWord8 s2356 = s2058 ? s2354 : s2355;
+  const SWord8 s2357 = sbv_bv_u8_rotr(s2356, 1);
+  const SWord8 s2358 = 128 | s2357;
+  const SWord8 s2359 = 127 & s2357;
+  const SWord8 s2360 = s2077 ? s2358 : s2359;
+  const SWord8 s2361 = sbv_bv_u8_rotr(s2360, 1);
+  const SWord8 s2362 = 128 | s2361;
+  const SWord8 s2363 = 127 & s2361;
+  const SWord8 s2364 = s2329 ? s2362 : s2363;
+  const SWord8 s2365 = sbv_bv_u8_rotr(s2364, 1);
+  const SWord8 s2366 = 128 | s2365;
+  const SWord8 s2367 = 127 & s2365;
+  const SWord8 s2368 = s2351 ? s2366 : s2367;
+  const SWord8 s2369 = sbv_bv_u8_add(s1, s2364);
+  const SBool  s2370 = s2369 < s1;
+  const SBool  s2371 = s2369 < s2364;
+  const SBool  s2372 = s2370 || s2371;
+  const SWord8 s2373 = sbv_bv_u8_rotr(s2369, 1);
+  const SWord8 s2374 = 128 | s2373;
+  const SWord8 s2375 = 127 & s2373;
+  const SWord8 s2376 = s2372 ? s2374 : s2375;
+  const SWord8 s2377 = s2352 ? s2368 : s2376;
+  const SWord8 s2378 = sbv_bv_u8_add(s1, s2360);
+  const SBool  s2379 = s2378 < s1;
+  const SBool  s2380 = s2378 < s2360;
+  const SBool  s2381 = s2379 || s2380;
+  const SWord8 s2382 = sbv_bv_u8_rotr(s2378, 1);
+  const SWord8 s2383 = 128 | s2382;
+  const SWord8 s2384 = 127 & s2382;
+  const SWord8 s2385 = s2381 ? s2383 : s2384;
+  const SWord8 s2386 = sbv_bv_u8_rotr(s2385, 1);
+  const SWord8 s2387 = 128 | s2386;
+  const SWord8 s2388 = 127 & s2386;
+  const SWord8 s2389 = s2351 ? s2387 : s2388;
+  const SWord8 s2390 = sbv_bv_u8_add(s1, s2385);
+  const SBool  s2391 = s2390 < s1;
+  const SBool  s2392 = s2390 < s2385;
+  const SBool  s2393 = s2391 || s2392;
+  const SWord8 s2394 = sbv_bv_u8_rotr(s2390, 1);
+  const SWord8 s2395 = 128 | s2394;
+  const SWord8 s2396 = 127 & s2394;
+  const SWord8 s2397 = s2393 ? s2395 : s2396;
+  const SWord8 s2398 = s2352 ? s2389 : s2397;
+  const SWord8 s2399 = s2330 ? s2377 : s2398;
+  const SWord8 s2400 = sbv_bv_u8_add(s1, s2356);
+  const SBool  s2401 = s2400 < s1;
+  const SBool  s2402 = s2400 < s2356;
+  const SBool  s2403 = s2401 || s2402;
+  const SWord8 s2404 = sbv_bv_u8_rotr(s2400, 1);
+  const SWord8 s2405 = 128 | s2404;
+  const SWord8 s2406 = 127 & s2404;
+  const SWord8 s2407 = s2403 ? s2405 : s2406;
+  const SWord8 s2408 = sbv_bv_u8_rotr(s2407, 1);
+  const SWord8 s2409 = 128 | s2408;
+  const SWord8 s2410 = 127 & s2408;
+  const SWord8 s2411 = s2329 ? s2409 : s2410;
+  const SWord8 s2412 = sbv_bv_u8_rotr(s2411, 1);
+  const SWord8 s2413 = 128 | s2412;
+  const SWord8 s2414 = 127 & s2412;
+  const SWord8 s2415 = s2351 ? s2413 : s2414;
+  const SWord8 s2416 = sbv_bv_u8_add(s1, s2411);
+  const SBool  s2417 = s2416 < s1;
+  const SBool  s2418 = s2416 < s2411;
+  const SBool  s2419 = s2417 || s2418;
+  const SWord8 s2420 = sbv_bv_u8_rotr(s2416, 1);
+  const SWord8 s2421 = 128 | s2420;
+  const SWord8 s2422 = 127 & s2420;
+  const SWord8 s2423 = s2419 ? s2421 : s2422;
+  const SWord8 s2424 = s2352 ? s2415 : s2423;
+  const SWord8 s2425 = sbv_bv_u8_add(s1, s2407);
+  const SBool  s2426 = s2425 < s1;
+  const SBool  s2427 = s2425 < s2407;
+  const SBool  s2428 = s2426 || s2427;
+  const SWord8 s2429 = sbv_bv_u8_rotr(s2425, 1);
+  const SWord8 s2430 = 128 | s2429;
+  const SWord8 s2431 = 127 & s2429;
+  const SWord8 s2432 = s2428 ? s2430 : s2431;
+  const SWord8 s2433 = sbv_bv_u8_rotr(s2432, 1);
+  const SWord8 s2434 = 128 | s2433;
+  const SWord8 s2435 = 127 & s2433;
+  const SWord8 s2436 = s2351 ? s2434 : s2435;
+  const SWord8 s2437 = sbv_bv_u8_add(s1, s2432);
+  const SBool  s2438 = s2437 < s1;
+  const SBool  s2439 = s2437 < s2432;
+  const SBool  s2440 = s2438 || s2439;
+  const SWord8 s2441 = sbv_bv_u8_rotr(s2437, 1);
+  const SWord8 s2442 = 128 | s2441;
+  const SWord8 s2443 = 127 & s2441;
+  const SWord8 s2444 = s2440 ? s2442 : s2443;
+  const SWord8 s2445 = s2352 ? s2436 : s2444;
+  const SWord8 s2446 = s2330 ? s2424 : s2445;
+  const SWord8 s2447 = s2078 ? s2399 : s2446;
+  const SWord8 s2448 = sbv_bv_u8_add(s1, s2337);
+  const SBool  s2449 = sbv_bv_extract_u8_0_0_u1(s2448);
+  const SBool  s2450 = false != s2449;
+  const SWord8 s2451 = s2450 ? s2341 : s2342;
+  const SBool  s2452 = sbv_bv_extract_u8_0_0_u1(s2451);
+  const SBool  s2453 = false != s2452;
+  const SWord8 s2454 = s2453 ? s2347 : s2348;
+  const SBool  s2455 = sbv_bv_extract_u8_0_0_u1(s2454);
+  const SBool  s2456 = false != s2455;
+  const SBool  s2457 = !s2456;
+  const SBool  s2458 = s2448 < s1;
+  const SBool  s2459 = s2448 < s2337;
+  const SBool  s2460 = s2458 || s2459;
+  const SWord8 s2461 = sbv_bv_u8_rotr(s2448, 1);
+  const SWord8 s2462 = 128 | s2461;
+  const SWord8 s2463 = 127 & s2461;
+  const SWord8 s2464 = s2460 ? s2462 : s2463;
+  const SWord8 s2465 = sbv_bv_u8_rotr(s2464, 1);
+  const SWord8 s2466 = 128 | s2465;
+  const SWord8 s2467 = 127 & s2465;
+  const SWord8 s2468 = s2077 ? s2466 : s2467;
+  const SWord8 s2469 = sbv_bv_u8_rotr(s2468, 1);
+  const SWord8 s2470 = 128 | s2469;
+  const SWord8 s2471 = 127 & s2469;
+  const SWord8 s2472 = s2329 ? s2470 : s2471;
+  const SWord8 s2473 = sbv_bv_u8_rotr(s2472, 1);
+  const SWord8 s2474 = 128 | s2473;
+  const SWord8 s2475 = 127 & s2473;
+  const SWord8 s2476 = s2456 ? s2474 : s2475;
+  const SWord8 s2477 = sbv_bv_u8_add(s1, s2472);
+  const SBool  s2478 = s2477 < s1;
+  const SBool  s2479 = s2477 < s2472;
+  const SBool  s2480 = s2478 || s2479;
+  const SWord8 s2481 = sbv_bv_u8_rotr(s2477, 1);
+  const SWord8 s2482 = 128 | s2481;
+  const SWord8 s2483 = 127 & s2481;
+  const SWord8 s2484 = s2480 ? s2482 : s2483;
+  const SWord8 s2485 = s2457 ? s2476 : s2484;
+  const SWord8 s2486 = sbv_bv_u8_add(s1, s2468);
+  const SBool  s2487 = s2486 < s1;
+  const SBool  s2488 = s2486 < s2468;
+  const SBool  s2489 = s2487 || s2488;
+  const SWord8 s2490 = sbv_bv_u8_rotr(s2486, 1);
+  const SWord8 s2491 = 128 | s2490;
+  const SWord8 s2492 = 127 & s2490;
+  const SWord8 s2493 = s2489 ? s2491 : s2492;
+  const SWord8 s2494 = sbv_bv_u8_rotr(s2493, 1);
+  const SWord8 s2495 = 128 | s2494;
+  const SWord8 s2496 = 127 & s2494;
+  const SWord8 s2497 = s2456 ? s2495 : s2496;
+  const SWord8 s2498 = sbv_bv_u8_add(s1, s2493);
+  const SBool  s2499 = s2498 < s1;
+  const SBool  s2500 = s2498 < s2493;
+  const SBool  s2501 = s2499 || s2500;
+  const SWord8 s2502 = sbv_bv_u8_rotr(s2498, 1);
+  const SWord8 s2503 = 128 | s2502;
+  const SWord8 s2504 = 127 & s2502;
+  const SWord8 s2505 = s2501 ? s2503 : s2504;
+  const SWord8 s2506 = s2457 ? s2497 : s2505;
+  const SWord8 s2507 = s2330 ? s2485 : s2506;
+  const SWord8 s2508 = sbv_bv_u8_add(s1, s2464);
+  const SBool  s2509 = s2508 < s1;
+  const SBool  s2510 = s2508 < s2464;
+  const SBool  s2511 = s2509 || s2510;
+  const SWord8 s2512 = sbv_bv_u8_rotr(s2508, 1);
+  const SWord8 s2513 = 128 | s2512;
+  const SWord8 s2514 = 127 & s2512;
+  const SWord8 s2515 = s2511 ? s2513 : s2514;
+  const SWord8 s2516 = sbv_bv_u8_rotr(s2515, 1);
+  const SWord8 s2517 = 128 | s2516;
+  const SWord8 s2518 = 127 & s2516;
+  const SWord8 s2519 = s2329 ? s2517 : s2518;
+  const SWord8 s2520 = sbv_bv_u8_rotr(s2519, 1);
+  const SWord8 s2521 = 128 | s2520;
+  const SWord8 s2522 = 127 & s2520;
+  const SWord8 s2523 = s2456 ? s2521 : s2522;
+  const SWord8 s2524 = sbv_bv_u8_add(s1, s2519);
+  const SBool  s2525 = s2524 < s1;
+  const SBool  s2526 = s2524 < s2519;
+  const SBool  s2527 = s2525 || s2526;
+  const SWord8 s2528 = sbv_bv_u8_rotr(s2524, 1);
+  const SWord8 s2529 = 128 | s2528;
+  const SWord8 s2530 = 127 & s2528;
+  const SWord8 s2531 = s2527 ? s2529 : s2530;
+  const SWord8 s2532 = s2457 ? s2523 : s2531;
+  const SWord8 s2533 = sbv_bv_u8_add(s1, s2515);
+  const SBool  s2534 = s2533 < s1;
+  const SBool  s2535 = s2533 < s2515;
+  const SBool  s2536 = s2534 || s2535;
+  const SWord8 s2537 = sbv_bv_u8_rotr(s2533, 1);
+  const SWord8 s2538 = 128 | s2537;
+  const SWord8 s2539 = 127 & s2537;
+  const SWord8 s2540 = s2536 ? s2538 : s2539;
+  const SWord8 s2541 = sbv_bv_u8_rotr(s2540, 1);
+  const SWord8 s2542 = 128 | s2541;
+  const SWord8 s2543 = 127 & s2541;
+  const SWord8 s2544 = s2456 ? s2542 : s2543;
+  const SWord8 s2545 = sbv_bv_u8_add(s1, s2540);
+  const SBool  s2546 = s2545 < s1;
+  const SBool  s2547 = s2545 < s2540;
+  const SBool  s2548 = s2546 || s2547;
+  const SWord8 s2549 = sbv_bv_u8_rotr(s2545, 1);
+  const SWord8 s2550 = 128 | s2549;
+  const SWord8 s2551 = 127 & s2549;
+  const SWord8 s2552 = s2548 ? s2550 : s2551;
+  const SWord8 s2553 = s2457 ? s2544 : s2552;
+  const SWord8 s2554 = s2330 ? s2532 : s2553;
+  const SWord8 s2555 = s2078 ? s2507 : s2554;
+  const SWord8 s2556 = s2059 ? s2447 : s2555;
+  const SWord8 s2557 = s2042 ? s2320 : s2556;
+  const SWord8 s2558 = sbv_bv_u8_add(s1, s2063);
+  const SBool  s2559 = sbv_bv_extract_u8_0_0_u1(s2558);
+  const SBool  s2560 = false != s2559;
+  const SWord8 s2561 = s2560 ? s2067 : s2068;
+  const SBool  s2562 = sbv_bv_extract_u8_0_0_u1(s2561);
+  const SBool  s2563 = false != s2562;
+  const SWord8 s2564 = s2563 ? s2073 : s2074;
+  const SBool  s2565 = sbv_bv_extract_u8_0_0_u1(s2564);
+  const SBool  s2566 = false != s2565;
+  const SBool  s2567 = !s2566;
+  const SBool  s2568 = s2558 < s1;
+  const SBool  s2569 = s2558 < s2063;
+  const SBool  s2570 = s2568 || s2569;
+  const SWord8 s2571 = sbv_bv_u8_rotr(s2558, 1);
+  const SWord8 s2572 = 128 | s2571;
+  const SWord8 s2573 = 127 & s2571;
+  const SWord8 s2574 = s2570 ? s2572 : s2573;
+  const SBool  s2575 = sbv_bv_extract_u8_0_0_u1(s2574);
+  const SBool  s2576 = false != s2575;
+  const SWord8 s2577 = sbv_bv_u8_rotr(s2561, 1);
+  const SWord8 s2578 = 128 | s2577;
+  const SWord8 s2579 = 127 & s2577;
+  const SWord8 s2580 = s2576 ? s2578 : s2579;
+  const SBool  s2581 = sbv_bv_extract_u8_0_0_u1(s2580);
+  const SBool  s2582 = false != s2581;
+  const SWord8 s2583 = sbv_bv_u8_rotr(s2564, 1);
+  const SWord8 s2584 = 128 | s2583;
+  const SWord8 s2585 = 127 & s2583;
+  const SWord8 s2586 = s2582 ? s2584 : s2585;
+  const SBool  s2587 = sbv_bv_extract_u8_0_0_u1(s2586);
+  const SBool  s2588 = false != s2587;
+  const SBool  s2589 = !s2588;
+  const SWord8 s2590 = sbv_bv_u8_rotr(s2574, 1);
+  const SWord8 s2591 = 128 | s2590;
+  const SWord8 s2592 = 127 & s2590;
+  const SWord8 s2593 = s2041 ? s2591 : s2592;
+  const SBool  s2594 = sbv_bv_extract_u8_0_0_u1(s2593);
+  const SBool  s2595 = false != s2594;
+  const SWord8 s2596 = sbv_bv_u8_rotr(s2580, 1);
+  const SWord8 s2597 = 128 | s2596;
+  const SWord8 s2598 = 127 & s2596;
+  const SWord8 s2599 = s2595 ? s2597 : s2598;
+  const SBool  s2600 = sbv_bv_extract_u8_0_0_u1(s2599);
+  const SBool  s2601 = false != s2600;
+  const SWord8 s2602 = sbv_bv_u8_rotr(s2586, 1);
+  const SWord8 s2603 = 128 | s2602;
+  const SWord8 s2604 = 127 & s2602;
+  const SWord8 s2605 = s2601 ? s2603 : s2604;
+  const SBool  s2606 = sbv_bv_extract_u8_0_0_u1(s2605);
+  const SBool  s2607 = false != s2606;
+  const SBool  s2608 = !s2607;
+  const SWord8 s2609 = sbv_bv_u8_rotr(s2593, 1);
+  const SWord8 s2610 = 128 | s2609;
+  const SWord8 s2611 = 127 & s2609;
+  const SWord8 s2612 = s2058 ? s2610 : s2611;
+  const SWord8 s2613 = sbv_bv_u8_rotr(s2612, 1);
+  const SWord8 s2614 = 128 | s2613;
+  const SWord8 s2615 = 127 & s2613;
+  const SWord8 s2616 = s2566 ? s2614 : s2615;
+  const SWord8 s2617 = sbv_bv_u8_rotr(s2616, 1);
+  const SWord8 s2618 = 128 | s2617;
+  const SWord8 s2619 = 127 & s2617;
+  const SWord8 s2620 = s2588 ? s2618 : s2619;
+  const SWord8 s2621 = sbv_bv_u8_rotr(s2620, 1);
+  const SWord8 s2622 = 128 | s2621;
+  const SWord8 s2623 = 127 & s2621;
+  const SWord8 s2624 = s2607 ? s2622 : s2623;
+  const SWord8 s2625 = sbv_bv_u8_add(s1, s2620);
+  const SBool  s2626 = s2625 < s1;
+  const SBool  s2627 = s2625 < s2620;
+  const SBool  s2628 = s2626 || s2627;
+  const SWord8 s2629 = sbv_bv_u8_rotr(s2625, 1);
+  const SWord8 s2630 = 128 | s2629;
+  const SWord8 s2631 = 127 & s2629;
+  const SWord8 s2632 = s2628 ? s2630 : s2631;
+  const SWord8 s2633 = s2608 ? s2624 : s2632;
+  const SWord8 s2634 = sbv_bv_u8_add(s1, s2616);
+  const SBool  s2635 = s2634 < s1;
+  const SBool  s2636 = s2634 < s2616;
+  const SBool  s2637 = s2635 || s2636;
+  const SWord8 s2638 = sbv_bv_u8_rotr(s2634, 1);
+  const SWord8 s2639 = 128 | s2638;
+  const SWord8 s2640 = 127 & s2638;
+  const SWord8 s2641 = s2637 ? s2639 : s2640;
+  const SWord8 s2642 = sbv_bv_u8_rotr(s2641, 1);
+  const SWord8 s2643 = 128 | s2642;
+  const SWord8 s2644 = 127 & s2642;
+  const SWord8 s2645 = s2607 ? s2643 : s2644;
+  const SWord8 s2646 = sbv_bv_u8_add(s1, s2641);
+  const SBool  s2647 = s2646 < s1;
+  const SBool  s2648 = s2646 < s2641;
+  const SBool  s2649 = s2647 || s2648;
+  const SWord8 s2650 = sbv_bv_u8_rotr(s2646, 1);
+  const SWord8 s2651 = 128 | s2650;
+  const SWord8 s2652 = 127 & s2650;
+  const SWord8 s2653 = s2649 ? s2651 : s2652;
+  const SWord8 s2654 = s2608 ? s2645 : s2653;
+  const SWord8 s2655 = s2589 ? s2633 : s2654;
+  const SWord8 s2656 = sbv_bv_u8_add(s1, s2612);
+  const SBool  s2657 = s2656 < s1;
+  const SBool  s2658 = s2656 < s2612;
+  const SBool  s2659 = s2657 || s2658;
+  const SWord8 s2660 = sbv_bv_u8_rotr(s2656, 1);
+  const SWord8 s2661 = 128 | s2660;
+  const SWord8 s2662 = 127 & s2660;
+  const SWord8 s2663 = s2659 ? s2661 : s2662;
+  const SWord8 s2664 = sbv_bv_u8_rotr(s2663, 1);
+  const SWord8 s2665 = 128 | s2664;
+  const SWord8 s2666 = 127 & s2664;
+  const SWord8 s2667 = s2588 ? s2665 : s2666;
+  const SWord8 s2668 = sbv_bv_u8_rotr(s2667, 1);
+  const SWord8 s2669 = 128 | s2668;
+  const SWord8 s2670 = 127 & s2668;
+  const SWord8 s2671 = s2607 ? s2669 : s2670;
+  const SWord8 s2672 = sbv_bv_u8_add(s1, s2667);
+  const SBool  s2673 = s2672 < s1;
+  const SBool  s2674 = s2672 < s2667;
+  const SBool  s2675 = s2673 || s2674;
+  const SWord8 s2676 = sbv_bv_u8_rotr(s2672, 1);
+  const SWord8 s2677 = 128 | s2676;
+  const SWord8 s2678 = 127 & s2676;
+  const SWord8 s2679 = s2675 ? s2677 : s2678;
+  const SWord8 s2680 = s2608 ? s2671 : s2679;
+  const SWord8 s2681 = sbv_bv_u8_add(s1, s2663);
+  const SBool  s2682 = s2681 < s1;
+  const SBool  s2683 = s2681 < s2663;
+  const SBool  s2684 = s2682 || s2683;
+  const SWord8 s2685 = sbv_bv_u8_rotr(s2681, 1);
+  const SWord8 s2686 = 128 | s2685;
+  const SWord8 s2687 = 127 & s2685;
+  const SWord8 s2688 = s2684 ? s2686 : s2687;
+  const SWord8 s2689 = sbv_bv_u8_rotr(s2688, 1);
+  const SWord8 s2690 = 128 | s2689;
+  const SWord8 s2691 = 127 & s2689;
+  const SWord8 s2692 = s2607 ? s2690 : s2691;
+  const SWord8 s2693 = sbv_bv_u8_add(s1, s2688);
+  const SBool  s2694 = s2693 < s1;
+  const SBool  s2695 = s2693 < s2688;
+  const SBool  s2696 = s2694 || s2695;
+  const SWord8 s2697 = sbv_bv_u8_rotr(s2693, 1);
+  const SWord8 s2698 = 128 | s2697;
+  const SWord8 s2699 = 127 & s2697;
+  const SWord8 s2700 = s2696 ? s2698 : s2699;
+  const SWord8 s2701 = s2608 ? s2692 : s2700;
+  const SWord8 s2702 = s2589 ? s2680 : s2701;
+  const SWord8 s2703 = s2567 ? s2655 : s2702;
+  const SWord8 s2704 = sbv_bv_u8_add(s1, s2593);
+  const SBool  s2705 = sbv_bv_extract_u8_0_0_u1(s2704);
+  const SBool  s2706 = false != s2705;
+  const SWord8 s2707 = s2706 ? s2597 : s2598;
+  const SBool  s2708 = sbv_bv_extract_u8_0_0_u1(s2707);
+  const SBool  s2709 = false != s2708;
+  const SWord8 s2710 = s2709 ? s2603 : s2604;
+  const SBool  s2711 = sbv_bv_extract_u8_0_0_u1(s2710);
+  const SBool  s2712 = false != s2711;
+  const SBool  s2713 = !s2712;
+  const SBool  s2714 = s2704 < s1;
+  const SBool  s2715 = s2704 < s2593;
+  const SBool  s2716 = s2714 || s2715;
+  const SWord8 s2717 = sbv_bv_u8_rotr(s2704, 1);
+  const SWord8 s2718 = 128 | s2717;
+  const SWord8 s2719 = 127 & s2717;
+  const SWord8 s2720 = s2716 ? s2718 : s2719;
+  const SWord8 s2721 = sbv_bv_u8_rotr(s2720, 1);
+  const SWord8 s2722 = 128 | s2721;
+  const SWord8 s2723 = 127 & s2721;
+  const SWord8 s2724 = s2566 ? s2722 : s2723;
+  const SWord8 s2725 = sbv_bv_u8_rotr(s2724, 1);
+  const SWord8 s2726 = 128 | s2725;
+  const SWord8 s2727 = 127 & s2725;
+  const SWord8 s2728 = s2588 ? s2726 : s2727;
+  const SWord8 s2729 = sbv_bv_u8_rotr(s2728, 1);
+  const SWord8 s2730 = 128 | s2729;
+  const SWord8 s2731 = 127 & s2729;
+  const SWord8 s2732 = s2712 ? s2730 : s2731;
+  const SWord8 s2733 = sbv_bv_u8_add(s1, s2728);
+  const SBool  s2734 = s2733 < s1;
+  const SBool  s2735 = s2733 < s2728;
+  const SBool  s2736 = s2734 || s2735;
+  const SWord8 s2737 = sbv_bv_u8_rotr(s2733, 1);
+  const SWord8 s2738 = 128 | s2737;
+  const SWord8 s2739 = 127 & s2737;
+  const SWord8 s2740 = s2736 ? s2738 : s2739;
+  const SWord8 s2741 = s2713 ? s2732 : s2740;
+  const SWord8 s2742 = sbv_bv_u8_add(s1, s2724);
+  const SBool  s2743 = s2742 < s1;
+  const SBool  s2744 = s2742 < s2724;
+  const SBool  s2745 = s2743 || s2744;
+  const SWord8 s2746 = sbv_bv_u8_rotr(s2742, 1);
+  const SWord8 s2747 = 128 | s2746;
+  const SWord8 s2748 = 127 & s2746;
+  const SWord8 s2749 = s2745 ? s2747 : s2748;
+  const SWord8 s2750 = sbv_bv_u8_rotr(s2749, 1);
+  const SWord8 s2751 = 128 | s2750;
+  const SWord8 s2752 = 127 & s2750;
+  const SWord8 s2753 = s2712 ? s2751 : s2752;
+  const SWord8 s2754 = sbv_bv_u8_add(s1, s2749);
+  const SBool  s2755 = s2754 < s1;
+  const SBool  s2756 = s2754 < s2749;
+  const SBool  s2757 = s2755 || s2756;
+  const SWord8 s2758 = sbv_bv_u8_rotr(s2754, 1);
+  const SWord8 s2759 = 128 | s2758;
+  const SWord8 s2760 = 127 & s2758;
+  const SWord8 s2761 = s2757 ? s2759 : s2760;
+  const SWord8 s2762 = s2713 ? s2753 : s2761;
+  const SWord8 s2763 = s2589 ? s2741 : s2762;
+  const SWord8 s2764 = sbv_bv_u8_add(s1, s2720);
+  const SBool  s2765 = s2764 < s1;
+  const SBool  s2766 = s2764 < s2720;
+  const SBool  s2767 = s2765 || s2766;
+  const SWord8 s2768 = sbv_bv_u8_rotr(s2764, 1);
+  const SWord8 s2769 = 128 | s2768;
+  const SWord8 s2770 = 127 & s2768;
+  const SWord8 s2771 = s2767 ? s2769 : s2770;
+  const SWord8 s2772 = sbv_bv_u8_rotr(s2771, 1);
+  const SWord8 s2773 = 128 | s2772;
+  const SWord8 s2774 = 127 & s2772;
+  const SWord8 s2775 = s2588 ? s2773 : s2774;
+  const SWord8 s2776 = sbv_bv_u8_rotr(s2775, 1);
+  const SWord8 s2777 = 128 | s2776;
+  const SWord8 s2778 = 127 & s2776;
+  const SWord8 s2779 = s2712 ? s2777 : s2778;
+  const SWord8 s2780 = sbv_bv_u8_add(s1, s2775);
+  const SBool  s2781 = s2780 < s1;
+  const SBool  s2782 = s2780 < s2775;
+  const SBool  s2783 = s2781 || s2782;
+  const SWord8 s2784 = sbv_bv_u8_rotr(s2780, 1);
+  const SWord8 s2785 = 128 | s2784;
+  const SWord8 s2786 = 127 & s2784;
+  const SWord8 s2787 = s2783 ? s2785 : s2786;
+  const SWord8 s2788 = s2713 ? s2779 : s2787;
+  const SWord8 s2789 = sbv_bv_u8_add(s1, s2771);
+  const SBool  s2790 = s2789 < s1;
+  const SBool  s2791 = s2789 < s2771;
+  const SBool  s2792 = s2790 || s2791;
+  const SWord8 s2793 = sbv_bv_u8_rotr(s2789, 1);
+  const SWord8 s2794 = 128 | s2793;
+  const SWord8 s2795 = 127 & s2793;
+  const SWord8 s2796 = s2792 ? s2794 : s2795;
+  const SWord8 s2797 = sbv_bv_u8_rotr(s2796, 1);
+  const SWord8 s2798 = 128 | s2797;
+  const SWord8 s2799 = 127 & s2797;
+  const SWord8 s2800 = s2712 ? s2798 : s2799;
+  const SWord8 s2801 = sbv_bv_u8_add(s1, s2796);
+  const SBool  s2802 = s2801 < s1;
+  const SBool  s2803 = s2801 < s2796;
+  const SBool  s2804 = s2802 || s2803;
+  const SWord8 s2805 = sbv_bv_u8_rotr(s2801, 1);
+  const SWord8 s2806 = 128 | s2805;
+  const SWord8 s2807 = 127 & s2805;
+  const SWord8 s2808 = s2804 ? s2806 : s2807;
+  const SWord8 s2809 = s2713 ? s2800 : s2808;
+  const SWord8 s2810 = s2589 ? s2788 : s2809;
+  const SWord8 s2811 = s2567 ? s2763 : s2810;
+  const SWord8 s2812 = s2059 ? s2703 : s2811;
+  const SWord8 s2813 = sbv_bv_u8_add(s1, s2574);
+  const SBool  s2814 = sbv_bv_extract_u8_0_0_u1(s2813);
+  const SBool  s2815 = false != s2814;
+  const SWord8 s2816 = s2815 ? s2578 : s2579;
+  const SBool  s2817 = sbv_bv_extract_u8_0_0_u1(s2816);
+  const SBool  s2818 = false != s2817;
+  const SWord8 s2819 = s2818 ? s2584 : s2585;
+  const SBool  s2820 = sbv_bv_extract_u8_0_0_u1(s2819);
+  const SBool  s2821 = false != s2820;
+  const SBool  s2822 = !s2821;
+  const SBool  s2823 = s2813 < s1;
+  const SBool  s2824 = s2813 < s2574;
+  const SBool  s2825 = s2823 || s2824;
+  const SWord8 s2826 = sbv_bv_u8_rotr(s2813, 1);
+  const SWord8 s2827 = 128 | s2826;
+  const SWord8 s2828 = 127 & s2826;
+  const SWord8 s2829 = s2825 ? s2827 : s2828;
+  const SBool  s2830 = sbv_bv_extract_u8_0_0_u1(s2829);
+  const SBool  s2831 = false != s2830;
+  const SWord8 s2832 = sbv_bv_u8_rotr(s2816, 1);
+  const SWord8 s2833 = 128 | s2832;
+  const SWord8 s2834 = 127 & s2832;
+  const SWord8 s2835 = s2831 ? s2833 : s2834;
+  const SBool  s2836 = sbv_bv_extract_u8_0_0_u1(s2835);
+  const SBool  s2837 = false != s2836;
+  const SWord8 s2838 = sbv_bv_u8_rotr(s2819, 1);
+  const SWord8 s2839 = 128 | s2838;
+  const SWord8 s2840 = 127 & s2838;
+  const SWord8 s2841 = s2837 ? s2839 : s2840;
+  const SBool  s2842 = sbv_bv_extract_u8_0_0_u1(s2841);
+  const SBool  s2843 = false != s2842;
+  const SBool  s2844 = !s2843;
+  const SWord8 s2845 = sbv_bv_u8_rotr(s2829, 1);
+  const SWord8 s2846 = 128 | s2845;
+  const SWord8 s2847 = 127 & s2845;
+  const SWord8 s2848 = s2058 ? s2846 : s2847;
+  const SWord8 s2849 = sbv_bv_u8_rotr(s2848, 1);
+  const SWord8 s2850 = 128 | s2849;
+  const SWord8 s2851 = 127 & s2849;
+  const SWord8 s2852 = s2566 ? s2850 : s2851;
+  const SWord8 s2853 = sbv_bv_u8_rotr(s2852, 1);
+  const SWord8 s2854 = 128 | s2853;
+  const SWord8 s2855 = 127 & s2853;
+  const SWord8 s2856 = s2821 ? s2854 : s2855;
+  const SWord8 s2857 = sbv_bv_u8_rotr(s2856, 1);
+  const SWord8 s2858 = 128 | s2857;
+  const SWord8 s2859 = 127 & s2857;
+  const SWord8 s2860 = s2843 ? s2858 : s2859;
+  const SWord8 s2861 = sbv_bv_u8_add(s1, s2856);
+  const SBool  s2862 = s2861 < s1;
+  const SBool  s2863 = s2861 < s2856;
+  const SBool  s2864 = s2862 || s2863;
+  const SWord8 s2865 = sbv_bv_u8_rotr(s2861, 1);
+  const SWord8 s2866 = 128 | s2865;
+  const SWord8 s2867 = 127 & s2865;
+  const SWord8 s2868 = s2864 ? s2866 : s2867;
+  const SWord8 s2869 = s2844 ? s2860 : s2868;
+  const SWord8 s2870 = sbv_bv_u8_add(s1, s2852);
+  const SBool  s2871 = s2870 < s1;
+  const SBool  s2872 = s2870 < s2852;
+  const SBool  s2873 = s2871 || s2872;
+  const SWord8 s2874 = sbv_bv_u8_rotr(s2870, 1);
+  const SWord8 s2875 = 128 | s2874;
+  const SWord8 s2876 = 127 & s2874;
+  const SWord8 s2877 = s2873 ? s2875 : s2876;
+  const SWord8 s2878 = sbv_bv_u8_rotr(s2877, 1);
+  const SWord8 s2879 = 128 | s2878;
+  const SWord8 s2880 = 127 & s2878;
+  const SWord8 s2881 = s2843 ? s2879 : s2880;
+  const SWord8 s2882 = sbv_bv_u8_add(s1, s2877);
+  const SBool  s2883 = s2882 < s1;
+  const SBool  s2884 = s2882 < s2877;
+  const SBool  s2885 = s2883 || s2884;
+  const SWord8 s2886 = sbv_bv_u8_rotr(s2882, 1);
+  const SWord8 s2887 = 128 | s2886;
+  const SWord8 s2888 = 127 & s2886;
+  const SWord8 s2889 = s2885 ? s2887 : s2888;
+  const SWord8 s2890 = s2844 ? s2881 : s2889;
+  const SWord8 s2891 = s2822 ? s2869 : s2890;
+  const SWord8 s2892 = sbv_bv_u8_add(s1, s2848);
+  const SBool  s2893 = s2892 < s1;
+  const SBool  s2894 = s2892 < s2848;
+  const SBool  s2895 = s2893 || s2894;
+  const SWord8 s2896 = sbv_bv_u8_rotr(s2892, 1);
+  const SWord8 s2897 = 128 | s2896;
+  const SWord8 s2898 = 127 & s2896;
+  const SWord8 s2899 = s2895 ? s2897 : s2898;
+  const SWord8 s2900 = sbv_bv_u8_rotr(s2899, 1);
+  const SWord8 s2901 = 128 | s2900;
+  const SWord8 s2902 = 127 & s2900;
+  const SWord8 s2903 = s2821 ? s2901 : s2902;
+  const SWord8 s2904 = sbv_bv_u8_rotr(s2903, 1);
+  const SWord8 s2905 = 128 | s2904;
+  const SWord8 s2906 = 127 & s2904;
+  const SWord8 s2907 = s2843 ? s2905 : s2906;
+  const SWord8 s2908 = sbv_bv_u8_add(s1, s2903);
+  const SBool  s2909 = s2908 < s1;
+  const SBool  s2910 = s2908 < s2903;
+  const SBool  s2911 = s2909 || s2910;
+  const SWord8 s2912 = sbv_bv_u8_rotr(s2908, 1);
+  const SWord8 s2913 = 128 | s2912;
+  const SWord8 s2914 = 127 & s2912;
+  const SWord8 s2915 = s2911 ? s2913 : s2914;
+  const SWord8 s2916 = s2844 ? s2907 : s2915;
+  const SWord8 s2917 = sbv_bv_u8_add(s1, s2899);
+  const SBool  s2918 = s2917 < s1;
+  const SBool  s2919 = s2917 < s2899;
+  const SBool  s2920 = s2918 || s2919;
+  const SWord8 s2921 = sbv_bv_u8_rotr(s2917, 1);
+  const SWord8 s2922 = 128 | s2921;
+  const SWord8 s2923 = 127 & s2921;
+  const SWord8 s2924 = s2920 ? s2922 : s2923;
+  const SWord8 s2925 = sbv_bv_u8_rotr(s2924, 1);
+  const SWord8 s2926 = 128 | s2925;
+  const SWord8 s2927 = 127 & s2925;
+  const SWord8 s2928 = s2843 ? s2926 : s2927;
+  const SWord8 s2929 = sbv_bv_u8_add(s1, s2924);
+  const SBool  s2930 = s2929 < s1;
+  const SBool  s2931 = s2929 < s2924;
+  const SBool  s2932 = s2930 || s2931;
+  const SWord8 s2933 = sbv_bv_u8_rotr(s2929, 1);
+  const SWord8 s2934 = 128 | s2933;
+  const SWord8 s2935 = 127 & s2933;
+  const SWord8 s2936 = s2932 ? s2934 : s2935;
+  const SWord8 s2937 = s2844 ? s2928 : s2936;
+  const SWord8 s2938 = s2822 ? s2916 : s2937;
+  const SWord8 s2939 = s2567 ? s2891 : s2938;
+  const SWord8 s2940 = sbv_bv_u8_add(s1, s2829);
+  const SBool  s2941 = sbv_bv_extract_u8_0_0_u1(s2940);
+  const SBool  s2942 = false != s2941;
+  const SWord8 s2943 = s2942 ? s2833 : s2834;
+  const SBool  s2944 = sbv_bv_extract_u8_0_0_u1(s2943);
+  const SBool  s2945 = false != s2944;
+  const SWord8 s2946 = s2945 ? s2839 : s2840;
+  const SBool  s2947 = sbv_bv_extract_u8_0_0_u1(s2946);
+  const SBool  s2948 = false != s2947;
+  const SBool  s2949 = !s2948;
+  const SBool  s2950 = s2940 < s1;
+  const SBool  s2951 = s2940 < s2829;
+  const SBool  s2952 = s2950 || s2951;
+  const SWord8 s2953 = sbv_bv_u8_rotr(s2940, 1);
+  const SWord8 s2954 = 128 | s2953;
+  const SWord8 s2955 = 127 & s2953;
+  const SWord8 s2956 = s2952 ? s2954 : s2955;
+  const SWord8 s2957 = sbv_bv_u8_rotr(s2956, 1);
+  const SWord8 s2958 = 128 | s2957;
+  const SWord8 s2959 = 127 & s2957;
+  const SWord8 s2960 = s2566 ? s2958 : s2959;
+  const SWord8 s2961 = sbv_bv_u8_rotr(s2960, 1);
+  const SWord8 s2962 = 128 | s2961;
+  const SWord8 s2963 = 127 & s2961;
+  const SWord8 s2964 = s2821 ? s2962 : s2963;
+  const SWord8 s2965 = sbv_bv_u8_rotr(s2964, 1);
+  const SWord8 s2966 = 128 | s2965;
+  const SWord8 s2967 = 127 & s2965;
+  const SWord8 s2968 = s2948 ? s2966 : s2967;
+  const SWord8 s2969 = sbv_bv_u8_add(s1, s2964);
+  const SBool  s2970 = s2969 < s1;
+  const SBool  s2971 = s2969 < s2964;
+  const SBool  s2972 = s2970 || s2971;
+  const SWord8 s2973 = sbv_bv_u8_rotr(s2969, 1);
+  const SWord8 s2974 = 128 | s2973;
+  const SWord8 s2975 = 127 & s2973;
+  const SWord8 s2976 = s2972 ? s2974 : s2975;
+  const SWord8 s2977 = s2949 ? s2968 : s2976;
+  const SWord8 s2978 = sbv_bv_u8_add(s1, s2960);
+  const SBool  s2979 = s2978 < s1;
+  const SBool  s2980 = s2978 < s2960;
+  const SBool  s2981 = s2979 || s2980;
+  const SWord8 s2982 = sbv_bv_u8_rotr(s2978, 1);
+  const SWord8 s2983 = 128 | s2982;
+  const SWord8 s2984 = 127 & s2982;
+  const SWord8 s2985 = s2981 ? s2983 : s2984;
+  const SWord8 s2986 = sbv_bv_u8_rotr(s2985, 1);
+  const SWord8 s2987 = 128 | s2986;
+  const SWord8 s2988 = 127 & s2986;
+  const SWord8 s2989 = s2948 ? s2987 : s2988;
+  const SWord8 s2990 = sbv_bv_u8_add(s1, s2985);
+  const SBool  s2991 = s2990 < s1;
+  const SBool  s2992 = s2990 < s2985;
+  const SBool  s2993 = s2991 || s2992;
+  const SWord8 s2994 = sbv_bv_u8_rotr(s2990, 1);
+  const SWord8 s2995 = 128 | s2994;
+  const SWord8 s2996 = 127 & s2994;
+  const SWord8 s2997 = s2993 ? s2995 : s2996;
+  const SWord8 s2998 = s2949 ? s2989 : s2997;
+  const SWord8 s2999 = s2822 ? s2977 : s2998;
+  const SWord8 s3000 = sbv_bv_u8_add(s1, s2956);
+  const SBool  s3001 = s3000 < s1;
+  const SBool  s3002 = s3000 < s2956;
+  const SBool  s3003 = s3001 || s3002;
+  const SWord8 s3004 = sbv_bv_u8_rotr(s3000, 1);
+  const SWord8 s3005 = 128 | s3004;
+  const SWord8 s3006 = 127 & s3004;
+  const SWord8 s3007 = s3003 ? s3005 : s3006;
+  const SWord8 s3008 = sbv_bv_u8_rotr(s3007, 1);
+  const SWord8 s3009 = 128 | s3008;
+  const SWord8 s3010 = 127 & s3008;
+  const SWord8 s3011 = s2821 ? s3009 : s3010;
+  const SWord8 s3012 = sbv_bv_u8_rotr(s3011, 1);
+  const SWord8 s3013 = 128 | s3012;
+  const SWord8 s3014 = 127 & s3012;
+  const SWord8 s3015 = s2948 ? s3013 : s3014;
+  const SWord8 s3016 = sbv_bv_u8_add(s1, s3011);
+  const SBool  s3017 = s3016 < s1;
+  const SBool  s3018 = s3016 < s3011;
+  const SBool  s3019 = s3017 || s3018;
+  const SWord8 s3020 = sbv_bv_u8_rotr(s3016, 1);
+  const SWord8 s3021 = 128 | s3020;
+  const SWord8 s3022 = 127 & s3020;
+  const SWord8 s3023 = s3019 ? s3021 : s3022;
+  const SWord8 s3024 = s2949 ? s3015 : s3023;
+  const SWord8 s3025 = sbv_bv_u8_add(s1, s3007);
+  const SBool  s3026 = s3025 < s1;
+  const SBool  s3027 = s3025 < s3007;
+  const SBool  s3028 = s3026 || s3027;
+  const SWord8 s3029 = sbv_bv_u8_rotr(s3025, 1);
+  const SWord8 s3030 = 128 | s3029;
+  const SWord8 s3031 = 127 & s3029;
+  const SWord8 s3032 = s3028 ? s3030 : s3031;
+  const SWord8 s3033 = sbv_bv_u8_rotr(s3032, 1);
+  const SWord8 s3034 = 128 | s3033;
+  const SWord8 s3035 = 127 & s3033;
+  const SWord8 s3036 = s2948 ? s3034 : s3035;
+  const SWord8 s3037 = sbv_bv_u8_add(s1, s3032);
+  const SBool  s3038 = s3037 < s1;
+  const SBool  s3039 = s3037 < s3032;
+  const SBool  s3040 = s3038 || s3039;
+  const SWord8 s3041 = sbv_bv_u8_rotr(s3037, 1);
+  const SWord8 s3042 = 128 | s3041;
+  const SWord8 s3043 = 127 & s3041;
+  const SWord8 s3044 = s3040 ? s3042 : s3043;
+  const SWord8 s3045 = s2949 ? s3036 : s3044;
+  const SWord8 s3046 = s2822 ? s3024 : s3045;
+  const SWord8 s3047 = s2567 ? s2999 : s3046;
+  const SWord8 s3048 = s2059 ? s2939 : s3047;
+  const SWord8 s3049 = s2042 ? s2812 : s3048;
+  const SWord8 s3050 = s16 ? s2557 : s3049;
+  const SWord8 s3051 = sbv_bv_u8_add(s1, s2044);
+  const SBool  s3052 = sbv_bv_extract_u8_0_0_u1(s3051);
+  const SBool  s3053 = false != s3052;
+  const SWord8 s3054 = s3053 ? s2048 : s2049;
+  const SBool  s3055 = sbv_bv_extract_u8_0_0_u1(s3054);
+  const SBool  s3056 = false != s3055;
+  const SWord8 s3057 = s3056 ? s2054 : s2055;
+  const SBool  s3058 = sbv_bv_extract_u8_0_0_u1(s3057);
+  const SBool  s3059 = false != s3058;
+  const SBool  s3060 = !s3059;
+  const SBool  s3061 = s3051 < s1;
+  const SBool  s3062 = s3051 < s2044;
+  const SBool  s3063 = s3061 || s3062;
+  const SWord8 s3064 = sbv_bv_u8_rotr(s3051, 1);
+  const SWord8 s3065 = 128 | s3064;
+  const SWord8 s3066 = 127 & s3064;
+  const SWord8 s3067 = s3063 ? s3065 : s3066;
+  const SBool  s3068 = sbv_bv_extract_u8_0_0_u1(s3067);
+  const SBool  s3069 = false != s3068;
+  const SWord8 s3070 = sbv_bv_u8_rotr(s3054, 1);
+  const SWord8 s3071 = 128 | s3070;
+  const SWord8 s3072 = 127 & s3070;
+  const SWord8 s3073 = s3069 ? s3071 : s3072;
+  const SBool  s3074 = sbv_bv_extract_u8_0_0_u1(s3073);
+  const SBool  s3075 = false != s3074;
+  const SWord8 s3076 = sbv_bv_u8_rotr(s3057, 1);
+  const SWord8 s3077 = 128 | s3076;
+  const SWord8 s3078 = 127 & s3076;
+  const SWord8 s3079 = s3075 ? s3077 : s3078;
+  const SBool  s3080 = sbv_bv_extract_u8_0_0_u1(s3079);
+  const SBool  s3081 = false != s3080;
+  const SBool  s3082 = !s3081;
+  const SWord8 s3083 = sbv_bv_u8_rotr(s3067, 1);
+  const SWord8 s3084 = 128 | s3083;
+  const SWord8 s3085 = 127 & s3083;
+  const SWord8 s3086 = s15 ? s3084 : s3085;
+  const SBool  s3087 = sbv_bv_extract_u8_0_0_u1(s3086);
+  const SBool  s3088 = false != s3087;
+  const SWord8 s3089 = sbv_bv_u8_rotr(s3073, 1);
+  const SWord8 s3090 = 128 | s3089;
+  const SWord8 s3091 = 127 & s3089;
+  const SWord8 s3092 = s3088 ? s3090 : s3091;
+  const SBool  s3093 = sbv_bv_extract_u8_0_0_u1(s3092);
+  const SBool  s3094 = false != s3093;
+  const SWord8 s3095 = sbv_bv_u8_rotr(s3079, 1);
+  const SWord8 s3096 = 128 | s3095;
+  const SWord8 s3097 = 127 & s3095;
+  const SWord8 s3098 = s3094 ? s3096 : s3097;
+  const SBool  s3099 = sbv_bv_extract_u8_0_0_u1(s3098);
+  const SBool  s3100 = false != s3099;
+  const SBool  s3101 = !s3100;
+  const SWord8 s3102 = sbv_bv_u8_rotr(s3086, 1);
+  const SWord8 s3103 = 128 | s3102;
+  const SWord8 s3104 = 127 & s3102;
+  const SWord8 s3105 = s2041 ? s3103 : s3104;
+  const SBool  s3106 = sbv_bv_extract_u8_0_0_u1(s3105);
+  const SBool  s3107 = false != s3106;
+  const SWord8 s3108 = sbv_bv_u8_rotr(s3092, 1);
+  const SWord8 s3109 = 128 | s3108;
+  const SWord8 s3110 = 127 & s3108;
+  const SWord8 s3111 = s3107 ? s3109 : s3110;
+  const SBool  s3112 = sbv_bv_extract_u8_0_0_u1(s3111);
+  const SBool  s3113 = false != s3112;
+  const SWord8 s3114 = sbv_bv_u8_rotr(s3098, 1);
+  const SWord8 s3115 = 128 | s3114;
+  const SWord8 s3116 = 127 & s3114;
+  const SWord8 s3117 = s3113 ? s3115 : s3116;
+  const SBool  s3118 = sbv_bv_extract_u8_0_0_u1(s3117);
+  const SBool  s3119 = false != s3118;
+  const SBool  s3120 = !s3119;
+  const SWord8 s3121 = sbv_bv_u8_rotr(s3105, 1);
+  const SWord8 s3122 = 128 | s3121;
+  const SWord8 s3123 = 127 & s3121;
+  const SWord8 s3124 = s3059 ? s3122 : s3123;
+  const SWord8 s3125 = sbv_bv_u8_rotr(s3124, 1);
+  const SWord8 s3126 = 128 | s3125;
+  const SWord8 s3127 = 127 & s3125;
+  const SWord8 s3128 = s3081 ? s3126 : s3127;
+  const SWord8 s3129 = sbv_bv_u8_rotr(s3128, 1);
+  const SWord8 s3130 = 128 | s3129;
+  const SWord8 s3131 = 127 & s3129;
+  const SWord8 s3132 = s3100 ? s3130 : s3131;
+  const SWord8 s3133 = sbv_bv_u8_rotr(s3132, 1);
+  const SWord8 s3134 = 128 | s3133;
+  const SWord8 s3135 = 127 & s3133;
+  const SWord8 s3136 = s3119 ? s3134 : s3135;
+  const SWord8 s3137 = sbv_bv_u8_add(s1, s3132);
+  const SBool  s3138 = s3137 < s1;
+  const SBool  s3139 = s3137 < s3132;
+  const SBool  s3140 = s3138 || s3139;
+  const SWord8 s3141 = sbv_bv_u8_rotr(s3137, 1);
+  const SWord8 s3142 = 128 | s3141;
+  const SWord8 s3143 = 127 & s3141;
+  const SWord8 s3144 = s3140 ? s3142 : s3143;
+  const SWord8 s3145 = s3120 ? s3136 : s3144;
+  const SWord8 s3146 = sbv_bv_u8_add(s1, s3128);
+  const SBool  s3147 = s3146 < s1;
+  const SBool  s3148 = s3146 < s3128;
+  const SBool  s3149 = s3147 || s3148;
+  const SWord8 s3150 = sbv_bv_u8_rotr(s3146, 1);
+  const SWord8 s3151 = 128 | s3150;
+  const SWord8 s3152 = 127 & s3150;
+  const SWord8 s3153 = s3149 ? s3151 : s3152;
+  const SWord8 s3154 = sbv_bv_u8_rotr(s3153, 1);
+  const SWord8 s3155 = 128 | s3154;
+  const SWord8 s3156 = 127 & s3154;
+  const SWord8 s3157 = s3119 ? s3155 : s3156;
+  const SWord8 s3158 = sbv_bv_u8_add(s1, s3153);
+  const SBool  s3159 = s3158 < s1;
+  const SBool  s3160 = s3158 < s3153;
+  const SBool  s3161 = s3159 || s3160;
+  const SWord8 s3162 = sbv_bv_u8_rotr(s3158, 1);
+  const SWord8 s3163 = 128 | s3162;
+  const SWord8 s3164 = 127 & s3162;
+  const SWord8 s3165 = s3161 ? s3163 : s3164;
+  const SWord8 s3166 = s3120 ? s3157 : s3165;
+  const SWord8 s3167 = s3101 ? s3145 : s3166;
+  const SWord8 s3168 = sbv_bv_u8_add(s1, s3124);
+  const SBool  s3169 = s3168 < s1;
+  const SBool  s3170 = s3168 < s3124;
+  const SBool  s3171 = s3169 || s3170;
+  const SWord8 s3172 = sbv_bv_u8_rotr(s3168, 1);
+  const SWord8 s3173 = 128 | s3172;
+  const SWord8 s3174 = 127 & s3172;
+  const SWord8 s3175 = s3171 ? s3173 : s3174;
+  const SWord8 s3176 = sbv_bv_u8_rotr(s3175, 1);
+  const SWord8 s3177 = 128 | s3176;
+  const SWord8 s3178 = 127 & s3176;
+  const SWord8 s3179 = s3100 ? s3177 : s3178;
+  const SWord8 s3180 = sbv_bv_u8_rotr(s3179, 1);
+  const SWord8 s3181 = 128 | s3180;
+  const SWord8 s3182 = 127 & s3180;
+  const SWord8 s3183 = s3119 ? s3181 : s3182;
+  const SWord8 s3184 = sbv_bv_u8_add(s1, s3179);
+  const SBool  s3185 = s3184 < s1;
+  const SBool  s3186 = s3184 < s3179;
+  const SBool  s3187 = s3185 || s3186;
+  const SWord8 s3188 = sbv_bv_u8_rotr(s3184, 1);
+  const SWord8 s3189 = 128 | s3188;
+  const SWord8 s3190 = 127 & s3188;
+  const SWord8 s3191 = s3187 ? s3189 : s3190;
+  const SWord8 s3192 = s3120 ? s3183 : s3191;
+  const SWord8 s3193 = sbv_bv_u8_add(s1, s3175);
+  const SBool  s3194 = s3193 < s1;
+  const SBool  s3195 = s3193 < s3175;
+  const SBool  s3196 = s3194 || s3195;
+  const SWord8 s3197 = sbv_bv_u8_rotr(s3193, 1);
+  const SWord8 s3198 = 128 | s3197;
+  const SWord8 s3199 = 127 & s3197;
+  const SWord8 s3200 = s3196 ? s3198 : s3199;
+  const SWord8 s3201 = sbv_bv_u8_rotr(s3200, 1);
+  const SWord8 s3202 = 128 | s3201;
+  const SWord8 s3203 = 127 & s3201;
+  const SWord8 s3204 = s3119 ? s3202 : s3203;
+  const SWord8 s3205 = sbv_bv_u8_add(s1, s3200);
+  const SBool  s3206 = s3205 < s1;
+  const SBool  s3207 = s3205 < s3200;
+  const SBool  s3208 = s3206 || s3207;
+  const SWord8 s3209 = sbv_bv_u8_rotr(s3205, 1);
+  const SWord8 s3210 = 128 | s3209;
+  const SWord8 s3211 = 127 & s3209;
+  const SWord8 s3212 = s3208 ? s3210 : s3211;
+  const SWord8 s3213 = s3120 ? s3204 : s3212;
+  const SWord8 s3214 = s3101 ? s3192 : s3213;
+  const SWord8 s3215 = s3082 ? s3167 : s3214;
+  const SWord8 s3216 = sbv_bv_u8_add(s1, s3105);
+  const SBool  s3217 = sbv_bv_extract_u8_0_0_u1(s3216);
+  const SBool  s3218 = false != s3217;
+  const SWord8 s3219 = s3218 ? s3109 : s3110;
+  const SBool  s3220 = sbv_bv_extract_u8_0_0_u1(s3219);
+  const SBool  s3221 = false != s3220;
+  const SWord8 s3222 = s3221 ? s3115 : s3116;
+  const SBool  s3223 = sbv_bv_extract_u8_0_0_u1(s3222);
+  const SBool  s3224 = false != s3223;
+  const SBool  s3225 = !s3224;
+  const SBool  s3226 = s3216 < s1;
+  const SBool  s3227 = s3216 < s3105;
+  const SBool  s3228 = s3226 || s3227;
+  const SWord8 s3229 = sbv_bv_u8_rotr(s3216, 1);
+  const SWord8 s3230 = 128 | s3229;
+  const SWord8 s3231 = 127 & s3229;
+  const SWord8 s3232 = s3228 ? s3230 : s3231;
+  const SWord8 s3233 = sbv_bv_u8_rotr(s3232, 1);
+  const SWord8 s3234 = 128 | s3233;
+  const SWord8 s3235 = 127 & s3233;
+  const SWord8 s3236 = s3081 ? s3234 : s3235;
+  const SWord8 s3237 = sbv_bv_u8_rotr(s3236, 1);
+  const SWord8 s3238 = 128 | s3237;
+  const SWord8 s3239 = 127 & s3237;
+  const SWord8 s3240 = s3100 ? s3238 : s3239;
+  const SWord8 s3241 = sbv_bv_u8_rotr(s3240, 1);
+  const SWord8 s3242 = 128 | s3241;
+  const SWord8 s3243 = 127 & s3241;
+  const SWord8 s3244 = s3224 ? s3242 : s3243;
+  const SWord8 s3245 = sbv_bv_u8_add(s1, s3240);
+  const SBool  s3246 = s3245 < s1;
+  const SBool  s3247 = s3245 < s3240;
+  const SBool  s3248 = s3246 || s3247;
+  const SWord8 s3249 = sbv_bv_u8_rotr(s3245, 1);
+  const SWord8 s3250 = 128 | s3249;
+  const SWord8 s3251 = 127 & s3249;
+  const SWord8 s3252 = s3248 ? s3250 : s3251;
+  const SWord8 s3253 = s3225 ? s3244 : s3252;
+  const SWord8 s3254 = sbv_bv_u8_add(s1, s3236);
+  const SBool  s3255 = s3254 < s1;
+  const SBool  s3256 = s3254 < s3236;
+  const SBool  s3257 = s3255 || s3256;
+  const SWord8 s3258 = sbv_bv_u8_rotr(s3254, 1);
+  const SWord8 s3259 = 128 | s3258;
+  const SWord8 s3260 = 127 & s3258;
+  const SWord8 s3261 = s3257 ? s3259 : s3260;
+  const SWord8 s3262 = sbv_bv_u8_rotr(s3261, 1);
+  const SWord8 s3263 = 128 | s3262;
+  const SWord8 s3264 = 127 & s3262;
+  const SWord8 s3265 = s3224 ? s3263 : s3264;
+  const SWord8 s3266 = sbv_bv_u8_add(s1, s3261);
+  const SBool  s3267 = s3266 < s1;
+  const SBool  s3268 = s3266 < s3261;
+  const SBool  s3269 = s3267 || s3268;
+  const SWord8 s3270 = sbv_bv_u8_rotr(s3266, 1);
+  const SWord8 s3271 = 128 | s3270;
+  const SWord8 s3272 = 127 & s3270;
+  const SWord8 s3273 = s3269 ? s3271 : s3272;
+  const SWord8 s3274 = s3225 ? s3265 : s3273;
+  const SWord8 s3275 = s3101 ? s3253 : s3274;
+  const SWord8 s3276 = sbv_bv_u8_add(s1, s3232);
+  const SBool  s3277 = s3276 < s1;
+  const SBool  s3278 = s3276 < s3232;
+  const SBool  s3279 = s3277 || s3278;
+  const SWord8 s3280 = sbv_bv_u8_rotr(s3276, 1);
+  const SWord8 s3281 = 128 | s3280;
+  const SWord8 s3282 = 127 & s3280;
+  const SWord8 s3283 = s3279 ? s3281 : s3282;
+  const SWord8 s3284 = sbv_bv_u8_rotr(s3283, 1);
+  const SWord8 s3285 = 128 | s3284;
+  const SWord8 s3286 = 127 & s3284;
+  const SWord8 s3287 = s3100 ? s3285 : s3286;
+  const SWord8 s3288 = sbv_bv_u8_rotr(s3287, 1);
+  const SWord8 s3289 = 128 | s3288;
+  const SWord8 s3290 = 127 & s3288;
+  const SWord8 s3291 = s3224 ? s3289 : s3290;
+  const SWord8 s3292 = sbv_bv_u8_add(s1, s3287);
+  const SBool  s3293 = s3292 < s1;
+  const SBool  s3294 = s3292 < s3287;
+  const SBool  s3295 = s3293 || s3294;
+  const SWord8 s3296 = sbv_bv_u8_rotr(s3292, 1);
+  const SWord8 s3297 = 128 | s3296;
+  const SWord8 s3298 = 127 & s3296;
+  const SWord8 s3299 = s3295 ? s3297 : s3298;
+  const SWord8 s3300 = s3225 ? s3291 : s3299;
+  const SWord8 s3301 = sbv_bv_u8_add(s1, s3283);
+  const SBool  s3302 = s3301 < s1;
+  const SBool  s3303 = s3301 < s3283;
+  const SBool  s3304 = s3302 || s3303;
+  const SWord8 s3305 = sbv_bv_u8_rotr(s3301, 1);
+  const SWord8 s3306 = 128 | s3305;
+  const SWord8 s3307 = 127 & s3305;
+  const SWord8 s3308 = s3304 ? s3306 : s3307;
+  const SWord8 s3309 = sbv_bv_u8_rotr(s3308, 1);
+  const SWord8 s3310 = 128 | s3309;
+  const SWord8 s3311 = 127 & s3309;
+  const SWord8 s3312 = s3224 ? s3310 : s3311;
+  const SWord8 s3313 = sbv_bv_u8_add(s1, s3308);
+  const SBool  s3314 = s3313 < s1;
+  const SBool  s3315 = s3313 < s3308;
+  const SBool  s3316 = s3314 || s3315;
+  const SWord8 s3317 = sbv_bv_u8_rotr(s3313, 1);
+  const SWord8 s3318 = 128 | s3317;
+  const SWord8 s3319 = 127 & s3317;
+  const SWord8 s3320 = s3316 ? s3318 : s3319;
+  const SWord8 s3321 = s3225 ? s3312 : s3320;
+  const SWord8 s3322 = s3101 ? s3300 : s3321;
+  const SWord8 s3323 = s3082 ? s3275 : s3322;
+  const SWord8 s3324 = s3060 ? s3215 : s3323;
+  const SWord8 s3325 = sbv_bv_u8_add(s1, s3086);
+  const SBool  s3326 = sbv_bv_extract_u8_0_0_u1(s3325);
+  const SBool  s3327 = false != s3326;
+  const SWord8 s3328 = s3327 ? s3090 : s3091;
+  const SBool  s3329 = sbv_bv_extract_u8_0_0_u1(s3328);
+  const SBool  s3330 = false != s3329;
+  const SWord8 s3331 = s3330 ? s3096 : s3097;
+  const SBool  s3332 = sbv_bv_extract_u8_0_0_u1(s3331);
+  const SBool  s3333 = false != s3332;
+  const SBool  s3334 = !s3333;
+  const SBool  s3335 = s3325 < s1;
+  const SBool  s3336 = s3325 < s3086;
+  const SBool  s3337 = s3335 || s3336;
+  const SWord8 s3338 = sbv_bv_u8_rotr(s3325, 1);
+  const SWord8 s3339 = 128 | s3338;
+  const SWord8 s3340 = 127 & s3338;
+  const SWord8 s3341 = s3337 ? s3339 : s3340;
+  const SBool  s3342 = sbv_bv_extract_u8_0_0_u1(s3341);
+  const SBool  s3343 = false != s3342;
+  const SWord8 s3344 = sbv_bv_u8_rotr(s3328, 1);
+  const SWord8 s3345 = 128 | s3344;
+  const SWord8 s3346 = 127 & s3344;
+  const SWord8 s3347 = s3343 ? s3345 : s3346;
+  const SBool  s3348 = sbv_bv_extract_u8_0_0_u1(s3347);
+  const SBool  s3349 = false != s3348;
+  const SWord8 s3350 = sbv_bv_u8_rotr(s3331, 1);
+  const SWord8 s3351 = 128 | s3350;
+  const SWord8 s3352 = 127 & s3350;
+  const SWord8 s3353 = s3349 ? s3351 : s3352;
+  const SBool  s3354 = sbv_bv_extract_u8_0_0_u1(s3353);
+  const SBool  s3355 = false != s3354;
+  const SBool  s3356 = !s3355;
+  const SWord8 s3357 = sbv_bv_u8_rotr(s3341, 1);
+  const SWord8 s3358 = 128 | s3357;
+  const SWord8 s3359 = 127 & s3357;
+  const SWord8 s3360 = s3059 ? s3358 : s3359;
+  const SWord8 s3361 = sbv_bv_u8_rotr(s3360, 1);
+  const SWord8 s3362 = 128 | s3361;
+  const SWord8 s3363 = 127 & s3361;
+  const SWord8 s3364 = s3081 ? s3362 : s3363;
+  const SWord8 s3365 = sbv_bv_u8_rotr(s3364, 1);
+  const SWord8 s3366 = 128 | s3365;
+  const SWord8 s3367 = 127 & s3365;
+  const SWord8 s3368 = s3333 ? s3366 : s3367;
+  const SWord8 s3369 = sbv_bv_u8_rotr(s3368, 1);
+  const SWord8 s3370 = 128 | s3369;
+  const SWord8 s3371 = 127 & s3369;
+  const SWord8 s3372 = s3355 ? s3370 : s3371;
+  const SWord8 s3373 = sbv_bv_u8_add(s1, s3368);
+  const SBool  s3374 = s3373 < s1;
+  const SBool  s3375 = s3373 < s3368;
+  const SBool  s3376 = s3374 || s3375;
+  const SWord8 s3377 = sbv_bv_u8_rotr(s3373, 1);
+  const SWord8 s3378 = 128 | s3377;
+  const SWord8 s3379 = 127 & s3377;
+  const SWord8 s3380 = s3376 ? s3378 : s3379;
+  const SWord8 s3381 = s3356 ? s3372 : s3380;
+  const SWord8 s3382 = sbv_bv_u8_add(s1, s3364);
+  const SBool  s3383 = s3382 < s1;
+  const SBool  s3384 = s3382 < s3364;
+  const SBool  s3385 = s3383 || s3384;
+  const SWord8 s3386 = sbv_bv_u8_rotr(s3382, 1);
+  const SWord8 s3387 = 128 | s3386;
+  const SWord8 s3388 = 127 & s3386;
+  const SWord8 s3389 = s3385 ? s3387 : s3388;
+  const SWord8 s3390 = sbv_bv_u8_rotr(s3389, 1);
+  const SWord8 s3391 = 128 | s3390;
+  const SWord8 s3392 = 127 & s3390;
+  const SWord8 s3393 = s3355 ? s3391 : s3392;
+  const SWord8 s3394 = sbv_bv_u8_add(s1, s3389);
+  const SBool  s3395 = s3394 < s1;
+  const SBool  s3396 = s3394 < s3389;
+  const SBool  s3397 = s3395 || s3396;
+  const SWord8 s3398 = sbv_bv_u8_rotr(s3394, 1);
+  const SWord8 s3399 = 128 | s3398;
+  const SWord8 s3400 = 127 & s3398;
+  const SWord8 s3401 = s3397 ? s3399 : s3400;
+  const SWord8 s3402 = s3356 ? s3393 : s3401;
+  const SWord8 s3403 = s3334 ? s3381 : s3402;
+  const SWord8 s3404 = sbv_bv_u8_add(s1, s3360);
+  const SBool  s3405 = s3404 < s1;
+  const SBool  s3406 = s3404 < s3360;
+  const SBool  s3407 = s3405 || s3406;
+  const SWord8 s3408 = sbv_bv_u8_rotr(s3404, 1);
+  const SWord8 s3409 = 128 | s3408;
+  const SWord8 s3410 = 127 & s3408;
+  const SWord8 s3411 = s3407 ? s3409 : s3410;
+  const SWord8 s3412 = sbv_bv_u8_rotr(s3411, 1);
+  const SWord8 s3413 = 128 | s3412;
+  const SWord8 s3414 = 127 & s3412;
+  const SWord8 s3415 = s3333 ? s3413 : s3414;
+  const SWord8 s3416 = sbv_bv_u8_rotr(s3415, 1);
+  const SWord8 s3417 = 128 | s3416;
+  const SWord8 s3418 = 127 & s3416;
+  const SWord8 s3419 = s3355 ? s3417 : s3418;
+  const SWord8 s3420 = sbv_bv_u8_add(s1, s3415);
+  const SBool  s3421 = s3420 < s1;
+  const SBool  s3422 = s3420 < s3415;
+  const SBool  s3423 = s3421 || s3422;
+  const SWord8 s3424 = sbv_bv_u8_rotr(s3420, 1);
+  const SWord8 s3425 = 128 | s3424;
+  const SWord8 s3426 = 127 & s3424;
+  const SWord8 s3427 = s3423 ? s3425 : s3426;
+  const SWord8 s3428 = s3356 ? s3419 : s3427;
+  const SWord8 s3429 = sbv_bv_u8_add(s1, s3411);
+  const SBool  s3430 = s3429 < s1;
+  const SBool  s3431 = s3429 < s3411;
+  const SBool  s3432 = s3430 || s3431;
+  const SWord8 s3433 = sbv_bv_u8_rotr(s3429, 1);
+  const SWord8 s3434 = 128 | s3433;
+  const SWord8 s3435 = 127 & s3433;
+  const SWord8 s3436 = s3432 ? s3434 : s3435;
+  const SWord8 s3437 = sbv_bv_u8_rotr(s3436, 1);
+  const SWord8 s3438 = 128 | s3437;
+  const SWord8 s3439 = 127 & s3437;
+  const SWord8 s3440 = s3355 ? s3438 : s3439;
+  const SWord8 s3441 = sbv_bv_u8_add(s1, s3436);
+  const SBool  s3442 = s3441 < s1;
+  const SBool  s3443 = s3441 < s3436;
+  const SBool  s3444 = s3442 || s3443;
+  const SWord8 s3445 = sbv_bv_u8_rotr(s3441, 1);
+  const SWord8 s3446 = 128 | s3445;
+  const SWord8 s3447 = 127 & s3445;
+  const SWord8 s3448 = s3444 ? s3446 : s3447;
+  const SWord8 s3449 = s3356 ? s3440 : s3448;
+  const SWord8 s3450 = s3334 ? s3428 : s3449;
+  const SWord8 s3451 = s3082 ? s3403 : s3450;
+  const SWord8 s3452 = sbv_bv_u8_add(s1, s3341);
+  const SBool  s3453 = sbv_bv_extract_u8_0_0_u1(s3452);
+  const SBool  s3454 = false != s3453;
+  const SWord8 s3455 = s3454 ? s3345 : s3346;
+  const SBool  s3456 = sbv_bv_extract_u8_0_0_u1(s3455);
+  const SBool  s3457 = false != s3456;
+  const SWord8 s3458 = s3457 ? s3351 : s3352;
+  const SBool  s3459 = sbv_bv_extract_u8_0_0_u1(s3458);
+  const SBool  s3460 = false != s3459;
+  const SBool  s3461 = !s3460;
+  const SBool  s3462 = s3452 < s1;
+  const SBool  s3463 = s3452 < s3341;
+  const SBool  s3464 = s3462 || s3463;
+  const SWord8 s3465 = sbv_bv_u8_rotr(s3452, 1);
+  const SWord8 s3466 = 128 | s3465;
+  const SWord8 s3467 = 127 & s3465;
+  const SWord8 s3468 = s3464 ? s3466 : s3467;
+  const SWord8 s3469 = sbv_bv_u8_rotr(s3468, 1);
+  const SWord8 s3470 = 128 | s3469;
+  const SWord8 s3471 = 127 & s3469;
+  const SWord8 s3472 = s3081 ? s3470 : s3471;
+  const SWord8 s3473 = sbv_bv_u8_rotr(s3472, 1);
+  const SWord8 s3474 = 128 | s3473;
+  const SWord8 s3475 = 127 & s3473;
+  const SWord8 s3476 = s3333 ? s3474 : s3475;
+  const SWord8 s3477 = sbv_bv_u8_rotr(s3476, 1);
+  const SWord8 s3478 = 128 | s3477;
+  const SWord8 s3479 = 127 & s3477;
+  const SWord8 s3480 = s3460 ? s3478 : s3479;
+  const SWord8 s3481 = sbv_bv_u8_add(s1, s3476);
+  const SBool  s3482 = s3481 < s1;
+  const SBool  s3483 = s3481 < s3476;
+  const SBool  s3484 = s3482 || s3483;
+  const SWord8 s3485 = sbv_bv_u8_rotr(s3481, 1);
+  const SWord8 s3486 = 128 | s3485;
+  const SWord8 s3487 = 127 & s3485;
+  const SWord8 s3488 = s3484 ? s3486 : s3487;
+  const SWord8 s3489 = s3461 ? s3480 : s3488;
+  const SWord8 s3490 = sbv_bv_u8_add(s1, s3472);
+  const SBool  s3491 = s3490 < s1;
+  const SBool  s3492 = s3490 < s3472;
+  const SBool  s3493 = s3491 || s3492;
+  const SWord8 s3494 = sbv_bv_u8_rotr(s3490, 1);
+  const SWord8 s3495 = 128 | s3494;
+  const SWord8 s3496 = 127 & s3494;
+  const SWord8 s3497 = s3493 ? s3495 : s3496;
+  const SWord8 s3498 = sbv_bv_u8_rotr(s3497, 1);
+  const SWord8 s3499 = 128 | s3498;
+  const SWord8 s3500 = 127 & s3498;
+  const SWord8 s3501 = s3460 ? s3499 : s3500;
+  const SWord8 s3502 = sbv_bv_u8_add(s1, s3497);
+  const SBool  s3503 = s3502 < s1;
+  const SBool  s3504 = s3502 < s3497;
+  const SBool  s3505 = s3503 || s3504;
+  const SWord8 s3506 = sbv_bv_u8_rotr(s3502, 1);
+  const SWord8 s3507 = 128 | s3506;
+  const SWord8 s3508 = 127 & s3506;
+  const SWord8 s3509 = s3505 ? s3507 : s3508;
+  const SWord8 s3510 = s3461 ? s3501 : s3509;
+  const SWord8 s3511 = s3334 ? s3489 : s3510;
+  const SWord8 s3512 = sbv_bv_u8_add(s1, s3468);
+  const SBool  s3513 = s3512 < s1;
+  const SBool  s3514 = s3512 < s3468;
+  const SBool  s3515 = s3513 || s3514;
+  const SWord8 s3516 = sbv_bv_u8_rotr(s3512, 1);
+  const SWord8 s3517 = 128 | s3516;
+  const SWord8 s3518 = 127 & s3516;
+  const SWord8 s3519 = s3515 ? s3517 : s3518;
+  const SWord8 s3520 = sbv_bv_u8_rotr(s3519, 1);
+  const SWord8 s3521 = 128 | s3520;
+  const SWord8 s3522 = 127 & s3520;
+  const SWord8 s3523 = s3333 ? s3521 : s3522;
+  const SWord8 s3524 = sbv_bv_u8_rotr(s3523, 1);
+  const SWord8 s3525 = 128 | s3524;
+  const SWord8 s3526 = 127 & s3524;
+  const SWord8 s3527 = s3460 ? s3525 : s3526;
+  const SWord8 s3528 = sbv_bv_u8_add(s1, s3523);
+  const SBool  s3529 = s3528 < s1;
+  const SBool  s3530 = s3528 < s3523;
+  const SBool  s3531 = s3529 || s3530;
+  const SWord8 s3532 = sbv_bv_u8_rotr(s3528, 1);
+  const SWord8 s3533 = 128 | s3532;
+  const SWord8 s3534 = 127 & s3532;
+  const SWord8 s3535 = s3531 ? s3533 : s3534;
+  const SWord8 s3536 = s3461 ? s3527 : s3535;
+  const SWord8 s3537 = sbv_bv_u8_add(s1, s3519);
+  const SBool  s3538 = s3537 < s1;
+  const SBool  s3539 = s3537 < s3519;
+  const SBool  s3540 = s3538 || s3539;
+  const SWord8 s3541 = sbv_bv_u8_rotr(s3537, 1);
+  const SWord8 s3542 = 128 | s3541;
+  const SWord8 s3543 = 127 & s3541;
+  const SWord8 s3544 = s3540 ? s3542 : s3543;
+  const SWord8 s3545 = sbv_bv_u8_rotr(s3544, 1);
+  const SWord8 s3546 = 128 | s3545;
+  const SWord8 s3547 = 127 & s3545;
+  const SWord8 s3548 = s3460 ? s3546 : s3547;
+  const SWord8 s3549 = sbv_bv_u8_add(s1, s3544);
+  const SBool  s3550 = s3549 < s1;
+  const SBool  s3551 = s3549 < s3544;
+  const SBool  s3552 = s3550 || s3551;
+  const SWord8 s3553 = sbv_bv_u8_rotr(s3549, 1);
+  const SWord8 s3554 = 128 | s3553;
+  const SWord8 s3555 = 127 & s3553;
+  const SWord8 s3556 = s3552 ? s3554 : s3555;
+  const SWord8 s3557 = s3461 ? s3548 : s3556;
+  const SWord8 s3558 = s3334 ? s3536 : s3557;
+  const SWord8 s3559 = s3082 ? s3511 : s3558;
+  const SWord8 s3560 = s3060 ? s3451 : s3559;
+  const SWord8 s3561 = s2042 ? s3324 : s3560;
+  const SWord8 s3562 = sbv_bv_u8_add(s1, s3067);
+  const SBool  s3563 = sbv_bv_extract_u8_0_0_u1(s3562);
+  const SBool  s3564 = false != s3563;
+  const SWord8 s3565 = s3564 ? s3071 : s3072;
+  const SBool  s3566 = sbv_bv_extract_u8_0_0_u1(s3565);
+  const SBool  s3567 = false != s3566;
+  const SWord8 s3568 = s3567 ? s3077 : s3078;
+  const SBool  s3569 = sbv_bv_extract_u8_0_0_u1(s3568);
+  const SBool  s3570 = false != s3569;
+  const SBool  s3571 = !s3570;
+  const SBool  s3572 = s3562 < s1;
+  const SBool  s3573 = s3562 < s3067;
+  const SBool  s3574 = s3572 || s3573;
+  const SWord8 s3575 = sbv_bv_u8_rotr(s3562, 1);
+  const SWord8 s3576 = 128 | s3575;
+  const SWord8 s3577 = 127 & s3575;
+  const SWord8 s3578 = s3574 ? s3576 : s3577;
+  const SBool  s3579 = sbv_bv_extract_u8_0_0_u1(s3578);
+  const SBool  s3580 = false != s3579;
+  const SWord8 s3581 = sbv_bv_u8_rotr(s3565, 1);
+  const SWord8 s3582 = 128 | s3581;
+  const SWord8 s3583 = 127 & s3581;
+  const SWord8 s3584 = s3580 ? s3582 : s3583;
+  const SBool  s3585 = sbv_bv_extract_u8_0_0_u1(s3584);
+  const SBool  s3586 = false != s3585;
+  const SWord8 s3587 = sbv_bv_u8_rotr(s3568, 1);
+  const SWord8 s3588 = 128 | s3587;
+  const SWord8 s3589 = 127 & s3587;
+  const SWord8 s3590 = s3586 ? s3588 : s3589;
+  const SBool  s3591 = sbv_bv_extract_u8_0_0_u1(s3590);
+  const SBool  s3592 = false != s3591;
+  const SBool  s3593 = !s3592;
+  const SWord8 s3594 = sbv_bv_u8_rotr(s3578, 1);
+  const SWord8 s3595 = 128 | s3594;
+  const SWord8 s3596 = 127 & s3594;
+  const SWord8 s3597 = s2041 ? s3595 : s3596;
+  const SBool  s3598 = sbv_bv_extract_u8_0_0_u1(s3597);
+  const SBool  s3599 = false != s3598;
+  const SWord8 s3600 = sbv_bv_u8_rotr(s3584, 1);
+  const SWord8 s3601 = 128 | s3600;
+  const SWord8 s3602 = 127 & s3600;
+  const SWord8 s3603 = s3599 ? s3601 : s3602;
+  const SBool  s3604 = sbv_bv_extract_u8_0_0_u1(s3603);
+  const SBool  s3605 = false != s3604;
+  const SWord8 s3606 = sbv_bv_u8_rotr(s3590, 1);
+  const SWord8 s3607 = 128 | s3606;
+  const SWord8 s3608 = 127 & s3606;
+  const SWord8 s3609 = s3605 ? s3607 : s3608;
+  const SBool  s3610 = sbv_bv_extract_u8_0_0_u1(s3609);
+  const SBool  s3611 = false != s3610;
+  const SBool  s3612 = !s3611;
+  const SWord8 s3613 = sbv_bv_u8_rotr(s3597, 1);
+  const SWord8 s3614 = 128 | s3613;
+  const SWord8 s3615 = 127 & s3613;
+  const SWord8 s3616 = s3059 ? s3614 : s3615;
+  const SWord8 s3617 = sbv_bv_u8_rotr(s3616, 1);
+  const SWord8 s3618 = 128 | s3617;
+  const SWord8 s3619 = 127 & s3617;
+  const SWord8 s3620 = s3570 ? s3618 : s3619;
+  const SWord8 s3621 = sbv_bv_u8_rotr(s3620, 1);
+  const SWord8 s3622 = 128 | s3621;
+  const SWord8 s3623 = 127 & s3621;
+  const SWord8 s3624 = s3592 ? s3622 : s3623;
+  const SWord8 s3625 = sbv_bv_u8_rotr(s3624, 1);
+  const SWord8 s3626 = 128 | s3625;
+  const SWord8 s3627 = 127 & s3625;
+  const SWord8 s3628 = s3611 ? s3626 : s3627;
+  const SWord8 s3629 = sbv_bv_u8_add(s1, s3624);
+  const SBool  s3630 = s3629 < s1;
+  const SBool  s3631 = s3629 < s3624;
+  const SBool  s3632 = s3630 || s3631;
+  const SWord8 s3633 = sbv_bv_u8_rotr(s3629, 1);
+  const SWord8 s3634 = 128 | s3633;
+  const SWord8 s3635 = 127 & s3633;
+  const SWord8 s3636 = s3632 ? s3634 : s3635;
+  const SWord8 s3637 = s3612 ? s3628 : s3636;
+  const SWord8 s3638 = sbv_bv_u8_add(s1, s3620);
+  const SBool  s3639 = s3638 < s1;
+  const SBool  s3640 = s3638 < s3620;
+  const SBool  s3641 = s3639 || s3640;
+  const SWord8 s3642 = sbv_bv_u8_rotr(s3638, 1);
+  const SWord8 s3643 = 128 | s3642;
+  const SWord8 s3644 = 127 & s3642;
+  const SWord8 s3645 = s3641 ? s3643 : s3644;
+  const SWord8 s3646 = sbv_bv_u8_rotr(s3645, 1);
+  const SWord8 s3647 = 128 | s3646;
+  const SWord8 s3648 = 127 & s3646;
+  const SWord8 s3649 = s3611 ? s3647 : s3648;
+  const SWord8 s3650 = sbv_bv_u8_add(s1, s3645);
+  const SBool  s3651 = s3650 < s1;
+  const SBool  s3652 = s3650 < s3645;
+  const SBool  s3653 = s3651 || s3652;
+  const SWord8 s3654 = sbv_bv_u8_rotr(s3650, 1);
+  const SWord8 s3655 = 128 | s3654;
+  const SWord8 s3656 = 127 & s3654;
+  const SWord8 s3657 = s3653 ? s3655 : s3656;
+  const SWord8 s3658 = s3612 ? s3649 : s3657;
+  const SWord8 s3659 = s3593 ? s3637 : s3658;
+  const SWord8 s3660 = sbv_bv_u8_add(s1, s3616);
+  const SBool  s3661 = s3660 < s1;
+  const SBool  s3662 = s3660 < s3616;
+  const SBool  s3663 = s3661 || s3662;
+  const SWord8 s3664 = sbv_bv_u8_rotr(s3660, 1);
+  const SWord8 s3665 = 128 | s3664;
+  const SWord8 s3666 = 127 & s3664;
+  const SWord8 s3667 = s3663 ? s3665 : s3666;
+  const SWord8 s3668 = sbv_bv_u8_rotr(s3667, 1);
+  const SWord8 s3669 = 128 | s3668;
+  const SWord8 s3670 = 127 & s3668;
+  const SWord8 s3671 = s3592 ? s3669 : s3670;
+  const SWord8 s3672 = sbv_bv_u8_rotr(s3671, 1);
+  const SWord8 s3673 = 128 | s3672;
+  const SWord8 s3674 = 127 & s3672;
+  const SWord8 s3675 = s3611 ? s3673 : s3674;
+  const SWord8 s3676 = sbv_bv_u8_add(s1, s3671);
+  const SBool  s3677 = s3676 < s1;
+  const SBool  s3678 = s3676 < s3671;
+  const SBool  s3679 = s3677 || s3678;
+  const SWord8 s3680 = sbv_bv_u8_rotr(s3676, 1);
+  const SWord8 s3681 = 128 | s3680;
+  const SWord8 s3682 = 127 & s3680;
+  const SWord8 s3683 = s3679 ? s3681 : s3682;
+  const SWord8 s3684 = s3612 ? s3675 : s3683;
+  const SWord8 s3685 = sbv_bv_u8_add(s1, s3667);
+  const SBool  s3686 = s3685 < s1;
+  const SBool  s3687 = s3685 < s3667;
+  const SBool  s3688 = s3686 || s3687;
+  const SWord8 s3689 = sbv_bv_u8_rotr(s3685, 1);
+  const SWord8 s3690 = 128 | s3689;
+  const SWord8 s3691 = 127 & s3689;
+  const SWord8 s3692 = s3688 ? s3690 : s3691;
+  const SWord8 s3693 = sbv_bv_u8_rotr(s3692, 1);
+  const SWord8 s3694 = 128 | s3693;
+  const SWord8 s3695 = 127 & s3693;
+  const SWord8 s3696 = s3611 ? s3694 : s3695;
+  const SWord8 s3697 = sbv_bv_u8_add(s1, s3692);
+  const SBool  s3698 = s3697 < s1;
+  const SBool  s3699 = s3697 < s3692;
+  const SBool  s3700 = s3698 || s3699;
+  const SWord8 s3701 = sbv_bv_u8_rotr(s3697, 1);
+  const SWord8 s3702 = 128 | s3701;
+  const SWord8 s3703 = 127 & s3701;
+  const SWord8 s3704 = s3700 ? s3702 : s3703;
+  const SWord8 s3705 = s3612 ? s3696 : s3704;
+  const SWord8 s3706 = s3593 ? s3684 : s3705;
+  const SWord8 s3707 = s3571 ? s3659 : s3706;
+  const SWord8 s3708 = sbv_bv_u8_add(s1, s3597);
+  const SBool  s3709 = sbv_bv_extract_u8_0_0_u1(s3708);
+  const SBool  s3710 = false != s3709;
+  const SWord8 s3711 = s3710 ? s3601 : s3602;
+  const SBool  s3712 = sbv_bv_extract_u8_0_0_u1(s3711);
+  const SBool  s3713 = false != s3712;
+  const SWord8 s3714 = s3713 ? s3607 : s3608;
+  const SBool  s3715 = sbv_bv_extract_u8_0_0_u1(s3714);
+  const SBool  s3716 = false != s3715;
+  const SBool  s3717 = !s3716;
+  const SBool  s3718 = s3708 < s1;
+  const SBool  s3719 = s3708 < s3597;
+  const SBool  s3720 = s3718 || s3719;
+  const SWord8 s3721 = sbv_bv_u8_rotr(s3708, 1);
+  const SWord8 s3722 = 128 | s3721;
+  const SWord8 s3723 = 127 & s3721;
+  const SWord8 s3724 = s3720 ? s3722 : s3723;
+  const SWord8 s3725 = sbv_bv_u8_rotr(s3724, 1);
+  const SWord8 s3726 = 128 | s3725;
+  const SWord8 s3727 = 127 & s3725;
+  const SWord8 s3728 = s3570 ? s3726 : s3727;
+  const SWord8 s3729 = sbv_bv_u8_rotr(s3728, 1);
+  const SWord8 s3730 = 128 | s3729;
+  const SWord8 s3731 = 127 & s3729;
+  const SWord8 s3732 = s3592 ? s3730 : s3731;
+  const SWord8 s3733 = sbv_bv_u8_rotr(s3732, 1);
+  const SWord8 s3734 = 128 | s3733;
+  const SWord8 s3735 = 127 & s3733;
+  const SWord8 s3736 = s3716 ? s3734 : s3735;
+  const SWord8 s3737 = sbv_bv_u8_add(s1, s3732);
+  const SBool  s3738 = s3737 < s1;
+  const SBool  s3739 = s3737 < s3732;
+  const SBool  s3740 = s3738 || s3739;
+  const SWord8 s3741 = sbv_bv_u8_rotr(s3737, 1);
+  const SWord8 s3742 = 128 | s3741;
+  const SWord8 s3743 = 127 & s3741;
+  const SWord8 s3744 = s3740 ? s3742 : s3743;
+  const SWord8 s3745 = s3717 ? s3736 : s3744;
+  const SWord8 s3746 = sbv_bv_u8_add(s1, s3728);
+  const SBool  s3747 = s3746 < s1;
+  const SBool  s3748 = s3746 < s3728;
+  const SBool  s3749 = s3747 || s3748;
+  const SWord8 s3750 = sbv_bv_u8_rotr(s3746, 1);
+  const SWord8 s3751 = 128 | s3750;
+  const SWord8 s3752 = 127 & s3750;
+  const SWord8 s3753 = s3749 ? s3751 : s3752;
+  const SWord8 s3754 = sbv_bv_u8_rotr(s3753, 1);
+  const SWord8 s3755 = 128 | s3754;
+  const SWord8 s3756 = 127 & s3754;
+  const SWord8 s3757 = s3716 ? s3755 : s3756;
+  const SWord8 s3758 = sbv_bv_u8_add(s1, s3753);
+  const SBool  s3759 = s3758 < s1;
+  const SBool  s3760 = s3758 < s3753;
+  const SBool  s3761 = s3759 || s3760;
+  const SWord8 s3762 = sbv_bv_u8_rotr(s3758, 1);
+  const SWord8 s3763 = 128 | s3762;
+  const SWord8 s3764 = 127 & s3762;
+  const SWord8 s3765 = s3761 ? s3763 : s3764;
+  const SWord8 s3766 = s3717 ? s3757 : s3765;
+  const SWord8 s3767 = s3593 ? s3745 : s3766;
+  const SWord8 s3768 = sbv_bv_u8_add(s1, s3724);
+  const SBool  s3769 = s3768 < s1;
+  const SBool  s3770 = s3768 < s3724;
+  const SBool  s3771 = s3769 || s3770;
+  const SWord8 s3772 = sbv_bv_u8_rotr(s3768, 1);
+  const SWord8 s3773 = 128 | s3772;
+  const SWord8 s3774 = 127 & s3772;
+  const SWord8 s3775 = s3771 ? s3773 : s3774;
+  const SWord8 s3776 = sbv_bv_u8_rotr(s3775, 1);
+  const SWord8 s3777 = 128 | s3776;
+  const SWord8 s3778 = 127 & s3776;
+  const SWord8 s3779 = s3592 ? s3777 : s3778;
+  const SWord8 s3780 = sbv_bv_u8_rotr(s3779, 1);
+  const SWord8 s3781 = 128 | s3780;
+  const SWord8 s3782 = 127 & s3780;
+  const SWord8 s3783 = s3716 ? s3781 : s3782;
+  const SWord8 s3784 = sbv_bv_u8_add(s1, s3779);
+  const SBool  s3785 = s3784 < s1;
+  const SBool  s3786 = s3784 < s3779;
+  const SBool  s3787 = s3785 || s3786;
+  const SWord8 s3788 = sbv_bv_u8_rotr(s3784, 1);
+  const SWord8 s3789 = 128 | s3788;
+  const SWord8 s3790 = 127 & s3788;
+  const SWord8 s3791 = s3787 ? s3789 : s3790;
+  const SWord8 s3792 = s3717 ? s3783 : s3791;
+  const SWord8 s3793 = sbv_bv_u8_add(s1, s3775);
+  const SBool  s3794 = s3793 < s1;
+  const SBool  s3795 = s3793 < s3775;
+  const SBool  s3796 = s3794 || s3795;
+  const SWord8 s3797 = sbv_bv_u8_rotr(s3793, 1);
+  const SWord8 s3798 = 128 | s3797;
+  const SWord8 s3799 = 127 & s3797;
+  const SWord8 s3800 = s3796 ? s3798 : s3799;
+  const SWord8 s3801 = sbv_bv_u8_rotr(s3800, 1);
+  const SWord8 s3802 = 128 | s3801;
+  const SWord8 s3803 = 127 & s3801;
+  const SWord8 s3804 = s3716 ? s3802 : s3803;
+  const SWord8 s3805 = sbv_bv_u8_add(s1, s3800);
+  const SBool  s3806 = s3805 < s1;
+  const SBool  s3807 = s3805 < s3800;
+  const SBool  s3808 = s3806 || s3807;
+  const SWord8 s3809 = sbv_bv_u8_rotr(s3805, 1);
+  const SWord8 s3810 = 128 | s3809;
+  const SWord8 s3811 = 127 & s3809;
+  const SWord8 s3812 = s3808 ? s3810 : s3811;
+  const SWord8 s3813 = s3717 ? s3804 : s3812;
+  const SWord8 s3814 = s3593 ? s3792 : s3813;
+  const SWord8 s3815 = s3571 ? s3767 : s3814;
+  const SWord8 s3816 = s3060 ? s3707 : s3815;
+  const SWord8 s3817 = sbv_bv_u8_add(s1, s3578);
+  const SBool  s3818 = sbv_bv_extract_u8_0_0_u1(s3817);
+  const SBool  s3819 = false != s3818;
+  const SWord8 s3820 = s3819 ? s3582 : s3583;
+  const SBool  s3821 = sbv_bv_extract_u8_0_0_u1(s3820);
+  const SBool  s3822 = false != s3821;
+  const SWord8 s3823 = s3822 ? s3588 : s3589;
+  const SBool  s3824 = sbv_bv_extract_u8_0_0_u1(s3823);
+  const SBool  s3825 = false != s3824;
+  const SBool  s3826 = !s3825;
+  const SBool  s3827 = s3817 < s1;
+  const SBool  s3828 = s3817 < s3578;
+  const SBool  s3829 = s3827 || s3828;
+  const SWord8 s3830 = sbv_bv_u8_rotr(s3817, 1);
+  const SWord8 s3831 = 128 | s3830;
+  const SWord8 s3832 = 127 & s3830;
+  const SWord8 s3833 = s3829 ? s3831 : s3832;
+  const SBool  s3834 = sbv_bv_extract_u8_0_0_u1(s3833);
+  const SBool  s3835 = false != s3834;
+  const SWord8 s3836 = sbv_bv_u8_rotr(s3820, 1);
+  const SWord8 s3837 = 128 | s3836;
+  const SWord8 s3838 = 127 & s3836;
+  const SWord8 s3839 = s3835 ? s3837 : s3838;
+  const SBool  s3840 = sbv_bv_extract_u8_0_0_u1(s3839);
+  const SBool  s3841 = false != s3840;
+  const SWord8 s3842 = sbv_bv_u8_rotr(s3823, 1);
+  const SWord8 s3843 = 128 | s3842;
+  const SWord8 s3844 = 127 & s3842;
+  const SWord8 s3845 = s3841 ? s3843 : s3844;
+  const SBool  s3846 = sbv_bv_extract_u8_0_0_u1(s3845);
+  const SBool  s3847 = false != s3846;
+  const SBool  s3848 = !s3847;
+  const SWord8 s3849 = sbv_bv_u8_rotr(s3833, 1);
+  const SWord8 s3850 = 128 | s3849;
+  const SWord8 s3851 = 127 & s3849;
+  const SWord8 s3852 = s3059 ? s3850 : s3851;
+  const SWord8 s3853 = sbv_bv_u8_rotr(s3852, 1);
+  const SWord8 s3854 = 128 | s3853;
+  const SWord8 s3855 = 127 & s3853;
+  const SWord8 s3856 = s3570 ? s3854 : s3855;
+  const SWord8 s3857 = sbv_bv_u8_rotr(s3856, 1);
+  const SWord8 s3858 = 128 | s3857;
+  const SWord8 s3859 = 127 & s3857;
+  const SWord8 s3860 = s3825 ? s3858 : s3859;
+  const SWord8 s3861 = sbv_bv_u8_rotr(s3860, 1);
+  const SWord8 s3862 = 128 | s3861;
+  const SWord8 s3863 = 127 & s3861;
+  const SWord8 s3864 = s3847 ? s3862 : s3863;
+  const SWord8 s3865 = sbv_bv_u8_add(s1, s3860);
+  const SBool  s3866 = s3865 < s1;
+  const SBool  s3867 = s3865 < s3860;
+  const SBool  s3868 = s3866 || s3867;
+  const SWord8 s3869 = sbv_bv_u8_rotr(s3865, 1);
+  const SWord8 s3870 = 128 | s3869;
+  const SWord8 s3871 = 127 & s3869;
+  const SWord8 s3872 = s3868 ? s3870 : s3871;
+  const SWord8 s3873 = s3848 ? s3864 : s3872;
+  const SWord8 s3874 = sbv_bv_u8_add(s1, s3856);
+  const SBool  s3875 = s3874 < s1;
+  const SBool  s3876 = s3874 < s3856;
+  const SBool  s3877 = s3875 || s3876;
+  const SWord8 s3878 = sbv_bv_u8_rotr(s3874, 1);
+  const SWord8 s3879 = 128 | s3878;
+  const SWord8 s3880 = 127 & s3878;
+  const SWord8 s3881 = s3877 ? s3879 : s3880;
+  const SWord8 s3882 = sbv_bv_u8_rotr(s3881, 1);
+  const SWord8 s3883 = 128 | s3882;
+  const SWord8 s3884 = 127 & s3882;
+  const SWord8 s3885 = s3847 ? s3883 : s3884;
+  const SWord8 s3886 = sbv_bv_u8_add(s1, s3881);
+  const SBool  s3887 = s3886 < s1;
+  const SBool  s3888 = s3886 < s3881;
+  const SBool  s3889 = s3887 || s3888;
+  const SWord8 s3890 = sbv_bv_u8_rotr(s3886, 1);
+  const SWord8 s3891 = 128 | s3890;
+  const SWord8 s3892 = 127 & s3890;
+  const SWord8 s3893 = s3889 ? s3891 : s3892;
+  const SWord8 s3894 = s3848 ? s3885 : s3893;
+  const SWord8 s3895 = s3826 ? s3873 : s3894;
+  const SWord8 s3896 = sbv_bv_u8_add(s1, s3852);
+  const SBool  s3897 = s3896 < s1;
+  const SBool  s3898 = s3896 < s3852;
+  const SBool  s3899 = s3897 || s3898;
+  const SWord8 s3900 = sbv_bv_u8_rotr(s3896, 1);
+  const SWord8 s3901 = 128 | s3900;
+  const SWord8 s3902 = 127 & s3900;
+  const SWord8 s3903 = s3899 ? s3901 : s3902;
+  const SWord8 s3904 = sbv_bv_u8_rotr(s3903, 1);
+  const SWord8 s3905 = 128 | s3904;
+  const SWord8 s3906 = 127 & s3904;
+  const SWord8 s3907 = s3825 ? s3905 : s3906;
+  const SWord8 s3908 = sbv_bv_u8_rotr(s3907, 1);
+  const SWord8 s3909 = 128 | s3908;
+  const SWord8 s3910 = 127 & s3908;
+  const SWord8 s3911 = s3847 ? s3909 : s3910;
+  const SWord8 s3912 = sbv_bv_u8_add(s1, s3907);
+  const SBool  s3913 = s3912 < s1;
+  const SBool  s3914 = s3912 < s3907;
+  const SBool  s3915 = s3913 || s3914;
+  const SWord8 s3916 = sbv_bv_u8_rotr(s3912, 1);
+  const SWord8 s3917 = 128 | s3916;
+  const SWord8 s3918 = 127 & s3916;
+  const SWord8 s3919 = s3915 ? s3917 : s3918;
+  const SWord8 s3920 = s3848 ? s3911 : s3919;
+  const SWord8 s3921 = sbv_bv_u8_add(s1, s3903);
+  const SBool  s3922 = s3921 < s1;
+  const SBool  s3923 = s3921 < s3903;
+  const SBool  s3924 = s3922 || s3923;
+  const SWord8 s3925 = sbv_bv_u8_rotr(s3921, 1);
+  const SWord8 s3926 = 128 | s3925;
+  const SWord8 s3927 = 127 & s3925;
+  const SWord8 s3928 = s3924 ? s3926 : s3927;
+  const SWord8 s3929 = sbv_bv_u8_rotr(s3928, 1);
+  const SWord8 s3930 = 128 | s3929;
+  const SWord8 s3931 = 127 & s3929;
+  const SWord8 s3932 = s3847 ? s3930 : s3931;
+  const SWord8 s3933 = sbv_bv_u8_add(s1, s3928);
+  const SBool  s3934 = s3933 < s1;
+  const SBool  s3935 = s3933 < s3928;
+  const SBool  s3936 = s3934 || s3935;
+  const SWord8 s3937 = sbv_bv_u8_rotr(s3933, 1);
+  const SWord8 s3938 = 128 | s3937;
+  const SWord8 s3939 = 127 & s3937;
+  const SWord8 s3940 = s3936 ? s3938 : s3939;
+  const SWord8 s3941 = s3848 ? s3932 : s3940;
+  const SWord8 s3942 = s3826 ? s3920 : s3941;
+  const SWord8 s3943 = s3571 ? s3895 : s3942;
+  const SWord8 s3944 = sbv_bv_u8_add(s1, s3833);
+  const SBool  s3945 = sbv_bv_extract_u8_0_0_u1(s3944);
+  const SBool  s3946 = false != s3945;
+  const SWord8 s3947 = s3946 ? s3837 : s3838;
+  const SBool  s3948 = sbv_bv_extract_u8_0_0_u1(s3947);
+  const SBool  s3949 = false != s3948;
+  const SWord8 s3950 = s3949 ? s3843 : s3844;
+  const SBool  s3951 = sbv_bv_extract_u8_0_0_u1(s3950);
+  const SBool  s3952 = false != s3951;
+  const SBool  s3953 = !s3952;
+  const SBool  s3954 = s3944 < s1;
+  const SBool  s3955 = s3944 < s3833;
+  const SBool  s3956 = s3954 || s3955;
+  const SWord8 s3957 = sbv_bv_u8_rotr(s3944, 1);
+  const SWord8 s3958 = 128 | s3957;
+  const SWord8 s3959 = 127 & s3957;
+  const SWord8 s3960 = s3956 ? s3958 : s3959;
+  const SWord8 s3961 = sbv_bv_u8_rotr(s3960, 1);
+  const SWord8 s3962 = 128 | s3961;
+  const SWord8 s3963 = 127 & s3961;
+  const SWord8 s3964 = s3570 ? s3962 : s3963;
+  const SWord8 s3965 = sbv_bv_u8_rotr(s3964, 1);
+  const SWord8 s3966 = 128 | s3965;
+  const SWord8 s3967 = 127 & s3965;
+  const SWord8 s3968 = s3825 ? s3966 : s3967;
+  const SWord8 s3969 = sbv_bv_u8_rotr(s3968, 1);
+  const SWord8 s3970 = 128 | s3969;
+  const SWord8 s3971 = 127 & s3969;
+  const SWord8 s3972 = s3952 ? s3970 : s3971;
+  const SWord8 s3973 = sbv_bv_u8_add(s1, s3968);
+  const SBool  s3974 = s3973 < s1;
+  const SBool  s3975 = s3973 < s3968;
+  const SBool  s3976 = s3974 || s3975;
+  const SWord8 s3977 = sbv_bv_u8_rotr(s3973, 1);
+  const SWord8 s3978 = 128 | s3977;
+  const SWord8 s3979 = 127 & s3977;
+  const SWord8 s3980 = s3976 ? s3978 : s3979;
+  const SWord8 s3981 = s3953 ? s3972 : s3980;
+  const SWord8 s3982 = sbv_bv_u8_add(s1, s3964);
+  const SBool  s3983 = s3982 < s1;
+  const SBool  s3984 = s3982 < s3964;
+  const SBool  s3985 = s3983 || s3984;
+  const SWord8 s3986 = sbv_bv_u8_rotr(s3982, 1);
+  const SWord8 s3987 = 128 | s3986;
+  const SWord8 s3988 = 127 & s3986;
+  const SWord8 s3989 = s3985 ? s3987 : s3988;
+  const SWord8 s3990 = sbv_bv_u8_rotr(s3989, 1);
+  const SWord8 s3991 = 128 | s3990;
+  const SWord8 s3992 = 127 & s3990;
+  const SWord8 s3993 = s3952 ? s3991 : s3992;
+  const SWord8 s3994 = sbv_bv_u8_add(s1, s3989);
+  const SBool  s3995 = s3994 < s1;
+  const SBool  s3996 = s3994 < s3989;
+  const SBool  s3997 = s3995 || s3996;
+  const SWord8 s3998 = sbv_bv_u8_rotr(s3994, 1);
+  const SWord8 s3999 = 128 | s3998;
+  const SWord8 s4000 = 127 & s3998;
+  const SWord8 s4001 = s3997 ? s3999 : s4000;
+  const SWord8 s4002 = s3953 ? s3993 : s4001;
+  const SWord8 s4003 = s3826 ? s3981 : s4002;
+  const SWord8 s4004 = sbv_bv_u8_add(s1, s3960);
+  const SBool  s4005 = s4004 < s1;
+  const SBool  s4006 = s4004 < s3960;
+  const SBool  s4007 = s4005 || s4006;
+  const SWord8 s4008 = sbv_bv_u8_rotr(s4004, 1);
+  const SWord8 s4009 = 128 | s4008;
+  const SWord8 s4010 = 127 & s4008;
+  const SWord8 s4011 = s4007 ? s4009 : s4010;
+  const SWord8 s4012 = sbv_bv_u8_rotr(s4011, 1);
+  const SWord8 s4013 = 128 | s4012;
+  const SWord8 s4014 = 127 & s4012;
+  const SWord8 s4015 = s3825 ? s4013 : s4014;
+  const SWord8 s4016 = sbv_bv_u8_rotr(s4015, 1);
+  const SWord8 s4017 = 128 | s4016;
+  const SWord8 s4018 = 127 & s4016;
+  const SWord8 s4019 = s3952 ? s4017 : s4018;
+  const SWord8 s4020 = sbv_bv_u8_add(s1, s4015);
+  const SBool  s4021 = s4020 < s1;
+  const SBool  s4022 = s4020 < s4015;
+  const SBool  s4023 = s4021 || s4022;
+  const SWord8 s4024 = sbv_bv_u8_rotr(s4020, 1);
+  const SWord8 s4025 = 128 | s4024;
+  const SWord8 s4026 = 127 & s4024;
+  const SWord8 s4027 = s4023 ? s4025 : s4026;
+  const SWord8 s4028 = s3953 ? s4019 : s4027;
+  const SWord8 s4029 = sbv_bv_u8_add(s1, s4011);
+  const SBool  s4030 = s4029 < s1;
+  const SBool  s4031 = s4029 < s4011;
+  const SBool  s4032 = s4030 || s4031;
+  const SWord8 s4033 = sbv_bv_u8_rotr(s4029, 1);
+  const SWord8 s4034 = 128 | s4033;
+  const SWord8 s4035 = 127 & s4033;
+  const SWord8 s4036 = s4032 ? s4034 : s4035;
+  const SWord8 s4037 = sbv_bv_u8_rotr(s4036, 1);
+  const SWord8 s4038 = 128 | s4037;
+  const SWord8 s4039 = 127 & s4037;
+  const SWord8 s4040 = s3952 ? s4038 : s4039;
+  const SWord8 s4041 = sbv_bv_u8_add(s1, s4036);
+  const SBool  s4042 = s4041 < s1;
+  const SBool  s4043 = s4041 < s4036;
+  const SBool  s4044 = s4042 || s4043;
+  const SWord8 s4045 = sbv_bv_u8_rotr(s4041, 1);
+  const SWord8 s4046 = 128 | s4045;
+  const SWord8 s4047 = 127 & s4045;
+  const SWord8 s4048 = s4044 ? s4046 : s4047;
+  const SWord8 s4049 = s3953 ? s4040 : s4048;
+  const SWord8 s4050 = s3826 ? s4028 : s4049;
+  const SWord8 s4051 = s3571 ? s4003 : s4050;
+  const SWord8 s4052 = s3060 ? s3943 : s4051;
+  const SWord8 s4053 = s2042 ? s3816 : s4052;
+  const SWord8 s4054 = s16 ? s3561 : s4053;
+  const SWord8 s4055 = s11 ? s3050 : s4054;
+  const SWord8 s4056 = s5 ? s2032 : s4055;
+  const SBool  s4057 = sbv_bv_extract_u8_0_0_u1(s105);
+  const SBool  s4058 = false != s4057;
+  const SBool  s4059 = sbv_bv_extract_u8_0_0_u1(s101);
+  const SBool  s4060 = false != s4059;
+  const SBool  s4061 = sbv_bv_extract_u8_0_0_u1(s97);
+  const SBool  s4062 = false != s4061;
+  const SWord8 s4063 = sbv_bv_u8_rotr(s84, 1);
+  const SWord8 s4064 = 128 | s4063;
+  const SWord8 s4065 = 127 & s4063;
+  const SWord8 s4066 = s4062 ? s4064 : s4065;
+  const SWord8 s4067 = sbv_bv_u8_rotr(s4066, 1);
+  const SWord8 s4068 = 128 | s4067;
+  const SWord8 s4069 = 127 & s4067;
+  const SWord8 s4070 = s4060 ? s4068 : s4069;
+  const SWord8 s4071 = sbv_bv_u8_rotr(s4070, 1);
+  const SWord8 s4072 = 128 | s4071;
+  const SWord8 s4073 = 127 & s4071;
+  const SWord8 s4074 = s4058 ? s4072 : s4073;
+  const SBool  s4075 = sbv_bv_extract_u8_0_0_u1(s110);
+  const SBool  s4076 = false != s4075;
+  const SWord8 s4077 = s4076 ? s4072 : s4073;
+  const SWord8 s4078 = s93 ? s4074 : s4077;
+  const SBool  s4079 = sbv_bv_extract_u8_0_0_u1(s126);
+  const SBool  s4080 = false != s4079;
+  const SBool  s4081 = sbv_bv_extract_u8_0_0_u1(s119);
+  const SBool  s4082 = false != s4081;
+  const SWord8 s4083 = s4082 ? s4068 : s4069;
+  const SWord8 s4084 = sbv_bv_u8_rotr(s4083, 1);
+  const SWord8 s4085 = 128 | s4084;
+  const SWord8 s4086 = 127 & s4084;
+  const SWord8 s4087 = s4080 ? s4085 : s4086;
+  const SBool  s4088 = sbv_bv_extract_u8_0_0_u1(s131);
+  const SBool  s4089 = false != s4088;
+  const SWord8 s4090 = s4089 ? s4085 : s4086;
+  const SWord8 s4091 = s93 ? s4087 : s4090;
+  const SWord8 s4092 = s74 ? s4078 : s4091;
+  const SBool  s4093 = sbv_bv_extract_u8_0_0_u1(s152);
+  const SBool  s4094 = false != s4093;
+  const SBool  s4095 = sbv_bv_extract_u8_0_0_u1(s148);
+  const SBool  s4096 = false != s4095;
+  const SBool  s4097 = sbv_bv_extract_u8_0_0_u1(s141);
+  const SBool  s4098 = false != s4097;
+  const SWord8 s4099 = s4098 ? s4064 : s4065;
+  const SWord8 s4100 = sbv_bv_u8_rotr(s4099, 1);
+  const SWord8 s4101 = 128 | s4100;
+  const SWord8 s4102 = 127 & s4100;
+  const SWord8 s4103 = s4096 ? s4101 : s4102;
+  const SWord8 s4104 = sbv_bv_u8_rotr(s4103, 1);
+  const SWord8 s4105 = 128 | s4104;
+  const SWord8 s4106 = 127 & s4104;
+  const SWord8 s4107 = s4094 ? s4105 : s4106;
+  const SBool  s4108 = sbv_bv_extract_u8_0_0_u1(s157);
+  const SBool  s4109 = false != s4108;
+  const SWord8 s4110 = s4109 ? s4105 : s4106;
+  const SWord8 s4111 = s93 ? s4107 : s4110;
+  const SBool  s4112 = sbv_bv_extract_u8_0_0_u1(s173);
+  const SBool  s4113 = false != s4112;
+  const SBool  s4114 = sbv_bv_extract_u8_0_0_u1(s166);
+  const SBool  s4115 = false != s4114;
+  const SWord8 s4116 = s4115 ? s4101 : s4102;
+  const SWord8 s4117 = sbv_bv_u8_rotr(s4116, 1);
+  const SWord8 s4118 = 128 | s4117;
+  const SWord8 s4119 = 127 & s4117;
+  const SWord8 s4120 = s4113 ? s4118 : s4119;
+  const SBool  s4121 = sbv_bv_extract_u8_0_0_u1(s178);
+  const SBool  s4122 = false != s4121;
+  const SWord8 s4123 = s4122 ? s4118 : s4119;
+  const SWord8 s4124 = s93 ? s4120 : s4123;
+  const SWord8 s4125 = s74 ? s4111 : s4124;
+  const SWord8 s4126 = s55 ? s4092 : s4125;
+  const SBool  s4127 = sbv_bv_extract_u8_0_0_u1(s213);
+  const SBool  s4128 = false != s4127;
+  const SBool  s4129 = sbv_bv_extract_u8_0_0_u1(s209);
+  const SBool  s4130 = false != s4129;
+  const SBool  s4131 = sbv_bv_extract_u8_0_0_u1(s205);
+  const SBool  s4132 = false != s4131;
+  const SWord8 s4133 = sbv_bv_u8_rotr(s192, 1);
+  const SWord8 s4134 = 128 | s4133;
+  const SWord8 s4135 = 127 & s4133;
+  const SWord8 s4136 = s4132 ? s4134 : s4135;
+  const SWord8 s4137 = sbv_bv_u8_rotr(s4136, 1);
+  const SWord8 s4138 = 128 | s4137;
+  const SWord8 s4139 = 127 & s4137;
+  const SWord8 s4140 = s4130 ? s4138 : s4139;
+  const SWord8 s4141 = sbv_bv_u8_rotr(s4140, 1);
+  const SWord8 s4142 = 128 | s4141;
+  const SWord8 s4143 = 127 & s4141;
+  const SWord8 s4144 = s4128 ? s4142 : s4143;
+  const SBool  s4145 = sbv_bv_extract_u8_0_0_u1(s218);
+  const SBool  s4146 = false != s4145;
+  const SWord8 s4147 = s4146 ? s4142 : s4143;
+  const SWord8 s4148 = s198 ? s4144 : s4147;
+  const SBool  s4149 = sbv_bv_extract_u8_0_0_u1(s234);
+  const SBool  s4150 = false != s4149;
+  const SBool  s4151 = sbv_bv_extract_u8_0_0_u1(s227);
+  const SBool  s4152 = false != s4151;
+  const SWord8 s4153 = s4152 ? s4138 : s4139;
+  const SWord8 s4154 = sbv_bv_u8_rotr(s4153, 1);
+  const SWord8 s4155 = 128 | s4154;
+  const SWord8 s4156 = 127 & s4154;
+  const SWord8 s4157 = s4150 ? s4155 : s4156;
+  const SBool  s4158 = sbv_bv_extract_u8_0_0_u1(s239);
+  const SBool  s4159 = false != s4158;
+  const SWord8 s4160 = s4159 ? s4155 : s4156;
+  const SWord8 s4161 = s198 ? s4157 : s4160;
+  const SWord8 s4162 = s74 ? s4148 : s4161;
+  const SBool  s4163 = sbv_bv_extract_u8_0_0_u1(s260);
+  const SBool  s4164 = false != s4163;
+  const SBool  s4165 = sbv_bv_extract_u8_0_0_u1(s256);
+  const SBool  s4166 = false != s4165;
+  const SBool  s4167 = sbv_bv_extract_u8_0_0_u1(s249);
+  const SBool  s4168 = false != s4167;
+  const SWord8 s4169 = s4168 ? s4134 : s4135;
+  const SWord8 s4170 = sbv_bv_u8_rotr(s4169, 1);
+  const SWord8 s4171 = 128 | s4170;
+  const SWord8 s4172 = 127 & s4170;
+  const SWord8 s4173 = s4166 ? s4171 : s4172;
+  const SWord8 s4174 = sbv_bv_u8_rotr(s4173, 1);
+  const SWord8 s4175 = 128 | s4174;
+  const SWord8 s4176 = 127 & s4174;
+  const SWord8 s4177 = s4164 ? s4175 : s4176;
+  const SBool  s4178 = sbv_bv_extract_u8_0_0_u1(s265);
+  const SBool  s4179 = false != s4178;
+  const SWord8 s4180 = s4179 ? s4175 : s4176;
+  const SWord8 s4181 = s198 ? s4177 : s4180;
+  const SBool  s4182 = sbv_bv_extract_u8_0_0_u1(s281);
+  const SBool  s4183 = false != s4182;
+  const SBool  s4184 = sbv_bv_extract_u8_0_0_u1(s274);
+  const SBool  s4185 = false != s4184;
+  const SWord8 s4186 = s4185 ? s4171 : s4172;
+  const SWord8 s4187 = sbv_bv_u8_rotr(s4186, 1);
+  const SWord8 s4188 = 128 | s4187;
+  const SWord8 s4189 = 127 & s4187;
+  const SWord8 s4190 = s4183 ? s4188 : s4189;
+  const SBool  s4191 = sbv_bv_extract_u8_0_0_u1(s286);
+  const SBool  s4192 = false != s4191;
+  const SWord8 s4193 = s4192 ? s4188 : s4189;
+  const SWord8 s4194 = s198 ? s4190 : s4193;
+  const SWord8 s4195 = s74 ? s4181 : s4194;
+  const SWord8 s4196 = s55 ? s4162 : s4195;
+  const SWord8 s4197 = s36 ? s4126 : s4196;
+  const SBool  s4198 = sbv_bv_extract_u8_0_0_u1(s341);
+  const SBool  s4199 = false != s4198;
+  const SBool  s4200 = sbv_bv_extract_u8_0_0_u1(s337);
+  const SBool  s4201 = false != s4200;
+  const SBool  s4202 = sbv_bv_extract_u8_0_0_u1(s333);
+  const SBool  s4203 = false != s4202;
+  const SWord8 s4204 = sbv_bv_u8_rotr(s320, 1);
+  const SWord8 s4205 = 128 | s4204;
+  const SWord8 s4206 = 127 & s4204;
+  const SWord8 s4207 = s4203 ? s4205 : s4206;
+  const SWord8 s4208 = sbv_bv_u8_rotr(s4207, 1);
+  const SWord8 s4209 = 128 | s4208;
+  const SWord8 s4210 = 127 & s4208;
+  const SWord8 s4211 = s4201 ? s4209 : s4210;
+  const SWord8 s4212 = sbv_bv_u8_rotr(s4211, 1);
+  const SWord8 s4213 = 128 | s4212;
+  const SWord8 s4214 = 127 & s4212;
+  const SWord8 s4215 = s4199 ? s4213 : s4214;
+  const SBool  s4216 = sbv_bv_extract_u8_0_0_u1(s346);
+  const SBool  s4217 = false != s4216;
+  const SWord8 s4218 = s4217 ? s4213 : s4214;
+  const SWord8 s4219 = s329 ? s4215 : s4218;
+  const SBool  s4220 = sbv_bv_extract_u8_0_0_u1(s362);
+  const SBool  s4221 = false != s4220;
+  const SBool  s4222 = sbv_bv_extract_u8_0_0_u1(s355);
+  const SBool  s4223 = false != s4222;
+  const SWord8 s4224 = s4223 ? s4209 : s4210;
+  const SWord8 s4225 = sbv_bv_u8_rotr(s4224, 1);
+  const SWord8 s4226 = 128 | s4225;
+  const SWord8 s4227 = 127 & s4225;
+  const SWord8 s4228 = s4221 ? s4226 : s4227;
+  const SBool  s4229 = sbv_bv_extract_u8_0_0_u1(s367);
+  const SBool  s4230 = false != s4229;
+  const SWord8 s4231 = s4230 ? s4226 : s4227;
+  const SWord8 s4232 = s329 ? s4228 : s4231;
+  const SWord8 s4233 = s307 ? s4219 : s4232;
+  const SBool  s4234 = sbv_bv_extract_u8_0_0_u1(s388);
+  const SBool  s4235 = false != s4234;
+  const SBool  s4236 = sbv_bv_extract_u8_0_0_u1(s384);
+  const SBool  s4237 = false != s4236;
+  const SBool  s4238 = sbv_bv_extract_u8_0_0_u1(s377);
+  const SBool  s4239 = false != s4238;
+  const SWord8 s4240 = s4239 ? s4205 : s4206;
+  const SWord8 s4241 = sbv_bv_u8_rotr(s4240, 1);
+  const SWord8 s4242 = 128 | s4241;
+  const SWord8 s4243 = 127 & s4241;
+  const SWord8 s4244 = s4237 ? s4242 : s4243;
+  const SWord8 s4245 = sbv_bv_u8_rotr(s4244, 1);
+  const SWord8 s4246 = 128 | s4245;
+  const SWord8 s4247 = 127 & s4245;
+  const SWord8 s4248 = s4235 ? s4246 : s4247;
+  const SBool  s4249 = sbv_bv_extract_u8_0_0_u1(s393);
+  const SBool  s4250 = false != s4249;
+  const SWord8 s4251 = s4250 ? s4246 : s4247;
+  const SWord8 s4252 = s329 ? s4248 : s4251;
+  const SBool  s4253 = sbv_bv_extract_u8_0_0_u1(s409);
+  const SBool  s4254 = false != s4253;
+  const SBool  s4255 = sbv_bv_extract_u8_0_0_u1(s402);
+  const SBool  s4256 = false != s4255;
+  const SWord8 s4257 = s4256 ? s4242 : s4243;
+  const SWord8 s4258 = sbv_bv_u8_rotr(s4257, 1);
+  const SWord8 s4259 = 128 | s4258;
+  const SWord8 s4260 = 127 & s4258;
+  const SWord8 s4261 = s4254 ? s4259 : s4260;
+  const SBool  s4262 = sbv_bv_extract_u8_0_0_u1(s414);
+  const SBool  s4263 = false != s4262;
+  const SWord8 s4264 = s4263 ? s4259 : s4260;
+  const SWord8 s4265 = s329 ? s4261 : s4264;
+  const SWord8 s4266 = s307 ? s4252 : s4265;
+  const SWord8 s4267 = s55 ? s4233 : s4266;
+  const SBool  s4268 = sbv_bv_extract_u8_0_0_u1(s449);
+  const SBool  s4269 = false != s4268;
+  const SBool  s4270 = sbv_bv_extract_u8_0_0_u1(s445);
+  const SBool  s4271 = false != s4270;
+  const SBool  s4272 = sbv_bv_extract_u8_0_0_u1(s441);
+  const SBool  s4273 = false != s4272;
+  const SWord8 s4274 = sbv_bv_u8_rotr(s428, 1);
+  const SWord8 s4275 = 128 | s4274;
+  const SWord8 s4276 = 127 & s4274;
+  const SWord8 s4277 = s4273 ? s4275 : s4276;
+  const SWord8 s4278 = sbv_bv_u8_rotr(s4277, 1);
+  const SWord8 s4279 = 128 | s4278;
+  const SWord8 s4280 = 127 & s4278;
+  const SWord8 s4281 = s4271 ? s4279 : s4280;
+  const SWord8 s4282 = sbv_bv_u8_rotr(s4281, 1);
+  const SWord8 s4283 = 128 | s4282;
+  const SWord8 s4284 = 127 & s4282;
+  const SWord8 s4285 = s4269 ? s4283 : s4284;
+  const SBool  s4286 = sbv_bv_extract_u8_0_0_u1(s454);
+  const SBool  s4287 = false != s4286;
+  const SWord8 s4288 = s4287 ? s4283 : s4284;
+  const SWord8 s4289 = s434 ? s4285 : s4288;
+  const SBool  s4290 = sbv_bv_extract_u8_0_0_u1(s470);
+  const SBool  s4291 = false != s4290;
+  const SBool  s4292 = sbv_bv_extract_u8_0_0_u1(s463);
+  const SBool  s4293 = false != s4292;
+  const SWord8 s4294 = s4293 ? s4279 : s4280;
+  const SWord8 s4295 = sbv_bv_u8_rotr(s4294, 1);
+  const SWord8 s4296 = 128 | s4295;
+  const SWord8 s4297 = 127 & s4295;
+  const SWord8 s4298 = s4291 ? s4296 : s4297;
+  const SBool  s4299 = sbv_bv_extract_u8_0_0_u1(s475);
+  const SBool  s4300 = false != s4299;
+  const SWord8 s4301 = s4300 ? s4296 : s4297;
+  const SWord8 s4302 = s434 ? s4298 : s4301;
+  const SWord8 s4303 = s307 ? s4289 : s4302;
+  const SBool  s4304 = sbv_bv_extract_u8_0_0_u1(s496);
+  const SBool  s4305 = false != s4304;
+  const SBool  s4306 = sbv_bv_extract_u8_0_0_u1(s492);
+  const SBool  s4307 = false != s4306;
+  const SBool  s4308 = sbv_bv_extract_u8_0_0_u1(s485);
+  const SBool  s4309 = false != s4308;
+  const SWord8 s4310 = s4309 ? s4275 : s4276;
+  const SWord8 s4311 = sbv_bv_u8_rotr(s4310, 1);
+  const SWord8 s4312 = 128 | s4311;
+  const SWord8 s4313 = 127 & s4311;
+  const SWord8 s4314 = s4307 ? s4312 : s4313;
+  const SWord8 s4315 = sbv_bv_u8_rotr(s4314, 1);
+  const SWord8 s4316 = 128 | s4315;
+  const SWord8 s4317 = 127 & s4315;
+  const SWord8 s4318 = s4305 ? s4316 : s4317;
+  const SBool  s4319 = sbv_bv_extract_u8_0_0_u1(s501);
+  const SBool  s4320 = false != s4319;
+  const SWord8 s4321 = s4320 ? s4316 : s4317;
+  const SWord8 s4322 = s434 ? s4318 : s4321;
+  const SBool  s4323 = sbv_bv_extract_u8_0_0_u1(s517);
+  const SBool  s4324 = false != s4323;
+  const SBool  s4325 = sbv_bv_extract_u8_0_0_u1(s510);
+  const SBool  s4326 = false != s4325;
+  const SWord8 s4327 = s4326 ? s4312 : s4313;
+  const SWord8 s4328 = sbv_bv_u8_rotr(s4327, 1);
+  const SWord8 s4329 = 128 | s4328;
+  const SWord8 s4330 = 127 & s4328;
+  const SWord8 s4331 = s4324 ? s4329 : s4330;
+  const SBool  s4332 = sbv_bv_extract_u8_0_0_u1(s522);
+  const SBool  s4333 = false != s4332;
+  const SWord8 s4334 = s4333 ? s4329 : s4330;
+  const SWord8 s4335 = s434 ? s4331 : s4334;
+  const SWord8 s4336 = s307 ? s4322 : s4335;
+  const SWord8 s4337 = s55 ? s4303 : s4336;
+  const SWord8 s4338 = s36 ? s4267 : s4337;
+  const SWord8 s4339 = s21 ? s4197 : s4338;
+  const SBool  s4340 = sbv_bv_extract_u8_0_0_u1(s597);
+  const SBool  s4341 = false != s4340;
+  const SBool  s4342 = sbv_bv_extract_u8_0_0_u1(s593);
+  const SBool  s4343 = false != s4342;
+  const SBool  s4344 = sbv_bv_extract_u8_0_0_u1(s589);
+  const SBool  s4345 = false != s4344;
+  const SWord8 s4346 = sbv_bv_u8_rotr(s576, 1);
+  const SWord8 s4347 = 128 | s4346;
+  const SWord8 s4348 = 127 & s4346;
+  const SWord8 s4349 = s4345 ? s4347 : s4348;
+  const SWord8 s4350 = sbv_bv_u8_rotr(s4349, 1);
+  const SWord8 s4351 = 128 | s4350;
+  const SWord8 s4352 = 127 & s4350;
+  const SWord8 s4353 = s4343 ? s4351 : s4352;
+  const SWord8 s4354 = sbv_bv_u8_rotr(s4353, 1);
+  const SWord8 s4355 = 128 | s4354;
+  const SWord8 s4356 = 127 & s4354;
+  const SWord8 s4357 = s4341 ? s4355 : s4356;
+  const SBool  s4358 = sbv_bv_extract_u8_0_0_u1(s602);
+  const SBool  s4359 = false != s4358;
+  const SWord8 s4360 = s4359 ? s4355 : s4356;
+  const SWord8 s4361 = s585 ? s4357 : s4360;
+  const SBool  s4362 = sbv_bv_extract_u8_0_0_u1(s618);
+  const SBool  s4363 = false != s4362;
+  const SBool  s4364 = sbv_bv_extract_u8_0_0_u1(s611);
+  const SBool  s4365 = false != s4364;
+  const SWord8 s4366 = s4365 ? s4351 : s4352;
+  const SWord8 s4367 = sbv_bv_u8_rotr(s4366, 1);
+  const SWord8 s4368 = 128 | s4367;
+  const SWord8 s4369 = 127 & s4367;
+  const SWord8 s4370 = s4363 ? s4368 : s4369;
+  const SBool  s4371 = sbv_bv_extract_u8_0_0_u1(s623);
+  const SBool  s4372 = false != s4371;
+  const SWord8 s4373 = s4372 ? s4368 : s4369;
+  const SWord8 s4374 = s585 ? s4370 : s4373;
+  const SWord8 s4375 = s566 ? s4361 : s4374;
+  const SBool  s4376 = sbv_bv_extract_u8_0_0_u1(s644);
+  const SBool  s4377 = false != s4376;
+  const SBool  s4378 = sbv_bv_extract_u8_0_0_u1(s640);
+  const SBool  s4379 = false != s4378;
+  const SBool  s4380 = sbv_bv_extract_u8_0_0_u1(s633);
+  const SBool  s4381 = false != s4380;
+  const SWord8 s4382 = s4381 ? s4347 : s4348;
+  const SWord8 s4383 = sbv_bv_u8_rotr(s4382, 1);
+  const SWord8 s4384 = 128 | s4383;
+  const SWord8 s4385 = 127 & s4383;
+  const SWord8 s4386 = s4379 ? s4384 : s4385;
+  const SWord8 s4387 = sbv_bv_u8_rotr(s4386, 1);
+  const SWord8 s4388 = 128 | s4387;
+  const SWord8 s4389 = 127 & s4387;
+  const SWord8 s4390 = s4377 ? s4388 : s4389;
+  const SBool  s4391 = sbv_bv_extract_u8_0_0_u1(s649);
+  const SBool  s4392 = false != s4391;
+  const SWord8 s4393 = s4392 ? s4388 : s4389;
+  const SWord8 s4394 = s585 ? s4390 : s4393;
+  const SBool  s4395 = sbv_bv_extract_u8_0_0_u1(s665);
+  const SBool  s4396 = false != s4395;
+  const SBool  s4397 = sbv_bv_extract_u8_0_0_u1(s658);
+  const SBool  s4398 = false != s4397;
+  const SWord8 s4399 = s4398 ? s4384 : s4385;
+  const SWord8 s4400 = sbv_bv_u8_rotr(s4399, 1);
+  const SWord8 s4401 = 128 | s4400;
+  const SWord8 s4402 = 127 & s4400;
+  const SWord8 s4403 = s4396 ? s4401 : s4402;
+  const SBool  s4404 = sbv_bv_extract_u8_0_0_u1(s670);
+  const SBool  s4405 = false != s4404;
+  const SWord8 s4406 = s4405 ? s4401 : s4402;
+  const SWord8 s4407 = s585 ? s4403 : s4406;
+  const SWord8 s4408 = s566 ? s4394 : s4407;
+  const SWord8 s4409 = s544 ? s4375 : s4408;
+  const SBool  s4410 = sbv_bv_extract_u8_0_0_u1(s705);
+  const SBool  s4411 = false != s4410;
+  const SBool  s4412 = sbv_bv_extract_u8_0_0_u1(s701);
+  const SBool  s4413 = false != s4412;
+  const SBool  s4414 = sbv_bv_extract_u8_0_0_u1(s697);
+  const SBool  s4415 = false != s4414;
+  const SWord8 s4416 = sbv_bv_u8_rotr(s684, 1);
+  const SWord8 s4417 = 128 | s4416;
+  const SWord8 s4418 = 127 & s4416;
+  const SWord8 s4419 = s4415 ? s4417 : s4418;
+  const SWord8 s4420 = sbv_bv_u8_rotr(s4419, 1);
+  const SWord8 s4421 = 128 | s4420;
+  const SWord8 s4422 = 127 & s4420;
+  const SWord8 s4423 = s4413 ? s4421 : s4422;
+  const SWord8 s4424 = sbv_bv_u8_rotr(s4423, 1);
+  const SWord8 s4425 = 128 | s4424;
+  const SWord8 s4426 = 127 & s4424;
+  const SWord8 s4427 = s4411 ? s4425 : s4426;
+  const SBool  s4428 = sbv_bv_extract_u8_0_0_u1(s710);
+  const SBool  s4429 = false != s4428;
+  const SWord8 s4430 = s4429 ? s4425 : s4426;
+  const SWord8 s4431 = s690 ? s4427 : s4430;
+  const SBool  s4432 = sbv_bv_extract_u8_0_0_u1(s726);
+  const SBool  s4433 = false != s4432;
+  const SBool  s4434 = sbv_bv_extract_u8_0_0_u1(s719);
+  const SBool  s4435 = false != s4434;
+  const SWord8 s4436 = s4435 ? s4421 : s4422;
+  const SWord8 s4437 = sbv_bv_u8_rotr(s4436, 1);
+  const SWord8 s4438 = 128 | s4437;
+  const SWord8 s4439 = 127 & s4437;
+  const SWord8 s4440 = s4433 ? s4438 : s4439;
+  const SBool  s4441 = sbv_bv_extract_u8_0_0_u1(s731);
+  const SBool  s4442 = false != s4441;
+  const SWord8 s4443 = s4442 ? s4438 : s4439;
+  const SWord8 s4444 = s690 ? s4440 : s4443;
+  const SWord8 s4445 = s566 ? s4431 : s4444;
+  const SBool  s4446 = sbv_bv_extract_u8_0_0_u1(s752);
+  const SBool  s4447 = false != s4446;
+  const SBool  s4448 = sbv_bv_extract_u8_0_0_u1(s748);
+  const SBool  s4449 = false != s4448;
+  const SBool  s4450 = sbv_bv_extract_u8_0_0_u1(s741);
+  const SBool  s4451 = false != s4450;
+  const SWord8 s4452 = s4451 ? s4417 : s4418;
+  const SWord8 s4453 = sbv_bv_u8_rotr(s4452, 1);
+  const SWord8 s4454 = 128 | s4453;
+  const SWord8 s4455 = 127 & s4453;
+  const SWord8 s4456 = s4449 ? s4454 : s4455;
+  const SWord8 s4457 = sbv_bv_u8_rotr(s4456, 1);
+  const SWord8 s4458 = 128 | s4457;
+  const SWord8 s4459 = 127 & s4457;
+  const SWord8 s4460 = s4447 ? s4458 : s4459;
+  const SBool  s4461 = sbv_bv_extract_u8_0_0_u1(s757);
+  const SBool  s4462 = false != s4461;
+  const SWord8 s4463 = s4462 ? s4458 : s4459;
+  const SWord8 s4464 = s690 ? s4460 : s4463;
+  const SBool  s4465 = sbv_bv_extract_u8_0_0_u1(s773);
+  const SBool  s4466 = false != s4465;
+  const SBool  s4467 = sbv_bv_extract_u8_0_0_u1(s766);
+  const SBool  s4468 = false != s4467;
+  const SWord8 s4469 = s4468 ? s4454 : s4455;
+  const SWord8 s4470 = sbv_bv_u8_rotr(s4469, 1);
+  const SWord8 s4471 = 128 | s4470;
+  const SWord8 s4472 = 127 & s4470;
+  const SWord8 s4473 = s4466 ? s4471 : s4472;
+  const SBool  s4474 = sbv_bv_extract_u8_0_0_u1(s778);
+  const SBool  s4475 = false != s4474;
+  const SWord8 s4476 = s4475 ? s4471 : s4472;
+  const SWord8 s4477 = s690 ? s4473 : s4476;
+  const SWord8 s4478 = s566 ? s4464 : s4477;
+  const SWord8 s4479 = s544 ? s4445 : s4478;
+  const SWord8 s4480 = s36 ? s4409 : s4479;
+  const SBool  s4481 = sbv_bv_extract_u8_0_0_u1(s833);
+  const SBool  s4482 = false != s4481;
+  const SBool  s4483 = sbv_bv_extract_u8_0_0_u1(s829);
+  const SBool  s4484 = false != s4483;
+  const SBool  s4485 = sbv_bv_extract_u8_0_0_u1(s825);
+  const SBool  s4486 = false != s4485;
+  const SWord8 s4487 = sbv_bv_u8_rotr(s812, 1);
+  const SWord8 s4488 = 128 | s4487;
+  const SWord8 s4489 = 127 & s4487;
+  const SWord8 s4490 = s4486 ? s4488 : s4489;
+  const SWord8 s4491 = sbv_bv_u8_rotr(s4490, 1);
+  const SWord8 s4492 = 128 | s4491;
+  const SWord8 s4493 = 127 & s4491;
+  const SWord8 s4494 = s4484 ? s4492 : s4493;
+  const SWord8 s4495 = sbv_bv_u8_rotr(s4494, 1);
+  const SWord8 s4496 = 128 | s4495;
+  const SWord8 s4497 = 127 & s4495;
+  const SWord8 s4498 = s4482 ? s4496 : s4497;
+  const SBool  s4499 = sbv_bv_extract_u8_0_0_u1(s838);
+  const SBool  s4500 = false != s4499;
+  const SWord8 s4501 = s4500 ? s4496 : s4497;
+  const SWord8 s4502 = s821 ? s4498 : s4501;
+  const SBool  s4503 = sbv_bv_extract_u8_0_0_u1(s854);
+  const SBool  s4504 = false != s4503;
+  const SBool  s4505 = sbv_bv_extract_u8_0_0_u1(s847);
+  const SBool  s4506 = false != s4505;
+  const SWord8 s4507 = s4506 ? s4492 : s4493;
+  const SWord8 s4508 = sbv_bv_u8_rotr(s4507, 1);
+  const SWord8 s4509 = 128 | s4508;
+  const SWord8 s4510 = 127 & s4508;
+  const SWord8 s4511 = s4504 ? s4509 : s4510;
+  const SBool  s4512 = sbv_bv_extract_u8_0_0_u1(s859);
+  const SBool  s4513 = false != s4512;
+  const SWord8 s4514 = s4513 ? s4509 : s4510;
+  const SWord8 s4515 = s821 ? s4511 : s4514;
+  const SWord8 s4516 = s799 ? s4502 : s4515;
+  const SBool  s4517 = sbv_bv_extract_u8_0_0_u1(s880);
+  const SBool  s4518 = false != s4517;
+  const SBool  s4519 = sbv_bv_extract_u8_0_0_u1(s876);
+  const SBool  s4520 = false != s4519;
+  const SBool  s4521 = sbv_bv_extract_u8_0_0_u1(s869);
+  const SBool  s4522 = false != s4521;
+  const SWord8 s4523 = s4522 ? s4488 : s4489;
+  const SWord8 s4524 = sbv_bv_u8_rotr(s4523, 1);
+  const SWord8 s4525 = 128 | s4524;
+  const SWord8 s4526 = 127 & s4524;
+  const SWord8 s4527 = s4520 ? s4525 : s4526;
+  const SWord8 s4528 = sbv_bv_u8_rotr(s4527, 1);
+  const SWord8 s4529 = 128 | s4528;
+  const SWord8 s4530 = 127 & s4528;
+  const SWord8 s4531 = s4518 ? s4529 : s4530;
+  const SBool  s4532 = sbv_bv_extract_u8_0_0_u1(s885);
+  const SBool  s4533 = false != s4532;
+  const SWord8 s4534 = s4533 ? s4529 : s4530;
+  const SWord8 s4535 = s821 ? s4531 : s4534;
+  const SBool  s4536 = sbv_bv_extract_u8_0_0_u1(s901);
+  const SBool  s4537 = false != s4536;
+  const SBool  s4538 = sbv_bv_extract_u8_0_0_u1(s894);
+  const SBool  s4539 = false != s4538;
+  const SWord8 s4540 = s4539 ? s4525 : s4526;
+  const SWord8 s4541 = sbv_bv_u8_rotr(s4540, 1);
+  const SWord8 s4542 = 128 | s4541;
+  const SWord8 s4543 = 127 & s4541;
+  const SWord8 s4544 = s4537 ? s4542 : s4543;
+  const SBool  s4545 = sbv_bv_extract_u8_0_0_u1(s906);
+  const SBool  s4546 = false != s4545;
+  const SWord8 s4547 = s4546 ? s4542 : s4543;
+  const SWord8 s4548 = s821 ? s4544 : s4547;
+  const SWord8 s4549 = s799 ? s4535 : s4548;
+  const SWord8 s4550 = s544 ? s4516 : s4549;
+  const SBool  s4551 = sbv_bv_extract_u8_0_0_u1(s941);
+  const SBool  s4552 = false != s4551;
+  const SBool  s4553 = sbv_bv_extract_u8_0_0_u1(s937);
+  const SBool  s4554 = false != s4553;
+  const SBool  s4555 = sbv_bv_extract_u8_0_0_u1(s933);
+  const SBool  s4556 = false != s4555;
+  const SWord8 s4557 = sbv_bv_u8_rotr(s920, 1);
+  const SWord8 s4558 = 128 | s4557;
+  const SWord8 s4559 = 127 & s4557;
+  const SWord8 s4560 = s4556 ? s4558 : s4559;
+  const SWord8 s4561 = sbv_bv_u8_rotr(s4560, 1);
+  const SWord8 s4562 = 128 | s4561;
+  const SWord8 s4563 = 127 & s4561;
+  const SWord8 s4564 = s4554 ? s4562 : s4563;
+  const SWord8 s4565 = sbv_bv_u8_rotr(s4564, 1);
+  const SWord8 s4566 = 128 | s4565;
+  const SWord8 s4567 = 127 & s4565;
+  const SWord8 s4568 = s4552 ? s4566 : s4567;
+  const SBool  s4569 = sbv_bv_extract_u8_0_0_u1(s946);
+  const SBool  s4570 = false != s4569;
+  const SWord8 s4571 = s4570 ? s4566 : s4567;
+  const SWord8 s4572 = s926 ? s4568 : s4571;
+  const SBool  s4573 = sbv_bv_extract_u8_0_0_u1(s962);
+  const SBool  s4574 = false != s4573;
+  const SBool  s4575 = sbv_bv_extract_u8_0_0_u1(s955);
+  const SBool  s4576 = false != s4575;
+  const SWord8 s4577 = s4576 ? s4562 : s4563;
+  const SWord8 s4578 = sbv_bv_u8_rotr(s4577, 1);
+  const SWord8 s4579 = 128 | s4578;
+  const SWord8 s4580 = 127 & s4578;
+  const SWord8 s4581 = s4574 ? s4579 : s4580;
+  const SBool  s4582 = sbv_bv_extract_u8_0_0_u1(s967);
+  const SBool  s4583 = false != s4582;
+  const SWord8 s4584 = s4583 ? s4579 : s4580;
+  const SWord8 s4585 = s926 ? s4581 : s4584;
+  const SWord8 s4586 = s799 ? s4572 : s4585;
+  const SBool  s4587 = sbv_bv_extract_u8_0_0_u1(s988);
+  const SBool  s4588 = false != s4587;
+  const SBool  s4589 = sbv_bv_extract_u8_0_0_u1(s984);
+  const SBool  s4590 = false != s4589;
+  const SBool  s4591 = sbv_bv_extract_u8_0_0_u1(s977);
+  const SBool  s4592 = false != s4591;
+  const SWord8 s4593 = s4592 ? s4558 : s4559;
+  const SWord8 s4594 = sbv_bv_u8_rotr(s4593, 1);
+  const SWord8 s4595 = 128 | s4594;
+  const SWord8 s4596 = 127 & s4594;
+  const SWord8 s4597 = s4590 ? s4595 : s4596;
+  const SWord8 s4598 = sbv_bv_u8_rotr(s4597, 1);
+  const SWord8 s4599 = 128 | s4598;
+  const SWord8 s4600 = 127 & s4598;
+  const SWord8 s4601 = s4588 ? s4599 : s4600;
+  const SBool  s4602 = sbv_bv_extract_u8_0_0_u1(s993);
+  const SBool  s4603 = false != s4602;
+  const SWord8 s4604 = s4603 ? s4599 : s4600;
+  const SWord8 s4605 = s926 ? s4601 : s4604;
+  const SBool  s4606 = sbv_bv_extract_u8_0_0_u1(s1009);
+  const SBool  s4607 = false != s4606;
+  const SBool  s4608 = sbv_bv_extract_u8_0_0_u1(s1002);
+  const SBool  s4609 = false != s4608;
+  const SWord8 s4610 = s4609 ? s4595 : s4596;
+  const SWord8 s4611 = sbv_bv_u8_rotr(s4610, 1);
+  const SWord8 s4612 = 128 | s4611;
+  const SWord8 s4613 = 127 & s4611;
+  const SWord8 s4614 = s4607 ? s4612 : s4613;
+  const SBool  s4615 = sbv_bv_extract_u8_0_0_u1(s1014);
+  const SBool  s4616 = false != s4615;
+  const SWord8 s4617 = s4616 ? s4612 : s4613;
+  const SWord8 s4618 = s926 ? s4614 : s4617;
+  const SWord8 s4619 = s799 ? s4605 : s4618;
+  const SWord8 s4620 = s544 ? s4586 : s4619;
+  const SWord8 s4621 = s36 ? s4550 : s4620;
+  const SWord8 s4622 = s21 ? s4480 : s4621;
+  const SWord8 s4623 = s16 ? s4339 : s4622;
+  const SBool  s4624 = sbv_bv_extract_u8_0_0_u1(s1109);
+  const SBool  s4625 = false != s4624;
+  const SBool  s4626 = sbv_bv_extract_u8_0_0_u1(s1105);
+  const SBool  s4627 = false != s4626;
+  const SBool  s4628 = sbv_bv_extract_u8_0_0_u1(s1101);
+  const SBool  s4629 = false != s4628;
+  const SWord8 s4630 = sbv_bv_u8_rotr(s1088, 1);
+  const SWord8 s4631 = 128 | s4630;
+  const SWord8 s4632 = 127 & s4630;
+  const SWord8 s4633 = s4629 ? s4631 : s4632;
+  const SWord8 s4634 = sbv_bv_u8_rotr(s4633, 1);
+  const SWord8 s4635 = 128 | s4634;
+  const SWord8 s4636 = 127 & s4634;
+  const SWord8 s4637 = s4627 ? s4635 : s4636;
+  const SWord8 s4638 = sbv_bv_u8_rotr(s4637, 1);
+  const SWord8 s4639 = 128 | s4638;
+  const SWord8 s4640 = 127 & s4638;
+  const SWord8 s4641 = s4625 ? s4639 : s4640;
+  const SBool  s4642 = sbv_bv_extract_u8_0_0_u1(s1114);
+  const SBool  s4643 = false != s4642;
+  const SWord8 s4644 = s4643 ? s4639 : s4640;
+  const SWord8 s4645 = s1097 ? s4641 : s4644;
+  const SBool  s4646 = sbv_bv_extract_u8_0_0_u1(s1130);
+  const SBool  s4647 = false != s4646;
+  const SBool  s4648 = sbv_bv_extract_u8_0_0_u1(s1123);
+  const SBool  s4649 = false != s4648;
+  const SWord8 s4650 = s4649 ? s4635 : s4636;
+  const SWord8 s4651 = sbv_bv_u8_rotr(s4650, 1);
+  const SWord8 s4652 = 128 | s4651;
+  const SWord8 s4653 = 127 & s4651;
+  const SWord8 s4654 = s4647 ? s4652 : s4653;
+  const SBool  s4655 = sbv_bv_extract_u8_0_0_u1(s1135);
+  const SBool  s4656 = false != s4655;
+  const SWord8 s4657 = s4656 ? s4652 : s4653;
+  const SWord8 s4658 = s1097 ? s4654 : s4657;
+  const SWord8 s4659 = s1078 ? s4645 : s4658;
+  const SBool  s4660 = sbv_bv_extract_u8_0_0_u1(s1156);
+  const SBool  s4661 = false != s4660;
+  const SBool  s4662 = sbv_bv_extract_u8_0_0_u1(s1152);
+  const SBool  s4663 = false != s4662;
+  const SBool  s4664 = sbv_bv_extract_u8_0_0_u1(s1145);
+  const SBool  s4665 = false != s4664;
+  const SWord8 s4666 = s4665 ? s4631 : s4632;
+  const SWord8 s4667 = sbv_bv_u8_rotr(s4666, 1);
+  const SWord8 s4668 = 128 | s4667;
+  const SWord8 s4669 = 127 & s4667;
+  const SWord8 s4670 = s4663 ? s4668 : s4669;
+  const SWord8 s4671 = sbv_bv_u8_rotr(s4670, 1);
+  const SWord8 s4672 = 128 | s4671;
+  const SWord8 s4673 = 127 & s4671;
+  const SWord8 s4674 = s4661 ? s4672 : s4673;
+  const SBool  s4675 = sbv_bv_extract_u8_0_0_u1(s1161);
+  const SBool  s4676 = false != s4675;
+  const SWord8 s4677 = s4676 ? s4672 : s4673;
+  const SWord8 s4678 = s1097 ? s4674 : s4677;
+  const SBool  s4679 = sbv_bv_extract_u8_0_0_u1(s1177);
+  const SBool  s4680 = false != s4679;
+  const SBool  s4681 = sbv_bv_extract_u8_0_0_u1(s1170);
+  const SBool  s4682 = false != s4681;
+  const SWord8 s4683 = s4682 ? s4668 : s4669;
+  const SWord8 s4684 = sbv_bv_u8_rotr(s4683, 1);
+  const SWord8 s4685 = 128 | s4684;
+  const SWord8 s4686 = 127 & s4684;
+  const SWord8 s4687 = s4680 ? s4685 : s4686;
+  const SBool  s4688 = sbv_bv_extract_u8_0_0_u1(s1182);
+  const SBool  s4689 = false != s4688;
+  const SWord8 s4690 = s4689 ? s4685 : s4686;
+  const SWord8 s4691 = s1097 ? s4687 : s4690;
+  const SWord8 s4692 = s1078 ? s4678 : s4691;
+  const SWord8 s4693 = s1059 ? s4659 : s4692;
+  const SBool  s4694 = sbv_bv_extract_u8_0_0_u1(s1217);
+  const SBool  s4695 = false != s4694;
+  const SBool  s4696 = sbv_bv_extract_u8_0_0_u1(s1213);
+  const SBool  s4697 = false != s4696;
+  const SBool  s4698 = sbv_bv_extract_u8_0_0_u1(s1209);
+  const SBool  s4699 = false != s4698;
+  const SWord8 s4700 = sbv_bv_u8_rotr(s1196, 1);
+  const SWord8 s4701 = 128 | s4700;
+  const SWord8 s4702 = 127 & s4700;
+  const SWord8 s4703 = s4699 ? s4701 : s4702;
+  const SWord8 s4704 = sbv_bv_u8_rotr(s4703, 1);
+  const SWord8 s4705 = 128 | s4704;
+  const SWord8 s4706 = 127 & s4704;
+  const SWord8 s4707 = s4697 ? s4705 : s4706;
+  const SWord8 s4708 = sbv_bv_u8_rotr(s4707, 1);
+  const SWord8 s4709 = 128 | s4708;
+  const SWord8 s4710 = 127 & s4708;
+  const SWord8 s4711 = s4695 ? s4709 : s4710;
+  const SBool  s4712 = sbv_bv_extract_u8_0_0_u1(s1222);
+  const SBool  s4713 = false != s4712;
+  const SWord8 s4714 = s4713 ? s4709 : s4710;
+  const SWord8 s4715 = s1202 ? s4711 : s4714;
+  const SBool  s4716 = sbv_bv_extract_u8_0_0_u1(s1238);
+  const SBool  s4717 = false != s4716;
+  const SBool  s4718 = sbv_bv_extract_u8_0_0_u1(s1231);
+  const SBool  s4719 = false != s4718;
+  const SWord8 s4720 = s4719 ? s4705 : s4706;
+  const SWord8 s4721 = sbv_bv_u8_rotr(s4720, 1);
+  const SWord8 s4722 = 128 | s4721;
+  const SWord8 s4723 = 127 & s4721;
+  const SWord8 s4724 = s4717 ? s4722 : s4723;
+  const SBool  s4725 = sbv_bv_extract_u8_0_0_u1(s1243);
+  const SBool  s4726 = false != s4725;
+  const SWord8 s4727 = s4726 ? s4722 : s4723;
+  const SWord8 s4728 = s1202 ? s4724 : s4727;
+  const SWord8 s4729 = s1078 ? s4715 : s4728;
+  const SBool  s4730 = sbv_bv_extract_u8_0_0_u1(s1264);
+  const SBool  s4731 = false != s4730;
+  const SBool  s4732 = sbv_bv_extract_u8_0_0_u1(s1260);
+  const SBool  s4733 = false != s4732;
+  const SBool  s4734 = sbv_bv_extract_u8_0_0_u1(s1253);
+  const SBool  s4735 = false != s4734;
+  const SWord8 s4736 = s4735 ? s4701 : s4702;
+  const SWord8 s4737 = sbv_bv_u8_rotr(s4736, 1);
+  const SWord8 s4738 = 128 | s4737;
+  const SWord8 s4739 = 127 & s4737;
+  const SWord8 s4740 = s4733 ? s4738 : s4739;
+  const SWord8 s4741 = sbv_bv_u8_rotr(s4740, 1);
+  const SWord8 s4742 = 128 | s4741;
+  const SWord8 s4743 = 127 & s4741;
+  const SWord8 s4744 = s4731 ? s4742 : s4743;
+  const SBool  s4745 = sbv_bv_extract_u8_0_0_u1(s1269);
+  const SBool  s4746 = false != s4745;
+  const SWord8 s4747 = s4746 ? s4742 : s4743;
+  const SWord8 s4748 = s1202 ? s4744 : s4747;
+  const SBool  s4749 = sbv_bv_extract_u8_0_0_u1(s1285);
+  const SBool  s4750 = false != s4749;
+  const SBool  s4751 = sbv_bv_extract_u8_0_0_u1(s1278);
+  const SBool  s4752 = false != s4751;
+  const SWord8 s4753 = s4752 ? s4738 : s4739;
+  const SWord8 s4754 = sbv_bv_u8_rotr(s4753, 1);
+  const SWord8 s4755 = 128 | s4754;
+  const SWord8 s4756 = 127 & s4754;
+  const SWord8 s4757 = s4750 ? s4755 : s4756;
+  const SBool  s4758 = sbv_bv_extract_u8_0_0_u1(s1290);
+  const SBool  s4759 = false != s4758;
+  const SWord8 s4760 = s4759 ? s4755 : s4756;
+  const SWord8 s4761 = s1202 ? s4757 : s4760;
+  const SWord8 s4762 = s1078 ? s4748 : s4761;
+  const SWord8 s4763 = s1059 ? s4729 : s4762;
+  const SWord8 s4764 = s1037 ? s4693 : s4763;
+  const SBool  s4765 = sbv_bv_extract_u8_0_0_u1(s1345);
+  const SBool  s4766 = false != s4765;
+  const SBool  s4767 = sbv_bv_extract_u8_0_0_u1(s1341);
+  const SBool  s4768 = false != s4767;
+  const SBool  s4769 = sbv_bv_extract_u8_0_0_u1(s1337);
+  const SBool  s4770 = false != s4769;
+  const SWord8 s4771 = sbv_bv_u8_rotr(s1324, 1);
+  const SWord8 s4772 = 128 | s4771;
+  const SWord8 s4773 = 127 & s4771;
+  const SWord8 s4774 = s4770 ? s4772 : s4773;
+  const SWord8 s4775 = sbv_bv_u8_rotr(s4774, 1);
+  const SWord8 s4776 = 128 | s4775;
+  const SWord8 s4777 = 127 & s4775;
+  const SWord8 s4778 = s4768 ? s4776 : s4777;
+  const SWord8 s4779 = sbv_bv_u8_rotr(s4778, 1);
+  const SWord8 s4780 = 128 | s4779;
+  const SWord8 s4781 = 127 & s4779;
+  const SWord8 s4782 = s4766 ? s4780 : s4781;
+  const SBool  s4783 = sbv_bv_extract_u8_0_0_u1(s1350);
+  const SBool  s4784 = false != s4783;
+  const SWord8 s4785 = s4784 ? s4780 : s4781;
+  const SWord8 s4786 = s1333 ? s4782 : s4785;
+  const SBool  s4787 = sbv_bv_extract_u8_0_0_u1(s1366);
+  const SBool  s4788 = false != s4787;
+  const SBool  s4789 = sbv_bv_extract_u8_0_0_u1(s1359);
+  const SBool  s4790 = false != s4789;
+  const SWord8 s4791 = s4790 ? s4776 : s4777;
+  const SWord8 s4792 = sbv_bv_u8_rotr(s4791, 1);
+  const SWord8 s4793 = 128 | s4792;
+  const SWord8 s4794 = 127 & s4792;
+  const SWord8 s4795 = s4788 ? s4793 : s4794;
+  const SBool  s4796 = sbv_bv_extract_u8_0_0_u1(s1371);
+  const SBool  s4797 = false != s4796;
+  const SWord8 s4798 = s4797 ? s4793 : s4794;
+  const SWord8 s4799 = s1333 ? s4795 : s4798;
+  const SWord8 s4800 = s1311 ? s4786 : s4799;
+  const SBool  s4801 = sbv_bv_extract_u8_0_0_u1(s1392);
+  const SBool  s4802 = false != s4801;
+  const SBool  s4803 = sbv_bv_extract_u8_0_0_u1(s1388);
+  const SBool  s4804 = false != s4803;
+  const SBool  s4805 = sbv_bv_extract_u8_0_0_u1(s1381);
+  const SBool  s4806 = false != s4805;
+  const SWord8 s4807 = s4806 ? s4772 : s4773;
+  const SWord8 s4808 = sbv_bv_u8_rotr(s4807, 1);
+  const SWord8 s4809 = 128 | s4808;
+  const SWord8 s4810 = 127 & s4808;
+  const SWord8 s4811 = s4804 ? s4809 : s4810;
+  const SWord8 s4812 = sbv_bv_u8_rotr(s4811, 1);
+  const SWord8 s4813 = 128 | s4812;
+  const SWord8 s4814 = 127 & s4812;
+  const SWord8 s4815 = s4802 ? s4813 : s4814;
+  const SBool  s4816 = sbv_bv_extract_u8_0_0_u1(s1397);
+  const SBool  s4817 = false != s4816;
+  const SWord8 s4818 = s4817 ? s4813 : s4814;
+  const SWord8 s4819 = s1333 ? s4815 : s4818;
+  const SBool  s4820 = sbv_bv_extract_u8_0_0_u1(s1413);
+  const SBool  s4821 = false != s4820;
+  const SBool  s4822 = sbv_bv_extract_u8_0_0_u1(s1406);
+  const SBool  s4823 = false != s4822;
+  const SWord8 s4824 = s4823 ? s4809 : s4810;
+  const SWord8 s4825 = sbv_bv_u8_rotr(s4824, 1);
+  const SWord8 s4826 = 128 | s4825;
+  const SWord8 s4827 = 127 & s4825;
+  const SWord8 s4828 = s4821 ? s4826 : s4827;
+  const SBool  s4829 = sbv_bv_extract_u8_0_0_u1(s1418);
+  const SBool  s4830 = false != s4829;
+  const SWord8 s4831 = s4830 ? s4826 : s4827;
+  const SWord8 s4832 = s1333 ? s4828 : s4831;
+  const SWord8 s4833 = s1311 ? s4819 : s4832;
+  const SWord8 s4834 = s1059 ? s4800 : s4833;
+  const SBool  s4835 = sbv_bv_extract_u8_0_0_u1(s1453);
+  const SBool  s4836 = false != s4835;
+  const SBool  s4837 = sbv_bv_extract_u8_0_0_u1(s1449);
+  const SBool  s4838 = false != s4837;
+  const SBool  s4839 = sbv_bv_extract_u8_0_0_u1(s1445);
+  const SBool  s4840 = false != s4839;
+  const SWord8 s4841 = sbv_bv_u8_rotr(s1432, 1);
+  const SWord8 s4842 = 128 | s4841;
+  const SWord8 s4843 = 127 & s4841;
+  const SWord8 s4844 = s4840 ? s4842 : s4843;
+  const SWord8 s4845 = sbv_bv_u8_rotr(s4844, 1);
+  const SWord8 s4846 = 128 | s4845;
+  const SWord8 s4847 = 127 & s4845;
+  const SWord8 s4848 = s4838 ? s4846 : s4847;
+  const SWord8 s4849 = sbv_bv_u8_rotr(s4848, 1);
+  const SWord8 s4850 = 128 | s4849;
+  const SWord8 s4851 = 127 & s4849;
+  const SWord8 s4852 = s4836 ? s4850 : s4851;
+  const SBool  s4853 = sbv_bv_extract_u8_0_0_u1(s1458);
+  const SBool  s4854 = false != s4853;
+  const SWord8 s4855 = s4854 ? s4850 : s4851;
+  const SWord8 s4856 = s1438 ? s4852 : s4855;
+  const SBool  s4857 = sbv_bv_extract_u8_0_0_u1(s1474);
+  const SBool  s4858 = false != s4857;
+  const SBool  s4859 = sbv_bv_extract_u8_0_0_u1(s1467);
+  const SBool  s4860 = false != s4859;
+  const SWord8 s4861 = s4860 ? s4846 : s4847;
+  const SWord8 s4862 = sbv_bv_u8_rotr(s4861, 1);
+  const SWord8 s4863 = 128 | s4862;
+  const SWord8 s4864 = 127 & s4862;
+  const SWord8 s4865 = s4858 ? s4863 : s4864;
+  const SBool  s4866 = sbv_bv_extract_u8_0_0_u1(s1479);
+  const SBool  s4867 = false != s4866;
+  const SWord8 s4868 = s4867 ? s4863 : s4864;
+  const SWord8 s4869 = s1438 ? s4865 : s4868;
+  const SWord8 s4870 = s1311 ? s4856 : s4869;
+  const SBool  s4871 = sbv_bv_extract_u8_0_0_u1(s1500);
+  const SBool  s4872 = false != s4871;
+  const SBool  s4873 = sbv_bv_extract_u8_0_0_u1(s1496);
+  const SBool  s4874 = false != s4873;
+  const SBool  s4875 = sbv_bv_extract_u8_0_0_u1(s1489);
+  const SBool  s4876 = false != s4875;
+  const SWord8 s4877 = s4876 ? s4842 : s4843;
+  const SWord8 s4878 = sbv_bv_u8_rotr(s4877, 1);
+  const SWord8 s4879 = 128 | s4878;
+  const SWord8 s4880 = 127 & s4878;
+  const SWord8 s4881 = s4874 ? s4879 : s4880;
+  const SWord8 s4882 = sbv_bv_u8_rotr(s4881, 1);
+  const SWord8 s4883 = 128 | s4882;
+  const SWord8 s4884 = 127 & s4882;
+  const SWord8 s4885 = s4872 ? s4883 : s4884;
+  const SBool  s4886 = sbv_bv_extract_u8_0_0_u1(s1505);
+  const SBool  s4887 = false != s4886;
+  const SWord8 s4888 = s4887 ? s4883 : s4884;
+  const SWord8 s4889 = s1438 ? s4885 : s4888;
+  const SBool  s4890 = sbv_bv_extract_u8_0_0_u1(s1521);
+  const SBool  s4891 = false != s4890;
+  const SBool  s4892 = sbv_bv_extract_u8_0_0_u1(s1514);
+  const SBool  s4893 = false != s4892;
+  const SWord8 s4894 = s4893 ? s4879 : s4880;
+  const SWord8 s4895 = sbv_bv_u8_rotr(s4894, 1);
+  const SWord8 s4896 = 128 | s4895;
+  const SWord8 s4897 = 127 & s4895;
+  const SWord8 s4898 = s4891 ? s4896 : s4897;
+  const SBool  s4899 = sbv_bv_extract_u8_0_0_u1(s1526);
+  const SBool  s4900 = false != s4899;
+  const SWord8 s4901 = s4900 ? s4896 : s4897;
+  const SWord8 s4902 = s1438 ? s4898 : s4901;
+  const SWord8 s4903 = s1311 ? s4889 : s4902;
+  const SWord8 s4904 = s1059 ? s4870 : s4903;
+  const SWord8 s4905 = s1037 ? s4834 : s4904;
+  const SWord8 s4906 = s21 ? s4764 : s4905;
+  const SBool  s4907 = sbv_bv_extract_u8_0_0_u1(s1601);
+  const SBool  s4908 = false != s4907;
+  const SBool  s4909 = sbv_bv_extract_u8_0_0_u1(s1597);
+  const SBool  s4910 = false != s4909;
+  const SBool  s4911 = sbv_bv_extract_u8_0_0_u1(s1593);
+  const SBool  s4912 = false != s4911;
+  const SWord8 s4913 = sbv_bv_u8_rotr(s1580, 1);
+  const SWord8 s4914 = 128 | s4913;
+  const SWord8 s4915 = 127 & s4913;
+  const SWord8 s4916 = s4912 ? s4914 : s4915;
+  const SWord8 s4917 = sbv_bv_u8_rotr(s4916, 1);
+  const SWord8 s4918 = 128 | s4917;
+  const SWord8 s4919 = 127 & s4917;
+  const SWord8 s4920 = s4910 ? s4918 : s4919;
+  const SWord8 s4921 = sbv_bv_u8_rotr(s4920, 1);
+  const SWord8 s4922 = 128 | s4921;
+  const SWord8 s4923 = 127 & s4921;
+  const SWord8 s4924 = s4908 ? s4922 : s4923;
+  const SBool  s4925 = sbv_bv_extract_u8_0_0_u1(s1606);
+  const SBool  s4926 = false != s4925;
+  const SWord8 s4927 = s4926 ? s4922 : s4923;
+  const SWord8 s4928 = s1589 ? s4924 : s4927;
+  const SBool  s4929 = sbv_bv_extract_u8_0_0_u1(s1622);
+  const SBool  s4930 = false != s4929;
+  const SBool  s4931 = sbv_bv_extract_u8_0_0_u1(s1615);
+  const SBool  s4932 = false != s4931;
+  const SWord8 s4933 = s4932 ? s4918 : s4919;
+  const SWord8 s4934 = sbv_bv_u8_rotr(s4933, 1);
+  const SWord8 s4935 = 128 | s4934;
+  const SWord8 s4936 = 127 & s4934;
+  const SWord8 s4937 = s4930 ? s4935 : s4936;
+  const SBool  s4938 = sbv_bv_extract_u8_0_0_u1(s1627);
+  const SBool  s4939 = false != s4938;
+  const SWord8 s4940 = s4939 ? s4935 : s4936;
+  const SWord8 s4941 = s1589 ? s4937 : s4940;
+  const SWord8 s4942 = s1570 ? s4928 : s4941;
+  const SBool  s4943 = sbv_bv_extract_u8_0_0_u1(s1648);
+  const SBool  s4944 = false != s4943;
+  const SBool  s4945 = sbv_bv_extract_u8_0_0_u1(s1644);
+  const SBool  s4946 = false != s4945;
+  const SBool  s4947 = sbv_bv_extract_u8_0_0_u1(s1637);
+  const SBool  s4948 = false != s4947;
+  const SWord8 s4949 = s4948 ? s4914 : s4915;
+  const SWord8 s4950 = sbv_bv_u8_rotr(s4949, 1);
+  const SWord8 s4951 = 128 | s4950;
+  const SWord8 s4952 = 127 & s4950;
+  const SWord8 s4953 = s4946 ? s4951 : s4952;
+  const SWord8 s4954 = sbv_bv_u8_rotr(s4953, 1);
+  const SWord8 s4955 = 128 | s4954;
+  const SWord8 s4956 = 127 & s4954;
+  const SWord8 s4957 = s4944 ? s4955 : s4956;
+  const SBool  s4958 = sbv_bv_extract_u8_0_0_u1(s1653);
+  const SBool  s4959 = false != s4958;
+  const SWord8 s4960 = s4959 ? s4955 : s4956;
+  const SWord8 s4961 = s1589 ? s4957 : s4960;
+  const SBool  s4962 = sbv_bv_extract_u8_0_0_u1(s1669);
+  const SBool  s4963 = false != s4962;
+  const SBool  s4964 = sbv_bv_extract_u8_0_0_u1(s1662);
+  const SBool  s4965 = false != s4964;
+  const SWord8 s4966 = s4965 ? s4951 : s4952;
+  const SWord8 s4967 = sbv_bv_u8_rotr(s4966, 1);
+  const SWord8 s4968 = 128 | s4967;
+  const SWord8 s4969 = 127 & s4967;
+  const SWord8 s4970 = s4963 ? s4968 : s4969;
+  const SBool  s4971 = sbv_bv_extract_u8_0_0_u1(s1674);
+  const SBool  s4972 = false != s4971;
+  const SWord8 s4973 = s4972 ? s4968 : s4969;
+  const SWord8 s4974 = s1589 ? s4970 : s4973;
+  const SWord8 s4975 = s1570 ? s4961 : s4974;
+  const SWord8 s4976 = s1548 ? s4942 : s4975;
+  const SBool  s4977 = sbv_bv_extract_u8_0_0_u1(s1709);
+  const SBool  s4978 = false != s4977;
+  const SBool  s4979 = sbv_bv_extract_u8_0_0_u1(s1705);
+  const SBool  s4980 = false != s4979;
+  const SBool  s4981 = sbv_bv_extract_u8_0_0_u1(s1701);
+  const SBool  s4982 = false != s4981;
+  const SWord8 s4983 = sbv_bv_u8_rotr(s1688, 1);
+  const SWord8 s4984 = 128 | s4983;
+  const SWord8 s4985 = 127 & s4983;
+  const SWord8 s4986 = s4982 ? s4984 : s4985;
+  const SWord8 s4987 = sbv_bv_u8_rotr(s4986, 1);
+  const SWord8 s4988 = 128 | s4987;
+  const SWord8 s4989 = 127 & s4987;
+  const SWord8 s4990 = s4980 ? s4988 : s4989;
+  const SWord8 s4991 = sbv_bv_u8_rotr(s4990, 1);
+  const SWord8 s4992 = 128 | s4991;
+  const SWord8 s4993 = 127 & s4991;
+  const SWord8 s4994 = s4978 ? s4992 : s4993;
+  const SBool  s4995 = sbv_bv_extract_u8_0_0_u1(s1714);
+  const SBool  s4996 = false != s4995;
+  const SWord8 s4997 = s4996 ? s4992 : s4993;
+  const SWord8 s4998 = s1694 ? s4994 : s4997;
+  const SBool  s4999 = sbv_bv_extract_u8_0_0_u1(s1730);
+  const SBool  s5000 = false != s4999;
+  const SBool  s5001 = sbv_bv_extract_u8_0_0_u1(s1723);
+  const SBool  s5002 = false != s5001;
+  const SWord8 s5003 = s5002 ? s4988 : s4989;
+  const SWord8 s5004 = sbv_bv_u8_rotr(s5003, 1);
+  const SWord8 s5005 = 128 | s5004;
+  const SWord8 s5006 = 127 & s5004;
+  const SWord8 s5007 = s5000 ? s5005 : s5006;
+  const SBool  s5008 = sbv_bv_extract_u8_0_0_u1(s1735);
+  const SBool  s5009 = false != s5008;
+  const SWord8 s5010 = s5009 ? s5005 : s5006;
+  const SWord8 s5011 = s1694 ? s5007 : s5010;
+  const SWord8 s5012 = s1570 ? s4998 : s5011;
+  const SBool  s5013 = sbv_bv_extract_u8_0_0_u1(s1756);
+  const SBool  s5014 = false != s5013;
+  const SBool  s5015 = sbv_bv_extract_u8_0_0_u1(s1752);
+  const SBool  s5016 = false != s5015;
+  const SBool  s5017 = sbv_bv_extract_u8_0_0_u1(s1745);
+  const SBool  s5018 = false != s5017;
+  const SWord8 s5019 = s5018 ? s4984 : s4985;
+  const SWord8 s5020 = sbv_bv_u8_rotr(s5019, 1);
+  const SWord8 s5021 = 128 | s5020;
+  const SWord8 s5022 = 127 & s5020;
+  const SWord8 s5023 = s5016 ? s5021 : s5022;
+  const SWord8 s5024 = sbv_bv_u8_rotr(s5023, 1);
+  const SWord8 s5025 = 128 | s5024;
+  const SWord8 s5026 = 127 & s5024;
+  const SWord8 s5027 = s5014 ? s5025 : s5026;
+  const SBool  s5028 = sbv_bv_extract_u8_0_0_u1(s1761);
+  const SBool  s5029 = false != s5028;
+  const SWord8 s5030 = s5029 ? s5025 : s5026;
+  const SWord8 s5031 = s1694 ? s5027 : s5030;
+  const SBool  s5032 = sbv_bv_extract_u8_0_0_u1(s1777);
+  const SBool  s5033 = false != s5032;
+  const SBool  s5034 = sbv_bv_extract_u8_0_0_u1(s1770);
+  const SBool  s5035 = false != s5034;
+  const SWord8 s5036 = s5035 ? s5021 : s5022;
+  const SWord8 s5037 = sbv_bv_u8_rotr(s5036, 1);
+  const SWord8 s5038 = 128 | s5037;
+  const SWord8 s5039 = 127 & s5037;
+  const SWord8 s5040 = s5033 ? s5038 : s5039;
+  const SBool  s5041 = sbv_bv_extract_u8_0_0_u1(s1782);
+  const SBool  s5042 = false != s5041;
+  const SWord8 s5043 = s5042 ? s5038 : s5039;
+  const SWord8 s5044 = s1694 ? s5040 : s5043;
+  const SWord8 s5045 = s1570 ? s5031 : s5044;
+  const SWord8 s5046 = s1548 ? s5012 : s5045;
+  const SWord8 s5047 = s1037 ? s4976 : s5046;
+  const SBool  s5048 = sbv_bv_extract_u8_0_0_u1(s1837);
+  const SBool  s5049 = false != s5048;
+  const SBool  s5050 = sbv_bv_extract_u8_0_0_u1(s1833);
+  const SBool  s5051 = false != s5050;
+  const SBool  s5052 = sbv_bv_extract_u8_0_0_u1(s1829);
+  const SBool  s5053 = false != s5052;
+  const SWord8 s5054 = sbv_bv_u8_rotr(s1816, 1);
+  const SWord8 s5055 = 128 | s5054;
+  const SWord8 s5056 = 127 & s5054;
+  const SWord8 s5057 = s5053 ? s5055 : s5056;
+  const SWord8 s5058 = sbv_bv_u8_rotr(s5057, 1);
+  const SWord8 s5059 = 128 | s5058;
+  const SWord8 s5060 = 127 & s5058;
+  const SWord8 s5061 = s5051 ? s5059 : s5060;
+  const SWord8 s5062 = sbv_bv_u8_rotr(s5061, 1);
+  const SWord8 s5063 = 128 | s5062;
+  const SWord8 s5064 = 127 & s5062;
+  const SWord8 s5065 = s5049 ? s5063 : s5064;
+  const SBool  s5066 = sbv_bv_extract_u8_0_0_u1(s1842);
+  const SBool  s5067 = false != s5066;
+  const SWord8 s5068 = s5067 ? s5063 : s5064;
+  const SWord8 s5069 = s1825 ? s5065 : s5068;
+  const SBool  s5070 = sbv_bv_extract_u8_0_0_u1(s1858);
+  const SBool  s5071 = false != s5070;
+  const SBool  s5072 = sbv_bv_extract_u8_0_0_u1(s1851);
+  const SBool  s5073 = false != s5072;
+  const SWord8 s5074 = s5073 ? s5059 : s5060;
+  const SWord8 s5075 = sbv_bv_u8_rotr(s5074, 1);
+  const SWord8 s5076 = 128 | s5075;
+  const SWord8 s5077 = 127 & s5075;
+  const SWord8 s5078 = s5071 ? s5076 : s5077;
+  const SBool  s5079 = sbv_bv_extract_u8_0_0_u1(s1863);
+  const SBool  s5080 = false != s5079;
+  const SWord8 s5081 = s5080 ? s5076 : s5077;
+  const SWord8 s5082 = s1825 ? s5078 : s5081;
+  const SWord8 s5083 = s1803 ? s5069 : s5082;
+  const SBool  s5084 = sbv_bv_extract_u8_0_0_u1(s1884);
+  const SBool  s5085 = false != s5084;
+  const SBool  s5086 = sbv_bv_extract_u8_0_0_u1(s1880);
+  const SBool  s5087 = false != s5086;
+  const SBool  s5088 = sbv_bv_extract_u8_0_0_u1(s1873);
+  const SBool  s5089 = false != s5088;
+  const SWord8 s5090 = s5089 ? s5055 : s5056;
+  const SWord8 s5091 = sbv_bv_u8_rotr(s5090, 1);
+  const SWord8 s5092 = 128 | s5091;
+  const SWord8 s5093 = 127 & s5091;
+  const SWord8 s5094 = s5087 ? s5092 : s5093;
+  const SWord8 s5095 = sbv_bv_u8_rotr(s5094, 1);
+  const SWord8 s5096 = 128 | s5095;
+  const SWord8 s5097 = 127 & s5095;
+  const SWord8 s5098 = s5085 ? s5096 : s5097;
+  const SBool  s5099 = sbv_bv_extract_u8_0_0_u1(s1889);
+  const SBool  s5100 = false != s5099;
+  const SWord8 s5101 = s5100 ? s5096 : s5097;
+  const SWord8 s5102 = s1825 ? s5098 : s5101;
+  const SBool  s5103 = sbv_bv_extract_u8_0_0_u1(s1905);
+  const SBool  s5104 = false != s5103;
+  const SBool  s5105 = sbv_bv_extract_u8_0_0_u1(s1898);
+  const SBool  s5106 = false != s5105;
+  const SWord8 s5107 = s5106 ? s5092 : s5093;
+  const SWord8 s5108 = sbv_bv_u8_rotr(s5107, 1);
+  const SWord8 s5109 = 128 | s5108;
+  const SWord8 s5110 = 127 & s5108;
+  const SWord8 s5111 = s5104 ? s5109 : s5110;
+  const SBool  s5112 = sbv_bv_extract_u8_0_0_u1(s1910);
+  const SBool  s5113 = false != s5112;
+  const SWord8 s5114 = s5113 ? s5109 : s5110;
+  const SWord8 s5115 = s1825 ? s5111 : s5114;
+  const SWord8 s5116 = s1803 ? s5102 : s5115;
+  const SWord8 s5117 = s1548 ? s5083 : s5116;
+  const SBool  s5118 = sbv_bv_extract_u8_0_0_u1(s1945);
+  const SBool  s5119 = false != s5118;
+  const SBool  s5120 = sbv_bv_extract_u8_0_0_u1(s1941);
+  const SBool  s5121 = false != s5120;
+  const SBool  s5122 = sbv_bv_extract_u8_0_0_u1(s1937);
+  const SBool  s5123 = false != s5122;
+  const SWord8 s5124 = sbv_bv_u8_rotr(s1924, 1);
+  const SWord8 s5125 = 128 | s5124;
+  const SWord8 s5126 = 127 & s5124;
+  const SWord8 s5127 = s5123 ? s5125 : s5126;
+  const SWord8 s5128 = sbv_bv_u8_rotr(s5127, 1);
+  const SWord8 s5129 = 128 | s5128;
+  const SWord8 s5130 = 127 & s5128;
+  const SWord8 s5131 = s5121 ? s5129 : s5130;
+  const SWord8 s5132 = sbv_bv_u8_rotr(s5131, 1);
+  const SWord8 s5133 = 128 | s5132;
+  const SWord8 s5134 = 127 & s5132;
+  const SWord8 s5135 = s5119 ? s5133 : s5134;
+  const SBool  s5136 = sbv_bv_extract_u8_0_0_u1(s1950);
+  const SBool  s5137 = false != s5136;
+  const SWord8 s5138 = s5137 ? s5133 : s5134;
+  const SWord8 s5139 = s1930 ? s5135 : s5138;
+  const SBool  s5140 = sbv_bv_extract_u8_0_0_u1(s1966);
+  const SBool  s5141 = false != s5140;
+  const SBool  s5142 = sbv_bv_extract_u8_0_0_u1(s1959);
+  const SBool  s5143 = false != s5142;
+  const SWord8 s5144 = s5143 ? s5129 : s5130;
+  const SWord8 s5145 = sbv_bv_u8_rotr(s5144, 1);
+  const SWord8 s5146 = 128 | s5145;
+  const SWord8 s5147 = 127 & s5145;
+  const SWord8 s5148 = s5141 ? s5146 : s5147;
+  const SBool  s5149 = sbv_bv_extract_u8_0_0_u1(s1971);
+  const SBool  s5150 = false != s5149;
+  const SWord8 s5151 = s5150 ? s5146 : s5147;
+  const SWord8 s5152 = s1930 ? s5148 : s5151;
+  const SWord8 s5153 = s1803 ? s5139 : s5152;
+  const SBool  s5154 = sbv_bv_extract_u8_0_0_u1(s1992);
+  const SBool  s5155 = false != s5154;
+  const SBool  s5156 = sbv_bv_extract_u8_0_0_u1(s1988);
+  const SBool  s5157 = false != s5156;
+  const SBool  s5158 = sbv_bv_extract_u8_0_0_u1(s1981);
+  const SBool  s5159 = false != s5158;
+  const SWord8 s5160 = s5159 ? s5125 : s5126;
+  const SWord8 s5161 = sbv_bv_u8_rotr(s5160, 1);
+  const SWord8 s5162 = 128 | s5161;
+  const SWord8 s5163 = 127 & s5161;
+  const SWord8 s5164 = s5157 ? s5162 : s5163;
+  const SWord8 s5165 = sbv_bv_u8_rotr(s5164, 1);
+  const SWord8 s5166 = 128 | s5165;
+  const SWord8 s5167 = 127 & s5165;
+  const SWord8 s5168 = s5155 ? s5166 : s5167;
+  const SBool  s5169 = sbv_bv_extract_u8_0_0_u1(s1997);
+  const SBool  s5170 = false != s5169;
+  const SWord8 s5171 = s5170 ? s5166 : s5167;
+  const SWord8 s5172 = s1930 ? s5168 : s5171;
+  const SBool  s5173 = sbv_bv_extract_u8_0_0_u1(s2013);
+  const SBool  s5174 = false != s5173;
+  const SBool  s5175 = sbv_bv_extract_u8_0_0_u1(s2006);
+  const SBool  s5176 = false != s5175;
+  const SWord8 s5177 = s5176 ? s5162 : s5163;
+  const SWord8 s5178 = sbv_bv_u8_rotr(s5177, 1);
+  const SWord8 s5179 = 128 | s5178;
+  const SWord8 s5180 = 127 & s5178;
+  const SWord8 s5181 = s5174 ? s5179 : s5180;
+  const SBool  s5182 = sbv_bv_extract_u8_0_0_u1(s2018);
+  const SBool  s5183 = false != s5182;
+  const SWord8 s5184 = s5183 ? s5179 : s5180;
+  const SWord8 s5185 = s1930 ? s5181 : s5184;
+  const SWord8 s5186 = s1803 ? s5172 : s5185;
+  const SWord8 s5187 = s1548 ? s5153 : s5186;
+  const SWord8 s5188 = s1037 ? s5117 : s5187;
+  const SWord8 s5189 = s21 ? s5047 : s5188;
+  const SWord8 s5190 = s16 ? s4906 : s5189;
+  const SWord8 s5191 = s11 ? s4623 : s5190;
+  const SBool  s5192 = sbv_bv_extract_u8_0_0_u1(s2128);
+  const SBool  s5193 = false != s5192;
+  const SBool  s5194 = sbv_bv_extract_u8_0_0_u1(s2124);
+  const SBool  s5195 = false != s5194;
+  const SBool  s5196 = sbv_bv_extract_u8_0_0_u1(s2120);
+  const SBool  s5197 = false != s5196;
+  const SWord8 s5198 = sbv_bv_u8_rotr(s2107, 1);
+  const SWord8 s5199 = 128 | s5198;
+  const SWord8 s5200 = 127 & s5198;
+  const SWord8 s5201 = s5197 ? s5199 : s5200;
+  const SWord8 s5202 = sbv_bv_u8_rotr(s5201, 1);
+  const SWord8 s5203 = 128 | s5202;
+  const SWord8 s5204 = 127 & s5202;
+  const SWord8 s5205 = s5195 ? s5203 : s5204;
+  const SWord8 s5206 = sbv_bv_u8_rotr(s5205, 1);
+  const SWord8 s5207 = 128 | s5206;
+  const SWord8 s5208 = 127 & s5206;
+  const SWord8 s5209 = s5193 ? s5207 : s5208;
+  const SBool  s5210 = sbv_bv_extract_u8_0_0_u1(s2133);
+  const SBool  s5211 = false != s5210;
+  const SWord8 s5212 = s5211 ? s5207 : s5208;
+  const SWord8 s5213 = s2116 ? s5209 : s5212;
+  const SBool  s5214 = sbv_bv_extract_u8_0_0_u1(s2149);
+  const SBool  s5215 = false != s5214;
+  const SBool  s5216 = sbv_bv_extract_u8_0_0_u1(s2142);
+  const SBool  s5217 = false != s5216;
+  const SWord8 s5218 = s5217 ? s5203 : s5204;
+  const SWord8 s5219 = sbv_bv_u8_rotr(s5218, 1);
+  const SWord8 s5220 = 128 | s5219;
+  const SWord8 s5221 = 127 & s5219;
+  const SWord8 s5222 = s5215 ? s5220 : s5221;
+  const SBool  s5223 = sbv_bv_extract_u8_0_0_u1(s2154);
+  const SBool  s5224 = false != s5223;
+  const SWord8 s5225 = s5224 ? s5220 : s5221;
+  const SWord8 s5226 = s2116 ? s5222 : s5225;
+  const SWord8 s5227 = s2097 ? s5213 : s5226;
+  const SBool  s5228 = sbv_bv_extract_u8_0_0_u1(s2175);
+  const SBool  s5229 = false != s5228;
+  const SBool  s5230 = sbv_bv_extract_u8_0_0_u1(s2171);
+  const SBool  s5231 = false != s5230;
+  const SBool  s5232 = sbv_bv_extract_u8_0_0_u1(s2164);
+  const SBool  s5233 = false != s5232;
+  const SWord8 s5234 = s5233 ? s5199 : s5200;
+  const SWord8 s5235 = sbv_bv_u8_rotr(s5234, 1);
+  const SWord8 s5236 = 128 | s5235;
+  const SWord8 s5237 = 127 & s5235;
+  const SWord8 s5238 = s5231 ? s5236 : s5237;
+  const SWord8 s5239 = sbv_bv_u8_rotr(s5238, 1);
+  const SWord8 s5240 = 128 | s5239;
+  const SWord8 s5241 = 127 & s5239;
+  const SWord8 s5242 = s5229 ? s5240 : s5241;
+  const SBool  s5243 = sbv_bv_extract_u8_0_0_u1(s2180);
+  const SBool  s5244 = false != s5243;
+  const SWord8 s5245 = s5244 ? s5240 : s5241;
+  const SWord8 s5246 = s2116 ? s5242 : s5245;
+  const SBool  s5247 = sbv_bv_extract_u8_0_0_u1(s2196);
+  const SBool  s5248 = false != s5247;
+  const SBool  s5249 = sbv_bv_extract_u8_0_0_u1(s2189);
+  const SBool  s5250 = false != s5249;
+  const SWord8 s5251 = s5250 ? s5236 : s5237;
+  const SWord8 s5252 = sbv_bv_u8_rotr(s5251, 1);
+  const SWord8 s5253 = 128 | s5252;
+  const SWord8 s5254 = 127 & s5252;
+  const SWord8 s5255 = s5248 ? s5253 : s5254;
+  const SBool  s5256 = sbv_bv_extract_u8_0_0_u1(s2201);
+  const SBool  s5257 = false != s5256;
+  const SWord8 s5258 = s5257 ? s5253 : s5254;
+  const SWord8 s5259 = s2116 ? s5255 : s5258;
+  const SWord8 s5260 = s2097 ? s5246 : s5259;
+  const SWord8 s5261 = s2078 ? s5227 : s5260;
+  const SBool  s5262 = sbv_bv_extract_u8_0_0_u1(s2236);
+  const SBool  s5263 = false != s5262;
+  const SBool  s5264 = sbv_bv_extract_u8_0_0_u1(s2232);
+  const SBool  s5265 = false != s5264;
+  const SBool  s5266 = sbv_bv_extract_u8_0_0_u1(s2228);
+  const SBool  s5267 = false != s5266;
+  const SWord8 s5268 = sbv_bv_u8_rotr(s2215, 1);
+  const SWord8 s5269 = 128 | s5268;
+  const SWord8 s5270 = 127 & s5268;
+  const SWord8 s5271 = s5267 ? s5269 : s5270;
+  const SWord8 s5272 = sbv_bv_u8_rotr(s5271, 1);
+  const SWord8 s5273 = 128 | s5272;
+  const SWord8 s5274 = 127 & s5272;
+  const SWord8 s5275 = s5265 ? s5273 : s5274;
+  const SWord8 s5276 = sbv_bv_u8_rotr(s5275, 1);
+  const SWord8 s5277 = 128 | s5276;
+  const SWord8 s5278 = 127 & s5276;
+  const SWord8 s5279 = s5263 ? s5277 : s5278;
+  const SBool  s5280 = sbv_bv_extract_u8_0_0_u1(s2241);
+  const SBool  s5281 = false != s5280;
+  const SWord8 s5282 = s5281 ? s5277 : s5278;
+  const SWord8 s5283 = s2221 ? s5279 : s5282;
+  const SBool  s5284 = sbv_bv_extract_u8_0_0_u1(s2257);
+  const SBool  s5285 = false != s5284;
+  const SBool  s5286 = sbv_bv_extract_u8_0_0_u1(s2250);
+  const SBool  s5287 = false != s5286;
+  const SWord8 s5288 = s5287 ? s5273 : s5274;
+  const SWord8 s5289 = sbv_bv_u8_rotr(s5288, 1);
+  const SWord8 s5290 = 128 | s5289;
+  const SWord8 s5291 = 127 & s5289;
+  const SWord8 s5292 = s5285 ? s5290 : s5291;
+  const SBool  s5293 = sbv_bv_extract_u8_0_0_u1(s2262);
+  const SBool  s5294 = false != s5293;
+  const SWord8 s5295 = s5294 ? s5290 : s5291;
+  const SWord8 s5296 = s2221 ? s5292 : s5295;
+  const SWord8 s5297 = s2097 ? s5283 : s5296;
+  const SBool  s5298 = sbv_bv_extract_u8_0_0_u1(s2283);
+  const SBool  s5299 = false != s5298;
+  const SBool  s5300 = sbv_bv_extract_u8_0_0_u1(s2279);
+  const SBool  s5301 = false != s5300;
+  const SBool  s5302 = sbv_bv_extract_u8_0_0_u1(s2272);
+  const SBool  s5303 = false != s5302;
+  const SWord8 s5304 = s5303 ? s5269 : s5270;
+  const SWord8 s5305 = sbv_bv_u8_rotr(s5304, 1);
+  const SWord8 s5306 = 128 | s5305;
+  const SWord8 s5307 = 127 & s5305;
+  const SWord8 s5308 = s5301 ? s5306 : s5307;
+  const SWord8 s5309 = sbv_bv_u8_rotr(s5308, 1);
+  const SWord8 s5310 = 128 | s5309;
+  const SWord8 s5311 = 127 & s5309;
+  const SWord8 s5312 = s5299 ? s5310 : s5311;
+  const SBool  s5313 = sbv_bv_extract_u8_0_0_u1(s2288);
+  const SBool  s5314 = false != s5313;
+  const SWord8 s5315 = s5314 ? s5310 : s5311;
+  const SWord8 s5316 = s2221 ? s5312 : s5315;
+  const SBool  s5317 = sbv_bv_extract_u8_0_0_u1(s2304);
+  const SBool  s5318 = false != s5317;
+  const SBool  s5319 = sbv_bv_extract_u8_0_0_u1(s2297);
+  const SBool  s5320 = false != s5319;
+  const SWord8 s5321 = s5320 ? s5306 : s5307;
+  const SWord8 s5322 = sbv_bv_u8_rotr(s5321, 1);
+  const SWord8 s5323 = 128 | s5322;
+  const SWord8 s5324 = 127 & s5322;
+  const SWord8 s5325 = s5318 ? s5323 : s5324;
+  const SBool  s5326 = sbv_bv_extract_u8_0_0_u1(s2309);
+  const SBool  s5327 = false != s5326;
+  const SWord8 s5328 = s5327 ? s5323 : s5324;
+  const SWord8 s5329 = s2221 ? s5325 : s5328;
+  const SWord8 s5330 = s2097 ? s5316 : s5329;
+  const SWord8 s5331 = s2078 ? s5297 : s5330;
+  const SWord8 s5332 = s2059 ? s5261 : s5331;
+  const SBool  s5333 = sbv_bv_extract_u8_0_0_u1(s2364);
+  const SBool  s5334 = false != s5333;
+  const SBool  s5335 = sbv_bv_extract_u8_0_0_u1(s2360);
+  const SBool  s5336 = false != s5335;
+  const SBool  s5337 = sbv_bv_extract_u8_0_0_u1(s2356);
+  const SBool  s5338 = false != s5337;
+  const SWord8 s5339 = sbv_bv_u8_rotr(s2343, 1);
+  const SWord8 s5340 = 128 | s5339;
+  const SWord8 s5341 = 127 & s5339;
+  const SWord8 s5342 = s5338 ? s5340 : s5341;
+  const SWord8 s5343 = sbv_bv_u8_rotr(s5342, 1);
+  const SWord8 s5344 = 128 | s5343;
+  const SWord8 s5345 = 127 & s5343;
+  const SWord8 s5346 = s5336 ? s5344 : s5345;
+  const SWord8 s5347 = sbv_bv_u8_rotr(s5346, 1);
+  const SWord8 s5348 = 128 | s5347;
+  const SWord8 s5349 = 127 & s5347;
+  const SWord8 s5350 = s5334 ? s5348 : s5349;
+  const SBool  s5351 = sbv_bv_extract_u8_0_0_u1(s2369);
+  const SBool  s5352 = false != s5351;
+  const SWord8 s5353 = s5352 ? s5348 : s5349;
+  const SWord8 s5354 = s2352 ? s5350 : s5353;
+  const SBool  s5355 = sbv_bv_extract_u8_0_0_u1(s2385);
+  const SBool  s5356 = false != s5355;
+  const SBool  s5357 = sbv_bv_extract_u8_0_0_u1(s2378);
+  const SBool  s5358 = false != s5357;
+  const SWord8 s5359 = s5358 ? s5344 : s5345;
+  const SWord8 s5360 = sbv_bv_u8_rotr(s5359, 1);
+  const SWord8 s5361 = 128 | s5360;
+  const SWord8 s5362 = 127 & s5360;
+  const SWord8 s5363 = s5356 ? s5361 : s5362;
+  const SBool  s5364 = sbv_bv_extract_u8_0_0_u1(s2390);
+  const SBool  s5365 = false != s5364;
+  const SWord8 s5366 = s5365 ? s5361 : s5362;
+  const SWord8 s5367 = s2352 ? s5363 : s5366;
+  const SWord8 s5368 = s2330 ? s5354 : s5367;
+  const SBool  s5369 = sbv_bv_extract_u8_0_0_u1(s2411);
+  const SBool  s5370 = false != s5369;
+  const SBool  s5371 = sbv_bv_extract_u8_0_0_u1(s2407);
+  const SBool  s5372 = false != s5371;
+  const SBool  s5373 = sbv_bv_extract_u8_0_0_u1(s2400);
+  const SBool  s5374 = false != s5373;
+  const SWord8 s5375 = s5374 ? s5340 : s5341;
+  const SWord8 s5376 = sbv_bv_u8_rotr(s5375, 1);
+  const SWord8 s5377 = 128 | s5376;
+  const SWord8 s5378 = 127 & s5376;
+  const SWord8 s5379 = s5372 ? s5377 : s5378;
+  const SWord8 s5380 = sbv_bv_u8_rotr(s5379, 1);
+  const SWord8 s5381 = 128 | s5380;
+  const SWord8 s5382 = 127 & s5380;
+  const SWord8 s5383 = s5370 ? s5381 : s5382;
+  const SBool  s5384 = sbv_bv_extract_u8_0_0_u1(s2416);
+  const SBool  s5385 = false != s5384;
+  const SWord8 s5386 = s5385 ? s5381 : s5382;
+  const SWord8 s5387 = s2352 ? s5383 : s5386;
+  const SBool  s5388 = sbv_bv_extract_u8_0_0_u1(s2432);
+  const SBool  s5389 = false != s5388;
+  const SBool  s5390 = sbv_bv_extract_u8_0_0_u1(s2425);
+  const SBool  s5391 = false != s5390;
+  const SWord8 s5392 = s5391 ? s5377 : s5378;
+  const SWord8 s5393 = sbv_bv_u8_rotr(s5392, 1);
+  const SWord8 s5394 = 128 | s5393;
+  const SWord8 s5395 = 127 & s5393;
+  const SWord8 s5396 = s5389 ? s5394 : s5395;
+  const SBool  s5397 = sbv_bv_extract_u8_0_0_u1(s2437);
+  const SBool  s5398 = false != s5397;
+  const SWord8 s5399 = s5398 ? s5394 : s5395;
+  const SWord8 s5400 = s2352 ? s5396 : s5399;
+  const SWord8 s5401 = s2330 ? s5387 : s5400;
+  const SWord8 s5402 = s2078 ? s5368 : s5401;
+  const SBool  s5403 = sbv_bv_extract_u8_0_0_u1(s2472);
+  const SBool  s5404 = false != s5403;
+  const SBool  s5405 = sbv_bv_extract_u8_0_0_u1(s2468);
+  const SBool  s5406 = false != s5405;
+  const SBool  s5407 = sbv_bv_extract_u8_0_0_u1(s2464);
+  const SBool  s5408 = false != s5407;
+  const SWord8 s5409 = sbv_bv_u8_rotr(s2451, 1);
+  const SWord8 s5410 = 128 | s5409;
+  const SWord8 s5411 = 127 & s5409;
+  const SWord8 s5412 = s5408 ? s5410 : s5411;
+  const SWord8 s5413 = sbv_bv_u8_rotr(s5412, 1);
+  const SWord8 s5414 = 128 | s5413;
+  const SWord8 s5415 = 127 & s5413;
+  const SWord8 s5416 = s5406 ? s5414 : s5415;
+  const SWord8 s5417 = sbv_bv_u8_rotr(s5416, 1);
+  const SWord8 s5418 = 128 | s5417;
+  const SWord8 s5419 = 127 & s5417;
+  const SWord8 s5420 = s5404 ? s5418 : s5419;
+  const SBool  s5421 = sbv_bv_extract_u8_0_0_u1(s2477);
+  const SBool  s5422 = false != s5421;
+  const SWord8 s5423 = s5422 ? s5418 : s5419;
+  const SWord8 s5424 = s2457 ? s5420 : s5423;
+  const SBool  s5425 = sbv_bv_extract_u8_0_0_u1(s2493);
+  const SBool  s5426 = false != s5425;
+  const SBool  s5427 = sbv_bv_extract_u8_0_0_u1(s2486);
+  const SBool  s5428 = false != s5427;
+  const SWord8 s5429 = s5428 ? s5414 : s5415;
+  const SWord8 s5430 = sbv_bv_u8_rotr(s5429, 1);
+  const SWord8 s5431 = 128 | s5430;
+  const SWord8 s5432 = 127 & s5430;
+  const SWord8 s5433 = s5426 ? s5431 : s5432;
+  const SBool  s5434 = sbv_bv_extract_u8_0_0_u1(s2498);
+  const SBool  s5435 = false != s5434;
+  const SWord8 s5436 = s5435 ? s5431 : s5432;
+  const SWord8 s5437 = s2457 ? s5433 : s5436;
+  const SWord8 s5438 = s2330 ? s5424 : s5437;
+  const SBool  s5439 = sbv_bv_extract_u8_0_0_u1(s2519);
+  const SBool  s5440 = false != s5439;
+  const SBool  s5441 = sbv_bv_extract_u8_0_0_u1(s2515);
+  const SBool  s5442 = false != s5441;
+  const SBool  s5443 = sbv_bv_extract_u8_0_0_u1(s2508);
+  const SBool  s5444 = false != s5443;
+  const SWord8 s5445 = s5444 ? s5410 : s5411;
+  const SWord8 s5446 = sbv_bv_u8_rotr(s5445, 1);
+  const SWord8 s5447 = 128 | s5446;
+  const SWord8 s5448 = 127 & s5446;
+  const SWord8 s5449 = s5442 ? s5447 : s5448;
+  const SWord8 s5450 = sbv_bv_u8_rotr(s5449, 1);
+  const SWord8 s5451 = 128 | s5450;
+  const SWord8 s5452 = 127 & s5450;
+  const SWord8 s5453 = s5440 ? s5451 : s5452;
+  const SBool  s5454 = sbv_bv_extract_u8_0_0_u1(s2524);
+  const SBool  s5455 = false != s5454;
+  const SWord8 s5456 = s5455 ? s5451 : s5452;
+  const SWord8 s5457 = s2457 ? s5453 : s5456;
+  const SBool  s5458 = sbv_bv_extract_u8_0_0_u1(s2540);
+  const SBool  s5459 = false != s5458;
+  const SBool  s5460 = sbv_bv_extract_u8_0_0_u1(s2533);
+  const SBool  s5461 = false != s5460;
+  const SWord8 s5462 = s5461 ? s5447 : s5448;
+  const SWord8 s5463 = sbv_bv_u8_rotr(s5462, 1);
+  const SWord8 s5464 = 128 | s5463;
+  const SWord8 s5465 = 127 & s5463;
+  const SWord8 s5466 = s5459 ? s5464 : s5465;
+  const SBool  s5467 = sbv_bv_extract_u8_0_0_u1(s2545);
+  const SBool  s5468 = false != s5467;
+  const SWord8 s5469 = s5468 ? s5464 : s5465;
+  const SWord8 s5470 = s2457 ? s5466 : s5469;
+  const SWord8 s5471 = s2330 ? s5457 : s5470;
+  const SWord8 s5472 = s2078 ? s5438 : s5471;
+  const SWord8 s5473 = s2059 ? s5402 : s5472;
+  const SWord8 s5474 = s2042 ? s5332 : s5473;
+  const SBool  s5475 = sbv_bv_extract_u8_0_0_u1(s2620);
+  const SBool  s5476 = false != s5475;
+  const SBool  s5477 = sbv_bv_extract_u8_0_0_u1(s2616);
+  const SBool  s5478 = false != s5477;
+  const SBool  s5479 = sbv_bv_extract_u8_0_0_u1(s2612);
+  const SBool  s5480 = false != s5479;
+  const SWord8 s5481 = sbv_bv_u8_rotr(s2599, 1);
+  const SWord8 s5482 = 128 | s5481;
+  const SWord8 s5483 = 127 & s5481;
+  const SWord8 s5484 = s5480 ? s5482 : s5483;
+  const SWord8 s5485 = sbv_bv_u8_rotr(s5484, 1);
+  const SWord8 s5486 = 128 | s5485;
+  const SWord8 s5487 = 127 & s5485;
+  const SWord8 s5488 = s5478 ? s5486 : s5487;
+  const SWord8 s5489 = sbv_bv_u8_rotr(s5488, 1);
+  const SWord8 s5490 = 128 | s5489;
+  const SWord8 s5491 = 127 & s5489;
+  const SWord8 s5492 = s5476 ? s5490 : s5491;
+  const SBool  s5493 = sbv_bv_extract_u8_0_0_u1(s2625);
+  const SBool  s5494 = false != s5493;
+  const SWord8 s5495 = s5494 ? s5490 : s5491;
+  const SWord8 s5496 = s2608 ? s5492 : s5495;
+  const SBool  s5497 = sbv_bv_extract_u8_0_0_u1(s2641);
+  const SBool  s5498 = false != s5497;
+  const SBool  s5499 = sbv_bv_extract_u8_0_0_u1(s2634);
+  const SBool  s5500 = false != s5499;
+  const SWord8 s5501 = s5500 ? s5486 : s5487;
+  const SWord8 s5502 = sbv_bv_u8_rotr(s5501, 1);
+  const SWord8 s5503 = 128 | s5502;
+  const SWord8 s5504 = 127 & s5502;
+  const SWord8 s5505 = s5498 ? s5503 : s5504;
+  const SBool  s5506 = sbv_bv_extract_u8_0_0_u1(s2646);
+  const SBool  s5507 = false != s5506;
+  const SWord8 s5508 = s5507 ? s5503 : s5504;
+  const SWord8 s5509 = s2608 ? s5505 : s5508;
+  const SWord8 s5510 = s2589 ? s5496 : s5509;
+  const SBool  s5511 = sbv_bv_extract_u8_0_0_u1(s2667);
+  const SBool  s5512 = false != s5511;
+  const SBool  s5513 = sbv_bv_extract_u8_0_0_u1(s2663);
+  const SBool  s5514 = false != s5513;
+  const SBool  s5515 = sbv_bv_extract_u8_0_0_u1(s2656);
+  const SBool  s5516 = false != s5515;
+  const SWord8 s5517 = s5516 ? s5482 : s5483;
+  const SWord8 s5518 = sbv_bv_u8_rotr(s5517, 1);
+  const SWord8 s5519 = 128 | s5518;
+  const SWord8 s5520 = 127 & s5518;
+  const SWord8 s5521 = s5514 ? s5519 : s5520;
+  const SWord8 s5522 = sbv_bv_u8_rotr(s5521, 1);
+  const SWord8 s5523 = 128 | s5522;
+  const SWord8 s5524 = 127 & s5522;
+  const SWord8 s5525 = s5512 ? s5523 : s5524;
+  const SBool  s5526 = sbv_bv_extract_u8_0_0_u1(s2672);
+  const SBool  s5527 = false != s5526;
+  const SWord8 s5528 = s5527 ? s5523 : s5524;
+  const SWord8 s5529 = s2608 ? s5525 : s5528;
+  const SBool  s5530 = sbv_bv_extract_u8_0_0_u1(s2688);
+  const SBool  s5531 = false != s5530;
+  const SBool  s5532 = sbv_bv_extract_u8_0_0_u1(s2681);
+  const SBool  s5533 = false != s5532;
+  const SWord8 s5534 = s5533 ? s5519 : s5520;
+  const SWord8 s5535 = sbv_bv_u8_rotr(s5534, 1);
+  const SWord8 s5536 = 128 | s5535;
+  const SWord8 s5537 = 127 & s5535;
+  const SWord8 s5538 = s5531 ? s5536 : s5537;
+  const SBool  s5539 = sbv_bv_extract_u8_0_0_u1(s2693);
+  const SBool  s5540 = false != s5539;
+  const SWord8 s5541 = s5540 ? s5536 : s5537;
+  const SWord8 s5542 = s2608 ? s5538 : s5541;
+  const SWord8 s5543 = s2589 ? s5529 : s5542;
+  const SWord8 s5544 = s2567 ? s5510 : s5543;
+  const SBool  s5545 = sbv_bv_extract_u8_0_0_u1(s2728);
+  const SBool  s5546 = false != s5545;
+  const SBool  s5547 = sbv_bv_extract_u8_0_0_u1(s2724);
+  const SBool  s5548 = false != s5547;
+  const SBool  s5549 = sbv_bv_extract_u8_0_0_u1(s2720);
+  const SBool  s5550 = false != s5549;
+  const SWord8 s5551 = sbv_bv_u8_rotr(s2707, 1);
+  const SWord8 s5552 = 128 | s5551;
+  const SWord8 s5553 = 127 & s5551;
+  const SWord8 s5554 = s5550 ? s5552 : s5553;
+  const SWord8 s5555 = sbv_bv_u8_rotr(s5554, 1);
+  const SWord8 s5556 = 128 | s5555;
+  const SWord8 s5557 = 127 & s5555;
+  const SWord8 s5558 = s5548 ? s5556 : s5557;
+  const SWord8 s5559 = sbv_bv_u8_rotr(s5558, 1);
+  const SWord8 s5560 = 128 | s5559;
+  const SWord8 s5561 = 127 & s5559;
+  const SWord8 s5562 = s5546 ? s5560 : s5561;
+  const SBool  s5563 = sbv_bv_extract_u8_0_0_u1(s2733);
+  const SBool  s5564 = false != s5563;
+  const SWord8 s5565 = s5564 ? s5560 : s5561;
+  const SWord8 s5566 = s2713 ? s5562 : s5565;
+  const SBool  s5567 = sbv_bv_extract_u8_0_0_u1(s2749);
+  const SBool  s5568 = false != s5567;
+  const SBool  s5569 = sbv_bv_extract_u8_0_0_u1(s2742);
+  const SBool  s5570 = false != s5569;
+  const SWord8 s5571 = s5570 ? s5556 : s5557;
+  const SWord8 s5572 = sbv_bv_u8_rotr(s5571, 1);
+  const SWord8 s5573 = 128 | s5572;
+  const SWord8 s5574 = 127 & s5572;
+  const SWord8 s5575 = s5568 ? s5573 : s5574;
+  const SBool  s5576 = sbv_bv_extract_u8_0_0_u1(s2754);
+  const SBool  s5577 = false != s5576;
+  const SWord8 s5578 = s5577 ? s5573 : s5574;
+  const SWord8 s5579 = s2713 ? s5575 : s5578;
+  const SWord8 s5580 = s2589 ? s5566 : s5579;
+  const SBool  s5581 = sbv_bv_extract_u8_0_0_u1(s2775);
+  const SBool  s5582 = false != s5581;
+  const SBool  s5583 = sbv_bv_extract_u8_0_0_u1(s2771);
+  const SBool  s5584 = false != s5583;
+  const SBool  s5585 = sbv_bv_extract_u8_0_0_u1(s2764);
+  const SBool  s5586 = false != s5585;
+  const SWord8 s5587 = s5586 ? s5552 : s5553;
+  const SWord8 s5588 = sbv_bv_u8_rotr(s5587, 1);
+  const SWord8 s5589 = 128 | s5588;
+  const SWord8 s5590 = 127 & s5588;
+  const SWord8 s5591 = s5584 ? s5589 : s5590;
+  const SWord8 s5592 = sbv_bv_u8_rotr(s5591, 1);
+  const SWord8 s5593 = 128 | s5592;
+  const SWord8 s5594 = 127 & s5592;
+  const SWord8 s5595 = s5582 ? s5593 : s5594;
+  const SBool  s5596 = sbv_bv_extract_u8_0_0_u1(s2780);
+  const SBool  s5597 = false != s5596;
+  const SWord8 s5598 = s5597 ? s5593 : s5594;
+  const SWord8 s5599 = s2713 ? s5595 : s5598;
+  const SBool  s5600 = sbv_bv_extract_u8_0_0_u1(s2796);
+  const SBool  s5601 = false != s5600;
+  const SBool  s5602 = sbv_bv_extract_u8_0_0_u1(s2789);
+  const SBool  s5603 = false != s5602;
+  const SWord8 s5604 = s5603 ? s5589 : s5590;
+  const SWord8 s5605 = sbv_bv_u8_rotr(s5604, 1);
+  const SWord8 s5606 = 128 | s5605;
+  const SWord8 s5607 = 127 & s5605;
+  const SWord8 s5608 = s5601 ? s5606 : s5607;
+  const SBool  s5609 = sbv_bv_extract_u8_0_0_u1(s2801);
+  const SBool  s5610 = false != s5609;
+  const SWord8 s5611 = s5610 ? s5606 : s5607;
+  const SWord8 s5612 = s2713 ? s5608 : s5611;
+  const SWord8 s5613 = s2589 ? s5599 : s5612;
+  const SWord8 s5614 = s2567 ? s5580 : s5613;
+  const SWord8 s5615 = s2059 ? s5544 : s5614;
+  const SBool  s5616 = sbv_bv_extract_u8_0_0_u1(s2856);
+  const SBool  s5617 = false != s5616;
+  const SBool  s5618 = sbv_bv_extract_u8_0_0_u1(s2852);
+  const SBool  s5619 = false != s5618;
+  const SBool  s5620 = sbv_bv_extract_u8_0_0_u1(s2848);
+  const SBool  s5621 = false != s5620;
+  const SWord8 s5622 = sbv_bv_u8_rotr(s2835, 1);
+  const SWord8 s5623 = 128 | s5622;
+  const SWord8 s5624 = 127 & s5622;
+  const SWord8 s5625 = s5621 ? s5623 : s5624;
+  const SWord8 s5626 = sbv_bv_u8_rotr(s5625, 1);
+  const SWord8 s5627 = 128 | s5626;
+  const SWord8 s5628 = 127 & s5626;
+  const SWord8 s5629 = s5619 ? s5627 : s5628;
+  const SWord8 s5630 = sbv_bv_u8_rotr(s5629, 1);
+  const SWord8 s5631 = 128 | s5630;
+  const SWord8 s5632 = 127 & s5630;
+  const SWord8 s5633 = s5617 ? s5631 : s5632;
+  const SBool  s5634 = sbv_bv_extract_u8_0_0_u1(s2861);
+  const SBool  s5635 = false != s5634;
+  const SWord8 s5636 = s5635 ? s5631 : s5632;
+  const SWord8 s5637 = s2844 ? s5633 : s5636;
+  const SBool  s5638 = sbv_bv_extract_u8_0_0_u1(s2877);
+  const SBool  s5639 = false != s5638;
+  const SBool  s5640 = sbv_bv_extract_u8_0_0_u1(s2870);
+  const SBool  s5641 = false != s5640;
+  const SWord8 s5642 = s5641 ? s5627 : s5628;
+  const SWord8 s5643 = sbv_bv_u8_rotr(s5642, 1);
+  const SWord8 s5644 = 128 | s5643;
+  const SWord8 s5645 = 127 & s5643;
+  const SWord8 s5646 = s5639 ? s5644 : s5645;
+  const SBool  s5647 = sbv_bv_extract_u8_0_0_u1(s2882);
+  const SBool  s5648 = false != s5647;
+  const SWord8 s5649 = s5648 ? s5644 : s5645;
+  const SWord8 s5650 = s2844 ? s5646 : s5649;
+  const SWord8 s5651 = s2822 ? s5637 : s5650;
+  const SBool  s5652 = sbv_bv_extract_u8_0_0_u1(s2903);
+  const SBool  s5653 = false != s5652;
+  const SBool  s5654 = sbv_bv_extract_u8_0_0_u1(s2899);
+  const SBool  s5655 = false != s5654;
+  const SBool  s5656 = sbv_bv_extract_u8_0_0_u1(s2892);
+  const SBool  s5657 = false != s5656;
+  const SWord8 s5658 = s5657 ? s5623 : s5624;
+  const SWord8 s5659 = sbv_bv_u8_rotr(s5658, 1);
+  const SWord8 s5660 = 128 | s5659;
+  const SWord8 s5661 = 127 & s5659;
+  const SWord8 s5662 = s5655 ? s5660 : s5661;
+  const SWord8 s5663 = sbv_bv_u8_rotr(s5662, 1);
+  const SWord8 s5664 = 128 | s5663;
+  const SWord8 s5665 = 127 & s5663;
+  const SWord8 s5666 = s5653 ? s5664 : s5665;
+  const SBool  s5667 = sbv_bv_extract_u8_0_0_u1(s2908);
+  const SBool  s5668 = false != s5667;
+  const SWord8 s5669 = s5668 ? s5664 : s5665;
+  const SWord8 s5670 = s2844 ? s5666 : s5669;
+  const SBool  s5671 = sbv_bv_extract_u8_0_0_u1(s2924);
+  const SBool  s5672 = false != s5671;
+  const SBool  s5673 = sbv_bv_extract_u8_0_0_u1(s2917);
+  const SBool  s5674 = false != s5673;
+  const SWord8 s5675 = s5674 ? s5660 : s5661;
+  const SWord8 s5676 = sbv_bv_u8_rotr(s5675, 1);
+  const SWord8 s5677 = 128 | s5676;
+  const SWord8 s5678 = 127 & s5676;
+  const SWord8 s5679 = s5672 ? s5677 : s5678;
+  const SBool  s5680 = sbv_bv_extract_u8_0_0_u1(s2929);
+  const SBool  s5681 = false != s5680;
+  const SWord8 s5682 = s5681 ? s5677 : s5678;
+  const SWord8 s5683 = s2844 ? s5679 : s5682;
+  const SWord8 s5684 = s2822 ? s5670 : s5683;
+  const SWord8 s5685 = s2567 ? s5651 : s5684;
+  const SBool  s5686 = sbv_bv_extract_u8_0_0_u1(s2964);
+  const SBool  s5687 = false != s5686;
+  const SBool  s5688 = sbv_bv_extract_u8_0_0_u1(s2960);
+  const SBool  s5689 = false != s5688;
+  const SBool  s5690 = sbv_bv_extract_u8_0_0_u1(s2956);
+  const SBool  s5691 = false != s5690;
+  const SWord8 s5692 = sbv_bv_u8_rotr(s2943, 1);
+  const SWord8 s5693 = 128 | s5692;
+  const SWord8 s5694 = 127 & s5692;
+  const SWord8 s5695 = s5691 ? s5693 : s5694;
+  const SWord8 s5696 = sbv_bv_u8_rotr(s5695, 1);
+  const SWord8 s5697 = 128 | s5696;
+  const SWord8 s5698 = 127 & s5696;
+  const SWord8 s5699 = s5689 ? s5697 : s5698;
+  const SWord8 s5700 = sbv_bv_u8_rotr(s5699, 1);
+  const SWord8 s5701 = 128 | s5700;
+  const SWord8 s5702 = 127 & s5700;
+  const SWord8 s5703 = s5687 ? s5701 : s5702;
+  const SBool  s5704 = sbv_bv_extract_u8_0_0_u1(s2969);
+  const SBool  s5705 = false != s5704;
+  const SWord8 s5706 = s5705 ? s5701 : s5702;
+  const SWord8 s5707 = s2949 ? s5703 : s5706;
+  const SBool  s5708 = sbv_bv_extract_u8_0_0_u1(s2985);
+  const SBool  s5709 = false != s5708;
+  const SBool  s5710 = sbv_bv_extract_u8_0_0_u1(s2978);
+  const SBool  s5711 = false != s5710;
+  const SWord8 s5712 = s5711 ? s5697 : s5698;
+  const SWord8 s5713 = sbv_bv_u8_rotr(s5712, 1);
+  const SWord8 s5714 = 128 | s5713;
+  const SWord8 s5715 = 127 & s5713;
+  const SWord8 s5716 = s5709 ? s5714 : s5715;
+  const SBool  s5717 = sbv_bv_extract_u8_0_0_u1(s2990);
+  const SBool  s5718 = false != s5717;
+  const SWord8 s5719 = s5718 ? s5714 : s5715;
+  const SWord8 s5720 = s2949 ? s5716 : s5719;
+  const SWord8 s5721 = s2822 ? s5707 : s5720;
+  const SBool  s5722 = sbv_bv_extract_u8_0_0_u1(s3011);
+  const SBool  s5723 = false != s5722;
+  const SBool  s5724 = sbv_bv_extract_u8_0_0_u1(s3007);
+  const SBool  s5725 = false != s5724;
+  const SBool  s5726 = sbv_bv_extract_u8_0_0_u1(s3000);
+  const SBool  s5727 = false != s5726;
+  const SWord8 s5728 = s5727 ? s5693 : s5694;
+  const SWord8 s5729 = sbv_bv_u8_rotr(s5728, 1);
+  const SWord8 s5730 = 128 | s5729;
+  const SWord8 s5731 = 127 & s5729;
+  const SWord8 s5732 = s5725 ? s5730 : s5731;
+  const SWord8 s5733 = sbv_bv_u8_rotr(s5732, 1);
+  const SWord8 s5734 = 128 | s5733;
+  const SWord8 s5735 = 127 & s5733;
+  const SWord8 s5736 = s5723 ? s5734 : s5735;
+  const SBool  s5737 = sbv_bv_extract_u8_0_0_u1(s3016);
+  const SBool  s5738 = false != s5737;
+  const SWord8 s5739 = s5738 ? s5734 : s5735;
+  const SWord8 s5740 = s2949 ? s5736 : s5739;
+  const SBool  s5741 = sbv_bv_extract_u8_0_0_u1(s3032);
+  const SBool  s5742 = false != s5741;
+  const SBool  s5743 = sbv_bv_extract_u8_0_0_u1(s3025);
+  const SBool  s5744 = false != s5743;
+  const SWord8 s5745 = s5744 ? s5730 : s5731;
+  const SWord8 s5746 = sbv_bv_u8_rotr(s5745, 1);
+  const SWord8 s5747 = 128 | s5746;
+  const SWord8 s5748 = 127 & s5746;
+  const SWord8 s5749 = s5742 ? s5747 : s5748;
+  const SBool  s5750 = sbv_bv_extract_u8_0_0_u1(s3037);
+  const SBool  s5751 = false != s5750;
+  const SWord8 s5752 = s5751 ? s5747 : s5748;
+  const SWord8 s5753 = s2949 ? s5749 : s5752;
+  const SWord8 s5754 = s2822 ? s5740 : s5753;
+  const SWord8 s5755 = s2567 ? s5721 : s5754;
+  const SWord8 s5756 = s2059 ? s5685 : s5755;
+  const SWord8 s5757 = s2042 ? s5615 : s5756;
+  const SWord8 s5758 = s16 ? s5474 : s5757;
+  const SBool  s5759 = sbv_bv_extract_u8_0_0_u1(s3132);
+  const SBool  s5760 = false != s5759;
+  const SBool  s5761 = sbv_bv_extract_u8_0_0_u1(s3128);
+  const SBool  s5762 = false != s5761;
+  const SBool  s5763 = sbv_bv_extract_u8_0_0_u1(s3124);
+  const SBool  s5764 = false != s5763;
+  const SWord8 s5765 = sbv_bv_u8_rotr(s3111, 1);
+  const SWord8 s5766 = 128 | s5765;
+  const SWord8 s5767 = 127 & s5765;
+  const SWord8 s5768 = s5764 ? s5766 : s5767;
+  const SWord8 s5769 = sbv_bv_u8_rotr(s5768, 1);
+  const SWord8 s5770 = 128 | s5769;
+  const SWord8 s5771 = 127 & s5769;
+  const SWord8 s5772 = s5762 ? s5770 : s5771;
+  const SWord8 s5773 = sbv_bv_u8_rotr(s5772, 1);
+  const SWord8 s5774 = 128 | s5773;
+  const SWord8 s5775 = 127 & s5773;
+  const SWord8 s5776 = s5760 ? s5774 : s5775;
+  const SBool  s5777 = sbv_bv_extract_u8_0_0_u1(s3137);
+  const SBool  s5778 = false != s5777;
+  const SWord8 s5779 = s5778 ? s5774 : s5775;
+  const SWord8 s5780 = s3120 ? s5776 : s5779;
+  const SBool  s5781 = sbv_bv_extract_u8_0_0_u1(s3153);
+  const SBool  s5782 = false != s5781;
+  const SBool  s5783 = sbv_bv_extract_u8_0_0_u1(s3146);
+  const SBool  s5784 = false != s5783;
+  const SWord8 s5785 = s5784 ? s5770 : s5771;
+  const SWord8 s5786 = sbv_bv_u8_rotr(s5785, 1);
+  const SWord8 s5787 = 128 | s5786;
+  const SWord8 s5788 = 127 & s5786;
+  const SWord8 s5789 = s5782 ? s5787 : s5788;
+  const SBool  s5790 = sbv_bv_extract_u8_0_0_u1(s3158);
+  const SBool  s5791 = false != s5790;
+  const SWord8 s5792 = s5791 ? s5787 : s5788;
+  const SWord8 s5793 = s3120 ? s5789 : s5792;
+  const SWord8 s5794 = s3101 ? s5780 : s5793;
+  const SBool  s5795 = sbv_bv_extract_u8_0_0_u1(s3179);
+  const SBool  s5796 = false != s5795;
+  const SBool  s5797 = sbv_bv_extract_u8_0_0_u1(s3175);
+  const SBool  s5798 = false != s5797;
+  const SBool  s5799 = sbv_bv_extract_u8_0_0_u1(s3168);
+  const SBool  s5800 = false != s5799;
+  const SWord8 s5801 = s5800 ? s5766 : s5767;
+  const SWord8 s5802 = sbv_bv_u8_rotr(s5801, 1);
+  const SWord8 s5803 = 128 | s5802;
+  const SWord8 s5804 = 127 & s5802;
+  const SWord8 s5805 = s5798 ? s5803 : s5804;
+  const SWord8 s5806 = sbv_bv_u8_rotr(s5805, 1);
+  const SWord8 s5807 = 128 | s5806;
+  const SWord8 s5808 = 127 & s5806;
+  const SWord8 s5809 = s5796 ? s5807 : s5808;
+  const SBool  s5810 = sbv_bv_extract_u8_0_0_u1(s3184);
+  const SBool  s5811 = false != s5810;
+  const SWord8 s5812 = s5811 ? s5807 : s5808;
+  const SWord8 s5813 = s3120 ? s5809 : s5812;
+  const SBool  s5814 = sbv_bv_extract_u8_0_0_u1(s3200);
+  const SBool  s5815 = false != s5814;
+  const SBool  s5816 = sbv_bv_extract_u8_0_0_u1(s3193);
+  const SBool  s5817 = false != s5816;
+  const SWord8 s5818 = s5817 ? s5803 : s5804;
+  const SWord8 s5819 = sbv_bv_u8_rotr(s5818, 1);
+  const SWord8 s5820 = 128 | s5819;
+  const SWord8 s5821 = 127 & s5819;
+  const SWord8 s5822 = s5815 ? s5820 : s5821;
+  const SBool  s5823 = sbv_bv_extract_u8_0_0_u1(s3205);
+  const SBool  s5824 = false != s5823;
+  const SWord8 s5825 = s5824 ? s5820 : s5821;
+  const SWord8 s5826 = s3120 ? s5822 : s5825;
+  const SWord8 s5827 = s3101 ? s5813 : s5826;
+  const SWord8 s5828 = s3082 ? s5794 : s5827;
+  const SBool  s5829 = sbv_bv_extract_u8_0_0_u1(s3240);
+  const SBool  s5830 = false != s5829;
+  const SBool  s5831 = sbv_bv_extract_u8_0_0_u1(s3236);
+  const SBool  s5832 = false != s5831;
+  const SBool  s5833 = sbv_bv_extract_u8_0_0_u1(s3232);
+  const SBool  s5834 = false != s5833;
+  const SWord8 s5835 = sbv_bv_u8_rotr(s3219, 1);
+  const SWord8 s5836 = 128 | s5835;
+  const SWord8 s5837 = 127 & s5835;
+  const SWord8 s5838 = s5834 ? s5836 : s5837;
+  const SWord8 s5839 = sbv_bv_u8_rotr(s5838, 1);
+  const SWord8 s5840 = 128 | s5839;
+  const SWord8 s5841 = 127 & s5839;
+  const SWord8 s5842 = s5832 ? s5840 : s5841;
+  const SWord8 s5843 = sbv_bv_u8_rotr(s5842, 1);
+  const SWord8 s5844 = 128 | s5843;
+  const SWord8 s5845 = 127 & s5843;
+  const SWord8 s5846 = s5830 ? s5844 : s5845;
+  const SBool  s5847 = sbv_bv_extract_u8_0_0_u1(s3245);
+  const SBool  s5848 = false != s5847;
+  const SWord8 s5849 = s5848 ? s5844 : s5845;
+  const SWord8 s5850 = s3225 ? s5846 : s5849;
+  const SBool  s5851 = sbv_bv_extract_u8_0_0_u1(s3261);
+  const SBool  s5852 = false != s5851;
+  const SBool  s5853 = sbv_bv_extract_u8_0_0_u1(s3254);
+  const SBool  s5854 = false != s5853;
+  const SWord8 s5855 = s5854 ? s5840 : s5841;
+  const SWord8 s5856 = sbv_bv_u8_rotr(s5855, 1);
+  const SWord8 s5857 = 128 | s5856;
+  const SWord8 s5858 = 127 & s5856;
+  const SWord8 s5859 = s5852 ? s5857 : s5858;
+  const SBool  s5860 = sbv_bv_extract_u8_0_0_u1(s3266);
+  const SBool  s5861 = false != s5860;
+  const SWord8 s5862 = s5861 ? s5857 : s5858;
+  const SWord8 s5863 = s3225 ? s5859 : s5862;
+  const SWord8 s5864 = s3101 ? s5850 : s5863;
+  const SBool  s5865 = sbv_bv_extract_u8_0_0_u1(s3287);
+  const SBool  s5866 = false != s5865;
+  const SBool  s5867 = sbv_bv_extract_u8_0_0_u1(s3283);
+  const SBool  s5868 = false != s5867;
+  const SBool  s5869 = sbv_bv_extract_u8_0_0_u1(s3276);
+  const SBool  s5870 = false != s5869;
+  const SWord8 s5871 = s5870 ? s5836 : s5837;
+  const SWord8 s5872 = sbv_bv_u8_rotr(s5871, 1);
+  const SWord8 s5873 = 128 | s5872;
+  const SWord8 s5874 = 127 & s5872;
+  const SWord8 s5875 = s5868 ? s5873 : s5874;
+  const SWord8 s5876 = sbv_bv_u8_rotr(s5875, 1);
+  const SWord8 s5877 = 128 | s5876;
+  const SWord8 s5878 = 127 & s5876;
+  const SWord8 s5879 = s5866 ? s5877 : s5878;
+  const SBool  s5880 = sbv_bv_extract_u8_0_0_u1(s3292);
+  const SBool  s5881 = false != s5880;
+  const SWord8 s5882 = s5881 ? s5877 : s5878;
+  const SWord8 s5883 = s3225 ? s5879 : s5882;
+  const SBool  s5884 = sbv_bv_extract_u8_0_0_u1(s3308);
+  const SBool  s5885 = false != s5884;
+  const SBool  s5886 = sbv_bv_extract_u8_0_0_u1(s3301);
+  const SBool  s5887 = false != s5886;
+  const SWord8 s5888 = s5887 ? s5873 : s5874;
+  const SWord8 s5889 = sbv_bv_u8_rotr(s5888, 1);
+  const SWord8 s5890 = 128 | s5889;
+  const SWord8 s5891 = 127 & s5889;
+  const SWord8 s5892 = s5885 ? s5890 : s5891;
+  const SBool  s5893 = sbv_bv_extract_u8_0_0_u1(s3313);
+  const SBool  s5894 = false != s5893;
+  const SWord8 s5895 = s5894 ? s5890 : s5891;
+  const SWord8 s5896 = s3225 ? s5892 : s5895;
+  const SWord8 s5897 = s3101 ? s5883 : s5896;
+  const SWord8 s5898 = s3082 ? s5864 : s5897;
+  const SWord8 s5899 = s3060 ? s5828 : s5898;
+  const SBool  s5900 = sbv_bv_extract_u8_0_0_u1(s3368);
+  const SBool  s5901 = false != s5900;
+  const SBool  s5902 = sbv_bv_extract_u8_0_0_u1(s3364);
+  const SBool  s5903 = false != s5902;
+  const SBool  s5904 = sbv_bv_extract_u8_0_0_u1(s3360);
+  const SBool  s5905 = false != s5904;
+  const SWord8 s5906 = sbv_bv_u8_rotr(s3347, 1);
+  const SWord8 s5907 = 128 | s5906;
+  const SWord8 s5908 = 127 & s5906;
+  const SWord8 s5909 = s5905 ? s5907 : s5908;
+  const SWord8 s5910 = sbv_bv_u8_rotr(s5909, 1);
+  const SWord8 s5911 = 128 | s5910;
+  const SWord8 s5912 = 127 & s5910;
+  const SWord8 s5913 = s5903 ? s5911 : s5912;
+  const SWord8 s5914 = sbv_bv_u8_rotr(s5913, 1);
+  const SWord8 s5915 = 128 | s5914;
+  const SWord8 s5916 = 127 & s5914;
+  const SWord8 s5917 = s5901 ? s5915 : s5916;
+  const SBool  s5918 = sbv_bv_extract_u8_0_0_u1(s3373);
+  const SBool  s5919 = false != s5918;
+  const SWord8 s5920 = s5919 ? s5915 : s5916;
+  const SWord8 s5921 = s3356 ? s5917 : s5920;
+  const SBool  s5922 = sbv_bv_extract_u8_0_0_u1(s3389);
+  const SBool  s5923 = false != s5922;
+  const SBool  s5924 = sbv_bv_extract_u8_0_0_u1(s3382);
+  const SBool  s5925 = false != s5924;
+  const SWord8 s5926 = s5925 ? s5911 : s5912;
+  const SWord8 s5927 = sbv_bv_u8_rotr(s5926, 1);
+  const SWord8 s5928 = 128 | s5927;
+  const SWord8 s5929 = 127 & s5927;
+  const SWord8 s5930 = s5923 ? s5928 : s5929;
+  const SBool  s5931 = sbv_bv_extract_u8_0_0_u1(s3394);
+  const SBool  s5932 = false != s5931;
+  const SWord8 s5933 = s5932 ? s5928 : s5929;
+  const SWord8 s5934 = s3356 ? s5930 : s5933;
+  const SWord8 s5935 = s3334 ? s5921 : s5934;
+  const SBool  s5936 = sbv_bv_extract_u8_0_0_u1(s3415);
+  const SBool  s5937 = false != s5936;
+  const SBool  s5938 = sbv_bv_extract_u8_0_0_u1(s3411);
+  const SBool  s5939 = false != s5938;
+  const SBool  s5940 = sbv_bv_extract_u8_0_0_u1(s3404);
+  const SBool  s5941 = false != s5940;
+  const SWord8 s5942 = s5941 ? s5907 : s5908;
+  const SWord8 s5943 = sbv_bv_u8_rotr(s5942, 1);
+  const SWord8 s5944 = 128 | s5943;
+  const SWord8 s5945 = 127 & s5943;
+  const SWord8 s5946 = s5939 ? s5944 : s5945;
+  const SWord8 s5947 = sbv_bv_u8_rotr(s5946, 1);
+  const SWord8 s5948 = 128 | s5947;
+  const SWord8 s5949 = 127 & s5947;
+  const SWord8 s5950 = s5937 ? s5948 : s5949;
+  const SBool  s5951 = sbv_bv_extract_u8_0_0_u1(s3420);
+  const SBool  s5952 = false != s5951;
+  const SWord8 s5953 = s5952 ? s5948 : s5949;
+  const SWord8 s5954 = s3356 ? s5950 : s5953;
+  const SBool  s5955 = sbv_bv_extract_u8_0_0_u1(s3436);
+  const SBool  s5956 = false != s5955;
+  const SBool  s5957 = sbv_bv_extract_u8_0_0_u1(s3429);
+  const SBool  s5958 = false != s5957;
+  const SWord8 s5959 = s5958 ? s5944 : s5945;
+  const SWord8 s5960 = sbv_bv_u8_rotr(s5959, 1);
+  const SWord8 s5961 = 128 | s5960;
+  const SWord8 s5962 = 127 & s5960;
+  const SWord8 s5963 = s5956 ? s5961 : s5962;
+  const SBool  s5964 = sbv_bv_extract_u8_0_0_u1(s3441);
+  const SBool  s5965 = false != s5964;
+  const SWord8 s5966 = s5965 ? s5961 : s5962;
+  const SWord8 s5967 = s3356 ? s5963 : s5966;
+  const SWord8 s5968 = s3334 ? s5954 : s5967;
+  const SWord8 s5969 = s3082 ? s5935 : s5968;
+  const SBool  s5970 = sbv_bv_extract_u8_0_0_u1(s3476);
+  const SBool  s5971 = false != s5970;
+  const SBool  s5972 = sbv_bv_extract_u8_0_0_u1(s3472);
+  const SBool  s5973 = false != s5972;
+  const SBool  s5974 = sbv_bv_extract_u8_0_0_u1(s3468);
+  const SBool  s5975 = false != s5974;
+  const SWord8 s5976 = sbv_bv_u8_rotr(s3455, 1);
+  const SWord8 s5977 = 128 | s5976;
+  const SWord8 s5978 = 127 & s5976;
+  const SWord8 s5979 = s5975 ? s5977 : s5978;
+  const SWord8 s5980 = sbv_bv_u8_rotr(s5979, 1);
+  const SWord8 s5981 = 128 | s5980;
+  const SWord8 s5982 = 127 & s5980;
+  const SWord8 s5983 = s5973 ? s5981 : s5982;
+  const SWord8 s5984 = sbv_bv_u8_rotr(s5983, 1);
+  const SWord8 s5985 = 128 | s5984;
+  const SWord8 s5986 = 127 & s5984;
+  const SWord8 s5987 = s5971 ? s5985 : s5986;
+  const SBool  s5988 = sbv_bv_extract_u8_0_0_u1(s3481);
+  const SBool  s5989 = false != s5988;
+  const SWord8 s5990 = s5989 ? s5985 : s5986;
+  const SWord8 s5991 = s3461 ? s5987 : s5990;
+  const SBool  s5992 = sbv_bv_extract_u8_0_0_u1(s3497);
+  const SBool  s5993 = false != s5992;
+  const SBool  s5994 = sbv_bv_extract_u8_0_0_u1(s3490);
+  const SBool  s5995 = false != s5994;
+  const SWord8 s5996 = s5995 ? s5981 : s5982;
+  const SWord8 s5997 = sbv_bv_u8_rotr(s5996, 1);
+  const SWord8 s5998 = 128 | s5997;
+  const SWord8 s5999 = 127 & s5997;
+  const SWord8 s6000 = s5993 ? s5998 : s5999;
+  const SBool  s6001 = sbv_bv_extract_u8_0_0_u1(s3502);
+  const SBool  s6002 = false != s6001;
+  const SWord8 s6003 = s6002 ? s5998 : s5999;
+  const SWord8 s6004 = s3461 ? s6000 : s6003;
+  const SWord8 s6005 = s3334 ? s5991 : s6004;
+  const SBool  s6006 = sbv_bv_extract_u8_0_0_u1(s3523);
+  const SBool  s6007 = false != s6006;
+  const SBool  s6008 = sbv_bv_extract_u8_0_0_u1(s3519);
+  const SBool  s6009 = false != s6008;
+  const SBool  s6010 = sbv_bv_extract_u8_0_0_u1(s3512);
+  const SBool  s6011 = false != s6010;
+  const SWord8 s6012 = s6011 ? s5977 : s5978;
+  const SWord8 s6013 = sbv_bv_u8_rotr(s6012, 1);
+  const SWord8 s6014 = 128 | s6013;
+  const SWord8 s6015 = 127 & s6013;
+  const SWord8 s6016 = s6009 ? s6014 : s6015;
+  const SWord8 s6017 = sbv_bv_u8_rotr(s6016, 1);
+  const SWord8 s6018 = 128 | s6017;
+  const SWord8 s6019 = 127 & s6017;
+  const SWord8 s6020 = s6007 ? s6018 : s6019;
+  const SBool  s6021 = sbv_bv_extract_u8_0_0_u1(s3528);
+  const SBool  s6022 = false != s6021;
+  const SWord8 s6023 = s6022 ? s6018 : s6019;
+  const SWord8 s6024 = s3461 ? s6020 : s6023;
+  const SBool  s6025 = sbv_bv_extract_u8_0_0_u1(s3544);
+  const SBool  s6026 = false != s6025;
+  const SBool  s6027 = sbv_bv_extract_u8_0_0_u1(s3537);
+  const SBool  s6028 = false != s6027;
+  const SWord8 s6029 = s6028 ? s6014 : s6015;
+  const SWord8 s6030 = sbv_bv_u8_rotr(s6029, 1);
+  const SWord8 s6031 = 128 | s6030;
+  const SWord8 s6032 = 127 & s6030;
+  const SWord8 s6033 = s6026 ? s6031 : s6032;
+  const SBool  s6034 = sbv_bv_extract_u8_0_0_u1(s3549);
+  const SBool  s6035 = false != s6034;
+  const SWord8 s6036 = s6035 ? s6031 : s6032;
+  const SWord8 s6037 = s3461 ? s6033 : s6036;
+  const SWord8 s6038 = s3334 ? s6024 : s6037;
+  const SWord8 s6039 = s3082 ? s6005 : s6038;
+  const SWord8 s6040 = s3060 ? s5969 : s6039;
+  const SWord8 s6041 = s2042 ? s5899 : s6040;
+  const SBool  s6042 = sbv_bv_extract_u8_0_0_u1(s3624);
+  const SBool  s6043 = false != s6042;
+  const SBool  s6044 = sbv_bv_extract_u8_0_0_u1(s3620);
+  const SBool  s6045 = false != s6044;
+  const SBool  s6046 = sbv_bv_extract_u8_0_0_u1(s3616);
+  const SBool  s6047 = false != s6046;
+  const SWord8 s6048 = sbv_bv_u8_rotr(s3603, 1);
+  const SWord8 s6049 = 128 | s6048;
+  const SWord8 s6050 = 127 & s6048;
+  const SWord8 s6051 = s6047 ? s6049 : s6050;
+  const SWord8 s6052 = sbv_bv_u8_rotr(s6051, 1);
+  const SWord8 s6053 = 128 | s6052;
+  const SWord8 s6054 = 127 & s6052;
+  const SWord8 s6055 = s6045 ? s6053 : s6054;
+  const SWord8 s6056 = sbv_bv_u8_rotr(s6055, 1);
+  const SWord8 s6057 = 128 | s6056;
+  const SWord8 s6058 = 127 & s6056;
+  const SWord8 s6059 = s6043 ? s6057 : s6058;
+  const SBool  s6060 = sbv_bv_extract_u8_0_0_u1(s3629);
+  const SBool  s6061 = false != s6060;
+  const SWord8 s6062 = s6061 ? s6057 : s6058;
+  const SWord8 s6063 = s3612 ? s6059 : s6062;
+  const SBool  s6064 = sbv_bv_extract_u8_0_0_u1(s3645);
+  const SBool  s6065 = false != s6064;
+  const SBool  s6066 = sbv_bv_extract_u8_0_0_u1(s3638);
+  const SBool  s6067 = false != s6066;
+  const SWord8 s6068 = s6067 ? s6053 : s6054;
+  const SWord8 s6069 = sbv_bv_u8_rotr(s6068, 1);
+  const SWord8 s6070 = 128 | s6069;
+  const SWord8 s6071 = 127 & s6069;
+  const SWord8 s6072 = s6065 ? s6070 : s6071;
+  const SBool  s6073 = sbv_bv_extract_u8_0_0_u1(s3650);
+  const SBool  s6074 = false != s6073;
+  const SWord8 s6075 = s6074 ? s6070 : s6071;
+  const SWord8 s6076 = s3612 ? s6072 : s6075;
+  const SWord8 s6077 = s3593 ? s6063 : s6076;
+  const SBool  s6078 = sbv_bv_extract_u8_0_0_u1(s3671);
+  const SBool  s6079 = false != s6078;
+  const SBool  s6080 = sbv_bv_extract_u8_0_0_u1(s3667);
+  const SBool  s6081 = false != s6080;
+  const SBool  s6082 = sbv_bv_extract_u8_0_0_u1(s3660);
+  const SBool  s6083 = false != s6082;
+  const SWord8 s6084 = s6083 ? s6049 : s6050;
+  const SWord8 s6085 = sbv_bv_u8_rotr(s6084, 1);
+  const SWord8 s6086 = 128 | s6085;
+  const SWord8 s6087 = 127 & s6085;
+  const SWord8 s6088 = s6081 ? s6086 : s6087;
+  const SWord8 s6089 = sbv_bv_u8_rotr(s6088, 1);
+  const SWord8 s6090 = 128 | s6089;
+  const SWord8 s6091 = 127 & s6089;
+  const SWord8 s6092 = s6079 ? s6090 : s6091;
+  const SBool  s6093 = sbv_bv_extract_u8_0_0_u1(s3676);
+  const SBool  s6094 = false != s6093;
+  const SWord8 s6095 = s6094 ? s6090 : s6091;
+  const SWord8 s6096 = s3612 ? s6092 : s6095;
+  const SBool  s6097 = sbv_bv_extract_u8_0_0_u1(s3692);
+  const SBool  s6098 = false != s6097;
+  const SBool  s6099 = sbv_bv_extract_u8_0_0_u1(s3685);
+  const SBool  s6100 = false != s6099;
+  const SWord8 s6101 = s6100 ? s6086 : s6087;
+  const SWord8 s6102 = sbv_bv_u8_rotr(s6101, 1);
+  const SWord8 s6103 = 128 | s6102;
+  const SWord8 s6104 = 127 & s6102;
+  const SWord8 s6105 = s6098 ? s6103 : s6104;
+  const SBool  s6106 = sbv_bv_extract_u8_0_0_u1(s3697);
+  const SBool  s6107 = false != s6106;
+  const SWord8 s6108 = s6107 ? s6103 : s6104;
+  const SWord8 s6109 = s3612 ? s6105 : s6108;
+  const SWord8 s6110 = s3593 ? s6096 : s6109;
+  const SWord8 s6111 = s3571 ? s6077 : s6110;
+  const SBool  s6112 = sbv_bv_extract_u8_0_0_u1(s3732);
+  const SBool  s6113 = false != s6112;
+  const SBool  s6114 = sbv_bv_extract_u8_0_0_u1(s3728);
+  const SBool  s6115 = false != s6114;
+  const SBool  s6116 = sbv_bv_extract_u8_0_0_u1(s3724);
+  const SBool  s6117 = false != s6116;
+  const SWord8 s6118 = sbv_bv_u8_rotr(s3711, 1);
+  const SWord8 s6119 = 128 | s6118;
+  const SWord8 s6120 = 127 & s6118;
+  const SWord8 s6121 = s6117 ? s6119 : s6120;
+  const SWord8 s6122 = sbv_bv_u8_rotr(s6121, 1);
+  const SWord8 s6123 = 128 | s6122;
+  const SWord8 s6124 = 127 & s6122;
+  const SWord8 s6125 = s6115 ? s6123 : s6124;
+  const SWord8 s6126 = sbv_bv_u8_rotr(s6125, 1);
+  const SWord8 s6127 = 128 | s6126;
+  const SWord8 s6128 = 127 & s6126;
+  const SWord8 s6129 = s6113 ? s6127 : s6128;
+  const SBool  s6130 = sbv_bv_extract_u8_0_0_u1(s3737);
+  const SBool  s6131 = false != s6130;
+  const SWord8 s6132 = s6131 ? s6127 : s6128;
+  const SWord8 s6133 = s3717 ? s6129 : s6132;
+  const SBool  s6134 = sbv_bv_extract_u8_0_0_u1(s3753);
+  const SBool  s6135 = false != s6134;
+  const SBool  s6136 = sbv_bv_extract_u8_0_0_u1(s3746);
+  const SBool  s6137 = false != s6136;
+  const SWord8 s6138 = s6137 ? s6123 : s6124;
+  const SWord8 s6139 = sbv_bv_u8_rotr(s6138, 1);
+  const SWord8 s6140 = 128 | s6139;
+  const SWord8 s6141 = 127 & s6139;
+  const SWord8 s6142 = s6135 ? s6140 : s6141;
+  const SBool  s6143 = sbv_bv_extract_u8_0_0_u1(s3758);
+  const SBool  s6144 = false != s6143;
+  const SWord8 s6145 = s6144 ? s6140 : s6141;
+  const SWord8 s6146 = s3717 ? s6142 : s6145;
+  const SWord8 s6147 = s3593 ? s6133 : s6146;
+  const SBool  s6148 = sbv_bv_extract_u8_0_0_u1(s3779);
+  const SBool  s6149 = false != s6148;
+  const SBool  s6150 = sbv_bv_extract_u8_0_0_u1(s3775);
+  const SBool  s6151 = false != s6150;
+  const SBool  s6152 = sbv_bv_extract_u8_0_0_u1(s3768);
+  const SBool  s6153 = false != s6152;
+  const SWord8 s6154 = s6153 ? s6119 : s6120;
+  const SWord8 s6155 = sbv_bv_u8_rotr(s6154, 1);
+  const SWord8 s6156 = 128 | s6155;
+  const SWord8 s6157 = 127 & s6155;
+  const SWord8 s6158 = s6151 ? s6156 : s6157;
+  const SWord8 s6159 = sbv_bv_u8_rotr(s6158, 1);
+  const SWord8 s6160 = 128 | s6159;
+  const SWord8 s6161 = 127 & s6159;
+  const SWord8 s6162 = s6149 ? s6160 : s6161;
+  const SBool  s6163 = sbv_bv_extract_u8_0_0_u1(s3784);
+  const SBool  s6164 = false != s6163;
+  const SWord8 s6165 = s6164 ? s6160 : s6161;
+  const SWord8 s6166 = s3717 ? s6162 : s6165;
+  const SBool  s6167 = sbv_bv_extract_u8_0_0_u1(s3800);
+  const SBool  s6168 = false != s6167;
+  const SBool  s6169 = sbv_bv_extract_u8_0_0_u1(s3793);
+  const SBool  s6170 = false != s6169;
+  const SWord8 s6171 = s6170 ? s6156 : s6157;
+  const SWord8 s6172 = sbv_bv_u8_rotr(s6171, 1);
+  const SWord8 s6173 = 128 | s6172;
+  const SWord8 s6174 = 127 & s6172;
+  const SWord8 s6175 = s6168 ? s6173 : s6174;
+  const SBool  s6176 = sbv_bv_extract_u8_0_0_u1(s3805);
+  const SBool  s6177 = false != s6176;
+  const SWord8 s6178 = s6177 ? s6173 : s6174;
+  const SWord8 s6179 = s3717 ? s6175 : s6178;
+  const SWord8 s6180 = s3593 ? s6166 : s6179;
+  const SWord8 s6181 = s3571 ? s6147 : s6180;
+  const SWord8 s6182 = s3060 ? s6111 : s6181;
+  const SBool  s6183 = sbv_bv_extract_u8_0_0_u1(s3860);
+  const SBool  s6184 = false != s6183;
+  const SBool  s6185 = sbv_bv_extract_u8_0_0_u1(s3856);
+  const SBool  s6186 = false != s6185;
+  const SBool  s6187 = sbv_bv_extract_u8_0_0_u1(s3852);
+  const SBool  s6188 = false != s6187;
+  const SWord8 s6189 = sbv_bv_u8_rotr(s3839, 1);
+  const SWord8 s6190 = 128 | s6189;
+  const SWord8 s6191 = 127 & s6189;
+  const SWord8 s6192 = s6188 ? s6190 : s6191;
+  const SWord8 s6193 = sbv_bv_u8_rotr(s6192, 1);
+  const SWord8 s6194 = 128 | s6193;
+  const SWord8 s6195 = 127 & s6193;
+  const SWord8 s6196 = s6186 ? s6194 : s6195;
+  const SWord8 s6197 = sbv_bv_u8_rotr(s6196, 1);
+  const SWord8 s6198 = 128 | s6197;
+  const SWord8 s6199 = 127 & s6197;
+  const SWord8 s6200 = s6184 ? s6198 : s6199;
+  const SBool  s6201 = sbv_bv_extract_u8_0_0_u1(s3865);
+  const SBool  s6202 = false != s6201;
+  const SWord8 s6203 = s6202 ? s6198 : s6199;
+  const SWord8 s6204 = s3848 ? s6200 : s6203;
+  const SBool  s6205 = sbv_bv_extract_u8_0_0_u1(s3881);
+  const SBool  s6206 = false != s6205;
+  const SBool  s6207 = sbv_bv_extract_u8_0_0_u1(s3874);
+  const SBool  s6208 = false != s6207;
+  const SWord8 s6209 = s6208 ? s6194 : s6195;
+  const SWord8 s6210 = sbv_bv_u8_rotr(s6209, 1);
+  const SWord8 s6211 = 128 | s6210;
+  const SWord8 s6212 = 127 & s6210;
+  const SWord8 s6213 = s6206 ? s6211 : s6212;
+  const SBool  s6214 = sbv_bv_extract_u8_0_0_u1(s3886);
+  const SBool  s6215 = false != s6214;
+  const SWord8 s6216 = s6215 ? s6211 : s6212;
+  const SWord8 s6217 = s3848 ? s6213 : s6216;
+  const SWord8 s6218 = s3826 ? s6204 : s6217;
+  const SBool  s6219 = sbv_bv_extract_u8_0_0_u1(s3907);
+  const SBool  s6220 = false != s6219;
+  const SBool  s6221 = sbv_bv_extract_u8_0_0_u1(s3903);
+  const SBool  s6222 = false != s6221;
+  const SBool  s6223 = sbv_bv_extract_u8_0_0_u1(s3896);
+  const SBool  s6224 = false != s6223;
+  const SWord8 s6225 = s6224 ? s6190 : s6191;
+  const SWord8 s6226 = sbv_bv_u8_rotr(s6225, 1);
+  const SWord8 s6227 = 128 | s6226;
+  const SWord8 s6228 = 127 & s6226;
+  const SWord8 s6229 = s6222 ? s6227 : s6228;
+  const SWord8 s6230 = sbv_bv_u8_rotr(s6229, 1);
+  const SWord8 s6231 = 128 | s6230;
+  const SWord8 s6232 = 127 & s6230;
+  const SWord8 s6233 = s6220 ? s6231 : s6232;
+  const SBool  s6234 = sbv_bv_extract_u8_0_0_u1(s3912);
+  const SBool  s6235 = false != s6234;
+  const SWord8 s6236 = s6235 ? s6231 : s6232;
+  const SWord8 s6237 = s3848 ? s6233 : s6236;
+  const SBool  s6238 = sbv_bv_extract_u8_0_0_u1(s3928);
+  const SBool  s6239 = false != s6238;
+  const SBool  s6240 = sbv_bv_extract_u8_0_0_u1(s3921);
+  const SBool  s6241 = false != s6240;
+  const SWord8 s6242 = s6241 ? s6227 : s6228;
+  const SWord8 s6243 = sbv_bv_u8_rotr(s6242, 1);
+  const SWord8 s6244 = 128 | s6243;
+  const SWord8 s6245 = 127 & s6243;
+  const SWord8 s6246 = s6239 ? s6244 : s6245;
+  const SBool  s6247 = sbv_bv_extract_u8_0_0_u1(s3933);
+  const SBool  s6248 = false != s6247;
+  const SWord8 s6249 = s6248 ? s6244 : s6245;
+  const SWord8 s6250 = s3848 ? s6246 : s6249;
+  const SWord8 s6251 = s3826 ? s6237 : s6250;
+  const SWord8 s6252 = s3571 ? s6218 : s6251;
+  const SBool  s6253 = sbv_bv_extract_u8_0_0_u1(s3968);
+  const SBool  s6254 = false != s6253;
+  const SBool  s6255 = sbv_bv_extract_u8_0_0_u1(s3964);
+  const SBool  s6256 = false != s6255;
+  const SBool  s6257 = sbv_bv_extract_u8_0_0_u1(s3960);
+  const SBool  s6258 = false != s6257;
+  const SWord8 s6259 = sbv_bv_u8_rotr(s3947, 1);
+  const SWord8 s6260 = 128 | s6259;
+  const SWord8 s6261 = 127 & s6259;
+  const SWord8 s6262 = s6258 ? s6260 : s6261;
+  const SWord8 s6263 = sbv_bv_u8_rotr(s6262, 1);
+  const SWord8 s6264 = 128 | s6263;
+  const SWord8 s6265 = 127 & s6263;
+  const SWord8 s6266 = s6256 ? s6264 : s6265;
+  const SWord8 s6267 = sbv_bv_u8_rotr(s6266, 1);
+  const SWord8 s6268 = 128 | s6267;
+  const SWord8 s6269 = 127 & s6267;
+  const SWord8 s6270 = s6254 ? s6268 : s6269;
+  const SBool  s6271 = sbv_bv_extract_u8_0_0_u1(s3973);
+  const SBool  s6272 = false != s6271;
+  const SWord8 s6273 = s6272 ? s6268 : s6269;
+  const SWord8 s6274 = s3953 ? s6270 : s6273;
+  const SBool  s6275 = sbv_bv_extract_u8_0_0_u1(s3989);
+  const SBool  s6276 = false != s6275;
+  const SBool  s6277 = sbv_bv_extract_u8_0_0_u1(s3982);
+  const SBool  s6278 = false != s6277;
+  const SWord8 s6279 = s6278 ? s6264 : s6265;
+  const SWord8 s6280 = sbv_bv_u8_rotr(s6279, 1);
+  const SWord8 s6281 = 128 | s6280;
+  const SWord8 s6282 = 127 & s6280;
+  const SWord8 s6283 = s6276 ? s6281 : s6282;
+  const SBool  s6284 = sbv_bv_extract_u8_0_0_u1(s3994);
+  const SBool  s6285 = false != s6284;
+  const SWord8 s6286 = s6285 ? s6281 : s6282;
+  const SWord8 s6287 = s3953 ? s6283 : s6286;
+  const SWord8 s6288 = s3826 ? s6274 : s6287;
+  const SBool  s6289 = sbv_bv_extract_u8_0_0_u1(s4015);
+  const SBool  s6290 = false != s6289;
+  const SBool  s6291 = sbv_bv_extract_u8_0_0_u1(s4011);
+  const SBool  s6292 = false != s6291;
+  const SBool  s6293 = sbv_bv_extract_u8_0_0_u1(s4004);
+  const SBool  s6294 = false != s6293;
+  const SWord8 s6295 = s6294 ? s6260 : s6261;
+  const SWord8 s6296 = sbv_bv_u8_rotr(s6295, 1);
+  const SWord8 s6297 = 128 | s6296;
+  const SWord8 s6298 = 127 & s6296;
+  const SWord8 s6299 = s6292 ? s6297 : s6298;
+  const SWord8 s6300 = sbv_bv_u8_rotr(s6299, 1);
+  const SWord8 s6301 = 128 | s6300;
+  const SWord8 s6302 = 127 & s6300;
+  const SWord8 s6303 = s6290 ? s6301 : s6302;
+  const SBool  s6304 = sbv_bv_extract_u8_0_0_u1(s4020);
+  const SBool  s6305 = false != s6304;
+  const SWord8 s6306 = s6305 ? s6301 : s6302;
+  const SWord8 s6307 = s3953 ? s6303 : s6306;
+  const SBool  s6308 = sbv_bv_extract_u8_0_0_u1(s4036);
+  const SBool  s6309 = false != s6308;
+  const SBool  s6310 = sbv_bv_extract_u8_0_0_u1(s4029);
+  const SBool  s6311 = false != s6310;
+  const SWord8 s6312 = s6311 ? s6297 : s6298;
+  const SWord8 s6313 = sbv_bv_u8_rotr(s6312, 1);
+  const SWord8 s6314 = 128 | s6313;
+  const SWord8 s6315 = 127 & s6313;
+  const SWord8 s6316 = s6309 ? s6314 : s6315;
+  const SBool  s6317 = sbv_bv_extract_u8_0_0_u1(s4041);
+  const SBool  s6318 = false != s6317;
+  const SWord8 s6319 = s6318 ? s6314 : s6315;
+  const SWord8 s6320 = s3953 ? s6316 : s6319;
+  const SWord8 s6321 = s3826 ? s6307 : s6320;
+  const SWord8 s6322 = s3571 ? s6288 : s6321;
+  const SWord8 s6323 = s3060 ? s6252 : s6322;
+  const SWord8 s6324 = s2042 ? s6182 : s6323;
+  const SWord8 s6325 = s16 ? s6041 : s6324;
+  const SWord8 s6326 = s11 ? s5758 : s6325;
+  const SWord8 s6327 = s5 ? s5191 : s6326;
+
+  *sbv_output_0 = s4056;
+  *sbv_output_1 = s6327;
 }
 == END: "legatoMult.c" ==================
diff --git a/SBVTestSuite/GoldFiles/listFloat2.gold b/SBVTestSuite/GoldFiles/listFloat2.gold
--- a/SBVTestSuite/GoldFiles/listFloat2.gold
+++ b/SBVTestSuite/GoldFiles/listFloat2.gold
@@ -1,3 +1,10 @@
+[MEASURE] Verifying termination measures for: listEq @(SBV [Float] -> SBV [Float] -> SBV Bool)
+[MEASURE] Checking: listEq @(SBV [Float] -> SBV [Float] -> SBV Bool)
+[MEASURE] listEq @(SBV [Float] -> SBV [Float] -> SBV Bool): barified = "|listEq @(SBV [Float] -> SBV [Float] -> SBV Bool)|"
+[MEASURE] listEq @(SBV [Float] -> SBV [Float] -> SBV Bool): Uninterpreted ops in DAG: [("|listEq @(SBV [Float] -> SBV [Float] -> SBV Bool)|",2)]
+[MEASURE] listEq @(SBV [Float] -> SBV [Float] -> SBV Bool): recursive calls found = 1
+[MEASURE] listEq @(SBV [Float] -> SBV [Float] -> SBV Bool): trying length arg1
+[MEASURE] replayDAG {listEq @(SBV [Float] -> SBV [Float] -> SBV Bool)}: replaying 16 node(s)
 ** Calling: z3 -nw -in -smt2
 [GOOD] ; Automatically generated by SBV. Do not edit.
 [GOOD] (set-option :print-success true)
@@ -9,11 +16,114 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
 [GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (_ FloatingPoint  8 24))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () (Seq (_ FloatingPoint  8 24))) ; tracks user variable "arg1"
+[GOOD] (declare-fun s15 () Bool) ; tracks user variable "__internal_sbv_s15"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Int (seq.len s1))
+[GOOD] (define-fun s7 () Bool (= s2 s6))
+[GOOD] (define-fun s8 () (_ FloatingPoint  8 24) (seq.nth s0 s2))
+[GOOD] (define-fun s9 () (_ FloatingPoint  8 24) (seq.nth s1 s2))
+[GOOD] (define-fun s10 () Bool (fp.eq s8 s9))
+[GOOD] (define-fun s11 () Int (- s4 s3))
+[GOOD] (define-fun s12 () (Seq (_ FloatingPoint  8 24)) (seq.extract s0 s3 s11))
+[GOOD] (define-fun s13 () Int (- s6 s3))
+[GOOD] (define-fun s14 () (Seq (_ FloatingPoint  8 24)) (seq.extract s1 s3 s13))
+[GOOD] (define-fun s16 () Bool (and s10 s15))
+[GOOD] (define-fun s17 () Bool (not s7))
+[GOOD] (define-fun s18 () Bool (and s16 s17))
+[GOOD] (define-fun s19 () Bool (ite s5 s7 s18))
+[GOOD] (define-fun s20 () Bool (>= s4 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s20))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {listEq @(SBV [Float] -> SBV [Float] -> SBV Bool)}: replaying 16 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (Seq (_ FloatingPoint  8 24))) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () (Seq (_ FloatingPoint  8 24))) ; tracks user variable "arg1"
+[GOOD] (declare-fun s15 () Bool) ; tracks user variable "__internal_sbv_s15"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Int (seq.len s0))
+[GOOD] (define-fun s5 () Bool (= s2 s4))
+[GOOD] (define-fun s6 () Int (seq.len s1))
+[GOOD] (define-fun s7 () Bool (= s2 s6))
+[GOOD] (define-fun s8 () (_ FloatingPoint  8 24) (seq.nth s0 s2))
+[GOOD] (define-fun s9 () (_ FloatingPoint  8 24) (seq.nth s1 s2))
+[GOOD] (define-fun s10 () Bool (fp.eq s8 s9))
+[GOOD] (define-fun s11 () Int (- s4 s3))
+[GOOD] (define-fun s12 () (Seq (_ FloatingPoint  8 24)) (seq.extract s0 s3 s11))
+[GOOD] (define-fun s13 () Int (- s6 s3))
+[GOOD] (define-fun s14 () (Seq (_ FloatingPoint  8 24)) (seq.extract s1 s3 s13))
+[GOOD] (define-fun s16 () Bool (and s10 s15))
+[GOOD] (define-fun s17 () Bool (not s7))
+[GOOD] (define-fun s18 () Bool (and s16 s17))
+[GOOD] (define-fun s19 () Bool (ite s5 s7 s18))
+[GOOD] (define-fun s20 () Int (seq.len s12))
+[GOOD] (define-fun s21 () Bool (not s5))
+[GOOD] (define-fun s22 () Bool (and s17 s21))
+[GOOD] (define-fun s23 () Bool (and s10 s22))
+[GOOD] (define-fun s24 () Bool (> s4 s20))
+[GOOD] (define-fun s25 () Bool (=> s23 s24))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s25))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] listEq @(SBV [Float] -> SBV [Float] -> SBV Bool): length arg1 -> OK
+[MEASURE] Passed (terminating): listEq @(SBV [Float] -> SBV [Float] -> SBV Bool)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
 [GOOD] (declare-fun s0 () (_ FloatingPoint  8 24)) ; tracks user variable "x"
 [GOOD] ; --- constant tables ---
 [GOOD] ; --- non-constant tables ---
@@ -36,8 +146,10 @@
                                  (let ((l1_s14 (seq.extract l1_s1 l1_s10 l1_s13)))
                                  (let ((l1_s15 (|listEq @(SBV [Float] -> SBV [Float] -> SBV Bool)| l1_s12 l1_s14)))
                                  (let ((l1_s16 (and l1_s9 l1_s15)))
-                                 (let ((l1_s17 (ite l1_s4 l1_s6 l1_s16)))
-                                 l1_s17)))))))))))))))))
+                                 (let ((l1_s17 (not l1_s6)))
+                                 (let ((l1_s18 (and l1_s16 l1_s17)))
+                                 (let ((l1_s19 (ite l1_s4 l1_s6 l1_s18)))
+                                 l1_s19)))))))))))))))))))
 [GOOD] ; --- assignments ---
 [GOOD] (define-fun s1 () (Seq (_ FloatingPoint  8 24)) (seq.unit s0))
 [GOOD] (define-fun s2 () Bool (|listEq @(SBV [Float] -> SBV [Float] -> SBV Bool)| s1 s1))
diff --git a/SBVTestSuite/GoldFiles/listFloat3.gold b/SBVTestSuite/GoldFiles/listFloat3.gold
--- a/SBVTestSuite/GoldFiles/listFloat3.gold
+++ b/SBVTestSuite/GoldFiles/listFloat3.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has lists, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/merge.gold b/SBVTestSuite/GoldFiles/merge.gold
--- a/SBVTestSuite/GoldFiles/merge.gold
+++ b/SBVTestSuite/GoldFiles/merge.gold
@@ -12,11 +12,11 @@
 merge.o: merge.c merge.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
-merge_driver.o: merge_driver.c
+merge_driver.o: merge_driver.c merge.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
 merge_driver: merge.o merge_driver.o
-	${CC} ${CCFLAGS} $^ -o $@
+	${CC} ${CCFLAGS} $^ -o $@ ${LDFLAGS}
 
 clean:
 	rm -f *.o
@@ -27,9 +27,10 @@
 == BEGIN: "merge.h" ================
 /* Header file for merge. Automatically generated by SBV. Do not edit! */
 
-#ifndef __merge__HEADER_INCLUDED__
-#define __merge__HEADER_INCLUDED__
+#ifndef SBV_GENERATED_merge_HEADER_INCLUDED
+#define SBV_GENERATED_merge_HEADER_INCLUDED
 
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <inttypes.h>
@@ -38,6 +39,13 @@
 #include <string.h>
 #include <math.h>
 
+/* Floating-point calling convention:
+ * Enter generated code in FE_TONEAREST (round-to-nearest, ties-to-even).
+ * Callbacks must preserve this mode before returning or re-entering.
+ * Generated code does not check or change the hardware rounding mode.
+ * Custom builds must disable implicit FP contraction, including at LTO link time.
+ */
+
 /* The boolean type */
 typedef bool SBool;
 
@@ -62,7 +70,7 @@
 /* Entry point prototype: */
 void merge(const SWord8 *xs, SWord8 *ys);
 
-#endif /* __merge__HEADER_INCLUDED__ */
+#endif /* SBV_GENERATED_merge_HEADER_INCLUDED */
 == END: "merge.h" ==================
 == BEGIN: "merge_driver.c" ================
 /* Example driver program for merge. */
@@ -73,23 +81,29 @@
 
 int main(void)
 {
-  const SWord8 xs[5] = {
+  const SWord8 sbv_driver_input_0[5] = {
       10,  6,  4, 82, 71
   };
 
   printf("Contents of input array xs:\n");
-  int xs_ctr;
-  for(xs_ctr = 0; xs_ctr < 5 ; ++xs_ctr)
-    printf("  xs[%1d] = %"PRIu8"\n", xs_ctr ,xs[xs_ctr]);
+  int sbv_driver_input_0_ctr;
+  for(sbv_driver_input_0_ctr = 0; sbv_driver_input_0_ctr < 5 ; ++sbv_driver_input_0_ctr)
+  { printf("  xs[%1d] = ", sbv_driver_input_0_ctr);
+    printf("%"PRIu8"", sbv_driver_input_0[sbv_driver_input_0_ctr]);
+    printf("\n");
+  }
 
-  SWord8 ys[5];
+  SWord8 sbv_driver_output_0[5];
 
-  merge(xs, ys);
+  merge(sbv_driver_input_0, sbv_driver_output_0);
 
   printf("merge(xs, ys) ->\n");
-  int ys_ctr;
-  for(ys_ctr = 0; ys_ctr < 5 ; ++ys_ctr)
-    printf("  ys[%1d] = %"PRIu8"\n", ys_ctr ,ys[ys_ctr]);
+  int sbv_driver_output_0_ctr;
+  for(sbv_driver_output_0_ctr = 0; sbv_driver_output_0_ctr < 5 ; ++sbv_driver_output_0_ctr)
+  { printf("  ys[%1d] = ", sbv_driver_output_0_ctr);
+    printf("%"PRIu8"", sbv_driver_output_0[sbv_driver_output_0_ctr]);
+    printf("\n");
+  }
 
   return 0;
 }
@@ -99,13 +113,13 @@
 
 #include "merge.h"
 
-void merge(const SWord8 *xs, SWord8 *ys)
+void merge(const SWord8 *sbv_input_0, SWord8 *sbv_output_0)
 {
-  const SWord8 s0 = xs[0];
-  const SWord8 s1 = xs[1];
-  const SWord8 s2 = xs[2];
-  const SWord8 s3 = xs[3];
-  const SWord8 s4 = xs[4];
+  const SWord8 s0 = sbv_input_0[0];
+  const SWord8 s1 = sbv_input_0[1];
+  const SWord8 s2 = sbv_input_0[2];
+  const SWord8 s3 = sbv_input_0[3];
+  const SWord8 s4 = sbv_input_0[4];
   const SBool  s5 = s0 < s1;
   const SWord8 s6 = s5 ? s0 : s1;
   const SBool  s7 = s3 < s4;
@@ -147,10 +161,10 @@
   const SWord8 s43 = s20 ? s40 : s42;
   const SWord8 s44 = s11 ? s41 : s43;
 
-  ys[0] = s12;
-  ys[1] = s22;
-  ys[2] = s31;
-  ys[3] = s38;
-  ys[4] = s44;
+  sbv_output_0[0] = s12;
+  sbv_output_0[1] = s22;
+  sbv_output_0[2] = s31;
+  sbv_output_0[3] = s38;
+  sbv_output_0[4] = s44;
 }
 == END: "merge.c" ==================
diff --git a/SBVTestSuite/GoldFiles/nested1.gold b/SBVTestSuite/GoldFiles/nested1.gold
--- a/SBVTestSuite/GoldFiles/nested1.gold
+++ b/SBVTestSuite/GoldFiles/nested1.gold
@@ -2,9 +2,6 @@
 
 Data.SBV: Mismatched contexts detected.
 ***
-***   Current context: SBVContext (-531973508589804280)
-***   Mixed with     : SBVContext (-7749304166575005736)
-***
 *** This happens if you call a proof-function (prove/sat/runSMT/isSatisfiable) etc.
 *** while another one is in execution, or use results from one such call in another.
 *** Please avoid such nested calls, all interactions should be from the same context.
diff --git a/SBVTestSuite/GoldFiles/nested2.gold b/SBVTestSuite/GoldFiles/nested2.gold
--- a/SBVTestSuite/GoldFiles/nested2.gold
+++ b/SBVTestSuite/GoldFiles/nested2.gold
@@ -2,9 +2,6 @@
 
 Data.SBV: Mismatched contexts detected.
 ***
-***   Current context: SBVContext (-531973508589804280)
-***   Mixed with     : SBVContext (-7749304166575005736)
-***
 *** This happens if you call a proof-function (prove/sat/runSMT/isSatisfiable) etc.
 *** while another one is in execution, or use results from one such call in another.
 *** Please avoid such nested calls, all interactions should be from the same context.
diff --git a/SBVTestSuite/GoldFiles/nested3.gold b/SBVTestSuite/GoldFiles/nested3.gold
--- a/SBVTestSuite/GoldFiles/nested3.gold
+++ b/SBVTestSuite/GoldFiles/nested3.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
@@ -24,9 +23,6 @@
 CAUGHT EXCEPTION
 
 Data.SBV: Mismatched contexts detected.
-***
-***   Current context: SBVContext (-7749304166575005736)
-***   Mixed with     : SBVContext (-531973508589804280)
 ***
 *** This happens if you call a proof-function (prove/sat/runSMT/isSatisfiable) etc.
 *** while another one is in execution, or use results from one such call in another.
diff --git a/SBVTestSuite/GoldFiles/nested4.gold b/SBVTestSuite/GoldFiles/nested4.gold
--- a/SBVTestSuite/GoldFiles/nested4.gold
+++ b/SBVTestSuite/GoldFiles/nested4.gold
@@ -2,9 +2,6 @@
 
 Data.SBV: Mismatched contexts detected.
 ***
-***   Current context: SBVContext (-531973508589804280)
-***   Mixed with     : SBVContext (-7749304166575005736)
-***
 *** This happens if you call a proof-function (prove/sat/runSMT/isSatisfiable) etc.
 *** while another one is in execution, or use results from one such call in another.
 *** Please avoid such nested calls, all interactions should be from the same context.
diff --git a/SBVTestSuite/GoldFiles/noOpt1.gold b/SBVTestSuite/GoldFiles/noOpt1.gold
--- a/SBVTestSuite/GoldFiles/noOpt1.gold
+++ b/SBVTestSuite/GoldFiles/noOpt1.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_BV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/noOpt2.gold b/SBVTestSuite/GoldFiles/noOpt2.gold
--- a/SBVTestSuite/GoldFiles/noOpt2.gold
+++ b/SBVTestSuite/GoldFiles/noOpt2.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_BV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/nonlinear_cvc4.gold b/SBVTestSuite/GoldFiles/nonlinear_cvc4.gold
--- a/SBVTestSuite/GoldFiles/nonlinear_cvc4.gold
+++ b/SBVTestSuite/GoldFiles/nonlinear_cvc4.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has algebraic reals, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/nonlinear_cvc5.gold b/SBVTestSuite/GoldFiles/nonlinear_cvc5.gold
--- a/SBVTestSuite/GoldFiles/nonlinear_cvc5.gold
+++ b/SBVTestSuite/GoldFiles/nonlinear_cvc5.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic HO_ALL) ; has algebraic reals, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/nonlinear_z3.gold b/SBVTestSuite/GoldFiles/nonlinear_z3.gold
--- a/SBVTestSuite/GoldFiles/nonlinear_z3.gold
+++ b/SBVTestSuite/GoldFiles/nonlinear_z3.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has algebraic reals, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/pareto1.gold b/SBVTestSuite/GoldFiles/pareto1.gold
--- a/SBVTestSuite/GoldFiles/pareto1.gold
+++ b/SBVTestSuite/GoldFiles/pareto1.gold
@@ -5,88 +5,88 @@
   max_x_plus_y = 2 :: Integer
   min_y        = 1 :: Integer
 Pareto front #2: Optimal model:
-  x            = 2 :: Integer
-  y            = 2 :: Integer
-  min_x        = 2 :: Integer
-  max_x_plus_y = 4 :: Integer
-  min_y        = 2 :: Integer
-Pareto front #3: Optimal model:
-  x            = 3 :: Integer
+  x            = 0 :: Integer
   y            = 3 :: Integer
-  min_x        = 3 :: Integer
-  max_x_plus_y = 6 :: Integer
+  min_x        = 0 :: Integer
+  max_x_plus_y = 3 :: Integer
   min_y        = 3 :: Integer
+Pareto front #3: Optimal model:
+  x            = 0 :: Integer
+  y            = 4 :: Integer
+  min_x        = 0 :: Integer
+  max_x_plus_y = 4 :: Integer
+  min_y        = 4 :: Integer
 Pareto front #4: Optimal model:
-  x            = 4 :: Integer
-  y            = 1 :: Integer
-  min_x        = 4 :: Integer
-  max_x_plus_y = 5 :: Integer
-  min_y        = 1 :: Integer
-Pareto front #5: Optimal model:
   x            = 3 :: Integer
   y            = 2 :: Integer
   min_x        = 3 :: Integer
   max_x_plus_y = 5 :: Integer
   min_y        = 2 :: Integer
+Pareto front #5: Optimal model:
+  x            = 2 :: Integer
+  y            = 1 :: Integer
+  min_x        = 2 :: Integer
+  max_x_plus_y = 3 :: Integer
+  min_y        = 1 :: Integer
 Pareto front #6: Optimal model:
-  x            = 5 :: Integer
+  x            = 3 :: Integer
   y            = 1 :: Integer
-  min_x        = 5 :: Integer
-  max_x_plus_y = 6 :: Integer
+  min_x        = 3 :: Integer
+  max_x_plus_y = 4 :: Integer
   min_y        = 1 :: Integer
 Pareto front #7: Optimal model:
-  x            = 5 :: Integer
+  x            = 4 :: Integer
   y            = 0 :: Integer
-  min_x        = 5 :: Integer
-  max_x_plus_y = 5 :: Integer
+  min_x        = 4 :: Integer
+  max_x_plus_y = 4 :: Integer
   min_y        = 0 :: Integer
 Pareto front #8: Optimal model:
   x            = 2 :: Integer
-  y            = 4 :: Integer
+  y            = 2 :: Integer
   min_x        = 2 :: Integer
-  max_x_plus_y = 6 :: Integer
-  min_y        = 4 :: Integer
+  max_x_plus_y = 4 :: Integer
+  min_y        = 2 :: Integer
 Pareto front #9: Optimal model:
-  x            = 3 :: Integer
-  y            = 4 :: Integer
-  min_x        = 3 :: Integer
-  max_x_plus_y = 7 :: Integer
-  min_y        = 4 :: Integer
+  x            = 1 :: Integer
+  y            = 3 :: Integer
+  min_x        = 1 :: Integer
+  max_x_plus_y = 4 :: Integer
+  min_y        = 3 :: Integer
 Pareto front #10: Optimal model:
-  x            = 5 :: Integer
-  y            = 2 :: Integer
-  min_x        = 5 :: Integer
-  max_x_plus_y = 7 :: Integer
-  min_y        = 2 :: Integer
+  x            = 0 :: Integer
+  y            = 0 :: Integer
+  min_x        = 0 :: Integer
+  max_x_plus_y = 0 :: Integer
+  min_y        = 0 :: Integer
 Pareto front #11: Optimal model:
-  x            = 4 :: Integer
-  y            = 4 :: Integer
-  min_x        = 4 :: Integer
-  max_x_plus_y = 8 :: Integer
-  min_y        = 4 :: Integer
+  x            = 0 :: Integer
+  y            = 1 :: Integer
+  min_x        = 0 :: Integer
+  max_x_plus_y = 1 :: Integer
+  min_y        = 1 :: Integer
 Pareto front #12: Optimal model:
-  x            = 4 :: Integer
-  y            = 3 :: Integer
-  min_x        = 4 :: Integer
-  max_x_plus_y = 7 :: Integer
-  min_y        = 3 :: Integer
+  x            = 2 :: Integer
+  y            = 0 :: Integer
+  min_x        = 2 :: Integer
+  max_x_plus_y = 2 :: Integer
+  min_y        = 0 :: Integer
 Pareto front #13: Optimal model:
-  x            = 5 :: Integer
-  y            = 3 :: Integer
-  min_x        = 5 :: Integer
-  max_x_plus_y = 8 :: Integer
-  min_y        = 3 :: Integer
+  x            = 0 :: Integer
+  y            = 2 :: Integer
+  min_x        = 0 :: Integer
+  max_x_plus_y = 2 :: Integer
+  min_y        = 2 :: Integer
 Pareto front #14: Optimal model:
-  x            = 5 :: Integer
-  y            = 4 :: Integer
-  min_x        = 5 :: Integer
-  max_x_plus_y = 9 :: Integer
-  min_y        = 4 :: Integer
+  x            = 3 :: Integer
+  y            = 0 :: Integer
+  min_x        = 3 :: Integer
+  max_x_plus_y = 3 :: Integer
+  min_y        = 0 :: Integer
 Pareto front #15: Optimal model:
-  x            = 4 :: Integer
+  x            = 1 :: Integer
   y            = 2 :: Integer
-  min_x        = 4 :: Integer
-  max_x_plus_y = 6 :: Integer
+  min_x        = 1 :: Integer
+  max_x_plus_y = 3 :: Integer
   min_y        = 2 :: Integer
 Pareto front #16: Optimal model:
   x            = 1 :: Integer
@@ -95,86 +95,86 @@
   max_x_plus_y = 1 :: Integer
   min_y        = 0 :: Integer
 Pareto front #17: Optimal model:
-  x            = 0 :: Integer
+  x            = 5 :: Integer
   y            = 0 :: Integer
-  min_x        = 0 :: Integer
-  max_x_plus_y = 0 :: Integer
+  min_x        = 5 :: Integer
+  max_x_plus_y = 5 :: Integer
   min_y        = 0 :: Integer
 Pareto front #18: Optimal model:
-  x            = 2 :: Integer
-  y            = 0 :: Integer
-  min_x        = 2 :: Integer
-  max_x_plus_y = 2 :: Integer
-  min_y        = 0 :: Integer
-Pareto front #19: Optimal model:
-  x            = 3 :: Integer
-  y            = 0 :: Integer
-  min_x        = 3 :: Integer
-  max_x_plus_y = 3 :: Integer
-  min_y        = 0 :: Integer
-Pareto front #20: Optimal model:
-  x            = 0 :: Integer
+  x            = 4 :: Integer
   y            = 1 :: Integer
-  min_x        = 0 :: Integer
-  max_x_plus_y = 1 :: Integer
+  min_x        = 4 :: Integer
+  max_x_plus_y = 5 :: Integer
   min_y        = 1 :: Integer
-Pareto front #21: Optimal model:
-  x            = 2 :: Integer
+Pareto front #19: Optimal model:
+  x            = 5 :: Integer
   y            = 1 :: Integer
-  min_x        = 2 :: Integer
-  max_x_plus_y = 3 :: Integer
+  min_x        = 5 :: Integer
+  max_x_plus_y = 6 :: Integer
   min_y        = 1 :: Integer
-Pareto front #22: Optimal model:
+Pareto front #20: Optimal model:
   x            = 1 :: Integer
-  y            = 2 :: Integer
+  y            = 4 :: Integer
   min_x        = 1 :: Integer
-  max_x_plus_y = 3 :: Integer
-  min_y        = 2 :: Integer
-Pareto front #23: Optimal model:
-  x            = 0 :: Integer
+  max_x_plus_y = 5 :: Integer
+  min_y        = 4 :: Integer
+Pareto front #21: Optimal model:
+  x            = 4 :: Integer
   y            = 2 :: Integer
-  min_x        = 0 :: Integer
-  max_x_plus_y = 2 :: Integer
+  min_x        = 4 :: Integer
+  max_x_plus_y = 6 :: Integer
   min_y        = 2 :: Integer
-Pareto front #24: Optimal model:
-  x            = 0 :: Integer
+Pareto front #22: Optimal model:
+  x            = 4 :: Integer
+  y            = 3 :: Integer
+  min_x        = 4 :: Integer
+  max_x_plus_y = 7 :: Integer
+  min_y        = 3 :: Integer
+Pareto front #23: Optimal model:
+  x            = 3 :: Integer
   y            = 4 :: Integer
-  min_x        = 0 :: Integer
-  max_x_plus_y = 4 :: Integer
+  min_x        = 3 :: Integer
+  max_x_plus_y = 7 :: Integer
   min_y        = 4 :: Integer
+Pareto front #24: Optimal model:
+  x            = 5 :: Integer
+  y            = 2 :: Integer
+  min_x        = 5 :: Integer
+  max_x_plus_y = 7 :: Integer
+  min_y        = 2 :: Integer
 Pareto front #25: Optimal model:
-  x            = 1 :: Integer
+  x            = 3 :: Integer
   y            = 3 :: Integer
-  min_x        = 1 :: Integer
-  max_x_plus_y = 4 :: Integer
+  min_x        = 3 :: Integer
+  max_x_plus_y = 6 :: Integer
   min_y        = 3 :: Integer
 Pareto front #26: Optimal model:
-  x            = 2 :: Integer
+  x            = 5 :: Integer
   y            = 3 :: Integer
-  min_x        = 2 :: Integer
-  max_x_plus_y = 5 :: Integer
+  min_x        = 5 :: Integer
+  max_x_plus_y = 8 :: Integer
   min_y        = 3 :: Integer
 Pareto front #27: Optimal model:
-  x            = 1 :: Integer
+  x            = 4 :: Integer
   y            = 4 :: Integer
-  min_x        = 1 :: Integer
-  max_x_plus_y = 5 :: Integer
+  min_x        = 4 :: Integer
+  max_x_plus_y = 8 :: Integer
   min_y        = 4 :: Integer
 Pareto front #28: Optimal model:
-  x            = 0 :: Integer
-  y            = 3 :: Integer
-  min_x        = 0 :: Integer
-  max_x_plus_y = 3 :: Integer
-  min_y        = 3 :: Integer
+  x            = 2 :: Integer
+  y            = 4 :: Integer
+  min_x        = 2 :: Integer
+  max_x_plus_y = 6 :: Integer
+  min_y        = 4 :: Integer
 Pareto front #29: Optimal model:
-  x            = 4 :: Integer
-  y            = 0 :: Integer
-  min_x        = 4 :: Integer
-  max_x_plus_y = 4 :: Integer
-  min_y        = 0 :: Integer
+  x            = 5 :: Integer
+  y            = 4 :: Integer
+  min_x        = 5 :: Integer
+  max_x_plus_y = 9 :: Integer
+  min_y        = 4 :: Integer
 Pareto front #30: Optimal model:
-  x            = 3 :: Integer
-  y            = 1 :: Integer
-  min_x        = 3 :: Integer
-  max_x_plus_y = 4 :: Integer
-  min_y        = 1 :: Integer
+  x            = 2 :: Integer
+  y            = 3 :: Integer
+  min_x        = 2 :: Integer
+  max_x_plus_y = 5 :: Integer
+  min_y        = 3 :: Integer
diff --git a/SBVTestSuite/GoldFiles/pareto2.gold b/SBVTestSuite/GoldFiles/pareto2.gold
--- a/SBVTestSuite/GoldFiles/pareto2.gold
+++ b/SBVTestSuite/GoldFiles/pareto2.gold
@@ -1,182 +1,182 @@
 Pareto front #1: Optimal model:
+  x            = 0 :: Integer
+  y            = 1 :: Integer
+  min_x        = 0 :: Integer
+  max_y        = 1 :: Integer
+  max_x_plus_y = 1 :: Integer
+Pareto front #2: Optimal model:
+  x            = 0 :: Integer
+  y            = 2 :: Integer
+  min_x        = 0 :: Integer
+  max_y        = 2 :: Integer
+  max_x_plus_y = 2 :: Integer
+Pareto front #3: Optimal model:
+  x            = 0 :: Integer
+  y            = 3 :: Integer
+  min_x        = 0 :: Integer
+  max_y        = 3 :: Integer
+  max_x_plus_y = 3 :: Integer
+Pareto front #4: Optimal model:
+  x            = 0 :: Integer
+  y            = 5 :: Integer
+  min_x        = 0 :: Integer
+  max_y        = 5 :: Integer
+  max_x_plus_y = 5 :: Integer
+Pareto front #5: Optimal model:
+  x            = 0 :: Integer
+  y            = 7 :: Integer
+  min_x        = 0 :: Integer
+  max_y        = 7 :: Integer
+  max_x_plus_y = 7 :: Integer
+Pareto front #6: Optimal model:
+  x            = 0 :: Integer
+  y            = 6 :: Integer
+  min_x        = 0 :: Integer
+  max_y        = 6 :: Integer
+  max_x_plus_y = 6 :: Integer
+Pareto front #7: Optimal model:
+  x            = 0 :: Integer
+  y            = 0 :: Integer
+  min_x        = 0 :: Integer
+  max_y        = 0 :: Integer
+  max_x_plus_y = 0 :: Integer
+Pareto front #8: Optimal model:
   x            =  0 :: Integer
-  y            = -1 :: Integer
+  y            = -2 :: Integer
   min_x        =  0 :: Integer
-  max_y        = -1 :: Integer
-  max_x_plus_y = -1 :: Integer
-Pareto front #2: Optimal model:
+  max_y        = -2 :: Integer
+  max_x_plus_y = -2 :: Integer
+Pareto front #9: Optimal model:
   x            =  0 :: Integer
-  y            = -3 :: Integer
+  y            = -4 :: Integer
   min_x        =  0 :: Integer
-  max_y        = -3 :: Integer
-  max_x_plus_y = -3 :: Integer
-Pareto front #3: Optimal model:
+  max_y        = -4 :: Integer
+  max_x_plus_y = -4 :: Integer
+Pareto front #10: Optimal model:
   x            =  0 :: Integer
   y            = -5 :: Integer
   min_x        =  0 :: Integer
   max_y        = -5 :: Integer
   max_x_plus_y = -5 :: Integer
-Pareto front #4: Optimal model:
+Pareto front #11: Optimal model:
   x            =  0 :: Integer
-  y            = -7 :: Integer
+  y            = -6 :: Integer
   min_x        =  0 :: Integer
-  max_y        = -7 :: Integer
-  max_x_plus_y = -7 :: Integer
-Pareto front #5: Optimal model:
+  max_y        = -6 :: Integer
+  max_x_plus_y = -6 :: Integer
+Pareto front #12: Optimal model:
   x            =  0 :: Integer
+  y            = -8 :: Integer
+  min_x        =  0 :: Integer
+  max_y        = -8 :: Integer
+  max_x_plus_y = -8 :: Integer
+Pareto front #13: Optimal model:
+  x            =  0 :: Integer
   y            = -9 :: Integer
   min_x        =  0 :: Integer
   max_y        = -9 :: Integer
   max_x_plus_y = -9 :: Integer
-Pareto front #6: Optimal model:
-  x            =   0 :: Integer
-  y            = -10 :: Integer
-  min_x        =   0 :: Integer
-  max_y        = -10 :: Integer
-  max_x_plus_y = -10 :: Integer
-Pareto front #7: Optimal model:
+Pareto front #14: Optimal model:
   x            =   0 :: Integer
   y            = -11 :: Integer
   min_x        =   0 :: Integer
   max_y        = -11 :: Integer
   max_x_plus_y = -11 :: Integer
-Pareto front #8: Optimal model:
+Pareto front #15: Optimal model:
   x            =   0 :: Integer
   y            = -13 :: Integer
   min_x        =   0 :: Integer
   max_y        = -13 :: Integer
   max_x_plus_y = -13 :: Integer
-Pareto front #9: Optimal model:
+Pareto front #16: Optimal model:
   x            =   0 :: Integer
   y            = -15 :: Integer
   min_x        =   0 :: Integer
   max_y        = -15 :: Integer
   max_x_plus_y = -15 :: Integer
-Pareto front #10: Optimal model:
+Pareto front #17: Optimal model:
   x            =   0 :: Integer
   y            = -16 :: Integer
   min_x        =   0 :: Integer
   max_y        = -16 :: Integer
   max_x_plus_y = -16 :: Integer
-Pareto front #11: Optimal model:
+Pareto front #18: Optimal model:
   x            =   0 :: Integer
   y            = -18 :: Integer
   min_x        =   0 :: Integer
   max_y        = -18 :: Integer
   max_x_plus_y = -18 :: Integer
-Pareto front #12: Optimal model:
+Pareto front #19: Optimal model:
   x            =   0 :: Integer
+  y            = -19 :: Integer
+  min_x        =   0 :: Integer
+  max_y        = -19 :: Integer
+  max_x_plus_y = -19 :: Integer
+Pareto front #20: Optimal model:
+  x            =   0 :: Integer
   y            = -20 :: Integer
   min_x        =   0 :: Integer
   max_y        = -20 :: Integer
   max_x_plus_y = -20 :: Integer
-Pareto front #13: Optimal model:
+Pareto front #21: Optimal model:
   x            =   0 :: Integer
   y            = -22 :: Integer
   min_x        =   0 :: Integer
   max_y        = -22 :: Integer
   max_x_plus_y = -22 :: Integer
-Pareto front #14: Optimal model:
-  x            =   0 :: Integer
-  y            = -23 :: Integer
-  min_x        =   0 :: Integer
-  max_y        = -23 :: Integer
-  max_x_plus_y = -23 :: Integer
-Pareto front #15: Optimal model:
+Pareto front #22: Optimal model:
   x            =   0 :: Integer
   y            = -24 :: Integer
   min_x        =   0 :: Integer
   max_y        = -24 :: Integer
   max_x_plus_y = -24 :: Integer
-Pareto front #16: Optimal model:
+Pareto front #23: Optimal model:
   x            =   0 :: Integer
-  y            = -26 :: Integer
+  y            = -25 :: Integer
   min_x        =   0 :: Integer
-  max_y        = -26 :: Integer
-  max_x_plus_y = -26 :: Integer
-Pareto front #17: Optimal model:
+  max_y        = -25 :: Integer
+  max_x_plus_y = -25 :: Integer
+Pareto front #24: Optimal model:
   x            =   0 :: Integer
+  y            = -27 :: Integer
+  min_x        =   0 :: Integer
+  max_y        = -27 :: Integer
+  max_x_plus_y = -27 :: Integer
+Pareto front #25: Optimal model:
+  x            =   0 :: Integer
   y            = -28 :: Integer
   min_x        =   0 :: Integer
   max_y        = -28 :: Integer
   max_x_plus_y = -28 :: Integer
-Pareto front #18: Optimal model:
-  x            =   0 :: Integer
-  y            = -29 :: Integer
-  min_x        =   0 :: Integer
-  max_y        = -29 :: Integer
-  max_x_plus_y = -29 :: Integer
-Pareto front #19: Optimal model:
+Pareto front #26: Optimal model:
   x            =   0 :: Integer
-  y            = -31 :: Integer
+  y            = -30 :: Integer
   min_x        =   0 :: Integer
-  max_y        = -31 :: Integer
-  max_x_plus_y = -31 :: Integer
-Pareto front #20: Optimal model:
+  max_y        = -30 :: Integer
+  max_x_plus_y = -30 :: Integer
+Pareto front #27: Optimal model:
   x            =   0 :: Integer
   y            = -32 :: Integer
   min_x        =   0 :: Integer
   max_y        = -32 :: Integer
   max_x_plus_y = -32 :: Integer
-Pareto front #21: Optimal model:
+Pareto front #28: Optimal model:
   x            =   0 :: Integer
-  y            = -34 :: Integer
+  y            = -33 :: Integer
   min_x        =   0 :: Integer
-  max_y        = -34 :: Integer
-  max_x_plus_y = -34 :: Integer
-Pareto front #22: Optimal model:
+  max_y        = -33 :: Integer
+  max_x_plus_y = -33 :: Integer
+Pareto front #29: Optimal model:
   x            =   0 :: Integer
   y            = -35 :: Integer
   min_x        =   0 :: Integer
   max_y        = -35 :: Integer
   max_x_plus_y = -35 :: Integer
-Pareto front #23: Optimal model:
+Pareto front #30: Optimal model:
   x            =   0 :: Integer
   y            = -37 :: Integer
   min_x        =   0 :: Integer
   max_y        = -37 :: Integer
   max_x_plus_y = -37 :: Integer
-Pareto front #24: Optimal model:
-  x            =   0 :: Integer
-  y            = -38 :: Integer
-  min_x        =   0 :: Integer
-  max_y        = -38 :: Integer
-  max_x_plus_y = -38 :: Integer
-Pareto front #25: Optimal model:
-  x            =   0 :: Integer
-  y            = -40 :: Integer
-  min_x        =   0 :: Integer
-  max_y        = -40 :: Integer
-  max_x_plus_y = -40 :: Integer
-Pareto front #26: Optimal model:
-  x            =   0 :: Integer
-  y            = -41 :: Integer
-  min_x        =   0 :: Integer
-  max_y        = -41 :: Integer
-  max_x_plus_y = -41 :: Integer
-Pareto front #27: Optimal model:
-  x            =   0 :: Integer
-  y            = -43 :: Integer
-  min_x        =   0 :: Integer
-  max_y        = -43 :: Integer
-  max_x_plus_y = -43 :: Integer
-Pareto front #28: Optimal model:
-  x            =   0 :: Integer
-  y            = -44 :: Integer
-  min_x        =   0 :: Integer
-  max_y        = -44 :: Integer
-  max_x_plus_y = -44 :: Integer
-Pareto front #29: Optimal model:
-  x            =   0 :: Integer
-  y            = -45 :: Integer
-  min_x        =   0 :: Integer
-  max_y        = -45 :: Integer
-  max_x_plus_y = -45 :: Integer
-Pareto front #30: Optimal model:
-  x            =   0 :: Integer
-  y            = -47 :: Integer
-  min_x        =   0 :: Integer
-  max_y        = -47 :: Integer
-  max_x_plus_y = -47 :: Integer
 *** Note: Pareto-front extraction was terminated as requested by the user.
 ***       There might be many other results!
diff --git a/SBVTestSuite/GoldFiles/pbAtLeast.gold b/SBVTestSuite/GoldFiles/pbAtLeast.gold
--- a/SBVTestSuite/GoldFiles/pbAtLeast.gold
+++ b/SBVTestSuite/GoldFiles/pbAtLeast.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/pbAtMost.gold b/SBVTestSuite/GoldFiles/pbAtMost.gold
--- a/SBVTestSuite/GoldFiles/pbAtMost.gold
+++ b/SBVTestSuite/GoldFiles/pbAtMost.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/pbEq.gold b/SBVTestSuite/GoldFiles/pbEq.gold
--- a/SBVTestSuite/GoldFiles/pbEq.gold
+++ b/SBVTestSuite/GoldFiles/pbEq.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/pbEq2.gold b/SBVTestSuite/GoldFiles/pbEq2.gold
--- a/SBVTestSuite/GoldFiles/pbEq2.gold
+++ b/SBVTestSuite/GoldFiles/pbEq2.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/pbExactly.gold b/SBVTestSuite/GoldFiles/pbExactly.gold
--- a/SBVTestSuite/GoldFiles/pbExactly.gold
+++ b/SBVTestSuite/GoldFiles/pbExactly.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/pbGe.gold b/SBVTestSuite/GoldFiles/pbGe.gold
--- a/SBVTestSuite/GoldFiles/pbGe.gold
+++ b/SBVTestSuite/GoldFiles/pbGe.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/pbLe.gold b/SBVTestSuite/GoldFiles/pbLe.gold
--- a/SBVTestSuite/GoldFiles/pbLe.gold
+++ b/SBVTestSuite/GoldFiles/pbLe.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/pbMutexed.gold b/SBVTestSuite/GoldFiles/pbMutexed.gold
--- a/SBVTestSuite/GoldFiles/pbMutexed.gold
+++ b/SBVTestSuite/GoldFiles/pbMutexed.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/pbStronglyMutexed.gold b/SBVTestSuite/GoldFiles/pbStronglyMutexed.gold
--- a/SBVTestSuite/GoldFiles/pbStronglyMutexed.gold
+++ b/SBVTestSuite/GoldFiles/pbStronglyMutexed.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/popCount1.gold b/SBVTestSuite/GoldFiles/popCount1.gold
--- a/SBVTestSuite/GoldFiles/popCount1.gold
+++ b/SBVTestSuite/GoldFiles/popCount1.gold
@@ -12,11 +12,11 @@
 popCount.o: popCount.c popCount.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
-popCount_driver.o: popCount_driver.c
+popCount_driver.o: popCount_driver.c popCount.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
 popCount_driver: popCount.o popCount_driver.o
-	${CC} ${CCFLAGS} $^ -o $@
+	${CC} ${CCFLAGS} $^ -o $@ ${LDFLAGS}
 
 clean:
 	rm -f *.o
@@ -27,9 +27,10 @@
 == BEGIN: "popCount.h" ================
 /* Header file for popCount. Automatically generated by SBV. Do not edit! */
 
-#ifndef __popCount__HEADER_INCLUDED__
-#define __popCount__HEADER_INCLUDED__
+#ifndef SBV_GENERATED_popCount_HEADER_INCLUDED
+#define SBV_GENERATED_popCount_HEADER_INCLUDED
 
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <inttypes.h>
@@ -38,6 +39,13 @@
 #include <string.h>
 #include <math.h>
 
+/* Floating-point calling convention:
+ * Enter generated code in FE_TONEAREST (round-to-nearest, ties-to-even).
+ * Callbacks must preserve this mode before returning or re-entering.
+ * Generated code does not check or change the hardware rounding mode.
+ * Custom builds must disable implicit FP contraction, including at LTO link time.
+ */
+
 /* The boolean type */
 typedef bool SBool;
 
@@ -62,7 +70,7 @@
 /* Entry point prototype: */
 SWord8 popCount(const SWord64 x);
 
-#endif /* __popCount__HEADER_INCLUDED__ */
+#endif /* SBV_GENERATED_popCount_HEADER_INCLUDED */
 == END: "popCount.h" ==================
 == BEGIN: "popCount_driver.c" ================
 /* Example driver program for popCount. */
@@ -73,9 +81,9 @@
 
 int main(void)
 {
-  const SWord8 __result = popCount(0x0123456789abcdefULL);
+  const SWord8 sbv_result = popCount(0x0123456789abcdefULL);
 
-  printf("popCount(0x0123456789abcdefULL) = %"PRIu8"\n", __result);
+  printf("popCount(0x0123456789abcdefULL) = %"PRIu8"\n", sbv_result);
 
   return 0;
 }
@@ -85,9 +93,68 @@
 
 #include "popCount.h"
 
-SWord8 popCount(const SWord64 x)
+/* Exact bit-vector runtime. All arithmetic is modulo the declared width. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static inline SBV_CGEN_UNUSED SWord64 sbv_bv_u64_shl(SWord64 a, SWord64 amount)
 {
-  const SWord64 s0 = x;
+  const uint64_t n = (uint64_t) (SWord64) amount;
+  const SWord64 result = n >= 64 ? (SWord64) 0 : (SWord64) ((uint64_t) (SWord64) a << n);
+  return result;
+}
+
+static inline SBV_CGEN_UNUSED SWord64 sbv_bv_u64_lshr(SWord64 a, SWord64 amount)
+{
+  const uint64_t n = (uint64_t) (SWord64) amount;
+  return n >= 64 ? (SWord64) 0 : (SWord64) ((uint64_t) (SWord64) a >> n);
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_u8_add(SWord8 a, SWord8 b)
+{
+  const SWord8 bits = (SWord8) ((((uint64_t) (SWord8) a) + ((uint64_t) (SWord8) b)) & UINT64_C(0x00000000000000ff));
+  return (SWord8) bits;
+}
+
+
+SWord8 popCount(const SWord64 sbv_input_0)
+{
+  const SWord64 s0 = sbv_input_0;
+  const SWord64 s11 = s0 & 0x00000000000000ffULL;
+  const SWord64 s14 = sbv_bv_u64_lshr(s0, 0x0000000000000008ULL);
+  const SWord64 s15 = 0x00000000000000ffULL & s14;
+  const SWord64 s18 = sbv_bv_u64_lshr(s14, 0x0000000000000008ULL);
+  const SWord64 s19 = 0x00000000000000ffULL & s18;
+  const SWord64 s22 = sbv_bv_u64_lshr(s18, 0x0000000000000008ULL);
+  const SWord64 s23 = 0x00000000000000ffULL & s22;
+  const SWord64 s26 = sbv_bv_u64_lshr(s22, 0x0000000000000008ULL);
+  const SWord64 s27 = 0x00000000000000ffULL & s26;
+  const SWord64 s30 = sbv_bv_u64_lshr(s26, 0x0000000000000008ULL);
+  const SWord64 s31 = 0x00000000000000ffULL & s30;
+  const SWord64 s34 = sbv_bv_u64_lshr(s30, 0x0000000000000008ULL);
+  const SWord64 s35 = 0x00000000000000ffULL & s34;
+  const SWord64 s38 = sbv_bv_u64_lshr(s34, 0x0000000000000008ULL);
+  const SWord64 s39 = 0x00000000000000ffULL & s38;
+        SWord8  s12;
+        SWord8  s16;
+        SWord8  s17;
+        SWord8  s20;
+        SWord8  s21;
+        SWord8  s24;
+        SWord8  s25;
+        SWord8  s28;
+        SWord8  s29;
+        SWord8  s32;
+        SWord8  s33;
+        SWord8  s36;
+        SWord8  s37;
+        SWord8  s40;
+        SWord8  s41;
   static const SWord8 table0[] = {
       0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3,
       3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4,
@@ -102,36 +169,21 @@
       5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5,
       5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
   };
-  const SWord64 s11 = s0 & 0x00000000000000ffULL;
-  const SWord8  s12 = table0[s11];
-  const SWord64 s14 = s0 >> 8;
-  const SWord64 s15 = 0x00000000000000ffULL & s14;
-  const SWord8  s16 = table0[s15];
-  const SWord8  s17 = s12 + s16;
-  const SWord64 s18 = s14 >> 8;
-  const SWord64 s19 = 0x00000000000000ffULL & s18;
-  const SWord8  s20 = table0[s19];
-  const SWord8  s21 = s17 + s20;
-  const SWord64 s22 = s18 >> 8;
-  const SWord64 s23 = 0x00000000000000ffULL & s22;
-  const SWord8  s24 = table0[s23];
-  const SWord8  s25 = s21 + s24;
-  const SWord64 s26 = s22 >> 8;
-  const SWord64 s27 = 0x00000000000000ffULL & s26;
-  const SWord8  s28 = table0[s27];
-  const SWord8  s29 = s25 + s28;
-  const SWord64 s30 = s26 >> 8;
-  const SWord64 s31 = 0x00000000000000ffULL & s30;
-  const SWord8  s32 = table0[s31];
-  const SWord8  s33 = s29 + s32;
-  const SWord64 s34 = s30 >> 8;
-  const SWord64 s35 = 0x00000000000000ffULL & s34;
-  const SWord8  s36 = table0[s35];
-  const SWord8  s37 = s33 + s36;
-  const SWord64 s38 = s34 >> 8;
-  const SWord64 s39 = 0x00000000000000ffULL & s38;
-  const SWord8  s40 = table0[s39];
-  const SWord8  s41 = s37 + s40;
+  s12 = table0[s11];
+  s16 = table0[s15];
+  s17 = sbv_bv_u8_add(s12, s16);
+  s20 = table0[s19];
+  s21 = sbv_bv_u8_add(s17, s20);
+  s24 = table0[s23];
+  s25 = sbv_bv_u8_add(s21, s24);
+  s28 = table0[s27];
+  s29 = sbv_bv_u8_add(s25, s28);
+  s32 = table0[s31];
+  s33 = sbv_bv_u8_add(s29, s32);
+  s36 = table0[s35];
+  s37 = sbv_bv_u8_add(s33, s36);
+  s40 = table0[s39];
+  s41 = sbv_bv_u8_add(s37, s40);
 
   return s41;
 }
diff --git a/SBVTestSuite/GoldFiles/popCount2.gold b/SBVTestSuite/GoldFiles/popCount2.gold
--- a/SBVTestSuite/GoldFiles/popCount2.gold
+++ b/SBVTestSuite/GoldFiles/popCount2.gold
@@ -12,11 +12,11 @@
 popCount.o: popCount.c popCount.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
-popCount_driver.o: popCount_driver.c
+popCount_driver.o: popCount_driver.c popCount.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
 popCount_driver: popCount.o popCount_driver.o
-	${CC} ${CCFLAGS} $^ -o $@
+	${CC} ${CCFLAGS} $^ -o $@ ${LDFLAGS}
 
 clean:
 	rm -f *.o
@@ -27,9 +27,10 @@
 == BEGIN: "popCount.h" ================
 /* Header file for popCount. Automatically generated by SBV. Do not edit! */
 
-#ifndef __popCount__HEADER_INCLUDED__
-#define __popCount__HEADER_INCLUDED__
+#ifndef SBV_GENERATED_popCount_HEADER_INCLUDED
+#define SBV_GENERATED_popCount_HEADER_INCLUDED
 
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <inttypes.h>
@@ -38,6 +39,13 @@
 #include <string.h>
 #include <math.h>
 
+/* Floating-point calling convention:
+ * Enter generated code in FE_TONEAREST (round-to-nearest, ties-to-even).
+ * Callbacks must preserve this mode before returning or re-entering.
+ * Generated code does not check or change the hardware rounding mode.
+ * Custom builds must disable implicit FP contraction, including at LTO link time.
+ */
+
 /* The boolean type */
 typedef bool SBool;
 
@@ -62,7 +70,7 @@
 /* Entry point prototype: */
 SWord8 popCount(const SWord64 x);
 
-#endif /* __popCount__HEADER_INCLUDED__ */
+#endif /* SBV_GENERATED_popCount_HEADER_INCLUDED */
 == END: "popCount.h" ==================
 == BEGIN: "popCount_driver.c" ================
 /* Example driver program for popCount. */
@@ -73,9 +81,9 @@
 
 int main(void)
 {
-  const SWord8 __result = popCount(0x0123456789abcdefULL);
+  const SWord8 sbv_result = popCount(0x0123456789abcdefULL);
 
-  printf("popCount(0x0123456789abcdefULL) = %"PRIu8"\n", __result);
+  printf("popCount(0x0123456789abcdefULL) = %"PRIu8"\n", sbv_result);
 
   return 0;
 }
@@ -85,9 +93,68 @@
 
 #include "popCount.h"
 
-SWord8 popCount(const SWord64 x)
+/* Exact bit-vector runtime. All arithmetic is modulo the declared width. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static inline SBV_CGEN_UNUSED SWord64 sbv_bv_u64_shl(SWord64 a, SWord64 amount)
 {
-  const SWord64 s0 = x;
+  const uint64_t n = (uint64_t) (SWord64) amount;
+  const SWord64 result = n >= 64 ? (SWord64) 0 : (SWord64) ((uint64_t) (SWord64) a << n);
+  return result;
+}
+
+static inline SBV_CGEN_UNUSED SWord64 sbv_bv_u64_lshr(SWord64 a, SWord64 amount)
+{
+  const uint64_t n = (uint64_t) (SWord64) amount;
+  return n >= 64 ? (SWord64) 0 : (SWord64) ((uint64_t) (SWord64) a >> n);
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_u8_add(SWord8 a, SWord8 b)
+{
+  const SWord8 bits = (SWord8) ((((uint64_t) (SWord8) a) + ((uint64_t) (SWord8) b)) & UINT64_C(0x00000000000000ff));
+  return (SWord8) bits;
+}
+
+
+SWord8 popCount(const SWord64 sbv_input_0)
+{
+  const SWord64 s0 = sbv_input_0;
+  const SWord64 s11 = s0 & 0x00000000000000ffULL;
+  const SWord64 s14 = sbv_bv_u64_lshr(s0, 0x0000000000000008ULL);
+  const SWord64 s15 = 0x00000000000000ffULL & s14;
+  const SWord64 s18 = sbv_bv_u64_lshr(s14, 0x0000000000000008ULL);
+  const SWord64 s19 = 0x00000000000000ffULL & s18;
+  const SWord64 s22 = sbv_bv_u64_lshr(s18, 0x0000000000000008ULL);
+  const SWord64 s23 = 0x00000000000000ffULL & s22;
+  const SWord64 s26 = sbv_bv_u64_lshr(s22, 0x0000000000000008ULL);
+  const SWord64 s27 = 0x00000000000000ffULL & s26;
+  const SWord64 s30 = sbv_bv_u64_lshr(s26, 0x0000000000000008ULL);
+  const SWord64 s31 = 0x00000000000000ffULL & s30;
+  const SWord64 s34 = sbv_bv_u64_lshr(s30, 0x0000000000000008ULL);
+  const SWord64 s35 = 0x00000000000000ffULL & s34;
+  const SWord64 s38 = sbv_bv_u64_lshr(s34, 0x0000000000000008ULL);
+  const SWord64 s39 = 0x00000000000000ffULL & s38;
+        SWord8  s12;
+        SWord8  s16;
+        SWord8  s17;
+        SWord8  s20;
+        SWord8  s21;
+        SWord8  s24;
+        SWord8  s25;
+        SWord8  s28;
+        SWord8  s29;
+        SWord8  s32;
+        SWord8  s33;
+        SWord8  s36;
+        SWord8  s37;
+        SWord8  s40;
+        SWord8  s41;
   static const SWord8 table0[] = {
       0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3,
       3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4,
@@ -102,36 +169,21 @@
       5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5,
       5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
   };
-  const SWord64 s11 = s0 & 0x00000000000000ffULL;
-  const SWord8  s12 = s11 >= 256 ? 0 : table0[s11];
-  const SWord64 s14 = s0 >> 8;
-  const SWord64 s15 = 0x00000000000000ffULL & s14;
-  const SWord8  s16 = s15 >= 256 ? 0 : table0[s15];
-  const SWord8  s17 = s12 + s16;
-  const SWord64 s18 = s14 >> 8;
-  const SWord64 s19 = 0x00000000000000ffULL & s18;
-  const SWord8  s20 = s19 >= 256 ? 0 : table0[s19];
-  const SWord8  s21 = s17 + s20;
-  const SWord64 s22 = s18 >> 8;
-  const SWord64 s23 = 0x00000000000000ffULL & s22;
-  const SWord8  s24 = s23 >= 256 ? 0 : table0[s23];
-  const SWord8  s25 = s21 + s24;
-  const SWord64 s26 = s22 >> 8;
-  const SWord64 s27 = 0x00000000000000ffULL & s26;
-  const SWord8  s28 = s27 >= 256 ? 0 : table0[s27];
-  const SWord8  s29 = s25 + s28;
-  const SWord64 s30 = s26 >> 8;
-  const SWord64 s31 = 0x00000000000000ffULL & s30;
-  const SWord8  s32 = s31 >= 256 ? 0 : table0[s31];
-  const SWord8  s33 = s29 + s32;
-  const SWord64 s34 = s30 >> 8;
-  const SWord64 s35 = 0x00000000000000ffULL & s34;
-  const SWord8  s36 = s35 >= 256 ? 0 : table0[s35];
-  const SWord8  s37 = s33 + s36;
-  const SWord64 s38 = s34 >> 8;
-  const SWord64 s39 = 0x00000000000000ffULL & s38;
-  const SWord8  s40 = s39 >= 256 ? 0 : table0[s39];
-  const SWord8  s41 = s37 + s40;
+  s12 = s11 >= 256 ? 0 : table0[s11];
+  s16 = s15 >= 256 ? 0 : table0[s15];
+  s17 = sbv_bv_u8_add(s12, s16);
+  s20 = s19 >= 256 ? 0 : table0[s19];
+  s21 = sbv_bv_u8_add(s17, s20);
+  s24 = s23 >= 256 ? 0 : table0[s23];
+  s25 = sbv_bv_u8_add(s21, s24);
+  s28 = s27 >= 256 ? 0 : table0[s27];
+  s29 = sbv_bv_u8_add(s25, s28);
+  s32 = s31 >= 256 ? 0 : table0[s31];
+  s33 = sbv_bv_u8_add(s29, s32);
+  s36 = s35 >= 256 ? 0 : table0[s35];
+  s37 = sbv_bv_u8_add(s33, s36);
+  s40 = s39 >= 256 ? 0 : table0[s39];
+  s41 = sbv_bv_u8_add(s37, s40);
 
   return s41;
 }
diff --git a/SBVTestSuite/GoldFiles/qEnum1.gold b/SBVTestSuite/GoldFiles/qEnum1.gold
--- a/SBVTestSuite/GoldFiles/qEnum1.gold
+++ b/SBVTestSuite/GoldFiles/qEnum1.gold
@@ -5,15 +5,25 @@
 [GOOD] (set-option :smtlib2_compliant true)
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
-[GOOD] (set-logic ALL) ; has user-defined sorts, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
-[GOOD] (declare-datatypes ((BinOp 0)) (((Plus) (Minus) (Times))))
-[GOOD] (define-fun BinOp_constrIndex ((x BinOp)) Int
-          (ite (= x Plus) 0 (ite (= x Minus) 1 2))
-       )
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: BinOp
+[GOOD] (declare-datatype BinOp (
+           (Plus)
+           (Minus)
+           (Times)
+       ))
 [GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () BinOp (as Plus BinOp))
+[GOOD] (define-fun s5 () Int 0)
+[GOOD] (define-fun s6 () BinOp (as Minus BinOp))
+[GOOD] (define-fun s8 () Int 1)
+[GOOD] (define-fun s9 () Int 2)
 [GOOD] ; --- top level inputs ---
 [GOOD] (declare-fun s0 () BinOp) ; tracks user variable "p"
 [GOOD] (declare-fun s1 () BinOp) ; tracks user variable "m"
@@ -23,14 +33,26 @@
 [GOOD] ; --- uninterpreted constants ---
 [GOOD] ; --- user defined functions ---
 [GOOD] ; --- assignments ---
-[GOOD] (define-fun s3 () Bool (<= (BinOp_constrIndex s0) (BinOp_constrIndex s1)))
-[GOOD] (define-fun s4 () Bool (<= (BinOp_constrIndex s1) (BinOp_constrIndex s2)))
-[GOOD] (define-fun s5 () Bool (distinct s0 s1 s2))
+[GOOD] (define-fun s4 () Bool (= s0 s3))
+[GOOD] (define-fun s7 () Bool (= s0 s6))
+[GOOD] (define-fun s10 () Int (ite s7 s8 s9))
+[GOOD] (define-fun s11 () Int (ite s4 s5 s10))
+[GOOD] (define-fun s12 () Bool (= s1 s3))
+[GOOD] (define-fun s13 () Bool (= s1 s6))
+[GOOD] (define-fun s14 () Int (ite s13 s8 s9))
+[GOOD] (define-fun s15 () Int (ite s12 s5 s14))
+[GOOD] (define-fun s16 () Bool (<= s11 s15))
+[GOOD] (define-fun s17 () Bool (= s2 s3))
+[GOOD] (define-fun s18 () Bool (= s2 s6))
+[GOOD] (define-fun s19 () Int (ite s18 s8 s9))
+[GOOD] (define-fun s20 () Int (ite s17 s5 s19))
+[GOOD] (define-fun s21 () Bool (<= s15 s20))
+[GOOD] (define-fun s22 () Bool (distinct s0 s1 s2))
 [GOOD] ; --- delayedEqualities ---
 [GOOD] ; --- formula ---
-[GOOD] (assert s3)
-[GOOD] (assert s4)
-[GOOD] (assert s5)
+[GOOD] (assert s16)
+[GOOD] (assert s21)
+[GOOD] (assert s22)
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
diff --git a/SBVTestSuite/GoldFiles/qOpt_1.gold b/SBVTestSuite/GoldFiles/qOpt_1.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/qOpt_1.gold
@@ -0,0 +1,109 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "x1"
+[GOOD] (declare-fun s4 () Int) ; tracks user variable "x2"
+[GOOD] (declare-fun s7 () Int) ; tracks user variable "x3"
+[GOOD] (declare-fun s10 () Int) ; tracks user variable "x4"
+[GOOD] (declare-fun s13 () Int) ; tracks user variable "x5"
+[GOOD] ; --- optimization tracker variables ---
+[GOOD] (declare-fun s3 () Int) ; tracks goal1
+[GOOD] (declare-fun s6 () Int) ; tracks goal2
+[GOOD] (declare-fun s9 () Int) ; tracks goal3
+[GOOD] (declare-fun s12 () Int) ; tracks goal4
+[GOOD] (declare-fun s15 () Int) ; tracks goal5
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (<= s1 s0))
+[GOOD] (define-fun s5 () Bool (<= s1 s4))
+[GOOD] (define-fun s8 () Bool (<= s1 s7))
+[GOOD] (define-fun s11 () Bool (<= s1 s10))
+[GOOD] (define-fun s14 () Bool (<= s1 s13))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s5)
+[GOOD] (assert s8)
+[GOOD] (assert s11)
+[GOOD] (assert s14)
+[GOOD] (assert (= s0 s3))
+[GOOD] (maximize s3)
+[GOOD] (assert (= s4 s6))
+[GOOD] (maximize s6)
+[GOOD] (assert (= s7 s9))
+[GOOD] (maximize s9)
+[GOOD] (assert (= s10 s12))
+[GOOD] (maximize s12)
+[GOOD] (assert (= s13 s15))
+[GOOD] (maximize s15)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-objectives)
+[RECV] (objectives
+        (s3 oo)
+        (s6  (interval (* (- 1) oo) oo))
+        (s9  (interval (* (- 1) oo) oo))
+        (s12  (interval (* (- 1) oo) oo))
+        (s15  (interval (* (- 1) oo) oo))
+       )
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s4))
+[RECV] ((s4 1))
+[SEND] (get-value (s7))
+[RECV] ((s7 1))
+[SEND] (get-value (s10))
+[RECV] ((s10 1))
+[SEND] (get-value (s13))
+[RECV] ((s13 1))
+[SEND] (get-value (s3))
+[RECV] ((s3 1))
+[SEND] (get-value (s6))
+[RECV] ((s6 1))
+[SEND] (get-value (s9))
+[RECV] ((s9 1))
+[SEND] (get-value (s12))
+[RECV] ((s12 1))
+[SEND] (get-value (s15))
+[RECV] ((s15 1))
+[SEND] (get-objectives)
+[RECV] (objectives
+        (s3 oo)
+        (s6  (interval (* (- 1) oo) oo))
+        (s9  (interval (* (- 1) oo) oo))
+        (s12  (interval (* (- 1) oo) oo))
+        (s15  (interval (* (- 1) oo) oo))
+       )
+*** Solver   : Z3
+*** Exit code: ExitFailure (-15)
+
+EXCEPTION CAUGHT:
+
+*** Data.SBV.getValue: The current solver state is satisfiable in an extension field.
+*** That is, the optimized values assume epsilon/infinity values.
+***
+*** Calls to getValue is not supported in this context. Instead, use the 'optimize' method
+*** directly and inspect the objective values explicitly.
+***
+*** The current model is:
+***
+***     Optimal in an extension field:
+***       goal1 =          oo :: Integer
+***       goal2 = [-oo .. oo] :: [Integer]
+***       goal3 = [-oo .. oo] :: [Integer]
+***       goal4 = [-oo .. oo] :: [Integer]
+***       goal5 = [-oo .. oo] :: [Integer]
+
diff --git a/SBVTestSuite/GoldFiles/qOpt_2.gold b/SBVTestSuite/GoldFiles/qOpt_2.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/qOpt_2.gold
@@ -0,0 +1,119 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 1)
+[GOOD] (define-fun s3 () Int 10)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "x1"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "x2"
+[GOOD] (declare-fun s10 () Int) ; tracks user variable "x3"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "x4"
+[GOOD] (declare-fun s18 () Int) ; tracks user variable "x5"
+[GOOD] ; --- optimization tracker variables ---
+[GOOD] (declare-fun s5 () Int) ; tracks goal1
+[GOOD] (declare-fun s9 () Int) ; tracks goal2
+[GOOD] (declare-fun s13 () Int) ; tracks goal3
+[GOOD] (declare-fun s17 () Int) ; tracks goal4
+[GOOD] (declare-fun s21 () Int) ; tracks goal5
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (<= s1 s0))
+[GOOD] (define-fun s4 () Bool (< s0 s3))
+[GOOD] (define-fun s7 () Bool (<= s1 s6))
+[GOOD] (define-fun s8 () Bool (< s6 s3))
+[GOOD] (define-fun s11 () Bool (<= s1 s10))
+[GOOD] (define-fun s12 () Bool (< s10 s3))
+[GOOD] (define-fun s15 () Bool (<= s1 s14))
+[GOOD] (define-fun s16 () Bool (< s14 s3))
+[GOOD] (define-fun s19 () Bool (<= s1 s18))
+[GOOD] (define-fun s20 () Bool (< s18 s3))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[GOOD] (assert s4)
+[GOOD] (assert s7)
+[GOOD] (assert s8)
+[GOOD] (assert s11)
+[GOOD] (assert s12)
+[GOOD] (assert s15)
+[GOOD] (assert s16)
+[GOOD] (assert s19)
+[GOOD] (assert s20)
+[GOOD] (assert (= s0 s5))
+[GOOD] (maximize s5)
+[GOOD] (assert (= s6 s9))
+[GOOD] (maximize s9)
+[GOOD] (assert (= s10 s13))
+[GOOD] (maximize s13)
+[GOOD] (assert (= s14 s17))
+[GOOD] (maximize s17)
+[GOOD] (assert (= s18 s21))
+[GOOD] (maximize s21)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-objectives)
+[RECV] (objectives
+        (s5 9)
+        (s9 9)
+        (s13 9)
+        (s17 9)
+        (s21 9)
+       )
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-objectives)
+[RECV] (objectives
+        (s5 9)
+        (s9 9)
+        (s13 9)
+        (s17 9)
+        (s21 9)
+       )
+[SEND] (get-value (s6))
+[RECV] ((s6 9))
+[SEND] (get-objectives)
+[RECV] (objectives
+        (s5 9)
+        (s9 9)
+        (s13 9)
+        (s17 9)
+        (s21 9)
+       )
+[SEND] (get-value (s10))
+[RECV] ((s10 9))
+[SEND] (get-objectives)
+[RECV] (objectives
+        (s5 9)
+        (s9 9)
+        (s13 9)
+        (s17 9)
+        (s21 9)
+       )
+[SEND] (get-value (s14))
+[RECV] ((s14 9))
+[SEND] (get-objectives)
+[RECV] (objectives
+        (s5 9)
+        (s9 9)
+        (s13 9)
+        (s17 9)
+        (s21 9)
+       )
+[SEND] (get-value (s18))
+[RECV] ((s18 9))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+
+ FINAL:[9,9,9,9,9]
+DONE!
diff --git a/SBVTestSuite/GoldFiles/qUninterp1.gold b/SBVTestSuite/GoldFiles/qUninterp1.gold
--- a/SBVTestSuite/GoldFiles/qUninterp1.gold
+++ b/SBVTestSuite/GoldFiles/qUninterp1.gold
@@ -5,14 +5,18 @@
 [GOOD] (set-option :smtlib2_compliant true)
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
-[GOOD] (set-logic ALL) ; has user-defined sorts, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
-[GOOD] (declare-datatypes ((L 0)) (((A) (B))))
-[GOOD] (define-fun L_constrIndex ((x L)) Int
-          (ite (= x A) 0 1)
-       )
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has user-defined data-types, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: L
+[GOOD] (declare-datatype L (
+           (A)
+           (B)
+       ))
 [GOOD] ; --- literal constants ---
 [GOOD] ; --- top level inputs ---
 [GOOD] (declare-fun s0 () L)
@@ -26,9 +30,9 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 B))
+[RECV] ((s0 A))
 *** Solver   : Z3
 *** Exit code: ExitSuccess
 
- FINAL:B
+ FINAL:A
 DONE!
diff --git a/SBVTestSuite/GoldFiles/quantifiedB_0.gold b/SBVTestSuite/GoldFiles/quantifiedB_0.gold
--- a/SBVTestSuite/GoldFiles/quantifiedB_0.gold
+++ b/SBVTestSuite/GoldFiles/quantifiedB_0.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantifiedB_1.gold b/SBVTestSuite/GoldFiles/quantifiedB_1.gold
--- a/SBVTestSuite/GoldFiles/quantifiedB_1.gold
+++ b/SBVTestSuite/GoldFiles/quantifiedB_1.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantifiedB_2.gold b/SBVTestSuite/GoldFiles/quantifiedB_2.gold
--- a/SBVTestSuite/GoldFiles/quantifiedB_2.gold
+++ b/SBVTestSuite/GoldFiles/quantifiedB_2.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantifiedB_3.gold b/SBVTestSuite/GoldFiles/quantifiedB_3.gold
--- a/SBVTestSuite/GoldFiles/quantifiedB_3.gold
+++ b/SBVTestSuite/GoldFiles/quantifiedB_3.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantifiedB_4.gold b/SBVTestSuite/GoldFiles/quantifiedB_4.gold
--- a/SBVTestSuite/GoldFiles/quantifiedB_4.gold
+++ b/SBVTestSuite/GoldFiles/quantifiedB_4.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantifiedB_5.gold b/SBVTestSuite/GoldFiles/quantifiedB_5.gold
--- a/SBVTestSuite/GoldFiles/quantifiedB_5.gold
+++ b/SBVTestSuite/GoldFiles/quantifiedB_5.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantifiedB_6.gold b/SBVTestSuite/GoldFiles/quantifiedB_6.gold
--- a/SBVTestSuite/GoldFiles/quantifiedB_6.gold
+++ b/SBVTestSuite/GoldFiles/quantifiedB_6.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantifiedB_7.gold b/SBVTestSuite/GoldFiles/quantifiedB_7.gold
--- a/SBVTestSuite/GoldFiles/quantifiedB_7.gold
+++ b/SBVTestSuite/GoldFiles/quantifiedB_7.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantifiedB_8.gold b/SBVTestSuite/GoldFiles/quantifiedB_8.gold
--- a/SBVTestSuite/GoldFiles/quantifiedB_8.gold
+++ b/SBVTestSuite/GoldFiles/quantifiedB_8.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantifiedB_9.gold b/SBVTestSuite/GoldFiles/quantifiedB_9.gold
--- a/SBVTestSuite/GoldFiles/quantifiedB_9.gold
+++ b/SBVTestSuite/GoldFiles/quantifiedB_9.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantifiedB_A.gold b/SBVTestSuite/GoldFiles/quantifiedB_A.gold
--- a/SBVTestSuite/GoldFiles/quantifiedB_A.gold
+++ b/SBVTestSuite/GoldFiles/quantifiedB_A.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantifiedB_B.gold b/SBVTestSuite/GoldFiles/quantifiedB_B.gold
--- a/SBVTestSuite/GoldFiles/quantifiedB_B.gold
+++ b/SBVTestSuite/GoldFiles/quantifiedB_B.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_prove_existsexists_contradiction_p.gold b/SBVTestSuite/GoldFiles/quantified_prove_existsexists_contradiction_p.gold
--- a/SBVTestSuite/GoldFiles/quantified_prove_existsexists_contradiction_p.gold
+++ b/SBVTestSuite/GoldFiles/quantified_prove_existsexists_contradiction_p.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_prove_existsexists_satisfiable_p.gold b/SBVTestSuite/GoldFiles/quantified_prove_existsexists_satisfiable_p.gold
--- a/SBVTestSuite/GoldFiles/quantified_prove_existsexists_satisfiable_p.gold
+++ b/SBVTestSuite/GoldFiles/quantified_prove_existsexists_satisfiable_p.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_prove_existsexists_thm_p.gold b/SBVTestSuite/GoldFiles/quantified_prove_existsexists_thm_p.gold
--- a/SBVTestSuite/GoldFiles/quantified_prove_existsexists_thm_p.gold
+++ b/SBVTestSuite/GoldFiles/quantified_prove_existsexists_thm_p.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_prove_existsforall_contradiction_p.gold b/SBVTestSuite/GoldFiles/quantified_prove_existsforall_contradiction_p.gold
--- a/SBVTestSuite/GoldFiles/quantified_prove_existsforall_contradiction_p.gold
+++ b/SBVTestSuite/GoldFiles/quantified_prove_existsforall_contradiction_p.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_prove_existsforall_satisfiable_p.gold b/SBVTestSuite/GoldFiles/quantified_prove_existsforall_satisfiable_p.gold
--- a/SBVTestSuite/GoldFiles/quantified_prove_existsforall_satisfiable_p.gold
+++ b/SBVTestSuite/GoldFiles/quantified_prove_existsforall_satisfiable_p.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_prove_existsforall_thm_p.gold b/SBVTestSuite/GoldFiles/quantified_prove_existsforall_thm_p.gold
--- a/SBVTestSuite/GoldFiles/quantified_prove_existsforall_thm_p.gold
+++ b/SBVTestSuite/GoldFiles/quantified_prove_existsforall_thm_p.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_prove_forallexists_contradiction_p.gold b/SBVTestSuite/GoldFiles/quantified_prove_forallexists_contradiction_p.gold
--- a/SBVTestSuite/GoldFiles/quantified_prove_forallexists_contradiction_p.gold
+++ b/SBVTestSuite/GoldFiles/quantified_prove_forallexists_contradiction_p.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_prove_forallexists_satisfiable_p.gold b/SBVTestSuite/GoldFiles/quantified_prove_forallexists_satisfiable_p.gold
--- a/SBVTestSuite/GoldFiles/quantified_prove_forallexists_satisfiable_p.gold
+++ b/SBVTestSuite/GoldFiles/quantified_prove_forallexists_satisfiable_p.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_prove_forallexists_thm_p.gold b/SBVTestSuite/GoldFiles/quantified_prove_forallexists_thm_p.gold
--- a/SBVTestSuite/GoldFiles/quantified_prove_forallexists_thm_p.gold
+++ b/SBVTestSuite/GoldFiles/quantified_prove_forallexists_thm_p.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_prove_forallforall_contradiction_p.gold b/SBVTestSuite/GoldFiles/quantified_prove_forallforall_contradiction_p.gold
--- a/SBVTestSuite/GoldFiles/quantified_prove_forallforall_contradiction_p.gold
+++ b/SBVTestSuite/GoldFiles/quantified_prove_forallforall_contradiction_p.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_prove_forallforall_satisfiable_p.gold b/SBVTestSuite/GoldFiles/quantified_prove_forallforall_satisfiable_p.gold
--- a/SBVTestSuite/GoldFiles/quantified_prove_forallforall_satisfiable_p.gold
+++ b/SBVTestSuite/GoldFiles/quantified_prove_forallforall_satisfiable_p.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_prove_forallforall_thm_p.gold b/SBVTestSuite/GoldFiles/quantified_prove_forallforall_thm_p.gold
--- a/SBVTestSuite/GoldFiles/quantified_prove_forallforall_thm_p.gold
+++ b/SBVTestSuite/GoldFiles/quantified_prove_forallforall_thm_p.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_sat_existsexists_contradiction_c.gold b/SBVTestSuite/GoldFiles/quantified_sat_existsexists_contradiction_c.gold
--- a/SBVTestSuite/GoldFiles/quantified_sat_existsexists_contradiction_c.gold
+++ b/SBVTestSuite/GoldFiles/quantified_sat_existsexists_contradiction_c.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_sat_existsexists_contradiction_p.gold b/SBVTestSuite/GoldFiles/quantified_sat_existsexists_contradiction_p.gold
--- a/SBVTestSuite/GoldFiles/quantified_sat_existsexists_contradiction_p.gold
+++ b/SBVTestSuite/GoldFiles/quantified_sat_existsexists_contradiction_p.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_sat_existsexists_satisfiable_c.gold b/SBVTestSuite/GoldFiles/quantified_sat_existsexists_satisfiable_c.gold
--- a/SBVTestSuite/GoldFiles/quantified_sat_existsexists_satisfiable_c.gold
+++ b/SBVTestSuite/GoldFiles/quantified_sat_existsexists_satisfiable_c.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_sat_existsexists_satisfiable_p.gold b/SBVTestSuite/GoldFiles/quantified_sat_existsexists_satisfiable_p.gold
--- a/SBVTestSuite/GoldFiles/quantified_sat_existsexists_satisfiable_p.gold
+++ b/SBVTestSuite/GoldFiles/quantified_sat_existsexists_satisfiable_p.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_sat_existsexists_thm_c.gold b/SBVTestSuite/GoldFiles/quantified_sat_existsexists_thm_c.gold
--- a/SBVTestSuite/GoldFiles/quantified_sat_existsexists_thm_c.gold
+++ b/SBVTestSuite/GoldFiles/quantified_sat_existsexists_thm_c.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_sat_existsexists_thm_p.gold b/SBVTestSuite/GoldFiles/quantified_sat_existsexists_thm_p.gold
--- a/SBVTestSuite/GoldFiles/quantified_sat_existsexists_thm_p.gold
+++ b/SBVTestSuite/GoldFiles/quantified_sat_existsexists_thm_p.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_sat_existsforall_contradiction_c.gold b/SBVTestSuite/GoldFiles/quantified_sat_existsforall_contradiction_c.gold
--- a/SBVTestSuite/GoldFiles/quantified_sat_existsforall_contradiction_c.gold
+++ b/SBVTestSuite/GoldFiles/quantified_sat_existsforall_contradiction_c.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_sat_existsforall_contradiction_p.gold b/SBVTestSuite/GoldFiles/quantified_sat_existsforall_contradiction_p.gold
--- a/SBVTestSuite/GoldFiles/quantified_sat_existsforall_contradiction_p.gold
+++ b/SBVTestSuite/GoldFiles/quantified_sat_existsforall_contradiction_p.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_sat_existsforall_satisfiable_c.gold b/SBVTestSuite/GoldFiles/quantified_sat_existsforall_satisfiable_c.gold
--- a/SBVTestSuite/GoldFiles/quantified_sat_existsforall_satisfiable_c.gold
+++ b/SBVTestSuite/GoldFiles/quantified_sat_existsforall_satisfiable_c.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_sat_existsforall_satisfiable_p.gold b/SBVTestSuite/GoldFiles/quantified_sat_existsforall_satisfiable_p.gold
--- a/SBVTestSuite/GoldFiles/quantified_sat_existsforall_satisfiable_p.gold
+++ b/SBVTestSuite/GoldFiles/quantified_sat_existsforall_satisfiable_p.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_sat_existsforall_thm_c.gold b/SBVTestSuite/GoldFiles/quantified_sat_existsforall_thm_c.gold
--- a/SBVTestSuite/GoldFiles/quantified_sat_existsforall_thm_c.gold
+++ b/SBVTestSuite/GoldFiles/quantified_sat_existsforall_thm_c.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_sat_existsforall_thm_p.gold b/SBVTestSuite/GoldFiles/quantified_sat_existsforall_thm_p.gold
--- a/SBVTestSuite/GoldFiles/quantified_sat_existsforall_thm_p.gold
+++ b/SBVTestSuite/GoldFiles/quantified_sat_existsforall_thm_p.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_sat_forallexists_contradiction_c.gold b/SBVTestSuite/GoldFiles/quantified_sat_forallexists_contradiction_c.gold
--- a/SBVTestSuite/GoldFiles/quantified_sat_forallexists_contradiction_c.gold
+++ b/SBVTestSuite/GoldFiles/quantified_sat_forallexists_contradiction_c.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_sat_forallexists_contradiction_p.gold b/SBVTestSuite/GoldFiles/quantified_sat_forallexists_contradiction_p.gold
--- a/SBVTestSuite/GoldFiles/quantified_sat_forallexists_contradiction_p.gold
+++ b/SBVTestSuite/GoldFiles/quantified_sat_forallexists_contradiction_p.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_sat_forallexists_satisfiable_c.gold b/SBVTestSuite/GoldFiles/quantified_sat_forallexists_satisfiable_c.gold
--- a/SBVTestSuite/GoldFiles/quantified_sat_forallexists_satisfiable_c.gold
+++ b/SBVTestSuite/GoldFiles/quantified_sat_forallexists_satisfiable_c.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_sat_forallexists_satisfiable_p.gold b/SBVTestSuite/GoldFiles/quantified_sat_forallexists_satisfiable_p.gold
--- a/SBVTestSuite/GoldFiles/quantified_sat_forallexists_satisfiable_p.gold
+++ b/SBVTestSuite/GoldFiles/quantified_sat_forallexists_satisfiable_p.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_sat_forallexists_thm_c.gold b/SBVTestSuite/GoldFiles/quantified_sat_forallexists_thm_c.gold
--- a/SBVTestSuite/GoldFiles/quantified_sat_forallexists_thm_c.gold
+++ b/SBVTestSuite/GoldFiles/quantified_sat_forallexists_thm_c.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_sat_forallexists_thm_p.gold b/SBVTestSuite/GoldFiles/quantified_sat_forallexists_thm_p.gold
--- a/SBVTestSuite/GoldFiles/quantified_sat_forallexists_thm_p.gold
+++ b/SBVTestSuite/GoldFiles/quantified_sat_forallexists_thm_p.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_sat_forallforall_contradiction_c.gold b/SBVTestSuite/GoldFiles/quantified_sat_forallforall_contradiction_c.gold
--- a/SBVTestSuite/GoldFiles/quantified_sat_forallforall_contradiction_c.gold
+++ b/SBVTestSuite/GoldFiles/quantified_sat_forallforall_contradiction_c.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_sat_forallforall_contradiction_p.gold b/SBVTestSuite/GoldFiles/quantified_sat_forallforall_contradiction_p.gold
--- a/SBVTestSuite/GoldFiles/quantified_sat_forallforall_contradiction_p.gold
+++ b/SBVTestSuite/GoldFiles/quantified_sat_forallforall_contradiction_p.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_sat_forallforall_satisfiable_c.gold b/SBVTestSuite/GoldFiles/quantified_sat_forallforall_satisfiable_c.gold
--- a/SBVTestSuite/GoldFiles/quantified_sat_forallforall_satisfiable_c.gold
+++ b/SBVTestSuite/GoldFiles/quantified_sat_forallforall_satisfiable_c.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_sat_forallforall_satisfiable_p.gold b/SBVTestSuite/GoldFiles/quantified_sat_forallforall_satisfiable_p.gold
--- a/SBVTestSuite/GoldFiles/quantified_sat_forallforall_satisfiable_p.gold
+++ b/SBVTestSuite/GoldFiles/quantified_sat_forallforall_satisfiable_p.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_sat_forallforall_thm_c.gold b/SBVTestSuite/GoldFiles/quantified_sat_forallforall_thm_c.gold
--- a/SBVTestSuite/GoldFiles/quantified_sat_forallforall_thm_c.gold
+++ b/SBVTestSuite/GoldFiles/quantified_sat_forallforall_thm_c.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/quantified_sat_forallforall_thm_p.gold b/SBVTestSuite/GoldFiles/quantified_sat_forallforall_thm_p.gold
--- a/SBVTestSuite/GoldFiles/quantified_sat_forallforall_thm_p.gold
+++ b/SBVTestSuite/GoldFiles/quantified_sat_forallforall_thm_p.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/query1.gold b/SBVTestSuite/GoldFiles/query1.gold
--- a/SBVTestSuite/GoldFiles/query1.gold
+++ b/SBVTestSuite/GoldFiles/query1.gold
@@ -15,7 +15,6 @@
 [GOOD] (set-info :bad what)
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
@@ -73,7 +72,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.15.3")
+[RECV] (:version "5.1.0")
 [SEND] (get-info :status)
 [RECV] (:status sat)
 [GOOD] (define-fun s16 () Int 4)
@@ -104,7 +103,7 @@
 [SEND] (get-info :reason-unknown)
 [RECV] (:reason-unknown "unknown")
 [SEND] (get-info :version)
-[RECV] (:version "4.15.3")
+[RECV] (:version "5.1.0")
 [SEND] (get-info :memory)
 [RECV] unsupported
 [SEND] (get-info :time)
@@ -165,19 +164,19 @@
 [SEND] (get-proof)
 [RECV] ((set-logic ALL)
        (proof
-       (let (($x267 (<= s0 6)))
-       (let (($x268 (not $x267)))
-       (let (($x275 (or (not bey) $x268)))
-       (let ((@x273 (monotonicity (rewrite (= (> s0 6) $x268)) (= (=> bey (> s0 6)) (=> bey $x268)))))
-       (let ((@x279 (trans @x273 (rewrite (= (=> bey $x268) $x275)) (= (=> bey (> s0 6)) $x275))))
-       (let ((@x280 (mp (asserted (=> bey (> s0 6))) @x279 $x275)))
-       (let (($x292 (>= s0 6)))
-       (let (($x291 (not $x292)))
-       (let (($x299 (or (not hey) $x291)))
-       (let ((@x290 (trans (rewrite (= (< s0 6) (not (<= 6 s0)))) (rewrite (= (not (<= 6 s0)) $x291)) (= (< s0 6) $x291))))
-       (let ((@x303 (trans (monotonicity @x290 (= (=> hey (< s0 6)) (=> hey $x291))) (rewrite (= (=> hey $x291) $x299)) (= (=> hey (< s0 6)) $x299))))
-       (let ((@x304 (mp (asserted (=> hey (< s0 6))) @x303 $x299)))
-       (unit-resolution ((_ th-lemma arith farkas 1 1) (or $x292 $x267)) (unit-resolution @x304 (asserted hey) $x291) (unit-resolution @x280 (asserted bey) $x268) false)))))))))))))))
+       (let (($x268 (<= s0 6)))
+       (let (($x269 (not $x268)))
+       (let (($x276 (or (not bey) $x269)))
+       (let ((@x274 (monotonicity (rewrite (= (> s0 6) $x269)) (= (=> bey (> s0 6)) (=> bey $x269)))))
+       (let ((@x280 (trans @x274 (rewrite (= (=> bey $x269) $x276)) (= (=> bey (> s0 6)) $x276))))
+       (let ((@x281 (mp (asserted (=> bey (> s0 6))) @x280 $x276)))
+       (let (($x293 (>= s0 6)))
+       (let (($x292 (not $x293)))
+       (let (($x300 (or (not hey) $x292)))
+       (let ((@x291 (trans (rewrite (= (< s0 6) (not (<= 6 s0)))) (rewrite (= (not (<= 6 s0)) $x292)) (= (< s0 6) $x292))))
+       (let ((@x304 (trans (monotonicity @x291 (= (=> hey (< s0 6)) (=> hey $x292))) (rewrite (= (=> hey $x292) $x300)) (= (=> hey (< s0 6)) $x300))))
+       (let ((@x305 (mp (asserted (=> hey (< s0 6))) @x304 $x300)))
+       (unit-resolution ((_ th-lemma arith farkas 1 1) (or $x293 $x268)) (unit-resolution @x305 (asserted hey) $x292) (unit-resolution @x281 (asserted bey) $x269) false)))))))))))))))
 [SEND, TimeOut: 90000ms] (get-assertions)
 
 [RECV] ((! s7 :named |a > 0|)
diff --git a/SBVTestSuite/GoldFiles/queryArrays1.gold b/SBVTestSuite/GoldFiles/queryArrays1.gold
--- a/SBVTestSuite/GoldFiles/queryArrays1.gold
+++ b/SBVTestSuite/GoldFiles/queryArrays1.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/queryArrays10.gold b/SBVTestSuite/GoldFiles/queryArrays10.gold
--- a/SBVTestSuite/GoldFiles/queryArrays10.gold
+++ b/SBVTestSuite/GoldFiles/queryArrays10.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/queryArrays11.gold b/SBVTestSuite/GoldFiles/queryArrays11.gold
--- a/SBVTestSuite/GoldFiles/queryArrays11.gold
+++ b/SBVTestSuite/GoldFiles/queryArrays11.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has non-bitvector arrays, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/queryArrays12.gold b/SBVTestSuite/GoldFiles/queryArrays12.gold
--- a/SBVTestSuite/GoldFiles/queryArrays12.gold
+++ b/SBVTestSuite/GoldFiles/queryArrays12.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] (declare-datatype SBVRational ((SBV.Rational (sbv.rat.numerator Int) (sbv.rat.denominator Int))))
diff --git a/SBVTestSuite/GoldFiles/queryArrays13.gold b/SBVTestSuite/GoldFiles/queryArrays13.gold
--- a/SBVTestSuite/GoldFiles/queryArrays13.gold
+++ b/SBVTestSuite/GoldFiles/queryArrays13.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] (declare-datatype SBVRational ((SBV.Rational (sbv.rat.numerator Int) (sbv.rat.denominator Int))))
diff --git a/SBVTestSuite/GoldFiles/queryArrays14.gold b/SBVTestSuite/GoldFiles/queryArrays14.gold
--- a/SBVTestSuite/GoldFiles/queryArrays14.gold
+++ b/SBVTestSuite/GoldFiles/queryArrays14.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has rational values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] (declare-datatype SBVRational ((SBV.Rational (sbv.rat.numerator Int) (sbv.rat.denominator Int))))
diff --git a/SBVTestSuite/GoldFiles/queryArrays15.gold b/SBVTestSuite/GoldFiles/queryArrays15.gold
--- a/SBVTestSuite/GoldFiles/queryArrays15.gold
+++ b/SBVTestSuite/GoldFiles/queryArrays15.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has rational values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] (declare-datatype SBVRational ((SBV.Rational (sbv.rat.numerator Int) (sbv.rat.denominator Int))))
diff --git a/SBVTestSuite/GoldFiles/queryArrays16.gold b/SBVTestSuite/GoldFiles/queryArrays16.gold
--- a/SBVTestSuite/GoldFiles/queryArrays16.gold
+++ b/SBVTestSuite/GoldFiles/queryArrays16.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has rational values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] (declare-datatype SBVRational ((SBV.Rational (sbv.rat.numerator Int) (sbv.rat.denominator Int))))
diff --git a/SBVTestSuite/GoldFiles/queryArrays17.gold b/SBVTestSuite/GoldFiles/queryArrays17.gold
--- a/SBVTestSuite/GoldFiles/queryArrays17.gold
+++ b/SBVTestSuite/GoldFiles/queryArrays17.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has rational values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/queryArrays2.gold b/SBVTestSuite/GoldFiles/queryArrays2.gold
--- a/SBVTestSuite/GoldFiles/queryArrays2.gold
+++ b/SBVTestSuite/GoldFiles/queryArrays2.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV) ; NB. User specified.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/queryArrays3.gold b/SBVTestSuite/GoldFiles/queryArrays3.gold
--- a/SBVTestSuite/GoldFiles/queryArrays3.gold
+++ b/SBVTestSuite/GoldFiles/queryArrays3.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV) ; NB. User specified.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/queryArrays4.gold b/SBVTestSuite/GoldFiles/queryArrays4.gold
--- a/SBVTestSuite/GoldFiles/queryArrays4.gold
+++ b/SBVTestSuite/GoldFiles/queryArrays4.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV) ; NB. User specified.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/queryArrays5.gold b/SBVTestSuite/GoldFiles/queryArrays5.gold
--- a/SBVTestSuite/GoldFiles/queryArrays5.gold
+++ b/SBVTestSuite/GoldFiles/queryArrays5.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/queryArrays6.gold b/SBVTestSuite/GoldFiles/queryArrays6.gold
--- a/SBVTestSuite/GoldFiles/queryArrays6.gold
+++ b/SBVTestSuite/GoldFiles/queryArrays6.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/queryArrays7.gold b/SBVTestSuite/GoldFiles/queryArrays7.gold
--- a/SBVTestSuite/GoldFiles/queryArrays7.gold
+++ b/SBVTestSuite/GoldFiles/queryArrays7.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/queryArrays8.gold b/SBVTestSuite/GoldFiles/queryArrays8.gold
--- a/SBVTestSuite/GoldFiles/queryArrays8.gold
+++ b/SBVTestSuite/GoldFiles/queryArrays8.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/queryArrays9.gold b/SBVTestSuite/GoldFiles/queryArrays9.gold
--- a/SBVTestSuite/GoldFiles/queryArrays9.gold
+++ b/SBVTestSuite/GoldFiles/queryArrays9.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/queryTables.gold b/SBVTestSuite/GoldFiles/queryTables.gold
--- a/SBVTestSuite/GoldFiles/queryTables.gold
+++ b/SBVTestSuite/GoldFiles/queryTables.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
@@ -37,14 +36,16 @@
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
                                                          (proj_2_SBVTuple2 T2))))))
-[GOOD] (declare-datatypes ((SBVMaybe 1)) ((par (T)
-                                           ((nothing_SBVMaybe)
-                                            (just_SBVMaybe (get_just_SBVMaybe T))))))
+[GOOD] ; User defined ADT: Maybe
+[GOOD] (declare-datatype Maybe (par (a) (
+           (Nothing)
+           (Just (getJust_1 a))
+       )))
 [GOOD] (define-fun s13 () (_ BitVec 16) #x000a)
 [GOOD] (define-fun s15 () (_ BitVec 16) (bvneg #x0001))
 [GOOD] (define-fun s17 () (_ BitVec 16) #x0007)
-[GOOD] (define-fun s19 () (SBVMaybe (_ BitVec 16)) ((as just_SBVMaybe (SBVMaybe (_ BitVec 16))) #x0000))
-[GOOD] (define-fun s20 () (SBVMaybe (_ BitVec 16)) (as nothing_SBVMaybe (SBVMaybe (_ BitVec 16))))
+[GOOD] (define-fun s19 () (Maybe (_ BitVec 16)) ((as Just (Maybe (_ BitVec 16))) #x0000))
+[GOOD] (define-fun s20 () (Maybe (_ BitVec 16)) (as Nothing (Maybe (_ BitVec 16))))
 [GOOD] (define-fun s28 () (_ BitVec 16) #x00ff)
 [GOOD] (declare-fun table0 ((_ BitVec 16)) (_ BitVec 16))
 [GOOD] (define-fun s10 () (SBVTuple2 (_ BitVec 16) (_ BitVec 16)) ((as mkSBVTuple2 (SBVTuple2 (_ BitVec 16) (_ BitVec 16))) s0 s6))
@@ -53,10 +54,10 @@
 [GOOD] (define-fun s14 () Bool (= s11 s13))
 [GOOD] (define-fun s16 () (_ BitVec 16) (proj_2_SBVTuple2 s10))
 [GOOD] (define-fun s18 () Bool (= s16 s17))
-[GOOD] (define-fun s21 () (SBVMaybe (_ BitVec 16)) (ite s18 s19 s20))
-[GOOD] (define-fun s22 () (_ BitVec 16) (get_just_SBVMaybe s21))
-[GOOD] (define-fun s23 () Bool ((_ is (nothing_SBVMaybe () (SBVMaybe (_ BitVec 16)))) s21))
-[GOOD] (define-fun s24 () (_ BitVec 16) (ite s23 s15 s22))
+[GOOD] (define-fun s21 () (Maybe (_ BitVec 16)) (ite s18 s19 s20))
+[GOOD] (define-fun s22 () Bool ((as is-Nothing Bool) s21))
+[GOOD] (define-fun s23 () (_ BitVec 16) (getJust_1 s21))
+[GOOD] (define-fun s24 () (_ BitVec 16) (ite s22 s15 s23))
 [GOOD] (define-fun s25 () (_ BitVec 16) (ite (or (bvslt s24 #x0000) (bvsle #x0001 s24)) s15 (table0 s24)))
 [GOOD] (define-fun s26 () Bool (= s1 s25))
 [GOOD] (define-fun s27 () Bool (= s1 s24))
@@ -107,10 +108,10 @@
 [GOOD] (define-fun s60 () Bool (= s1 s59))
 [GOOD] (define-fun s61 () Bool (= s13 s44))
 [GOOD] (define-fun s62 () Bool (= s17 s46))
-[GOOD] (define-fun s63 () (SBVMaybe (_ BitVec 16)) (ite s62 s19 s20))
-[GOOD] (define-fun s64 () (_ BitVec 16) (get_just_SBVMaybe s63))
-[GOOD] (define-fun s65 () Bool ((_ is (nothing_SBVMaybe () (SBVMaybe (_ BitVec 16)))) s63))
-[GOOD] (define-fun s66 () (_ BitVec 16) (ite s65 s15 s64))
+[GOOD] (define-fun s63 () (Maybe (_ BitVec 16)) (ite s62 s19 s20))
+[GOOD] (define-fun s64 () Bool ((as is-Nothing Bool) s63))
+[GOOD] (define-fun s65 () (_ BitVec 16) (getJust_1 s63))
+[GOOD] (define-fun s66 () (_ BitVec 16) (ite s64 s15 s65))
 [GOOD] (define-fun s67 () (_ BitVec 16) (ite (or (bvslt s66 #x0000) (bvsle #x0001 s66)) s15 (table2 s66)))
 [GOOD] (define-fun s68 () Bool (= s1 s67))
 [GOOD] (define-fun s69 () Bool (= s1 s66))
diff --git a/SBVTestSuite/GoldFiles/query_Chars1.gold b/SBVTestSuite/GoldFiles/query_Chars1.gold
--- a/SBVTestSuite/GoldFiles/query_Chars1.gold
+++ b/SBVTestSuite/GoldFiles/query_Chars1.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/query_Interpolant1.gold b/SBVTestSuite/GoldFiles/query_Interpolant1.gold
--- a/SBVTestSuite/GoldFiles/query_Interpolant1.gold
+++ b/SBVTestSuite/GoldFiles/query_Interpolant1.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :produce-interpolants true)
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/query_Interpolant2.gold b/SBVTestSuite/GoldFiles/query_Interpolant2.gold
--- a/SBVTestSuite/GoldFiles/query_Interpolant2.gold
+++ b/SBVTestSuite/GoldFiles/query_Interpolant2.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :produce-interpolants true)
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/query_Interpolant3.gold b/SBVTestSuite/GoldFiles/query_Interpolant3.gold
--- a/SBVTestSuite/GoldFiles/query_Interpolant3.gold
+++ b/SBVTestSuite/GoldFiles/query_Interpolant3.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/query_Interpolant4.gold b/SBVTestSuite/GoldFiles/query_Interpolant4.gold
--- a/SBVTestSuite/GoldFiles/query_Interpolant4.gold
+++ b/SBVTestSuite/GoldFiles/query_Interpolant4.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
@@ -37,10 +36,10 @@
 [SEND] (get-interpolant s8 s13)
 [RECV] (or (and (= s1 s2) (= s1 s3))
            (<= (+ (* (- 1) s1) s0) (- 1))
-           (<= (+ s1 (* (- 1) s0)) (- 1))
+           (<= (+ (* (- 1) s0) s1) (- 1))
            (= s2 s3))
 *** Solver   : Z3
 *** Exit code: ExitSuccess
 
 FINAL OUTPUT:
-"(or (and (= s1 s2) (= s1 s3)) (<= (+ (* (- 1) s1) s0) (- 1)) (<= (+ s1 (* (- 1) s0)) (- 1)) (= s2 s3))"
+"(or (and (= s1 s2) (= s1 s3)) (<= (+ (* (- 1) s1) s0) (- 1)) (<= (+ (* (- 1) s0) s1) (- 1)) (= s2 s3))"
diff --git a/SBVTestSuite/GoldFiles/query_ListOfMaybe.gold b/SBVTestSuite/GoldFiles/query_ListOfMaybe.gold
--- a/SBVTestSuite/GoldFiles/query_ListOfMaybe.gold
+++ b/SBVTestSuite/GoldFiles/query_ListOfMaybe.gold
@@ -9,45 +9,42 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
-[GOOD] (declare-datatypes ((SBVMaybe 1)) ((par (T)
-                                           ((nothing_SBVMaybe)
-                                            (just_SBVMaybe (get_just_SBVMaybe T))))))
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Maybe
+[GOOD] (declare-datatype Maybe (par (a) (
+           (Nothing)
+           (Just (getJust_1 a))
+       )))
 [GOOD] ; --- literal constants ---
-[GOOD] (define-fun s2 () Int 2)
-[GOOD] (define-fun s4 () Int 0)
-[GOOD] (define-fun s8 () Int 1)
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s4 () Int 1)
 [GOOD] ; --- top level inputs ---
-[GOOD] (declare-fun s0 () (Seq (SBVMaybe String))) ; tracks user variable "lst"
-[GOOD] (assert (forall ((seq0 Int)) (=> (and (>= seq0 0) (< seq0 (seq.len s0))) (=> ((_ is (just_SBVMaybe (String) (SBVMaybe String))) (seq.nth s0 seq0)) (= 1 (str.len (get_just_SBVMaybe (seq.nth s0 seq0))))))))
+[GOOD] (declare-fun s0 () (Seq (Maybe String))) ; tracks user variable "lst"
+[GOOD] (assert (forall ((seq0 Int)) (=> (and (>= seq0 0) (< seq0 (seq.len s0))) (= 1 (str.len (getJust_1 (seq.nth s0 seq0)))))))
 [GOOD] ; --- constant tables ---
 [GOOD] ; --- non-constant tables ---
 [GOOD] ; --- uninterpreted constants ---
 [GOOD] ; --- user defined functions ---
 [GOOD] ; --- assignments ---
-[GOOD] (define-fun s1 () Int (seq.len s0))
-[GOOD] (define-fun s3 () Bool (= s1 s2))
-[GOOD] (define-fun s5 () (SBVMaybe String) (seq.nth s0 s4))
-[GOOD] (define-fun s6 () Bool ((_ is (nothing_SBVMaybe () (SBVMaybe String))) s5))
-[GOOD] (define-fun s7 () Bool (ite s6 false true))
-[GOOD] (define-fun s9 () Int (- s1 s8))
-[GOOD] (define-fun s10 () (Seq (SBVMaybe String)) (seq.extract s0 s8 s9))
-[GOOD] (define-fun s11 () (SBVMaybe String) (seq.nth s10 s4))
-[GOOD] (define-fun s12 () Bool ((_ is (nothing_SBVMaybe () (SBVMaybe String))) s11))
-[GOOD] (define-fun s13 () Bool (ite s12 true false))
+[GOOD] (define-fun s2 () (Maybe String) (seq.nth s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Just Bool) s2))
+[GOOD] (define-fun s5 () Int (seq.len s0))
+[GOOD] (define-fun s6 () Int (- s5 s4))
+[GOOD] (define-fun s7 () (Seq (Maybe String)) (seq.extract s0 s4 s6))
+[GOOD] (define-fun s8 () (Maybe String) (seq.nth s7 s1))
+[GOOD] (define-fun s9 () Bool ((as is-Nothing Bool) s8))
 [GOOD] ; --- delayedEqualities ---
 [GOOD] ; --- formula ---
 [GOOD] (assert s3)
-[GOOD] (assert s7)
-[GOOD] (assert s13)
+[GOOD] (assert s9)
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (seq.++ (seq.unit (just_SBVMaybe "A")) (seq.unit nothing_SBVMaybe))))
+[RECV] ((s0 (seq.unit (Just "A"))))
 *** Solver   : Z3
 *** Exit code: ExitSuccess
 
 FINAL OUTPUT:
-[Just 'A',Nothing]
+[Just 'A']
diff --git a/SBVTestSuite/GoldFiles/query_ListOfSum.gold b/SBVTestSuite/GoldFiles/query_ListOfSum.gold
--- a/SBVTestSuite/GoldFiles/query_ListOfSum.gold
+++ b/SBVTestSuite/GoldFiles/query_ListOfSum.gold
@@ -9,45 +9,41 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
-[GOOD] (declare-datatypes ((SBVEither 2)) ((par (T1 T2)
-                                           ((left_SBVEither  (get_left_SBVEither  T1))
-                                            (right_SBVEither (get_right_SBVEither T2))))))
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Either
+[GOOD] (declare-datatype Either (par (a b) (
+           (Left (getLeft_1 a))
+           (Right (getRight_1 b))
+       )))
 [GOOD] ; --- literal constants ---
-[GOOD] (define-fun s2 () Int 2)
-[GOOD] (define-fun s4 () Int 0)
-[GOOD] (define-fun s8 () Int 1)
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s4 () Int 1)
 [GOOD] ; --- top level inputs ---
-[GOOD] (declare-fun s0 () (Seq (SBVEither Int String))) ; tracks user variable "lst"
-[GOOD] (assert (forall ((seq0 Int)) (=> (and (>= seq0 0) (< seq0 (seq.len s0))) (=> ((_ is (right_SBVEither (String) (SBVEither Int String))) (seq.nth s0 seq0)) (= 1 (str.len (get_right_SBVEither (seq.nth s0 seq0))))))))
+[GOOD] (declare-fun s0 () (Seq (Either Int Int))) ; tracks user variable "lst"
 [GOOD] ; --- constant tables ---
 [GOOD] ; --- non-constant tables ---
 [GOOD] ; --- uninterpreted constants ---
 [GOOD] ; --- user defined functions ---
 [GOOD] ; --- assignments ---
-[GOOD] (define-fun s1 () Int (seq.len s0))
-[GOOD] (define-fun s3 () Bool (= s1 s2))
-[GOOD] (define-fun s5 () (SBVEither Int String) (seq.nth s0 s4))
-[GOOD] (define-fun s6 () Bool ((_ is (left_SBVEither (Int) (SBVEither Int String))) s5))
-[GOOD] (define-fun s7 () Bool (ite s6 true false))
-[GOOD] (define-fun s9 () Int (- s1 s8))
-[GOOD] (define-fun s10 () (Seq (SBVEither Int String)) (seq.extract s0 s8 s9))
-[GOOD] (define-fun s11 () (SBVEither Int String) (seq.nth s10 s4))
-[GOOD] (define-fun s12 () Bool ((_ is (left_SBVEither (Int) (SBVEither Int String))) s11))
-[GOOD] (define-fun s13 () Bool (ite s12 false true))
+[GOOD] (define-fun s2 () (Either Int Int) (seq.nth s0 s1))
+[GOOD] (define-fun s3 () Bool ((as is-Left Bool) s2))
+[GOOD] (define-fun s5 () Int (seq.len s0))
+[GOOD] (define-fun s6 () Int (- s5 s4))
+[GOOD] (define-fun s7 () (Seq (Either Int Int)) (seq.extract s0 s4 s6))
+[GOOD] (define-fun s8 () (Either Int Int) (seq.nth s7 s1))
+[GOOD] (define-fun s9 () Bool ((as is-Right Bool) s8))
 [GOOD] ; --- delayedEqualities ---
 [GOOD] ; --- formula ---
 [GOOD] (assert s3)
-[GOOD] (assert s7)
-[GOOD] (assert s13)
+[GOOD] (assert s9)
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (seq.++ (seq.unit (left_SBVEither 3)) (seq.unit (right_SBVEither "A")))))
+[RECV] ((s0 (seq.unit (Left 3))))
 *** Solver   : Z3
 *** Exit code: ExitSuccess
 
 FINAL OUTPUT:
-[Left 3,Right 'A']
+[Left 3]
diff --git a/SBVTestSuite/GoldFiles/query_Lists1.gold b/SBVTestSuite/GoldFiles/query_Lists1.gold
--- a/SBVTestSuite/GoldFiles/query_Lists1.gold
+++ b/SBVTestSuite/GoldFiles/query_Lists1.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/query_Maybe.gold b/SBVTestSuite/GoldFiles/query_Maybe.gold
--- a/SBVTestSuite/GoldFiles/query_Maybe.gold
+++ b/SBVTestSuite/GoldFiles/query_Maybe.gold
@@ -9,32 +9,35 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
-[GOOD] (declare-datatypes ((SBVMaybe 1)) ((par (T)
-                                           ((nothing_SBVMaybe)
-                                            (just_SBVMaybe (get_just_SBVMaybe T))))))
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Maybe
+[GOOD] (declare-datatype Maybe (par (a) (
+           (Nothing)
+           (Just (getJust_1 a))
+       )))
 [GOOD] ; --- literal constants ---
-[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 1)
 [GOOD] ; --- top level inputs ---
-[GOOD] (declare-fun s0 () (SBVMaybe Int)) ; tracks user variable "a"
+[GOOD] (declare-fun s0 () (Maybe Int)) ; tracks user variable "a"
 [GOOD] ; --- constant tables ---
 [GOOD] ; --- non-constant tables ---
 [GOOD] ; --- uninterpreted constants ---
 [GOOD] ; --- user defined functions ---
 [GOOD] ; --- assignments ---
-[GOOD] (define-fun s1 () Int (get_just_SBVMaybe s0))
-[GOOD] (define-fun s3 () Bool (= s1 s2))
-[GOOD] (define-fun s4 () Bool ((_ is (nothing_SBVMaybe () (SBVMaybe Int))) s0))
-[GOOD] (define-fun s5 () Bool (ite s4 false s3))
+[GOOD] (define-fun s1 () Bool ((as is-Nothing Bool) s0))
+[GOOD] (define-fun s2 () Int (getJust_1 s0))
+[GOOD] (define-fun s4 () Bool (= s2 s3))
+[GOOD] (define-fun s5 () Bool (not s1))
+[GOOD] (define-fun s6 () Bool (and s4 s5))
 [GOOD] ; --- delayedEqualities ---
 [GOOD] ; --- formula ---
-[GOOD] (assert s5)
+[GOOD] (assert s6)
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (just_SBVMaybe 1)))
+[RECV] ((s0 (Just 1)))
 *** Solver   : Z3
 *** Exit code: ExitSuccess
 
diff --git a/SBVTestSuite/GoldFiles/query_Strings1.gold b/SBVTestSuite/GoldFiles/query_Strings1.gold
--- a/SBVTestSuite/GoldFiles/query_Strings1.gold
+++ b/SBVTestSuite/GoldFiles/query_Strings1.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has strings, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
@@ -17,7 +16,7 @@
 [GOOD] ; --- uninterpreted constants ---
 [GOOD] ; --- user defined functions ---
 [GOOD] ; --- assignments ---
-[GOOD] (define-fun s1 () Bool (str.in.re s0 ((_ re.loop 5 5) (str.to.re "xyz"))))
+[GOOD] (define-fun s1 () Bool (str.in_re s0 ((_ re.loop 5 5) (str.to_re "xyz"))))
 [GOOD] ; --- delayedEqualities ---
 [GOOD] ; --- formula ---
 [GOOD] (assert s1)
diff --git a/SBVTestSuite/GoldFiles/query_SumMaybeBoth.gold b/SBVTestSuite/GoldFiles/query_SumMaybeBoth.gold
--- a/SBVTestSuite/GoldFiles/query_SumMaybeBoth.gold
+++ b/SBVTestSuite/GoldFiles/query_SumMaybeBoth.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
@@ -21,29 +20,31 @@
 [GOOD] (set-option :pp.max_depth      4294967295)
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
-[GOOD] (declare-datatypes ((SBVEither 2)) ((par (T1 T2)
-                                           ((left_SBVEither  (get_left_SBVEither  T1))
-                                            (right_SBVEither (get_right_SBVEither T2))))))
-[GOOD] (declare-fun s0 () (SBVEither Int Int))
+[GOOD] ; User defined ADT: Either
+[GOOD] (declare-datatype Either (par (a b) (
+           (Left (getLeft_1 a))
+           (Right (getRight_1 b))
+       )))
+[GOOD] (declare-fun s0 () (Either Int Int))
 [GOOD] (set-option :pp.max_depth      4294967295)
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
-[GOOD] (declare-datatypes ((SBVMaybe 1)) ((par (T)
-                                           ((nothing_SBVMaybe)
-                                            (just_SBVMaybe (get_just_SBVMaybe T))))))
-[GOOD] (declare-fun s1 () (SBVMaybe Int))
-[GOOD] (define-fun s2 () Bool ((_ is (left_SBVEither (Int) (SBVEither Int Int))) s0))
-[GOOD] (define-fun s3 () Bool (ite s2 true false))
+[GOOD] ; User defined ADT: Maybe
+[GOOD] (declare-datatype Maybe (par (a) (
+           (Nothing)
+           (Just (getJust_1 a))
+       )))
+[GOOD] (declare-fun s1 () (Maybe Int))
+[GOOD] (define-fun s2 () Bool ((as is-Left Bool) s0))
+[GOOD] (assert s2)
+[GOOD] (define-fun s3 () Bool ((as is-Just Bool) s1))
 [GOOD] (assert s3)
-[GOOD] (define-fun s4 () Bool ((_ is (nothing_SBVMaybe () (SBVMaybe Int))) s1))
-[GOOD] (define-fun s5 () Bool (ite s4 false true))
-[GOOD] (assert s5)
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (left_SBVEither 2)))
+[RECV] ((s0 (Left 2)))
 [SEND] (get-value (s1))
-[RECV] ((s1 (just_SBVMaybe 3)))
+[RECV] ((s1 (Just 3)))
 *** Solver   : Z3
 *** Exit code: ExitSuccess
 
diff --git a/SBVTestSuite/GoldFiles/query_Sums.gold b/SBVTestSuite/GoldFiles/query_Sums.gold
--- a/SBVTestSuite/GoldFiles/query_Sums.gold
+++ b/SBVTestSuite/GoldFiles/query_Sums.gold
@@ -9,33 +9,35 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
-[GOOD] (declare-datatypes ((SBVEither 2)) ((par (T1 T2)
-                                           ((left_SBVEither  (get_left_SBVEither  T1))
-                                            (right_SBVEither (get_right_SBVEither T2))))))
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Either
+[GOOD] (declare-datatype Either (par (a b) (
+           (Left (getLeft_1 a))
+           (Right (getRight_1 b))
+       )))
 [GOOD] ; --- literal constants ---
-[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 1)
 [GOOD] ; --- top level inputs ---
-[GOOD] (declare-fun s0 () (SBVEither Int String)) ; tracks user variable "a"
-[GOOD] (assert (=> ((_ is (right_SBVEither (String) (SBVEither Int String))) s0) (= 1 (str.len (get_right_SBVEither s0)))))
+[GOOD] (declare-fun s0 () (Either Int String)) ; tracks user variable "a"
+[GOOD] (assert (= 1 (str.len (getRight_1 s0))))
 [GOOD] ; --- constant tables ---
 [GOOD] ; --- non-constant tables ---
 [GOOD] ; --- uninterpreted constants ---
 [GOOD] ; --- user defined functions ---
 [GOOD] ; --- assignments ---
-[GOOD] (define-fun s1 () Int (get_left_SBVEither s0))
-[GOOD] (define-fun s3 () Bool (= s1 s2))
-[GOOD] (define-fun s4 () Bool ((_ is (left_SBVEither (Int) (SBVEither Int String))) s0))
-[GOOD] (define-fun s5 () Bool (ite s4 s3 false))
+[GOOD] (define-fun s1 () Bool ((as is-Left Bool) s0))
+[GOOD] (define-fun s2 () Int (getLeft_1 s0))
+[GOOD] (define-fun s4 () Bool (= s2 s3))
+[GOOD] (define-fun s5 () Bool (and s1 s4))
 [GOOD] ; --- delayedEqualities ---
 [GOOD] ; --- formula ---
 [GOOD] (assert s5)
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (left_SBVEither 1)))
+[RECV] ((s0 (Left 1)))
 *** Solver   : Z3
 *** Exit code: ExitSuccess
 
diff --git a/SBVTestSuite/GoldFiles/query_Tuples1.gold b/SBVTestSuite/GoldFiles/query_Tuples1.gold
--- a/SBVTestSuite/GoldFiles/query_Tuples1.gold
+++ b/SBVTestSuite/GoldFiles/query_Tuples1.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/query_Tuples2.gold b/SBVTestSuite/GoldFiles/query_Tuples2.gold
--- a/SBVTestSuite/GoldFiles/query_Tuples2.gold
+++ b/SBVTestSuite/GoldFiles/query_Tuples2.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple0 0)) (((mkSBVTuple0))))
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
diff --git a/SBVTestSuite/GoldFiles/query_abc.gold b/SBVTestSuite/GoldFiles/query_abc.gold
--- a/SBVTestSuite/GoldFiles/query_abc.gold
+++ b/SBVTestSuite/GoldFiles/query_abc.gold
@@ -6,7 +6,6 @@
 [ISSUE] (set-option :diagnostic-output-channel "stdout")
 [ISSUE] (set-option :produce-models true)
 [ISSUE] (set-logic ALL) ; external query, using all logics.
-[ISSUE] ; --- uninterpreted sorts ---
 [ISSUE] ; --- tuples ---
 [ISSUE] ; --- sums ---
 [ISSUE] ; --- literal constants ---
@@ -47,4 +46,3 @@
 [RECV] ((s1 #x1))
 *** Solver   : ABC
 *** Exit code: ExitSuccess
-*** Std-err  : Cmd warning: redefining '%graft'
diff --git a/SBVTestSuite/GoldFiles/query_badOption.gold b/SBVTestSuite/GoldFiles/query_badOption.gold
--- a/SBVTestSuite/GoldFiles/query_badOption.gold
+++ b/SBVTestSuite/GoldFiles/query_badOption.gold
@@ -29,6 +29,7 @@
 ***                  rlimit (unsigned int) (default: 0)
 ***                  smtlib2_compliant (bool) (default: false)
 ***                  stats (bool) (default: false)
+***                  suppress_platform_verbose (bool) (default: false)
 ***                  timeout (unsigned int) (default: 4294967295)
 ***                  trace (bool) (default: false)
 ***                  trace_file_name (string) (default: z3.log)
@@ -39,7 +40,7 @@
 ***                  well_sorted_check (bool) (default: false)")
 ***
 ***    Exit code : ExitFailure (-15)
-***    Executable: /usr/local/bin/z3
+***    Executable: /Users/lerkok/Projects/Solvers/bin/z3
 ***    Options   : -nw -in -smt2
 ***
 ***    Reason    : Backend solver reports it does not support this option.
diff --git a/SBVTestSuite/GoldFiles/query_bitwuzla.gold b/SBVTestSuite/GoldFiles/query_bitwuzla.gold
--- a/SBVTestSuite/GoldFiles/query_bitwuzla.gold
+++ b/SBVTestSuite/GoldFiles/query_bitwuzla.gold
@@ -4,7 +4,6 @@
 [GOOD] (set-option :global-declarations true)
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/query_boolector.gold b/SBVTestSuite/GoldFiles/query_boolector.gold
--- a/SBVTestSuite/GoldFiles/query_boolector.gold
+++ b/SBVTestSuite/GoldFiles/query_boolector.gold
@@ -4,7 +4,6 @@
 [GOOD] (set-option :global-declarations true)
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/query_cvc4.gold b/SBVTestSuite/GoldFiles/query_cvc4.gold
--- a/SBVTestSuite/GoldFiles/query_cvc4.gold
+++ b/SBVTestSuite/GoldFiles/query_cvc4.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/query_cvc5.gold b/SBVTestSuite/GoldFiles/query_cvc5.gold
--- a/SBVTestSuite/GoldFiles/query_cvc5.gold
+++ b/SBVTestSuite/GoldFiles/query_cvc5.gold
@@ -4,8 +4,7 @@
 [GOOD] (set-option :global-declarations true)
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
-[GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
+[GOOD] (set-logic HO_ALL) ; external query, using all logics.
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/query_mathsat.gold b/SBVTestSuite/GoldFiles/query_mathsat.gold
--- a/SBVTestSuite/GoldFiles/query_mathsat.gold
+++ b/SBVTestSuite/GoldFiles/query_mathsat.gold
@@ -5,7 +5,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/query_sumMergeEither1.gold b/SBVTestSuite/GoldFiles/query_sumMergeEither1.gold
--- a/SBVTestSuite/GoldFiles/query_sumMergeEither1.gold
+++ b/SBVTestSuite/GoldFiles/query_sumMergeEither1.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
@@ -21,22 +20,23 @@
 [GOOD] (set-option :pp.max_depth      4294967295)
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
-[GOOD] (declare-datatypes ((SBVEither 2)) ((par (T1 T2)
-                                           ((left_SBVEither  (get_left_SBVEither  T1))
-                                            (right_SBVEither (get_right_SBVEither T2))))))
-[GOOD] (declare-fun s0 () (SBVEither Int Bool))
-[GOOD] (declare-fun s1 () (SBVEither Int Bool))
+[GOOD] ; User defined ADT: Either
+[GOOD] (declare-datatype Either (par (a b) (
+           (Left (getLeft_1 a))
+           (Right (getRight_1 b))
+       )))
+[GOOD] (declare-fun s0 () (Either Int Bool))
+[GOOD] (declare-fun s1 () (Either Int Bool))
 [GOOD] (declare-fun s2 () Bool)
-[GOOD] (define-fun s3 () (SBVEither Int Bool) (ite s2 s0 s1))
-[GOOD] (define-fun s4 () Bool ((_ is (left_SBVEither (Int) (SBVEither Int Bool))) s3))
-[GOOD] (define-fun s5 () Bool (ite s4 true false))
-[GOOD] (assert s5)
+[GOOD] (define-fun s3 () (Either Int Bool) (ite s2 s0 s1))
+[GOOD] (define-fun s4 () Bool ((as is-Left Bool) s3))
+[GOOD] (assert s4)
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (left_SBVEither 2)))
+[RECV] ((s0 (Left 2)))
 [SEND] (get-value (s1))
-[RECV] ((s1 (left_SBVEither 2)))
+[RECV] ((s1 (Left 2)))
 [SEND] (get-value (s2))
 [RECV] ((s2 false))
 *** Solver   : Z3
diff --git a/SBVTestSuite/GoldFiles/query_sumMergeEither2.gold b/SBVTestSuite/GoldFiles/query_sumMergeEither2.gold
--- a/SBVTestSuite/GoldFiles/query_sumMergeEither2.gold
+++ b/SBVTestSuite/GoldFiles/query_sumMergeEither2.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
@@ -21,22 +20,23 @@
 [GOOD] (set-option :pp.max_depth      4294967295)
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
-[GOOD] (declare-datatypes ((SBVEither 2)) ((par (T1 T2)
-                                           ((left_SBVEither  (get_left_SBVEither  T1))
-                                            (right_SBVEither (get_right_SBVEither T2))))))
-[GOOD] (declare-fun s0 () (SBVEither Int Bool))
-[GOOD] (declare-fun s1 () (SBVEither Int Bool))
+[GOOD] ; User defined ADT: Either
+[GOOD] (declare-datatype Either (par (a b) (
+           (Left (getLeft_1 a))
+           (Right (getRight_1 b))
+       )))
+[GOOD] (declare-fun s0 () (Either Int Bool))
+[GOOD] (declare-fun s1 () (Either Int Bool))
 [GOOD] (declare-fun s2 () Bool)
-[GOOD] (define-fun s3 () (SBVEither Int Bool) (ite s2 s0 s1))
-[GOOD] (define-fun s4 () Bool ((_ is (left_SBVEither (Int) (SBVEither Int Bool))) s3))
-[GOOD] (define-fun s5 () Bool (ite s4 false true))
-[GOOD] (assert s5)
+[GOOD] (define-fun s3 () (Either Int Bool) (ite s2 s0 s1))
+[GOOD] (define-fun s4 () Bool ((as is-Right Bool) s3))
+[GOOD] (assert s4)
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (right_SBVEither false)))
+[RECV] ((s0 (Right false)))
 [SEND] (get-value (s1))
-[RECV] ((s1 (right_SBVEither false)))
+[RECV] ((s1 (Right false)))
 [SEND] (get-value (s2))
 [RECV] ((s2 false))
 *** Solver   : Z3
diff --git a/SBVTestSuite/GoldFiles/query_sumMergeMaybe1.gold b/SBVTestSuite/GoldFiles/query_sumMergeMaybe1.gold
--- a/SBVTestSuite/GoldFiles/query_sumMergeMaybe1.gold
+++ b/SBVTestSuite/GoldFiles/query_sumMergeMaybe1.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
@@ -21,22 +20,23 @@
 [GOOD] (set-option :pp.max_depth      4294967295)
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
-[GOOD] (declare-datatypes ((SBVMaybe 1)) ((par (T)
-                                           ((nothing_SBVMaybe)
-                                            (just_SBVMaybe (get_just_SBVMaybe T))))))
-[GOOD] (declare-fun s0 () (SBVMaybe Int))
-[GOOD] (declare-fun s1 () (SBVMaybe Int))
+[GOOD] ; User defined ADT: Maybe
+[GOOD] (declare-datatype Maybe (par (a) (
+           (Nothing)
+           (Just (getJust_1 a))
+       )))
+[GOOD] (declare-fun s0 () (Maybe Int))
+[GOOD] (declare-fun s1 () (Maybe Int))
 [GOOD] (declare-fun s2 () Bool)
-[GOOD] (define-fun s3 () (SBVMaybe Int) (ite s2 s0 s1))
-[GOOD] (define-fun s4 () Bool ((_ is (nothing_SBVMaybe () (SBVMaybe Int))) s3))
-[GOOD] (define-fun s5 () Bool (ite s4 true false))
-[GOOD] (assert s5)
+[GOOD] (define-fun s3 () (Maybe Int) (ite s2 s0 s1))
+[GOOD] (define-fun s4 () Bool ((as is-Nothing Bool) s3))
+[GOOD] (assert s4)
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 nothing_SBVMaybe))
+[RECV] ((s0 Nothing))
 [SEND] (get-value (s1))
-[RECV] ((s1 nothing_SBVMaybe))
+[RECV] ((s1 Nothing))
 [SEND] (get-value (s2))
 [RECV] ((s2 false))
 *** Solver   : Z3
diff --git a/SBVTestSuite/GoldFiles/query_sumMergeMaybe2.gold b/SBVTestSuite/GoldFiles/query_sumMergeMaybe2.gold
--- a/SBVTestSuite/GoldFiles/query_sumMergeMaybe2.gold
+++ b/SBVTestSuite/GoldFiles/query_sumMergeMaybe2.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
@@ -21,22 +20,23 @@
 [GOOD] (set-option :pp.max_depth      4294967295)
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
-[GOOD] (declare-datatypes ((SBVMaybe 1)) ((par (T)
-                                           ((nothing_SBVMaybe)
-                                            (just_SBVMaybe (get_just_SBVMaybe T))))))
-[GOOD] (declare-fun s0 () (SBVMaybe Int))
-[GOOD] (declare-fun s1 () (SBVMaybe Int))
+[GOOD] ; User defined ADT: Maybe
+[GOOD] (declare-datatype Maybe (par (a) (
+           (Nothing)
+           (Just (getJust_1 a))
+       )))
+[GOOD] (declare-fun s0 () (Maybe Int))
+[GOOD] (declare-fun s1 () (Maybe Int))
 [GOOD] (declare-fun s2 () Bool)
-[GOOD] (define-fun s3 () (SBVMaybe Int) (ite s2 s0 s1))
-[GOOD] (define-fun s4 () Bool ((_ is (nothing_SBVMaybe () (SBVMaybe Int))) s3))
-[GOOD] (define-fun s5 () Bool (ite s4 false true))
-[GOOD] (assert s5)
+[GOOD] (define-fun s3 () (Maybe Int) (ite s2 s0 s1))
+[GOOD] (define-fun s4 () Bool ((as is-Just Bool) s3))
+[GOOD] (assert s4)
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (just_SBVMaybe 2)))
+[RECV] ((s0 (Just 2)))
 [SEND] (get-value (s1))
-[RECV] ((s1 (just_SBVMaybe 2)))
+[RECV] ((s1 (Just 2)))
 [SEND] (get-value (s2))
 [RECV] ((s2 false))
 *** Solver   : Z3
diff --git a/SBVTestSuite/GoldFiles/query_uiSat_test1.gold b/SBVTestSuite/GoldFiles/query_uiSat_test1.gold
--- a/SBVTestSuite/GoldFiles/query_uiSat_test1.gold
+++ b/SBVTestSuite/GoldFiles/query_uiSat_test1.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; NB. User specified.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
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
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; NB. User specified.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
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
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
@@ -20,34 +19,32 @@
 [GOOD] (define-fun s9 () Int (- 3))
 [GOOD] (define-fun s11 () Int 9)
 [GOOD] (define-fun s14 () Int 1)
-[GOOD] (define-fun s21 () Int 5)
-[GOOD] (define-fun s23 () Int 7)
-[GOOD] (define-fun s25 () Int 6)
-[GOOD] (define-fun s29 () (_ FloatingPoint  8 24) ((_ to_fp 8 24) roundNearestTiesToEven (/ 4508877.0 524288.0)))
-[GOOD] (define-fun s32 () (_ FloatingPoint  8 24) ((_ to_fp 8 24) roundNearestTiesToEven (/ 5033165.0 524288.0)))
-[GOOD] (define-fun s33 () Int 121)
-[GOOD] (define-fun s38 () Int 8)
-[GOOD] (define-fun s40 () (_ FloatingPoint  8 24) (_ +oo 8 24))
-[GOOD] (define-fun s42 () String (_ char #x63))
-[GOOD] (define-fun s43 () String "hey")
-[GOOD] (define-fun s45 () (_ FloatingPoint  8 24) ((_ to_fp 8 24) roundNearestTiesToEven (/ 78.0 1.0)))
-[GOOD] (define-fun s47 () String "tey")
-[GOOD] (define-fun s49 () (_ FloatingPoint  8 24) ((_ to_fp 8 24) roundNearestTiesToEven (/ 92.0 1.0)))
-[GOOD] (define-fun s51 () String (_ char #x72))
-[GOOD] (define-fun s52 () String "foo")
-[GOOD] (define-fun s54 () (_ FloatingPoint  8 24) ((_ to_fp 8 24) roundNearestTiesToEven (/ 7.0 2.0)))
-[GOOD] (define-fun s56 () (Seq Int) (seq.++ (seq.unit 1) (seq.unit 2) (seq.unit 3)))
-[GOOD] (define-fun s57 () (Seq (_ FloatingPoint  8 24)) (seq.++ (seq.unit ((_ to_fp 8 24) roundNearestTiesToEven (/ 8598323.0 1048576.0))) (seq.unit ((_ to_fp 8 24) roundNearestTiesToEven (/ 3.0 1.0)))))
-[GOOD] (define-fun s60 () (Seq Int) (seq.++ (seq.unit 9) (seq.unit 5)))
-[GOOD] (define-fun s61 () (Seq (_ FloatingPoint  8 24)) (seq.++ (seq.unit ((_ to_fp 8 24) roundNearestTiesToEven (/ 8598323.0 1048576.0))) (seq.unit ((_ to_fp 8 24) roundNearestTiesToEven (/ 9.0 1.0)))))
-[GOOD] (define-fun s63 () Int 21)
-[GOOD] (define-fun s65 () (Seq Int) (seq.unit 5))
-[GOOD] (define-fun s66 () (Seq (_ FloatingPoint  8 24)) (seq.++ (seq.unit ((_ to_fp 8 24) roundNearestTiesToEven (/ 8598323.0 1048576.0))) (seq.unit (_ +zero 8 24))))
-[GOOD] (define-fun s68 () Int 210)
+[GOOD] (define-fun s18 () Int 5)
+[GOOD] (define-fun s20 () Int 7)
+[GOOD] (define-fun s22 () Int 6)
+[GOOD] (define-fun s26 () (_ FloatingPoint  8 24) (fp #b0 #b10000010 #b00010011001100110011010))
+[GOOD] (define-fun s29 () (_ FloatingPoint  8 24) (fp #b0 #b10000010 #b00110011001100110011010))
+[GOOD] (define-fun s30 () Int 121)
+[GOOD] (define-fun s35 () Int 8)
+[GOOD] (define-fun s37 () (_ FloatingPoint  8 24) (_ +oo 8 24))
+[GOOD] (define-fun s39 () String (_ char #x63))
+[GOOD] (define-fun s40 () String "hey")
+[GOOD] (define-fun s42 () (_ FloatingPoint  8 24) (fp #b0 #b10000101 #b00111000000000000000000))
+[GOOD] (define-fun s44 () String "tey")
+[GOOD] (define-fun s46 () (_ FloatingPoint  8 24) (fp #b0 #b10000101 #b01110000000000000000000))
+[GOOD] (define-fun s48 () String (_ char #x72))
+[GOOD] (define-fun s49 () String "foo")
+[GOOD] (define-fun s51 () (_ FloatingPoint  8 24) (fp #b0 #b10000000 #b11000000000000000000000))
+[GOOD] (define-fun s53 () (Seq Int) (seq.++ (seq.unit 1) (seq.unit 2) (seq.unit 3)))
+[GOOD] (define-fun s54 () (Seq (_ FloatingPoint  8 24)) (seq.++ (seq.unit (fp #b0 #b10000010 #b00000110011001100110011)) (seq.unit (fp #b0 #b10000000 #b10000000000000000000000))))
+[GOOD] (define-fun s57 () (Seq Int) (seq.++ (seq.unit 9) (seq.unit 5)))
+[GOOD] (define-fun s58 () (Seq (_ FloatingPoint  8 24)) (seq.++ (seq.unit (fp #b0 #b10000010 #b00000110011001100110011)) (seq.unit (fp #b0 #b10000010 #b00100000000000000000000))))
+[GOOD] (define-fun s60 () Int 21)
+[GOOD] (define-fun s62 () (Seq Int) (seq.unit 5))
+[GOOD] (define-fun s63 () (Seq (_ FloatingPoint  8 24)) (seq.++ (seq.unit (fp #b0 #b10000010 #b00000110011001100110011)) (seq.unit (_ +zero 8 24))))
+[GOOD] (define-fun s65 () Int 210)
 [GOOD] ; --- top level inputs ---
 [GOOD] (declare-fun s0 () Int)
-[GOOD] (declare-fun s17 () Bool) ; tracks user variable "__internal_sbv_s17"
-[GOOD] (declare-fun s18 () Int) ; tracks user variable "__internal_sbv_s18"
 [GOOD] ; --- constant tables ---
 [GOOD] ; --- non-constant tables ---
 [GOOD] ; --- uninterpreted constants ---
@@ -67,59 +64,54 @@
 [GOOD] (define-fun s13 () Int (q1 s0))
 [GOOD] (define-fun s15 () Int (+ s0 s14))
 [GOOD] (define-fun s16 () Bool (= s13 s15))
-[GOOD] (define-fun s19 () Int (q2 s17 s18))
-[GOOD] (define-fun s20 () Int (q2 true s5))
-[GOOD] (define-fun s22 () Bool (= s20 s21))
-[GOOD] (define-fun s24 () Int (q2 false s23))
-[GOOD] (define-fun s26 () Bool (= s24 s25))
-[GOOD] (define-fun s27 () Int (q2 false s3))
-[GOOD] (define-fun s28 () Bool (= s5 s27))
-[GOOD] (define-fun s30 () (_ FloatingPoint  8 24) (q3 s29 true s3))
-[GOOD] (define-fun s31 () Bool (fp.eq s29 s30))
-[GOOD] (define-fun s34 () (_ FloatingPoint  8 24) (q3 s32 true s33))
-[GOOD] (define-fun s35 () Bool (fp.isZero s34))
-[GOOD] (define-fun s36 () Bool (fp.isNegative s34))
-[GOOD] (define-fun s37 () Bool (and s35 s36))
-[GOOD] (define-fun s39 () (_ FloatingPoint  8 24) (q3 s32 false s38))
-[GOOD] (define-fun s41 () Bool (fp.eq s39 s40))
-[GOOD] (define-fun s44 () (_ FloatingPoint  8 24) (q4 s42 s43))
-[GOOD] (define-fun s46 () Bool (fp.eq s44 s45))
-[GOOD] (define-fun s48 () (_ FloatingPoint  8 24) (q4 s42 s47))
-[GOOD] (define-fun s50 () Bool (fp.eq s48 s49))
-[GOOD] (define-fun s53 () (_ FloatingPoint  8 24) (q4 s51 s52))
-[GOOD] (define-fun s55 () Bool (fp.eq s53 s54))
-[GOOD] (define-fun s58 () Int (q5 s56 s57))
-[GOOD] (define-fun s59 () Bool (= s23 s58))
-[GOOD] (define-fun s62 () Int (q5 s60 s61))
-[GOOD] (define-fun s64 () Bool (= s62 s63))
-[GOOD] (define-fun s67 () Int (q5 s65 s66))
-[GOOD] (define-fun s69 () Bool (= s67 s68))
+[GOOD] (define-fun s17 () Int (q2 true s5))
+[GOOD] (define-fun s19 () Bool (= s17 s18))
+[GOOD] (define-fun s21 () Int (q2 false s20))
+[GOOD] (define-fun s23 () Bool (= s21 s22))
+[GOOD] (define-fun s24 () Int (q2 false s3))
+[GOOD] (define-fun s25 () Bool (= s5 s24))
+[GOOD] (define-fun s27 () (_ FloatingPoint  8 24) (q3 s26 true s3))
+[GOOD] (define-fun s28 () Bool (fp.eq s26 s27))
+[GOOD] (define-fun s31 () (_ FloatingPoint  8 24) (q3 s29 true s30))
+[GOOD] (define-fun s32 () Bool (fp.isZero s31))
+[GOOD] (define-fun s33 () Bool (fp.isNegative s31))
+[GOOD] (define-fun s34 () Bool (and s32 s33))
+[GOOD] (define-fun s36 () (_ FloatingPoint  8 24) (q3 s29 false s35))
+[GOOD] (define-fun s38 () Bool (fp.eq s36 s37))
+[GOOD] (define-fun s41 () (_ FloatingPoint  8 24) (q4 s39 s40))
+[GOOD] (define-fun s43 () Bool (fp.eq s41 s42))
+[GOOD] (define-fun s45 () (_ FloatingPoint  8 24) (q4 s39 s44))
+[GOOD] (define-fun s47 () Bool (fp.eq s45 s46))
+[GOOD] (define-fun s50 () (_ FloatingPoint  8 24) (q4 s48 s49))
+[GOOD] (define-fun s52 () Bool (fp.eq s50 s51))
+[GOOD] (define-fun s55 () Int (q5 s53 s54))
+[GOOD] (define-fun s56 () Bool (= s20 s55))
+[GOOD] (define-fun s59 () Int (q5 s57 s58))
+[GOOD] (define-fun s61 () Bool (= s59 s60))
+[GOOD] (define-fun s64 () Int (q5 s62 s63))
+[GOOD] (define-fun s66 () Bool (= s64 s65))
 [GOOD] ; --- delayedEqualities ---
 [GOOD] ; --- formula ---
 [GOOD] (assert s4)
 [GOOD] (assert s8)
 [GOOD] (assert s12)
 [GOOD] (assert s16)
-[GOOD] (assert s22)
-[GOOD] (assert s26)
+[GOOD] (assert s19)
+[GOOD] (assert s23)
+[GOOD] (assert s25)
 [GOOD] (assert s28)
-[GOOD] (assert s31)
-[GOOD] (assert s37)
-[GOOD] (assert s41)
-[GOOD] (assert s46)
-[GOOD] (assert s50)
-[GOOD] (assert s55)
-[GOOD] (assert s59)
-[GOOD] (assert s64)
-[GOOD] (assert s69)
+[GOOD] (assert s34)
+[GOOD] (assert s38)
+[GOOD] (assert s43)
+[GOOD] (assert s47)
+[GOOD] (assert s52)
+[GOOD] (assert s56)
+[GOOD] (assert s61)
+[GOOD] (assert s66)
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
 [RECV] ((s0 0))
-[SEND] (get-value (s17))
-[RECV] ((s17 false))
-[SEND] (get-value (s18))
-[RECV] ((s18 0))
 [GOOD] (set-option :pp.max_depth      4294967295)
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
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
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
@@ -20,35 +19,33 @@
 [GOOD] (define-fun s9 () Int (- 3))
 [GOOD] (define-fun s11 () Int 9)
 [GOOD] (define-fun s14 () Int 1)
-[GOOD] (define-fun s21 () Int 5)
-[GOOD] (define-fun s23 () Int 7)
-[GOOD] (define-fun s25 () Int 6)
-[GOOD] (define-fun s29 () (_ FloatingPoint  8 24) ((_ to_fp 8 24) roundNearestTiesToEven (/ 4508877.0 524288.0)))
-[GOOD] (define-fun s32 () (_ FloatingPoint  8 24) ((_ to_fp 8 24) roundNearestTiesToEven (/ 5033165.0 524288.0)))
-[GOOD] (define-fun s33 () Int 121)
-[GOOD] (define-fun s38 () Int 8)
-[GOOD] (define-fun s40 () (_ FloatingPoint  8 24) (_ +oo 8 24))
-[GOOD] (define-fun s42 () String (_ char #x63))
-[GOOD] (define-fun s43 () String "hey")
-[GOOD] (define-fun s45 () (_ FloatingPoint  8 24) ((_ to_fp 8 24) roundNearestTiesToEven (/ 78.0 1.0)))
-[GOOD] (define-fun s47 () String "tey")
-[GOOD] (define-fun s49 () (_ FloatingPoint  8 24) ((_ to_fp 8 24) roundNearestTiesToEven (/ 92.0 1.0)))
-[GOOD] (define-fun s51 () String (_ char #x72))
-[GOOD] (define-fun s52 () String "foo")
-[GOOD] (define-fun s54 () (_ FloatingPoint  8 24) ((_ to_fp 8 24) roundNearestTiesToEven (/ 7.0 2.0)))
-[GOOD] (define-fun s56 () (Seq Int) (seq.++ (seq.unit 1) (seq.unit 2) (seq.unit 3)))
-[GOOD] (define-fun s57 () (Seq (_ FloatingPoint  8 24)) (seq.++ (seq.unit ((_ to_fp 8 24) roundNearestTiesToEven (/ 8598323.0 1048576.0))) (seq.unit ((_ to_fp 8 24) roundNearestTiesToEven (/ 3.0 1.0)))))
-[GOOD] (define-fun s60 () (Seq Int) (seq.++ (seq.unit 9) (seq.unit 5)))
-[GOOD] (define-fun s61 () (Seq (_ FloatingPoint  8 24)) (seq.++ (seq.unit ((_ to_fp 8 24) roundNearestTiesToEven (/ 8598323.0 1048576.0))) (seq.unit ((_ to_fp 8 24) roundNearestTiesToEven (/ 9.0 1.0)))))
-[GOOD] (define-fun s63 () Int 21)
-[GOOD] (define-fun s65 () (Seq Int) (seq.unit 5))
-[GOOD] (define-fun s66 () (Seq (_ FloatingPoint  8 24)) (seq.++ (seq.unit ((_ to_fp 8 24) roundNearestTiesToEven (/ 8598323.0 1048576.0))) (seq.unit (_ +zero 8 24))))
-[GOOD] (define-fun s68 () Int 210)
+[GOOD] (define-fun s18 () Int 5)
+[GOOD] (define-fun s20 () Int 7)
+[GOOD] (define-fun s22 () Int 6)
+[GOOD] (define-fun s26 () (_ FloatingPoint  8 24) (fp #b0 #b10000010 #b00010011001100110011010))
+[GOOD] (define-fun s29 () (_ FloatingPoint  8 24) (fp #b0 #b10000010 #b00110011001100110011010))
+[GOOD] (define-fun s30 () Int 121)
+[GOOD] (define-fun s35 () Int 8)
+[GOOD] (define-fun s37 () (_ FloatingPoint  8 24) (_ +oo 8 24))
+[GOOD] (define-fun s39 () String (_ char #x63))
+[GOOD] (define-fun s40 () String "hey")
+[GOOD] (define-fun s42 () (_ FloatingPoint  8 24) (fp #b0 #b10000101 #b00111000000000000000000))
+[GOOD] (define-fun s44 () String "tey")
+[GOOD] (define-fun s46 () (_ FloatingPoint  8 24) (fp #b0 #b10000101 #b01110000000000000000000))
+[GOOD] (define-fun s48 () String (_ char #x72))
+[GOOD] (define-fun s49 () String "foo")
+[GOOD] (define-fun s51 () (_ FloatingPoint  8 24) (fp #b0 #b10000000 #b11000000000000000000000))
+[GOOD] (define-fun s53 () (Seq Int) (seq.++ (seq.unit 1) (seq.unit 2) (seq.unit 3)))
+[GOOD] (define-fun s54 () (Seq (_ FloatingPoint  8 24)) (seq.++ (seq.unit (fp #b0 #b10000010 #b00000110011001100110011)) (seq.unit (fp #b0 #b10000000 #b10000000000000000000000))))
+[GOOD] (define-fun s57 () (Seq Int) (seq.++ (seq.unit 9) (seq.unit 5)))
+[GOOD] (define-fun s58 () (Seq (_ FloatingPoint  8 24)) (seq.++ (seq.unit (fp #b0 #b10000010 #b00000110011001100110011)) (seq.unit (fp #b0 #b10000010 #b00100000000000000000000))))
+[GOOD] (define-fun s60 () Int 21)
+[GOOD] (define-fun s62 () (Seq Int) (seq.unit 5))
+[GOOD] (define-fun s63 () (Seq (_ FloatingPoint  8 24)) (seq.++ (seq.unit (fp #b0 #b10000010 #b00000110011001100110011)) (seq.unit (_ +zero 8 24))))
+[GOOD] (define-fun s65 () Int 210)
 [GOOD] ; --- top level inputs ---
 [GOOD] (declare-fun s0 () Int)
-[GOOD] (declare-fun s17 () Bool) ; tracks user variable "__internal_sbv_s17"
-[GOOD] (declare-fun s18 () Int) ; tracks user variable "__internal_sbv_s18"
-[GOOD] (declare-fun s70 () Int) ; tracks user variable "__internal_sbv_s70"
+[GOOD] (declare-fun s67 () Int) ; tracks user variable "__internal_sbv_s67"
 [GOOD] ; --- constant tables ---
 [GOOD] ; --- non-constant tables ---
 [GOOD] ; --- uninterpreted constants ---
@@ -69,52 +66,51 @@
 [GOOD] (define-fun s13 () Int (q1 s0))
 [GOOD] (define-fun s15 () Int (+ s0 s14))
 [GOOD] (define-fun s16 () Bool (= s13 s15))
-[GOOD] (define-fun s19 () Int (q2 s17 s18))
-[GOOD] (define-fun s20 () Int (q2 true s5))
-[GOOD] (define-fun s22 () Bool (= s20 s21))
-[GOOD] (define-fun s24 () Int (q2 false s23))
-[GOOD] (define-fun s26 () Bool (= s24 s25))
-[GOOD] (define-fun s27 () Int (q2 false s3))
-[GOOD] (define-fun s28 () Bool (= s5 s27))
-[GOOD] (define-fun s30 () (_ FloatingPoint  8 24) (q3 s29 true s3))
-[GOOD] (define-fun s31 () Bool (fp.eq s29 s30))
-[GOOD] (define-fun s34 () (_ FloatingPoint  8 24) (q3 s32 true s33))
-[GOOD] (define-fun s35 () Bool (fp.isZero s34))
-[GOOD] (define-fun s36 () Bool (fp.isNegative s34))
-[GOOD] (define-fun s37 () Bool (and s35 s36))
-[GOOD] (define-fun s39 () (_ FloatingPoint  8 24) (q3 s32 false s38))
-[GOOD] (define-fun s41 () Bool (fp.eq s39 s40))
-[GOOD] (define-fun s44 () (_ FloatingPoint  8 24) (q4 s42 s43))
-[GOOD] (define-fun s46 () Bool (fp.eq s44 s45))
-[GOOD] (define-fun s48 () (_ FloatingPoint  8 24) (q4 s42 s47))
-[GOOD] (define-fun s50 () Bool (fp.eq s48 s49))
-[GOOD] (define-fun s53 () (_ FloatingPoint  8 24) (q4 s51 s52))
-[GOOD] (define-fun s55 () Bool (fp.eq s53 s54))
-[GOOD] (define-fun s58 () Int (q5 s56 s57))
-[GOOD] (define-fun s59 () Bool (= s23 s58))
-[GOOD] (define-fun s62 () Int (q5 s60 s61))
-[GOOD] (define-fun s64 () Bool (= s62 s63))
-[GOOD] (define-fun s67 () Int (q5 s65 s66))
-[GOOD] (define-fun s69 () Bool (= s67 s68))
-[GOOD] (define-fun s71 () Bool (q6 s70))
+[GOOD] (define-fun s17 () Int (q2 true s5))
+[GOOD] (define-fun s19 () Bool (= s17 s18))
+[GOOD] (define-fun s21 () Int (q2 false s20))
+[GOOD] (define-fun s23 () Bool (= s21 s22))
+[GOOD] (define-fun s24 () Int (q2 false s3))
+[GOOD] (define-fun s25 () Bool (= s5 s24))
+[GOOD] (define-fun s27 () (_ FloatingPoint  8 24) (q3 s26 true s3))
+[GOOD] (define-fun s28 () Bool (fp.eq s26 s27))
+[GOOD] (define-fun s31 () (_ FloatingPoint  8 24) (q3 s29 true s30))
+[GOOD] (define-fun s32 () Bool (fp.isZero s31))
+[GOOD] (define-fun s33 () Bool (fp.isNegative s31))
+[GOOD] (define-fun s34 () Bool (and s32 s33))
+[GOOD] (define-fun s36 () (_ FloatingPoint  8 24) (q3 s29 false s35))
+[GOOD] (define-fun s38 () Bool (fp.eq s36 s37))
+[GOOD] (define-fun s41 () (_ FloatingPoint  8 24) (q4 s39 s40))
+[GOOD] (define-fun s43 () Bool (fp.eq s41 s42))
+[GOOD] (define-fun s45 () (_ FloatingPoint  8 24) (q4 s39 s44))
+[GOOD] (define-fun s47 () Bool (fp.eq s45 s46))
+[GOOD] (define-fun s50 () (_ FloatingPoint  8 24) (q4 s48 s49))
+[GOOD] (define-fun s52 () Bool (fp.eq s50 s51))
+[GOOD] (define-fun s55 () Int (q5 s53 s54))
+[GOOD] (define-fun s56 () Bool (= s20 s55))
+[GOOD] (define-fun s59 () Int (q5 s57 s58))
+[GOOD] (define-fun s61 () Bool (= s59 s60))
+[GOOD] (define-fun s64 () Int (q5 s62 s63))
+[GOOD] (define-fun s66 () Bool (= s64 s65))
+[GOOD] (define-fun s68 () Bool (q6 s67))
 [GOOD] ; --- delayedEqualities ---
 [GOOD] ; --- formula ---
 [GOOD] (assert s4)
 [GOOD] (assert s8)
 [GOOD] (assert s12)
 [GOOD] (assert s16)
-[GOOD] (assert s22)
-[GOOD] (assert s26)
+[GOOD] (assert s19)
+[GOOD] (assert s23)
+[GOOD] (assert s25)
 [GOOD] (assert s28)
-[GOOD] (assert s31)
-[GOOD] (assert s37)
-[GOOD] (assert s41)
-[GOOD] (assert s46)
-[GOOD] (assert s50)
-[GOOD] (assert s55)
-[GOOD] (assert s59)
-[GOOD] (assert s64)
-[GOOD] (assert s69)
+[GOOD] (assert s34)
+[GOOD] (assert s38)
+[GOOD] (assert s43)
+[GOOD] (assert s47)
+[GOOD] (assert s52)
+[GOOD] (assert s56)
+[GOOD] (assert s61)
+[GOOD] (assert s66)
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
diff --git a/SBVTestSuite/GoldFiles/query_uisatex3.gold b/SBVTestSuite/GoldFiles/query_uisatex3.gold
--- a/SBVTestSuite/GoldFiles/query_uisatex3.gold
+++ b/SBVTestSuite/GoldFiles/query_uisatex3.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
@@ -34,5 +33,5 @@
 *** Exit code: ExitSuccess
 
  FINAL:
-("y x = 3 * x",(True,Just ["x"],EApp [ECon "lambda",EApp [EApp [ECon "x!1",ECon "Int"]],EApp [ECon "*",ENum (3,Nothing),ECon "x!1"]]))
+("y x = 3 * x",(True,Just ["x"],EApp [ECon "lambda",EApp [EApp [ECon "x!1",ECon "Int"]],EApp [ECon "*",ENum (3,Nothing,False),ECon "x!1"]]))
 DONE!
diff --git a/SBVTestSuite/GoldFiles/query_yices.gold b/SBVTestSuite/GoldFiles/query_yices.gold
--- a/SBVTestSuite/GoldFiles/query_yices.gold
+++ b/SBVTestSuite/GoldFiles/query_yices.gold
@@ -4,7 +4,6 @@
 [GOOD] (set-option :global-declarations true)
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/query_z3.gold b/SBVTestSuite/GoldFiles/query_z3.gold
--- a/SBVTestSuite/GoldFiles/query_z3.gold
+++ b/SBVTestSuite/GoldFiles/query_z3.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/recursive10_mutual.gold b/SBVTestSuite/GoldFiles/recursive10_mutual.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/recursive10_mutual.gold
@@ -0,0 +1,212 @@
+[MEASURE] Verifying termination measures for: mf @(SBV Integer -> SBV Integer), mg @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: mf @(SBV Integer -> SBV Integer)
+[MEASURE] Checking mutual recursion group: {mf :: SBV Integer -> SBV Integer, mg :: SBV Integer -> SBV Integer}
+[MEASURE] Mutual group: trying measure abs arg1 for all members
+[MEASURE] replayDAG {mf @(SBV Integer -> SBV Integer), mg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (>= s8 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s9))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {mf @(SBV Integer -> SBV Integer), mg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Int (abs s4))
+[GOOD] (define-fun s10 () Bool (not s3))
+[GOOD] (define-fun s11 () Bool (> s8 s9))
+[GOOD] (define-fun s12 () Bool (=> s10 s11))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for mf @(SBV Integer -> SBV Integer)
+[MEASURE] replayDAG {mf @(SBV Integer -> SBV Integer), mg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (>= s8 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s9))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {mf @(SBV Integer -> SBV Integer), mg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Int (abs s4))
+[GOOD] (define-fun s10 () Bool (not s3))
+[GOOD] (define-fun s11 () Bool (> s8 s9))
+[GOOD] (define-fun s12 () Bool (=> s10 s11))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for mg @(SBV Integer -> SBV Integer)
+[MEASURE] Mutual group: measure abs arg1 works for all members
+[MEASURE] Passed (terminating): mf @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: mg @(SBV Integer -> SBV Integer)
+[MEASURE] mg @(SBV Integer -> SBV Integer): mutual group already verified, skipping
+[MEASURE] Passed (terminating): mg @(SBV Integer -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |mf @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger, |mg @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger
+[GOOD] (define-funs-rec
+         ((|mf @(SBV Integer -> SBV Integer)| ((l1_s0 Int)) Int)
+          (|mg @(SBV Integer -> SBV Integer)| ((l2_s0 Int)) Int))
+         (; Definition of: |mf @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |mg @(SBV Integer -> SBV Integer)|]
+                                  (let ((l1_s1 0))
+                                  (let ((l1_s3 1))
+                                  (let ((l1_s2 (<= l1_s0 l1_s1)))
+                                  (let ((l1_s4 (- l1_s0 l1_s3)))
+                                  (let ((l1_s5 (|mg @(SBV Integer -> SBV Integer)| l1_s4)))
+                                  (let ((l1_s6 (+ l1_s3 l1_s5)))
+                                  (let ((l1_s7 (ite l1_s2 l1_s1 l1_s6)))
+                                  l1_s7)))))))
+          ; Definition of: |mg @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |mf @(SBV Integer -> SBV Integer)|]
+                                                  (let ((l2_s1 0))
+                                                  (let ((l2_s3 1))
+                                                  (let ((l2_s2 (<= l2_s0 l2_s1)))
+                                                  (let ((l2_s4 (- l2_s0 l2_s3)))
+                                                  (let ((l2_s5 (|mf @(SBV Integer -> SBV Integer)| l2_s4)))
+                                                  (let ((l2_s6 (+ l2_s3 l2_s5)))
+                                                  (let ((l2_s7 (ite l2_s2 l2_s1 l2_s6)))
+                                                  l2_s7)))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Int (|mf @(SBV Integer -> SBV Integer)| s0))
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+
+RESULT:
+Satisfiable. Model:
+  s0 = 0 :: Integer
diff --git a/SBVTestSuite/GoldFiles/recursive11_chain.gold b/SBVTestSuite/GoldFiles/recursive11_chain.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/recursive11_chain.gold
@@ -0,0 +1,299 @@
+[MEASURE] Verifying termination measures for: ca @(SBV Integer -> SBV Integer), cb @(SBV Integer -> SBV Integer), cc @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: ca @(SBV Integer -> SBV Integer)
+[MEASURE] Checking mutual recursion group: {ca :: SBV Integer -> SBV Integer, cb :: SBV Integer -> SBV Integer, cc :: SBV Integer -> SBV Integer}
+[MEASURE] Mutual group: trying measure abs arg1 for all members
+[MEASURE] replayDAG {ca @(SBV Integer -> SBV Integer), cb @(SBV Integer -> SBV Integer), cc @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (>= s8 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s9))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {ca @(SBV Integer -> SBV Integer), cb @(SBV Integer -> SBV Integer), cc @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Int (abs s4))
+[GOOD] (define-fun s10 () Bool (not s3))
+[GOOD] (define-fun s11 () Bool (> s8 s9))
+[GOOD] (define-fun s12 () Bool (=> s10 s11))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for ca @(SBV Integer -> SBV Integer)
+[MEASURE] replayDAG {ca @(SBV Integer -> SBV Integer), cb @(SBV Integer -> SBV Integer), cc @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (>= s8 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s9))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {ca @(SBV Integer -> SBV Integer), cb @(SBV Integer -> SBV Integer), cc @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Int (abs s4))
+[GOOD] (define-fun s10 () Bool (not s3))
+[GOOD] (define-fun s11 () Bool (> s8 s9))
+[GOOD] (define-fun s12 () Bool (=> s10 s11))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for cb @(SBV Integer -> SBV Integer)
+[MEASURE] replayDAG {ca @(SBV Integer -> SBV Integer), cb @(SBV Integer -> SBV Integer), cc @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (>= s8 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s9))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {ca @(SBV Integer -> SBV Integer), cb @(SBV Integer -> SBV Integer), cc @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Int (abs s4))
+[GOOD] (define-fun s10 () Bool (not s3))
+[GOOD] (define-fun s11 () Bool (> s8 s9))
+[GOOD] (define-fun s12 () Bool (=> s10 s11))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for cc @(SBV Integer -> SBV Integer)
+[MEASURE] Mutual group: measure abs arg1 works for all members
+[MEASURE] Passed (terminating): ca @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: cb @(SBV Integer -> SBV Integer)
+[MEASURE] cb @(SBV Integer -> SBV Integer): mutual group already verified, skipping
+[MEASURE] Passed (terminating): cb @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: cc @(SBV Integer -> SBV Integer)
+[MEASURE] cc @(SBV Integer -> SBV Integer): mutual group already verified, skipping
+[MEASURE] Passed (terminating): cc @(SBV Integer -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |ca @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger, |cb @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger, |cc @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger
+[GOOD] (define-funs-rec
+         ((|ca @(SBV Integer -> SBV Integer)| ((l1_s0 Int)) Int)
+          (|cb @(SBV Integer -> SBV Integer)| ((l2_s0 Int)) Int)
+          (|cc @(SBV Integer -> SBV Integer)| ((l3_s0 Int)) Int))
+         (; Definition of: |ca @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |cb @(SBV Integer -> SBV Integer)|]
+                                  (let ((l1_s1 0))
+                                  (let ((l1_s3 1))
+                                  (let ((l1_s2 (<= l1_s0 l1_s1)))
+                                  (let ((l1_s4 (- l1_s0 l1_s3)))
+                                  (let ((l1_s5 (|cb @(SBV Integer -> SBV Integer)| l1_s4)))
+                                  (let ((l1_s6 (+ l1_s3 l1_s5)))
+                                  (let ((l1_s7 (ite l1_s2 l1_s1 l1_s6)))
+                                  l1_s7)))))))
+          ; Definition of: |cb @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |cc @(SBV Integer -> SBV Integer)|]
+                                                  (let ((l2_s1 0))
+                                                  (let ((l2_s3 1))
+                                                  (let ((l2_s2 (<= l2_s0 l2_s1)))
+                                                  (let ((l2_s4 (- l2_s0 l2_s3)))
+                                                  (let ((l2_s5 (|cc @(SBV Integer -> SBV Integer)| l2_s4)))
+                                                  (let ((l2_s6 (+ l2_s3 l2_s5)))
+                                                  (let ((l2_s7 (ite l2_s2 l2_s1 l2_s6)))
+                                                  l2_s7)))))))
+          ; Definition of: |cc @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |ca @(SBV Integer -> SBV Integer)|]
+                                                                  (let ((l3_s1 0))
+                                                                  (let ((l3_s3 1))
+                                                                  (let ((l3_s2 (<= l3_s0 l3_s1)))
+                                                                  (let ((l3_s4 (- l3_s0 l3_s3)))
+                                                                  (let ((l3_s5 (|ca @(SBV Integer -> SBV Integer)| l3_s4)))
+                                                                  (let ((l3_s6 (+ l3_s3 l3_s5)))
+                                                                  (let ((l3_s7 (ite l3_s2 l3_s1 l3_s6)))
+                                                                  l3_s7)))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Int (|ca @(SBV Integer -> SBV Integer)| s0))
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+
+RESULT:
+Satisfiable. Model:
+  s0 = 0 :: Integer
diff --git a/SBVTestSuite/GoldFiles/recursive12_badMutual.gold b/SBVTestSuite/GoldFiles/recursive12_badMutual.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/recursive12_badMutual.gold
@@ -0,0 +1,526 @@
+[MEASURE] Verifying termination measures for: bf @(SBV Integer -> SBV Integer), bg @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: bf @(SBV Integer -> SBV Integer)
+[MEASURE] Checking mutual recursion group: {bf :: SBV Integer -> SBV Integer, bg :: SBV Integer -> SBV Integer}
+[MEASURE] Mutual group: trying measure abs arg1 for all members
+[MEASURE] replayDAG {bf @(SBV Integer -> SBV Integer), bg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (+ s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (>= s8 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s9))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {bf @(SBV Integer -> SBV Integer), bg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (+ s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Int (abs s4))
+[GOOD] (define-fun s10 () Bool (not s3))
+[GOOD] (define-fun s11 () Bool (> s8 s9))
+[GOOD] (define-fun s12 () Bool (=> s10 s11))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s8))
+[RECV] ((s8 1))
+[SEND] (get-value (s9))
+[RECV] ((s9 2))
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s5))
+[RECV] ((s5 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease failed for bf @(SBV Integer -> SBV Integer): Falsifiable. Counter-example:
+  arg    = 1 :: Integer
+  before = 1 :: Integer
+  then   = 2 :: Integer
+[MEASURE] Mutual group: measure abs arg1 failed, trying next
+[MEASURE] Mutual group: trying measure smax 0 arg1 for all members
+[MEASURE] replayDAG {bf @(SBV Integer -> SBV Integer), bg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (+ s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Bool (<= s1 s0))
+[GOOD] (define-fun s9 () Int (ite s8 s0 s1))
+[GOOD] (define-fun s10 () Bool (>= s9 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s10))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {bf @(SBV Integer -> SBV Integer), bg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (+ s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Bool (<= s1 s0))
+[GOOD] (define-fun s9 () Int (ite s8 s0 s1))
+[GOOD] (define-fun s10 () Bool (<= s1 s4))
+[GOOD] (define-fun s11 () Int (ite s10 s4 s1))
+[GOOD] (define-fun s12 () Bool (not s3))
+[GOOD] (define-fun s13 () Bool (> s9 s11))
+[GOOD] (define-fun s14 () Bool (=> s12 s13))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s9))
+[RECV] ((s9 1))
+[SEND] (get-value (s11))
+[RECV] ((s11 2))
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s5))
+[RECV] ((s5 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease failed for bf @(SBV Integer -> SBV Integer): Falsifiable. Counter-example:
+  arg    = 1 :: Integer
+  before = 1 :: Integer
+  then   = 2 :: Integer
+[MEASURE] Mutual group: measure smax 0 arg1 failed, trying next
+[MEASURE] Mutual group: trying measure abs arg1 + smax 0 arg1 for all members
+[MEASURE] replayDAG {bf @(SBV Integer -> SBV Integer), bg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (+ s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (<= s1 s0))
+[GOOD] (define-fun s10 () Int (ite s9 s0 s1))
+[GOOD] (define-fun s11 () Int (+ s8 s10))
+[GOOD] (define-fun s12 () Bool (>= s11 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {bf @(SBV Integer -> SBV Integer), bg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (+ s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (<= s1 s0))
+[GOOD] (define-fun s10 () Int (ite s9 s0 s1))
+[GOOD] (define-fun s11 () Int (+ s8 s10))
+[GOOD] (define-fun s12 () Int (abs s4))
+[GOOD] (define-fun s13 () Bool (<= s1 s4))
+[GOOD] (define-fun s14 () Int (ite s13 s4 s1))
+[GOOD] (define-fun s15 () Int (+ s12 s14))
+[GOOD] (define-fun s16 () Bool (not s3))
+[GOOD] (define-fun s17 () Bool (> s11 s15))
+[GOOD] (define-fun s18 () Bool (=> s16 s17))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s18))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s11))
+[RECV] ((s11 2))
+[SEND] (get-value (s15))
+[RECV] ((s15 4))
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s5))
+[RECV] ((s5 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease failed for bf @(SBV Integer -> SBV Integer): Falsifiable. Counter-example:
+  arg    = 1 :: Integer
+  before = 2 :: Integer
+  then   = 4 :: Integer
+[MEASURE] Mutual group: measure abs arg1 + smax 0 arg1 failed, trying next
+[MEASURE] Mutual group: trying measure (abs arg1, smax 0 arg1) for all members
+[MEASURE] replayDAG {bf @(SBV Integer -> SBV Integer), bg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (+ s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (<= s1 s0))
+[GOOD] (define-fun s10 () Int (ite s9 s0 s1))
+[GOOD] (define-fun s11 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s8 s10))
+[GOOD] (define-fun s12 () Int (proj_1_SBVTuple2 s11))
+[GOOD] (define-fun s13 () Bool (>= s12 s1))
+[GOOD] (define-fun s14 () Int (proj_2_SBVTuple2 s11))
+[GOOD] (define-fun s15 () Bool (>= s14 s1))
+[GOOD] (define-fun s16 () Bool (and s13 s15))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s16))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {bf @(SBV Integer -> SBV Integer), bg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (+ s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (<= s1 s0))
+[GOOD] (define-fun s10 () Int (ite s9 s0 s1))
+[GOOD] (define-fun s11 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s8 s10))
+[GOOD] (define-fun s12 () Int (abs s4))
+[GOOD] (define-fun s13 () Bool (<= s1 s4))
+[GOOD] (define-fun s14 () Int (ite s13 s4 s1))
+[GOOD] (define-fun s15 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s12 s14))
+[GOOD] (define-fun s16 () Bool (not s3))
+[GOOD] (define-fun s17 () Int (proj_1_SBVTuple2 s15))
+[GOOD] (define-fun s18 () Int (proj_1_SBVTuple2 s11))
+[GOOD] (define-fun s19 () Bool (< s17 s18))
+[GOOD] (define-fun s20 () Bool (= s17 s18))
+[GOOD] (define-fun s21 () Int (proj_2_SBVTuple2 s15))
+[GOOD] (define-fun s22 () Int (proj_2_SBVTuple2 s11))
+[GOOD] (define-fun s23 () Bool (< s21 s22))
+[GOOD] (define-fun s24 () Bool (and s20 s23))
+[GOOD] (define-fun s25 () Bool (or s19 s24))
+[GOOD] (define-fun s26 () Bool (=> s16 s25))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s26))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s11))
+[RECV] ((s11 (mkSBVTuple2 1 1)))
+[SEND] (get-value (s15))
+[RECV] ((s15 (mkSBVTuple2 2 2)))
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s5))
+[RECV] ((s5 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease failed for bf @(SBV Integer -> SBV Integer): Falsifiable. Counter-example:
+  arg    =     1 :: Integer
+  before = (1,1) :: (Integer, Integer)
+  then   = (2,2) :: (Integer, Integer)
+[MEASURE] Mutual group: measure (abs arg1, smax 0 arg1) failed, trying next
+[MEASURE] Mutual group: trying measure (smax 0 arg1, abs arg1) for all members
+[MEASURE] replayDAG {bf @(SBV Integer -> SBV Integer), bg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (+ s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Bool (<= s1 s0))
+[GOOD] (define-fun s9 () Int (ite s8 s0 s1))
+[GOOD] (define-fun s10 () Int (abs s0))
+[GOOD] (define-fun s11 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s9 s10))
+[GOOD] (define-fun s12 () Int (proj_1_SBVTuple2 s11))
+[GOOD] (define-fun s13 () Bool (>= s12 s1))
+[GOOD] (define-fun s14 () Int (proj_2_SBVTuple2 s11))
+[GOOD] (define-fun s15 () Bool (>= s14 s1))
+[GOOD] (define-fun s16 () Bool (and s13 s15))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s16))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {bf @(SBV Integer -> SBV Integer), bg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (+ s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Bool (<= s1 s0))
+[GOOD] (define-fun s9 () Int (ite s8 s0 s1))
+[GOOD] (define-fun s10 () Int (abs s0))
+[GOOD] (define-fun s11 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s9 s10))
+[GOOD] (define-fun s12 () Bool (<= s1 s4))
+[GOOD] (define-fun s13 () Int (ite s12 s4 s1))
+[GOOD] (define-fun s14 () Int (abs s4))
+[GOOD] (define-fun s15 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s13 s14))
+[GOOD] (define-fun s16 () Bool (not s3))
+[GOOD] (define-fun s17 () Int (proj_1_SBVTuple2 s15))
+[GOOD] (define-fun s18 () Int (proj_1_SBVTuple2 s11))
+[GOOD] (define-fun s19 () Bool (< s17 s18))
+[GOOD] (define-fun s20 () Bool (= s17 s18))
+[GOOD] (define-fun s21 () Int (proj_2_SBVTuple2 s15))
+[GOOD] (define-fun s22 () Int (proj_2_SBVTuple2 s11))
+[GOOD] (define-fun s23 () Bool (< s21 s22))
+[GOOD] (define-fun s24 () Bool (and s20 s23))
+[GOOD] (define-fun s25 () Bool (or s19 s24))
+[GOOD] (define-fun s26 () Bool (=> s16 s25))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s26))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s11))
+[RECV] ((s11 (mkSBVTuple2 1 1)))
+[SEND] (get-value (s15))
+[RECV] ((s15 (mkSBVTuple2 2 2)))
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s5))
+[RECV] ((s5 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease failed for bf @(SBV Integer -> SBV Integer): Falsifiable. Counter-example:
+  arg    =     1 :: Integer
+  before = (1,1) :: (Integer, Integer)
+  then   = (2,2) :: (Integer, Integer)
+[MEASURE] Mutual group: measure (smax 0 arg1, abs arg1) failed, trying next
+
+EXCEPTION:
+
+*** Data.SBV: Cannot determine a termination measure for mutual recursion group.
+***
+***     bf  :: SBV Integer -> SBV Integer
+***     bg  :: SBV Integer -> SBV Integer
+***
+*** Please use 'smtFunctionWithMeasure' to provide explicit measures.
+
diff --git a/SBVTestSuite/GoldFiles/recursive13_mutualMeasure.gold b/SBVTestSuite/GoldFiles/recursive13_mutualMeasure.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/recursive13_mutualMeasure.gold
@@ -0,0 +1,212 @@
+[MEASURE] Verifying termination measures for: ef @(SBV Integer -> SBV Integer), eg @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: ef @(SBV Integer -> SBV Integer)
+[MEASURE] Checking mutual recursion group: {ef :: SBV Integer -> SBV Integer, eg :: SBV Integer -> SBV Integer}
+[MEASURE] Mutual group: trying user-provided measure for all members
+[MEASURE] replayDAG {ef @(SBV Integer -> SBV Integer), eg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (>= s8 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s9))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {ef @(SBV Integer -> SBV Integer), eg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Int (abs s4))
+[GOOD] (define-fun s10 () Bool (not s3))
+[GOOD] (define-fun s11 () Bool (> s8 s9))
+[GOOD] (define-fun s12 () Bool (=> s10 s11))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for ef @(SBV Integer -> SBV Integer)
+[MEASURE] replayDAG {ef @(SBV Integer -> SBV Integer), eg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (>= s8 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s9))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {ef @(SBV Integer -> SBV Integer), eg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Int (abs s4))
+[GOOD] (define-fun s10 () Bool (not s3))
+[GOOD] (define-fun s11 () Bool (> s8 s9))
+[GOOD] (define-fun s12 () Bool (=> s10 s11))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for eg @(SBV Integer -> SBV Integer)
+[MEASURE] Mutual group: user-provided measure works for all members
+[MEASURE] Passed (terminating): ef @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: eg @(SBV Integer -> SBV Integer)
+[MEASURE] eg @(SBV Integer -> SBV Integer): mutual group already verified, skipping
+[MEASURE] Passed (terminating): eg @(SBV Integer -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |ef @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger, |eg @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger
+[GOOD] (define-funs-rec
+         ((|ef @(SBV Integer -> SBV Integer)| ((l1_s0 Int)) Int)
+          (|eg @(SBV Integer -> SBV Integer)| ((l2_s0 Int)) Int))
+         (; Definition of: |ef @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |eg @(SBV Integer -> SBV Integer)|]
+                                  (let ((l1_s1 0))
+                                  (let ((l1_s3 1))
+                                  (let ((l1_s2 (<= l1_s0 l1_s1)))
+                                  (let ((l1_s4 (- l1_s0 l1_s3)))
+                                  (let ((l1_s5 (|eg @(SBV Integer -> SBV Integer)| l1_s4)))
+                                  (let ((l1_s6 (+ l1_s3 l1_s5)))
+                                  (let ((l1_s7 (ite l1_s2 l1_s1 l1_s6)))
+                                  l1_s7)))))))
+          ; Definition of: |eg @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |ef @(SBV Integer -> SBV Integer)|]
+                                                  (let ((l2_s1 0))
+                                                  (let ((l2_s3 1))
+                                                  (let ((l2_s2 (<= l2_s0 l2_s1)))
+                                                  (let ((l2_s4 (- l2_s0 l2_s3)))
+                                                  (let ((l2_s5 (|ef @(SBV Integer -> SBV Integer)| l2_s4)))
+                                                  (let ((l2_s6 (+ l2_s3 l2_s5)))
+                                                  (let ((l2_s7 (ite l2_s2 l2_s1 l2_s6)))
+                                                  l2_s7)))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Int (|ef @(SBV Integer -> SBV Integer)| s0))
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+
+RESULT:
+Satisfiable. Model:
+  s0 = 0 :: Integer
diff --git a/SBVTestSuite/GoldFiles/recursive14_badMutualMeasure.gold b/SBVTestSuite/GoldFiles/recursive14_badMutualMeasure.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/recursive14_badMutualMeasure.gold
@@ -0,0 +1,294 @@
+[MEASURE] Verifying termination measures for: hf @(SBV Integer -> SBV Integer), hg @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: hf @(SBV Integer -> SBV Integer)
+[MEASURE] Checking mutual recursion group: {hf :: SBV Integer -> SBV Integer, hg :: SBV Integer -> SBV Integer}
+[MEASURE] Mutual group: trying user-provided measure for all members
+[MEASURE] replayDAG {hf @(SBV Integer -> SBV Integer), hg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {hf @(SBV Integer -> SBV Integer), hg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Bool (not s3))
+[GOOD] (define-fun s9 () Bool (=> s8 false))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s9))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s5))
+[RECV] ((s5 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease failed for hf @(SBV Integer -> SBV Integer): Falsifiable. Counter-example:
+  arg    = 1 :: Integer
+  before = 1 :: Integer
+  then   = 1 :: Integer
+[MEASURE] Mutual group: user-provided measure failed, falling back to auto-guess
+[MEASURE] Mutual group: trying measure abs arg1 for all members
+[MEASURE] replayDAG {hf @(SBV Integer -> SBV Integer), hg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (>= s8 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s9))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {hf @(SBV Integer -> SBV Integer), hg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Int (abs s4))
+[GOOD] (define-fun s10 () Bool (not s3))
+[GOOD] (define-fun s11 () Bool (> s8 s9))
+[GOOD] (define-fun s12 () Bool (=> s10 s11))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for hf @(SBV Integer -> SBV Integer)
+[MEASURE] replayDAG {hf @(SBV Integer -> SBV Integer), hg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (>= s8 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s9))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {hf @(SBV Integer -> SBV Integer), hg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Int (abs s4))
+[GOOD] (define-fun s10 () Bool (not s3))
+[GOOD] (define-fun s11 () Bool (> s8 s9))
+[GOOD] (define-fun s12 () Bool (=> s10 s11))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for hg @(SBV Integer -> SBV Integer)
+[MEASURE] Mutual group: measure abs arg1 works for all members
+[MEASURE] Passed (terminating): hf @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: hg @(SBV Integer -> SBV Integer)
+[MEASURE] hg @(SBV Integer -> SBV Integer): mutual group already verified, skipping
+[MEASURE] Passed (terminating): hg @(SBV Integer -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |hf @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger, |hg @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger
+[GOOD] (define-funs-rec
+         ((|hf @(SBV Integer -> SBV Integer)| ((l1_s0 Int)) Int)
+          (|hg @(SBV Integer -> SBV Integer)| ((l2_s0 Int)) Int))
+         (; Definition of: |hf @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |hg @(SBV Integer -> SBV Integer)|]
+                                  (let ((l1_s1 0))
+                                  (let ((l1_s3 1))
+                                  (let ((l1_s2 (<= l1_s0 l1_s1)))
+                                  (let ((l1_s4 (- l1_s0 l1_s3)))
+                                  (let ((l1_s5 (|hg @(SBV Integer -> SBV Integer)| l1_s4)))
+                                  (let ((l1_s6 (+ l1_s3 l1_s5)))
+                                  (let ((l1_s7 (ite l1_s2 l1_s1 l1_s6)))
+                                  l1_s7)))))))
+          ; Definition of: |hg @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |hf @(SBV Integer -> SBV Integer)|]
+                                                  (let ((l2_s1 0))
+                                                  (let ((l2_s3 1))
+                                                  (let ((l2_s2 (<= l2_s0 l2_s1)))
+                                                  (let ((l2_s4 (- l2_s0 l2_s3)))
+                                                  (let ((l2_s5 (|hf @(SBV Integer -> SBV Integer)| l2_s4)))
+                                                  (let ((l2_s6 (+ l2_s3 l2_s5)))
+                                                  (let ((l2_s7 (ite l2_s2 l2_s1 l2_s6)))
+                                                  l2_s7)))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Int (|hf @(SBV Integer -> SBV Integer)| s0))
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+
+RESULT:
+Satisfiable. Model:
+  s0 = 0 :: Integer
diff --git a/SBVTestSuite/GoldFiles/recursive15_mixedMutualMeasure.gold b/SBVTestSuite/GoldFiles/recursive15_mixedMutualMeasure.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/recursive15_mixedMutualMeasure.gold
@@ -0,0 +1,212 @@
+[MEASURE] Verifying termination measures for: xf @(SBV Integer -> SBV Integer), xg @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: xf @(SBV Integer -> SBV Integer)
+[MEASURE] Checking mutual recursion group: {xf :: SBV Integer -> SBV Integer, xg :: SBV Integer -> SBV Integer}
+[MEASURE] Mutual group: trying user-provided measure for all members
+[MEASURE] replayDAG {xf @(SBV Integer -> SBV Integer), xg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (>= s8 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s9))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {xf @(SBV Integer -> SBV Integer), xg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Int (abs s4))
+[GOOD] (define-fun s10 () Bool (not s3))
+[GOOD] (define-fun s11 () Bool (> s8 s9))
+[GOOD] (define-fun s12 () Bool (=> s10 s11))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for xf @(SBV Integer -> SBV Integer)
+[MEASURE] replayDAG {xf @(SBV Integer -> SBV Integer), xg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (>= s8 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s9))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {xf @(SBV Integer -> SBV Integer), xg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Int (abs s4))
+[GOOD] (define-fun s10 () Bool (not s3))
+[GOOD] (define-fun s11 () Bool (> s8 s9))
+[GOOD] (define-fun s12 () Bool (=> s10 s11))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for xg @(SBV Integer -> SBV Integer)
+[MEASURE] Mutual group: user-provided measure works for all members
+[MEASURE] Passed (terminating): xf @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: xg @(SBV Integer -> SBV Integer)
+[MEASURE] xg @(SBV Integer -> SBV Integer): mutual group already verified, skipping
+[MEASURE] Passed (terminating): xg @(SBV Integer -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |xf @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger, |xg @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger
+[GOOD] (define-funs-rec
+         ((|xf @(SBV Integer -> SBV Integer)| ((l1_s0 Int)) Int)
+          (|xg @(SBV Integer -> SBV Integer)| ((l2_s0 Int)) Int))
+         (; Definition of: |xf @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |xg @(SBV Integer -> SBV Integer)|]
+                                  (let ((l1_s1 0))
+                                  (let ((l1_s3 1))
+                                  (let ((l1_s2 (<= l1_s0 l1_s1)))
+                                  (let ((l1_s4 (- l1_s0 l1_s3)))
+                                  (let ((l1_s5 (|xg @(SBV Integer -> SBV Integer)| l1_s4)))
+                                  (let ((l1_s6 (+ l1_s3 l1_s5)))
+                                  (let ((l1_s7 (ite l1_s2 l1_s1 l1_s6)))
+                                  l1_s7)))))))
+          ; Definition of: |xg @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |xf @(SBV Integer -> SBV Integer)|]
+                                                  (let ((l2_s1 0))
+                                                  (let ((l2_s3 1))
+                                                  (let ((l2_s2 (<= l2_s0 l2_s1)))
+                                                  (let ((l2_s4 (- l2_s0 l2_s3)))
+                                                  (let ((l2_s5 (|xf @(SBV Integer -> SBV Integer)| l2_s4)))
+                                                  (let ((l2_s6 (+ l2_s3 l2_s5)))
+                                                  (let ((l2_s7 (ite l2_s2 l2_s1 l2_s6)))
+                                                  l2_s7)))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Int (|xf @(SBV Integer -> SBV Integer)| s0))
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+
+RESULT:
+Satisfiable. Model:
+  s0 = 0 :: Integer
diff --git a/SBVTestSuite/GoldFiles/recursive16_badMixedMutualMeasure.gold b/SBVTestSuite/GoldFiles/recursive16_badMixedMutualMeasure.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/recursive16_badMixedMutualMeasure.gold
@@ -0,0 +1,1135 @@
+[MEASURE] Verifying termination measures for: yf @(SBV Integer -> SBV Integer), yg @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: yf @(SBV Integer -> SBV Integer)
+[MEASURE] Checking mutual recursion group: {yf :: SBV Integer -> SBV Integer, yg :: SBV Integer -> SBV Integer}
+[MEASURE] Mutual group: trying user-provided measure for all members
+[MEASURE] replayDAG {yf @(SBV Integer -> SBV Integer), yg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (>= s8 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s9))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {yf @(SBV Integer -> SBV Integer), yg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Int (abs s4))
+[GOOD] (define-fun s10 () Bool (not s3))
+[GOOD] (define-fun s11 () Bool (> s8 s9))
+[GOOD] (define-fun s12 () Bool (=> s10 s11))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for yf @(SBV Integer -> SBV Integer)
+[MEASURE] replayDAG {yf @(SBV Integer -> SBV Integer), yg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (+ s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (>= s8 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s9))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {yf @(SBV Integer -> SBV Integer), yg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (+ s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Int (abs s4))
+[GOOD] (define-fun s10 () Bool (not s3))
+[GOOD] (define-fun s11 () Bool (> s8 s9))
+[GOOD] (define-fun s12 () Bool (=> s10 s11))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s8))
+[RECV] ((s8 1))
+[SEND] (get-value (s9))
+[RECV] ((s9 2))
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s5))
+[RECV] ((s5 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease failed for yg @(SBV Integer -> SBV Integer): Falsifiable. Counter-example:
+  arg    = 1 :: Integer
+  before = 1 :: Integer
+  then   = 2 :: Integer
+[MEASURE] Mutual group: user-provided measure failed, falling back to auto-guess
+[MEASURE] Mutual group: trying measure abs arg1 for all members
+[MEASURE] replayDAG {yf @(SBV Integer -> SBV Integer), yg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (>= s8 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s9))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {yf @(SBV Integer -> SBV Integer), yg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Int (abs s4))
+[GOOD] (define-fun s10 () Bool (not s3))
+[GOOD] (define-fun s11 () Bool (> s8 s9))
+[GOOD] (define-fun s12 () Bool (=> s10 s11))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for yf @(SBV Integer -> SBV Integer)
+[MEASURE] replayDAG {yf @(SBV Integer -> SBV Integer), yg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (+ s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (>= s8 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s9))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {yf @(SBV Integer -> SBV Integer), yg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (+ s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Int (abs s4))
+[GOOD] (define-fun s10 () Bool (not s3))
+[GOOD] (define-fun s11 () Bool (> s8 s9))
+[GOOD] (define-fun s12 () Bool (=> s10 s11))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s8))
+[RECV] ((s8 1))
+[SEND] (get-value (s9))
+[RECV] ((s9 2))
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s5))
+[RECV] ((s5 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease failed for yg @(SBV Integer -> SBV Integer): Falsifiable. Counter-example:
+  arg    = 1 :: Integer
+  before = 1 :: Integer
+  then   = 2 :: Integer
+[MEASURE] Mutual group: measure abs arg1 failed, trying next
+[MEASURE] Mutual group: trying measure smax 0 arg1 for all members
+[MEASURE] replayDAG {yf @(SBV Integer -> SBV Integer), yg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Bool (<= s1 s0))
+[GOOD] (define-fun s9 () Int (ite s8 s0 s1))
+[GOOD] (define-fun s10 () Bool (>= s9 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s10))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {yf @(SBV Integer -> SBV Integer), yg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Bool (<= s1 s0))
+[GOOD] (define-fun s9 () Int (ite s8 s0 s1))
+[GOOD] (define-fun s10 () Bool (<= s1 s4))
+[GOOD] (define-fun s11 () Int (ite s10 s4 s1))
+[GOOD] (define-fun s12 () Bool (not s3))
+[GOOD] (define-fun s13 () Bool (> s9 s11))
+[GOOD] (define-fun s14 () Bool (=> s12 s13))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for yf @(SBV Integer -> SBV Integer)
+[MEASURE] replayDAG {yf @(SBV Integer -> SBV Integer), yg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (+ s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Bool (<= s1 s0))
+[GOOD] (define-fun s9 () Int (ite s8 s0 s1))
+[GOOD] (define-fun s10 () Bool (>= s9 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s10))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {yf @(SBV Integer -> SBV Integer), yg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (+ s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Bool (<= s1 s0))
+[GOOD] (define-fun s9 () Int (ite s8 s0 s1))
+[GOOD] (define-fun s10 () Bool (<= s1 s4))
+[GOOD] (define-fun s11 () Int (ite s10 s4 s1))
+[GOOD] (define-fun s12 () Bool (not s3))
+[GOOD] (define-fun s13 () Bool (> s9 s11))
+[GOOD] (define-fun s14 () Bool (=> s12 s13))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s9))
+[RECV] ((s9 1))
+[SEND] (get-value (s11))
+[RECV] ((s11 2))
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s5))
+[RECV] ((s5 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease failed for yg @(SBV Integer -> SBV Integer): Falsifiable. Counter-example:
+  arg    = 1 :: Integer
+  before = 1 :: Integer
+  then   = 2 :: Integer
+[MEASURE] Mutual group: measure smax 0 arg1 failed, trying next
+[MEASURE] Mutual group: trying measure abs arg1 + smax 0 arg1 for all members
+[MEASURE] replayDAG {yf @(SBV Integer -> SBV Integer), yg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (<= s1 s0))
+[GOOD] (define-fun s10 () Int (ite s9 s0 s1))
+[GOOD] (define-fun s11 () Int (+ s8 s10))
+[GOOD] (define-fun s12 () Bool (>= s11 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {yf @(SBV Integer -> SBV Integer), yg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (<= s1 s0))
+[GOOD] (define-fun s10 () Int (ite s9 s0 s1))
+[GOOD] (define-fun s11 () Int (+ s8 s10))
+[GOOD] (define-fun s12 () Int (abs s4))
+[GOOD] (define-fun s13 () Bool (<= s1 s4))
+[GOOD] (define-fun s14 () Int (ite s13 s4 s1))
+[GOOD] (define-fun s15 () Int (+ s12 s14))
+[GOOD] (define-fun s16 () Bool (not s3))
+[GOOD] (define-fun s17 () Bool (> s11 s15))
+[GOOD] (define-fun s18 () Bool (=> s16 s17))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s18))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for yf @(SBV Integer -> SBV Integer)
+[MEASURE] replayDAG {yf @(SBV Integer -> SBV Integer), yg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (+ s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (<= s1 s0))
+[GOOD] (define-fun s10 () Int (ite s9 s0 s1))
+[GOOD] (define-fun s11 () Int (+ s8 s10))
+[GOOD] (define-fun s12 () Bool (>= s11 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {yf @(SBV Integer -> SBV Integer), yg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (+ s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (<= s1 s0))
+[GOOD] (define-fun s10 () Int (ite s9 s0 s1))
+[GOOD] (define-fun s11 () Int (+ s8 s10))
+[GOOD] (define-fun s12 () Int (abs s4))
+[GOOD] (define-fun s13 () Bool (<= s1 s4))
+[GOOD] (define-fun s14 () Int (ite s13 s4 s1))
+[GOOD] (define-fun s15 () Int (+ s12 s14))
+[GOOD] (define-fun s16 () Bool (not s3))
+[GOOD] (define-fun s17 () Bool (> s11 s15))
+[GOOD] (define-fun s18 () Bool (=> s16 s17))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s18))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s11))
+[RECV] ((s11 2))
+[SEND] (get-value (s15))
+[RECV] ((s15 4))
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s5))
+[RECV] ((s5 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease failed for yg @(SBV Integer -> SBV Integer): Falsifiable. Counter-example:
+  arg    = 1 :: Integer
+  before = 2 :: Integer
+  then   = 4 :: Integer
+[MEASURE] Mutual group: measure abs arg1 + smax 0 arg1 failed, trying next
+[MEASURE] Mutual group: trying measure (abs arg1, smax 0 arg1) for all members
+[MEASURE] replayDAG {yf @(SBV Integer -> SBV Integer), yg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (<= s1 s0))
+[GOOD] (define-fun s10 () Int (ite s9 s0 s1))
+[GOOD] (define-fun s11 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s8 s10))
+[GOOD] (define-fun s12 () Int (proj_1_SBVTuple2 s11))
+[GOOD] (define-fun s13 () Bool (>= s12 s1))
+[GOOD] (define-fun s14 () Int (proj_2_SBVTuple2 s11))
+[GOOD] (define-fun s15 () Bool (>= s14 s1))
+[GOOD] (define-fun s16 () Bool (and s13 s15))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s16))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {yf @(SBV Integer -> SBV Integer), yg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (<= s1 s0))
+[GOOD] (define-fun s10 () Int (ite s9 s0 s1))
+[GOOD] (define-fun s11 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s8 s10))
+[GOOD] (define-fun s12 () Int (abs s4))
+[GOOD] (define-fun s13 () Bool (<= s1 s4))
+[GOOD] (define-fun s14 () Int (ite s13 s4 s1))
+[GOOD] (define-fun s15 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s12 s14))
+[GOOD] (define-fun s16 () Bool (not s3))
+[GOOD] (define-fun s17 () Int (proj_1_SBVTuple2 s15))
+[GOOD] (define-fun s18 () Int (proj_1_SBVTuple2 s11))
+[GOOD] (define-fun s19 () Bool (< s17 s18))
+[GOOD] (define-fun s20 () Bool (= s17 s18))
+[GOOD] (define-fun s21 () Int (proj_2_SBVTuple2 s15))
+[GOOD] (define-fun s22 () Int (proj_2_SBVTuple2 s11))
+[GOOD] (define-fun s23 () Bool (< s21 s22))
+[GOOD] (define-fun s24 () Bool (and s20 s23))
+[GOOD] (define-fun s25 () Bool (or s19 s24))
+[GOOD] (define-fun s26 () Bool (=> s16 s25))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s26))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for yf @(SBV Integer -> SBV Integer)
+[MEASURE] replayDAG {yf @(SBV Integer -> SBV Integer), yg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (+ s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (<= s1 s0))
+[GOOD] (define-fun s10 () Int (ite s9 s0 s1))
+[GOOD] (define-fun s11 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s8 s10))
+[GOOD] (define-fun s12 () Int (proj_1_SBVTuple2 s11))
+[GOOD] (define-fun s13 () Bool (>= s12 s1))
+[GOOD] (define-fun s14 () Int (proj_2_SBVTuple2 s11))
+[GOOD] (define-fun s15 () Bool (>= s14 s1))
+[GOOD] (define-fun s16 () Bool (and s13 s15))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s16))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {yf @(SBV Integer -> SBV Integer), yg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (+ s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (<= s1 s0))
+[GOOD] (define-fun s10 () Int (ite s9 s0 s1))
+[GOOD] (define-fun s11 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s8 s10))
+[GOOD] (define-fun s12 () Int (abs s4))
+[GOOD] (define-fun s13 () Bool (<= s1 s4))
+[GOOD] (define-fun s14 () Int (ite s13 s4 s1))
+[GOOD] (define-fun s15 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s12 s14))
+[GOOD] (define-fun s16 () Bool (not s3))
+[GOOD] (define-fun s17 () Int (proj_1_SBVTuple2 s15))
+[GOOD] (define-fun s18 () Int (proj_1_SBVTuple2 s11))
+[GOOD] (define-fun s19 () Bool (< s17 s18))
+[GOOD] (define-fun s20 () Bool (= s17 s18))
+[GOOD] (define-fun s21 () Int (proj_2_SBVTuple2 s15))
+[GOOD] (define-fun s22 () Int (proj_2_SBVTuple2 s11))
+[GOOD] (define-fun s23 () Bool (< s21 s22))
+[GOOD] (define-fun s24 () Bool (and s20 s23))
+[GOOD] (define-fun s25 () Bool (or s19 s24))
+[GOOD] (define-fun s26 () Bool (=> s16 s25))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s26))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s11))
+[RECV] ((s11 (mkSBVTuple2 1 1)))
+[SEND] (get-value (s15))
+[RECV] ((s15 (mkSBVTuple2 2 2)))
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s5))
+[RECV] ((s5 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease failed for yg @(SBV Integer -> SBV Integer): Falsifiable. Counter-example:
+  arg    =     1 :: Integer
+  before = (1,1) :: (Integer, Integer)
+  then   = (2,2) :: (Integer, Integer)
+[MEASURE] Mutual group: measure (abs arg1, smax 0 arg1) failed, trying next
+[MEASURE] Mutual group: trying measure (smax 0 arg1, abs arg1) for all members
+[MEASURE] replayDAG {yf @(SBV Integer -> SBV Integer), yg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Bool (<= s1 s0))
+[GOOD] (define-fun s9 () Int (ite s8 s0 s1))
+[GOOD] (define-fun s10 () Int (abs s0))
+[GOOD] (define-fun s11 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s9 s10))
+[GOOD] (define-fun s12 () Int (proj_1_SBVTuple2 s11))
+[GOOD] (define-fun s13 () Bool (>= s12 s1))
+[GOOD] (define-fun s14 () Int (proj_2_SBVTuple2 s11))
+[GOOD] (define-fun s15 () Bool (>= s14 s1))
+[GOOD] (define-fun s16 () Bool (and s13 s15))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s16))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {yf @(SBV Integer -> SBV Integer), yg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Bool (<= s1 s0))
+[GOOD] (define-fun s9 () Int (ite s8 s0 s1))
+[GOOD] (define-fun s10 () Int (abs s0))
+[GOOD] (define-fun s11 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s9 s10))
+[GOOD] (define-fun s12 () Bool (<= s1 s4))
+[GOOD] (define-fun s13 () Int (ite s12 s4 s1))
+[GOOD] (define-fun s14 () Int (abs s4))
+[GOOD] (define-fun s15 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s13 s14))
+[GOOD] (define-fun s16 () Bool (not s3))
+[GOOD] (define-fun s17 () Int (proj_1_SBVTuple2 s15))
+[GOOD] (define-fun s18 () Int (proj_1_SBVTuple2 s11))
+[GOOD] (define-fun s19 () Bool (< s17 s18))
+[GOOD] (define-fun s20 () Bool (= s17 s18))
+[GOOD] (define-fun s21 () Int (proj_2_SBVTuple2 s15))
+[GOOD] (define-fun s22 () Int (proj_2_SBVTuple2 s11))
+[GOOD] (define-fun s23 () Bool (< s21 s22))
+[GOOD] (define-fun s24 () Bool (and s20 s23))
+[GOOD] (define-fun s25 () Bool (or s19 s24))
+[GOOD] (define-fun s26 () Bool (=> s16 s25))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s26))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for yf @(SBV Integer -> SBV Integer)
+[MEASURE] replayDAG {yf @(SBV Integer -> SBV Integer), yg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (+ s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Bool (<= s1 s0))
+[GOOD] (define-fun s9 () Int (ite s8 s0 s1))
+[GOOD] (define-fun s10 () Int (abs s0))
+[GOOD] (define-fun s11 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s9 s10))
+[GOOD] (define-fun s12 () Int (proj_1_SBVTuple2 s11))
+[GOOD] (define-fun s13 () Bool (>= s12 s1))
+[GOOD] (define-fun s14 () Int (proj_2_SBVTuple2 s11))
+[GOOD] (define-fun s15 () Bool (>= s14 s1))
+[GOOD] (define-fun s16 () Bool (and s13 s15))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s16))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {yf @(SBV Integer -> SBV Integer), yg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (+ s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Bool (<= s1 s0))
+[GOOD] (define-fun s9 () Int (ite s8 s0 s1))
+[GOOD] (define-fun s10 () Int (abs s0))
+[GOOD] (define-fun s11 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s9 s10))
+[GOOD] (define-fun s12 () Bool (<= s1 s4))
+[GOOD] (define-fun s13 () Int (ite s12 s4 s1))
+[GOOD] (define-fun s14 () Int (abs s4))
+[GOOD] (define-fun s15 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s13 s14))
+[GOOD] (define-fun s16 () Bool (not s3))
+[GOOD] (define-fun s17 () Int (proj_1_SBVTuple2 s15))
+[GOOD] (define-fun s18 () Int (proj_1_SBVTuple2 s11))
+[GOOD] (define-fun s19 () Bool (< s17 s18))
+[GOOD] (define-fun s20 () Bool (= s17 s18))
+[GOOD] (define-fun s21 () Int (proj_2_SBVTuple2 s15))
+[GOOD] (define-fun s22 () Int (proj_2_SBVTuple2 s11))
+[GOOD] (define-fun s23 () Bool (< s21 s22))
+[GOOD] (define-fun s24 () Bool (and s20 s23))
+[GOOD] (define-fun s25 () Bool (or s19 s24))
+[GOOD] (define-fun s26 () Bool (=> s16 s25))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s26))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s11))
+[RECV] ((s11 (mkSBVTuple2 1 1)))
+[SEND] (get-value (s15))
+[RECV] ((s15 (mkSBVTuple2 2 2)))
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s5))
+[RECV] ((s5 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease failed for yg @(SBV Integer -> SBV Integer): Falsifiable. Counter-example:
+  arg    =     1 :: Integer
+  before = (1,1) :: (Integer, Integer)
+  then   = (2,2) :: (Integer, Integer)
+[MEASURE] Mutual group: measure (smax 0 arg1, abs arg1) failed, trying next
+
+EXCEPTION:
+
+*** Data.SBV: Cannot determine a termination measure for mutual recursion group.
+***
+***     yf  :: SBV Integer -> SBV Integer
+***     yg  :: SBV Integer -> SBV Integer
+***
+*** The user-provided measure did not work, and auto-guessing also failed.
+
diff --git a/SBVTestSuite/GoldFiles/recursive17_chainMeasure.gold b/SBVTestSuite/GoldFiles/recursive17_chainMeasure.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/recursive17_chainMeasure.gold
@@ -0,0 +1,299 @@
+[MEASURE] Verifying termination measures for: da @(SBV Integer -> SBV Integer), db @(SBV Integer -> SBV Integer), dc @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: da @(SBV Integer -> SBV Integer)
+[MEASURE] Checking mutual recursion group: {da :: SBV Integer -> SBV Integer, db :: SBV Integer -> SBV Integer, dc :: SBV Integer -> SBV Integer}
+[MEASURE] Mutual group: trying user-provided measure for all members
+[MEASURE] replayDAG {da @(SBV Integer -> SBV Integer), db @(SBV Integer -> SBV Integer), dc @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (>= s8 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s9))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {da @(SBV Integer -> SBV Integer), db @(SBV Integer -> SBV Integer), dc @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Int (abs s4))
+[GOOD] (define-fun s10 () Bool (not s3))
+[GOOD] (define-fun s11 () Bool (> s8 s9))
+[GOOD] (define-fun s12 () Bool (=> s10 s11))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for da @(SBV Integer -> SBV Integer)
+[MEASURE] replayDAG {da @(SBV Integer -> SBV Integer), db @(SBV Integer -> SBV Integer), dc @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (>= s8 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s9))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {da @(SBV Integer -> SBV Integer), db @(SBV Integer -> SBV Integer), dc @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Int (abs s4))
+[GOOD] (define-fun s10 () Bool (not s3))
+[GOOD] (define-fun s11 () Bool (> s8 s9))
+[GOOD] (define-fun s12 () Bool (=> s10 s11))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for db @(SBV Integer -> SBV Integer)
+[MEASURE] replayDAG {da @(SBV Integer -> SBV Integer), db @(SBV Integer -> SBV Integer), dc @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (>= s8 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s9))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {da @(SBV Integer -> SBV Integer), db @(SBV Integer -> SBV Integer), dc @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Int (abs s4))
+[GOOD] (define-fun s10 () Bool (not s3))
+[GOOD] (define-fun s11 () Bool (> s8 s9))
+[GOOD] (define-fun s12 () Bool (=> s10 s11))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for dc @(SBV Integer -> SBV Integer)
+[MEASURE] Mutual group: user-provided measure works for all members
+[MEASURE] Passed (terminating): da @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: db @(SBV Integer -> SBV Integer)
+[MEASURE] db @(SBV Integer -> SBV Integer): mutual group already verified, skipping
+[MEASURE] Passed (terminating): db @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: dc @(SBV Integer -> SBV Integer)
+[MEASURE] dc @(SBV Integer -> SBV Integer): mutual group already verified, skipping
+[MEASURE] Passed (terminating): dc @(SBV Integer -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |da @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger, |db @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger, |dc @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger
+[GOOD] (define-funs-rec
+         ((|da @(SBV Integer -> SBV Integer)| ((l1_s0 Int)) Int)
+          (|db @(SBV Integer -> SBV Integer)| ((l2_s0 Int)) Int)
+          (|dc @(SBV Integer -> SBV Integer)| ((l3_s0 Int)) Int))
+         (; Definition of: |da @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |db @(SBV Integer -> SBV Integer)|]
+                                  (let ((l1_s1 0))
+                                  (let ((l1_s3 1))
+                                  (let ((l1_s2 (<= l1_s0 l1_s1)))
+                                  (let ((l1_s4 (- l1_s0 l1_s3)))
+                                  (let ((l1_s5 (|db @(SBV Integer -> SBV Integer)| l1_s4)))
+                                  (let ((l1_s6 (+ l1_s3 l1_s5)))
+                                  (let ((l1_s7 (ite l1_s2 l1_s1 l1_s6)))
+                                  l1_s7)))))))
+          ; Definition of: |db @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |dc @(SBV Integer -> SBV Integer)|]
+                                                  (let ((l2_s1 0))
+                                                  (let ((l2_s3 1))
+                                                  (let ((l2_s2 (<= l2_s0 l2_s1)))
+                                                  (let ((l2_s4 (- l2_s0 l2_s3)))
+                                                  (let ((l2_s5 (|dc @(SBV Integer -> SBV Integer)| l2_s4)))
+                                                  (let ((l2_s6 (+ l2_s3 l2_s5)))
+                                                  (let ((l2_s7 (ite l2_s2 l2_s1 l2_s6)))
+                                                  l2_s7)))))))
+          ; Definition of: |dc @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |da @(SBV Integer -> SBV Integer)|]
+                                                                  (let ((l3_s1 0))
+                                                                  (let ((l3_s3 1))
+                                                                  (let ((l3_s2 (<= l3_s0 l3_s1)))
+                                                                  (let ((l3_s4 (- l3_s0 l3_s3)))
+                                                                  (let ((l3_s5 (|da @(SBV Integer -> SBV Integer)| l3_s4)))
+                                                                  (let ((l3_s6 (+ l3_s3 l3_s5)))
+                                                                  (let ((l3_s7 (ite l3_s2 l3_s1 l3_s6)))
+                                                                  l3_s7)))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Int (|da @(SBV Integer -> SBV Integer)| s0))
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+
+RESULT:
+Satisfiable. Model:
+  s0 = 0 :: Integer
diff --git a/SBVTestSuite/GoldFiles/recursive19_selfAndMutual.gold b/SBVTestSuite/GoldFiles/recursive19_selfAndMutual.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/recursive19_selfAndMutual.gold
@@ -0,0 +1,297 @@
+[MEASURE] Verifying termination measures for: sf @(SBV Integer -> SBV Integer), sf @(SBV Integer -> SBV Integer), sg @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: sf @(SBV Integer -> SBV Integer)
+[MEASURE] Checking mutual recursion group: {sf :: SBV Integer -> SBV Integer, sg :: SBV Integer -> SBV Integer}
+[MEASURE] Mutual group: trying measure abs arg1 for all members
+[MEASURE] replayDAG {sf @(SBV Integer -> SBV Integer), sg @(SBV Integer -> SBV Integer)}: replaying 6 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (+ s5 s6))
+[GOOD] (define-fun s8 () Int (ite s3 s1 s7))
+[GOOD] (define-fun s9 () Int (abs s0))
+[GOOD] (define-fun s10 () Bool (>= s9 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s10))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sf @(SBV Integer -> SBV Integer), sg @(SBV Integer -> SBV Integer)}: replaying 6 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (+ s5 s6))
+[GOOD] (define-fun s8 () Int (ite s3 s1 s7))
+[GOOD] (define-fun s9 () Int (abs s0))
+[GOOD] (define-fun s10 () Int (abs s4))
+[GOOD] (define-fun s11 () Bool (not s3))
+[GOOD] (define-fun s12 () Bool (> s9 s10))
+[GOOD] (define-fun s13 () Bool (=> s11 s12))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s13))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for sf @(SBV Integer -> SBV Integer)
+[MEASURE] replayDAG {sf @(SBV Integer -> SBV Integer), sg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (>= s8 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s9))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sf @(SBV Integer -> SBV Integer), sg @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Int (abs s4))
+[GOOD] (define-fun s10 () Bool (not s3))
+[GOOD] (define-fun s11 () Bool (> s8 s9))
+[GOOD] (define-fun s12 () Bool (=> s10 s11))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for sg @(SBV Integer -> SBV Integer)
+[MEASURE] Mutual group: measure abs arg1 works for all members
+[MEASURE] Passed (terminating): sf @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: sf @(SBV Integer -> SBV Integer)
+[MEASURE] sf @(SBV Integer -> SBV Integer): barified = "|sf @(SBV Integer -> SBV Integer)|"
+[MEASURE] sf @(SBV Integer -> SBV Integer): Uninterpreted ops in DAG: [("|sf @(SBV Integer -> SBV Integer)|",1),("|sg @(SBV Integer -> SBV Integer)|",1)]
+[MEASURE] sf @(SBV Integer -> SBV Integer): recursive calls found = 1
+[MEASURE] sf @(SBV Integer -> SBV Integer): trying abs arg1
+[MEASURE] replayDAG {sf @(SBV Integer -> SBV Integer)}: replaying 6 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (+ s5 s6))
+[GOOD] (define-fun s8 () Int (ite s3 s1 s7))
+[GOOD] (define-fun s9 () Int (abs s0))
+[GOOD] (define-fun s10 () Bool (>= s9 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s10))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {sf @(SBV Integer -> SBV Integer)}: replaying 6 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (+ s5 s6))
+[GOOD] (define-fun s8 () Int (ite s3 s1 s7))
+[GOOD] (define-fun s9 () Int (abs s0))
+[GOOD] (define-fun s10 () Int (abs s4))
+[GOOD] (define-fun s11 () Bool (not s3))
+[GOOD] (define-fun s12 () Bool (> s9 s10))
+[GOOD] (define-fun s13 () Bool (=> s11 s12))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s13))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] sf @(SBV Integer -> SBV Integer): abs arg1 -> OK
+[MEASURE] Passed (terminating): sf @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: sg @(SBV Integer -> SBV Integer)
+[MEASURE] sg @(SBV Integer -> SBV Integer): mutual group already verified, skipping
+[MEASURE] Passed (terminating): sg @(SBV Integer -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |sf @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger, |sg @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger
+[GOOD] (define-funs-rec
+         ((|sf @(SBV Integer -> SBV Integer)| ((l1_s0 Int)) Int)
+          (|sg @(SBV Integer -> SBV Integer)| ((l2_s0 Int)) Int))
+         (; Definition of: |sf @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |sf @(SBV Integer -> SBV Integer)|, |sg @(SBV Integer -> SBV Integer)|]
+                                  (let ((l1_s1 0))
+                                  (let ((l1_s3 1))
+                                  (let ((l1_s2 (<= l1_s0 l1_s1)))
+                                  (let ((l1_s4 (- l1_s0 l1_s3)))
+                                  (let ((l1_s5 (|sf @(SBV Integer -> SBV Integer)| l1_s4)))
+                                  (let ((l1_s6 (|sg @(SBV Integer -> SBV Integer)| l1_s4)))
+                                  (let ((l1_s7 (+ l1_s5 l1_s6)))
+                                  (let ((l1_s8 (ite l1_s2 l1_s1 l1_s7)))
+                                  l1_s8))))))))
+          ; Definition of: |sg @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |sf @(SBV Integer -> SBV Integer)|]
+                                                  (let ((l2_s1 0))
+                                                  (let ((l2_s3 1))
+                                                  (let ((l2_s2 (<= l2_s0 l2_s1)))
+                                                  (let ((l2_s4 (- l2_s0 l2_s3)))
+                                                  (let ((l2_s5 (|sf @(SBV Integer -> SBV Integer)| l2_s4)))
+                                                  (let ((l2_s6 (+ l2_s3 l2_s5)))
+                                                  (let ((l2_s7 (ite l2_s2 l2_s1 l2_s6)))
+                                                  l2_s7)))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Int (|sf @(SBV Integer -> SBV Integer)| s0))
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+
+RESULT:
+Satisfiable. Model:
+  s0 = 0 :: Integer
diff --git a/SBVTestSuite/GoldFiles/recursive1_ack.gold b/SBVTestSuite/GoldFiles/recursive1_ack.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/recursive1_ack.gold
@@ -0,0 +1,1003 @@
+[MEASURE] Verifying termination measures for: ack @(SBV Integer -> SBV Integer -> SBV Integer)
+[MEASURE] Checking: ack @(SBV Integer -> SBV Integer -> SBV Integer)
+[MEASURE] ack @(SBV Integer -> SBV Integer -> SBV Integer): barified = "|ack @(SBV Integer -> SBV Integer -> SBV Integer)|"
+[MEASURE] ack @(SBV Integer -> SBV Integer -> SBV Integer): Uninterpreted ops in DAG: [("|ack @(SBV Integer -> SBV Integer -> SBV Integer)|",2),("|ack @(SBV Integer -> SBV Integer -> SBV Integer)|",2),("|ack @(SBV Integer -> SBV Integer -> SBV Integer)|",2)]
+[MEASURE] ack @(SBV Integer -> SBV Integer -> SBV Integer): recursive calls found = 3
+[MEASURE] ack @(SBV Integer -> SBV Integer -> SBV Integer): trying abs arg1
+[MEASURE] replayDAG {ack @(SBV Integer -> SBV Integer -> SBV Integer)}: replaying 10 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () Int) ; tracks user variable "arg1"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] (declare-fun s10 () Int) ; tracks user variable "__internal_sbv_s10"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s2))
+[GOOD] (define-fun s5 () Int (+ s1 s3))
+[GOOD] (define-fun s6 () Bool (<= s1 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (- s1 s3))
+[GOOD] (define-fun s12 () Int (ite s6 s8 s11))
+[GOOD] (define-fun s13 () Int (ite s4 s5 s12))
+[GOOD] (define-fun s14 () Int (abs s0))
+[GOOD] (define-fun s15 () Bool (>= s14 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s15))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {ack @(SBV Integer -> SBV Integer -> SBV Integer)}: replaying 10 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () Int) ; tracks user variable "arg1"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] (declare-fun s10 () Int) ; tracks user variable "__internal_sbv_s10"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s2))
+[GOOD] (define-fun s5 () Int (+ s1 s3))
+[GOOD] (define-fun s6 () Bool (<= s1 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (- s1 s3))
+[GOOD] (define-fun s12 () Int (ite s6 s8 s11))
+[GOOD] (define-fun s13 () Int (ite s4 s5 s12))
+[GOOD] (define-fun s14 () Int (abs s0))
+[GOOD] (define-fun s15 () Int (abs s7))
+[GOOD] (define-fun s16 () Bool (not s4))
+[GOOD] (define-fun s17 () Bool (and s6 s16))
+[GOOD] (define-fun s18 () Bool (> s14 s15))
+[GOOD] (define-fun s19 () Bool (=> s17 s18))
+[GOOD] (define-fun s20 () Bool (not s6))
+[GOOD] (define-fun s21 () Bool (and s16 s20))
+[GOOD] (define-fun s22 () Bool (=> s21 false))
+[GOOD] (define-fun s23 () Bool (=> s21 s18))
+[GOOD] (define-fun s24 () Bool (and s22 s23))
+[GOOD] (define-fun s25 () Bool (and s19 s24))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s25))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s14))
+[RECV] ((s14 2))
+[SEND] (get-value (s15))
+[RECV] ((s15 1))
+[SEND] (get-value (s14))
+[RECV] ((s14 2))
+[SEND] (get-value (s15))
+[RECV] ((s15 1))
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s8))
+[RECV] ((s8 0))
+[SEND] (get-value (s10))
+[RECV] ((s10 0))
+[SEND] (get-value (s11))
+[RECV] ((s11 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] ack @(SBV Integer -> SBV Integer -> SBV Integer): abs arg1 failed strict decrease: Falsifiable. Counter-example:
+  arg0    = 2 :: Integer
+  arg1    = 1 :: Integer
+  before  = 2 :: Integer
+  then[1] = 1 :: Integer
+  then[2] = 2 :: Integer
+  then[3] = 1 :: Integer
+[MEASURE] ack @(SBV Integer -> SBV Integer -> SBV Integer): trying next candidate..
+[MEASURE] ack @(SBV Integer -> SBV Integer -> SBV Integer): trying smax 0 arg1
+[MEASURE] replayDAG {ack @(SBV Integer -> SBV Integer -> SBV Integer)}: replaying 10 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () Int) ; tracks user variable "arg1"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] (declare-fun s10 () Int) ; tracks user variable "__internal_sbv_s10"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s2))
+[GOOD] (define-fun s5 () Int (+ s1 s3))
+[GOOD] (define-fun s6 () Bool (<= s1 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (- s1 s3))
+[GOOD] (define-fun s12 () Int (ite s6 s8 s11))
+[GOOD] (define-fun s13 () Int (ite s4 s5 s12))
+[GOOD] (define-fun s14 () Bool (<= s2 s0))
+[GOOD] (define-fun s15 () Int (ite s14 s0 s2))
+[GOOD] (define-fun s16 () Bool (>= s15 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s16))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {ack @(SBV Integer -> SBV Integer -> SBV Integer)}: replaying 10 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () Int) ; tracks user variable "arg1"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] (declare-fun s10 () Int) ; tracks user variable "__internal_sbv_s10"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s2))
+[GOOD] (define-fun s5 () Int (+ s1 s3))
+[GOOD] (define-fun s6 () Bool (<= s1 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (- s1 s3))
+[GOOD] (define-fun s12 () Int (ite s6 s8 s11))
+[GOOD] (define-fun s13 () Int (ite s4 s5 s12))
+[GOOD] (define-fun s14 () Bool (<= s2 s0))
+[GOOD] (define-fun s15 () Int (ite s14 s0 s2))
+[GOOD] (define-fun s16 () Bool (<= s2 s7))
+[GOOD] (define-fun s17 () Int (ite s16 s7 s2))
+[GOOD] (define-fun s18 () Bool (not s4))
+[GOOD] (define-fun s19 () Bool (and s6 s18))
+[GOOD] (define-fun s20 () Bool (> s15 s17))
+[GOOD] (define-fun s21 () Bool (=> s19 s20))
+[GOOD] (define-fun s22 () Bool (not s6))
+[GOOD] (define-fun s23 () Bool (and s18 s22))
+[GOOD] (define-fun s24 () Bool (=> s23 false))
+[GOOD] (define-fun s25 () Bool (=> s23 s20))
+[GOOD] (define-fun s26 () Bool (and s24 s25))
+[GOOD] (define-fun s27 () Bool (and s21 s26))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s27))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s15))
+[RECV] ((s15 2))
+[SEND] (get-value (s17))
+[RECV] ((s17 1))
+[SEND] (get-value (s15))
+[RECV] ((s15 2))
+[SEND] (get-value (s17))
+[RECV] ((s17 1))
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s8))
+[RECV] ((s8 0))
+[SEND] (get-value (s10))
+[RECV] ((s10 0))
+[SEND] (get-value (s11))
+[RECV] ((s11 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] ack @(SBV Integer -> SBV Integer -> SBV Integer): smax 0 arg1 failed strict decrease: Falsifiable. Counter-example:
+  arg0    = 2 :: Integer
+  arg1    = 1 :: Integer
+  before  = 2 :: Integer
+  then[1] = 1 :: Integer
+  then[2] = 2 :: Integer
+  then[3] = 1 :: Integer
+[MEASURE] ack @(SBV Integer -> SBV Integer -> SBV Integer): trying next candidate..
+[MEASURE] ack @(SBV Integer -> SBV Integer -> SBV Integer): trying abs arg2
+[MEASURE] replayDAG {ack @(SBV Integer -> SBV Integer -> SBV Integer)}: replaying 10 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () Int) ; tracks user variable "arg1"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] (declare-fun s10 () Int) ; tracks user variable "__internal_sbv_s10"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s2))
+[GOOD] (define-fun s5 () Int (+ s1 s3))
+[GOOD] (define-fun s6 () Bool (<= s1 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (- s1 s3))
+[GOOD] (define-fun s12 () Int (ite s6 s8 s11))
+[GOOD] (define-fun s13 () Int (ite s4 s5 s12))
+[GOOD] (define-fun s14 () Int (abs s1))
+[GOOD] (define-fun s15 () Bool (>= s14 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s15))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {ack @(SBV Integer -> SBV Integer -> SBV Integer)}: replaying 10 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () Int) ; tracks user variable "arg1"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] (declare-fun s10 () Int) ; tracks user variable "__internal_sbv_s10"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s2))
+[GOOD] (define-fun s5 () Int (+ s1 s3))
+[GOOD] (define-fun s6 () Bool (<= s1 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (- s1 s3))
+[GOOD] (define-fun s12 () Int (ite s6 s8 s11))
+[GOOD] (define-fun s13 () Int (ite s4 s5 s12))
+[GOOD] (define-fun s14 () Int (abs s1))
+[GOOD] (define-fun s15 () Int (abs s3))
+[GOOD] (define-fun s16 () Int (abs s9))
+[GOOD] (define-fun s17 () Int (abs s10))
+[GOOD] (define-fun s18 () Bool (not s4))
+[GOOD] (define-fun s19 () Bool (and s6 s18))
+[GOOD] (define-fun s20 () Bool (> s14 s15))
+[GOOD] (define-fun s21 () Bool (=> s19 s20))
+[GOOD] (define-fun s22 () Bool (not s6))
+[GOOD] (define-fun s23 () Bool (and s18 s22))
+[GOOD] (define-fun s24 () Bool (> s14 s16))
+[GOOD] (define-fun s25 () Bool (=> s23 s24))
+[GOOD] (define-fun s26 () Bool (> s14 s17))
+[GOOD] (define-fun s27 () Bool (=> s23 s26))
+[GOOD] (define-fun s28 () Bool (and s25 s27))
+[GOOD] (define-fun s29 () Bool (and s21 s28))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s29))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s14))
+[RECV] ((s14 1))
+[SEND] (get-value (s15))
+[RECV] ((s15 1))
+[SEND] (get-value (s16))
+[RECV] ((s16 2))
+[SEND] (get-value (s17))
+[RECV] ((s17 1))
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 (- 1)))
+[SEND] (get-value (s8))
+[RECV] ((s8 0))
+[SEND] (get-value (s10))
+[RECV] ((s10 (- 1)))
+[SEND] (get-value (s11))
+[RECV] ((s11 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] ack @(SBV Integer -> SBV Integer -> SBV Integer): abs arg2 failed strict decrease: Falsifiable. Counter-example:
+  arg0    =  1 :: Integer
+  arg1    = -1 :: Integer
+  before  =  1 :: Integer
+  then[1] =  1 :: Integer
+  then[2] =  2 :: Integer
+  then[3] =  1 :: Integer
+[MEASURE] ack @(SBV Integer -> SBV Integer -> SBV Integer): trying next candidate..
+[MEASURE] ack @(SBV Integer -> SBV Integer -> SBV Integer): trying smax 0 arg2
+[MEASURE] replayDAG {ack @(SBV Integer -> SBV Integer -> SBV Integer)}: replaying 10 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () Int) ; tracks user variable "arg1"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] (declare-fun s10 () Int) ; tracks user variable "__internal_sbv_s10"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s2))
+[GOOD] (define-fun s5 () Int (+ s1 s3))
+[GOOD] (define-fun s6 () Bool (<= s1 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (- s1 s3))
+[GOOD] (define-fun s12 () Int (ite s6 s8 s11))
+[GOOD] (define-fun s13 () Int (ite s4 s5 s12))
+[GOOD] (define-fun s14 () Bool (<= s2 s1))
+[GOOD] (define-fun s15 () Int (ite s14 s1 s2))
+[GOOD] (define-fun s16 () Bool (>= s15 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s16))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {ack @(SBV Integer -> SBV Integer -> SBV Integer)}: replaying 10 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () Int) ; tracks user variable "arg1"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] (declare-fun s10 () Int) ; tracks user variable "__internal_sbv_s10"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s2))
+[GOOD] (define-fun s5 () Int (+ s1 s3))
+[GOOD] (define-fun s6 () Bool (<= s1 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (- s1 s3))
+[GOOD] (define-fun s12 () Int (ite s6 s8 s11))
+[GOOD] (define-fun s13 () Int (ite s4 s5 s12))
+[GOOD] (define-fun s14 () Bool (<= s2 s1))
+[GOOD] (define-fun s15 () Int (ite s14 s1 s2))
+[GOOD] (define-fun s16 () Bool (<= s2 s3))
+[GOOD] (define-fun s17 () Int (ite s16 s3 s2))
+[GOOD] (define-fun s18 () Bool (<= s2 s9))
+[GOOD] (define-fun s19 () Int (ite s18 s9 s2))
+[GOOD] (define-fun s20 () Bool (<= s2 s10))
+[GOOD] (define-fun s21 () Int (ite s20 s10 s2))
+[GOOD] (define-fun s22 () Bool (not s4))
+[GOOD] (define-fun s23 () Bool (and s6 s22))
+[GOOD] (define-fun s24 () Bool (> s15 s17))
+[GOOD] (define-fun s25 () Bool (=> s23 s24))
+[GOOD] (define-fun s26 () Bool (not s6))
+[GOOD] (define-fun s27 () Bool (and s22 s26))
+[GOOD] (define-fun s28 () Bool (> s15 s19))
+[GOOD] (define-fun s29 () Bool (=> s27 s28))
+[GOOD] (define-fun s30 () Bool (> s15 s21))
+[GOOD] (define-fun s31 () Bool (=> s27 s30))
+[GOOD] (define-fun s32 () Bool (and s29 s31))
+[GOOD] (define-fun s33 () Bool (and s25 s32))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s33))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s15))
+[RECV] ((s15 2))
+[SEND] (get-value (s17))
+[RECV] ((s17 1))
+[SEND] (get-value (s19))
+[RECV] ((s19 1))
+[SEND] (get-value (s21))
+[RECV] ((s21 2))
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s8))
+[RECV] ((s8 0))
+[SEND] (get-value (s10))
+[RECV] ((s10 2))
+[SEND] (get-value (s11))
+[RECV] ((s11 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] ack @(SBV Integer -> SBV Integer -> SBV Integer): smax 0 arg2 failed strict decrease: Falsifiable. Counter-example:
+  arg0    = 1 :: Integer
+  arg1    = 2 :: Integer
+  before  = 2 :: Integer
+  then[1] = 1 :: Integer
+  then[2] = 1 :: Integer
+  then[3] = 2 :: Integer
+[MEASURE] ack @(SBV Integer -> SBV Integer -> SBV Integer): trying next candidate..
+[MEASURE] ack @(SBV Integer -> SBV Integer -> SBV Integer): trying abs arg1 + smax 0 arg1 + abs arg2 + smax 0 arg2
+[MEASURE] replayDAG {ack @(SBV Integer -> SBV Integer -> SBV Integer)}: replaying 10 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () Int) ; tracks user variable "arg1"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] (declare-fun s10 () Int) ; tracks user variable "__internal_sbv_s10"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s2))
+[GOOD] (define-fun s5 () Int (+ s1 s3))
+[GOOD] (define-fun s6 () Bool (<= s1 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (- s1 s3))
+[GOOD] (define-fun s12 () Int (ite s6 s8 s11))
+[GOOD] (define-fun s13 () Int (ite s4 s5 s12))
+[GOOD] (define-fun s14 () Int (abs s0))
+[GOOD] (define-fun s15 () Bool (<= s2 s0))
+[GOOD] (define-fun s16 () Int (ite s15 s0 s2))
+[GOOD] (define-fun s17 () Int (+ s14 s16))
+[GOOD] (define-fun s18 () Int (abs s1))
+[GOOD] (define-fun s19 () Int (+ s17 s18))
+[GOOD] (define-fun s20 () Bool (<= s2 s1))
+[GOOD] (define-fun s21 () Int (ite s20 s1 s2))
+[GOOD] (define-fun s22 () Int (+ s19 s21))
+[GOOD] (define-fun s23 () Bool (>= s22 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s23))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {ack @(SBV Integer -> SBV Integer -> SBV Integer)}: replaying 10 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () Int) ; tracks user variable "arg1"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] (declare-fun s10 () Int) ; tracks user variable "__internal_sbv_s10"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s2))
+[GOOD] (define-fun s5 () Int (+ s1 s3))
+[GOOD] (define-fun s6 () Bool (<= s1 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (- s1 s3))
+[GOOD] (define-fun s12 () Int (ite s6 s8 s11))
+[GOOD] (define-fun s13 () Int (ite s4 s5 s12))
+[GOOD] (define-fun s14 () Int (abs s0))
+[GOOD] (define-fun s15 () Bool (<= s2 s0))
+[GOOD] (define-fun s16 () Int (ite s15 s0 s2))
+[GOOD] (define-fun s17 () Int (+ s14 s16))
+[GOOD] (define-fun s18 () Int (abs s1))
+[GOOD] (define-fun s19 () Int (+ s17 s18))
+[GOOD] (define-fun s20 () Bool (<= s2 s1))
+[GOOD] (define-fun s21 () Int (ite s20 s1 s2))
+[GOOD] (define-fun s22 () Int (+ s19 s21))
+[GOOD] (define-fun s23 () Int (abs s7))
+[GOOD] (define-fun s24 () Bool (<= s2 s7))
+[GOOD] (define-fun s25 () Int (ite s24 s7 s2))
+[GOOD] (define-fun s26 () Int (+ s23 s25))
+[GOOD] (define-fun s27 () Int (abs s3))
+[GOOD] (define-fun s28 () Int (+ s26 s27))
+[GOOD] (define-fun s29 () Bool (<= s2 s3))
+[GOOD] (define-fun s30 () Int (ite s29 s3 s2))
+[GOOD] (define-fun s31 () Int (+ s28 s30))
+[GOOD] (define-fun s32 () Int (abs s9))
+[GOOD] (define-fun s33 () Int (+ s17 s32))
+[GOOD] (define-fun s34 () Bool (<= s2 s9))
+[GOOD] (define-fun s35 () Int (ite s34 s9 s2))
+[GOOD] (define-fun s36 () Int (+ s33 s35))
+[GOOD] (define-fun s37 () Int (abs s10))
+[GOOD] (define-fun s38 () Int (+ s26 s37))
+[GOOD] (define-fun s39 () Bool (<= s2 s10))
+[GOOD] (define-fun s40 () Int (ite s39 s10 s2))
+[GOOD] (define-fun s41 () Int (+ s38 s40))
+[GOOD] (define-fun s42 () Bool (not s4))
+[GOOD] (define-fun s43 () Bool (and s6 s42))
+[GOOD] (define-fun s44 () Bool (> s22 s31))
+[GOOD] (define-fun s45 () Bool (=> s43 s44))
+[GOOD] (define-fun s46 () Bool (not s6))
+[GOOD] (define-fun s47 () Bool (and s42 s46))
+[GOOD] (define-fun s48 () Bool (> s22 s36))
+[GOOD] (define-fun s49 () Bool (=> s47 s48))
+[GOOD] (define-fun s50 () Bool (> s22 s41))
+[GOOD] (define-fun s51 () Bool (=> s47 s50))
+[GOOD] (define-fun s52 () Bool (and s49 s51))
+[GOOD] (define-fun s53 () Bool (and s45 s52))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s53))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s22))
+[RECV] ((s22 8))
+[SEND] (get-value (s31))
+[RECV] ((s31 4))
+[SEND] (get-value (s36))
+[RECV] ((s36 6))
+[SEND] (get-value (s41))
+[RECV] ((s41 8))
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 2))
+[SEND] (get-value (s8))
+[RECV] ((s8 0))
+[SEND] (get-value (s10))
+[RECV] ((s10 (- 6)))
+[SEND] (get-value (s11))
+[RECV] ((s11 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] ack @(SBV Integer -> SBV Integer -> SBV Integer): abs arg1 + smax 0 arg1 + abs arg2 + smax 0 arg2 failed strict decrease: Falsifiable. Counter-example:
+  arg0    = 2 :: Integer
+  arg1    = 2 :: Integer
+  before  = 8 :: Integer
+  then[1] = 4 :: Integer
+  then[2] = 6 :: Integer
+  then[3] = 8 :: Integer
+[MEASURE] ack @(SBV Integer -> SBV Integer -> SBV Integer): trying next candidate..
+[MEASURE] ack @(SBV Integer -> SBV Integer -> SBV Integer): trying (abs arg1, smax 0 arg1)
+[MEASURE] replayDAG {ack @(SBV Integer -> SBV Integer -> SBV Integer)}: replaying 10 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () Int) ; tracks user variable "arg1"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] (declare-fun s10 () Int) ; tracks user variable "__internal_sbv_s10"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s2))
+[GOOD] (define-fun s5 () Int (+ s1 s3))
+[GOOD] (define-fun s6 () Bool (<= s1 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (- s1 s3))
+[GOOD] (define-fun s12 () Int (ite s6 s8 s11))
+[GOOD] (define-fun s13 () Int (ite s4 s5 s12))
+[GOOD] (define-fun s14 () Int (abs s0))
+[GOOD] (define-fun s15 () Bool (<= s2 s0))
+[GOOD] (define-fun s16 () Int (ite s15 s0 s2))
+[GOOD] (define-fun s17 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s14 s16))
+[GOOD] (define-fun s18 () Int (proj_1_SBVTuple2 s17))
+[GOOD] (define-fun s19 () Bool (>= s18 s2))
+[GOOD] (define-fun s20 () Int (proj_2_SBVTuple2 s17))
+[GOOD] (define-fun s21 () Bool (>= s20 s2))
+[GOOD] (define-fun s22 () Bool (and s19 s21))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s22))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {ack @(SBV Integer -> SBV Integer -> SBV Integer)}: replaying 10 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () Int) ; tracks user variable "arg1"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] (declare-fun s10 () Int) ; tracks user variable "__internal_sbv_s10"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s2))
+[GOOD] (define-fun s5 () Int (+ s1 s3))
+[GOOD] (define-fun s6 () Bool (<= s1 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (- s1 s3))
+[GOOD] (define-fun s12 () Int (ite s6 s8 s11))
+[GOOD] (define-fun s13 () Int (ite s4 s5 s12))
+[GOOD] (define-fun s14 () Int (abs s0))
+[GOOD] (define-fun s15 () Bool (<= s2 s0))
+[GOOD] (define-fun s16 () Int (ite s15 s0 s2))
+[GOOD] (define-fun s17 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s14 s16))
+[GOOD] (define-fun s18 () Int (abs s7))
+[GOOD] (define-fun s19 () Bool (<= s2 s7))
+[GOOD] (define-fun s20 () Int (ite s19 s7 s2))
+[GOOD] (define-fun s21 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s18 s20))
+[GOOD] (define-fun s22 () Bool (not s4))
+[GOOD] (define-fun s23 () Bool (and s6 s22))
+[GOOD] (define-fun s24 () Int (proj_1_SBVTuple2 s21))
+[GOOD] (define-fun s25 () Int (proj_1_SBVTuple2 s17))
+[GOOD] (define-fun s26 () Bool (< s24 s25))
+[GOOD] (define-fun s27 () Bool (= s24 s25))
+[GOOD] (define-fun s28 () Int (proj_2_SBVTuple2 s21))
+[GOOD] (define-fun s29 () Int (proj_2_SBVTuple2 s17))
+[GOOD] (define-fun s30 () Bool (< s28 s29))
+[GOOD] (define-fun s31 () Bool (and s27 s30))
+[GOOD] (define-fun s32 () Bool (or s26 s31))
+[GOOD] (define-fun s33 () Bool (=> s23 s32))
+[GOOD] (define-fun s34 () Bool (not s6))
+[GOOD] (define-fun s35 () Bool (and s22 s34))
+[GOOD] (define-fun s36 () Bool (=> s35 false))
+[GOOD] (define-fun s37 () Bool (=> s35 s32))
+[GOOD] (define-fun s38 () Bool (and s36 s37))
+[GOOD] (define-fun s39 () Bool (and s33 s38))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s39))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s17))
+[RECV] ((s17 (mkSBVTuple2 2 2)))
+[SEND] (get-value (s21))
+[RECV] ((s21 (mkSBVTuple2 1 1)))
+[SEND] (get-value (s17))
+[RECV] ((s17 (mkSBVTuple2 2 2)))
+[SEND] (get-value (s21))
+[RECV] ((s21 (mkSBVTuple2 1 1)))
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s1))
+[RECV] ((s1 1))
+[SEND] (get-value (s8))
+[RECV] ((s8 0))
+[SEND] (get-value (s10))
+[RECV] ((s10 0))
+[SEND] (get-value (s11))
+[RECV] ((s11 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] ack @(SBV Integer -> SBV Integer -> SBV Integer): (abs arg1, smax 0 arg1) failed strict decrease: Falsifiable. Counter-example:
+  arg0    =     2 :: Integer
+  arg1    =     1 :: Integer
+  before  = (2,2) :: (Integer, Integer)
+  then[1] = (1,1) :: (Integer, Integer)
+  then[2] = (2,2) :: (Integer, Integer)
+  then[3] = (1,1) :: (Integer, Integer)
+[MEASURE] ack @(SBV Integer -> SBV Integer -> SBV Integer): trying next candidate..
+[MEASURE] ack @(SBV Integer -> SBV Integer -> SBV Integer): trying (abs arg1, abs arg2)
+[MEASURE] replayDAG {ack @(SBV Integer -> SBV Integer -> SBV Integer)}: replaying 10 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () Int) ; tracks user variable "arg1"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] (declare-fun s10 () Int) ; tracks user variable "__internal_sbv_s10"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s2))
+[GOOD] (define-fun s5 () Int (+ s1 s3))
+[GOOD] (define-fun s6 () Bool (<= s1 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (- s1 s3))
+[GOOD] (define-fun s12 () Int (ite s6 s8 s11))
+[GOOD] (define-fun s13 () Int (ite s4 s5 s12))
+[GOOD] (define-fun s14 () Int (abs s0))
+[GOOD] (define-fun s15 () Int (abs s1))
+[GOOD] (define-fun s16 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s14 s15))
+[GOOD] (define-fun s17 () Int (proj_1_SBVTuple2 s16))
+[GOOD] (define-fun s18 () Bool (>= s17 s2))
+[GOOD] (define-fun s19 () Int (proj_2_SBVTuple2 s16))
+[GOOD] (define-fun s20 () Bool (>= s19 s2))
+[GOOD] (define-fun s21 () Bool (and s18 s20))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {ack @(SBV Integer -> SBV Integer -> SBV Integer)}: replaying 10 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () Int) ; tracks user variable "arg1"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] (declare-fun s10 () Int) ; tracks user variable "__internal_sbv_s10"
+[GOOD] (declare-fun s11 () Int) ; tracks user variable "__internal_sbv_s11"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (<= s0 s2))
+[GOOD] (define-fun s5 () Int (+ s1 s3))
+[GOOD] (define-fun s6 () Bool (<= s1 s2))
+[GOOD] (define-fun s7 () Int (- s0 s3))
+[GOOD] (define-fun s9 () Int (- s1 s3))
+[GOOD] (define-fun s12 () Int (ite s6 s8 s11))
+[GOOD] (define-fun s13 () Int (ite s4 s5 s12))
+[GOOD] (define-fun s14 () Int (abs s0))
+[GOOD] (define-fun s15 () Int (abs s1))
+[GOOD] (define-fun s16 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s14 s15))
+[GOOD] (define-fun s17 () Int (abs s7))
+[GOOD] (define-fun s18 () Int (abs s3))
+[GOOD] (define-fun s19 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s17 s18))
+[GOOD] (define-fun s20 () Int (abs s9))
+[GOOD] (define-fun s21 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s14 s20))
+[GOOD] (define-fun s22 () Int (abs s10))
+[GOOD] (define-fun s23 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s17 s22))
+[GOOD] (define-fun s24 () Bool (not s4))
+[GOOD] (define-fun s25 () Bool (and s6 s24))
+[GOOD] (define-fun s26 () Int (proj_1_SBVTuple2 s19))
+[GOOD] (define-fun s27 () Int (proj_1_SBVTuple2 s16))
+[GOOD] (define-fun s28 () Bool (< s26 s27))
+[GOOD] (define-fun s29 () Bool (= s26 s27))
+[GOOD] (define-fun s30 () Int (proj_2_SBVTuple2 s19))
+[GOOD] (define-fun s31 () Int (proj_2_SBVTuple2 s16))
+[GOOD] (define-fun s32 () Bool (< s30 s31))
+[GOOD] (define-fun s33 () Bool (and s29 s32))
+[GOOD] (define-fun s34 () Bool (or s28 s33))
+[GOOD] (define-fun s35 () Bool (=> s25 s34))
+[GOOD] (define-fun s36 () Bool (not s6))
+[GOOD] (define-fun s37 () Bool (and s24 s36))
+[GOOD] (define-fun s38 () Int (proj_1_SBVTuple2 s21))
+[GOOD] (define-fun s39 () Bool (< s38 s27))
+[GOOD] (define-fun s40 () Bool (= s27 s38))
+[GOOD] (define-fun s41 () Int (proj_2_SBVTuple2 s21))
+[GOOD] (define-fun s42 () Bool (< s41 s31))
+[GOOD] (define-fun s43 () Bool (and s40 s42))
+[GOOD] (define-fun s44 () Bool (or s39 s43))
+[GOOD] (define-fun s45 () Bool (=> s37 s44))
+[GOOD] (define-fun s46 () Int (proj_1_SBVTuple2 s23))
+[GOOD] (define-fun s47 () Bool (< s46 s27))
+[GOOD] (define-fun s48 () Bool (= s27 s46))
+[GOOD] (define-fun s49 () Int (proj_2_SBVTuple2 s23))
+[GOOD] (define-fun s50 () Bool (< s49 s31))
+[GOOD] (define-fun s51 () Bool (and s48 s50))
+[GOOD] (define-fun s52 () Bool (or s47 s51))
+[GOOD] (define-fun s53 () Bool (=> s37 s52))
+[GOOD] (define-fun s54 () Bool (and s45 s53))
+[GOOD] (define-fun s55 () Bool (and s35 s54))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s55))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] ack @(SBV Integer -> SBV Integer -> SBV Integer): (abs arg1, abs arg2) -> OK
+[MEASURE] Passed (terminating): ack @(SBV Integer -> SBV Integer -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 5)
+[GOOD] (define-fun s4 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int)
+[GOOD] (declare-fun s1 () Int)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |ack @(SBV Integer -> SBV Integer -> SBV Integer)| :: SInteger -> SInteger -> SInteger [Recursive]
+[GOOD] (define-fun-rec |ack @(SBV Integer -> SBV Integer -> SBV Integer)| ((l1_s0 Int) (l1_s1 Int)) Int
+                                 (let ((l1_s2 0))
+                                 (let ((l1_s4 1))
+                                 (let ((l1_s3 (<= l1_s0 l1_s2)))
+                                 (let ((l1_s5 (+ l1_s1 l1_s4)))
+                                 (let ((l1_s6 (<= l1_s1 l1_s2)))
+                                 (let ((l1_s7 (- l1_s0 l1_s4)))
+                                 (let ((l1_s8 (|ack @(SBV Integer -> SBV Integer -> SBV Integer)| l1_s7 l1_s4)))
+                                 (let ((l1_s9 (- l1_s1 l1_s4)))
+                                 (let ((l1_s10 (|ack @(SBV Integer -> SBV Integer -> SBV Integer)| l1_s0 l1_s9)))
+                                 (let ((l1_s11 (|ack @(SBV Integer -> SBV Integer -> SBV Integer)| l1_s7 l1_s10)))
+                                 (let ((l1_s12 (ite l1_s6 l1_s8 l1_s11)))
+                                 (let ((l1_s13 (ite l1_s3 l1_s5 l1_s12)))
+                                 l1_s13)))))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (= s0 s2))
+[GOOD] (define-fun s5 () Int (|ack @(SBV Integer -> SBV Integer -> SBV Integer)| s4 s0))
+[GOOD] (define-fun s6 () Bool (= s1 s5))
+[GOOD] (define-fun s7 () Bool (and s3 s6))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s7)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 5))
+[SEND] (get-value (s1))
+[RECV] ((s1 7))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+
+RESULT:
+Satisfiable. Model:
+  s0 = 5 :: Integer
+  s1 = 7 :: Integer
diff --git a/SBVTestSuite/GoldFiles/recursive20_mutualTP.gold b/SBVTestSuite/GoldFiles/recursive20_mutualTP.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/recursive20_mutualTP.gold
@@ -0,0 +1,221 @@
+[MEASURE] checkNewMeasures: 2 to verify
+[MEASURE] checkNewMeasures: verifying mf_tp @(SBV Integer -> SBV Integer)
+[MEASURE] Checking mutual recursion group: {mf_tp :: SBV Integer -> SBV Integer, mg_tp :: SBV Integer -> SBV Integer}
+[MEASURE] Mutual group: trying measure abs arg1 for all members
+[MEASURE] replayDAG {mf_tp @(SBV Integer -> SBV Integer), mg_tp @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (>= s8 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s9))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {mf_tp @(SBV Integer -> SBV Integer), mg_tp @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Int (abs s4))
+[GOOD] (define-fun s10 () Bool (not s3))
+[GOOD] (define-fun s11 () Bool (> s8 s9))
+[GOOD] (define-fun s12 () Bool (=> s10 s11))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for mf_tp @(SBV Integer -> SBV Integer)
+[MEASURE] replayDAG {mf_tp @(SBV Integer -> SBV Integer), mg_tp @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (>= s8 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s9))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {mf_tp @(SBV Integer -> SBV Integer), mg_tp @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s2 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Int (abs s4))
+[GOOD] (define-fun s10 () Bool (not s3))
+[GOOD] (define-fun s11 () Bool (> s8 s9))
+[GOOD] (define-fun s12 () Bool (=> s10 s11))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for mg_tp @(SBV Integer -> SBV Integer)
+[MEASURE] Mutual group: measure abs arg1 works for all members
+[MEASURE] checkNewMeasures: mf_tp @(SBV Integer -> SBV Integer) verified
+[MEASURE] checkNewMeasures: verifying mg_tp @(SBV Integer -> SBV Integer)
+[MEASURE] mg_tp @(SBV Integer -> SBV Integer): mutual group already verified, skipping
+[MEASURE] checkNewMeasures: mg_tp @(SBV Integer -> SBV Integer) verified
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "__internal_sbv_s0"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |mf_tp @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger, |mg_tp @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger
+[GOOD] (define-funs-rec
+         ((|mf_tp @(SBV Integer -> SBV Integer)| ((l1_s0 Int)) Int)
+          (|mg_tp @(SBV Integer -> SBV Integer)| ((l2_s0 Int)) Int))
+         (; Definition of: |mf_tp @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |mg_tp @(SBV Integer -> SBV Integer)|]
+                                  (let ((l1_s1 0))
+                                  (let ((l1_s3 1))
+                                  (let ((l1_s2 (<= l1_s0 l1_s1)))
+                                  (let ((l1_s4 (- l1_s0 l1_s3)))
+                                  (let ((l1_s5 (|mg_tp @(SBV Integer -> SBV Integer)| l1_s4)))
+                                  (let ((l1_s6 (+ l1_s3 l1_s5)))
+                                  (let ((l1_s7 (ite l1_s2 l1_s1 l1_s6)))
+                                  l1_s7)))))))
+          ; Definition of: |mg_tp @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |mf_tp @(SBV Integer -> SBV Integer)|]
+                                                  (let ((l2_s1 0))
+                                                  (let ((l2_s3 1))
+                                                  (let ((l2_s2 (<= l2_s0 l2_s1)))
+                                                  (let ((l2_s4 (- l2_s0 l2_s3)))
+                                                  (let ((l2_s5 (|mf_tp @(SBV Integer -> SBV Integer)| l2_s4)))
+                                                  (let ((l2_s6 (+ l2_s3 l2_s5)))
+                                                  (let ((l2_s7 (ite l2_s2 l2_s1 l2_s6)))
+                                                  l2_s7)))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Int (|mf_tp @(SBV Integer -> SBV Integer)| s0))
+[GOOD] (define-fun s4 () Bool (= s1 s3))
+[GOOD] (define-fun s5 () Bool (=> s2 s4))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+; smtProofStep: No context value to push.
+Lemma: mutual_at_0
+[GOOD] (define-fun s6 () Bool (forall ((l1_s0 Int))
+                                 (let ((l1_s1 0))
+                                 (let ((l1_s2 (= l1_s0 l1_s1)))
+                                 (let ((l1_s3 (|mf_tp @(SBV Integer -> SBV Integer)| l1_s0)))
+                                 (let ((l1_s4 (= l1_s1 l1_s3)))
+                                 (let ((l1_s5 (=> l1_s2 l1_s4)))
+                                 l1_s5)))))))
+[GOOD] (define-fun s7 () Bool (not s6))
+[GOOD] (assert s7)
+[SEND] (check-sat)
+[RECV] unsat
+    Q.E.D.
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+Functions proven terminating: mf_tp, mg_tp
diff --git a/SBVTestSuite/GoldFiles/recursive21_allSelfBadCross.gold b/SBVTestSuite/GoldFiles/recursive21_allSelfBadCross.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/recursive21_allSelfBadCross.gold
@@ -0,0 +1,613 @@
+[MEASURE] Verifying termination measures for: bf21 @(SBV Integer -> SBV Integer), bf21 @(SBV Integer -> SBV Integer), bg21 @(SBV Integer -> SBV Integer), bg21 @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: bf21 @(SBV Integer -> SBV Integer)
+[MEASURE] Checking mutual recursion group: {bf21 :: SBV Integer -> SBV Integer, bg21 :: SBV Integer -> SBV Integer}
+[MEASURE] Mutual group: trying measure abs arg1 for all members
+[MEASURE] replayDAG {bf21 @(SBV Integer -> SBV Integer), bg21 @(SBV Integer -> SBV Integer)}: replaying 7 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] (declare-fun s7 () Int) ; tracks user variable "__internal_sbv_s7"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s0 s2))
+[GOOD] (define-fun s8 () Int (+ s5 s7))
+[GOOD] (define-fun s9 () Int (ite s3 s1 s8))
+[GOOD] (define-fun s10 () Int (abs s0))
+[GOOD] (define-fun s11 () Bool (>= s10 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s11))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {bf21 @(SBV Integer -> SBV Integer), bg21 @(SBV Integer -> SBV Integer)}: replaying 7 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] (declare-fun s7 () Int) ; tracks user variable "__internal_sbv_s7"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s0 s2))
+[GOOD] (define-fun s8 () Int (+ s5 s7))
+[GOOD] (define-fun s9 () Int (ite s3 s1 s8))
+[GOOD] (define-fun s10 () Int (abs s0))
+[GOOD] (define-fun s11 () Int (abs s4))
+[GOOD] (define-fun s12 () Int (abs s6))
+[GOOD] (define-fun s13 () Bool (not s3))
+[GOOD] (define-fun s14 () Bool (> s10 s11))
+[GOOD] (define-fun s15 () Bool (=> s13 s14))
+[GOOD] (define-fun s16 () Bool (> s10 s12))
+[GOOD] (define-fun s17 () Bool (=> s13 s16))
+[GOOD] (define-fun s18 () Bool (and s15 s17))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s18))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s10))
+[RECV] ((s10 2))
+[SEND] (get-value (s11))
+[RECV] ((s11 1))
+[SEND] (get-value (s12))
+[RECV] ((s12 3))
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s5))
+[RECV] ((s5 0))
+[SEND] (get-value (s7))
+[RECV] ((s7 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease failed for bf21 @(SBV Integer -> SBV Integer): Falsifiable. Counter-example:
+  arg     = 2 :: Integer
+  before  = 2 :: Integer
+  then[1] = 1 :: Integer
+  then[2] = 3 :: Integer
+[MEASURE] Mutual group: measure abs arg1 failed, trying next
+[MEASURE] Mutual group: trying measure smax 0 arg1 for all members
+[MEASURE] replayDAG {bf21 @(SBV Integer -> SBV Integer), bg21 @(SBV Integer -> SBV Integer)}: replaying 7 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] (declare-fun s7 () Int) ; tracks user variable "__internal_sbv_s7"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s0 s2))
+[GOOD] (define-fun s8 () Int (+ s5 s7))
+[GOOD] (define-fun s9 () Int (ite s3 s1 s8))
+[GOOD] (define-fun s10 () Bool (<= s1 s0))
+[GOOD] (define-fun s11 () Int (ite s10 s0 s1))
+[GOOD] (define-fun s12 () Bool (>= s11 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {bf21 @(SBV Integer -> SBV Integer), bg21 @(SBV Integer -> SBV Integer)}: replaying 7 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] (declare-fun s7 () Int) ; tracks user variable "__internal_sbv_s7"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s0 s2))
+[GOOD] (define-fun s8 () Int (+ s5 s7))
+[GOOD] (define-fun s9 () Int (ite s3 s1 s8))
+[GOOD] (define-fun s10 () Bool (<= s1 s0))
+[GOOD] (define-fun s11 () Int (ite s10 s0 s1))
+[GOOD] (define-fun s12 () Bool (<= s1 s4))
+[GOOD] (define-fun s13 () Int (ite s12 s4 s1))
+[GOOD] (define-fun s14 () Bool (<= s1 s6))
+[GOOD] (define-fun s15 () Int (ite s14 s6 s1))
+[GOOD] (define-fun s16 () Bool (not s3))
+[GOOD] (define-fun s17 () Bool (> s11 s13))
+[GOOD] (define-fun s18 () Bool (=> s16 s17))
+[GOOD] (define-fun s19 () Bool (> s11 s15))
+[GOOD] (define-fun s20 () Bool (=> s16 s19))
+[GOOD] (define-fun s21 () Bool (and s18 s20))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s21))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s11))
+[RECV] ((s11 2))
+[SEND] (get-value (s13))
+[RECV] ((s13 1))
+[SEND] (get-value (s15))
+[RECV] ((s15 3))
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s5))
+[RECV] ((s5 0))
+[SEND] (get-value (s7))
+[RECV] ((s7 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease failed for bf21 @(SBV Integer -> SBV Integer): Falsifiable. Counter-example:
+  arg     = 2 :: Integer
+  before  = 2 :: Integer
+  then[1] = 1 :: Integer
+  then[2] = 3 :: Integer
+[MEASURE] Mutual group: measure smax 0 arg1 failed, trying next
+[MEASURE] Mutual group: trying measure abs arg1 + smax 0 arg1 for all members
+[MEASURE] replayDAG {bf21 @(SBV Integer -> SBV Integer), bg21 @(SBV Integer -> SBV Integer)}: replaying 7 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] (declare-fun s7 () Int) ; tracks user variable "__internal_sbv_s7"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s0 s2))
+[GOOD] (define-fun s8 () Int (+ s5 s7))
+[GOOD] (define-fun s9 () Int (ite s3 s1 s8))
+[GOOD] (define-fun s10 () Int (abs s0))
+[GOOD] (define-fun s11 () Bool (<= s1 s0))
+[GOOD] (define-fun s12 () Int (ite s11 s0 s1))
+[GOOD] (define-fun s13 () Int (+ s10 s12))
+[GOOD] (define-fun s14 () Bool (>= s13 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s14))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {bf21 @(SBV Integer -> SBV Integer), bg21 @(SBV Integer -> SBV Integer)}: replaying 7 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] (declare-fun s7 () Int) ; tracks user variable "__internal_sbv_s7"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s0 s2))
+[GOOD] (define-fun s8 () Int (+ s5 s7))
+[GOOD] (define-fun s9 () Int (ite s3 s1 s8))
+[GOOD] (define-fun s10 () Int (abs s0))
+[GOOD] (define-fun s11 () Bool (<= s1 s0))
+[GOOD] (define-fun s12 () Int (ite s11 s0 s1))
+[GOOD] (define-fun s13 () Int (+ s10 s12))
+[GOOD] (define-fun s14 () Int (abs s4))
+[GOOD] (define-fun s15 () Bool (<= s1 s4))
+[GOOD] (define-fun s16 () Int (ite s15 s4 s1))
+[GOOD] (define-fun s17 () Int (+ s14 s16))
+[GOOD] (define-fun s18 () Int (abs s6))
+[GOOD] (define-fun s19 () Bool (<= s1 s6))
+[GOOD] (define-fun s20 () Int (ite s19 s6 s1))
+[GOOD] (define-fun s21 () Int (+ s18 s20))
+[GOOD] (define-fun s22 () Bool (not s3))
+[GOOD] (define-fun s23 () Bool (> s13 s17))
+[GOOD] (define-fun s24 () Bool (=> s22 s23))
+[GOOD] (define-fun s25 () Bool (> s13 s21))
+[GOOD] (define-fun s26 () Bool (=> s22 s25))
+[GOOD] (define-fun s27 () Bool (and s24 s26))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s27))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s13))
+[RECV] ((s13 4))
+[SEND] (get-value (s17))
+[RECV] ((s17 2))
+[SEND] (get-value (s21))
+[RECV] ((s21 6))
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s5))
+[RECV] ((s5 0))
+[SEND] (get-value (s7))
+[RECV] ((s7 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease failed for bf21 @(SBV Integer -> SBV Integer): Falsifiable. Counter-example:
+  arg     = 2 :: Integer
+  before  = 4 :: Integer
+  then[1] = 2 :: Integer
+  then[2] = 6 :: Integer
+[MEASURE] Mutual group: measure abs arg1 + smax 0 arg1 failed, trying next
+[MEASURE] Mutual group: trying measure (abs arg1, smax 0 arg1) for all members
+[MEASURE] replayDAG {bf21 @(SBV Integer -> SBV Integer), bg21 @(SBV Integer -> SBV Integer)}: replaying 7 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] (declare-fun s7 () Int) ; tracks user variable "__internal_sbv_s7"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s0 s2))
+[GOOD] (define-fun s8 () Int (+ s5 s7))
+[GOOD] (define-fun s9 () Int (ite s3 s1 s8))
+[GOOD] (define-fun s10 () Int (abs s0))
+[GOOD] (define-fun s11 () Bool (<= s1 s0))
+[GOOD] (define-fun s12 () Int (ite s11 s0 s1))
+[GOOD] (define-fun s13 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s10 s12))
+[GOOD] (define-fun s14 () Int (proj_1_SBVTuple2 s13))
+[GOOD] (define-fun s15 () Bool (>= s14 s1))
+[GOOD] (define-fun s16 () Int (proj_2_SBVTuple2 s13))
+[GOOD] (define-fun s17 () Bool (>= s16 s1))
+[GOOD] (define-fun s18 () Bool (and s15 s17))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s18))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {bf21 @(SBV Integer -> SBV Integer), bg21 @(SBV Integer -> SBV Integer)}: replaying 7 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] (declare-fun s7 () Int) ; tracks user variable "__internal_sbv_s7"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s0 s2))
+[GOOD] (define-fun s8 () Int (+ s5 s7))
+[GOOD] (define-fun s9 () Int (ite s3 s1 s8))
+[GOOD] (define-fun s10 () Int (abs s0))
+[GOOD] (define-fun s11 () Bool (<= s1 s0))
+[GOOD] (define-fun s12 () Int (ite s11 s0 s1))
+[GOOD] (define-fun s13 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s10 s12))
+[GOOD] (define-fun s14 () Int (abs s4))
+[GOOD] (define-fun s15 () Bool (<= s1 s4))
+[GOOD] (define-fun s16 () Int (ite s15 s4 s1))
+[GOOD] (define-fun s17 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s14 s16))
+[GOOD] (define-fun s18 () Int (abs s6))
+[GOOD] (define-fun s19 () Bool (<= s1 s6))
+[GOOD] (define-fun s20 () Int (ite s19 s6 s1))
+[GOOD] (define-fun s21 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s18 s20))
+[GOOD] (define-fun s22 () Bool (not s3))
+[GOOD] (define-fun s23 () Int (proj_1_SBVTuple2 s17))
+[GOOD] (define-fun s24 () Int (proj_1_SBVTuple2 s13))
+[GOOD] (define-fun s25 () Bool (< s23 s24))
+[GOOD] (define-fun s26 () Bool (= s23 s24))
+[GOOD] (define-fun s27 () Int (proj_2_SBVTuple2 s17))
+[GOOD] (define-fun s28 () Int (proj_2_SBVTuple2 s13))
+[GOOD] (define-fun s29 () Bool (< s27 s28))
+[GOOD] (define-fun s30 () Bool (and s26 s29))
+[GOOD] (define-fun s31 () Bool (or s25 s30))
+[GOOD] (define-fun s32 () Bool (=> s22 s31))
+[GOOD] (define-fun s33 () Int (proj_1_SBVTuple2 s21))
+[GOOD] (define-fun s34 () Bool (< s33 s24))
+[GOOD] (define-fun s35 () Bool (= s24 s33))
+[GOOD] (define-fun s36 () Int (proj_2_SBVTuple2 s21))
+[GOOD] (define-fun s37 () Bool (< s36 s28))
+[GOOD] (define-fun s38 () Bool (and s35 s37))
+[GOOD] (define-fun s39 () Bool (or s34 s38))
+[GOOD] (define-fun s40 () Bool (=> s22 s39))
+[GOOD] (define-fun s41 () Bool (and s32 s40))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s41))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s13))
+[RECV] ((s13 (mkSBVTuple2 2 2)))
+[SEND] (get-value (s17))
+[RECV] ((s17 (mkSBVTuple2 1 1)))
+[SEND] (get-value (s21))
+[RECV] ((s21 (mkSBVTuple2 3 3)))
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s5))
+[RECV] ((s5 0))
+[SEND] (get-value (s7))
+[RECV] ((s7 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease failed for bf21 @(SBV Integer -> SBV Integer): Falsifiable. Counter-example:
+  arg     =     2 :: Integer
+  before  = (2,2) :: (Integer, Integer)
+  then[1] = (1,1) :: (Integer, Integer)
+  then[2] = (3,3) :: (Integer, Integer)
+[MEASURE] Mutual group: measure (abs arg1, smax 0 arg1) failed, trying next
+[MEASURE] Mutual group: trying measure (smax 0 arg1, abs arg1) for all members
+[MEASURE] replayDAG {bf21 @(SBV Integer -> SBV Integer), bg21 @(SBV Integer -> SBV Integer)}: replaying 7 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] (declare-fun s7 () Int) ; tracks user variable "__internal_sbv_s7"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s0 s2))
+[GOOD] (define-fun s8 () Int (+ s5 s7))
+[GOOD] (define-fun s9 () Int (ite s3 s1 s8))
+[GOOD] (define-fun s10 () Bool (<= s1 s0))
+[GOOD] (define-fun s11 () Int (ite s10 s0 s1))
+[GOOD] (define-fun s12 () Int (abs s0))
+[GOOD] (define-fun s13 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s11 s12))
+[GOOD] (define-fun s14 () Int (proj_1_SBVTuple2 s13))
+[GOOD] (define-fun s15 () Bool (>= s14 s1))
+[GOOD] (define-fun s16 () Int (proj_2_SBVTuple2 s13))
+[GOOD] (define-fun s17 () Bool (>= s16 s1))
+[GOOD] (define-fun s18 () Bool (and s15 s17))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s18))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {bf21 @(SBV Integer -> SBV Integer), bg21 @(SBV Integer -> SBV Integer)}: replaying 7 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
+                                           ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
+                                                         (proj_2_SBVTuple2 T2))))))
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] (declare-fun s7 () Int) ; tracks user variable "__internal_sbv_s7"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s0 s2))
+[GOOD] (define-fun s8 () Int (+ s5 s7))
+[GOOD] (define-fun s9 () Int (ite s3 s1 s8))
+[GOOD] (define-fun s10 () Bool (<= s1 s0))
+[GOOD] (define-fun s11 () Int (ite s10 s0 s1))
+[GOOD] (define-fun s12 () Int (abs s0))
+[GOOD] (define-fun s13 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s11 s12))
+[GOOD] (define-fun s14 () Bool (<= s1 s4))
+[GOOD] (define-fun s15 () Int (ite s14 s4 s1))
+[GOOD] (define-fun s16 () Int (abs s4))
+[GOOD] (define-fun s17 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s15 s16))
+[GOOD] (define-fun s18 () Bool (<= s1 s6))
+[GOOD] (define-fun s19 () Int (ite s18 s6 s1))
+[GOOD] (define-fun s20 () Int (abs s6))
+[GOOD] (define-fun s21 () (SBVTuple2 Int Int) ((as mkSBVTuple2 (SBVTuple2 Int Int)) s19 s20))
+[GOOD] (define-fun s22 () Bool (not s3))
+[GOOD] (define-fun s23 () Int (proj_1_SBVTuple2 s17))
+[GOOD] (define-fun s24 () Int (proj_1_SBVTuple2 s13))
+[GOOD] (define-fun s25 () Bool (< s23 s24))
+[GOOD] (define-fun s26 () Bool (= s23 s24))
+[GOOD] (define-fun s27 () Int (proj_2_SBVTuple2 s17))
+[GOOD] (define-fun s28 () Int (proj_2_SBVTuple2 s13))
+[GOOD] (define-fun s29 () Bool (< s27 s28))
+[GOOD] (define-fun s30 () Bool (and s26 s29))
+[GOOD] (define-fun s31 () Bool (or s25 s30))
+[GOOD] (define-fun s32 () Bool (=> s22 s31))
+[GOOD] (define-fun s33 () Int (proj_1_SBVTuple2 s21))
+[GOOD] (define-fun s34 () Bool (< s33 s24))
+[GOOD] (define-fun s35 () Bool (= s24 s33))
+[GOOD] (define-fun s36 () Int (proj_2_SBVTuple2 s21))
+[GOOD] (define-fun s37 () Bool (< s36 s28))
+[GOOD] (define-fun s38 () Bool (and s35 s37))
+[GOOD] (define-fun s39 () Bool (or s34 s38))
+[GOOD] (define-fun s40 () Bool (=> s22 s39))
+[GOOD] (define-fun s41 () Bool (and s32 s40))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s41))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s13))
+[RECV] ((s13 (mkSBVTuple2 2 2)))
+[SEND] (get-value (s17))
+[RECV] ((s17 (mkSBVTuple2 1 1)))
+[SEND] (get-value (s21))
+[RECV] ((s21 (mkSBVTuple2 3 3)))
+[SEND] (get-value (s0))
+[RECV] ((s0 2))
+[SEND] (get-value (s5))
+[RECV] ((s5 0))
+[SEND] (get-value (s7))
+[RECV] ((s7 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease failed for bf21 @(SBV Integer -> SBV Integer): Falsifiable. Counter-example:
+  arg     =     2 :: Integer
+  before  = (2,2) :: (Integer, Integer)
+  then[1] = (1,1) :: (Integer, Integer)
+  then[2] = (3,3) :: (Integer, Integer)
+[MEASURE] Mutual group: measure (smax 0 arg1, abs arg1) failed, trying next
+
+EXCEPTION:
+
+*** Data.SBV: Cannot determine a termination measure for mutual recursion group.
+***
+***     bf21  :: SBV Integer -> SBV Integer
+***     bg21  :: SBV Integer -> SBV Integer
+***
+*** Please use 'smtFunctionWithMeasure' to provide explicit measures.
+
diff --git a/SBVTestSuite/GoldFiles/recursive22_allSelfGoodCross.gold b/SBVTestSuite/GoldFiles/recursive22_allSelfGoodCross.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/recursive22_allSelfGoodCross.gold
@@ -0,0 +1,376 @@
+[MEASURE] Verifying termination measures for: bf22 @(SBV Integer -> SBV Integer), bf22 @(SBV Integer -> SBV Integer), bg22 @(SBV Integer -> SBV Integer), bg22 @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: bf22 @(SBV Integer -> SBV Integer)
+[MEASURE] Checking mutual recursion group: {bf22 :: SBV Integer -> SBV Integer, bg22 :: SBV Integer -> SBV Integer}
+[MEASURE] Mutual group: trying user-provided measure for all members
+[MEASURE] replayDAG {bf22 @(SBV Integer -> SBV Integer), bg22 @(SBV Integer -> SBV Integer)}: replaying 6 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (+ s5 s6))
+[GOOD] (define-fun s8 () Int (ite s3 s1 s7))
+[GOOD] (define-fun s9 () Int (abs s0))
+[GOOD] (define-fun s10 () Bool (>= s9 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s10))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {bf22 @(SBV Integer -> SBV Integer), bg22 @(SBV Integer -> SBV Integer)}: replaying 6 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (+ s5 s6))
+[GOOD] (define-fun s8 () Int (ite s3 s1 s7))
+[GOOD] (define-fun s9 () Int (abs s0))
+[GOOD] (define-fun s10 () Int (abs s4))
+[GOOD] (define-fun s11 () Bool (not s3))
+[GOOD] (define-fun s12 () Bool (> s9 s10))
+[GOOD] (define-fun s13 () Bool (=> s11 s12))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s13))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for bf22 @(SBV Integer -> SBV Integer)
+[MEASURE] replayDAG {bf22 @(SBV Integer -> SBV Integer), bg22 @(SBV Integer -> SBV Integer)}: replaying 6 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (+ s5 s6))
+[GOOD] (define-fun s8 () Int (ite s3 s1 s7))
+[GOOD] (define-fun s9 () Int (abs s0))
+[GOOD] (define-fun s10 () Bool (>= s9 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s10))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {bf22 @(SBV Integer -> SBV Integer), bg22 @(SBV Integer -> SBV Integer)}: replaying 6 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (+ s5 s6))
+[GOOD] (define-fun s8 () Int (ite s3 s1 s7))
+[GOOD] (define-fun s9 () Int (abs s0))
+[GOOD] (define-fun s10 () Int (abs s4))
+[GOOD] (define-fun s11 () Bool (not s3))
+[GOOD] (define-fun s12 () Bool (> s9 s10))
+[GOOD] (define-fun s13 () Bool (=> s11 s12))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s13))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Mutual group: decrease verified for bg22 @(SBV Integer -> SBV Integer)
+[MEASURE] Mutual group: user-provided measure works for all members
+[MEASURE] Passed (terminating): bf22 @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: bf22 @(SBV Integer -> SBV Integer)
+[MEASURE] bf22 @(SBV Integer -> SBV Integer): verifying with 0 helper(s)
+[MEASURE] bf22 @(SBV Integer -> SBV Integer): 0 helper axiom(s) collected, checking measure
+[MEASURE] replayDAG {bf22 @(SBV Integer -> SBV Integer)}: replaying 6 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (+ s5 s6))
+[GOOD] (define-fun s8 () Int (ite s3 s1 s7))
+[GOOD] (define-fun s9 () Int (abs s0))
+[GOOD] (define-fun s10 () Bool (>= s9 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s10))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {bf22 @(SBV Integer -> SBV Integer)}: replaying 6 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (+ s5 s6))
+[GOOD] (define-fun s8 () Int (ite s3 s1 s7))
+[GOOD] (define-fun s9 () Int (abs s0))
+[GOOD] (define-fun s10 () Int (abs s4))
+[GOOD] (define-fun s11 () Bool (not s3))
+[GOOD] (define-fun s12 () Bool (> s9 s10))
+[GOOD] (define-fun s13 () Bool (=> s11 s12))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s13))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Passed (terminating): bf22 @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: bg22 @(SBV Integer -> SBV Integer)
+[MEASURE] bg22 @(SBV Integer -> SBV Integer): mutual group already verified, skipping
+[MEASURE] Passed (terminating): bg22 @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: bg22 @(SBV Integer -> SBV Integer)
+[MEASURE] bg22 @(SBV Integer -> SBV Integer): verifying with 0 helper(s)
+[MEASURE] bg22 @(SBV Integer -> SBV Integer): 0 helper axiom(s) collected, checking measure
+[MEASURE] replayDAG {bg22 @(SBV Integer -> SBV Integer)}: replaying 6 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (+ s5 s6))
+[GOOD] (define-fun s8 () Int (ite s3 s1 s7))
+[GOOD] (define-fun s9 () Int (abs s0))
+[GOOD] (define-fun s10 () Bool (>= s9 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s10))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {bg22 @(SBV Integer -> SBV Integer)}: replaying 6 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] (declare-fun s6 () Int) ; tracks user variable "__internal_sbv_s6"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s7 () Int (+ s5 s6))
+[GOOD] (define-fun s8 () Int (ite s3 s1 s7))
+[GOOD] (define-fun s9 () Int (abs s0))
+[GOOD] (define-fun s10 () Int (abs s4))
+[GOOD] (define-fun s11 () Bool (not s3))
+[GOOD] (define-fun s12 () Bool (> s9 s10))
+[GOOD] (define-fun s13 () Bool (=> s11 s12))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s13))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Passed (terminating): bg22 @(SBV Integer -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |bf22 @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger, |bg22 @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger
+[GOOD] (define-funs-rec
+         ((|bf22 @(SBV Integer -> SBV Integer)| ((l1_s0 Int)) Int)
+          (|bg22 @(SBV Integer -> SBV Integer)| ((l2_s0 Int)) Int))
+         (; Definition of: |bf22 @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |bf22 @(SBV Integer -> SBV Integer)|, |bg22 @(SBV Integer -> SBV Integer)|]
+                                  (let ((l1_s1 0))
+                                  (let ((l1_s3 1))
+                                  (let ((l1_s2 (<= l1_s0 l1_s1)))
+                                  (let ((l1_s4 (- l1_s0 l1_s3)))
+                                  (let ((l1_s5 (|bf22 @(SBV Integer -> SBV Integer)| l1_s4)))
+                                  (let ((l1_s6 (|bg22 @(SBV Integer -> SBV Integer)| l1_s4)))
+                                  (let ((l1_s7 (+ l1_s5 l1_s6)))
+                                  (let ((l1_s8 (ite l1_s2 l1_s1 l1_s7)))
+                                  l1_s8))))))))
+          ; Definition of: |bg22 @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger. [Refers to: |bf22 @(SBV Integer -> SBV Integer)|, |bg22 @(SBV Integer -> SBV Integer)|]
+                                                  (let ((l2_s1 0))
+                                                  (let ((l2_s3 1))
+                                                  (let ((l2_s2 (<= l2_s0 l2_s1)))
+                                                  (let ((l2_s4 (- l2_s0 l2_s3)))
+                                                  (let ((l2_s5 (|bg22 @(SBV Integer -> SBV Integer)| l2_s4)))
+                                                  (let ((l2_s6 (|bf22 @(SBV Integer -> SBV Integer)| l2_s4)))
+                                                  (let ((l2_s7 (+ l2_s5 l2_s6)))
+                                                  (let ((l2_s8 (ite l2_s2 l2_s1 l2_s7)))
+                                                  l2_s8))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Int (|bf22 @(SBV Integer -> SBV Integer)| s0))
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s2)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+
+RESULT:
+Satisfiable. Model:
+  s0 = 0 :: Integer
diff --git a/SBVTestSuite/GoldFiles/recursive23_mutualProductive.gold b/SBVTestSuite/GoldFiles/recursive23_mutualProductive.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/recursive23_mutualProductive.gold
@@ -0,0 +1,74 @@
+[MEASURE] Verifying termination measures for: pf23 @(SBV Integer -> SBV [Integer]), pg23 @(SBV Integer -> SBV [Integer])
+[MEASURE] Checking: pf23 @(SBV Integer -> SBV [Integer])
+[MEASURE] Checking mutual productive group: {pf23 :: SBV Integer -> SBV [Integer], pg23 :: SBV Integer -> SBV [Integer]}
+[MEASURE] Mutual productive group: all members are guarded
+[MEASURE] Passed (productive): pf23 @(SBV Integer -> SBV [Integer])
+[MEASURE] Checking: pg23 @(SBV Integer -> SBV [Integer])
+[MEASURE] pg23 @(SBV Integer -> SBV [Integer]): mutual productive group already verified, skipping
+[MEASURE] Passed (productive): pg23 @(SBV Integer -> SBV [Integer])
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |pf23 @(SBV Integer -> SBV [Integer])| :: SInteger -> [SInteger], |pg23 @(SBV Integer -> SBV [Integer])| :: SInteger -> [SInteger]
+[GOOD] (define-funs-rec
+         ((|pf23 @(SBV Integer -> SBV [Integer])| ((l1_s0 Int)) (Seq Int))
+          (|pg23 @(SBV Integer -> SBV [Integer])| ((l2_s0 Int)) (Seq Int)))
+         (; Definition of: |pf23 @(SBV Integer -> SBV [Integer])| :: SInteger -> [SInteger]. [Refers to: |pg23 @(SBV Integer -> SBV [Integer])|]
+                                  (let ((l1_s1 0))
+                                  (let ((l1_s3 (seq.unit 0)))
+                                  (let ((l1_s5 1))
+                                  (let ((l1_s2 (<= l1_s0 l1_s1)))
+                                  (let ((l1_s4 (seq.unit l1_s0)))
+                                  (let ((l1_s6 (- l1_s0 l1_s5)))
+                                  (let ((l1_s7 (|pg23 @(SBV Integer -> SBV [Integer])| l1_s6)))
+                                  (let ((l1_s8 (seq.++ l1_s4 l1_s7)))
+                                  (let ((l1_s9 (ite l1_s2 l1_s3 l1_s8)))
+                                  l1_s9)))))))))
+          ; Definition of: |pg23 @(SBV Integer -> SBV [Integer])| :: SInteger -> [SInteger]. [Refers to: |pf23 @(SBV Integer -> SBV [Integer])|]
+                                                  (let ((l2_s1 0))
+                                                  (let ((l2_s3 (seq.unit 0)))
+                                                  (let ((l2_s5 1))
+                                                  (let ((l2_s2 (<= l2_s0 l2_s1)))
+                                                  (let ((l2_s4 (seq.unit l2_s0)))
+                                                  (let ((l2_s6 (- l2_s0 l2_s5)))
+                                                  (let ((l2_s7 (|pf23 @(SBV Integer -> SBV [Integer])| l2_s6)))
+                                                  (let ((l2_s8 (seq.++ l2_s4 l2_s7)))
+                                                  (let ((l2_s9 (ite l2_s2 l2_s3 l2_s8)))
+                                                  l2_s9)))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () (Seq Int) (|pf23 @(SBV Integer -> SBV [Integer])| s0))
+[GOOD] (define-fun s3 () Int (seq.nth s1 s2))
+[GOOD] (define-fun s4 () Bool (= s0 s3))
+[GOOD] (define-fun s5 () Bool (> s0 s2))
+[GOOD] (define-fun s6 () Bool (and s4 s5))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s6)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+
+RESULT:
+Satisfiable. Model:
+  s0 = 1 :: Integer
diff --git a/SBVTestSuite/GoldFiles/recursive24_badMutualProductive.gold b/SBVTestSuite/GoldFiles/recursive24_badMutualProductive.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/recursive24_badMutualProductive.gold
@@ -0,0 +1,15 @@
+[MEASURE] Verifying termination measures for: bad_pf @(SBV Integer -> SBV [Integer]), bad_pg @(SBV Integer -> SBV [Integer])
+[MEASURE] Checking: bad_pf @(SBV Integer -> SBV [Integer])
+[MEASURE] Checking mutual productive group: {bad_pf :: SBV Integer -> SBV [Integer], bad_pg :: SBV Integer -> SBV [Integer]}
+
+EXCEPTION:
+
+*** Data.SBV: Mutual productive group has unguarded recursive calls.
+***
+***     bad_pf  :: SBV Integer -> SBV [Integer]
+***     bad_pg  :: SBV Integer -> SBV [Integer]
+***   Unguarded: bad_pg :: SBV Integer -> SBV [Integer]
+***
+*** Every recursive call (self or cross) must be a direct argument to a data constructor.
+
+
diff --git a/SBVTestSuite/GoldFiles/recursive25_contractMutualRejected.gold b/SBVTestSuite/GoldFiles/recursive25_contractMutualRejected.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/recursive25_contractMutualRejected.gold
@@ -0,0 +1,16 @@
+[MEASURE] Verifying termination measures for: cf_mut @(SBV Integer -> SBV Integer), cf_mut @(SBV Integer -> SBV Integer), cg_mut @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: cf_mut @(SBV Integer -> SBV Integer)
+[MEASURE] cf_mut @(SBV Integer -> SBV Integer) (contract): verifying with 0 helper(s)
+[MEASURE] cf_mut @(SBV Integer -> SBV Integer) (contract): 0 helper axiom(s) collected, checking measure+contract
+[MEASURE] Passed (terminating): cf_mut @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: cf_mut @(SBV Integer -> SBV Integer)
+
+EXCEPTION:
+
+*** Data.SBV: smtFunctionWithContract does not support mutual recursion.
+***
+***   Function: cf_mut :: SBV Integer -> SBV Integer
+***
+*** Please use smtFunction or smtFunctionWithMeasure for mutual recursion groups.
+
+
diff --git a/SBVTestSuite/GoldFiles/recursive26_selfAndMutualProductive.gold b/SBVTestSuite/GoldFiles/recursive26_selfAndMutualProductive.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/recursive26_selfAndMutualProductive.gold
@@ -0,0 +1,83 @@
+[MEASURE] Verifying termination measures for: spf26 @(SBV Integer -> SBV [Integer]), spf26 @(SBV Integer -> SBV [Integer]), spg26 @(SBV Integer -> SBV [Integer])
+[MEASURE] Checking: spf26 @(SBV Integer -> SBV [Integer])
+[MEASURE] Checking mutual productive group: {spf26 :: SBV Integer -> SBV [Integer], spg26 :: SBV Integer -> SBV [Integer]}
+[MEASURE] Mutual productive group: all members are guarded
+[MEASURE] Passed (productive): spf26 @(SBV Integer -> SBV [Integer])
+[MEASURE] Checking: spf26 @(SBV Integer -> SBV [Integer])
+[MEASURE] spf26 @(SBV Integer -> SBV [Integer]): productive (all recursive calls are guarded by constructors)
+[MEASURE] Passed (productive): spf26 @(SBV Integer -> SBV [Integer])
+[MEASURE] Checking: spg26 @(SBV Integer -> SBV [Integer])
+[MEASURE] spg26 @(SBV Integer -> SBV [Integer]): mutual productive group already verified, skipping
+[MEASURE] Passed (productive): spg26 @(SBV Integer -> SBV [Integer])
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |spf26 @(SBV Integer -> SBV [Integer])| :: SInteger -> [SInteger], |spg26 @(SBV Integer -> SBV [Integer])| :: SInteger -> [SInteger]
+[GOOD] (define-funs-rec
+         ((|spf26 @(SBV Integer -> SBV [Integer])| ((l1_s0 Int)) (Seq Int))
+          (|spg26 @(SBV Integer -> SBV [Integer])| ((l2_s0 Int)) (Seq Int)))
+         (; Definition of: |spf26 @(SBV Integer -> SBV [Integer])| :: SInteger -> [SInteger]. [Refers to: |spf26 @(SBV Integer -> SBV [Integer])|, |spg26 @(SBV Integer -> SBV [Integer])|]
+                                  (let ((l1_s1 0))
+                                  (let ((l1_s3 (seq.unit 0)))
+                                  (let ((l1_s4 2))
+                                  (let ((l1_s8 1))
+                                  (let ((l1_s2 (<= l1_s0 l1_s1)))
+                                  (let ((l1_s5 (mod l1_s0 l1_s4)))
+                                  (let ((l1_s6 (= l1_s1 l1_s5)))
+                                  (let ((l1_s7 (seq.unit l1_s0)))
+                                  (let ((l1_s9 (- l1_s0 l1_s8)))
+                                  (let ((l1_s10 (|spf26 @(SBV Integer -> SBV [Integer])| l1_s9)))
+                                  (let ((l1_s11 (seq.++ l1_s7 l1_s10)))
+                                  (let ((l1_s12 (|spg26 @(SBV Integer -> SBV [Integer])| l1_s9)))
+                                  (let ((l1_s13 (seq.++ l1_s7 l1_s12)))
+                                  (let ((l1_s14 (ite l1_s6 l1_s11 l1_s13)))
+                                  (let ((l1_s15 (ite l1_s2 l1_s3 l1_s14)))
+                                  l1_s15)))))))))))))))
+          ; Definition of: |spg26 @(SBV Integer -> SBV [Integer])| :: SInteger -> [SInteger]. [Refers to: |spf26 @(SBV Integer -> SBV [Integer])|]
+                                                  (let ((l2_s1 0))
+                                                  (let ((l2_s3 (seq.unit 0)))
+                                                  (let ((l2_s5 1))
+                                                  (let ((l2_s2 (<= l2_s0 l2_s1)))
+                                                  (let ((l2_s4 (seq.unit l2_s0)))
+                                                  (let ((l2_s6 (- l2_s0 l2_s5)))
+                                                  (let ((l2_s7 (|spf26 @(SBV Integer -> SBV [Integer])| l2_s6)))
+                                                  (let ((l2_s8 (seq.++ l2_s4 l2_s7)))
+                                                  (let ((l2_s9 (ite l2_s2 l2_s3 l2_s8)))
+                                                  l2_s9)))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () (Seq Int) (|spf26 @(SBV Integer -> SBV [Integer])| s0))
+[GOOD] (define-fun s3 () Int (seq.nth s1 s2))
+[GOOD] (define-fun s4 () Bool (= s0 s3))
+[GOOD] (define-fun s5 () Bool (> s0 s2))
+[GOOD] (define-fun s6 () Bool (and s4 s5))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s6)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+
+RESULT:
+Satisfiable. Model:
+  s0 = 1 :: Integer
diff --git a/SBVTestSuite/GoldFiles/recursive27_mutualProductive3.gold b/SBVTestSuite/GoldFiles/recursive27_mutualProductive3.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/recursive27_mutualProductive3.gold
@@ -0,0 +1,93 @@
+[MEASURE] Verifying termination measures for: pa27 @(SBV Integer -> SBV [Integer]), pb27 @(SBV Integer -> SBV [Integer]), pc27 @(SBV Integer -> SBV [Integer])
+[MEASURE] Checking: pa27 @(SBV Integer -> SBV [Integer])
+[MEASURE] Checking mutual productive group: {pa27 :: SBV Integer -> SBV [Integer], pb27 :: SBV Integer -> SBV [Integer], pc27 :: SBV Integer -> SBV [Integer]}
+[MEASURE] Mutual productive group: all members are guarded
+[MEASURE] Passed (productive): pa27 @(SBV Integer -> SBV [Integer])
+[MEASURE] Checking: pb27 @(SBV Integer -> SBV [Integer])
+[MEASURE] pb27 @(SBV Integer -> SBV [Integer]): mutual productive group already verified, skipping
+[MEASURE] Passed (productive): pb27 @(SBV Integer -> SBV [Integer])
+[MEASURE] Checking: pc27 @(SBV Integer -> SBV [Integer])
+[MEASURE] pc27 @(SBV Integer -> SBV [Integer]): mutual productive group already verified, skipping
+[MEASURE] Passed (productive): pc27 @(SBV Integer -> SBV [Integer])
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |pa27 @(SBV Integer -> SBV [Integer])| :: SInteger -> [SInteger], |pb27 @(SBV Integer -> SBV [Integer])| :: SInteger -> [SInteger], |pc27 @(SBV Integer -> SBV [Integer])| :: SInteger -> [SInteger]
+[GOOD] (define-funs-rec
+         ((|pa27 @(SBV Integer -> SBV [Integer])| ((l1_s0 Int)) (Seq Int))
+          (|pb27 @(SBV Integer -> SBV [Integer])| ((l2_s0 Int)) (Seq Int))
+          (|pc27 @(SBV Integer -> SBV [Integer])| ((l3_s0 Int)) (Seq Int)))
+         (; Definition of: |pa27 @(SBV Integer -> SBV [Integer])| :: SInteger -> [SInteger]. [Refers to: |pb27 @(SBV Integer -> SBV [Integer])|]
+                                  (let ((l1_s1 0))
+                                  (let ((l1_s3 (seq.unit 0)))
+                                  (let ((l1_s5 1))
+                                  (let ((l1_s2 (<= l1_s0 l1_s1)))
+                                  (let ((l1_s4 (seq.unit l1_s0)))
+                                  (let ((l1_s6 (- l1_s0 l1_s5)))
+                                  (let ((l1_s7 (|pb27 @(SBV Integer -> SBV [Integer])| l1_s6)))
+                                  (let ((l1_s8 (seq.++ l1_s4 l1_s7)))
+                                  (let ((l1_s9 (ite l1_s2 l1_s3 l1_s8)))
+                                  l1_s9)))))))))
+          ; Definition of: |pb27 @(SBV Integer -> SBV [Integer])| :: SInteger -> [SInteger]. [Refers to: |pc27 @(SBV Integer -> SBV [Integer])|]
+                                                  (let ((l2_s1 0))
+                                                  (let ((l2_s3 (seq.unit 0)))
+                                                  (let ((l2_s4 10))
+                                                  (let ((l2_s7 1))
+                                                  (let ((l2_s2 (<= l2_s0 l2_s1)))
+                                                  (let ((l2_s5 (* l2_s0 l2_s4)))
+                                                  (let ((l2_s6 (seq.unit l2_s5)))
+                                                  (let ((l2_s8 (- l2_s0 l2_s7)))
+                                                  (let ((l2_s9 (|pc27 @(SBV Integer -> SBV [Integer])| l2_s8)))
+                                                  (let ((l2_s10 (seq.++ l2_s6 l2_s9)))
+                                                  (let ((l2_s11 (ite l2_s2 l2_s3 l2_s10)))
+                                                  l2_s11)))))))))))
+          ; Definition of: |pc27 @(SBV Integer -> SBV [Integer])| :: SInteger -> [SInteger]. [Refers to: |pa27 @(SBV Integer -> SBV [Integer])|]
+                                                                  (let ((l3_s1 0))
+                                                                  (let ((l3_s3 (seq.unit 0)))
+                                                                  (let ((l3_s4 100))
+                                                                  (let ((l3_s7 1))
+                                                                  (let ((l3_s2 (<= l3_s0 l3_s1)))
+                                                                  (let ((l3_s5 (* l3_s0 l3_s4)))
+                                                                  (let ((l3_s6 (seq.unit l3_s5)))
+                                                                  (let ((l3_s8 (- l3_s0 l3_s7)))
+                                                                  (let ((l3_s9 (|pa27 @(SBV Integer -> SBV [Integer])| l3_s8)))
+                                                                  (let ((l3_s10 (seq.++ l3_s6 l3_s9)))
+                                                                  (let ((l3_s11 (ite l3_s2 l3_s3 l3_s10)))
+                                                                  l3_s11)))))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () (Seq Int) (|pa27 @(SBV Integer -> SBV [Integer])| s0))
+[GOOD] (define-fun s3 () Int (seq.nth s1 s2))
+[GOOD] (define-fun s4 () Bool (= s0 s3))
+[GOOD] (define-fun s5 () Bool (> s0 s2))
+[GOOD] (define-fun s6 () Bool (and s4 s5))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s6)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+
+RESULT:
+Satisfiable. Model:
+  s0 = 1 :: Integer
diff --git a/SBVTestSuite/GoldFiles/recursive28_noTermCheck.gold b/SBVTestSuite/GoldFiles/recursive28_noTermCheck.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/recursive28_noTermCheck.gold
@@ -0,0 +1,53 @@
+[MEASURE] ntc28 @(SBV Integer -> SBV Integer): no termination check (smtFunctionNoTermination)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 5)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "__internal_sbv_s0"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |ntc28 @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger [Recursive]
+[GOOD] (define-fun-rec |ntc28 @(SBV Integer -> SBV Integer)| ((l1_s0 Int)) Int
+                                 (let ((l1_s1 0))
+                                 (let ((l1_s3 1))
+                                 (let ((l1_s2 (<= l1_s0 l1_s1)))
+                                 (let ((l1_s4 (- l1_s0 l1_s3)))
+                                 (let ((l1_s5 (|ntc28 @(SBV Integer -> SBV Integer)| l1_s4)))
+                                 (let ((l1_s6 (+ l1_s3 l1_s5)))
+                                 (let ((l1_s7 (ite l1_s2 l1_s1 l1_s6)))
+                                 l1_s7))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (= s0 s1))
+[GOOD] (define-fun s3 () Int (|ntc28 @(SBV Integer -> SBV Integer)| s0))
+[GOOD] (define-fun s4 () Bool (= s1 s3))
+[GOOD] (define-fun s5 () Bool (=> s2 s4))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+; smtProofStep: No context value to push.
+Lemma: ntc_at_5
+[GOOD] (define-fun s6 () Bool (forall ((l1_s0 Int))
+                                 (let ((l1_s1 5))
+                                 (let ((l1_s2 (= l1_s0 l1_s1)))
+                                 (let ((l1_s3 (|ntc28 @(SBV Integer -> SBV Integer)| l1_s0)))
+                                 (let ((l1_s4 (= l1_s1 l1_s3)))
+                                 (let ((l1_s5 (=> l1_s2 l1_s4)))
+                                 l1_s5)))))))
+[GOOD] (define-fun s7 () Bool (not s6))
+[GOOD] (assert s7)
+[SEND] (check-sat)
+[RECV] unsat
+     Q.E.D. [Modulo: ntc28 termination]
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[Modulo: ntc28 termination] ntc_at_5 :: Ɐn ∷ Integer → Bool
diff --git a/SBVTestSuite/GoldFiles/recursive2_enum.gold b/SBVTestSuite/GoldFiles/recursive2_enum.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/recursive2_enum.gold
@@ -0,0 +1,158 @@
+[MEASURE] Verifying termination measures for: EnumSymbolic.Integer.enumFromThenTo.down @(SBV Integer -> SBV Integer -> SBV Integer -> SBV [Integer])
+[MEASURE] Checking: EnumSymbolic.Integer.enumFromThenTo.down @(SBV Integer -> SBV Integer -> SBV Integer -> SBV [Integer])
+[MEASURE] EnumSymbolic.Integer.enumFromThenTo.down @(SBV Integer -> SBV Integer -> SBV Integer -> SBV [Integer]): verifying with 0 helper(s)
+[MEASURE] EnumSymbolic.Integer.enumFromThenTo.down @(SBV Integer -> SBV Integer -> SBV Integer -> SBV [Integer]): 0 helper axiom(s) collected, checking measure
+[MEASURE] replayDAG {EnumSymbolic.Integer.enumFromThenTo.down @(SBV Integer -> SBV Integer -> SBV Integer -> SBV [Integer])}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () Int 0)
+[GOOD] (define-fun s4 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] (define-fun s14 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () Int) ; tracks user variable "arg1"
+[GOOD] (declare-fun s2 () Int) ; tracks user variable "arg2"
+[GOOD] (declare-fun s10 () (Seq Int)) ; tracks user variable "__internal_sbv_s10"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s5 () Bool (< s0 s2))
+[GOOD] (define-fun s6 () Bool (>= s1 s3))
+[GOOD] (define-fun s7 () Bool (or s5 s6))
+[GOOD] (define-fun s8 () (Seq Int) (seq.unit s0))
+[GOOD] (define-fun s9 () Int (+ s0 s1))
+[GOOD] (define-fun s11 () (Seq Int) (seq.++ s8 s10))
+[GOOD] (define-fun s12 () (Seq Int) (ite s7 s4 s11))
+[GOOD] (define-fun s13 () Int (- s0 s2))
+[GOOD] (define-fun s15 () Int (+ s13 s14))
+[GOOD] (define-fun s16 () Bool (<= s3 s15))
+[GOOD] (define-fun s17 () Int (ite s16 s15 s3))
+[GOOD] (define-fun s18 () Bool (>= s17 s3))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s18))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {EnumSymbolic.Integer.enumFromThenTo.down @(SBV Integer -> SBV Integer -> SBV Integer -> SBV [Integer])}: replaying 8 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () Int 0)
+[GOOD] (define-fun s4 () (Seq Int) (as seq.empty (Seq Int)))
+[GOOD] (define-fun s14 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg0"
+[GOOD] (declare-fun s1 () Int) ; tracks user variable "arg1"
+[GOOD] (declare-fun s2 () Int) ; tracks user variable "arg2"
+[GOOD] (declare-fun s10 () (Seq Int)) ; tracks user variable "__internal_sbv_s10"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s5 () Bool (< s0 s2))
+[GOOD] (define-fun s6 () Bool (>= s1 s3))
+[GOOD] (define-fun s7 () Bool (or s5 s6))
+[GOOD] (define-fun s8 () (Seq Int) (seq.unit s0))
+[GOOD] (define-fun s9 () Int (+ s0 s1))
+[GOOD] (define-fun s11 () (Seq Int) (seq.++ s8 s10))
+[GOOD] (define-fun s12 () (Seq Int) (ite s7 s4 s11))
+[GOOD] (define-fun s13 () Int (- s0 s2))
+[GOOD] (define-fun s15 () Int (+ s13 s14))
+[GOOD] (define-fun s16 () Bool (<= s3 s15))
+[GOOD] (define-fun s17 () Int (ite s16 s15 s3))
+[GOOD] (define-fun s18 () Int (- s9 s2))
+[GOOD] (define-fun s19 () Int (+ s14 s18))
+[GOOD] (define-fun s20 () Bool (<= s3 s19))
+[GOOD] (define-fun s21 () Int (ite s20 s19 s3))
+[GOOD] (define-fun s22 () Bool (not s7))
+[GOOD] (define-fun s23 () Bool (> s17 s21))
+[GOOD] (define-fun s24 () Bool (=> s22 s23))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s24))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Passed (terminating): EnumSymbolic.Integer.enumFromThenTo.down @(SBV Integer -> SBV Integer -> SBV Integer -> SBV [Integer])
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 5)
+[GOOD] (define-fun s2 () Int (- 1))
+[GOOD] (define-fun s5 () Int 0)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |EnumSymbolic.Integer.enumFromThenTo.down @(SBV Integer -> SBV Integer -> SBV Integer -> SBV [Integer])| :: SInteger -> SInteger -> SInteger -> [SInteger] [Recursive]
+[GOOD] (define-fun-rec |EnumSymbolic.Integer.enumFromThenTo.down @(SBV Integer -> SBV Integer -> SBV Integer -> SBV [Integer])| ((l1_s0 Int) (l1_s1 Int) (l1_s2 Int)) (Seq Int)
+                                 (let ((l1_s4 0))
+                                 (let ((l1_s7 (as seq.empty (Seq Int))))
+                                 (let ((l1_s3 (< l1_s0 l1_s2)))
+                                 (let ((l1_s5 (>= l1_s1 l1_s4)))
+                                 (let ((l1_s6 (or l1_s3 l1_s5)))
+                                 (let ((l1_s8 (seq.unit l1_s0)))
+                                 (let ((l1_s9 (+ l1_s0 l1_s1)))
+                                 (let ((l1_s10 (|EnumSymbolic.Integer.enumFromThenTo.down @(SBV Integer -> SBV Integer -> SBV Integer -> SBV [Integer])| l1_s9 l1_s1 l1_s2)))
+                                 (let ((l1_s11 (seq.++ l1_s8 l1_s10)))
+                                 (let ((l1_s12 (ite l1_s6 l1_s7 l1_s11)))
+                                 l1_s12)))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () (Seq Int) (|EnumSymbolic.Integer.enumFromThenTo.down @(SBV Integer -> SBV Integer -> SBV Integer -> SBV [Integer])| s1 s2 s0))
+[GOOD] (define-fun s4 () Int (seq.len s3))
+[GOOD] (define-fun s6 () Bool (>= s4 s5))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s6)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 6))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+
+RESULT:
+Satisfiable. Model:
+  s0 = 6 :: Integer
diff --git a/SBVTestSuite/GoldFiles/recursive3_badMeasure.gold b/SBVTestSuite/GoldFiles/recursive3_badMeasure.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/recursive3_badMeasure.gold
@@ -0,0 +1,94 @@
+[MEASURE] Verifying termination measures for: badSum @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: badSum @(SBV Integer -> SBV Integer)
+[MEASURE] badSum @(SBV Integer -> SBV Integer): verifying with 0 helper(s)
+[MEASURE] badSum @(SBV Integer -> SBV Integer): 0 helper axiom(s) collected, checking measure
+[MEASURE] replayDAG {badSum @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s0 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert false)
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {badSum @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s0 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Bool (not s3))
+[GOOD] (define-fun s9 () Bool (=> s8 false))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s9))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[SEND] (get-value (s2))
+[RECV] ((s2 1))
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+[SEND] (get-value (s5))
+[RECV] ((s5 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+
+EXCEPTION:
+
+*** Data.SBV: Termination measure does not strictly decrease at a recursive call site.
+***
+***   Function: badSum :: SBV Integer -> SBV Integer
+***
+***   Falsifiable. Counter-example:
+***     arg    = 1 :: Integer
+***     before = 1 :: Integer
+***     then   = 1 :: Integer
+***
+*** The measure must strictly decrease at every recursive call.
+
diff --git a/SBVTestSuite/GoldFiles/recursive4_mcCarthy91.gold b/SBVTestSuite/GoldFiles/recursive4_mcCarthy91.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/recursive4_mcCarthy91.gold
@@ -0,0 +1,175 @@
+[MEASURE] Verifying termination measures for: mcCarthy91 @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: mcCarthy91 @(SBV Integer -> SBV Integer)
+[MEASURE] mcCarthy91 @(SBV Integer -> SBV Integer) (contract): verifying with 0 helper(s)
+[MEASURE] mcCarthy91 @(SBV Integer -> SBV Integer) (contract): 0 helper axiom(s) collected, checking measure+contract
+[MEASURE] replayDAG {mcCarthy91 @(SBV Integer -> SBV Integer)}: replaying 6 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 10)
+[GOOD] (define-fun s2 () Int 11)
+[GOOD] (define-fun s3 () Int 100)
+[GOOD] (define-fun s10 () Int 0)
+[GOOD] (define-fun s11 () Int 101)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s7 () Int) ; tracks user variable "__internal_sbv_s7"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (> s0 s3))
+[GOOD] (define-fun s5 () Int (- s0 s1))
+[GOOD] (define-fun s6 () Int (+ s0 s2))
+[GOOD] (define-fun s9 () Int (ite s4 s5 s8))
+[GOOD] (define-fun s12 () Int (- s11 s0))
+[GOOD] (define-fun s13 () Bool (<= s10 s12))
+[GOOD] (define-fun s14 () Int (ite s13 s12 s10))
+[GOOD] (define-fun s15 () Bool (>= s14 s10))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s15))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {mcCarthy91 @(SBV Integer -> SBV Integer)}: replaying 6 node(s)
+[MEASURE] replayDAG {mcCarthy91 @(SBV Integer -> SBV Integer)}: replaying 6 node(s)
+[MEASURE] replayDAG {mcCarthy91 @(SBV Integer -> SBV Integer)}: replaying 6 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 10)
+[GOOD] (define-fun s2 () Int 11)
+[GOOD] (define-fun s3 () Int 100)
+[GOOD] (define-fun s25 () Int 91)
+[GOOD] (define-fun s31 () Int 0)
+[GOOD] (define-fun s32 () Int 101)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s7 () Int) ; tracks user variable "__internal_sbv_s7"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] (declare-fun s13 () Int) ; tracks user variable "__internal_sbv_s13"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] (declare-fun s20 () Int) ; tracks user variable "__internal_sbv_s20"
+[GOOD] (declare-fun s21 () Int) ; tracks user variable "__internal_sbv_s21"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (> s0 s3))
+[GOOD] (define-fun s5 () Int (- s0 s1))
+[GOOD] (define-fun s6 () Int (+ s0 s2))
+[GOOD] (define-fun s9 () Int (ite s4 s5 s8))
+[GOOD] (define-fun s10 () Bool (> s6 s3))
+[GOOD] (define-fun s11 () Int (- s6 s1))
+[GOOD] (define-fun s12 () Int (+ s2 s6))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Bool (= s7 s15))
+[GOOD] (define-fun s17 () Bool (> s7 s3))
+[GOOD] (define-fun s18 () Int (- s7 s1))
+[GOOD] (define-fun s19 () Int (+ s2 s7))
+[GOOD] (define-fun s22 () Int (ite s17 s18 s21))
+[GOOD] (define-fun s23 () Bool (= s8 s22))
+[GOOD] (define-fun s24 () Bool (<= s6 s3))
+[GOOD] (define-fun s26 () Bool (= s7 s25))
+[GOOD] (define-fun s27 () Bool (=> s24 s26))
+[GOOD] (define-fun s28 () Bool (<= s7 s3))
+[GOOD] (define-fun s29 () Bool (= s8 s25))
+[GOOD] (define-fun s30 () Bool (=> s28 s29))
+[GOOD] (define-fun s33 () Int (- s32 s0))
+[GOOD] (define-fun s34 () Bool (<= s31 s33))
+[GOOD] (define-fun s35 () Int (ite s34 s33 s31))
+[GOOD] (define-fun s36 () Int (- s32 s6))
+[GOOD] (define-fun s37 () Bool (<= s31 s36))
+[GOOD] (define-fun s38 () Int (ite s37 s36 s31))
+[GOOD] (define-fun s39 () Int (- s32 s7))
+[GOOD] (define-fun s40 () Bool (<= s31 s39))
+[GOOD] (define-fun s41 () Int (ite s40 s39 s31))
+[GOOD] (define-fun s42 () Bool (not s4))
+[GOOD] (define-fun s43 () Bool (> s35 s38))
+[GOOD] (define-fun s44 () Bool (=> s42 s43))
+[GOOD] (define-fun s45 () Bool (> s35 s41))
+[GOOD] (define-fun s46 () Bool (=> s42 s45))
+[GOOD] (define-fun s47 () Bool (and s44 s46))
+[GOOD] (define-fun s48 () Bool (<= s0 s3))
+[GOOD] (define-fun s49 () Bool (= s9 s25))
+[GOOD] (define-fun s50 () Bool (=> s48 s49))
+[GOOD] (define-fun s51 () Bool (and s47 s50))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s16)
+[GOOD] (assert s23)
+[GOOD] (assert s27)
+[GOOD] (assert s30)
+[GOOD] (assert (not s51))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] Passed (terminating): mcCarthy91 @(SBV Integer -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 91)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |mcCarthy91 @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger [Recursive]
+[GOOD] (define-fun-rec |mcCarthy91 @(SBV Integer -> SBV Integer)| ((l1_s0 Int)) Int
+                                 (let ((l1_s1 100))
+                                 (let ((l1_s3 10))
+                                 (let ((l1_s5 11))
+                                 (let ((l1_s2 (> l1_s0 l1_s1)))
+                                 (let ((l1_s4 (- l1_s0 l1_s3)))
+                                 (let ((l1_s6 (+ l1_s0 l1_s5)))
+                                 (let ((l1_s7 (|mcCarthy91 @(SBV Integer -> SBV Integer)| l1_s6)))
+                                 (let ((l1_s8 (|mcCarthy91 @(SBV Integer -> SBV Integer)| l1_s7)))
+                                 (let ((l1_s9 (ite l1_s2 l1_s4 l1_s8)))
+                                 l1_s9))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Int (|mcCarthy91 @(SBV Integer -> SBV Integer)| s0))
+[GOOD] (define-fun s3 () Bool (= s1 s2))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s3)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 101))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+
+RESULT:
+Satisfiable. Model:
+  s0 = 101 :: Integer
diff --git a/SBVTestSuite/GoldFiles/recursive5_badContract.gold b/SBVTestSuite/GoldFiles/recursive5_badContract.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/recursive5_badContract.gold
@@ -0,0 +1,159 @@
+[MEASURE] Verifying termination measures for: mc91bad @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: mc91bad @(SBV Integer -> SBV Integer)
+[MEASURE] mc91bad @(SBV Integer -> SBV Integer) (contract): verifying with 0 helper(s)
+[MEASURE] mc91bad @(SBV Integer -> SBV Integer) (contract): 0 helper axiom(s) collected, checking measure+contract
+[MEASURE] replayDAG {mc91bad @(SBV Integer -> SBV Integer)}: replaying 6 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 10)
+[GOOD] (define-fun s2 () Int 11)
+[GOOD] (define-fun s3 () Int 100)
+[GOOD] (define-fun s10 () Int 0)
+[GOOD] (define-fun s11 () Int 101)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s7 () Int) ; tracks user variable "__internal_sbv_s7"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (> s0 s3))
+[GOOD] (define-fun s5 () Int (- s0 s1))
+[GOOD] (define-fun s6 () Int (+ s0 s2))
+[GOOD] (define-fun s9 () Int (ite s4 s5 s8))
+[GOOD] (define-fun s12 () Int (- s11 s0))
+[GOOD] (define-fun s13 () Bool (<= s10 s12))
+[GOOD] (define-fun s14 () Int (ite s13 s12 s10))
+[GOOD] (define-fun s15 () Bool (>= s14 s10))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s15))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {mc91bad @(SBV Integer -> SBV Integer)}: replaying 6 node(s)
+[MEASURE] replayDAG {mc91bad @(SBV Integer -> SBV Integer)}: replaying 6 node(s)
+[MEASURE] replayDAG {mc91bad @(SBV Integer -> SBV Integer)}: replaying 6 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 10)
+[GOOD] (define-fun s2 () Int 11)
+[GOOD] (define-fun s3 () Int 100)
+[GOOD] (define-fun s24 () Int 0)
+[GOOD] (define-fun s27 () Int 101)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s7 () Int) ; tracks user variable "__internal_sbv_s7"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] (declare-fun s13 () Int) ; tracks user variable "__internal_sbv_s13"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] (declare-fun s20 () Int) ; tracks user variable "__internal_sbv_s20"
+[GOOD] (declare-fun s21 () Int) ; tracks user variable "__internal_sbv_s21"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (> s0 s3))
+[GOOD] (define-fun s5 () Int (- s0 s1))
+[GOOD] (define-fun s6 () Int (+ s0 s2))
+[GOOD] (define-fun s9 () Int (ite s4 s5 s8))
+[GOOD] (define-fun s10 () Bool (> s6 s3))
+[GOOD] (define-fun s11 () Int (- s6 s1))
+[GOOD] (define-fun s12 () Int (+ s2 s6))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Bool (= s7 s15))
+[GOOD] (define-fun s17 () Bool (> s7 s3))
+[GOOD] (define-fun s18 () Int (- s7 s1))
+[GOOD] (define-fun s19 () Int (+ s2 s7))
+[GOOD] (define-fun s22 () Int (ite s17 s18 s21))
+[GOOD] (define-fun s23 () Bool (= s8 s22))
+[GOOD] (define-fun s25 () Bool (= s7 s24))
+[GOOD] (define-fun s26 () Bool (= s8 s24))
+[GOOD] (define-fun s28 () Int (- s27 s0))
+[GOOD] (define-fun s29 () Bool (<= s24 s28))
+[GOOD] (define-fun s30 () Int (ite s29 s28 s24))
+[GOOD] (define-fun s31 () Int (- s27 s6))
+[GOOD] (define-fun s32 () Bool (<= s24 s31))
+[GOOD] (define-fun s33 () Int (ite s32 s31 s24))
+[GOOD] (define-fun s34 () Int (- s27 s7))
+[GOOD] (define-fun s35 () Bool (<= s24 s34))
+[GOOD] (define-fun s36 () Int (ite s35 s34 s24))
+[GOOD] (define-fun s37 () Bool (not s4))
+[GOOD] (define-fun s38 () Bool (> s30 s33))
+[GOOD] (define-fun s39 () Bool (=> s37 s38))
+[GOOD] (define-fun s40 () Bool (> s30 s36))
+[GOOD] (define-fun s41 () Bool (=> s37 s40))
+[GOOD] (define-fun s42 () Bool (and s39 s41))
+[GOOD] (define-fun s43 () Bool (= s9 s24))
+[GOOD] (define-fun s44 () Bool (and s42 s43))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s16)
+[GOOD] (assert s23)
+[GOOD] (assert s25)
+[GOOD] (assert s26)
+[GOOD] (assert (not s44))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s30))
+[RECV] ((s30 92))
+[SEND] (get-value (s33))
+[RECV] ((s33 81))
+[SEND] (get-value (s36))
+[RECV] ((s36 101))
+[SEND] (get-value (s0))
+[RECV] ((s0 9))
+[SEND] (get-value (s7))
+[RECV] ((s7 0))
+[SEND] (get-value (s8))
+[RECV] ((s8 0))
+[SEND] (get-value (s13))
+[RECV] ((s13 0))
+[SEND] (get-value (s14))
+[RECV] ((s14 0))
+[SEND] (get-value (s20))
+[RECV] ((s20 0))
+[SEND] (get-value (s21))
+[RECV] ((s21 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+
+EXCEPTION:
+
+*** Data.SBV: Measure+contract verification failed.
+***
+***   Function: mc91bad :: SBV Integer -> SBV Integer
+***
+***   Falsifiable. Counter-example:
+***     arg     =   9 :: Integer
+***     before  =  92 :: Integer
+***     then[1] =  81 :: Integer
+***     then[2] = 101 :: Integer
+***
+*** The measure must strictly decrease at every recursive call,
+*** and the contract must hold for the function's output.
+*** The inductive hypothesis provides the contract on recursive call
+*** results for inputs with strictly smaller measure.
+
diff --git a/SBVTestSuite/GoldFiles/recursive6_uselessContract.gold b/SBVTestSuite/GoldFiles/recursive6_uselessContract.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/recursive6_uselessContract.gold
@@ -0,0 +1,153 @@
+[MEASURE] Verifying termination measures for: mc91triv @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: mc91triv @(SBV Integer -> SBV Integer)
+[MEASURE] mc91triv @(SBV Integer -> SBV Integer) (contract): verifying with 0 helper(s)
+[MEASURE] mc91triv @(SBV Integer -> SBV Integer) (contract): 0 helper axiom(s) collected, checking measure+contract
+[MEASURE] replayDAG {mc91triv @(SBV Integer -> SBV Integer)}: replaying 6 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 10)
+[GOOD] (define-fun s2 () Int 11)
+[GOOD] (define-fun s3 () Int 100)
+[GOOD] (define-fun s10 () Int 0)
+[GOOD] (define-fun s11 () Int 101)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s7 () Int) ; tracks user variable "__internal_sbv_s7"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (> s0 s3))
+[GOOD] (define-fun s5 () Int (- s0 s1))
+[GOOD] (define-fun s6 () Int (+ s0 s2))
+[GOOD] (define-fun s9 () Int (ite s4 s5 s8))
+[GOOD] (define-fun s12 () Int (- s11 s0))
+[GOOD] (define-fun s13 () Bool (<= s10 s12))
+[GOOD] (define-fun s14 () Int (ite s13 s12 s10))
+[GOOD] (define-fun s15 () Bool (>= s14 s10))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s15))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {mc91triv @(SBV Integer -> SBV Integer)}: replaying 6 node(s)
+[MEASURE] replayDAG {mc91triv @(SBV Integer -> SBV Integer)}: replaying 6 node(s)
+[MEASURE] replayDAG {mc91triv @(SBV Integer -> SBV Integer)}: replaying 6 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 10)
+[GOOD] (define-fun s2 () Int 11)
+[GOOD] (define-fun s3 () Int 100)
+[GOOD] (define-fun s24 () Int 0)
+[GOOD] (define-fun s25 () Int 101)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s7 () Int) ; tracks user variable "__internal_sbv_s7"
+[GOOD] (declare-fun s8 () Int) ; tracks user variable "__internal_sbv_s8"
+[GOOD] (declare-fun s13 () Int) ; tracks user variable "__internal_sbv_s13"
+[GOOD] (declare-fun s14 () Int) ; tracks user variable "__internal_sbv_s14"
+[GOOD] (declare-fun s20 () Int) ; tracks user variable "__internal_sbv_s20"
+[GOOD] (declare-fun s21 () Int) ; tracks user variable "__internal_sbv_s21"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s4 () Bool (> s0 s3))
+[GOOD] (define-fun s5 () Int (- s0 s1))
+[GOOD] (define-fun s6 () Int (+ s0 s2))
+[GOOD] (define-fun s9 () Int (ite s4 s5 s8))
+[GOOD] (define-fun s10 () Bool (> s6 s3))
+[GOOD] (define-fun s11 () Int (- s6 s1))
+[GOOD] (define-fun s12 () Int (+ s2 s6))
+[GOOD] (define-fun s15 () Int (ite s10 s11 s14))
+[GOOD] (define-fun s16 () Bool (= s7 s15))
+[GOOD] (define-fun s17 () Bool (> s7 s3))
+[GOOD] (define-fun s18 () Int (- s7 s1))
+[GOOD] (define-fun s19 () Int (+ s2 s7))
+[GOOD] (define-fun s22 () Int (ite s17 s18 s21))
+[GOOD] (define-fun s23 () Bool (= s8 s22))
+[GOOD] (define-fun s26 () Int (- s25 s0))
+[GOOD] (define-fun s27 () Bool (<= s24 s26))
+[GOOD] (define-fun s28 () Int (ite s27 s26 s24))
+[GOOD] (define-fun s29 () Int (- s25 s6))
+[GOOD] (define-fun s30 () Bool (<= s24 s29))
+[GOOD] (define-fun s31 () Int (ite s30 s29 s24))
+[GOOD] (define-fun s32 () Int (- s25 s7))
+[GOOD] (define-fun s33 () Bool (<= s24 s32))
+[GOOD] (define-fun s34 () Int (ite s33 s32 s24))
+[GOOD] (define-fun s35 () Bool (not s4))
+[GOOD] (define-fun s36 () Bool (> s28 s31))
+[GOOD] (define-fun s37 () Bool (=> s35 s36))
+[GOOD] (define-fun s38 () Bool (> s28 s34))
+[GOOD] (define-fun s39 () Bool (=> s35 s38))
+[GOOD] (define-fun s40 () Bool (and s37 s39))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s16)
+[GOOD] (assert s23)
+[GOOD] (assert (not s40))
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s28))
+[RECV] ((s28 12))
+[SEND] (get-value (s31))
+[RECV] ((s31 1))
+[SEND] (get-value (s34))
+[RECV] ((s34 12))
+[SEND] (get-value (s0))
+[RECV] ((s0 89))
+[SEND] (get-value (s7))
+[RECV] ((s7 89))
+[SEND] (get-value (s8))
+[RECV] ((s8 0))
+[SEND] (get-value (s13))
+[RECV] ((s13 0))
+[SEND] (get-value (s14))
+[RECV] ((s14 89))
+[SEND] (get-value (s20))
+[RECV] ((s20 0))
+[SEND] (get-value (s21))
+[RECV] ((s21 0))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+
+EXCEPTION:
+
+*** Data.SBV: Measure+contract verification failed.
+***
+***   Function: mc91triv :: SBV Integer -> SBV Integer
+***
+***   Falsifiable. Counter-example:
+***     arg     = 89 :: Integer
+***     before  = 12 :: Integer
+***     then[1] =  1 :: Integer
+***     then[2] = 12 :: Integer
+***
+*** The measure must strictly decrease at every recursive call,
+*** and the contract must hold for the function's output.
+*** The inductive hypothesis provides the contract on recursive call
+*** results for inputs with strictly smaller measure.
+
diff --git a/SBVTestSuite/GoldFiles/recursive7_productive.gold b/SBVTestSuite/GoldFiles/recursive7_productive.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/recursive7_productive.gold
@@ -0,0 +1,54 @@
+[MEASURE] Verifying termination measures for: rep @(SBV Integer -> SBV Integer -> SBV [Integer])
+[MEASURE] Checking: rep @(SBV Integer -> SBV Integer -> SBV [Integer])
+[MEASURE] rep @(SBV Integer -> SBV Integer -> SBV [Integer]): productive (all recursive calls are guarded by constructors)
+[MEASURE] Passed (productive): rep @(SBV Integer -> SBV Integer -> SBV [Integer])
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 3)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |rep @(SBV Integer -> SBV Integer -> SBV [Integer])| :: SInteger -> SInteger -> [SInteger] [Recursive]
+[GOOD] (define-fun-rec |rep @(SBV Integer -> SBV Integer -> SBV [Integer])| ((l1_s0 Int) (l1_s1 Int)) (Seq Int)
+                                 (let ((l1_s2 0))
+                                 (let ((l1_s4 (as seq.empty (Seq Int))))
+                                 (let ((l1_s6 1))
+                                 (let ((l1_s3 (<= l1_s0 l1_s2)))
+                                 (let ((l1_s5 (seq.unit l1_s1)))
+                                 (let ((l1_s7 (- l1_s0 l1_s6)))
+                                 (let ((l1_s8 (|rep @(SBV Integer -> SBV Integer -> SBV [Integer])| l1_s7 l1_s1)))
+                                 (let ((l1_s9 (seq.++ l1_s5 l1_s8)))
+                                 (let ((l1_s10 (ite l1_s3 l1_s4 l1_s9)))
+                                 l1_s10))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () (Seq Int) (|rep @(SBV Integer -> SBV Integer -> SBV [Integer])| s1 s0))
+[GOOD] (define-fun s3 () Int (seq.len s2))
+[GOOD] (define-fun s4 () Bool (= s1 s3))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s4)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 4))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+
+RESULT:
+Satisfiable. Model:
+  s0 = 4 :: Integer
diff --git a/SBVTestSuite/GoldFiles/recursive8_badProductive.gold b/SBVTestSuite/GoldFiles/recursive8_badProductive.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/recursive8_badProductive.gold
@@ -0,0 +1,12 @@
+[MEASURE] Verifying termination measures for: bad @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: bad @(SBV Integer -> SBV Integer)
+
+EXCEPTION:
+
+*** Data.SBV: Function marked as productive is not guarded-recursive.
+***
+***   Function: bad :: SBV Integer -> SBV Integer
+***
+*** Every recursive call must be a direct argument to a data constructor
+*** (list cons, ADT constructor, etc.) to ensure productivity.
+
diff --git a/SBVTestSuite/GoldFiles/recursive9_productive2.gold b/SBVTestSuite/GoldFiles/recursive9_productive2.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/recursive9_productive2.gold
@@ -0,0 +1,56 @@
+[MEASURE] Verifying termination measures for: countdown @(SBV Integer -> SBV [Integer])
+[MEASURE] Checking: countdown @(SBV Integer -> SBV [Integer])
+[MEASURE] countdown @(SBV Integer -> SBV [Integer]): productive (all recursive calls are guarded by constructors)
+[MEASURE] Passed (productive): countdown @(SBV Integer -> SBV [Integer])
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s2 () Int 0)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |countdown @(SBV Integer -> SBV [Integer])| :: SInteger -> [SInteger] [Recursive]
+[GOOD] (define-fun-rec |countdown @(SBV Integer -> SBV [Integer])| ((l1_s0 Int)) (Seq Int)
+                                 (let ((l1_s1 0))
+                                 (let ((l1_s3 (seq.unit 0)))
+                                 (let ((l1_s5 1))
+                                 (let ((l1_s2 (<= l1_s0 l1_s1)))
+                                 (let ((l1_s4 (seq.unit l1_s0)))
+                                 (let ((l1_s6 (- l1_s0 l1_s5)))
+                                 (let ((l1_s7 (|countdown @(SBV Integer -> SBV [Integer])| l1_s6)))
+                                 (let ((l1_s8 (seq.++ l1_s4 l1_s7)))
+                                 (let ((l1_s9 (ite l1_s2 l1_s3 l1_s8)))
+                                 l1_s9))))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () (Seq Int) (|countdown @(SBV Integer -> SBV [Integer])| s0))
+[GOOD] (define-fun s3 () Int (seq.nth s1 s2))
+[GOOD] (define-fun s4 () Bool (= s0 s3))
+[GOOD] (define-fun s5 () Bool (> s0 s2))
+[GOOD] (define-fun s6 () Bool (and s4 s5))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s6)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+
+RESULT:
+Satisfiable. Model:
+  s0 = 1 :: Integer
diff --git a/SBVTestSuite/GoldFiles/safe1.gold b/SBVTestSuite/GoldFiles/safe1.gold
--- a/SBVTestSuite/GoldFiles/safe1.gold
+++ b/SBVTestSuite/GoldFiles/safe1.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/safe2.gold b/SBVTestSuite/GoldFiles/safe2.gold
--- a/SBVTestSuite/GoldFiles/safe2.gold
+++ b/SBVTestSuite/GoldFiles/safe2.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/selChecked.gold b/SBVTestSuite/GoldFiles/selChecked.gold
--- a/SBVTestSuite/GoldFiles/selChecked.gold
+++ b/SBVTestSuite/GoldFiles/selChecked.gold
@@ -12,11 +12,11 @@
 selChecked.o: selChecked.c selChecked.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
-selChecked_driver.o: selChecked_driver.c
+selChecked_driver.o: selChecked_driver.c selChecked.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
 selChecked_driver: selChecked.o selChecked_driver.o
-	${CC} ${CCFLAGS} $^ -o $@
+	${CC} ${CCFLAGS} $^ -o $@ ${LDFLAGS}
 
 clean:
 	rm -f *.o
@@ -27,9 +27,10 @@
 == BEGIN: "selChecked.h" ================
 /* Header file for selChecked. Automatically generated by SBV. Do not edit! */
 
-#ifndef __selChecked__HEADER_INCLUDED__
-#define __selChecked__HEADER_INCLUDED__
+#ifndef SBV_GENERATED_selChecked_HEADER_INCLUDED
+#define SBV_GENERATED_selChecked_HEADER_INCLUDED
 
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <inttypes.h>
@@ -38,6 +39,13 @@
 #include <string.h>
 #include <math.h>
 
+/* Floating-point calling convention:
+ * Enter generated code in FE_TONEAREST (round-to-nearest, ties-to-even).
+ * Callbacks must preserve this mode before returning or re-entering.
+ * Generated code does not check or change the hardware rounding mode.
+ * Custom builds must disable implicit FP contraction, including at LTO link time.
+ */
+
 /* The boolean type */
 typedef bool SBool;
 
@@ -62,7 +70,7 @@
 /* Entry point prototype: */
 SWord8 selChecked(const SWord8 x);
 
-#endif /* __selChecked__HEADER_INCLUDED__ */
+#endif /* SBV_GENERATED_selChecked_HEADER_INCLUDED */
 == END: "selChecked.h" ==================
 == BEGIN: "selChecked_driver.c" ================
 /* Example driver program for selChecked. */
@@ -73,9 +81,9 @@
 
 int main(void)
 {
-  const SWord8 __result = selChecked(65);
+  const SWord8 sbv_result = selChecked(65);
 
-  printf("selChecked(65) = %"PRIu8"\n", __result);
+  printf("selChecked(65) = %"PRIu8"\n", sbv_result);
 
   return 0;
 }
@@ -85,14 +93,31 @@
 
 #include "selChecked.h"
 
-SWord8 selChecked(const SWord8 x)
+/* Exact bit-vector runtime. All arithmetic is modulo the declared width. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_u8_add(SWord8 a, SWord8 b)
 {
-  const SWord8 s0 = x;
-  const SWord8 s3 = s0 + 2;
+  const SWord8 bits = (SWord8) ((((uint64_t) (SWord8) a) + ((uint64_t) (SWord8) b)) & UINT64_C(0x00000000000000ff));
+  return (SWord8) bits;
+}
+
+
+SWord8 selChecked(const SWord8 sbv_input_0)
+{
+  const SWord8 s0 = sbv_input_0;
+  const SWord8 s3 = sbv_bv_u8_add(s0, 2);
+        SWord8 s5;
   const SWord8 table0[] = {
        1, s3
   };
-  const SWord8 s5 = s0 >= 2 ? 3 : table0[s0];
+  s5 = s0 >= 2 ? 3 : table0[s0];
 
   return s5;
 }
diff --git a/SBVTestSuite/GoldFiles/selUnchecked.gold b/SBVTestSuite/GoldFiles/selUnchecked.gold
--- a/SBVTestSuite/GoldFiles/selUnchecked.gold
+++ b/SBVTestSuite/GoldFiles/selUnchecked.gold
@@ -12,11 +12,11 @@
 selUnChecked.o: selUnChecked.c selUnChecked.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
-selUnChecked_driver.o: selUnChecked_driver.c
+selUnChecked_driver.o: selUnChecked_driver.c selUnChecked.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
 selUnChecked_driver: selUnChecked.o selUnChecked_driver.o
-	${CC} ${CCFLAGS} $^ -o $@
+	${CC} ${CCFLAGS} $^ -o $@ ${LDFLAGS}
 
 clean:
 	rm -f *.o
@@ -27,9 +27,10 @@
 == BEGIN: "selUnChecked.h" ================
 /* Header file for selUnChecked. Automatically generated by SBV. Do not edit! */
 
-#ifndef __selUnChecked__HEADER_INCLUDED__
-#define __selUnChecked__HEADER_INCLUDED__
+#ifndef SBV_GENERATED_selUnChecked_HEADER_INCLUDED
+#define SBV_GENERATED_selUnChecked_HEADER_INCLUDED
 
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <inttypes.h>
@@ -38,6 +39,13 @@
 #include <string.h>
 #include <math.h>
 
+/* Floating-point calling convention:
+ * Enter generated code in FE_TONEAREST (round-to-nearest, ties-to-even).
+ * Callbacks must preserve this mode before returning or re-entering.
+ * Generated code does not check or change the hardware rounding mode.
+ * Custom builds must disable implicit FP contraction, including at LTO link time.
+ */
+
 /* The boolean type */
 typedef bool SBool;
 
@@ -62,7 +70,7 @@
 /* Entry point prototype: */
 SWord8 selUnChecked(const SWord8 x);
 
-#endif /* __selUnChecked__HEADER_INCLUDED__ */
+#endif /* SBV_GENERATED_selUnChecked_HEADER_INCLUDED */
 == END: "selUnChecked.h" ==================
 == BEGIN: "selUnChecked_driver.c" ================
 /* Example driver program for selUnChecked. */
@@ -73,9 +81,9 @@
 
 int main(void)
 {
-  const SWord8 __result = selUnChecked(65);
+  const SWord8 sbv_result = selUnChecked(65);
 
-  printf("selUnChecked(65) = %"PRIu8"\n", __result);
+  printf("selUnChecked(65) = %"PRIu8"\n", sbv_result);
 
   return 0;
 }
@@ -85,14 +93,31 @@
 
 #include "selUnChecked.h"
 
-SWord8 selUnChecked(const SWord8 x)
+/* Exact bit-vector runtime. All arithmetic is modulo the declared width. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_u8_add(SWord8 a, SWord8 b)
 {
-  const SWord8 s0 = x;
-  const SWord8 s3 = s0 + 2;
+  const SWord8 bits = (SWord8) ((((uint64_t) (SWord8) a) + ((uint64_t) (SWord8) b)) & UINT64_C(0x00000000000000ff));
+  return (SWord8) bits;
+}
+
+
+SWord8 selUnChecked(const SWord8 sbv_input_0)
+{
+  const SWord8 s0 = sbv_input_0;
+  const SWord8 s3 = sbv_bv_u8_add(s0, 2);
+        SWord8 s5;
   const SWord8 table0[] = {
        1, s3
   };
-  const SWord8 s5 = table0[s0];
+  s5 = table0[s0];
 
   return s5;
 }
diff --git a/SBVTestSuite/GoldFiles/seqConcat.gold b/SBVTestSuite/GoldFiles/seqConcat.gold
--- a/SBVTestSuite/GoldFiles/seqConcat.gold
+++ b/SBVTestSuite/GoldFiles/seqConcat.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/seqConcatBad.gold b/SBVTestSuite/GoldFiles/seqConcatBad.gold
--- a/SBVTestSuite/GoldFiles/seqConcatBad.gold
+++ b/SBVTestSuite/GoldFiles/seqConcatBad.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/seqExamples1.gold b/SBVTestSuite/GoldFiles/seqExamples1.gold
--- a/SBVTestSuite/GoldFiles/seqExamples1.gold
+++ b/SBVTestSuite/GoldFiles/seqExamples1.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/seqExamples2.gold b/SBVTestSuite/GoldFiles/seqExamples2.gold
--- a/SBVTestSuite/GoldFiles/seqExamples2.gold
+++ b/SBVTestSuite/GoldFiles/seqExamples2.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/seqExamples3.gold b/SBVTestSuite/GoldFiles/seqExamples3.gold
--- a/SBVTestSuite/GoldFiles/seqExamples3.gold
+++ b/SBVTestSuite/GoldFiles/seqExamples3.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/seqExamples4.gold b/SBVTestSuite/GoldFiles/seqExamples4.gold
--- a/SBVTestSuite/GoldFiles/seqExamples4.gold
+++ b/SBVTestSuite/GoldFiles/seqExamples4.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/seqExamples5.gold b/SBVTestSuite/GoldFiles/seqExamples5.gold
--- a/SBVTestSuite/GoldFiles/seqExamples5.gold
+++ b/SBVTestSuite/GoldFiles/seqExamples5.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/seqExamples6.gold b/SBVTestSuite/GoldFiles/seqExamples6.gold
--- a/SBVTestSuite/GoldFiles/seqExamples6.gold
+++ b/SBVTestSuite/GoldFiles/seqExamples6.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/seqExamples7.gold b/SBVTestSuite/GoldFiles/seqExamples7.gold
--- a/SBVTestSuite/GoldFiles/seqExamples7.gold
+++ b/SBVTestSuite/GoldFiles/seqExamples7.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/seqExamples8.gold b/SBVTestSuite/GoldFiles/seqExamples8.gold
--- a/SBVTestSuite/GoldFiles/seqExamples8.gold
+++ b/SBVTestSuite/GoldFiles/seqExamples8.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/seqIndexOf.gold b/SBVTestSuite/GoldFiles/seqIndexOf.gold
--- a/SBVTestSuite/GoldFiles/seqIndexOf.gold
+++ b/SBVTestSuite/GoldFiles/seqIndexOf.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/seqIndexOfBad.gold b/SBVTestSuite/GoldFiles/seqIndexOfBad.gold
--- a/SBVTestSuite/GoldFiles/seqIndexOfBad.gold
+++ b/SBVTestSuite/GoldFiles/seqIndexOfBad.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/set_compl1.gold b/SBVTestSuite/GoldFiles/set_compl1.gold
--- a/SBVTestSuite/GoldFiles/set_compl1.gold
+++ b/SBVTestSuite/GoldFiles/set_compl1.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/set_delete1.gold b/SBVTestSuite/GoldFiles/set_delete1.gold
--- a/SBVTestSuite/GoldFiles/set_delete1.gold
+++ b/SBVTestSuite/GoldFiles/set_delete1.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/set_diff1.gold b/SBVTestSuite/GoldFiles/set_diff1.gold
--- a/SBVTestSuite/GoldFiles/set_diff1.gold
+++ b/SBVTestSuite/GoldFiles/set_diff1.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/set_disj1.gold b/SBVTestSuite/GoldFiles/set_disj1.gold
--- a/SBVTestSuite/GoldFiles/set_disj1.gold
+++ b/SBVTestSuite/GoldFiles/set_disj1.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/set_empty1.gold b/SBVTestSuite/GoldFiles/set_empty1.gold
--- a/SBVTestSuite/GoldFiles/set_empty1.gold
+++ b/SBVTestSuite/GoldFiles/set_empty1.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/set_full1.gold b/SBVTestSuite/GoldFiles/set_full1.gold
--- a/SBVTestSuite/GoldFiles/set_full1.gold
+++ b/SBVTestSuite/GoldFiles/set_full1.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/set_insert1.gold b/SBVTestSuite/GoldFiles/set_insert1.gold
--- a/SBVTestSuite/GoldFiles/set_insert1.gold
+++ b/SBVTestSuite/GoldFiles/set_insert1.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/set_intersect1.gold b/SBVTestSuite/GoldFiles/set_intersect1.gold
--- a/SBVTestSuite/GoldFiles/set_intersect1.gold
+++ b/SBVTestSuite/GoldFiles/set_intersect1.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/set_member1.gold b/SBVTestSuite/GoldFiles/set_member1.gold
--- a/SBVTestSuite/GoldFiles/set_member1.gold
+++ b/SBVTestSuite/GoldFiles/set_member1.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/set_notMember1.gold b/SBVTestSuite/GoldFiles/set_notMember1.gold
--- a/SBVTestSuite/GoldFiles/set_notMember1.gold
+++ b/SBVTestSuite/GoldFiles/set_notMember1.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/set_psubset1.gold b/SBVTestSuite/GoldFiles/set_psubset1.gold
--- a/SBVTestSuite/GoldFiles/set_psubset1.gold
+++ b/SBVTestSuite/GoldFiles/set_psubset1.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/set_subset1.gold b/SBVTestSuite/GoldFiles/set_subset1.gold
--- a/SBVTestSuite/GoldFiles/set_subset1.gold
+++ b/SBVTestSuite/GoldFiles/set_subset1.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
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
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has tuples, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
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
@@ -8,14 +8,16 @@
 [GOOD] (set-option :pp.max_depth      4294967295)
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
-[GOOD] (set-logic ALL) ; has user-defined sorts, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
-[GOOD] (declare-datatypes ((E 0)) (((A) (B) (C))))
-[GOOD] (define-fun E_constrIndex ((x E)) Int
-          (ite (= x A) 0 (ite (= x B) 1 2))
-       )
+[GOOD] (set-logic ALL) ; has user-defined data-types, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: E
+[GOOD] (declare-datatype E (
+           (A)
+           (B)
+           (C)
+       ))
 [GOOD] ; --- literal constants ---
 [GOOD] ; --- top level inputs ---
 [GOOD] (declare-fun s0 () (Array E Bool))
@@ -40,9 +42,9 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (store ((as const (Array E Bool)) false) B true)))
+[RECV] ((s0 (store ((as const (Array E Bool)) false) C true)))
 [GOOD] (push 1)
-[GOOD] (define-fun s3 () (Array E Bool) (store ((as const (Array E Bool)) false) B true))
+[GOOD] (define-fun s3 () (Array E Bool) (store ((as const (Array E Bool)) false) (as C E) true))
 [GOOD] (define-fun s4 () Bool (distinct s0 s3))
 [GOOD] (assert s4)
 Fast allSat, Looking for solution 3
@@ -51,52 +53,52 @@
 [SEND] (get-value (s0))
 [RECV] ((s0 (store ((as const (Array E Bool)) false) A true)))
 [GOOD] (push 1)
-[GOOD] (define-fun s5 () (Array E Bool) (store ((as const (Array E Bool)) false) A true))
+[GOOD] (define-fun s5 () (Array E Bool) (store ((as const (Array E Bool)) false) (as A E) true))
 [GOOD] (define-fun s6 () Bool (distinct s0 s5))
 [GOOD] (assert s6)
 Fast allSat, Looking for solution 4
 [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) A true) B true)))
 [GOOD] (push 1)
-[GOOD] (define-fun s7 () (Array E Bool) (store (store ((as const (Array E Bool)) false) C true) A true))
+[GOOD] (define-fun s7 () (Array E Bool) (store (store ((as const (Array E Bool)) false) (as B E) true) (as A E) true))
 [GOOD] (define-fun s8 () Bool (distinct s0 s7))
 [GOOD] (assert s8)
 Fast allSat, Looking for solution 5
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 ((as const (Array E Bool)) true)))
+[RECV] ((s0 (store ((as const (Array E Bool)) false) B true)))
 [GOOD] (push 1)
-[GOOD] (define-fun s9 () (Array E Bool) ((as const (Array E Bool)) true))
+[GOOD] (define-fun s9 () (Array E Bool) (store ((as const (Array E Bool)) false) (as B E) true))
 [GOOD] (define-fun s10 () Bool (distinct s0 s9))
 [GOOD] (assert s10)
 Fast allSat, Looking for solution 6
 [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 (store ((as const (Array E Bool)) true) A false)))
 [GOOD] (push 1)
-[GOOD] (define-fun s11 () (Array E Bool) (store (store ((as const (Array E Bool)) false) B true) A true))
+[GOOD] (define-fun s11 () (Array E Bool) (store ((as const (Array E Bool)) true) (as A E) false))
 [GOOD] (define-fun s12 () Bool (distinct s0 s11))
 [GOOD] (assert s12)
 Fast allSat, Looking for solution 7
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (store (store ((as const (Array E Bool)) false) C true) B 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 (store ((as const (Array E Bool)) false) C true) B true))
+[GOOD] (define-fun s13 () (Array E Bool) (store (store ((as const (Array E Bool)) false) (as C E) true) (as A E) true))
 [GOOD] (define-fun s14 () Bool (distinct s0 s13))
 [GOOD] (assert s14)
 Fast allSat, Looking for solution 8
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (store ((as const (Array E Bool)) false) C true)))
+[RECV] ((s0 (store (store (store ((as const (Array E Bool)) false) C true) A true) B true)))
 [GOOD] (push 1)
-[GOOD] (define-fun s15 () (Array E Bool) (store ((as const (Array E Bool)) false) C true))
+[GOOD] (define-fun s15 () (Array E Bool) (store (store (store ((as const (Array E Bool)) false) (as C E) true) (as B E) true) (as A E) true))
 [GOOD] (define-fun s16 () Bool (distinct s0 s15))
 [GOOD] (assert s16)
 Fast allSat, Looking for solution 9
@@ -115,19 +117,19 @@
 
 FINAL:
 Solution #1:
-  s0 = {C} :: {E}
+  s0 = {A,B,C} :: {E}
 Solution #2:
-  s0 = {B,C} :: {E}
+  s0 = {A,C} :: {E}
 Solution #3:
-  s0 = {A,B} :: {E}
+  s0 = U - {A} :: {E}
 Solution #4:
-  s0 = U :: {E}
+  s0 = {B} :: {E}
 Solution #5:
-  s0 = {A,C} :: {E}
+  s0 = {A,B} :: {E}
 Solution #6:
   s0 = {A} :: {E}
 Solution #7:
-  s0 = {B} :: {E}
+  s0 = {C} :: {E}
 Solution #8:
   s0 = {} :: {E}
 Found 8 different solutions.
diff --git a/SBVTestSuite/GoldFiles/set_uninterp2.gold b/SBVTestSuite/GoldFiles/set_uninterp2.gold
--- a/SBVTestSuite/GoldFiles/set_uninterp2.gold
+++ b/SBVTestSuite/GoldFiles/set_uninterp2.gold
@@ -8,14 +8,16 @@
 [GOOD] (set-option :pp.max_depth      4294967295)
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
-[GOOD] (set-logic ALL) ; has user-defined sorts, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
-[GOOD] (declare-datatypes ((E 0)) (((A) (B) (C))))
-[GOOD] (define-fun E_constrIndex ((x E)) Int
-          (ite (= x A) 0 (ite (= x B) 1 2))
-       )
+[GOOD] (set-logic ALL) ; has user-defined data-types, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: E
+[GOOD] (declare-datatype E (
+           (A)
+           (B)
+           (C)
+       ))
 [GOOD] ; --- literal constants ---
 [GOOD] ; --- top level inputs ---
 [GOOD] (declare-fun s0 () (Array E Bool)) ; tracks user variable "a"
@@ -32,12 +34,12 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (store ((as const (Array E Bool)) false) B true)))
+[RECV] ((s0 (store ((as const (Array E Bool)) false) C true)))
 [SEND] (get-value (s1))
 [RECV] ((s1 ((as const (Array E Bool)) false)))
 *** Solver   : Z3
 *** Exit code: ExitSuccess
 
 FINAL:
-({B},{})
+({C},{})
 DONE!
diff --git a/SBVTestSuite/GoldFiles/set_union1.gold b/SBVTestSuite/GoldFiles/set_union1.gold
--- a/SBVTestSuite/GoldFiles/set_union1.gold
+++ b/SBVTestSuite/GoldFiles/set_union1.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/sha256HashBlock.gold b/SBVTestSuite/GoldFiles/sha256HashBlock.gold
--- a/SBVTestSuite/GoldFiles/sha256HashBlock.gold
+++ b/SBVTestSuite/GoldFiles/sha256HashBlock.gold
@@ -12,2578 +12,2687 @@
 sha256HashBlock.o: sha256HashBlock.c sha256HashBlock.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
-sha256HashBlock_driver.o: sha256HashBlock_driver.c
-	${CC} ${CCFLAGS} -c $< -o $@
-
-sha256HashBlock_driver: sha256HashBlock.o sha256HashBlock_driver.o
-	${CC} ${CCFLAGS} $^ -o $@
-
-clean:
-	rm -f *.o
-
-veryclean: clean
-	rm -f sha256HashBlock_driver
-== END: "Makefile" ==================
-== BEGIN: "sha256HashBlock.h" ================
-/* Header file for sha256HashBlock. Automatically generated by SBV. Do not edit! */
-
-#ifndef __sha256HashBlock__HEADER_INCLUDED__
-#define __sha256HashBlock__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 prototype: */
-void sha256HashBlock(const SWord8 *hIn, const SWord8 *block,
-                     SWord8 *hash);
-
-#endif /* __sha256HashBlock__HEADER_INCLUDED__ */
-== END: "sha256HashBlock.h" ==================
-== BEGIN: "sha256HashBlock_driver.c" ================
-/* Example driver program for sha256HashBlock. */
-/* Automatically generated by SBV. Edit as you see fit! */
-
-#include <stdio.h>
-#include "sha256HashBlock.h"
-
-int main(void)
-{
-  const SWord8 hIn[32] = {
-      0x6a, 0x09, 0xe6, 0x67, 0xbb, 0x67, 0xae, 0x85, 0x3c, 0x6e, 0xf3,
-      0x72, 0xa5, 0x4f, 0xf5, 0x3a, 0x51, 0x0e, 0x52, 0x7f, 0x9b, 0x05,
-      0x68, 0x8c, 0x1f, 0x83, 0xd9, 0xab, 0x5b, 0xe0, 0xcd, 0x19
-  };
-
-  printf("Contents of input array hIn:\n");
-  int hIn_ctr;
-  for(hIn_ctr = 0; hIn_ctr < 32 ; ++hIn_ctr)
-    printf("  hIn[%2d] = 0x%02"PRIx8"\n", hIn_ctr ,hIn[hIn_ctr]);
-
-  const SWord8 block[64] = {
-      0x53, 0x42, 0x56, 0x20, 0x67, 0x6f, 0x65, 0x73, 0x20, 0x53, 0x48,
-      0x41, 0x32, 0x35, 0x36, 0x21, 0x21, 0x80, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88
-  };
-
-  printf("Contents of input array block:\n");
-  int block_ctr;
-  for(block_ctr = 0; block_ctr < 64 ; ++block_ctr)
-    printf("  block[%2d] = 0x%02"PRIx8"\n", block_ctr ,block[block_ctr]);
-
-  SWord8 hash[32];
-
-  sha256HashBlock(hIn, block, hash);
-
-  printf("sha256HashBlock(hIn, block, hash) ->\n");
-  int hash_ctr;
-  for(hash_ctr = 0; hash_ctr < 32 ; ++hash_ctr)
-    printf("  hash[%2d] = 0x%02"PRIx8"\n", hash_ctr ,hash[hash_ctr]);
-
-  return 0;
-}
-== END: "sha256HashBlock_driver.c" ==================
-== BEGIN: "sha256HashBlock.c" ================
-/* File: "sha256HashBlock.c". Automatically generated by SBV. Do not edit! */
-
-#include "sha256HashBlock.h"
-
-void sha256HashBlock(const SWord8 *hIn, const SWord8 *block,
-                     SWord8 *hash)
-{
-  const SWord8  s0 = hIn[0];
-  const SWord8  s1 = hIn[1];
-  const SWord8  s2 = hIn[2];
-  const SWord8  s3 = hIn[3];
-  const SWord8  s4 = hIn[4];
-  const SWord8  s5 = hIn[5];
-  const SWord8  s6 = hIn[6];
-  const SWord8  s7 = hIn[7];
-  const SWord8  s8 = hIn[8];
-  const SWord8  s9 = hIn[9];
-  const SWord8  s10 = hIn[10];
-  const SWord8  s11 = hIn[11];
-  const SWord8  s12 = hIn[12];
-  const SWord8  s13 = hIn[13];
-  const SWord8  s14 = hIn[14];
-  const SWord8  s15 = hIn[15];
-  const SWord8  s16 = hIn[16];
-  const SWord8  s17 = hIn[17];
-  const SWord8  s18 = hIn[18];
-  const SWord8  s19 = hIn[19];
-  const SWord8  s20 = hIn[20];
-  const SWord8  s21 = hIn[21];
-  const SWord8  s22 = hIn[22];
-  const SWord8  s23 = hIn[23];
-  const SWord8  s24 = hIn[24];
-  const SWord8  s25 = hIn[25];
-  const SWord8  s26 = hIn[26];
-  const SWord8  s27 = hIn[27];
-  const SWord8  s28 = hIn[28];
-  const SWord8  s29 = hIn[29];
-  const SWord8  s30 = hIn[30];
-  const SWord8  s31 = hIn[31];
-  const SWord8  s32 = block[0];
-  const SWord8  s33 = block[1];
-  const SWord8  s34 = block[2];
-  const SWord8  s35 = block[3];
-  const SWord8  s36 = block[4];
-  const SWord8  s37 = block[5];
-  const SWord8  s38 = block[6];
-  const SWord8  s39 = block[7];
-  const SWord8  s40 = block[8];
-  const SWord8  s41 = block[9];
-  const SWord8  s42 = block[10];
-  const SWord8  s43 = block[11];
-  const SWord8  s44 = block[12];
-  const SWord8  s45 = block[13];
-  const SWord8  s46 = block[14];
-  const SWord8  s47 = block[15];
-  const SWord8  s48 = block[16];
-  const SWord8  s49 = block[17];
-  const SWord8  s50 = block[18];
-  const SWord8  s51 = block[19];
-  const SWord8  s52 = block[20];
-  const SWord8  s53 = block[21];
-  const SWord8  s54 = block[22];
-  const SWord8  s55 = block[23];
-  const SWord8  s56 = block[24];
-  const SWord8  s57 = block[25];
-  const SWord8  s58 = block[26];
-  const SWord8  s59 = block[27];
-  const SWord8  s60 = block[28];
-  const SWord8  s61 = block[29];
-  const SWord8  s62 = block[30];
-  const SWord8  s63 = block[31];
-  const SWord8  s64 = block[32];
-  const SWord8  s65 = block[33];
-  const SWord8  s66 = block[34];
-  const SWord8  s67 = block[35];
-  const SWord8  s68 = block[36];
-  const SWord8  s69 = block[37];
-  const SWord8  s70 = block[38];
-  const SWord8  s71 = block[39];
-  const SWord8  s72 = block[40];
-  const SWord8  s73 = block[41];
-  const SWord8  s74 = block[42];
-  const SWord8  s75 = block[43];
-  const SWord8  s76 = block[44];
-  const SWord8  s77 = block[45];
-  const SWord8  s78 = block[46];
-  const SWord8  s79 = block[47];
-  const SWord8  s80 = block[48];
-  const SWord8  s81 = block[49];
-  const SWord8  s82 = block[50];
-  const SWord8  s83 = block[51];
-  const SWord8  s84 = block[52];
-  const SWord8  s85 = block[53];
-  const SWord8  s86 = block[54];
-  const SWord8  s87 = block[55];
-  const SWord8  s88 = block[56];
-  const SWord8  s89 = block[57];
-  const SWord8  s90 = block[58];
-  const SWord8  s91 = block[59];
-  const SWord8  s92 = block[60];
-  const SWord8  s93 = block[61];
-  const SWord8  s94 = block[62];
-  const SWord8  s95 = block[63];
-  const SWord16 s96 = (((SWord16) s0) << 8) | ((SWord16) s1);
-  const SWord16 s97 = (((SWord16) s2) << 8) | ((SWord16) s3);
-  const SWord32 s98 = (((SWord32) s96) << 16) | ((SWord32) s97);
-  const SWord16 s99 = (((SWord16) s16) << 8) | ((SWord16) s17);
-  const SWord16 s100 = (((SWord16) s18) << 8) | ((SWord16) s19);
-  const SWord32 s101 = (((SWord32) s99) << 16) | ((SWord32) s100);
-  const SWord16 s102 = (((SWord16) s4) << 8) | ((SWord16) s5);
-  const SWord16 s103 = (((SWord16) s6) << 8) | ((SWord16) s7);
-  const SWord32 s104 = (((SWord32) s102) << 16) | ((SWord32) s103);
-  const SWord16 s105 = (((SWord16) s20) << 8) | ((SWord16) s21);
-  const SWord16 s106 = (((SWord16) s22) << 8) | ((SWord16) s23);
-  const SWord32 s107 = (((SWord32) s105) << 16) | ((SWord32) s106);
-  const SWord16 s108 = (((SWord16) s8) << 8) | ((SWord16) s9);
-  const SWord16 s109 = (((SWord16) s10) << 8) | ((SWord16) s11);
-  const SWord32 s110 = (((SWord32) s108) << 16) | ((SWord32) s109);
-  const SWord16 s111 = (((SWord16) s24) << 8) | ((SWord16) s25);
-  const SWord16 s112 = (((SWord16) s26) << 8) | ((SWord16) s27);
-  const SWord32 s113 = (((SWord32) s111) << 16) | ((SWord32) s112);
-  const SWord16 s114 = (((SWord16) s12) << 8) | ((SWord16) s13);
-  const SWord16 s115 = (((SWord16) s14) << 8) | ((SWord16) s15);
-  const SWord32 s116 = (((SWord32) s114) << 16) | ((SWord32) s115);
-  const SWord16 s117 = (((SWord16) s28) << 8) | ((SWord16) s29);
-  const SWord16 s118 = (((SWord16) s30) << 8) | ((SWord16) s31);
-  const SWord32 s119 = (((SWord32) s117) << 16) | ((SWord32) s118);
-  const SWord32 s120 = (s101 >> 6) | (s101 << 26);
-  const SWord32 s121 = (s101 >> 11) | (s101 << 21);
-  const SWord32 s122 = s120 ^ s121;
-  const SWord32 s123 = (s101 >> 25) | (s101 << 7);
-  const SWord32 s124 = s122 ^ s123;
-  const SWord32 s125 = s119 + s124;
-  const SWord32 s126 = s101 & s107;
-  const SWord32 s127 = ~s101;
-  const SWord32 s128 = s113 & s127;
-  const SWord32 s129 = s126 ^ s128;
-  const SWord32 s130 = s125 + s129;
-  const SWord32 s132 = s130 + 0x428a2f98UL;
-  const SWord16 s133 = (((SWord16) s32) << 8) | ((SWord16) s33);
-  const SWord16 s134 = (((SWord16) s34) << 8) | ((SWord16) s35);
-  const SWord32 s135 = (((SWord32) s133) << 16) | ((SWord32) s134);
-  const SWord32 s136 = s132 + s135;
-  const SWord32 s137 = s116 + s136;
-  const SWord32 s138 = (s137 >> 6) | (s137 << 26);
-  const SWord32 s139 = (s137 >> 11) | (s137 << 21);
-  const SWord32 s140 = s138 ^ s139;
-  const SWord32 s141 = (s137 >> 25) | (s137 << 7);
-  const SWord32 s142 = s140 ^ s141;
-  const SWord32 s143 = s113 + s142;
-  const SWord32 s144 = s101 & s137;
-  const SWord32 s145 = ~s137;
-  const SWord32 s146 = s107 & s145;
-  const SWord32 s147 = s144 ^ s146;
-  const SWord32 s148 = s143 + s147;
-  const SWord32 s150 = s148 + 0x71374491UL;
-  const SWord16 s151 = (((SWord16) s36) << 8) | ((SWord16) s37);
-  const SWord16 s152 = (((SWord16) s38) << 8) | ((SWord16) s39);
-  const SWord32 s153 = (((SWord32) s151) << 16) | ((SWord32) s152);
-  const SWord32 s154 = s150 + s153;
-  const SWord32 s155 = s110 + s154;
-  const SWord32 s156 = (s155 >> 6) | (s155 << 26);
-  const SWord32 s157 = (s155 >> 11) | (s155 << 21);
-  const SWord32 s158 = s156 ^ s157;
-  const SWord32 s159 = (s155 >> 25) | (s155 << 7);
-  const SWord32 s160 = s158 ^ s159;
-  const SWord32 s161 = s107 + s160;
-  const SWord32 s162 = s137 & s155;
-  const SWord32 s163 = ~s155;
-  const SWord32 s164 = s101 & s163;
-  const SWord32 s165 = s162 ^ s164;
-  const SWord32 s166 = s161 + s165;
-  const SWord32 s168 = s166 + 0xb5c0fbcfUL;
-  const SWord16 s169 = (((SWord16) s40) << 8) | ((SWord16) s41);
-  const SWord16 s170 = (((SWord16) s42) << 8) | ((SWord16) s43);
-  const SWord32 s171 = (((SWord32) s169) << 16) | ((SWord32) s170);
-  const SWord32 s172 = s168 + s171;
-  const SWord32 s173 = s104 + s172;
-  const SWord32 s174 = (s173 >> 6) | (s173 << 26);
-  const SWord32 s175 = (s173 >> 11) | (s173 << 21);
-  const SWord32 s176 = s174 ^ s175;
-  const SWord32 s177 = (s173 >> 25) | (s173 << 7);
-  const SWord32 s178 = s176 ^ s177;
-  const SWord32 s179 = s101 + s178;
-  const SWord32 s180 = s155 & s173;
-  const SWord32 s181 = ~s173;
-  const SWord32 s182 = s137 & s181;
-  const SWord32 s183 = s180 ^ s182;
-  const SWord32 s184 = s179 + s183;
-  const SWord32 s186 = s184 + 0xe9b5dba5UL;
-  const SWord16 s187 = (((SWord16) s44) << 8) | ((SWord16) s45);
-  const SWord16 s188 = (((SWord16) s46) << 8) | ((SWord16) s47);
-  const SWord32 s189 = (((SWord32) s187) << 16) | ((SWord32) s188);
-  const SWord32 s190 = s186 + s189;
-  const SWord32 s191 = s98 + s190;
-  const SWord32 s192 = (s98 >> 2) | (s98 << 30);
-  const SWord32 s193 = (s98 >> 13) | (s98 << 19);
-  const SWord32 s194 = s192 ^ s193;
-  const SWord32 s195 = (s98 >> 22) | (s98 << 10);
-  const SWord32 s196 = s194 ^ s195;
-  const SWord32 s197 = s98 & s104;
-  const SWord32 s198 = s98 & s110;
-  const SWord32 s199 = s197 ^ s198;
-  const SWord32 s200 = s104 & s110;
-  const SWord32 s201 = s199 ^ s200;
-  const SWord32 s202 = s196 + s201;
-  const SWord32 s203 = s136 + s202;
-  const SWord32 s204 = (s203 >> 2) | (s203 << 30);
-  const SWord32 s205 = (s203 >> 13) | (s203 << 19);
-  const SWord32 s206 = s204 ^ s205;
-  const SWord32 s207 = (s203 >> 22) | (s203 << 10);
-  const SWord32 s208 = s206 ^ s207;
-  const SWord32 s209 = s98 & s203;
-  const SWord32 s210 = s104 & s203;
-  const SWord32 s211 = s209 ^ s210;
-  const SWord32 s212 = s197 ^ s211;
-  const SWord32 s213 = s208 + s212;
-  const SWord32 s214 = s154 + s213;
-  const SWord32 s215 = (s214 >> 2) | (s214 << 30);
-  const SWord32 s216 = (s214 >> 13) | (s214 << 19);
-  const SWord32 s217 = s215 ^ s216;
-  const SWord32 s218 = (s214 >> 22) | (s214 << 10);
-  const SWord32 s219 = s217 ^ s218;
-  const SWord32 s220 = s203 & s214;
-  const SWord32 s221 = s98 & s214;
-  const SWord32 s222 = s220 ^ s221;
-  const SWord32 s223 = s209 ^ s222;
-  const SWord32 s224 = s219 + s223;
-  const SWord32 s225 = s172 + s224;
-  const SWord32 s226 = (s191 >> 6) | (s191 << 26);
-  const SWord32 s227 = (s191 >> 11) | (s191 << 21);
-  const SWord32 s228 = s226 ^ s227;
-  const SWord32 s229 = (s191 >> 25) | (s191 << 7);
-  const SWord32 s230 = s228 ^ s229;
-  const SWord32 s231 = s137 + s230;
-  const SWord32 s232 = s173 & s191;
-  const SWord32 s233 = ~s191;
-  const SWord32 s234 = s155 & s233;
-  const SWord32 s235 = s232 ^ s234;
-  const SWord32 s236 = s231 + s235;
-  const SWord32 s238 = s236 + 0x3956c25bUL;
-  const SWord16 s239 = (((SWord16) s48) << 8) | ((SWord16) s49);
-  const SWord16 s240 = (((SWord16) s50) << 8) | ((SWord16) s51);
-  const SWord32 s241 = (((SWord32) s239) << 16) | ((SWord32) s240);
-  const SWord32 s242 = s238 + s241;
-  const SWord32 s243 = s203 + s242;
-  const SWord32 s244 = (s243 >> 6) | (s243 << 26);
-  const SWord32 s245 = (s243 >> 11) | (s243 << 21);
-  const SWord32 s246 = s244 ^ s245;
-  const SWord32 s247 = (s243 >> 25) | (s243 << 7);
-  const SWord32 s248 = s246 ^ s247;
-  const SWord32 s249 = s155 + s248;
-  const SWord32 s250 = s191 & s243;
-  const SWord32 s251 = ~s243;
-  const SWord32 s252 = s173 & s251;
-  const SWord32 s253 = s250 ^ s252;
-  const SWord32 s254 = s249 + s253;
-  const SWord32 s256 = s254 + 0x59f111f1UL;
-  const SWord16 s257 = (((SWord16) s52) << 8) | ((SWord16) s53);
-  const SWord16 s258 = (((SWord16) s54) << 8) | ((SWord16) s55);
-  const SWord32 s259 = (((SWord32) s257) << 16) | ((SWord32) s258);
-  const SWord32 s260 = s256 + s259;
-  const SWord32 s261 = s214 + s260;
-  const SWord32 s262 = (s261 >> 6) | (s261 << 26);
-  const SWord32 s263 = (s261 >> 11) | (s261 << 21);
-  const SWord32 s264 = s262 ^ s263;
-  const SWord32 s265 = (s261 >> 25) | (s261 << 7);
-  const SWord32 s266 = s264 ^ s265;
-  const SWord32 s267 = s173 + s266;
-  const SWord32 s268 = s243 & s261;
-  const SWord32 s269 = ~s261;
-  const SWord32 s270 = s191 & s269;
-  const SWord32 s271 = s268 ^ s270;
-  const SWord32 s272 = s267 + s271;
-  const SWord32 s274 = s272 + 0x923f82a4UL;
-  const SWord16 s275 = (((SWord16) s56) << 8) | ((SWord16) s57);
-  const SWord16 s276 = (((SWord16) s58) << 8) | ((SWord16) s59);
-  const SWord32 s277 = (((SWord32) s275) << 16) | ((SWord32) s276);
-  const SWord32 s278 = s274 + s277;
-  const SWord32 s279 = s225 + s278;
-  const SWord32 s280 = (s279 >> 6) | (s279 << 26);
-  const SWord32 s281 = (s279 >> 11) | (s279 << 21);
-  const SWord32 s282 = s280 ^ s281;
-  const SWord32 s283 = (s279 >> 25) | (s279 << 7);
-  const SWord32 s284 = s282 ^ s283;
-  const SWord32 s285 = s191 + s284;
-  const SWord32 s286 = s261 & s279;
-  const SWord32 s287 = ~s279;
-  const SWord32 s288 = s243 & s287;
-  const SWord32 s289 = s286 ^ s288;
-  const SWord32 s290 = s285 + s289;
-  const SWord32 s292 = s290 + 0xab1c5ed5UL;
-  const SWord16 s293 = (((SWord16) s60) << 8) | ((SWord16) s61);
-  const SWord16 s294 = (((SWord16) s62) << 8) | ((SWord16) s63);
-  const SWord32 s295 = (((SWord32) s293) << 16) | ((SWord32) s294);
-  const SWord32 s296 = s292 + s295;
-  const SWord32 s297 = (s225 >> 2) | (s225 << 30);
-  const SWord32 s298 = (s225 >> 13) | (s225 << 19);
-  const SWord32 s299 = s297 ^ s298;
-  const SWord32 s300 = (s225 >> 22) | (s225 << 10);
-  const SWord32 s301 = s299 ^ s300;
-  const SWord32 s302 = s214 & s225;
-  const SWord32 s303 = s203 & s225;
-  const SWord32 s304 = s302 ^ s303;
-  const SWord32 s305 = s220 ^ s304;
-  const SWord32 s306 = s301 + s305;
-  const SWord32 s307 = s190 + s306;
-  const SWord32 s308 = (s307 >> 2) | (s307 << 30);
-  const SWord32 s309 = (s307 >> 13) | (s307 << 19);
-  const SWord32 s310 = s308 ^ s309;
-  const SWord32 s311 = (s307 >> 22) | (s307 << 10);
-  const SWord32 s312 = s310 ^ s311;
-  const SWord32 s313 = s225 & s307;
-  const SWord32 s314 = s214 & s307;
-  const SWord32 s315 = s313 ^ s314;
-  const SWord32 s316 = s302 ^ s315;
-  const SWord32 s317 = s312 + s316;
-  const SWord32 s318 = s242 + s317;
-  const SWord32 s319 = (s318 >> 2) | (s318 << 30);
-  const SWord32 s320 = (s318 >> 13) | (s318 << 19);
-  const SWord32 s321 = s319 ^ s320;
-  const SWord32 s322 = (s318 >> 22) | (s318 << 10);
-  const SWord32 s323 = s321 ^ s322;
-  const SWord32 s324 = s307 & s318;
-  const SWord32 s325 = s225 & s318;
-  const SWord32 s326 = s324 ^ s325;
-  const SWord32 s327 = s313 ^ s326;
-  const SWord32 s328 = s323 + s327;
-  const SWord32 s329 = s260 + s328;
-  const SWord32 s330 = (s329 >> 2) | (s329 << 30);
-  const SWord32 s331 = (s329 >> 13) | (s329 << 19);
-  const SWord32 s332 = s330 ^ s331;
-  const SWord32 s333 = (s329 >> 22) | (s329 << 10);
-  const SWord32 s334 = s332 ^ s333;
-  const SWord32 s335 = s318 & s329;
-  const SWord32 s336 = s307 & s329;
-  const SWord32 s337 = s335 ^ s336;
-  const SWord32 s338 = s324 ^ s337;
-  const SWord32 s339 = s334 + s338;
-  const SWord32 s340 = s278 + s339;
-  const SWord32 s341 = (s340 >> 2) | (s340 << 30);
-  const SWord32 s342 = (s340 >> 13) | (s340 << 19);
-  const SWord32 s343 = s341 ^ s342;
-  const SWord32 s344 = (s340 >> 22) | (s340 << 10);
-  const SWord32 s345 = s343 ^ s344;
-  const SWord32 s346 = s329 & s340;
-  const SWord32 s347 = s318 & s340;
-  const SWord32 s348 = s346 ^ s347;
-  const SWord32 s349 = s335 ^ s348;
-  const SWord32 s350 = s345 + s349;
-  const SWord32 s351 = s296 + s350;
-  const SWord32 s352 = s296 + s307;
-  const SWord32 s353 = (s352 >> 6) | (s352 << 26);
-  const SWord32 s354 = (s352 >> 11) | (s352 << 21);
-  const SWord32 s355 = s353 ^ s354;
-  const SWord32 s356 = (s352 >> 25) | (s352 << 7);
-  const SWord32 s357 = s355 ^ s356;
-  const SWord32 s358 = s243 + s357;
-  const SWord32 s359 = s279 & s352;
-  const SWord32 s360 = ~s352;
-  const SWord32 s361 = s261 & s360;
-  const SWord32 s362 = s359 ^ s361;
-  const SWord32 s363 = s358 + s362;
-  const SWord32 s365 = s363 + 0xd807aa98UL;
-  const SWord16 s366 = (((SWord16) s64) << 8) | ((SWord16) s65);
-  const SWord16 s367 = (((SWord16) s66) << 8) | ((SWord16) s67);
-  const SWord32 s368 = (((SWord32) s366) << 16) | ((SWord32) s367);
-  const SWord32 s369 = s365 + s368;
-  const SWord32 s370 = s318 + s369;
-  const SWord32 s371 = (s370 >> 6) | (s370 << 26);
-  const SWord32 s372 = (s370 >> 11) | (s370 << 21);
-  const SWord32 s373 = s371 ^ s372;
-  const SWord32 s374 = (s370 >> 25) | (s370 << 7);
-  const SWord32 s375 = s373 ^ s374;
-  const SWord32 s376 = s261 + s375;
-  const SWord32 s377 = s352 & s370;
-  const SWord32 s378 = ~s370;
-  const SWord32 s379 = s279 & s378;
-  const SWord32 s380 = s377 ^ s379;
-  const SWord32 s381 = s376 + s380;
-  const SWord32 s383 = s381 + 0x12835b01UL;
-  const SWord16 s384 = (((SWord16) s68) << 8) | ((SWord16) s69);
-  const SWord16 s385 = (((SWord16) s70) << 8) | ((SWord16) s71);
-  const SWord32 s386 = (((SWord32) s384) << 16) | ((SWord32) s385);
-  const SWord32 s387 = s383 + s386;
-  const SWord32 s388 = s329 + s387;
-  const SWord32 s389 = (s388 >> 6) | (s388 << 26);
-  const SWord32 s390 = (s388 >> 11) | (s388 << 21);
-  const SWord32 s391 = s389 ^ s390;
-  const SWord32 s392 = (s388 >> 25) | (s388 << 7);
-  const SWord32 s393 = s391 ^ s392;
-  const SWord32 s394 = s279 + s393;
-  const SWord32 s395 = s370 & s388;
-  const SWord32 s396 = ~s388;
-  const SWord32 s397 = s352 & s396;
-  const SWord32 s398 = s395 ^ s397;
-  const SWord32 s399 = s394 + s398;
-  const SWord32 s401 = s399 + 0x243185beUL;
-  const SWord16 s402 = (((SWord16) s72) << 8) | ((SWord16) s73);
-  const SWord16 s403 = (((SWord16) s74) << 8) | ((SWord16) s75);
-  const SWord32 s404 = (((SWord32) s402) << 16) | ((SWord32) s403);
-  const SWord32 s405 = s401 + s404;
-  const SWord32 s406 = s340 + s405;
-  const SWord32 s407 = (s406 >> 6) | (s406 << 26);
-  const SWord32 s408 = (s406 >> 11) | (s406 << 21);
-  const SWord32 s409 = s407 ^ s408;
-  const SWord32 s410 = (s406 >> 25) | (s406 << 7);
-  const SWord32 s411 = s409 ^ s410;
-  const SWord32 s412 = s352 + s411;
-  const SWord32 s413 = s388 & s406;
-  const SWord32 s414 = ~s406;
-  const SWord32 s415 = s370 & s414;
-  const SWord32 s416 = s413 ^ s415;
-  const SWord32 s417 = s412 + s416;
-  const SWord32 s419 = s417 + 0x550c7dc3UL;
-  const SWord16 s420 = (((SWord16) s76) << 8) | ((SWord16) s77);
-  const SWord16 s421 = (((SWord16) s78) << 8) | ((SWord16) s79);
-  const SWord32 s422 = (((SWord32) s420) << 16) | ((SWord32) s421);
-  const SWord32 s423 = s419 + s422;
-  const SWord32 s424 = s351 + s423;
-  const SWord32 s425 = (s351 >> 2) | (s351 << 30);
-  const SWord32 s426 = (s351 >> 13) | (s351 << 19);
-  const SWord32 s427 = s425 ^ s426;
-  const SWord32 s428 = (s351 >> 22) | (s351 << 10);
-  const SWord32 s429 = s427 ^ s428;
-  const SWord32 s430 = s340 & s351;
-  const SWord32 s431 = s329 & s351;
-  const SWord32 s432 = s430 ^ s431;
-  const SWord32 s433 = s346 ^ s432;
-  const SWord32 s434 = s429 + s433;
-  const SWord32 s435 = s369 + s434;
-  const SWord32 s436 = (s435 >> 2) | (s435 << 30);
-  const SWord32 s437 = (s435 >> 13) | (s435 << 19);
-  const SWord32 s438 = s436 ^ s437;
-  const SWord32 s439 = (s435 >> 22) | (s435 << 10);
-  const SWord32 s440 = s438 ^ s439;
-  const SWord32 s441 = s351 & s435;
-  const SWord32 s442 = s340 & s435;
-  const SWord32 s443 = s441 ^ s442;
-  const SWord32 s444 = s430 ^ s443;
-  const SWord32 s445 = s440 + s444;
-  const SWord32 s446 = s387 + s445;
-  const SWord32 s447 = (s446 >> 2) | (s446 << 30);
-  const SWord32 s448 = (s446 >> 13) | (s446 << 19);
-  const SWord32 s449 = s447 ^ s448;
-  const SWord32 s450 = (s446 >> 22) | (s446 << 10);
-  const SWord32 s451 = s449 ^ s450;
-  const SWord32 s452 = s435 & s446;
-  const SWord32 s453 = s351 & s446;
-  const SWord32 s454 = s452 ^ s453;
-  const SWord32 s455 = s441 ^ s454;
-  const SWord32 s456 = s451 + s455;
-  const SWord32 s457 = s405 + s456;
-  const SWord32 s458 = (s424 >> 6) | (s424 << 26);
-  const SWord32 s459 = (s424 >> 11) | (s424 << 21);
-  const SWord32 s460 = s458 ^ s459;
-  const SWord32 s461 = (s424 >> 25) | (s424 << 7);
-  const SWord32 s462 = s460 ^ s461;
-  const SWord32 s463 = s370 + s462;
-  const SWord32 s464 = s406 & s424;
-  const SWord32 s465 = ~s424;
-  const SWord32 s466 = s388 & s465;
-  const SWord32 s467 = s464 ^ s466;
-  const SWord32 s468 = s463 + s467;
-  const SWord32 s470 = s468 + 0x72be5d74UL;
-  const SWord16 s471 = (((SWord16) s80) << 8) | ((SWord16) s81);
-  const SWord16 s472 = (((SWord16) s82) << 8) | ((SWord16) s83);
-  const SWord32 s473 = (((SWord32) s471) << 16) | ((SWord32) s472);
-  const SWord32 s474 = s470 + s473;
-  const SWord32 s475 = s435 + s474;
-  const SWord32 s476 = (s475 >> 6) | (s475 << 26);
-  const SWord32 s477 = (s475 >> 11) | (s475 << 21);
-  const SWord32 s478 = s476 ^ s477;
-  const SWord32 s479 = (s475 >> 25) | (s475 << 7);
-  const SWord32 s480 = s478 ^ s479;
-  const SWord32 s481 = s388 + s480;
-  const SWord32 s482 = s424 & s475;
-  const SWord32 s483 = ~s475;
-  const SWord32 s484 = s406 & s483;
-  const SWord32 s485 = s482 ^ s484;
-  const SWord32 s486 = s481 + s485;
-  const SWord32 s488 = s486 + 0x80deb1feUL;
-  const SWord16 s489 = (((SWord16) s84) << 8) | ((SWord16) s85);
-  const SWord16 s490 = (((SWord16) s86) << 8) | ((SWord16) s87);
-  const SWord32 s491 = (((SWord32) s489) << 16) | ((SWord32) s490);
-  const SWord32 s492 = s488 + s491;
-  const SWord32 s493 = s446 + s492;
-  const SWord32 s494 = (s493 >> 6) | (s493 << 26);
-  const SWord32 s495 = (s493 >> 11) | (s493 << 21);
-  const SWord32 s496 = s494 ^ s495;
-  const SWord32 s497 = (s493 >> 25) | (s493 << 7);
-  const SWord32 s498 = s496 ^ s497;
-  const SWord32 s499 = s406 + s498;
-  const SWord32 s500 = s475 & s493;
-  const SWord32 s501 = ~s493;
-  const SWord32 s502 = s424 & s501;
-  const SWord32 s503 = s500 ^ s502;
-  const SWord32 s504 = s499 + s503;
-  const SWord32 s506 = s504 + 0x9bdc06a7UL;
-  const SWord16 s507 = (((SWord16) s88) << 8) | ((SWord16) s89);
-  const SWord16 s508 = (((SWord16) s90) << 8) | ((SWord16) s91);
-  const SWord32 s509 = (((SWord32) s507) << 16) | ((SWord32) s508);
-  const SWord32 s510 = s506 + s509;
-  const SWord32 s511 = s457 + s510;
-  const SWord32 s512 = (s511 >> 6) | (s511 << 26);
-  const SWord32 s513 = (s511 >> 11) | (s511 << 21);
-  const SWord32 s514 = s512 ^ s513;
-  const SWord32 s515 = (s511 >> 25) | (s511 << 7);
-  const SWord32 s516 = s514 ^ s515;
-  const SWord32 s517 = s424 + s516;
-  const SWord32 s518 = s493 & s511;
-  const SWord32 s519 = ~s511;
-  const SWord32 s520 = s475 & s519;
-  const SWord32 s521 = s518 ^ s520;
-  const SWord32 s522 = s517 + s521;
-  const SWord32 s524 = s522 + 0xc19bf174UL;
-  const SWord16 s525 = (((SWord16) s92) << 8) | ((SWord16) s93);
-  const SWord16 s526 = (((SWord16) s94) << 8) | ((SWord16) s95);
-  const SWord32 s527 = (((SWord32) s525) << 16) | ((SWord32) s526);
-  const SWord32 s528 = s524 + s527;
-  const SWord32 s529 = (s457 >> 2) | (s457 << 30);
-  const SWord32 s530 = (s457 >> 13) | (s457 << 19);
-  const SWord32 s531 = s529 ^ s530;
-  const SWord32 s532 = (s457 >> 22) | (s457 << 10);
-  const SWord32 s533 = s531 ^ s532;
-  const SWord32 s534 = s446 & s457;
-  const SWord32 s535 = s435 & s457;
-  const SWord32 s536 = s534 ^ s535;
-  const SWord32 s537 = s452 ^ s536;
-  const SWord32 s538 = s533 + s537;
-  const SWord32 s539 = s423 + s538;
-  const SWord32 s540 = (s539 >> 2) | (s539 << 30);
-  const SWord32 s541 = (s539 >> 13) | (s539 << 19);
-  const SWord32 s542 = s540 ^ s541;
-  const SWord32 s543 = (s539 >> 22) | (s539 << 10);
-  const SWord32 s544 = s542 ^ s543;
-  const SWord32 s545 = s457 & s539;
-  const SWord32 s546 = s446 & s539;
-  const SWord32 s547 = s545 ^ s546;
-  const SWord32 s548 = s534 ^ s547;
-  const SWord32 s549 = s544 + s548;
-  const SWord32 s550 = s474 + s549;
-  const SWord32 s551 = (s550 >> 2) | (s550 << 30);
-  const SWord32 s552 = (s550 >> 13) | (s550 << 19);
-  const SWord32 s553 = s551 ^ s552;
-  const SWord32 s554 = (s550 >> 22) | (s550 << 10);
-  const SWord32 s555 = s553 ^ s554;
-  const SWord32 s556 = s539 & s550;
-  const SWord32 s557 = s457 & s550;
-  const SWord32 s558 = s556 ^ s557;
-  const SWord32 s559 = s545 ^ s558;
-  const SWord32 s560 = s555 + s559;
-  const SWord32 s561 = s492 + s560;
-  const SWord32 s562 = (s561 >> 2) | (s561 << 30);
-  const SWord32 s563 = (s561 >> 13) | (s561 << 19);
-  const SWord32 s564 = s562 ^ s563;
-  const SWord32 s565 = (s561 >> 22) | (s561 << 10);
-  const SWord32 s566 = s564 ^ s565;
-  const SWord32 s567 = s550 & s561;
-  const SWord32 s568 = s539 & s561;
-  const SWord32 s569 = s567 ^ s568;
-  const SWord32 s570 = s556 ^ s569;
-  const SWord32 s571 = s566 + s570;
-  const SWord32 s572 = s510 + s571;
-  const SWord32 s573 = (s572 >> 2) | (s572 << 30);
-  const SWord32 s574 = (s572 >> 13) | (s572 << 19);
-  const SWord32 s575 = s573 ^ s574;
-  const SWord32 s576 = (s572 >> 22) | (s572 << 10);
-  const SWord32 s577 = s575 ^ s576;
-  const SWord32 s578 = s561 & s572;
-  const SWord32 s579 = s550 & s572;
-  const SWord32 s580 = s578 ^ s579;
-  const SWord32 s581 = s567 ^ s580;
-  const SWord32 s582 = s577 + s581;
-  const SWord32 s583 = s528 + s582;
-  const SWord32 s584 = s528 + s539;
-  const SWord32 s585 = (s584 >> 6) | (s584 << 26);
-  const SWord32 s586 = (s584 >> 11) | (s584 << 21);
-  const SWord32 s587 = s585 ^ s586;
-  const SWord32 s588 = (s584 >> 25) | (s584 << 7);
-  const SWord32 s589 = s587 ^ s588;
-  const SWord32 s590 = s475 + s589;
-  const SWord32 s591 = s511 & s584;
-  const SWord32 s592 = ~s584;
-  const SWord32 s593 = s493 & s592;
-  const SWord32 s594 = s591 ^ s593;
-  const SWord32 s595 = s590 + s594;
-  const SWord32 s597 = s595 + 0xe49b69c1UL;
-  const SWord32 s598 = (s509 >> 17) | (s509 << 15);
-  const SWord32 s599 = (s509 >> 19) | (s509 << 13);
-  const SWord32 s600 = s598 ^ s599;
-  const SWord32 s602 = s509 >> 10;
-  const SWord32 s603 = s600 ^ s602;
-  const SWord32 s604 = s386 + s603;
-  const SWord32 s605 = (s153 >> 7) | (s153 << 25);
-  const SWord32 s606 = (s153 >> 18) | (s153 << 14);
-  const SWord32 s607 = s605 ^ s606;
-  const SWord32 s609 = s153 >> 3;
-  const SWord32 s610 = s607 ^ s609;
-  const SWord32 s611 = s604 + s610;
-  const SWord32 s612 = s135 + s611;
-  const SWord32 s613 = s597 + s612;
-  const SWord32 s614 = s550 + s613;
-  const SWord32 s615 = (s614 >> 6) | (s614 << 26);
-  const SWord32 s616 = (s614 >> 11) | (s614 << 21);
-  const SWord32 s617 = s615 ^ s616;
-  const SWord32 s618 = (s614 >> 25) | (s614 << 7);
-  const SWord32 s619 = s617 ^ s618;
-  const SWord32 s620 = s493 + s619;
-  const SWord32 s621 = s584 & s614;
-  const SWord32 s622 = ~s614;
-  const SWord32 s623 = s511 & s622;
-  const SWord32 s624 = s621 ^ s623;
-  const SWord32 s625 = s620 + s624;
-  const SWord32 s627 = s625 + 0xefbe4786UL;
-  const SWord32 s628 = (s527 >> 17) | (s527 << 15);
-  const SWord32 s629 = (s527 >> 19) | (s527 << 13);
-  const SWord32 s630 = s628 ^ s629;
-  const SWord32 s631 = s527 >> 10;
-  const SWord32 s632 = s630 ^ s631;
-  const SWord32 s633 = s404 + s632;
-  const SWord32 s634 = (s171 >> 7) | (s171 << 25);
-  const SWord32 s635 = (s171 >> 18) | (s171 << 14);
-  const SWord32 s636 = s634 ^ s635;
-  const SWord32 s637 = s171 >> 3;
-  const SWord32 s638 = s636 ^ s637;
-  const SWord32 s639 = s633 + s638;
-  const SWord32 s640 = s153 + s639;
-  const SWord32 s641 = s627 + s640;
-  const SWord32 s642 = s561 + s641;
-  const SWord32 s643 = (s642 >> 6) | (s642 << 26);
-  const SWord32 s644 = (s642 >> 11) | (s642 << 21);
-  const SWord32 s645 = s643 ^ s644;
-  const SWord32 s646 = (s642 >> 25) | (s642 << 7);
-  const SWord32 s647 = s645 ^ s646;
-  const SWord32 s648 = s511 + s647;
-  const SWord32 s649 = s614 & s642;
-  const SWord32 s650 = ~s642;
-  const SWord32 s651 = s584 & s650;
-  const SWord32 s652 = s649 ^ s651;
-  const SWord32 s653 = s648 + s652;
-  const SWord32 s655 = s653 + 0x0fc19dc6UL;
-  const SWord32 s656 = (s612 >> 17) | (s612 << 15);
-  const SWord32 s657 = (s612 >> 19) | (s612 << 13);
-  const SWord32 s658 = s656 ^ s657;
-  const SWord32 s659 = s612 >> 10;
-  const SWord32 s660 = s658 ^ s659;
-  const SWord32 s661 = s422 + s660;
-  const SWord32 s662 = (s189 >> 7) | (s189 << 25);
-  const SWord32 s663 = (s189 >> 18) | (s189 << 14);
-  const SWord32 s664 = s662 ^ s663;
-  const SWord32 s665 = s189 >> 3;
-  const SWord32 s666 = s664 ^ s665;
-  const SWord32 s667 = s661 + s666;
-  const SWord32 s668 = s171 + s667;
-  const SWord32 s669 = s655 + s668;
-  const SWord32 s670 = s572 + s669;
-  const SWord32 s671 = (s670 >> 6) | (s670 << 26);
-  const SWord32 s672 = (s670 >> 11) | (s670 << 21);
-  const SWord32 s673 = s671 ^ s672;
-  const SWord32 s674 = (s670 >> 25) | (s670 << 7);
-  const SWord32 s675 = s673 ^ s674;
-  const SWord32 s676 = s584 + s675;
-  const SWord32 s677 = s642 & s670;
-  const SWord32 s678 = ~s670;
-  const SWord32 s679 = s614 & s678;
-  const SWord32 s680 = s677 ^ s679;
-  const SWord32 s681 = s676 + s680;
-  const SWord32 s683 = s681 + 0x240ca1ccUL;
-  const SWord32 s684 = (s640 >> 17) | (s640 << 15);
-  const SWord32 s685 = (s640 >> 19) | (s640 << 13);
-  const SWord32 s686 = s684 ^ s685;
-  const SWord32 s687 = s640 >> 10;
-  const SWord32 s688 = s686 ^ s687;
-  const SWord32 s689 = s473 + s688;
-  const SWord32 s690 = (s241 >> 7) | (s241 << 25);
-  const SWord32 s691 = (s241 >> 18) | (s241 << 14);
-  const SWord32 s692 = s690 ^ s691;
-  const SWord32 s693 = s241 >> 3;
-  const SWord32 s694 = s692 ^ s693;
-  const SWord32 s695 = s689 + s694;
-  const SWord32 s696 = s189 + s695;
-  const SWord32 s697 = s683 + s696;
-  const SWord32 s698 = s583 + s697;
-  const SWord32 s699 = (s583 >> 2) | (s583 << 30);
-  const SWord32 s700 = (s583 >> 13) | (s583 << 19);
-  const SWord32 s701 = s699 ^ s700;
-  const SWord32 s702 = (s583 >> 22) | (s583 << 10);
-  const SWord32 s703 = s701 ^ s702;
-  const SWord32 s704 = s572 & s583;
-  const SWord32 s705 = s561 & s583;
-  const SWord32 s706 = s704 ^ s705;
-  const SWord32 s707 = s578 ^ s706;
-  const SWord32 s708 = s703 + s707;
-  const SWord32 s709 = s613 + s708;
-  const SWord32 s710 = (s709 >> 2) | (s709 << 30);
-  const SWord32 s711 = (s709 >> 13) | (s709 << 19);
-  const SWord32 s712 = s710 ^ s711;
-  const SWord32 s713 = (s709 >> 22) | (s709 << 10);
-  const SWord32 s714 = s712 ^ s713;
-  const SWord32 s715 = s583 & s709;
-  const SWord32 s716 = s572 & s709;
-  const SWord32 s717 = s715 ^ s716;
-  const SWord32 s718 = s704 ^ s717;
-  const SWord32 s719 = s714 + s718;
-  const SWord32 s720 = s641 + s719;
-  const SWord32 s721 = (s720 >> 2) | (s720 << 30);
-  const SWord32 s722 = (s720 >> 13) | (s720 << 19);
-  const SWord32 s723 = s721 ^ s722;
-  const SWord32 s724 = (s720 >> 22) | (s720 << 10);
-  const SWord32 s725 = s723 ^ s724;
-  const SWord32 s726 = s709 & s720;
-  const SWord32 s727 = s583 & s720;
-  const SWord32 s728 = s726 ^ s727;
-  const SWord32 s729 = s715 ^ s728;
-  const SWord32 s730 = s725 + s729;
-  const SWord32 s731 = s669 + s730;
-  const SWord32 s732 = (s698 >> 6) | (s698 << 26);
-  const SWord32 s733 = (s698 >> 11) | (s698 << 21);
-  const SWord32 s734 = s732 ^ s733;
-  const SWord32 s735 = (s698 >> 25) | (s698 << 7);
-  const SWord32 s736 = s734 ^ s735;
-  const SWord32 s737 = s614 + s736;
-  const SWord32 s738 = s670 & s698;
-  const SWord32 s739 = ~s698;
-  const SWord32 s740 = s642 & s739;
-  const SWord32 s741 = s738 ^ s740;
-  const SWord32 s742 = s737 + s741;
-  const SWord32 s744 = s742 + 0x2de92c6fUL;
-  const SWord32 s745 = (s668 >> 17) | (s668 << 15);
-  const SWord32 s746 = (s668 >> 19) | (s668 << 13);
-  const SWord32 s747 = s745 ^ s746;
-  const SWord32 s748 = s668 >> 10;
-  const SWord32 s749 = s747 ^ s748;
-  const SWord32 s750 = s491 + s749;
-  const SWord32 s751 = (s259 >> 7) | (s259 << 25);
-  const SWord32 s752 = (s259 >> 18) | (s259 << 14);
-  const SWord32 s753 = s751 ^ s752;
-  const SWord32 s754 = s259 >> 3;
-  const SWord32 s755 = s753 ^ s754;
-  const SWord32 s756 = s750 + s755;
-  const SWord32 s757 = s241 + s756;
-  const SWord32 s758 = s744 + s757;
-  const SWord32 s759 = s709 + s758;
-  const SWord32 s760 = (s759 >> 6) | (s759 << 26);
-  const SWord32 s761 = (s759 >> 11) | (s759 << 21);
-  const SWord32 s762 = s760 ^ s761;
-  const SWord32 s763 = (s759 >> 25) | (s759 << 7);
-  const SWord32 s764 = s762 ^ s763;
-  const SWord32 s765 = s642 + s764;
-  const SWord32 s766 = s698 & s759;
-  const SWord32 s767 = ~s759;
-  const SWord32 s768 = s670 & s767;
-  const SWord32 s769 = s766 ^ s768;
-  const SWord32 s770 = s765 + s769;
-  const SWord32 s772 = s770 + 0x4a7484aaUL;
-  const SWord32 s773 = (s696 >> 17) | (s696 << 15);
-  const SWord32 s774 = (s696 >> 19) | (s696 << 13);
-  const SWord32 s775 = s773 ^ s774;
-  const SWord32 s776 = s696 >> 10;
-  const SWord32 s777 = s775 ^ s776;
-  const SWord32 s778 = s509 + s777;
-  const SWord32 s779 = (s277 >> 7) | (s277 << 25);
-  const SWord32 s780 = (s277 >> 18) | (s277 << 14);
-  const SWord32 s781 = s779 ^ s780;
-  const SWord32 s782 = s277 >> 3;
-  const SWord32 s783 = s781 ^ s782;
-  const SWord32 s784 = s778 + s783;
-  const SWord32 s785 = s259 + s784;
-  const SWord32 s786 = s772 + s785;
-  const SWord32 s787 = s720 + s786;
-  const SWord32 s788 = (s787 >> 6) | (s787 << 26);
-  const SWord32 s789 = (s787 >> 11) | (s787 << 21);
-  const SWord32 s790 = s788 ^ s789;
-  const SWord32 s791 = (s787 >> 25) | (s787 << 7);
-  const SWord32 s792 = s790 ^ s791;
-  const SWord32 s793 = s670 + s792;
-  const SWord32 s794 = s759 & s787;
-  const SWord32 s795 = ~s787;
-  const SWord32 s796 = s698 & s795;
-  const SWord32 s797 = s794 ^ s796;
-  const SWord32 s798 = s793 + s797;
-  const SWord32 s800 = s798 + 0x5cb0a9dcUL;
-  const SWord32 s801 = (s757 >> 17) | (s757 << 15);
-  const SWord32 s802 = (s757 >> 19) | (s757 << 13);
-  const SWord32 s803 = s801 ^ s802;
-  const SWord32 s804 = s757 >> 10;
-  const SWord32 s805 = s803 ^ s804;
-  const SWord32 s806 = s527 + s805;
-  const SWord32 s807 = (s295 >> 7) | (s295 << 25);
-  const SWord32 s808 = (s295 >> 18) | (s295 << 14);
-  const SWord32 s809 = s807 ^ s808;
-  const SWord32 s810 = s295 >> 3;
-  const SWord32 s811 = s809 ^ s810;
-  const SWord32 s812 = s806 + s811;
-  const SWord32 s813 = s277 + s812;
-  const SWord32 s814 = s800 + s813;
-  const SWord32 s815 = s731 + s814;
-  const SWord32 s816 = (s815 >> 6) | (s815 << 26);
-  const SWord32 s817 = (s815 >> 11) | (s815 << 21);
-  const SWord32 s818 = s816 ^ s817;
-  const SWord32 s819 = (s815 >> 25) | (s815 << 7);
-  const SWord32 s820 = s818 ^ s819;
-  const SWord32 s821 = s698 + s820;
-  const SWord32 s822 = s787 & s815;
-  const SWord32 s823 = ~s815;
-  const SWord32 s824 = s759 & s823;
-  const SWord32 s825 = s822 ^ s824;
-  const SWord32 s826 = s821 + s825;
-  const SWord32 s828 = s826 + 0x76f988daUL;
-  const SWord32 s829 = (s785 >> 17) | (s785 << 15);
-  const SWord32 s830 = (s785 >> 19) | (s785 << 13);
-  const SWord32 s831 = s829 ^ s830;
-  const SWord32 s832 = s785 >> 10;
-  const SWord32 s833 = s831 ^ s832;
-  const SWord32 s834 = s612 + s833;
-  const SWord32 s835 = (s368 >> 7) | (s368 << 25);
-  const SWord32 s836 = (s368 >> 18) | (s368 << 14);
-  const SWord32 s837 = s835 ^ s836;
-  const SWord32 s838 = s368 >> 3;
-  const SWord32 s839 = s837 ^ s838;
-  const SWord32 s840 = s834 + s839;
-  const SWord32 s841 = s295 + s840;
-  const SWord32 s842 = s828 + s841;
-  const SWord32 s843 = (s731 >> 2) | (s731 << 30);
-  const SWord32 s844 = (s731 >> 13) | (s731 << 19);
-  const SWord32 s845 = s843 ^ s844;
-  const SWord32 s846 = (s731 >> 22) | (s731 << 10);
-  const SWord32 s847 = s845 ^ s846;
-  const SWord32 s848 = s720 & s731;
-  const SWord32 s849 = s709 & s731;
-  const SWord32 s850 = s848 ^ s849;
-  const SWord32 s851 = s726 ^ s850;
-  const SWord32 s852 = s847 + s851;
-  const SWord32 s853 = s697 + s852;
-  const SWord32 s854 = (s853 >> 2) | (s853 << 30);
-  const SWord32 s855 = (s853 >> 13) | (s853 << 19);
-  const SWord32 s856 = s854 ^ s855;
-  const SWord32 s857 = (s853 >> 22) | (s853 << 10);
-  const SWord32 s858 = s856 ^ s857;
-  const SWord32 s859 = s731 & s853;
-  const SWord32 s860 = s720 & s853;
-  const SWord32 s861 = s859 ^ s860;
-  const SWord32 s862 = s848 ^ s861;
-  const SWord32 s863 = s858 + s862;
-  const SWord32 s864 = s758 + s863;
-  const SWord32 s865 = (s864 >> 2) | (s864 << 30);
-  const SWord32 s866 = (s864 >> 13) | (s864 << 19);
-  const SWord32 s867 = s865 ^ s866;
-  const SWord32 s868 = (s864 >> 22) | (s864 << 10);
-  const SWord32 s869 = s867 ^ s868;
-  const SWord32 s870 = s853 & s864;
-  const SWord32 s871 = s731 & s864;
-  const SWord32 s872 = s870 ^ s871;
-  const SWord32 s873 = s859 ^ s872;
-  const SWord32 s874 = s869 + s873;
-  const SWord32 s875 = s786 + s874;
-  const SWord32 s876 = (s875 >> 2) | (s875 << 30);
-  const SWord32 s877 = (s875 >> 13) | (s875 << 19);
-  const SWord32 s878 = s876 ^ s877;
-  const SWord32 s879 = (s875 >> 22) | (s875 << 10);
-  const SWord32 s880 = s878 ^ s879;
-  const SWord32 s881 = s864 & s875;
-  const SWord32 s882 = s853 & s875;
-  const SWord32 s883 = s881 ^ s882;
-  const SWord32 s884 = s870 ^ s883;
-  const SWord32 s885 = s880 + s884;
-  const SWord32 s886 = s814 + s885;
-  const SWord32 s887 = (s886 >> 2) | (s886 << 30);
-  const SWord32 s888 = (s886 >> 13) | (s886 << 19);
-  const SWord32 s889 = s887 ^ s888;
-  const SWord32 s890 = (s886 >> 22) | (s886 << 10);
-  const SWord32 s891 = s889 ^ s890;
-  const SWord32 s892 = s875 & s886;
-  const SWord32 s893 = s864 & s886;
-  const SWord32 s894 = s892 ^ s893;
-  const SWord32 s895 = s881 ^ s894;
-  const SWord32 s896 = s891 + s895;
-  const SWord32 s897 = s842 + s896;
-  const SWord32 s898 = s842 + s853;
-  const SWord32 s899 = (s898 >> 6) | (s898 << 26);
-  const SWord32 s900 = (s898 >> 11) | (s898 << 21);
-  const SWord32 s901 = s899 ^ s900;
-  const SWord32 s902 = (s898 >> 25) | (s898 << 7);
-  const SWord32 s903 = s901 ^ s902;
-  const SWord32 s904 = s759 + s903;
-  const SWord32 s905 = s815 & s898;
-  const SWord32 s906 = ~s898;
-  const SWord32 s907 = s787 & s906;
-  const SWord32 s908 = s905 ^ s907;
-  const SWord32 s909 = s904 + s908;
-  const SWord32 s911 = s909 + 0x983e5152UL;
-  const SWord32 s912 = (s813 >> 17) | (s813 << 15);
-  const SWord32 s913 = (s813 >> 19) | (s813 << 13);
-  const SWord32 s914 = s912 ^ s913;
-  const SWord32 s915 = s813 >> 10;
-  const SWord32 s916 = s914 ^ s915;
-  const SWord32 s917 = s640 + s916;
-  const SWord32 s918 = (s386 >> 7) | (s386 << 25);
-  const SWord32 s919 = (s386 >> 18) | (s386 << 14);
-  const SWord32 s920 = s918 ^ s919;
-  const SWord32 s921 = s386 >> 3;
-  const SWord32 s922 = s920 ^ s921;
-  const SWord32 s923 = s917 + s922;
-  const SWord32 s924 = s368 + s923;
-  const SWord32 s925 = s911 + s924;
-  const SWord32 s926 = s864 + s925;
-  const SWord32 s927 = (s926 >> 6) | (s926 << 26);
-  const SWord32 s928 = (s926 >> 11) | (s926 << 21);
-  const SWord32 s929 = s927 ^ s928;
-  const SWord32 s930 = (s926 >> 25) | (s926 << 7);
-  const SWord32 s931 = s929 ^ s930;
-  const SWord32 s932 = s787 + s931;
-  const SWord32 s933 = s898 & s926;
-  const SWord32 s934 = ~s926;
-  const SWord32 s935 = s815 & s934;
-  const SWord32 s936 = s933 ^ s935;
-  const SWord32 s937 = s932 + s936;
-  const SWord32 s939 = s937 + 0xa831c66dUL;
-  const SWord32 s940 = (s841 >> 17) | (s841 << 15);
-  const SWord32 s941 = (s841 >> 19) | (s841 << 13);
-  const SWord32 s942 = s940 ^ s941;
-  const SWord32 s943 = s841 >> 10;
-  const SWord32 s944 = s942 ^ s943;
-  const SWord32 s945 = s668 + s944;
-  const SWord32 s946 = (s404 >> 7) | (s404 << 25);
-  const SWord32 s947 = (s404 >> 18) | (s404 << 14);
-  const SWord32 s948 = s946 ^ s947;
-  const SWord32 s949 = s404 >> 3;
-  const SWord32 s950 = s948 ^ s949;
-  const SWord32 s951 = s945 + s950;
-  const SWord32 s952 = s386 + s951;
-  const SWord32 s953 = s939 + s952;
-  const SWord32 s954 = s875 + s953;
-  const SWord32 s955 = (s954 >> 6) | (s954 << 26);
-  const SWord32 s956 = (s954 >> 11) | (s954 << 21);
-  const SWord32 s957 = s955 ^ s956;
-  const SWord32 s958 = (s954 >> 25) | (s954 << 7);
-  const SWord32 s959 = s957 ^ s958;
-  const SWord32 s960 = s815 + s959;
-  const SWord32 s961 = s926 & s954;
-  const SWord32 s962 = ~s954;
-  const SWord32 s963 = s898 & s962;
-  const SWord32 s964 = s961 ^ s963;
-  const SWord32 s965 = s960 + s964;
-  const SWord32 s967 = s965 + 0xb00327c8UL;
-  const SWord32 s968 = (s924 >> 17) | (s924 << 15);
-  const SWord32 s969 = (s924 >> 19) | (s924 << 13);
-  const SWord32 s970 = s968 ^ s969;
-  const SWord32 s971 = s924 >> 10;
-  const SWord32 s972 = s970 ^ s971;
-  const SWord32 s973 = s696 + s972;
-  const SWord32 s974 = (s422 >> 7) | (s422 << 25);
-  const SWord32 s975 = (s422 >> 18) | (s422 << 14);
-  const SWord32 s976 = s974 ^ s975;
-  const SWord32 s977 = s422 >> 3;
-  const SWord32 s978 = s976 ^ s977;
-  const SWord32 s979 = s973 + s978;
-  const SWord32 s980 = s404 + s979;
-  const SWord32 s981 = s967 + s980;
-  const SWord32 s982 = s886 + s981;
-  const SWord32 s983 = (s982 >> 6) | (s982 << 26);
-  const SWord32 s984 = (s982 >> 11) | (s982 << 21);
-  const SWord32 s985 = s983 ^ s984;
-  const SWord32 s986 = (s982 >> 25) | (s982 << 7);
-  const SWord32 s987 = s985 ^ s986;
-  const SWord32 s988 = s898 + s987;
-  const SWord32 s989 = s954 & s982;
-  const SWord32 s990 = ~s982;
-  const SWord32 s991 = s926 & s990;
-  const SWord32 s992 = s989 ^ s991;
-  const SWord32 s993 = s988 + s992;
-  const SWord32 s995 = s993 + 0xbf597fc7UL;
-  const SWord32 s996 = (s952 >> 17) | (s952 << 15);
-  const SWord32 s997 = (s952 >> 19) | (s952 << 13);
-  const SWord32 s998 = s996 ^ s997;
-  const SWord32 s999 = s952 >> 10;
-  const SWord32 s1000 = s998 ^ s999;
-  const SWord32 s1001 = s757 + s1000;
-  const SWord32 s1002 = (s473 >> 7) | (s473 << 25);
-  const SWord32 s1003 = (s473 >> 18) | (s473 << 14);
-  const SWord32 s1004 = s1002 ^ s1003;
-  const SWord32 s1005 = s473 >> 3;
-  const SWord32 s1006 = s1004 ^ s1005;
-  const SWord32 s1007 = s1001 + s1006;
-  const SWord32 s1008 = s422 + s1007;
-  const SWord32 s1009 = s995 + s1008;
-  const SWord32 s1010 = s897 + s1009;
-  const SWord32 s1011 = (s897 >> 2) | (s897 << 30);
-  const SWord32 s1012 = (s897 >> 13) | (s897 << 19);
-  const SWord32 s1013 = s1011 ^ s1012;
-  const SWord32 s1014 = (s897 >> 22) | (s897 << 10);
-  const SWord32 s1015 = s1013 ^ s1014;
-  const SWord32 s1016 = s886 & s897;
-  const SWord32 s1017 = s875 & s897;
-  const SWord32 s1018 = s1016 ^ s1017;
-  const SWord32 s1019 = s892 ^ s1018;
-  const SWord32 s1020 = s1015 + s1019;
-  const SWord32 s1021 = s925 + s1020;
-  const SWord32 s1022 = (s1021 >> 2) | (s1021 << 30);
-  const SWord32 s1023 = (s1021 >> 13) | (s1021 << 19);
-  const SWord32 s1024 = s1022 ^ s1023;
-  const SWord32 s1025 = (s1021 >> 22) | (s1021 << 10);
-  const SWord32 s1026 = s1024 ^ s1025;
-  const SWord32 s1027 = s897 & s1021;
-  const SWord32 s1028 = s886 & s1021;
-  const SWord32 s1029 = s1027 ^ s1028;
-  const SWord32 s1030 = s1016 ^ s1029;
-  const SWord32 s1031 = s1026 + s1030;
-  const SWord32 s1032 = s953 + s1031;
-  const SWord32 s1033 = (s1032 >> 2) | (s1032 << 30);
-  const SWord32 s1034 = (s1032 >> 13) | (s1032 << 19);
-  const SWord32 s1035 = s1033 ^ s1034;
-  const SWord32 s1036 = (s1032 >> 22) | (s1032 << 10);
-  const SWord32 s1037 = s1035 ^ s1036;
-  const SWord32 s1038 = s1021 & s1032;
-  const SWord32 s1039 = s897 & s1032;
-  const SWord32 s1040 = s1038 ^ s1039;
-  const SWord32 s1041 = s1027 ^ s1040;
-  const SWord32 s1042 = s1037 + s1041;
-  const SWord32 s1043 = s981 + s1042;
-  const SWord32 s1044 = (s1010 >> 6) | (s1010 << 26);
-  const SWord32 s1045 = (s1010 >> 11) | (s1010 << 21);
-  const SWord32 s1046 = s1044 ^ s1045;
-  const SWord32 s1047 = (s1010 >> 25) | (s1010 << 7);
-  const SWord32 s1048 = s1046 ^ s1047;
-  const SWord32 s1049 = s926 + s1048;
-  const SWord32 s1050 = s982 & s1010;
-  const SWord32 s1051 = ~s1010;
-  const SWord32 s1052 = s954 & s1051;
-  const SWord32 s1053 = s1050 ^ s1052;
-  const SWord32 s1054 = s1049 + s1053;
-  const SWord32 s1056 = s1054 + 0xc6e00bf3UL;
-  const SWord32 s1057 = (s980 >> 17) | (s980 << 15);
-  const SWord32 s1058 = (s980 >> 19) | (s980 << 13);
-  const SWord32 s1059 = s1057 ^ s1058;
-  const SWord32 s1060 = s980 >> 10;
-  const SWord32 s1061 = s1059 ^ s1060;
-  const SWord32 s1062 = s785 + s1061;
-  const SWord32 s1063 = (s491 >> 7) | (s491 << 25);
-  const SWord32 s1064 = (s491 >> 18) | (s491 << 14);
-  const SWord32 s1065 = s1063 ^ s1064;
-  const SWord32 s1066 = s491 >> 3;
-  const SWord32 s1067 = s1065 ^ s1066;
-  const SWord32 s1068 = s1062 + s1067;
-  const SWord32 s1069 = s473 + s1068;
-  const SWord32 s1070 = s1056 + s1069;
-  const SWord32 s1071 = s1021 + s1070;
-  const SWord32 s1072 = (s1071 >> 6) | (s1071 << 26);
-  const SWord32 s1073 = (s1071 >> 11) | (s1071 << 21);
-  const SWord32 s1074 = s1072 ^ s1073;
-  const SWord32 s1075 = (s1071 >> 25) | (s1071 << 7);
-  const SWord32 s1076 = s1074 ^ s1075;
-  const SWord32 s1077 = s954 + s1076;
-  const SWord32 s1078 = s1010 & s1071;
-  const SWord32 s1079 = ~s1071;
-  const SWord32 s1080 = s982 & s1079;
-  const SWord32 s1081 = s1078 ^ s1080;
-  const SWord32 s1082 = s1077 + s1081;
-  const SWord32 s1084 = s1082 + 0xd5a79147UL;
-  const SWord32 s1085 = (s1008 >> 17) | (s1008 << 15);
-  const SWord32 s1086 = (s1008 >> 19) | (s1008 << 13);
-  const SWord32 s1087 = s1085 ^ s1086;
-  const SWord32 s1088 = s1008 >> 10;
-  const SWord32 s1089 = s1087 ^ s1088;
-  const SWord32 s1090 = s813 + s1089;
-  const SWord32 s1091 = (s509 >> 7) | (s509 << 25);
-  const SWord32 s1092 = (s509 >> 18) | (s509 << 14);
-  const SWord32 s1093 = s1091 ^ s1092;
-  const SWord32 s1094 = s509 >> 3;
-  const SWord32 s1095 = s1093 ^ s1094;
-  const SWord32 s1096 = s1090 + s1095;
-  const SWord32 s1097 = s491 + s1096;
-  const SWord32 s1098 = s1084 + s1097;
-  const SWord32 s1099 = s1032 + s1098;
-  const SWord32 s1100 = (s1099 >> 6) | (s1099 << 26);
-  const SWord32 s1101 = (s1099 >> 11) | (s1099 << 21);
-  const SWord32 s1102 = s1100 ^ s1101;
-  const SWord32 s1103 = (s1099 >> 25) | (s1099 << 7);
-  const SWord32 s1104 = s1102 ^ s1103;
-  const SWord32 s1105 = s982 + s1104;
-  const SWord32 s1106 = s1071 & s1099;
-  const SWord32 s1107 = ~s1099;
-  const SWord32 s1108 = s1010 & s1107;
-  const SWord32 s1109 = s1106 ^ s1108;
-  const SWord32 s1110 = s1105 + s1109;
-  const SWord32 s1112 = s1110 + 0x06ca6351UL;
-  const SWord32 s1113 = (s1069 >> 17) | (s1069 << 15);
-  const SWord32 s1114 = (s1069 >> 19) | (s1069 << 13);
-  const SWord32 s1115 = s1113 ^ s1114;
-  const SWord32 s1116 = s1069 >> 10;
-  const SWord32 s1117 = s1115 ^ s1116;
-  const SWord32 s1118 = s841 + s1117;
-  const SWord32 s1119 = (s527 >> 7) | (s527 << 25);
-  const SWord32 s1120 = (s527 >> 18) | (s527 << 14);
-  const SWord32 s1121 = s1119 ^ s1120;
-  const SWord32 s1122 = s527 >> 3;
-  const SWord32 s1123 = s1121 ^ s1122;
-  const SWord32 s1124 = s1118 + s1123;
-  const SWord32 s1125 = s509 + s1124;
-  const SWord32 s1126 = s1112 + s1125;
-  const SWord32 s1127 = s1043 + s1126;
-  const SWord32 s1128 = (s1127 >> 6) | (s1127 << 26);
-  const SWord32 s1129 = (s1127 >> 11) | (s1127 << 21);
-  const SWord32 s1130 = s1128 ^ s1129;
-  const SWord32 s1131 = (s1127 >> 25) | (s1127 << 7);
-  const SWord32 s1132 = s1130 ^ s1131;
-  const SWord32 s1133 = s1010 + s1132;
-  const SWord32 s1134 = s1099 & s1127;
-  const SWord32 s1135 = ~s1127;
-  const SWord32 s1136 = s1071 & s1135;
-  const SWord32 s1137 = s1134 ^ s1136;
-  const SWord32 s1138 = s1133 + s1137;
-  const SWord32 s1140 = s1138 + 0x14292967UL;
-  const SWord32 s1141 = (s1097 >> 17) | (s1097 << 15);
-  const SWord32 s1142 = (s1097 >> 19) | (s1097 << 13);
-  const SWord32 s1143 = s1141 ^ s1142;
-  const SWord32 s1144 = s1097 >> 10;
-  const SWord32 s1145 = s1143 ^ s1144;
-  const SWord32 s1146 = s924 + s1145;
-  const SWord32 s1147 = (s612 >> 7) | (s612 << 25);
-  const SWord32 s1148 = (s612 >> 18) | (s612 << 14);
-  const SWord32 s1149 = s1147 ^ s1148;
-  const SWord32 s1150 = s612 >> 3;
-  const SWord32 s1151 = s1149 ^ s1150;
-  const SWord32 s1152 = s1146 + s1151;
-  const SWord32 s1153 = s527 + s1152;
-  const SWord32 s1154 = s1140 + s1153;
-  const SWord32 s1155 = (s1043 >> 2) | (s1043 << 30);
-  const SWord32 s1156 = (s1043 >> 13) | (s1043 << 19);
-  const SWord32 s1157 = s1155 ^ s1156;
-  const SWord32 s1158 = (s1043 >> 22) | (s1043 << 10);
-  const SWord32 s1159 = s1157 ^ s1158;
-  const SWord32 s1160 = s1032 & s1043;
-  const SWord32 s1161 = s1021 & s1043;
-  const SWord32 s1162 = s1160 ^ s1161;
-  const SWord32 s1163 = s1038 ^ s1162;
-  const SWord32 s1164 = s1159 + s1163;
-  const SWord32 s1165 = s1009 + s1164;
-  const SWord32 s1166 = (s1165 >> 2) | (s1165 << 30);
-  const SWord32 s1167 = (s1165 >> 13) | (s1165 << 19);
-  const SWord32 s1168 = s1166 ^ s1167;
-  const SWord32 s1169 = (s1165 >> 22) | (s1165 << 10);
-  const SWord32 s1170 = s1168 ^ s1169;
-  const SWord32 s1171 = s1043 & s1165;
-  const SWord32 s1172 = s1032 & s1165;
-  const SWord32 s1173 = s1171 ^ s1172;
-  const SWord32 s1174 = s1160 ^ s1173;
-  const SWord32 s1175 = s1170 + s1174;
-  const SWord32 s1176 = s1070 + s1175;
-  const SWord32 s1177 = (s1176 >> 2) | (s1176 << 30);
-  const SWord32 s1178 = (s1176 >> 13) | (s1176 << 19);
-  const SWord32 s1179 = s1177 ^ s1178;
-  const SWord32 s1180 = (s1176 >> 22) | (s1176 << 10);
-  const SWord32 s1181 = s1179 ^ s1180;
-  const SWord32 s1182 = s1165 & s1176;
-  const SWord32 s1183 = s1043 & s1176;
-  const SWord32 s1184 = s1182 ^ s1183;
-  const SWord32 s1185 = s1171 ^ s1184;
-  const SWord32 s1186 = s1181 + s1185;
-  const SWord32 s1187 = s1098 + s1186;
-  const SWord32 s1188 = (s1187 >> 2) | (s1187 << 30);
-  const SWord32 s1189 = (s1187 >> 13) | (s1187 << 19);
-  const SWord32 s1190 = s1188 ^ s1189;
-  const SWord32 s1191 = (s1187 >> 22) | (s1187 << 10);
-  const SWord32 s1192 = s1190 ^ s1191;
-  const SWord32 s1193 = s1176 & s1187;
-  const SWord32 s1194 = s1165 & s1187;
-  const SWord32 s1195 = s1193 ^ s1194;
-  const SWord32 s1196 = s1182 ^ s1195;
-  const SWord32 s1197 = s1192 + s1196;
-  const SWord32 s1198 = s1126 + s1197;
-  const SWord32 s1199 = (s1198 >> 2) | (s1198 << 30);
-  const SWord32 s1200 = (s1198 >> 13) | (s1198 << 19);
-  const SWord32 s1201 = s1199 ^ s1200;
-  const SWord32 s1202 = (s1198 >> 22) | (s1198 << 10);
-  const SWord32 s1203 = s1201 ^ s1202;
-  const SWord32 s1204 = s1187 & s1198;
-  const SWord32 s1205 = s1176 & s1198;
-  const SWord32 s1206 = s1204 ^ s1205;
-  const SWord32 s1207 = s1193 ^ s1206;
-  const SWord32 s1208 = s1203 + s1207;
-  const SWord32 s1209 = s1154 + s1208;
-  const SWord32 s1210 = s1154 + s1165;
-  const SWord32 s1211 = (s1210 >> 6) | (s1210 << 26);
-  const SWord32 s1212 = (s1210 >> 11) | (s1210 << 21);
-  const SWord32 s1213 = s1211 ^ s1212;
-  const SWord32 s1214 = (s1210 >> 25) | (s1210 << 7);
-  const SWord32 s1215 = s1213 ^ s1214;
-  const SWord32 s1216 = s1071 + s1215;
-  const SWord32 s1217 = s1127 & s1210;
-  const SWord32 s1218 = ~s1210;
-  const SWord32 s1219 = s1099 & s1218;
-  const SWord32 s1220 = s1217 ^ s1219;
-  const SWord32 s1221 = s1216 + s1220;
-  const SWord32 s1223 = s1221 + 0x27b70a85UL;
-  const SWord32 s1224 = (s1125 >> 17) | (s1125 << 15);
-  const SWord32 s1225 = (s1125 >> 19) | (s1125 << 13);
-  const SWord32 s1226 = s1224 ^ s1225;
-  const SWord32 s1227 = s1125 >> 10;
-  const SWord32 s1228 = s1226 ^ s1227;
-  const SWord32 s1229 = s952 + s1228;
-  const SWord32 s1230 = (s640 >> 7) | (s640 << 25);
-  const SWord32 s1231 = (s640 >> 18) | (s640 << 14);
-  const SWord32 s1232 = s1230 ^ s1231;
-  const SWord32 s1233 = s640 >> 3;
-  const SWord32 s1234 = s1232 ^ s1233;
-  const SWord32 s1235 = s1229 + s1234;
-  const SWord32 s1236 = s612 + s1235;
-  const SWord32 s1237 = s1223 + s1236;
-  const SWord32 s1238 = s1176 + s1237;
-  const SWord32 s1239 = (s1238 >> 6) | (s1238 << 26);
-  const SWord32 s1240 = (s1238 >> 11) | (s1238 << 21);
-  const SWord32 s1241 = s1239 ^ s1240;
-  const SWord32 s1242 = (s1238 >> 25) | (s1238 << 7);
-  const SWord32 s1243 = s1241 ^ s1242;
-  const SWord32 s1244 = s1099 + s1243;
-  const SWord32 s1245 = s1210 & s1238;
-  const SWord32 s1246 = ~s1238;
-  const SWord32 s1247 = s1127 & s1246;
-  const SWord32 s1248 = s1245 ^ s1247;
-  const SWord32 s1249 = s1244 + s1248;
-  const SWord32 s1251 = s1249 + 0x2e1b2138UL;
-  const SWord32 s1252 = (s1153 >> 17) | (s1153 << 15);
-  const SWord32 s1253 = (s1153 >> 19) | (s1153 << 13);
-  const SWord32 s1254 = s1252 ^ s1253;
-  const SWord32 s1255 = s1153 >> 10;
-  const SWord32 s1256 = s1254 ^ s1255;
-  const SWord32 s1257 = s980 + s1256;
-  const SWord32 s1258 = (s668 >> 7) | (s668 << 25);
-  const SWord32 s1259 = (s668 >> 18) | (s668 << 14);
-  const SWord32 s1260 = s1258 ^ s1259;
-  const SWord32 s1261 = s668 >> 3;
-  const SWord32 s1262 = s1260 ^ s1261;
-  const SWord32 s1263 = s1257 + s1262;
-  const SWord32 s1264 = s640 + s1263;
-  const SWord32 s1265 = s1251 + s1264;
-  const SWord32 s1266 = s1187 + s1265;
-  const SWord32 s1267 = (s1266 >> 6) | (s1266 << 26);
-  const SWord32 s1268 = (s1266 >> 11) | (s1266 << 21);
-  const SWord32 s1269 = s1267 ^ s1268;
-  const SWord32 s1270 = (s1266 >> 25) | (s1266 << 7);
-  const SWord32 s1271 = s1269 ^ s1270;
-  const SWord32 s1272 = s1127 + s1271;
-  const SWord32 s1273 = s1238 & s1266;
-  const SWord32 s1274 = ~s1266;
-  const SWord32 s1275 = s1210 & s1274;
-  const SWord32 s1276 = s1273 ^ s1275;
-  const SWord32 s1277 = s1272 + s1276;
-  const SWord32 s1279 = s1277 + 0x4d2c6dfcUL;
-  const SWord32 s1280 = (s1236 >> 17) | (s1236 << 15);
-  const SWord32 s1281 = (s1236 >> 19) | (s1236 << 13);
-  const SWord32 s1282 = s1280 ^ s1281;
-  const SWord32 s1283 = s1236 >> 10;
-  const SWord32 s1284 = s1282 ^ s1283;
-  const SWord32 s1285 = s1008 + s1284;
-  const SWord32 s1286 = (s696 >> 7) | (s696 << 25);
-  const SWord32 s1287 = (s696 >> 18) | (s696 << 14);
-  const SWord32 s1288 = s1286 ^ s1287;
-  const SWord32 s1289 = s696 >> 3;
-  const SWord32 s1290 = s1288 ^ s1289;
-  const SWord32 s1291 = s1285 + s1290;
-  const SWord32 s1292 = s668 + s1291;
-  const SWord32 s1293 = s1279 + s1292;
-  const SWord32 s1294 = s1198 + s1293;
-  const SWord32 s1295 = (s1294 >> 6) | (s1294 << 26);
-  const SWord32 s1296 = (s1294 >> 11) | (s1294 << 21);
-  const SWord32 s1297 = s1295 ^ s1296;
-  const SWord32 s1298 = (s1294 >> 25) | (s1294 << 7);
-  const SWord32 s1299 = s1297 ^ s1298;
-  const SWord32 s1300 = s1210 + s1299;
-  const SWord32 s1301 = s1266 & s1294;
-  const SWord32 s1302 = ~s1294;
-  const SWord32 s1303 = s1238 & s1302;
-  const SWord32 s1304 = s1301 ^ s1303;
-  const SWord32 s1305 = s1300 + s1304;
-  const SWord32 s1307 = s1305 + 0x53380d13UL;
-  const SWord32 s1308 = (s1264 >> 17) | (s1264 << 15);
-  const SWord32 s1309 = (s1264 >> 19) | (s1264 << 13);
-  const SWord32 s1310 = s1308 ^ s1309;
-  const SWord32 s1311 = s1264 >> 10;
-  const SWord32 s1312 = s1310 ^ s1311;
-  const SWord32 s1313 = s1069 + s1312;
-  const SWord32 s1314 = (s757 >> 7) | (s757 << 25);
-  const SWord32 s1315 = (s757 >> 18) | (s757 << 14);
-  const SWord32 s1316 = s1314 ^ s1315;
-  const SWord32 s1317 = s757 >> 3;
-  const SWord32 s1318 = s1316 ^ s1317;
-  const SWord32 s1319 = s1313 + s1318;
-  const SWord32 s1320 = s696 + s1319;
-  const SWord32 s1321 = s1307 + s1320;
-  const SWord32 s1322 = s1209 + s1321;
-  const SWord32 s1323 = (s1209 >> 2) | (s1209 << 30);
-  const SWord32 s1324 = (s1209 >> 13) | (s1209 << 19);
-  const SWord32 s1325 = s1323 ^ s1324;
-  const SWord32 s1326 = (s1209 >> 22) | (s1209 << 10);
-  const SWord32 s1327 = s1325 ^ s1326;
-  const SWord32 s1328 = s1198 & s1209;
-  const SWord32 s1329 = s1187 & s1209;
-  const SWord32 s1330 = s1328 ^ s1329;
-  const SWord32 s1331 = s1204 ^ s1330;
-  const SWord32 s1332 = s1327 + s1331;
-  const SWord32 s1333 = s1237 + s1332;
-  const SWord32 s1334 = (s1333 >> 2) | (s1333 << 30);
-  const SWord32 s1335 = (s1333 >> 13) | (s1333 << 19);
-  const SWord32 s1336 = s1334 ^ s1335;
-  const SWord32 s1337 = (s1333 >> 22) | (s1333 << 10);
-  const SWord32 s1338 = s1336 ^ s1337;
-  const SWord32 s1339 = s1209 & s1333;
-  const SWord32 s1340 = s1198 & s1333;
-  const SWord32 s1341 = s1339 ^ s1340;
-  const SWord32 s1342 = s1328 ^ s1341;
-  const SWord32 s1343 = s1338 + s1342;
-  const SWord32 s1344 = s1265 + s1343;
-  const SWord32 s1345 = (s1344 >> 2) | (s1344 << 30);
-  const SWord32 s1346 = (s1344 >> 13) | (s1344 << 19);
-  const SWord32 s1347 = s1345 ^ s1346;
-  const SWord32 s1348 = (s1344 >> 22) | (s1344 << 10);
-  const SWord32 s1349 = s1347 ^ s1348;
-  const SWord32 s1350 = s1333 & s1344;
-  const SWord32 s1351 = s1209 & s1344;
-  const SWord32 s1352 = s1350 ^ s1351;
-  const SWord32 s1353 = s1339 ^ s1352;
-  const SWord32 s1354 = s1349 + s1353;
-  const SWord32 s1355 = s1293 + s1354;
-  const SWord32 s1356 = (s1322 >> 6) | (s1322 << 26);
-  const SWord32 s1357 = (s1322 >> 11) | (s1322 << 21);
-  const SWord32 s1358 = s1356 ^ s1357;
-  const SWord32 s1359 = (s1322 >> 25) | (s1322 << 7);
-  const SWord32 s1360 = s1358 ^ s1359;
-  const SWord32 s1361 = s1238 + s1360;
-  const SWord32 s1362 = s1294 & s1322;
-  const SWord32 s1363 = ~s1322;
-  const SWord32 s1364 = s1266 & s1363;
-  const SWord32 s1365 = s1362 ^ s1364;
-  const SWord32 s1366 = s1361 + s1365;
-  const SWord32 s1368 = s1366 + 0x650a7354UL;
-  const SWord32 s1369 = (s1292 >> 17) | (s1292 << 15);
-  const SWord32 s1370 = (s1292 >> 19) | (s1292 << 13);
-  const SWord32 s1371 = s1369 ^ s1370;
-  const SWord32 s1372 = s1292 >> 10;
-  const SWord32 s1373 = s1371 ^ s1372;
-  const SWord32 s1374 = s1097 + s1373;
-  const SWord32 s1375 = (s785 >> 7) | (s785 << 25);
-  const SWord32 s1376 = (s785 >> 18) | (s785 << 14);
-  const SWord32 s1377 = s1375 ^ s1376;
-  const SWord32 s1378 = s785 >> 3;
-  const SWord32 s1379 = s1377 ^ s1378;
-  const SWord32 s1380 = s1374 + s1379;
-  const SWord32 s1381 = s757 + s1380;
-  const SWord32 s1382 = s1368 + s1381;
-  const SWord32 s1383 = s1333 + s1382;
-  const SWord32 s1384 = (s1383 >> 6) | (s1383 << 26);
-  const SWord32 s1385 = (s1383 >> 11) | (s1383 << 21);
-  const SWord32 s1386 = s1384 ^ s1385;
-  const SWord32 s1387 = (s1383 >> 25) | (s1383 << 7);
-  const SWord32 s1388 = s1386 ^ s1387;
-  const SWord32 s1389 = s1266 + s1388;
-  const SWord32 s1390 = s1322 & s1383;
-  const SWord32 s1391 = ~s1383;
-  const SWord32 s1392 = s1294 & s1391;
-  const SWord32 s1393 = s1390 ^ s1392;
-  const SWord32 s1394 = s1389 + s1393;
-  const SWord32 s1396 = s1394 + 0x766a0abbUL;
-  const SWord32 s1397 = (s1320 >> 17) | (s1320 << 15);
-  const SWord32 s1398 = (s1320 >> 19) | (s1320 << 13);
-  const SWord32 s1399 = s1397 ^ s1398;
-  const SWord32 s1400 = s1320 >> 10;
-  const SWord32 s1401 = s1399 ^ s1400;
-  const SWord32 s1402 = s1125 + s1401;
-  const SWord32 s1403 = (s813 >> 7) | (s813 << 25);
-  const SWord32 s1404 = (s813 >> 18) | (s813 << 14);
-  const SWord32 s1405 = s1403 ^ s1404;
-  const SWord32 s1406 = s813 >> 3;
-  const SWord32 s1407 = s1405 ^ s1406;
-  const SWord32 s1408 = s1402 + s1407;
-  const SWord32 s1409 = s785 + s1408;
-  const SWord32 s1410 = s1396 + s1409;
-  const SWord32 s1411 = s1344 + s1410;
-  const SWord32 s1412 = (s1411 >> 6) | (s1411 << 26);
-  const SWord32 s1413 = (s1411 >> 11) | (s1411 << 21);
-  const SWord32 s1414 = s1412 ^ s1413;
-  const SWord32 s1415 = (s1411 >> 25) | (s1411 << 7);
-  const SWord32 s1416 = s1414 ^ s1415;
-  const SWord32 s1417 = s1294 + s1416;
-  const SWord32 s1418 = s1383 & s1411;
-  const SWord32 s1419 = ~s1411;
-  const SWord32 s1420 = s1322 & s1419;
-  const SWord32 s1421 = s1418 ^ s1420;
-  const SWord32 s1422 = s1417 + s1421;
-  const SWord32 s1424 = s1422 + 0x81c2c92eUL;
-  const SWord32 s1425 = (s1381 >> 17) | (s1381 << 15);
-  const SWord32 s1426 = (s1381 >> 19) | (s1381 << 13);
-  const SWord32 s1427 = s1425 ^ s1426;
-  const SWord32 s1428 = s1381 >> 10;
-  const SWord32 s1429 = s1427 ^ s1428;
-  const SWord32 s1430 = s1153 + s1429;
-  const SWord32 s1431 = (s841 >> 7) | (s841 << 25);
-  const SWord32 s1432 = (s841 >> 18) | (s841 << 14);
-  const SWord32 s1433 = s1431 ^ s1432;
-  const SWord32 s1434 = s841 >> 3;
-  const SWord32 s1435 = s1433 ^ s1434;
-  const SWord32 s1436 = s1430 + s1435;
-  const SWord32 s1437 = s813 + s1436;
-  const SWord32 s1438 = s1424 + s1437;
-  const SWord32 s1439 = s1355 + s1438;
-  const SWord32 s1440 = (s1439 >> 6) | (s1439 << 26);
-  const SWord32 s1441 = (s1439 >> 11) | (s1439 << 21);
-  const SWord32 s1442 = s1440 ^ s1441;
-  const SWord32 s1443 = (s1439 >> 25) | (s1439 << 7);
-  const SWord32 s1444 = s1442 ^ s1443;
-  const SWord32 s1445 = s1322 + s1444;
-  const SWord32 s1446 = s1411 & s1439;
-  const SWord32 s1447 = ~s1439;
-  const SWord32 s1448 = s1383 & s1447;
-  const SWord32 s1449 = s1446 ^ s1448;
-  const SWord32 s1450 = s1445 + s1449;
-  const SWord32 s1452 = s1450 + 0x92722c85UL;
-  const SWord32 s1453 = (s1409 >> 17) | (s1409 << 15);
-  const SWord32 s1454 = (s1409 >> 19) | (s1409 << 13);
-  const SWord32 s1455 = s1453 ^ s1454;
-  const SWord32 s1456 = s1409 >> 10;
-  const SWord32 s1457 = s1455 ^ s1456;
-  const SWord32 s1458 = s1236 + s1457;
-  const SWord32 s1459 = (s924 >> 7) | (s924 << 25);
-  const SWord32 s1460 = (s924 >> 18) | (s924 << 14);
-  const SWord32 s1461 = s1459 ^ s1460;
-  const SWord32 s1462 = s924 >> 3;
-  const SWord32 s1463 = s1461 ^ s1462;
-  const SWord32 s1464 = s1458 + s1463;
-  const SWord32 s1465 = s841 + s1464;
-  const SWord32 s1466 = s1452 + s1465;
-  const SWord32 s1467 = (s1355 >> 2) | (s1355 << 30);
-  const SWord32 s1468 = (s1355 >> 13) | (s1355 << 19);
-  const SWord32 s1469 = s1467 ^ s1468;
-  const SWord32 s1470 = (s1355 >> 22) | (s1355 << 10);
-  const SWord32 s1471 = s1469 ^ s1470;
-  const SWord32 s1472 = s1344 & s1355;
-  const SWord32 s1473 = s1333 & s1355;
-  const SWord32 s1474 = s1472 ^ s1473;
-  const SWord32 s1475 = s1350 ^ s1474;
-  const SWord32 s1476 = s1471 + s1475;
-  const SWord32 s1477 = s1321 + s1476;
-  const SWord32 s1478 = (s1477 >> 2) | (s1477 << 30);
-  const SWord32 s1479 = (s1477 >> 13) | (s1477 << 19);
-  const SWord32 s1480 = s1478 ^ s1479;
-  const SWord32 s1481 = (s1477 >> 22) | (s1477 << 10);
-  const SWord32 s1482 = s1480 ^ s1481;
-  const SWord32 s1483 = s1355 & s1477;
-  const SWord32 s1484 = s1344 & s1477;
-  const SWord32 s1485 = s1483 ^ s1484;
-  const SWord32 s1486 = s1472 ^ s1485;
-  const SWord32 s1487 = s1482 + s1486;
-  const SWord32 s1488 = s1382 + s1487;
-  const SWord32 s1489 = (s1488 >> 2) | (s1488 << 30);
-  const SWord32 s1490 = (s1488 >> 13) | (s1488 << 19);
-  const SWord32 s1491 = s1489 ^ s1490;
-  const SWord32 s1492 = (s1488 >> 22) | (s1488 << 10);
-  const SWord32 s1493 = s1491 ^ s1492;
-  const SWord32 s1494 = s1477 & s1488;
-  const SWord32 s1495 = s1355 & s1488;
-  const SWord32 s1496 = s1494 ^ s1495;
-  const SWord32 s1497 = s1483 ^ s1496;
-  const SWord32 s1498 = s1493 + s1497;
-  const SWord32 s1499 = s1410 + s1498;
-  const SWord32 s1500 = (s1499 >> 2) | (s1499 << 30);
-  const SWord32 s1501 = (s1499 >> 13) | (s1499 << 19);
-  const SWord32 s1502 = s1500 ^ s1501;
-  const SWord32 s1503 = (s1499 >> 22) | (s1499 << 10);
-  const SWord32 s1504 = s1502 ^ s1503;
-  const SWord32 s1505 = s1488 & s1499;
-  const SWord32 s1506 = s1477 & s1499;
-  const SWord32 s1507 = s1505 ^ s1506;
-  const SWord32 s1508 = s1494 ^ s1507;
-  const SWord32 s1509 = s1504 + s1508;
-  const SWord32 s1510 = s1438 + s1509;
-  const SWord32 s1511 = (s1510 >> 2) | (s1510 << 30);
-  const SWord32 s1512 = (s1510 >> 13) | (s1510 << 19);
-  const SWord32 s1513 = s1511 ^ s1512;
-  const SWord32 s1514 = (s1510 >> 22) | (s1510 << 10);
-  const SWord32 s1515 = s1513 ^ s1514;
-  const SWord32 s1516 = s1499 & s1510;
-  const SWord32 s1517 = s1488 & s1510;
-  const SWord32 s1518 = s1516 ^ s1517;
-  const SWord32 s1519 = s1505 ^ s1518;
-  const SWord32 s1520 = s1515 + s1519;
-  const SWord32 s1521 = s1466 + s1520;
-  const SWord32 s1522 = s1466 + s1477;
-  const SWord32 s1523 = (s1522 >> 6) | (s1522 << 26);
-  const SWord32 s1524 = (s1522 >> 11) | (s1522 << 21);
-  const SWord32 s1525 = s1523 ^ s1524;
-  const SWord32 s1526 = (s1522 >> 25) | (s1522 << 7);
-  const SWord32 s1527 = s1525 ^ s1526;
-  const SWord32 s1528 = s1383 + s1527;
-  const SWord32 s1529 = s1439 & s1522;
-  const SWord32 s1530 = ~s1522;
-  const SWord32 s1531 = s1411 & s1530;
-  const SWord32 s1532 = s1529 ^ s1531;
-  const SWord32 s1533 = s1528 + s1532;
-  const SWord32 s1535 = s1533 + 0xa2bfe8a1UL;
-  const SWord32 s1536 = (s1437 >> 17) | (s1437 << 15);
-  const SWord32 s1537 = (s1437 >> 19) | (s1437 << 13);
-  const SWord32 s1538 = s1536 ^ s1537;
-  const SWord32 s1539 = s1437 >> 10;
-  const SWord32 s1540 = s1538 ^ s1539;
-  const SWord32 s1541 = s1264 + s1540;
-  const SWord32 s1542 = (s952 >> 7) | (s952 << 25);
-  const SWord32 s1543 = (s952 >> 18) | (s952 << 14);
-  const SWord32 s1544 = s1542 ^ s1543;
-  const SWord32 s1545 = s952 >> 3;
-  const SWord32 s1546 = s1544 ^ s1545;
-  const SWord32 s1547 = s1541 + s1546;
-  const SWord32 s1548 = s924 + s1547;
-  const SWord32 s1549 = s1535 + s1548;
-  const SWord32 s1550 = s1488 + s1549;
-  const SWord32 s1551 = (s1550 >> 6) | (s1550 << 26);
-  const SWord32 s1552 = (s1550 >> 11) | (s1550 << 21);
-  const SWord32 s1553 = s1551 ^ s1552;
-  const SWord32 s1554 = (s1550 >> 25) | (s1550 << 7);
-  const SWord32 s1555 = s1553 ^ s1554;
-  const SWord32 s1556 = s1411 + s1555;
-  const SWord32 s1557 = s1522 & s1550;
-  const SWord32 s1558 = ~s1550;
-  const SWord32 s1559 = s1439 & s1558;
-  const SWord32 s1560 = s1557 ^ s1559;
-  const SWord32 s1561 = s1556 + s1560;
-  const SWord32 s1563 = s1561 + 0xa81a664bUL;
-  const SWord32 s1564 = (s1465 >> 17) | (s1465 << 15);
-  const SWord32 s1565 = (s1465 >> 19) | (s1465 << 13);
-  const SWord32 s1566 = s1564 ^ s1565;
-  const SWord32 s1567 = s1465 >> 10;
-  const SWord32 s1568 = s1566 ^ s1567;
-  const SWord32 s1569 = s1292 + s1568;
-  const SWord32 s1570 = (s980 >> 7) | (s980 << 25);
-  const SWord32 s1571 = (s980 >> 18) | (s980 << 14);
-  const SWord32 s1572 = s1570 ^ s1571;
-  const SWord32 s1573 = s980 >> 3;
-  const SWord32 s1574 = s1572 ^ s1573;
-  const SWord32 s1575 = s1569 + s1574;
-  const SWord32 s1576 = s952 + s1575;
-  const SWord32 s1577 = s1563 + s1576;
-  const SWord32 s1578 = s1499 + s1577;
-  const SWord32 s1579 = (s1578 >> 6) | (s1578 << 26);
-  const SWord32 s1580 = (s1578 >> 11) | (s1578 << 21);
-  const SWord32 s1581 = s1579 ^ s1580;
-  const SWord32 s1582 = (s1578 >> 25) | (s1578 << 7);
-  const SWord32 s1583 = s1581 ^ s1582;
-  const SWord32 s1584 = s1439 + s1583;
-  const SWord32 s1585 = s1550 & s1578;
-  const SWord32 s1586 = ~s1578;
-  const SWord32 s1587 = s1522 & s1586;
-  const SWord32 s1588 = s1585 ^ s1587;
-  const SWord32 s1589 = s1584 + s1588;
-  const SWord32 s1591 = s1589 + 0xc24b8b70UL;
-  const SWord32 s1592 = (s1548 >> 17) | (s1548 << 15);
-  const SWord32 s1593 = (s1548 >> 19) | (s1548 << 13);
-  const SWord32 s1594 = s1592 ^ s1593;
-  const SWord32 s1595 = s1548 >> 10;
-  const SWord32 s1596 = s1594 ^ s1595;
-  const SWord32 s1597 = s1320 + s1596;
-  const SWord32 s1598 = (s1008 >> 7) | (s1008 << 25);
-  const SWord32 s1599 = (s1008 >> 18) | (s1008 << 14);
-  const SWord32 s1600 = s1598 ^ s1599;
-  const SWord32 s1601 = s1008 >> 3;
-  const SWord32 s1602 = s1600 ^ s1601;
-  const SWord32 s1603 = s1597 + s1602;
-  const SWord32 s1604 = s980 + s1603;
-  const SWord32 s1605 = s1591 + s1604;
-  const SWord32 s1606 = s1510 + s1605;
-  const SWord32 s1607 = (s1606 >> 6) | (s1606 << 26);
-  const SWord32 s1608 = (s1606 >> 11) | (s1606 << 21);
-  const SWord32 s1609 = s1607 ^ s1608;
-  const SWord32 s1610 = (s1606 >> 25) | (s1606 << 7);
-  const SWord32 s1611 = s1609 ^ s1610;
-  const SWord32 s1612 = s1522 + s1611;
-  const SWord32 s1613 = s1578 & s1606;
-  const SWord32 s1614 = ~s1606;
-  const SWord32 s1615 = s1550 & s1614;
-  const SWord32 s1616 = s1613 ^ s1615;
-  const SWord32 s1617 = s1612 + s1616;
-  const SWord32 s1619 = s1617 + 0xc76c51a3UL;
-  const SWord32 s1620 = (s1576 >> 17) | (s1576 << 15);
-  const SWord32 s1621 = (s1576 >> 19) | (s1576 << 13);
-  const SWord32 s1622 = s1620 ^ s1621;
-  const SWord32 s1623 = s1576 >> 10;
-  const SWord32 s1624 = s1622 ^ s1623;
-  const SWord32 s1625 = s1381 + s1624;
-  const SWord32 s1626 = (s1069 >> 7) | (s1069 << 25);
-  const SWord32 s1627 = (s1069 >> 18) | (s1069 << 14);
-  const SWord32 s1628 = s1626 ^ s1627;
-  const SWord32 s1629 = s1069 >> 3;
-  const SWord32 s1630 = s1628 ^ s1629;
-  const SWord32 s1631 = s1625 + s1630;
-  const SWord32 s1632 = s1008 + s1631;
-  const SWord32 s1633 = s1619 + s1632;
-  const SWord32 s1634 = s1521 + s1633;
-  const SWord32 s1635 = (s1521 >> 2) | (s1521 << 30);
-  const SWord32 s1636 = (s1521 >> 13) | (s1521 << 19);
-  const SWord32 s1637 = s1635 ^ s1636;
-  const SWord32 s1638 = (s1521 >> 22) | (s1521 << 10);
-  const SWord32 s1639 = s1637 ^ s1638;
-  const SWord32 s1640 = s1510 & s1521;
-  const SWord32 s1641 = s1499 & s1521;
-  const SWord32 s1642 = s1640 ^ s1641;
-  const SWord32 s1643 = s1516 ^ s1642;
-  const SWord32 s1644 = s1639 + s1643;
-  const SWord32 s1645 = s1549 + s1644;
-  const SWord32 s1646 = (s1645 >> 2) | (s1645 << 30);
-  const SWord32 s1647 = (s1645 >> 13) | (s1645 << 19);
-  const SWord32 s1648 = s1646 ^ s1647;
-  const SWord32 s1649 = (s1645 >> 22) | (s1645 << 10);
-  const SWord32 s1650 = s1648 ^ s1649;
-  const SWord32 s1651 = s1521 & s1645;
-  const SWord32 s1652 = s1510 & s1645;
-  const SWord32 s1653 = s1651 ^ s1652;
-  const SWord32 s1654 = s1640 ^ s1653;
-  const SWord32 s1655 = s1650 + s1654;
-  const SWord32 s1656 = s1577 + s1655;
-  const SWord32 s1657 = (s1656 >> 2) | (s1656 << 30);
-  const SWord32 s1658 = (s1656 >> 13) | (s1656 << 19);
-  const SWord32 s1659 = s1657 ^ s1658;
-  const SWord32 s1660 = (s1656 >> 22) | (s1656 << 10);
-  const SWord32 s1661 = s1659 ^ s1660;
-  const SWord32 s1662 = s1645 & s1656;
-  const SWord32 s1663 = s1521 & s1656;
-  const SWord32 s1664 = s1662 ^ s1663;
-  const SWord32 s1665 = s1651 ^ s1664;
-  const SWord32 s1666 = s1661 + s1665;
-  const SWord32 s1667 = s1605 + s1666;
-  const SWord32 s1668 = (s1634 >> 6) | (s1634 << 26);
-  const SWord32 s1669 = (s1634 >> 11) | (s1634 << 21);
-  const SWord32 s1670 = s1668 ^ s1669;
-  const SWord32 s1671 = (s1634 >> 25) | (s1634 << 7);
-  const SWord32 s1672 = s1670 ^ s1671;
-  const SWord32 s1673 = s1550 + s1672;
-  const SWord32 s1674 = s1606 & s1634;
-  const SWord32 s1675 = ~s1634;
-  const SWord32 s1676 = s1578 & s1675;
-  const SWord32 s1677 = s1674 ^ s1676;
-  const SWord32 s1678 = s1673 + s1677;
-  const SWord32 s1680 = s1678 + 0xd192e819UL;
-  const SWord32 s1681 = (s1604 >> 17) | (s1604 << 15);
-  const SWord32 s1682 = (s1604 >> 19) | (s1604 << 13);
-  const SWord32 s1683 = s1681 ^ s1682;
-  const SWord32 s1684 = s1604 >> 10;
-  const SWord32 s1685 = s1683 ^ s1684;
-  const SWord32 s1686 = s1409 + s1685;
-  const SWord32 s1687 = (s1097 >> 7) | (s1097 << 25);
-  const SWord32 s1688 = (s1097 >> 18) | (s1097 << 14);
-  const SWord32 s1689 = s1687 ^ s1688;
-  const SWord32 s1690 = s1097 >> 3;
-  const SWord32 s1691 = s1689 ^ s1690;
-  const SWord32 s1692 = s1686 + s1691;
-  const SWord32 s1693 = s1069 + s1692;
-  const SWord32 s1694 = s1680 + s1693;
-  const SWord32 s1695 = s1645 + s1694;
-  const SWord32 s1696 = (s1695 >> 6) | (s1695 << 26);
-  const SWord32 s1697 = (s1695 >> 11) | (s1695 << 21);
-  const SWord32 s1698 = s1696 ^ s1697;
-  const SWord32 s1699 = (s1695 >> 25) | (s1695 << 7);
-  const SWord32 s1700 = s1698 ^ s1699;
-  const SWord32 s1701 = s1578 + s1700;
-  const SWord32 s1702 = s1634 & s1695;
-  const SWord32 s1703 = ~s1695;
-  const SWord32 s1704 = s1606 & s1703;
-  const SWord32 s1705 = s1702 ^ s1704;
-  const SWord32 s1706 = s1701 + s1705;
-  const SWord32 s1708 = s1706 + 0xd6990624UL;
-  const SWord32 s1709 = (s1632 >> 17) | (s1632 << 15);
-  const SWord32 s1710 = (s1632 >> 19) | (s1632 << 13);
-  const SWord32 s1711 = s1709 ^ s1710;
-  const SWord32 s1712 = s1632 >> 10;
-  const SWord32 s1713 = s1711 ^ s1712;
-  const SWord32 s1714 = s1437 + s1713;
-  const SWord32 s1715 = (s1125 >> 7) | (s1125 << 25);
-  const SWord32 s1716 = (s1125 >> 18) | (s1125 << 14);
-  const SWord32 s1717 = s1715 ^ s1716;
-  const SWord32 s1718 = s1125 >> 3;
-  const SWord32 s1719 = s1717 ^ s1718;
-  const SWord32 s1720 = s1714 + s1719;
-  const SWord32 s1721 = s1097 + s1720;
-  const SWord32 s1722 = s1708 + s1721;
-  const SWord32 s1723 = s1656 + s1722;
-  const SWord32 s1724 = (s1723 >> 6) | (s1723 << 26);
-  const SWord32 s1725 = (s1723 >> 11) | (s1723 << 21);
-  const SWord32 s1726 = s1724 ^ s1725;
-  const SWord32 s1727 = (s1723 >> 25) | (s1723 << 7);
-  const SWord32 s1728 = s1726 ^ s1727;
-  const SWord32 s1729 = s1606 + s1728;
-  const SWord32 s1730 = s1695 & s1723;
-  const SWord32 s1731 = ~s1723;
-  const SWord32 s1732 = s1634 & s1731;
-  const SWord32 s1733 = s1730 ^ s1732;
-  const SWord32 s1734 = s1729 + s1733;
-  const SWord32 s1736 = s1734 + 0xf40e3585UL;
-  const SWord32 s1737 = (s1693 >> 17) | (s1693 << 15);
-  const SWord32 s1738 = (s1693 >> 19) | (s1693 << 13);
-  const SWord32 s1739 = s1737 ^ s1738;
-  const SWord32 s1740 = s1693 >> 10;
-  const SWord32 s1741 = s1739 ^ s1740;
-  const SWord32 s1742 = s1465 + s1741;
-  const SWord32 s1743 = (s1153 >> 7) | (s1153 << 25);
-  const SWord32 s1744 = (s1153 >> 18) | (s1153 << 14);
-  const SWord32 s1745 = s1743 ^ s1744;
-  const SWord32 s1746 = s1153 >> 3;
-  const SWord32 s1747 = s1745 ^ s1746;
-  const SWord32 s1748 = s1742 + s1747;
-  const SWord32 s1749 = s1125 + s1748;
-  const SWord32 s1750 = s1736 + s1749;
-  const SWord32 s1751 = s1667 + s1750;
-  const SWord32 s1752 = (s1751 >> 6) | (s1751 << 26);
-  const SWord32 s1753 = (s1751 >> 11) | (s1751 << 21);
-  const SWord32 s1754 = s1752 ^ s1753;
-  const SWord32 s1755 = (s1751 >> 25) | (s1751 << 7);
-  const SWord32 s1756 = s1754 ^ s1755;
-  const SWord32 s1757 = s1634 + s1756;
-  const SWord32 s1758 = s1723 & s1751;
-  const SWord32 s1759 = ~s1751;
-  const SWord32 s1760 = s1695 & s1759;
-  const SWord32 s1761 = s1758 ^ s1760;
-  const SWord32 s1762 = s1757 + s1761;
-  const SWord32 s1764 = s1762 + 0x106aa070UL;
-  const SWord32 s1765 = (s1721 >> 17) | (s1721 << 15);
-  const SWord32 s1766 = (s1721 >> 19) | (s1721 << 13);
-  const SWord32 s1767 = s1765 ^ s1766;
-  const SWord32 s1768 = s1721 >> 10;
-  const SWord32 s1769 = s1767 ^ s1768;
-  const SWord32 s1770 = s1548 + s1769;
-  const SWord32 s1771 = (s1236 >> 7) | (s1236 << 25);
-  const SWord32 s1772 = (s1236 >> 18) | (s1236 << 14);
-  const SWord32 s1773 = s1771 ^ s1772;
-  const SWord32 s1774 = s1236 >> 3;
-  const SWord32 s1775 = s1773 ^ s1774;
-  const SWord32 s1776 = s1770 + s1775;
-  const SWord32 s1777 = s1153 + s1776;
-  const SWord32 s1778 = s1764 + s1777;
-  const SWord32 s1779 = (s1667 >> 2) | (s1667 << 30);
-  const SWord32 s1780 = (s1667 >> 13) | (s1667 << 19);
-  const SWord32 s1781 = s1779 ^ s1780;
-  const SWord32 s1782 = (s1667 >> 22) | (s1667 << 10);
-  const SWord32 s1783 = s1781 ^ s1782;
-  const SWord32 s1784 = s1656 & s1667;
-  const SWord32 s1785 = s1645 & s1667;
-  const SWord32 s1786 = s1784 ^ s1785;
-  const SWord32 s1787 = s1662 ^ s1786;
-  const SWord32 s1788 = s1783 + s1787;
-  const SWord32 s1789 = s1633 + s1788;
-  const SWord32 s1790 = (s1789 >> 2) | (s1789 << 30);
-  const SWord32 s1791 = (s1789 >> 13) | (s1789 << 19);
-  const SWord32 s1792 = s1790 ^ s1791;
-  const SWord32 s1793 = (s1789 >> 22) | (s1789 << 10);
-  const SWord32 s1794 = s1792 ^ s1793;
-  const SWord32 s1795 = s1667 & s1789;
-  const SWord32 s1796 = s1656 & s1789;
-  const SWord32 s1797 = s1795 ^ s1796;
-  const SWord32 s1798 = s1784 ^ s1797;
-  const SWord32 s1799 = s1794 + s1798;
-  const SWord32 s1800 = s1694 + s1799;
-  const SWord32 s1801 = (s1800 >> 2) | (s1800 << 30);
-  const SWord32 s1802 = (s1800 >> 13) | (s1800 << 19);
-  const SWord32 s1803 = s1801 ^ s1802;
-  const SWord32 s1804 = (s1800 >> 22) | (s1800 << 10);
-  const SWord32 s1805 = s1803 ^ s1804;
-  const SWord32 s1806 = s1789 & s1800;
-  const SWord32 s1807 = s1667 & s1800;
-  const SWord32 s1808 = s1806 ^ s1807;
-  const SWord32 s1809 = s1795 ^ s1808;
-  const SWord32 s1810 = s1805 + s1809;
-  const SWord32 s1811 = s1722 + s1810;
-  const SWord32 s1812 = (s1811 >> 2) | (s1811 << 30);
-  const SWord32 s1813 = (s1811 >> 13) | (s1811 << 19);
-  const SWord32 s1814 = s1812 ^ s1813;
-  const SWord32 s1815 = (s1811 >> 22) | (s1811 << 10);
-  const SWord32 s1816 = s1814 ^ s1815;
-  const SWord32 s1817 = s1800 & s1811;
-  const SWord32 s1818 = s1789 & s1811;
-  const SWord32 s1819 = s1817 ^ s1818;
-  const SWord32 s1820 = s1806 ^ s1819;
-  const SWord32 s1821 = s1816 + s1820;
-  const SWord32 s1822 = s1750 + s1821;
-  const SWord32 s1823 = (s1822 >> 2) | (s1822 << 30);
-  const SWord32 s1824 = (s1822 >> 13) | (s1822 << 19);
-  const SWord32 s1825 = s1823 ^ s1824;
-  const SWord32 s1826 = (s1822 >> 22) | (s1822 << 10);
-  const SWord32 s1827 = s1825 ^ s1826;
-  const SWord32 s1828 = s1811 & s1822;
-  const SWord32 s1829 = s1800 & s1822;
-  const SWord32 s1830 = s1828 ^ s1829;
-  const SWord32 s1831 = s1817 ^ s1830;
-  const SWord32 s1832 = s1827 + s1831;
-  const SWord32 s1833 = s1778 + s1832;
-  const SWord32 s1834 = s1778 + s1789;
-  const SWord32 s1835 = (s1834 >> 6) | (s1834 << 26);
-  const SWord32 s1836 = (s1834 >> 11) | (s1834 << 21);
-  const SWord32 s1837 = s1835 ^ s1836;
-  const SWord32 s1838 = (s1834 >> 25) | (s1834 << 7);
-  const SWord32 s1839 = s1837 ^ s1838;
-  const SWord32 s1840 = s1695 + s1839;
-  const SWord32 s1841 = s1751 & s1834;
-  const SWord32 s1842 = ~s1834;
-  const SWord32 s1843 = s1723 & s1842;
-  const SWord32 s1844 = s1841 ^ s1843;
-  const SWord32 s1845 = s1840 + s1844;
-  const SWord32 s1847 = s1845 + 0x19a4c116UL;
-  const SWord32 s1848 = (s1749 >> 17) | (s1749 << 15);
-  const SWord32 s1849 = (s1749 >> 19) | (s1749 << 13);
-  const SWord32 s1850 = s1848 ^ s1849;
-  const SWord32 s1851 = s1749 >> 10;
-  const SWord32 s1852 = s1850 ^ s1851;
-  const SWord32 s1853 = s1576 + s1852;
-  const SWord32 s1854 = (s1264 >> 7) | (s1264 << 25);
-  const SWord32 s1855 = (s1264 >> 18) | (s1264 << 14);
-  const SWord32 s1856 = s1854 ^ s1855;
-  const SWord32 s1857 = s1264 >> 3;
-  const SWord32 s1858 = s1856 ^ s1857;
-  const SWord32 s1859 = s1853 + s1858;
-  const SWord32 s1860 = s1236 + s1859;
-  const SWord32 s1861 = s1847 + s1860;
-  const SWord32 s1862 = s1800 + s1861;
-  const SWord32 s1863 = (s1862 >> 6) | (s1862 << 26);
-  const SWord32 s1864 = (s1862 >> 11) | (s1862 << 21);
-  const SWord32 s1865 = s1863 ^ s1864;
-  const SWord32 s1866 = (s1862 >> 25) | (s1862 << 7);
-  const SWord32 s1867 = s1865 ^ s1866;
-  const SWord32 s1868 = s1723 + s1867;
-  const SWord32 s1869 = s1834 & s1862;
-  const SWord32 s1870 = ~s1862;
-  const SWord32 s1871 = s1751 & s1870;
-  const SWord32 s1872 = s1869 ^ s1871;
-  const SWord32 s1873 = s1868 + s1872;
-  const SWord32 s1875 = s1873 + 0x1e376c08UL;
-  const SWord32 s1876 = (s1777 >> 17) | (s1777 << 15);
-  const SWord32 s1877 = (s1777 >> 19) | (s1777 << 13);
-  const SWord32 s1878 = s1876 ^ s1877;
-  const SWord32 s1879 = s1777 >> 10;
-  const SWord32 s1880 = s1878 ^ s1879;
-  const SWord32 s1881 = s1604 + s1880;
-  const SWord32 s1882 = (s1292 >> 7) | (s1292 << 25);
-  const SWord32 s1883 = (s1292 >> 18) | (s1292 << 14);
-  const SWord32 s1884 = s1882 ^ s1883;
-  const SWord32 s1885 = s1292 >> 3;
-  const SWord32 s1886 = s1884 ^ s1885;
-  const SWord32 s1887 = s1881 + s1886;
-  const SWord32 s1888 = s1264 + s1887;
-  const SWord32 s1889 = s1875 + s1888;
-  const SWord32 s1890 = s1811 + s1889;
-  const SWord32 s1891 = (s1890 >> 6) | (s1890 << 26);
-  const SWord32 s1892 = (s1890 >> 11) | (s1890 << 21);
-  const SWord32 s1893 = s1891 ^ s1892;
-  const SWord32 s1894 = (s1890 >> 25) | (s1890 << 7);
-  const SWord32 s1895 = s1893 ^ s1894;
-  const SWord32 s1896 = s1751 + s1895;
-  const SWord32 s1897 = s1862 & s1890;
-  const SWord32 s1898 = ~s1890;
-  const SWord32 s1899 = s1834 & s1898;
-  const SWord32 s1900 = s1897 ^ s1899;
-  const SWord32 s1901 = s1896 + s1900;
-  const SWord32 s1903 = s1901 + 0x2748774cUL;
-  const SWord32 s1904 = (s1860 >> 17) | (s1860 << 15);
-  const SWord32 s1905 = (s1860 >> 19) | (s1860 << 13);
-  const SWord32 s1906 = s1904 ^ s1905;
-  const SWord32 s1907 = s1860 >> 10;
-  const SWord32 s1908 = s1906 ^ s1907;
-  const SWord32 s1909 = s1632 + s1908;
-  const SWord32 s1910 = (s1320 >> 7) | (s1320 << 25);
-  const SWord32 s1911 = (s1320 >> 18) | (s1320 << 14);
-  const SWord32 s1912 = s1910 ^ s1911;
-  const SWord32 s1913 = s1320 >> 3;
-  const SWord32 s1914 = s1912 ^ s1913;
-  const SWord32 s1915 = s1909 + s1914;
-  const SWord32 s1916 = s1292 + s1915;
-  const SWord32 s1917 = s1903 + s1916;
-  const SWord32 s1918 = s1822 + s1917;
-  const SWord32 s1919 = (s1918 >> 6) | (s1918 << 26);
-  const SWord32 s1920 = (s1918 >> 11) | (s1918 << 21);
-  const SWord32 s1921 = s1919 ^ s1920;
-  const SWord32 s1922 = (s1918 >> 25) | (s1918 << 7);
-  const SWord32 s1923 = s1921 ^ s1922;
-  const SWord32 s1924 = s1834 + s1923;
-  const SWord32 s1925 = s1890 & s1918;
-  const SWord32 s1926 = ~s1918;
-  const SWord32 s1927 = s1862 & s1926;
-  const SWord32 s1928 = s1925 ^ s1927;
-  const SWord32 s1929 = s1924 + s1928;
-  const SWord32 s1931 = s1929 + 0x34b0bcb5UL;
-  const SWord32 s1932 = (s1888 >> 17) | (s1888 << 15);
-  const SWord32 s1933 = (s1888 >> 19) | (s1888 << 13);
-  const SWord32 s1934 = s1932 ^ s1933;
-  const SWord32 s1935 = s1888 >> 10;
-  const SWord32 s1936 = s1934 ^ s1935;
-  const SWord32 s1937 = s1693 + s1936;
-  const SWord32 s1938 = (s1381 >> 7) | (s1381 << 25);
-  const SWord32 s1939 = (s1381 >> 18) | (s1381 << 14);
-  const SWord32 s1940 = s1938 ^ s1939;
-  const SWord32 s1941 = s1381 >> 3;
-  const SWord32 s1942 = s1940 ^ s1941;
-  const SWord32 s1943 = s1937 + s1942;
-  const SWord32 s1944 = s1320 + s1943;
-  const SWord32 s1945 = s1931 + s1944;
-  const SWord32 s1946 = s1833 + s1945;
-  const SWord32 s1947 = (s1833 >> 2) | (s1833 << 30);
-  const SWord32 s1948 = (s1833 >> 13) | (s1833 << 19);
-  const SWord32 s1949 = s1947 ^ s1948;
-  const SWord32 s1950 = (s1833 >> 22) | (s1833 << 10);
-  const SWord32 s1951 = s1949 ^ s1950;
-  const SWord32 s1952 = s1822 & s1833;
-  const SWord32 s1953 = s1811 & s1833;
-  const SWord32 s1954 = s1952 ^ s1953;
-  const SWord32 s1955 = s1828 ^ s1954;
-  const SWord32 s1956 = s1951 + s1955;
-  const SWord32 s1957 = s1861 + s1956;
-  const SWord32 s1958 = (s1957 >> 2) | (s1957 << 30);
-  const SWord32 s1959 = (s1957 >> 13) | (s1957 << 19);
-  const SWord32 s1960 = s1958 ^ s1959;
-  const SWord32 s1961 = (s1957 >> 22) | (s1957 << 10);
-  const SWord32 s1962 = s1960 ^ s1961;
-  const SWord32 s1963 = s1833 & s1957;
-  const SWord32 s1964 = s1822 & s1957;
-  const SWord32 s1965 = s1963 ^ s1964;
-  const SWord32 s1966 = s1952 ^ s1965;
-  const SWord32 s1967 = s1962 + s1966;
-  const SWord32 s1968 = s1889 + s1967;
-  const SWord32 s1969 = (s1968 >> 2) | (s1968 << 30);
-  const SWord32 s1970 = (s1968 >> 13) | (s1968 << 19);
-  const SWord32 s1971 = s1969 ^ s1970;
-  const SWord32 s1972 = (s1968 >> 22) | (s1968 << 10);
-  const SWord32 s1973 = s1971 ^ s1972;
-  const SWord32 s1974 = s1957 & s1968;
-  const SWord32 s1975 = s1833 & s1968;
-  const SWord32 s1976 = s1974 ^ s1975;
-  const SWord32 s1977 = s1963 ^ s1976;
-  const SWord32 s1978 = s1973 + s1977;
-  const SWord32 s1979 = s1917 + s1978;
-  const SWord32 s1980 = (s1946 >> 6) | (s1946 << 26);
-  const SWord32 s1981 = (s1946 >> 11) | (s1946 << 21);
-  const SWord32 s1982 = s1980 ^ s1981;
-  const SWord32 s1983 = (s1946 >> 25) | (s1946 << 7);
-  const SWord32 s1984 = s1982 ^ s1983;
-  const SWord32 s1985 = s1862 + s1984;
-  const SWord32 s1986 = s1918 & s1946;
-  const SWord32 s1987 = ~s1946;
-  const SWord32 s1988 = s1890 & s1987;
-  const SWord32 s1989 = s1986 ^ s1988;
-  const SWord32 s1990 = s1985 + s1989;
-  const SWord32 s1992 = s1990 + 0x391c0cb3UL;
-  const SWord32 s1993 = (s1916 >> 17) | (s1916 << 15);
-  const SWord32 s1994 = (s1916 >> 19) | (s1916 << 13);
-  const SWord32 s1995 = s1993 ^ s1994;
-  const SWord32 s1996 = s1916 >> 10;
-  const SWord32 s1997 = s1995 ^ s1996;
-  const SWord32 s1998 = s1721 + s1997;
-  const SWord32 s1999 = (s1409 >> 7) | (s1409 << 25);
-  const SWord32 s2000 = (s1409 >> 18) | (s1409 << 14);
-  const SWord32 s2001 = s1999 ^ s2000;
-  const SWord32 s2002 = s1409 >> 3;
-  const SWord32 s2003 = s2001 ^ s2002;
-  const SWord32 s2004 = s1998 + s2003;
-  const SWord32 s2005 = s1381 + s2004;
-  const SWord32 s2006 = s1992 + s2005;
-  const SWord32 s2007 = s1957 + s2006;
-  const SWord32 s2008 = (s2007 >> 6) | (s2007 << 26);
-  const SWord32 s2009 = (s2007 >> 11) | (s2007 << 21);
-  const SWord32 s2010 = s2008 ^ s2009;
-  const SWord32 s2011 = (s2007 >> 25) | (s2007 << 7);
-  const SWord32 s2012 = s2010 ^ s2011;
-  const SWord32 s2013 = s1890 + s2012;
-  const SWord32 s2014 = s1946 & s2007;
-  const SWord32 s2015 = ~s2007;
-  const SWord32 s2016 = s1918 & s2015;
-  const SWord32 s2017 = s2014 ^ s2016;
-  const SWord32 s2018 = s2013 + s2017;
-  const SWord32 s2020 = s2018 + 0x4ed8aa4aUL;
-  const SWord32 s2021 = (s1944 >> 17) | (s1944 << 15);
-  const SWord32 s2022 = (s1944 >> 19) | (s1944 << 13);
-  const SWord32 s2023 = s2021 ^ s2022;
-  const SWord32 s2024 = s1944 >> 10;
-  const SWord32 s2025 = s2023 ^ s2024;
-  const SWord32 s2026 = s1749 + s2025;
-  const SWord32 s2027 = (s1437 >> 7) | (s1437 << 25);
-  const SWord32 s2028 = (s1437 >> 18) | (s1437 << 14);
-  const SWord32 s2029 = s2027 ^ s2028;
-  const SWord32 s2030 = s1437 >> 3;
-  const SWord32 s2031 = s2029 ^ s2030;
-  const SWord32 s2032 = s2026 + s2031;
-  const SWord32 s2033 = s1409 + s2032;
-  const SWord32 s2034 = s2020 + s2033;
-  const SWord32 s2035 = s1968 + s2034;
-  const SWord32 s2036 = (s2035 >> 6) | (s2035 << 26);
-  const SWord32 s2037 = (s2035 >> 11) | (s2035 << 21);
-  const SWord32 s2038 = s2036 ^ s2037;
-  const SWord32 s2039 = (s2035 >> 25) | (s2035 << 7);
-  const SWord32 s2040 = s2038 ^ s2039;
-  const SWord32 s2041 = s1918 + s2040;
-  const SWord32 s2042 = s2007 & s2035;
-  const SWord32 s2043 = ~s2035;
-  const SWord32 s2044 = s1946 & s2043;
-  const SWord32 s2045 = s2042 ^ s2044;
-  const SWord32 s2046 = s2041 + s2045;
-  const SWord32 s2048 = s2046 + 0x5b9cca4fUL;
-  const SWord32 s2049 = (s2005 >> 17) | (s2005 << 15);
-  const SWord32 s2050 = (s2005 >> 19) | (s2005 << 13);
-  const SWord32 s2051 = s2049 ^ s2050;
-  const SWord32 s2052 = s2005 >> 10;
-  const SWord32 s2053 = s2051 ^ s2052;
-  const SWord32 s2054 = s1777 + s2053;
-  const SWord32 s2055 = (s1465 >> 7) | (s1465 << 25);
-  const SWord32 s2056 = (s1465 >> 18) | (s1465 << 14);
-  const SWord32 s2057 = s2055 ^ s2056;
-  const SWord32 s2058 = s1465 >> 3;
-  const SWord32 s2059 = s2057 ^ s2058;
-  const SWord32 s2060 = s2054 + s2059;
-  const SWord32 s2061 = s1437 + s2060;
-  const SWord32 s2062 = s2048 + s2061;
-  const SWord32 s2063 = s1979 + s2062;
-  const SWord32 s2064 = (s2063 >> 6) | (s2063 << 26);
-  const SWord32 s2065 = (s2063 >> 11) | (s2063 << 21);
-  const SWord32 s2066 = s2064 ^ s2065;
-  const SWord32 s2067 = (s2063 >> 25) | (s2063 << 7);
-  const SWord32 s2068 = s2066 ^ s2067;
-  const SWord32 s2069 = s1946 + s2068;
-  const SWord32 s2070 = s2035 & s2063;
-  const SWord32 s2071 = ~s2063;
-  const SWord32 s2072 = s2007 & s2071;
-  const SWord32 s2073 = s2070 ^ s2072;
-  const SWord32 s2074 = s2069 + s2073;
-  const SWord32 s2076 = s2074 + 0x682e6ff3UL;
-  const SWord32 s2077 = (s2033 >> 17) | (s2033 << 15);
-  const SWord32 s2078 = (s2033 >> 19) | (s2033 << 13);
-  const SWord32 s2079 = s2077 ^ s2078;
-  const SWord32 s2080 = s2033 >> 10;
-  const SWord32 s2081 = s2079 ^ s2080;
-  const SWord32 s2082 = s1860 + s2081;
-  const SWord32 s2083 = (s1548 >> 7) | (s1548 << 25);
-  const SWord32 s2084 = (s1548 >> 18) | (s1548 << 14);
-  const SWord32 s2085 = s2083 ^ s2084;
-  const SWord32 s2086 = s1548 >> 3;
-  const SWord32 s2087 = s2085 ^ s2086;
-  const SWord32 s2088 = s2082 + s2087;
-  const SWord32 s2089 = s1465 + s2088;
-  const SWord32 s2090 = s2076 + s2089;
-  const SWord32 s2091 = (s1979 >> 2) | (s1979 << 30);
-  const SWord32 s2092 = (s1979 >> 13) | (s1979 << 19);
-  const SWord32 s2093 = s2091 ^ s2092;
-  const SWord32 s2094 = (s1979 >> 22) | (s1979 << 10);
-  const SWord32 s2095 = s2093 ^ s2094;
-  const SWord32 s2096 = s1968 & s1979;
-  const SWord32 s2097 = s1957 & s1979;
-  const SWord32 s2098 = s2096 ^ s2097;
-  const SWord32 s2099 = s1974 ^ s2098;
-  const SWord32 s2100 = s2095 + s2099;
-  const SWord32 s2101 = s1945 + s2100;
-  const SWord32 s2102 = (s2101 >> 2) | (s2101 << 30);
-  const SWord32 s2103 = (s2101 >> 13) | (s2101 << 19);
-  const SWord32 s2104 = s2102 ^ s2103;
-  const SWord32 s2105 = (s2101 >> 22) | (s2101 << 10);
-  const SWord32 s2106 = s2104 ^ s2105;
-  const SWord32 s2107 = s1979 & s2101;
-  const SWord32 s2108 = s1968 & s2101;
-  const SWord32 s2109 = s2107 ^ s2108;
-  const SWord32 s2110 = s2096 ^ s2109;
-  const SWord32 s2111 = s2106 + s2110;
-  const SWord32 s2112 = s2006 + s2111;
-  const SWord32 s2113 = (s2112 >> 2) | (s2112 << 30);
-  const SWord32 s2114 = (s2112 >> 13) | (s2112 << 19);
-  const SWord32 s2115 = s2113 ^ s2114;
-  const SWord32 s2116 = (s2112 >> 22) | (s2112 << 10);
-  const SWord32 s2117 = s2115 ^ s2116;
-  const SWord32 s2118 = s2101 & s2112;
-  const SWord32 s2119 = s1979 & s2112;
-  const SWord32 s2120 = s2118 ^ s2119;
-  const SWord32 s2121 = s2107 ^ s2120;
-  const SWord32 s2122 = s2117 + s2121;
-  const SWord32 s2123 = s2034 + s2122;
-  const SWord32 s2124 = (s2123 >> 2) | (s2123 << 30);
-  const SWord32 s2125 = (s2123 >> 13) | (s2123 << 19);
-  const SWord32 s2126 = s2124 ^ s2125;
-  const SWord32 s2127 = (s2123 >> 22) | (s2123 << 10);
-  const SWord32 s2128 = s2126 ^ s2127;
-  const SWord32 s2129 = s2112 & s2123;
-  const SWord32 s2130 = s2101 & s2123;
-  const SWord32 s2131 = s2129 ^ s2130;
-  const SWord32 s2132 = s2118 ^ s2131;
-  const SWord32 s2133 = s2128 + s2132;
-  const SWord32 s2134 = s2062 + s2133;
-  const SWord32 s2135 = (s2134 >> 2) | (s2134 << 30);
-  const SWord32 s2136 = (s2134 >> 13) | (s2134 << 19);
-  const SWord32 s2137 = s2135 ^ s2136;
-  const SWord32 s2138 = (s2134 >> 22) | (s2134 << 10);
-  const SWord32 s2139 = s2137 ^ s2138;
-  const SWord32 s2140 = s2123 & s2134;
-  const SWord32 s2141 = s2112 & s2134;
-  const SWord32 s2142 = s2140 ^ s2141;
-  const SWord32 s2143 = s2129 ^ s2142;
-  const SWord32 s2144 = s2139 + s2143;
-  const SWord32 s2145 = s2090 + s2144;
-  const SWord32 s2146 = s2090 + s2101;
-  const SWord32 s2147 = (s2146 >> 6) | (s2146 << 26);
-  const SWord32 s2148 = (s2146 >> 11) | (s2146 << 21);
-  const SWord32 s2149 = s2147 ^ s2148;
-  const SWord32 s2150 = (s2146 >> 25) | (s2146 << 7);
-  const SWord32 s2151 = s2149 ^ s2150;
-  const SWord32 s2152 = s2007 + s2151;
-  const SWord32 s2153 = s2063 & s2146;
-  const SWord32 s2154 = ~s2146;
-  const SWord32 s2155 = s2035 & s2154;
-  const SWord32 s2156 = s2153 ^ s2155;
-  const SWord32 s2157 = s2152 + s2156;
-  const SWord32 s2159 = s2157 + 0x748f82eeUL;
-  const SWord32 s2160 = (s2061 >> 17) | (s2061 << 15);
-  const SWord32 s2161 = (s2061 >> 19) | (s2061 << 13);
-  const SWord32 s2162 = s2160 ^ s2161;
-  const SWord32 s2163 = s2061 >> 10;
-  const SWord32 s2164 = s2162 ^ s2163;
-  const SWord32 s2165 = s1888 + s2164;
-  const SWord32 s2166 = (s1576 >> 7) | (s1576 << 25);
-  const SWord32 s2167 = (s1576 >> 18) | (s1576 << 14);
-  const SWord32 s2168 = s2166 ^ s2167;
-  const SWord32 s2169 = s1576 >> 3;
-  const SWord32 s2170 = s2168 ^ s2169;
-  const SWord32 s2171 = s2165 + s2170;
-  const SWord32 s2172 = s1548 + s2171;
-  const SWord32 s2173 = s2159 + s2172;
-  const SWord32 s2174 = s2112 + s2173;
-  const SWord32 s2175 = (s2174 >> 6) | (s2174 << 26);
-  const SWord32 s2176 = (s2174 >> 11) | (s2174 << 21);
-  const SWord32 s2177 = s2175 ^ s2176;
-  const SWord32 s2178 = (s2174 >> 25) | (s2174 << 7);
-  const SWord32 s2179 = s2177 ^ s2178;
-  const SWord32 s2180 = s2035 + s2179;
-  const SWord32 s2181 = s2146 & s2174;
-  const SWord32 s2182 = ~s2174;
-  const SWord32 s2183 = s2063 & s2182;
-  const SWord32 s2184 = s2181 ^ s2183;
-  const SWord32 s2185 = s2180 + s2184;
-  const SWord32 s2187 = s2185 + 0x78a5636fUL;
-  const SWord32 s2188 = (s2089 >> 17) | (s2089 << 15);
-  const SWord32 s2189 = (s2089 >> 19) | (s2089 << 13);
-  const SWord32 s2190 = s2188 ^ s2189;
-  const SWord32 s2191 = s2089 >> 10;
-  const SWord32 s2192 = s2190 ^ s2191;
-  const SWord32 s2193 = s1916 + s2192;
-  const SWord32 s2194 = (s1604 >> 7) | (s1604 << 25);
-  const SWord32 s2195 = (s1604 >> 18) | (s1604 << 14);
-  const SWord32 s2196 = s2194 ^ s2195;
-  const SWord32 s2197 = s1604 >> 3;
-  const SWord32 s2198 = s2196 ^ s2197;
-  const SWord32 s2199 = s2193 + s2198;
-  const SWord32 s2200 = s1576 + s2199;
-  const SWord32 s2201 = s2187 + s2200;
-  const SWord32 s2202 = s2123 + s2201;
-  const SWord32 s2203 = (s2202 >> 6) | (s2202 << 26);
-  const SWord32 s2204 = (s2202 >> 11) | (s2202 << 21);
-  const SWord32 s2205 = s2203 ^ s2204;
-  const SWord32 s2206 = (s2202 >> 25) | (s2202 << 7);
-  const SWord32 s2207 = s2205 ^ s2206;
-  const SWord32 s2208 = s2063 + s2207;
-  const SWord32 s2209 = s2174 & s2202;
-  const SWord32 s2210 = ~s2202;
-  const SWord32 s2211 = s2146 & s2210;
-  const SWord32 s2212 = s2209 ^ s2211;
-  const SWord32 s2213 = s2208 + s2212;
-  const SWord32 s2215 = s2213 + 0x84c87814UL;
-  const SWord32 s2216 = (s2172 >> 17) | (s2172 << 15);
-  const SWord32 s2217 = (s2172 >> 19) | (s2172 << 13);
-  const SWord32 s2218 = s2216 ^ s2217;
-  const SWord32 s2219 = s2172 >> 10;
-  const SWord32 s2220 = s2218 ^ s2219;
-  const SWord32 s2221 = s1944 + s2220;
-  const SWord32 s2222 = (s1632 >> 7) | (s1632 << 25);
-  const SWord32 s2223 = (s1632 >> 18) | (s1632 << 14);
-  const SWord32 s2224 = s2222 ^ s2223;
-  const SWord32 s2225 = s1632 >> 3;
-  const SWord32 s2226 = s2224 ^ s2225;
-  const SWord32 s2227 = s2221 + s2226;
-  const SWord32 s2228 = s1604 + s2227;
-  const SWord32 s2229 = s2215 + s2228;
-  const SWord32 s2230 = s2134 + s2229;
-  const SWord32 s2231 = (s2230 >> 6) | (s2230 << 26);
-  const SWord32 s2232 = (s2230 >> 11) | (s2230 << 21);
-  const SWord32 s2233 = s2231 ^ s2232;
-  const SWord32 s2234 = (s2230 >> 25) | (s2230 << 7);
-  const SWord32 s2235 = s2233 ^ s2234;
-  const SWord32 s2236 = s2146 + s2235;
-  const SWord32 s2237 = s2202 & s2230;
-  const SWord32 s2238 = ~s2230;
-  const SWord32 s2239 = s2174 & s2238;
-  const SWord32 s2240 = s2237 ^ s2239;
-  const SWord32 s2241 = s2236 + s2240;
-  const SWord32 s2243 = s2241 + 0x8cc70208UL;
-  const SWord32 s2244 = (s2200 >> 17) | (s2200 << 15);
-  const SWord32 s2245 = (s2200 >> 19) | (s2200 << 13);
-  const SWord32 s2246 = s2244 ^ s2245;
-  const SWord32 s2247 = s2200 >> 10;
-  const SWord32 s2248 = s2246 ^ s2247;
-  const SWord32 s2249 = s2005 + s2248;
-  const SWord32 s2250 = (s1693 >> 7) | (s1693 << 25);
-  const SWord32 s2251 = (s1693 >> 18) | (s1693 << 14);
-  const SWord32 s2252 = s2250 ^ s2251;
-  const SWord32 s2253 = s1693 >> 3;
-  const SWord32 s2254 = s2252 ^ s2253;
-  const SWord32 s2255 = s2249 + s2254;
-  const SWord32 s2256 = s1632 + s2255;
-  const SWord32 s2257 = s2243 + s2256;
-  const SWord32 s2258 = s2145 + s2257;
-  const SWord32 s2259 = (s2145 >> 2) | (s2145 << 30);
-  const SWord32 s2260 = (s2145 >> 13) | (s2145 << 19);
-  const SWord32 s2261 = s2259 ^ s2260;
-  const SWord32 s2262 = (s2145 >> 22) | (s2145 << 10);
-  const SWord32 s2263 = s2261 ^ s2262;
-  const SWord32 s2264 = s2134 & s2145;
-  const SWord32 s2265 = s2123 & s2145;
-  const SWord32 s2266 = s2264 ^ s2265;
-  const SWord32 s2267 = s2140 ^ s2266;
-  const SWord32 s2268 = s2263 + s2267;
-  const SWord32 s2269 = s2173 + s2268;
-  const SWord32 s2270 = (s2269 >> 2) | (s2269 << 30);
-  const SWord32 s2271 = (s2269 >> 13) | (s2269 << 19);
-  const SWord32 s2272 = s2270 ^ s2271;
-  const SWord32 s2273 = (s2269 >> 22) | (s2269 << 10);
-  const SWord32 s2274 = s2272 ^ s2273;
-  const SWord32 s2275 = s2145 & s2269;
-  const SWord32 s2276 = s2134 & s2269;
-  const SWord32 s2277 = s2275 ^ s2276;
-  const SWord32 s2278 = s2264 ^ s2277;
-  const SWord32 s2279 = s2274 + s2278;
-  const SWord32 s2280 = s2201 + s2279;
-  const SWord32 s2281 = (s2280 >> 2) | (s2280 << 30);
-  const SWord32 s2282 = (s2280 >> 13) | (s2280 << 19);
-  const SWord32 s2283 = s2281 ^ s2282;
-  const SWord32 s2284 = (s2280 >> 22) | (s2280 << 10);
-  const SWord32 s2285 = s2283 ^ s2284;
-  const SWord32 s2286 = s2269 & s2280;
-  const SWord32 s2287 = s2145 & s2280;
-  const SWord32 s2288 = s2286 ^ s2287;
-  const SWord32 s2289 = s2275 ^ s2288;
-  const SWord32 s2290 = s2285 + s2289;
-  const SWord32 s2291 = s2229 + s2290;
-  const SWord32 s2292 = (s2258 >> 6) | (s2258 << 26);
-  const SWord32 s2293 = (s2258 >> 11) | (s2258 << 21);
-  const SWord32 s2294 = s2292 ^ s2293;
-  const SWord32 s2295 = (s2258 >> 25) | (s2258 << 7);
-  const SWord32 s2296 = s2294 ^ s2295;
-  const SWord32 s2297 = s2174 + s2296;
-  const SWord32 s2298 = s2230 & s2258;
-  const SWord32 s2299 = ~s2258;
-  const SWord32 s2300 = s2202 & s2299;
-  const SWord32 s2301 = s2298 ^ s2300;
-  const SWord32 s2302 = s2297 + s2301;
-  const SWord32 s2304 = s2302 + 0x90befffaUL;
-  const SWord32 s2305 = (s2228 >> 17) | (s2228 << 15);
-  const SWord32 s2306 = (s2228 >> 19) | (s2228 << 13);
-  const SWord32 s2307 = s2305 ^ s2306;
-  const SWord32 s2308 = s2228 >> 10;
-  const SWord32 s2309 = s2307 ^ s2308;
-  const SWord32 s2310 = s2033 + s2309;
-  const SWord32 s2311 = (s1721 >> 7) | (s1721 << 25);
-  const SWord32 s2312 = (s1721 >> 18) | (s1721 << 14);
-  const SWord32 s2313 = s2311 ^ s2312;
-  const SWord32 s2314 = s1721 >> 3;
-  const SWord32 s2315 = s2313 ^ s2314;
-  const SWord32 s2316 = s2310 + s2315;
-  const SWord32 s2317 = s1693 + s2316;
-  const SWord32 s2318 = s2304 + s2317;
-  const SWord32 s2319 = s2269 + s2318;
-  const SWord32 s2320 = (s2319 >> 6) | (s2319 << 26);
-  const SWord32 s2321 = (s2319 >> 11) | (s2319 << 21);
-  const SWord32 s2322 = s2320 ^ s2321;
-  const SWord32 s2323 = (s2319 >> 25) | (s2319 << 7);
-  const SWord32 s2324 = s2322 ^ s2323;
-  const SWord32 s2325 = s2202 + s2324;
-  const SWord32 s2326 = s2258 & s2319;
-  const SWord32 s2327 = ~s2319;
-  const SWord32 s2328 = s2230 & s2327;
-  const SWord32 s2329 = s2326 ^ s2328;
-  const SWord32 s2330 = s2325 + s2329;
-  const SWord32 s2332 = s2330 + 0xa4506cebUL;
-  const SWord32 s2333 = (s2256 >> 17) | (s2256 << 15);
-  const SWord32 s2334 = (s2256 >> 19) | (s2256 << 13);
-  const SWord32 s2335 = s2333 ^ s2334;
-  const SWord32 s2336 = s2256 >> 10;
-  const SWord32 s2337 = s2335 ^ s2336;
-  const SWord32 s2338 = s2061 + s2337;
-  const SWord32 s2339 = (s1749 >> 7) | (s1749 << 25);
-  const SWord32 s2340 = (s1749 >> 18) | (s1749 << 14);
-  const SWord32 s2341 = s2339 ^ s2340;
-  const SWord32 s2342 = s1749 >> 3;
-  const SWord32 s2343 = s2341 ^ s2342;
-  const SWord32 s2344 = s2338 + s2343;
-  const SWord32 s2345 = s1721 + s2344;
-  const SWord32 s2346 = s2332 + s2345;
-  const SWord32 s2347 = s2280 + s2346;
-  const SWord32 s2348 = (s2347 >> 6) | (s2347 << 26);
-  const SWord32 s2349 = (s2347 >> 11) | (s2347 << 21);
-  const SWord32 s2350 = s2348 ^ s2349;
-  const SWord32 s2351 = (s2347 >> 25) | (s2347 << 7);
-  const SWord32 s2352 = s2350 ^ s2351;
-  const SWord32 s2353 = s2230 + s2352;
-  const SWord32 s2354 = s2319 & s2347;
-  const SWord32 s2355 = ~s2347;
-  const SWord32 s2356 = s2258 & s2355;
-  const SWord32 s2357 = s2354 ^ s2356;
-  const SWord32 s2358 = s2353 + s2357;
-  const SWord32 s2360 = s2358 + 0xbef9a3f7UL;
-  const SWord32 s2361 = (s2317 >> 17) | (s2317 << 15);
-  const SWord32 s2362 = (s2317 >> 19) | (s2317 << 13);
-  const SWord32 s2363 = s2361 ^ s2362;
-  const SWord32 s2364 = s2317 >> 10;
-  const SWord32 s2365 = s2363 ^ s2364;
-  const SWord32 s2366 = s2089 + s2365;
-  const SWord32 s2367 = (s1777 >> 7) | (s1777 << 25);
-  const SWord32 s2368 = (s1777 >> 18) | (s1777 << 14);
-  const SWord32 s2369 = s2367 ^ s2368;
-  const SWord32 s2370 = s1777 >> 3;
-  const SWord32 s2371 = s2369 ^ s2370;
-  const SWord32 s2372 = s2366 + s2371;
-  const SWord32 s2373 = s1749 + s2372;
-  const SWord32 s2374 = s2360 + s2373;
-  const SWord32 s2375 = s2291 + s2374;
-  const SWord32 s2376 = (s2375 >> 6) | (s2375 << 26);
-  const SWord32 s2377 = (s2375 >> 11) | (s2375 << 21);
-  const SWord32 s2378 = s2376 ^ s2377;
-  const SWord32 s2379 = (s2375 >> 25) | (s2375 << 7);
-  const SWord32 s2380 = s2378 ^ s2379;
-  const SWord32 s2381 = s2258 + s2380;
-  const SWord32 s2382 = s2347 & s2375;
-  const SWord32 s2383 = ~s2375;
-  const SWord32 s2384 = s2319 & s2383;
-  const SWord32 s2385 = s2382 ^ s2384;
-  const SWord32 s2386 = s2381 + s2385;
-  const SWord32 s2388 = s2386 + 0xc67178f2UL;
-  const SWord32 s2389 = (s2345 >> 17) | (s2345 << 15);
-  const SWord32 s2390 = (s2345 >> 19) | (s2345 << 13);
-  const SWord32 s2391 = s2389 ^ s2390;
-  const SWord32 s2392 = s2345 >> 10;
-  const SWord32 s2393 = s2391 ^ s2392;
-  const SWord32 s2394 = s2172 + s2393;
-  const SWord32 s2395 = (s1860 >> 7) | (s1860 << 25);
-  const SWord32 s2396 = (s1860 >> 18) | (s1860 << 14);
-  const SWord32 s2397 = s2395 ^ s2396;
-  const SWord32 s2398 = s1860 >> 3;
-  const SWord32 s2399 = s2397 ^ s2398;
-  const SWord32 s2400 = s2394 + s2399;
-  const SWord32 s2401 = s1777 + s2400;
-  const SWord32 s2402 = s2388 + s2401;
-  const SWord32 s2403 = (s2291 >> 2) | (s2291 << 30);
-  const SWord32 s2404 = (s2291 >> 13) | (s2291 << 19);
-  const SWord32 s2405 = s2403 ^ s2404;
-  const SWord32 s2406 = (s2291 >> 22) | (s2291 << 10);
-  const SWord32 s2407 = s2405 ^ s2406;
-  const SWord32 s2408 = s2280 & s2291;
-  const SWord32 s2409 = s2269 & s2291;
-  const SWord32 s2410 = s2408 ^ s2409;
-  const SWord32 s2411 = s2286 ^ s2410;
-  const SWord32 s2412 = s2407 + s2411;
-  const SWord32 s2413 = s2257 + s2412;
-  const SWord32 s2414 = (s2413 >> 2) | (s2413 << 30);
-  const SWord32 s2415 = (s2413 >> 13) | (s2413 << 19);
-  const SWord32 s2416 = s2414 ^ s2415;
-  const SWord32 s2417 = (s2413 >> 22) | (s2413 << 10);
-  const SWord32 s2418 = s2416 ^ s2417;
-  const SWord32 s2419 = s2291 & s2413;
-  const SWord32 s2420 = s2280 & s2413;
-  const SWord32 s2421 = s2419 ^ s2420;
-  const SWord32 s2422 = s2408 ^ s2421;
-  const SWord32 s2423 = s2418 + s2422;
-  const SWord32 s2424 = s2318 + s2423;
-  const SWord32 s2425 = (s2424 >> 2) | (s2424 << 30);
-  const SWord32 s2426 = (s2424 >> 13) | (s2424 << 19);
-  const SWord32 s2427 = s2425 ^ s2426;
-  const SWord32 s2428 = (s2424 >> 22) | (s2424 << 10);
-  const SWord32 s2429 = s2427 ^ s2428;
-  const SWord32 s2430 = s2413 & s2424;
-  const SWord32 s2431 = s2291 & s2424;
-  const SWord32 s2432 = s2430 ^ s2431;
-  const SWord32 s2433 = s2419 ^ s2432;
-  const SWord32 s2434 = s2429 + s2433;
-  const SWord32 s2435 = s2346 + s2434;
-  const SWord32 s2436 = (s2435 >> 2) | (s2435 << 30);
-  const SWord32 s2437 = (s2435 >> 13) | (s2435 << 19);
-  const SWord32 s2438 = s2436 ^ s2437;
-  const SWord32 s2439 = (s2435 >> 22) | (s2435 << 10);
-  const SWord32 s2440 = s2438 ^ s2439;
-  const SWord32 s2441 = s2424 & s2435;
-  const SWord32 s2442 = s2413 & s2435;
-  const SWord32 s2443 = s2441 ^ s2442;
-  const SWord32 s2444 = s2430 ^ s2443;
-  const SWord32 s2445 = s2440 + s2444;
-  const SWord32 s2446 = s2374 + s2445;
-  const SWord32 s2447 = (s2446 >> 2) | (s2446 << 30);
-  const SWord32 s2448 = (s2446 >> 13) | (s2446 << 19);
-  const SWord32 s2449 = s2447 ^ s2448;
-  const SWord32 s2450 = (s2446 >> 22) | (s2446 << 10);
-  const SWord32 s2451 = s2449 ^ s2450;
-  const SWord32 s2452 = s2435 & s2446;
-  const SWord32 s2453 = s2424 & s2446;
-  const SWord32 s2454 = s2452 ^ s2453;
-  const SWord32 s2455 = s2441 ^ s2454;
-  const SWord32 s2456 = s2451 + s2455;
-  const SWord32 s2457 = s2402 + s2456;
-  const SWord32 s2458 = s98 + s2457;
-  const SWord8  s2459 = (SWord8) (s2458 >> 24);
-  const SWord8  s2460 = (SWord8) (s2458 >> 16);
-  const SWord8  s2461 = (SWord8) (s2458 >> 8);
-  const SWord8  s2462 = (SWord8) s2458;
-  const SWord32 s2463 = s104 + s2446;
-  const SWord8  s2464 = (SWord8) (s2463 >> 24);
-  const SWord8  s2465 = (SWord8) (s2463 >> 16);
-  const SWord8  s2466 = (SWord8) (s2463 >> 8);
-  const SWord8  s2467 = (SWord8) s2463;
-  const SWord32 s2468 = s110 + s2435;
-  const SWord8  s2469 = (SWord8) (s2468 >> 24);
-  const SWord8  s2470 = (SWord8) (s2468 >> 16);
-  const SWord8  s2471 = (SWord8) (s2468 >> 8);
-  const SWord8  s2472 = (SWord8) s2468;
-  const SWord32 s2473 = s116 + s2424;
-  const SWord8  s2474 = (SWord8) (s2473 >> 24);
-  const SWord8  s2475 = (SWord8) (s2473 >> 16);
-  const SWord8  s2476 = (SWord8) (s2473 >> 8);
-  const SWord8  s2477 = (SWord8) s2473;
-  const SWord32 s2478 = s2402 + s2413;
-  const SWord32 s2479 = s101 + s2478;
-  const SWord8  s2480 = (SWord8) (s2479 >> 24);
-  const SWord8  s2481 = (SWord8) (s2479 >> 16);
-  const SWord8  s2482 = (SWord8) (s2479 >> 8);
-  const SWord8  s2483 = (SWord8) s2479;
-  const SWord32 s2484 = s107 + s2375;
-  const SWord8  s2485 = (SWord8) (s2484 >> 24);
-  const SWord8  s2486 = (SWord8) (s2484 >> 16);
-  const SWord8  s2487 = (SWord8) (s2484 >> 8);
-  const SWord8  s2488 = (SWord8) s2484;
-  const SWord32 s2489 = s113 + s2347;
-  const SWord8  s2490 = (SWord8) (s2489 >> 24);
-  const SWord8  s2491 = (SWord8) (s2489 >> 16);
-  const SWord8  s2492 = (SWord8) (s2489 >> 8);
-  const SWord8  s2493 = (SWord8) s2489;
-  const SWord32 s2494 = s119 + s2319;
-  const SWord8  s2495 = (SWord8) (s2494 >> 24);
-  const SWord8  s2496 = (SWord8) (s2494 >> 16);
-  const SWord8  s2497 = (SWord8) (s2494 >> 8);
-  const SWord8  s2498 = (SWord8) s2494;
-
-  hash[0] = s2459;
-  hash[1] = s2460;
-  hash[2] = s2461;
-  hash[3] = s2462;
-  hash[4] = s2464;
-  hash[5] = s2465;
-  hash[6] = s2466;
-  hash[7] = s2467;
-  hash[8] = s2469;
-  hash[9] = s2470;
-  hash[10] = s2471;
-  hash[11] = s2472;
-  hash[12] = s2474;
-  hash[13] = s2475;
-  hash[14] = s2476;
-  hash[15] = s2477;
-  hash[16] = s2480;
-  hash[17] = s2481;
-  hash[18] = s2482;
-  hash[19] = s2483;
-  hash[20] = s2485;
-  hash[21] = s2486;
-  hash[22] = s2487;
-  hash[23] = s2488;
-  hash[24] = s2490;
-  hash[25] = s2491;
-  hash[26] = s2492;
-  hash[27] = s2493;
-  hash[28] = s2495;
-  hash[29] = s2496;
-  hash[30] = s2497;
-  hash[31] = s2498;
+sha256HashBlock_driver.o: sha256HashBlock_driver.c sha256HashBlock.h
+	${CC} ${CCFLAGS} -c $< -o $@
+
+sha256HashBlock_driver: sha256HashBlock.o sha256HashBlock_driver.o
+	${CC} ${CCFLAGS} $^ -o $@ ${LDFLAGS}
+
+clean:
+	rm -f *.o
+
+veryclean: clean
+	rm -f sha256HashBlock_driver
+== END: "Makefile" ==================
+== BEGIN: "sha256HashBlock.h" ================
+/* Header file for sha256HashBlock. Automatically generated by SBV. Do not edit! */
+
+#ifndef SBV_GENERATED_sha256HashBlock_HEADER_INCLUDED
+#define SBV_GENERATED_sha256HashBlock_HEADER_INCLUDED
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <math.h>
+
+/* Floating-point calling convention:
+ * Enter generated code in FE_TONEAREST (round-to-nearest, ties-to-even).
+ * Callbacks must preserve this mode before returning or re-entering.
+ * Generated code does not check or change the hardware rounding mode.
+ * Custom builds must disable implicit FP contraction, including at LTO link time.
+ */
+
+/* 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 prototype: */
+void sha256HashBlock(const SWord8 *hIn, const SWord8 *block,
+                     SWord8 *hash);
+
+#endif /* SBV_GENERATED_sha256HashBlock_HEADER_INCLUDED */
+== END: "sha256HashBlock.h" ==================
+== BEGIN: "sha256HashBlock_driver.c" ================
+/* Example driver program for sha256HashBlock. */
+/* Automatically generated by SBV. Edit as you see fit! */
+
+#include <stdio.h>
+#include "sha256HashBlock.h"
+
+int main(void)
+{
+  const SWord8 sbv_driver_input_0[32] = {
+      0x6a, 0x09, 0xe6, 0x67, 0xbb, 0x67, 0xae, 0x85, 0x3c, 0x6e, 0xf3,
+      0x72, 0xa5, 0x4f, 0xf5, 0x3a, 0x51, 0x0e, 0x52, 0x7f, 0x9b, 0x05,
+      0x68, 0x8c, 0x1f, 0x83, 0xd9, 0xab, 0x5b, 0xe0, 0xcd, 0x19
+  };
+
+  printf("Contents of input array hIn:\n");
+  int sbv_driver_input_0_ctr;
+  for(sbv_driver_input_0_ctr = 0; sbv_driver_input_0_ctr < 32 ; ++sbv_driver_input_0_ctr)
+  { printf("  hIn[%2d] = ", sbv_driver_input_0_ctr);
+    printf("0x%02"PRIx8"", sbv_driver_input_0[sbv_driver_input_0_ctr]);
+    printf("\n");
+  }
+
+  const SWord8 sbv_driver_input_1[64] = {
+      0x53, 0x42, 0x56, 0x20, 0x67, 0x6f, 0x65, 0x73, 0x20, 0x53, 0x48,
+      0x41, 0x32, 0x35, 0x36, 0x21, 0x21, 0x80, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88
+  };
+
+  printf("Contents of input array block:\n");
+  int sbv_driver_input_1_ctr;
+  for(sbv_driver_input_1_ctr = 0; sbv_driver_input_1_ctr < 64 ; ++sbv_driver_input_1_ctr)
+  { printf("  block[%2d] = ", sbv_driver_input_1_ctr);
+    printf("0x%02"PRIx8"", sbv_driver_input_1[sbv_driver_input_1_ctr]);
+    printf("\n");
+  }
+
+  SWord8 sbv_driver_output_0[32];
+
+  sha256HashBlock(sbv_driver_input_0, sbv_driver_input_1,
+                  sbv_driver_output_0);
+
+  printf("sha256HashBlock(hIn, block, hash) ->\n");
+  int sbv_driver_output_0_ctr;
+  for(sbv_driver_output_0_ctr = 0; sbv_driver_output_0_ctr < 32 ; ++sbv_driver_output_0_ctr)
+  { printf("  hash[%2d] = ", sbv_driver_output_0_ctr);
+    printf("0x%02"PRIx8"", sbv_driver_output_0[sbv_driver_output_0_ctr]);
+    printf("\n");
+  }
+
+  return 0;
+}
+== END: "sha256HashBlock_driver.c" ==================
+== BEGIN: "sha256HashBlock.c" ================
+/* File: "sha256HashBlock.c". Automatically generated by SBV. Do not edit! */
+
+#include "sha256HashBlock.h"
+
+/* Exact bit-vector runtime. All arithmetic is modulo the declared width. */
+#ifndef SBV_CGEN_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define SBV_CGEN_UNUSED __attribute__((unused))
+#else
+#define SBV_CGEN_UNUSED
+#endif
+#endif
+
+static inline SBV_CGEN_UNUSED SWord16 sbv_bv_join_u8_u8_u16(SWord8 high, SWord8 low)
+{
+  SWord16 r = (SWord16) 0; uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord16) ((uint64_t) r | ((uint64_t) (((((uint64_t) low) >> (i)) & UINT64_C(1)) != 0) << (i))); }
+  for (i = 0; i < 8; ++i) { r = (SWord16) ((uint64_t) r | ((uint64_t) (((((uint64_t) high) >> (i)) & UINT64_C(1)) != 0) << (i + 8))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord32 sbv_bv_join_u16_u16_u32(SWord16 high, SWord16 low)
+{
+  SWord32 r = (SWord32) 0; uint64_t i;
+  for (i = 0; i < 16; ++i) { r = (SWord32) ((uint64_t) r | ((uint64_t) (((((uint64_t) low) >> (i)) & UINT64_C(1)) != 0) << (i))); }
+  for (i = 0; i < 16; ++i) { r = (SWord32) ((uint64_t) r | ((uint64_t) (((((uint64_t) high) >> (i)) & UINT64_C(1)) != 0) << (i + 16))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord32 sbv_bv_u32_rotl(SWord32 a, uint64_t amount)
+{
+  amount %= 32;
+  if (amount == 0) return a;
+  return (SWord32) ((((uint64_t) (SWord32) a) << amount) | (((uint64_t) (SWord32) a) >> (32 - amount)));
+}
+
+static inline SBV_CGEN_UNUSED SWord32 sbv_bv_u32_rotr(SWord32 a, uint64_t amount)
+{
+  amount %= 32;
+  if (amount == 0) return a;
+  return (SWord32) ((((uint64_t) (SWord32) a) >> amount) | (((uint64_t) (SWord32) a) << (32 - amount)));
+}
+
+static inline SBV_CGEN_UNUSED SWord32 sbv_bv_u32_add(SWord32 a, SWord32 b)
+{
+  const SWord32 bits = (SWord32) ((((uint64_t) (SWord32) a) + ((uint64_t) (SWord32) b)) & UINT64_C(0x00000000ffffffff));
+  return (SWord32) bits;
+}
+
+static inline SBV_CGEN_UNUSED SWord32 sbv_bv_u32_shl(SWord32 a, SWord32 amount)
+{
+  const uint64_t n = (uint64_t) (SWord32) amount;
+  const SWord32 result = n >= 32 ? (SWord32) 0 : (SWord32) ((uint64_t) (SWord32) a << n);
+  return result;
+}
+
+static inline SBV_CGEN_UNUSED SWord32 sbv_bv_u32_lshr(SWord32 a, SWord32 amount)
+{
+  const uint64_t n = (uint64_t) (SWord32) amount;
+  return n >= 32 ? (SWord32) 0 : (SWord32) ((uint64_t) (SWord32) a >> n);
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_31_24_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 24)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_23_16_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 16)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_15_8_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i + 8)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+static inline SBV_CGEN_UNUSED SWord8 sbv_bv_extract_u32_7_0_u8(SWord32 a)
+{
+  SWord8 r = (SWord8) 0;
+  uint64_t i;
+  for (i = 0; i < 8; ++i) { r = (SWord8) ((uint64_t) r | ((uint64_t) (((((uint64_t) a) >> (i)) & UINT64_C(1)) != 0) << (i))); }
+  return r;
+}
+
+
+void sha256HashBlock(const SWord8 *sbv_input_0,
+                     const SWord8 *sbv_input_1, SWord8 *sbv_output_0)
+{
+  const SWord8  s0 = sbv_input_0[0];
+  const SWord8  s1 = sbv_input_0[1];
+  const SWord8  s2 = sbv_input_0[2];
+  const SWord8  s3 = sbv_input_0[3];
+  const SWord8  s4 = sbv_input_0[4];
+  const SWord8  s5 = sbv_input_0[5];
+  const SWord8  s6 = sbv_input_0[6];
+  const SWord8  s7 = sbv_input_0[7];
+  const SWord8  s8 = sbv_input_0[8];
+  const SWord8  s9 = sbv_input_0[9];
+  const SWord8  s10 = sbv_input_0[10];
+  const SWord8  s11 = sbv_input_0[11];
+  const SWord8  s12 = sbv_input_0[12];
+  const SWord8  s13 = sbv_input_0[13];
+  const SWord8  s14 = sbv_input_0[14];
+  const SWord8  s15 = sbv_input_0[15];
+  const SWord8  s16 = sbv_input_0[16];
+  const SWord8  s17 = sbv_input_0[17];
+  const SWord8  s18 = sbv_input_0[18];
+  const SWord8  s19 = sbv_input_0[19];
+  const SWord8  s20 = sbv_input_0[20];
+  const SWord8  s21 = sbv_input_0[21];
+  const SWord8  s22 = sbv_input_0[22];
+  const SWord8  s23 = sbv_input_0[23];
+  const SWord8  s24 = sbv_input_0[24];
+  const SWord8  s25 = sbv_input_0[25];
+  const SWord8  s26 = sbv_input_0[26];
+  const SWord8  s27 = sbv_input_0[27];
+  const SWord8  s28 = sbv_input_0[28];
+  const SWord8  s29 = sbv_input_0[29];
+  const SWord8  s30 = sbv_input_0[30];
+  const SWord8  s31 = sbv_input_0[31];
+  const SWord8  s32 = sbv_input_1[0];
+  const SWord8  s33 = sbv_input_1[1];
+  const SWord8  s34 = sbv_input_1[2];
+  const SWord8  s35 = sbv_input_1[3];
+  const SWord8  s36 = sbv_input_1[4];
+  const SWord8  s37 = sbv_input_1[5];
+  const SWord8  s38 = sbv_input_1[6];
+  const SWord8  s39 = sbv_input_1[7];
+  const SWord8  s40 = sbv_input_1[8];
+  const SWord8  s41 = sbv_input_1[9];
+  const SWord8  s42 = sbv_input_1[10];
+  const SWord8  s43 = sbv_input_1[11];
+  const SWord8  s44 = sbv_input_1[12];
+  const SWord8  s45 = sbv_input_1[13];
+  const SWord8  s46 = sbv_input_1[14];
+  const SWord8  s47 = sbv_input_1[15];
+  const SWord8  s48 = sbv_input_1[16];
+  const SWord8  s49 = sbv_input_1[17];
+  const SWord8  s50 = sbv_input_1[18];
+  const SWord8  s51 = sbv_input_1[19];
+  const SWord8  s52 = sbv_input_1[20];
+  const SWord8  s53 = sbv_input_1[21];
+  const SWord8  s54 = sbv_input_1[22];
+  const SWord8  s55 = sbv_input_1[23];
+  const SWord8  s56 = sbv_input_1[24];
+  const SWord8  s57 = sbv_input_1[25];
+  const SWord8  s58 = sbv_input_1[26];
+  const SWord8  s59 = sbv_input_1[27];
+  const SWord8  s60 = sbv_input_1[28];
+  const SWord8  s61 = sbv_input_1[29];
+  const SWord8  s62 = sbv_input_1[30];
+  const SWord8  s63 = sbv_input_1[31];
+  const SWord8  s64 = sbv_input_1[32];
+  const SWord8  s65 = sbv_input_1[33];
+  const SWord8  s66 = sbv_input_1[34];
+  const SWord8  s67 = sbv_input_1[35];
+  const SWord8  s68 = sbv_input_1[36];
+  const SWord8  s69 = sbv_input_1[37];
+  const SWord8  s70 = sbv_input_1[38];
+  const SWord8  s71 = sbv_input_1[39];
+  const SWord8  s72 = sbv_input_1[40];
+  const SWord8  s73 = sbv_input_1[41];
+  const SWord8  s74 = sbv_input_1[42];
+  const SWord8  s75 = sbv_input_1[43];
+  const SWord8  s76 = sbv_input_1[44];
+  const SWord8  s77 = sbv_input_1[45];
+  const SWord8  s78 = sbv_input_1[46];
+  const SWord8  s79 = sbv_input_1[47];
+  const SWord8  s80 = sbv_input_1[48];
+  const SWord8  s81 = sbv_input_1[49];
+  const SWord8  s82 = sbv_input_1[50];
+  const SWord8  s83 = sbv_input_1[51];
+  const SWord8  s84 = sbv_input_1[52];
+  const SWord8  s85 = sbv_input_1[53];
+  const SWord8  s86 = sbv_input_1[54];
+  const SWord8  s87 = sbv_input_1[55];
+  const SWord8  s88 = sbv_input_1[56];
+  const SWord8  s89 = sbv_input_1[57];
+  const SWord8  s90 = sbv_input_1[58];
+  const SWord8  s91 = sbv_input_1[59];
+  const SWord8  s92 = sbv_input_1[60];
+  const SWord8  s93 = sbv_input_1[61];
+  const SWord8  s94 = sbv_input_1[62];
+  const SWord8  s95 = sbv_input_1[63];
+  const SWord16 s96 = sbv_bv_join_u8_u8_u16(s0, s1);
+  const SWord16 s97 = sbv_bv_join_u8_u8_u16(s2, s3);
+  const SWord32 s98 = sbv_bv_join_u16_u16_u32(s96, s97);
+  const SWord16 s99 = sbv_bv_join_u8_u8_u16(s16, s17);
+  const SWord16 s100 = sbv_bv_join_u8_u8_u16(s18, s19);
+  const SWord32 s101 = sbv_bv_join_u16_u16_u32(s99, s100);
+  const SWord16 s102 = sbv_bv_join_u8_u8_u16(s4, s5);
+  const SWord16 s103 = sbv_bv_join_u8_u8_u16(s6, s7);
+  const SWord32 s104 = sbv_bv_join_u16_u16_u32(s102, s103);
+  const SWord16 s105 = sbv_bv_join_u8_u8_u16(s20, s21);
+  const SWord16 s106 = sbv_bv_join_u8_u8_u16(s22, s23);
+  const SWord32 s107 = sbv_bv_join_u16_u16_u32(s105, s106);
+  const SWord16 s108 = sbv_bv_join_u8_u8_u16(s8, s9);
+  const SWord16 s109 = sbv_bv_join_u8_u8_u16(s10, s11);
+  const SWord32 s110 = sbv_bv_join_u16_u16_u32(s108, s109);
+  const SWord16 s111 = sbv_bv_join_u8_u8_u16(s24, s25);
+  const SWord16 s112 = sbv_bv_join_u8_u8_u16(s26, s27);
+  const SWord32 s113 = sbv_bv_join_u16_u16_u32(s111, s112);
+  const SWord16 s114 = sbv_bv_join_u8_u8_u16(s12, s13);
+  const SWord16 s115 = sbv_bv_join_u8_u8_u16(s14, s15);
+  const SWord32 s116 = sbv_bv_join_u16_u16_u32(s114, s115);
+  const SWord16 s117 = sbv_bv_join_u8_u8_u16(s28, s29);
+  const SWord16 s118 = sbv_bv_join_u8_u8_u16(s30, s31);
+  const SWord32 s119 = sbv_bv_join_u16_u16_u32(s117, s118);
+  const SWord32 s120 = sbv_bv_u32_rotr(s101, 6);
+  const SWord32 s121 = sbv_bv_u32_rotr(s101, 11);
+  const SWord32 s122 = s120 ^ s121;
+  const SWord32 s123 = sbv_bv_u32_rotr(s101, 25);
+  const SWord32 s124 = s122 ^ s123;
+  const SWord32 s125 = sbv_bv_u32_add(s119, s124);
+  const SWord32 s126 = s101 & s107;
+  const SWord32 s127 = ~s101;
+  const SWord32 s128 = s113 & s127;
+  const SWord32 s129 = s126 ^ s128;
+  const SWord32 s130 = sbv_bv_u32_add(s125, s129);
+  const SWord32 s132 = sbv_bv_u32_add(s130, 0x428a2f98UL);
+  const SWord16 s133 = sbv_bv_join_u8_u8_u16(s32, s33);
+  const SWord16 s134 = sbv_bv_join_u8_u8_u16(s34, s35);
+  const SWord32 s135 = sbv_bv_join_u16_u16_u32(s133, s134);
+  const SWord32 s136 = sbv_bv_u32_add(s132, s135);
+  const SWord32 s137 = sbv_bv_u32_add(s116, s136);
+  const SWord32 s138 = sbv_bv_u32_rotr(s137, 6);
+  const SWord32 s139 = sbv_bv_u32_rotr(s137, 11);
+  const SWord32 s140 = s138 ^ s139;
+  const SWord32 s141 = sbv_bv_u32_rotr(s137, 25);
+  const SWord32 s142 = s140 ^ s141;
+  const SWord32 s143 = sbv_bv_u32_add(s113, s142);
+  const SWord32 s144 = s101 & s137;
+  const SWord32 s145 = ~s137;
+  const SWord32 s146 = s107 & s145;
+  const SWord32 s147 = s144 ^ s146;
+  const SWord32 s148 = sbv_bv_u32_add(s143, s147);
+  const SWord32 s150 = sbv_bv_u32_add(s148, 0x71374491UL);
+  const SWord16 s151 = sbv_bv_join_u8_u8_u16(s36, s37);
+  const SWord16 s152 = sbv_bv_join_u8_u8_u16(s38, s39);
+  const SWord32 s153 = sbv_bv_join_u16_u16_u32(s151, s152);
+  const SWord32 s154 = sbv_bv_u32_add(s150, s153);
+  const SWord32 s155 = sbv_bv_u32_add(s110, s154);
+  const SWord32 s156 = sbv_bv_u32_rotr(s155, 6);
+  const SWord32 s157 = sbv_bv_u32_rotr(s155, 11);
+  const SWord32 s158 = s156 ^ s157;
+  const SWord32 s159 = sbv_bv_u32_rotr(s155, 25);
+  const SWord32 s160 = s158 ^ s159;
+  const SWord32 s161 = sbv_bv_u32_add(s107, s160);
+  const SWord32 s162 = s137 & s155;
+  const SWord32 s163 = ~s155;
+  const SWord32 s164 = s101 & s163;
+  const SWord32 s165 = s162 ^ s164;
+  const SWord32 s166 = sbv_bv_u32_add(s161, s165);
+  const SWord32 s168 = sbv_bv_u32_add(s166, 0xb5c0fbcfUL);
+  const SWord16 s169 = sbv_bv_join_u8_u8_u16(s40, s41);
+  const SWord16 s170 = sbv_bv_join_u8_u8_u16(s42, s43);
+  const SWord32 s171 = sbv_bv_join_u16_u16_u32(s169, s170);
+  const SWord32 s172 = sbv_bv_u32_add(s168, s171);
+  const SWord32 s173 = sbv_bv_u32_add(s104, s172);
+  const SWord32 s174 = sbv_bv_u32_rotr(s173, 6);
+  const SWord32 s175 = sbv_bv_u32_rotr(s173, 11);
+  const SWord32 s176 = s174 ^ s175;
+  const SWord32 s177 = sbv_bv_u32_rotr(s173, 25);
+  const SWord32 s178 = s176 ^ s177;
+  const SWord32 s179 = sbv_bv_u32_add(s101, s178);
+  const SWord32 s180 = s155 & s173;
+  const SWord32 s181 = ~s173;
+  const SWord32 s182 = s137 & s181;
+  const SWord32 s183 = s180 ^ s182;
+  const SWord32 s184 = sbv_bv_u32_add(s179, s183);
+  const SWord32 s186 = sbv_bv_u32_add(s184, 0xe9b5dba5UL);
+  const SWord16 s187 = sbv_bv_join_u8_u8_u16(s44, s45);
+  const SWord16 s188 = sbv_bv_join_u8_u8_u16(s46, s47);
+  const SWord32 s189 = sbv_bv_join_u16_u16_u32(s187, s188);
+  const SWord32 s190 = sbv_bv_u32_add(s186, s189);
+  const SWord32 s191 = sbv_bv_u32_add(s98, s190);
+  const SWord32 s192 = sbv_bv_u32_rotr(s98, 2);
+  const SWord32 s193 = sbv_bv_u32_rotr(s98, 13);
+  const SWord32 s194 = s192 ^ s193;
+  const SWord32 s195 = sbv_bv_u32_rotr(s98, 22);
+  const SWord32 s196 = s194 ^ s195;
+  const SWord32 s197 = s98 & s104;
+  const SWord32 s198 = s98 & s110;
+  const SWord32 s199 = s197 ^ s198;
+  const SWord32 s200 = s104 & s110;
+  const SWord32 s201 = s199 ^ s200;
+  const SWord32 s202 = sbv_bv_u32_add(s196, s201);
+  const SWord32 s203 = sbv_bv_u32_add(s136, s202);
+  const SWord32 s204 = sbv_bv_u32_rotr(s203, 2);
+  const SWord32 s205 = sbv_bv_u32_rotr(s203, 13);
+  const SWord32 s206 = s204 ^ s205;
+  const SWord32 s207 = sbv_bv_u32_rotr(s203, 22);
+  const SWord32 s208 = s206 ^ s207;
+  const SWord32 s209 = s98 & s203;
+  const SWord32 s210 = s104 & s203;
+  const SWord32 s211 = s209 ^ s210;
+  const SWord32 s212 = s197 ^ s211;
+  const SWord32 s213 = sbv_bv_u32_add(s208, s212);
+  const SWord32 s214 = sbv_bv_u32_add(s154, s213);
+  const SWord32 s215 = sbv_bv_u32_rotr(s214, 2);
+  const SWord32 s216 = sbv_bv_u32_rotr(s214, 13);
+  const SWord32 s217 = s215 ^ s216;
+  const SWord32 s218 = sbv_bv_u32_rotr(s214, 22);
+  const SWord32 s219 = s217 ^ s218;
+  const SWord32 s220 = s203 & s214;
+  const SWord32 s221 = s98 & s214;
+  const SWord32 s222 = s220 ^ s221;
+  const SWord32 s223 = s209 ^ s222;
+  const SWord32 s224 = sbv_bv_u32_add(s219, s223);
+  const SWord32 s225 = sbv_bv_u32_add(s172, s224);
+  const SWord32 s226 = sbv_bv_u32_rotr(s191, 6);
+  const SWord32 s227 = sbv_bv_u32_rotr(s191, 11);
+  const SWord32 s228 = s226 ^ s227;
+  const SWord32 s229 = sbv_bv_u32_rotr(s191, 25);
+  const SWord32 s230 = s228 ^ s229;
+  const SWord32 s231 = sbv_bv_u32_add(s137, s230);
+  const SWord32 s232 = s173 & s191;
+  const SWord32 s233 = ~s191;
+  const SWord32 s234 = s155 & s233;
+  const SWord32 s235 = s232 ^ s234;
+  const SWord32 s236 = sbv_bv_u32_add(s231, s235);
+  const SWord32 s238 = sbv_bv_u32_add(s236, 0x3956c25bUL);
+  const SWord16 s239 = sbv_bv_join_u8_u8_u16(s48, s49);
+  const SWord16 s240 = sbv_bv_join_u8_u8_u16(s50, s51);
+  const SWord32 s241 = sbv_bv_join_u16_u16_u32(s239, s240);
+  const SWord32 s242 = sbv_bv_u32_add(s238, s241);
+  const SWord32 s243 = sbv_bv_u32_add(s203, s242);
+  const SWord32 s244 = sbv_bv_u32_rotr(s243, 6);
+  const SWord32 s245 = sbv_bv_u32_rotr(s243, 11);
+  const SWord32 s246 = s244 ^ s245;
+  const SWord32 s247 = sbv_bv_u32_rotr(s243, 25);
+  const SWord32 s248 = s246 ^ s247;
+  const SWord32 s249 = sbv_bv_u32_add(s155, s248);
+  const SWord32 s250 = s191 & s243;
+  const SWord32 s251 = ~s243;
+  const SWord32 s252 = s173 & s251;
+  const SWord32 s253 = s250 ^ s252;
+  const SWord32 s254 = sbv_bv_u32_add(s249, s253);
+  const SWord32 s256 = sbv_bv_u32_add(s254, 0x59f111f1UL);
+  const SWord16 s257 = sbv_bv_join_u8_u8_u16(s52, s53);
+  const SWord16 s258 = sbv_bv_join_u8_u8_u16(s54, s55);
+  const SWord32 s259 = sbv_bv_join_u16_u16_u32(s257, s258);
+  const SWord32 s260 = sbv_bv_u32_add(s256, s259);
+  const SWord32 s261 = sbv_bv_u32_add(s214, s260);
+  const SWord32 s262 = sbv_bv_u32_rotr(s261, 6);
+  const SWord32 s263 = sbv_bv_u32_rotr(s261, 11);
+  const SWord32 s264 = s262 ^ s263;
+  const SWord32 s265 = sbv_bv_u32_rotr(s261, 25);
+  const SWord32 s266 = s264 ^ s265;
+  const SWord32 s267 = sbv_bv_u32_add(s173, s266);
+  const SWord32 s268 = s243 & s261;
+  const SWord32 s269 = ~s261;
+  const SWord32 s270 = s191 & s269;
+  const SWord32 s271 = s268 ^ s270;
+  const SWord32 s272 = sbv_bv_u32_add(s267, s271);
+  const SWord32 s274 = sbv_bv_u32_add(s272, 0x923f82a4UL);
+  const SWord16 s275 = sbv_bv_join_u8_u8_u16(s56, s57);
+  const SWord16 s276 = sbv_bv_join_u8_u8_u16(s58, s59);
+  const SWord32 s277 = sbv_bv_join_u16_u16_u32(s275, s276);
+  const SWord32 s278 = sbv_bv_u32_add(s274, s277);
+  const SWord32 s279 = sbv_bv_u32_add(s225, s278);
+  const SWord32 s280 = sbv_bv_u32_rotr(s279, 6);
+  const SWord32 s281 = sbv_bv_u32_rotr(s279, 11);
+  const SWord32 s282 = s280 ^ s281;
+  const SWord32 s283 = sbv_bv_u32_rotr(s279, 25);
+  const SWord32 s284 = s282 ^ s283;
+  const SWord32 s285 = sbv_bv_u32_add(s191, s284);
+  const SWord32 s286 = s261 & s279;
+  const SWord32 s287 = ~s279;
+  const SWord32 s288 = s243 & s287;
+  const SWord32 s289 = s286 ^ s288;
+  const SWord32 s290 = sbv_bv_u32_add(s285, s289);
+  const SWord32 s292 = sbv_bv_u32_add(s290, 0xab1c5ed5UL);
+  const SWord16 s293 = sbv_bv_join_u8_u8_u16(s60, s61);
+  const SWord16 s294 = sbv_bv_join_u8_u8_u16(s62, s63);
+  const SWord32 s295 = sbv_bv_join_u16_u16_u32(s293, s294);
+  const SWord32 s296 = sbv_bv_u32_add(s292, s295);
+  const SWord32 s297 = sbv_bv_u32_rotr(s225, 2);
+  const SWord32 s298 = sbv_bv_u32_rotr(s225, 13);
+  const SWord32 s299 = s297 ^ s298;
+  const SWord32 s300 = sbv_bv_u32_rotr(s225, 22);
+  const SWord32 s301 = s299 ^ s300;
+  const SWord32 s302 = s214 & s225;
+  const SWord32 s303 = s203 & s225;
+  const SWord32 s304 = s302 ^ s303;
+  const SWord32 s305 = s220 ^ s304;
+  const SWord32 s306 = sbv_bv_u32_add(s301, s305);
+  const SWord32 s307 = sbv_bv_u32_add(s190, s306);
+  const SWord32 s308 = sbv_bv_u32_rotr(s307, 2);
+  const SWord32 s309 = sbv_bv_u32_rotr(s307, 13);
+  const SWord32 s310 = s308 ^ s309;
+  const SWord32 s311 = sbv_bv_u32_rotr(s307, 22);
+  const SWord32 s312 = s310 ^ s311;
+  const SWord32 s313 = s225 & s307;
+  const SWord32 s314 = s214 & s307;
+  const SWord32 s315 = s313 ^ s314;
+  const SWord32 s316 = s302 ^ s315;
+  const SWord32 s317 = sbv_bv_u32_add(s312, s316);
+  const SWord32 s318 = sbv_bv_u32_add(s242, s317);
+  const SWord32 s319 = sbv_bv_u32_rotr(s318, 2);
+  const SWord32 s320 = sbv_bv_u32_rotr(s318, 13);
+  const SWord32 s321 = s319 ^ s320;
+  const SWord32 s322 = sbv_bv_u32_rotr(s318, 22);
+  const SWord32 s323 = s321 ^ s322;
+  const SWord32 s324 = s307 & s318;
+  const SWord32 s325 = s225 & s318;
+  const SWord32 s326 = s324 ^ s325;
+  const SWord32 s327 = s313 ^ s326;
+  const SWord32 s328 = sbv_bv_u32_add(s323, s327);
+  const SWord32 s329 = sbv_bv_u32_add(s260, s328);
+  const SWord32 s330 = sbv_bv_u32_rotr(s329, 2);
+  const SWord32 s331 = sbv_bv_u32_rotr(s329, 13);
+  const SWord32 s332 = s330 ^ s331;
+  const SWord32 s333 = sbv_bv_u32_rotr(s329, 22);
+  const SWord32 s334 = s332 ^ s333;
+  const SWord32 s335 = s318 & s329;
+  const SWord32 s336 = s307 & s329;
+  const SWord32 s337 = s335 ^ s336;
+  const SWord32 s338 = s324 ^ s337;
+  const SWord32 s339 = sbv_bv_u32_add(s334, s338);
+  const SWord32 s340 = sbv_bv_u32_add(s278, s339);
+  const SWord32 s341 = sbv_bv_u32_rotr(s340, 2);
+  const SWord32 s342 = sbv_bv_u32_rotr(s340, 13);
+  const SWord32 s343 = s341 ^ s342;
+  const SWord32 s344 = sbv_bv_u32_rotr(s340, 22);
+  const SWord32 s345 = s343 ^ s344;
+  const SWord32 s346 = s329 & s340;
+  const SWord32 s347 = s318 & s340;
+  const SWord32 s348 = s346 ^ s347;
+  const SWord32 s349 = s335 ^ s348;
+  const SWord32 s350 = sbv_bv_u32_add(s345, s349);
+  const SWord32 s351 = sbv_bv_u32_add(s296, s350);
+  const SWord32 s352 = sbv_bv_u32_add(s296, s307);
+  const SWord32 s353 = sbv_bv_u32_rotr(s352, 6);
+  const SWord32 s354 = sbv_bv_u32_rotr(s352, 11);
+  const SWord32 s355 = s353 ^ s354;
+  const SWord32 s356 = sbv_bv_u32_rotr(s352, 25);
+  const SWord32 s357 = s355 ^ s356;
+  const SWord32 s358 = sbv_bv_u32_add(s243, s357);
+  const SWord32 s359 = s279 & s352;
+  const SWord32 s360 = ~s352;
+  const SWord32 s361 = s261 & s360;
+  const SWord32 s362 = s359 ^ s361;
+  const SWord32 s363 = sbv_bv_u32_add(s358, s362);
+  const SWord32 s365 = sbv_bv_u32_add(s363, 0xd807aa98UL);
+  const SWord16 s366 = sbv_bv_join_u8_u8_u16(s64, s65);
+  const SWord16 s367 = sbv_bv_join_u8_u8_u16(s66, s67);
+  const SWord32 s368 = sbv_bv_join_u16_u16_u32(s366, s367);
+  const SWord32 s369 = sbv_bv_u32_add(s365, s368);
+  const SWord32 s370 = sbv_bv_u32_add(s318, s369);
+  const SWord32 s371 = sbv_bv_u32_rotr(s370, 6);
+  const SWord32 s372 = sbv_bv_u32_rotr(s370, 11);
+  const SWord32 s373 = s371 ^ s372;
+  const SWord32 s374 = sbv_bv_u32_rotr(s370, 25);
+  const SWord32 s375 = s373 ^ s374;
+  const SWord32 s376 = sbv_bv_u32_add(s261, s375);
+  const SWord32 s377 = s352 & s370;
+  const SWord32 s378 = ~s370;
+  const SWord32 s379 = s279 & s378;
+  const SWord32 s380 = s377 ^ s379;
+  const SWord32 s381 = sbv_bv_u32_add(s376, s380);
+  const SWord32 s383 = sbv_bv_u32_add(s381, 0x12835b01UL);
+  const SWord16 s384 = sbv_bv_join_u8_u8_u16(s68, s69);
+  const SWord16 s385 = sbv_bv_join_u8_u8_u16(s70, s71);
+  const SWord32 s386 = sbv_bv_join_u16_u16_u32(s384, s385);
+  const SWord32 s387 = sbv_bv_u32_add(s383, s386);
+  const SWord32 s388 = sbv_bv_u32_add(s329, s387);
+  const SWord32 s389 = sbv_bv_u32_rotr(s388, 6);
+  const SWord32 s390 = sbv_bv_u32_rotr(s388, 11);
+  const SWord32 s391 = s389 ^ s390;
+  const SWord32 s392 = sbv_bv_u32_rotr(s388, 25);
+  const SWord32 s393 = s391 ^ s392;
+  const SWord32 s394 = sbv_bv_u32_add(s279, s393);
+  const SWord32 s395 = s370 & s388;
+  const SWord32 s396 = ~s388;
+  const SWord32 s397 = s352 & s396;
+  const SWord32 s398 = s395 ^ s397;
+  const SWord32 s399 = sbv_bv_u32_add(s394, s398);
+  const SWord32 s401 = sbv_bv_u32_add(s399, 0x243185beUL);
+  const SWord16 s402 = sbv_bv_join_u8_u8_u16(s72, s73);
+  const SWord16 s403 = sbv_bv_join_u8_u8_u16(s74, s75);
+  const SWord32 s404 = sbv_bv_join_u16_u16_u32(s402, s403);
+  const SWord32 s405 = sbv_bv_u32_add(s401, s404);
+  const SWord32 s406 = sbv_bv_u32_add(s340, s405);
+  const SWord32 s407 = sbv_bv_u32_rotr(s406, 6);
+  const SWord32 s408 = sbv_bv_u32_rotr(s406, 11);
+  const SWord32 s409 = s407 ^ s408;
+  const SWord32 s410 = sbv_bv_u32_rotr(s406, 25);
+  const SWord32 s411 = s409 ^ s410;
+  const SWord32 s412 = sbv_bv_u32_add(s352, s411);
+  const SWord32 s413 = s388 & s406;
+  const SWord32 s414 = ~s406;
+  const SWord32 s415 = s370 & s414;
+  const SWord32 s416 = s413 ^ s415;
+  const SWord32 s417 = sbv_bv_u32_add(s412, s416);
+  const SWord32 s419 = sbv_bv_u32_add(s417, 0x550c7dc3UL);
+  const SWord16 s420 = sbv_bv_join_u8_u8_u16(s76, s77);
+  const SWord16 s421 = sbv_bv_join_u8_u8_u16(s78, s79);
+  const SWord32 s422 = sbv_bv_join_u16_u16_u32(s420, s421);
+  const SWord32 s423 = sbv_bv_u32_add(s419, s422);
+  const SWord32 s424 = sbv_bv_u32_add(s351, s423);
+  const SWord32 s425 = sbv_bv_u32_rotr(s351, 2);
+  const SWord32 s426 = sbv_bv_u32_rotr(s351, 13);
+  const SWord32 s427 = s425 ^ s426;
+  const SWord32 s428 = sbv_bv_u32_rotr(s351, 22);
+  const SWord32 s429 = s427 ^ s428;
+  const SWord32 s430 = s340 & s351;
+  const SWord32 s431 = s329 & s351;
+  const SWord32 s432 = s430 ^ s431;
+  const SWord32 s433 = s346 ^ s432;
+  const SWord32 s434 = sbv_bv_u32_add(s429, s433);
+  const SWord32 s435 = sbv_bv_u32_add(s369, s434);
+  const SWord32 s436 = sbv_bv_u32_rotr(s435, 2);
+  const SWord32 s437 = sbv_bv_u32_rotr(s435, 13);
+  const SWord32 s438 = s436 ^ s437;
+  const SWord32 s439 = sbv_bv_u32_rotr(s435, 22);
+  const SWord32 s440 = s438 ^ s439;
+  const SWord32 s441 = s351 & s435;
+  const SWord32 s442 = s340 & s435;
+  const SWord32 s443 = s441 ^ s442;
+  const SWord32 s444 = s430 ^ s443;
+  const SWord32 s445 = sbv_bv_u32_add(s440, s444);
+  const SWord32 s446 = sbv_bv_u32_add(s387, s445);
+  const SWord32 s447 = sbv_bv_u32_rotr(s446, 2);
+  const SWord32 s448 = sbv_bv_u32_rotr(s446, 13);
+  const SWord32 s449 = s447 ^ s448;
+  const SWord32 s450 = sbv_bv_u32_rotr(s446, 22);
+  const SWord32 s451 = s449 ^ s450;
+  const SWord32 s452 = s435 & s446;
+  const SWord32 s453 = s351 & s446;
+  const SWord32 s454 = s452 ^ s453;
+  const SWord32 s455 = s441 ^ s454;
+  const SWord32 s456 = sbv_bv_u32_add(s451, s455);
+  const SWord32 s457 = sbv_bv_u32_add(s405, s456);
+  const SWord32 s458 = sbv_bv_u32_rotr(s424, 6);
+  const SWord32 s459 = sbv_bv_u32_rotr(s424, 11);
+  const SWord32 s460 = s458 ^ s459;
+  const SWord32 s461 = sbv_bv_u32_rotr(s424, 25);
+  const SWord32 s462 = s460 ^ s461;
+  const SWord32 s463 = sbv_bv_u32_add(s370, s462);
+  const SWord32 s464 = s406 & s424;
+  const SWord32 s465 = ~s424;
+  const SWord32 s466 = s388 & s465;
+  const SWord32 s467 = s464 ^ s466;
+  const SWord32 s468 = sbv_bv_u32_add(s463, s467);
+  const SWord32 s470 = sbv_bv_u32_add(s468, 0x72be5d74UL);
+  const SWord16 s471 = sbv_bv_join_u8_u8_u16(s80, s81);
+  const SWord16 s472 = sbv_bv_join_u8_u8_u16(s82, s83);
+  const SWord32 s473 = sbv_bv_join_u16_u16_u32(s471, s472);
+  const SWord32 s474 = sbv_bv_u32_add(s470, s473);
+  const SWord32 s475 = sbv_bv_u32_add(s435, s474);
+  const SWord32 s476 = sbv_bv_u32_rotr(s475, 6);
+  const SWord32 s477 = sbv_bv_u32_rotr(s475, 11);
+  const SWord32 s478 = s476 ^ s477;
+  const SWord32 s479 = sbv_bv_u32_rotr(s475, 25);
+  const SWord32 s480 = s478 ^ s479;
+  const SWord32 s481 = sbv_bv_u32_add(s388, s480);
+  const SWord32 s482 = s424 & s475;
+  const SWord32 s483 = ~s475;
+  const SWord32 s484 = s406 & s483;
+  const SWord32 s485 = s482 ^ s484;
+  const SWord32 s486 = sbv_bv_u32_add(s481, s485);
+  const SWord32 s488 = sbv_bv_u32_add(s486, 0x80deb1feUL);
+  const SWord16 s489 = sbv_bv_join_u8_u8_u16(s84, s85);
+  const SWord16 s490 = sbv_bv_join_u8_u8_u16(s86, s87);
+  const SWord32 s491 = sbv_bv_join_u16_u16_u32(s489, s490);
+  const SWord32 s492 = sbv_bv_u32_add(s488, s491);
+  const SWord32 s493 = sbv_bv_u32_add(s446, s492);
+  const SWord32 s494 = sbv_bv_u32_rotr(s493, 6);
+  const SWord32 s495 = sbv_bv_u32_rotr(s493, 11);
+  const SWord32 s496 = s494 ^ s495;
+  const SWord32 s497 = sbv_bv_u32_rotr(s493, 25);
+  const SWord32 s498 = s496 ^ s497;
+  const SWord32 s499 = sbv_bv_u32_add(s406, s498);
+  const SWord32 s500 = s475 & s493;
+  const SWord32 s501 = ~s493;
+  const SWord32 s502 = s424 & s501;
+  const SWord32 s503 = s500 ^ s502;
+  const SWord32 s504 = sbv_bv_u32_add(s499, s503);
+  const SWord32 s506 = sbv_bv_u32_add(s504, 0x9bdc06a7UL);
+  const SWord16 s507 = sbv_bv_join_u8_u8_u16(s88, s89);
+  const SWord16 s508 = sbv_bv_join_u8_u8_u16(s90, s91);
+  const SWord32 s509 = sbv_bv_join_u16_u16_u32(s507, s508);
+  const SWord32 s510 = sbv_bv_u32_add(s506, s509);
+  const SWord32 s511 = sbv_bv_u32_add(s457, s510);
+  const SWord32 s512 = sbv_bv_u32_rotr(s511, 6);
+  const SWord32 s513 = sbv_bv_u32_rotr(s511, 11);
+  const SWord32 s514 = s512 ^ s513;
+  const SWord32 s515 = sbv_bv_u32_rotr(s511, 25);
+  const SWord32 s516 = s514 ^ s515;
+  const SWord32 s517 = sbv_bv_u32_add(s424, s516);
+  const SWord32 s518 = s493 & s511;
+  const SWord32 s519 = ~s511;
+  const SWord32 s520 = s475 & s519;
+  const SWord32 s521 = s518 ^ s520;
+  const SWord32 s522 = sbv_bv_u32_add(s517, s521);
+  const SWord32 s524 = sbv_bv_u32_add(s522, 0xc19bf174UL);
+  const SWord16 s525 = sbv_bv_join_u8_u8_u16(s92, s93);
+  const SWord16 s526 = sbv_bv_join_u8_u8_u16(s94, s95);
+  const SWord32 s527 = sbv_bv_join_u16_u16_u32(s525, s526);
+  const SWord32 s528 = sbv_bv_u32_add(s524, s527);
+  const SWord32 s529 = sbv_bv_u32_rotr(s457, 2);
+  const SWord32 s530 = sbv_bv_u32_rotr(s457, 13);
+  const SWord32 s531 = s529 ^ s530;
+  const SWord32 s532 = sbv_bv_u32_rotr(s457, 22);
+  const SWord32 s533 = s531 ^ s532;
+  const SWord32 s534 = s446 & s457;
+  const SWord32 s535 = s435 & s457;
+  const SWord32 s536 = s534 ^ s535;
+  const SWord32 s537 = s452 ^ s536;
+  const SWord32 s538 = sbv_bv_u32_add(s533, s537);
+  const SWord32 s539 = sbv_bv_u32_add(s423, s538);
+  const SWord32 s540 = sbv_bv_u32_rotr(s539, 2);
+  const SWord32 s541 = sbv_bv_u32_rotr(s539, 13);
+  const SWord32 s542 = s540 ^ s541;
+  const SWord32 s543 = sbv_bv_u32_rotr(s539, 22);
+  const SWord32 s544 = s542 ^ s543;
+  const SWord32 s545 = s457 & s539;
+  const SWord32 s546 = s446 & s539;
+  const SWord32 s547 = s545 ^ s546;
+  const SWord32 s548 = s534 ^ s547;
+  const SWord32 s549 = sbv_bv_u32_add(s544, s548);
+  const SWord32 s550 = sbv_bv_u32_add(s474, s549);
+  const SWord32 s551 = sbv_bv_u32_rotr(s550, 2);
+  const SWord32 s552 = sbv_bv_u32_rotr(s550, 13);
+  const SWord32 s553 = s551 ^ s552;
+  const SWord32 s554 = sbv_bv_u32_rotr(s550, 22);
+  const SWord32 s555 = s553 ^ s554;
+  const SWord32 s556 = s539 & s550;
+  const SWord32 s557 = s457 & s550;
+  const SWord32 s558 = s556 ^ s557;
+  const SWord32 s559 = s545 ^ s558;
+  const SWord32 s560 = sbv_bv_u32_add(s555, s559);
+  const SWord32 s561 = sbv_bv_u32_add(s492, s560);
+  const SWord32 s562 = sbv_bv_u32_rotr(s561, 2);
+  const SWord32 s563 = sbv_bv_u32_rotr(s561, 13);
+  const SWord32 s564 = s562 ^ s563;
+  const SWord32 s565 = sbv_bv_u32_rotr(s561, 22);
+  const SWord32 s566 = s564 ^ s565;
+  const SWord32 s567 = s550 & s561;
+  const SWord32 s568 = s539 & s561;
+  const SWord32 s569 = s567 ^ s568;
+  const SWord32 s570 = s556 ^ s569;
+  const SWord32 s571 = sbv_bv_u32_add(s566, s570);
+  const SWord32 s572 = sbv_bv_u32_add(s510, s571);
+  const SWord32 s573 = sbv_bv_u32_rotr(s572, 2);
+  const SWord32 s574 = sbv_bv_u32_rotr(s572, 13);
+  const SWord32 s575 = s573 ^ s574;
+  const SWord32 s576 = sbv_bv_u32_rotr(s572, 22);
+  const SWord32 s577 = s575 ^ s576;
+  const SWord32 s578 = s561 & s572;
+  const SWord32 s579 = s550 & s572;
+  const SWord32 s580 = s578 ^ s579;
+  const SWord32 s581 = s567 ^ s580;
+  const SWord32 s582 = sbv_bv_u32_add(s577, s581);
+  const SWord32 s583 = sbv_bv_u32_add(s528, s582);
+  const SWord32 s584 = sbv_bv_u32_add(s528, s539);
+  const SWord32 s585 = sbv_bv_u32_rotr(s584, 6);
+  const SWord32 s586 = sbv_bv_u32_rotr(s584, 11);
+  const SWord32 s587 = s585 ^ s586;
+  const SWord32 s588 = sbv_bv_u32_rotr(s584, 25);
+  const SWord32 s589 = s587 ^ s588;
+  const SWord32 s590 = sbv_bv_u32_add(s475, s589);
+  const SWord32 s591 = s511 & s584;
+  const SWord32 s592 = ~s584;
+  const SWord32 s593 = s493 & s592;
+  const SWord32 s594 = s591 ^ s593;
+  const SWord32 s595 = sbv_bv_u32_add(s590, s594);
+  const SWord32 s597 = sbv_bv_u32_add(s595, 0xe49b69c1UL);
+  const SWord32 s598 = sbv_bv_u32_rotr(s509, 17);
+  const SWord32 s599 = sbv_bv_u32_rotr(s509, 19);
+  const SWord32 s600 = s598 ^ s599;
+  const SWord32 s602 = sbv_bv_u32_lshr(s509, 0x0000000aUL);
+  const SWord32 s603 = s600 ^ s602;
+  const SWord32 s604 = sbv_bv_u32_add(s386, s603);
+  const SWord32 s605 = sbv_bv_u32_rotr(s153, 7);
+  const SWord32 s606 = sbv_bv_u32_rotr(s153, 18);
+  const SWord32 s607 = s605 ^ s606;
+  const SWord32 s609 = sbv_bv_u32_lshr(s153, 0x00000003UL);
+  const SWord32 s610 = s607 ^ s609;
+  const SWord32 s611 = sbv_bv_u32_add(s604, s610);
+  const SWord32 s612 = sbv_bv_u32_add(s135, s611);
+  const SWord32 s613 = sbv_bv_u32_add(s597, s612);
+  const SWord32 s614 = sbv_bv_u32_add(s550, s613);
+  const SWord32 s615 = sbv_bv_u32_rotr(s614, 6);
+  const SWord32 s616 = sbv_bv_u32_rotr(s614, 11);
+  const SWord32 s617 = s615 ^ s616;
+  const SWord32 s618 = sbv_bv_u32_rotr(s614, 25);
+  const SWord32 s619 = s617 ^ s618;
+  const SWord32 s620 = sbv_bv_u32_add(s493, s619);
+  const SWord32 s621 = s584 & s614;
+  const SWord32 s622 = ~s614;
+  const SWord32 s623 = s511 & s622;
+  const SWord32 s624 = s621 ^ s623;
+  const SWord32 s625 = sbv_bv_u32_add(s620, s624);
+  const SWord32 s627 = sbv_bv_u32_add(s625, 0xefbe4786UL);
+  const SWord32 s628 = sbv_bv_u32_rotr(s527, 17);
+  const SWord32 s629 = sbv_bv_u32_rotr(s527, 19);
+  const SWord32 s630 = s628 ^ s629;
+  const SWord32 s631 = sbv_bv_u32_lshr(s527, 0x0000000aUL);
+  const SWord32 s632 = s630 ^ s631;
+  const SWord32 s633 = sbv_bv_u32_add(s404, s632);
+  const SWord32 s634 = sbv_bv_u32_rotr(s171, 7);
+  const SWord32 s635 = sbv_bv_u32_rotr(s171, 18);
+  const SWord32 s636 = s634 ^ s635;
+  const SWord32 s637 = sbv_bv_u32_lshr(s171, 0x00000003UL);
+  const SWord32 s638 = s636 ^ s637;
+  const SWord32 s639 = sbv_bv_u32_add(s633, s638);
+  const SWord32 s640 = sbv_bv_u32_add(s153, s639);
+  const SWord32 s641 = sbv_bv_u32_add(s627, s640);
+  const SWord32 s642 = sbv_bv_u32_add(s561, s641);
+  const SWord32 s643 = sbv_bv_u32_rotr(s642, 6);
+  const SWord32 s644 = sbv_bv_u32_rotr(s642, 11);
+  const SWord32 s645 = s643 ^ s644;
+  const SWord32 s646 = sbv_bv_u32_rotr(s642, 25);
+  const SWord32 s647 = s645 ^ s646;
+  const SWord32 s648 = sbv_bv_u32_add(s511, s647);
+  const SWord32 s649 = s614 & s642;
+  const SWord32 s650 = ~s642;
+  const SWord32 s651 = s584 & s650;
+  const SWord32 s652 = s649 ^ s651;
+  const SWord32 s653 = sbv_bv_u32_add(s648, s652);
+  const SWord32 s655 = sbv_bv_u32_add(s653, 0x0fc19dc6UL);
+  const SWord32 s656 = sbv_bv_u32_rotr(s612, 17);
+  const SWord32 s657 = sbv_bv_u32_rotr(s612, 19);
+  const SWord32 s658 = s656 ^ s657;
+  const SWord32 s659 = sbv_bv_u32_lshr(s612, 0x0000000aUL);
+  const SWord32 s660 = s658 ^ s659;
+  const SWord32 s661 = sbv_bv_u32_add(s422, s660);
+  const SWord32 s662 = sbv_bv_u32_rotr(s189, 7);
+  const SWord32 s663 = sbv_bv_u32_rotr(s189, 18);
+  const SWord32 s664 = s662 ^ s663;
+  const SWord32 s665 = sbv_bv_u32_lshr(s189, 0x00000003UL);
+  const SWord32 s666 = s664 ^ s665;
+  const SWord32 s667 = sbv_bv_u32_add(s661, s666);
+  const SWord32 s668 = sbv_bv_u32_add(s171, s667);
+  const SWord32 s669 = sbv_bv_u32_add(s655, s668);
+  const SWord32 s670 = sbv_bv_u32_add(s572, s669);
+  const SWord32 s671 = sbv_bv_u32_rotr(s670, 6);
+  const SWord32 s672 = sbv_bv_u32_rotr(s670, 11);
+  const SWord32 s673 = s671 ^ s672;
+  const SWord32 s674 = sbv_bv_u32_rotr(s670, 25);
+  const SWord32 s675 = s673 ^ s674;
+  const SWord32 s676 = sbv_bv_u32_add(s584, s675);
+  const SWord32 s677 = s642 & s670;
+  const SWord32 s678 = ~s670;
+  const SWord32 s679 = s614 & s678;
+  const SWord32 s680 = s677 ^ s679;
+  const SWord32 s681 = sbv_bv_u32_add(s676, s680);
+  const SWord32 s683 = sbv_bv_u32_add(s681, 0x240ca1ccUL);
+  const SWord32 s684 = sbv_bv_u32_rotr(s640, 17);
+  const SWord32 s685 = sbv_bv_u32_rotr(s640, 19);
+  const SWord32 s686 = s684 ^ s685;
+  const SWord32 s687 = sbv_bv_u32_lshr(s640, 0x0000000aUL);
+  const SWord32 s688 = s686 ^ s687;
+  const SWord32 s689 = sbv_bv_u32_add(s473, s688);
+  const SWord32 s690 = sbv_bv_u32_rotr(s241, 7);
+  const SWord32 s691 = sbv_bv_u32_rotr(s241, 18);
+  const SWord32 s692 = s690 ^ s691;
+  const SWord32 s693 = sbv_bv_u32_lshr(s241, 0x00000003UL);
+  const SWord32 s694 = s692 ^ s693;
+  const SWord32 s695 = sbv_bv_u32_add(s689, s694);
+  const SWord32 s696 = sbv_bv_u32_add(s189, s695);
+  const SWord32 s697 = sbv_bv_u32_add(s683, s696);
+  const SWord32 s698 = sbv_bv_u32_add(s583, s697);
+  const SWord32 s699 = sbv_bv_u32_rotr(s583, 2);
+  const SWord32 s700 = sbv_bv_u32_rotr(s583, 13);
+  const SWord32 s701 = s699 ^ s700;
+  const SWord32 s702 = sbv_bv_u32_rotr(s583, 22);
+  const SWord32 s703 = s701 ^ s702;
+  const SWord32 s704 = s572 & s583;
+  const SWord32 s705 = s561 & s583;
+  const SWord32 s706 = s704 ^ s705;
+  const SWord32 s707 = s578 ^ s706;
+  const SWord32 s708 = sbv_bv_u32_add(s703, s707);
+  const SWord32 s709 = sbv_bv_u32_add(s613, s708);
+  const SWord32 s710 = sbv_bv_u32_rotr(s709, 2);
+  const SWord32 s711 = sbv_bv_u32_rotr(s709, 13);
+  const SWord32 s712 = s710 ^ s711;
+  const SWord32 s713 = sbv_bv_u32_rotr(s709, 22);
+  const SWord32 s714 = s712 ^ s713;
+  const SWord32 s715 = s583 & s709;
+  const SWord32 s716 = s572 & s709;
+  const SWord32 s717 = s715 ^ s716;
+  const SWord32 s718 = s704 ^ s717;
+  const SWord32 s719 = sbv_bv_u32_add(s714, s718);
+  const SWord32 s720 = sbv_bv_u32_add(s641, s719);
+  const SWord32 s721 = sbv_bv_u32_rotr(s720, 2);
+  const SWord32 s722 = sbv_bv_u32_rotr(s720, 13);
+  const SWord32 s723 = s721 ^ s722;
+  const SWord32 s724 = sbv_bv_u32_rotr(s720, 22);
+  const SWord32 s725 = s723 ^ s724;
+  const SWord32 s726 = s709 & s720;
+  const SWord32 s727 = s583 & s720;
+  const SWord32 s728 = s726 ^ s727;
+  const SWord32 s729 = s715 ^ s728;
+  const SWord32 s730 = sbv_bv_u32_add(s725, s729);
+  const SWord32 s731 = sbv_bv_u32_add(s669, s730);
+  const SWord32 s732 = sbv_bv_u32_rotr(s698, 6);
+  const SWord32 s733 = sbv_bv_u32_rotr(s698, 11);
+  const SWord32 s734 = s732 ^ s733;
+  const SWord32 s735 = sbv_bv_u32_rotr(s698, 25);
+  const SWord32 s736 = s734 ^ s735;
+  const SWord32 s737 = sbv_bv_u32_add(s614, s736);
+  const SWord32 s738 = s670 & s698;
+  const SWord32 s739 = ~s698;
+  const SWord32 s740 = s642 & s739;
+  const SWord32 s741 = s738 ^ s740;
+  const SWord32 s742 = sbv_bv_u32_add(s737, s741);
+  const SWord32 s744 = sbv_bv_u32_add(s742, 0x2de92c6fUL);
+  const SWord32 s745 = sbv_bv_u32_rotr(s668, 17);
+  const SWord32 s746 = sbv_bv_u32_rotr(s668, 19);
+  const SWord32 s747 = s745 ^ s746;
+  const SWord32 s748 = sbv_bv_u32_lshr(s668, 0x0000000aUL);
+  const SWord32 s749 = s747 ^ s748;
+  const SWord32 s750 = sbv_bv_u32_add(s491, s749);
+  const SWord32 s751 = sbv_bv_u32_rotr(s259, 7);
+  const SWord32 s752 = sbv_bv_u32_rotr(s259, 18);
+  const SWord32 s753 = s751 ^ s752;
+  const SWord32 s754 = sbv_bv_u32_lshr(s259, 0x00000003UL);
+  const SWord32 s755 = s753 ^ s754;
+  const SWord32 s756 = sbv_bv_u32_add(s750, s755);
+  const SWord32 s757 = sbv_bv_u32_add(s241, s756);
+  const SWord32 s758 = sbv_bv_u32_add(s744, s757);
+  const SWord32 s759 = sbv_bv_u32_add(s709, s758);
+  const SWord32 s760 = sbv_bv_u32_rotr(s759, 6);
+  const SWord32 s761 = sbv_bv_u32_rotr(s759, 11);
+  const SWord32 s762 = s760 ^ s761;
+  const SWord32 s763 = sbv_bv_u32_rotr(s759, 25);
+  const SWord32 s764 = s762 ^ s763;
+  const SWord32 s765 = sbv_bv_u32_add(s642, s764);
+  const SWord32 s766 = s698 & s759;
+  const SWord32 s767 = ~s759;
+  const SWord32 s768 = s670 & s767;
+  const SWord32 s769 = s766 ^ s768;
+  const SWord32 s770 = sbv_bv_u32_add(s765, s769);
+  const SWord32 s772 = sbv_bv_u32_add(s770, 0x4a7484aaUL);
+  const SWord32 s773 = sbv_bv_u32_rotr(s696, 17);
+  const SWord32 s774 = sbv_bv_u32_rotr(s696, 19);
+  const SWord32 s775 = s773 ^ s774;
+  const SWord32 s776 = sbv_bv_u32_lshr(s696, 0x0000000aUL);
+  const SWord32 s777 = s775 ^ s776;
+  const SWord32 s778 = sbv_bv_u32_add(s509, s777);
+  const SWord32 s779 = sbv_bv_u32_rotr(s277, 7);
+  const SWord32 s780 = sbv_bv_u32_rotr(s277, 18);
+  const SWord32 s781 = s779 ^ s780;
+  const SWord32 s782 = sbv_bv_u32_lshr(s277, 0x00000003UL);
+  const SWord32 s783 = s781 ^ s782;
+  const SWord32 s784 = sbv_bv_u32_add(s778, s783);
+  const SWord32 s785 = sbv_bv_u32_add(s259, s784);
+  const SWord32 s786 = sbv_bv_u32_add(s772, s785);
+  const SWord32 s787 = sbv_bv_u32_add(s720, s786);
+  const SWord32 s788 = sbv_bv_u32_rotr(s787, 6);
+  const SWord32 s789 = sbv_bv_u32_rotr(s787, 11);
+  const SWord32 s790 = s788 ^ s789;
+  const SWord32 s791 = sbv_bv_u32_rotr(s787, 25);
+  const SWord32 s792 = s790 ^ s791;
+  const SWord32 s793 = sbv_bv_u32_add(s670, s792);
+  const SWord32 s794 = s759 & s787;
+  const SWord32 s795 = ~s787;
+  const SWord32 s796 = s698 & s795;
+  const SWord32 s797 = s794 ^ s796;
+  const SWord32 s798 = sbv_bv_u32_add(s793, s797);
+  const SWord32 s800 = sbv_bv_u32_add(s798, 0x5cb0a9dcUL);
+  const SWord32 s801 = sbv_bv_u32_rotr(s757, 17);
+  const SWord32 s802 = sbv_bv_u32_rotr(s757, 19);
+  const SWord32 s803 = s801 ^ s802;
+  const SWord32 s804 = sbv_bv_u32_lshr(s757, 0x0000000aUL);
+  const SWord32 s805 = s803 ^ s804;
+  const SWord32 s806 = sbv_bv_u32_add(s527, s805);
+  const SWord32 s807 = sbv_bv_u32_rotr(s295, 7);
+  const SWord32 s808 = sbv_bv_u32_rotr(s295, 18);
+  const SWord32 s809 = s807 ^ s808;
+  const SWord32 s810 = sbv_bv_u32_lshr(s295, 0x00000003UL);
+  const SWord32 s811 = s809 ^ s810;
+  const SWord32 s812 = sbv_bv_u32_add(s806, s811);
+  const SWord32 s813 = sbv_bv_u32_add(s277, s812);
+  const SWord32 s814 = sbv_bv_u32_add(s800, s813);
+  const SWord32 s815 = sbv_bv_u32_add(s731, s814);
+  const SWord32 s816 = sbv_bv_u32_rotr(s815, 6);
+  const SWord32 s817 = sbv_bv_u32_rotr(s815, 11);
+  const SWord32 s818 = s816 ^ s817;
+  const SWord32 s819 = sbv_bv_u32_rotr(s815, 25);
+  const SWord32 s820 = s818 ^ s819;
+  const SWord32 s821 = sbv_bv_u32_add(s698, s820);
+  const SWord32 s822 = s787 & s815;
+  const SWord32 s823 = ~s815;
+  const SWord32 s824 = s759 & s823;
+  const SWord32 s825 = s822 ^ s824;
+  const SWord32 s826 = sbv_bv_u32_add(s821, s825);
+  const SWord32 s828 = sbv_bv_u32_add(s826, 0x76f988daUL);
+  const SWord32 s829 = sbv_bv_u32_rotr(s785, 17);
+  const SWord32 s830 = sbv_bv_u32_rotr(s785, 19);
+  const SWord32 s831 = s829 ^ s830;
+  const SWord32 s832 = sbv_bv_u32_lshr(s785, 0x0000000aUL);
+  const SWord32 s833 = s831 ^ s832;
+  const SWord32 s834 = sbv_bv_u32_add(s612, s833);
+  const SWord32 s835 = sbv_bv_u32_rotr(s368, 7);
+  const SWord32 s836 = sbv_bv_u32_rotr(s368, 18);
+  const SWord32 s837 = s835 ^ s836;
+  const SWord32 s838 = sbv_bv_u32_lshr(s368, 0x00000003UL);
+  const SWord32 s839 = s837 ^ s838;
+  const SWord32 s840 = sbv_bv_u32_add(s834, s839);
+  const SWord32 s841 = sbv_bv_u32_add(s295, s840);
+  const SWord32 s842 = sbv_bv_u32_add(s828, s841);
+  const SWord32 s843 = sbv_bv_u32_rotr(s731, 2);
+  const SWord32 s844 = sbv_bv_u32_rotr(s731, 13);
+  const SWord32 s845 = s843 ^ s844;
+  const SWord32 s846 = sbv_bv_u32_rotr(s731, 22);
+  const SWord32 s847 = s845 ^ s846;
+  const SWord32 s848 = s720 & s731;
+  const SWord32 s849 = s709 & s731;
+  const SWord32 s850 = s848 ^ s849;
+  const SWord32 s851 = s726 ^ s850;
+  const SWord32 s852 = sbv_bv_u32_add(s847, s851);
+  const SWord32 s853 = sbv_bv_u32_add(s697, s852);
+  const SWord32 s854 = sbv_bv_u32_rotr(s853, 2);
+  const SWord32 s855 = sbv_bv_u32_rotr(s853, 13);
+  const SWord32 s856 = s854 ^ s855;
+  const SWord32 s857 = sbv_bv_u32_rotr(s853, 22);
+  const SWord32 s858 = s856 ^ s857;
+  const SWord32 s859 = s731 & s853;
+  const SWord32 s860 = s720 & s853;
+  const SWord32 s861 = s859 ^ s860;
+  const SWord32 s862 = s848 ^ s861;
+  const SWord32 s863 = sbv_bv_u32_add(s858, s862);
+  const SWord32 s864 = sbv_bv_u32_add(s758, s863);
+  const SWord32 s865 = sbv_bv_u32_rotr(s864, 2);
+  const SWord32 s866 = sbv_bv_u32_rotr(s864, 13);
+  const SWord32 s867 = s865 ^ s866;
+  const SWord32 s868 = sbv_bv_u32_rotr(s864, 22);
+  const SWord32 s869 = s867 ^ s868;
+  const SWord32 s870 = s853 & s864;
+  const SWord32 s871 = s731 & s864;
+  const SWord32 s872 = s870 ^ s871;
+  const SWord32 s873 = s859 ^ s872;
+  const SWord32 s874 = sbv_bv_u32_add(s869, s873);
+  const SWord32 s875 = sbv_bv_u32_add(s786, s874);
+  const SWord32 s876 = sbv_bv_u32_rotr(s875, 2);
+  const SWord32 s877 = sbv_bv_u32_rotr(s875, 13);
+  const SWord32 s878 = s876 ^ s877;
+  const SWord32 s879 = sbv_bv_u32_rotr(s875, 22);
+  const SWord32 s880 = s878 ^ s879;
+  const SWord32 s881 = s864 & s875;
+  const SWord32 s882 = s853 & s875;
+  const SWord32 s883 = s881 ^ s882;
+  const SWord32 s884 = s870 ^ s883;
+  const SWord32 s885 = sbv_bv_u32_add(s880, s884);
+  const SWord32 s886 = sbv_bv_u32_add(s814, s885);
+  const SWord32 s887 = sbv_bv_u32_rotr(s886, 2);
+  const SWord32 s888 = sbv_bv_u32_rotr(s886, 13);
+  const SWord32 s889 = s887 ^ s888;
+  const SWord32 s890 = sbv_bv_u32_rotr(s886, 22);
+  const SWord32 s891 = s889 ^ s890;
+  const SWord32 s892 = s875 & s886;
+  const SWord32 s893 = s864 & s886;
+  const SWord32 s894 = s892 ^ s893;
+  const SWord32 s895 = s881 ^ s894;
+  const SWord32 s896 = sbv_bv_u32_add(s891, s895);
+  const SWord32 s897 = sbv_bv_u32_add(s842, s896);
+  const SWord32 s898 = sbv_bv_u32_add(s842, s853);
+  const SWord32 s899 = sbv_bv_u32_rotr(s898, 6);
+  const SWord32 s900 = sbv_bv_u32_rotr(s898, 11);
+  const SWord32 s901 = s899 ^ s900;
+  const SWord32 s902 = sbv_bv_u32_rotr(s898, 25);
+  const SWord32 s903 = s901 ^ s902;
+  const SWord32 s904 = sbv_bv_u32_add(s759, s903);
+  const SWord32 s905 = s815 & s898;
+  const SWord32 s906 = ~s898;
+  const SWord32 s907 = s787 & s906;
+  const SWord32 s908 = s905 ^ s907;
+  const SWord32 s909 = sbv_bv_u32_add(s904, s908);
+  const SWord32 s911 = sbv_bv_u32_add(s909, 0x983e5152UL);
+  const SWord32 s912 = sbv_bv_u32_rotr(s813, 17);
+  const SWord32 s913 = sbv_bv_u32_rotr(s813, 19);
+  const SWord32 s914 = s912 ^ s913;
+  const SWord32 s915 = sbv_bv_u32_lshr(s813, 0x0000000aUL);
+  const SWord32 s916 = s914 ^ s915;
+  const SWord32 s917 = sbv_bv_u32_add(s640, s916);
+  const SWord32 s918 = sbv_bv_u32_rotr(s386, 7);
+  const SWord32 s919 = sbv_bv_u32_rotr(s386, 18);
+  const SWord32 s920 = s918 ^ s919;
+  const SWord32 s921 = sbv_bv_u32_lshr(s386, 0x00000003UL);
+  const SWord32 s922 = s920 ^ s921;
+  const SWord32 s923 = sbv_bv_u32_add(s917, s922);
+  const SWord32 s924 = sbv_bv_u32_add(s368, s923);
+  const SWord32 s925 = sbv_bv_u32_add(s911, s924);
+  const SWord32 s926 = sbv_bv_u32_add(s864, s925);
+  const SWord32 s927 = sbv_bv_u32_rotr(s926, 6);
+  const SWord32 s928 = sbv_bv_u32_rotr(s926, 11);
+  const SWord32 s929 = s927 ^ s928;
+  const SWord32 s930 = sbv_bv_u32_rotr(s926, 25);
+  const SWord32 s931 = s929 ^ s930;
+  const SWord32 s932 = sbv_bv_u32_add(s787, s931);
+  const SWord32 s933 = s898 & s926;
+  const SWord32 s934 = ~s926;
+  const SWord32 s935 = s815 & s934;
+  const SWord32 s936 = s933 ^ s935;
+  const SWord32 s937 = sbv_bv_u32_add(s932, s936);
+  const SWord32 s939 = sbv_bv_u32_add(s937, 0xa831c66dUL);
+  const SWord32 s940 = sbv_bv_u32_rotr(s841, 17);
+  const SWord32 s941 = sbv_bv_u32_rotr(s841, 19);
+  const SWord32 s942 = s940 ^ s941;
+  const SWord32 s943 = sbv_bv_u32_lshr(s841, 0x0000000aUL);
+  const SWord32 s944 = s942 ^ s943;
+  const SWord32 s945 = sbv_bv_u32_add(s668, s944);
+  const SWord32 s946 = sbv_bv_u32_rotr(s404, 7);
+  const SWord32 s947 = sbv_bv_u32_rotr(s404, 18);
+  const SWord32 s948 = s946 ^ s947;
+  const SWord32 s949 = sbv_bv_u32_lshr(s404, 0x00000003UL);
+  const SWord32 s950 = s948 ^ s949;
+  const SWord32 s951 = sbv_bv_u32_add(s945, s950);
+  const SWord32 s952 = sbv_bv_u32_add(s386, s951);
+  const SWord32 s953 = sbv_bv_u32_add(s939, s952);
+  const SWord32 s954 = sbv_bv_u32_add(s875, s953);
+  const SWord32 s955 = sbv_bv_u32_rotr(s954, 6);
+  const SWord32 s956 = sbv_bv_u32_rotr(s954, 11);
+  const SWord32 s957 = s955 ^ s956;
+  const SWord32 s958 = sbv_bv_u32_rotr(s954, 25);
+  const SWord32 s959 = s957 ^ s958;
+  const SWord32 s960 = sbv_bv_u32_add(s815, s959);
+  const SWord32 s961 = s926 & s954;
+  const SWord32 s962 = ~s954;
+  const SWord32 s963 = s898 & s962;
+  const SWord32 s964 = s961 ^ s963;
+  const SWord32 s965 = sbv_bv_u32_add(s960, s964);
+  const SWord32 s967 = sbv_bv_u32_add(s965, 0xb00327c8UL);
+  const SWord32 s968 = sbv_bv_u32_rotr(s924, 17);
+  const SWord32 s969 = sbv_bv_u32_rotr(s924, 19);
+  const SWord32 s970 = s968 ^ s969;
+  const SWord32 s971 = sbv_bv_u32_lshr(s924, 0x0000000aUL);
+  const SWord32 s972 = s970 ^ s971;
+  const SWord32 s973 = sbv_bv_u32_add(s696, s972);
+  const SWord32 s974 = sbv_bv_u32_rotr(s422, 7);
+  const SWord32 s975 = sbv_bv_u32_rotr(s422, 18);
+  const SWord32 s976 = s974 ^ s975;
+  const SWord32 s977 = sbv_bv_u32_lshr(s422, 0x00000003UL);
+  const SWord32 s978 = s976 ^ s977;
+  const SWord32 s979 = sbv_bv_u32_add(s973, s978);
+  const SWord32 s980 = sbv_bv_u32_add(s404, s979);
+  const SWord32 s981 = sbv_bv_u32_add(s967, s980);
+  const SWord32 s982 = sbv_bv_u32_add(s886, s981);
+  const SWord32 s983 = sbv_bv_u32_rotr(s982, 6);
+  const SWord32 s984 = sbv_bv_u32_rotr(s982, 11);
+  const SWord32 s985 = s983 ^ s984;
+  const SWord32 s986 = sbv_bv_u32_rotr(s982, 25);
+  const SWord32 s987 = s985 ^ s986;
+  const SWord32 s988 = sbv_bv_u32_add(s898, s987);
+  const SWord32 s989 = s954 & s982;
+  const SWord32 s990 = ~s982;
+  const SWord32 s991 = s926 & s990;
+  const SWord32 s992 = s989 ^ s991;
+  const SWord32 s993 = sbv_bv_u32_add(s988, s992);
+  const SWord32 s995 = sbv_bv_u32_add(s993, 0xbf597fc7UL);
+  const SWord32 s996 = sbv_bv_u32_rotr(s952, 17);
+  const SWord32 s997 = sbv_bv_u32_rotr(s952, 19);
+  const SWord32 s998 = s996 ^ s997;
+  const SWord32 s999 = sbv_bv_u32_lshr(s952, 0x0000000aUL);
+  const SWord32 s1000 = s998 ^ s999;
+  const SWord32 s1001 = sbv_bv_u32_add(s757, s1000);
+  const SWord32 s1002 = sbv_bv_u32_rotr(s473, 7);
+  const SWord32 s1003 = sbv_bv_u32_rotr(s473, 18);
+  const SWord32 s1004 = s1002 ^ s1003;
+  const SWord32 s1005 = sbv_bv_u32_lshr(s473, 0x00000003UL);
+  const SWord32 s1006 = s1004 ^ s1005;
+  const SWord32 s1007 = sbv_bv_u32_add(s1001, s1006);
+  const SWord32 s1008 = sbv_bv_u32_add(s422, s1007);
+  const SWord32 s1009 = sbv_bv_u32_add(s995, s1008);
+  const SWord32 s1010 = sbv_bv_u32_add(s897, s1009);
+  const SWord32 s1011 = sbv_bv_u32_rotr(s897, 2);
+  const SWord32 s1012 = sbv_bv_u32_rotr(s897, 13);
+  const SWord32 s1013 = s1011 ^ s1012;
+  const SWord32 s1014 = sbv_bv_u32_rotr(s897, 22);
+  const SWord32 s1015 = s1013 ^ s1014;
+  const SWord32 s1016 = s886 & s897;
+  const SWord32 s1017 = s875 & s897;
+  const SWord32 s1018 = s1016 ^ s1017;
+  const SWord32 s1019 = s892 ^ s1018;
+  const SWord32 s1020 = sbv_bv_u32_add(s1015, s1019);
+  const SWord32 s1021 = sbv_bv_u32_add(s925, s1020);
+  const SWord32 s1022 = sbv_bv_u32_rotr(s1021, 2);
+  const SWord32 s1023 = sbv_bv_u32_rotr(s1021, 13);
+  const SWord32 s1024 = s1022 ^ s1023;
+  const SWord32 s1025 = sbv_bv_u32_rotr(s1021, 22);
+  const SWord32 s1026 = s1024 ^ s1025;
+  const SWord32 s1027 = s897 & s1021;
+  const SWord32 s1028 = s886 & s1021;
+  const SWord32 s1029 = s1027 ^ s1028;
+  const SWord32 s1030 = s1016 ^ s1029;
+  const SWord32 s1031 = sbv_bv_u32_add(s1026, s1030);
+  const SWord32 s1032 = sbv_bv_u32_add(s953, s1031);
+  const SWord32 s1033 = sbv_bv_u32_rotr(s1032, 2);
+  const SWord32 s1034 = sbv_bv_u32_rotr(s1032, 13);
+  const SWord32 s1035 = s1033 ^ s1034;
+  const SWord32 s1036 = sbv_bv_u32_rotr(s1032, 22);
+  const SWord32 s1037 = s1035 ^ s1036;
+  const SWord32 s1038 = s1021 & s1032;
+  const SWord32 s1039 = s897 & s1032;
+  const SWord32 s1040 = s1038 ^ s1039;
+  const SWord32 s1041 = s1027 ^ s1040;
+  const SWord32 s1042 = sbv_bv_u32_add(s1037, s1041);
+  const SWord32 s1043 = sbv_bv_u32_add(s981, s1042);
+  const SWord32 s1044 = sbv_bv_u32_rotr(s1010, 6);
+  const SWord32 s1045 = sbv_bv_u32_rotr(s1010, 11);
+  const SWord32 s1046 = s1044 ^ s1045;
+  const SWord32 s1047 = sbv_bv_u32_rotr(s1010, 25);
+  const SWord32 s1048 = s1046 ^ s1047;
+  const SWord32 s1049 = sbv_bv_u32_add(s926, s1048);
+  const SWord32 s1050 = s982 & s1010;
+  const SWord32 s1051 = ~s1010;
+  const SWord32 s1052 = s954 & s1051;
+  const SWord32 s1053 = s1050 ^ s1052;
+  const SWord32 s1054 = sbv_bv_u32_add(s1049, s1053);
+  const SWord32 s1056 = sbv_bv_u32_add(s1054, 0xc6e00bf3UL);
+  const SWord32 s1057 = sbv_bv_u32_rotr(s980, 17);
+  const SWord32 s1058 = sbv_bv_u32_rotr(s980, 19);
+  const SWord32 s1059 = s1057 ^ s1058;
+  const SWord32 s1060 = sbv_bv_u32_lshr(s980, 0x0000000aUL);
+  const SWord32 s1061 = s1059 ^ s1060;
+  const SWord32 s1062 = sbv_bv_u32_add(s785, s1061);
+  const SWord32 s1063 = sbv_bv_u32_rotr(s491, 7);
+  const SWord32 s1064 = sbv_bv_u32_rotr(s491, 18);
+  const SWord32 s1065 = s1063 ^ s1064;
+  const SWord32 s1066 = sbv_bv_u32_lshr(s491, 0x00000003UL);
+  const SWord32 s1067 = s1065 ^ s1066;
+  const SWord32 s1068 = sbv_bv_u32_add(s1062, s1067);
+  const SWord32 s1069 = sbv_bv_u32_add(s473, s1068);
+  const SWord32 s1070 = sbv_bv_u32_add(s1056, s1069);
+  const SWord32 s1071 = sbv_bv_u32_add(s1021, s1070);
+  const SWord32 s1072 = sbv_bv_u32_rotr(s1071, 6);
+  const SWord32 s1073 = sbv_bv_u32_rotr(s1071, 11);
+  const SWord32 s1074 = s1072 ^ s1073;
+  const SWord32 s1075 = sbv_bv_u32_rotr(s1071, 25);
+  const SWord32 s1076 = s1074 ^ s1075;
+  const SWord32 s1077 = sbv_bv_u32_add(s954, s1076);
+  const SWord32 s1078 = s1010 & s1071;
+  const SWord32 s1079 = ~s1071;
+  const SWord32 s1080 = s982 & s1079;
+  const SWord32 s1081 = s1078 ^ s1080;
+  const SWord32 s1082 = sbv_bv_u32_add(s1077, s1081);
+  const SWord32 s1084 = sbv_bv_u32_add(s1082, 0xd5a79147UL);
+  const SWord32 s1085 = sbv_bv_u32_rotr(s1008, 17);
+  const SWord32 s1086 = sbv_bv_u32_rotr(s1008, 19);
+  const SWord32 s1087 = s1085 ^ s1086;
+  const SWord32 s1088 = sbv_bv_u32_lshr(s1008, 0x0000000aUL);
+  const SWord32 s1089 = s1087 ^ s1088;
+  const SWord32 s1090 = sbv_bv_u32_add(s813, s1089);
+  const SWord32 s1091 = sbv_bv_u32_rotr(s509, 7);
+  const SWord32 s1092 = sbv_bv_u32_rotr(s509, 18);
+  const SWord32 s1093 = s1091 ^ s1092;
+  const SWord32 s1094 = sbv_bv_u32_lshr(s509, 0x00000003UL);
+  const SWord32 s1095 = s1093 ^ s1094;
+  const SWord32 s1096 = sbv_bv_u32_add(s1090, s1095);
+  const SWord32 s1097 = sbv_bv_u32_add(s491, s1096);
+  const SWord32 s1098 = sbv_bv_u32_add(s1084, s1097);
+  const SWord32 s1099 = sbv_bv_u32_add(s1032, s1098);
+  const SWord32 s1100 = sbv_bv_u32_rotr(s1099, 6);
+  const SWord32 s1101 = sbv_bv_u32_rotr(s1099, 11);
+  const SWord32 s1102 = s1100 ^ s1101;
+  const SWord32 s1103 = sbv_bv_u32_rotr(s1099, 25);
+  const SWord32 s1104 = s1102 ^ s1103;
+  const SWord32 s1105 = sbv_bv_u32_add(s982, s1104);
+  const SWord32 s1106 = s1071 & s1099;
+  const SWord32 s1107 = ~s1099;
+  const SWord32 s1108 = s1010 & s1107;
+  const SWord32 s1109 = s1106 ^ s1108;
+  const SWord32 s1110 = sbv_bv_u32_add(s1105, s1109);
+  const SWord32 s1112 = sbv_bv_u32_add(s1110, 0x06ca6351UL);
+  const SWord32 s1113 = sbv_bv_u32_rotr(s1069, 17);
+  const SWord32 s1114 = sbv_bv_u32_rotr(s1069, 19);
+  const SWord32 s1115 = s1113 ^ s1114;
+  const SWord32 s1116 = sbv_bv_u32_lshr(s1069, 0x0000000aUL);
+  const SWord32 s1117 = s1115 ^ s1116;
+  const SWord32 s1118 = sbv_bv_u32_add(s841, s1117);
+  const SWord32 s1119 = sbv_bv_u32_rotr(s527, 7);
+  const SWord32 s1120 = sbv_bv_u32_rotr(s527, 18);
+  const SWord32 s1121 = s1119 ^ s1120;
+  const SWord32 s1122 = sbv_bv_u32_lshr(s527, 0x00000003UL);
+  const SWord32 s1123 = s1121 ^ s1122;
+  const SWord32 s1124 = sbv_bv_u32_add(s1118, s1123);
+  const SWord32 s1125 = sbv_bv_u32_add(s509, s1124);
+  const SWord32 s1126 = sbv_bv_u32_add(s1112, s1125);
+  const SWord32 s1127 = sbv_bv_u32_add(s1043, s1126);
+  const SWord32 s1128 = sbv_bv_u32_rotr(s1127, 6);
+  const SWord32 s1129 = sbv_bv_u32_rotr(s1127, 11);
+  const SWord32 s1130 = s1128 ^ s1129;
+  const SWord32 s1131 = sbv_bv_u32_rotr(s1127, 25);
+  const SWord32 s1132 = s1130 ^ s1131;
+  const SWord32 s1133 = sbv_bv_u32_add(s1010, s1132);
+  const SWord32 s1134 = s1099 & s1127;
+  const SWord32 s1135 = ~s1127;
+  const SWord32 s1136 = s1071 & s1135;
+  const SWord32 s1137 = s1134 ^ s1136;
+  const SWord32 s1138 = sbv_bv_u32_add(s1133, s1137);
+  const SWord32 s1140 = sbv_bv_u32_add(s1138, 0x14292967UL);
+  const SWord32 s1141 = sbv_bv_u32_rotr(s1097, 17);
+  const SWord32 s1142 = sbv_bv_u32_rotr(s1097, 19);
+  const SWord32 s1143 = s1141 ^ s1142;
+  const SWord32 s1144 = sbv_bv_u32_lshr(s1097, 0x0000000aUL);
+  const SWord32 s1145 = s1143 ^ s1144;
+  const SWord32 s1146 = sbv_bv_u32_add(s924, s1145);
+  const SWord32 s1147 = sbv_bv_u32_rotr(s612, 7);
+  const SWord32 s1148 = sbv_bv_u32_rotr(s612, 18);
+  const SWord32 s1149 = s1147 ^ s1148;
+  const SWord32 s1150 = sbv_bv_u32_lshr(s612, 0x00000003UL);
+  const SWord32 s1151 = s1149 ^ s1150;
+  const SWord32 s1152 = sbv_bv_u32_add(s1146, s1151);
+  const SWord32 s1153 = sbv_bv_u32_add(s527, s1152);
+  const SWord32 s1154 = sbv_bv_u32_add(s1140, s1153);
+  const SWord32 s1155 = sbv_bv_u32_rotr(s1043, 2);
+  const SWord32 s1156 = sbv_bv_u32_rotr(s1043, 13);
+  const SWord32 s1157 = s1155 ^ s1156;
+  const SWord32 s1158 = sbv_bv_u32_rotr(s1043, 22);
+  const SWord32 s1159 = s1157 ^ s1158;
+  const SWord32 s1160 = s1032 & s1043;
+  const SWord32 s1161 = s1021 & s1043;
+  const SWord32 s1162 = s1160 ^ s1161;
+  const SWord32 s1163 = s1038 ^ s1162;
+  const SWord32 s1164 = sbv_bv_u32_add(s1159, s1163);
+  const SWord32 s1165 = sbv_bv_u32_add(s1009, s1164);
+  const SWord32 s1166 = sbv_bv_u32_rotr(s1165, 2);
+  const SWord32 s1167 = sbv_bv_u32_rotr(s1165, 13);
+  const SWord32 s1168 = s1166 ^ s1167;
+  const SWord32 s1169 = sbv_bv_u32_rotr(s1165, 22);
+  const SWord32 s1170 = s1168 ^ s1169;
+  const SWord32 s1171 = s1043 & s1165;
+  const SWord32 s1172 = s1032 & s1165;
+  const SWord32 s1173 = s1171 ^ s1172;
+  const SWord32 s1174 = s1160 ^ s1173;
+  const SWord32 s1175 = sbv_bv_u32_add(s1170, s1174);
+  const SWord32 s1176 = sbv_bv_u32_add(s1070, s1175);
+  const SWord32 s1177 = sbv_bv_u32_rotr(s1176, 2);
+  const SWord32 s1178 = sbv_bv_u32_rotr(s1176, 13);
+  const SWord32 s1179 = s1177 ^ s1178;
+  const SWord32 s1180 = sbv_bv_u32_rotr(s1176, 22);
+  const SWord32 s1181 = s1179 ^ s1180;
+  const SWord32 s1182 = s1165 & s1176;
+  const SWord32 s1183 = s1043 & s1176;
+  const SWord32 s1184 = s1182 ^ s1183;
+  const SWord32 s1185 = s1171 ^ s1184;
+  const SWord32 s1186 = sbv_bv_u32_add(s1181, s1185);
+  const SWord32 s1187 = sbv_bv_u32_add(s1098, s1186);
+  const SWord32 s1188 = sbv_bv_u32_rotr(s1187, 2);
+  const SWord32 s1189 = sbv_bv_u32_rotr(s1187, 13);
+  const SWord32 s1190 = s1188 ^ s1189;
+  const SWord32 s1191 = sbv_bv_u32_rotr(s1187, 22);
+  const SWord32 s1192 = s1190 ^ s1191;
+  const SWord32 s1193 = s1176 & s1187;
+  const SWord32 s1194 = s1165 & s1187;
+  const SWord32 s1195 = s1193 ^ s1194;
+  const SWord32 s1196 = s1182 ^ s1195;
+  const SWord32 s1197 = sbv_bv_u32_add(s1192, s1196);
+  const SWord32 s1198 = sbv_bv_u32_add(s1126, s1197);
+  const SWord32 s1199 = sbv_bv_u32_rotr(s1198, 2);
+  const SWord32 s1200 = sbv_bv_u32_rotr(s1198, 13);
+  const SWord32 s1201 = s1199 ^ s1200;
+  const SWord32 s1202 = sbv_bv_u32_rotr(s1198, 22);
+  const SWord32 s1203 = s1201 ^ s1202;
+  const SWord32 s1204 = s1187 & s1198;
+  const SWord32 s1205 = s1176 & s1198;
+  const SWord32 s1206 = s1204 ^ s1205;
+  const SWord32 s1207 = s1193 ^ s1206;
+  const SWord32 s1208 = sbv_bv_u32_add(s1203, s1207);
+  const SWord32 s1209 = sbv_bv_u32_add(s1154, s1208);
+  const SWord32 s1210 = sbv_bv_u32_add(s1154, s1165);
+  const SWord32 s1211 = sbv_bv_u32_rotr(s1210, 6);
+  const SWord32 s1212 = sbv_bv_u32_rotr(s1210, 11);
+  const SWord32 s1213 = s1211 ^ s1212;
+  const SWord32 s1214 = sbv_bv_u32_rotr(s1210, 25);
+  const SWord32 s1215 = s1213 ^ s1214;
+  const SWord32 s1216 = sbv_bv_u32_add(s1071, s1215);
+  const SWord32 s1217 = s1127 & s1210;
+  const SWord32 s1218 = ~s1210;
+  const SWord32 s1219 = s1099 & s1218;
+  const SWord32 s1220 = s1217 ^ s1219;
+  const SWord32 s1221 = sbv_bv_u32_add(s1216, s1220);
+  const SWord32 s1223 = sbv_bv_u32_add(s1221, 0x27b70a85UL);
+  const SWord32 s1224 = sbv_bv_u32_rotr(s1125, 17);
+  const SWord32 s1225 = sbv_bv_u32_rotr(s1125, 19);
+  const SWord32 s1226 = s1224 ^ s1225;
+  const SWord32 s1227 = sbv_bv_u32_lshr(s1125, 0x0000000aUL);
+  const SWord32 s1228 = s1226 ^ s1227;
+  const SWord32 s1229 = sbv_bv_u32_add(s952, s1228);
+  const SWord32 s1230 = sbv_bv_u32_rotr(s640, 7);
+  const SWord32 s1231 = sbv_bv_u32_rotr(s640, 18);
+  const SWord32 s1232 = s1230 ^ s1231;
+  const SWord32 s1233 = sbv_bv_u32_lshr(s640, 0x00000003UL);
+  const SWord32 s1234 = s1232 ^ s1233;
+  const SWord32 s1235 = sbv_bv_u32_add(s1229, s1234);
+  const SWord32 s1236 = sbv_bv_u32_add(s612, s1235);
+  const SWord32 s1237 = sbv_bv_u32_add(s1223, s1236);
+  const SWord32 s1238 = sbv_bv_u32_add(s1176, s1237);
+  const SWord32 s1239 = sbv_bv_u32_rotr(s1238, 6);
+  const SWord32 s1240 = sbv_bv_u32_rotr(s1238, 11);
+  const SWord32 s1241 = s1239 ^ s1240;
+  const SWord32 s1242 = sbv_bv_u32_rotr(s1238, 25);
+  const SWord32 s1243 = s1241 ^ s1242;
+  const SWord32 s1244 = sbv_bv_u32_add(s1099, s1243);
+  const SWord32 s1245 = s1210 & s1238;
+  const SWord32 s1246 = ~s1238;
+  const SWord32 s1247 = s1127 & s1246;
+  const SWord32 s1248 = s1245 ^ s1247;
+  const SWord32 s1249 = sbv_bv_u32_add(s1244, s1248);
+  const SWord32 s1251 = sbv_bv_u32_add(s1249, 0x2e1b2138UL);
+  const SWord32 s1252 = sbv_bv_u32_rotr(s1153, 17);
+  const SWord32 s1253 = sbv_bv_u32_rotr(s1153, 19);
+  const SWord32 s1254 = s1252 ^ s1253;
+  const SWord32 s1255 = sbv_bv_u32_lshr(s1153, 0x0000000aUL);
+  const SWord32 s1256 = s1254 ^ s1255;
+  const SWord32 s1257 = sbv_bv_u32_add(s980, s1256);
+  const SWord32 s1258 = sbv_bv_u32_rotr(s668, 7);
+  const SWord32 s1259 = sbv_bv_u32_rotr(s668, 18);
+  const SWord32 s1260 = s1258 ^ s1259;
+  const SWord32 s1261 = sbv_bv_u32_lshr(s668, 0x00000003UL);
+  const SWord32 s1262 = s1260 ^ s1261;
+  const SWord32 s1263 = sbv_bv_u32_add(s1257, s1262);
+  const SWord32 s1264 = sbv_bv_u32_add(s640, s1263);
+  const SWord32 s1265 = sbv_bv_u32_add(s1251, s1264);
+  const SWord32 s1266 = sbv_bv_u32_add(s1187, s1265);
+  const SWord32 s1267 = sbv_bv_u32_rotr(s1266, 6);
+  const SWord32 s1268 = sbv_bv_u32_rotr(s1266, 11);
+  const SWord32 s1269 = s1267 ^ s1268;
+  const SWord32 s1270 = sbv_bv_u32_rotr(s1266, 25);
+  const SWord32 s1271 = s1269 ^ s1270;
+  const SWord32 s1272 = sbv_bv_u32_add(s1127, s1271);
+  const SWord32 s1273 = s1238 & s1266;
+  const SWord32 s1274 = ~s1266;
+  const SWord32 s1275 = s1210 & s1274;
+  const SWord32 s1276 = s1273 ^ s1275;
+  const SWord32 s1277 = sbv_bv_u32_add(s1272, s1276);
+  const SWord32 s1279 = sbv_bv_u32_add(s1277, 0x4d2c6dfcUL);
+  const SWord32 s1280 = sbv_bv_u32_rotr(s1236, 17);
+  const SWord32 s1281 = sbv_bv_u32_rotr(s1236, 19);
+  const SWord32 s1282 = s1280 ^ s1281;
+  const SWord32 s1283 = sbv_bv_u32_lshr(s1236, 0x0000000aUL);
+  const SWord32 s1284 = s1282 ^ s1283;
+  const SWord32 s1285 = sbv_bv_u32_add(s1008, s1284);
+  const SWord32 s1286 = sbv_bv_u32_rotr(s696, 7);
+  const SWord32 s1287 = sbv_bv_u32_rotr(s696, 18);
+  const SWord32 s1288 = s1286 ^ s1287;
+  const SWord32 s1289 = sbv_bv_u32_lshr(s696, 0x00000003UL);
+  const SWord32 s1290 = s1288 ^ s1289;
+  const SWord32 s1291 = sbv_bv_u32_add(s1285, s1290);
+  const SWord32 s1292 = sbv_bv_u32_add(s668, s1291);
+  const SWord32 s1293 = sbv_bv_u32_add(s1279, s1292);
+  const SWord32 s1294 = sbv_bv_u32_add(s1198, s1293);
+  const SWord32 s1295 = sbv_bv_u32_rotr(s1294, 6);
+  const SWord32 s1296 = sbv_bv_u32_rotr(s1294, 11);
+  const SWord32 s1297 = s1295 ^ s1296;
+  const SWord32 s1298 = sbv_bv_u32_rotr(s1294, 25);
+  const SWord32 s1299 = s1297 ^ s1298;
+  const SWord32 s1300 = sbv_bv_u32_add(s1210, s1299);
+  const SWord32 s1301 = s1266 & s1294;
+  const SWord32 s1302 = ~s1294;
+  const SWord32 s1303 = s1238 & s1302;
+  const SWord32 s1304 = s1301 ^ s1303;
+  const SWord32 s1305 = sbv_bv_u32_add(s1300, s1304);
+  const SWord32 s1307 = sbv_bv_u32_add(s1305, 0x53380d13UL);
+  const SWord32 s1308 = sbv_bv_u32_rotr(s1264, 17);
+  const SWord32 s1309 = sbv_bv_u32_rotr(s1264, 19);
+  const SWord32 s1310 = s1308 ^ s1309;
+  const SWord32 s1311 = sbv_bv_u32_lshr(s1264, 0x0000000aUL);
+  const SWord32 s1312 = s1310 ^ s1311;
+  const SWord32 s1313 = sbv_bv_u32_add(s1069, s1312);
+  const SWord32 s1314 = sbv_bv_u32_rotr(s757, 7);
+  const SWord32 s1315 = sbv_bv_u32_rotr(s757, 18);
+  const SWord32 s1316 = s1314 ^ s1315;
+  const SWord32 s1317 = sbv_bv_u32_lshr(s757, 0x00000003UL);
+  const SWord32 s1318 = s1316 ^ s1317;
+  const SWord32 s1319 = sbv_bv_u32_add(s1313, s1318);
+  const SWord32 s1320 = sbv_bv_u32_add(s696, s1319);
+  const SWord32 s1321 = sbv_bv_u32_add(s1307, s1320);
+  const SWord32 s1322 = sbv_bv_u32_add(s1209, s1321);
+  const SWord32 s1323 = sbv_bv_u32_rotr(s1209, 2);
+  const SWord32 s1324 = sbv_bv_u32_rotr(s1209, 13);
+  const SWord32 s1325 = s1323 ^ s1324;
+  const SWord32 s1326 = sbv_bv_u32_rotr(s1209, 22);
+  const SWord32 s1327 = s1325 ^ s1326;
+  const SWord32 s1328 = s1198 & s1209;
+  const SWord32 s1329 = s1187 & s1209;
+  const SWord32 s1330 = s1328 ^ s1329;
+  const SWord32 s1331 = s1204 ^ s1330;
+  const SWord32 s1332 = sbv_bv_u32_add(s1327, s1331);
+  const SWord32 s1333 = sbv_bv_u32_add(s1237, s1332);
+  const SWord32 s1334 = sbv_bv_u32_rotr(s1333, 2);
+  const SWord32 s1335 = sbv_bv_u32_rotr(s1333, 13);
+  const SWord32 s1336 = s1334 ^ s1335;
+  const SWord32 s1337 = sbv_bv_u32_rotr(s1333, 22);
+  const SWord32 s1338 = s1336 ^ s1337;
+  const SWord32 s1339 = s1209 & s1333;
+  const SWord32 s1340 = s1198 & s1333;
+  const SWord32 s1341 = s1339 ^ s1340;
+  const SWord32 s1342 = s1328 ^ s1341;
+  const SWord32 s1343 = sbv_bv_u32_add(s1338, s1342);
+  const SWord32 s1344 = sbv_bv_u32_add(s1265, s1343);
+  const SWord32 s1345 = sbv_bv_u32_rotr(s1344, 2);
+  const SWord32 s1346 = sbv_bv_u32_rotr(s1344, 13);
+  const SWord32 s1347 = s1345 ^ s1346;
+  const SWord32 s1348 = sbv_bv_u32_rotr(s1344, 22);
+  const SWord32 s1349 = s1347 ^ s1348;
+  const SWord32 s1350 = s1333 & s1344;
+  const SWord32 s1351 = s1209 & s1344;
+  const SWord32 s1352 = s1350 ^ s1351;
+  const SWord32 s1353 = s1339 ^ s1352;
+  const SWord32 s1354 = sbv_bv_u32_add(s1349, s1353);
+  const SWord32 s1355 = sbv_bv_u32_add(s1293, s1354);
+  const SWord32 s1356 = sbv_bv_u32_rotr(s1322, 6);
+  const SWord32 s1357 = sbv_bv_u32_rotr(s1322, 11);
+  const SWord32 s1358 = s1356 ^ s1357;
+  const SWord32 s1359 = sbv_bv_u32_rotr(s1322, 25);
+  const SWord32 s1360 = s1358 ^ s1359;
+  const SWord32 s1361 = sbv_bv_u32_add(s1238, s1360);
+  const SWord32 s1362 = s1294 & s1322;
+  const SWord32 s1363 = ~s1322;
+  const SWord32 s1364 = s1266 & s1363;
+  const SWord32 s1365 = s1362 ^ s1364;
+  const SWord32 s1366 = sbv_bv_u32_add(s1361, s1365);
+  const SWord32 s1368 = sbv_bv_u32_add(s1366, 0x650a7354UL);
+  const SWord32 s1369 = sbv_bv_u32_rotr(s1292, 17);
+  const SWord32 s1370 = sbv_bv_u32_rotr(s1292, 19);
+  const SWord32 s1371 = s1369 ^ s1370;
+  const SWord32 s1372 = sbv_bv_u32_lshr(s1292, 0x0000000aUL);
+  const SWord32 s1373 = s1371 ^ s1372;
+  const SWord32 s1374 = sbv_bv_u32_add(s1097, s1373);
+  const SWord32 s1375 = sbv_bv_u32_rotr(s785, 7);
+  const SWord32 s1376 = sbv_bv_u32_rotr(s785, 18);
+  const SWord32 s1377 = s1375 ^ s1376;
+  const SWord32 s1378 = sbv_bv_u32_lshr(s785, 0x00000003UL);
+  const SWord32 s1379 = s1377 ^ s1378;
+  const SWord32 s1380 = sbv_bv_u32_add(s1374, s1379);
+  const SWord32 s1381 = sbv_bv_u32_add(s757, s1380);
+  const SWord32 s1382 = sbv_bv_u32_add(s1368, s1381);
+  const SWord32 s1383 = sbv_bv_u32_add(s1333, s1382);
+  const SWord32 s1384 = sbv_bv_u32_rotr(s1383, 6);
+  const SWord32 s1385 = sbv_bv_u32_rotr(s1383, 11);
+  const SWord32 s1386 = s1384 ^ s1385;
+  const SWord32 s1387 = sbv_bv_u32_rotr(s1383, 25);
+  const SWord32 s1388 = s1386 ^ s1387;
+  const SWord32 s1389 = sbv_bv_u32_add(s1266, s1388);
+  const SWord32 s1390 = s1322 & s1383;
+  const SWord32 s1391 = ~s1383;
+  const SWord32 s1392 = s1294 & s1391;
+  const SWord32 s1393 = s1390 ^ s1392;
+  const SWord32 s1394 = sbv_bv_u32_add(s1389, s1393);
+  const SWord32 s1396 = sbv_bv_u32_add(s1394, 0x766a0abbUL);
+  const SWord32 s1397 = sbv_bv_u32_rotr(s1320, 17);
+  const SWord32 s1398 = sbv_bv_u32_rotr(s1320, 19);
+  const SWord32 s1399 = s1397 ^ s1398;
+  const SWord32 s1400 = sbv_bv_u32_lshr(s1320, 0x0000000aUL);
+  const SWord32 s1401 = s1399 ^ s1400;
+  const SWord32 s1402 = sbv_bv_u32_add(s1125, s1401);
+  const SWord32 s1403 = sbv_bv_u32_rotr(s813, 7);
+  const SWord32 s1404 = sbv_bv_u32_rotr(s813, 18);
+  const SWord32 s1405 = s1403 ^ s1404;
+  const SWord32 s1406 = sbv_bv_u32_lshr(s813, 0x00000003UL);
+  const SWord32 s1407 = s1405 ^ s1406;
+  const SWord32 s1408 = sbv_bv_u32_add(s1402, s1407);
+  const SWord32 s1409 = sbv_bv_u32_add(s785, s1408);
+  const SWord32 s1410 = sbv_bv_u32_add(s1396, s1409);
+  const SWord32 s1411 = sbv_bv_u32_add(s1344, s1410);
+  const SWord32 s1412 = sbv_bv_u32_rotr(s1411, 6);
+  const SWord32 s1413 = sbv_bv_u32_rotr(s1411, 11);
+  const SWord32 s1414 = s1412 ^ s1413;
+  const SWord32 s1415 = sbv_bv_u32_rotr(s1411, 25);
+  const SWord32 s1416 = s1414 ^ s1415;
+  const SWord32 s1417 = sbv_bv_u32_add(s1294, s1416);
+  const SWord32 s1418 = s1383 & s1411;
+  const SWord32 s1419 = ~s1411;
+  const SWord32 s1420 = s1322 & s1419;
+  const SWord32 s1421 = s1418 ^ s1420;
+  const SWord32 s1422 = sbv_bv_u32_add(s1417, s1421);
+  const SWord32 s1424 = sbv_bv_u32_add(s1422, 0x81c2c92eUL);
+  const SWord32 s1425 = sbv_bv_u32_rotr(s1381, 17);
+  const SWord32 s1426 = sbv_bv_u32_rotr(s1381, 19);
+  const SWord32 s1427 = s1425 ^ s1426;
+  const SWord32 s1428 = sbv_bv_u32_lshr(s1381, 0x0000000aUL);
+  const SWord32 s1429 = s1427 ^ s1428;
+  const SWord32 s1430 = sbv_bv_u32_add(s1153, s1429);
+  const SWord32 s1431 = sbv_bv_u32_rotr(s841, 7);
+  const SWord32 s1432 = sbv_bv_u32_rotr(s841, 18);
+  const SWord32 s1433 = s1431 ^ s1432;
+  const SWord32 s1434 = sbv_bv_u32_lshr(s841, 0x00000003UL);
+  const SWord32 s1435 = s1433 ^ s1434;
+  const SWord32 s1436 = sbv_bv_u32_add(s1430, s1435);
+  const SWord32 s1437 = sbv_bv_u32_add(s813, s1436);
+  const SWord32 s1438 = sbv_bv_u32_add(s1424, s1437);
+  const SWord32 s1439 = sbv_bv_u32_add(s1355, s1438);
+  const SWord32 s1440 = sbv_bv_u32_rotr(s1439, 6);
+  const SWord32 s1441 = sbv_bv_u32_rotr(s1439, 11);
+  const SWord32 s1442 = s1440 ^ s1441;
+  const SWord32 s1443 = sbv_bv_u32_rotr(s1439, 25);
+  const SWord32 s1444 = s1442 ^ s1443;
+  const SWord32 s1445 = sbv_bv_u32_add(s1322, s1444);
+  const SWord32 s1446 = s1411 & s1439;
+  const SWord32 s1447 = ~s1439;
+  const SWord32 s1448 = s1383 & s1447;
+  const SWord32 s1449 = s1446 ^ s1448;
+  const SWord32 s1450 = sbv_bv_u32_add(s1445, s1449);
+  const SWord32 s1452 = sbv_bv_u32_add(s1450, 0x92722c85UL);
+  const SWord32 s1453 = sbv_bv_u32_rotr(s1409, 17);
+  const SWord32 s1454 = sbv_bv_u32_rotr(s1409, 19);
+  const SWord32 s1455 = s1453 ^ s1454;
+  const SWord32 s1456 = sbv_bv_u32_lshr(s1409, 0x0000000aUL);
+  const SWord32 s1457 = s1455 ^ s1456;
+  const SWord32 s1458 = sbv_bv_u32_add(s1236, s1457);
+  const SWord32 s1459 = sbv_bv_u32_rotr(s924, 7);
+  const SWord32 s1460 = sbv_bv_u32_rotr(s924, 18);
+  const SWord32 s1461 = s1459 ^ s1460;
+  const SWord32 s1462 = sbv_bv_u32_lshr(s924, 0x00000003UL);
+  const SWord32 s1463 = s1461 ^ s1462;
+  const SWord32 s1464 = sbv_bv_u32_add(s1458, s1463);
+  const SWord32 s1465 = sbv_bv_u32_add(s841, s1464);
+  const SWord32 s1466 = sbv_bv_u32_add(s1452, s1465);
+  const SWord32 s1467 = sbv_bv_u32_rotr(s1355, 2);
+  const SWord32 s1468 = sbv_bv_u32_rotr(s1355, 13);
+  const SWord32 s1469 = s1467 ^ s1468;
+  const SWord32 s1470 = sbv_bv_u32_rotr(s1355, 22);
+  const SWord32 s1471 = s1469 ^ s1470;
+  const SWord32 s1472 = s1344 & s1355;
+  const SWord32 s1473 = s1333 & s1355;
+  const SWord32 s1474 = s1472 ^ s1473;
+  const SWord32 s1475 = s1350 ^ s1474;
+  const SWord32 s1476 = sbv_bv_u32_add(s1471, s1475);
+  const SWord32 s1477 = sbv_bv_u32_add(s1321, s1476);
+  const SWord32 s1478 = sbv_bv_u32_rotr(s1477, 2);
+  const SWord32 s1479 = sbv_bv_u32_rotr(s1477, 13);
+  const SWord32 s1480 = s1478 ^ s1479;
+  const SWord32 s1481 = sbv_bv_u32_rotr(s1477, 22);
+  const SWord32 s1482 = s1480 ^ s1481;
+  const SWord32 s1483 = s1355 & s1477;
+  const SWord32 s1484 = s1344 & s1477;
+  const SWord32 s1485 = s1483 ^ s1484;
+  const SWord32 s1486 = s1472 ^ s1485;
+  const SWord32 s1487 = sbv_bv_u32_add(s1482, s1486);
+  const SWord32 s1488 = sbv_bv_u32_add(s1382, s1487);
+  const SWord32 s1489 = sbv_bv_u32_rotr(s1488, 2);
+  const SWord32 s1490 = sbv_bv_u32_rotr(s1488, 13);
+  const SWord32 s1491 = s1489 ^ s1490;
+  const SWord32 s1492 = sbv_bv_u32_rotr(s1488, 22);
+  const SWord32 s1493 = s1491 ^ s1492;
+  const SWord32 s1494 = s1477 & s1488;
+  const SWord32 s1495 = s1355 & s1488;
+  const SWord32 s1496 = s1494 ^ s1495;
+  const SWord32 s1497 = s1483 ^ s1496;
+  const SWord32 s1498 = sbv_bv_u32_add(s1493, s1497);
+  const SWord32 s1499 = sbv_bv_u32_add(s1410, s1498);
+  const SWord32 s1500 = sbv_bv_u32_rotr(s1499, 2);
+  const SWord32 s1501 = sbv_bv_u32_rotr(s1499, 13);
+  const SWord32 s1502 = s1500 ^ s1501;
+  const SWord32 s1503 = sbv_bv_u32_rotr(s1499, 22);
+  const SWord32 s1504 = s1502 ^ s1503;
+  const SWord32 s1505 = s1488 & s1499;
+  const SWord32 s1506 = s1477 & s1499;
+  const SWord32 s1507 = s1505 ^ s1506;
+  const SWord32 s1508 = s1494 ^ s1507;
+  const SWord32 s1509 = sbv_bv_u32_add(s1504, s1508);
+  const SWord32 s1510 = sbv_bv_u32_add(s1438, s1509);
+  const SWord32 s1511 = sbv_bv_u32_rotr(s1510, 2);
+  const SWord32 s1512 = sbv_bv_u32_rotr(s1510, 13);
+  const SWord32 s1513 = s1511 ^ s1512;
+  const SWord32 s1514 = sbv_bv_u32_rotr(s1510, 22);
+  const SWord32 s1515 = s1513 ^ s1514;
+  const SWord32 s1516 = s1499 & s1510;
+  const SWord32 s1517 = s1488 & s1510;
+  const SWord32 s1518 = s1516 ^ s1517;
+  const SWord32 s1519 = s1505 ^ s1518;
+  const SWord32 s1520 = sbv_bv_u32_add(s1515, s1519);
+  const SWord32 s1521 = sbv_bv_u32_add(s1466, s1520);
+  const SWord32 s1522 = sbv_bv_u32_add(s1466, s1477);
+  const SWord32 s1523 = sbv_bv_u32_rotr(s1522, 6);
+  const SWord32 s1524 = sbv_bv_u32_rotr(s1522, 11);
+  const SWord32 s1525 = s1523 ^ s1524;
+  const SWord32 s1526 = sbv_bv_u32_rotr(s1522, 25);
+  const SWord32 s1527 = s1525 ^ s1526;
+  const SWord32 s1528 = sbv_bv_u32_add(s1383, s1527);
+  const SWord32 s1529 = s1439 & s1522;
+  const SWord32 s1530 = ~s1522;
+  const SWord32 s1531 = s1411 & s1530;
+  const SWord32 s1532 = s1529 ^ s1531;
+  const SWord32 s1533 = sbv_bv_u32_add(s1528, s1532);
+  const SWord32 s1535 = sbv_bv_u32_add(s1533, 0xa2bfe8a1UL);
+  const SWord32 s1536 = sbv_bv_u32_rotr(s1437, 17);
+  const SWord32 s1537 = sbv_bv_u32_rotr(s1437, 19);
+  const SWord32 s1538 = s1536 ^ s1537;
+  const SWord32 s1539 = sbv_bv_u32_lshr(s1437, 0x0000000aUL);
+  const SWord32 s1540 = s1538 ^ s1539;
+  const SWord32 s1541 = sbv_bv_u32_add(s1264, s1540);
+  const SWord32 s1542 = sbv_bv_u32_rotr(s952, 7);
+  const SWord32 s1543 = sbv_bv_u32_rotr(s952, 18);
+  const SWord32 s1544 = s1542 ^ s1543;
+  const SWord32 s1545 = sbv_bv_u32_lshr(s952, 0x00000003UL);
+  const SWord32 s1546 = s1544 ^ s1545;
+  const SWord32 s1547 = sbv_bv_u32_add(s1541, s1546);
+  const SWord32 s1548 = sbv_bv_u32_add(s924, s1547);
+  const SWord32 s1549 = sbv_bv_u32_add(s1535, s1548);
+  const SWord32 s1550 = sbv_bv_u32_add(s1488, s1549);
+  const SWord32 s1551 = sbv_bv_u32_rotr(s1550, 6);
+  const SWord32 s1552 = sbv_bv_u32_rotr(s1550, 11);
+  const SWord32 s1553 = s1551 ^ s1552;
+  const SWord32 s1554 = sbv_bv_u32_rotr(s1550, 25);
+  const SWord32 s1555 = s1553 ^ s1554;
+  const SWord32 s1556 = sbv_bv_u32_add(s1411, s1555);
+  const SWord32 s1557 = s1522 & s1550;
+  const SWord32 s1558 = ~s1550;
+  const SWord32 s1559 = s1439 & s1558;
+  const SWord32 s1560 = s1557 ^ s1559;
+  const SWord32 s1561 = sbv_bv_u32_add(s1556, s1560);
+  const SWord32 s1563 = sbv_bv_u32_add(s1561, 0xa81a664bUL);
+  const SWord32 s1564 = sbv_bv_u32_rotr(s1465, 17);
+  const SWord32 s1565 = sbv_bv_u32_rotr(s1465, 19);
+  const SWord32 s1566 = s1564 ^ s1565;
+  const SWord32 s1567 = sbv_bv_u32_lshr(s1465, 0x0000000aUL);
+  const SWord32 s1568 = s1566 ^ s1567;
+  const SWord32 s1569 = sbv_bv_u32_add(s1292, s1568);
+  const SWord32 s1570 = sbv_bv_u32_rotr(s980, 7);
+  const SWord32 s1571 = sbv_bv_u32_rotr(s980, 18);
+  const SWord32 s1572 = s1570 ^ s1571;
+  const SWord32 s1573 = sbv_bv_u32_lshr(s980, 0x00000003UL);
+  const SWord32 s1574 = s1572 ^ s1573;
+  const SWord32 s1575 = sbv_bv_u32_add(s1569, s1574);
+  const SWord32 s1576 = sbv_bv_u32_add(s952, s1575);
+  const SWord32 s1577 = sbv_bv_u32_add(s1563, s1576);
+  const SWord32 s1578 = sbv_bv_u32_add(s1499, s1577);
+  const SWord32 s1579 = sbv_bv_u32_rotr(s1578, 6);
+  const SWord32 s1580 = sbv_bv_u32_rotr(s1578, 11);
+  const SWord32 s1581 = s1579 ^ s1580;
+  const SWord32 s1582 = sbv_bv_u32_rotr(s1578, 25);
+  const SWord32 s1583 = s1581 ^ s1582;
+  const SWord32 s1584 = sbv_bv_u32_add(s1439, s1583);
+  const SWord32 s1585 = s1550 & s1578;
+  const SWord32 s1586 = ~s1578;
+  const SWord32 s1587 = s1522 & s1586;
+  const SWord32 s1588 = s1585 ^ s1587;
+  const SWord32 s1589 = sbv_bv_u32_add(s1584, s1588);
+  const SWord32 s1591 = sbv_bv_u32_add(s1589, 0xc24b8b70UL);
+  const SWord32 s1592 = sbv_bv_u32_rotr(s1548, 17);
+  const SWord32 s1593 = sbv_bv_u32_rotr(s1548, 19);
+  const SWord32 s1594 = s1592 ^ s1593;
+  const SWord32 s1595 = sbv_bv_u32_lshr(s1548, 0x0000000aUL);
+  const SWord32 s1596 = s1594 ^ s1595;
+  const SWord32 s1597 = sbv_bv_u32_add(s1320, s1596);
+  const SWord32 s1598 = sbv_bv_u32_rotr(s1008, 7);
+  const SWord32 s1599 = sbv_bv_u32_rotr(s1008, 18);
+  const SWord32 s1600 = s1598 ^ s1599;
+  const SWord32 s1601 = sbv_bv_u32_lshr(s1008, 0x00000003UL);
+  const SWord32 s1602 = s1600 ^ s1601;
+  const SWord32 s1603 = sbv_bv_u32_add(s1597, s1602);
+  const SWord32 s1604 = sbv_bv_u32_add(s980, s1603);
+  const SWord32 s1605 = sbv_bv_u32_add(s1591, s1604);
+  const SWord32 s1606 = sbv_bv_u32_add(s1510, s1605);
+  const SWord32 s1607 = sbv_bv_u32_rotr(s1606, 6);
+  const SWord32 s1608 = sbv_bv_u32_rotr(s1606, 11);
+  const SWord32 s1609 = s1607 ^ s1608;
+  const SWord32 s1610 = sbv_bv_u32_rotr(s1606, 25);
+  const SWord32 s1611 = s1609 ^ s1610;
+  const SWord32 s1612 = sbv_bv_u32_add(s1522, s1611);
+  const SWord32 s1613 = s1578 & s1606;
+  const SWord32 s1614 = ~s1606;
+  const SWord32 s1615 = s1550 & s1614;
+  const SWord32 s1616 = s1613 ^ s1615;
+  const SWord32 s1617 = sbv_bv_u32_add(s1612, s1616);
+  const SWord32 s1619 = sbv_bv_u32_add(s1617, 0xc76c51a3UL);
+  const SWord32 s1620 = sbv_bv_u32_rotr(s1576, 17);
+  const SWord32 s1621 = sbv_bv_u32_rotr(s1576, 19);
+  const SWord32 s1622 = s1620 ^ s1621;
+  const SWord32 s1623 = sbv_bv_u32_lshr(s1576, 0x0000000aUL);
+  const SWord32 s1624 = s1622 ^ s1623;
+  const SWord32 s1625 = sbv_bv_u32_add(s1381, s1624);
+  const SWord32 s1626 = sbv_bv_u32_rotr(s1069, 7);
+  const SWord32 s1627 = sbv_bv_u32_rotr(s1069, 18);
+  const SWord32 s1628 = s1626 ^ s1627;
+  const SWord32 s1629 = sbv_bv_u32_lshr(s1069, 0x00000003UL);
+  const SWord32 s1630 = s1628 ^ s1629;
+  const SWord32 s1631 = sbv_bv_u32_add(s1625, s1630);
+  const SWord32 s1632 = sbv_bv_u32_add(s1008, s1631);
+  const SWord32 s1633 = sbv_bv_u32_add(s1619, s1632);
+  const SWord32 s1634 = sbv_bv_u32_add(s1521, s1633);
+  const SWord32 s1635 = sbv_bv_u32_rotr(s1521, 2);
+  const SWord32 s1636 = sbv_bv_u32_rotr(s1521, 13);
+  const SWord32 s1637 = s1635 ^ s1636;
+  const SWord32 s1638 = sbv_bv_u32_rotr(s1521, 22);
+  const SWord32 s1639 = s1637 ^ s1638;
+  const SWord32 s1640 = s1510 & s1521;
+  const SWord32 s1641 = s1499 & s1521;
+  const SWord32 s1642 = s1640 ^ s1641;
+  const SWord32 s1643 = s1516 ^ s1642;
+  const SWord32 s1644 = sbv_bv_u32_add(s1639, s1643);
+  const SWord32 s1645 = sbv_bv_u32_add(s1549, s1644);
+  const SWord32 s1646 = sbv_bv_u32_rotr(s1645, 2);
+  const SWord32 s1647 = sbv_bv_u32_rotr(s1645, 13);
+  const SWord32 s1648 = s1646 ^ s1647;
+  const SWord32 s1649 = sbv_bv_u32_rotr(s1645, 22);
+  const SWord32 s1650 = s1648 ^ s1649;
+  const SWord32 s1651 = s1521 & s1645;
+  const SWord32 s1652 = s1510 & s1645;
+  const SWord32 s1653 = s1651 ^ s1652;
+  const SWord32 s1654 = s1640 ^ s1653;
+  const SWord32 s1655 = sbv_bv_u32_add(s1650, s1654);
+  const SWord32 s1656 = sbv_bv_u32_add(s1577, s1655);
+  const SWord32 s1657 = sbv_bv_u32_rotr(s1656, 2);
+  const SWord32 s1658 = sbv_bv_u32_rotr(s1656, 13);
+  const SWord32 s1659 = s1657 ^ s1658;
+  const SWord32 s1660 = sbv_bv_u32_rotr(s1656, 22);
+  const SWord32 s1661 = s1659 ^ s1660;
+  const SWord32 s1662 = s1645 & s1656;
+  const SWord32 s1663 = s1521 & s1656;
+  const SWord32 s1664 = s1662 ^ s1663;
+  const SWord32 s1665 = s1651 ^ s1664;
+  const SWord32 s1666 = sbv_bv_u32_add(s1661, s1665);
+  const SWord32 s1667 = sbv_bv_u32_add(s1605, s1666);
+  const SWord32 s1668 = sbv_bv_u32_rotr(s1634, 6);
+  const SWord32 s1669 = sbv_bv_u32_rotr(s1634, 11);
+  const SWord32 s1670 = s1668 ^ s1669;
+  const SWord32 s1671 = sbv_bv_u32_rotr(s1634, 25);
+  const SWord32 s1672 = s1670 ^ s1671;
+  const SWord32 s1673 = sbv_bv_u32_add(s1550, s1672);
+  const SWord32 s1674 = s1606 & s1634;
+  const SWord32 s1675 = ~s1634;
+  const SWord32 s1676 = s1578 & s1675;
+  const SWord32 s1677 = s1674 ^ s1676;
+  const SWord32 s1678 = sbv_bv_u32_add(s1673, s1677);
+  const SWord32 s1680 = sbv_bv_u32_add(s1678, 0xd192e819UL);
+  const SWord32 s1681 = sbv_bv_u32_rotr(s1604, 17);
+  const SWord32 s1682 = sbv_bv_u32_rotr(s1604, 19);
+  const SWord32 s1683 = s1681 ^ s1682;
+  const SWord32 s1684 = sbv_bv_u32_lshr(s1604, 0x0000000aUL);
+  const SWord32 s1685 = s1683 ^ s1684;
+  const SWord32 s1686 = sbv_bv_u32_add(s1409, s1685);
+  const SWord32 s1687 = sbv_bv_u32_rotr(s1097, 7);
+  const SWord32 s1688 = sbv_bv_u32_rotr(s1097, 18);
+  const SWord32 s1689 = s1687 ^ s1688;
+  const SWord32 s1690 = sbv_bv_u32_lshr(s1097, 0x00000003UL);
+  const SWord32 s1691 = s1689 ^ s1690;
+  const SWord32 s1692 = sbv_bv_u32_add(s1686, s1691);
+  const SWord32 s1693 = sbv_bv_u32_add(s1069, s1692);
+  const SWord32 s1694 = sbv_bv_u32_add(s1680, s1693);
+  const SWord32 s1695 = sbv_bv_u32_add(s1645, s1694);
+  const SWord32 s1696 = sbv_bv_u32_rotr(s1695, 6);
+  const SWord32 s1697 = sbv_bv_u32_rotr(s1695, 11);
+  const SWord32 s1698 = s1696 ^ s1697;
+  const SWord32 s1699 = sbv_bv_u32_rotr(s1695, 25);
+  const SWord32 s1700 = s1698 ^ s1699;
+  const SWord32 s1701 = sbv_bv_u32_add(s1578, s1700);
+  const SWord32 s1702 = s1634 & s1695;
+  const SWord32 s1703 = ~s1695;
+  const SWord32 s1704 = s1606 & s1703;
+  const SWord32 s1705 = s1702 ^ s1704;
+  const SWord32 s1706 = sbv_bv_u32_add(s1701, s1705);
+  const SWord32 s1708 = sbv_bv_u32_add(s1706, 0xd6990624UL);
+  const SWord32 s1709 = sbv_bv_u32_rotr(s1632, 17);
+  const SWord32 s1710 = sbv_bv_u32_rotr(s1632, 19);
+  const SWord32 s1711 = s1709 ^ s1710;
+  const SWord32 s1712 = sbv_bv_u32_lshr(s1632, 0x0000000aUL);
+  const SWord32 s1713 = s1711 ^ s1712;
+  const SWord32 s1714 = sbv_bv_u32_add(s1437, s1713);
+  const SWord32 s1715 = sbv_bv_u32_rotr(s1125, 7);
+  const SWord32 s1716 = sbv_bv_u32_rotr(s1125, 18);
+  const SWord32 s1717 = s1715 ^ s1716;
+  const SWord32 s1718 = sbv_bv_u32_lshr(s1125, 0x00000003UL);
+  const SWord32 s1719 = s1717 ^ s1718;
+  const SWord32 s1720 = sbv_bv_u32_add(s1714, s1719);
+  const SWord32 s1721 = sbv_bv_u32_add(s1097, s1720);
+  const SWord32 s1722 = sbv_bv_u32_add(s1708, s1721);
+  const SWord32 s1723 = sbv_bv_u32_add(s1656, s1722);
+  const SWord32 s1724 = sbv_bv_u32_rotr(s1723, 6);
+  const SWord32 s1725 = sbv_bv_u32_rotr(s1723, 11);
+  const SWord32 s1726 = s1724 ^ s1725;
+  const SWord32 s1727 = sbv_bv_u32_rotr(s1723, 25);
+  const SWord32 s1728 = s1726 ^ s1727;
+  const SWord32 s1729 = sbv_bv_u32_add(s1606, s1728);
+  const SWord32 s1730 = s1695 & s1723;
+  const SWord32 s1731 = ~s1723;
+  const SWord32 s1732 = s1634 & s1731;
+  const SWord32 s1733 = s1730 ^ s1732;
+  const SWord32 s1734 = sbv_bv_u32_add(s1729, s1733);
+  const SWord32 s1736 = sbv_bv_u32_add(s1734, 0xf40e3585UL);
+  const SWord32 s1737 = sbv_bv_u32_rotr(s1693, 17);
+  const SWord32 s1738 = sbv_bv_u32_rotr(s1693, 19);
+  const SWord32 s1739 = s1737 ^ s1738;
+  const SWord32 s1740 = sbv_bv_u32_lshr(s1693, 0x0000000aUL);
+  const SWord32 s1741 = s1739 ^ s1740;
+  const SWord32 s1742 = sbv_bv_u32_add(s1465, s1741);
+  const SWord32 s1743 = sbv_bv_u32_rotr(s1153, 7);
+  const SWord32 s1744 = sbv_bv_u32_rotr(s1153, 18);
+  const SWord32 s1745 = s1743 ^ s1744;
+  const SWord32 s1746 = sbv_bv_u32_lshr(s1153, 0x00000003UL);
+  const SWord32 s1747 = s1745 ^ s1746;
+  const SWord32 s1748 = sbv_bv_u32_add(s1742, s1747);
+  const SWord32 s1749 = sbv_bv_u32_add(s1125, s1748);
+  const SWord32 s1750 = sbv_bv_u32_add(s1736, s1749);
+  const SWord32 s1751 = sbv_bv_u32_add(s1667, s1750);
+  const SWord32 s1752 = sbv_bv_u32_rotr(s1751, 6);
+  const SWord32 s1753 = sbv_bv_u32_rotr(s1751, 11);
+  const SWord32 s1754 = s1752 ^ s1753;
+  const SWord32 s1755 = sbv_bv_u32_rotr(s1751, 25);
+  const SWord32 s1756 = s1754 ^ s1755;
+  const SWord32 s1757 = sbv_bv_u32_add(s1634, s1756);
+  const SWord32 s1758 = s1723 & s1751;
+  const SWord32 s1759 = ~s1751;
+  const SWord32 s1760 = s1695 & s1759;
+  const SWord32 s1761 = s1758 ^ s1760;
+  const SWord32 s1762 = sbv_bv_u32_add(s1757, s1761);
+  const SWord32 s1764 = sbv_bv_u32_add(s1762, 0x106aa070UL);
+  const SWord32 s1765 = sbv_bv_u32_rotr(s1721, 17);
+  const SWord32 s1766 = sbv_bv_u32_rotr(s1721, 19);
+  const SWord32 s1767 = s1765 ^ s1766;
+  const SWord32 s1768 = sbv_bv_u32_lshr(s1721, 0x0000000aUL);
+  const SWord32 s1769 = s1767 ^ s1768;
+  const SWord32 s1770 = sbv_bv_u32_add(s1548, s1769);
+  const SWord32 s1771 = sbv_bv_u32_rotr(s1236, 7);
+  const SWord32 s1772 = sbv_bv_u32_rotr(s1236, 18);
+  const SWord32 s1773 = s1771 ^ s1772;
+  const SWord32 s1774 = sbv_bv_u32_lshr(s1236, 0x00000003UL);
+  const SWord32 s1775 = s1773 ^ s1774;
+  const SWord32 s1776 = sbv_bv_u32_add(s1770, s1775);
+  const SWord32 s1777 = sbv_bv_u32_add(s1153, s1776);
+  const SWord32 s1778 = sbv_bv_u32_add(s1764, s1777);
+  const SWord32 s1779 = sbv_bv_u32_rotr(s1667, 2);
+  const SWord32 s1780 = sbv_bv_u32_rotr(s1667, 13);
+  const SWord32 s1781 = s1779 ^ s1780;
+  const SWord32 s1782 = sbv_bv_u32_rotr(s1667, 22);
+  const SWord32 s1783 = s1781 ^ s1782;
+  const SWord32 s1784 = s1656 & s1667;
+  const SWord32 s1785 = s1645 & s1667;
+  const SWord32 s1786 = s1784 ^ s1785;
+  const SWord32 s1787 = s1662 ^ s1786;
+  const SWord32 s1788 = sbv_bv_u32_add(s1783, s1787);
+  const SWord32 s1789 = sbv_bv_u32_add(s1633, s1788);
+  const SWord32 s1790 = sbv_bv_u32_rotr(s1789, 2);
+  const SWord32 s1791 = sbv_bv_u32_rotr(s1789, 13);
+  const SWord32 s1792 = s1790 ^ s1791;
+  const SWord32 s1793 = sbv_bv_u32_rotr(s1789, 22);
+  const SWord32 s1794 = s1792 ^ s1793;
+  const SWord32 s1795 = s1667 & s1789;
+  const SWord32 s1796 = s1656 & s1789;
+  const SWord32 s1797 = s1795 ^ s1796;
+  const SWord32 s1798 = s1784 ^ s1797;
+  const SWord32 s1799 = sbv_bv_u32_add(s1794, s1798);
+  const SWord32 s1800 = sbv_bv_u32_add(s1694, s1799);
+  const SWord32 s1801 = sbv_bv_u32_rotr(s1800, 2);
+  const SWord32 s1802 = sbv_bv_u32_rotr(s1800, 13);
+  const SWord32 s1803 = s1801 ^ s1802;
+  const SWord32 s1804 = sbv_bv_u32_rotr(s1800, 22);
+  const SWord32 s1805 = s1803 ^ s1804;
+  const SWord32 s1806 = s1789 & s1800;
+  const SWord32 s1807 = s1667 & s1800;
+  const SWord32 s1808 = s1806 ^ s1807;
+  const SWord32 s1809 = s1795 ^ s1808;
+  const SWord32 s1810 = sbv_bv_u32_add(s1805, s1809);
+  const SWord32 s1811 = sbv_bv_u32_add(s1722, s1810);
+  const SWord32 s1812 = sbv_bv_u32_rotr(s1811, 2);
+  const SWord32 s1813 = sbv_bv_u32_rotr(s1811, 13);
+  const SWord32 s1814 = s1812 ^ s1813;
+  const SWord32 s1815 = sbv_bv_u32_rotr(s1811, 22);
+  const SWord32 s1816 = s1814 ^ s1815;
+  const SWord32 s1817 = s1800 & s1811;
+  const SWord32 s1818 = s1789 & s1811;
+  const SWord32 s1819 = s1817 ^ s1818;
+  const SWord32 s1820 = s1806 ^ s1819;
+  const SWord32 s1821 = sbv_bv_u32_add(s1816, s1820);
+  const SWord32 s1822 = sbv_bv_u32_add(s1750, s1821);
+  const SWord32 s1823 = sbv_bv_u32_rotr(s1822, 2);
+  const SWord32 s1824 = sbv_bv_u32_rotr(s1822, 13);
+  const SWord32 s1825 = s1823 ^ s1824;
+  const SWord32 s1826 = sbv_bv_u32_rotr(s1822, 22);
+  const SWord32 s1827 = s1825 ^ s1826;
+  const SWord32 s1828 = s1811 & s1822;
+  const SWord32 s1829 = s1800 & s1822;
+  const SWord32 s1830 = s1828 ^ s1829;
+  const SWord32 s1831 = s1817 ^ s1830;
+  const SWord32 s1832 = sbv_bv_u32_add(s1827, s1831);
+  const SWord32 s1833 = sbv_bv_u32_add(s1778, s1832);
+  const SWord32 s1834 = sbv_bv_u32_add(s1778, s1789);
+  const SWord32 s1835 = sbv_bv_u32_rotr(s1834, 6);
+  const SWord32 s1836 = sbv_bv_u32_rotr(s1834, 11);
+  const SWord32 s1837 = s1835 ^ s1836;
+  const SWord32 s1838 = sbv_bv_u32_rotr(s1834, 25);
+  const SWord32 s1839 = s1837 ^ s1838;
+  const SWord32 s1840 = sbv_bv_u32_add(s1695, s1839);
+  const SWord32 s1841 = s1751 & s1834;
+  const SWord32 s1842 = ~s1834;
+  const SWord32 s1843 = s1723 & s1842;
+  const SWord32 s1844 = s1841 ^ s1843;
+  const SWord32 s1845 = sbv_bv_u32_add(s1840, s1844);
+  const SWord32 s1847 = sbv_bv_u32_add(s1845, 0x19a4c116UL);
+  const SWord32 s1848 = sbv_bv_u32_rotr(s1749, 17);
+  const SWord32 s1849 = sbv_bv_u32_rotr(s1749, 19);
+  const SWord32 s1850 = s1848 ^ s1849;
+  const SWord32 s1851 = sbv_bv_u32_lshr(s1749, 0x0000000aUL);
+  const SWord32 s1852 = s1850 ^ s1851;
+  const SWord32 s1853 = sbv_bv_u32_add(s1576, s1852);
+  const SWord32 s1854 = sbv_bv_u32_rotr(s1264, 7);
+  const SWord32 s1855 = sbv_bv_u32_rotr(s1264, 18);
+  const SWord32 s1856 = s1854 ^ s1855;
+  const SWord32 s1857 = sbv_bv_u32_lshr(s1264, 0x00000003UL);
+  const SWord32 s1858 = s1856 ^ s1857;
+  const SWord32 s1859 = sbv_bv_u32_add(s1853, s1858);
+  const SWord32 s1860 = sbv_bv_u32_add(s1236, s1859);
+  const SWord32 s1861 = sbv_bv_u32_add(s1847, s1860);
+  const SWord32 s1862 = sbv_bv_u32_add(s1800, s1861);
+  const SWord32 s1863 = sbv_bv_u32_rotr(s1862, 6);
+  const SWord32 s1864 = sbv_bv_u32_rotr(s1862, 11);
+  const SWord32 s1865 = s1863 ^ s1864;
+  const SWord32 s1866 = sbv_bv_u32_rotr(s1862, 25);
+  const SWord32 s1867 = s1865 ^ s1866;
+  const SWord32 s1868 = sbv_bv_u32_add(s1723, s1867);
+  const SWord32 s1869 = s1834 & s1862;
+  const SWord32 s1870 = ~s1862;
+  const SWord32 s1871 = s1751 & s1870;
+  const SWord32 s1872 = s1869 ^ s1871;
+  const SWord32 s1873 = sbv_bv_u32_add(s1868, s1872);
+  const SWord32 s1875 = sbv_bv_u32_add(s1873, 0x1e376c08UL);
+  const SWord32 s1876 = sbv_bv_u32_rotr(s1777, 17);
+  const SWord32 s1877 = sbv_bv_u32_rotr(s1777, 19);
+  const SWord32 s1878 = s1876 ^ s1877;
+  const SWord32 s1879 = sbv_bv_u32_lshr(s1777, 0x0000000aUL);
+  const SWord32 s1880 = s1878 ^ s1879;
+  const SWord32 s1881 = sbv_bv_u32_add(s1604, s1880);
+  const SWord32 s1882 = sbv_bv_u32_rotr(s1292, 7);
+  const SWord32 s1883 = sbv_bv_u32_rotr(s1292, 18);
+  const SWord32 s1884 = s1882 ^ s1883;
+  const SWord32 s1885 = sbv_bv_u32_lshr(s1292, 0x00000003UL);
+  const SWord32 s1886 = s1884 ^ s1885;
+  const SWord32 s1887 = sbv_bv_u32_add(s1881, s1886);
+  const SWord32 s1888 = sbv_bv_u32_add(s1264, s1887);
+  const SWord32 s1889 = sbv_bv_u32_add(s1875, s1888);
+  const SWord32 s1890 = sbv_bv_u32_add(s1811, s1889);
+  const SWord32 s1891 = sbv_bv_u32_rotr(s1890, 6);
+  const SWord32 s1892 = sbv_bv_u32_rotr(s1890, 11);
+  const SWord32 s1893 = s1891 ^ s1892;
+  const SWord32 s1894 = sbv_bv_u32_rotr(s1890, 25);
+  const SWord32 s1895 = s1893 ^ s1894;
+  const SWord32 s1896 = sbv_bv_u32_add(s1751, s1895);
+  const SWord32 s1897 = s1862 & s1890;
+  const SWord32 s1898 = ~s1890;
+  const SWord32 s1899 = s1834 & s1898;
+  const SWord32 s1900 = s1897 ^ s1899;
+  const SWord32 s1901 = sbv_bv_u32_add(s1896, s1900);
+  const SWord32 s1903 = sbv_bv_u32_add(s1901, 0x2748774cUL);
+  const SWord32 s1904 = sbv_bv_u32_rotr(s1860, 17);
+  const SWord32 s1905 = sbv_bv_u32_rotr(s1860, 19);
+  const SWord32 s1906 = s1904 ^ s1905;
+  const SWord32 s1907 = sbv_bv_u32_lshr(s1860, 0x0000000aUL);
+  const SWord32 s1908 = s1906 ^ s1907;
+  const SWord32 s1909 = sbv_bv_u32_add(s1632, s1908);
+  const SWord32 s1910 = sbv_bv_u32_rotr(s1320, 7);
+  const SWord32 s1911 = sbv_bv_u32_rotr(s1320, 18);
+  const SWord32 s1912 = s1910 ^ s1911;
+  const SWord32 s1913 = sbv_bv_u32_lshr(s1320, 0x00000003UL);
+  const SWord32 s1914 = s1912 ^ s1913;
+  const SWord32 s1915 = sbv_bv_u32_add(s1909, s1914);
+  const SWord32 s1916 = sbv_bv_u32_add(s1292, s1915);
+  const SWord32 s1917 = sbv_bv_u32_add(s1903, s1916);
+  const SWord32 s1918 = sbv_bv_u32_add(s1822, s1917);
+  const SWord32 s1919 = sbv_bv_u32_rotr(s1918, 6);
+  const SWord32 s1920 = sbv_bv_u32_rotr(s1918, 11);
+  const SWord32 s1921 = s1919 ^ s1920;
+  const SWord32 s1922 = sbv_bv_u32_rotr(s1918, 25);
+  const SWord32 s1923 = s1921 ^ s1922;
+  const SWord32 s1924 = sbv_bv_u32_add(s1834, s1923);
+  const SWord32 s1925 = s1890 & s1918;
+  const SWord32 s1926 = ~s1918;
+  const SWord32 s1927 = s1862 & s1926;
+  const SWord32 s1928 = s1925 ^ s1927;
+  const SWord32 s1929 = sbv_bv_u32_add(s1924, s1928);
+  const SWord32 s1931 = sbv_bv_u32_add(s1929, 0x34b0bcb5UL);
+  const SWord32 s1932 = sbv_bv_u32_rotr(s1888, 17);
+  const SWord32 s1933 = sbv_bv_u32_rotr(s1888, 19);
+  const SWord32 s1934 = s1932 ^ s1933;
+  const SWord32 s1935 = sbv_bv_u32_lshr(s1888, 0x0000000aUL);
+  const SWord32 s1936 = s1934 ^ s1935;
+  const SWord32 s1937 = sbv_bv_u32_add(s1693, s1936);
+  const SWord32 s1938 = sbv_bv_u32_rotr(s1381, 7);
+  const SWord32 s1939 = sbv_bv_u32_rotr(s1381, 18);
+  const SWord32 s1940 = s1938 ^ s1939;
+  const SWord32 s1941 = sbv_bv_u32_lshr(s1381, 0x00000003UL);
+  const SWord32 s1942 = s1940 ^ s1941;
+  const SWord32 s1943 = sbv_bv_u32_add(s1937, s1942);
+  const SWord32 s1944 = sbv_bv_u32_add(s1320, s1943);
+  const SWord32 s1945 = sbv_bv_u32_add(s1931, s1944);
+  const SWord32 s1946 = sbv_bv_u32_add(s1833, s1945);
+  const SWord32 s1947 = sbv_bv_u32_rotr(s1833, 2);
+  const SWord32 s1948 = sbv_bv_u32_rotr(s1833, 13);
+  const SWord32 s1949 = s1947 ^ s1948;
+  const SWord32 s1950 = sbv_bv_u32_rotr(s1833, 22);
+  const SWord32 s1951 = s1949 ^ s1950;
+  const SWord32 s1952 = s1822 & s1833;
+  const SWord32 s1953 = s1811 & s1833;
+  const SWord32 s1954 = s1952 ^ s1953;
+  const SWord32 s1955 = s1828 ^ s1954;
+  const SWord32 s1956 = sbv_bv_u32_add(s1951, s1955);
+  const SWord32 s1957 = sbv_bv_u32_add(s1861, s1956);
+  const SWord32 s1958 = sbv_bv_u32_rotr(s1957, 2);
+  const SWord32 s1959 = sbv_bv_u32_rotr(s1957, 13);
+  const SWord32 s1960 = s1958 ^ s1959;
+  const SWord32 s1961 = sbv_bv_u32_rotr(s1957, 22);
+  const SWord32 s1962 = s1960 ^ s1961;
+  const SWord32 s1963 = s1833 & s1957;
+  const SWord32 s1964 = s1822 & s1957;
+  const SWord32 s1965 = s1963 ^ s1964;
+  const SWord32 s1966 = s1952 ^ s1965;
+  const SWord32 s1967 = sbv_bv_u32_add(s1962, s1966);
+  const SWord32 s1968 = sbv_bv_u32_add(s1889, s1967);
+  const SWord32 s1969 = sbv_bv_u32_rotr(s1968, 2);
+  const SWord32 s1970 = sbv_bv_u32_rotr(s1968, 13);
+  const SWord32 s1971 = s1969 ^ s1970;
+  const SWord32 s1972 = sbv_bv_u32_rotr(s1968, 22);
+  const SWord32 s1973 = s1971 ^ s1972;
+  const SWord32 s1974 = s1957 & s1968;
+  const SWord32 s1975 = s1833 & s1968;
+  const SWord32 s1976 = s1974 ^ s1975;
+  const SWord32 s1977 = s1963 ^ s1976;
+  const SWord32 s1978 = sbv_bv_u32_add(s1973, s1977);
+  const SWord32 s1979 = sbv_bv_u32_add(s1917, s1978);
+  const SWord32 s1980 = sbv_bv_u32_rotr(s1946, 6);
+  const SWord32 s1981 = sbv_bv_u32_rotr(s1946, 11);
+  const SWord32 s1982 = s1980 ^ s1981;
+  const SWord32 s1983 = sbv_bv_u32_rotr(s1946, 25);
+  const SWord32 s1984 = s1982 ^ s1983;
+  const SWord32 s1985 = sbv_bv_u32_add(s1862, s1984);
+  const SWord32 s1986 = s1918 & s1946;
+  const SWord32 s1987 = ~s1946;
+  const SWord32 s1988 = s1890 & s1987;
+  const SWord32 s1989 = s1986 ^ s1988;
+  const SWord32 s1990 = sbv_bv_u32_add(s1985, s1989);
+  const SWord32 s1992 = sbv_bv_u32_add(s1990, 0x391c0cb3UL);
+  const SWord32 s1993 = sbv_bv_u32_rotr(s1916, 17);
+  const SWord32 s1994 = sbv_bv_u32_rotr(s1916, 19);
+  const SWord32 s1995 = s1993 ^ s1994;
+  const SWord32 s1996 = sbv_bv_u32_lshr(s1916, 0x0000000aUL);
+  const SWord32 s1997 = s1995 ^ s1996;
+  const SWord32 s1998 = sbv_bv_u32_add(s1721, s1997);
+  const SWord32 s1999 = sbv_bv_u32_rotr(s1409, 7);
+  const SWord32 s2000 = sbv_bv_u32_rotr(s1409, 18);
+  const SWord32 s2001 = s1999 ^ s2000;
+  const SWord32 s2002 = sbv_bv_u32_lshr(s1409, 0x00000003UL);
+  const SWord32 s2003 = s2001 ^ s2002;
+  const SWord32 s2004 = sbv_bv_u32_add(s1998, s2003);
+  const SWord32 s2005 = sbv_bv_u32_add(s1381, s2004);
+  const SWord32 s2006 = sbv_bv_u32_add(s1992, s2005);
+  const SWord32 s2007 = sbv_bv_u32_add(s1957, s2006);
+  const SWord32 s2008 = sbv_bv_u32_rotr(s2007, 6);
+  const SWord32 s2009 = sbv_bv_u32_rotr(s2007, 11);
+  const SWord32 s2010 = s2008 ^ s2009;
+  const SWord32 s2011 = sbv_bv_u32_rotr(s2007, 25);
+  const SWord32 s2012 = s2010 ^ s2011;
+  const SWord32 s2013 = sbv_bv_u32_add(s1890, s2012);
+  const SWord32 s2014 = s1946 & s2007;
+  const SWord32 s2015 = ~s2007;
+  const SWord32 s2016 = s1918 & s2015;
+  const SWord32 s2017 = s2014 ^ s2016;
+  const SWord32 s2018 = sbv_bv_u32_add(s2013, s2017);
+  const SWord32 s2020 = sbv_bv_u32_add(s2018, 0x4ed8aa4aUL);
+  const SWord32 s2021 = sbv_bv_u32_rotr(s1944, 17);
+  const SWord32 s2022 = sbv_bv_u32_rotr(s1944, 19);
+  const SWord32 s2023 = s2021 ^ s2022;
+  const SWord32 s2024 = sbv_bv_u32_lshr(s1944, 0x0000000aUL);
+  const SWord32 s2025 = s2023 ^ s2024;
+  const SWord32 s2026 = sbv_bv_u32_add(s1749, s2025);
+  const SWord32 s2027 = sbv_bv_u32_rotr(s1437, 7);
+  const SWord32 s2028 = sbv_bv_u32_rotr(s1437, 18);
+  const SWord32 s2029 = s2027 ^ s2028;
+  const SWord32 s2030 = sbv_bv_u32_lshr(s1437, 0x00000003UL);
+  const SWord32 s2031 = s2029 ^ s2030;
+  const SWord32 s2032 = sbv_bv_u32_add(s2026, s2031);
+  const SWord32 s2033 = sbv_bv_u32_add(s1409, s2032);
+  const SWord32 s2034 = sbv_bv_u32_add(s2020, s2033);
+  const SWord32 s2035 = sbv_bv_u32_add(s1968, s2034);
+  const SWord32 s2036 = sbv_bv_u32_rotr(s2035, 6);
+  const SWord32 s2037 = sbv_bv_u32_rotr(s2035, 11);
+  const SWord32 s2038 = s2036 ^ s2037;
+  const SWord32 s2039 = sbv_bv_u32_rotr(s2035, 25);
+  const SWord32 s2040 = s2038 ^ s2039;
+  const SWord32 s2041 = sbv_bv_u32_add(s1918, s2040);
+  const SWord32 s2042 = s2007 & s2035;
+  const SWord32 s2043 = ~s2035;
+  const SWord32 s2044 = s1946 & s2043;
+  const SWord32 s2045 = s2042 ^ s2044;
+  const SWord32 s2046 = sbv_bv_u32_add(s2041, s2045);
+  const SWord32 s2048 = sbv_bv_u32_add(s2046, 0x5b9cca4fUL);
+  const SWord32 s2049 = sbv_bv_u32_rotr(s2005, 17);
+  const SWord32 s2050 = sbv_bv_u32_rotr(s2005, 19);
+  const SWord32 s2051 = s2049 ^ s2050;
+  const SWord32 s2052 = sbv_bv_u32_lshr(s2005, 0x0000000aUL);
+  const SWord32 s2053 = s2051 ^ s2052;
+  const SWord32 s2054 = sbv_bv_u32_add(s1777, s2053);
+  const SWord32 s2055 = sbv_bv_u32_rotr(s1465, 7);
+  const SWord32 s2056 = sbv_bv_u32_rotr(s1465, 18);
+  const SWord32 s2057 = s2055 ^ s2056;
+  const SWord32 s2058 = sbv_bv_u32_lshr(s1465, 0x00000003UL);
+  const SWord32 s2059 = s2057 ^ s2058;
+  const SWord32 s2060 = sbv_bv_u32_add(s2054, s2059);
+  const SWord32 s2061 = sbv_bv_u32_add(s1437, s2060);
+  const SWord32 s2062 = sbv_bv_u32_add(s2048, s2061);
+  const SWord32 s2063 = sbv_bv_u32_add(s1979, s2062);
+  const SWord32 s2064 = sbv_bv_u32_rotr(s2063, 6);
+  const SWord32 s2065 = sbv_bv_u32_rotr(s2063, 11);
+  const SWord32 s2066 = s2064 ^ s2065;
+  const SWord32 s2067 = sbv_bv_u32_rotr(s2063, 25);
+  const SWord32 s2068 = s2066 ^ s2067;
+  const SWord32 s2069 = sbv_bv_u32_add(s1946, s2068);
+  const SWord32 s2070 = s2035 & s2063;
+  const SWord32 s2071 = ~s2063;
+  const SWord32 s2072 = s2007 & s2071;
+  const SWord32 s2073 = s2070 ^ s2072;
+  const SWord32 s2074 = sbv_bv_u32_add(s2069, s2073);
+  const SWord32 s2076 = sbv_bv_u32_add(s2074, 0x682e6ff3UL);
+  const SWord32 s2077 = sbv_bv_u32_rotr(s2033, 17);
+  const SWord32 s2078 = sbv_bv_u32_rotr(s2033, 19);
+  const SWord32 s2079 = s2077 ^ s2078;
+  const SWord32 s2080 = sbv_bv_u32_lshr(s2033, 0x0000000aUL);
+  const SWord32 s2081 = s2079 ^ s2080;
+  const SWord32 s2082 = sbv_bv_u32_add(s1860, s2081);
+  const SWord32 s2083 = sbv_bv_u32_rotr(s1548, 7);
+  const SWord32 s2084 = sbv_bv_u32_rotr(s1548, 18);
+  const SWord32 s2085 = s2083 ^ s2084;
+  const SWord32 s2086 = sbv_bv_u32_lshr(s1548, 0x00000003UL);
+  const SWord32 s2087 = s2085 ^ s2086;
+  const SWord32 s2088 = sbv_bv_u32_add(s2082, s2087);
+  const SWord32 s2089 = sbv_bv_u32_add(s1465, s2088);
+  const SWord32 s2090 = sbv_bv_u32_add(s2076, s2089);
+  const SWord32 s2091 = sbv_bv_u32_rotr(s1979, 2);
+  const SWord32 s2092 = sbv_bv_u32_rotr(s1979, 13);
+  const SWord32 s2093 = s2091 ^ s2092;
+  const SWord32 s2094 = sbv_bv_u32_rotr(s1979, 22);
+  const SWord32 s2095 = s2093 ^ s2094;
+  const SWord32 s2096 = s1968 & s1979;
+  const SWord32 s2097 = s1957 & s1979;
+  const SWord32 s2098 = s2096 ^ s2097;
+  const SWord32 s2099 = s1974 ^ s2098;
+  const SWord32 s2100 = sbv_bv_u32_add(s2095, s2099);
+  const SWord32 s2101 = sbv_bv_u32_add(s1945, s2100);
+  const SWord32 s2102 = sbv_bv_u32_rotr(s2101, 2);
+  const SWord32 s2103 = sbv_bv_u32_rotr(s2101, 13);
+  const SWord32 s2104 = s2102 ^ s2103;
+  const SWord32 s2105 = sbv_bv_u32_rotr(s2101, 22);
+  const SWord32 s2106 = s2104 ^ s2105;
+  const SWord32 s2107 = s1979 & s2101;
+  const SWord32 s2108 = s1968 & s2101;
+  const SWord32 s2109 = s2107 ^ s2108;
+  const SWord32 s2110 = s2096 ^ s2109;
+  const SWord32 s2111 = sbv_bv_u32_add(s2106, s2110);
+  const SWord32 s2112 = sbv_bv_u32_add(s2006, s2111);
+  const SWord32 s2113 = sbv_bv_u32_rotr(s2112, 2);
+  const SWord32 s2114 = sbv_bv_u32_rotr(s2112, 13);
+  const SWord32 s2115 = s2113 ^ s2114;
+  const SWord32 s2116 = sbv_bv_u32_rotr(s2112, 22);
+  const SWord32 s2117 = s2115 ^ s2116;
+  const SWord32 s2118 = s2101 & s2112;
+  const SWord32 s2119 = s1979 & s2112;
+  const SWord32 s2120 = s2118 ^ s2119;
+  const SWord32 s2121 = s2107 ^ s2120;
+  const SWord32 s2122 = sbv_bv_u32_add(s2117, s2121);
+  const SWord32 s2123 = sbv_bv_u32_add(s2034, s2122);
+  const SWord32 s2124 = sbv_bv_u32_rotr(s2123, 2);
+  const SWord32 s2125 = sbv_bv_u32_rotr(s2123, 13);
+  const SWord32 s2126 = s2124 ^ s2125;
+  const SWord32 s2127 = sbv_bv_u32_rotr(s2123, 22);
+  const SWord32 s2128 = s2126 ^ s2127;
+  const SWord32 s2129 = s2112 & s2123;
+  const SWord32 s2130 = s2101 & s2123;
+  const SWord32 s2131 = s2129 ^ s2130;
+  const SWord32 s2132 = s2118 ^ s2131;
+  const SWord32 s2133 = sbv_bv_u32_add(s2128, s2132);
+  const SWord32 s2134 = sbv_bv_u32_add(s2062, s2133);
+  const SWord32 s2135 = sbv_bv_u32_rotr(s2134, 2);
+  const SWord32 s2136 = sbv_bv_u32_rotr(s2134, 13);
+  const SWord32 s2137 = s2135 ^ s2136;
+  const SWord32 s2138 = sbv_bv_u32_rotr(s2134, 22);
+  const SWord32 s2139 = s2137 ^ s2138;
+  const SWord32 s2140 = s2123 & s2134;
+  const SWord32 s2141 = s2112 & s2134;
+  const SWord32 s2142 = s2140 ^ s2141;
+  const SWord32 s2143 = s2129 ^ s2142;
+  const SWord32 s2144 = sbv_bv_u32_add(s2139, s2143);
+  const SWord32 s2145 = sbv_bv_u32_add(s2090, s2144);
+  const SWord32 s2146 = sbv_bv_u32_add(s2090, s2101);
+  const SWord32 s2147 = sbv_bv_u32_rotr(s2146, 6);
+  const SWord32 s2148 = sbv_bv_u32_rotr(s2146, 11);
+  const SWord32 s2149 = s2147 ^ s2148;
+  const SWord32 s2150 = sbv_bv_u32_rotr(s2146, 25);
+  const SWord32 s2151 = s2149 ^ s2150;
+  const SWord32 s2152 = sbv_bv_u32_add(s2007, s2151);
+  const SWord32 s2153 = s2063 & s2146;
+  const SWord32 s2154 = ~s2146;
+  const SWord32 s2155 = s2035 & s2154;
+  const SWord32 s2156 = s2153 ^ s2155;
+  const SWord32 s2157 = sbv_bv_u32_add(s2152, s2156);
+  const SWord32 s2159 = sbv_bv_u32_add(s2157, 0x748f82eeUL);
+  const SWord32 s2160 = sbv_bv_u32_rotr(s2061, 17);
+  const SWord32 s2161 = sbv_bv_u32_rotr(s2061, 19);
+  const SWord32 s2162 = s2160 ^ s2161;
+  const SWord32 s2163 = sbv_bv_u32_lshr(s2061, 0x0000000aUL);
+  const SWord32 s2164 = s2162 ^ s2163;
+  const SWord32 s2165 = sbv_bv_u32_add(s1888, s2164);
+  const SWord32 s2166 = sbv_bv_u32_rotr(s1576, 7);
+  const SWord32 s2167 = sbv_bv_u32_rotr(s1576, 18);
+  const SWord32 s2168 = s2166 ^ s2167;
+  const SWord32 s2169 = sbv_bv_u32_lshr(s1576, 0x00000003UL);
+  const SWord32 s2170 = s2168 ^ s2169;
+  const SWord32 s2171 = sbv_bv_u32_add(s2165, s2170);
+  const SWord32 s2172 = sbv_bv_u32_add(s1548, s2171);
+  const SWord32 s2173 = sbv_bv_u32_add(s2159, s2172);
+  const SWord32 s2174 = sbv_bv_u32_add(s2112, s2173);
+  const SWord32 s2175 = sbv_bv_u32_rotr(s2174, 6);
+  const SWord32 s2176 = sbv_bv_u32_rotr(s2174, 11);
+  const SWord32 s2177 = s2175 ^ s2176;
+  const SWord32 s2178 = sbv_bv_u32_rotr(s2174, 25);
+  const SWord32 s2179 = s2177 ^ s2178;
+  const SWord32 s2180 = sbv_bv_u32_add(s2035, s2179);
+  const SWord32 s2181 = s2146 & s2174;
+  const SWord32 s2182 = ~s2174;
+  const SWord32 s2183 = s2063 & s2182;
+  const SWord32 s2184 = s2181 ^ s2183;
+  const SWord32 s2185 = sbv_bv_u32_add(s2180, s2184);
+  const SWord32 s2187 = sbv_bv_u32_add(s2185, 0x78a5636fUL);
+  const SWord32 s2188 = sbv_bv_u32_rotr(s2089, 17);
+  const SWord32 s2189 = sbv_bv_u32_rotr(s2089, 19);
+  const SWord32 s2190 = s2188 ^ s2189;
+  const SWord32 s2191 = sbv_bv_u32_lshr(s2089, 0x0000000aUL);
+  const SWord32 s2192 = s2190 ^ s2191;
+  const SWord32 s2193 = sbv_bv_u32_add(s1916, s2192);
+  const SWord32 s2194 = sbv_bv_u32_rotr(s1604, 7);
+  const SWord32 s2195 = sbv_bv_u32_rotr(s1604, 18);
+  const SWord32 s2196 = s2194 ^ s2195;
+  const SWord32 s2197 = sbv_bv_u32_lshr(s1604, 0x00000003UL);
+  const SWord32 s2198 = s2196 ^ s2197;
+  const SWord32 s2199 = sbv_bv_u32_add(s2193, s2198);
+  const SWord32 s2200 = sbv_bv_u32_add(s1576, s2199);
+  const SWord32 s2201 = sbv_bv_u32_add(s2187, s2200);
+  const SWord32 s2202 = sbv_bv_u32_add(s2123, s2201);
+  const SWord32 s2203 = sbv_bv_u32_rotr(s2202, 6);
+  const SWord32 s2204 = sbv_bv_u32_rotr(s2202, 11);
+  const SWord32 s2205 = s2203 ^ s2204;
+  const SWord32 s2206 = sbv_bv_u32_rotr(s2202, 25);
+  const SWord32 s2207 = s2205 ^ s2206;
+  const SWord32 s2208 = sbv_bv_u32_add(s2063, s2207);
+  const SWord32 s2209 = s2174 & s2202;
+  const SWord32 s2210 = ~s2202;
+  const SWord32 s2211 = s2146 & s2210;
+  const SWord32 s2212 = s2209 ^ s2211;
+  const SWord32 s2213 = sbv_bv_u32_add(s2208, s2212);
+  const SWord32 s2215 = sbv_bv_u32_add(s2213, 0x84c87814UL);
+  const SWord32 s2216 = sbv_bv_u32_rotr(s2172, 17);
+  const SWord32 s2217 = sbv_bv_u32_rotr(s2172, 19);
+  const SWord32 s2218 = s2216 ^ s2217;
+  const SWord32 s2219 = sbv_bv_u32_lshr(s2172, 0x0000000aUL);
+  const SWord32 s2220 = s2218 ^ s2219;
+  const SWord32 s2221 = sbv_bv_u32_add(s1944, s2220);
+  const SWord32 s2222 = sbv_bv_u32_rotr(s1632, 7);
+  const SWord32 s2223 = sbv_bv_u32_rotr(s1632, 18);
+  const SWord32 s2224 = s2222 ^ s2223;
+  const SWord32 s2225 = sbv_bv_u32_lshr(s1632, 0x00000003UL);
+  const SWord32 s2226 = s2224 ^ s2225;
+  const SWord32 s2227 = sbv_bv_u32_add(s2221, s2226);
+  const SWord32 s2228 = sbv_bv_u32_add(s1604, s2227);
+  const SWord32 s2229 = sbv_bv_u32_add(s2215, s2228);
+  const SWord32 s2230 = sbv_bv_u32_add(s2134, s2229);
+  const SWord32 s2231 = sbv_bv_u32_rotr(s2230, 6);
+  const SWord32 s2232 = sbv_bv_u32_rotr(s2230, 11);
+  const SWord32 s2233 = s2231 ^ s2232;
+  const SWord32 s2234 = sbv_bv_u32_rotr(s2230, 25);
+  const SWord32 s2235 = s2233 ^ s2234;
+  const SWord32 s2236 = sbv_bv_u32_add(s2146, s2235);
+  const SWord32 s2237 = s2202 & s2230;
+  const SWord32 s2238 = ~s2230;
+  const SWord32 s2239 = s2174 & s2238;
+  const SWord32 s2240 = s2237 ^ s2239;
+  const SWord32 s2241 = sbv_bv_u32_add(s2236, s2240);
+  const SWord32 s2243 = sbv_bv_u32_add(s2241, 0x8cc70208UL);
+  const SWord32 s2244 = sbv_bv_u32_rotr(s2200, 17);
+  const SWord32 s2245 = sbv_bv_u32_rotr(s2200, 19);
+  const SWord32 s2246 = s2244 ^ s2245;
+  const SWord32 s2247 = sbv_bv_u32_lshr(s2200, 0x0000000aUL);
+  const SWord32 s2248 = s2246 ^ s2247;
+  const SWord32 s2249 = sbv_bv_u32_add(s2005, s2248);
+  const SWord32 s2250 = sbv_bv_u32_rotr(s1693, 7);
+  const SWord32 s2251 = sbv_bv_u32_rotr(s1693, 18);
+  const SWord32 s2252 = s2250 ^ s2251;
+  const SWord32 s2253 = sbv_bv_u32_lshr(s1693, 0x00000003UL);
+  const SWord32 s2254 = s2252 ^ s2253;
+  const SWord32 s2255 = sbv_bv_u32_add(s2249, s2254);
+  const SWord32 s2256 = sbv_bv_u32_add(s1632, s2255);
+  const SWord32 s2257 = sbv_bv_u32_add(s2243, s2256);
+  const SWord32 s2258 = sbv_bv_u32_add(s2145, s2257);
+  const SWord32 s2259 = sbv_bv_u32_rotr(s2145, 2);
+  const SWord32 s2260 = sbv_bv_u32_rotr(s2145, 13);
+  const SWord32 s2261 = s2259 ^ s2260;
+  const SWord32 s2262 = sbv_bv_u32_rotr(s2145, 22);
+  const SWord32 s2263 = s2261 ^ s2262;
+  const SWord32 s2264 = s2134 & s2145;
+  const SWord32 s2265 = s2123 & s2145;
+  const SWord32 s2266 = s2264 ^ s2265;
+  const SWord32 s2267 = s2140 ^ s2266;
+  const SWord32 s2268 = sbv_bv_u32_add(s2263, s2267);
+  const SWord32 s2269 = sbv_bv_u32_add(s2173, s2268);
+  const SWord32 s2270 = sbv_bv_u32_rotr(s2269, 2);
+  const SWord32 s2271 = sbv_bv_u32_rotr(s2269, 13);
+  const SWord32 s2272 = s2270 ^ s2271;
+  const SWord32 s2273 = sbv_bv_u32_rotr(s2269, 22);
+  const SWord32 s2274 = s2272 ^ s2273;
+  const SWord32 s2275 = s2145 & s2269;
+  const SWord32 s2276 = s2134 & s2269;
+  const SWord32 s2277 = s2275 ^ s2276;
+  const SWord32 s2278 = s2264 ^ s2277;
+  const SWord32 s2279 = sbv_bv_u32_add(s2274, s2278);
+  const SWord32 s2280 = sbv_bv_u32_add(s2201, s2279);
+  const SWord32 s2281 = sbv_bv_u32_rotr(s2280, 2);
+  const SWord32 s2282 = sbv_bv_u32_rotr(s2280, 13);
+  const SWord32 s2283 = s2281 ^ s2282;
+  const SWord32 s2284 = sbv_bv_u32_rotr(s2280, 22);
+  const SWord32 s2285 = s2283 ^ s2284;
+  const SWord32 s2286 = s2269 & s2280;
+  const SWord32 s2287 = s2145 & s2280;
+  const SWord32 s2288 = s2286 ^ s2287;
+  const SWord32 s2289 = s2275 ^ s2288;
+  const SWord32 s2290 = sbv_bv_u32_add(s2285, s2289);
+  const SWord32 s2291 = sbv_bv_u32_add(s2229, s2290);
+  const SWord32 s2292 = sbv_bv_u32_rotr(s2258, 6);
+  const SWord32 s2293 = sbv_bv_u32_rotr(s2258, 11);
+  const SWord32 s2294 = s2292 ^ s2293;
+  const SWord32 s2295 = sbv_bv_u32_rotr(s2258, 25);
+  const SWord32 s2296 = s2294 ^ s2295;
+  const SWord32 s2297 = sbv_bv_u32_add(s2174, s2296);
+  const SWord32 s2298 = s2230 & s2258;
+  const SWord32 s2299 = ~s2258;
+  const SWord32 s2300 = s2202 & s2299;
+  const SWord32 s2301 = s2298 ^ s2300;
+  const SWord32 s2302 = sbv_bv_u32_add(s2297, s2301);
+  const SWord32 s2304 = sbv_bv_u32_add(s2302, 0x90befffaUL);
+  const SWord32 s2305 = sbv_bv_u32_rotr(s2228, 17);
+  const SWord32 s2306 = sbv_bv_u32_rotr(s2228, 19);
+  const SWord32 s2307 = s2305 ^ s2306;
+  const SWord32 s2308 = sbv_bv_u32_lshr(s2228, 0x0000000aUL);
+  const SWord32 s2309 = s2307 ^ s2308;
+  const SWord32 s2310 = sbv_bv_u32_add(s2033, s2309);
+  const SWord32 s2311 = sbv_bv_u32_rotr(s1721, 7);
+  const SWord32 s2312 = sbv_bv_u32_rotr(s1721, 18);
+  const SWord32 s2313 = s2311 ^ s2312;
+  const SWord32 s2314 = sbv_bv_u32_lshr(s1721, 0x00000003UL);
+  const SWord32 s2315 = s2313 ^ s2314;
+  const SWord32 s2316 = sbv_bv_u32_add(s2310, s2315);
+  const SWord32 s2317 = sbv_bv_u32_add(s1693, s2316);
+  const SWord32 s2318 = sbv_bv_u32_add(s2304, s2317);
+  const SWord32 s2319 = sbv_bv_u32_add(s2269, s2318);
+  const SWord32 s2320 = sbv_bv_u32_rotr(s2319, 6);
+  const SWord32 s2321 = sbv_bv_u32_rotr(s2319, 11);
+  const SWord32 s2322 = s2320 ^ s2321;
+  const SWord32 s2323 = sbv_bv_u32_rotr(s2319, 25);
+  const SWord32 s2324 = s2322 ^ s2323;
+  const SWord32 s2325 = sbv_bv_u32_add(s2202, s2324);
+  const SWord32 s2326 = s2258 & s2319;
+  const SWord32 s2327 = ~s2319;
+  const SWord32 s2328 = s2230 & s2327;
+  const SWord32 s2329 = s2326 ^ s2328;
+  const SWord32 s2330 = sbv_bv_u32_add(s2325, s2329);
+  const SWord32 s2332 = sbv_bv_u32_add(s2330, 0xa4506cebUL);
+  const SWord32 s2333 = sbv_bv_u32_rotr(s2256, 17);
+  const SWord32 s2334 = sbv_bv_u32_rotr(s2256, 19);
+  const SWord32 s2335 = s2333 ^ s2334;
+  const SWord32 s2336 = sbv_bv_u32_lshr(s2256, 0x0000000aUL);
+  const SWord32 s2337 = s2335 ^ s2336;
+  const SWord32 s2338 = sbv_bv_u32_add(s2061, s2337);
+  const SWord32 s2339 = sbv_bv_u32_rotr(s1749, 7);
+  const SWord32 s2340 = sbv_bv_u32_rotr(s1749, 18);
+  const SWord32 s2341 = s2339 ^ s2340;
+  const SWord32 s2342 = sbv_bv_u32_lshr(s1749, 0x00000003UL);
+  const SWord32 s2343 = s2341 ^ s2342;
+  const SWord32 s2344 = sbv_bv_u32_add(s2338, s2343);
+  const SWord32 s2345 = sbv_bv_u32_add(s1721, s2344);
+  const SWord32 s2346 = sbv_bv_u32_add(s2332, s2345);
+  const SWord32 s2347 = sbv_bv_u32_add(s2280, s2346);
+  const SWord32 s2348 = sbv_bv_u32_rotr(s2347, 6);
+  const SWord32 s2349 = sbv_bv_u32_rotr(s2347, 11);
+  const SWord32 s2350 = s2348 ^ s2349;
+  const SWord32 s2351 = sbv_bv_u32_rotr(s2347, 25);
+  const SWord32 s2352 = s2350 ^ s2351;
+  const SWord32 s2353 = sbv_bv_u32_add(s2230, s2352);
+  const SWord32 s2354 = s2319 & s2347;
+  const SWord32 s2355 = ~s2347;
+  const SWord32 s2356 = s2258 & s2355;
+  const SWord32 s2357 = s2354 ^ s2356;
+  const SWord32 s2358 = sbv_bv_u32_add(s2353, s2357);
+  const SWord32 s2360 = sbv_bv_u32_add(s2358, 0xbef9a3f7UL);
+  const SWord32 s2361 = sbv_bv_u32_rotr(s2317, 17);
+  const SWord32 s2362 = sbv_bv_u32_rotr(s2317, 19);
+  const SWord32 s2363 = s2361 ^ s2362;
+  const SWord32 s2364 = sbv_bv_u32_lshr(s2317, 0x0000000aUL);
+  const SWord32 s2365 = s2363 ^ s2364;
+  const SWord32 s2366 = sbv_bv_u32_add(s2089, s2365);
+  const SWord32 s2367 = sbv_bv_u32_rotr(s1777, 7);
+  const SWord32 s2368 = sbv_bv_u32_rotr(s1777, 18);
+  const SWord32 s2369 = s2367 ^ s2368;
+  const SWord32 s2370 = sbv_bv_u32_lshr(s1777, 0x00000003UL);
+  const SWord32 s2371 = s2369 ^ s2370;
+  const SWord32 s2372 = sbv_bv_u32_add(s2366, s2371);
+  const SWord32 s2373 = sbv_bv_u32_add(s1749, s2372);
+  const SWord32 s2374 = sbv_bv_u32_add(s2360, s2373);
+  const SWord32 s2375 = sbv_bv_u32_add(s2291, s2374);
+  const SWord32 s2376 = sbv_bv_u32_rotr(s2375, 6);
+  const SWord32 s2377 = sbv_bv_u32_rotr(s2375, 11);
+  const SWord32 s2378 = s2376 ^ s2377;
+  const SWord32 s2379 = sbv_bv_u32_rotr(s2375, 25);
+  const SWord32 s2380 = s2378 ^ s2379;
+  const SWord32 s2381 = sbv_bv_u32_add(s2258, s2380);
+  const SWord32 s2382 = s2347 & s2375;
+  const SWord32 s2383 = ~s2375;
+  const SWord32 s2384 = s2319 & s2383;
+  const SWord32 s2385 = s2382 ^ s2384;
+  const SWord32 s2386 = sbv_bv_u32_add(s2381, s2385);
+  const SWord32 s2388 = sbv_bv_u32_add(s2386, 0xc67178f2UL);
+  const SWord32 s2389 = sbv_bv_u32_rotr(s2345, 17);
+  const SWord32 s2390 = sbv_bv_u32_rotr(s2345, 19);
+  const SWord32 s2391 = s2389 ^ s2390;
+  const SWord32 s2392 = sbv_bv_u32_lshr(s2345, 0x0000000aUL);
+  const SWord32 s2393 = s2391 ^ s2392;
+  const SWord32 s2394 = sbv_bv_u32_add(s2172, s2393);
+  const SWord32 s2395 = sbv_bv_u32_rotr(s1860, 7);
+  const SWord32 s2396 = sbv_bv_u32_rotr(s1860, 18);
+  const SWord32 s2397 = s2395 ^ s2396;
+  const SWord32 s2398 = sbv_bv_u32_lshr(s1860, 0x00000003UL);
+  const SWord32 s2399 = s2397 ^ s2398;
+  const SWord32 s2400 = sbv_bv_u32_add(s2394, s2399);
+  const SWord32 s2401 = sbv_bv_u32_add(s1777, s2400);
+  const SWord32 s2402 = sbv_bv_u32_add(s2388, s2401);
+  const SWord32 s2403 = sbv_bv_u32_rotr(s2291, 2);
+  const SWord32 s2404 = sbv_bv_u32_rotr(s2291, 13);
+  const SWord32 s2405 = s2403 ^ s2404;
+  const SWord32 s2406 = sbv_bv_u32_rotr(s2291, 22);
+  const SWord32 s2407 = s2405 ^ s2406;
+  const SWord32 s2408 = s2280 & s2291;
+  const SWord32 s2409 = s2269 & s2291;
+  const SWord32 s2410 = s2408 ^ s2409;
+  const SWord32 s2411 = s2286 ^ s2410;
+  const SWord32 s2412 = sbv_bv_u32_add(s2407, s2411);
+  const SWord32 s2413 = sbv_bv_u32_add(s2257, s2412);
+  const SWord32 s2414 = sbv_bv_u32_rotr(s2413, 2);
+  const SWord32 s2415 = sbv_bv_u32_rotr(s2413, 13);
+  const SWord32 s2416 = s2414 ^ s2415;
+  const SWord32 s2417 = sbv_bv_u32_rotr(s2413, 22);
+  const SWord32 s2418 = s2416 ^ s2417;
+  const SWord32 s2419 = s2291 & s2413;
+  const SWord32 s2420 = s2280 & s2413;
+  const SWord32 s2421 = s2419 ^ s2420;
+  const SWord32 s2422 = s2408 ^ s2421;
+  const SWord32 s2423 = sbv_bv_u32_add(s2418, s2422);
+  const SWord32 s2424 = sbv_bv_u32_add(s2318, s2423);
+  const SWord32 s2425 = sbv_bv_u32_rotr(s2424, 2);
+  const SWord32 s2426 = sbv_bv_u32_rotr(s2424, 13);
+  const SWord32 s2427 = s2425 ^ s2426;
+  const SWord32 s2428 = sbv_bv_u32_rotr(s2424, 22);
+  const SWord32 s2429 = s2427 ^ s2428;
+  const SWord32 s2430 = s2413 & s2424;
+  const SWord32 s2431 = s2291 & s2424;
+  const SWord32 s2432 = s2430 ^ s2431;
+  const SWord32 s2433 = s2419 ^ s2432;
+  const SWord32 s2434 = sbv_bv_u32_add(s2429, s2433);
+  const SWord32 s2435 = sbv_bv_u32_add(s2346, s2434);
+  const SWord32 s2436 = sbv_bv_u32_rotr(s2435, 2);
+  const SWord32 s2437 = sbv_bv_u32_rotr(s2435, 13);
+  const SWord32 s2438 = s2436 ^ s2437;
+  const SWord32 s2439 = sbv_bv_u32_rotr(s2435, 22);
+  const SWord32 s2440 = s2438 ^ s2439;
+  const SWord32 s2441 = s2424 & s2435;
+  const SWord32 s2442 = s2413 & s2435;
+  const SWord32 s2443 = s2441 ^ s2442;
+  const SWord32 s2444 = s2430 ^ s2443;
+  const SWord32 s2445 = sbv_bv_u32_add(s2440, s2444);
+  const SWord32 s2446 = sbv_bv_u32_add(s2374, s2445);
+  const SWord32 s2447 = sbv_bv_u32_rotr(s2446, 2);
+  const SWord32 s2448 = sbv_bv_u32_rotr(s2446, 13);
+  const SWord32 s2449 = s2447 ^ s2448;
+  const SWord32 s2450 = sbv_bv_u32_rotr(s2446, 22);
+  const SWord32 s2451 = s2449 ^ s2450;
+  const SWord32 s2452 = s2435 & s2446;
+  const SWord32 s2453 = s2424 & s2446;
+  const SWord32 s2454 = s2452 ^ s2453;
+  const SWord32 s2455 = s2441 ^ s2454;
+  const SWord32 s2456 = sbv_bv_u32_add(s2451, s2455);
+  const SWord32 s2457 = sbv_bv_u32_add(s2402, s2456);
+  const SWord32 s2458 = sbv_bv_u32_add(s98, s2457);
+  const SWord8  s2459 = sbv_bv_extract_u32_31_24_u8(s2458);
+  const SWord8  s2460 = sbv_bv_extract_u32_23_16_u8(s2458);
+  const SWord8  s2461 = sbv_bv_extract_u32_15_8_u8(s2458);
+  const SWord8  s2462 = sbv_bv_extract_u32_7_0_u8(s2458);
+  const SWord32 s2463 = sbv_bv_u32_add(s104, s2446);
+  const SWord8  s2464 = sbv_bv_extract_u32_31_24_u8(s2463);
+  const SWord8  s2465 = sbv_bv_extract_u32_23_16_u8(s2463);
+  const SWord8  s2466 = sbv_bv_extract_u32_15_8_u8(s2463);
+  const SWord8  s2467 = sbv_bv_extract_u32_7_0_u8(s2463);
+  const SWord32 s2468 = sbv_bv_u32_add(s110, s2435);
+  const SWord8  s2469 = sbv_bv_extract_u32_31_24_u8(s2468);
+  const SWord8  s2470 = sbv_bv_extract_u32_23_16_u8(s2468);
+  const SWord8  s2471 = sbv_bv_extract_u32_15_8_u8(s2468);
+  const SWord8  s2472 = sbv_bv_extract_u32_7_0_u8(s2468);
+  const SWord32 s2473 = sbv_bv_u32_add(s116, s2424);
+  const SWord8  s2474 = sbv_bv_extract_u32_31_24_u8(s2473);
+  const SWord8  s2475 = sbv_bv_extract_u32_23_16_u8(s2473);
+  const SWord8  s2476 = sbv_bv_extract_u32_15_8_u8(s2473);
+  const SWord8  s2477 = sbv_bv_extract_u32_7_0_u8(s2473);
+  const SWord32 s2478 = sbv_bv_u32_add(s2402, s2413);
+  const SWord32 s2479 = sbv_bv_u32_add(s101, s2478);
+  const SWord8  s2480 = sbv_bv_extract_u32_31_24_u8(s2479);
+  const SWord8  s2481 = sbv_bv_extract_u32_23_16_u8(s2479);
+  const SWord8  s2482 = sbv_bv_extract_u32_15_8_u8(s2479);
+  const SWord8  s2483 = sbv_bv_extract_u32_7_0_u8(s2479);
+  const SWord32 s2484 = sbv_bv_u32_add(s107, s2375);
+  const SWord8  s2485 = sbv_bv_extract_u32_31_24_u8(s2484);
+  const SWord8  s2486 = sbv_bv_extract_u32_23_16_u8(s2484);
+  const SWord8  s2487 = sbv_bv_extract_u32_15_8_u8(s2484);
+  const SWord8  s2488 = sbv_bv_extract_u32_7_0_u8(s2484);
+  const SWord32 s2489 = sbv_bv_u32_add(s113, s2347);
+  const SWord8  s2490 = sbv_bv_extract_u32_31_24_u8(s2489);
+  const SWord8  s2491 = sbv_bv_extract_u32_23_16_u8(s2489);
+  const SWord8  s2492 = sbv_bv_extract_u32_15_8_u8(s2489);
+  const SWord8  s2493 = sbv_bv_extract_u32_7_0_u8(s2489);
+  const SWord32 s2494 = sbv_bv_u32_add(s119, s2319);
+  const SWord8  s2495 = sbv_bv_extract_u32_31_24_u8(s2494);
+  const SWord8  s2496 = sbv_bv_extract_u32_23_16_u8(s2494);
+  const SWord8  s2497 = sbv_bv_extract_u32_15_8_u8(s2494);
+  const SWord8  s2498 = sbv_bv_extract_u32_7_0_u8(s2494);
+
+  sbv_output_0[0] = s2459;
+  sbv_output_0[1] = s2460;
+  sbv_output_0[2] = s2461;
+  sbv_output_0[3] = s2462;
+  sbv_output_0[4] = s2464;
+  sbv_output_0[5] = s2465;
+  sbv_output_0[6] = s2466;
+  sbv_output_0[7] = s2467;
+  sbv_output_0[8] = s2469;
+  sbv_output_0[9] = s2470;
+  sbv_output_0[10] = s2471;
+  sbv_output_0[11] = s2472;
+  sbv_output_0[12] = s2474;
+  sbv_output_0[13] = s2475;
+  sbv_output_0[14] = s2476;
+  sbv_output_0[15] = s2477;
+  sbv_output_0[16] = s2480;
+  sbv_output_0[17] = s2481;
+  sbv_output_0[18] = s2482;
+  sbv_output_0[19] = s2483;
+  sbv_output_0[20] = s2485;
+  sbv_output_0[21] = s2486;
+  sbv_output_0[22] = s2487;
+  sbv_output_0[23] = s2488;
+  sbv_output_0[24] = s2490;
+  sbv_output_0[25] = s2491;
+  sbv_output_0[26] = s2492;
+  sbv_output_0[27] = s2493;
+  sbv_output_0[28] = s2495;
+  sbv_output_0[29] = s2496;
+  sbv_output_0[30] = s2497;
+  sbv_output_0[31] = s2498;
 }
 == END: "sha256HashBlock.c" ==================
diff --git a/SBVTestSuite/GoldFiles/smtFuncUniq_captureConflict.gold b/SBVTestSuite/GoldFiles/smtFuncUniq_captureConflict.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/smtFuncUniq_captureConflict.gold
@@ -0,0 +1,9 @@
+
+*** Data.SBV: Function 'bar @(SBV Integer -> SBV Integer)' defined with conflicting bodies.
+***
+*** Two calls to smtFunction (or related) used the name 'bar @(SBV Integer -> SBV Integer)'
+*** but with different definitions. This would generate conflicting
+*** SMTLib define-fun-rec declarations.
+***
+*** Please use a unique name for each distinct function.
+
diff --git a/SBVTestSuite/GoldFiles/smtFuncUniq_captureTagged.gold b/SBVTestSuite/GoldFiles/smtFuncUniq_captureTagged.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/smtFuncUniq_captureTagged.gold
@@ -0,0 +1,43 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s4 () Int 10)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |bar_two @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger
+[GOOD] (define-fun |bar_two @(SBV Integer -> SBV Integer)| ((l1_s0 Int)) Int
+                                 (let ((l1_s1 2))
+                                 (let ((l1_s2 (+ l1_s0 l1_s1)))
+                                 l1_s2)))
+[GOOD] ; |bar_three @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger
+[GOOD] (define-fun |bar_three @(SBV Integer -> SBV Integer)| ((l1_s0 Int)) Int
+                                 (let ((l1_s1 3))
+                                 (let ((l1_s2 (+ l1_s0 l1_s1)))
+                                 l1_s2)))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Int (|bar_two @(SBV Integer -> SBV Integer)| s0))
+[GOOD] (define-fun s2 () Int (|bar_three @(SBV Integer -> SBV Integer)| s0))
+[GOOD] (define-fun s3 () Int (+ s1 s2))
+[GOOD] (define-fun s5 () Bool (= s3 s4))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s5)
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+
+RESULT:
+Unsatisfiable
diff --git a/SBVTestSuite/GoldFiles/smtFuncUniq_conflict.gold b/SBVTestSuite/GoldFiles/smtFuncUniq_conflict.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/smtFuncUniq_conflict.gold
@@ -0,0 +1,9 @@
+
+*** Data.SBV: Function 'f @(SBV Integer -> SBV Integer)' defined with conflicting bodies.
+***
+*** Two calls to smtFunction (or related) used the name 'f @(SBV Integer -> SBV Integer)'
+*** but with different definitions. This would generate conflicting
+*** SMTLib define-fun-rec declarations.
+***
+*** Please use a unique name for each distinct function.
+
diff --git a/SBVTestSuite/GoldFiles/smtFuncUniq_recursiveConflict.gold b/SBVTestSuite/GoldFiles/smtFuncUniq_recursiveConflict.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/smtFuncUniq_recursiveConflict.gold
@@ -0,0 +1,9 @@
+
+*** Data.SBV: Function 'f @(SBV Integer -> SBV Integer)' defined with conflicting bodies.
+***
+*** Two calls to smtFunction (or related) used the name 'f @(SBV Integer -> SBV Integer)'
+*** but with different definitions. This would generate conflicting
+*** SMTLib define-fun-rec declarations.
+***
+*** Please use a unique name for each distinct function.
+
diff --git a/SBVTestSuite/GoldFiles/smtFuncUniq_recursiveOk.gold b/SBVTestSuite/GoldFiles/smtFuncUniq_recursiveOk.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/smtFuncUniq_recursiveOk.gold
@@ -0,0 +1,131 @@
+[MEASURE] Verifying termination measures for: f @(SBV Integer -> SBV Integer)
+[MEASURE] Checking: f @(SBV Integer -> SBV Integer)
+[MEASURE] f @(SBV Integer -> SBV Integer): barified = "|f @(SBV Integer -> SBV Integer)|"
+[MEASURE] f @(SBV Integer -> SBV Integer): Uninterpreted ops in DAG: [("|f @(SBV Integer -> SBV Integer)|",1)]
+[MEASURE] f @(SBV Integer -> SBV Integer): recursive calls found = 1
+[MEASURE] f @(SBV Integer -> SBV Integer): trying abs arg1
+[MEASURE] replayDAG {f @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s0 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Bool (>= s8 s1))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s9))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] replayDAG {f @(SBV Integer -> SBV Integer)}: replaying 5 node(s)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s2 () Int 1)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int) ; tracks user variable "arg"
+[GOOD] (declare-fun s5 () Int) ; tracks user variable "__internal_sbv_s5"
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (<= s0 s1))
+[GOOD] (define-fun s4 () Int (- s0 s2))
+[GOOD] (define-fun s6 () Int (+ s0 s5))
+[GOOD] (define-fun s7 () Int (ite s3 s1 s6))
+[GOOD] (define-fun s8 () Int (abs s0))
+[GOOD] (define-fun s9 () Int (abs s4))
+[GOOD] (define-fun s10 () Bool (not s3))
+[GOOD] (define-fun s11 () Bool (> s8 s9))
+[GOOD] (define-fun s12 () Bool (=> s10 s11))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert (not s12))
+[SEND] (check-sat)
+[RECV] unsat
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+[MEASURE] f @(SBV Integer -> SBV Integer): abs arg1 -> OK
+[MEASURE] Passed (terminating): f @(SBV Integer -> SBV Integer)
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s1 () Int 0)
+[GOOD] (define-fun s3 () Int 3)
+[GOOD] (define-fun s6 () Int 6)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |f @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger [Recursive]
+[GOOD] (define-fun-rec |f @(SBV Integer -> SBV Integer)| ((l1_s0 Int)) Int
+                                 (let ((l1_s1 0))
+                                 (let ((l1_s3 1))
+                                 (let ((l1_s2 (<= l1_s0 l1_s1)))
+                                 (let ((l1_s4 (- l1_s0 l1_s3)))
+                                 (let ((l1_s5 (|f @(SBV Integer -> SBV Integer)| l1_s4)))
+                                 (let ((l1_s6 (+ l1_s0 l1_s5)))
+                                 (let ((l1_s7 (ite l1_s2 l1_s1 l1_s6)))
+                                 l1_s7))))))))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s2 () Bool (>= s0 s1))
+[GOOD] (define-fun s4 () Bool (<= s0 s3))
+[GOOD] (define-fun s5 () Int (|f @(SBV Integer -> SBV Integer)| s0))
+[GOOD] (define-fun s7 () Bool (= s5 s6))
+[GOOD] (define-fun s8 () Bool (and s4 s7))
+[GOOD] (define-fun s9 () Bool (and s2 s8))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s9)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 3))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+
+RESULT:
+Satisfiable. Model:
+  s0 = 3 :: Integer
diff --git a/SBVTestSuite/GoldFiles/smtFuncUniq_sameOk.gold b/SBVTestSuite/GoldFiles/smtFuncUniq_sameOk.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/smtFuncUniq_sameOk.gold
@@ -0,0 +1,40 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] (define-fun s3 () Int 4)
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () Int)
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] ; --- user defined functions ---
+[GOOD] ; |f @(SBV Integer -> SBV Integer)| :: SInteger -> SInteger
+[GOOD] (define-fun |f @(SBV Integer -> SBV Integer)| ((l1_s0 Int)) Int
+                                 (let ((l1_s1 1))
+                                 (let ((l1_s2 (+ l1_s0 l1_s1)))
+                                 l1_s2)))
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s1 () Int (|f @(SBV Integer -> SBV Integer)| s0))
+[GOOD] (define-fun s2 () Int (+ s1 s1))
+[GOOD] (define-fun s4 () Bool (= s2 s3))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s4)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 1))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+
+RESULT:
+Satisfiable. Model:
+  s0 = 1 :: Integer
diff --git a/SBVTestSuite/GoldFiles/strConcat.gold b/SBVTestSuite/GoldFiles/strConcat.gold
--- a/SBVTestSuite/GoldFiles/strConcat.gold
+++ b/SBVTestSuite/GoldFiles/strConcat.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/strConcatBad.gold b/SBVTestSuite/GoldFiles/strConcatBad.gold
--- a/SBVTestSuite/GoldFiles/strConcatBad.gold
+++ b/SBVTestSuite/GoldFiles/strConcatBad.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/strExamples1.gold b/SBVTestSuite/GoldFiles/strExamples1.gold
--- a/SBVTestSuite/GoldFiles/strExamples1.gold
+++ b/SBVTestSuite/GoldFiles/strExamples1.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/strExamples10.gold b/SBVTestSuite/GoldFiles/strExamples10.gold
--- a/SBVTestSuite/GoldFiles/strExamples10.gold
+++ b/SBVTestSuite/GoldFiles/strExamples10.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
@@ -18,7 +17,7 @@
 [GOOD] ; --- uninterpreted constants ---
 [GOOD] ; --- user defined functions ---
 [GOOD] ; --- assignments ---
-[GOOD] (define-fun s1 () Bool (str.in.re s0 ((_ re.loop 1 3) (str.to.re "ab"))))
+[GOOD] (define-fun s1 () Bool (str.in_re s0 ((_ re.loop 1 3) (str.to_re "ab"))))
 [GOOD] (define-fun s2 () Int (str.len s0))
 [GOOD] (define-fun s4 () Bool (> s2 s3))
 [GOOD] ; --- delayedEqualities ---
diff --git a/SBVTestSuite/GoldFiles/strExamples11.gold b/SBVTestSuite/GoldFiles/strExamples11.gold
--- a/SBVTestSuite/GoldFiles/strExamples11.gold
+++ b/SBVTestSuite/GoldFiles/strExamples11.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/strExamples12.gold b/SBVTestSuite/GoldFiles/strExamples12.gold
--- a/SBVTestSuite/GoldFiles/strExamples12.gold
+++ b/SBVTestSuite/GoldFiles/strExamples12.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/strExamples13.gold b/SBVTestSuite/GoldFiles/strExamples13.gold
--- a/SBVTestSuite/GoldFiles/strExamples13.gold
+++ b/SBVTestSuite/GoldFiles/strExamples13.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/strExamples2.gold b/SBVTestSuite/GoldFiles/strExamples2.gold
--- a/SBVTestSuite/GoldFiles/strExamples2.gold
+++ b/SBVTestSuite/GoldFiles/strExamples2.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has strings, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/strExamples3.gold b/SBVTestSuite/GoldFiles/strExamples3.gold
--- a/SBVTestSuite/GoldFiles/strExamples3.gold
+++ b/SBVTestSuite/GoldFiles/strExamples3.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has strings, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/strExamples4.gold b/SBVTestSuite/GoldFiles/strExamples4.gold
--- a/SBVTestSuite/GoldFiles/strExamples4.gold
+++ b/SBVTestSuite/GoldFiles/strExamples4.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/strExamples5.gold b/SBVTestSuite/GoldFiles/strExamples5.gold
--- a/SBVTestSuite/GoldFiles/strExamples5.gold
+++ b/SBVTestSuite/GoldFiles/strExamples5.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has strings, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/strExamples6.gold b/SBVTestSuite/GoldFiles/strExamples6.gold
--- a/SBVTestSuite/GoldFiles/strExamples6.gold
+++ b/SBVTestSuite/GoldFiles/strExamples6.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has strings, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/strExamples7.gold b/SBVTestSuite/GoldFiles/strExamples7.gold
--- a/SBVTestSuite/GoldFiles/strExamples7.gold
+++ b/SBVTestSuite/GoldFiles/strExamples7.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has strings, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/strExamples8.gold b/SBVTestSuite/GoldFiles/strExamples8.gold
--- a/SBVTestSuite/GoldFiles/strExamples8.gold
+++ b/SBVTestSuite/GoldFiles/strExamples8.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/strExamples9.gold b/SBVTestSuite/GoldFiles/strExamples9.gold
--- a/SBVTestSuite/GoldFiles/strExamples9.gold
+++ b/SBVTestSuite/GoldFiles/strExamples9.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
@@ -18,7 +17,7 @@
 [GOOD] ; --- uninterpreted constants ---
 [GOOD] ; --- user defined functions ---
 [GOOD] ; --- assignments ---
-[GOOD] (define-fun s1 () Bool (str.in.re s0 ((_ re.loop 1 3) (str.to.re "ab"))))
+[GOOD] (define-fun s1 () Bool (str.in_re s0 ((_ re.loop 1 3) (str.to_re "ab"))))
 [GOOD] (define-fun s2 () Int (str.len s0))
 [GOOD] (define-fun s4 () Bool (= s2 s3))
 [GOOD] ; --- delayedEqualities ---
diff --git a/SBVTestSuite/GoldFiles/strIndexOf.gold b/SBVTestSuite/GoldFiles/strIndexOf.gold
--- a/SBVTestSuite/GoldFiles/strIndexOf.gold
+++ b/SBVTestSuite/GoldFiles/strIndexOf.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/strIndexOfBad.gold b/SBVTestSuite/GoldFiles/strIndexOfBad.gold
--- a/SBVTestSuite/GoldFiles/strIndexOfBad.gold
+++ b/SBVTestSuite/GoldFiles/strIndexOfBad.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; external query, using all logics.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/sumBimapPlus.gold b/SBVTestSuite/GoldFiles/sumBimapPlus.gold
--- a/SBVTestSuite/GoldFiles/sumBimapPlus.gold
+++ b/SBVTestSuite/GoldFiles/sumBimapPlus.gold
@@ -9,35 +9,37 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
-[GOOD] (declare-datatypes ((SBVEither 2)) ((par (T1 T2)
-                                           ((left_SBVEither  (get_left_SBVEither  T1))
-                                            (right_SBVEither (get_right_SBVEither T2))))))
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Either
+[GOOD] (declare-datatype Either (par (a b) (
+           (Left (getLeft_1 a))
+           (Right (getRight_1 b))
+       )))
 [GOOD] ; --- literal constants ---
-[GOOD] (define-fun s2 () Int 1)
+[GOOD] (define-fun s3 () Int 1)
 [GOOD] ; --- top level inputs ---
-[GOOD] (declare-fun s0 () (SBVEither Int Int)) ; tracks user variable "x"
+[GOOD] (declare-fun s0 () (Either Int Int)) ; tracks user variable "x"
 [GOOD] ; --- constant tables ---
 [GOOD] ; --- non-constant tables ---
 [GOOD] ; --- uninterpreted constants ---
 [GOOD] ; --- user defined functions ---
 [GOOD] ; --- assignments ---
-[GOOD] (define-fun s1 () Int (get_left_SBVEither s0))
-[GOOD] (define-fun s3 () Int (+ s1 s2))
-[GOOD] (define-fun s4 () (SBVEither Int Int) ((as left_SBVEither (SBVEither Int Int)) s3))
-[GOOD] (define-fun s5 () Int (get_right_SBVEither s0))
-[GOOD] (define-fun s6 () Int (+ s2 s5))
-[GOOD] (define-fun s7 () (SBVEither Int Int) ((as right_SBVEither (SBVEither Int Int)) s6))
-[GOOD] (define-fun s8 () Bool ((_ is (left_SBVEither (Int) (SBVEither Int Int))) s0))
-[GOOD] (define-fun s9 () (SBVEither Int Int) (ite s8 s4 s7))
-[GOOD] (define-fun s10 () Int (get_left_SBVEither s9))
-[GOOD] (define-fun s11 () Int (get_right_SBVEither s9))
-[GOOD] (define-fun s12 () Bool ((_ is (left_SBVEither (Int) (SBVEither Int Int))) s9))
-[GOOD] (define-fun s13 () Int (ite s12 s10 s11))
-[GOOD] (define-fun s14 () Int (ite s8 s1 s5))
-[GOOD] (define-fun s15 () Int (+ s2 s14))
+[GOOD] (define-fun s1 () Bool ((as is-Left Bool) s0))
+[GOOD] (define-fun s2 () Int (getLeft_1 s0))
+[GOOD] (define-fun s4 () Int (+ s2 s3))
+[GOOD] (define-fun s5 () (Either Int Int) ((as Left (Either Int Int)) s4))
+[GOOD] (define-fun s6 () Int (getRight_1 s0))
+[GOOD] (define-fun s7 () Int (+ s3 s6))
+[GOOD] (define-fun s8 () (Either Int Int) ((as Right (Either Int Int)) s7))
+[GOOD] (define-fun s9 () (Either Int Int) (ite s1 s5 s8))
+[GOOD] (define-fun s10 () Bool ((as is-Left Bool) s9))
+[GOOD] (define-fun s11 () Int (getLeft_1 s9))
+[GOOD] (define-fun s12 () Int (getRight_1 s9))
+[GOOD] (define-fun s13 () Int (ite s10 s11 s12))
+[GOOD] (define-fun s14 () Int (ite s1 s2 s6))
+[GOOD] (define-fun s15 () Int (+ s3 s14))
 [GOOD] (define-fun s16 () Bool (= s13 s15))
 [GOOD] ; --- delayedEqualities ---
 [GOOD] ; --- formula ---
@@ -45,8 +47,8 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (left_SBVEither 0)))
+[RECV] ((s0 (Left (- 1))))
 
-MODEL: SMTModel {modelObjectives = [], modelBindings = Nothing, modelAssocs = [("x",Left 0 :: Either Integer Integer)], modelUIFuns = []}
+MODEL: SMTModel {modelObjectives = [], modelBindings = Nothing, modelAssocs = [("x",Left (-1) :: Either Integer Integer)], modelUIFuns = []}
 DONE.*** Solver   : Z3
 *** Exit code: ExitSuccess
diff --git a/SBVTestSuite/GoldFiles/sumEitherSat.gold b/SBVTestSuite/GoldFiles/sumEitherSat.gold
--- a/SBVTestSuite/GoldFiles/sumEitherSat.gold
+++ b/SBVTestSuite/GoldFiles/sumEitherSat.gold
@@ -9,34 +9,36 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
-[GOOD] (declare-datatypes ((SBVEither 2)) ((par (T1 T2)
-                                           ((left_SBVEither  (get_left_SBVEither  T1))
-                                            (right_SBVEither (get_right_SBVEither T2))))))
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Either
+[GOOD] (declare-datatype Either (par (a b) (
+           (Left (getLeft_1 a))
+           (Right (getRight_1 b))
+       )))
 [GOOD] ; --- literal constants ---
-[GOOD] (define-fun s2 () Int 0)
+[GOOD] (define-fun s3 () Int 0)
 [GOOD] ; --- top level inputs ---
-[GOOD] (declare-fun s0 () (SBVEither Int Bool)) ; tracks user variable "x"
+[GOOD] (declare-fun s0 () (Either Int Bool)) ; tracks user variable "x"
 [GOOD] ; --- constant tables ---
 [GOOD] ; --- non-constant tables ---
 [GOOD] ; --- uninterpreted constants ---
 [GOOD] ; --- user defined functions ---
 [GOOD] ; --- assignments ---
-[GOOD] (define-fun s1 () Int (get_left_SBVEither s0))
-[GOOD] (define-fun s3 () Bool (> s1 s2))
-[GOOD] (define-fun s4 () Bool (get_right_SBVEither s0))
-[GOOD] (define-fun s5 () Bool (not s4))
-[GOOD] (define-fun s6 () Bool ((_ is (left_SBVEither (Int) (SBVEither Int Bool))) s0))
-[GOOD] (define-fun s7 () Bool (ite s6 s3 s5))
+[GOOD] (define-fun s1 () Bool ((as is-Left Bool) s0))
+[GOOD] (define-fun s2 () Int (getLeft_1 s0))
+[GOOD] (define-fun s4 () Bool (> s2 s3))
+[GOOD] (define-fun s5 () Bool (getRight_1 s0))
+[GOOD] (define-fun s6 () Bool (not s5))
+[GOOD] (define-fun s7 () Bool (ite s1 s4 s6))
 [GOOD] ; --- delayedEqualities ---
 [GOOD] ; --- formula ---
 [GOOD] (assert s7)
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (right_SBVEither false)))
+[RECV] ((s0 (Right false)))
 
 MODEL: SMTModel {modelObjectives = [], modelBindings = Nothing, modelAssocs = [("x",Right False :: Either Integer Bool)], modelUIFuns = []}
 DONE.*** Solver   : Z3
diff --git a/SBVTestSuite/GoldFiles/sumLiftEither.gold b/SBVTestSuite/GoldFiles/sumLiftEither.gold
--- a/SBVTestSuite/GoldFiles/sumLiftEither.gold
+++ b/SBVTestSuite/GoldFiles/sumLiftEither.gold
@@ -9,12 +9,14 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
-[GOOD] (declare-datatypes ((SBVEither 2)) ((par (T1 T2)
-                                           ((left_SBVEither  (get_left_SBVEither  T1))
-                                            (right_SBVEither (get_right_SBVEither T2))))))
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Either
+[GOOD] (declare-datatype Either (par (a b) (
+           (Left (getLeft_1 a))
+           (Right (getRight_1 b))
+       )))
 [GOOD] ; --- literal constants ---
 [GOOD] ; --- top level inputs ---
 [GOOD] (declare-fun s0 () Int) ; tracks user variable "i"
@@ -25,16 +27,14 @@
 [GOOD] ; --- uninterpreted constants ---
 [GOOD] ; --- user defined functions ---
 [GOOD] ; --- assignments ---
-[GOOD] (define-fun s2 () (SBVEither Int String) ((as left_SBVEither (SBVEither Int String)) s0))
-[GOOD] (define-fun s3 () Bool ((_ is (left_SBVEither (Int) (SBVEither Int String))) s2))
-[GOOD] (define-fun s4 () Bool (ite s3 true false))
-[GOOD] (define-fun s5 () (SBVEither Int String) ((as right_SBVEither (SBVEither Int String)) s1))
-[GOOD] (define-fun s6 () Bool ((_ is (left_SBVEither (Int) (SBVEither Int String))) s5))
-[GOOD] (define-fun s7 () Bool (ite s6 false true))
+[GOOD] (define-fun s2 () (Either Int String) ((as Left (Either Int String)) s0))
+[GOOD] (define-fun s3 () Bool ((as is-Left Bool) s2))
+[GOOD] (define-fun s4 () (Either Int String) ((as Right (Either Int String)) s1))
+[GOOD] (define-fun s5 () Bool ((as is-Right Bool) s4))
 [GOOD] ; --- delayedEqualities ---
 [GOOD] ; --- formula ---
-[GOOD] (assert s4)
-[GOOD] (assert s7)
+[GOOD] (assert s3)
+[GOOD] (assert s5)
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
diff --git a/SBVTestSuite/GoldFiles/sumLiftMaybe.gold b/SBVTestSuite/GoldFiles/sumLiftMaybe.gold
--- a/SBVTestSuite/GoldFiles/sumLiftMaybe.gold
+++ b/SBVTestSuite/GoldFiles/sumLiftMaybe.gold
@@ -9,14 +9,16 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
-[GOOD] (declare-datatypes ((SBVMaybe 1)) ((par (T)
-                                           ((nothing_SBVMaybe)
-                                            (just_SBVMaybe (get_just_SBVMaybe T))))))
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Maybe
+[GOOD] (declare-datatype Maybe (par (a) (
+           (Nothing)
+           (Just (getJust_1 a))
+       )))
 [GOOD] ; --- literal constants ---
-[GOOD] (define-fun s2 () (SBVMaybe Int) (as nothing_SBVMaybe (SBVMaybe Int)))
+[GOOD] (define-fun s2 () (Maybe Int) (as Nothing (Maybe Int)))
 [GOOD] ; --- top level inputs ---
 [GOOD] (declare-fun s0 () Int) ; tracks user variable "i"
 [GOOD] ; --- constant tables ---
@@ -24,7 +26,7 @@
 [GOOD] ; --- uninterpreted constants ---
 [GOOD] ; --- user defined functions ---
 [GOOD] ; --- assignments ---
-[GOOD] (define-fun s1 () (SBVMaybe Int) ((as just_SBVMaybe (SBVMaybe Int)) s0))
+[GOOD] (define-fun s1 () (Maybe Int) ((as Just (Maybe Int)) s0))
 [GOOD] (define-fun s3 () Bool (distinct s1 s2))
 [GOOD] ; --- delayedEqualities ---
 [GOOD] ; --- formula ---
diff --git a/SBVTestSuite/GoldFiles/sumMaybe.gold b/SBVTestSuite/GoldFiles/sumMaybe.gold
--- a/SBVTestSuite/GoldFiles/sumMaybe.gold
+++ b/SBVTestSuite/GoldFiles/sumMaybe.gold
@@ -9,49 +9,49 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
-[GOOD] (declare-datatypes ((SBVMaybe 1)) ((par (T)
-                                           ((nothing_SBVMaybe)
-                                            (just_SBVMaybe (get_just_SBVMaybe T))))))
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Maybe
+[GOOD] (declare-datatype Maybe (par (a) (
+           (Nothing)
+           (Just (getJust_1 a))
+       )))
 [GOOD] ; --- literal constants ---
-[GOOD] (define-fun s3 () (SBVMaybe Int) (as nothing_SBVMaybe (SBVMaybe Int)))
-[GOOD] (define-fun s5 () Int 1)
-[GOOD] (define-fun s15 () Int 0)
+[GOOD] (define-fun s2 () (Maybe Int) (as Nothing (Maybe Int)))
+[GOOD] (define-fun s4 () Int 1)
+[GOOD] (define-fun s13 () Int 0)
 [GOOD] ; --- top level inputs ---
-[GOOD] (declare-fun s0 () (SBVMaybe Int)) ; tracks user variable "x"
+[GOOD] (declare-fun s0 () (Maybe Int)) ; tracks user variable "x"
 [GOOD] ; --- constant tables ---
 [GOOD] ; --- non-constant tables ---
 [GOOD] ; --- uninterpreted constants ---
 [GOOD] ; --- user defined functions ---
 [GOOD] ; --- assignments ---
-[GOOD] (define-fun s1 () Bool ((_ is (nothing_SBVMaybe () (SBVMaybe Int))) s0))
-[GOOD] (define-fun s2 () Bool (ite s1 true false))
-[GOOD] (define-fun s4 () Int (get_just_SBVMaybe s0))
-[GOOD] (define-fun s6 () Int (+ s4 s5))
-[GOOD] (define-fun s7 () (SBVMaybe Int) ((as just_SBVMaybe (SBVMaybe Int)) s6))
-[GOOD] (define-fun s8 () (SBVMaybe Int) (ite s1 s3 s7))
-[GOOD] (define-fun s9 () Bool ((_ is (nothing_SBVMaybe () (SBVMaybe Int))) s8))
-[GOOD] (define-fun s10 () Bool (ite s9 true false))
-[GOOD] (define-fun s11 () Bool (= s2 s10))
-[GOOD] (define-fun s12 () Bool (ite s1 false true))
-[GOOD] (define-fun s13 () Bool (ite s9 false true))
-[GOOD] (define-fun s14 () Bool (= s12 s13))
-[GOOD] (define-fun s16 () Int (ite s1 s15 s4))
-[GOOD] (define-fun s17 () Int (get_just_SBVMaybe s8))
-[GOOD] (define-fun s18 () Int (ite s9 s15 s17))
-[GOOD] (define-fun s19 () Int (- s18 s5))
-[GOOD] (define-fun s20 () Bool (= s16 s19))
+[GOOD] (define-fun s1 () Bool ((as is-Nothing Bool) s0))
+[GOOD] (define-fun s3 () Int (getJust_1 s0))
+[GOOD] (define-fun s5 () Int (+ s3 s4))
+[GOOD] (define-fun s6 () (Maybe Int) ((as Just (Maybe Int)) s5))
+[GOOD] (define-fun s7 () (Maybe Int) (ite s1 s2 s6))
+[GOOD] (define-fun s8 () Bool ((as is-Nothing Bool) s7))
+[GOOD] (define-fun s9 () Bool (= s1 s8))
+[GOOD] (define-fun s10 () Bool ((as is-Just Bool) s0))
+[GOOD] (define-fun s11 () Bool ((as is-Just Bool) s7))
+[GOOD] (define-fun s12 () Bool (= s10 s11))
+[GOOD] (define-fun s14 () Int (ite s1 s13 s3))
+[GOOD] (define-fun s15 () Int (getJust_1 s7))
+[GOOD] (define-fun s16 () Int (ite s8 s13 s15))
+[GOOD] (define-fun s17 () Int (- s16 s4))
+[GOOD] (define-fun s18 () Bool (= s14 s17))
 [GOOD] ; --- delayedEqualities ---
 [GOOD] ; --- formula ---
-[GOOD] (assert s11)
-[GOOD] (assert s14)
-[GOOD] (assert s20)
+[GOOD] (assert s9)
+[GOOD] (assert s12)
+[GOOD] (assert s18)
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (just_SBVMaybe 0)))
+[RECV] ((s0 (Just 0)))
 
 MODEL: SMTModel {modelObjectives = [], modelBindings = Nothing, modelAssocs = [("x",Just 0 :: Maybe Integer)], modelUIFuns = []}
 DONE.*** Solver   : Z3
diff --git a/SBVTestSuite/GoldFiles/sumMaybeBoth.gold b/SBVTestSuite/GoldFiles/sumMaybeBoth.gold
--- a/SBVTestSuite/GoldFiles/sumMaybeBoth.gold
+++ b/SBVTestSuite/GoldFiles/sumMaybeBoth.gold
@@ -9,38 +9,40 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
-[GOOD] (declare-datatypes ((SBVEither 2)) ((par (T1 T2)
-                                           ((left_SBVEither  (get_left_SBVEither  T1))
-                                            (right_SBVEither (get_right_SBVEither T2))))))
-[GOOD] (declare-datatypes ((SBVMaybe 1)) ((par (T)
-                                           ((nothing_SBVMaybe)
-                                            (just_SBVMaybe (get_just_SBVMaybe T))))))
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Maybe
+[GOOD] (declare-datatype Maybe (par (a) (
+           (Nothing)
+           (Just (getJust_1 a))
+       )))
+[GOOD] ; User defined ADT: Either
+[GOOD] (declare-datatype Either (par (a b) (
+           (Left (getLeft_1 a))
+           (Right (getRight_1 b))
+       )))
 [GOOD] ; --- literal constants ---
 [GOOD] ; --- top level inputs ---
-[GOOD] (declare-fun s0 () (SBVEither Int Int))
-[GOOD] (declare-fun s1 () (SBVMaybe Int))
+[GOOD] (declare-fun s0 () (Either Int Int))
+[GOOD] (declare-fun s1 () (Maybe Int))
 [GOOD] ; --- constant tables ---
 [GOOD] ; --- non-constant tables ---
 [GOOD] ; --- uninterpreted constants ---
 [GOOD] ; --- user defined functions ---
 [GOOD] ; --- assignments ---
-[GOOD] (define-fun s2 () Bool ((_ is (left_SBVEither (Int) (SBVEither Int Int))) s0))
-[GOOD] (define-fun s3 () Bool (ite s2 true false))
-[GOOD] (define-fun s4 () Bool ((_ is (nothing_SBVMaybe () (SBVMaybe Int))) s1))
-[GOOD] (define-fun s5 () Bool (ite s4 false true))
+[GOOD] (define-fun s2 () Bool ((as is-Left Bool) s0))
+[GOOD] (define-fun s3 () Bool ((as is-Just Bool) s1))
 [GOOD] ; --- delayedEqualities ---
 [GOOD] ; --- formula ---
+[GOOD] (assert s2)
 [GOOD] (assert s3)
-[GOOD] (assert s5)
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (left_SBVEither 2)))
+[RECV] ((s0 (Left 2)))
 [SEND] (get-value (s1))
-[RECV] ((s1 (just_SBVMaybe 3)))
+[RECV] ((s1 (Just 3)))
 
 MODEL: SMTModel {modelObjectives = [], modelBindings = Nothing, modelAssocs = [("s0",Left 2 :: Either Integer Integer),("s1",Just 3 :: Maybe Integer)], modelUIFuns = []}
 DONE.*** Solver   : Z3
diff --git a/SBVTestSuite/GoldFiles/sumMergeEither1.gold b/SBVTestSuite/GoldFiles/sumMergeEither1.gold
--- a/SBVTestSuite/GoldFiles/sumMergeEither1.gold
+++ b/SBVTestSuite/GoldFiles/sumMergeEither1.gold
@@ -9,34 +9,35 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
-[GOOD] (declare-datatypes ((SBVEither 2)) ((par (T1 T2)
-                                           ((left_SBVEither  (get_left_SBVEither  T1))
-                                            (right_SBVEither (get_right_SBVEither T2))))))
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Either
+[GOOD] (declare-datatype Either (par (a b) (
+           (Left (getLeft_1 a))
+           (Right (getRight_1 b))
+       )))
 [GOOD] ; --- literal constants ---
 [GOOD] ; --- top level inputs ---
-[GOOD] (declare-fun s0 () (SBVEither Int Bool))
-[GOOD] (declare-fun s1 () (SBVEither Int Bool))
+[GOOD] (declare-fun s0 () (Either Int Bool))
+[GOOD] (declare-fun s1 () (Either Int Bool))
 [GOOD] (declare-fun s2 () Bool)
 [GOOD] ; --- constant tables ---
 [GOOD] ; --- non-constant tables ---
 [GOOD] ; --- uninterpreted constants ---
 [GOOD] ; --- user defined functions ---
 [GOOD] ; --- assignments ---
-[GOOD] (define-fun s3 () (SBVEither Int Bool) (ite s2 s0 s1))
-[GOOD] (define-fun s4 () Bool ((_ is (left_SBVEither (Int) (SBVEither Int Bool))) s3))
-[GOOD] (define-fun s5 () Bool (ite s4 true false))
+[GOOD] (define-fun s3 () (Either Int Bool) (ite s2 s0 s1))
+[GOOD] (define-fun s4 () Bool ((as is-Left Bool) s3))
 [GOOD] ; --- delayedEqualities ---
 [GOOD] ; --- formula ---
-[GOOD] (assert s5)
+[GOOD] (assert s4)
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (left_SBVEither 2)))
+[RECV] ((s0 (Left 2)))
 [SEND] (get-value (s1))
-[RECV] ((s1 (left_SBVEither 2)))
+[RECV] ((s1 (Left 2)))
 [SEND] (get-value (s2))
 [RECV] ((s2 false))
 
diff --git a/SBVTestSuite/GoldFiles/sumMergeEither2.gold b/SBVTestSuite/GoldFiles/sumMergeEither2.gold
--- a/SBVTestSuite/GoldFiles/sumMergeEither2.gold
+++ b/SBVTestSuite/GoldFiles/sumMergeEither2.gold
@@ -9,34 +9,35 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
-[GOOD] (declare-datatypes ((SBVEither 2)) ((par (T1 T2)
-                                           ((left_SBVEither  (get_left_SBVEither  T1))
-                                            (right_SBVEither (get_right_SBVEither T2))))))
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Either
+[GOOD] (declare-datatype Either (par (a b) (
+           (Left (getLeft_1 a))
+           (Right (getRight_1 b))
+       )))
 [GOOD] ; --- literal constants ---
 [GOOD] ; --- top level inputs ---
-[GOOD] (declare-fun s0 () (SBVEither Int Bool))
-[GOOD] (declare-fun s1 () (SBVEither Int Bool))
+[GOOD] (declare-fun s0 () (Either Int Bool))
+[GOOD] (declare-fun s1 () (Either Int Bool))
 [GOOD] (declare-fun s2 () Bool)
 [GOOD] ; --- constant tables ---
 [GOOD] ; --- non-constant tables ---
 [GOOD] ; --- uninterpreted constants ---
 [GOOD] ; --- user defined functions ---
 [GOOD] ; --- assignments ---
-[GOOD] (define-fun s3 () (SBVEither Int Bool) (ite s2 s0 s1))
-[GOOD] (define-fun s4 () Bool ((_ is (left_SBVEither (Int) (SBVEither Int Bool))) s3))
-[GOOD] (define-fun s5 () Bool (ite s4 false true))
+[GOOD] (define-fun s3 () (Either Int Bool) (ite s2 s0 s1))
+[GOOD] (define-fun s4 () Bool ((as is-Right Bool) s3))
 [GOOD] ; --- delayedEqualities ---
 [GOOD] ; --- formula ---
-[GOOD] (assert s5)
+[GOOD] (assert s4)
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (right_SBVEither false)))
+[RECV] ((s0 (Right false)))
 [SEND] (get-value (s1))
-[RECV] ((s1 (right_SBVEither false)))
+[RECV] ((s1 (Right false)))
 [SEND] (get-value (s2))
 [RECV] ((s2 false))
 
diff --git a/SBVTestSuite/GoldFiles/sumMergeMaybe1.gold b/SBVTestSuite/GoldFiles/sumMergeMaybe1.gold
--- a/SBVTestSuite/GoldFiles/sumMergeMaybe1.gold
+++ b/SBVTestSuite/GoldFiles/sumMergeMaybe1.gold
@@ -9,34 +9,35 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
-[GOOD] (declare-datatypes ((SBVMaybe 1)) ((par (T)
-                                           ((nothing_SBVMaybe)
-                                            (just_SBVMaybe (get_just_SBVMaybe T))))))
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Maybe
+[GOOD] (declare-datatype Maybe (par (a) (
+           (Nothing)
+           (Just (getJust_1 a))
+       )))
 [GOOD] ; --- literal constants ---
 [GOOD] ; --- top level inputs ---
-[GOOD] (declare-fun s0 () (SBVMaybe Int))
-[GOOD] (declare-fun s1 () (SBVMaybe Int))
+[GOOD] (declare-fun s0 () (Maybe Int))
+[GOOD] (declare-fun s1 () (Maybe Int))
 [GOOD] (declare-fun s2 () Bool)
 [GOOD] ; --- constant tables ---
 [GOOD] ; --- non-constant tables ---
 [GOOD] ; --- uninterpreted constants ---
 [GOOD] ; --- user defined functions ---
 [GOOD] ; --- assignments ---
-[GOOD] (define-fun s3 () (SBVMaybe Int) (ite s2 s0 s1))
-[GOOD] (define-fun s4 () Bool ((_ is (nothing_SBVMaybe () (SBVMaybe Int))) s3))
-[GOOD] (define-fun s5 () Bool (ite s4 true false))
+[GOOD] (define-fun s3 () (Maybe Int) (ite s2 s0 s1))
+[GOOD] (define-fun s4 () Bool ((as is-Nothing Bool) s3))
 [GOOD] ; --- delayedEqualities ---
 [GOOD] ; --- formula ---
-[GOOD] (assert s5)
+[GOOD] (assert s4)
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 nothing_SBVMaybe))
+[RECV] ((s0 Nothing))
 [SEND] (get-value (s1))
-[RECV] ((s1 nothing_SBVMaybe))
+[RECV] ((s1 Nothing))
 [SEND] (get-value (s2))
 [RECV] ((s2 false))
 
diff --git a/SBVTestSuite/GoldFiles/sumMergeMaybe2.gold b/SBVTestSuite/GoldFiles/sumMergeMaybe2.gold
--- a/SBVTestSuite/GoldFiles/sumMergeMaybe2.gold
+++ b/SBVTestSuite/GoldFiles/sumMergeMaybe2.gold
@@ -9,34 +9,35 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
-[GOOD] (declare-datatypes ((SBVMaybe 1)) ((par (T)
-                                           ((nothing_SBVMaybe)
-                                            (just_SBVMaybe (get_just_SBVMaybe T))))))
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: Maybe
+[GOOD] (declare-datatype Maybe (par (a) (
+           (Nothing)
+           (Just (getJust_1 a))
+       )))
 [GOOD] ; --- literal constants ---
 [GOOD] ; --- top level inputs ---
-[GOOD] (declare-fun s0 () (SBVMaybe Int))
-[GOOD] (declare-fun s1 () (SBVMaybe Int))
+[GOOD] (declare-fun s0 () (Maybe Int))
+[GOOD] (declare-fun s1 () (Maybe Int))
 [GOOD] (declare-fun s2 () Bool)
 [GOOD] ; --- constant tables ---
 [GOOD] ; --- non-constant tables ---
 [GOOD] ; --- uninterpreted constants ---
 [GOOD] ; --- user defined functions ---
 [GOOD] ; --- assignments ---
-[GOOD] (define-fun s3 () (SBVMaybe Int) (ite s2 s0 s1))
-[GOOD] (define-fun s4 () Bool ((_ is (nothing_SBVMaybe () (SBVMaybe Int))) s3))
-[GOOD] (define-fun s5 () Bool (ite s4 false true))
+[GOOD] (define-fun s3 () (Maybe Int) (ite s2 s0 s1))
+[GOOD] (define-fun s4 () Bool ((as is-Just Bool) s3))
 [GOOD] ; --- delayedEqualities ---
 [GOOD] ; --- formula ---
-[GOOD] (assert s5)
+[GOOD] (assert s4)
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (just_SBVMaybe 2)))
+[RECV] ((s0 (Just 2)))
 [SEND] (get-value (s1))
-[RECV] ((s1 (just_SBVMaybe 2)))
+[RECV] ((s1 (Just 2)))
 [SEND] (get-value (s2))
 [RECV] ((s2 false))
 
diff --git a/SBVTestSuite/GoldFiles/tpCache_alias.gold b/SBVTestSuite/GoldFiles/tpCache_alias.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/tpCache_alias.gold
@@ -0,0 +1,3 @@
+Lemma: nameA        Q.E.D.
+Lemma: nameB        Q.E.D.
+Lemma: nameC        Q.E.D. [Cached] (a.k.a. nameA, nameB)
diff --git a/SBVTestSuite/GoldFiles/tpCache_barFail.gold b/SBVTestSuite/GoldFiles/tpCache_barFail.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/tpCache_barFail.gold
@@ -0,0 +1,4 @@
+Lemma: foo
+*** Failed to prove foo.
+Falsifiable. Counter-example:
+  x = 0 :: Integer
diff --git a/SBVTestSuite/GoldFiles/tpCache_calcCollapse.gold b/SBVTestSuite/GoldFiles/tpCache_calcCollapse.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/tpCache_calcCollapse.gold
@@ -0,0 +1,4 @@
+Lemma: addZero
+  Step: 1           Q.E.D.
+  Result:           Q.E.D.
+Lemma: addZero      Q.E.D. [Cached]
diff --git a/SBVTestSuite/GoldFiles/tpCache_fooFail.gold b/SBVTestSuite/GoldFiles/tpCache_fooFail.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/tpCache_fooFail.gold
@@ -0,0 +1,4 @@
+Lemma: foo
+*** Failed to prove foo.
+Falsifiable. Counter-example:
+  x = 0 :: Integer
diff --git a/SBVTestSuite/GoldFiles/tpCache_hit.gold b/SBVTestSuite/GoldFiles/tpCache_hit.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/tpCache_hit.gold
@@ -0,0 +1,2 @@
+Lemma: fact         Q.E.D.
+Lemma: fact         Q.E.D. [Cached]
diff --git a/SBVTestSuite/GoldFiles/tpCache_miss.gold b/SBVTestSuite/GoldFiles/tpCache_miss.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/tpCache_miss.gold
@@ -0,0 +1,1 @@
+Lemma: fact         Q.E.D.
diff --git a/SBVTestSuite/GoldFiles/tpCache_nested.gold b/SBVTestSuite/GoldFiles/tpCache_nested.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/tpCache_nested.gold
@@ -0,0 +1,3 @@
+Lemma: inner        Q.E.D.
+Lemma: outer        Q.E.D.
+Lemma: outer        Q.E.D. [Cached] (a.k.a. inner)
diff --git a/SBVTestSuite/GoldFiles/tpCache_recallFail.gold b/SBVTestSuite/GoldFiles/tpCache_recallFail.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/tpCache_recallFail.gold
@@ -0,0 +1,4 @@
+Lemma: bad
+*** Failed to prove bad.
+Falsifiable. Counter-example:
+  x = 0 :: Integer
diff --git a/SBVTestSuite/GoldFiles/tpCache_statsHit.gold b/SBVTestSuite/GoldFiles/tpCache_statsHit.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/tpCache_statsHit.gold
@@ -0,0 +1,4 @@
+Lemma: addZero
+  Step: 1           Q.E.D.
+  Result:           Q.E.D.
+Lemma: addZero      Q.E.D. [Cached]
diff --git a/SBVTestSuite/GoldFiles/tpCache_statsMiss.gold b/SBVTestSuite/GoldFiles/tpCache_statsMiss.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/tpCache_statsMiss.gold
@@ -0,0 +1,3 @@
+Lemma: addZero
+  Step: 1           Q.E.D.
+  Result:           Q.E.D.
diff --git a/SBVTestSuite/GoldFiles/tpCache_statsNested.gold b/SBVTestSuite/GoldFiles/tpCache_statsNested.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/tpCache_statsNested.gold
@@ -0,0 +1,4 @@
+Lemma: inner        Q.E.D.
+Lemma: outer        Q.E.D.
+Lemma: inner        Q.E.D. [Cached] (a.k.a. outer)
+Lemma: outer        Q.E.D. [Cached] (a.k.a. inner)
diff --git a/SBVTestSuite/GoldFiles/tuple_enum.gold b/SBVTestSuite/GoldFiles/tuple_enum.gold
--- a/SBVTestSuite/GoldFiles/tuple_enum.gold
+++ b/SBVTestSuite/GoldFiles/tuple_enum.gold
@@ -9,22 +9,23 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
-[GOOD] (declare-datatypes ((E 0)) (((A) (B) (C))))
-[GOOD] (define-fun E_constrIndex ((x E)) Int
-          (ite (= x A) 0 (ite (= x B) 1 2))
-       )
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
                                                          (proj_2_SBVTuple2 T2))))))
 [GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] ; User defined ADT: E
+[GOOD] (declare-datatype E (
+           (A)
+           (B)
+           (C)
+       ))
 [GOOD] ; --- literal constants ---
 [GOOD] (define-fun s3 () Int 1)
-[GOOD] (define-fun s6 () (Seq Bool) (seq.unit true))
 [GOOD] (define-fun s11 () Int 3)
 [GOOD] (define-fun s13 () Int 2)
-[GOOD] (define-fun s16 () E C)
+[GOOD] (define-fun s16 () E (as C E))
 [GOOD] (define-fun s20 () Int 6)
 [GOOD] (define-fun s22 () Int 4)
 [GOOD] ; --- top level inputs ---
@@ -38,6 +39,7 @@
 [GOOD] (define-fun s2 () Bool (not s1))
 [GOOD] (define-fun s4 () (SBVTuple2 E (Seq Bool)) (seq.nth s0 s3))
 [GOOD] (define-fun s5 () (Seq Bool) (proj_2_SBVTuple2 s4))
+[GOOD] (define-fun s6 () (Seq Bool) (seq.unit true))
 [GOOD] (define-fun s7 () (Seq Bool) (seq.unit s1))
 [GOOD] (define-fun s8 () (Seq Bool) (seq.++ s6 s7))
 [GOOD] (define-fun s9 () Bool (= s5 s8))
@@ -67,10 +69,10 @@
                                                          (proj_3_SBVTuple3 T3))))))
 [GOOD] (declare-fun s24 () (SBVTuple2 (_ BitVec 8) (SBVTuple3 E String Int)))
 [GOOD] (assert (= 1 (str.len (proj_2_SBVTuple3 (proj_2_SBVTuple2 s24)))))
-[GOOD] (define-fun s25 () (SBVTuple2 (_ BitVec 8) (SBVTuple3 E String Int)) (mkSBVTuple2 #x05 (mkSBVTuple3 C (_ char #x41) 812)))
+[GOOD] (define-fun s25 () (SBVTuple2 (_ BitVec 8) (SBVTuple3 E String Int)) (mkSBVTuple2 #x05 (mkSBVTuple3 (as C E) (_ char #x41) 812)))
 [GOOD] (define-fun s26 () Bool (= s24 s25))
 [GOOD] (assert s26)
-[GOOD] (define-fun s27 () (Seq (SBVTuple2 E (Seq Bool))) (seq.++ (seq.unit (mkSBVTuple2 B (as seq.empty (Seq Bool)))) (seq.unit (mkSBVTuple2 A (seq.++ (seq.unit true) (seq.unit false)))) (seq.unit (mkSBVTuple2 C (seq.++ (seq.unit false) (seq.unit false) (seq.unit false) (seq.unit false) (seq.unit true) (seq.unit false))))))
+[GOOD] (define-fun s27 () (Seq (SBVTuple2 E (Seq Bool))) (seq.++ (seq.unit (mkSBVTuple2 (as B E) (as seq.empty (Seq Bool)))) (seq.unit (mkSBVTuple2 (as A E) (seq.++ (seq.unit true) (seq.unit false)))) (seq.unit (mkSBVTuple2 (as C E) (seq.++ (seq.unit false) (seq.unit false) (seq.unit false) (seq.unit false) (seq.unit true) (seq.unit false))))))
 [GOOD] (define-fun s28 () Bool (= s0 s27))
 [GOOD] (assert s28)
 [SEND] (check-sat)
diff --git a/SBVTestSuite/GoldFiles/tuple_list.gold b/SBVTestSuite/GoldFiles/tuple_list.gold
--- a/SBVTestSuite/GoldFiles/tuple_list.gold
+++ b/SBVTestSuite/GoldFiles/tuple_list.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/tuple_nested.gold b/SBVTestSuite/GoldFiles/tuple_nested.gold
--- a/SBVTestSuite/GoldFiles/tuple_nested.gold
+++ b/SBVTestSuite/GoldFiles/tuple_nested.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/tuple_swap.gold b/SBVTestSuite/GoldFiles/tuple_swap.gold
--- a/SBVTestSuite/GoldFiles/tuple_swap.gold
+++ b/SBVTestSuite/GoldFiles/tuple_swap.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple3 3)) ((par (T1 T2 T3)
                                            ((mkSBVTuple3 (proj_1_SBVTuple3 T1)
diff --git a/SBVTestSuite/GoldFiles/tuple_twoTwo.gold b/SBVTestSuite/GoldFiles/tuple_twoTwo.gold
--- a/SBVTestSuite/GoldFiles/tuple_twoTwo.gold
+++ b/SBVTestSuite/GoldFiles/tuple_twoTwo.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
diff --git a/SBVTestSuite/GoldFiles/tuple_unequal.gold b/SBVTestSuite/GoldFiles/tuple_unequal.gold
--- a/SBVTestSuite/GoldFiles/tuple_unequal.gold
+++ b/SBVTestSuite/GoldFiles/tuple_unequal.gold
@@ -9,7 +9,6 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] (declare-datatypes ((SBVTuple2 2)) ((par (T1 T2)
                                            ((mkSBVTuple2 (proj_1_SBVTuple2 T1)
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
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; NB. User specified.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
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
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; NB. User specified.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
@@ -90,10 +89,10 @@
 [SEND] (get-value (q2))
 [RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false true true)
               true
-              true
+              false
               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 true) (= x!1 false)) true
           (ite (and (= x!0 false) (= x!1 true)) true
           false))
        )
@@ -107,10 +106,14 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) true true true)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) true false true)
+              true
+              true
+              true)))
 [GOOD] (define-fun q2_model6 ((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)) true
+          false))
        )
 [GOOD] (define-fun q2_model6_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -122,14 +125,10 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false true true)
-              true
-              false
-              true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) false true false)))
 [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 false) (= x!1 true)) true
-          false))
+          (ite (and (= x!0 false) (= x!1 true)) false
+          true)
        )
 [GOOD] (define-fun q2_model7_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -141,10 +140,14 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) true false true)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) false true false)
+              true
+              true
+              false)))
 [GOOD] (define-fun q2_model8 ((x!0 Bool) (x!1 Bool)) Bool
-          (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 true)) false
+          true))
        )
 [GOOD] (define-fun q2_model8_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -156,14 +159,10 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) true false true)
-              true
-              true
-              true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) true true false)))
 [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))
+          (ite (and (= x!0 true) (= x!1 true)) false
+          true)
        )
 [GOOD] (define-fun q2_model9_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -175,10 +174,10 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) false false true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) true false false)))
 [GOOD] (define-fun q2_model10 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 false) (= x!1 false)) 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))
@@ -190,14 +189,14 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false false true)
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) true false false)
               true
               true
-              true)))
+              false)))
 [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))
+          (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))
@@ -209,13 +208,13 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) false true false)
-              true
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) true false false)
+              false
               true
               false)))
 [GOOD] (define-fun q2_model12 ((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 true) (= x!1 false)) false
           true))
        )
 [GOOD] (define-fun q2_model12_reject () Bool
@@ -228,10 +227,10 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) false true false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) false false true)))
 [GOOD] (define-fun q2_model13 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 false) (= x!1 true)) false
-          true)
+          (ite (and (= x!0 false) (= x!1 false)) true
+          false)
        )
 [GOOD] (define-fun q2_model13_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -243,10 +242,14 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) true false false)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) true false false)
+              false
+              false
+              false)))
 [GOOD] (define-fun q2_model14 ((x!0 Bool) (x!1 Bool)) Bool
+          (ite (and (= x!0 false) (= x!1 false)) false
           (ite (and (= x!0 true) (= x!1 false)) false
-          true)
+          true))
        )
 [GOOD] (define-fun q2_model14_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -258,14 +261,10 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) true false false)
-              true
-              true
-              false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) true true true)))
 [GOOD] (define-fun q2_model15 ((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))
+          (ite (and (= x!0 true) (= x!1 true)) true
+          false)
        )
 [GOOD] (define-fun q2_model15_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -277,10 +276,10 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) true true false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) true false true)))
 [GOOD] (define-fun q2_model16 ((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
+          false)
        )
 [GOOD] (define-fun q2_model16_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -296,58 +295,58 @@
 
 RESULT: Solution #1:
   q2 :: Bool -> Bool -> Bool
-  q2 True True = False
-  q2 _    _    = True
+  q2 True False = True
+  q2 _    _     = False
 Solution #2:
   q2 :: Bool -> Bool -> Bool
-  q2 True True  = False
-  q2 True False = False
-  q2 _    _     = True
+  q2 True True = True
+  q2 _    _    = False
 Solution #3:
   q2 :: Bool -> Bool -> Bool
-  q2 True False = False
-  q2 _    _     = True
+  q2 False False = False
+  q2 True  False = False
+  q2 _     _     = True
 Solution #4:
   q2 :: Bool -> Bool -> Bool
-  q2 False True = False
-  q2 _     _    = True
+  q2 False False = True
+  q2 _     _     = False
 Solution #5:
   q2 :: Bool -> Bool -> Bool
-  q2 True  True = False
-  q2 False True = False
-  q2 _     _    = True
+  q2 False True  = False
+  q2 True  False = False
+  q2 _     _     = True
 Solution #6:
   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 #7:
   q2 :: Bool -> Bool -> Bool
-  q2 False False = True
-  q2 _     _     = False
+  q2 True False = False
+  q2 _    _     = True
 Solution #8:
   q2 :: Bool -> Bool -> Bool
-  q2 True True  = True
-  q2 True False = True
-  q2 _    _     = False
+  q2 True True = False
+  q2 _    _    = True
 Solution #9:
   q2 :: Bool -> Bool -> Bool
-  q2 True False = True
-  q2 _    _     = False
+  q2 True  True = False
+  q2 False True = False
+  q2 _     _    = True
 Solution #10:
   q2 :: Bool -> Bool -> Bool
-  q2 True  False = True
-  q2 False True  = True
-  q2 _     _     = False
+  q2 False True = False
+  q2 _     _    = True
 Solution #11:
   q2 :: Bool -> Bool -> Bool
-  q2 True True = True
-  q2 _    _    = False
+  q2 True True  = True
+  q2 True False = True
+  q2 _    _     = False
 Solution #12:
   q2 :: Bool -> Bool -> Bool
-  q2 True  True = True
-  q2 False True = True
-  q2 _     _    = False
+  q2 True  False = True
+  q2 False 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
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; NB. User specified.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
@@ -113,7 +112,7 @@
 [SEND] (get-value (q1))
 [RECV] ((q1 ((as const (Array Bool Bool)) false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) true false false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) false true false)))
 [GOOD] (define-fun q1_model4 ((x!0 Bool)) Bool
           false
        )
@@ -122,7 +121,7 @@
                   (distinct (q1        x!0)
                             (q1_model4 x!0))))
 [GOOD] (define-fun q2_model4 ((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)
        )
 [GOOD] (define-fun q2_model4_reject () Bool
@@ -165,23 +164,20 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const (Array Bool Bool)) false)))
+[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false false true)
-              true
-              true
-              true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) false false true)))
 [GOOD] (define-fun q1_model6 ((x!0 Bool)) Bool
-          false
+          (ite (and (= x!0 true)) true
+          false)
        )
 [GOOD] (define-fun q1_model6_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1        x!0)
                             (q1_model6 x!0))))
 [GOOD] (define-fun q2_model6 ((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_model6_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -198,10 +194,7 @@
 [SEND] (get-value (q1))
 [RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false false true)
-              true
-              true
-              true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) false true false)))
 [GOOD] (define-fun q1_model7 ((x!0 Bool)) Bool
           (ite (and (= x!0 true)) true
           false)
@@ -211,9 +204,8 @@
                   (distinct (q1        x!0)
                             (q1_model7 x!0))))
 [GOOD] (define-fun q2_model7 ((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 false) (= x!1 true)) false
+          true)
        )
 [GOOD] (define-fun q2_model7_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -230,7 +222,10 @@
 [SEND] (get-value (q1))
 [RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) true false false)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) false true false)
+              true
+              true
+              false)))
 [GOOD] (define-fun q1_model8 ((x!0 Bool)) Bool
           (ite (and (= x!0 true)) true
           false)
@@ -240,8 +235,9 @@
                   (distinct (q1        x!0)
                             (q1_model8 x!0))))
 [GOOD] (define-fun q2_model8 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= 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_model8_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -256,24 +252,20 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const (Array Bool Bool)) true) true false)))
+[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false false true)
-              true
-              true
-              true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) 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
+          true)
        )
 [GOOD] (define-fun q2_model9_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -288,23 +280,19 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const (Array Bool Bool)) true)))
+[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false false true)
-              true
-              true
-              true)))
+[RECV] ((q2 ((as const (Array Bool Bool Bool)) true)))
 [GOOD] (define-fun q1_model10 ((x!0 Bool)) Bool
-          true
+          (ite (and (= x!0 true)) 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))
+          true
        )
 [GOOD] (define-fun q2_model10_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -319,18 +307,19 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const (Array Bool Bool)) false)))
+[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) false true false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) true false false)))
 [GOOD] (define-fun q1_model11 ((x!0 Bool)) Bool
-          false
+          (ite (and (= x!0 true)) 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
+          (ite (and (= x!0 true) (= x!1 false)) false
           true)
        )
 [GOOD] (define-fun q2_model11_reject () Bool
@@ -348,7 +337,10 @@
 [SEND] (get-value (q1))
 [RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) false true false)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) true false false)
+              false
+              true
+              false)))
 [GOOD] (define-fun q1_model12 ((x!0 Bool)) Bool
           (ite (and (= x!0 true)) true
           false)
@@ -359,7 +351,8 @@
                             (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 false)) false
+          true))
        )
 [GOOD] (define-fun q2_model12_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -374,12 +367,14 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const (Array Bool Bool)) false) false true)))
+[RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) false true false)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) true false false)
+              false
+              true
+              false)))
 [GOOD] (define-fun q1_model13 ((x!0 Bool)) Bool
-          (ite (and (= x!0 false)) true
-          false)
+          true
        )
 [GOOD] (define-fun q1_model13_reject () Bool
           (exists ((x!0 Bool))
@@ -387,7 +382,8 @@
                             (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
-          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))
@@ -404,7 +400,7 @@
 [SEND] (get-value (q1))
 [RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) 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
        )
@@ -413,7 +409,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
@@ -429,20 +425,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 Bool Bool Bool)) false) false false true)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) true false false)
+              false
+              true
+              false)))
 [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))
                   (distinct (q1         x!0)
                             (q1_model15 x!0))))
 [GOOD] (define-fun q2_model15 ((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
+          (ite (and (= x!0 true) (= x!1 false)) false
+          true))
        )
 [GOOD] (define-fun q2_model15_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -457,24 +457,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)) false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false false true)
-              true
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) true false false)
               false
-              true)))
+              true
+              false)))
 [GOOD] (define-fun q1_model16 ((x!0 Bool)) Bool
-          (ite (and (= x!0 true)) true
-          false)
+          false
        )
 [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 false) (= x!1 false)) true
-          false))
+          (ite (and (= x!0 false) (= x!1 true)) false
+          (ite (and (= x!0 true) (= x!1 false)) false
+          true))
        )
 [GOOD] (define-fun q2_model16_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -491,10 +490,7 @@
 [SEND] (get-value (q1))
 [RECV] ((q1 ((as const (Array Bool Bool)) false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) false true false)
-              true
-              true
-              false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) true false false)))
 [GOOD] (define-fun q1_model17 ((x!0 Bool)) Bool
           false
        )
@@ -503,9 +499,8 @@
                   (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 true) (= x!1 false)) false
+          true)
        )
 [GOOD] (define-fun q2_model17_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -520,20 +515,20 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const (Array Bool Bool)) true) true false)))
+[RECV] ((q1 (store ((as const (Array Bool Bool)) false) false true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) false false true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) true false false)))
 [GOOD] (define-fun q1_model18 ((x!0 Bool)) Bool
-          (ite (and (= x!0 true)) false
-          true)
+          (ite (and (= x!0 false)) true
+          false)
        )
 [GOOD] (define-fun q1_model18_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model18 x!0))))
 [GOOD] (define-fun q2_model18 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 false) (= x!1 false)) true
-          false)
+          (ite (and (= x!0 true) (= x!1 false)) false
+          true)
        )
 [GOOD] (define-fun q2_model18_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -548,24 +543,20 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const (Array Bool Bool)) false) false true)))
+[RECV] ((q1 (store ((as const (Array Bool Bool)) true) true false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false false true)
-              true
-              false
-              true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) false true false)))
 [GOOD] (define-fun q1_model19 ((x!0 Bool)) Bool
-          (ite (and (= x!0 false)) true
-          false)
+          (ite (and (= x!0 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 false) (= x!1 false)) true
-          false))
+          (ite (and (= x!0 false) (= x!1 true)) false
+          true)
        )
 [GOOD] (define-fun q2_model19_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -582,7 +573,7 @@
 [SEND] (get-value (q1))
 [RECV] ((q1 (store ((as const (Array Bool Bool)) true) true false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) true false false)))
+[RECV] ((q2 ((as const (Array Bool Bool Bool)) true)))
 [GOOD] (define-fun q1_model20 ((x!0 Bool)) Bool
           (ite (and (= x!0 true)) false
           true)
@@ -592,8 +583,7 @@
                   (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 false)) false
-          true)
+          true
        )
 [GOOD] (define-fun q2_model20_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -608,12 +598,11 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const (Array Bool Bool)) true) true false)))
+[RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [SEND] (get-value (q2))
 [RECV] ((q2 ((as const (Array Bool Bool Bool)) true)))
 [GOOD] (define-fun q1_model21 ((x!0 Bool)) Bool
-          (ite (and (= x!0 true)) false
-          true)
+          true
        )
 [GOOD] (define-fun q1_model21_reject () Bool
           (exists ((x!0 Bool))
@@ -635,19 +624,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 ((as const (Array Bool Bool Bool)) true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) false true false)))
 [GOOD] (define-fun q1_model22 ((x!0 Bool)) Bool
-          (ite (and (= x!0 true)) true
-          false)
+          true
        )
 [GOOD] (define-fun q1_model22_reject () Bool
           (exists ((x!0 Bool))
                   (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 false) (= x!1 true)) false
+          true)
        )
 [GOOD] (define-fun q2_model22_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -662,18 +651,19 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const (Array Bool Bool)) true)))
+[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 ((as const (Array Bool Bool Bool)) true)))
+[RECV] ((q2 ((as const (Array Bool Bool Bool)) false)))
 [GOOD] (define-fun q1_model23 ((x!0 Bool)) Bool
-          true
+          (ite (and (= x!0 true)) true
+          false)
        )
 [GOOD] (define-fun q1_model23_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model23 x!0))))
 [GOOD] (define-fun q2_model23 ((x!0 Bool) (x!1 Bool)) Bool
-          true
+          false
        )
 [GOOD] (define-fun q2_model23_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -690,7 +680,7 @@
 [SEND] (get-value (q1))
 [RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) true true false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) true false true)))
 [GOOD] (define-fun q1_model24 ((x!0 Bool)) Bool
           (ite (and (= x!0 true)) true
           false)
@@ -700,8 +690,8 @@
                   (distinct (q1         x!0)
                             (q1_model24 x!0))))
 [GOOD] (define-fun q2_model24 ((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
+          false)
        )
 [GOOD] (define-fun q2_model24_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -716,19 +706,20 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const (Array Bool Bool)) false)))
+[RECV] ((q1 (store ((as const (Array Bool Bool)) true) true false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) true true false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) true false true)))
 [GOOD] (define-fun q1_model25 ((x!0 Bool)) Bool
-          false
+          (ite (and (= x!0 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 true)) false
-          true)
+          (ite (and (= x!0 true) (= x!1 false)) true
+          false)
        )
 [GOOD] (define-fun q2_model25_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -743,20 +734,19 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const (Array Bool Bool)) false) false true)))
+[RECV] ((q1 (store ((as const (Array Bool Bool)) true) true false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) true true false)))
+[RECV] ((q2 ((as const (Array Bool Bool Bool)) false)))
 [GOOD] (define-fun q1_model26 ((x!0 Bool)) Bool
-          (ite (and (= x!0 false)) true
-          false)
+          (ite (and (= x!0 true)) false
+          true)
        )
 [GOOD] (define-fun q1_model26_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model26 x!0))))
 [GOOD] (define-fun q2_model26 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 true)) false
-          true)
+          false
        )
 [GOOD] (define-fun q2_model26_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -771,19 +761,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 (store ((as const (Array Bool Bool Bool)) false) true true true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) false true true)))
 [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 true)) true
+          (ite (and (= x!0 false) (= x!1 true)) true
           false)
        )
 [GOOD] (define-fun q2_model27_reject () Bool
@@ -827,19 +817,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 ((as const (Array Bool Bool Bool)) false)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) false false false)
+              true
+              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
-          false
+          (ite (and (= x!0 true) (= x!1 true)) false
+          (ite (and (= x!0 false) (= x!1 false)) false
+          true))
        )
 [GOOD] (define-fun q2_model29_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -854,20 +849,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 Bool Bool Bool)) false) false true true)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) false false false)
+              false
+              true
+              false)))
 [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))
                   (distinct (q1         x!0)
                             (q1_model30 x!0))))
 [GOOD] (define-fun q2_model30 ((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
+          (ite (and (= x!0 false) (= x!1 false)) false
+          true))
        )
 [GOOD] (define-fun q2_model30_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -882,20 +881,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 Bool Bool Bool)) true) false false false)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) false false false)
+              false
+              true
+              false)))
 [GOOD] (define-fun q1_model31 ((x!0 Bool)) Bool
-          (ite (and (= x!0 true)) true
-          false)
+          true
        )
 [GOOD] (define-fun q1_model31_reject () Bool
           (exists ((x!0 Bool))
                   (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)) false
           (ite (and (= x!0 false) (= x!1 false)) false
-          true)
+          true))
        )
 [GOOD] (define-fun q2_model31_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -910,11 +912,11 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const (Array Bool Bool)) false)))
+[RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [SEND] (get-value (q2))
 [RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) true false true)))
 [GOOD] (define-fun q1_model32 ((x!0 Bool)) Bool
-          false
+          true
        )
 [GOOD] (define-fun q1_model32_reject () Bool
           (exists ((x!0 Bool))
@@ -937,19 +939,19 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const (Array Bool Bool)) false)))
+[RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) false false false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) true true true)))
 [GOOD] (define-fun q1_model33 ((x!0 Bool)) Bool
-          false
+          true
        )
 [GOOD] (define-fun q1_model33_reject () Bool
           (exists ((x!0 Bool))
                   (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)) true
+          false)
        )
 [GOOD] (define-fun q2_model33_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -964,18 +966,19 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const (Array Bool Bool)) false)))
+[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) false true true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) true true true)))
 [GOOD] (define-fun q1_model34 ((x!0 Bool)) Bool
-          false
+          (ite (and (= x!0 true)) true
+          false)
        )
 [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
+          (ite (and (= x!0 true) (= x!1 true)) true
           false)
        )
 [GOOD] (define-fun q2_model34_reject () Bool
@@ -991,19 +994,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)) false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) true false true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) true true true)))
 [GOOD] (define-fun q1_model35 ((x!0 Bool)) Bool
-          (ite (and (= x!0 true)) true
-          false)
+          false
        )
 [GOOD] (define-fun q1_model35_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model35 x!0))))
 [GOOD] (define-fun q2_model35 ((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
           false)
        )
 [GOOD] (define-fun q2_model35_reject () Bool
@@ -1021,7 +1023,7 @@
 [SEND] (get-value (q1))
 [RECV] ((q1 (store ((as const (Array Bool Bool)) false) false true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 ((as const (Array Bool Bool Bool)) false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) true true true)))
 [GOOD] (define-fun q1_model36 ((x!0 Bool)) Bool
           (ite (and (= x!0 false)) true
           false)
@@ -1031,7 +1033,8 @@
                   (distinct (q1         x!0)
                             (q1_model36 x!0))))
 [GOOD] (define-fun q2_model36 ((x!0 Bool) (x!1 Bool)) Bool
-          false
+          (ite (and (= x!0 true) (= x!1 true)) true
+          false)
        )
 [GOOD] (define-fun q2_model36_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1046,14 +1049,14 @@
 [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)) false) false true)))
 [SEND] (get-value (q2))
 [RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) false false false)
               true
-              true
+              false
               false)))
 [GOOD] (define-fun q1_model37 ((x!0 Bool)) Bool
-          (ite (and (= x!0 true)) true
+          (ite (and (= x!0 false)) true
           false)
        )
 [GOOD] (define-fun q1_model37_reject () Bool
@@ -1061,7 +1064,7 @@
                   (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 true)) false
+          (ite (and (= x!0 true) (= x!1 false)) false
           (ite (and (= x!0 false) (= x!1 false)) false
           true))
        )
@@ -1078,23 +1081,23 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const (Array Bool Bool)) false)))
+[RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false true true)
-              true
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) false false false)
               true
-              true)))
+              false
+              false)))
 [GOOD] (define-fun q1_model38 ((x!0 Bool)) Bool
-          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
-          false))
+          (ite (and (= x!0 true) (= x!1 false)) false
+          (ite (and (= x!0 false) (= x!1 false)) false
+          true))
        )
 [GOOD] (define-fun q2_model38_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1109,19 +1112,19 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const (Array Bool Bool)) false)))
+[RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) true true true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) false false false)))
 [GOOD] (define-fun q1_model39 ((x!0 Bool)) Bool
-          false
+          true
        )
 [GOOD] (define-fun q1_model39_reject () Bool
           (exists ((x!0 Bool))
                   (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
-          false)
+          (ite (and (= x!0 false) (= x!1 false)) false
+          true)
        )
 [GOOD] (define-fun q2_model39_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1136,22 +1139,21 @@
 [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 Bool Bool Bool)) true) false false false)
               true
-              false
+              true
               false)))
 [GOOD] (define-fun q1_model40 ((x!0 Bool)) Bool
-          (ite (and (= x!0 true)) true
-          false)
+          true
        )
 [GOOD] (define-fun q1_model40_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model40 x!0))))
 [GOOD] (define-fun q2_model40 ((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
           (ite (and (= x!0 false) (= x!1 false)) false
           true))
        )
@@ -1168,22 +1170,23 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const (Array Bool Bool)) false)))
+[RECV] ((q1 (store ((as const (Array Bool Bool)) true) true false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) true false true)
-              false
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false false true)
               true
+              false
               true)))
 [GOOD] (define-fun q1_model41 ((x!0 Bool)) Bool
-          false
+          (ite (and (= x!0 true)) false
+          true)
        )
 [GOOD] (define-fun q1_model41_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model41 x!0))))
 [GOOD] (define-fun q2_model41 ((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
+          (ite (and (= x!0 false) (= x!1 false)) true
           false))
        )
 [GOOD] (define-fun q2_model41_reject () Bool
@@ -1199,20 +1202,20 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const (Array Bool Bool)) false) false true)))
+[RECV] ((q1 (store ((as const (Array Bool Bool)) true) true false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) false true true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) true true false)))
 [GOOD] (define-fun q1_model42 ((x!0 Bool)) Bool
-          (ite (and (= x!0 false)) true
-          false)
+          (ite (and (= x!0 true)) false
+          true)
        )
 [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 false) (= x!1 true)) true
-          false)
+          (ite (and (= x!0 true) (= x!1 true)) false
+          true)
        )
 [GOOD] (define-fun q2_model42_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1227,24 +1230,19 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const (Array Bool Bool)) false) false true)))
+[RECV] ((q1 ((as const (Array Bool Bool)) false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false true true)
-              true
-              true
-              true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) true true false)))
 [GOOD] (define-fun q1_model43 ((x!0 Bool)) Bool
-          (ite (and (= x!0 false)) true
-          false)
+          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 false) (= x!1 true)) true
-          false))
+          (ite (and (= x!0 true) (= x!1 true)) false
+          true)
        )
 [GOOD] (define-fun q2_model43_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1259,19 +1257,18 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const (Array Bool Bool)) false) false true)))
+[RECV] ((q1 ((as const (Array Bool Bool)) false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) true true true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) false true true)))
 [GOOD] (define-fun q1_model44 ((x!0 Bool)) Bool
-          (ite (and (= x!0 false)) true
-          false)
+          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 true) (= x!1 true)) true
+          (ite (and (= x!0 false) (= x!1 true)) true
           false)
        )
 [GOOD] (define-fun q2_model44_reject () Bool
@@ -1287,12 +1284,11 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const (Array Bool Bool)) false) false true)))
+[RECV] ((q1 ((as const (Array Bool Bool)) false)))
 [SEND] (get-value (q2))
 [RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) true false true)))
 [GOOD] (define-fun q1_model45 ((x!0 Bool)) Bool
-          (ite (and (= x!0 false)) true
-          false)
+          false
        )
 [GOOD] (define-fun q1_model45_reject () Bool
           (exists ((x!0 Bool))
@@ -1315,15 +1311,14 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const (Array Bool Bool)) false) false true)))
+[RECV] ((q1 ((as const (Array Bool Bool)) false)))
 [SEND] (get-value (q2))
 [RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) true false true)
               true
               true
               true)))
 [GOOD] (define-fun q1_model46 ((x!0 Bool)) Bool
-          (ite (and (= x!0 false)) true
-          false)
+          false
        )
 [GOOD] (define-fun q1_model46_reject () Bool
           (exists ((x!0 Bool))
@@ -1347,23 +1342,20 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const (Array Bool Bool)) false)))
+[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) false false false)
-              false
-              true
-              false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) false true true)))
 [GOOD] (define-fun q1_model47 ((x!0 Bool)) Bool
-          false
+          (ite (and (= x!0 true)) true
+          false)
        )
 [GOOD] (define-fun q1_model47_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model47 x!0))))
 [GOOD] (define-fun q2_model47 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 false) (= x!1 true)) false
-          (ite (and (= x!0 false) (= x!1 false)) false
-          true))
+          (ite (and (= x!0 false) (= x!1 true)) true
+          false)
        )
 [GOOD] (define-fun q2_model47_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1412,10 +1404,10 @@
 [SEND] (get-value (q1))
 [RECV] ((q1 ((as const (Array Bool Bool)) false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) true true false)
-              true
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) true false true)
               false
-              false)))
+              true
+              true)))
 [GOOD] (define-fun q1_model49 ((x!0 Bool)) Bool
           false
        )
@@ -1424,9 +1416,9 @@
                   (distinct (q1         x!0)
                             (q1_model49 x!0))))
 [GOOD] (define-fun q2_model49 ((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)) true
+          (ite (and (= x!0 true) (= x!1 false)) true
+          false))
        )
 [GOOD] (define-fun q2_model49_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1441,24 +1433,19 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const (Array Bool Bool)) false) false true)))
+[RECV] ((q1 ((as const (Array Bool Bool)) false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false true true)
-              true
-              false
-              true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) false false false)))
 [GOOD] (define-fun q1_model50 ((x!0 Bool)) Bool
-          (ite (and (= x!0 false)) true
-          false)
+          false
        )
 [GOOD] (define-fun q1_model50_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model50 x!0))))
 [GOOD] (define-fun q2_model50 ((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))
+          (ite (and (= x!0 false) (= x!1 false)) false
+          true)
        )
 [GOOD] (define-fun q2_model50_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1473,19 +1460,20 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const (Array Bool Bool)) true)))
+[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) true false true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) false false false)))
 [GOOD] (define-fun q1_model51 ((x!0 Bool)) Bool
-          true
+          (ite (and (= x!0 true)) true
+          false)
        )
 [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 true) (= x!1 false)) true
-          false)
+          (ite (and (= x!0 false) (= x!1 false)) false
+          true)
        )
 [GOOD] (define-fun q2_model51_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1500,23 +1488,24 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const (Array Bool Bool)) true)))
+[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) true false true)
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) false false false)
               true
               true
-              true)))
+              false)))
 [GOOD] (define-fun q1_model52 ((x!0 Bool)) Bool
-          true
+          (ite (and (= x!0 true)) true
+          false)
        )
 [GOOD] (define-fun q1_model52_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model52 x!0))))
 [GOOD] (define-fun q2_model52 ((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 true) (= x!1 true)) false
+          (ite (and (= x!0 false) (= x!1 false)) false
+          true))
        )
 [GOOD] (define-fun q2_model52_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1531,19 +1520,23 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const (Array Bool Bool)) true)))
+[RECV] ((q1 ((as const (Array Bool Bool)) false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) false false true)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) false true false)
+              true
+              true
+              false)))
 [GOOD] (define-fun q1_model53 ((x!0 Bool)) Bool
-          true
+          false
        )
 [GOOD] (define-fun q1_model53_reject () Bool
           (exists ((x!0 Bool))
                   (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 false)) true
-          false)
+          (ite (and (= x!0 true) (= x!1 true)) false
+          (ite (and (= x!0 false) (= x!1 true)) false
+          true))
        )
 [GOOD] (define-fun q2_model53_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1560,9 +1553,9 @@
 [SEND] (get-value (q1))
 [RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false false true)
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) true false true)
               false
-              true
+              false
               true)))
 [GOOD] (define-fun q1_model54 ((x!0 Bool)) Bool
           true
@@ -1572,8 +1565,8 @@
                   (distinct (q1         x!0)
                             (q1_model54 x!0))))
 [GOOD] (define-fun q2_model54 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 false) (= x!1 true)) true
           (ite (and (= x!0 false) (= x!1 false)) true
+          (ite (and (= x!0 true) (= x!1 false)) true
           false))
        )
 [GOOD] (define-fun q2_model54_reject () Bool
@@ -1591,7 +1584,7 @@
 [SEND] (get-value (q1))
 [RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) true false false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) true true false)))
 [GOOD] (define-fun q1_model55 ((x!0 Bool)) Bool
           true
        )
@@ -1600,7 +1593,7 @@
                   (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 false)) false
+          (ite (and (= x!0 true) (= x!1 true)) false
           true)
        )
 [GOOD] (define-fun q2_model55_reject () Bool
@@ -1616,19 +1609,23 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const (Array Bool Bool)) true)))
+[RECV] ((q1 ((as const (Array Bool Bool)) false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) true true true)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false true true)
+              false
+              false
+              true)))
 [GOOD] (define-fun q1_model56 ((x!0 Bool)) Bool
-          true
+          false
        )
 [GOOD] (define-fun q1_model56_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model56 x!0))))
 [GOOD] (define-fun q2_model56 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 true)) true
-          false)
+          (ite (and (= x!0 false) (= x!1 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))
@@ -1643,19 +1640,24 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const (Array Bool Bool)) true)))
+[RECV] ((q1 (store ((as const (Array Bool Bool)) false) false true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) false true true)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) true true false)
+              true
+              false
+              false)))
 [GOOD] (define-fun q1_model57 ((x!0 Bool)) Bool
-          true
+          (ite (and (= x!0 false)) true
+          false)
        )
 [GOOD] (define-fun q1_model57_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model57 x!0))))
 [GOOD] (define-fun q2_model57 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 false) (= x!1 true)) true
-          false)
+          (ite (and (= x!0 true) (= x!1 false)) false
+          (ite (and (= x!0 true) (= x!1 true)) false
+          true))
        )
 [GOOD] (define-fun q2_model57_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1670,23 +1672,23 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const (Array Bool Bool)) true)))
+[RECV] ((q1 ((as const (Array Bool Bool)) false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false true true)
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) false false false)
               true
               false
-              true)))
+              false)))
 [GOOD] (define-fun q1_model58 ((x!0 Bool)) Bool
-          true
+          false
        )
 [GOOD] (define-fun q1_model58_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model58 x!0))))
 [GOOD] (define-fun q2_model58 ((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))
+          (ite (and (= x!0 true) (= x!1 false)) false
+          (ite (and (= x!0 false) (= x!1 false)) false
+          true))
        )
 [GOOD] (define-fun q2_model58_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1703,10 +1705,10 @@
 [SEND] (get-value (q1))
 [RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false true true)
-              false
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) false false false)
+              true
               false
-              true)))
+              false)))
 [GOOD] (define-fun q1_model59 ((x!0 Bool)) Bool
           (ite (and (= x!0 true)) true
           false)
@@ -1716,9 +1718,9 @@
                   (distinct (q1         x!0)
                             (q1_model59 x!0))))
 [GOOD] (define-fun q2_model59 ((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)) false
+          (ite (and (= x!0 false) (= x!1 false)) false
+          true))
        )
 [GOOD] (define-fun q2_model59_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1733,24 +1735,19 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const (Array Bool Bool)) false) false true)))
+[RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false true true)
-              false
-              false
-              true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) false true true)))
 [GOOD] (define-fun q1_model60 ((x!0 Bool)) Bool
-          (ite (and (= x!0 false)) true
-          false)
+          true
        )
 [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 false) (= x!1 false)) true
           (ite (and (= x!0 false) (= x!1 true)) true
-          false))
+          false)
        )
 [GOOD] (define-fun q2_model60_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1765,19 +1762,24 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const (Array Bool Bool)) true)))
+[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) true true false)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) true true false)
+              true
+              false
+              false)))
 [GOOD] (define-fun q1_model61 ((x!0 Bool)) Bool
-          true
+          (ite (and (= x!0 true)) true
+          false)
        )
 [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 true) (= x!1 false)) false
           (ite (and (= x!0 true) (= x!1 true)) false
-          true)
+          true))
        )
 [GOOD] (define-fun q2_model61_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1794,10 +1796,10 @@
 [SEND] (get-value (q1))
 [RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false false true)
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) true true false)
               true
               false
-              true)))
+              false)))
 [GOOD] (define-fun q1_model62 ((x!0 Bool)) Bool
           true
        )
@@ -1806,9 +1808,9 @@
                   (distinct (q1         x!0)
                             (q1_model62 x!0))))
 [GOOD] (define-fun q2_model62 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 false)) true
-          (ite (and (= x!0 false) (= x!1 false)) true
-          false))
+          (ite (and (= x!0 true) (= x!1 false)) false
+          (ite (and (= x!0 true) (= x!1 true)) false
+          true))
        )
 [GOOD] (define-fun q2_model62_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1823,19 +1825,20 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const (Array Bool Bool)) true)))
+[RECV] ((q1 (store ((as const (Array Bool Bool)) false) false true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) false false false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) false false true)))
 [GOOD] (define-fun q1_model63 ((x!0 Bool)) Bool
-          true
+          (ite (and (= x!0 false)) true
+          false)
        )
 [GOOD] (define-fun q1_model63_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model63 x!0))))
 [GOOD] (define-fun q2_model63 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 false) (= x!1 false)) false
-          true)
+          (ite (and (= x!0 false) (= x!1 false)) true
+          false)
        )
 [GOOD] (define-fun q2_model63_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1852,10 +1855,7 @@
 [SEND] (get-value (q1))
 [RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) false false false)
-              true
-              false
-              false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) false false true)))
 [GOOD] (define-fun q1_model64 ((x!0 Bool)) Bool
           true
        )
@@ -1864,9 +1864,8 @@
                   (distinct (q1         x!0)
                             (q1_model64 x!0))))
 [GOOD] (define-fun q2_model64 ((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 false) (= x!1 false)) true
+          false)
        )
 [GOOD] (define-fun q2_model64_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1888,125 +1887,129 @@
   q1 _ = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 True  False = False
-  q2 False False = False
-  q2 _     _     = True
+  q2 False False = True
+  q2 _     _     = False
 Solution #2:
   q1 :: Bool -> Bool
-  q1 _ = True
+  q1 False = True
+  q1 _     = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 False False = False
-  q2 _     _     = True
+  q2 False False = True
+  q2 _     _     = False
 Solution #3:
   q1 :: Bool -> Bool
   q1 _ = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 True  False = True
-  q2 False False = True
-  q2 _     _     = False
+  q2 True False = False
+  q2 True True  = False
+  q2 _    _     = True
 Solution #4:
   q1 :: Bool -> Bool
-  q1 _ = True
+  q1 True = True
+  q1 _    = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True True = False
-  q2 _    _    = True
+  q2 True False = False
+  q2 True True  = False
+  q2 _    _     = True
 Solution #5:
   q1 :: Bool -> Bool
-  q1 False = True
-  q1 _     = False
+  q1 _ = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 False False = True
-  q2 False True  = True
-  q2 _     _     = False
+  q2 False True = True
+  q2 _     _    = False
 Solution #6:
   q1 :: Bool -> Bool
   q1 True = True
   q1 _    = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 False False = True
-  q2 False True  = True
-  q2 _     _     = False
+  q2 True  False = False
+  q2 False False = False
+  q2 _     _     = True
 Solution #7:
   q1 :: Bool -> Bool
-  q1 _ = True
+  q1 _ = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True  False = True
-  q2 False True  = True
-  q2 _     _     = False
+  q2 True  False = False
+  q2 False False = False
+  q2 _     _     = True
 Solution #8:
   q1 :: Bool -> Bool
-  q1 _ = True
+  q1 False = True
+  q1 _     = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 False True = True
-  q2 _     _    = False
+  q2 True False = False
+  q2 True True  = False
+  q2 _    _     = True
 Solution #9:
   q1 :: Bool -> Bool
-  q1 _ = True
+  q1 _ = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True True = True
-  q2 _    _    = False
+  q2 False False = True
+  q2 False True  = True
+  q2 _     _     = False
 Solution #10:
   q1 :: Bool -> Bool
   q1 _ = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 True False = False
-  q2 _    _     = True
+  q2 True True = False
+  q2 _    _    = True
 Solution #11:
   q1 :: Bool -> Bool
   q1 _ = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 False True  = True
   q2 False False = True
+  q2 True  False = True
   q2 _     _     = False
 Solution #12:
   q1 :: Bool -> Bool
-  q1 _ = True
+  q1 _ = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 False False = True
-  q2 _     _     = False
+  q2 True  True = False
+  q2 False True = False
+  q2 _     _    = True
 Solution #13:
   q1 :: Bool -> Bool
-  q1 _ = True
+  q1 True = True
+  q1 _    = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True True  = True
-  q2 True False = True
-  q2 _    _     = False
+  q2 True  True  = False
+  q2 False False = False
+  q2 _     _     = True
 Solution #14:
   q1 :: Bool -> Bool
-  q1 _ = True
+  q1 True = True
+  q1 _    = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True False = True
-  q2 _    _     = False
+  q2 False False = False
+  q2 _     _     = True
 Solution #15:
   q1 :: Bool -> Bool
-  q1 False = True
-  q1 _     = False
+  q1 _ = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True  False = True
-  q2 False True  = True
-  q2 _     _     = False
+  q2 False False = False
+  q2 _     _     = True
 Solution #16:
   q1 :: Bool -> Bool
   q1 _ = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True False = False
-  q2 True True  = False
-  q2 _    _     = True
+  q2 False True  = True
+  q2 True  False = True
+  q2 _     _     = False
 Solution #17:
   q1 :: Bool -> Bool
   q1 True = True
@@ -2018,16 +2021,15 @@
   q2 _     _     = True
 Solution #18:
   q1 :: Bool -> Bool
-  q1 _ = False
+  q1 True = True
+  q1 _    = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 False True  = False
-  q2 False False = False
-  q2 _     _     = True
+  q2 False True = True
+  q2 _     _    = False
 Solution #19:
   q1 :: Bool -> Bool
-  q1 False = True
-  q1 _     = False
+  q1 _ = False
 
   q2 :: Bool -> Bool -> Bool
   q2 True True  = True
@@ -2035,76 +2037,72 @@
   q2 _    _     = False
 Solution #20:
   q1 :: Bool -> Bool
-  q1 False = True
-  q1 _     = False
+  q1 _ = False
 
   q2 :: Bool -> Bool -> Bool
   q2 True False = True
   q2 _    _     = False
 Solution #21:
   q1 :: Bool -> Bool
-  q1 False = True
-  q1 _     = False
+  q1 _ = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True True = True
-  q2 _    _    = False
+  q2 False True = True
+  q2 _     _    = False
 Solution #22:
   q1 :: Bool -> Bool
-  q1 False = True
-  q1 _     = False
+  q1 _ = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True  True = True
-  q2 False True = True
-  q2 _     _    = False
+  q2 True True = False
+  q2 _    _    = True
 Solution #23:
   q1 :: Bool -> Bool
-  q1 False = True
-  q1 _     = False
+  q1 True = False
+  q1 _    = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 False True = True
-  q2 _     _    = False
+  q2 True True = False
+  q2 _    _    = True
 Solution #24:
   q1 :: Bool -> Bool
-  q1 _ = False
+  q1 True = False
+  q1 _    = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 False True  = True
   q2 True  False = True
+  q2 False False = True
   q2 _     _     = False
 Solution #25:
   q1 :: Bool -> Bool
-  q1 True = True
-  q1 _    = False
+  q1 _ = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 True  False = False
+  q2 True  True  = False
   q2 False False = False
   q2 _     _     = True
 Solution #26:
   q1 :: Bool -> Bool
-  q1 _ = False
+  q1 _ = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 True True = True
-  q2 _    _    = False
+  q2 False False = False
+  q2 _     _     = True
 Solution #27:
   q1 :: Bool -> Bool
-  q1 _ = False
+  q1 _ = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 True  True = True
-  q2 False True = True
-  q2 _     _    = False
+  q2 True  False = False
+  q2 False False = False
+  q2 _     _     = True
 Solution #28:
   q1 :: Bool -> Bool
-  q1 True = True
-  q1 _    = False
+  q1 False = True
+  q1 _     = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True  True  = False
+  q2 True  False = False
   q2 False False = False
   q2 _     _     = True
 Solution #29:
@@ -2113,59 +2111,63 @@
   q1 _     = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 _ _ = False
+  q2 True True = True
+  q2 _    _    = False
 Solution #30:
   q1 :: Bool -> Bool
-  q1 True = True
-  q1 _    = False
+  q1 _ = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True False = True
-  q2 _    _     = False
+  q2 True True = True
+  q2 _    _    = False
 Solution #31:
   q1 :: Bool -> Bool
-  q1 _ = False
+  q1 True = True
+  q1 _    = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 False True = True
-  q2 _     _    = False
+  q2 True True = True
+  q2 _    _    = False
 Solution #32:
   q1 :: Bool -> Bool
-  q1 _ = False
+  q1 _ = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 False False = False
-  q2 _     _     = True
+  q2 True True = True
+  q2 _    _    = False
 Solution #33:
   q1 :: Bool -> Bool
-  q1 _ = False
+  q1 _ = True
 
   q2 :: Bool -> Bool -> Bool
   q2 True False = True
   q2 _    _     = False
 Solution #34:
   q1 :: Bool -> Bool
-  q1 True = True
-  q1 _    = False
+  q1 _ = True
 
   q2 :: Bool -> Bool -> Bool
+  q2 False True  = False
   q2 False False = False
   q2 _     _     = True
 Solution #35:
   q1 :: Bool -> Bool
-  q1 True = True
-  q1 _    = False
+  q1 True = False
+  q1 _    = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 False True = True
-  q2 _     _    = False
+  q2 False True  = False
+  q2 False False = False
+  q2 _     _     = True
 Solution #36:
   q1 :: Bool -> Bool
-  q1 True = True
-  q1 _    = False
+  q1 True = False
+  q1 _    = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 _ _ = False
+  q2 True  True  = False
+  q2 False False = False
+  q2 _     _     = True
 Solution #37:
   q1 :: Bool -> Bool
   q1 True = False
@@ -2176,52 +2178,52 @@
   q2 _     _     = True
 Solution #38:
   q1 :: Bool -> Bool
-  q1 True = True
-  q1 _    = False
+  q1 True = False
+  q1 _    = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 True True = True
-  q2 _    _    = False
+  q2 False True = True
+  q2 _     _    = False
 Solution #39:
   q1 :: Bool -> Bool
-  q1 False = True
-  q1 _     = False
+  q1 True = False
+  q1 _    = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 True True = False
-  q2 _    _    = True
+  q2 _ _ = False
 Solution #40:
   q1 :: Bool -> Bool
-  q1 _ = False
+  q1 True = False
+  q1 _    = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 True True = False
-  q2 _    _    = True
+  q2 True False = True
+  q2 _    _     = False
 Solution #41:
   q1 :: Bool -> Bool
   q1 True = True
   q1 _    = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True True = False
-  q2 _    _    = True
+  q2 True False = True
+  q2 _    _     = False
 Solution #42:
   q1 :: Bool -> Bool
-  q1 _ = True
+  q1 True = True
+  q1 _    = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 _ _ = True
+  q2 _ _ = False
 Solution #43:
   q1 :: Bool -> Bool
-  q1 True = True
-  q1 _    = False
+  q1 _ = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 _ _ = True
+  q2 False True = False
+  q2 _     _    = True
 Solution #44:
   q1 :: Bool -> Bool
-  q1 True = False
-  q1 _    = True
+  q1 _ = True
 
   q2 :: Bool -> Bool -> Bool
   q2 _ _ = True
@@ -2231,120 +2233,117 @@
   q1 _    = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 True False = False
-  q2 _    _     = True
+  q2 _ _ = True
 Solution #46:
   q1 :: Bool -> Bool
-  q1 False = True
-  q1 _     = False
+  q1 True = False
+  q1 _    = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 True  False = True
-  q2 False False = True
-  q2 _     _     = False
+  q2 False True = False
+  q2 _     _    = True
 Solution #47:
   q1 :: Bool -> Bool
-  q1 True = False
-  q1 _    = True
+  q1 False = True
+  q1 _     = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 False False = True
-  q2 _     _     = False
+  q2 True False = False
+  q2 _    _     = True
 Solution #48:
   q1 :: Bool -> Bool
   q1 _ = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True  True = False
-  q2 False True = False
-  q2 _     _    = True
+  q2 True False = False
+  q2 _    _     = True
 Solution #49:
   q1 :: Bool -> Bool
-  q1 True = True
-  q1 _    = False
+  q1 _ = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True  False = True
-  q2 False False = True
-  q2 _     _     = False
+  q2 False True  = False
+  q2 True  False = False
+  q2 _     _     = True
 Solution #50:
   q1 :: Bool -> Bool
-  q1 True = True
-  q1 _    = False
+  q1 True = False
+  q1 _    = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 False False = True
-  q2 _     _     = False
+  q2 False True  = False
+  q2 True  False = False
+  q2 _     _     = True
 Solution #51:
   q1 :: Bool -> Bool
   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
 
   q2 :: Bool -> Bool -> Bool
-  q2 False True = False
-  q2 _     _    = True
+  q2 False True  = False
+  q2 True  False = False
+  q2 _     _     = True
 Solution #53:
   q1 :: Bool -> Bool
   q1 True = True
   q1 _    = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 False True = False
-  q2 _     _    = True
+  q2 False True  = False
+  q2 True  False = False
+  q2 _     _     = True
 Solution #54:
   q1 :: Bool -> Bool
-  q1 _ = False
+  q1 True = True
+  q1 _    = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 False True = False
-  q2 _     _    = True
+  q2 True False = False
+  q2 _    _     = True
 Solution #55:
   q1 :: Bool -> Bool
-  q1 _ = True
+  q1 True = True
+  q1 _    = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True  True  = True
-  q2 False False = True
-  q2 _     _     = 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
 Solution #57:
   q1 :: Bool -> Bool
   q1 True = True
   q1 _    = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True False = False
-  q2 _    _     = True
+  q2 True  True = False
+  q2 False True = False
+  q2 _     _    = True
 Solution #58:
   q1 :: Bool -> Bool
   q1 True = True
   q1 _    = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True  True  = True
-  q2 False False = True
-  q2 _     _     = False
+  q2 False True = False
+  q2 _     _    = True
 Solution #59:
   q1 :: Bool -> Bool
-  q1 _ = False
+  q1 True = True
+  q1 _    = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True  True  = True
   q2 False False = True
   q2 _     _     = False
 Solution #60:
@@ -2359,8 +2358,8 @@
   q1 _ = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True False = False
-  q2 _    _     = True
+  q2 False True = False
+  q2 _     _    = True
 Solution #62:
   q1 :: Bool -> Bool
   q1 _ = False
diff --git a/SBVTestSuite/GoldFiles/unint-axioms-empty.gold b/SBVTestSuite/GoldFiles/unint-axioms-empty.gold
--- a/SBVTestSuite/GoldFiles/unint-axioms-empty.gold
+++ b/SBVTestSuite/GoldFiles/unint-axioms-empty.gold
@@ -5,18 +5,15 @@
 [GOOD] (set-option :smtlib2_compliant true)
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
-[GOOD] (set-logic ALL) ; has user-defined sorts, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
-[GOOD] (declare-sort Thing 0)  ; N.B. Uninterpreted sort.
-[GOOD] (declare-fun Thing_witness () Thing)
+[GOOD] (set-logic ALL) ; has user-defined data-types, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] (declare-sort Thing 0) ; N.B. Uninterpreted sort.
 [GOOD] ; --- literal constants ---
 [GOOD] ; --- top level inputs ---
-[GOOD] (declare-fun s2 () Thing) ; tracks user variable "__internal_sbv_s2"
-[GOOD] (declare-fun s3 () Thing) ; tracks user variable "__internal_sbv_s3"
-[GOOD] (declare-fun s5 () Thing)
-[GOOD] (declare-fun s6 () Thing)
+[GOOD] (declare-fun s2 () Thing)
+[GOOD] (declare-fun s3 () Thing)
 [GOOD] ; --- constant tables ---
 [GOOD] ; --- non-constant tables ---
 [GOOD] ; --- uninterpreted constants ---
@@ -30,15 +27,14 @@
                                  (let ((l1_s2 (thingMerge l1_s0 l1_s1)))
                                  (let ((l1_s3 (distinct l1_s0 l1_s2)))
                                  l1_s3))))
-[GOOD] (define-fun s4 () Thing (thingMerge s2 s3))
-[GOOD] (define-fun s7 () Bool (= s5 s6))
-[GOOD] (define-fun s8 () Bool (thingCompare s5 s6))
-[GOOD] (define-fun s9 () Bool (=> s7 s8))
+[GOOD] (define-fun s4 () Bool (= s2 s3))
+[GOOD] (define-fun s5 () Bool (thingCompare s2 s3))
+[GOOD] (define-fun s6 () Bool (=> s4 s5))
 [GOOD] ; --- delayedEqualities ---
 [GOOD] ; --- formula ---
 [GOOD] (assert s0)
 [GOOD] (assert s1)
-[GOOD] (assert (not s9))
+[GOOD] (assert (not s6))
 [SEND] (check-sat)
 [RECV] unsat
 *** Solver   : Z3
diff --git a/SBVTestSuite/GoldFiles/unint-axioms-query.gold b/SBVTestSuite/GoldFiles/unint-axioms-query.gold
--- a/SBVTestSuite/GoldFiles/unint-axioms-query.gold
+++ b/SBVTestSuite/GoldFiles/unint-axioms-query.gold
@@ -5,12 +5,11 @@
 [GOOD] (set-option :smtlib2_compliant true)
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
-[GOOD] (set-logic ALL) ; has user-defined sorts, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
-[GOOD] (declare-sort B 0)  ; N.B. Uninterpreted sort.
-[GOOD] (declare-fun B_witness () B)
+[GOOD] (set-logic ALL) ; has user-defined data-types, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] (declare-sort B 0) ; N.B. Uninterpreted sort.
 [GOOD] ; --- literal constants ---
 [GOOD] ; --- top level inputs ---
 [GOOD] (declare-fun s0 () B) ; tracks user variable "p"
diff --git a/SBVTestSuite/GoldFiles/unint-axioms.gold b/SBVTestSuite/GoldFiles/unint-axioms.gold
--- a/SBVTestSuite/GoldFiles/unint-axioms.gold
+++ b/SBVTestSuite/GoldFiles/unint-axioms.gold
@@ -5,12 +5,11 @@
 [GOOD] (set-option :smtlib2_compliant true)
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
-[GOOD] (set-logic ALL) ; has user-defined sorts, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
-[GOOD] (declare-sort Bitstring 0)  ; N.B. Uninterpreted sort.
-[GOOD] (declare-fun Bitstring_witness () Bitstring)
+[GOOD] (set-logic ALL) ; has user-defined data-types, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] (declare-sort Bitstring 0) ; N.B. Uninterpreted sort.
 [GOOD] ; --- literal constants ---
 [GOOD] ; --- top level inputs ---
 [GOOD] (declare-fun s1 () Bitstring) ; tracks user variable "p"
diff --git a/SBVTestSuite/GoldFiles/unint-sort01.gold b/SBVTestSuite/GoldFiles/unint-sort01.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/unint-sort01.gold
@@ -0,0 +1,37 @@
+Solution #1:
+  l  = L_1 :: L
+  l0 = L_0 :: L
+  l1 = L_1 :: L
+  x  =   1 :: Integer
+
+  len :: L -> Integer
+  len L_1 = 1
+  len _   = 0
+Solution #2:
+  l  = L_0 :: L
+  l0 = L_0 :: L
+  l1 = L_1 :: L
+  x  =   0 :: Integer
+
+  len :: L -> Integer
+  len L_1 = 1
+  len _   = 0
+Solution #3:
+  l  = L_1 :: L
+  l0 = L_0 :: L
+  l1 = L_1 :: L
+  x  =   0 :: Integer
+
+  len :: L -> Integer
+  len L_1 = 1
+  len _   = 0
+Solution #4:
+  l  = L_0 :: L
+  l0 = L_0 :: L
+  l1 = L_1 :: L
+  x  =   1 :: Integer
+
+  len :: L -> Integer
+  len L_1 = 1
+  len _   = 0
+Found 4 different solutions.
diff --git a/SBVTestSuite/GoldFiles/uninterpreted-1a.gold b/SBVTestSuite/GoldFiles/uninterpreted-1a.gold
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/GoldFiles/uninterpreted-1a.gold
@@ -0,0 +1,53 @@
+** Calling: z3 -nw -in -smt2
+[GOOD] ; Automatically generated by SBV. Do not edit.
+[GOOD] (set-option :print-success true)
+[GOOD] (set-option :global-declarations true)
+[GOOD] (set-option :smtlib2_compliant true)
+[GOOD] (set-option :diagnostic-output-channel "stdout")
+[GOOD] (set-option :produce-models true)
+[GOOD] (set-logic QF_UFBV)
+[GOOD] ; --- tuples ---
+[GOOD] ; --- sums ---
+[GOOD] ; --- literal constants ---
+[GOOD] ; --- top level inputs ---
+[GOOD] (declare-fun s0 () (_ BitVec 8))
+[GOOD] (declare-fun s1 () (_ BitVec 16))
+[GOOD] (declare-fun s2 () (_ BitVec 16))
+[GOOD] ; --- constant tables ---
+[GOOD] ; --- non-constant tables ---
+[GOOD] ; --- uninterpreted constants ---
+[GOOD] (declare-fun g ((_ BitVec 8) (_ BitVec 16)) (_ BitVec 32))
+[GOOD] ; --- user defined functions ---
+[GOOD] ; --- assignments ---
+[GOOD] (define-fun s3 () Bool (= s1 s2))
+[GOOD] (define-fun s4 () (_ BitVec 32) (g s0 s1))
+[GOOD] (define-fun s5 () (_ BitVec 32) (g s0 s2))
+[GOOD] (define-fun s6 () Bool (= s4 s5))
+[GOOD] (define-fun s7 () Bool (=> s3 s6))
+[GOOD] ; --- delayedEqualities ---
+[GOOD] ; --- formula ---
+[GOOD] (assert s7)
+[SEND] (check-sat)
+[RECV] sat
+[SEND] (get-value (s0))
+[RECV] ((s0 #x00))
+[SEND] (get-value (s1))
+[RECV] ((s1 #x0000))
+[SEND] (get-value (s2))
+[RECV] ((s2 #x0000))
+[GOOD] (set-option :pp.max_depth      4294967295)
+[GOOD] (set-option :pp.min_alias_size 4294967295)
+[GOOD] (set-option :model.inline_def  true      )
+[SEND] (get-value (g))
+[RECV] ((g ((as const (Array (_ BitVec 8) (_ BitVec 16) (_ BitVec 32))) #x00000000)))
+*** Solver   : Z3
+*** Exit code: ExitSuccess
+
+ FINAL:Satisfiable. Model:
+  s0 = 0 :: Int8
+  s1 = 0 :: Word16
+  s2 = 0 :: Word16
+
+  g :: (Int8, Word16) -> Word32
+  g (_, _) = 0
+DONE!
diff --git a/SBVTestSuite/GoldFiles/uninterpreted-3.gold b/SBVTestSuite/GoldFiles/uninterpreted-3.gold
--- a/SBVTestSuite/GoldFiles/uninterpreted-3.gold
+++ b/SBVTestSuite/GoldFiles/uninterpreted-3.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/uninterpreted-3a.gold b/SBVTestSuite/GoldFiles/uninterpreted-3a.gold
--- a/SBVTestSuite/GoldFiles/uninterpreted-3a.gold
+++ b/SBVTestSuite/GoldFiles/uninterpreted-3a.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_UFBV)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/uninterpreted-4.gold b/SBVTestSuite/GoldFiles/uninterpreted-4.gold
--- a/SBVTestSuite/GoldFiles/uninterpreted-4.gold
+++ b/SBVTestSuite/GoldFiles/uninterpreted-4.gold
@@ -5,12 +5,11 @@
 [GOOD] (set-option :smtlib2_compliant true)
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
-[GOOD] (set-logic ALL) ; has user-defined sorts, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
-[GOOD] (declare-sort Q 0)  ; N.B. Uninterpreted sort.
-[GOOD] (declare-fun Q_witness () Q)
+[GOOD] (set-logic ALL) ; has user-defined data-types, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] (declare-sort Q 0) ; N.B. Uninterpreted sort.
 [GOOD] ; --- literal constants ---
 [GOOD] ; --- top level inputs ---
 [GOOD] ; --- constant tables ---
diff --git a/SBVTestSuite/GoldFiles/uninterpreted-4a.gold b/SBVTestSuite/GoldFiles/uninterpreted-4a.gold
--- a/SBVTestSuite/GoldFiles/uninterpreted-4a.gold
+++ b/SBVTestSuite/GoldFiles/uninterpreted-4a.gold
@@ -5,12 +5,11 @@
 [GOOD] (set-option :smtlib2_compliant true)
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
-[GOOD] (set-logic ALL) ; has user-defined sorts, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
-[GOOD] (declare-sort Q 0)  ; N.B. Uninterpreted sort.
-[GOOD] (declare-fun Q_witness () Q)
+[GOOD] (set-logic ALL) ; has user-defined data-types, using catch-all.
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
+[GOOD] ; --- ADTs  --- 
+[GOOD] (declare-sort Q 0) ; N.B. Uninterpreted sort.
 [GOOD] ; --- literal constants ---
 [GOOD] ; --- top level inputs ---
 [GOOD] ; --- constant tables ---
diff --git a/SBVTestSuite/GoldFiles/validate_0.gold b/SBVTestSuite/GoldFiles/validate_0.gold
--- a/SBVTestSuite/GoldFiles/validate_0.gold
+++ b/SBVTestSuite/GoldFiles/validate_0.gold
@@ -6,7 +6,6 @@
 [ISSUE] (set-option :diagnostic-output-channel "stdout")
 [ISSUE] (set-option :produce-models true)
 [ISSUE] (set-logic QF_BV)
-[ISSUE] ; --- uninterpreted sorts ---
 [ISSUE] ; --- tuples ---
 [ISSUE] ; --- sums ---
 [ISSUE] ; --- literal constants ---
@@ -28,7 +27,6 @@
 [RECV] ((s0 #x0))
 *** Solver   : ABC
 *** Exit code: ExitSuccess
-*** Std-err  : Cmd warning: redefining '%graft'
 [VALIDATE] Validating the model. Assignment:
 [VALIDATE]       x = 0 :: Word8
 [VALIDATE] There are no constraints to check.
diff --git a/SBVTestSuite/GoldFiles/validate_1.gold b/SBVTestSuite/GoldFiles/validate_1.gold
--- a/SBVTestSuite/GoldFiles/validate_1.gold
+++ b/SBVTestSuite/GoldFiles/validate_1.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_FP)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/validate_2.gold b/SBVTestSuite/GoldFiles/validate_2.gold
--- a/SBVTestSuite/GoldFiles/validate_2.gold
+++ b/SBVTestSuite/GoldFiles/validate_2.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic QF_FP)
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
@@ -26,11 +25,11 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (fp #b0 #x00 #b00000001001110100110010)))
+[RECV] ((s0 (fp #b0 #x00 #b00000000101010111000111)))
 *** Solver   : Z3
 *** Exit code: ExitSuccess
 [VALIDATE] Validating the model. Assignment:
-[VALIDATE]       x = 5.6391e-41 :: Float
+[VALIDATE]       x = 3.0771e-41 :: Float
 [VALIDATE] There are no constraints to check.
 [VALIDATE] Validating outputs.
 
@@ -39,7 +38,7 @@
 *** 
 *** Assignment:
 *** 
-***       x = 5.6391e-41 :: Float
+***       x = 3.0771e-41 :: Float
 *** 
 *** Floating point FMA operation is not supported concretely.
 *** 
@@ -49,4 +48,4 @@
 *** Alleged model:
 ***
 *** Satisfiable. Model:
-***   x = 5.6391e-41 :: Float
+***   x = 3.0771e-41 :: Float
diff --git a/SBVTestSuite/GoldFiles/validate_3.gold b/SBVTestSuite/GoldFiles/validate_3.gold
--- a/SBVTestSuite/GoldFiles/validate_3.gold
+++ b/SBVTestSuite/GoldFiles/validate_3.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/validate_4.gold b/SBVTestSuite/GoldFiles/validate_4.gold
--- a/SBVTestSuite/GoldFiles/validate_4.gold
+++ b/SBVTestSuite/GoldFiles/validate_4.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/validate_5.gold b/SBVTestSuite/GoldFiles/validate_5.gold
--- a/SBVTestSuite/GoldFiles/validate_5.gold
+++ b/SBVTestSuite/GoldFiles/validate_5.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/validate_6.gold b/SBVTestSuite/GoldFiles/validate_6.gold
--- a/SBVTestSuite/GoldFiles/validate_6.gold
+++ b/SBVTestSuite/GoldFiles/validate_6.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has unbounded values, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/GoldFiles/validate_7.gold b/SBVTestSuite/GoldFiles/validate_7.gold
--- a/SBVTestSuite/GoldFiles/validate_7.gold
+++ b/SBVTestSuite/GoldFiles/validate_7.gold
@@ -6,7 +6,6 @@
 [GOOD] (set-option :diagnostic-output-channel "stdout")
 [GOOD] (set-option :produce-models true)
 [GOOD] (set-logic ALL) ; has quantified booleans, using catch-all.
-[GOOD] ; --- uninterpreted sorts ---
 [GOOD] ; --- tuples ---
 [GOOD] ; --- sums ---
 [GOOD] ; --- literal constants ---
diff --git a/SBVTestSuite/SBVTest.hs b/SBVTestSuite/SBVTest.hs
--- a/SBVTestSuite/SBVTest.hs
+++ b/SBVTestSuite/SBVTest.hs
@@ -9,14 +9,17 @@
 -- Main entry point to the test suite
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE ScopedTypeVariables #-}
-
 {-# OPTIONS_GHC -Wall -Werror #-}
 
 module Main(main) where
 
 import Test.Tasty
 
+import qualified TestSuite.ADT.ADT
+import qualified TestSuite.ADT.Expr
+import qualified TestSuite.ADT.MutRec
+import qualified TestSuite.ADT.PExpr
+import qualified TestSuite.ADT.Registration
 import qualified TestSuite.Arrays.InitVals
 import qualified TestSuite.Arrays.Memory
 import qualified TestSuite.Arrays.Query
@@ -45,7 +48,9 @@
 import qualified TestSuite.Basics.QRem
 import qualified TestSuite.Basics.Quantifiers
 import qualified TestSuite.Basics.Recursive
+import qualified TestSuite.Basics.TPCaching
 import qualified TestSuite.Basics.Set
+import qualified TestSuite.Basics.SmtFunctionUnique
 import qualified TestSuite.Basics.SmallShifts
 import qualified TestSuite.Basics.SquashReals
 import qualified TestSuite.Basics.String
@@ -60,12 +65,21 @@
 import qualified TestSuite.CantTypeCheck.Misc
 import qualified TestSuite.Char.Char
 import qualified TestSuite.CodeGeneration.AddSub
+import qualified TestSuite.CodeGeneration.ArbitraryBits
+import qualified TestSuite.CodeGeneration.ArbitraryFloats
+import qualified TestSuite.CodeGeneration.ArrayCaptures
+import qualified TestSuite.CodeGeneration.Boundaries
 import qualified TestSuite.CodeGeneration.CgTests
 import qualified TestSuite.CodeGeneration.CRC_USB5
+import qualified TestSuite.CodeGeneration.ExactNumbers
 import qualified TestSuite.CodeGeneration.Fibonacci
 import qualified TestSuite.CodeGeneration.Floats
 import qualified TestSuite.CodeGeneration.GCD
 import qualified TestSuite.CodeGeneration.PopulationCount
+import qualified TestSuite.CodeGeneration.LibraryBuild
+import qualified TestSuite.CodeGeneration.PseudoBoolean
+import qualified TestSuite.CodeGeneration.RegExp
+import qualified TestSuite.CodeGeneration.ScalarSafety
 import qualified TestSuite.CodeGeneration.Uninterpreted
 import qualified TestSuite.CRC.CCITT
 import qualified TestSuite.CRC.CCITT_Unidir
@@ -112,6 +126,7 @@
 import qualified TestSuite.Queries.Int_Z3
 import qualified TestSuite.Queries.Interpolants
 import qualified TestSuite.Queries.Lists
+import qualified TestSuite.Queries.Registration
 import qualified TestSuite.Queries.Strings
 import qualified TestSuite.Queries.Sums
 import qualified TestSuite.Queries.Tables
@@ -120,16 +135,26 @@
 import qualified TestSuite.Queries.UISatEx
 import qualified TestSuite.Queries.Uninterpreted
 import qualified TestSuite.QuickCheck.QC
+import qualified TestSuite.CompileTests.SCase
+import qualified TestSuite.CompileTests.PCase
 import qualified TestSuite.Transformers.SymbolicEval
 import qualified TestSuite.Uninterpreted.AUF
 import qualified TestSuite.Uninterpreted.Axioms
+import qualified TestSuite.Uninterpreted.EUFLogic
 import qualified TestSuite.Uninterpreted.Function
 import qualified TestSuite.Uninterpreted.Sort
 import qualified TestSuite.Uninterpreted.Uninterpreted
 
 main :: IO ()
-main = defaultMain $ testGroup "SBV" [
-                        TestSuite.Arrays.InitVals.tests
+main = do sCaseTests <- TestSuite.CompileTests.SCase.tests
+          pCaseTests <- TestSuite.CompileTests.PCase.tests
+          defaultMain $ testGroup "SBV" [
+                        TestSuite.ADT.ADT.tests
+                      , TestSuite.ADT.Expr.tests
+                      , TestSuite.ADT.MutRec.tests
+                      , TestSuite.ADT.PExpr.tests
+                      , TestSuite.ADT.Registration.tests
+                      , TestSuite.Arrays.InitVals.tests
                       , TestSuite.Arrays.Memory.tests
                       , TestSuite.Arrays.Query.tests
                       , TestSuite.Arrays.Caching.tests
@@ -159,7 +184,9 @@
                       , TestSuite.Basics.QRem.tests
                       , TestSuite.Basics.Quantifiers.tests
                       , TestSuite.Basics.Recursive.tests
+                      , TestSuite.Basics.TPCaching.tests
                       , TestSuite.Basics.Set.tests
+                      , TestSuite.Basics.SmtFunctionUnique.tests
                       , TestSuite.Basics.SmallShifts.tests
                       , TestSuite.Basics.SquashReals.tests
                       , TestSuite.Basics.String.tests
@@ -174,12 +201,21 @@
                       , TestSuite.CantTypeCheck.Misc.tests
                       , TestSuite.Char.Char.tests
                       , TestSuite.CodeGeneration.AddSub.tests
+                      , TestSuite.CodeGeneration.ArbitraryBits.tests
+                      , TestSuite.CodeGeneration.ArbitraryFloats.tests
+                      , TestSuite.CodeGeneration.ArrayCaptures.tests
+                      , TestSuite.CodeGeneration.Boundaries.tests
                       , TestSuite.CodeGeneration.CgTests.tests
                       , TestSuite.CodeGeneration.CRC_USB5.tests
+                      , TestSuite.CodeGeneration.ExactNumbers.tests
                       , TestSuite.CodeGeneration.Fibonacci.tests
                       , TestSuite.CodeGeneration.Floats.tests
                       , TestSuite.CodeGeneration.GCD.tests
                       , TestSuite.CodeGeneration.PopulationCount.tests
+                      , TestSuite.CodeGeneration.LibraryBuild.tests
+                      , TestSuite.CodeGeneration.PseudoBoolean.tests
+                      , TestSuite.CodeGeneration.RegExp.tests
+                      , TestSuite.CodeGeneration.ScalarSafety.tests
                       , TestSuite.CodeGeneration.Uninterpreted.tests
                       , TestSuite.CRC.CCITT.tests
                       , TestSuite.CRC.CCITT_Unidir.tests
@@ -226,6 +262,7 @@
                       , TestSuite.Queries.Int_Mathsat.tests
                       , TestSuite.Queries.Int_Yices.tests
                       , TestSuite.Queries.Lists.tests
+                      , TestSuite.Queries.Registration.tests
                       , TestSuite.Queries.Strings.tests
                       , TestSuite.Queries.Sums.tests
                       , TestSuite.Queries.Tables.tests
@@ -240,4 +277,7 @@
                       , TestSuite.Uninterpreted.Function.tests
                       , TestSuite.Uninterpreted.Sort.tests
                       , TestSuite.Uninterpreted.Uninterpreted.tests
+                      , TestSuite.Uninterpreted.EUFLogic.tests
+                      , sCaseTests
+                      , pCaseTests
                       ]
diff --git a/SBVTestSuite/TestSuite/ADT/ADT.hs b/SBVTestSuite/TestSuite/ADT/ADT.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/ADT/ADT.hs
@@ -0,0 +1,172 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : TestSuite.ADT.ADT
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Testing ADTs
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE FlexibleInstances   #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -Wno-unused-top-binds #-}
+
+module TestSuite.ADT.ADT(tests) where
+
+import Utils.SBVTestFramework
+import Data.SBV.Control
+import Data.SBV.Maybe
+import Data.SBV.Either (sRight)
+import Data.SBV.Set    (insert, empty)
+import Data.SBV.Tuple  (tuple)
+
+data ADT  = AEmpty
+          | ABool     Bool
+          | AInteger  Integer
+          | AWord8    Word8
+          | AWord16   Word16
+          | AWord32   Word32
+          | AWord64   Word64
+          | AInt8     Int8
+          | AInt16    Int16
+          | AInt32    Int32
+          | AInt64    Int64
+          | AWord1    (WordN  1)
+          | AWord5    (WordN  5)
+          | AWord30   (WordN 30)
+          | AInt1     (IntN   1)
+          | AInt5     (IntN   5)
+          | AInt30    (IntN  30)
+          | AReal     AlgReal
+          | AFloat    Float
+          | ADouble   Double
+          | AFP       (FloatingPoint 5 12)
+          | AString   String
+          | AList     [Integer]
+          | ATuple    (Double, [(WordN 5, [Float])])
+          | AMaybe    (Maybe (AlgReal, Float, (Either Integer Float, [Bool])))
+          | AEither   (Either (Maybe Integer, Bool) [Integer])
+          | APair     ADT ADT
+          | KChar     Char
+          | KRational Rational
+          | KArray    (ArrayModel Integer Bool)
+          -- NB. KADT is covered by the APair constructor above. KSet is deliberately
+          -- absent: t05 has to run on cvc5 (z3 is buggy on it), and cvc5 doesn't
+          -- support sets; a single set field here would make every test over this
+          -- type require set support. Sets in ADT fields are covered by t08 instead.
+          deriving Show
+
+mkSymbolic [''ADT]
+
+data Probe = PSet   (RCSet Integer)
+           | PArr   (ArrayModel Integer Bool)
+           | PInt   Integer
+           deriving Show
+
+mkSymbolic [''Probe]
+
+tests :: TestTree
+tests =
+  testGroup "ADT" [
+      goldenCapturedIO "adt00" $ checkWith t00
+    , goldenCapturedIO "adt01" $ checkWith t01
+    , goldenCapturedIO "adt02" $ checkWith t02
+    , goldenCapturedIO "adt03" $ checkWith t03
+    , goldenCapturedIO "adt04" t04
+    , goldenCapturedIO "adt05" t05
+    , goldenCapturedIO "adt06" t06
+    , goldenCapturedIO "adt07" t07
+    , goldenCapturedIO "adt08" t08
+    ]
+
+checkWith :: Symbolic () -> FilePath -> IO ()
+checkWith props rf = runSMTWith z3{verbose=True, redirectVerbose = Just rf} $ do
+        _ <- props
+        query $ do cs <- checkSat
+                   case cs of
+                     Unsat  -> io $ appendFile rf "\nUNSAT"
+                     DSat{} -> io $ appendFile rf "\nDSAT"
+                     Sat{}  -> getModel         >>= \m -> io $ appendFile rf $ "\nMODEL: "   ++ show m ++ "\nDONE."
+                     Unk    -> getUnknownReason >>= \r -> io $ appendFile rf $ "\nUNKNOWN: " ++ show r ++ "\nDONE."
+
+t00 :: Symbolic ()
+t00 = do a :: SADT <- free "e"
+         constrain $ a ./== a
+
+t01 :: Symbolic ()
+t01 = do a :: SADT <- free "e"
+         constrain $ a .=== literal (APair (AInt64 4) (AMaybe (Just (0, 12, (Left 3, [False, True])))))
+
+t02 :: Symbolic ()
+t02 = do a :: SADT <- free "e"
+         constrain $ isAList a
+
+t03 :: Symbolic ()
+t03 = do a :: SADT <- free "e"
+         constrain $ isAList a .&& isAFP a
+
+t04 :: FilePath -> IO ()
+t04 rf = do AllSatResult _ _ _ ms <- allSatWith z3{verbose=True, redirectVerbose = Just rf} t
+            let sh m = appendFile rf $ "\nMODEL:" ++ show (SatResult m)
+            mapM_ sh ms
+  where t = do a :: SADT <- free "a"
+               constrain $ isAInteger a
+               constrain $ getAInteger_1 a .>= 0
+               constrain $ getAInteger_1 a .<= 5
+
+-- z3 is buggy on this. So we use cvc5. See: https://github.com/Z3Prover/z3/issues/7842
+t05 :: FilePath -> IO ()
+t05 rf = do AllSatResult _ _ _ ms <- allSatWith cvc5{verbose=True, redirectVerbose = Just rf, allSatMaxModelCount=Just 10} t
+            let sh m = appendFile rf $ "\nMODEL:" ++ show (SatResult m)
+            mapM_ sh ms
+  where t = do a :: SADT <- free "a"
+               b :: SADT <- free "b"
+               constrain $ isAFloat a .&& getAFloat_1 a .== 4
+               constrain $ isAFloat b .&& fpIsNaN (getAFloat_1 b)
+
+t06 :: FilePath -> IO ()
+t06 rf = runSMTWith z3{verbose=True, redirectVerbose = Just rf} $ do
+             a :: SADT <- free "a"
+             constrain $ isAMaybe a
+             constrain $ isJust (getAMaybe_1 a)
+             query $ do cs <- checkSat
+                        case cs of
+                         Sat{} -> do v <- getValue a
+                                     io $ do appendFile rf $ "\ngetValue: " ++ show v
+                                             appendFile rf   "\nDONE\n"
+                         _     -> error ("BAD RESULT: " ++ show cs)
+
+-- Sets (and arrays) nested inside an ADT field: The model parser used to strip the
+-- (as const (Array Int Bool)) annotation off the field while looking for the constructor,
+-- which made the set unparseable. See interpretADT/removeAS in Data.SBV.Control.Utils.
+t07 :: FilePath -> IO ()
+t07 rf = runSMTWith z3{verbose=True, redirectVerbose = Just rf} $ do
+             a :: SEither Integer (Integer, RCSet Integer) <- free "a"
+             constrain $ a .== sRight (tuple (4, insert 2 empty))
+             query $ do cs <- checkSat
+                        case cs of
+                         Sat{} -> do v <- getValue a
+                                     io $ do appendFile rf $ "\ngetValue: " ++ show v
+                                             appendFile rf   "\nDONE\n"
+                         _     -> error ("BAD RESULT: " ++ show cs)
+
+t08 :: FilePath -> IO ()
+t08 rf = runSMTWith z3{verbose=True, redirectVerbose = Just rf} $ do
+             a :: SProbe <- free "a"
+             b :: SProbe <- free "b"
+             constrain $ isPSet a .&& getPSet_1 a .== insert 2 empty
+             constrain $ isPArr b .&& readArray (getPArr_1 b) 3 .== sTrue
+             query $ do cs <- checkSat
+                        case cs of
+                         Sat{} -> do va <- getValue a
+                                     vb <- getValue b
+                                     io $ do appendFile rf $ "\ngetValue a: " ++ show va
+                                             appendFile rf $ "\ngetValue b: " ++ show vb
+                                             appendFile rf   "\nDONE\n"
+                         _     -> error ("BAD RESULT: " ++ show cs)
diff --git a/SBVTestSuite/TestSuite/ADT/Expr.hs b/SBVTestSuite/TestSuite/ADT/Expr.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/ADT/Expr.hs
@@ -0,0 +1,419 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : TestSuite.ADT.Expr
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Testing ADTs, expressions
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE FlexibleInstances   #-}
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module TestSuite.ADT.Expr(tests) where
+
+import Control.Monad (void)
+
+import Data.SBV
+import Data.SBV.Control
+import Utils.SBVTestFramework
+
+import Documentation.SBV.Examples.ADT.Expr
+
+-- Testing constructor/type name conflct
+data A = A Integer
+       | B Word8
+       | C A A
+       deriving Show
+
+mkSymbolic [''A]
+
+tests :: TestTree
+tests =
+  testGroup "ADT" [
+      goldenCapturedIO "adt_expr00c" $ evalCheck  (eval e00,  3)
+    , goldenCapturedIO "adt_expr00"  $ evalCheckS eval (e00,  3)
+
+    , goldenCapturedIO "adt_expr01c" $ evalCheck  (eval e01,  7)
+    , goldenCapturedIO "adt_expr01"  $ evalCheckS eval (e01,  7)
+
+    , goldenCapturedIO "adt_expr02c" $ evalCheck  (eval e02, 21)
+    , goldenCapturedIO "adt_expr02"  $ evalCheckS eval (e02, 21)
+
+    , goldenCapturedIO "adt_expr03c" $ evalCheck  (eval e03, 28)
+    , goldenCapturedIO "adt_expr03"  $ evalCheckS eval (e03, 28)
+
+    , goldenCapturedIO "adt_expr04" $ evalTest  (eval e04)
+    , goldenCapturedIO "adt_expr05" $ evalTest  (eval e05)
+
+    , goldenCapturedIO "adt_expr06c" $ evalCheck  (f (sVar (literal "a")), 0)
+    , goldenCapturedIO "adt_expr06"  $ evalCheckS f  (sVar (literal "a") , 0)
+
+    , goldenCapturedIO "adt_expr07c" $ evalCheck  (f (sVar (literal "b")), 1)
+    , goldenCapturedIO "adt_expr07"  $ evalCheckS f  (sVar (literal "b") , 1)
+
+    , goldenCapturedIO "adt_expr08c" $ evalCheck  (f (sVar (literal "c")), 1)
+    , goldenCapturedIO "adt_expr08"  $ evalCheckS f  (sVar (literal "c") , 1)
+
+    , goldenCapturedIO "adt_expr09c" $ evalCheck  (f (sVar (literal "d")), 2)
+    , goldenCapturedIO "adt_expr09"  $ evalCheckS f  (sVar (literal "d") , 2)
+
+    , goldenCapturedIO "adt_expr10c" $ evalCheck   (sum (map (f . sVal . literal)      [-5 .. 9]),  45)
+    , goldenCapturedIO "adt_expr10"  $ evalCheckSL (sum . map f) (map (sVal . literal) [-5 .. 9],   45)
+
+    , goldenCapturedIO "adt_expr11c" $ evalCheck   (sum (map (f . sVal . literal)      [10, 10]),    8)
+    , goldenCapturedIO "adt_expr11"  $ evalCheckSL (sum . map f) (map (sVal . literal) [10, 10],     8)
+
+    , goldenCapturedIO "adt_expr12c" $ evalCheck   (sum (map (f . sVal . literal)      [11 .. 20]), 50)
+    , goldenCapturedIO "adt_expr12"  $ evalCheckSL (sum . map f) (map (sVal . literal) [11 .. 20],  50)
+
+    , goldenCapturedIO "adt_expr13c" $ evalCheck  (f e00, 3)
+    , goldenCapturedIO "adt_expr13"  $ evalCheckS f (e00, 3)
+
+    , goldenCapturedIO "adt_expr14c" $ evalCheck  (f e01, 6)
+    , goldenCapturedIO "adt_expr14"  $ evalCheckS f (e01, 6)
+
+    , goldenCapturedIO "adt_expr15c" $ evalCheck  (f e02, 6)
+    , goldenCapturedIO "adt_expr15"  $ evalCheckS f (e02, 6)
+
+    , goldenCapturedIO "adt_expr16c" $ evalCheck  (f e03, 6)
+    , goldenCapturedIO "adt_expr16"  $ evalCheckS f (e03, 6)
+
+    , goldenCapturedIO "adt_expr17c" $ evalCheck  (f e04, 6)
+    , goldenCapturedIO "adt_expr17"  $ evalCheckS f (e04, 6)
+
+    , goldenCapturedIO "adt_expr18c" $ evalCheck  (f e05, 6)
+    , goldenCapturedIO "adt_expr18"  $ evalCheckS f (e05, 6)
+
+    , goldenCapturedIO "adt_gen00"  t00
+    , goldenCapturedIO "adt_gen01"  $ tSat (-1)
+    , goldenCapturedIO "adt_gen02"  $ tSat 0
+    , goldenCapturedIO "adt_gen03"  $ tSat 1
+    , goldenCapturedIO "adt_gen04"  $ tSat 2
+    , goldenCapturedIO "adt_gen05"  $ tSat 3
+    , goldenCapturedIO "adt_gen06"  $ tSat 4
+    , goldenCapturedIO "adt_gen07"  $ tSat 5
+    , goldenCapturedIO "adt_gen08"  $ tSat 6
+    , goldenCapturedIO "adt_gen09"  $ tSat 7
+    , goldenCapturedIO "adt_gen10"  $ tSat 8
+    , goldenCapturedIO "adt_gen11"  $ tSat 9
+    , goldenCapturedIO "adt_gen12"  $ tSat 100
+    , goldenCapturedIO "adt_chk01"  $ evalTest (t (sA 12))
+
+    -- Nested pattern tests: h is a simplifier using nested patterns
+    -- Add (Val 0) e => e
+    , goldenCapturedIO "adt_nested00c" $ evalCheck (h (sAdd (sVal 0) (sVal 5)),  sVal 5)
+    , goldenCapturedIO "adt_nested00"  $ evalCheckS h (sAdd (sVal 0) (sVal 5),   sVal 5)
+    -- Add e (Val 0) => e
+    , goldenCapturedIO "adt_nested01c" $ evalCheck (h (sAdd (sVal 7) (sVal 0)),  sVal 7)
+    , goldenCapturedIO "adt_nested01"  $ evalCheckS h (sAdd (sVal 7) (sVal 0),   sVal 7)
+    -- Mul (Val 1) e => e
+    , goldenCapturedIO "adt_nested02c" $ evalCheck (h (sMul (sVal 1) (sVal 9)),  sVal 9)
+    , goldenCapturedIO "adt_nested02"  $ evalCheckS h (sMul (sVal 1) (sVal 9),   sVal 9)
+    -- Mul e (Val 1) => e
+    , goldenCapturedIO "adt_nested03c" $ evalCheck (h (sMul (sVal 4) (sVal 1)),  sVal 4)
+    , goldenCapturedIO "adt_nested03"  $ evalCheckS h (sMul (sVal 4) (sVal 1),   sVal 4)
+    -- Mul (Val 0) _ => 0
+    , goldenCapturedIO "adt_nested04c" $ evalCheck (h (sMul (sVal 0) (sVal 99)), sVal 0)
+    , goldenCapturedIO "adt_nested04"  $ evalCheckS h (sMul (sVal 0) (sVal 99),  sVal 0)
+    -- No simplification applies: Add (Val 3) (Val 4) stays as-is
+    , goldenCapturedIO "adt_nested05c" $ evalCheck (h (sAdd (sVal 3) (sVal 4)),  sAdd (sVal 3) (sVal 4))
+    , goldenCapturedIO "adt_nested05"  $ evalCheckS h (sAdd (sVal 3) (sVal 4),   sAdd (sVal 3) (sVal 4))
+    -- Guard miss: Add (Val 1) e, i /= 0, falls through to _
+    , goldenCapturedIO "adt_nested06c" $ evalCheck (h (sAdd (sVal 1) (sVal 5)),  sAdd (sVal 1) (sVal 5))
+    , goldenCapturedIO "adt_nested06"  $ evalCheckS h (sAdd (sVal 1) (sVal 5),   sAdd (sVal 1) (sVal 5))
+    -- Pattern ordering: Add (Val 0) (Val 0) => Val 0 (first rule fires, not second)
+    , goldenCapturedIO "adt_nested07c" $ evalCheck (h (sAdd (sVal 0) (sVal 0)),  sVal 0)
+    , goldenCapturedIO "adt_nested07"  $ evalCheckS h (sAdd (sVal 0) (sVal 0),   sVal 0)
+    -- Mul (Val 1) e where e is compound: result is the compound expression
+    , goldenCapturedIO "adt_nested08c" $ evalCheck (h (sMul (sVal 1) (sAdd (sVal 3) (sVal 4))),  sAdd (sVal 3) (sVal 4))
+    , goldenCapturedIO "adt_nested08"  $ evalCheckS h (sMul (sVal 1) (sAdd (sVal 3) (sVal 4)),   sAdd (sVal 3) (sVal 4))
+    -- Mul (Val 0) e where e is compound: result is Val 0 regardless of right side
+    , goldenCapturedIO "adt_nested09c" $ evalCheck (h (sMul (sVal 0) (sAdd (sVal 3) (sVal 4))),  sVal 0)
+    , goldenCapturedIO "adt_nested09"  $ evalCheckS h (sMul (sVal 0) (sAdd (sVal 3) (sVal 4)),   sVal 0)
+    -- Non-Add/Mul constructor: Var falls through to _
+    , goldenCapturedIO "adt_nested10c" $ evalCheck (h (sVar (literal "x")),  sVar (literal "x"))
+    , goldenCapturedIO "adt_nested10"  $ evalCheckS h (sVar (literal "x"),   sVar (literal "x"))
+    -- Non-Add/Mul constructor: Val falls through to _
+    , goldenCapturedIO "adt_nested11c" $ evalCheck (h (sVal 42),  sVal 42)
+    , goldenCapturedIO "adt_nested11"  $ evalCheckS h (sVal 42,   sVal 42)
+    -- Let falls through to _
+    , goldenCapturedIO "adt_nested12c" $ evalCheck (h (sLet (literal "x") (sVal 1) (sVar (literal "x"))),  sLet (literal "x") (sVal 1) (sVar (literal "x")))
+    , goldenCapturedIO "adt_nested12"  $ evalCheckS h (sLet (literal "x") (sVal 1) (sVar (literal "x")),   sLet (literal "x") (sVal 1) (sVar (literal "x")))
+    -- Mul (Val 0) with a non-Val right side (Var): result is Val 0, wildcard ignores it
+    , goldenCapturedIO "adt_nested13c" $ evalCheck (h (sMul (sVal 0) (sVar (literal "x"))),  sVal 0)
+    , goldenCapturedIO "adt_nested13"  $ evalCheckS h (sMul (sVal 0) (sVar (literal "x")),   sVal 0)
+    -- Add (Val 0) with a compound right side (Add)
+    , goldenCapturedIO "adt_nested14c" $ evalCheck (h (sAdd (sVal 0) (sMul (sVal 2) (sVal 3))),  sMul (sVal 2) (sVal 3))
+    , goldenCapturedIO "adt_nested14"  $ evalCheckS h (sAdd (sVal 0) (sMul (sVal 2) (sVal 3)),   sMul (sVal 2) (sVal 3))
+    -- Idempotency: h (h e) == h e (using a simplifiable input)
+    , goldenCapturedIO "adt_nested15c" $ evalCheck (h (h (sAdd (sVal 0) (sVal 5))),  sVal 5)
+    , goldenCapturedIO "adt_nested15"  $ evalCheckS (h . h) (sAdd (sVal 0) (sVal 5),  sVal 5)
+    -- Idempotency: h (h e) == h e (using a non-simplifiable input)
+    , goldenCapturedIO "adt_nested16c" $ evalCheck (h (h (sAdd (sVal 3) (sVal 4))),  sAdd (sVal 3) (sVal 4))
+    , goldenCapturedIO "adt_nested16"  $ evalCheckS (h . h) (sAdd (sVal 3) (sVal 4),  sAdd (sVal 3) (sVal 4))
+    -- Two-step simplification: h (h (Mul (Val 1) (Add (Val 0) (Val 5)))) => Val 5
+    -- First h: Mul (Val 1) (Add (Val 0) (Val 5)) => Add (Val 0) (Val 5)
+    -- Second h: Add (Val 0) (Val 5)              => Val 5
+    , goldenCapturedIO "adt_nested17c" $ evalCheck (h (h (sMul (sVal 1) (sAdd (sVal 0) (sVal 5)))),  sVal 5)
+    , goldenCapturedIO "adt_nested17"  $ evalCheckS (h . h) (sMul (sVal 1) (sAdd (sVal 0) (sVal 5)),  sVal 5)
+    -- Semantics preservation: eval (h e) == eval e for all closed e
+    , goldenCapturedIO "adt_nested18"  hPreservesEval
+    -- Mul rule ordering: Mul (Val 1) (Val 1) => Val 1 (first Mul rule fires, not second)
+    , goldenCapturedIO "adt_nested19c" $ evalCheck (h (sMul (sVal 1) (sVal 1)),  sVal 1)
+    , goldenCapturedIO "adt_nested19"  $ evalCheckS h (sMul (sVal 1) (sVal 1),   sVal 1)
+    -- Guard miss on both Mul rules: Mul (Val 2) (Val 3) falls through to _
+    , goldenCapturedIO "adt_nested20c" $ evalCheck (h (sMul (sVal 2) (sVal 3)),  sMul (sVal 2) (sVal 3))
+    , goldenCapturedIO "adt_nested20"  $ evalCheckS h (sMul (sVal 2) (sVal 3),   sMul (sVal 2) (sVal 3))
+    -- Mul (Val 1) (Var "x") => Var "x": Mul rule returns a non-Val expression
+    , goldenCapturedIO "adt_nested21c" $ evalCheck (h (sMul (sVal 1) (sVar (literal "x"))),  sVar (literal "x"))
+    , goldenCapturedIO "adt_nested21"  $ evalCheckS h (sMul (sVal 1) (sVar (literal "x")),   sVar (literal "x"))
+    -- Add (Val 0) (Var "x") => Var "x": Add rule returns a non-Val expression
+    , goldenCapturedIO "adt_nested22c" $ evalCheck (h (sAdd (sVal 0) (sVar (literal "x"))),  sVar (literal "x"))
+    , goldenCapturedIO "adt_nested22"  $ evalCheckS h (sAdd (sVal 0) (sVar (literal "x")),   sVar (literal "x"))
+    -- Focused proof: h preserves eval for Add expressions specifically
+    , goldenCapturedIO "adt_nested23"  hPreservesEvalAdd
+    -- Focused proof: h preserves eval for Mul expressions specifically
+    , goldenCapturedIO "adt_nested24"  hPreservesEvalMul
+
+    -- Deep nesting: cfold constant-folds Add (Mul (Val a) (Val b)) (Mul (Val c) (Val d)) => Val (a*b + c*d)
+    -- 4-level deep nested pattern on all branches simultaneously
+    -- Fires: Add (Mul (Val 2) (Val 3)) (Mul (Val 4) (Val 5)) => Val 26
+    , goldenCapturedIO "adt_nested25c" $ evalCheck (cfold (sAdd (sMul (sVal 2) (sVal 3)) (sMul (sVal 4) (sVal 5))),  sVal 26)
+    , goldenCapturedIO "adt_nested25"  $ evalCheckS cfold (sAdd (sMul (sVal 2) (sVal 3)) (sMul (sVal 4) (sVal 5)),   sVal 26)
+    -- Fires: Add (Mul (Val 0) (Val 99)) (Mul (Val 1) (Val 1)) => Val 1
+    , goldenCapturedIO "adt_nested26c" $ evalCheck (cfold (sAdd (sMul (sVal 0) (sVal 99)) (sMul (sVal 1) (sVal 1))),  sVal 1)
+    , goldenCapturedIO "adt_nested26"  $ evalCheckS cfold (sAdd (sMul (sVal 0) (sVal 99)) (sMul (sVal 1) (sVal 1)),   sVal 1)
+    -- No match: right branch is Var, not Mul (Val _) (Val _)
+    , goldenCapturedIO "adt_nested27c" $ evalCheck (cfold (sAdd (sMul (sVal 2) (sVal 3)) (sVar (literal "x"))),  sAdd (sMul (sVal 2) (sVal 3)) (sVar (literal "x")))
+    , goldenCapturedIO "adt_nested27"  $ evalCheckS cfold (sAdd (sMul (sVal 2) (sVal 3)) (sVar (literal "x")),   sAdd (sMul (sVal 2) (sVal 3)) (sVar (literal "x")))
+    -- No match: outer constructor is Mul, not Add
+    , goldenCapturedIO "adt_nested28c" $ evalCheck (cfold (sMul (sVal 2) (sVal 3)),  sMul (sVal 2) (sVal 3))
+    , goldenCapturedIO "adt_nested28"  $ evalCheckS cfold (sMul (sVal 2) (sVal 3),   sMul (sVal 2) (sVal 3))
+    -- Semantics preservation: eval (cfold e) == eval e for all e
+    , goldenCapturedIO "adt_nested29"  cfoldPreservesEval
+
+    -- Pipeline tests: cfold (h e) — first simplify with h, then constant-fold with cfold
+    -- Neither h nor cfold fires: Add (Mul (Val 2) (Val 3)) (Mul (Val 4) (Val 5)) passes through h unchanged, cfold folds to Val 26
+    , goldenCapturedIO "adt_nested30c" $ evalCheck (cfold (h (sAdd (sMul (sVal 2) (sVal 3)) (sMul (sVal 4) (sVal 5)))),  sVal 26)
+    , goldenCapturedIO "adt_nested30"  $ evalCheckS (cfold . h) (sAdd (sMul (sVal 2) (sVal 3)) (sMul (sVal 4) (sVal 5)),  sVal 26)
+    -- h leaves outer Add unchanged; cfold still sees Add (Mul (Val 1) (Val 2)) (Mul (Val 0) (Val 4)) and folds to Val 2
+    , goldenCapturedIO "adt_nested31c" $ evalCheck (cfold (h (sAdd (sMul (sVal 1) (sVal 2)) (sMul (sVal 0) (sVal 4)))),  sVal 2)
+    , goldenCapturedIO "adt_nested31"  $ evalCheckS (cfold . h) (sAdd (sMul (sVal 1) (sVal 2)) (sMul (sVal 0) (sVal 4)),  sVal 2)
+    -- h fires (Mul (Val 1) r => r), exposing a cfold-able expression; cfold then folds to Val 26
+    , goldenCapturedIO "adt_nested32c" $ evalCheck (cfold (h (sMul (sVal 1) (sAdd (sMul (sVal 2) (sVal 3)) (sMul (sVal 4) (sVal 5))))),  sVal 26)
+    , goldenCapturedIO "adt_nested32"  $ evalCheckS (cfold . h) (sMul (sVal 1) (sAdd (sMul (sVal 2) (sVal 3)) (sMul (sVal 4) (sVal 5))),  sVal 26)
+    -- h fires (Add (Val 0) r => r), exposing a cfold-able expression; cfold then folds to Val 26
+    , goldenCapturedIO "adt_nested33c" $ evalCheck (cfold (h (sAdd (sVal 0) (sAdd (sMul (sVal 2) (sVal 3)) (sMul (sVal 4) (sVal 5))))),  sVal 26)
+    , goldenCapturedIO "adt_nested33"  $ evalCheckS (cfold . h) (sAdd (sVal 0) (sAdd (sMul (sVal 2) (sVal 3)) (sMul (sVal 4) (sVal 5))),  sVal 26)
+
+    -- Literal pattern tests: p uses integer and string literal patterns
+    -- Top-level literal fires: Val 0 => 100
+    , goldenCapturedIO "adt_lit00c" $ evalCheck (p (sVal 0),  100)
+    , goldenCapturedIO "adt_lit00"  $ evalCheckS p (sVal 0,   100)
+    -- Top-level literal fires: Val 1 => 200
+    , goldenCapturedIO "adt_lit01c" $ evalCheck (p (sVal 1),  200)
+    , goldenCapturedIO "adt_lit01"  $ evalCheckS p (sVal 1,   200)
+    -- Top-level literal misses: Val 2 falls through to eval e = 2
+    , goldenCapturedIO "adt_lit02c" $ evalCheck (p (sVal 2),  2)
+    , goldenCapturedIO "adt_lit02"  $ evalCheckS p (sVal 2,   2)
+    -- Nested literal fires: Add (Val 0) (Val 5) => eval (Val 5) = 5
+    , goldenCapturedIO "adt_lit03c" $ evalCheck (p (sAdd (sVal 0) (sVal 5)),  5)
+    , goldenCapturedIO "adt_lit03"  $ evalCheckS p (sAdd (sVal 0) (sVal 5),   5)
+    -- Nested literal misses: Add (Val 1) (Val 5) => eval e = 6
+    , goldenCapturedIO "adt_lit04c" $ evalCheck (p (sAdd (sVal 1) (sVal 5)),  6)
+    , goldenCapturedIO "adt_lit04"  $ evalCheckS p (sAdd (sVal 1) (sVal 5),   6)
+    -- Var falls through to eval e (= 0 for unbound var)
+    , goldenCapturedIO "adt_lit05c" $ evalCheck (p (sVar (literal "x")),  0)
+    , goldenCapturedIO "adt_lit05"  $ evalCheckS p (sVar (literal "x"),   0)
+    ]
+    where a = literal "a"
+          b = literal "a"
+
+          e00 = 3                                -- 3
+          e01 = 3 + 4                            -- 7
+          e02 = e00 * e01                        -- 21
+          e03 = sLet a e02 (sVar a + e01)        -- 28
+          e04 = e03 + sLet a e03 (sVar a + e01)  -- 28 + 28 + 7 = 63
+          e05 = sLet b e04 (sVar b * sVar b)     -- 63 * 63 = 3969
+
+evalCheck :: SymVal a => (SBV a, SBV a) -> FilePath -> IO ()
+evalCheck (sv, v) rf = runSMTWith z3{verbose=True, redirectVerbose = Just rf} $ do
+                        constrain $ sv ./= v
+                        query $ do cs <- checkSat
+                                   case cs of
+                                     Unsat{} -> io $ appendFile rf "All good.\n"
+                                     _       -> error $ "Unexpected: " ++ show cs
+
+evalCheckS :: SymVal b => (SExpr -> SBV b) -> (SExpr, SBV b) -> FilePath -> IO ()
+evalCheckS fun (e, v) rf = runSMTWith z3{verbose=True, redirectVerbose = Just rf} $ do
+                        se :: SExpr <- free_
+                        constrain $ se .== e
+                        constrain $ fun se ./= v
+                        query $ do cs <- checkSat
+                                   case cs of
+                                     Unsat{} -> io $ appendFile rf "All good.\n"
+                                     _       -> error $ "Unexpected: " ++ show cs
+
+evalCheckSL :: ([SExpr] -> SInteger) -> ([SExpr], Integer) -> FilePath -> IO ()
+evalCheckSL fun (e, v) rf = runSMTWith z3{verbose=True, redirectVerbose = Just rf} $ do
+                        ses :: [SExpr] <- mapM (const free_) e
+                        constrain $ ses .== e
+                        constrain $ fun ses ./= literal v
+                        query $ do cs <- checkSat
+                                   case cs of
+                                     Unsat{} -> io $ appendFile rf "All good.\n"
+                                     _       -> error $ "Unexpected: " ++ show cs
+
+evalTest :: (Show a, SymVal a) => SBV a -> FilePath -> IO ()
+evalTest sv rf = runSMTWith z3{verbose=True, redirectVerbose = Just rf} $ do
+                    res <- free "res"
+                    constrain $ sv .== res
+                    query $ do cs <- checkSat
+                               case cs of
+                                 Sat -> do r <- getValue res
+                                           io $ appendFile rf ("Result: " ++ show r ++ "\n")
+                                 _       -> error $ "Unexpected: " ++ show cs
+
+f :: SExpr -> SInteger
+f e = [sCase| e of
+         Var s     | s .== literal "a"                       -> 0
+                   | s .== literal "b" .|| s .== literal "c" -> 1
+                   | sTrue                                   -> 2
+
+         Val i     | i .<  10                                -> 3
+                   | i .== 10                                -> 4
+                   | i .>  10                                -> 5
+
+         _                                                   -> 6
+      |]
+
+-- Create something like:
+--       let a = _
+--    in let b = _
+--    in _ + _
+-- such that it evaluates to 12
+t00 :: FilePath -> IO ()
+t00 rf = runSMTWith z3{verbose=True, redirectVerbose = Just rf} $ do
+            a :: SExpr <- free "a"
+            constrain $ isValid a
+            constrain $ eval a .== 12
+
+            constrain $ isLet a
+            constrain $ isLet (getLet_3 a)
+            constrain $ isAdd (getLet_3 (getLet_3 a))
+
+            query $ do cs <- checkSat
+                       case cs of
+                         Sat{} -> do v <- getValue a
+                                     io $ do appendFile rf $ "\nGot: " ++ show v
+                                             appendFile rf   "\nDONE\n"
+                         _     -> error $ "Unexpected: " ++ show cs
+
+g :: SExpr -> SInteger
+g e = [sCase| e of
+         Var s     | s .== literal "a"                       -> 0
+                   | s .== literal "b" .|| s .== literal "c" -> 1
+                   | sTrue                                   -> 2
+
+         Val i     | i .<  10                                -> 3
+                   | i .== 10                                -> 4
+                   | i .>  10                                -> 5
+
+         Add _ _ -> 6
+         Mul _ _ -> 7
+         Let{}   -> 8
+
+         _ -> 100
+      |]
+
+-- Show that g can never produce anything but 0..8
+tSat :: Integer -> FilePath -> IO ()
+tSat i rf = runSMTWith z3{verbose=True, redirectVerbose = Just rf} $ do
+              a :: SExpr <- free "a"
+              constrain $ g a .== literal i
+
+              query $ do cs <- checkSat
+                         case cs of
+                           Sat{} -> do v <- getValue a
+                                       io $ do appendFile rf $ "\nGot: " ++ show v
+                                               appendFile rf   "\nDONE\n"
+                           Unsat -> io $ do appendFile rf "\nUNSAT\n"
+                           _     -> error $ "Unexpected: " ++ show cs
+
+t :: SA -> SA
+t = smtFunction "t" $ \a ->
+       [sCase| a of
+         A u     -> sA (u+1)
+         B w     -> sB (w+2)
+         C a1 a2 -> sC (t a1) (t a2)
+      |]
+
+-- | A simplifier that uses nested patterns to special-case identity/zero elements.
+-- Add (Val 0) e  => e
+-- Add e (Val 0)  => e
+-- Mul (Val 1) e  => e
+-- Mul e (Val 1)  => e
+-- Mul (Val 0) _  => 0
+-- otherwise      => identity
+h :: SExpr -> SExpr
+h e = [sCase| e of
+         Add (Val i) r | i .== 0 -> r
+         Add l (Val i) | i .== 0 -> l
+         Mul (Val i) r | i .== 1 -> r
+         Mul l (Val i) | i .== 1 -> l
+         Mul (Val i) _ | i .== 0 -> sVal 0
+         _                        -> e
+      |]
+
+-- | Prove that h preserves evaluation semantics: eval (h e) == eval e for all e.
+hPreservesEval :: FilePath -> IO ()
+hPreservesEval rf = void $ proveWith z3{verbose=True, redirectVerbose=Just rf} $ do
+                      e :: SExpr <- free "e"
+                      pure $ eval (h e) .== eval e
+
+-- | Focused proof: h preserves eval specifically when the top-level node is Add.
+hPreservesEvalAdd :: FilePath -> IO ()
+hPreservesEvalAdd rf = void $ proveWith z3{verbose=True, redirectVerbose=Just rf} $ do
+                         e :: SExpr <- free "e"
+                         pure $ isAdd e .=> (eval (h e) .== eval e)
+
+-- | Focused proof: h preserves eval specifically when the top-level node is Mul.
+hPreservesEvalMul :: FilePath -> IO ()
+hPreservesEvalMul rf = void $ proveWith z3{verbose=True, redirectVerbose=Just rf} $ do
+                         e :: SExpr <- free "e"
+                         pure $ isMul e .=> (eval (h e) .== eval e)
+
+-- | A constant-folder using a deeply nested pattern: recognizes Add (Mul (Val a) (Val b)) (Mul (Val c) (Val d))
+-- and folds it to Val (a*b + c*d). All four leaf positions use nested Val patterns simultaneously.
+cfold :: SExpr -> SExpr
+cfold e = [sCase| e of
+             Add (Mul (Val a) (Val b)) (Mul (Val c) (Val d)) -> sVal (a*b + c*d)
+             _                                               -> e
+          |]
+
+-- | Prove that cfold preserves evaluation semantics: eval (cfold e) == eval e for all e.
+cfoldPreservesEval :: FilePath -> IO ()
+cfoldPreservesEval rf = void $ proveWith z3{verbose=True, redirectVerbose=Just rf} $ do
+                          e :: SExpr <- free "e"
+                          pure $ eval (cfold e) .== eval e
+
+-- | A function using literal patterns: dispatches on specific integer/string values directly in the pattern.
+-- Val 0         => 100
+-- Val 1         => 200
+-- Add (Val 0) r => eval r   (nested integer literal)
+-- _             => eval e   (fallthrough)
+p :: SExpr -> SInteger
+p e = [sCase| e of
+         Val 0         -> 100
+         Val 1         -> 200
+         Add (Val 0) r -> eval r
+         _             -> eval e
+      |]
diff --git a/SBVTestSuite/TestSuite/ADT/MutRec.hs b/SBVTestSuite/TestSuite/ADT/MutRec.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/ADT/MutRec.hs
@@ -0,0 +1,195 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : TestSuite.ADT.MutRec
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Testing ADTs, mutual-recursion and other parameterization checks
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE FlexibleInstances   #-}
+{-# LANGUAGE OverloadedLists     #-}
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -Wno-incomplete-record-selectors #-}
+
+module TestSuite.ADT.MutRec(tests) where
+
+import Data.SBV
+import Data.SBV.Control
+import Utils.SBVTestFramework
+
+import Data.SBV.RegExp
+import Data.SBV.Tuple
+import Data.SBV.Maybe
+import qualified Data.SBV.List  as SL
+import qualified Data.SBV.Tuple as ST
+
+-- | Expression layer
+data Expr var val = Con { con :: val }
+                  | Var { var :: var }
+                  | Add { add1 :: Expr var val, add2 :: Expr var val }
+                  | Mul { mul1 :: Expr var val, mul2 :: Expr var val }
+
+-- | Statement layer
+data Stmt var val = Assign {lhs  :: var,          rhs  :: Expr var val }
+                  | Seq    {seqH :: Stmt var val, seqT :: Stmt var val }
+
+mkSymbolic [''Expr, ''Stmt]
+
+data A a b = Aa   { aa :: a }
+           | Ab   { ab :: b }
+           | Aab  { aba :: a, abb :: b }
+           | A2   { a2 :: A b String }
+           | A3   { a3 :: A b a }
+           deriving Show
+
+mkSymbolic [''A]
+
+-- | Show instance for 'Expr'.
+instance (Show var, Show val) => Show (Expr var val) where
+  show (Con i)   = show i
+  show (Var a)   = show a
+  show (Add l r) = "(" ++ show l ++ " + " ++ show r ++ ")"
+  show (Mul l r) = "(" ++ show l ++ " * " ++ show r ++ ")"
+
+-- | Show instance for 'Stmt'.
+instance (Show var, Show val) => Show (Stmt var val) where
+  show (Assign v e) = show v ++ " := " ++ show e
+  show (Seq a b)    = show a ++ ";\n" ++ show b
+
+-- | Show instance for 'Expr' specialized when var is string.
+instance {-# OVERLAPPING #-} Show val => Show (Expr String val) where
+  show (Con i)   = show i
+  show (Var a)   = a
+  show (Add l r) = "(" ++ show l ++ " + " ++ show r ++ ")"
+  show (Mul l r) = "(" ++ show l ++ " * " ++ show r ++ ")"
+
+-- | Show instance for 'Stmt' specialized when var is string.
+instance {-# OVERLAPPING #-} Show val => Show (Stmt String val) where
+  show (Assign v e) =      v ++ " := " ++ show e
+  show (Seq a b)    = show a ++ ";\n" ++ show b
+
+-- | Validity: We require each variable appearing to be an identifier (lowercase letter followed by
+-- any number of upper-lower case letters and digits), and all expressions are closed; i.e., any
+-- variable referenced is assigned by a prior assignment expression.
+isValid :: forall val. SymVal val => SStmt String val -> SBool
+isValid = ST.fst . goS []
+  where isId s = s `match` (asciiLower * KStar (asciiLetter + digit))
+
+        goE :: SList String -> SExpr String val -> SBool
+        goE = smtFunction "validE"
+            $ \env expr -> [sCase| expr of
+                               Con _   -> sTrue
+                               Var s   -> isId s .&& s `SL.elem` env
+                               Add l r -> goE env l .&& goE env r
+                               Mul l r -> goE env l .&& goE env r
+                            |]
+
+        goS :: SList String -> SStmt String val -> STuple Bool [String]
+        goS = smtFunction "validS"
+            $ \env stmt -> [sCase| stmt of
+                               Assign v e -> tuple (isId v .&& goE env e, v SL..: env)
+                               Seq    a b -> let (lv, env')  = untuple $ goS env  a
+                                                 (rv, env'') = untuple $ goS env' b
+                                             in tuple (lv .&& rv, env'')
+                            |]
+
+tests :: TestTree
+tests =
+  testGroup "ADT_MR" [
+      goldenCapturedIO "adt_mr00" $ r t00
+    , goldenCapturedIO "adt_mr01" $ r t01
+    , goldenCapturedIO "adt_mr02" $ r t02
+    , goldenCapturedIO "adt_mr03" $ r t03
+    , goldenCapturedIO "adt_mr04" $ r t04
+    ]
+  where r p rf = runSMTWith z3{verbose=True, redirectVerbose = Just rf} (p rf)
+
+t00 :: FilePath -> Symbolic ()
+t00 rf = do p :: SStmt String Integer <- free "p"
+
+            -- Make sure there's some structure to the program:
+            constrain $ isSeq    p
+            constrain $ isSeq    (getSeq_2 p)
+            constrain $ isSeq    (getSeq_2 (getSeq_2 p))
+            constrain $ isAssign (getSeq_2 (getSeq_2 (getSeq_2 p)))
+            constrain $ isAdd    (getAssign_2 (getSeq_2 (getSeq_2 (getSeq_2 p))))
+            constrain $ isVar    (getAdd_1    (getAssign_2 (getSeq_2 (getSeq_2 (getSeq_2 p)))))
+
+            -- Would love to have the following. But it creates too big of a problem.
+            -- constrain $ isValid p
+            constrain $ isValid (sAssign (literal "a") (sCon (literal 1)) :: SStmt String Float)
+
+            query $ do cs <- checkSat
+                       case cs of
+                         Sat -> do r <- getValue p
+                                   io $ do appendFile rf $ "\nGot:\n" ++ show r
+                                           appendFile rf   "\nDONE\n"
+                         _   -> error $ "Unexpected result: " ++ show cs
+
+t01 :: FilePath -> Symbolic ()
+t01 rf = do p :: SStmt String (Maybe (Either Integer Bool)) <- free "p"
+
+            constrain $ isAssign  p
+            constrain $ isAdd     (srhs p)
+            constrain $ isCon     (sadd1 (srhs p))
+            constrain $ isCon     (sadd2 (srhs p))
+            constrain $ isNothing (scon (sadd1 (srhs p)))
+            constrain $ isJust    (scon (sadd2 (srhs p)))
+
+            query $ do cs <- checkSat
+                       case cs of
+                         Sat -> do r <- getValue p
+                                   io $ do appendFile rf $ "\nGot:\n" ++ show r
+                                           appendFile rf   "\nDONE\n"
+                         _   -> error $ "Unexpected result: " ++ show cs
+
+t02 :: FilePath -> Symbolic ()
+t02 rf = do p :: SA Integer Bool <- free "p"
+
+            constrain $ isA2 p
+            constrain $ isA2 (sa2 p)
+            constrain $ isAa (sa2 (sa2 p))
+
+            query $ do cs <- checkSat
+                       case cs of
+                         Sat -> do r <- getValue p
+                                   io $ do appendFile rf $ "\nGot:\n" ++ show r
+                                           appendFile rf   "\nDONE\n"
+                         _   -> error $ "Unexpected result: " ++ show cs
+
+t03 :: FilePath -> Symbolic ()
+t03 rf = do p :: SA Integer Bool <- free "p"
+
+            constrain $ isA3 p
+            constrain $ isAb (sa3 p)
+
+            query $ do cs <- checkSat
+                       case cs of
+                         Sat -> do r <- getValue p
+                                   io $ do appendFile rf $ "\nGot:\n" ++ show r
+                                           appendFile rf   "\nDONE\n"
+                         _   -> error $ "Unexpected result: " ++ show cs
+
+t04 :: FilePath -> Symbolic ()
+t04 rf = do p :: SA Integer (A Float Bool) <- free "p"
+
+            constrain $ isA2 p
+            constrain $ isA3 (sa2 p)
+            constrain $ isAab (sa3 (sa2 p))
+
+            query $ do cs <- checkSat
+                       case cs of
+                         Sat -> do r <- getValue p
+                                   io $ do appendFile rf $ "\nGot:\n" ++ show r
+                                           appendFile rf   "\nDONE\n"
+                         _   -> error $ "Unexpected result: " ++ show cs
+
+_unused :: a
+_unused = undefined con var add1 add2 mul1 mul2 lhs rhs seqH seqT
diff --git a/SBVTestSuite/TestSuite/ADT/PExpr.hs b/SBVTestSuite/TestSuite/ADT/PExpr.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/ADT/PExpr.hs
@@ -0,0 +1,230 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : TestSuite.ADT.PExpr
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Testing ADTs, parameterized expressions
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE FlexibleContexts    #-}
+{-# LANGUAGE FlexibleInstances   #-}
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module TestSuite.ADT.PExpr(tests) where
+
+import Data.SBV
+import Data.SBV.Control
+import Utils.SBVTestFramework
+
+import Documentation.SBV.Examples.ADT.Param
+
+-- Testing constructor/type name conflct
+data A = A Integer
+       | B Word8
+       | C A A
+       deriving Show
+
+mkSymbolic [''A]
+
+tests :: TestTree
+tests =
+  testGroup "ADT" [
+      goldenCapturedIO "adt_pexpr00c" $ evalCheck  (eval e00,  3)
+    , goldenCapturedIO "adt_pexpr00"  $ evalCheckS eval (e00,  3)
+
+    , goldenCapturedIO "adt_pexpr01c" $ evalCheck  (eval e01,  7)
+    , goldenCapturedIO "adt_pexpr01"  $ evalCheckS eval (e01,  7)
+
+    , goldenCapturedIO "adt_pexpr02c" $ evalCheck  (eval e02, 21)
+    , goldenCapturedIO "adt_pexpr02"  $ evalCheckS eval (e02, 21)
+
+    , goldenCapturedIO "adt_pexpr03c" $ evalCheck  (eval e03, 28)
+    , goldenCapturedIO "adt_pexpr03"  $ evalCheckS eval (e03, 28)
+
+    , goldenCapturedIO "adt_pexpr04" $ evalTest  (eval e04)
+    , goldenCapturedIO "adt_pexpr05" $ evalTest  (eval e05)
+
+    , goldenCapturedIO "adt_pexpr06c" $ evalCheck  (f (sVar (literal "a")), 0)
+    , goldenCapturedIO "adt_pexpr06"  $ evalCheckS f  (sVar (literal "a") , 0)
+
+    , goldenCapturedIO "adt_pexpr07c" $ evalCheck  (f (sVar (literal "b")), 1)
+    , goldenCapturedIO "adt_pexpr07"  $ evalCheckS f  (sVar (literal "b") , 1)
+
+    , goldenCapturedIO "adt_pexpr08c" $ evalCheck  (f (sVar (literal "c")), 1)
+    , goldenCapturedIO "adt_pexpr08"  $ evalCheckS f  (sVar (literal "c") , 1)
+
+    , goldenCapturedIO "adt_pexpr09c" $ evalCheck  (f (sVar (literal "d")), 2)
+    , goldenCapturedIO "adt_pexpr09"  $ evalCheckS f  (sVar (literal "d") , 2)
+
+    , goldenCapturedIO "adt_pexpr10c" $ evalCheck   (sum (map (f . sVal . literal)      [-5 .. 9]), 45)
+    , goldenCapturedIO "adt_pexpr10"  $ evalCheckSL (sum . map f) (map (sVal . literal) [-5 .. 9],  45)
+
+    , goldenCapturedIO "adt_pexpr11c" $ evalCheck   (sum (map (f . sVal . literal)      [10, 10]),   8)
+    , goldenCapturedIO "adt_pexpr11"  $ evalCheckSL (sum . map f) (map (sVal . literal) [10, 10],    8)
+
+    , goldenCapturedIO "adt_pexpr12c" $ evalCheck   (sum (map (f . sVal . literal)      [11 .. 20]), 50)
+    , goldenCapturedIO "adt_pexpr12"  $ evalCheckSL (sum . map f) (map (sVal . literal) [11 .. 20],  50)
+
+    , goldenCapturedIO "adt_pexpr13c" $ evalCheck  (f e00, 3)
+    , goldenCapturedIO "adt_pexpr13"  $ evalCheckS f (e00, 3)
+
+    , goldenCapturedIO "adt_pexpr14c" $ evalCheck  (f e01, 6)
+    , goldenCapturedIO "adt_pexpr14"  $ evalCheckS f (e01, 6)
+
+    , goldenCapturedIO "adt_pexpr15c" $ evalCheck  (f e02, 6)
+    , goldenCapturedIO "adt_pexpr15"  $ evalCheckS f (e02, 6)
+
+    , goldenCapturedIO "adt_pexpr16c" $ evalCheck  (f e03, 6)
+    , goldenCapturedIO "adt_pexpr16"  $ evalCheckS f (e03, 6)
+
+    , goldenCapturedIO "adt_pexpr17c" $ evalCheck  (f e04, 6)
+    , goldenCapturedIO "adt_pexpr17"  $ evalCheckS f (e04, 6)
+
+    , goldenCapturedIO "adt_pexpr18c" $ evalCheck  (f e05, 6)
+    , goldenCapturedIO "adt_pexpr18"  $ evalCheckS f (e05, 6)
+
+    , goldenCapturedIO "adt_pgen00"  t00
+    , goldenCapturedIO "adt_pgen01"  $ tSat (-1)
+    , goldenCapturedIO "adt_pgen02"  $ tSat 0
+    , goldenCapturedIO "adt_pgen03"  $ tSat 1
+    , goldenCapturedIO "adt_pgen04"  $ tSat 2
+    , goldenCapturedIO "adt_pgen05"  $ tSat 3
+    , goldenCapturedIO "adt_pgen06"  $ tSat 4
+    , goldenCapturedIO "adt_pgen07"  $ tSat 5
+    , goldenCapturedIO "adt_pgen08"  $ tSat 6
+    , goldenCapturedIO "adt_pgen09"  $ tSat 7
+    , goldenCapturedIO "adt_pgen10"  $ tSat 8
+    , goldenCapturedIO "adt_pgen11"  $ tSat 9
+    , goldenCapturedIO "adt_pgen12"  $ tSat 100
+    , goldenCapturedIO "adt_pchk01"  $ evalTest (t (sA 12))
+    ]
+    where a = literal "a"
+          b = literal "a"
+
+          e00, e01, e02, e03, e04, e05 :: SExpr String Integer
+          e00 = 3                                -- 3
+          e01 = 3 + 4                            -- 7
+          e02 = e00 * e01                        -- 21
+          e03 = sLet a e02 (sVar a + e01)        -- 28
+          e04 = e03 + sLet a e03 (sVar a + e01)  -- 28 + 28 + 7 = 63
+          e05 = sLet b e04 (sVar b * sVar b)     -- 63 * 63 = 3969
+
+evalCheck :: SymVal a => (SBV a, a) -> FilePath -> IO ()
+evalCheck (sv, v) rf = runSMTWith z3{verbose=True, redirectVerbose = Just rf} $ do
+                        constrain $ sv ./= literal v
+                        query $ do cs <- checkSat
+                                   case cs of
+                                     Unsat{} -> io $ appendFile rf "All good.\n"
+                                     _       -> error $ "Unexpected: " ++ show cs
+
+evalCheckS :: (SExpr String Integer -> SInteger) -> (SExpr String Integer , Integer) -> FilePath -> IO ()
+evalCheckS fun (e, v) rf = runSMTWith z3{verbose=True, redirectVerbose = Just rf} $ do
+                        se :: SExpr String Integer <- free_
+                        constrain $ se .== e
+                        constrain $ fun se ./= literal v
+                        query $ do cs <- checkSat
+                                   case cs of
+                                     Unsat{} -> io $ appendFile rf "All good.\n"
+                                     _       -> error $ "Unexpected: " ++ show cs
+
+evalCheckSL :: ([SExpr String Integer] -> SInteger) -> ([SExpr String Integer], Integer) -> FilePath -> IO ()
+evalCheckSL fun (e, v) rf = runSMTWith z3{verbose=True, redirectVerbose = Just rf} $ do
+                        ses :: [SExpr String Integer] <- mapM (const free_) e
+                        constrain $ ses .== e
+                        constrain $ fun ses ./= literal v
+                        query $ do cs <- checkSat
+                                   case cs of
+                                     Unsat{} -> io $ appendFile rf "All good.\n"
+                                     _       -> error $ "Unexpected: " ++ show cs
+
+evalTest :: (Show a, SymVal a) => SBV a -> FilePath -> IO ()
+evalTest sv rf = runSMTWith z3{verbose=True, redirectVerbose = Just rf} $ do
+                    res <- free "res"
+                    constrain $ sv .== res
+                    query $ do cs <- checkSat
+                               case cs of
+                                 Sat -> do r <- getValue res
+                                           io $ appendFile rf ("Result: " ++ show r ++ "\n")
+                                 _       -> error $ "Unexpected: " ++ show cs
+
+f :: SExpr String Integer -> SInteger
+f e = [sCase| e of
+         Var s     | s .== literal "a"                       -> 0
+                   | s .== literal "b" .|| s .== literal "c" -> 1
+                   | sTrue                                   -> 2
+
+         Val i     | i .<  10                                -> 3
+                   | i .== 10                                -> 4
+                   | i .>  10                                -> 5
+
+         _                                                   -> 6
+      |]
+
+-- Create something like:
+--       let a = _
+--    in let b = _
+--    in _ + _
+-- such that it evaluates to 12
+t00 :: FilePath -> IO ()
+t00 rf = runSMTWith z3{verbose=True, redirectVerbose = Just rf} $ do
+            a :: SExpr String Integer <- free "a"
+            constrain $ isValid isId a
+            constrain $ eval a .== 12
+
+            constrain $ isLet a
+            constrain $ isLet (getLet_3 a)
+            constrain $ isAdd (getLet_3 (getLet_3 a))
+
+            query $ do cs <- checkSat
+                       case cs of
+                         Sat{} -> do v <- getValue a
+                                     io $ do appendFile rf $ "\nGot: " ++ show v
+                                             appendFile rf   "\nDONE\n"
+                         _     -> error $ "Unexpected: " ++ show cs
+
+g :: (SymVal val, OrdSymbolic (SBV val), Num (SBV val)) => SExpr String val -> SInteger
+g e = [sCase| e of
+         Var s     | s .== literal "a"                       -> 0
+                   | s .== literal "b" .|| s .== literal "c" -> 1
+                   | sTrue                                   -> 2
+
+         Val i     | i .<  10                                -> 3
+                   | i .== 10                                -> 4
+                   | i .>  10                                -> 5
+
+         Add _ _ -> 6
+         Mul _ _ -> 7
+         Let{}   -> 8
+
+         _ -> 100
+      |]
+
+-- Show that g can never produce anything but 0..8
+tSat :: Integer -> FilePath -> IO ()
+tSat i rf = runSMTWith z3{verbose=True, redirectVerbose = Just rf} $ do
+              a :: SExpr String Integer <- free "a"
+              constrain $ g a .== literal i
+
+              query $ do cs <- checkSat
+                         case cs of
+                           Sat{} -> do v <- getValue a
+                                       io $ do appendFile rf $ "\nGot: " ++ show v
+                                               appendFile rf   "\nDONE\n"
+                           Unsat -> io $ do appendFile rf "\nUNSAT\n"
+                           _     -> error $ "Unexpected: " ++ show cs
+
+t :: SA -> SA
+t = smtFunction "t" $ \a ->
+       [sCase| a of
+         A u     -> sA (u+1)
+         B w     -> sB (w+2)
+         C a1 a2 -> sC (t a1) (t a2)
+      |]
diff --git a/SBVTestSuite/TestSuite/ADT/Registration.hs b/SBVTestSuite/TestSuite/ADT/Registration.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/ADT/Registration.hs
@@ -0,0 +1,124 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : TestSuite.ADT.Registration
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Registration of ADT dependencies without incidental uses of their fields.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE FlexibleInstances   #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module TestSuite.ADT.Registration (tests) where
+
+import Data.Proxy (Proxy(..))
+import Control.DeepSeq (force)
+import Control.Exception (evaluate)
+import Control.Monad (void)
+import Data.SBV.Control
+import Test.Tasty.HUnit (assertEqual)
+import Utils.SBVTestFramework
+
+-- | A parameterized leaf whose definition must be discovered from its uses.
+newtype RegistrationLeaf a = RegistrationLeaf a deriving (Eq, Ord, Show)
+
+-- | An ADT reference underneath a tuple field.
+newtype RegistrationTuple = RegistrationTuple (RegistrationLeaf Word8, Word8) deriving Show
+
+-- | An ADT reference underneath a list field.
+newtype RegistrationList = RegistrationList [RegistrationLeaf Word8] deriving Show
+
+-- | An ADT reference underneath a set field.
+newtype RegistrationSet = RegistrationSet (RCSet (RegistrationLeaf Word8)) deriving Show
+
+-- | An ADT reference in an array's index type.
+newtype RegistrationKey = RegistrationKey (ArrayModel (RegistrationLeaf Word8) Word8) deriving Show
+
+-- | An ADT reference in an array's element type.
+newtype RegistrationValue = RegistrationValue (ArrayModel Word8 (RegistrationLeaf Word8)) deriving Show
+
+-- | A synonym must not hide dependencies from the registration traversal.
+type RegistrationAlias = ([RegistrationLeaf Word8], Word8)
+
+-- | A field whose container structure is supplied by a type synonym.
+newtype RegistrationSynonym = RegistrationSynonym RegistrationAlias deriving Show
+
+-- | Type arguments may themselves contain ADT references behind containers.
+newtype RegistrationParameter a = RegistrationParameter (Maybe ([RegistrationLeaf a], a)) deriving Show
+
+-- | Discover dependencies of an ADT that is itself only referenced by name.
+newtype RegistrationChain = RegistrationChain RegistrationTuple deriving Show
+
+-- | The root of a mutually recursive group, with a nested reference to its peer.
+data RegistrationEven = RegistrationEnd | RegistrationEven (RegistrationOdd, Word8) deriving Show
+
+-- | The return edge of the mutually recursive group.
+newtype RegistrationOdd = RegistrationOdd RegistrationEven deriving Show
+
+-- | Recursion through a type argument must not make retained metadata cyclic.
+data RegistrationParamCycle = RegistrationParamEnd
+                            | RegistrationParamNext (RegistrationParamLink RegistrationParamCycle)
+                            deriving Show
+
+-- | A parameter carrying the return edge of a recursive dependency.
+newtype RegistrationParamLink a = RegistrationParamLink a deriving Show
+
+-- | Generate all schemas without registering any symbolic values in advance.
+mkSymbolic [''RegistrationLeaf, ''RegistrationTuple, ''RegistrationList, ''RegistrationSet, ''RegistrationKey, ''RegistrationValue, ''RegistrationSynonym, ''RegistrationParameter, ''RegistrationChain, ''RegistrationEven, ''RegistrationOdd, ''RegistrationParamCycle, ''RegistrationParamLink]
+
+-- | Each fresh solver session uses only its root type, through either a literal
+-- or a fresh variable. Field selectors and extra inner-type inputs must not mask
+-- missing schemas.
+tests :: TestTree
+tests = testGroup "ADT.Registration" $
+  [ testCase "literal-only symbolic constraint" $ do
+      result <- runSMT $ do
+        constrain (uninterpret "observeRegistrationEnd" (literal RegistrationEnd) :: SBool)
+        query checkSat
+      assertEqual "A leaf literal must register its unused recursive partner" Sat result
+  , testCase "literal-only query constraint" $ do
+      result <- runSMT $ query $ do
+        constrain (uninterpret "observeRegistrationEnd" (literal RegistrationEnd) :: SBool)
+        checkSat
+      assertEqual "A query literal must register its unused recursive partner" Sat result
+  , testCase "finite parameter-mediated recursive metadata" $ do
+      let leaf = literal RegistrationParamEnd
+      void $ evaluate (force (kindOf leaf))
+      result <- runSMT $ do
+        constrain (uninterpret "observeRegistrationParamEnd" leaf :: SBool)
+        query checkSat
+      assertEqual "Recursive type arguments must retain a finite declaration registry" Sat result
+  ] ++ [ testGroup phase
+           [ check interactive "tuple"         (Proxy @RegistrationTuple)
+           , check interactive "list"          (Proxy @RegistrationList)
+           , check interactive "set"           (Proxy @RegistrationSet)
+           , check interactive "array key"     (Proxy @RegistrationKey)
+           , check interactive "array value"   (Proxy @RegistrationValue)
+           , check interactive "type synonym"  (Proxy @RegistrationSynonym)
+           , check interactive "parameter"     (Proxy @(RegistrationParameter Word8))
+           , check interactive "transitive"    (Proxy @RegistrationChain)
+           , check interactive "mutual root"   (Proxy @RegistrationEven)
+           , check interactive "mutual peer"   (Proxy @RegistrationOdd)
+           ]
+       | (phase, interactive) <- [("symbolic", Nothing), ("query named", Just False), ("query unnamed", Just True)]
+       ]
+ where check :: forall a. SymVal a => Maybe Bool -> String -> Proxy a -> TestTree
+       check interactive testName _ = testCase testName $ do
+         result <- runSMT $ case interactive of
+           Just anonymous -> query $ do left  <- if anonymous then freshVar_ @a else freshVar @a "left"
+                                        right <- if anonymous then freshVar_ @a else freshVar @a "right"
+                                        constrain (left ./= right)
+                                        checkSat
+           Nothing -> do left  <- free "left"  :: Symbolic (SBV a)
+                         right <- free "right" :: Symbolic (SBV a)
+                         constrain (left ./= right)
+                         query checkSat
+         assertEqual "Distinct root values must be satisfiable without explicit subfield registration" Sat result
diff --git a/SBVTestSuite/TestSuite/Arrays/Caching.hs b/SBVTestSuite/TestSuite/Arrays/Caching.hs
--- a/SBVTestSuite/TestSuite/Arrays/Caching.hs
+++ b/SBVTestSuite/TestSuite/Arrays/Caching.hs
@@ -29,7 +29,7 @@
 test :: Bool -> Symbolic SBool
 test swap = do
     let arr :: SArray Integer Integer
-        arr = lambdaArray (const 0)
+        arr = constArray 0
 
     x   <- sInteger "x"
 
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
@@ -10,7 +10,7 @@
 -----------------------------------------------------------------------------
 
 {-# LANGUAGE DataKinds           #-}
-{-# LANGUAGE Rank2Types          #-}
+{-# LANGUAGE RankNTypes          #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
@@ -24,7 +24,7 @@
 readDef = do c :: SInteger <- free "c"
              i :: SInteger <- free "i"
              j <- free "j"
-             let a = lambdaArray (const c)
+             let a = constArray c
 
              let a' = writeArray a j 32
 
diff --git a/SBVTestSuite/TestSuite/Arrays/Memory.hs b/SBVTestSuite/TestSuite/Arrays/Memory.hs
--- a/SBVTestSuite/TestSuite/Arrays/Memory.hs
+++ b/SBVTestSuite/TestSuite/Arrays/Memory.hs
@@ -9,7 +9,7 @@
 -- Test suite for Examples.Arrays.Memory
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE Rank2Types #-}
+{-# LANGUAGE RankNTypes #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
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
@@ -217,3 +217,5 @@
 
          query $ do constrain $ readArray x (literal ('z', 5 % 3)) .== literal (5 % 3, 'z')
                     checkSat
+
+{- HLint ignore module "Reduce duplication" -}
diff --git a/SBVTestSuite/TestSuite/Basics/AllSat.hs b/SBVTestSuite/TestSuite/Basics/AllSat.hs
--- a/SBVTestSuite/TestSuite/Basics/AllSat.hs
+++ b/SBVTestSuite/TestSuite/Basics/AllSat.hs
@@ -9,10 +9,7 @@
 -- Test suite for basic allsat calls
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DeriveAnyClass      #-}
-{-# LANGUAGE DeriveDataTypeable  #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE StandaloneDeriving  #-}
 {-# LANGUAGE TemplateHaskell     #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
@@ -27,7 +24,7 @@
 import qualified Control.Exception as C
 
 data Q
-mkUninterpretedSort ''Q
+mkSymbolic [''Q]
 
 tests :: TestTree
 tests =
diff --git a/SBVTestSuite/TestSuite/Basics/ArbFloats.hs b/SBVTestSuite/TestSuite/Basics/ArbFloats.hs
--- a/SBVTestSuite/TestSuite/Basics/ArbFloats.hs
+++ b/SBVTestSuite/TestSuite/Basics/ArbFloats.hs
@@ -17,14 +17,23 @@
 module TestSuite.Basics.ArbFloats(tests) where
 
 import Utils.SBVTestFramework
+import Test.Tasty.HUnit (assertEqual)
+import Control.Monad (forM, forM_)
+import Data.SBV.Control
 
--- # of inhabitants is 2^sb(2^eb - 1) + 3
+-- | Number of inhabitants: @2^sb(2^eb - 1) + 3@.
 count :: Integer -> Integer -> Integer
 count eb sb = 2^sb * (2^eb - 1) + 3
 
+-- | Concrete and symbolic arbitrary-format floating-point checks.
 tests :: TestTree
 tests = testGroup "Basics.ArbFloats"
-  [ testCase "FP_2_2" (assert $ (== fromIntegral (count 2 2)) <$> numberOfModels (const sTrue :: SFloatingPoint 2 2 -> SBool))
+  [ testCase "integral conversion rounding" integralConversionRounding
+  , testCase "integral conversion format widths" integralConversionWidths
+  , testCase "symbolic integral conversion rounding" symbolicIntegralConversionRounding
+  , testCase "native integral conversion rounding" nativeIntegralConversionRounding
+  , testCase "native integral conversion solver agreement" nativeIntegralConversionAgreement
+  , testCase "FP_2_2" (assert $ (== fromIntegral (count 2 2)) <$> numberOfModels (const sTrue :: SFloatingPoint 2 2 -> SBool))
   , testCase "FP_2_3" (assert $ (== fromIntegral (count 2 3)) <$> numberOfModels (const sTrue :: SFloatingPoint 2 3 -> SBool))
   , testCase "FP_2_4" (assert $ (== fromIntegral (count 2 4)) <$> numberOfModels (const sTrue :: SFloatingPoint 2 4 -> SBool))
 
@@ -38,3 +47,128 @@
 
   , goldenVsStringShow "arbFp_opt_1" (optimize Lexicographic $ \x -> do {constrain (fpIsPoint x);  maximize "x" (x::SFPHalf)})
   ]
+
+-- | Integer literals must fold in the requested direction, including both
+-- tie parities and overflow. Expectations use exactly representable values.
+integralConversionRounding :: Assertion
+integralConversionRounding = do
+  mapM_ check
+    [ (0,      [0, 0, 0, 0, 0])
+    , (2049,   [2048, 2050, 2050, 2048, 2048])
+    , (2051,   [2052, 2052, 2052, 2050, 2050])
+    , (-2049,  [-2048, -2050, -2048, -2050, -2048])
+    , (-2051,  [-2052, -2052, -2050, -2052, -2050])
+    , (65536,  [halfInfinity, halfInfinity, halfInfinity, 65504, 65504])
+    , (-65536, [-halfInfinity, -halfInfinity, -65504, -halfInfinity, -65504])
+    , (2 ^ (200 :: Int), [halfInfinity, halfInfinity, halfInfinity, 65504, 65504])
+    ]
+  mapM_ (\(mode, signed, unsigned) -> do
+           assertEqual (show mode ++ ": signed native source") (Just signed)
+             (unliteral (toSFloatingPoint (literal mode) (literal (-2049 :: Int16))) :: Maybe FPHalf)
+           assertEqual (show mode ++ ": unsigned native source") (Just unsigned)
+             (unliteral (toSFloatingPoint (literal mode) (literal (2049 :: Word16))) :: Maybe FPHalf))
+    (zip3 modes [-2048, -2050, -2048, -2050, -2048] [2048, 2050, 2050, 2048, 2048])
+ where modes = [RoundNearestTiesToEven, RoundNearestTiesToAway, RoundTowardPositive, RoundTowardNegative, RoundTowardZero]
+       halfInfinity = 1 / 0 :: FPHalf
+
+       check (sample, expected) = mapM_ (\(mode, value) ->
+           assertEqual (show (sample, mode) ++ ": integer source") (Just value)
+             (unliteral (toSFloatingPoint (literal mode) (literal sample :: SInteger))))
+         (zip modes expected)
+
+-- | Conversion must use the target format, not a binary64 intermediate.
+-- Check a tiny nonstandard format and integer information beyond double's
+-- precision, including a halfway value beyond quadruple's precision.
+integralConversionWidths :: Assertion
+integralConversionWidths = do
+  assertEqual "tiny upward tie" (Just 10)
+    (unliteral (toSFloatingPoint sRTP (9 :: SInteger)) :: Maybe (FloatingPoint 4 3))
+  assertEqual "tiny downward negative tie" (Just (-10))
+    (unliteral (toSFloatingPoint sRTN (-9 :: SInteger)) :: Maybe (FloatingPoint 4 3))
+  let large = 2 ^ (100 :: Int) + 1
+      tie   = 2 ^ (113 :: Int) + 1
+  assertEqual "retain integer bits beyond binary64" (Just (fromInteger large))
+    (unliteral (toSFloatingPoint sRNE (literal large :: SInteger)) :: Maybe FPQuad)
+  assertEqual "quadruple upward tie" (Just (fromInteger (tie + 1)))
+    (unliteral (toSFloatingPoint sRTP (literal tie :: SInteger)) :: Maybe FPQuad)
+
+-- | Symbolic operands must still reach the solver; a symbolic rounding mode
+-- must not be ignored merely because the integer operand is concrete.
+symbolicIntegralConversionRounding :: Assertion
+symbolicIntegralConversionRounding = do
+  assertIsThm $ \mode -> (toSFloatingPoint mode (2049 :: SInteger) :: SFPHalf)
+                     .== ite (mode .== sRNA .|| mode .== sRTP) 2050 2048
+  assertIsThm $ \(value :: SInt16) -> value .== -2049
+                                .=> (toSFloatingPoint sRTN value :: SFPHalf) .== -2050
+
+-- | Check both native target formats at ties of either parity, with both
+-- signs and directed overflow. All expectations are exactly representable.
+nativeIntegralConversionRounding :: Assertion
+nativeIntegralConversionRounding = do
+  check (toSFloat, 24, 128)
+  check (toSDouble, 53, 1024)
+  source (literal (-127)              :: SInt8)
+  source (literal (-32767)            :: SInt16)
+  source (literal (-16777217)         :: SInt32)
+  source (literal (-9007199254740993) :: SInt64)
+  source (literal 255                 :: SWord8)
+  source (literal 65535               :: SWord16)
+  source (literal 16777217            :: SWord32)
+  source (literal 9007199254740993    :: SWord64)
+ where check :: (RealFloat a, SymVal a, Show a) => (SRoundingMode -> SInteger -> SBV a, Int, Int) -> Assertion
+       check (convert, precision, exponentLimit) = do
+         let base           = 2 ^ precision :: Integer
+             number         = fromInteger
+             nativeInfinity = 1 / 0
+             largest        = number ((2 ^ precision - 1) * 2 ^ (exponentLimit - precision))
+             cases = [ (0, [0, 0, 0, 0, 0])
+                     , (base + 1, map number [base, base + 2, base + 2, base, base])
+                     , (base + 3, map number [base + 4, base + 4, base + 4, base + 2, base + 2])
+                     , (negate (base + 1), map (negate . number) [base, base + 2, base, base + 2, base])
+                     , (negate (base + 3), map (negate . number) [base + 4, base + 4, base + 2, base + 4, base + 2])
+                     , (2 ^ exponentLimit, [nativeInfinity, nativeInfinity, nativeInfinity, largest, largest])
+                     , (negate (2 ^ exponentLimit), [-nativeInfinity, -nativeInfinity, -largest, -nativeInfinity, -largest])
+                     , (2 ^ (exponentLimit + 200), [nativeInfinity, nativeInfinity, nativeInfinity, largest, largest])
+                     ]
+         forM_ cases $ \(sample, expected) ->
+           forM_ (zip [minBound .. maxBound] expected) $ \(mode, value) ->
+             assertEqual (show (precision, sample, mode)) (Just value) (unliteral (convert (literal mode) (literal sample)))
+         forM_ [sRNE, sRNA, sRTP, sRTN, sRTZ] $ \mode ->
+           assertEqual "Integer zero stays positive" (Just False) (isNegativeZero <$> unliteral (convert mode 0))
+
+       source :: (Integral a, IEEEFloatConvertible a) => SBV a -> Assertion
+       source value = forM_ [minBound .. maxBound] $ \mode -> do
+         let integer = literal (maybe (error "Expected a literal source") toInteger (unliteral value)) :: SInteger
+             rm      = literal mode
+         assertEqual "Native source to Float"  (unliteral (toSFloat  rm integer)) (unliteral (toSFloat  rm value))
+         assertEqual "Native source to Double" (unliteral (toSDouble rm integer)) (unliteral (toSDouble rm value))
+
+-- | Compare native folding with solver casts, keeping both the integer and
+-- rounding mode symbolic. Include near-ties that exceed binary64 precision
+-- to detect accidental rounding through Double on the way to Float.
+nativeIntegralConversionAgreement :: Assertion
+nativeIntegralConversionAgreement = do
+  observations <- runSMT $ do
+    input <- sInteger "input"
+    mode  <- free "mode"
+    query $ forM [(n, rm) | n <- samples, rm <- [minBound .. maxBound]] $ \(n, rm) -> inNewAssertionStack $ do
+      constrain (input .== literal n)
+      constrain (mode .== literal rm)
+      status <- checkSat
+      case status of
+        Sat -> do f <- getValue (toSFloat mode input)
+                  d <- getValue (toSDouble mode input)
+                  pure (n, rm, status, Just f, Just d)
+        _   -> pure (n, rm, status, Nothing, Nothing)
+  forM_ observations $ \(n, rm, status, f, d) -> do
+    assertEqual "Concrete input and rounding mode are satisfiable" Sat status
+    assertEqual (show (n, rm) ++ ": Float")  f (unliteral (toSFloat  (literal rm) (literal n :: SInteger)))
+    assertEqual (show (n, rm) ++ ": Double") d (unliteral (toSDouble (literal rm) (literal n :: SInteger)))
+  assertIsThm $ \mode -> toSFloat mode (16777217 :: SInteger)
+                     .== ite (mode .== sRNA .|| mode .== sRTP) 16777218 16777216
+  assertIsThm $ \mode -> toSDouble mode (-9007199254740993 :: SInteger)
+                     .== ite (mode .== sRNA .|| mode .== sRTN) (-9007199254740994) (-9007199254740992)
+ where samples = 0 : [sign * n | sign <- [1, -1], n <- [2 ^ (24 :: Int) + 1, 2 ^ (24 :: Int) + 3,
+                                                      2 ^ (53 :: Int) + 1, 2 ^ (53 :: Int) + 3,
+                                                      2 ^ (54 :: Int) + 2 ^ (30 :: Int) + 1,
+                                                      2 ^ (128 :: Int), 2 ^ (1024 :: Int)]]
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
@@ -10,17 +10,10 @@
 -- the constant folding based arithmetic implementation in SBV
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE CPP              #-}
-{-# LANGUAGE DataKinds        #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE Rank2Types       #-}
-{-# LANGUAGE TupleSections    #-}
+{-# LANGUAGE RankNTypes    #-}
+{-# LANGUAGE TupleSections #-}
 
-#if MIN_VERSION_base(4,19,0)
 {-# OPTIONS_GHC -Wall -Werror -Wno-incomplete-uni-patterns -Wno-x-partial #-}
-#else
-{-# OPTIONS_GHC -Wall -Werror -Wno-incomplete-uni-patterns #-}
-#endif
 
 module TestSuite.Basics.ArithNoSolver(tests) where
 
@@ -29,9 +22,7 @@
 
 import Data.Maybe (fromJust, fromMaybe)
 
-import qualified Data.Char     as C
-
-import qualified Data.SBV.Char () -- instances only
+import qualified Data.Char as C
 
 -- Test suite
 tests :: TestTree
@@ -162,8 +153,6 @@
         -- Haskell's divMod and quotRem differs from SBV's in two ways:
         --     - when y is 0, Haskell throws an exception, SBV sets the result to 0; like in division
         --     - Haskell overflows if x == minBound and y == -1 for bounded signed types; but SBV returns minBound, 0; which is more meaningful
-        -- NB. There was a ticket filed against the second anomaly above, See: http://ghc.haskell.org/trac/ghc/ticket/8695
-        -- But the Haskell folks decided not to fix it. Sigh..
         overflow x y = x == minBound && y == -1
         divMod0  x y = if y == 0       then (0, x) else x `divMod`   y
         divMod1  x y = if overflow x y then (x, 0) else x `divMod0`  y
diff --git a/SBVTestSuite/TestSuite/Basics/ArithNoSolver2.hs b/SBVTestSuite/TestSuite/Basics/ArithNoSolver2.hs
--- a/SBVTestSuite/TestSuite/Basics/ArithNoSolver2.hs
+++ b/SBVTestSuite/TestSuite/Basics/ArithNoSolver2.hs
@@ -10,24 +10,15 @@
 -- the constant folding based arithmetic implementation in SBV
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE CPP                #-}
-{-# LANGUAGE DataKinds          #-}
-{-# LANGUAGE DeriveAnyClass     #-}
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE FlexibleContexts   #-}
-{-# LANGUAGE FlexibleInstances  #-}
-{-# LANGUAGE Rank2Types         #-}
-{-# LANGUAGE StandaloneDeriving #-}
-{-# LANGUAGE TemplateHaskell    #-}
-{-# LANGUAGE TupleSections      #-}
-{-# LANGUAGE TypeApplications   #-}
-{-# LANGUAGE QuasiQuotes        #-}
+{-# LANGUAGE DataKinds         #-}
+{-# LANGUAGE FlexibleContexts  #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE RankNTypes        #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE TypeApplications  #-}
+{-# LANGUAGE QuasiQuotes       #-}
 
-#if MIN_VERSION_base(4,19,0)
 {-# OPTIONS_GHC -Wall -Werror -Wno-incomplete-uni-patterns -Wno-x-partial #-}
-#else
-{-# OPTIONS_GHC -Wall -Werror -Wno-incomplete-uni-patterns #-}
-#endif
 
 module TestSuite.Basics.ArithNoSolver2(tests) where
 
@@ -42,8 +33,8 @@
 import qualified Data.SBV.Char   as SC
 import qualified Data.SBV.List   as SL
 
-data Day = Mon | Tue | Wed | Thu | Fri | Sat | Sun deriving (Bounded, Enum, Eq)
-mkSymbolicEnumeration  ''Day
+data Day = Mon | Tue | Wed | Thu | Fri | Sat | Sun deriving (Show, Eq, Enum, Bounded)
+mkSymbolic  [''Day]
 
 -- Test suite
 tests :: TestTree
@@ -449,7 +440,6 @@
 
         -- NB. Precision here is important. If you pick too small of a significand
         -- size then you can turn this enumeration into an infinite list, busting the tests.
-        -- For details see: https://gitlab.haskell.org/ghc/ghc/-/issues/15081
         fps :: [FloatingPoint 5 8]
         fps = [-3.4, -3.2 .. 3.5]
 
@@ -539,6 +529,8 @@
 
 -- Quiet GHC about unused enum elts
 _unused :: SDay
-_unused = undefined sMon sTue sWed sThu sFri sSat sSun
+_unused = undefined  sMon  sTue  sWed  sThu  sFri  sSat  sSun
+                    isMon isTue isWed isThu isFri isSat isSun
+                    (sCaseDay @SInteger)
 
 {- 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
@@ -11,24 +11,16 @@
 -- constant folding.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE CPP                 #-}
 {-# LANGUAGE DataKinds           #-}
-{-# LANGUAGE DeriveAnyClass      #-}
-{-# LANGUAGE DeriveDataTypeable  #-}
 {-# LANGUAGE FlexibleContexts    #-}
 {-# LANGUAGE FlexibleInstances   #-}
-{-# LANGUAGE Rank2Types          #-}
 {-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE RankNTypes          #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE StandaloneDeriving  #-}
 {-# LANGUAGE TemplateHaskell     #-}
 {-# LANGUAGE TypeApplications    #-}
 
-#if MIN_VERSION_base(4,19,0)
 {-# OPTIONS_GHC -Wall -Werror -Wno-incomplete-uni-patterns -Wno-x-partial #-}
-#else
-{-# OPTIONS_GHC -Wall -Werror -Wno-incomplete-uni-patterns #-}
-#endif
 
 module TestSuite.Basics.ArithSolver(tests) where
 
@@ -41,8 +33,8 @@
 import qualified Data.SBV.Char   as SC
 import qualified Data.SBV.List   as SL
 
-data Day = Mon | Tue | Wed | Thu | Fri | Sat | Sun deriving (Bounded, Enum, Eq)
-mkSymbolicEnumeration  ''Day
+data Day = Mon | Tue | Wed | Thu | Fri | Sat | Sun deriving (Show, Bounded, Enum, Eq)
+mkSymbolic  [''Day]
 
 -- Test suite
 tests :: TestTree
@@ -93,6 +85,7 @@
      ++ genLists
      ++ genEnums
      ++ misc
+     ++ realRatConvs
      )
 
 genExtends :: [TestTree]
@@ -396,7 +389,7 @@
 genDoubles :: [TestTree]
 genDoubles = genIEEE754 "genDoubles" ds
 
-genIEEE754 :: (IEEEFloating a, OrdSymbolic (SBV a), Num (SBV a), Show a) => String -> [a] -> [TestTree]
+genIEEE754 :: (IEEEFloating a, OrdSymbolic (SBV a), Num (SBV a), Fractional (SBV a), Show a) => String -> [a] -> [TestTree]
 genIEEE754 origin vs =  [tst1 ("pred_"   ++ nm, x, y)    | (nm, x, y)    <- preds]
                      ++ [tst1 ("unary_"  ++ nm, x, y)    | (nm, x, y)    <- uns]
                      ++ [tst2 ("binary_" ++ nm, x, y, r) | (nm, x, y, r) <- bins]
@@ -880,7 +873,7 @@
 
 rs :: [Ratio Integer]
 rs = [i % d | i <- is, d <- dens]
- where is   = [-1000000] ++ [-1 .. 1] ++ [10000001]
+ where is   = [-1000000] ++ [-1 .. 1] ++ [1000001]
        dens = [5,100,1000000]
 
 -- Admittedly paltry test-cases for float/double
@@ -926,10 +919,128 @@
 misc :: [TestTree]
 misc = [ testCase "misc-t1" $ assertIsSat t1
        ]
- where -- https://stackoverflow.com/questions/69033969/trivial-rationals-problems-without-variables-in-sbv-solver-in-haskell
-       t1 = do _xs <- sRationals []
+ where t1 = do _xs <- sRationals []
                constrain $ (5.%1:: SRational) .<= (5.%1:: SRational)
 
+realRatConvs :: [TestTree]
+realRatConvs = [ testCase "realConv1" $ assertIsThm $ respectsLe sRealToSIntegerRM
+               , testCase "realConv2" $ assertIsThm realFloorCorrect
+               , testCase "realConv3" $ assertIsThm realFloorCorrect2
+               , testCase "realConv4" $ assertIsThm realCeilingCorrect
+               , testCase "realConv5" $ assertIsThm realCeilingCorrect2
+               , testCase "realConv6" $ assertIsThm $ realRoundNearest sRNE
+               , testCase "realConv7" $ assertIsThm $ realRoundNearest sRNA
+               , testCase "realConv8" $ assertIsThm realRneTieEven
+               , testCase "realConv9" $ assertIsThm realRnaTieAway
+
+               , testCase "ratConv1"  $ assertIsThm $ respectsLe sRationalToSIntegerRM
+               , testCase "ratConv2"  $ assertIsThm rationalFloorCorrect
+               , testCase "ratConv3"  $ assertIsThm rationalFloorCorrect2
+               , testCase "ratConv4"  $ assertIsThm rationalCeilingCorrect
+               , testCase "ratConv5"  $ assertIsThm rationalCeilingCorrect2
+               , testCase "ratConv6"  $ assertIsThm $ ratRoundNearest sRNE
+               , testCase "ratConv7"  $ assertIsThm $ ratRoundNearest sRNA
+               , testCase "ratConv8"  $ assertIsThm ratRneTieEven
+               , testCase "ratConv9"  $ assertIsThm ratRnaTieAway
+
+               , testCase "ratRealRoundTrip1" $ assert $ isTheorem ratToRealToRat
+               , testCase "ratRealRoundTrip2" $ assert $ isTheorem realToRatToReal
+
+               , testCase "convertCov1" $ assertIsSat (\x y -> sFromIntegral @Word8   @Integer  x .== y)
+               , testCase "convertCov2" $ assertIsSat (\x y -> sFromIntegral @Integer @Word8    x .== y)
+               , testCase "convertCov3" $ assertIsSat (\x y -> sFromIntegral @Integer @AlgReal  x .== y)
+               , testCase "convertCov4" $ assertIsSat (\x y -> sFromIntegral @Integer @Float    x .== y)
+               , testCase "convertCov5" $ assertIsSat (\x y -> sFromIntegral @Word8   @Float    x .== y)
+               , testCase "convertCov6" $ assertIsSat (\x y -> sFromIntegral @Integer @Rational x .== y)
+               , testCase "convertCov7" $ assertIsSat (\x y -> sFromIntegral @Word8   @AlgReal  x .== y)
+               , testCase "convertCov8" $ assertIsSat (\x y -> sFromIntegral @Word8   @Rational x .== y)
+               , testCase "convertCov9" $ assertIsSat $ \(x :: SRational) (y :: SRational) (r :: SRational) -> (x / y) .== r
+
+               , testCase "ratDiv1" $ assertIsThm ratDivCancels
+               , testCase "ratDiv2" $ assertIsThm ratDivByZero
+               ]
+ where -- (x <= y) ==> (round x <= round y)
+       respectsLe :: OrdSymbolic a => (SRoundingMode -> a -> SInteger) -> SRoundingMode -> a -> a -> SBool
+       respectsLe rnd rm x y = (x .<= y) .=> (rnd rm x .<= rnd rm y)
+
+       -- floor x <= x
+       realFloorCorrect :: SReal -> SBool
+       realFloorCorrect x = sFromIntegral (sRealToSIntegerRM sRTN x) .<= x
+
+       -- (x <= y) ==> (x <= floor y) [where x is an Integer]
+       realFloorCorrect2 :: SInteger -> SReal -> SBool
+       realFloorCorrect2 x y = (sFromIntegral x .<= y) .=> (x .<= sRealToSIntegerRM sRTN y)
+
+       -- ceiling x >= x
+       realCeilingCorrect :: SReal -> SBool
+       realCeilingCorrect x = sFromIntegral (sRealToSIntegerRM sRTP x) .>= x
+
+       -- (x >= y) ==> (x >= ceiling y) [where x is an integer]
+       realCeilingCorrect2 :: SInteger -> SReal -> SBool
+       realCeilingCorrect2 x y = (sFromIntegral x .>= y) .=> (x .>= sRealToSIntegerRM sRTP y)
+
+       -- Rounding to nearest is within 1/2 of the input (holds for both round-to-even and round-away).
+       realRoundNearest :: SRoundingMode -> SReal -> SBool
+       realRoundNearest rm x = abs (sFromIntegral (sRealToSIntegerRM rm x) - x) .<= 0.5
+
+       -- On a tie (x = k + 1/2), round-to-even produces an even integer.
+       realRneTieEven :: SInteger -> SBool
+       realRneTieEven k = sDivides 2 (sRealToSIntegerRM sRNE x)
+         where x = sFromIntegral k + 0.5 :: SReal
+
+       -- On a tie (x = k + 1/2), round-away picks the integer further from zero.
+       realRnaTieAway :: SInteger -> SBool
+       realRnaTieAway k = sRealToSIntegerRM sRNA x .== ite (x .>= 0) (k+1) k
+         where x = sFromIntegral k + 0.5 :: SReal
+
+       -- floor x <= x
+       rationalFloorCorrect :: SRational -> SBool
+       rationalFloorCorrect x = (sRationalToSIntegerRM sRTN x .% 1) .<= x
+
+       -- (x <= y) ==> (x <= floor y) [where x is an integer]
+       rationalFloorCorrect2 :: SInteger -> SRational -> SBool
+       rationalFloorCorrect2 x y = ((x .% 1) .<= y) .=> (x .<= sRationalToSIntegerRM sRTN y)
+
+       -- (x >= y) ==> (x >= ceiling y) [where x is an integer]
+       rationalCeilingCorrect2 :: SInteger -> SRational -> SBool
+       rationalCeilingCorrect2 x y = ((x .% 1) .>= y) .=> (x .>= sRationalToSIntegerRM sRTP y)
+
+       -- ceiling x >= x
+       rationalCeilingCorrect :: SRational -> SBool
+       rationalCeilingCorrect x = (sRationalToSIntegerRM sRTP x .% 1) .>= x
+
+       -- Rounding to nearest is within 1/2 of the input (holds for both round-to-even and round-away).
+       ratRoundNearest :: SRoundingMode -> SRational -> SBool
+       ratRoundNearest rm x = abs ((sRationalToSIntegerRM rm x .% 1) - x) .<= (1 .% 2)
+
+       -- On a tie (x = k + 1/2), round-to-even produces an even integer.
+       ratRneTieEven :: SInteger -> SBool
+       ratRneTieEven k = sDivides 2 (sRationalToSIntegerRM sRNE x)
+         where x = (2*k+1) .% 2
+
+       -- On a tie (x = k + 1/2), round-away picks the integer further from zero.
+       ratRnaTieAway :: SInteger -> SBool
+       ratRnaTieAway k = sRationalToSIntegerRM sRNA x .== ite (x .>= 0) (k+1) k
+         where x = (2*k+1) .% 2
+
+       -- Division cancels: for a non-zero divisor, (x / y) * y == x.
+       ratDivCancels :: SRational -> SRational -> SBool
+       ratDivCancels x y = (y ./= 0) .=> ((x / y) * y .== x)
+
+       -- Division by zero is defined to be zero, matching the SBV convention for reals.
+       ratDivByZero :: SRational -> SRational -> SBool
+       ratDivByZero x y = (y .== 0) .=> ((x / y) .== 0)
+
+       -- rational -> real -> rational is the identity: no precision is lost.
+       ratToRealToRat :: SRational -> SBool
+       ratToRealToRat x = sRealToSRational (sRationalToSReal x) .== x
+
+       -- real -> rational -> real is the identity. Recall that sRealToSRational
+       -- implicitly asserts that its argument is rational, so this holds for
+       -- every (well-defined) real here.
+       realToRatToReal :: SReal -> SBool
+       realToRatToReal x = sRationalToSReal (sRealToSRational x) .== x
+
 -- Test these with make test TGT=sEnum_
 genEnums :: [TestTree]
 genEnums =
@@ -1029,8 +1140,6 @@
 
         -- NB. Precision here is important. If you pick too small of a significand
         -- size then you can turn this enumeration into an infinite list, busting the tests.
-        -- For details see: https://gitlab.haskell.org/ghc/ghc/-/issues/15081
-        -- And likewise, constant folding doesn't happen, too difficult for z3
         fps :: [FloatingPoint 5 8]
         -- fps = [-3.4, -3.2 .. 3.5]
         fps = []
@@ -1046,6 +1155,8 @@
 
 -- Quiet GHC about unused enum elts
 _unused :: SDay
-_unused = undefined sMon sTue sWed sThu sFri sSat sSun
+_unused = undefined  sMon  sTue  sWed  sThu  sFri  sSat  sSun
+                    isMon isTue isWed isThu isFri isSat isSun
+                    (sCaseDay @SInteger)
 
 {- HLint ignore module "Reduce duplication" -}
diff --git a/SBVTestSuite/TestSuite/Basics/BarrelRotate.hs b/SBVTestSuite/TestSuite/Basics/BarrelRotate.hs
--- a/SBVTestSuite/TestSuite/Basics/BarrelRotate.hs
+++ b/SBVTestSuite/TestSuite/Basics/BarrelRotate.hs
@@ -10,7 +10,6 @@
 -----------------------------------------------------------------------------
 
 {-# LANGUAGE FlexibleContexts    #-}
-{-# LANGUAGE RankNTypes          #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeApplications    #-}
 
diff --git a/SBVTestSuite/TestSuite/Basics/BasicTests.hs b/SBVTestSuite/TestSuite/Basics/BasicTests.hs
--- a/SBVTestSuite/TestSuite/Basics/BasicTests.hs
+++ b/SBVTestSuite/TestSuite/Basics/BasicTests.hs
@@ -9,7 +9,7 @@
 -- Test suite for Examples.Basics.BasicTests
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE Rank2Types          #-}
+{-# LANGUAGE RankNTypes          #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
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
@@ -10,14 +10,10 @@
 -----------------------------------------------------------------------------
 
 {-# LANGUAGE DataKinds           #-}
-{-# LANGUAGE DeriveAnyClass      #-}
-{-# LANGUAGE DeriveDataTypeable  #-}
 {-# LANGUAGE FlexibleContexts    #-}
 {-# LANGUAGE OverloadedLists     #-}
 {-# LANGUAGE QuasiQuotes         #-}
-{-# LANGUAGE RankNTypes          #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE StandaloneDeriving  #-}
 {-# LANGUAGE TemplateHaskell     #-}
 {-# LANGUAGE TypeApplications    #-}
 
@@ -46,7 +42,7 @@
 import Utils.SBVTestFramework
 
 data P
-mkUninterpretedSort ''P
+mkSymbolic [''P]
 
 drinker :: Predicate
 drinker = pure $ quantifiedBool $ \(Exists x) (Forall y) -> d x .=> d y
@@ -80,7 +76,7 @@
       , goldenCapturedIO "lambda12" $ eval1 [1 .. 3 :: Integer] (map singleton, P.map (: []))
 
       , goldenCapturedIO "lambda13" $ eval1 [(x, y) | x <- [1..3], y <- [4..6 :: Integer]]
-                                            (map (\t -> t^._1 + t^._2), P.map (uncurry (+)))
+                                            (map (\t -> t^._1 + t^._2), P.map (P.uncurry (+)))
 
       , goldenCapturedIO "lambda14" $ eval1 [1 .. 5 :: Integer] (zipWithL (+) [sEnum|10..15|], P.zipWith (+) [10..15])
 
@@ -162,7 +158,7 @@
       , goldenCapturedIO "lambda52_c" $ runSat  (isOdd  21 .==)
 
       -- make sure we can pass globals
-      , goldenCapturedIO "lambda53" $ runSat $ \x -> x .== smtFunction "foo" (+(x::SInteger)) x
+      , goldenCapturedIO "lambda53" $ runS $ \x -> x .== smtFunction "foo" (+(x::SInteger)) x
 
       -- Make sure we can handle dependency orders
       , goldenCapturedIO "lambda54" $ runSat   $ \x -> let foo = smtFunction "foo" (\a -> bar a + 1)
@@ -179,6 +175,23 @@
                                                            f3 = smtFunction "f3" (\a -> ite (a .== 0) 0 (1 + (f3 (a-1) + f4 (a-2))))
                                                            f4 = smtFunction "f4" (\a -> ite (a .== 0) 0 (1 + (f4 (a-1) + f1 (a-2))))
                                                        in f1 x .== (x :: SWord8)
+      , goldenCapturedIO "lambda57a" $ runSat $ \x -> let f1 = smtFunction "f1i" (\a -> ite (a .<= 0) 0 (1 + (f1 (a-1) + f2 (a-2))))
+                                                          f2 = smtFunction "f2i" (\a -> ite (a .<= 0) 0 (1 + (f2 (a-1) + f3 (a-2))))
+                                                          f3 = smtFunction "f3i" (\a -> ite (a .<= 0) 0 (1 + (f3 (a-1) + f4 (a-2))))
+                                                          f4 = smtFunction "f4i" (\a -> ite (a .<= 0) 0 (1 + (f4 (a-1) + f1 (a-2))))
+                                                      in f1 x .== (x :: SInteger)
+      , goldenCapturedIO "lambda57b" $ runSat $ \x -> let m a = 0 `smax` a :: SInteger
+                                                          f1 = smtFunctionWithMeasure "f1m" (m, []) (\a -> ite (a .<= 0) 0 (1 + (f1 (a-1) + f2 (a-2))))
+                                                          f2 = smtFunctionWithMeasure "f2m" (m, []) (\a -> ite (a .<= 0) 0 (1 + (f2 (a-1) + f3 (a-2))))
+                                                          f3 = smtFunctionWithMeasure "f3m" (m, []) (\a -> ite (a .<= 0) 0 (1 + (f3 (a-1) + f4 (a-2))))
+                                                          f4 = smtFunctionWithMeasure "f4m" (m, []) (\a -> ite (a .<= 0) 0 (1 + (f4 (a-1) + f1 (a-2))))
+                                                      in f1 x .== (x :: SInteger)
+      , goldenCapturedIO "lambda57c" $ runSat $ \x -> let m  = sFromIntegral :: SWord8 -> SInteger
+                                                          f1 = smtFunctionWithMeasure "f1w" (m, []) (\a -> ite (a .== 0) 0 (1 + (f1 (a-1) + f2 (a-2))))
+                                                          f2 = smtFunctionWithMeasure "f2w" (m, []) (\a -> ite (a .== 0) 0 (1 + (f2 (a-1) + f3 (a-2))))
+                                                          f3 = smtFunctionWithMeasure "f3w" (m, []) (\a -> ite (a .== 0) 0 (1 + (f3 (a-1) + f4 (a-2))))
+                                                          f4 = smtFunctionWithMeasure "f4w" (m, []) (\a -> ite (a .== 0) 0 (1 + (f4 (a-1) + f1 (a-2))))
+                                                      in f1 x .== (x :: SWord8)
 
       -- Quantified axioms
       , goldenCapturedIO "lambda58" $ record $ \st -> constraintStr st $ \(Forall b) (Exists c) -> sNot b .|| c
@@ -211,6 +224,17 @@
       , goldenCapturedIO "lambda69" $ runS $ \(Forall x) (Forall y) -> uninterpret "F" x y .== 2*x+(3-y::SInteger)
 
       -- Most skolems are tested inline, here's a fancy one!
+      -- This is satisfiable. A model for this will present two functions, x_eu1 and x_eu2
+      -- If these functions differ on all mappings i.e. forall x. x_eu1 x /= x_eu2 x, then
+      -- it would be a valid model for this problem. Note that these functions can
+      -- be constant functions mapping to different values; or functions that distinguish
+      -- some subset of inputs, so long as they map it to different values. Examples:
+      --    x_eu1 _ = 0      x_eu2 _ = 0
+      -- OR
+      --    x_eu1 1 = 0      x_eu2 1 = 1
+      --    x_eu1 _ = 1      x_eu2 _ = 0
+      --
+      -- are all good.
       , goldenCapturedIO "lambda70" $
                 let phi :: ExistsUnique "x" Integer -> SBool
                     phi (ExistsUnique  x) = x .== 0 .|| x .== 1
@@ -298,7 +322,7 @@
 
         rel, leq :: Relation Integer
         rel = uninterpret "R"
-        leq = uncurry $ smtFunction "leq" (.<=)
+        leq = P.uncurry $ smtFunction "leq" (.<=)
         po  = isPartialOrder "poR" rel
         poI = isPartialOrder "poI" leq
 
@@ -437,7 +461,7 @@
 
    xs <- free_
    ys <- free_
-   pure $ map (ae xs) ys .== nil
+   pure $ map (ae xs) ys .== []
 
 -- This one is ok, because we're using the global xs. (i.e., no free vars)
 filterHead :: Symbolic String
diff --git a/SBVTestSuite/TestSuite/Basics/List.hs b/SBVTestSuite/TestSuite/Basics/List.hs
--- a/SBVTestSuite/TestSuite/Basics/List.hs
+++ b/SBVTestSuite/TestSuite/Basics/List.hs
@@ -133,7 +133,7 @@
   constrain $ sNot $ c `L.isInfixOf` b
   constrain $ sNot $ b `L.isInfixOf` c
 
--- Any string is equal to the prefix and suffix that add up to a its length.
+-- Any string is equal to the prefix and suffix that add up to its length.
 seqExamples8 :: Symbolic ()
 seqExamples8 = do
   [a, b, c :: SList Integer] <- sLists ["a", "b", "c"]
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
@@ -9,15 +9,10 @@
 -- Various combinations of quantifiers
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE CPP                 #-}
 {-# LANGUAGE DataKinds           #-}
 {-# LANGUAGE FlexibleContexts    #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeApplications    #-}
-
-#if MIN_VERSION_base(4,19,0)
 {-# LANGUAGE TypeAbstractions    #-}
-#endif
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
diff --git a/SBVTestSuite/TestSuite/Basics/Recursive.hs b/SBVTestSuite/TestSuite/Basics/Recursive.hs
--- a/SBVTestSuite/TestSuite/Basics/Recursive.hs
+++ b/SBVTestSuite/TestSuite/Basics/Recursive.hs
@@ -9,6 +9,12 @@
 -- Some recursive definitions.
 -----------------------------------------------------------------------------
 
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE OverloadedLists     #-}
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+
 {-# OPTIONS_GHC -Wall -Werror #-}
 
 module TestSuite.Basics.Recursive(tests) where
@@ -17,12 +23,24 @@
 
 import Data.SBV.Internals  (genMkSymVar, unSBV, VarContext(..))
 
+import Data.List (isInfixOf)
+
+import qualified Data.SBV.List as L
 import qualified Data.SBV.Dynamic as D
+import Data.SBV.TP (runTPWith, lemma)
 
--- This is recursive and suffers from the termination problem.
+import qualified Control.Exception as C
+
+import Documentation.SBV.Examples.Misc.Definitions (ack)
+import Documentation.SBV.Examples.TP.McCarthy91    (mcCarthy91)
+
+-- This is recursive and can't be symbolically simulated for arbitrary inputs.
 -- But we can still prove a few things about it!
 mgcd :: SWord8 -> SWord8 -> SWord8
-mgcd a b = ite (b .== 0) a (mgcd b (a `sMod` b))
+mgcd a b = [sCase| b of
+              _ | b .== 0 -> a
+              _           -> mgcd b (a `sMod` b)
+           |]
 
 -- Same construction, expressed in terms of the dynamic interface
 mgcdDyn :: Int -> IO ThmResult
@@ -50,11 +68,402 @@
                   ThmResult Satisfiable{}   -> return False
                   _                         -> error "checkThm: Unexpected result!"
 
+-- | Test that auto-guess succeeds for an integer-recursive function (abs measure)
+autoGuessInteger :: Assertion
+autoGuessInteger = assertIsSat $ \(x :: SInteger) -> f x .== x
+  where f :: SInteger -> SInteger
+        f = smtFunction "autoGuessIntF" $ \x -> ite (x .<= 0) 0 (1 + f (x - 1))
+
+-- | Test that auto-guess succeeds for a list-recursive function (length measure)
+autoGuessList :: Assertion
+autoGuessList = assertIsSat $ \(xs :: SList Integer) -> myLen xs .>= 0
+  where myLen :: SList Integer -> SInteger
+        myLen = smtFunction "autoGuessListLen" $ \xs ->
+                  ite (L.null xs) 0 (1 + myLen (L.tail xs))
+
+-- | Test that auto-guess fails when candidates exist but don't work (Ackermann)
+autoGuessFailCandidates :: Assertion
+autoGuessFailCandidates = do
+  r <- C.try $ sat $ \(x :: SInteger) (y :: SInteger) -> ack' x y .== 0
+  case r of
+    Left (e :: C.SomeException) -> if "Cannot determine a termination measure" `isInfixOf` show e
+                                      then pure ()
+                                      else assertFailure $ "Unexpected exception: " ++ show e
+    Right _                     -> assertFailure "Expected error for Ackermann auto-guess"
+  where ack' :: SInteger -> SInteger -> SInteger
+        ack' = smtFunction "ackermann" $ \m n ->
+                ite (m .== 0) (n + 1)
+                    (ite (n .== 0) (ack' (m - 1) 1)
+                                   (ack' (m - 1) (ack' m (n - 1))))
+
+-- | Test that auto-guess fails when no candidates can be derived (non-integer, non-list args)
+autoGuessNoCandidates :: Assertion
+autoGuessNoCandidates = do
+  r <- C.try $ sat $ \(b :: SBool) -> h b .== 0
+  case r of
+    Left (e :: C.SomeException) -> if "No measure candidates" `isInfixOf` show e
+                                      then pure ()
+                                      else assertFailure $ "Unexpected exception: " ++ show e
+    Right _                     -> assertFailure "Expected error for no-candidate auto-guess"
+  where h :: SBool -> SInteger
+        h = smtFunction "noCandidate" $ \b -> ite b (1 + h (sNot b)) 0
+
+-- | Test that a non-recursive smtFunction without a measure is accepted
+nonRecursiveNoMeasure :: Assertion
+nonRecursiveNoMeasure = assertIsSat $ \(x :: SInteger) -> g x .== 4
+  where g :: SInteger -> SInteger
+        g = smtFunction "nonRecG" $ \x -> 2 * x
+
 -- Test suite
 tests :: TestTree
 tests = testGroup "Basics.Recursive"
-   [ testCase "recursive1"    $ assertIsThm $ \x -> mgcd    0 x .== x
-   , testCase "recursive2"    $ assertIsThm $ \x -> mgcd    x 0 .== x
-   , testCase "recursiveDyn1" $ checkThm =<< mgcdDyn 0
-   , testCase "recursiveDyn2" $ checkThm =<< mgcdDyn 1
+   [ testCase "recursive1"                $ assertIsThm $ \x -> mgcd    0 x .== x
+   , testCase "recursive2"                $ assertIsThm $ \x -> mgcd    x 0 .== x
+   , testCase "recursiveDyn1"             $ checkThm =<< mgcdDyn 0
+   , testCase "recursiveDyn2"             $ checkThm =<< mgcdDyn 1
+   , testCase "autoGuessInteger"          autoGuessInteger
+   , testCase "autoGuessList"             autoGuessList
+   , testCase "autoGuessFailCandidates"   autoGuessFailCandidates
+   , testCase "autoGuessNoCandidates"     autoGuessNoCandidates
+   , testCase "nonRecursiveNoMeasure"     nonRecursiveNoMeasure
+
+   -- Test that an explicit measure that doesn't decrease is rejected
+   , goldenCapturedIO "recursive3_badMeasure" $ \rf -> do
+        let badSum :: SInteger -> SInteger
+            badSum = smtFunctionWithMeasure "badSum" (\_ -> 1 :: SInteger, [])
+                   $ \x -> ite (x .<= 0) 0 (x + badSum (x - 1))
+        r <- C.try $ satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \x -> badSum x .>= 0
+        case r of
+          Left (e :: C.SomeException) -> appendFile rf ("\nEXCEPTION:\n" ++ show e ++ "\n")
+          Right m                     -> appendFile rf ("\nRESULT:\n" ++ show m ++ "\n")
+
+   -- Test that lexicographic measure auto-guess works for Ackermann (nested recursion)
+   , goldenCapturedIO "recursive1_ack" $ \rf -> do
+        m <- satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \y r -> y .== (5 :: SInteger) .&& r .== ack 1 y
+        appendFile rf ("\nRESULT:\n" ++ show m ++ "\n")
+
+   -- Test that explicit measure works for enumFromThenTo.down (descending enumeration)
+   , goldenCapturedIO "recursive2_enum" $ \rf -> do
+        m <- satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \x -> L.length [sEnum|(5::SInteger), 4 .. x|] .>= 0
+        appendFile rf ("\nRESULT:\n" ++ show m ++ "\n")
+
+   -- Test that contract-based measure works for McCarthy91 (nested recursion)
+   , goldenCapturedIO "recursive4_mcCarthy91" $ \rf -> do
+        m <- satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \n -> mcCarthy91 n .== (91 :: SInteger)
+        appendFile rf ("\nRESULT:\n" ++ show m ++ "\n")
+
+   -- Test that a bad contract is rejected (contract says result is always 0, which is wrong)
+   , goldenCapturedIO "recursive5_badContract" $ \rf -> do
+        let mc91bad :: SInteger -> SInteger
+            mc91bad = smtFunctionWithContract "mc91bad"
+                        ( \n -> 0 `smax` (101 - n)
+                        , \_ r -> r .== 0
+                        , []
+                        )
+                    $ \n -> ite (n .> 100) (n - 10) (mc91bad (mc91bad (n + 11)))
+        r <- C.try $ satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \n -> mc91bad n .>= 0
+        case r of
+          Left (e :: C.SomeException) -> appendFile rf ("\nEXCEPTION:\n" ++ show e ++ "\n")
+          Right m                     -> appendFile rf ("\nRESULT:\n" ++ show m ++ "\n")
+
+   -- Test that a true-but-useless contract is rejected (contract is trivially True,
+   -- so the IH provides no information about recursive call results, and the measure
+   -- decrease for the outer call can't be proven)
+   , goldenCapturedIO "recursive6_uselessContract" $ \rf -> do
+        let mc91triv :: SInteger -> SInteger
+            mc91triv = smtFunctionWithContract "mc91triv"
+                         ( \n -> 0 `smax` (101 - n)
+                         , \_ _ -> sTrue
+                         , []
+                         )
+                     $ \n -> ite (n .> 100) (n - 10) (mc91triv (mc91triv (n + 11)))
+        r <- C.try $ satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \n -> mc91triv n .>= 0
+        case r of
+          Left (e :: C.SomeException) -> appendFile rf ("\nEXCEPTION:\n" ++ show e ++ "\n")
+          Right m                     -> appendFile rf ("\nRESULT:\n" ++ show m ++ "\n")
+
+   -- Test that a productive function (guarded recursion) is accepted
+   , goldenCapturedIO "recursive7_productive" $ \rf -> do
+        let rep :: SInteger -> SInteger -> SList Integer
+            rep = smtProductiveFunction "rep" $ \n x ->
+                    ite (n .<= 0) L.nil (x L..: rep (n - 1) x)
+        m <- satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \x -> L.length (rep 3 x) .== 3
+        appendFile rf ("\nRESULT:\n" ++ show m ++ "\n")
+
+   -- Test that a non-guarded function marked productive is rejected
+   , goldenCapturedIO "recursive8_badProductive" $ \rf -> do
+        let bad :: SInteger -> SInteger
+            bad = smtProductiveFunction "bad" $ \n -> ite (n .== 0) 0 (1 + bad (n - 1))
+        r <- C.try $ satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \n -> bad n .>= 0
+        case r of
+          Left (e :: C.SomeException) -> appendFile rf ("\nEXCEPTION:\n" ++ show e ++ "\n")
+          Right m                     -> appendFile rf ("\nRESULT:\n" ++ show m ++ "\n")
+
+   -- Test that a multi-arg productive function (guarded recursion) is accepted
+   , goldenCapturedIO "recursive9_productive2" $ \rf -> do
+        let countdown :: SInteger -> SList Integer
+            countdown = smtProductiveFunction "countdown" $ \n ->
+                          ite (n .<= 0) (L.singleton 0) (n L..: countdown (n - 1))
+        m <- satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \n -> L.head (countdown n) .== (n :: SInteger) .&& n .> 0
+        appendFile rf ("\nRESULT:\n" ++ show m ++ "\n")
+
+   -- Test mutual recursion (2-way): mf calls mg, mg calls mf, neither is self-recursive.
+   -- No measure check should fire. The SMTLib emission should use define-funs-rec.
+   , goldenCapturedIO "recursive10_mutual" $ \rf -> do
+        let mf :: SInteger -> SInteger
+            mf = smtFunction "mf" $ \n -> ite (n .<= 0) 0 (1 + mg (n - 1))
+            mg :: SInteger -> SInteger
+            mg = smtFunction "mg" $ \n -> ite (n .<= 0) 0 (1 + mf (n - 1))
+        m <- satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \x -> mf x .== (x :: SInteger)
+        appendFile rf ("\nRESULT:\n" ++ show m ++ "\n")
+
+   -- Test chain recursion (3-way): ca calls cb, cb calls cc, cc calls ca.
+   -- No measure check should fire. The SMTLib emission should use define-funs-rec.
+   , goldenCapturedIO "recursive11_chain" $ \rf -> do
+        let ca :: SInteger -> SInteger
+            ca = smtFunction "ca" $ \n -> ite (n .<= 0) 0 (1 + cb (n - 1))
+            cb :: SInteger -> SInteger
+            cb = smtFunction "cb" $ \n -> ite (n .<= 0) 0 (1 + cc (n - 1))
+            cc :: SInteger -> SInteger
+            cc = smtFunction "cc" $ \n -> ite (n .<= 0) 0 (1 + ca (n - 1))
+        m <- satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \x -> ca x .== (x :: SInteger)
+        appendFile rf ("\nRESULT:\n" ++ show m ++ "\n")
+
+   -- Test bad mutual recursion: bf calls bg with (n+1), so no measure can decrease.
+   , goldenCapturedIO "recursive12_badMutual" $ \rf -> do
+        let bf :: SInteger -> SInteger
+            bf = smtFunction "bf" $ \n -> ite (n .<= 0) 0 (1 + bg (n + 1))
+            bg :: SInteger -> SInteger
+            bg = smtFunction "bg" $ \n -> ite (n .<= 0) 0 (1 + bf (n - 1))
+        r <- C.try $ satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \x -> bf x .== (x :: SInteger)
+        case r of
+          Left (e :: C.SomeException) -> appendFile rf ("\nEXCEPTION:\n" ++ show e ++ "\n")
+          Right m                     -> appendFile rf ("\nRESULT:\n" ++ show m ++ "\n")
+
+   -- Test mutual recursion with explicit measures: ef calls eg, eg calls ef, both decreasing.
+   , goldenCapturedIO "recursive13_mutualMeasure" $ \rf -> do
+        let ef :: SInteger -> SInteger
+            ef = smtFunctionWithMeasure "ef" (abs, [])
+               $ \n -> ite (n .<= 0) 0 (1 + eg (n - 1))
+            eg :: SInteger -> SInteger
+            eg = smtFunctionWithMeasure "eg" (abs, [])
+               $ \n -> ite (n .<= 0) 0 (1 + ef (n - 1))
+        m <- satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \x -> ef x .== (x :: SInteger)
+        appendFile rf ("\nRESULT:\n" ++ show m ++ "\n")
+
+   -- Test mutual recursion with explicit measure that fails: constant measure doesn't decrease.
+   , goldenCapturedIO "recursive14_badMutualMeasure" $ \rf -> do
+        let hf :: SInteger -> SInteger
+            hf = smtFunctionWithMeasure "hf" (\_ -> 1 :: SInteger, [])
+               $ \n -> ite (n .<= 0) 0 (1 + hg (n - 1))
+            hg :: SInteger -> SInteger
+            hg = smtFunctionWithMeasure "hg" (\_ -> 1 :: SInteger, [])
+               $ \n -> ite (n .<= 0) 0 (1 + hf (n - 1))
+        r <- C.try $ satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \x -> hf x .== (x :: SInteger)
+        case r of
+          Left (e :: C.SomeException) -> appendFile rf ("\nEXCEPTION:\n" ++ show e ++ "\n")
+          Right m                     -> appendFile rf ("\nRESULT:\n" ++ show m ++ "\n")
+
+   -- Test mixed mutual recursion: xf has explicit measure, xg uses auto-guess.
+   -- xf's user-provided measure (abs n) is tried first and works for the whole group.
+   , goldenCapturedIO "recursive15_mixedMutualMeasure" $ \rf -> do
+        let xf :: SInteger -> SInteger
+            xf = smtFunctionWithMeasure "xf" (abs, [])
+               $ \n -> ite (n .<= 0) 0 (1 + xg (n - 1))
+            xg :: SInteger -> SInteger
+            xg = smtFunction "xg"
+               $ \n -> ite (n .<= 0) 0 (1 + xf (n - 1))
+        m <- satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \x -> xf x .== (x :: SInteger)
+        appendFile rf ("\nRESULT:\n" ++ show m ++ "\n")
+
+   -- Test bad mixed mutual recursion: yf has explicit measure but yg calls yf with (n+1).
+   -- The user-provided measure fails, and auto-guess also fails.
+   , goldenCapturedIO "recursive16_badMixedMutualMeasure" $ \rf -> do
+        let yf :: SInteger -> SInteger
+            yf = smtFunctionWithMeasure "yf" (abs, [])
+               $ \n -> ite (n .<= 0) 0 (1 + yg (n - 1))
+            yg :: SInteger -> SInteger
+            yg = smtFunction "yg"
+               $ \n -> ite (n .<= 0) 0 (1 + yf (n + 1))
+        r <- C.try $ satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \x -> yf x .== (x :: SInteger)
+        case r of
+          Left (e :: C.SomeException) -> appendFile rf ("\nEXCEPTION:\n" ++ show e ++ "\n")
+          Right m                     -> appendFile rf ("\nRESULT:\n" ++ show m ++ "\n")
+
+   -- Test 3-way chain with explicit measures: da calls db, db calls dc, dc calls da, all with abs measure.
+   , goldenCapturedIO "recursive17_chainMeasure" $ \rf -> do
+        let da :: SInteger -> SInteger
+            da = smtFunctionWithMeasure "da" (abs, [])
+               $ \n -> ite (n .<= 0) 0 (1 + db (n - 1))
+            db :: SInteger -> SInteger
+            db = smtFunctionWithMeasure "db" (abs, [])
+               $ \n -> ite (n .<= 0) 0 (1 + dc (n - 1))
+            dc :: SInteger -> SInteger
+            dc = smtFunctionWithMeasure "dc" (abs, [])
+               $ \n -> ite (n .<= 0) 0 (1 + da (n - 1))
+        m <- satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \x -> da x .== (x :: SInteger)
+        appendFile rf ("\nRESULT:\n" ++ show m ++ "\n")
+
+   -- Test mutual recursion with different arg types: tf takes Integer, tg takes a list.
+   -- Auto-guess fails because no single measure applies to both signatures.
+   , testCase "diffTypeMutual" $ do
+        let tf :: SInteger -> SInteger
+            tf = smtFunction "tf" $ \n -> ite (n .<= 0) 0 (1 + tg (L.singleton n))
+            tg :: SList Integer -> SInteger
+            tg = smtFunction "tg" $ \xs -> ite (L.null xs) 0 (tf (L.head xs - 1))
+        r <- C.try $ sat $ \(x :: SInteger) -> tf x .== 0
+        case r of
+          Left (e :: C.SomeException) -> if "Cannot determine a termination measure" `isInfixOf` show e
+                                            then pure ()
+                                            else assertFailure $ "Unexpected exception: " ++ show e
+          Right _                     -> assertFailure "Expected error for different-type mutual recursion"
+
+   -- Test self-recursive + mutual: sf calls itself AND sg. Both paths should be checked.
+   , goldenCapturedIO "recursive19_selfAndMutual" $ \rf -> do
+        let sf :: SInteger -> SInteger
+            sf = smtFunction "sf" $ \n -> ite (n .<= 0) 0 (sf (n - 1) + sg (n - 1))
+            sg :: SInteger -> SInteger
+            sg = smtFunction "sg" $ \n -> ite (n .<= 0) 0 (1 + sf (n - 1))
+        m <- satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \x -> sf x .== (x :: SInteger)
+        appendFile rf ("\nRESULT:\n" ++ show m ++ "\n")
+
+   -- Test all-self-recursive mutual group with bad cross-calls:
+   -- bf and bg both self-recurse (n-1), but cross-call with (n+1).
+   -- Self-recursion checks pass, but mutual group check must catch the bad cross-calls.
+   , goldenCapturedIO "recursive21_allSelfBadCross" $ \rf -> do
+        let bf :: SInteger -> SInteger
+            bf = smtFunction "bf21" $ \n -> ite (n .<= 0) 0 (bf (n - 1) + bg (n + 1))
+            bg :: SInteger -> SInteger
+            bg = smtFunction "bg21" $ \n -> ite (n .<= 0) 0 (bg (n - 1) + bf (n + 1))
+        r <- C.try $ satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \x -> bf x .== (x :: SInteger)
+        case r of
+          Left (e :: C.SomeException) -> appendFile rf ("\nEXCEPTION:\n" ++ show e ++ "\n")
+          Right m                     -> appendFile rf ("\nRESULT:\n" ++ show m ++ "\n")
+
+   -- Test all-self-recursive mutual group with good cross-calls and explicit measures:
+   -- Both bf and bg self-recurse and cross-call with (n-1). User-provided abs measure works.
+   , goldenCapturedIO "recursive22_allSelfGoodCross" $ \rf -> do
+        let bf :: SInteger -> SInteger
+            bf = smtFunctionWithMeasure "bf22" (abs, []) $ \n -> ite (n .<= 0) 0 (bf (n - 1) + bg (n - 1))
+            bg :: SInteger -> SInteger
+            bg = smtFunctionWithMeasure "bg22" (abs, []) $ \n -> ite (n .<= 0) 0 (bg (n - 1) + bf (n - 1))
+        m <- satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \x -> bf x .== (x :: SInteger)
+        appendFile rf ("\nRESULT:\n" ++ show m ++ "\n")
+
+   -- Test mutual recursion via TP proofs (exercises checkNewMeasures in Kernel.hs)
+   , goldenCapturedIO "recursive20_mutualTP" $ \rf -> do
+        let cfg = z3{verbose=True, redirectVerbose=Just rf}
+            mf :: SInteger -> SInteger
+            mf = smtFunction "mf_tp" $ \n -> ite (n .<= 0) 0 (1 + mg (n - 1))
+            mg :: SInteger -> SInteger
+            mg = smtFunction "mg_tp" $ \n -> ite (n .<= 0) 0 (1 + mf (n - 1))
+        _ <- runTPWith cfg $
+                lemma "mutual_at_0"
+                      (\(Forall @"n" n) -> n .== 0 .=> mf n .== 0)
+                      []
+        pure ()
+
+   -- Test mutual productive functions (guarded cross-calls): pf and pg build lists via each other.
+   , goldenCapturedIO "recursive23_mutualProductive" $ \rf -> do
+        let pf :: SInteger -> SList Integer
+            pf = smtProductiveFunction "pf23" $ \n ->
+                   ite (n .<= 0) (L.singleton 0) (n L..: pg (n - 1))
+            pg :: SInteger -> SList Integer
+            pg = smtProductiveFunction "pg23" $ \n ->
+                   ite (n .<= 0) (L.singleton 0) (n L..: pf (n - 1))
+        m <- satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \n -> L.head (pf n) .== (n :: SInteger) .&& n .> 0
+        appendFile rf ("\nRESULT:\n" ++ show m ++ "\n")
+
+   -- Test mutual productive functions with unguarded cross-call: bad_pg calls bad_pf without a constructor guard.
+   , goldenCapturedIO "recursive24_badMutualProductive" $ \rf -> do
+        let bad_pf :: SInteger -> SList Integer
+            bad_pf = smtProductiveFunction "bad_pf" $ \n ->
+                       ite (n .<= 0) (L.singleton 0) (n L..: bad_pg (n - 1))
+            bad_pg :: SInteger -> SList Integer
+            bad_pg = smtProductiveFunction "bad_pg" $ \n ->
+                       ite (n .<= 0) (L.singleton 0) (bad_pf (n - 1))  -- not guarded!
+        r <- C.try $ satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \(n :: SInteger) -> L.head (bad_pf n) .== n
+        case r of
+          Left (e :: C.SomeException) -> appendFile rf ("\nEXCEPTION:\n" ++ show e ++ "\n")
+          Right m                     -> appendFile rf ("\nRESULT:\n" ++ show m ++ "\n")
+
+   -- Test that smtFunctionWithContract in a mutual group is rejected.
+   , goldenCapturedIO "recursive25_contractMutualRejected" $ \rf -> do
+        let cf :: SInteger -> SInteger
+            cf = smtFunctionWithContract "cf_mut"
+                   ( \n -> 0 `smax` (101 - n)
+                   , \_ r -> r .== 91
+                   , []
+                   )
+                 $ \n -> ite (n .> 100) (n - 10) (cg (n + 11))
+            cg :: SInteger -> SInteger
+            cg = smtFunction "cg_mut" $ \n -> ite (n .<= 0) 0 (1 + cf (n - 1))
+        r <- C.try $ satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \(n :: SInteger) -> cf n .== 0
+        case r of
+          Left (e :: C.SomeException) -> appendFile rf ("\nEXCEPTION:\n" ++ show e ++ "\n")
+          Right m                     -> appendFile rf ("\nRESULT:\n" ++ show m ++ "\n")
+
+   -- Test productive function that is both self-recursive and has cross-refs.
+   -- spf calls itself AND spg, both guarded by L..:
+   , goldenCapturedIO "recursive26_selfAndMutualProductive" $ \rf -> do
+        let spf :: SInteger -> SList Integer
+            spf = smtProductiveFunction "spf26" $ \n ->
+                    ite (n .<= 0) (L.singleton 0)
+                        (ite (sMod n 2 .== 0) (n L..: spf (n - 1))
+                                              (n L..: spg (n - 1)))
+            spg :: SInteger -> SList Integer
+            spg = smtProductiveFunction "spg26" $ \n ->
+                    ite (n .<= 0) (L.singleton 0) (n L..: spf (n - 1))
+        m <- satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \n -> L.head (spf n) .== (n :: SInteger) .&& n .> 0
+        appendFile rf ("\nRESULT:\n" ++ show m ++ "\n")
+
+   -- Test 3-way mutually-recursive productive streams.
+   -- pa -> pb -> pc -> pa, all guarded by L..:
+   , goldenCapturedIO "recursive27_mutualProductive3" $ \rf -> do
+        let pa :: SInteger -> SList Integer
+            pa = smtProductiveFunction "pa27" $ \n ->
+                   ite (n .<= 0) (L.singleton 0) (n L..: pb (n - 1))
+            pb :: SInteger -> SList Integer
+            pb = smtProductiveFunction "pb27" $ \n ->
+                   ite (n .<= 0) (L.singleton 0) ((n * 10) L..: pc (n - 1))
+            pc :: SInteger -> SList Integer
+            pc = smtProductiveFunction "pc27" $ \n ->
+                   ite (n .<= 0) (L.singleton 0) ((n * 100) L..: pa (n - 1))
+        m <- satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \n -> L.head (pa n) .== (n :: SInteger) .&& n .> 0
+        appendFile rf ("\nRESULT:\n" ++ show m ++ "\n")
+
+   -- Test smtFunctionNoTermination: proofs show [Modulo: <name> termination]
+   , goldenCapturedIO "recursive28_noTermCheck" $ \rf -> do
+        let f :: SInteger -> SInteger
+            f = smtFunctionNoTermination "ntc28" $ \n -> ite (n .<= 0) 0 (1 + f (n - 1))
+        p <- runTPWith z3{verbose=True, redirectVerbose=Just rf} $
+                lemma "ntc_at_5"
+                      (\(Forall @"n" n) -> n .== 5 .=> f n .== 5)
+                      []
+        appendFile rf (show p ++ "\n")
    ]
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
@@ -9,12 +9,10 @@
 -- Test sets.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DeriveAnyClass      #-}
-{-# LANGUAGE DeriveDataTypeable  #-}
 {-# LANGUAGE FlexibleInstances   #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE StandaloneDeriving  #-}
 {-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE TypeApplications    #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -29,11 +27,8 @@
 
 import Utils.SBVTestFramework hiding (complement)
 
-data E = A | B | C deriving (Bounded, Enum, Ord, Eq)
-mkSymbolicEnumeration ''E
-
-__unused :: SE
-__unused = error "stop GHC from complaining unused names" sA sB sC
+data E = A | B | C deriving (Show, Eq, Ord)
+mkSymbolic [''E]
 
 type SC = SSet  Integer
 type RC = RCSet Integer
diff --git a/SBVTestSuite/TestSuite/Basics/SmtFunctionUnique.hs b/SBVTestSuite/TestSuite/Basics/SmtFunctionUnique.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/Basics/SmtFunctionUnique.hs
@@ -0,0 +1,84 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : TestSuite.Basics.SmtFunctionUnique
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Tests for smtFunction name uniqueness enforcement.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE ScopedTypeVariables #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module TestSuite.Basics.SmtFunctionUnique(tests) where
+
+import Utils.SBVTestFramework
+
+import qualified Control.Exception as C
+
+-- Test suite
+tests :: TestTree
+tests = testGroup "Basics.SmtFunctionUnique"
+   [
+   -- Same name, same body: should succeed (idempotent re-registration).
+     goldenCapturedIO "smtFuncUniq_sameOk" $ \rf -> do
+        let f :: SInteger -> SInteger
+            f = smtFunction "f" $ \x -> x + 1
+        m <- satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \x -> f x + f x .== 4
+        appendFile rf ("\nRESULT:\n" ++ show m ++ "\n")
+
+   -- Same name, different body: should error.
+   , goldenCapturedIO "smtFuncUniq_conflict" $ \rf -> do
+        let f :: SInteger -> SInteger
+            f = smtFunction "f" $ \x -> x + 1
+            g :: SInteger -> SInteger
+            g = smtFunction "f" $ \x -> x + 2
+        r <- C.try $ satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \x -> f x + g x .== 5
+        case r of
+          Left (e :: C.SomeException) -> appendFile rf (show e ++ "\n")
+          Right m                     -> appendFile rf ("\nUNEXPECTED SUCCESS:\n" ++ show m ++ "\n")
+
+   -- Same name, same recursive body: should succeed.
+   , goldenCapturedIO "smtFuncUniq_recursiveOk" $ \rf -> do
+        let f :: SInteger -> SInteger
+            f = smtFunction "f" $ \x -> ite (x .<= 0) 0 (x + f (x - 1))
+        m <- satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \x -> x .>= 0 .&& x .<= 3 .&& f x .== 6
+        appendFile rf ("\nRESULT:\n" ++ show m ++ "\n")
+
+   -- Same name, different recursive body: should error.
+   , goldenCapturedIO "smtFuncUniq_recursiveConflict" $ \rf -> do
+        let f :: SInteger -> SInteger
+            f = smtFunction "f" $ \x -> ite (x .<= 0) 0 (x + f (x - 1))
+            g :: SInteger -> SInteger
+            g = smtFunction "f" $ \x -> ite (x .<= 0) 1 (x * g (x - 1))
+        r <- C.try $ satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \x -> f x + g x .== 10
+        case r of
+          Left (e :: C.SomeException) -> appendFile rf (show e ++ "\n")
+          Right m                     -> appendFile rf ("\nUNEXPECTED SUCCESS:\n" ++ show m ++ "\n")
+
+   -- Same name via parameter capture: bar 2 and bar 3 create different closures
+   -- for "bar", which should be detected as a conflict.
+   , goldenCapturedIO "smtFuncUniq_captureConflict" $ \rf -> do
+        let bar :: SInteger -> SInteger -> SInteger
+            bar k = smtFunction "bar" (+ k)
+        r <- C.try $ satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \x -> bar 2 x + bar 3 x .== 10
+        case r of
+          Left (e :: C.SomeException) -> appendFile rf (show e ++ "\n")
+          Right m                     -> appendFile rf ("\nUNEXPECTED SUCCESS:\n" ++ show m ++ "\n")
+
+   -- Fix for the above: use a tag to give each instantiation a unique name.
+   , goldenCapturedIO "smtFuncUniq_captureTagged" $ \rf -> do
+        let bar :: String -> SInteger -> SInteger -> SInteger
+            bar tag k = smtFunction ("bar_" ++ tag) (+ k)
+        m <- satWith z3{verbose=True, redirectVerbose=Just rf} $
+                \x -> bar "two" 2 x + bar "three" 3 x .== 10
+        appendFile rf ("\nRESULT:\n" ++ show m ++ "\n")
+   ]
diff --git a/SBVTestSuite/TestSuite/Basics/String.hs b/SBVTestSuite/TestSuite/Basics/String.hs
--- a/SBVTestSuite/TestSuite/Basics/String.hs
+++ b/SBVTestSuite/TestSuite/Basics/String.hs
@@ -26,8 +26,10 @@
 import qualified Data.SBV.Char   as SC
 import qualified Data.SBV.RegExp as R
 
-import Control.Monad (unless)
-import Data.List (sort)
+import Control.Monad (forM, forM_, replicateM, unless, void)
+import Control.Exception (ErrorCall, displayException, evaluate, try)
+import Data.List (isInfixOf, nub, sort)
+import Test.Tasty.HUnit (assertBool, assertEqual)
 
 import qualified Data.Map.Strict as M
 
@@ -55,8 +57,110 @@
     , goldenCapturedIO "strExamples12" $ \rf -> checkWith z3{redirectVerbose=Just rf} strExamples12   Unsat
     , goldenCapturedIO "strExamples13" $ \rf -> checkWith z3{redirectVerbose=Just rf} strExamples13   Unsat
     , testCase         "strExamples14" $ assert strExamples14
+    , testGroup "literal regex semantics"
+        [testCase (show sample P.++ " against " P.++ show regex)
+           (assertEqual "Literal regex membership" (Just expected) (unliteral (literal sample `R.match` regex)))
+        | (sample, regex, expected) <- regexLiteralCases]
+    , testCase "regex literal and solver agreement" regexLiteralAgreement
+    , testCase "invalid regex repetition bounds" regexInvalidBounds
     ]
 
+-- | Regressions for continuation handling: universal matching must not
+-- discard a suffix, and Boolean operations must inspect the same prefix.
+-- Include nullable repetition, empty inputs, Unicode, and embedded NULs.
+regexLiteralCases :: [(String, R.RegExp, Bool)]
+regexLiteralCases =
+  [ ("", R.Conc [], True)
+  , ("a", R.Conc [], False)
+  , ("a", R.Conc [R.Conc [], "a", R.Conc []], True)
+  , ("", R.Loop 0 0 "a", True)
+  , ("a", R.Loop 0 0 "a", False)
+  , ("", R.Power 0 "a", True)
+  , ("aa", R.Loop 2 2 "a", True)
+  , ("a", R.Conc [R.All, "b"], False)
+  , ("ab", R.Conc [R.All, "b"], True)
+  , ("b", R.Conc [R.All, "b"], True)
+  , ("", R.Conc [R.All, "b"], False)
+  , ("", R.All, True)
+  , ("a", R.Conc [R.Comp "a", "b"], False)
+  , ("b", R.Conc [R.Comp "a", "b"], True)
+  , ("ab", R.Conc [R.Comp "a", "b"], False)
+  , ("aab", R.Conc [R.Comp "a", "b"], True)
+  , ("ab", R.Conc [R.Diff "ab" "a", R.Opt "b"], True)
+  , ("ab", R.Conc [R.Diff "a" "ab", R.Opt "b"], True)
+  , ("ab", R.Conc [R.Inter "a" "ab", R.All], False)
+  , ("ab", R.Conc [R.Inter "a" (R.Opt "a"), "b"], True)
+  , ("a", R.Conc [R.Diff R.All "", "a"], False)
+  , ("ba", R.Conc [R.Diff R.All "", "a"], True)
+  , ("", R.KStar (R.Opt "a"), True)
+  , ("aaa", R.KStar (R.Inter (R.Opt "a") (R.Comp "b")), True)
+  , ("b", R.KStar (R.Inter (R.Opt "a") (R.Comp "b")), False)
+  , ("a", R.KStar (R.Conc [R.All, "b"]), False)
+  , ("b", R.Conc [R.Loop 0 2 (R.Opt "a"), "b"], True)
+  , ("aab", R.Conc [R.Power 2 (R.Diff "a" "b"), "b"], True)
+  , ("a\0", R.Conc [R.Comp "b", "\0"], True)
+  , ("\0a", R.Conc [R.All, "\0"], False)
+  , ("\955b", R.Conc [R.Inter R.All (R.Comp "a"), "b"], True)
+  , ("\955a", R.Conc [R.All, "b"], False)
+  ]
+
+-- | Compare folding with actual solver evaluation over a bounded matrix of
+-- regexes and strings. Keep the solver input symbolic and constrain its value
+-- so the reference path cannot silently reuse literal constant folding.
+regexLiteralAgreement :: Assertion
+regexLiteralAgreement = do
+  observations <- runSMT $ do
+    input <- sString "input"
+    query $ forM samples $ \sample -> inNewAssertionStack $ do
+      constrain (input .== literal sample)
+      status <- checkSat
+      actual <- case status of
+                  Sat -> getValue (S.implode [input `R.match` regex | regex <- regexes])
+                  _   -> pure []
+      pure (sample, status, actual)
+  forM_ observations $ \(sample, status, actual) -> do
+    assertEqual "A concrete string assignment must be satisfiable" Sat status
+    assertEqual "One result per regex" (length regexes) (length actual)
+    forM_ (zip regexes actual) $ \(regex, expected) ->
+      assertEqual ("Literal/solver disagreement for " P.++ show sample P.++ " against " P.++ show regex)
+                  (Just expected) (unliteral (literal sample `R.match` regex))
+ where atoms   = [R.All, R.None, R.Conc [], "", "a", "ab"]
+       unary   = [op regex | op <- [R.Comp, R.KStar, R.KPlus, R.Opt, R.Loop 0 2], regex <- atoms]
+       binary  = [op left right | op <- [R.Inter, R.Diff, \a b -> R.Union [a, b]], left <- atoms, right <- atoms]
+       base    = atoms P.++ unary P.++ binary
+       regexes = nub $ [regex | (_, regex, _) <- regexLiteralCases]
+                  P.++ [wrapped | regex <- base, wrapped <- [regex, R.Conc [regex, "b"], R.Conc ["a", regex]]]
+       samples = nub $ concatMap (`replicateM` "ab") [0 .. 3] P.++ [sample | (sample, _, _) <- regexLiteralCases]
+
+-- | Invalid bounds must fail on both literal and symbolic inputs, even when
+-- matching could skip the offending branch. The printer uses the same check.
+regexInvalidBounds :: Assertion
+regexInvalidBounds = forM_ invalid $ \(regex, diagnostic) ->
+  forM_ wrappers $ \wrap -> do
+    let r = wrap regex
+    forM_ ["", "aa"] $ \sample ->
+      rejects diagnostic $ void $ evaluate (unliteral ((literal sample :: SString) `R.match` r))
+    rejects diagnostic $ void $ evaluate (length (show r))
+    rejects diagnostic $ runSMT $ do
+      input <- sString "input"
+      constrain (input `R.match` r)
+    -- Language equality bypasses match and exercises SMT serialization itself.
+    rejects diagnostic $ void $ sat (r .== R.All)
+ where invalid = [ (R.Loop 2 1 "a", "Loop with arguments: (2,1)")
+                 , (R.Loop (-1) 2 "a", "Loop with arguments: (-1,2)")
+                 , (R.Loop 0 (-1) "a", "Loop with arguments: (0,-1)")
+                 , (R.Power (-1) "a", "Power with arguments: -1")
+                 ]
+       wrappers = [id, \r -> R.Union [R.All, r], \r -> R.Conc [R.None, r],
+                   R.KStar, R.KPlus, R.Opt, R.Comp, R.Loop 0 0, R.Power 0,
+                   R.Inter R.None, R.Diff R.None]
+
+       rejects diagnostic action = do
+         result <- try action :: IO (Either ErrorCall ())
+         case result of
+           Left err -> assertBool ("Expected diagnostic: " P.++ diagnostic) (diagnostic `isInfixOf` displayException err)
+           Right () -> assertFailure ("Accepted invalid regex: " P.++ diagnostic)
+
 checkWith :: SMTConfig -> Symbolic () -> CheckSatResult -> IO ()
 checkWith cfg props csExpected = runSMTWith cfg{verbose=True} $ do
         _ <- props
@@ -135,7 +239,7 @@
   constrain $ sNot $ c `S.isInfixOf` b
   constrain $ sNot $ b `S.isInfixOf` c
 
--- Any string is equal to the prefix and suffix that add up to a its length.
+-- Any string is equal to the prefix and suffix that add up to its length.
 strExamples8 :: Symbolic ()
 strExamples8 = do
   [a, b, c] <- sStrings ["a", "b", "c"]
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
@@ -86,7 +86,7 @@
 -- Test 'sMaybe', 'map', 'isNothing', 'isJust', and 'maybe'
 sumMaybe :: Symbolic ()
 sumMaybe = do
-  x <- sMaybe @Integer "x"
+  x :: SMaybe Integer <- free "x"
   let x' = M.map (+1) x
   constrain $ isNothing x .== isNothing x'
   constrain $ isJust x    .== isJust x'
@@ -105,23 +105,23 @@
 sumMaybeBoth :: Symbolic ()
 sumMaybeBoth = do
    (x :: SEither Integer Integer) <- sEither_
-   (y :: SMaybe Integer)          <- sMaybe_
+   (y :: SMaybe Integer)          <- free_
 
    constrain $ isLeft x
    constrain $ isJust y
 
 sumMergeMaybe1 :: Symbolic ()
 sumMergeMaybe1 = do
-   (x :: SMaybe Integer) <- sMaybe_
-   (y :: SMaybe Integer) <- sMaybe_
+   (x :: SMaybe Integer) <- free_
+   (y :: SMaybe Integer) <- free_
    b  <- sBool_
 
    constrain $ isNothing $ ite b x y
 
 sumMergeMaybe2 :: Symbolic ()
 sumMergeMaybe2 = do
-   (x :: SMaybe Integer) <- sMaybe_
-   (y :: SMaybe Integer) <- sMaybe_
+   (x :: SMaybe Integer) <- free_
+   (y :: SMaybe Integer) <- free_
    b  <- sBool_
 
    constrain $ isJust $ ite b x y
diff --git a/SBVTestSuite/TestSuite/Basics/TPCaching.hs b/SBVTestSuite/TestSuite/Basics/TPCaching.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/Basics/TPCaching.hs
@@ -0,0 +1,178 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : TestSuite.Basics.TPCaching
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Tests for the TP proof caching mechanism.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module TestSuite.Basics.TPCaching(tests) where
+
+import Utils.SBVTestFramework
+
+import Data.SBV.TP (TP, Proof, runTPWith, lemma, calc, recall, tpStats, (|-), (=:), qed)
+
+import Control.Monad (void)
+import Control.Exception (try, SomeException)
+
+import Data.Char (isSpace)
+import Data.List (isPrefixOf, dropWhileEnd)
+
+import Control.DeepSeq (($!!))
+
+-- | Strip timing info like @[0.05s]@ from the end of output lines.
+-- Only matches brackets whose content looks like a time value (digits, dots, and 's').
+-- Handles multiple consecutive timings like @[0.001s][0.002s]@.
+stripTiming :: String -> String
+stripTiming s = reverse $ go $ reverse $ dropWhileEnd isSpace s
+ where go (']':rest) | (inner, '[':before) <- break (== '[') rest
+                     , all (`elem` ("0123456789.s" :: String)) inner
+                     = go $ dropWhile isSpace before
+       go xs = xs
+
+-- | Filter out the statistics summary line from verbose output.
+isStatsLine :: String -> Bool
+isStatsLine s = "[SBV:" `isPrefixOf` dropWhile isSpace s
+
+-- | Clean captured verbose output: strip timing and stats.
+cleanStatsOutput :: String -> String
+cleanStatsOutput = unlines . map stripTiming . filter (not . isStatsLine) . lines
+
+-- Test suite
+tests :: TestTree
+tests = testGroup "Basics.TPCaching"
+   [
+   -- Normal mode: recall when cache is empty (cache miss).
+   -- The proof runs from scratch; recallWith shows "Lemma:" one-liner.
+     goldenCapturedIO "tpCache_miss" $ \rf -> do
+        let cfg = z3 { redirectVerbose = Just rf }
+        void $ runTPWith cfg $
+           recall (lemma "fact" sTrue [])
+
+   -- Normal mode: direct proof then recall (cache hit).
+   -- The direct proof shows "Lemma:", the recall shows "Lemma: ... [Cached]".
+   , goldenCapturedIO "tpCache_hit" $ \rf -> do
+        let cfg = z3 { redirectVerbose = Just rf }
+        void $ runTPWith cfg $ do
+           _ <- lemma "fact" sTrue []
+           recall (lemma "fact" sTrue [])
+
+   -- Normal mode: same proposition proved under two names, then recalled (aliases).
+   -- The recall shows "Lemma: ... [Cached]" with "(a.k.a. ...)" listing the other name.
+   , goldenCapturedIO "tpCache_alias" $ \rf -> do
+        let cfg = z3 { redirectVerbose = Just rf }
+        void $ runTPWith cfg $ do
+           _ <- lemma "nameA" sTrue []
+           _ <- lemma "nameB" sTrue []
+           recall (lemma "nameC" sTrue [])
+
+   -- Normal mode: calc proof with steps, then recall (cache hit).
+   -- The direct proof shows each step; the recall collapses to one line.
+   , goldenCapturedIO "tpCache_calcCollapse" $ \rf -> do
+        let cfg = z3 { redirectVerbose = Just rf }
+        void $ runTPWith cfg $ do
+           let addZeroProof = calc "addZero"
+                                   (\(Forall @"x" (x :: SInteger)) -> x + 0 .== x) $
+                                   \x -> [] |- x + 0
+                                            =: (x :: SInteger)
+                                            =: qed
+           _ <- addZeroProof
+           recall addZeroProof
+
+   -- Normal mode: nested recall.
+   -- First run proves inner and outer. Second run (via recall) hits cache for outer.
+   , goldenCapturedIO "tpCache_nested" $ \rf -> do
+        let cfg = z3 { redirectVerbose = Just rf }
+        void $ runTPWith cfg $ do
+           let myProof = do _ <- recall (lemma "inner" sTrue [])
+                            lemma "outer" sTrue []
+           _ <- myProof
+           recall myProof
+
+   -- Stats mode: recall when cache is empty (cache miss).
+   -- In stats mode, recall does NOT suppress inner output, so full proof steps are visible.
+   , goldenCapturedIO "tpCache_statsMiss" $ \rf -> do
+        let cfg = (tpStats z3) { redirectVerbose = Just rf }
+        void $ runTPWith cfg $
+           recall (calc "addZero"
+                        (\(Forall @"x" (x :: SInteger)) -> x + 0 .== x) $
+                        \x -> [] |- x + 0
+                                 =: (x :: SInteger)
+                                 =: qed)
+        contents <- readFile rf
+        writeFile rf $!! cleanStatsOutput contents
+
+   -- Stats mode: direct proof then recall (cache hit).
+   -- Direct proof shows full steps; recall shows "Lemma: ... [Cached]" one-liner.
+   , goldenCapturedIO "tpCache_statsHit" $ \rf -> do
+        let cfg = (tpStats z3) { redirectVerbose = Just rf }
+        void $ runTPWith cfg $ do
+           let addZeroProof = calc "addZero"
+                                   (\(Forall @"x" (x :: SInteger)) -> x + 0 .== x) $
+                                   \x -> [] |- x + 0
+                                            =: (x :: SInteger)
+                                            =: qed
+           _ <- addZeroProof
+           recall addZeroProof
+        contents <- readFile rf
+        writeFile rf $!! cleanStatsOutput contents
+
+   -- Stats mode: nested recall showing inner cache dynamics.
+   -- First recall misses (shows full inner proofs). Second recall hits (shows "Lemma: ... [Cached]").
+   , goldenCapturedIO "tpCache_statsNested" $ \rf -> do
+        let cfg = (tpStats z3) { redirectVerbose = Just rf }
+        void $ runTPWith cfg $ do
+           _ <- recall (lemma "inner" sTrue [])
+           _ <- lemma "outer" sTrue []
+           _ <- recall (lemma "inner" sTrue [])
+           recall (lemma "outer" sTrue [])
+        contents <- readFile rf
+        writeFile rf $!! cleanStatsOutput contents
+
+   -- Recall of a failing proof: the lemma is false (x > x), so the proof should fail.
+   , goldenCapturedIO "tpCache_recallFail" $ \rf -> do
+        let cfg = z3 { redirectVerbose = Just rf }
+        res <- try $ void $ runTPWith cfg $
+           recall bad
+        case res of
+           Left  (_ :: SomeException) -> pure ()
+           Right _                    -> appendFile rf "Unexpected success\n"
+
+   -- Direct proof of a false lemma.
+   , goldenCapturedIO "tpCache_fooFail" $ \rf -> do
+        let cfg = z3 { redirectVerbose = Just rf }
+        res <- try $ void $ runTPWith cfg foo
+        case res of
+           Left  (_ :: SomeException) -> pure ()
+           Right _                    -> appendFile rf "Unexpected success\n"
+
+   -- Recall of a failing lemma inside a larger proof.
+   , goldenCapturedIO "tpCache_barFail" $ \rf -> do
+        let cfg = z3 { redirectVerbose = Just rf }
+        res <- try $ void $ runTPWith cfg bar
+        case res of
+           Left  (_ :: SomeException) -> pure ()
+           Right _                    -> appendFile rf "Unexpected success\n"
+   ]
+
+-- | A trivially false lemma, used to test recall of a failing proof.
+bad :: TP (Proof (Forall "x" Integer -> SBool))
+bad = lemma "bad" (\(Forall @"x" (x :: SInteger)) -> x .> x) []
+
+-- | A false lemma: x == x+1.
+foo :: TP (Proof (Forall "x" Integer -> SBool))
+foo = lemma "foo" (\(Forall @"x" (x :: SInteger)) -> x .== x + 1) []
+
+-- | Recalls foo (which fails), then tries to prove another false lemma.
+bar :: TP (Proof (Forall "x" Integer -> SBool))
+bar = do _f <- recall foo
+         lemma "bar" (\(Forall @"x" (x :: SInteger)) -> x .== x + 2) []
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
@@ -9,12 +9,9 @@
 -- Test tuples.
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DataKinds           #-}
-{-# LANGUAGE DeriveAnyClass      #-}
-{-# LANGUAGE DeriveDataTypeable  #-}
 {-# LANGUAGE FlexibleInstances   #-}
+{-# LANGUAGE OverloadedLists     #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE StandaloneDeriving  #-}
 {-# LANGUAGE TemplateHaskell     #-}
 {-# LANGUAGE TypeApplications    #-}
 
@@ -25,18 +22,16 @@
 import Prelude hiding ((!!))
 
 import Data.SBV.Control
-import Data.SBV.List ((!!), (.:))
+import Data.SBV.List ((!!))
+
 import Data.SBV.Tuple
 
 import qualified Data.SBV.List as L
 
 import Utils.SBVTestFramework
 
-data E = A | B | C deriving (Bounded, Enum)
-mkSymbolicEnumeration ''E
-
-__unused :: SE
-__unused = error "stop GHC from complaining unused names" sA sB sC
+data E = A | B | C deriving Show
+mkSymbolic [''E]
 
 -- Test suite
 tests :: TestTree
@@ -104,7 +99,7 @@
    vTup1 :: SList (E, [Bool]) <- sList "v1"
    q <- sBool "q"
    constrain $ sNot q
-   constrain $ (vTup1 !! 1)^._2 .== sTrue .: q .: L.nil
+   constrain $ (vTup1 !! 1)^._2 .== sTrue .: q .: []
    constrain $ L.length vTup1 .== 3
 
    case untuple (vTup1 !! 2)  of
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
@@ -8,14 +8,18 @@
 --
 -- Testing UI function sat examples
 -----------------------------------------------------------------------------
-{-# LANGUAGE OverloadedStrings #-}
 
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
 {-# OPTIONS_GHC -Wall -Werror #-}
 
 module TestSuite.Basics.UISat(tests)  where
 
 import Utils.SBVTestFramework
 
+import Data.SBV.Control
+
 -- Test suite
 tests :: TestTree
 tests =
@@ -23,6 +27,36 @@
       goldenCapturedIO "uiSat_test1" $ \rf -> checkWith rf test1
     , goldenCapturedIO "uiSat_test2" $ \rf -> checkWith rf test2
     , goldenCapturedIO "uiSat_test3" $ \rf -> checkWith rf test3
+    , testCase "register_float_nan" $ assertIsSat $ do
+        let f = uninterpret "nanFloat" :: SInteger -> SFloat
+        constrain $ \(Forall x) -> fpIsNaN (f x)
+        registerFunction f
+        pure sTrue
+    , testCase "register_double_nan" $ assertIsSat $ do
+        let f = uninterpret "nanDouble" :: SInteger -> SDouble
+        constrain $ \(Forall x) -> fpIsNaN (f x)
+        registerFunction f
+        pure sTrue
+    , testCase "register_sized_float_nan" $ assertIsSat $ do
+        let f = uninterpret "nanHalf" :: SInteger -> SFPHalf
+        constrain $ \(Forall x) -> fpIsNaN (f x)
+        registerFunction f
+        pure sTrue
+    , testCase "register_defined_nan" $ assertIsSat $ do
+        let f = smtFunction "definedNaN" $ \(_ :: SInteger) -> (sNaN :: SFloat)
+        registerFunction f
+        pure sTrue
+    , testCase "register_nan_literal" $ assertIsSat $ do
+        registerFunction (sNaN :: SFloat)
+        pure sTrue
+    , testCase "register_unused_binary_function_model" $ do
+        result <- runSMT $ do
+          registerFunction q2
+          query $ do ensureSat
+                     getFunction q2
+        case result of
+          Right{} -> pure ()
+          Left{}  -> assertFailure "Expected a binary Boolean function interpretation"
     ]
 
 cfg :: FilePath -> SMTConfig
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
@@ -18,10 +18,10 @@
 import Utils.SBVTestFramework
 import Data.SBV.Control
 
+import qualified Data.SBV.Either as E
 import qualified Data.SBV.List   as L
-import qualified Data.SBV.Set    as S
 import qualified Data.SBV.Maybe  as M
-import qualified Data.SBV.Either as E
+import qualified Data.SBV.Set    as S
 import Data.SBV.Tuple
 
 tests :: TestTree
diff --git a/SBVTestSuite/TestSuite/CodeGeneration/ArbitraryBits.hs b/SBVTestSuite/TestSuite/CodeGeneration/ArbitraryBits.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CodeGeneration/ArbitraryBits.hs
@@ -0,0 +1,450 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : TestSuite.CodeGeneration.ArbitraryBits
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Compile-and-run tests for C lowering of arbitrary-width bit-vectors.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE TypeApplications #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module TestSuite.CodeGeneration.ArbitraryBits (tests) where
+
+import Data.List                 (isInfixOf)
+import Data.Proxy                (Proxy(..))
+import Numeric                   (showHex)
+import System.Environment        (lookupEnv)
+import System.Exit               (ExitCode(..))
+import System.FilePath           ((</>))
+import System.IO.Temp            (withSystemTempDirectory)
+import System.Process            (readProcessWithExitCode)
+import Test.Tasty.HUnit          (assertBool, assertEqual)
+
+import Data.SBV.Internals
+import Data.SBV.Tools.Overflow
+
+import Utils.SBVTestFramework hiding ((#), bvExtract)
+
+-- | Arbitrary-width C backend tests.
+tests :: TestTree
+tests = testGroup "CodeGeneration.ArbitraryBits"
+  [ testCase "compile and execute 673-bit arithmetic" wide673
+  , testCase "compile and execute signed 673-bit arithmetic" signed673
+  , testCase "compile and execute non-aligned join/extract" joinExtract
+  , testCase "compile and execute unsigned overflow predicates" unsignedOverflow
+  , testCase "compile and execute signed overflow predicates" signedOverflow
+  , testCase "compile and execute native overflow predicates" nativeOverflow
+  , testCase "compile and execute one-bit overflow predicates" oneBitOverflow
+  , testCase "compile and execute exact native bit operations" nativeBitOperations
+  , testCase "compile and execute exact native arithmetic" nativeArithmetic
+  , testCase "convert mapped integers and arbitrary-width bit-vectors" mappedIntegerBitVectorCasts
+  , testCase "compile and execute checked wide table lookup" wideLookup
+  , testCase "compile and execute wide array keys and values" wideArray
+  , testCase "compile and execute a wide callback-backed array" wideArrayInput
+  , testCase "compile and execute a wide structured lambda array" wideLambdaArray
+  , testCase "compile and execute a wide structured lambda table" wideLambdaTable
+  , testCase "compile and execute arithmetic boundary cases" arithmeticBoundaries
+  ]
+
+-- | Mapped integers sign-extend from their selected representation and reduce
+-- incoming bit-vectors modulo that width. One-bit targets must retain bit 0,
+-- not C's nonzero-to-Boolean interpretation.
+mappedIntegerBitVectorCasts :: Assertion
+mappedIntegerBitVectorCasts = mapM_ check [(width, sample) | width <- [8, 16, 32, 64], sample <- [-2, negate (2 ^ (width - 1)), 2 ^ (width - 1) - 1]]
+ where check (width, sample) = withSystemTempDirectory "sbv-mapped-integer-bit-vectors" $ \dir -> do
+         let signedSample   = negate (2 ^ (670 :: Int)) - 129
+             unsignedSample = 2 ^ (672 :: Int) + 131
+             program = do
+               cgOverwriteFiles True
+               cgIntegerSize width
+               cgSetDriverValues [sample, signedSample, unsignedSample, 2 ^ (64 :: Int) - 1, -3]
+               value    <- cgInput "value"         :: SBVCodeGen SInteger
+               signed   <- cgInput "signedValue"   :: SBVCodeGen (SInt 673)
+               unsigned <- cgInput "unsignedValue" :: SBVCodeGen (SWord 673)
+               native   <- cgInput "native"        :: SBVCodeGen SWord64
+               small    <- cgInput "small"         :: SBVCodeGen SInt8
+               cgReturn $ sAnd
+                 [ (sFromIntegral value :: SWord 1)     .== fromInteger sample
+                 , (sFromIntegral value :: SInt 7)      .== fromInteger sample
+                 , (sFromIntegral value :: SWord 9)     .== fromInteger sample
+                 , (sFromIntegral value :: SInt 65)     .== fromInteger sample
+                 , (sFromIntegral value :: SWord 673)   .== fromInteger sample
+                 , (sFromIntegral value :: SInt64)      .== fromInteger sample
+                 , (sFromIntegral signed :: SInteger)   .== fromInteger signedSample
+                 , (sFromIntegral unsigned :: SInteger) .== fromInteger unsignedSample
+                 , (sFromIntegral native :: SInteger)   .== -1
+                 , (sFromIntegral small :: SInteger)    .== -3
+                 ]
+         compileAndRun dir "mappedIntegerBitVectors" program ") = 1"
+
+-- | Exercise unsigned 673-bit arithmetic, shifts, rotation, and division.
+wide673 :: Assertion
+wide673 = withSystemTempDirectory "sbv-wide673" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [x, y]
+        a <- cgInput "a" :: SBVCodeGen (SWord 673)
+        b <- cgInput "b" :: SBVCodeGen (SWord 673)
+        let symbolicResult = rotateL (((a + b) * (a - b)) `xor` shiftR a 67) 193
+        cgReturn (symbolicResult `sQuot` (b + 1))
+  compileAndRun dir "wide673" program (asHex 11 result)
+ where w                 = 673
+       modulus           = 2 ^ w
+       mask              = modulus - 1
+       x                 = 2 ^ (672 :: Int) + 9
+       y                 = 17
+       add a b           = (a + b) .&. mask
+       sub a b           = (a - b) .&. mask
+       mul a b           = (a * b) .&. mask
+       shr a n           = a `shiftR` n
+       rotl a n          = let r = n `mod` w in ((a `shiftLInteger` r) .|. (a `shiftR` (w - r))) .&. mask
+       expectedZ         = rotl (mul (add x y) (sub x y) `xor` shr x 67) 193
+       result            = expectedZ `quot` add y 1
+       shiftLInteger a n = a * (2 ^ n)
+
+-- | Exercise signed 673-bit ordering, quotient, remainder, and arithmetic shift.
+signed673 :: Assertion
+signed673 = withSystemTempDirectory "sbv-signed673" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [x, y]
+        a <- cgInput "a" :: SBVCodeGen (SInt 673)
+        b <- cgInput "b" :: SBVCodeGen (SInt 673)
+        let q = a `sQuot` b
+            r = a `sRem` b
+        cgReturn $ ite (a .< b) (q + r) (shiftR a 130)
+  compileAndRun dir "signed673" program (asHex 11 expectedRaw)
+ where modulus     = 2 ^ (673 :: Int)
+       x           = negate (2 ^ (671 :: Int)) + 12345
+       y           = -17
+       expectedRaw = ((x `quot` y) + (x `rem` y)) `mod` modulus
+
+-- | Exercise non-aligned concatenation and extraction across limb boundaries.
+joinExtract :: Assertion
+joinExtract = withSystemTempDirectory "sbv-join-extract" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [hi, lo]
+        a <- cgInput "high" :: SBVCodeGen (SWord 337)
+        b <- cgInput "low"  :: SBVCodeGen (SWord 336)
+        let joined = a # b :: SWord 673
+        cgReturn (bvExtract (Proxy @511) (Proxy @128) joined :: SWord 384)
+  compileAndRun dir "joinExtract" program (asHex 6 expected)
+ where hi             = 2 ^ (336 :: Int) + 0x123456789abcdef
+       lo             = 2 ^ (335 :: Int) + 0xfedcba987654321
+       expectedJoined = hi * 2 ^ (336 :: Int) + lo
+       expected       = (expectedJoined `shiftR` 128) .&. (2 ^ (384 :: Int) - 1)
+
+-- | Exercise unsigned overflow and underflow predicates at a non-native width.
+unsignedOverflow :: Assertion
+unsignedOverflow = withSystemTempDirectory "sbv-unsigned-overflow" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [2 ^ (65 :: Int) - 1, 2]
+        a <- cgInput "a" :: SBVCodeGen (SWord 65)
+        b <- cgInput "b" :: SBVCodeGen (SWord 65)
+        cgReturn $ pack [bvAddO a b, bvSubO 0 b, bvMulO a b, bvMulO b 3]
+  compileAndRun dir "unsignedOverflow" program (asHex 2 7)
+ where pack :: [SBool] -> SWord 65
+       pack flags = sum (zipWith (\flag weight -> ite flag weight 0) flags [1, 2, 4, 8])
+
+-- | Exercise signed overflow predicates, including both signed extrema.
+signedOverflow :: Assertion
+signedOverflow = withSystemTempDirectory "sbv-signed-overflow" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [2 ^ (64 :: Int) - 1, 1]
+        a <- cgInput "a" :: SBVCodeGen (SInt 65)
+        b <- cgInput "b" :: SBVCodeGen (SInt 65)
+        let minValue = fromInteger (negate (2 ^ (64 :: Int))) :: SInt 65
+        cgReturn $ pack [bvAddO a b, bvSubO minValue b, bvMulO a (b + b), bvDivO minValue (negate b), bvNegO minValue, bvMulO a b]
+  compileAndRun dir "signedOverflow" program (asHex 2 31)
+ where pack :: [SBool] -> SWord 65
+       pack flags = sum (zipWith (\flag weight -> ite flag weight 0) flags [1, 2, 4, 8, 16, 32])
+
+-- | Exercise every unsigned and signed overflow predicate at native C widths,
+-- including promotion-sensitive 8-bit and undefined-in-C 64-bit boundaries.
+nativeOverflow :: Assertion
+nativeOverflow = withSystemTempDirectory "sbv-native-overflow" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [maxWord, 2, maxInt, 1, minInt, minInt8]
+        unsignedMax <- cgInput "unsignedMax" :: SBVCodeGen SWord64
+        unsignedTwo <- cgInput "unsignedTwo" :: SBVCodeGen SWord64
+        signedMax   <- cgInput "signedMax"   :: SBVCodeGen SInt64
+        signedOne   <- cgInput "signedOne"   :: SBVCodeGen SInt64
+        signedMin   <- cgInput "signedMin"   :: SBVCodeGen SInt64
+        signedMin8  <- cgInput "signedMin8"  :: SBVCodeGen SInt8
+        let flags = [ bvAddO unsignedMax unsignedTwo
+                    , bvSubO 0 unsignedTwo
+                    , bvMulO unsignedMax unsignedTwo
+                    , bvMulO unsignedTwo 3
+                    , bvAddO signedMax signedOne
+                    , bvSubO signedMin signedOne
+                    , bvMulO signedMax 2
+                    , bvDivO signedMin (negate signedOne)
+                    , bvNegO signedMin
+                    , bvMulO signedMax signedOne
+                    , bvNegO signedMin8
+                    , bvMulO signedMin8 (-1)
+                    ]
+        cgReturn $ pack flags
+      maxWord = 2 ^ (64 :: Int) - 1
+      maxInt  = 2 ^ (63 :: Int) - 1
+      minInt  = negate (2 ^ (63 :: Int))
+      minInt8 = -128
+  compileAndRun dir "nativeOverflow" program "0x0df7U"
+ where pack :: [SBool] -> SWord16
+       pack flags = sum (zipWith (\flag weight -> ite flag weight 0) flags [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048])
+
+-- | Exercise the Boolean truth tables for overflow and underflow on an
+-- unsigned one-bit vector, including the public constant-false predicates.
+oneBitOverflow :: Assertion
+oneBitOverflow = withSystemTempDirectory "sbv-one-bit-overflow" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [1, 0]
+        oneBit  <- cgInput "oneBit"  :: SBVCodeGen (SWord 1)
+        zeroBit <- cgInput "zeroBit" :: SBVCodeGen (SWord 1)
+        cgReturn $ pack [ bvAddO oneBit oneBit
+                        , bvAddO oneBit zeroBit
+                        , bvAddO zeroBit oneBit
+                        , bvAddO zeroBit zeroBit
+                        , bvSubO zeroBit oneBit
+                        , bvSubO oneBit zeroBit
+                        , bvSubO oneBit oneBit
+                        , bvSubO zeroBit zeroBit
+                        , bvMulO oneBit oneBit
+                        , bvMulO oneBit zeroBit
+                        , bvMulO zeroBit oneBit
+                        , bvMulO zeroBit zeroBit
+                        , bvDivO oneBit oneBit
+                        , bvNegO oneBit
+                        ]
+  compileAndRun dir "oneBitOverflow" program "0x0011U"
+ where pack :: [SBool] -> SWord16
+       pack flags = sum (zipWith (\flag weight -> ite flag weight 0) flags [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192])
+
+-- | Exercise non-byte-aligned native extraction and signed rotations,
+-- including counts larger than the operand width and SBV's unchanged result
+-- for a negative constant count.
+nativeBitOperations :: Assertion
+nativeBitOperations = withSystemTempDirectory "sbv-native-bit-operations" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [wordSample, signedSample]
+        wordValue   <- cgInput "wordValue"   :: SBVCodeGen (SWord 32)
+        signedValue <- cgInput "signedValue" :: SBVCodeGen (SInt 32)
+        let extracted    = bvExtract (Proxy @10) (Proxy @3) wordValue :: SWord 8
+            highHalf     = bvExtract (Proxy @31) (Proxy @16) wordValue :: SWord 16
+            lowHalf      = bvExtract (Proxy @15) (Proxy @0) wordValue :: SWord 16
+            rejoined     = highHalf # lowHalf :: SWord 32
+            signExtended = signExtend signedValue :: SInt 64
+            zeroExtended = zeroExtend wordValue :: SWord 64
+            narrowed     = sFromIntegral signedValue :: SWord8
+            shiftedLeft  = signed32 (raw32 (raw32 signedSample * 2 ^ (3 :: Int)))
+            shiftedRight = signedSample `div` 2 ^ (3 :: Int)
+            flags        = [ extracted .== fromInteger extractedExpected
+                           , rotateL signedValue 37   .== fromInteger rotatedLeftExpected
+                           , rotateR signedValue 39   .== fromInteger rotatedRightExpected
+                           , rotateR signedValue (-5) .== signedValue
+                           , signExtended .== fromInteger signedSample
+                           , zeroExtended .== fromInteger wordSample
+                           , narrowed .== fromInteger (raw32 signedSample `mod` 2 ^ (8 :: Int))
+                           , rejoined .== wordValue
+                           , shiftL signedValue 3  .== fromInteger shiftedLeft
+                           , shiftR signedValue 3  .== fromInteger shiftedRight
+                           , shiftL signedValue 32 .== 0
+                           , shiftR signedValue 32 .== (-1)
+                           ]
+        cgReturn $ pack flags
+  compileAndRun dir "nativeBitOperations" program "0x0fffU"
+ where wordSample :: Integer
+       wordSample           = 0xdeadbeef
+
+       signedSample :: Integer
+       signedSample         = -19088744
+
+       extractedExpected :: Integer
+       extractedExpected    = (wordSample `div` (2 ^ (3 :: Int))) `mod` (2 ^ (8 :: Int))
+
+       rotatedLeftExpected :: Integer
+       rotatedLeftExpected  = signed32 (rotateLeft32 signedSample 5)
+
+       rotatedRightExpected :: Integer
+       rotatedRightExpected = signed32 (rotateRight32 signedSample 7)
+
+       rotateLeft32 :: Integer -> Int -> Integer
+       rotateLeft32 value amount = (raw32 value * 2 ^ amount + raw32 value `div` 2 ^ (32 - amount)) `mod` 2 ^ (32 :: Int)
+
+       rotateRight32 :: Integer -> Int -> Integer
+       rotateRight32 value amount = (raw32 value `div` 2 ^ amount + raw32 value * 2 ^ (32 - amount)) `mod` 2 ^ (32 :: Int)
+
+       raw32 :: Integer -> Integer
+       raw32 value = value `mod` 2 ^ (32 :: Int)
+
+       signed32 :: Integer -> Integer
+       signed32 value
+         | value >= 2 ^ (31 :: Int) = value - 2 ^ (32 :: Int)
+         | True                     = value
+
+       pack :: [SBool] -> SWord16
+       pack flags = sum (zipWith (\flag weight -> ite flag weight 0) flags [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048])
+
+-- | Exercise modular native arithmetic and the two division cases that would
+-- otherwise be undefined in C.
+nativeArithmetic :: Assertion
+nativeArithmetic = withSystemTempDirectory "sbv-native-arithmetic" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [minimumInt64, -1, maximumInt64, maximumInt32, maximumWord16]
+        minimum64 <- cgInput "minimum64" :: SBVCodeGen SInt64
+        negative1 <- cgInput "negative1" :: SBVCodeGen SInt64
+        maximum64 <- cgInput "maximum64" :: SBVCodeGen SInt64
+        maximum32 <- cgInput "maximum32" :: SBVCodeGen SInt32
+        maximum16 <- cgInput "maximum16" :: SBVCodeGen SWord16
+        let flags = [ maximum64 + 1 .== fromInteger minimumInt64
+                    , minimum64 + negative1 .== fromInteger maximumInt64
+                    , minimum64 - 1 .== fromInteger maximumInt64
+                    , maximum64 * 2 .== (-2)
+                    , negate minimum64 .== minimum64
+                    , abs minimum64 .== minimum64
+                    , minimum64 `sQuot` negative1 .== minimum64
+                    , minimum64 `sRem` negative1 .== 0
+                    , minimum64 `sQuot` 0 .== 0
+                    , minimum64 `sRem` 0 .== minimum64
+                    , maximum32 * maximum32 .== 1
+                    , maximum16 * maximum16 .== 1
+                    ]
+        cgReturn $ pack flags
+  compileAndRun dir "nativeArithmetic" program "0x0fffU"
+ where minimumInt64 :: Integer
+       minimumInt64 = negate (2 ^ (63 :: Int))
+
+       maximumInt64 :: Integer
+       maximumInt64 = 2 ^ (63 :: Int) - 1
+
+       maximumInt32 :: Integer
+       maximumInt32 = 2 ^ (31 :: Int) - 1
+
+       maximumWord16 :: Integer
+       maximumWord16 = 2 ^ (16 :: Int) - 1
+
+       pack :: [SBool] -> SWord16
+       pack flags = sum (zipWith (\flag weight -> ite flag weight 0) flags [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048])
+
+-- | Exercise checked table lookup with both a wide index and wide elements.
+wideLookup :: Assertion
+wideLookup = withSystemTempDirectory "sbv-wide-lookup" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgPerformRTCs True
+        cgSetDriverValues [2 ^ (64 :: Int) + 1]
+        index <- cgInput "index" :: SBVCodeGen (SWord 65)
+        cgReturn (select [11, 22] 99 index :: SWord 673)
+  compileAndRun dir "wideLookup" program (asHex 11 99)
+
+-- | Exercise persistent arrays whose keys and values both use exact-width
+-- limb representations.
+wideArray :: Assertion
+wideArray = withSystemTempDirectory "sbv-wide-array" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [keySample, valueSample]
+        key   <- cgInput "key"   :: SBVCodeGen (SWord 673)
+        value <- cgInput "value" :: SBVCodeGen (SWord 257)
+        let base    = constArray 3
+            updated = writeArray base key value
+        cgOutput "defaultRead" (readArray updated (key + 1))
+        cgReturn (readArray updated key)
+      keySample   = 2 ^ (672 :: Int) + 17
+      valueSample = 2 ^ (256 :: Int) + 5
+  compileAndRun dir "wideArray" program (asHex 5 valueSample)
+
+-- | Exercise the public callback descriptor when both its key and returned
+-- value use multi-limb bit-vector representations.
+wideArrayInput :: Assertion
+wideArrayInput = withSystemTempDirectory "sbv-wide-array-input" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [valueSample, keySample]
+        source <- cgInput "source" :: SBVCodeGen (SArray (WordN 673) (WordN 257))
+        key    <- cgInput "key"    :: SBVCodeGen (SWord 673)
+        cgReturn (readArray source key)
+      keySample   = 2 ^ (672 :: Int) + 17
+      valueSample = 2 ^ (256 :: Int) + 5
+  compileAndRun dir "wideArrayInput" program (asHex 5 valueSample)
+
+-- | Exercise a structured array lambda whose parameter, local arithmetic,
+-- and result all use the 673-bit limb representation.
+wideLambdaArray :: Assertion
+wideLambdaArray = withSystemTempDirectory "sbv-wide-lambda-array" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [keySample]
+        key <- cgInput "key" :: SBVCodeGen (SWord 673)
+        let source = lambdaArray (\index -> index * 3 + 5) :: SArray (WordN 673) (WordN 673)
+        cgReturn (readArray source key)
+      keySample = 2 ^ (672 :: Int) + 17
+      expected  = (keySample * 3 + 5) `mod` (2 ^ (673 :: Int))
+  compileAndRun dir "wideLambdaArray" program (asHex 11 expected)
+
+-- | Exercise a parameter-dependent lookup table entirely within a structured
+-- lambda using arbitrary-width indices, elements, and results.
+wideLambdaTable :: Assertion
+wideLambdaTable = withSystemTempDirectory "sbv-wide-lambda-table" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [1]
+        key <- cgInput "key" :: SBVCodeGen (SWord 673)
+        let source = lambdaArray (\index -> select [index + 1, index * 3] 99 index) :: SArray (WordN 673) (WordN 673)
+        cgReturn (readArray source key)
+  compileAndRun dir "wideLambdaTable" program (asHex 11 3)
+
+-- | Exercise division-by-zero, extreme shifts, and signed-minimum division.
+arithmeticBoundaries :: Assertion
+arithmeticBoundaries = withSystemTempDirectory "sbv-arithmetic-boundaries" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [negate (2 ^ (64 :: Int))]
+        a <- cgInput "a" :: SBVCodeGen (SInt 65)
+        let z = 0 :: SInt 65
+        cgReturn $ pack [a `sQuot` z .== z
+                        , a `sRem` z .== a
+                        , shiftL a 65 .== z
+                        , shiftR a 65 .== (-1)
+                        , a `sQuot` (-1) .== a
+                        , a `sRem` (-1) .== z
+                        , rotateL a 66 .== 1]
+  compileAndRun dir "arithmeticBoundaries" program (asHex 2 127)
+ where pack :: [SBool] -> SWord 65
+       pack flags = sum (zipWith (\flag weight -> ite flag weight 0) flags [1, 2, 4, 8, 16, 32, 64])
+
+-- | Generate, compile, and execute a C program, checking its encoded result.
+-- @SBV_C_TEST_FLAGS@ supplies extra flags for optimization and sanitizer runs.
+compileAndRun :: FilePath -> String -> SBVCodeGen () -> String -> Assertion
+compileAndRun dir functionName program expected = do
+  (_, cfg, bundle) <- compileToC' functionName program
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+
+  let source = dir </> functionName ++ ".c"
+      driver = dir </> functionName ++ "_driver.c"
+      exe    = dir </> functionName ++ "_driver"
+  extraFlags <- maybe [] words <$> lookupEnv "SBV_C_TEST_FLAGS"
+  (ccExit, _, ccErr) <- readProcessWithExitCode "cc" (["-std=c11", "-Wall", "-Werror", source, driver, "-o", exe] ++ extraFlags) ""
+  assertEqual ccErr ExitSuccess ccExit
+
+  (runExit, out, runErr) <- readProcessWithExitCode exe [] ""
+  assertEqual runErr ExitSuccess runExit
+  assertBool ("Expected generated output to contain " ++ expected ++ ", received:\n" ++ out) (expected `isInfixOf` out)
+
+-- | Render the fixed-limb hexadecimal form printed by generated drivers.
+asHex :: Int -> Integer -> String
+asHex limbCount value = "0x" ++ replicate (16 * limbCount - length h) '0' ++ h
+ where h = showHex value ""
diff --git a/SBVTestSuite/TestSuite/CodeGeneration/ArbitraryFloats.hs b/SBVTestSuite/TestSuite/CodeGeneration/ArbitraryFloats.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CodeGeneration/ArbitraryFloats.hs
@@ -0,0 +1,1073 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : TestSuite.CodeGeneration.ArbitraryFloats
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Compile-and-run tests for LibBF-backed arbitrary floating-point C lowering.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module TestSuite.CodeGeneration.ArbitraryFloats (tests) where
+
+import Control.Monad             (when)
+import Data.List                 (isInfixOf)
+import Data.Maybe                (fromMaybe)
+import Numeric                   (showHex)
+import System.Directory          (doesFileExist)
+import System.Environment        (lookupEnv)
+import System.Exit               (ExitCode(..))
+import System.FilePath           ((</>))
+import System.IO.Temp            (withSystemTempDirectory)
+import System.Process            (readProcessWithExitCode)
+import Test.Tasty.HUnit          (assertBool, assertEqual)
+
+import qualified Data.SBV.Dynamic as D
+import qualified Data.SBV.Rational as Rat
+
+import Data.SBV.Internals
+import Data.SBV.Tuple (tuple, untuple)
+
+import Utils.SBVTestFramework hiding ((#))
+import Utils.CCodeGen (locateLibBF, generatedMakeOptions)
+
+-- | Arbitrary floating-point C backend tests.
+tests :: TestTree
+tests = testGroup "CodeGeneration.ArbitraryFloats"
+  [ testCase "compile and execute arithmetic" arbitraryFloatArithmetic
+  , testCase "preserve division, signed zero, and extreme-exponent FMA" reviewedFloatArithmetic
+  , testCase "compile and execute a nonstandard wide format" arbitraryFloatWideFormat
+  , testCase "compile and execute classification" arbitraryFloatClassification
+  , testCase "compile and execute rounding modes" arbitraryFloatRoundingModes
+  , testCase "compile and execute symbolic rounding modes" arbitraryFloatSymbolicRoundingMode
+  , testCase "compile and execute native rounding modes" nativeFloatRoundingModes
+  , testCase "preserve native floating rounding steps under optimization" nativeFloatRoundingSteps
+  , testCase "reject unsafe floating compiler modes" nativeFloatCompilerModes
+  , testCase "convert between native floats and bit-vectors" nativeFloatBitVectorConversions
+  , testCase "convert native floats across non-native widths" nativeFloatWidthConversions
+  , testCase "preserve native floating casts under caller rounding modes" nativeFloatCastEnvironment
+  , testCase "totalize exceptional native floating casts without C overflow" nativeFloatExceptionalCasts
+  , testCase "keep exact native floating casts free of LibBF" nativeExactFloatConversions
+  , testCase "convert between native floats and exact numbers" nativeFloatExactConversions
+  , testCase "convert mapped integers with explicit float rounding" mappedIntegerFloatConversions
+  , testCase "convert mapped reals across numeric representations" mappedRealConversions
+  , testCase "preserve target long-double precision across numeric bridges" longDoubleNumericBoundaries
+  , testCase "reject unsupported target long-double formats explicitly" unsupportedLongDoubleFormat
+  , testCase "compile and execute special arithmetic" arbitraryFloatSpecialArithmetic
+  , testCase "compile and execute arbitrary-float table lookup" arbitraryFloatTableLookup
+  , testCase "preserve arbitrary floating-point array-key equality" arbitraryFloatArrayKeys
+  , testCase "compile and execute an arbitrary-float callback-backed array" arbitraryFloatArrayInput
+  , testCase "compile and execute an arbitrary-float structured lambda array" arbitraryFloatLambdaArray
+  , testCase "compile and execute an arbitrary-float structured lambda table" arbitraryFloatLambdaTable
+  , testCase "convert between arbitrary floats and exact numbers" arbitraryFloatExactConversions
+  , testCase "compile and execute a mixed repeated-type library" mixedRepeatedTypeLibrary
+  , testCase "compile a repeated-type library without a driver" repeatedTypeLibraryWithoutDriver
+  , testCase "compile a wide arbitrary-float tuple" wideFloatingTuple
+  , testCase "preserve dependencies with optional library files" optionalLibraryFiles
+  ]
+
+-- | Exercise the ordinary fractional operator, both same-sign zero arguments,
+-- and cancellation after a product beyond the target format's exponent range.
+reviewedFloatArithmetic :: Assertion
+reviewedFloatArithmetic = withSystemTempDirectory "sbv-reviewed-floats" $ \dir -> do
+  let bias = 2 ^ (28 :: Int) - 1
+      aBits = (bias + 2 ^ (27 :: Int)) * 4
+      cBits = 2 ^ (31 :: Int) + (2 ^ (29 :: Int) - 2) * 4 + 3
+      program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [6, 2, 0x8000, 0x8000, aBits, cBits]
+        dividendValue <- cgInput "numerator" :: SBVCodeGen SFPQuad
+        divisorValue <- cgInput "denominator" :: SBVCodeGen SFPQuad
+        negativeZeroBits <- cgInput "zeroBits" :: SBVCodeGen (SWord 16)
+        otherZeroBits <- cgInput "otherZeroBits" :: SBVCodeGen (SWord 16)
+        aRaw <- cgInput "aBits" :: SBVCodeGen (SWord 32)
+        cRaw <- cgInput "cBits" :: SBVCodeGen (SWord 32)
+        let negativeZero = sWordAsSFloatingPoint negativeZeroBits :: SFPHalf
+            otherNegativeZero = sWordAsSFloatingPoint otherZeroBits :: SFPHalf
+            a = sWordAsSFloatingPoint aRaw :: SFloatingPoint 29 3
+            c = sWordAsSFloatingPoint cRaw :: SFloatingPoint 29 3
+            result = fpFMA sRNE a a c
+            expected = literal (fromInteger ((bias + 2 ^ (28 :: Int) - 3) * 4)) :: SWord 32
+        cgReturn $ dividendValue / divisorValue .== 3
+               .&& fpIsEqualObject (fpMin negativeZero otherNegativeZero) negativeZero
+               .&& fpIsEqualObject (fpMax negativeZero otherNegativeZero) negativeZero
+               .&& sFloatingPointAsSWord result .== expected
+  compileAndRunLibBF dir "reviewedFloatArithmetic" program ") = 1"
+
+-- | Keep LibBF requirements when its component disables Makefile generation,
+-- and associate an enabled driver with its own component after a disabled one.
+optionalLibraryFiles :: Assertion
+optionalLibraryFiles = mapM_ check [False, True]
+ where check generateMakefile = withSystemTempDirectory "sbv-optional-library-files" $ \dir -> do
+         (includeDir, archive) <- locateLibBF
+         (_, cfg, bundle) <- compileToCLib' "optionalLibrary"
+           [ ("scalar", do
+                 cgOverwriteFiles True
+                 cgGenerateDriver False
+                 cgGenerateMakefile generateMakefile
+                 value <- cgInput "value" :: SBVCodeGen SWord8
+                 cgReturn (value + 1))
+           , ("half", do
+                 cgOverwriteFiles True
+                 cgGenerateMakefile False
+                 cgSetDriverValues [1]
+                 value <- cgInput "value" :: SBVCodeGen SFPHalf
+                 cgReturn (value + 1))
+           ]
+         renderCgPgmBundle (Just dir) (cfg, bundle)
+         hasMakefile <- doesFileExist (dir </> "Makefile")
+         assertEqual "Unexpected optional Makefile" generateMakefile hasMakefile
+         when generateMakefile $ do
+           makefile <- readFile (dir </> "Makefile")
+           assertBool "Hidden component lost its LibBF link dependency" ("-lbf" `isInfixOf` makefile)
+         let driverPath = dir </> "driver"
+         extraFlags <- maybe [] words <$> lookupEnv "SBV_C_TEST_FLAGS"
+         (buildExit, _, buildError) <- readProcessWithExitCode "cc"
+           ([ "-std=c11", "-Wall", "-Werror", "-I" ++ includeDir
+           , dir </> "scalar.c", dir </> "half.c", dir </> "optionalLibrary_driver.c"
+           , archive, "-lm", "-o", driverPath
+           ] ++ extraFlags) ""
+         assertEqual buildError ExitSuccess buildExit
+         (runExit, outputText, runError) <- readProcessWithExitCode driverPath [] ""
+         assertEqual runError ExitSuccess runExit
+         assertBool outputText ("Driver run for half:" `isInfixOf` outputText && asHex 1 0x4000 `isInfixOf` outputText)
+
+-- | Exercise tuple fields whose value representations are generated wide
+-- bit-vector and arbitrary floating-point structures.
+wideFloatingTuple :: Assertion
+wideFloatingTuple = withSystemTempDirectory "sbv-wide-floating-tuple" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [5]
+        source <- cgInput "source" :: SBVCodeGen (SBV (WordN 65, FloatingPoint 7 19))
+        let (word, float) = untuple source
+        cgReturn (tuple (word + 1, float + 1))
+
+  compileAndRunLibBF dir "wideFloatingTuple" program "(0x00000000000000000000000000000006, 0x"
+
+-- | Exercise LibBF-backed quadruple arithmetic and floating-point predicates.
+arbitraryFloatArithmetic :: Assertion
+arbitraryFloatArithmetic = withSystemTempDirectory "sbv-arbitrary-float" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [3, 2, -17]
+        a <- cgInput "a" :: SBVCodeGen SFPQuad
+        b <- cgInput "b" :: SBVCodeGen SFPQuad
+        c <- cgInput "c" :: SBVCodeGen SInt64
+        let added     = fpAdd sRNE a b
+            fused     = fpFMA sRNE a b b
+            half      = toSFloatingPoint sRNE fused :: SFPHalf
+            viaHalf   = toSFloatingPoint sRNE half :: SFPQuad
+            asDouble  = fromSFloatingPoint sRNE fused :: SDouble
+            viaDouble = toSFloatingPoint sRNE asDouble :: SFPQuad
+            fromInt   = toSFloatingPoint sRNE c :: SFPQuad
+            backInt   = fromSFloatingPoint sRNE fromInt :: SInt64
+            bits      = sFloatingPointAsSWord viaDouble :: SWord 128
+            roundTrip = sWordAsSFloatingPoint bits :: SFPQuad
+        cgOutput "added" added
+        cgOutput "fusedBits" bits
+        cgReturn $ ite (fpIsNormal a .&& a .> b .&& fpIsEqualObject fused viaHalf .&& fpIsEqualObject fused roundTrip .&& backInt .== c) roundTrip added
+      bias     = 2 ^ (14 :: Int) - 1 :: Integer
+      eightRaw = (bias + 3) * 2 ^ (112 :: Int)
+  compileAndRunLibBF dir "arbitraryFloatArithmetic" program (asHex 2 eightRaw)
+
+-- | Exercise a nonstandard format whose interchange value spans four limbs.
+arbitraryFloatWideFormat :: Assertion
+arbitraryFloatWideFormat = withSystemTempDirectory "sbv-arbitrary-float-wide-format" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [3, 5]
+        a <- cgInput "a" :: SBVCodeGen (SFloatingPoint 17 237)
+        b <- cgInput "b" :: SBVCodeGen (SFloatingPoint 17 237)
+        let result = fpAdd sRNE a b
+            bits   = sFloatingPointAsSWord result :: SWord 254
+        cgOutput "bits" bits
+        cgReturn result
+      bias     = 2 ^ (16 :: Int) - 1 :: Integer
+      eightRaw = (bias + 3) * 2 ^ (236 :: Int)
+  compileAndRunLibBF dir "arbitraryFloatWideFormat" program (asHex 4 eightRaw)
+
+-- | Exercise special-value classification through raw half-precision inputs.
+arbitraryFloatClassification :: Assertion
+arbitraryFloatClassification = withSystemTempDirectory "sbv-arbitrary-float-classification" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [0x7e00, 0x8000, 0x0001, 0x7c00]
+        nanBits <- cgInput "nanBits"          :: SBVCodeGen (SWord 16)
+        nzBits  <- cgInput "negativeZeroBits" :: SBVCodeGen (SWord 16)
+        subBits <- cgInput "subnormalBits"    :: SBVCodeGen (SWord 16)
+        infBits <- cgInput "infinityBits"     :: SBVCodeGen (SWord 16)
+        let nanValue     = sWordAsSFloatingPoint nanBits :: SFPHalf
+            negativeZero = sWordAsSFloatingPoint nzBits :: SFPHalf
+            subnormal    = sWordAsSFloatingPoint subBits :: SFPHalf
+            infValue     = sWordAsSFloatingPoint infBits :: SFPHalf
+            positiveZero = 0 :: SFPHalf
+        cgReturn $ pack [fpIsNaN nanValue
+                        , nanValue ./= nanValue
+                        , fpIsEqualObject nanValue nanValue
+                        , fpIsZero negativeZero
+                        , fpIsNegative negativeZero
+                        , sNot (fpIsEqualObject negativeZero positiveZero)
+                        , negativeZero .== positiveZero
+                        , fpIsSubnormal subnormal
+                        , fpIsPositive subnormal
+                        , sNot (fpIsNormal subnormal)
+                        , fpIsInfinite infValue
+                        , sNot (fpIsNormal infValue)
+                        , distinct [nanValue, nanValue, positiveZero]
+                        , sNot (distinct [negativeZero, positiveZero])]
+  compileAndRunLibBF dir "arbitraryFloatClassification" program "0x3fff"
+ where pack :: [SBool] -> SWord16
+       pack flags = sum (zipWith (\flag weight -> ite flag weight 0) flags [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192])
+
+-- | Exercise all IEEE rounding modes on an exactly halfway format conversion.
+arbitraryFloatRoundingModes :: Assertion
+arbitraryFloatRoundingModes = withSystemTempDirectory "sbv-arbitrary-float-rounding" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [2049, 2048]
+        numValue <- cgInput "numerator"   :: SBVCodeGen SFPQuad
+        denValue <- cgInput "denominator" :: SBVCodeGen SFPQuad
+        let value = fpDiv sRNE numValue denValue
+            rne   = rawHalf (toSFloatingPoint sRNE value)
+            rna   = rawHalf (toSFloatingPoint sRNA value)
+            rtp   = rawHalf (toSFloatingPoint sRTP value)
+            rtn   = rawHalf (toSFloatingPoint sRTN value)
+            rtz   = rawHalf (toSFloatingPoint sRTZ value)
+        cgReturn (rne # rna # rtp # rtn # rtz :: SWord 80)
+      expected = foldl (\acc word -> acc * 2 ^ (16 :: Int) + word) 0 [0x3c00, 0x3c01, 0x3c01, 0x3c00, 0x3c00]
+  compileAndRunLibBF dir "arbitraryFloatRoundingModes" program (asHex 2 expected)
+ where rawHalf :: SFPHalf -> SWord 16
+       rawHalf = sFloatingPointAsSWord
+
+-- | Exercise a runtime-selected rounding mode in arithmetic and conversion.
+arbitraryFloatSymbolicRoundingMode :: Assertion
+arbitraryFloatSymbolicRoundingMode = withSystemTempDirectory "sbv-arbitrary-float-symbolic-rounding" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [1, 0, 1, 2, 3, 4, 2049, 2048, 1, 3]
+        choose    <- cgInput "chooseInputMode" :: SBVCodeGen SBool
+        modeRNE   <- cgInput "rne"             :: SBVCodeGen SRoundingMode
+        modeRNA   <- cgInput "rna"             :: SBVCodeGen SRoundingMode
+        modeRTP   <- cgInput "rtp"             :: SBVCodeGen SRoundingMode
+        modeRTN   <- cgInput "rtn"             :: SBVCodeGen SRoundingMode
+        modeRTZ   <- cgInput "rtz"             :: SBVCodeGen SRoundingMode
+        numValue  <- cgInput "numerator"       :: SBVCodeGen SFPQuad
+        denValue  <- cgInput "denominator"     :: SBVCodeGen SFPQuad
+        one       <- cgInput "one"             :: SBVCodeGen SFPHalf
+        three     <- cgInput "three"           :: SBVCodeGen SFPHalf
+        let runtimeMode mode = ite choose mode sRTZ
+            value            = fpDiv sRNE numValue denValue
+            rne              = rawHalf (toSFloatingPoint (runtimeMode modeRNE) value)
+            rna              = rawHalf (toSFloatingPoint (runtimeMode modeRNA) value)
+            rtp              = rawHalf (toSFloatingPoint (runtimeMode modeRTP) value)
+            rtn              = rawHalf (toSFloatingPoint (runtimeMode modeRTN) value)
+            rtz              = rawHalf (toSFloatingPoint (runtimeMode modeRTZ) value)
+            divided          = rawHalf (fpDiv (runtimeMode modeRTP) one three)
+        cgOutput "selectedMode" (runtimeMode modeRTP)
+        cgReturn (rne # rna # rtp # rtn # rtz # divided :: SWord 96)
+      expected = foldl (\acc word -> acc * 2 ^ (16 :: Int) + word) 0 [0x3c00, 0x3c01, 0x3c01, 0x3c00, 0x3c00, 0x3556]
+  compileAndRunLibBF dir "arbitraryFloatSymbolicRoundingMode" program (asHex 2 expected)
+ where rawHalf :: SFPHalf -> SWord 16
+       rawHalf = sFloatingPointAsSWord
+
+-- | Separate multiplication and addition round the product before adding;
+-- explicit FMA must keep the exact product until the final rounding. The
+-- near-one factors make these results differ in both native formats.
+nativeRoundingProgram :: SBVCodeGen ()
+nativeRoundingProgram = do
+  cgOverwriteFiles True
+  cgSetDriverValues [0x3f800001, 0x3f7ffffe, 0x3ff0000000000001, 0x3feffffffffffffe]
+  floatLeft   <- cgInput "floatLeft"   :: SBVCodeGen SWord32
+  floatRight  <- cgInput "floatRight"  :: SBVCodeGen SWord32
+  doubleLeft  <- cgInput "doubleLeft"  :: SBVCodeGen SWord64
+  doubleRight <- cgInput "doubleRight" :: SBVCodeGen SWord64
+  let xf = sWord32AsSFloat floatLeft
+      yf = sWord32AsSFloat floatRight
+      xd = sWord64AsSDouble doubleLeft
+      yd = sWord64AsSDouble doubleRight
+  cgReturn $ sAnd
+    [ fpAdd sRNE (fpMul sRNE xf yf) (-1) .== 0
+    , fpAdd sRNE (fpMul sRNE xd yd) (-1) .== 0
+    , xf * yf - 1 .== 0
+    , xd * yd - 1 .== 0
+    , fpFMA sRNE xf yf (-1) .== literal (-(2 ** (-46)) :: Float)
+    , fpFMA sRNE xd yd (-1) .== literal (-(2 ** (-104)) :: Double)
+    ]
+
+-- | Generated standalone and library Makefiles must preserve rounding steps
+-- under optimization and LTO, even when user CCFLAGS enable contraction.
+nativeFloatRoundingSteps :: Assertion
+nativeFloatRoundingSteps = mapM_ check [(library, flags) | library <- [False, True], flags <- ["-O3", "-O3 -ffp-contract=fast", "-O3 -flto -ffp-contract=fast"]]
+ where check (library, flags) = withSystemTempDirectory "sbv-native-rounding-steps" $ \dir -> do
+         let functionName = "nativeRoundingSteps"
+         (_, cfg, bundle) <- if library
+                               then compileToCLib' functionName [("roundingComponent", nativeRoundingProgram)]
+                               else compileToC' functionName ((:[]) <$> nativeRoundingProgram)
+         renderCgPgmBundle (Just dir) (cfg, bundle)
+         extraFlags <- fromMaybe "" <$> lookupEnv "SBV_C_TEST_FLAGS"
+         writeFile (dir </> "rounding.mk") ("CCFLAGS=-Wall -Werror " ++ flags ++ " " ++ extraFlags ++ "\n")
+         (makeExit, _, makeError) <- readProcessWithExitCode "make" ["-C", dir] ""
+         assertEqual makeError ExitSuccess makeExit
+         (runExit, outputText, runError) <- readProcessWithExitCode (dir </> functionName ++ "_driver") [] ""
+         assertEqual runError ExitSuccess runExit
+         assertBool (flags ++ ":\n" ++ outputText) (") = 1" `isInfixOf` outputText)
+
+-- | Reject detectable compiler modes that can discard NaNs, signed zeros,
+-- or IEEE rounding, instead of silently compiling a different computation.
+nativeFloatCompilerModes :: Assertion
+nativeFloatCompilerModes = withSystemTempDirectory "sbv-native-unsafe-compiler-modes" $ \dir -> do
+  let functionName = "nativeCompilerModes"
+  (_, cfg, bundle) <- compileToC' functionName nativeRoundingProgram
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  let check flag = do
+        (ccExit, _, ccError) <- readProcessWithExitCode "cc"
+          ["-std=c11", "-O3", flag, "-c", dir </> functionName ++ ".c", "-o", dir </> "unsafe.o"] ""
+        assertBool ("Expected rejection of " ++ flag) (ccExit /= ExitSuccess)
+        assertBool ccError ("SBV-generated C requires IEEE floating-point semantics" `isInfixOf` ccError)
+  mapM_ check ["-ffast-math", "-ffinite-math-only"]
+
+-- | Exercise all constant rounding modes and runtime-selected modes while
+-- retaining native @float@ and @double@ values at the generated C boundary.
+nativeFloatRoundingModes :: Assertion
+nativeFloatRoundingModes = withSystemTempDirectory "sbv-native-float-rounding" $ \dir -> do
+  let floatProgram = do
+        cgOverwriteFiles True
+        cgSetDriverValues [0x3f800000, 0x33800000, 1, 2]
+        oneRaw   <- cgInput "oneBits"  :: SBVCodeGen SWord32
+        halfBits <- cgInput "halfBits" :: SBVCodeGen SWord32
+        modeRNA  <- cgInput "modeRNA"  :: SBVCodeGen SRoundingMode
+        modeRTP  <- cgInput "modeRTP"  :: SBVCodeGen SRoundingMode
+        let one     = sWord32AsSFloat oneRaw
+            halfUlp = sWord32AsSFloat halfBits
+            raw mode = sFromIntegral (sFloatAsSWord32 (fpAdd mode one halfUlp)) :: SWord 32
+        cgReturn (raw sRNE # raw sRNA # raw sRTP # raw sRTN # raw sRTZ # raw modeRNA # raw modeRTP :: SWord 224)
+
+      doubleProgram = do
+        cgOverwriteFiles True
+        cgSetDriverValues [0x3ff0000000000000, 0x3ca0000000000000, 1, 2]
+        oneRaw   <- cgInput "oneBits"  :: SBVCodeGen SWord64
+        halfBits <- cgInput "halfBits" :: SBVCodeGen SWord64
+        modeRNA  <- cgInput "modeRNA"  :: SBVCodeGen SRoundingMode
+        modeRTP  <- cgInput "modeRTP"  :: SBVCodeGen SRoundingMode
+        let one     = sWord64AsSDouble oneRaw
+            halfUlp = sWord64AsSDouble halfBits
+            raw mode = sFromIntegral (sDoubleAsSWord64 (fpAdd mode one halfUlp)) :: SWord 64
+        cgReturn (raw sRNE # raw sRNA # raw sRTP # raw sRTN # raw sRTZ # raw modeRNA # raw modeRTP :: SWord 448)
+
+      scalarProgram = do
+        cgOverwriteFiles True
+        cgSetDriverValues [0x3f800000, 0x33800000]
+        oneRaw   <- cgInput "oneBits"  :: SBVCodeGen SWord32
+        halfBits <- cgInput "halfBits" :: SBVCodeGen SWord32
+        let result = fpAdd sRNA (sWord32AsSFloat oneRaw) (sWord32AsSFloat halfBits)
+        cgOutput "resultBits" (sFloatAsSWord32 result)
+        cgReturn result
+
+      floatOne      = 0x3f800000
+      floatNext     = 0x3f800001
+      doubleOne     = 0x3ff0000000000000
+      doubleNext    = 0x3ff0000000000001
+      assemble width = foldl (\acc word -> acc * 2 ^ width + word) 0
+      floatExpected  = assemble (32 :: Int) [floatOne, floatNext, floatNext, floatOne, floatOne, floatNext, floatNext]
+      doubleExpected = assemble (64 :: Int) [doubleOne, doubleNext, doubleNext, doubleOne, doubleOne, doubleNext, doubleNext]
+
+  compileAndRunLibBF dir "nativeFloatRoundingModesFloat" floatProgram (asHex 4 floatExpected)
+  compileAndRunLibBF dir "nativeFloatRoundingModesDouble" doubleProgram (asHex 7 doubleExpected)
+  compileAndRunLibBF dir "nativeFloatRoundingScalar" scalarProgram "resultBits = 0x3f800001UL"
+
+-- | Exercise all rounding directions between native floats and exact-width
+-- bit-vectors.
+nativeFloatBitVectorConversions :: Assertion
+nativeFloatBitVectorConversions = withSystemTempDirectory "sbv-native-float-bit-vector" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [16777217, 5, 2]
+        nativeInteger <- cgInput "nativeInteger" :: SBVCodeGen SInt32
+        five          <- cgInput "five"          :: SBVCodeGen SFloat
+        two           <- cgInput "two"           :: SBVCodeGen SFloat
+        let nativeRNE   = toSFloat sRNE nativeInteger
+            nativeRTP   = toSFloat sRTP nativeInteger
+            twoAndAHalf = fpDiv sRNE five two
+            nativeEven  = fromSFloat sRNE twoAndAHalf :: SInt32
+            nativeAway  = fromSFloat sRNA twoAndAHalf :: SInt32
+            nativeDown  = fromSFloat sRTN twoAndAHalf :: SInt32
+            nativeUp    = fromSFloat sRTP twoAndAHalf :: SInt32
+        cgReturn $ nativeRNE .== 16777216
+               .&& nativeRTP .== 16777218
+               .&& nativeEven .== 2
+               .&& nativeAway .== 3
+               .&& nativeDown .== 2
+               .&& nativeUp   .== 3
+  compileAndRunLibBF dir "nativeFloatBitVectorConversions" program "= 1"
+
+-- | Exercise explicitly rounded native float-to-float conversion, RNE
+-- conversion to and from a limb-backed bit-vector, and the one-bit scalar
+-- fallback type.
+nativeFloatWidthConversions :: Assertion
+nativeFloatWidthConversions = withSystemTempDirectory "sbv-native-float-width-conversions" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [halfwayBits, 42, 1, 1]
+        rawHalfway <- cgInput "rawHalfway" :: SBVCodeGen SWord64
+        wideValue  <- svCgInput wideKind "wideValue"
+        oneBit     <- svCgInput oneBitKind "oneBit"
+        runtimeRNA <- cgInput "runtimeRNA" :: SBVCodeGen SRoundingMode
+        let halfway      = sWord64AsSDouble rawHalfway
+            floatBits rm = sFloatAsSWord32 (toSFloat rm halfway)
+            nativeChecks = floatBits sRNE       .== floatOne
+                       .&& floatBits sRNA       .== floatNext
+                       .&& floatBits sRTP       .== floatNext
+                       .&& floatBits sRTN       .== floatOne
+                       .&& floatBits sRTZ       .== floatOne
+                       .&& floatBits runtimeRNA .== floatNext
+            wideAsDouble = D.svCastToFP KDouble rneValue wideValue
+            wideAgain    = D.svCastFromFP wideKind rneValue wideAsDouble
+            oneAsFloat   = D.svCastToFP KFloat rneValue oneBit
+            oneAgain     = D.svCastFromFP oneBitKind rneValue oneAsFloat
+            allChecks    = foldl D.svAnd (unSBV nativeChecks) [D.svEqual wideAgain wideValue, D.svEqual oneAgain oneBit]
+        svCgReturn allChecks
+      halfwayBits = 0x3ff0000010000000
+      floatOne    = 0x3f800000
+      floatNext   = 0x3f800001
+      rneValue    = unSBV sRNE
+      wideKind    = KBounded True 673
+      oneBitKind  = KBounded False 1
+  compileAndRunLibBF dir "nativeFloatWidthConversions" program "= 1"
+
+-- | A separately compiled caller changes the hardware rounding mode around
+-- explicitly rounded casts. Check halfway values at native and non-native
+-- bit widths, large signed/unsigned integers, and binary64-to-binary32 narrowing.
+-- This deliberately tests a stronger property of the conversion bridges than
+-- the public FE_TONEAREST entry-point precondition; it is not a supported
+-- calling convention for general generated arithmetic.
+nativeFloatCastEnvironment :: Assertion
+nativeFloatCastEnvironment = withSystemTempDirectory "sbv-native-float-cast-environment" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgGenerateDriver False
+        floatBits  <- cgInput "floatBits"     :: SBVCodeGen SWord32
+        doubleBits <- cgInput "doubleBits"    :: SBVCodeGen SWord64
+        halfBits   <- cgInput "halfBits"      :: SBVCodeGen SWord32
+        signed     <- cgInput "signedValue"   :: SBVCodeGen SInt64
+        unsigned   <- cgInput "unsignedValue" :: SBVCodeGen SWord64
+        let float    = sWord32AsSFloat floatBits
+            double   = sWord64AsSDouble doubleBits
+            half     = sWord32AsSFloat halfBits
+            modes    = [sRNE, sRNA, sRTP, sRTN, sRTZ]
+            widths   = [1, 7, 8, 9, 16, 32, 64, 65, 673]
+            checks signedKind width = zipWith check modes expected
+              where kind     = KBounded signedKind width
+                    positive = if width == 1 then half else float
+                    value    = if signedKind then negate positive else positive
+                    expected
+                      | width == 1 = if signedKind then [0, -1, 0, -1, 0] else [0, 1, 1, 0, 0]
+                      | signedKind = [-2, -3, -2, -3, -2]
+                      | True       = [2, 3, 3, 2, 2]
+                    check rm result = D.svEqual (D.svCastFromFP kind (unSBV rm) (unSBV value)) (D.svInteger kind result)
+            nativeChecks = sFloatAsSWord32 (toSFloat sRNE double) .== 0x3f800000
+                       .&& toSDouble sRNE signed .== -9007199254740992
+                       .&& toSFloat sRNE signed .== -9007199254740992
+                       .&& toSDouble sRNE unsigned .== 18446744073709551616
+                       .&& toSFloat sRNE unsigned .== 18446744073709551616
+        svCgReturn (foldl D.svAnd (unSBV nativeChecks) (concat [checks sign width | sign <- [False, True], width <- widths]))
+      caller = unlines
+        [ "#include <fenv.h>"
+        , "#include \"nativeFloatCastEnvironment.h\""
+        , "int main(void)"
+        , "{"
+        , "  const int modes[] = { FE_TONEAREST, FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO };"
+        , "  const int original = fegetround();"
+        , "  for (size_t i = 0; i < sizeof modes / sizeof modes[0]; ++i) {"
+        , "    if (fesetround(modes[i]) != 0) return 1;"
+        , "    if (!nativeFloatCastEnvironment(UINT32_C(0x40200000), UINT64_C(0x3ff0000010000000), UINT32_C(0x3f000000), -INT64_C(9007199254740993), UINT64_MAX)) return 2;"
+        , "    if (fegetround() != modes[i]) return 3;"
+        , "  }"
+        , "  return fesetround(original) != 0;"
+        , "}"
+        ]
+  compileAndRunLibBFCaller dir "nativeFloatCastEnvironment" program caller
+
+-- | SMT leaves non-finite and out-of-range floating-to-bit-vector results
+-- unspecified. The backend chooses zero for non-finite inputs and low bits
+-- for finite ones, without invoking an overflowing native C integer cast.
+nativeFloatExceptionalCasts :: Assertion
+nativeFloatExceptionalCasts = mapM_ check [0x7ff0000000000000, 0xfff0000000000000, 0x7ff8000000000000, 0x8000000000000000, 0x7e70000000000000, 0xfe70000000000000]
+ where check bits = withSystemTempDirectory "sbv-native-float-exceptional-casts" $ \dir -> do
+         let program = do
+               cgOverwriteFiles True
+               cgSetDriverValues [bits]
+               raw <- cgInput "raw" :: SBVCodeGen SWord64
+               let value  = sWord64AsSDouble raw
+                   values = [unSBV value, unSBV (toSFloat sRNE value)]
+                   kinds  = [KBounded sign width | sign <- [False, True], width <- [1, 7, 8, 16, 32, 64, 65, 673]]
+                   checks = [D.svEqual (D.svCastFromFP kind (unSBV sRNE) source) (D.svInteger kind 0) | kind <- kinds, source <- values]
+               svCgReturn (foldl D.svAnd (unSBV sTrue) checks)
+         compileAndRunLibBF dir "nativeFloatExceptionalCasts" program ") = 1"
+
+-- | Exactly representable casts stay native even with symbolic rounding.
+-- Include negative zero so widening cannot accidentally change its sign.
+nativeExactFloatConversions :: Assertion
+nativeExactFloatConversions = withSystemTempDirectory "sbv-exact-native-float-casts" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [-32768, 4294967295, 0x80000000, 2]
+        small    <- cgInput "small"    :: SBVCodeGen SInt16
+        unsigned <- cgInput "word"     :: SBVCodeGen SWord32
+        zeroRaw  <- cgInput "zeroBits" :: SBVCodeGen SWord32
+        mode     <- cgInput "mode"     :: SBVCodeGen SRoundingMode
+        let checks rm = [ toSFloat rm small .== -32768
+                        , toSDouble rm unsigned .== 4294967295
+                        , sDoubleAsSWord64 (toSDouble rm (sWord32AsSFloat zeroRaw)) .== 0x8000000000000000
+                        ]
+        cgReturn (sAnd (concatMap checks [sRNE, sRNA, sRTP, sRTN, sRTZ, mode]))
+  compileAndRunWith ["-lm"] dir "nativeExactFloatConversions" program ") = 1"
+  source <- readFile (dir </> "nativeExactFloatConversions.c")
+  makefile <- readFile (dir </> "Makefile")
+  assertBool "Exact native conversions must not include LibBF" (not ("<libbf.h>" `isInfixOf` source))
+  assertBool "Exact native conversions must not link LibBF" (not ("-lbf" `isInfixOf` makefile))
+
+-- | Exercise LibBF-mediated conversion between native floats and GMP-backed
+-- exact numbers without introducing an arbitrary floating-point format.
+nativeFloatExactConversions :: Assertion
+nativeFloatExactConversions = withSystemTempDirectory "sbv-native-float-exact" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [16777217, 3, 2, 5, 2]
+        integer         <- cgInput "integer"         :: SBVCodeGen SInteger
+        realNumerator   <- cgInput "realNumerator"   :: SBVCodeGen SReal
+        realDenominator <- cgInput "realDenominator" :: SBVCodeGen SReal
+        five            <- cgInput "five"            :: SBVCodeGen SFloat
+        two             <- cgInput "two"             :: SBVCodeGen SFloat
+        let rational      = realNumerator / realDenominator
+            integerRNE    = toSFloat sRNE integer
+            integerRTP    = toSFloat sRTP integer
+            rationalValue = toSDouble sRNE rational
+            twoAndAHalf   = fpDiv sRNE five two
+            roundedEven   = fromSFloat sRNE twoAndAHalf :: SInteger
+            roundedAway   = fromSFloat sRNA twoAndAHalf :: SInteger
+            roundedUp     = fromSFloat sRTP twoAndAHalf :: SInteger
+            roundedDown   = fromSFloat sRTN twoAndAHalf :: SInteger
+            roundedZero   = fromSFloat sRTZ twoAndAHalf :: SInteger
+            exactRational = fromSDouble sRNE rationalValue :: SReal
+        cgReturn $ integerRNE .== 16777216
+               .&& integerRTP .== 16777218
+               .&& rationalValue .== 1.5
+               .&& roundedEven .== 2
+               .&& roundedAway .== 3
+               .&& roundedUp   .== 3
+               .&& roundedDown .== 2
+               .&& roundedZero .== 2
+               .&& exactRational .== 3 / 2
+  compileAndRunLibBFGMP dir "nativeFloatExactConversions" program "= 1"
+
+-- | Mapped integer casts must use the selected width in both directions while
+-- preserving every explicit rounding mode, including halfway negative values.
+mappedIntegerFloatConversions :: Assertion
+mappedIntegerFloatConversions = mapM_ check [(width, exposeChecks, arbitraryResult) | width <- [8, 16, 32, 64], exposeChecks <- [True, False], arbitraryResult <- [False, True]]
+ where check (width, exposeChecks, arbitraryResult) = withSystemTempDirectory "sbv-mapped-integer-float" $ \dir -> do
+         let program = do
+               cgOverwriteFiles True
+               cgIntegerSize width
+               cgSetDriverValues [sample, -5, 65539]
+               value <- cgInput "value" :: SBVCodeGen SInteger
+               five  <- cgInput "five"  :: SBVCodeGen SDouble
+               large <- cgInput "large" :: SBVCodeGen SDouble
+               let fraction = fpDiv sRNE five 2
+                   half rm = toSFloatingPoint rm value :: SFPHalf
+                   halfFraction = fpDiv sRNE (toSFloatingPoint sRNE five :: SFPHalf) 2
+                   reference rm
+                     | width == 8 = 5
+                     | True       = ite (rm .== sRNA .|| rm .== sRTP) 2050 2048 :: SFPHalf
+                   checks (rm, expected) =
+                     [ sFloatingPointAsSWord (half rm) .== sFloatingPointAsSWord (reference rm)
+                     , (fromSDouble rm fraction :: SInteger) .== expected
+                     , toSDouble rm value .== fromInteger sample
+                     ]
+                     ++ [(fromSFloatingPoint rm halfFraction :: SInteger) .== expected | arbitraryResult]
+                   allChecks = ((fromSDouble sRNE large :: SInteger) .== 65539)
+                             : concatMap checks [(sRNE, -2), (sRNA, -3), (sRTP, -2), (sRTN, -3), (sRTZ, -2)]
+               when exposeChecks $ do
+                 cgOutputArr "checks" allChecks
+                 cgOutputArr "actual" (map (sFloatingPointAsSWord . half) [sRNE, sRNA, sRTP, sRTN, sRTZ])
+                 cgOutputArr "expected" (map (sFloatingPointAsSWord . reference) [sRNE, sRNA, sRTP, sRTN, sRTZ])
+               cgReturn (sAnd allChecks)
+             sample = if width == 8 then 5 else 2049
+         compileAndRunLibBF dir "mappedIntegerFloat" program ") = 1"
+
+-- | Native real mappings still require representation-aware conversion:
+-- exact integers round to the selected real format, real-to-integer casts
+-- floor, and explicit floating casts honor their requested rounding mode.
+mappedRealConversions :: Assertion
+mappedRealConversions = mapM_ check [(realType, mappedInteger) | realType <- [CgFloat, CgDouble, CgLongDouble], mappedInteger <- [False, True]]
+ where check (realType, mappedInteger) = withSystemTempDirectory "sbv-mapped-real-conversions" $ \dir -> do
+         let program = do
+               cgOverwriteFiles True
+               cgSRealType realType
+               when mappedInteger $ cgIntegerSize 32
+               cgSetDriverValues [16777217, -5, 7]
+               value <- cgInput "value" :: SBVCodeGen SInteger
+               real  <- cgInput "real"  :: SBVCodeGen SReal
+               seven <- cgInput "seven" :: SBVCodeGen SFPHalf
+               let expected = case realType of
+                                CgFloat -> 16777216
+                                _       -> 16777217
+                   half = toSFloatingPoint sRTP real :: SFPHalf
+               cgReturn $ (sFromIntegral value :: SReal) .== expected
+                      .&& sRealToSIntegerFloor (real / 2) .== -3
+                      .&& (fromSFloatingPoint sRNE seven :: SReal) .== 7
+                      .&& half .== -5
+                      .&& toSDouble sRNE real .== -5
+         compileAndRunLibBFGMP dir "mappedRealConversions" program "= 1"
+
+-- | Exercise target-dependent precision, exponent extremes, signed zero, NaN,
+-- and all five rounding modes through an independent library caller. On targets
+-- wider than binary64 the same tests explicitly preserve the additional bits.
+longDoubleNumericBoundaries :: Assertion
+longDoubleNumericBoundaries = withSystemTempDirectory "sbv-long-double-bridges" $ \dir -> do
+  let prepare program = cgOverwriteFiles True >> cgGenerateDriver False >> cgSRealType CgLongDouble >> program
+      wide :: SReal -> SFloatingPoint 20 200
+      wide = toSFloatingPoint sRNE
+      components =
+        [ ("integerToLong", do
+            value <- cgInput "value" :: SBVCodeGen SInteger
+            cgReturn (sFromIntegral value :: SReal))
+        , ("wordToLong", do
+            value <- cgInput "value" :: SBVCodeGen SWord64
+            cgReturn (sFromIntegral value :: SReal))
+        , ("rationalToLong", do
+            value <- cgInput "value" :: SBVCodeGen SRational
+            cgReturn (Rat.sRationalToSReal value))
+        , ("floorLong", do
+            value <- cgInput "value" :: SBVCodeGen SReal
+            cgOutput "result" (sRealToSIntegerFloor value))
+        , ("roundedInteger", do
+            mode  <- cgInput "mode"  :: SBVCodeGen SRoundingMode
+            value <- cgInput "value" :: SBVCodeGen SInteger
+            let exact = toSFloatingPoint sRNE value :: SFloatingPoint 20 200
+            cgReturn (fromSFloatingPoint mode exact :: SReal))
+        , ("wideRoundTrip", do
+            value <- cgInput "value" :: SBVCodeGen SReal
+            cgReturn (fromSFloatingPoint sRNE (wide value) :: SReal))
+        , ("tinyLong", do
+            mode  <- cgInput "mode"  :: SBVCodeGen SRoundingMode
+            value <- cgInput "value" :: SBVCodeGen SReal
+            cgReturn (fromSFloatingPoint mode (fpDiv sRNE (wide value) 2) :: SReal))
+        , ("narrowFloat", do
+            mode  <- cgInput "mode"  :: SBVCodeGen SRoundingMode
+            value <- cgInput "value" :: SBVCodeGen SReal
+            cgReturn (toSFloat mode value))
+        , ("nativeRoundTrip", do
+            value <- cgInput "value" :: SBVCodeGen SDouble
+            cgReturn (toSDouble sRNE (fromSDouble sRNE value :: SReal)))
+        ]
+  _ <- D.compileToCLib (Just dir) "longBridges" [(functionName, prepare program) | (functionName, program) <- components]
+  writeFile (dir </> "caller.c") $ unlines
+    [ "#include <assert.h>"
+    , "#include <float.h>"
+    , "#include <math.h>"
+    , "#include \"longBridges.h\""
+    , "int main(int argc, char **argv)"
+    , "{"
+    , "  mpz_t input, output; mpz_inits(input, output, NULL);"
+    , "  (void) argv; if (argc > 1) { floorLong(HUGE_VALL, output); return 0; }"
+    , "  const long double base = ldexpl(1.0L, LDBL_MANT_DIG);"
+    , "  for (int negative = 0; negative < 2; ++negative) for (int odd = 0; odd < 2; ++odd) {"
+    , "    mpz_set_ui(input, 1); mpz_mul_2exp(input, input, LDBL_MANT_DIG); mpz_add_ui(input, input, 1 + 2 * odd);"
+    , "    if (negative) mpz_neg(input, input);"
+    , "    for (int mode = 0; mode < 5; ++mode) {"
+    , "      const bool up = mode == SBV_RM_RNA || (mode == SBV_RM_RNE && odd) || (mode == SBV_RM_RTP && !negative) || (mode == SBV_RM_RTN && negative);"
+    , "      const long double magnitude = base + 2 * odd + (up ? 2 : 0);"
+    , "      assert(roundedInteger((RoundingMode) mode, input) == (negative ? -magnitude : magnitude));"
+    , "    }"
+    , "    const long double nearest = base + (odd ? 4 : 0);"
+    , "    assert(integerToLong(input) == (negative ? -nearest : nearest));"
+    , "  }"
+    , "  mpz_set_ui(input, 1); mpz_mul_2exp(input, input, LDBL_MANT_DIG - 1); mpz_add_ui(input, input, 1);"
+    , "  const long double precise = ldexpl(1.0L, LDBL_MANT_DIG - 1) + 1;"
+    , "  assert(integerToLong(input) == precise); floorLong(precise, output); assert(mpz_cmp(input, output) == 0);"
+    , "  mpq_t rational; mpq_init(rational); mpz_set(mpq_numref(rational), input);"
+    , "  mpz_set_ui(mpq_denref(rational), 1); mpz_mul_2exp(mpq_denref(rational), mpq_denref(rational), LDBL_MANT_DIG - 1);"
+    , "  assert(rationalToLong(rational) == 1.0L + ldexpl(1.0L, 1 - LDBL_MANT_DIG)); mpq_clear(rational);"
+    , "  assert(wordToLong(UINT64_C(9007199254740993)) == (LDBL_MANT_DIG > 53 ? 9007199254740993.0L : 9007199254740992.0L));"
+    , "  floorLong(-2.5L, output); assert(mpz_cmp_si(output, -3) == 0);"
+    , "  const long double tiny = nextafterl(0.0L, 1.0L);"
+    , "  const long double values[] = {0.0L, -0.0L, tiny, -tiny, LDBL_MIN, -LDBL_MIN, LDBL_MAX, -LDBL_MAX, precise, -precise, HUGE_VALL, -HUGE_VALL};"
+    , "  for (size_t i = 0; i < sizeof values / sizeof *values; ++i) {"
+    , "    const long double result = wideRoundTrip(values[i]);"
+    , "    assert(result == values[i] && (signbit(result) != 0) == (signbit(values[i]) != 0));"
+    , "  }"
+    , "  assert(isnan(wideRoundTrip(nanl(\"\"))));"
+    , "  for (int mode = 0; mode < 5; ++mode) {"
+    , "    const RoundingMode rm = (RoundingMode) mode;"
+    , "    const long double positive = tinyLong(rm, tiny), negative = tinyLong(rm, -tiny);"
+    , "    assert(positive == ((rm == SBV_RM_RNA || rm == SBV_RM_RTP) ? tiny : 0));"
+    , "    assert(negative == ((rm == SBV_RM_RNA || rm == SBV_RM_RTN) ? -tiny : 0));"
+    , "    assert(signbit(negative));"
+    , "    assert(narrowFloat(rm, 1.0L + 0x1p-24L) == ((rm == SBV_RM_RNA || rm == SBV_RM_RTP) ? 0x1.000002p0f : 1.0f));"
+    , "    mpz_set_ui(input, 1); mpz_mul_2exp(input, input, LDBL_MAX_EXP);"
+    , "    const long double large = roundedInteger(rm, input);"
+    , "    assert(large == ((rm == SBV_RM_RTZ || rm == SBV_RM_RTN) ? LDBL_MAX : HUGE_VALL));"
+    , "    mpz_neg(input, input); const long double small = roundedInteger(rm, input);"
+    , "    assert(small == ((rm == SBV_RM_RTZ || rm == SBV_RM_RTP) ? -LDBL_MAX : -HUGE_VALL));"
+    , "  }"
+    , "  assert(nativeRoundTrip(DBL_MAX) == DBL_MAX); assert(signbit(nativeRoundTrip(-0.0)));"
+    , "  assert(isinf(nativeRoundTrip(HUGE_VAL))); assert(isnan(nativeRoundTrip(NAN)));"
+    , "  mpz_clears(input, output, NULL); return 0;"
+    , "}"
+    ]
+  writeFile (dir </> "caller.mk") $ unlines
+    [ "caller: caller.c longBridges.h longBridges.a"
+    , "\t${CC} ${CCFLAGS} ${GMP_CFLAGS} caller.c longBridges.a ${LDFLAGS} ${SBV_LIBS} -o $@"
+    ]
+  makeOptions <- generatedMakeOptions dir
+  (buildExit, _, buildError) <- readProcessWithExitCode "make" (["-C", dir, "caller"] ++ makeOptions) ""
+  assertEqual buildError ExitSuccess buildExit
+  (runExit, _, runError) <- readProcessWithExitCode (dir </> "caller") [] ""
+  assertEqual runError ExitSuccess runExit
+  (invalidExit, _, invalidError) <- readProcessWithExitCode (dir </> "caller") ["nonfinite"] ""
+  assertBool "Non-finite real flooring must terminate" (invalidExit /= ExitSuccess)
+  assertBool invalidError ("Cannot convert a non-finite mapped SReal to exact SInteger" `isInfixOf` invalidError)
+
+-- | Simulate an unsupported double-double target format at the generated
+-- translation unit's feature check, without pretending to execute that ABI.
+unsupportedLongDoubleFormat :: Assertion
+unsupportedLongDoubleFormat = withSystemTempDirectory "sbv-long-double-format" $ \dir -> do
+  D.compileToC (Just dir) "unsupportedLongDouble" $ do
+    cgOverwriteFiles True
+    cgGenerateDriver False
+    cgSRealType CgLongDouble
+    cgAddDecl ["#include <float.h>", "#undef LDBL_MANT_DIG", "#define LDBL_MANT_DIG 106"]
+    value <- cgInput "value" :: SBVCodeGen SReal
+    cgReturn (toSFloatingPoint sRNE value :: SFPHalf)
+  makeOptions <- generatedMakeOptions dir
+  (buildExit, _, buildError) <- readProcessWithExitCode "make" (["-C", dir, "unsupportedLongDouble.o"] ++ makeOptions) ""
+  assertBool "Unsupported long-double formats must not compile" (buildExit /= ExitSuccess)
+  assertBool buildError ("long-double conversions require binary64, x87 extended, or binary128" `isInfixOf` buildError)
+
+-- | Exercise LibBF encoding of subnormal results, NaN, and signed zero.
+arbitraryFloatSpecialArithmetic :: Assertion
+arbitraryFloatSpecialArithmetic = withSystemTempDirectory "sbv-arbitrary-float-special" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [0x0001, 0x7c00, 0x8000, 5, 2]
+        subBits <- cgInput "subnormalBits"    :: SBVCodeGen (SWord 16)
+        infBits <- cgInput "infinityBits"     :: SBVCodeGen (SWord 16)
+        nzBits  <- cgInput "negativeZeroBits" :: SBVCodeGen (SWord 16)
+        five    <- cgInput "five"             :: SBVCodeGen SFPHalf
+        two     <- cgInput "two"              :: SBVCodeGen SFPHalf
+        let subnormal    = sWordAsSFloatingPoint subBits :: SFPHalf
+            infValue     = sWordAsSFloatingPoint infBits :: SFPHalf
+            negativeZero = sWordAsSFloatingPoint nzBits :: SFPHalf
+            doubled      = rawHalf (fpAdd sRNE subnormal subnormal)
+            nanResult    = rawHalf (fpSub sRNE infValue infValue)
+            zeroResult   = rawHalf (fpSqrt sRNE negativeZero)
+            remResult    = rawHalf (fpRem five two)
+            roundResult  = rawHalf (fpRoundToIntegral sRNE (fpDiv sRNE five two))
+            minResult    = rawHalf (fpMin five two)
+            maxResult    = rawHalf (fpMax five two)
+            absResult    = rawHalf (abs (negate five))
+        cgReturn (doubled # nanResult # zeroResult # remResult # roundResult # minResult # maxResult # absResult :: SWord 128)
+      expected = foldl (\acc word -> acc * 2 ^ (16 :: Int) + word) 0 [0x0002, 0x7e00, 0x8000, 0x3c00, 0x4000, 0x4000, 0x4500, 0x4500]
+  compileAndRunLibBF dir "arbitraryFloatSpecialArithmetic" program (asHex 2 expected)
+ where rawHalf :: SFPHalf -> SWord 16
+       rawHalf = sFloatingPointAsSWord
+
+-- | Exercise a finite table containing computed arbitrary-precision floating
+-- point values. The table is emitted after the computation on which it
+-- depends and its result remains an ordinary by-value interchange object.
+arbitraryFloatTableLookup :: Assertion
+arbitraryFloatTableLookup = withSystemTempDirectory "sbv-arbitrary-float-table" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgPerformRTCs True
+        cgSetDriverValues [1, 3]
+        index <- cgInput "index" :: SBVCodeGen SWord8
+        value <- cgInput "value" :: SBVCodeGen SFPQuad
+        let selected = select [value, fpAdd sRNE value 2] 99 index
+        cgReturn (sFloatingPointAsSWord selected :: SWord 128)
+      bias    = 2 ^ (14 :: Int) - 1 :: Integer
+      fiveRaw = (bias + 2) * 2 ^ (112 :: Int) + 2 ^ (110 :: Int)
+  compileAndRunLibBF dir "arbitraryFloatTableLookup" program (asHex 2 fiveRaw)
+
+-- | Check that LibBF-backed array keys use SMT object equality: NaNs match,
+-- while positive and negative zero remain distinct.
+arbitraryFloatArrayKeys :: Assertion
+arbitraryFloatArrayKeys = withSystemTempDirectory "sbv-arbitrary-float-array-keys" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [0x7e00, 0x0000, 0x8000]
+        nanBits      <- cgInput "nanBits"      :: SBVCodeGen (SWord 16)
+        positiveBits <- cgInput "positiveBits" :: SBVCodeGen (SWord 16)
+        negativeBits <- cgInput "negativeBits" :: SBVCodeGen (SWord 16)
+        let nanKey       = sWordAsSFloatingPoint nanBits :: SFPHalf
+            positiveZero = sWordAsSFloatingPoint positiveBits :: SFPHalf
+            negativeZero = sWordAsSFloatingPoint negativeBits :: SFPHalf
+            base         = constArray 3
+            withNaN      = writeArray base nanKey 11
+            withZero     = writeArray withNaN positiveZero 12
+            flags        = [ readArray withZero nanKey .== (11 :: SWord8)
+                           , readArray withZero positiveZero .== (12 :: SWord8)
+                           , readArray withZero negativeZero .== (3 :: SWord8)
+                           ]
+        cgReturn (sum (zipWith (\flag weight -> ite flag weight 0) flags [1, 2, 4]) :: SWord8)
+  compileAndRunLibBF dir "arbitraryFloatArrayKeys" program "= 7"
+
+-- | Exercise a callback-backed array whose returned values use LibBF's raw
+-- arbitrary floating-point interchange representation.
+arbitraryFloatArrayInput :: Assertion
+arbitraryFloatArrayInput = withSystemTempDirectory "sbv-arbitrary-float-array-input" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [3, 7]
+        source <- cgInput "source" :: SBVCodeGen (SArray Word8 (FloatingPoint 15 113))
+        key    <- cgInput "key"    :: SBVCodeGen SWord8
+        cgReturn (sFloatingPointAsSWord (readArray source key) :: SWord 128)
+      bias     = 2 ^ (14 :: Int) - 1 :: Integer
+      threeRaw = (bias + 1) * 2 ^ (112 :: Int) + 2 ^ (111 :: Int)
+  compileAndRunLibBF dir "arbitraryFloatArrayInput" program (asHex 2 threeRaw)
+
+-- | Exercise a LibBF conversion that occurs only inside a retained array
+-- lambda, ensuring its format-specific runtime helper is still discovered.
+arbitraryFloatLambdaArray :: Assertion
+arbitraryFloatLambdaArray = withSystemTempDirectory "sbv-arbitrary-float-lambda-array" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [3]
+        key <- cgInput "key" :: SBVCodeGen SWord8
+        let source = lambdaArray (\index -> toSFloatingPoint sRNE index :: SFloatingPoint 15 113)
+                     :: SArray Word8 (FloatingPoint 15 113)
+        cgReturn (sFloatingPointAsSWord (readArray source key) :: SWord 128)
+      bias     = 2 ^ (14 :: Int) - 1 :: Integer
+      threeRaw = (bias + 1) * 2 ^ (112 :: Int) + 2 ^ (111 :: Int)
+  compileAndRunLibBF dir "arbitraryFloatLambdaArray" program (asHex 2 threeRaw)
+
+-- | Exercise LibBF-valued table entries constructed from a structured
+-- lambda's parameter and selected entirely inside its retained DAG.
+arbitraryFloatLambdaTable :: Assertion
+arbitraryFloatLambdaTable = withSystemTempDirectory "sbv-arbitrary-float-lambda-table" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [1]
+        key <- cgInput "key" :: SBVCodeGen SWord8
+        let source = lambdaArray (\index -> select [toFP index, fpAdd sRNE (toFP index) 1] 0 index)
+                     :: SArray Word8 (FloatingPoint 15 113)
+        cgReturn (sFloatingPointAsSWord (readArray source key) :: SWord 128)
+      toFP value = toSFloatingPoint sRNE value :: SFloatingPoint 15 113
+      bias       = 2 ^ (14 :: Int) - 1 :: Integer
+      twoRaw     = (bias + 1) * 2 ^ (112 :: Int)
+  compileAndRunLibBF dir "arbitraryFloatLambdaTable" program (asHex 2 twoRaw)
+
+-- | Exercise correctly rounded conversions between LibBF formats and
+-- GMP-backed unbounded integers and rational reals.
+arbitraryFloatExactConversions :: Assertion
+arbitraryFloatExactConversions = withSystemTempDirectory "sbv-arbitrary-float-exact" $ \dir -> do
+  let largeSample = negate (2 ^ (200 :: Int) + 2 ^ (100 :: Int))
+      program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [2049, largeSample, 7, 2, 5, 2]
+        integer         <- cgInput "integer"      :: SBVCodeGen SInteger
+        largeInteger    <- cgInput "largeInteger" :: SBVCodeGen SInteger
+        realNumerator   <- cgInput "numerator"    :: SBVCodeGen SReal
+        realDenominator <- cgInput "denominator"  :: SBVCodeGen SReal
+        five            <- cgInput "five"         :: SBVCodeGen SFPHalf
+        two             <- cgInput "two"          :: SBVCodeGen SFPHalf
+        let rational       = realNumerator / realDenominator
+            integerRNE     = toSFloatingPoint sRNE integer :: SFPHalf
+            integerRTP     = toSFloatingPoint sRTP integer :: SFPHalf
+            largeQuad      = toSFloatingPoint sRNE largeInteger :: SFPQuad
+            largeRoundTrip = fromSFloatingPoint sRNE largeQuad :: SInteger
+            rationalHalf   = toSFloatingPoint sRNE rational :: SFPHalf
+            twoAndAHalf    = fpDiv sRNE five two
+            roundedEven    = fromSFloatingPoint sRNE twoAndAHalf :: SInteger
+            roundedAway    = fromSFloatingPoint sRNA twoAndAHalf :: SInteger
+            roundedUp      = fromSFloatingPoint sRTP twoAndAHalf :: SInteger
+            roundedDown    = fromSFloatingPoint sRTN twoAndAHalf :: SInteger
+            roundedZero    = fromSFloatingPoint sRTZ twoAndAHalf :: SInteger
+            exactRational  = fromSFloatingPoint sRNE rationalHalf :: SReal
+            integerRNEBits = sFloatingPointAsSWord integerRNE :: SWord 16
+            integerRTPBits = sFloatingPointAsSWord integerRTP :: SWord 16
+        cgReturn $ integerRNEBits .== 0x6800
+               .&& integerRTPBits .== 0x6801
+               .&& largeRoundTrip .== largeInteger
+               .&& rationalHalf .== 3.5
+               .&& roundedEven .== 2
+               .&& roundedAway .== 3
+               .&& roundedUp   .== 3
+               .&& roundedDown .== 2
+               .&& roundedZero .== 2
+               .&& exactRational .== 7 / 2
+  compileAndRunLibBFGMP dir "arbitraryFloatExactConversions" program "= 1"
+
+-- | Exercise repeated declarations and dependencies in a mixed generated library.
+mixedRepeatedTypeLibrary :: Assertion
+mixedRepeatedTypeLibrary = withSystemTempDirectory "sbv-mixed-repeated-library" $ \dir -> do
+  let configure values = do
+        cgOverwriteFiles True
+        cgSetDriverValues values
+
+      wideAddProgram = do
+        configure [5]
+        value <- cgInput "value" :: SBVCodeGen (SWord 673)
+        cgReturn (value + 1)
+
+      wideXorProgram = do
+        configure [7]
+        value <- cgInput "value" :: SBVCodeGen (SWord 673)
+        cgReturn (value `xor` 3)
+
+      fpDivideProgram = do
+        configure [2, 1, 3]
+        mode  <- cgInput "mode"  :: SBVCodeGen SRoundingMode
+        value <- cgInput "value" :: SBVCodeGen SFPHalf
+        three <- cgInput "three" :: SBVCodeGen SFPHalf
+        cgReturn (fpDiv mode value three)
+
+      fpDivideAgainProgram = do
+        configure [3, 1, 3]
+        mode  <- cgInput "mode"  :: SBVCodeGen SRoundingMode
+        value <- cgInput "value" :: SBVCodeGen SFPHalf
+        three <- cgInput "three" :: SBVCodeGen SFPHalf
+        cgReturn (fpDiv mode value three)
+
+      integerAddProgram = do
+        configure [2 ^ (130 :: Int)]
+        value <- cgInput "value" :: SBVCodeGen SInteger
+        cgReturn (value + 7)
+
+      integerMulProgram = do
+        configure [9]
+        value <- cgInput "value" :: SBVCodeGen SInteger
+        cgReturn (value * 3)
+
+      realDivideProgram = do
+        configure [5]
+        value <- cgInput "value" :: SBVCodeGen SReal
+        cgReturn (value / 3)
+
+      realAddProgram = do
+        configure [2]
+        value <- cgInput "value" :: SBVCodeGen SReal
+        cgReturn (value + 1 / 7)
+
+      components = [ ("wideAdd",       wideAddProgram)
+                   , ("wideXor",       wideXorProgram)
+                   , ("fpDivide",      fpDivideProgram)
+                   , ("fpDivideAgain", fpDivideAgainProgram)
+                   , ("integerAdd",    integerAddProgram)
+                   , ("integerMul",    integerMulProgram)
+                   , ("realDivide",    realDivideProgram)
+                   , ("realAdd",       realAddProgram)
+                   ]
+
+  (_, cfg, bundle) <- compileToCLib' "mixedRepeatedTypeLibrary" components
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  makeOptions <- generatedMakeOptions dir
+  (makeExit, _, makeError) <- readProcessWithExitCode "make" (["-C", dir] ++ makeOptions) ""
+  assertEqual makeError ExitSuccess makeExit
+
+  let driverExecutable = dir </> "mixedRepeatedTypeLibrary_driver"
+  (runExit, stdoutText, runError) <- readProcessWithExitCode driverExecutable [] ""
+  assertEqual runError ExitSuccess runExit
+  mapM_ (assertOutput stdoutText)
+    [ asHex 11 6
+    , asHex 11 4
+    , "0x0000000000003556"
+    , "0x0000000000003555"
+    , show (2 ^ (130 :: Int) + 7 :: Integer)
+    , "27"
+    , "5/3"
+    , "15/7"
+    ]
+
+  makefile <- readFile (dir </> "Makefile")
+  assertBool "Mixed library Makefile lost the LibBF dependency" ("-lbf" `isInfixOf` makefile)
+  assertBool "Mixed library Makefile lost the GMP dependency" ("${GMP_LIBS}" `isInfixOf` makefile)
+ where assertOutput stdoutText fragment =
+         assertBool ("Expected generated library output to contain " ++ fragment ++ ", received:\n" ++ stdoutText) (fragment `isInfixOf` stdoutText)
+
+-- | Exercise archive-only generation with a type shared across translation units.
+repeatedTypeLibraryWithoutDriver :: Assertion
+repeatedTypeLibraryWithoutDriver = withSystemTempDirectory "sbv-repeated-library-no-driver" $ \dir -> do
+  let component operation = do
+        cgOverwriteFiles True
+        cgGenerateDriver False
+        value <- cgInput "value" :: SBVCodeGen (SWord 673)
+        cgReturn (operation value)
+      components = [ ("increment", component (+ 1))
+                   , ("decrement", component (subtract 1))
+                   ]
+
+  (_, cfg, bundle) <- compileToCLib' "repeatedTypeLibraryWithoutDriver" components
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+
+  makeOptions <- generatedMakeOptions dir
+  (makeExit, _, makeError) <- readProcessWithExitCode "make" (["-C", dir] ++ makeOptions) ""
+  assertEqual makeError ExitSuccess makeExit
+  archiveExists <- doesFileExist (dir </> "repeatedTypeLibraryWithoutDriver.a")
+  driverExists  <- doesFileExist (dir </> "repeatedTypeLibraryWithoutDriver_driver.c")
+  assertBool "Generated library archive is missing" archiveExists
+  assertBool "Driver generation was disabled, but a driver was emitted" (not driverExists)
+
+-- | Generate and execute a C program linked to the LibBF bundled with the
+-- Haskell @libBF@ package.
+compileAndRunLibBF :: FilePath -> String -> SBVCodeGen () -> String -> Assertion
+compileAndRunLibBF dir functionName program expected = do
+  (includeDir, archive) <- locateLibBF
+  compileAndRunWith ["-I" ++ includeDir, archive, "-lm"] dir functionName program expected
+
+-- | Generate and execute a C program using both LibBF and GMP.
+compileAndRunLibBFGMP :: FilePath -> String -> SBVCodeGen () -> String -> Assertion
+compileAndRunLibBFGMP dir functionName program expected = do
+  (includeDir, archive) <- locateLibBF
+  (pkgExit, pkgOutput, pkgError) <- readProcessWithExitCode "pkg-config" ["--cflags", "--libs", "gmp"] ""
+  assertEqual pkgError ExitSuccess pkgExit
+  compileAndRunWith (["-I" ++ includeDir, archive, "-lm"] ++ words pkgOutput) dir functionName program expected
+
+-- | Generate, compile, and execute C with additional compiler/linker options.
+-- @SBV_C_TEST_FLAGS@ supplies extra flags for optimization and sanitizer runs.
+compileAndRunWith :: [String] -> FilePath -> String -> SBVCodeGen () -> String -> Assertion
+compileAndRunWith ccOptions dir functionName program expected = do
+  (_, cfg, bundle) <- compileToC' functionName program
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+
+  out <- compileAndRunGenerated ccOptions dir functionName
+  assertBool ("Expected generated output to contain " ++ expected ++ ", received:\n" ++ out) (expected `isInfixOf` out)
+
+-- | Exercise a generated native ABI from an independent caller, linked with
+-- LibBF. Enable dynamic rounding for callers that modify the floating-point
+-- environment; the caller reports failure through its exit status.
+compileAndRunLibBFCaller :: FilePath -> String -> SBVCodeGen () -> String -> Assertion
+compileAndRunLibBFCaller dir functionName program caller = do
+  (includeDir, archive) <- locateLibBF
+  (_, cfg, bundle) <- compileToC' functionName program
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  writeFile (dir </> functionName ++ "_driver.c") caller
+  _ <- compileAndRunGenerated ["-frounding-math", "-I" ++ includeDir, archive, "-lm"] dir functionName
+  pure ()
+
+-- | Compile and run an already rendered program and driver. Honor optional
+-- optimization and sanitizer flags supplied by @SBV_C_TEST_FLAGS@.
+compileAndRunGenerated :: [String] -> FilePath -> String -> IO String
+compileAndRunGenerated ccOptions dir functionName = do
+  let source = dir </> functionName ++ ".c"
+      driver = dir </> functionName ++ "_driver.c"
+      exe    = dir </> functionName ++ "_driver"
+  extraFlags <- maybe [] words <$> lookupEnv "SBV_C_TEST_FLAGS"
+  (ccExit, _, ccErr) <- readProcessWithExitCode "cc" (["-std=c11", "-Wall", "-Werror", source, driver, "-o", exe] ++ extraFlags ++ ccOptions) ""
+  assertEqual ccErr ExitSuccess ccExit
+
+  (runExit, out, runErr) <- readProcessWithExitCode exe [] ""
+  assertEqual runErr ExitSuccess runExit
+  pure out
+
+-- | Render the fixed-limb hexadecimal form printed by generated drivers.
+asHex :: Int -> Integer -> String
+asHex limbCount value = "0x" ++ replicate (16 * limbCount - length h) '0' ++ h
+ where h = showHex value ""
diff --git a/SBVTestSuite/TestSuite/CodeGeneration/ArrayCaptures.hs b/SBVTestSuite/TestSuite/CodeGeneration/ArrayCaptures.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CodeGeneration/ArrayCaptures.hs
@@ -0,0 +1,119 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : TestSuite.CodeGeneration.ArrayCaptures
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Reject unsupported array-lambda captures before emitting C artifacts.
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module TestSuite.CodeGeneration.ArrayCaptures (tests) where
+
+import Control.Exception (ErrorCall, displayException, try)
+import Control.Monad (void)
+import Data.List (isInfixOf)
+import System.Directory (listDirectory)
+import System.IO.Temp (withSystemTempDirectory)
+import Test.Tasty.HUnit (assertBool, assertEqual)
+
+import Data.SBV.Tools.CodeGen
+import Utils.SBVTestFramework
+
+-- | Captures in ordinary and operator-embedded operands must fail clearly,
+-- including in nested callbacks and library components. Existing frontend
+-- restrictions remain in place; closed callbacks remain supported.
+tests :: TestTree
+tests = testGroup "CodeGeneration.ArrayCaptures"
+  [ rejects "direct result capture" captureDiagnostic $ do
+      value <- cgInput "value" :: SBVCodeGen SWord32
+      cgReturn (lambdaArray (const value) :: SArray Word8 Word32)
+  , rejects "arithmetic capture" captureDiagnostic $ do
+      value <- cgInput "value" :: SBVCodeGen SWord32
+      cgReturn (lambdaArray (+ value) :: SArray Word32 Word32)
+  , rejects "managed value capture" captureDiagnostic $ do
+      value <- cgInput "value" :: SBVCodeGen SString
+      cgReturn (lambdaArray (const value) :: SArray Word8 String)
+  , rejects "array descriptor capture" captureDiagnostic $ do
+      value <- cgInput "value" :: SBVCodeGen (SArray Word32 Word32)
+      cgReturn (lambdaArray (readArray value) :: SArray Word32 Word32)
+  , rejects "table entry capture" captureDiagnostic $ do
+      value <- cgInput "value" :: SBVCodeGen SWord32
+      cgReturn (lambdaArray (select [value, 17] 0) :: SArray Word8 Word32)
+  , rejects "table default capture" captureDiagnostic $ do
+      cgPerformRTCs True
+      value <- cgInput "value" :: SBVCodeGen SWord32
+      cgReturn (lambdaArray (select [3, 17] value) :: SArray Word8 Word32)
+  , rejects "unchecked table default capture" captureDiagnostic $ do
+      cgPerformRTCs False
+      value <- cgInput "value" :: SBVCodeGen SWord32
+      cgReturn (lambdaArray (select [3, 17] value) :: SArray Word8 Word32)
+  , rejects "rounding-mode operand capture" captureDiagnostic $ do
+      rounding <- cgInput "rounding" :: SBVCodeGen SRoundingMode
+      cgReturn (lambdaArray (toSFloat rounding) :: SArray Word32 Float)
+  , rejects "capture hidden in nested array" captureDiagnostic $ do
+      value <- cgInput "value" :: SBVCodeGen SWord32
+      cgReturn (lambdaArray (\_ -> lambdaArray (+ value)) :: SArray Word8 (ArrayModel Word32 Word32))
+  , rejects "nested parameter hidden in a rounding-mode operand" captureDiagnostic $
+      cgReturn (lambdaArray (lambdaArray . toSFloat) :: SArray RoundingMode (ArrayModel Word32 Float))
+  , rejects "defined-function parameter hidden in a rounding-mode operand" captureDiagnostic $ do
+      rounding <- cgInput "rounding" :: SBVCodeGen SRoundingMode
+      cgReturn (smtFunction "rounding array" (\mode -> lambdaArray (toSFloat mode) :: SArray Word32 Float) rounding)
+  , rejects "nested parameter capture remains frontend-rejected" "Detected free variables passed to a lambda" $
+      cgReturn (lambdaArray (\outer -> lambdaArray (+ outer)) :: SArray Word32 (ArrayModel Word32 Word32))
+  , rejects "defined-function parameter capture remains frontend-rejected" "Detected free variables passed to a lambda" $ do
+      value <- cgInput "value" :: SBVCodeGen SWord32
+      cgReturn (smtFunction "capturing array" (\offset -> lambdaArray (+ offset) :: SArray Word32 Word32) value)
+  , testCase "library rejects captures without writing earlier components" libraryCapture
+  , testCase "closed nested callbacks with literal constants still compile" closedArrays
+  ]
+
+-- | Stable user-facing diagnostic shared by all C-side capture failures.
+captureDiagnostic :: String
+captureDiagnostic = "Array lambdas that capture outer symbolic values are not supported"
+
+-- | A failed standalone generation must create no files and must not expose
+-- the scheduler's internal missing-assignment error as its capture diagnostic.
+rejects :: String -> String -> SBVCodeGen () -> TestTree
+rejects testName diagnostic program = testCase testName $
+  withSystemTempDirectory "sbv-c-array-capture-rejection" $ \dir -> do
+    result <- try (compileToC (Just dir) "capturingArray" (cgGenerateDriver False >> program)) :: IO (Either ErrorCall ())
+    checkRejection diagnostic result
+    assertEqual "Rejected generation must not create files" [] =<< listDirectory dir
+
+-- | Keep whole-library preflight atomic even when a valid component precedes
+-- the component with an unsupported capture.
+libraryCapture :: Assertion
+libraryCapture = withSystemTempDirectory "sbv-c-array-capture-library" $ \dir -> do
+  let closed = cgGenerateDriver False >> cgReturn (lambdaArray (+ 3) :: SArray Word32 Word32)
+      capturing = do
+        cgGenerateDriver False
+        value <- cgInput "value" :: SBVCodeGen SWord32
+        cgReturn (lambdaArray (+ value) :: SArray Word32 Word32)
+  result <- try (void $ compileToCLib (Just dir) "captureLibrary" [("closedArray", closed), ("capturingArray", capturing)])
+  checkRejection captureDiagnostic result
+  assertEqual "Rejected library must not create any component files" [] =<< listDirectory dir
+
+-- | Check the explicit unsupported boundary instead of accepting any failure.
+checkRejection :: String -> Either ErrorCall () -> Assertion
+checkRejection diagnostic result = case result of
+  Left err -> do
+    let message = displayException err
+    assertBool message (diagnostic `isInfixOf` message)
+    assertBool "Capture diagnostics must not expose an internal scheduling failure"
+               (not ("Missing assignment" `isInfixOf` message))
+  Right () -> assertFailure "Expected generation to reject an array-lambda capture"
+
+-- | Haskell lexical bindings that contain only literal constants do not
+-- require a runtime environment, nor does nesting otherwise closed lambdas.
+closedArrays :: Assertion
+closedArrays = withSystemTempDirectory "sbv-c-closed-array-lambdas" $ \dir -> do
+  compileToC (Just dir) "closedArrays" $ do
+    cgOverwriteFiles True
+    cgGenerateDriver False
+    let offset = literal (3 :: Word32)
+    cgReturn (lambdaArray (\_ -> lambdaArray (+ offset)) :: SArray Word8 (ArrayModel Word32 Word32))
+  assertBool "Closed callbacks still produce C artifacts" . not . null =<< listDirectory dir
diff --git a/SBVTestSuite/TestSuite/CodeGeneration/Boundaries.hs b/SBVTestSuite/TestSuite/CodeGeneration/Boundaries.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CodeGeneration/Boundaries.hs
@@ -0,0 +1,142 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : TestSuite.CodeGeneration.Boundaries
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Executable contracts for deliberately unsupported C-backend features.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE DataKinds             #-}
+{-# LANGUAGE EmptyDataDecls        #-}
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE ScopedTypeVariables   #-}
+{-# LANGUAGE TemplateHaskell       #-}
+{-# LANGUAGE TypeApplications      #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module TestSuite.CodeGeneration.Boundaries (tests) where
+
+import Control.Exception (ErrorCall, displayException, try)
+import Control.Monad (void)
+import Data.List (isInfixOf)
+import System.Directory (listDirectory)
+import System.IO.Temp (withSystemTempDirectory)
+import Test.Tasty.HUnit (assertBool, assertEqual)
+
+import Data.SBV.Internals (AlgRealPoly(..))
+import Data.SBV.Control (SMTOption(..))
+import qualified Data.SBV.List as SL
+import Data.SBV.Tools.CodeGen
+import Utils.SBVTestFramework
+
+-- | An abstract solver sort deliberately lacking a C representation.
+data Opaque
+
+-- | Recursive references hidden inside a by-value tuple cannot have a finite C layout.
+data NestedRecursion = EndRecursion | NestedRecursion (Word8, NestedRecursion)
+
+mkSymbolic [''Opaque, ''NestedRecursion]
+
+-- | Every rejected feature is checked through both public entry points;
+-- library failures must not leave even an earlier, valid component behind.
+tests :: TestTree
+tests = testGroup "CodeGeneration.Boundaries"
+  [ rejects "uninterpreted sort" "uninterpreted sorts" $ do
+      value <- cgInput "value" :: SBVCodeGen (SBV Opaque)
+      cgReturn value
+  , rejects "nested recursive ADT" "Recursive ADT references nested inside composite fields" $ do
+      value <- cgInput "value" :: SBVCodeGen (SBV NestedRecursion)
+      cgReturn value
+  , rejects "solver option" "SMT solver options have no executable C semantics" $ do
+      setOption (ProduceAssertions True)
+      cgReturn sTrue
+  , rejects "solver option through cgSym" "SMT solver options have no executable C semantics" $ do
+      cgSym $ setOption (ProduceAssertions True)
+      cgReturn sTrue
+  , rejects "nested uninterpreted sort" "uninterpreted sorts" $ do
+      value <- cgInput "value" :: SBVCodeGen (SList (Maybe Opaque))
+      cgReturn value
+  , rejects "finite quantifier" "quantified" $ do
+      value <- cgInput "value" :: SBVCodeGen SBool
+      cgReturn (quantifiedBool (\(Forall b) -> b .|| value))
+  , rejects "infinite quantifier" "quantified" $ do
+      value <- cgInput "value" :: SBVCodeGen SInteger
+      cgReturn (quantifiedBool (\(Forall n) -> n .>= value))
+  , rejects "quantifier in private function" "quantified" $ do
+      value <- cgInput "value" :: SBVCodeGen SInteger
+      cgReturn (smtFunction "quantifiedFunction" (\v -> quantifiedBool (\(Forall n) -> n .>= v)) value)
+  , rejects "quantifier in array lambda" "quantified" $
+      cgReturn (lambdaArray (\v -> quantifiedBool (\(Forall n) -> n .>= v)) :: SArray Integer Bool)
+  , rejects "special relation" "special relations" $
+      cgReturn (isPartialOrder "order" (uncurry ((.<=) :: SInteger -> SInteger -> SBool)))
+  , rejects "soft constraint" "Soft constraints" $ do
+      value <- cgInput "value" :: SBVCodeGen SBool
+      softConstrain value
+      cgReturn value
+  , rejects "SMT-only constraint attribute" "Constraint attributes: :weight" $ do
+      value <- cgInput "value" :: SBVCodeGen SBool
+      constrainWithAttribute [(":weight", "2")] value
+      cgReturn value
+  , rejects "minimize" "Optimization objectives require a solver" $ do
+      value <- cgInput "value" :: SBVCodeGen SInteger
+      cgSym $ minimize "minimum" value
+      cgReturn value
+  , rejects "maximize" "Optimization objectives require a solver" $ do
+      value <- cgInput "value" :: SBVCodeGen SWord8
+      cgSym $ maximize "maximum" value
+      cgReturn value
+  , rejects "implicit higher-order capture" "Defined functions with implicit captures" $ do
+      offset <- cgInput "offset" :: SBVCodeGen SInteger
+      values <- cgInput "values" :: SBVCodeGen (SList Integer)
+      cgReturn (SL.map (+ offset) values)
+  , rejects "implicit managed higher-order capture" "Defined functions with implicit captures" $ do
+      offset <- cgInput "offset" :: SBVCodeGen SString
+      values <- cgInput "values" :: SBVCodeGen (SList String)
+      cgReturn (SL.map (.== offset) values)
+  , rejects "penalized assertion" "Optimization objectives require a solver" $ do
+      value <- cgInput "value" :: SBVCodeGen SBool
+      cgSym $ assertWithPenalty "penalty" value DefaultPenalty
+      cgReturn value
+  , rejects "algebraic real literal" "Algebraic SReal literals" $ cgReturn (literal algebraic)
+  , rejects "nested algebraic real literal" "Algebraic SReal literals" $ cgReturn (literal [algebraic])
+  , rejects "mapped algebraic real literal" "Algebraic SReal literals" $ cgSRealType CgDouble >> cgReturn (literal algebraic)
+  , rejects "inexact real literal" "Inexact SReal literals" $ cgReturn (literal (AlgRational False (1 / 3)))
+  , rejects "exact transcendental" "exact GMP-rational SReal representation cannot represent" $ do
+      value <- cgInput "value" :: SBVCodeGen SReal
+      cgReturn (sin value)
+  , rejects "private exact transcendental" "exact GMP-rational SReal representation cannot represent" $ do
+      value <- cgInput "value" :: SBVCodeGen SReal
+      cgReturn (smtFunction "exactSine" sin value)
+  , rejects "sparse infinite-domain equality" "cannot enumerate key domain" $ do
+      value <- cgInput "value" :: SBVCodeGen SWord8
+      let base = constArray 0 :: SArray Integer Word8
+      cgReturn (writeArray base 1 value .== writeArray base 2 value)
+  ]
+
+-- | The positive square root of two, represented without an approximation.
+algebraic :: AlgReal
+algebraic = AlgPolyRoot (2, AlgRealPoly [(1, 2), (-2, 0)]) Nothing
+
+-- | Check an intentional diagnostic, not just any exception, and ensure that
+-- validation completes before standalone or library output is written.
+rejects :: String -> String -> SBVCodeGen () -> TestTree
+rejects testName diagnostic program = testGroup testName
+  [ testCase mode $ withSystemTempDirectory "sbv-c-boundary" $ \dir -> do
+      let prepare body = cgGenerateDriver False >> cgOverwriteFiles True >> body
+          action | library = void $ compileToCLib (Just dir) "rejectedLibrary"
+                               [("validComponent", prepare (cgReturn sTrue)), ("rejectedComponent", prepare program)]
+                 | True    = compileToC (Just dir) "rejectedComponent" (prepare program)
+      result <- try action :: IO (Either ErrorCall ())
+      case result of
+        Left exception -> do
+          let message = displayException exception
+          assertBool message (diagnostic `isInfixOf` message)
+          assertBool message (not (any (`isInfixOf` message) ["Unexpected:", "Missing assignment", "Impossible happened"]))
+        Right () -> assertFailure "Expected an explicit unsupported-feature diagnostic"
+      assertEqual "Rejected generation must not write any files" [] =<< listDirectory dir
+  | (mode, library) <- [("standalone", False), ("library", True)]
+  ]
diff --git a/SBVTestSuite/TestSuite/CodeGeneration/CgTests.hs b/SBVTestSuite/TestSuite/CodeGeneration/CgTests.hs
--- a/SBVTestSuite/TestSuite/CodeGeneration/CgTests.hs
+++ b/SBVTestSuite/TestSuite/CodeGeneration/CgTests.hs
@@ -9,37 +9,5074 @@
 -- Test suite for code-generation features
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE ScopedTypeVariables #-}
-
-{-# OPTIONS_GHC -Wall -Werror #-}
-
-module TestSuite.CodeGeneration.CgTests(tests) where
-
-import Data.SBV.Internals
-
-import Utils.SBVTestFramework
-
--- Test suite
-tests :: TestTree
-tests = testGroup "CodeGeneration.CgTests" [
-   goldenVsStringShow "selChecked"   $ genSelect True  "selChecked"
- , goldenVsStringShow "selUnchecked" $ genSelect False "selUnChecked"
- , goldenVsStringShow "codeGen1"       foo
- ]
- where thd (_, _, r) = r
-
-       genSelect b n = thd <$> compileToC' n (do
-                         cgSetDriverValues [65]
-                         cgPerformRTCs b
-                         let sel :: SWord8 -> SWord8
-                             sel x = select [1, x+2] 3 x
-                         x <- cgInput "x"
-                         cgReturn $ sel x)
-       foo = thd <$> compileToC' "foo" (do
-                        cgSetDriverValues $ repeat 0
-                        (x::SInt16)    <- cgInput "x"
-                        (ys::[SInt64]) <- cgInputArr 45 "xArr"
-                        cgOutput "z" (5 :: SWord16)
-                        cgOutputArr "zArr" (replicate 7 (x+1))
-                        cgOutputArr "yArr" ys
-                        cgReturn (x*2))
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE FlexibleInstances   #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module TestSuite.CodeGeneration.CgTests(tests) where
+
+import Control.Exception (ErrorCall, displayException, evaluate, try)
+import Control.DeepSeq (force)
+import Control.Monad (forM, forM_, unless, void, when)
+import qualified Data.Bifunctor as B
+import Data.List (isInfixOf)
+import Data.Proxy (Proxy(..))
+import Data.SBV.Internals
+import Data.SBV.Tools.CodeGen (compileToC, compileToCLib)
+import qualified Data.SBV.Char as SC
+import qualified Data.SBV.List as SL
+import qualified Data.SBV.Set as SS
+import Data.SBV.Tuple (tuple, untuple)
+import qualified Data.SBV.Tools.CodeGen.Legacy as PublicLegacy
+
+import System.Directory (listDirectory)
+import System.Exit      (ExitCode(..))
+import System.FilePath  ((</>))
+import System.IO.Temp   (withSystemTempDirectory)
+import System.Process   (readProcessWithExitCode)
+
+import Test.Tasty.HUnit (assertBool, assertEqual)
+
+import Utils.SBVTestFramework
+import Utils.CCodeGen (generatedMakeOptions)
+
+-- | A non-recursive, parameterized sum type used to exercise C tagged-union
+-- generation with nullary, unary, and product constructors.
+data CodeGenADT a = CGEmpty
+                  | CGOne a
+                  | CGPair a Word16
+                  deriving Show
+
+-- | A finite enumeration used to check that constructor order is preserved by
+-- the C tag representation.
+data CodeGenEnum = CGRed | CGGreen | CGBlue deriving (Eq, Ord, Show)
+
+-- | An acyclic parameterized ADT reference used to exercise 'KApp'
+-- resolution and dependency-ordered C declarations.
+data CodeGenEnvelope a = CGNoEnvelope | CGEnvelope (CodeGenADT a) deriving Show
+
+-- | A recursive type used to verify the current C ABI boundary.
+data CodeGenTree = CGLeaf Word8 | CGNode CodeGenTree CodeGenTree deriving (Eq, Ord, Show)
+
+-- | An acyclic wrapper around a recursive value, used to check transitive
+-- ownership without changing its embedded by-value layout.
+newtype CodeGenForest = CGForest CodeGenTree deriving Show
+
+-- | The even layer of a mutually recursive pair used to exercise C forward
+-- declarations and cross-type ownership helpers.
+data CodeGenEven = CGEvenEnd Word8 | CGEvenStep CodeGenOdd deriving Show
+
+-- | The odd layer of the mutually recursive code-generation test pair.
+newtype CodeGenOdd = CGOddStep CodeGenEven deriving Show
+
+-- | A recursive type with no finite inhabitant, used to check generated-driver
+-- diagnostics.
+newtype CodeGenLoop = CGLoop CodeGenLoop deriving Show
+
+-- | A managed aggregate used to exercise direct and tuple-nested collection
+-- fields in generated C ADTs.
+data CodeGenCollections = CGNoCollections
+                        | CGCollections [Integer] (RCSet Rational) ([Integer], RCSet Rational)
+                        deriving Show
+
+-- | A managed aggregate used to exercise native-width collection ownership
+-- without relying on exact-element storage to select the owned ABI.
+data CodeGenNativeCollections = CGNativeCollections [Word16] (RCSet Word16) deriving Show
+
+-- | A managed aggregate used to exercise direct text fields and collections
+-- whose elements are strings.
+data CodeGenText = CGText String [String] (RCSet String) deriving Show
+
+-- | An aggregate used to exercise retained array fields in generated C ADTs.
+data CodeGenArrayBox = CGArrayBox (ArrayModel Word8 Word32) Word8 deriving Show
+
+-- | An ADT that hides an array-owning ADT behind an intermediate tuple.
+newtype CodeGenArrayEnvelope = CGArrayEnvelope (CodeGenArrayBox, Word16) deriving Show
+
+-- | A recursive managed aggregate whose leaf owns exact-element collections.
+data CodeGenCollectionTree = CGCollectionLeaf [Integer] (RCSet Rational)
+                           | CGCollectionBranch CodeGenCollectionTree
+                           deriving Show
+
+-- | A recursive type whose spelling differs from 'CodeGenCASE' only in case.
+data CodeGenCase = CGCaseLeaf Word8 | CGCaseNext CodeGenCase deriving (Eq, Ord, Show)
+
+-- | The case-sensitive companion used to expose collisions in generated
+-- declaration guards, constructor tags, and transitive collection helpers.
+data CodeGenCASE = CGCASELeaf Word8 | CGCASENext CodeGenCASE deriving (Eq, Ord, Show)
+
+-- | Generate the symbolic interfaces for the code-generation ADTs.
+mkSymbolic [''CodeGenADT, ''CodeGenEnum, ''CodeGenEnvelope, ''CodeGenTree, ''CodeGenForest, ''CodeGenEven, ''CodeGenOdd, ''CodeGenLoop, ''CodeGenCollections, ''CodeGenNativeCollections, ''CodeGenText, ''CodeGenArrayBox, ''CodeGenArrayEnvelope, ''CodeGenCollectionTree, ''CodeGenCase, ''CodeGenCASE]
+
+-- | Code-generation tests.
+tests :: TestTree
+tests = testGroup "CodeGeneration.CgTests"
+  [ goldenVsStringShow "selChecked"   $ genSelect True  "selChecked"
+  , goldenVsStringShow "selUnchecked" $ genSelect False "selUnChecked"
+  , goldenVsStringShow "codeGen1"       foo
+  , testCase "compile through the public legacy facade" legacyPublicFacade
+  , testCase "execute guarded pseudo-Boolean reductions in functions and array lambdas" scopedPseudoBoolean
+  , testCase "floor long doubles inside functions and array lambdas" scopedMappedRealFloor
+  , testCase "collect C runtime requirements" dependencyRequirements
+  , testCase "escape assertion messages in generated C" escapedAssertionMessages
+  , escapedValueLabels
+  , testCase "execute IEEE native floating-point remainders" nativeFloatingRemainders
+  , testCase "declare rounding modes in nested collections" collectionRoundingModes
+  , testCase "relink library drivers after component changes" libraryDriverDependencies
+  , arrayCollectionComparisons
+  , testCase "preserve external prototypes in libraries" libraryExternalPrototypes
+  , testCase "reject empty or conflicting libraries before rendering" libraryValidation
+  , testCase "terminate on failed library preconditions and assertions" libraryRuntimeFailures
+  , testCase "reject invalid and reserved public C names before rendering" publicCNameValidation
+  , testCase "preserve public C names without local collisions" privateCBindings
+  , testCase "preserve case through ADTs and structural type guards" caseSensitiveCKinds
+  , testCase "frame nested array key and value type names" structuralCNameFraming
+  , testCase "honor ownership across independent C library calls" libraryOwnershipContract
+  , testCase "compare finite ADT set universes" finiteADTSetUniverses
+  , testCase "compile exact symbolic rationals" exactSymbolicRationals
+  , testCase "compile rationals with mapped integers" mappedIntegerRationals
+  , testCase "compile divisibility with mapped integers" mappedIntegerDivisibility
+  , testCase "compile mapped real non-linear operations" mappedRealNonLinearOperations
+  , testCase "compile mapped integer exponentiation" mappedIntegerExponentiation
+  , testCase "execute mapped integer arithmetic at every native width" mappedIntegerArithmetic
+  , testCase "reject non-linear exact real operations" exactRealNonLinearDiagnostic
+  , testCase "compile repeated exact rationals into a library" exactRationalLibrary
+  , testCase "compile and execute persistent arrays" persistentArrays
+  , testCase "compare finite arrays including callback and defined-function values" finiteArrayEquality
+  , testCase "configure finite array equality limits" finiteArrayEqualityLimits
+  , testCase "enumerate scalar and aggregate finite array keys" finiteArrayKeyKinds
+  , testCase "observe finite array callback coverage and short circuiting" finiteArrayCallbacks
+  , testCase "reject unsupported finite array equality domains before rendering" finiteArrayRejections
+  , testCase "compare managed and floating finite array values" finiteArrayValues
+  , testCase "compile and execute nested persistent arrays" nestedPersistentArrays
+  , testCase "compile and execute arrays stored in tuples" tupleStoredArrays
+  , testCase "compile and execute arrays stored in ADTs" adtStoredArrays
+  , testCase "compile and execute arrays stored in lists" listStoredArrays
+  , testCase "initialize aggregate inputs containing arrays" aggregateArrayInputs
+  , testCase "initialize transitively nested array inputs" transitiveAggregateArrayInputs
+  , testCase "preserve native floating-point array-key equality" nativeFloatArrayKeys
+  , testCase "compile repeated array types into a library" persistentArrayLibrary
+  , testCase "compile and execute a callback-backed array input" callbackArrayInput
+  , testCase "compile and execute a structured lambda array" structuredLambdaArray
+  , testCase "compile managed structured lambda arrays" managedStructuredLambdaArrays
+  , testCase "retain an escaping managed lambda array" escapingManagedLambdaArray
+  , testCase "call defined functions inside array lambdas" definedFunctionsInsideArrayLambdas
+  , testCase "call defined functions from library array lambdas" definedFunctionArrayLambdaLibrary
+  , testCase "return arrays from structured array lambdas" arrayValuedLambdaResults
+  , testCase "return array-valued lambdas from a library" arrayValuedLambdaLibrary
+  , testCase "compile nested structured array lambdas" nestedStructuredArrayLambdas
+  , testCase "compile nested structured lambdas in a library" nestedStructuredArrayLambdaLibrary
+  , testCase "compile and execute structured lambda tables" structuredLambdaTables
+  , testCase "compile and execute a defined SBV function" definedSBVFunction
+  , testCase "compose acyclic defined SBV functions" composedDefinedSBVFunctions
+  , testCase "guard inactive branches in acyclic defined functions" guardedAcyclicDefinedFunctions
+  , testCase "guard inactive branches in entry points" (guardedProgramEvaluation False)
+  , testCase "guard inactive branches in array lambdas" (guardedProgramEvaluation True)
+  , testCase "retain checks as demand-driven evaluation roots" guardedRuntimeChecks
+  , testCase "preserve sharing across guarded evaluation diamonds" guardedEvaluationSharing
+  , testCase "evaluate shared external calls at most once on each path" guardedExternalSharing
+  , testCase "force and execute a deep memoized chain beneath nested branches" deepGuardedSharing
+  , testCase "reuse the full ADT registry for nested and leaf-only literals" sharedADTConstantRegistry
+  , testCase "register ADT dependencies without symbolic ADT inputs" literalADTRegistration
+  , testCase "straight-line sharing needs no runtime readiness flags" straightLineSharing
+  , testCase "text arena rejects allocation-size overflow" textAllocationOverflow
+  , testCase "shared arenas preserve allocation and cleanup contracts" ownershipArenaChecks
+  , testCase "empty concatenation borrows internally and owns outputs" emptyConcatenation
+  , testCase "original bundle header patterns cover both backends" compatibleHeaderPatterns
+  , testCase "merged configuration describes artifacts and protects existing files" mergedConfiguration
+  , testCase "reject excess-precision floating-point compilation" excessFloatingPrecision
+  , testCase "honor linker overrides, ignored assertions, and nonreserved macro prefixes" reviewedBuildOptions
+  , testCase "remove all matching elements from borrowed duplicate sets" borrowedDuplicateRemoval
+  , testCase "guard unselected finite-table entries and defaults" guardedTableEvaluation
+  , testCase "check wide and exact indices before guarded table selection" guardedTableIndices
+  , testCase "compile structural defined SBV functions" structuralDefinedSBVFunctions
+  , testCase "compile managed scalar defined SBV functions" managedScalarDefinedSBVFunctions
+  , testCase "compile collection defined SBV functions" collectionDefinedSBVFunctions
+  , testCase "compile persistent-array defined SBV functions" persistentArrayDefinedSBVFunctions
+  , testCase "compile owned-ADT defined SBV functions" ownedADTDefinedSBVFunctions
+  , testCase "compile recursive defined SBV functions" recursiveDefinedSBVFunctions
+  , testCase "compile recursive defined SBV functions in a library" recursiveDefinedSBVFunctionLibrary
+  , testCase "compile recursive persistent-array functions" recursivePersistentArrayFunctions
+  , testCase "compile recursive ADT functions" recursiveADTDefinedSBVFunctions
+  , testCase "compile recursive ADT functions in a library" recursiveADTDefinedSBVFunctionLibrary
+  , testCase "compile firstified higher-order list functions" higherOrderListFunctions
+  , testCase "compile higher-order list functions in a library" higherOrderListFunctionLibrary
+  , testCase "compile explicit hard constraints" explicitHardConstraints
+  , testCase "reject solver-only constraint features" unsupportedConstraintFeatures
+  , testCase "return a non-atomic value group" nonAtomicReturnGroup
+  , testCase "return multiple value groups" multipleReturnGroups
+  , testCase "return managed non-atomic value groups" managedReturnGroups
+  , testCase "return grouped values from a library" groupedReturnLibrary
+  , testCase "borrow symbolic-array input groups" (groupedArrayInputs False)
+  , testCase "borrow symbolic-array input groups in a library" (groupedArrayInputs True)
+  , testCase "retain grouped callback inputs across independent library calls" groupedArrayInputOwnership
+  , testCase "initialize and release managed input groups" (groupedManagedInputs False)
+  , testCase "share driver initialization for mixed aggregate fields" sharedDriverInitialization
+  , testCase "pair collection driver cleanup with storage selection" collectionDriverStorageModes
+  , testCase "initialize and release managed input groups in a library" (groupedManagedInputs True)
+  , testCase "compile and execute a free array with a C definition" definedFreeArray
+  , testCase "return and output owned arrays" ownedArrayResults
+  , testCase "retain an escaping callback array" escapingCallbackArray
+  , testCase "compile arrays with managed aggregate fields" managedAggregateArrays
+  , testCase "return managed aggregate arrays from a library" managedAggregateArrayLibrary
+  , testCase "compile managed aggregate lookup tables" managedAggregateTables
+  , testCase "compile array-valued lookup tables" (arrayValuedTables False)
+  , testCase "retain ready array-valued lookup tables" (arrayValuedTables True)
+  , testCase "return managed table values from a library" managedAggregateTableLibrary
+  , testCase "compile and execute structural tuples" structuralTuples
+  , testCase "compile repeated tuple types into a library" structuralTupleLibrary
+  , testCase "compile and execute tuples containing strings" ownedTextTuples
+  , testCase "return string tuples from a generated library" ownedTextTupleLibrary
+  , testCase "compile and execute tuples containing collections" ownedCollectionTuples
+  , testCase "return collection tuples from a generated library" ownedCollectionTupleLibrary
+  , testCase "compile tuple-valued symbolic collections" tupleValuedCollections
+  , testCase "return tuple-valued collections from a library" tupleValuedCollectionLibrary
+  , testCase "compile managed tuple-valued collections" managedTupleValuedCollections
+  , testCase "return managed tuple-valued collections from a library" managedTupleValuedCollectionLibrary
+  , testCase "compile string-valued collections and text ADTs" textAggregateCollections
+  , testCase "return text ADTs from a library" textAggregateLibrary
+  , testCase "compile directly nested collections" directlyNestedCollections
+  , testCase "return nested collections from a library" directlyNestedCollectionLibrary
+  , testCase "compile ADT-valued collections" adtValuedCollections
+  , testCase "return ADT-valued collections from a library" adtValuedCollectionLibrary
+  , testCase "compile and execute characters and strings" characterStrings
+  , testCase "compile strings with mapped integers" mappedIntegerStrings
+  , testCase "return owned strings from a generated library" ownedStringLibrary
+  , testCase "compile and execute symbolic lists" symbolicLists
+  , testCase "compile arbitrary-width symbolic lists" wideSymbolicLists
+  , testCase "compile arbitrary floating-point symbolic lists" arbitraryFloatLists
+  , testCase "preserve native floating-point list equality" nativeFloatLists
+  , testCase "compile lists with mapped numeric elements" mappedNumericLists
+  , testCase "return owned lists from a generated library" ownedListLibrary
+  , testCase "compile lists of exact GMP values" exactGMPLists
+  , testCase "compile and execute symbolic sets" symbolicSets
+  , testCase "compare finite and cofinite Boolean sets" finiteUniverseSets
+  , testCase "compile arbitrary-width symbolic sets" wideSymbolicSets
+  , testCase "compile character symbolic sets" characterSets
+  , testCase "compile arbitrary floating-point symbolic sets" arbitraryFloatSets
+  , testCase "preserve native floating-point set equality" nativeFloatSets
+  , testCase "compile sets with mapped numeric elements" mappedNumericSets
+  , testCase "return owned sets from a generated library" ownedSetLibrary
+  , testCase "compile sets of exact GMP values" exactGMPSets
+  , testCase "compile and execute non-recursive ADTs" nonRecursiveADTs
+  , testCase "compile and execute nested ADTs" nestedADTs
+  , testCase "compile repeated ADT types into a library" nonRecursiveADTLibrary
+  , testCase "compile ADTs containing managed collections" collectionADTs
+  , testCase "compile recursive ADTs containing collections" recursiveCollectionADTs
+  , testCase "return collection ADTs from a generated library" collectionADTLibrary
+  , testCase "preserve ADT aggregate equality" adtAggregateEquality
+  , testCase "compile and execute recursive ADTs" recursiveADTs
+  , testCase "embed recursive ADTs by value" wrappedRecursiveADTs
+  , testCase "compile and execute mutually recursive ADTs" mutuallyRecursiveADTs
+  , testCase "compile repeated recursive ADTs into a library" recursiveADTLibrary
+  , testCase "report recursive ADTs without finite samples" uninhabitedRecursiveADT
+  ]
+ where thd (_, _, r) = r
+
+       genSelect b n = thd <$> compileToC' n (do
+                         cgSetDriverValues [65]
+                         cgPerformRTCs b
+                         let sel :: SWord8 -> SWord8
+                             sel x = select [1, x+2] 3 x
+                         x <- cgInput "x"
+                         cgReturn $ sel x)
+       foo = thd <$> compileToC' "foo" fooProgram
+
+       fooProgram = do
+                        cgSetDriverValues $ repeat 0
+                        (x::SInt16)    <- cgInput "x"
+                        (ys::[SInt64]) <- cgInputArr 45 "xArr"
+                        cgOutput "z" (5 :: SWord16)
+                        cgOutputArr "zArr" (replicate 7 (x+1))
+                        cgOutputArr "yArr" ys
+                        cgReturn (x*2)
+
+-- | Preserve diagnostic text literally, both in C comments and as a printf
+-- argument, including characters that could otherwise alter the generated C.
+escapedAssertionMessages :: Assertion
+escapedAssertionMessages = withSystemTempDirectory "sbv-assertion-escaping" $ \dir -> do
+  let message = "must be \"small\"; 100% %n */\n\\\n??/"
+  compileToC (Just dir) "escapedAssertion" $ do
+    cgOverwriteFiles True
+    cgSetDriverValues [7]
+    value <- cgInput "value" :: SBVCodeGen SWord8
+    cgReturn (sAssert Nothing message (value .< 5) value)
+  makeOptions <- generatedMakeOptions dir
+  (makeExit, _, makeError) <- readProcessWithExitCode "make" (["-C", dir] ++ makeOptions) ""
+  assertEqual makeError ExitSuccess makeExit
+  (runExit, _, runError) <- readProcessWithExitCode (dir </> "escapedAssertion_driver") [] ""
+  assertBool "Expected the violated assertion to terminate the driver" (runExit /= ExitSuccess)
+  assertBool ("Assertion text was changed: " ++ runError) (("ASSERTION FAILED: " ++ message) `isInfixOf` runError)
+
+-- | Labels are semantic no-ops even when their text contains C statements,
+-- nested comment markers, preprocessing splices, trigraphs, or control bytes.
+-- Exercise scalar, tuple, acyclic/recursive ADT, and persistent-array labels in
+-- entry points, private functions, and closed lambdas, including static libraries.
+escapedValueLabels :: TestTree
+escapedValueLabels = testGroup "escaped C labels"
+  [ testCase (form ++ "/" ++ scopeName ++ "/" ++ sampleName) (check (library, scope, message))
+  | (form, library) <- [("program", False), ("library", True)]
+  , (scopeName, scope) <- [("entry", 0 :: Int), ("function", 1), ("array lambda", 2)]
+  , (sampleName, message) <- messages
+  ]
+ where messages = [ ("statements", "*/; abort(); /*")
+                  , ("preprocessing", "nested /* comment; \\\n??/\n*/")
+                  , ("control characters", "Unicode \955, NUL \0, CR \r, tab \t and control \SOH")
+                  ]
+
+       check (library, scope, message) = withSystemTempDirectory "sbv-c-label-escaping" $ \dir -> do
+         let functionName = "escapedLabels"
+             evaluateValue :: SWord8 -> SBool
+             evaluateValue value =
+               let annotate :: SymVal a => SBV a -> SBV a
+                   annotate = label message
+                   (firstField, secondField) = untuple (annotate (tuple (value, value + 1)))
+                   tagged = annotate (sCGOne value)
+                   tree   = annotate (sCGNode (sCGLeaf value) (sCGLeaf (value + 1)))
+                   array  = annotate (constArray value :: SArray Word8 Word8)
+               in sAnd [ annotate value .== value
+                       , firstField .== value
+                       , secondField .== value + 1
+                       , getCGOne_1 tagged .== value
+                       , getCGLeaf_1 (getCGNode_1 tree) .== value
+                       , readArray array value .== value
+                       ]
+             evaluateScoped value = case scope of
+               0 -> evaluateValue value
+               1 -> smtFunction "C escaped labels" evaluateValue value
+               _ -> readArray (lambdaArray evaluateValue) value
+             program = do
+               cgOverwriteFiles True
+               cgSetDriverValues [7]
+               value <- cgInput "value"
+               cgReturn (evaluateScoped value)
+         (_, cfg, bundle) <- if library
+                               then compileToCLib' functionName [("labelComponent", program)]
+                               else compileToC' functionName ((:[]) <$> program)
+         renderCgPgmBundle (Just dir) (cfg, bundle)
+         outputText <- compileAndRunGenerated dir functionName
+         assertBool outputText (") = 1" `isInfixOf` outputText)
+
+-- | Compare executed native remainders against constant SBV evaluation,
+-- including quotient ties, negative operands, and a negative divisor.
+nativeFloatingRemainders :: Assertion
+nativeFloatingRemainders = mapM_ check [(7, 4), (6, 4), (-7, 4), (7, -4)]
+ where check (left, right) = withSystemTempDirectory "sbv-native-remainder" $ \dir -> do
+         let program = do
+               cgOverwriteFiles True
+               cgSetDriverValues [left, right, left, right]
+               leftFloat   <- cgInput "leftFloat"   :: SBVCodeGen SFloat
+               rightFloat  <- cgInput "rightFloat"  :: SBVCodeGen SFloat
+               leftDouble  <- cgInput "leftDouble"  :: SBVCodeGen SDouble
+               rightDouble <- cgInput "rightDouble" :: SBVCodeGen SDouble
+               let expectedFloat  = fpRem (fromInteger left) (fromInteger right) :: SFloat
+                   expectedDouble = fpRem (fromInteger left) (fromInteger right) :: SDouble
+               cgReturn ((fpRem leftFloat rightFloat .== expectedFloat) .&& (fpRem leftDouble rightDouble .== expectedDouble))
+         outputText <- compileProgramAndRunGenerated dir "nativeRemainder" program
+         assertBool ("Incorrect native remainder: " ++ outputText) ("= 1" `isInfixOf` outputText)
+
+-- | Equality observes every key, including a mismatch at the last key. The
+-- same helper is available inside defined functions and retained lambdas.
+finiteArrayEquality :: Assertion
+finiteArrayEquality = mapM_ check [(library, identical) | library <- [False, True], identical <- [False, True]]
+ where check (library, identical) = withSystemTempDirectory "sbv-finite-array-equality" $ \dir -> do
+         let functionName = "finiteArrayEquality"
+             program = do
+               cgOverwriteFiles True
+               cgSetDriverValues [3, if identical then 3 else 4]
+               left  <- cgInput "left"  :: SBVCodeGen (SArray Word8 Word32)
+               right <- cgInput "right" :: SBVCodeGen (SArray Word8 Word32)
+               let equalArrays = smtFunction "C finite array equality" ((.==) :: SArray Word8 Word32 -> SArray Word8 Word32 -> SBool)
+                   changed     = writeArray left 255 (readArray left 255 + 1)
+                   another     = writeArray left 255 (readArray left 255 + 2)
+                   callback    = lambdaArray (\key -> (constArray key :: SArray Bool Bool) .== constArray sTrue) :: SArray Bool Bool
+               cgReturn $ sAnd [ (left .== right) .== literal identical
+                               , equalArrays left right .== literal identical
+                               , left ./= changed
+                               , distinct [left, changed, another]
+                               , (left .=== right) .== literal identical
+                               , readArray callback sTrue
+                               , sNot (readArray callback sFalse)
+                               ]
+         (_, cfg, bundle) <- if library
+                               then compileToCLib' functionName [("equalityComponent", program)]
+                               else compileToC' functionName ((:[]) <$> program)
+         renderCgPgmBundle (Just dir) (cfg, bundle)
+         outputText <- compileAndRunGenerated dir functionName
+         assertBool outputText (") = 1" `isInfixOf` outputText)
+
+-- | The limit rejects excessive work during generation, can be raised to
+-- admit a 16-bit key domain, and can be set to zero to disable enumeration.
+finiteArrayEqualityLimits :: Assertion
+finiteArrayEqualityLimits = do
+  let program limit = do
+        cgOverwriteFiles True
+        cgSetDriverValues [7, 7]
+        mapM_ cgArrayEqualityLimit limit
+        left  <- cgInput "left"  :: SBVCodeGen (SArray Word16 Word8)
+        right <- cgInput "right" :: SBVCodeGen (SArray Word16 Word8)
+        cgReturn (left .== right)
+  mapM_ (\limit -> do
+    result <- try (do (_, _, bundle) <- compileToC' "limitedEquality" (program limit)
+                      evaluate (length (show bundle))) :: IO (Either ErrorCall Int)
+    case result of
+      Left exception -> assertBool (displayException exception) ("cgArrayEqualityLimit" `isInfixOf` displayException exception)
+      Right _        -> assertFailure "Expected the array equality limit to reject generation") [Nothing, Just 0, Just (-1)]
+  withSystemTempDirectory "sbv-configured-array-equality" $ \dir -> do
+    outputText <- compileProgramAndRunGenerated dir "configuredEquality" (program (Just 65536))
+    sourceText <- readFile (dir </> "configuredEquality.c")
+    assertBool outputText (") = 1" `isInfixOf` outputText)
+    assertBool "Equality must use a compact loop, not an unrolled key table" (length sourceText < 50000)
+
+-- | Enumerate signed bit patterns, sub-native bit-vectors, sums, products,
+-- and rounding modes without relying on the example driver's sample keys.
+finiteArrayKeyKinds :: Assertion
+finiteArrayKeyKinds = withSystemTempDirectory "sbv-finite-array-key-kinds" $ \dir -> do
+  let pair :: forall key. SymVal key => Proxy key -> String -> SBVCodeGen SBool
+      pair _ prefix = do
+        left  <- cgInput (prefix ++ "Left")  :: SBVCodeGen (SArray key Word8)
+        right <- cgInput (prefix ++ "Right") :: SBVCodeGen (SArray key Word8)
+        pure (left .=== right)
+      program = do
+        cgOverwriteFiles True
+        cgSetDriverValues (repeat 3)
+        results <- sequence [ pair (Proxy @Bool) "bool"
+                            , pair (Proxy @Int8) "signed"
+                            , pair (Proxy @(WordN 1)) "bit"
+                            , pair (Proxy @(IntN 1)) "signedBit"
+                            , pair (Proxy @(WordN 5)) "wide"
+                            , pair (Proxy @(IntN 5)) "signedWide"
+                            , pair (Proxy @(Bool, WordN 2)) "tuple"
+                            , pair (Proxy @(Maybe Bool)) "maybe"
+                            , pair (Proxy @(Either Bool (WordN 2))) "either"
+                            , pair (Proxy @CodeGenEnum) "enum"
+                            , pair (Proxy @RoundingMode) "rounding"
+                            , pair (Proxy @(FloatingPoint 2 3)) "tinyFloat"
+                            , pair (Proxy @()) "unit"
+                            ]
+        cgReturn (sAnd results)
+  outputText <- compileProgramAndRunGenerated dir "finiteArrayKeys" program
+  assertBool outputText (") = 1" `isInfixOf` outputText)
+
+-- | Exercise actual C callbacks, counting complete enumeration and early
+-- mismatches. Tiny floats cover every object exactly once, including both
+-- zeros and a single NaN, and library components retain independent limits.
+finiteArrayCallbacks :: Assertion
+finiteArrayCallbacks = withSystemTempDirectory "sbv-finite-array-callbacks" $ \dir -> do
+  let component :: forall key. SymVal key => Proxy key -> Integer -> SBVCodeGen ()
+      component _ limit = do
+        cgOverwriteFiles True
+        cgGenerateDriver False
+        cgArrayEqualityLimit limit
+        left  <- cgInput "left"  :: SBVCodeGen (SArray key Word8)
+        right <- cgInput "right" :: SBVCodeGen (SArray key Word8)
+        cgReturn (left .=== right)
+      large = do
+        cgOverwriteFiles True
+        cgGenerateDriver False
+        cgArrayEqualityLimit 65536
+        left  <- cgInput "left"  :: SBVCodeGen (SArray Word16 Word8)
+        right <- cgInput "right" :: SBVCodeGen (SArray Word16 Word8)
+        let compareArrays = smtFunction "C configured equality" ((.==) :: SArray Word16 Word8 -> SArray Word16 Word8 -> SBool)
+        cgReturn (compareArrays left right)
+  _ <- compileToCLib (Just dir) "arrayEqualityLibrary"
+    [("compareBytes", component (Proxy @Word8) 256)
+    , ("compareTinyFloats", component (Proxy @(FloatingPoint 2 3)) 27)
+    , ("compareChars", component (Proxy @Char) 0x30000)
+    , ("compareLarge", large)
+    ]
+  compileAndRunCaller dir "arrayEqualityLibrary" $ unlines
+    ["#include \"arrayEqualityLibrary.h\""
+    , "#include <assert.h>"
+    , "static unsigned calls, nans, positive_zeros, negative_zeros;"
+    , "static SWord8 byte_lookup(const void *context, SWord8 key)"
+    , "{ ++calls; return context != NULL && key == *(const unsigned *) context; }"
+    , "static SWord8 float_lookup(const void *context, SFP2_3 key)"
+    , "{"
+    , "  (void) context; ++calls;"
+    , "  unsigned raw = (unsigned) key.limb[0];"
+    , "  bool nan = (raw & 12) == 12 && (raw & 3) != 0;"
+    , "  nans += nan; positive_zeros += raw == 0; negative_zeros += raw == 16;"
+    , "  return nan ? 1 : (SWord8) raw;"
+    , "}"
+    , "static SWord8 char_lookup(const void *context, SChar key)"
+    , "{ (void) context; ++calls; return (SWord8) key; }"
+    , "static SWord8 large_lookup(const void *context, SWord16 key)"
+    , "{ (void) context; ++calls; return (SWord8) key; }"
+    , "int main(void)"
+    , "{"
+    , "  unsigned changed = 255;"
+    , "  SBVArrayInput_2_u8_2_u8 left = {byte_lookup, NULL, NULL, NULL};"
+    , "  SBVArrayInput_2_u8_2_u8 right = {byte_lookup, &changed, NULL, NULL};"
+    , "  assert(!compareBytes(left, right) && calls == 512);"
+    , "  calls = 0; changed = 0; assert(!compareBytes(left, right) && calls == 2);"
+    , "  calls = 0; assert(compareBytes(left, left) && calls == 512);"
+    , "  SBVArrayInput_8_fp_e2_s3_2_u8 floats = {float_lookup, NULL, NULL, NULL};"
+    , "  calls = 0; assert(compareTinyFloats(floats, floats) && calls == 54);"
+    , "  assert(nans == 2 && positive_zeros == 2 && negative_zeros == 2);"
+    , "  SBVArrayInput_4_char_2_u8 chars = {char_lookup, NULL, NULL, NULL};"
+    , "  calls = 0; assert(compareChars(chars, chars) && calls == 0x60000);"
+    , "  SBVArrayInput_3_u16_2_u8 large = {large_lookup, NULL, NULL, NULL};"
+    , "  calls = 0; assert(compareLarge(large, large) && calls == 131072);"
+    , "  return 0;"
+    , "}"
+    ]
+
+-- | Reject disabled, oversized, infinite, recursive, and nested-array comparisons
+-- with user-facing diagnostics before creating standalone or library files.
+-- Opt-in permits compact native-floating and wide
+-- bit-vector loops to be generated without attempting to execute them.
+finiteArrayRejections :: Assertion
+finiteArrayRejections = do
+  let comparison :: forall key. SymVal key => Proxy key -> SBVCodeGen ()
+      comparison _ = do
+        cgGenerateDriver False
+        left  <- cgInput "left"  :: SBVCodeGen (SArray key Word8)
+        right <- cgInput "right" :: SBVCodeGen (SArray key Word8)
+        cgReturn (left .=== right)
+      reject diagnostic program = mapM_ (checkRejection diagnostic program) [False, True]
+      checkRejection diagnostic program library = withSystemTempDirectory "sbv-array-equality-rejection" $ \dir -> do
+        let closed = cgGenerateDriver False >> cgReturn sTrue
+            action | library = void $ compileToCLib (Just dir) "rejectedLibrary" [("closedComponent", closed), ("rejectedEquality", program)]
+                   | True    = compileToC (Just dir) "rejectedEquality" program
+        result <- try action :: IO (Either ErrorCall ())
+        case result of
+          Left exception -> do
+            let message = displayException exception
+            assertBool message (diagnostic `isInfixOf` message)
+            assertBool "An intentional array-equality limit must not be reported as an internal error"
+                       (not ("Unexpected" `isInfixOf` message))
+          Right _ -> assertFailure "Expected array equality to reject generation"
+        assertEqual "Rejected equality must not create any component files" [] =<< listDirectory dir
+      checkCompact program = do
+        (_, _, bundle) <- compileToC' "largeDomain" (cgArrayEqualityLimit (2 ^ (673 :: Int)) >> program)
+        assertBool "Explicitly admitted large domains must generate compact loops" (length (show bundle) < 100000)
+  mapM_ (reject "cgArrayEqualityLimit")
+    [comparison (Proxy @Word32), comparison (Proxy @(WordN 673)), comparison (Proxy @Float)
+    , cgArrayEqualityLimit 26 >> comparison (Proxy @(FloatingPoint 2 3))]
+  reject "disabled by cgArrayEqualityLimit 0" (cgArrayEqualityLimit 0 >> comparison (Proxy @Bool))
+  mapM_ (reject "cannot enumerate key domain")
+    [comparison (Proxy @Integer), comparison (Proxy @String), comparison (Proxy @CodeGenTree)]
+  reject "Nested extensional array equality" $ do
+    cgGenerateDriver False
+    left  <- cgInput "left"  :: SBVCodeGen (SArray Bool (ArrayModel Bool Word8))
+    right <- cgInput "right" :: SBVCodeGen (SArray Bool (ArrayModel Bool Word8))
+    cgReturn (left .== right)
+  mapM_ checkCompact [comparison (Proxy @Float), comparison (Proxy @Double), comparison (Proxy @(WordN 673))]
+
+-- | Array values use structural object equality, including managed GMP,
+-- collection and ADT values, NaNs, and the distinction between signed zeros.
+finiteArrayValues :: Assertion
+finiteArrayValues = withSystemTempDirectory "sbv-finite-array-values" $ \dir -> do
+  let pair :: forall value. SymVal value => Proxy value -> String -> SBVCodeGen SBool
+      pair _ prefix = do
+        left  <- cgInput (prefix ++ "Left")  :: SBVCodeGen (SArray Bool value)
+        right <- cgInput (prefix ++ "Right") :: SBVCodeGen (SArray Bool value)
+        pure (left .=== right)
+      program = do
+        cgOverwriteFiles True
+        cgSetDriverValues (repeat 3)
+        results <- sequence [ pair (Proxy @Integer) "integer"
+                            , pair (Proxy @Rational) "rational"
+                            , pair (Proxy @String) "string"
+                            , pair (Proxy @[Integer]) "list"
+                            , pair (Proxy @(RCSet Word8)) "set"
+                            , pair (Proxy @(Maybe Integer)) "adt"
+                            ]
+        bits <- cgInput "bits" :: SBVCodeGen SWord32
+        let array value = constArray value :: SArray Bool Float
+            nanValue    = sWord32AsSFloat (bits .|. 0x7fc00000)
+            positive    = sWord32AsSFloat (bits .&. 0)
+            negative    = sWord32AsSFloat ((bits .&. 0) .|. 0x80000000)
+        cgReturn $ sAnd (results ++ [array nanValue .=== array (nanValue + 1), sNot (array positive .=== array negative)])
+  outputText <- compileProgramAndRunGenerated dir "finiteArrayValues" program
+  assertBool outputText (") = 1" `isInfixOf` outputText)
+
+-- | Discover rounding-mode declarations through collection element kinds,
+-- and compile their borrowed/owned interfaces with strict C warnings.
+collectionRoundingModes :: Assertion
+collectionRoundingModes = withSystemTempDirectory "sbv-collection-rounding" $ \dir -> do
+  compileToC (Just dir) "collectionRounding" $ do
+    cgOverwriteFiles True
+    values <- cgInput "values" :: SBVCodeGen (SList RoundingMode)
+    modes  <- cgInput "modes"  :: SBVCodeGen (SList [RoundingMode])
+    cgOutput "modesResult" modes
+    cgReturn values
+  makeOptions <- generatedMakeOptions dir
+  (makeExit, _, makeError) <- readProcessWithExitCode "make" (["-C", dir] ++ makeOptions) ""
+  assertEqual makeError ExitSuccess makeExit
+  _ <- compileAndRunGenerated dir "collectionRounding"
+  pure ()
+
+-- | The driver must wait for its archive in parallel builds and become stale
+-- whenever a component source changes, even if the public header is unchanged.
+libraryDriverDependencies :: Assertion
+libraryDriverDependencies = withSystemTempDirectory "sbv-library-dependencies" $ \dir -> do
+  _ <- compileToCLib (Just dir) "dependencyLibrary"
+    [("component", do cgOverwriteFiles True
+                      value <- cgInput "value" :: SBVCodeGen SWord8
+                      cgReturn (value + 1))]
+  makeOptions <- generatedMakeOptions dir
+  (makeExit, _, makeError) <- readProcessWithExitCode "make" (["-j2", "-C", dir] ++ makeOptions) ""
+  assertEqual makeError ExitSuccess makeExit
+  (queryExit, _, queryError) <- readProcessWithExitCode "make" ["-q", "-C", dir, "-W", "component.c", "dependencyLibrary_driver"] ""
+  assertEqual queryError (ExitFailure 1) queryExit
+
+-- | Reject direct and nested array comparisons, including sequence operations
+-- that implicitly compare elements and comparisons inside defined functions.
+-- Every rejection must precede file creation, even after a valid library entry.
+arrayCollectionComparisons :: TestTree
+arrayCollectionComparisons = testGroup "reject comparisons of array-valued collections"
+  [ testCase (testName ++ if library then " library" else " standalone") (checkOutput testName program library)
+  | (testName, program) <- programs, library <- [False, True]
+  ]
+ where binary :: forall a b. (SymVal a, SymVal b) => Proxy a -> (SBV a -> SBV a -> SBV b) -> SBVCodeGen ()
+       binary _ operation = do
+         cgGenerateDriver False
+         left  <- cgInput "left"  :: SBVCodeGen (SBV a)
+         right <- cgInput "right" :: SBVCodeGen (SBV a)
+         cgReturn (operation left right)
+
+       comparisons :: SymVal a => Proxy a -> [(String, SBVCodeGen ())]
+       comparisons proxy = [("equal", binary proxy (.==)), ("distinct", binary proxy (./=)), ("objectEqual", binary proxy (.===))]
+
+       -- ArrayModel deliberately has no Haskell Eq instance, so construct the
+       -- sequence primitives directly to test the backend boundary independently
+       -- of the public list API's concrete-folding constraints.
+       sequenceExpr :: forall a b. (SymVal a, SymVal b)
+                    => (Kind -> SeqOp) -> SList a -> SList a -> [SVal] -> SBV b
+       sequenceExpr operation left right extra = SBV $ SVal resultKind $ Right $ cache $ \st -> do
+         arguments <- mapM (svToSV st) ([unSBV left, unSBV right] ++ extra)
+         newExpr st resultKind (SBVApp (SeqOp (operation (kindOf (Proxy @a)))) arguments)
+        where resultKind = kindOf (Proxy @b)
+
+       sequences :: forall a. SymVal a => Proxy [a] -> [(String, SBVCodeGen ())]
+       sequences proxy = comparisons proxy ++
+         [ ("indexOf",  binary proxy (\left right -> sequenceExpr SeqIndexOf left right [unSBV (1 :: SInteger)] :: SInteger))
+         , ("contains", predicate SeqContains)
+         , ("prefix",   predicate SeqPrefixOf)
+         , ("suffix",   predicate SeqSuffixOf)
+         , ("replace",  binary proxy (\left right -> sequenceExpr SeqReplace left right [unSBV left] :: SList a))
+         ]
+        where predicate operation = binary proxy (\left right -> sequenceExpr operation left right [] :: SBool)
+
+       named prefix = map (B.first (prefix ++))
+
+       programs = named "list_"      (sequences   (Proxy @[ArrayModel Word8 Word8]))
+               ++ named "listTuple_" (sequences   (Proxy @[(Word8, ArrayModel Word8 Word8)]))
+               ++ named "nested_"    (sequences   (Proxy @[[ArrayModel Word8 Word8]]))
+               ++ named "tuple_"     (comparisons (Proxy @(Word8, ArrayModel Word8 Word8)))
+               ++ named "adt_"       (comparisons (Proxy @CodeGenArrayBox))
+               ++ named "envelope_"  (comparisons (Proxy @CodeGenArrayEnvelope))
+               ++ named "recursive_" (comparisons (Proxy @(Either CodeGenTree CodeGenArrayBox)))
+               ++ [ ("defined", binary (Proxy @[ArrayModel Word8 Word8]) (smtFunction "compareArrayElements" (.===)))
+                  , ("definedSearch", binary (Proxy @[ArrayModel Word8 Word8])
+                      (smtFunction "findArrayElements" (\left right -> sequenceExpr SeqIndexOf left right [unSBV (0 :: SInteger)] :: SInteger)))
+                  , ("lambda", cgReturn (lambdaArray (\index -> tuple (constArray index :: SArray Word8 Word8, index)
+                                                          .=== tuple (constArray (index + 1) :: SArray Word8 Word8, index))
+                                         :: SArray Word8 Bool))
+                  , ("arrayKeys", do value <- cgInput "value" :: SBVCodeGen (SArray (Word8, ArrayModel Word8 Word8) Word8)
+                                     cgReturn value)
+                  ]
+
+       checkOutput testName program library = withSystemTempDirectory "sbv-array-comparison-rejection" $ \dir -> do
+         let valid = cgGenerateDriver False >> cgReturn sTrue
+             action | library = void $ compileToCLib (Just dir) "rejectedLibrary" [("validComponent", valid), (testName, program)]
+                    | True    = compileToC (Just dir) testName program
+         result <- try action :: IO (Either ErrorCall ())
+         case result of
+           Left exception -> do
+             let message = displayException exception
+             assertBool (testName ++ ": " ++ message) ("extensional array equality" `isInfixOf` message)
+             assertBool (testName ++ ": intentional rejection must not be an internal compiler error")
+                        (not ("Unexpected" `isInfixOf` message))
+           Right _ -> assertFailure (testName ++ ": expected generation to reject array-element comparison")
+         assertEqual (testName ++ ": rejected comparisons must not create any files") [] =<< listDirectory dir
+
+-- | An external C provider may return a borrowed set containing duplicates.
+-- Removing an element must count every retained slot before exporting it.
+borrowedDuplicateRemoval :: Assertion
+borrowedDuplicateRemoval = withSystemTempDirectory "sbv-duplicate-set" $ \dir -> do
+  compileToC (Just dir) "removeDuplicates" $ do
+    cgOverwriteFiles True
+    cgGenerateDriver False
+    cgAddPrototype ["SBVSet_u8 duplicates(SWord8);"]
+    cgAddDecl [ "SBVSet_u8 duplicates(SWord8 unused) { (void) unused; static const SWord8 values[] = {7, 7, 9};"
+              , "return (SBVSet_u8) {values, 3, false}; }"
+              , "int main(void) { SBVSet_u8 result = removeDuplicates(0);"
+              , "int failed = result.length != 1 || result.data[0] != 9;"
+              , "sbv_set_release_u8(&result); return failed; }"
+              ]
+    input <- cgInput "input" :: SBVCodeGen SWord8
+    cgReturn (SS.delete 7 (uninterpret "duplicates" input :: SSet Word8))
+  runEmbeddedCaller dir "removeDuplicates"
+
+-- | Instrument an external function: a branch-local demand followed by an
+-- unconditional demand must not repeat the call, and a dead arm must not call it.
+guardedExternalSharing :: Assertion
+guardedExternalSharing = withSystemTempDirectory "sbv-shared-external" $ \dir -> do
+  compileToC (Just dir) "sharedExternal" $ do
+    cgOverwriteFiles True
+    cgGenerateDriver False
+    cgAddPrototype ["SWord8 counted(SWord8);"]
+    cgAddDecl [ "static unsigned calls;"
+              , "SWord8 counted(SWord8 x) { ++calls; return x; }"
+              , "int main(void) { SWord8 first, second;"
+              , "sharedExternal(true, 7, &first, &second); if (calls != 1 || first != 7 || second != 7) return 1;"
+              , "calls = 0; sharedExternal(false, 8, &first, &second); return calls != 1 || first != 0 || second != 8; }"
+              ]
+    condition <- cgInput "condition" :: SBVCodeGen SBool
+    value <- cgInput "value" :: SBVCodeGen SWord8
+    let shared = uninterpret "counted" value :: SWord8
+    cgOutput "first" (ite condition shared 0)
+    cgOutput "second" shared
+  source <- readFile (dir </> "sharedExternal.c")
+  assertEqual "Only the post-join demand needs a readiness guard" 1
+    (length (filter ("if(!sbv_ready_" `isInfixOf`) (lines source)))
+  runEmbeddedCaller dir "sharedExternal"
+
+-- | Force the full bundle for a three-stage dependency chain first demanded
+-- beneath nested branches. All eight paths must reuse every computed stage;
+-- a later unconditional demand must also compute any previously skipped stage.
+deepGuardedSharing :: Assertion
+deepGuardedSharing = withSystemTempDirectory "sbv-deep-sharing" $ \dir -> do
+  (_, cfg, bundle) <- compileToC' "deepSharing" $ do
+    cgOverwriteFiles True
+    cgGenerateDriver False
+    cgAddPrototype ["SWord8 stageOne(SWord8);", "SWord8 stageTwo(SWord8);", "SWord8 stageThree(SWord8);"]
+    cgAddDecl [ "static unsigned calls[3];"
+              , "SWord8 stageOne(SWord8 x) { ++calls[0]; return x + 1; }"
+              , "SWord8 stageTwo(SWord8 x) { ++calls[1]; return x + 1; }"
+              , "SWord8 stageThree(SWord8 x) { ++calls[2]; return x + 1; }"
+              , "int main(void) {"
+              , "  for (SWord8 flags = 0; flags < 8; ++flags) {"
+              , "    SWord8 first, second, intermediate; calls[0] = calls[1] = calls[2] = 0;"
+              , "    deepSharing(flags, 7, &first, &second, &intermediate);"
+              , "    if (first != (flags == 7 ? 10 : 0) || second != 10 || intermediate != 9) return 1;"
+              , "    if (calls[0] != 1 || calls[1] != 1 || calls[2] != 1) return 2;"
+              , "  }"
+              , "  return 0;"
+              , "}"
+              ]
+    flags <- cgInput "flags" :: SBVCodeGen SWord8
+    value <- cgInput "value" :: SBVCodeGen SWord8
+    let stage1 = uninterpret "stageOne"   value  :: SWord8
+        stage2 = uninterpret "stageTwo"   stage1 :: SWord8
+        stage3 = uninterpret "stageThree" stage2 :: SWord8
+    cgOutput "first" (ite (sTestBit flags 0) (ite (sTestBit flags 1) (ite (sTestBit flags 2) stage3 0) 0) 0)
+    cgOutput "second" stage3
+    cgOutput "intermediate" stage2
+  void $ evaluate (length (show bundle))
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  source <- readFile (dir </> "deepSharing.c")
+  assertEqual "Each stage needs a post-join readiness guard" 3
+    (length (filter ("if(!sbv_ready_" `isInfixOf`) (lines source)))
+  runEmbeddedCaller dir "deepSharing"
+
+-- | A leaf literal contains no value of the mutually recursive partner type,
+-- but its type's other constructor still needs that partner's declaration.
+-- An ADT input registers the full mutually recursive group; both leaf-only and
+-- nested literals inside a managed collection must reuse that same registry.
+sharedADTConstantRegistry :: Assertion
+sharedADTConstantRegistry = mapM_ check [0, 1]
+ where check seed = withSystemTempDirectory "sbv-adt-constant-registry" $ \dir -> do
+         outputText <- compileProgramAndRunGenerated dir "sharedADTRegistry" $ do
+           cgOverwriteFiles True
+           cgSetDriverValues [seed, 0]
+           chooseLeaf <- cgInput "chooseLeaf" :: SBVCodeGen SBool
+           value <- cgInput "value" :: SBVCodeGen SCodeGenEven
+           cgOutput "copy" value
+           cgReturn (ite chooseLeaf (literal [CGEvenEnd 7])
+                                    (literal [CGEvenStep (CGOddStep (CGEvenEnd 9))]))
+         let expected | seed == 0 = "CGEvenStep(CGOddStep(CGEvenEnd(9)))"
+                      | True      = "CGEvenEnd(7)"
+         assertBool outputText (expected `isInfixOf` outputText)
+
+-- | Literal-only ADTs retain their complete declarations without an ADT input
+-- or explicit registration. Metadata remains finite and does not affect kind
+-- identity, structural traversal, or constant folding, even under containers.
+literalADTRegistration :: Assertion
+literalADTRegistration = do
+  let leaf     = literal (CGEvenEnd 7)
+      rootKind = kindOf leaf
+  assertEqual "The leaf remains concrete" (Just "CGEvenEnd 7") (show <$> unliteral leaf)
+  assertEqual "The symbolic constructor remains concrete" (Just "CGEvenEnd 7") (show <$> unliteral (sCGEvenEnd 7))
+  void $ evaluate (force rootKind)
+  case rootKind of
+    KADT typeName parameters constructors -> do
+      let bare = KADT typeName parameters constructors
+      assertEqual "Metadata preserves kind equality" bare rootKind
+      assertEqual "Metadata preserves kind ordering" EQ (compare bare rootKind)
+      assertEqual "Metadata is not part of structural kind traversal" (expandKinds bare) (expandKinds rootKind)
+    _ -> assertFailure "Expected an ADT kind"
+  let parameterKind = kindOf (Proxy @(CodeGenEnvelope Word8))
+  assertEqual "Substitution must not enter independent declaration scopes"
+              (adtKindDependencies parameterKind)
+              (adtKindDependencies (substituteADTVars "CodeGenEnvelope" [("a", KBounded False 8)] parameterKind))
+  forM_ [ ("literalLeaf", cgReturn leaf, "CGEvenEnd(7)")
+        , ("constructorLeaf", cgReturn (sCGEvenEnd 7), "CGEvenEnd(7)")
+        , ("literalLeaves", cgReturn (literal [CGEvenEnd 7]), "CGEvenEnd(7)")
+        , ("literalEmptyLeaves", cgReturn (literal [] :: SList CodeGenEven), "")
+        , ("literalTupleLeaf", cgReturn (literal (CGEvenEnd 7, True)), "CGEvenEnd(7)")
+        , ("literalArrayLeaf", cgReturn (constArray leaf :: SArray Word8 CodeGenEven), "CGEvenEnd(7)")
+        ] $ \(entry, program, expected) -> withSystemTempDirectory "sbv-literal-adt" $ \dir -> do
+          outputText <- compileProgramAndRunGenerated dir entry program
+          headerText <- readFile (dir </> entry ++ ".h")
+          assertBool outputText (expected `isInfixOf` outputText)
+          assertBool "The unused partner still needs a declaration"
+                     ("typedef struct SBVADT_CodeGenOdd SBVADT_CodeGenOdd;" `isInfixOf` headerText)
+  withSystemTempDirectory "sbv-literal-adt-parameter" $ \dir -> do
+    outputText <- compileProgramAndRunGenerated dir "literalEnvelope" $
+      cgReturn (literal CGNoEnvelope :: SCodeGenEnvelope Word8)
+    headerText <- readFile (dir </> "literalEnvelope.h")
+    assertBool outputText ("CGNoEnvelope" `isInfixOf` outputText)
+    assertBool "The unused constructor must instantiate its dependency at Word8"
+               ("SBVADT_CodeGenADT_2_u8" `isInfixOf` headerText)
+    assertBool "The placeholder registration schema is not the generated ADT"
+               (not ("SBVADT_CodeGenADT_7_integer" `isInfixOf` headerText))
+
+-- | The original four-way file-kind match must stay exhaustive under -Werror
+-- and expose signatures for current and legacy generated headers alike.
+compatibleHeaderPatterns :: Assertion
+compatibleHeaderPatterns = mapM_ check [compileToC', PublicLegacy.compileToC']
+ where check compiler = do
+         (_, _, CgPgmBundle _ files) <- compiler "compatibleHeader" $ do
+           value <- cgInput "value" :: SBVCodeGen SWord8
+           cgReturn (value + 1)
+         assertEqual "One header with one public signature" [1]
+           [count | (_, (fileKind, _)) <- files, Just count <- [signatures fileKind]]
+       signatures (CgMakefile _) = Nothing
+       signatures (CgHeader ds)  = Just (length ds)
+       signatures CgSource       = Nothing
+       signatures CgDriver       = Nothing
+
+-- | Per-component generation options need not agree, but a library's returned
+-- artifact flags must reflect the union, and overwriting needs unanimous opt-in.
+mergedConfiguration :: Assertion
+mergedConfiguration = do
+  (_, cfg, _) <- compileToCLib' "mixedConfiguration"
+    [ ("withoutDriver", do cgGenerateDriver False
+                           cgGenerateMakefile False
+                           cgOverwriteFiles True
+                           cgReturn sTrue)
+    , ("withDriver", cgReturn sFalse)
+    ]
+  assertBool "Merged library includes a driver" (cgGenDriver cfg)
+  assertBool "Merged library includes a Makefile" (cgGenMakefile cfg)
+  assertBool "One component cannot authorize overwriting for the others" (not (cgOverwriteGenerated cfg))
+
+-- | Detect unsupported excess precision at C compilation, without depending
+-- on whether the local processor offers an x87-style evaluation mode.
+excessFloatingPrecision :: Assertion
+excessFloatingPrecision = mapM_ check [-1, 1, 2 :: Int]
+ where check evaluationMethod = withSystemTempDirectory "sbv-excess-precision" $ \dir -> do
+         compileToC (Just dir) "floatingPrecision" $ do
+           cgOverwriteFiles True
+           cgGenerateDriver False
+           value <- cgInput "value" :: SBVCodeGen SDouble
+           cgReturn (value + 1)
+         writeFile (dir </> "excess.c") $ unlines
+           [ "#include <float.h>"
+           , "#undef FLT_EVAL_METHOD"
+           , "#define FLT_EVAL_METHOD " ++ show evaluationMethod
+           , "#include \"floatingPrecision.h\""
+           ]
+         (compileExit, _, compileError) <- readProcessWithExitCode "cc" ["-std=c11", "-fsyntax-only", dir </> "excess.c"] ""
+         assertBool "Excess precision must be rejected" (compileExit /= ExitSuccess)
+         assertBool compileError ("indeterminate or excess-precision floating evaluation is unsupported" `isInfixOf` compileError)
+
+-- | Exercise the arena's size check directly, without constructing an invalid
+-- borrowed string or relying on an enormous allocation to fail incidentally.
+textAllocationOverflow :: Assertion
+textAllocationOverflow = withSystemTempDirectory "sbv-text-overflow" $ \dir -> do
+  compileToC (Just dir) "textOverflow" $ do
+    cgOverwriteFiles True
+    cgGenerateDriver False
+    value <- cgInput "value" :: SBVCodeGen SString
+    cgReturn (value SL.++ value)
+  appendFile (dir </> "textOverflow.c") $ unlines
+    [ "int main(void) {"
+    , "  sbv_text_ctx ctx = {NULL};"
+    , "  (void) sbv_text_alloc(&ctx, SIZE_MAX);"
+    , "  sbv_text_ctx_end(&ctx); return 0;"
+    , "}"
+    ]
+  writeFile (dir </> "caller.mk") $ unlines
+    [ "textOverflow: textOverflow.o"
+    , "\t${CC} ${CCFLAGS} $^ -o $@ ${LDFLAGS} ${SBV_LIBS}"
+    ]
+  makeOptions <- generatedMakeOptions dir
+  (buildExit, _, buildError) <- readProcessWithExitCode "make" (["-C", dir, "textOverflow"] ++ makeOptions) ""
+  assertEqual buildError ExitSuccess buildExit
+  (runExit, _, runError) <- readProcessWithExitCode (dir </> "textOverflow") [] ""
+  assertBool ("Expected allocation overflow to abort: " ++ runError) (runExit /= ExitSuccess)
+
+-- | Mix literal-backed collections with owned numbers, ADTs, and collections
+-- of ADTs in one driver input. Only fields needing initialization get element
+-- variables, and the cloned output survives cleanup of the borrowed input.
+sharedDriverInitialization :: Assertion
+sharedDriverInitialization = withSystemTempDirectory "sbv-shared-driver-init" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [5]
+        value <- cgInput "value" :: SBVCodeGen (SBV (Integer, [Word8], RCSet Word8, CodeGenADT Integer, [CodeGenADT Word8]))
+        let (_, listValue, setValue, _, _) = untuple value
+        cgOutput "copy" value
+        cgReturn (SL.head listValue .== 6 .&& sNot (SS.member 7 setValue))
+  stdoutText <- compileProgramAndRunGenerated dir "sharedDriverInitialization" program
+  assertBool ("Expected the mixed input's driver samples to agree: " ++ stdoutText) (") = 1" `isInfixOf` stdoutText)
+  driverText <- readFile (dir </> "sharedDriverInitialization_driver.c")
+  assertBool "Literal-backed list elements need no separate driver variables"
+             (not ("sbv_driver_input_0_field_2_element_" `isInfixOf` driverText))
+  assertBool "Literal-backed set elements need no separate driver variables"
+             (not ("sbv_driver_input_0_field_3_element_" `isInfixOf` driverText))
+  assertBool "ADT collection elements retain their explicit initialization"
+             ("sbv_driver_input_0_field_5_element_0" `isInfixOf` driverText)
+
+-- | The same tuple-element collections require individual initialization and
+-- cleanup with exact integers, but borrow compound literals with mapped ones.
+-- Keep both decisions tied to the selected representation, including when the
+-- collections occur inside an independently owned outer tuple.
+collectionDriverStorageModes :: Assertion
+collectionDriverStorageModes = mapM_ check [False, True]
+ where check mapped = withSystemTempDirectory "sbv-collection-driver-storage" $ \dir -> do
+         let program = do
+               cgOverwriteFiles True
+               when mapped (cgIntegerSize 64)
+               cgSetDriverValues [10]
+               value <- cgInput "value" :: SBVCodeGen (SBV (String, [(Integer, Word8)], RCSet (Integer, Word8)))
+               let (_, listValue, setValue) = untuple value
+                   (firstValue, _) = untuple (SL.head listValue)
+               cgOutput "copy" value
+               cgReturn (firstValue .== 11 .&& SS.member (tuple (12, 13)) setValue)
+         stdoutText <- compileProgramAndRunGenerated dir "collectionDriverStorage" program
+         assertBool ("Expected the collection driver samples to agree: " ++ stdoutText) (") = 1" `isInfixOf` stdoutText)
+         driverText <- readFile (dir </> "collectionDriverStorage_driver.c")
+         forM_ [2, 3 :: Int] $ \fieldIndex -> forM_ [0 .. 2 :: Int] $ \elementIndex -> do
+           let elementName = "sbv_driver_input_0_field_" ++ show fieldIndex ++ "_element_" ++ show elementIndex
+               clearsElement line = "sbv_tuple_owned_release_" `isInfixOf` line && ("(&" ++ elementName ++ ");") `isInfixOf` line
+           assertEqual ("Element variables follow storage selection: " ++ elementName)
+                       (not mapped) (elementName `isInfixOf` driverText)
+           assertEqual ("Element cleanup follows initialization: " ++ elementName)
+                       (not mapped) (any clearsElement (lines driverText))
+
+-- | Exercise all three instances of the shared arena emitter, including empty
+-- allocation, element alignment, independent payloads, repeated cleanup, and
+-- overflow of both the payload multiplication and allocation-header addition.
+ownershipArenaChecks :: Assertion
+ownershipArenaChecks = withSystemTempDirectory "sbv-ownership-arenas" $ \dir -> do
+  compileToC (Just dir) "ownershipArenas" $ do
+    cgOverwriteFiles True
+    cgGenerateDriver False
+    stringValue <- cgInput "string" :: SBVCodeGen SString
+    listValue   <- cgInput "list"   :: SBVCodeGen (SList Word32)
+    setValue    <- cgInput "set"    :: SBVCodeGen (SSet Word32)
+    cgOutput "stringCopy" (stringValue SL.++ stringValue)
+    cgOutput "listCopy"   (listValue SL.++ listValue)
+    cgOutput "setCopy"    (SS.insert 7 setValue)
+  appendFile (dir </> "ownershipArenas.c") $ unlines
+    [ "int main(int argc, char **argv) {"
+    , "  sbv_text_ctx text_ctx = {NULL};"
+    , "  sbv_list_ctx list_ctx = {NULL};"
+    , "  sbv_set_ctx set_ctx = {NULL};"
+    , "  if (argc != 2) return 2;"
+    , "  switch (argv[1][0]) {"
+    , "    case '0': {"
+    , "      if (sbv_text_alloc(&text_ctx, 0) != NULL) return 3;"
+    , "      if (sbv_list_alloc(&list_ctx, 0, 0) != NULL) return 4;"
+    , "      if (sbv_set_alloc(&set_ctx, 0, 0) != NULL) return 5;"
+    , "      if (text_ctx.head != NULL || list_ctx.head != NULL || set_ctx.head != NULL) return 6;"
+    , "      uint8_t *first = sbv_text_alloc(&text_ctx, 2); first[0] = 17; first[1] = 19;"
+    , "      uint8_t *second = sbv_text_alloc(&text_ctx, 1); second[0] = 23;"
+    , "      long double *items = (long double *) sbv_list_alloc(&list_ctx, 2, sizeof(*items));"
+    , "      long double *members = (long double *) sbv_set_alloc(&set_ctx, 2, sizeof(*members));"
+    , "      if ((uintptr_t) items % _Alignof(long double) != 0) return 7;"
+    , "      if ((uintptr_t) members % _Alignof(long double) != 0) return 8;"
+    , "      items[0] = 29; items[1] = 31; members[0] = 37; members[1] = 41;"
+    , "      (void) sbv_list_alloc(&list_ctx, 3, sizeof(*items));"
+    , "      (void) sbv_set_alloc(&set_ctx, 3, sizeof(*members));"
+    , "      if (first[0] != 17 || first[1] != 19 || second[0] != 23) return 9;"
+    , "      if (items[0] != 29 || items[1] != 31 || members[0] != 37 || members[1] != 41) return 10;"
+    , "      break;"
+    , "    }"
+    , "    case '1': (void) sbv_text_alloc(&text_ctx, SIZE_MAX); break;"
+    , "    case '2': (void) sbv_list_alloc(&list_ctx, 1, 0); break;"
+    , "    case '3': (void) sbv_set_alloc(&set_ctx, 1, 0); break;"
+    , "    case '4': (void) sbv_list_alloc(&list_ctx, SIZE_MAX / 2 + 1, 2); break;"
+    , "    case '5': (void) sbv_set_alloc(&set_ctx, SIZE_MAX / 2 + 1, 2); break;"
+    , "    case '6': (void) sbv_list_alloc(&list_ctx, SIZE_MAX, 1); break;"
+    , "    case '7': (void) sbv_set_alloc(&set_ctx, SIZE_MAX, 1); break;"
+    , "    default: return 11;"
+    , "  }"
+    , "  sbv_text_ctx_end(&text_ctx); sbv_list_ctx_end(&list_ctx); sbv_set_ctx_end(&set_ctx);"
+    , "  if (text_ctx.head != NULL || list_ctx.head != NULL || set_ctx.head != NULL) return 12;"
+    , "  sbv_text_ctx_end(&text_ctx); sbv_list_ctx_end(&list_ctx); sbv_set_ctx_end(&set_ctx);"
+    , "  return 0;"
+    , "}"
+    ]
+  writeFile (dir </> "caller.mk") $ unlines
+    [ "ownershipArenas: ownershipArenas.o"
+    , "\t${CC} ${CCFLAGS} $^ -o $@ ${LDFLAGS} ${SBV_LIBS}"
+    ]
+  makeOptions <- generatedMakeOptions dir
+  (buildExit, _, buildError) <- readProcessWithExitCode "make" (["-C", dir, "ownershipArenas"] ++ makeOptions) ""
+  assertEqual buildError ExitSuccess buildExit
+  (normalExit, _, normalError) <- readProcessWithExitCode (dir </> "ownershipArenas") ["0"] ""
+  assertEqual normalError ExitSuccess normalExit
+  forM_ [1 :: Int .. 7] $ \scenario -> do
+    (runExit, _, runError) <- readProcessWithExitCode (dir </> "ownershipArenas") [show scenario] ""
+    assertBool ("Expected arena size check " ++ show scenario ++ " to abort: " ++ runError) (runExit /= ExitSuccess)
+
+-- | Runtime-empty operands require no arena allocation for text, scalar lists,
+-- or lists of owned strings. Public outputs must still be independent copies,
+-- including when both operands are nonempty or contain embedded NULs and UTF-8.
+emptyConcatenation :: Assertion
+emptyConcatenation = withSystemTempDirectory "sbv-empty-concat" $ \dir -> do
+  compileToC (Just dir) "emptyConcat" $ do
+    cgOverwriteFiles True
+    cgGenerateDriver False
+    textLeft   <- cgInput "textLeft"   :: SBVCodeGen SString
+    textRight  <- cgInput "textRight"  :: SBVCodeGen SString
+    listLeft   <- cgInput "listLeft"   :: SBVCodeGen (SList Word32)
+    listRight  <- cgInput "listRight"  :: SBVCodeGen (SList Word32)
+    ownedLeft  <- cgInput "ownedLeft"  :: SBVCodeGen (SList String)
+    ownedRight <- cgInput "ownedRight" :: SBVCodeGen (SList String)
+    cgOutput "textCopy"  (textLeft SL.++ textRight)
+    cgOutput "listCopy"  (listLeft SL.++ listRight)
+    cgOutput "ownedCopy" (ownedLeft SL.++ ownedRight)
+  appendFile (dir </> "emptyConcat.c") $ unlines
+    [ "#include <assert.h>"
+    , "int main(void) {"
+    , "  for (unsigned scenario = 0; scenario < 4; ++scenario) {"
+    , "    sbv_text_ctx text_ctx = {NULL}; sbv_list_ctx list_ctx = {NULL};"
+    , "    uint8_t bytes[] = {0xc3, 0xa9, 0}; SWord32 numbers[] = {7, 11};"
+    , "    SString text_value = sbv_string_borrow(bytes, 3, 2);"
+    , "    SString text_empty = sbv_string_borrow(NULL, 0, 0);"
+    , "    SBVList_u32 list_value = {numbers, 2}, list_empty = {NULL, 0};"
+    , "    SBVList_string owned_value = {&text_value, 1}, owned_empty = {NULL, 0};"
+    , "    SString text_left = (scenario & 1) ? text_value : text_empty;"
+    , "    SString text_right = (scenario & 2) ? text_value : text_empty;"
+    , "    SBVList_u32 list_left = (scenario & 1) ? list_value : list_empty;"
+    , "    SBVList_u32 list_right = (scenario & 2) ? list_value : list_empty;"
+    , "    SBVList_string owned_left = (scenario & 1) ? owned_value : owned_empty;"
+    , "    SBVList_string owned_right = (scenario & 2) ? owned_value : owned_empty;"
+    , "    SString text_result = sbv_text_concat(&text_ctx, text_left, text_right);"
+    , "    SBVList_u32 list_result = sbv_list_u32_concat(&list_ctx, list_left, list_right);"
+    , "    SBVList_string owned_result = sbv_list_string_concat(&list_ctx, owned_left, owned_right);"
+    , "    const size_t copies = ((scenario & 1) != 0) + ((scenario & 2) != 0);"
+    , "    assert(text_result.byte_length == 3 * copies && text_result.length == 2 * copies);"
+    , "    assert(list_result.length == 2 * copies && owned_result.length == copies);"
+    , "    if (scenario != 3) {"
+    , "      assert(text_ctx.head == NULL && list_ctx.head == NULL);"
+    , "      assert(text_result.data == (scenario == 0 ? NULL : bytes));"
+    , "      assert(list_result.data == (scenario == 0 ? NULL : numbers));"
+    , "      assert(owned_result.data == (scenario == 0 ? NULL : &text_value));"
+    , "    } else {"
+    , "      assert(text_ctx.head != NULL && list_ctx.head != NULL);"
+    , "    }"
+    , "    sbv_text_ctx_end(&text_ctx); sbv_list_ctx_end(&list_ctx);"
+    , "    SString text_copy; SBVList_u32 list_copy; SBVList_string owned_copy;"
+    , "    emptyConcat(text_left, text_right, list_left, list_right, owned_left, owned_right,"
+    , "                &text_copy, &list_copy, &owned_copy);"
+    , "    bytes[0] = 'x'; numbers[0] = 99;"
+    , "    assert(text_copy.byte_length == 3 * copies && text_copy.length == 2 * copies);"
+    , "    assert(list_copy.length == 2 * copies && owned_copy.length == copies);"
+    , "    for (size_t i = 0; i < copies; ++i) {"
+    , "      assert(text_copy.data[3 * i] == 0xc3 && text_copy.data[3 * i + 1] == 0xa9 && text_copy.data[3 * i + 2] == 0);"
+    , "      assert(list_copy.data[2 * i] == 7 && list_copy.data[2 * i + 1] == 11);"
+    , "      assert(owned_copy.data[i].byte_length == 3 && owned_copy.data[i].length == 2);"
+    , "      assert(owned_copy.data[i].data[0] == 0xc3 && owned_copy.data[i].data[1] == 0xa9 && owned_copy.data[i].data[2] == 0);"
+    , "    }"
+    , "    sbv_string_release(&text_copy); sbv_list_release_u32(&list_copy); sbv_list_release_string(&owned_copy);"
+    , "  }"
+    , "  return 0;"
+    , "}"
+    ]
+  runEmbeddedCaller dir "emptyConcat"
+
+-- | Sharing non-speculatable arithmetic in a straight-line program needs one
+-- assignment, not a zero initializer, readiness flag, or conditional wrapper.
+straightLineSharing :: Assertion
+straightLineSharing = mapM_ check [("sharedDouble", doubles), ("sharedInteger", integers)]
+ where doubles = do
+         value <- cgInput "value" :: SBVCodeGen SDouble
+         let productValue = value * value
+         cgOutput "first" productValue
+         cgOutput "second" productValue
+       integers = do
+         value <- cgInput "value" :: SBVCodeGen SInteger
+         let productValue = value * value
+         cgOutput "first" productValue
+         cgOutput "second" productValue
+       check (entry, program) = withSystemTempDirectory "sbv-straight-sharing" $ \dir -> do
+         outputText <- compileProgramAndRunGenerated dir entry $ do
+           cgOverwriteFiles True
+           cgSetDriverValues [7]
+           program
+         source <- readFile (dir </> entry ++ ".c")
+         assertBool source (not ("sbv_ready_" `isInfixOf` source))
+         assertBool source (not ("= {0}" `isInfixOf` source))
+         assertBool source (not ("sbv_gmp_integer_shift" `isInfixOf` source))
+         assertBool outputText ("49" `isInfixOf` outputText || "0x1.88p+5" `isInfixOf` outputText)
+
+-- | Build a translation unit containing its own test main, preserving the
+-- same compilation, sanitizer, and dependency flags at the final link step.
+runEmbeddedCaller :: FilePath -> String -> Assertion
+runEmbeddedCaller dir entry = do
+  writeFile (dir </> "caller.mk") $ unlines
+    [entry ++ ": " ++ entry ++ ".o"
+    , "\t${CC} ${CCFLAGS} $^ -o $@ ${LDFLAGS} ${SBV_LIBS}"
+    ]
+  makeOptions <- generatedMakeOptions dir
+  (buildExit, _, buildError) <- readProcessWithExitCode "make" (["-C", dir, entry] ++ makeOptions) ""
+  assertEqual buildError ExitSuccess buildExit
+  (runExit, _, runError) <- readProcessWithExitCode (dir </> entry) [] ""
+  assertEqual runError ExitSuccess runExit
+
+-- | Linker settings must survive a caller's LDFLAGS, and disabling assertions
+-- must remove executable checks without imposing floating rules on integer C.
+reviewedBuildOptions :: Assertion
+reviewedBuildOptions = withSystemTempDirectory "sbv-reviewed-options" $ \dir -> do
+  compileToC (Just dir) "INTERVAL" $ do
+    cgOverwriteFiles True
+    cgIgnoreSAssert True
+    cgAddLDFlags ["-lm"]
+    cgSetDriverValues [7]
+    value <- cgInput "PRIMARY" :: SBVCodeGen SInteger
+    cgReturn (sAssert Nothing "deliberately disabled" (value .< 0) (value + 1))
+  makefile <- readFile (dir </> "Makefile")
+  header <- readFile (dir </> "INTERVAL.h")
+  assertBool makefile (not ("-ffp-contract" `isInfixOf` makefile))
+  assertBool "cgAddLDFlags must contribute to separately retained link dependencies"
+             ("SBV_LIBS?=" `isInfixOf` makefile && "-lm" `isInfixOf` makefile)
+  assertBool header (not ("__FAST_MATH__" `isInfixOf` header))
+  makeOptions <- generatedMakeOptions dir
+  (buildExit, _, buildError) <- readProcessWithExitCode "make" (["-C", dir, "LDFLAGS="] ++ makeOptions) ""
+  assertEqual buildError ExitSuccess buildExit
+  (runExit, outputText, runError) <- readProcessWithExitCode (dir </> "INTERVAL_driver") [] ""
+  assertEqual runError ExitSuccess runExit
+  assertBool outputText ("=8" `isInfixOf` outputText)
+
+-- | A library header must retain user prototypes needed by its translation
+-- units, even when the external implementation is supplied at final linking.
+libraryExternalPrototypes :: Assertion
+libraryExternalPrototypes = withSystemTempDirectory "sbv-library-prototypes" $ \dir -> do
+  _ <- compileToCLib (Just dir) "prototypeLibrary"
+    [("externalCall", do cgOverwriteFiles True
+                         cgAddPrototype ["SWord8 external(SWord8);"]
+                         value <- cgInput "value" :: SBVCodeGen SWord8
+                         cgReturn (uninterpret "external" value :: SWord8))]
+  makeOptions <- generatedMakeOptions dir
+  (makeExit, _, makeError) <- readProcessWithExitCode "make" (["-C", dir, "externalCall.o"] ++ makeOptions) ""
+  assertEqual makeError ExitSuccess makeExit
+
+-- | Reject invalid library layouts before rendering any files. Driver symbols
+-- are checked separately from file names, and disabled drivers reserve neither.
+libraryValidation :: Assertion
+libraryValidation = do
+  mapM_ check
+    [("emptyLibrary", [], "at least one component")
+    , ("duplicateLibrary", [("duplicate", program True), ("duplicate", program True)], "Duplicate component names")
+    , ("fileLibrary", [("fileLibrary_driver", program True)], "Conflicting generated file names")
+    , ("symbolLibrary", [("entry", program True), ("entry_driver", program False)], "Conflicting generated entry points")
+    , ("mainLibrary", [("main", program True)], "reserved C/backend name")
+    , ("caseLibrary", [("entry", program True), ("Entry", program True)], "Conflicting generated file names")
+    ]
+  withSystemTempDirectory "sbv-library-no-drivers" $ \dir -> do
+    _ <- compileToCLib (Just dir) "noDriverLibrary"
+      [("noDriverLibrary_driver", program False), ("entry", program False), ("entry_driver", program False)]
+    makeOptions <- generatedMakeOptions dir
+    (makeExit, _, makeError) <- readProcessWithExitCode "make" (["-C", dir] ++ makeOptions) ""
+    assertEqual makeError ExitSuccess makeExit
+ where program driver = do
+         cgOverwriteFiles True
+         cgGenerateDriver driver
+         value <- cgInput "value" :: SBVCodeGen SWord8
+         cgReturn value
+
+       check (libName, components, diagnostic) = withSystemTempDirectory "sbv-library-validation" $ \dir -> do
+         result <- try (compileToCLib (Just dir) libName components) :: IO (Either ErrorCall [()])
+         case result of
+           Left exception -> assertBool (displayException exception) (diagnostic `isInfixOf` displayException exception)
+           Right _        -> assertBool ("Expected library rejection: " ++ libName) False
+         assertEqual "Invalid libraries must not write files" [] =<< listDirectory dir
+
+-- | Check all public naming entry points and ensure diagnostics precede any
+-- file writes, including names that could otherwise escape the output directory.
+publicCNameValidation :: Assertion
+publicCNameValidation = do
+  mapM_ (\badName -> rejects $ \dir -> compileToC (Just dir) badName scalar)
+    ["", "my-function", "../escape", "line\nbreak", "switch", "9lives", "caf\233", "sbv_bv_s16_mul", "SBVList_u8", "SFP7_19", "__result", "printf", "remainder", "uint32_t"]
+  rejects $ \dir -> compileToC (Just dir) "badInput" $ do
+    value <- cgInput "switch" :: SBVCodeGen SWord8
+    cgReturn value
+  rejects $ \dir -> compileToC (Just dir) "badOutput" $ do
+    value <- cgInput "value" :: SBVCodeGen SWord8
+    cgOutput "sbv_output_0" value
+  rejects $ \dir -> compileToC (Just dir) "badInputGroup" $ do
+    values <- cgInputArr 2 "my-values" :: SBVCodeGen [SWord8]
+    cgReturnArr values
+  rejects $ \dir -> compileToC (Just dir) "badOutputGroup" $ cgOutputArr "int" [literal (3 :: Word8)]
+  rejects $ \dir -> void $ compileToCLib (Just dir) "my-library" [("component", scalar)]
+  rejects $ \dir -> void $ compileToCLib (Just dir) "validLibrary" [("my-component", scalar)]
+ where scalar = do
+         value <- cgInput "value" :: SBVCodeGen SWord8
+         cgReturn value
+
+       rejects generate = withSystemTempDirectory "sbv-c-names" $ \dir -> do
+         result <- try (generate dir) :: IO (Either ErrorCall ())
+         case result of
+           Left exception -> assertBool (displayException exception) ("Invalid" `isInfixOf` displayException exception)
+           Right _        -> assertBool "Expected a public name diagnostic" False
+         assertEqual "Invalid names must not write files" [] =<< listDirectory dir
+
+-- | Keep valid identifiers in the ABI while isolating symbolic temporaries,
+-- table names, and recursively generated driver storage from user names.
+privateCBindings :: Assertion
+privateCBindings = withSystemTempDirectory "sbv-private-c-bindings" $ \dir -> do
+  compileToC (Just dir) "s0" $ do
+    cgOverwriteFiles True
+    cgSetDriverValues [7, 2, 3, 4, 5]
+    value      <- cgInput "s0" :: SBVCodeGen SWord8
+    tableValue <- cgInput "table0" :: SBVCodeGen SWord8
+    values     <- cgInput "values" :: SBVCodeGen (SList Integer)
+    moreValues <- cgInput "values_data" :: SBVCodeGen (SList Integer)
+    group      <- cgInputArr 1 "group" :: SBVCodeGen [SWord8]
+    cgOutput "s1" (select [value, value+1, value+2] 0 tableValue)
+    cgOutput "group_ctr" (sum group)
+    cgOutput "values_element_0" moreValues
+    cgReturn values
+  headerText <- readFile (dir </> "s0.h")
+  mapM_ (\fragment -> assertBool headerText (fragment `isInfixOf` headerText))
+    ["SWord8 s0", "SWord8 table0", "*s1", "*group_ctr"]
+  outputText <- compileAndRunGenerated dir "s0"
+  mapM_ (\fragment -> assertBool outputText (fragment `isInfixOf` outputText))
+    ["s1 = 9", "group_ctr = 5", "values_element_0 =", "s0(7, 2, values, values_data, group"]
+
+-- | Distinct recursive ADTs must coexist both directly and through every
+-- structural wrapper. Repeated library components must deduplicate each
+-- type's helpers without suppressing the differently-cased companion.
+caseSensitiveCKinds :: Assertion
+caseSensitiveCKinds = mapM_ check [False, True]
+ where check library = withSystemTempDirectory "sbv-case-sensitive-kinds" $ \dir -> do
+         if library
+            then do _ <- compileToCLib (Just dir) "caseSensitiveKinds" [("firstCase", program), ("secondCase", program)]
+                    pure ()
+            else compileToC (Just dir) "caseSensitiveKinds" program
+         outputText <- compileAndRunGenerated dir "caseSensitiveKinds"
+         mapM_ (\fragment -> assertBool outputText (fragment `isInfixOf` outputText))
+           ["CGCaseNext", "CGCASENext", "lowerList =", "upperList =", "lowerSet =", "upperSet ="]
+
+       program = do
+         cgOverwriteFiles True
+         cgSetDriverValues (repeat 1)
+         lower      <- cgInput "lower"      :: SBVCodeGen (SBV CodeGenCase)
+         upper      <- cgInput "upper"      :: SBVCodeGen (SBV CodeGenCASE)
+         lowerTuple <- cgInput "lowerTuple" :: SBVCodeGen (SBV (CodeGenCase, Word8))
+         upperTuple <- cgInput "upperTuple" :: SBVCodeGen (SBV (CodeGenCASE, Word8))
+         lowerList  <- cgInput "lowerListInput" :: SBVCodeGen (SList CodeGenCase)
+         upperList  <- cgInput "upperListInput" :: SBVCodeGen (SList CodeGenCASE)
+         lowerSet   <- cgInput "lowerSetInput"  :: SBVCodeGen (SSet CodeGenCase)
+         upperSet   <- cgInput "upperSetInput"  :: SBVCodeGen (SSet CodeGenCASE)
+         lowerArray <- cgInput "lowerArray" :: SBVCodeGen (SArray Word8 CodeGenCase)
+         upperArray <- cgInput "upperArray" :: SBVCodeGen (SArray Word8 CodeGenCASE)
+         cgOutput "lowerChild" (getCGCaseNext_1 lower)
+         cgOutput "upperChild" (getCGCASENext_1 upper)
+         cgOutput "lowerPair" lowerTuple
+         cgOutput "upperPair" upperTuple
+         cgOutput "lowerList" lowerList
+         cgOutput "upperList" upperList
+         cgOutput "lowerSet" lowerSet
+         cgOutput "upperSet" upperSet
+         cgOutput "lowerArrayResult" (writeArray lowerArray 0 lower)
+         cgOutput "upperArrayResult" (writeArray upperArray 0 upper)
+         cgReturn (tuple (sCGCaseNext lower, sCGCASENext upper))
+
+-- | Different placements of tuple and array boundaries produce distinct C
+-- descriptor names, and the framed names agree across declarations, storage,
+-- access helpers, and driver-side ownership operations.
+structuralCNameFraming :: Assertion
+structuralCNameFraming = withSystemTempDirectory "sbv-structural-c-names" $ \dir -> do
+  compileToC (Just dir) "structuralNames" $ do
+    cgOverwriteFiles True
+    cgSetDriverValues [7, 0, 0]
+    value <- cgInput "value" :: SBVCodeGen SWord32
+    keyed <- cgInput "keyed" :: SBVCodeGen (SArray (Word8, Word16) Word32)
+    paired <- cgInput "paired" :: SBVCodeGen (SArray Word8 (Word16, Word32))
+    let key = tuple (1 :: SWord8, 2 :: SWord16)
+        keyedResult = writeArray keyed key value
+        pairedResult = writeArray paired 1 (tuple (2 :: SWord16, value))
+        nested = constArray (constArray value :: SArray Word16 Word32) :: SArray Word8 (ArrayModel Word16 Word32)
+        (_, pairedValue) = untuple (readArray pairedResult 1)
+    cgOutput "keyedResult" keyedResult
+    cgOutput "pairedResult" pairedResult
+    cgOutput "nested" nested
+    cgReturn (readArray keyedResult key .== value .&& pairedValue .== value .&& readArray (readArray nested 1) 2 .== value)
+  headerText <- readFile (dir </> "structuralNames.h")
+  mapM_ (\typeName -> assertBool headerText (typeName `isInfixOf` headerText))
+    ["SBVArrayOutput_13_t2_2_u8_3_u16_3_u32"
+    , "SBVArrayOutput_2_u8_14_t2_3_u16_3_u32"
+    , "SBVArrayOutput_2_u8_20_array_11_3_u16_3_u32"
+    ]
+  outputText <- compileAndRunGenerated dir "structuralNames"
+  assertBool outputText (") = 1" `isInfixOf` outputText)
+
+-- | Use a hand-written caller to check output reuse, independent ownership,
+-- borrowed array reads, and balanced callback lifetimes across library calls.
+libraryOwnershipContract :: Assertion
+libraryOwnershipContract = withSystemTempDirectory "sbv-library-ownership" $ \dir -> do
+  let component program = do
+        cgOverwriteFiles True
+        cgGenerateDriver False
+        program
+  _ <- compileToCLib (Just dir) "ownershipLibrary"
+    [("copyLists", component $ do
+        values <- cgInput "values" :: SBVCodeGen (SList Word16)
+        cgOutput "copy" values
+        cgReturn values)
+    , ("listArray", component $ do
+        values <- cgInput "values" :: SBVCodeGen (SList Word16)
+        cgReturn (constArray values :: SArray Word8 [Word16]))
+    , ("retainArray", component $ do
+        values <- cgInput "values" :: SBVCodeGen (SArray Word8 Word16)
+        cgReturn (writeArray values 0 42))
+    , ("readArrayValue", component $ do
+        values <- cgInput "values" :: SBVCodeGen (SArray Word8 Word16)
+        cgReturn (readArray values 1))
+    , ("exactOutputs", component $ do
+        value <- cgInput "value" :: SBVCodeGen SInteger
+        cgOutput "copy" (value + 1)
+        cgReturn (value + 2))
+    ]
+  compileAndRunCaller dir "ownershipLibrary" $ unlines
+    ["#include \"ownershipLibrary.h\""
+    , "#include <assert.h>"
+    , "typedef struct { unsigned references; SWord16 value; } Context;"
+    , "static unsigned live_contexts;"
+    , "static SWord16 lookup(const void *opaque, SWord8 key)"
+    , "{ const Context *context = opaque; return context->value + key; }"
+    , "static const void *retain(const void *opaque)"
+    , "{ Context *context = (Context *) opaque; ++context->references; return context; }"
+    , "static void release(const void *opaque)"
+    , "{ Context *context = (Context *) opaque; if (--context->references == 0) { --live_contexts; free(context); } }"
+    , "int main(void)"
+    , "{"
+    , "  mpz_t input, first, second; mpz_inits(input, first, second, NULL);"
+    , "  for (unsigned i = 0; i < 32; ++i) {"
+    , "    SWord16 data[] = {7, 11}; SBVList_u16 borrowed = {data, 2}, copy;"
+    , "    SBVList_u16 result = copyLists(borrowed, &copy);"
+    , "    data[0] = 99;"
+    , "    assert(copy.data[0] == 7 && result.data[0] == 7);"
+    , "    sbv_list_release_u16(&copy);"
+    , "    assert(result.data[1] == 11);"
+    , "    copy = copyLists(result, &borrowed);"
+    , "    sbv_list_release_u16(&result); sbv_list_release_u16(&borrowed);"
+    , "    SBVArrayOutput_2_u8_10_list_3_u16 array = listArray(copy);"
+    , "    sbv_list_release_u16(&copy);"
+    , "    SBVList_u16 read = sbv_array_output_read_2_u8_10_list_3_u16(array, 3);"
+    , "    SBVList_u16 saved = sbv_list_clone_u16(read);"
+    , "    sbv_array_output_release_2_u8_10_list_3_u16(&array);"
+    , "    assert(saved.length == 2 && saved.data[0] == 7); sbv_list_release_u16(&saved);"
+    , "    Context *context = malloc(sizeof *context); assert(context != NULL);"
+    , "    *context = (Context) {1, 17}; ++live_contexts;"
+    , "    SBVArrayInput_2_u8_3_u16 source = {lookup, context, retain, release};"
+    , "    assert(readArrayValue(source) == 18 && context->references == 1);"
+    , "    SBVArrayOutput_2_u8_3_u16 owned = retainArray(source);"
+    , "    release(context);"
+    , "    SBVArrayOutput_2_u8_3_u16 retained = sbv_array_output_retain_2_u8_3_u16(owned);"
+    , "    sbv_array_output_release_2_u8_3_u16(&owned);"
+    , "    assert(readArrayValue(sbv_array_output_as_input_2_u8_3_u16(retained)) == 18);"
+    , "    assert(sbv_array_output_read_2_u8_3_u16(retained, 0) == 42);"
+    , "    sbv_array_output_release_2_u8_3_u16(&retained); assert(live_contexts == 0);"
+    , "    mpz_set_ui(input, i); exactOutputs(input, first, second);"
+    , "    assert(mpz_cmp_ui(first, i + 1) == 0 && mpz_cmp_ui(second, i + 2) == 0);"
+    , "  }"
+    , "  mpz_clears(input, first, second, NULL); return 0;"
+    , "}"
+    ]
+
+-- | Compile and execute an independent C caller against a generated library.
+-- Use its Makefile so compiler overrides, dependencies, and runtime link flags
+-- match those used for the generated translation units.
+compileAndRunCaller :: FilePath -> String -> String -> Assertion
+compileAndRunCaller dir libraryName source = do
+  writeFile (dir </> "caller.c") source
+  writeFile (dir </> "caller.mk") $ unlines
+    ["caller: caller.c " ++ libraryName ++ ".h " ++ libraryName ++ ".a"
+    , "\t${CC} ${CCFLAGS} ${GMP_CFLAGS} caller.c " ++ libraryName ++ ".a ${LDFLAGS} ${SBV_LIBS} -o $@"
+    ]
+  makeOptions <- generatedMakeOptions dir
+  (makeExit, _, makeError) <- readProcessWithExitCode "make" (["-C", dir, "caller"] ++ makeOptions) ""
+  assertEqual makeError ExitSuccess makeExit
+  (runExit, _, runError) <- readProcessWithExitCode (dir </> "caller") [] ""
+  assertEqual runError ExitSuccess runExit
+
+-- | Library calls share the standalone fail-fast contract. Exercise both
+-- executable hard constraints and explicit assertions in separate processes.
+libraryRuntimeFailures :: Assertion
+libraryRuntimeFailures = mapM_ check [False, True]
+ where check assertion = withSystemTempDirectory "sbv-library-fail-fast" $ \dir -> do
+         _ <- compileToCLib (Just dir) "failFastLibrary"
+           [("checkedEntry", do cgOverwriteFiles True
+                                cgSetDriverValues [7]
+                                value <- cgInput "value" :: SBVCodeGen SWord8
+                                if assertion
+                                   then cgReturn (sAssert Nothing "library assertion" (value .< 5) value)
+                                   else do constrain (value .< 5)
+                                           cgReturn value)]
+         makeOptions <- generatedMakeOptions dir
+         (makeExit, _, makeError) <- readProcessWithExitCode "make" (["-C", dir] ++ makeOptions) ""
+         assertEqual makeError ExitSuccess makeExit
+         (runExit, _, runError) <- readProcessWithExitCode (dir </> "failFastLibrary_driver") [] ""
+         assertBool "Expected a failed library call to terminate the process" (runExit /= ExitSuccess)
+         let diagnostic = if assertion then "ASSERTION FAILED" else "CONSTRAINT FAILED"
+         assertBool runError (diagnostic `isInfixOf` runError)
+
+-- | Finite sums and products have complete universes even when constructors
+-- carry fields. Dynamic inputs prevent constant folding from hiding the C
+-- finite/cofinite comparison; both regular and complemented inputs are tested.
+finiteADTSetUniverses :: Assertion
+finiteADTSetUniverses = mapM_ check [1, 2]
+ where check seed = withSystemTempDirectory "sbv-finite-adt-sets" $ \dir -> do
+         let program = do
+               cgOverwriteFiles True
+               cgSetDriverValues [seed, seed]
+               simple <- cgInput "simple" :: SBVCodeGen (SSet (Maybe Bool))
+               nested <- cgInput "nested" :: SBVCodeGen (SSet (Maybe (Either Bool Bool), Bool))
+               let simpleUniverse = SS.fromList [Nothing, Just False, Just True]
+                   alternatives   = [Nothing, Just (Left False), Just (Left True), Just (Right False), Just (Right True)]
+                   nestedUniverse = SS.fromList [(value, flag) | value <- alternatives, flag <- [False, True]]
+                   simpleFull     = simple `SS.union` simpleUniverse
+                   nestedFull     = nested `SS.union` nestedUniverse
+               cgReturn (simpleFull .== SS.full .&& nestedFull .== SS.full .&& SS.full `SS.isSubsetOf` nestedFull)
+         outputText <- compileProgramAndRunGenerated dir "finiteADTUniverses" program
+         assertBool outputText ("= 1" `isInfixOf` outputText)
+
+-- | Compile and execute a scalar program using only the public compatibility
+-- module's code-generation interface.
+legacyPublicFacade :: Assertion
+legacyPublicFacade = withSystemTempDirectory "sbv-legacy-c-backend" $ \dir -> do
+  let programDir = dir </> "program"
+      libraryDir = dir </> "library"
+
+  PublicLegacy.compileToC (Just programDir) "legacyFacade" $ do
+    PublicLegacy.cgOverwriteFiles True
+    PublicLegacy.cgSetDriverValues [41]
+    value <- PublicLegacy.cgInput "value" :: PublicLegacy.SBVCodeGen SWord32
+    PublicLegacy.cgReturn (value + 1)
+
+  programOutput <- compileAndRunGenerated programDir "legacyFacade"
+  let expectedProgram = "0x0000002aUL"
+  assertBool ("Expected legacy generated output to contain " ++ expectedProgram ++ ", received:\n" ++ programOutput) (expectedProgram `isInfixOf` programOutput)
+
+  let component operation = do
+        PublicLegacy.cgOverwriteFiles True
+        PublicLegacy.cgSetDriverValues [41]
+        value <- PublicLegacy.cgInput "value" :: PublicLegacy.SBVCodeGen SWord32
+        PublicLegacy.cgReturn (operation value)
+  _ <- PublicLegacy.compileToCLib (Just libraryDir) "legacyLibrary"
+         [ ("increment", component (+ 1))
+         , ("twice", component (* 2))
+         ]
+  libraryOutput <- compileAndRunGenerated libraryDir "legacyLibrary"
+  let expectedLibrary = ["0x0000002aUL", "0x00000052UL"]
+  mapM_ (\expected -> assertBool ("Expected legacy library output to contain " ++ expected ++ ", received:\n" ++ libraryOutput) (expected `isInfixOf` libraryOutput)) expectedLibrary
+  (_, _, lowLevelProgram) <- PublicLegacy.compileToC' "legacyLowLevel" (component (+ 1))
+  (_, _, lowLevelLibrary) <- PublicLegacy.compileToCLib' "legacyLowLevelLibrary" [("increment", component (+ 1))]
+  assertBool "Public Legacy low-level entry points must generate bundles"
+             ("legacyLowLevel.c" `isInfixOf` show lowLevelProgram && "legacyLowLevelLibrary.a" `isInfixOf` show lowLevelLibrary)
+
+-- | Build and execute a generated C program or library driver with strict
+-- warnings so representation and ownership qualifier errors cannot pass silently.
+compileAndRunGenerated :: FilePath -> String -> IO String
+compileAndRunGenerated dir executableName = do
+  makeOptions <- generatedMakeOptions dir
+  (makeExit, _, makeError) <- readProcessWithExitCode "make" (["-C", dir] ++ makeOptions) ""
+  assertEqual makeError ExitSuccess makeExit
+  (runExit, outputText, runError) <- readProcessWithExitCode (dir </> executableName ++ "_driver") [] ""
+  assertEqual runError ExitSuccess runExit
+  pure outputText
+
+-- | Exercise Unicode and embedded-NUL literals, character-based indexing,
+-- string combinators, exact numeric conversions, printing, and owned results.
+characterStrings :: Assertion
+characterStrings = withSystemTempDirectory "sbv-character-strings" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [7, 1, 65]
+        value     <- cgInput "value"     :: SBVCodeGen SString
+        index     <- cgInput "index"     :: SBVCodeGen SInteger
+        character <- cgInput "character" :: SBVCodeGen SChar
+        let joined      = value SL.++ literal "\955\NUL"
+            numeric     = SL.replace value value (literal "123")
+            parsed      = SL.strToNat numeric
+            indexedChar = SL.elemAt joined index
+        cgOutput "length"         (SL.length joined)
+        cgOutput "lambdaIndex"    (SL.indexOf joined (literal "\955"))
+        cgOutput "contains"       (literal "v7" `SL.isInfixOf` joined)
+        cgOutput "prefix"         (literal "sbv" `SL.isPrefixOf` joined)
+        cgOutput "suffix"         (literal "\955\NUL" `SL.isSuffixOf` joined)
+        cgOutput "sameObject"     (value .=== value)
+        cgOutput "ordered"        (value .< joined)
+        cgOutput "slice"          (SL.subList joined 3 2)
+        cgOutput "replacement"    (SL.replace joined (literal "bv") (literal "X"))
+        cgOutput "indexedChar"    indexedChar
+        cgOutput "characterCode"  (SC.ord indexedChar)
+        cgOutput "roundTripChar"  (SC.chr (SC.ord indexedChar))
+        cgOutput "inputCharacter" character
+        cgOutput "parsed"         parsed
+        cgOutput "rendered"       (SL.natToStr (parsed + 1))
+        cgReturn joined
+
+  stdoutText <- compileProgramAndRunGenerated dir "characterStrings" program
+  headerText <- readFile (dir </> "characterStrings.h")
+  mapM_ (\fragment -> assertBool ("Expected generated text output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ ") =sbv7\955\NUL"
+    , "length =6"
+    , "lambdaIndex =4"
+    , "contains = 1"
+    , "prefix = 1"
+    , "suffix = 1"
+    , "sameObject = 1"
+    , "ordered = 1"
+    , "slice =7\955"
+    , "replacement =sX7\955\NUL"
+    , "indexedChar =b"
+    , "characterCode =98"
+    , "roundTripChar =b"
+    , "inputCharacter =a"
+    , "parsed =123"
+    , "rendered =124"
+    ]
+  assertBool "Expected a length-aware public string descriptor"
+             ("size_t byte_length;" `isInfixOf` headerText && "size_t length;" `isInfixOf` headerText)
+  assertBool "Expected public string ownership helpers"
+             ("sbv_string_clone" `isInfixOf` headerText && "sbv_string_release" `isInfixOf` headerText)
+
+-- | Exercise string indices and numeric conversions when the user explicitly
+-- selects the historical lossy native mapping for 'SInteger'.
+mappedIntegerStrings :: Assertion
+mappedIntegerStrings = withSystemTempDirectory "sbv-mapped-integer-strings" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgIntegerSize 64
+        cgSetDriverValues [42, 1]
+        value <- cgInput "value" :: SBVCodeGen SString
+        index <- cgInput "index" :: SBVCodeGen SInteger
+        cgOutput "selected" (SL.elemAt value index)
+        cgOutput "numeric"  (SL.strToNat (SL.replace value value (literal "99")))
+        cgReturn (SL.natToStr (SL.length value + 1))
+
+  stdoutText <- compileProgramAndRunGenerated dir "mappedIntegerStrings" program
+  mapM_ (\fragment -> assertBool ("Expected mapped-integer text output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ ") =6"
+    , "selected =b"
+    , "numeric = 99LL"
+    ]
+
+-- | Exercise guarded string declarations and independent owned returns from
+-- multiple generated library translation units.
+ownedStringLibrary :: Assertion
+ownedStringLibrary = withSystemTempDirectory "sbv-owned-string-library" $ \dir -> do
+  let component suffix seed = do
+        cgOverwriteFiles True
+        cgSetDriverValues [seed]
+        value <- cgInput "value" :: SBVCodeGen SString
+        cgReturn (value SL.++ suffix)
+
+  (_, cfg, bundle) <- compileToCLib' "ownedStringLibrary"
+    [ ("firstText",  component (literal "\955") 4)
+    , ("secondText", component (literal "!") 5)
+    ]
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  stdoutText <- compileAndRunGenerated dir "ownedStringLibrary"
+  assertBool ("Expected both owned string results, received:\n" ++ stdoutText)
+             ("sbv4\955" `isInfixOf` stdoutText && "sbv5!" `isInfixOf` stdoutText)
+
+-- | Exercise the primitive symbolic-list operations, exact indices, borrowed
+-- inputs, and independently owned output and return values.
+symbolicLists :: Assertion
+symbolicLists = withSystemTempDirectory "sbv-symbolic-lists" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [10, 1]
+        values <- cgInput "values" :: SBVCodeGen (SList Word16)
+        index  <- cgInput "index"  :: SBVCodeGen SInteger
+        let suffix      = literal ([99, 100] :: [Word16])
+            joined      = values SL.++ suffix
+            contains    = suffix `SL.isInfixOf` joined
+            slice       = SL.subList joined 2 2
+            replaced    = SL.replace joined (literal ([11, 12] :: [Word16])) (SL.singleton 77)
+        cgOutput "length"      (SL.length joined)
+        cgOutput "selected"    (SL.elemAt joined index)
+        cgOutput "suffixIndex" (SL.indexOf joined suffix)
+        cgOutput "contains"    contains
+        cgOutput "prefix"      (values `SL.isPrefixOf` joined)
+        cgOutput "suffix"      (suffix `SL.isSuffixOf` joined)
+        cgOutput "sameObject"  (values .=== values)
+        cgOutput "different"   (values ./== suffix)
+        cgOutput "conditional" (ite contains joined values)
+        cgOutput "slice"       slice
+        cgOutput "replaced"    replaced
+        cgReturn joined
+
+  stdoutText <- compileProgramAndRunGenerated dir "symbolicLists" program
+  headerText <- readFile (dir </> "symbolicLists.h")
+  mapM_ (\fragment -> assertBool ("Expected generated list output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ ") =[0x000aU, 0x000bU, 0x000cU, 0x0063U, 0x0064U]"
+    , "length =5"
+    , "selected = 0x000bU"
+    , "suffixIndex =3"
+    , "contains = 1"
+    , "prefix = 1"
+    , "suffix = 1"
+    , "sameObject = 1"
+    , "different = 1"
+    , "conditional =[0x000aU, 0x000bU, 0x000cU, 0x0063U, 0x0064U]"
+    , "slice =[0x000cU, 0x0063U]"
+    , "replaced =[0x000aU, 0x004dU, 0x0063U, 0x0064U]"
+    ]
+  assertBool "Expected a typed public list descriptor"
+             ("struct SBVList_u16 { const SWord16 *data; size_t length; };" `isInfixOf` headerText)
+  assertBool "Expected public list ownership helpers"
+             ("sbv_list_clone_u16" `isInfixOf` headerText && "sbv_list_release_u16" `isInfixOf` headerText)
+
+-- | Check that list descriptors remain agnostic to element width by compiling
+-- and executing a list whose elements use the arbitrary-width bit-vector ABI.
+wideSymbolicLists :: Assertion
+wideSymbolicLists = withSystemTempDirectory "sbv-wide-symbolic-lists" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [1]
+        values <- cgInput "values" :: SBVCodeGen (SList (WordN 673))
+        cgOutput "length" (SL.length values)
+        cgReturn values
+
+  stdoutText <- compileProgramAndRunGenerated dir "wideSymbolicLists" program
+  headerText <- readFile (dir </> "wideSymbolicLists.h")
+  assertBool ("Expected the wide-list driver to report its three sample elements, received:\n" ++ stdoutText)
+             ("length =3" `isInfixOf` stdoutText)
+  assertBool "Expected an arbitrary-width typed list descriptor"
+             ("struct SBVList_u673 { const SWord673 *data; size_t length; };" `isInfixOf` headerText)
+
+-- | Check that arbitrary floating-point elements retain their raw interchange
+-- representation and use the LibBF-backed object-equality semantics.
+arbitraryFloatLists :: Assertion
+arbitraryFloatLists = do
+  (_, _, bundle) <- compileToC' "arbitraryFloatLists" $ do
+    cgSetDriverValues [1]
+    values <- cgInput "values" :: SBVCodeGen (SList (FloatingPoint 7 19))
+    cgOutput "sameObject" (values .=== values)
+    cgReturn values
+  let generated = show bundle
+  assertBool "Expected a typed arbitrary-float list descriptor"
+             ("struct SBVList_fp_e7_s19 { const SFP7_19 *data; size_t length; };" `isInfixOf` generated)
+  assertBool "Expected arbitrary-float list equality to use object equality"
+             ("sbv_fp_e7_s19_obj_eq(left, right)" `isInfixOf` generated)
+
+-- | Check that native floating-point list equality treats NaNs as identical
+-- objects while distinguishing positive and negative zero.
+nativeFloatLists :: Assertion
+nativeFloatLists = withSystemTempDirectory "sbv-native-float-lists" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [0x7fc00000, 0x00000000, 0x80000000]
+        nanBits      <- cgInput "nanBits"      :: SBVCodeGen SWord32
+        positiveBits <- cgInput "positiveBits" :: SBVCodeGen SWord32
+        negativeBits <- cgInput "negativeBits" :: SBVCodeGen SWord32
+        let nanList      = SL.singleton (sWord32AsSFloat nanBits)
+            positiveList = SL.singleton (sWord32AsSFloat positiveBits)
+            negativeList = SL.singleton (sWord32AsSFloat negativeBits)
+        cgOutput "nanSameObject" (nanList .=== nanList)
+        cgOutput "zeroObjectsDiffer" (positiveList ./== negativeList)
+        cgReturn (nanList SL.++ positiveList)
+
+  stdoutText <- compileProgramAndRunGenerated dir "nativeFloatLists" program
+  assertBool ("Expected native floating-point list object equality, received:\n" ++ stdoutText)
+             ("nanSameObject = 1" `isInfixOf` stdoutText && "zeroObjectsDiffer = 1" `isInfixOf` stdoutText)
+
+-- | Exercise lists after explicitly selecting the historical native mappings
+-- for unbounded integers and reals, including declaration dependency order.
+mappedNumericLists :: Assertion
+mappedNumericLists = withSystemTempDirectory "sbv-mapped-numeric-lists" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgIntegerSize 64
+        cgSRealType CgDouble
+        cgSetDriverValues [7, 9]
+        integers <- cgInput "integers" :: SBVCodeGen (SList Integer)
+        reals    <- cgInput "reals"    :: SBVCodeGen (SList AlgReal)
+        cgOutput "integerLength" (SL.length integers)
+        cgOutput "realSameObject" (reals .=== reals)
+        cgReturn integers
+
+  stdoutText <- compileProgramAndRunGenerated dir "mappedNumericLists" program
+  mapM_ (\fragment -> assertBool ("Expected mapped-numeric list output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ "integerLength = 3LL"
+    , "realSameObject = 1"
+    , "[7LL, 8LL, 9LL]"
+    ]
+
+-- | Exercise guarded list declarations and independent owned returns from
+-- multiple generated library translation units.
+ownedListLibrary :: Assertion
+ownedListLibrary = withSystemTempDirectory "sbv-owned-list-library" $ \dir -> do
+  let component suffix seed = do
+        cgOverwriteFiles True
+        cgSetDriverValues [seed]
+        values <- cgInput "values" :: SBVCodeGen (SList Word16)
+        cgReturn (values SL.++ literal suffix)
+
+  (_, cfg, bundle) <- compileToCLib' "ownedListLibrary"
+    [ ("firstList",  component ([40] :: [Word16]) 4)
+    , ("secondList", component ([50] :: [Word16]) 5)
+    ]
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  stdoutText <- compileAndRunGenerated dir "ownedListLibrary"
+  assertBool ("Expected both owned list results, received:\n" ++ stdoutText)
+             ("[0x0004U, 0x0005U, 0x0006U, 0x0028U]" `isInfixOf` stdoutText
+           && "[0x0005U, 0x0006U, 0x0007U, 0x0032U]" `isInfixOf` stdoutText)
+
+-- | Exercise borrowed exact elements, exact indexing and comparison, list
+-- operations, and deep-cloned list results across the generated C ABI.
+exactGMPLists :: Assertion
+exactGMPLists = withSystemTempDirectory "sbv-exact-gmp-lists" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [10, 20, 30, 1]
+        integers  <- cgInput "integers"  :: SBVCodeGen (SList Integer)
+        reals     <- cgInput "reals"     :: SBVCodeGen (SList AlgReal)
+        rationals <- cgInput "rationals" :: SBVCodeGen (SList Rational)
+        index     <- cgInput "index"     :: SBVCodeGen SInteger
+        let joinedIntegers  = integers  SL.++ literal ([13, 14] :: [Integer])
+            joinedReals     = reals     SL.++ literal ([23, 24] :: [AlgReal])
+            joinedRationals = rationals SL.++ literal ([33, 34] :: [Rational])
+        cgOutput "length"           (SL.length joinedIntegers)
+        cgOutput "selectedInteger"  (SL.elemAt joinedIntegers index)
+        cgOutput "selectedReal"     (SL.elemAt joinedReals index)
+        cgOutput "selectedRational" (SL.elemAt joinedRationals index)
+        cgOutput "outOfRange"       (SL.elemAt joinedRationals 99)
+        cgOutput "sameIntegers"     (joinedIntegers .== literal ([10, 11, 12, 13, 14] :: [Integer]))
+        cgOutput "realSlice"        (SL.subList joinedReals 1 3)
+        cgOutput "rationalResult"   joinedRationals
+        cgReturn joinedIntegers
+
+  stdoutText <- compileProgramAndRunGenerated dir "exactGMPLists" program
+  headerText <- readFile (dir </> "exactGMPLists.h")
+  mapM_ (\fragment -> assertBool ("Expected exact-list output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ ") =[10, 11, 12, 13, 14]"
+    , "length =5"
+    , "selectedInteger =11"
+    , "selectedReal =21"
+    , "selectedRational =31"
+    , "outOfRange =0"
+    , "sameIntegers = 1"
+    , "realSlice =[21, 22, 23]"
+    , "rationalResult =[30, 31, 32, 33, 34]"
+    ]
+  assertBool "Expected exact list ownership to clone and clear individual GMP elements"
+             ("mpz_init_set(element, value.data[i]);" `isInfixOf` headerText
+           && "mpz_clear(element); free(element);" `isInfixOf` headerText
+           && "mpq_set(element, value.data[i]);" `isInfixOf` headerText
+           && "mpq_clear(element); free(element);" `isInfixOf` headerText)
+
+-- | Exercise finite and cofinite symbolic sets, normalization, every primitive
+-- set operation, and independently owned outputs and returns.
+symbolicSets :: Assertion
+symbolicSets = withSystemTempDirectory "sbv-symbolic-sets" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [10, 12, 11, 13]
+        left       <- cgInput "left"       :: SBVCodeGen (SSet Word16)
+        right      <- cgInput "right"      :: SBVCodeGen (SSet Word16)
+        cofinite   <- cgInput "cofinite"   :: SBVCodeGen (SSet Word16)
+        element    <- cgInput "element"    :: SBVCodeGen SWord16
+        let inserted             = SS.insert element left
+            deleted              = SS.delete 11 inserted
+            unioned              = SS.union left right
+            intersected          = SS.intersection left right
+            subtracted           = SS.difference left right
+            mixedUnion           = SS.union left cofinite
+            mixedIntersection    = SS.intersection left cofinite
+            cofiniteDifference   = SS.difference cofinite left
+            cofiniteInserted     = SS.insert 12 cofinite
+            cofiniteDeleted      = SS.delete 14 cofinite
+            otherCofinite        = SS.complement right
+            cofiniteUnion        = SS.union cofinite otherCofinite
+            cofiniteIntersection = SS.intersection cofinite otherCofinite
+            cofiniteSubtraction  = SS.difference cofinite otherCofinite
+            containsElement      = element `SS.member` unioned
+            conditional          = ite containsElement intersected subtracted
+        cgOutput "inserted"             inserted
+        cgOutput "deleted"              deleted
+        cgOutput "unioned"              unioned
+        cgOutput "intersected"          intersected
+        cgOutput "subtracted"           subtracted
+        cgOutput "mixedUnion"           mixedUnion
+        cgOutput "mixedIntersection"    mixedIntersection
+        cgOutput "cofiniteDifference"   cofiniteDifference
+        cgOutput "cofiniteInserted"     cofiniteInserted
+        cgOutput "cofiniteDeleted"      cofiniteDeleted
+        cgOutput "cofiniteUnion"        cofiniteUnion
+        cgOutput "cofiniteIntersection" cofiniteIntersection
+        cgOutput "cofiniteSubtraction"  cofiniteSubtraction
+        cgOutput "complemented"         (SS.complement left)
+        cgOutput "containsElement"      containsElement
+        cgOutput "subset"               (intersected `SS.isSubsetOf` left)
+        cgOutput "sameObject"           (left .=== left)
+        cgOutput "different"            (left ./== right)
+        cgOutput "conditional"          conditional
+        cgReturn unioned
+
+  stdoutText <- compileProgramAndRunGenerated dir "symbolicSets" program
+  headerText <- readFile (dir </> "symbolicSets.h")
+  mapM_ (\fragment -> assertBool ("Expected generated set output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ ") ={0x000aU, 0x000bU, 0x000cU, 0x000dU, 0x000eU}"
+    , "inserted ={0x000aU, 0x000bU, 0x000cU, 0x000dU}"
+    , "deleted ={0x000aU, 0x000cU, 0x000dU}"
+    , "unioned ={0x000aU, 0x000bU, 0x000cU, 0x000dU, 0x000eU}"
+    , "intersected ={0x000cU}"
+    , "subtracted ={0x000aU, 0x000bU}"
+    , "mixedUnion =U - {0x000dU}"
+    , "mixedIntersection ={0x000aU}"
+    , "cofiniteDifference =U - {0x000bU, 0x000cU, 0x000dU, 0x000aU}"
+    , "cofiniteInserted =U - {0x000bU, 0x000dU}"
+    , "cofiniteDeleted =U - {0x000bU, 0x000cU, 0x000dU, 0x000eU}"
+    , "cofiniteUnion =U - {0x000cU, 0x000dU}"
+    , "cofiniteIntersection =U - {0x000bU, 0x000cU, 0x000dU, 0x000eU}"
+    , "cofiniteSubtraction ={0x000eU}"
+    , "complemented =U - {0x000aU, 0x000bU, 0x000cU}"
+    , "containsElement = 1"
+    , "subset = 1"
+    , "sameObject = 1"
+    , "different = 1"
+    , "conditional ={0x000cU}"
+    ]
+  assertBool "Expected a finite/cofinite public set descriptor"
+             ("struct SBVSet_u16 { const SWord16 *data; size_t length; bool is_complement; };" `isInfixOf` headerText)
+  assertBool "Expected public set ownership helpers"
+             ("sbv_set_clone_u16" `isInfixOf` headerText && "sbv_set_release_u16" `isInfixOf` headerText)
+
+-- | Check equality and subset relations when regular and complemented forms
+-- denote the same set over the complete Boolean universe.
+finiteUniverseSets :: Assertion
+finiteUniverseSets = withSystemTempDirectory "sbv-finite-universe-sets" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [0]
+        inputFull <- cgInput "inputFull" :: SBVCodeGen (SSet Bool)
+        let regularTrue   = SS.fromList [True]
+            cofiniteFalse = SS.complement (SS.fromList [False])
+            regularFull   = SS.fromList [False, True]
+            universal     = SS.full :: SSet Bool
+        cgOutput "sameSingleton"   (regularTrue .== cofiniteFalse)
+        cgOutput "sameUniverse"    (regularFull .== universal)
+        cgOutput "leftSubset"      (regularTrue `SS.isSubsetOf` cofiniteFalse)
+        cgOutput "rightSubset"     (cofiniteFalse `SS.isSubsetOf` regularTrue)
+        cgOutput "normalizedInput" (inputFull .== universal)
+        cgReturn (regularTrue .== cofiniteFalse .&& regularFull .== universal .&& inputFull .== universal)
+
+  stdoutText <- compileProgramAndRunGenerated dir "finiteUniverseSets" program
+  mapM_ (\fragment -> assertBool ("Expected finite-universe set output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ ") = 1"
+    , "sameSingleton = 1"
+    , "sameUniverse = 1"
+    , "leftSubset = 1"
+    , "rightSubset = 1"
+    , "normalizedInput = 1"
+    ]
+
+-- | Check that set descriptors remain agnostic to element width by compiling
+-- and executing insert and membership over 673-bit elements.
+wideSymbolicSets :: Assertion
+wideSymbolicSets = withSystemTempDirectory "sbv-wide-symbolic-sets" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [10, 13]
+        values  <- cgInput "values"  :: SBVCodeGen (SSet (WordN 673))
+        element <- cgInput "element" :: SBVCodeGen (SWord 673)
+        let updated = SS.insert element values
+        cgOutput "contains" (element `SS.member` updated)
+        cgReturn updated
+
+  stdoutText <- compileProgramAndRunGenerated dir "wideSymbolicSets" program
+  headerText <- readFile (dir </> "wideSymbolicSets.h")
+  assertBool ("Expected arbitrary-width set membership to hold, received:\n" ++ stdoutText)
+             ("contains = 1" `isInfixOf` stdoutText)
+  assertBool "Expected an arbitrary-width typed set descriptor"
+             ("struct SBVSet_u673 { const SWord673 *data; size_t length; bool is_complement; };" `isInfixOf` headerText)
+
+-- | Exercise character elements through the shared scalar text representation
+-- without requiring string ownership inside the set descriptor.
+characterSets :: Assertion
+characterSets = withSystemTempDirectory "sbv-character-sets" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [64, 70]
+        values    <- cgInput "values"    :: SBVCodeGen (SSet Char)
+        character <- cgInput "character" :: SBVCodeGen SChar
+        let updated = SS.insert character values
+        cgOutput "contains" (character `SS.member` updated)
+        cgReturn updated
+
+  stdoutText <- compileProgramAndRunGenerated dir "characterSets" program
+  headerText <- readFile (dir </> "characterSets.h")
+  assertBool ("Expected character-set membership to hold, received:\n" ++ stdoutText)
+             ("contains = 1" `isInfixOf` stdoutText)
+  assertBool "Expected a typed character set descriptor"
+             ("struct SBVSet_char { const SChar *data; size_t length; bool is_complement; };" `isInfixOf` headerText)
+
+-- | Check that arbitrary floating-point set elements retain their raw
+-- interchange representation and use LibBF-backed object equality.
+arbitraryFloatSets :: Assertion
+arbitraryFloatSets = do
+  (_, _, bundle) <- compileToC' "arbitraryFloatSets" $ do
+    cgSetDriverValues [1]
+    values <- cgInput "values" :: SBVCodeGen (SSet (FloatingPoint 7 19))
+    cgOutput "sameObject" (values .=== values)
+    cgReturn values
+  let generated = show bundle
+  assertBool "Expected a typed arbitrary-float set descriptor"
+             ("struct SBVSet_fp_e7_s19 { const SFP7_19 *data; size_t length; bool is_complement; };" `isInfixOf` generated)
+  assertBool "Expected arbitrary-float set equality to use object equality"
+             ("sbv_fp_e7_s19_obj_eq(left, right)" `isInfixOf` generated)
+
+-- | Check that native floating-point set operations treat NaNs as identical
+-- objects while distinguishing positive and negative zero.
+nativeFloatSets :: Assertion
+nativeFloatSets = withSystemTempDirectory "sbv-native-float-sets" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [0x7fc00000, 0x00000000, 0x80000000]
+        nanBits      <- cgInput "nanBits"      :: SBVCodeGen SWord32
+        positiveBits <- cgInput "positiveBits" :: SBVCodeGen SWord32
+        negativeBits <- cgInput "negativeBits" :: SBVCodeGen SWord32
+        let nanValue      = sWord32AsSFloat nanBits
+            positiveValue = sWord32AsSFloat positiveBits
+            negativeValue = sWord32AsSFloat negativeBits
+            nanSet        = SS.singleton nanValue
+            positiveSet   = SS.singleton positiveValue
+            negativeSet   = SS.singleton negativeValue
+        cgOutput "nanMember" (nanValue `SS.member` nanSet)
+        cgOutput "zeroObjectsDiffer" (positiveSet ./== negativeSet)
+        cgReturn (SS.union nanSet positiveSet)
+
+  stdoutText <- compileProgramAndRunGenerated dir "nativeFloatSets" program
+  assertBool ("Expected native floating-point set object equality, received:\n" ++ stdoutText)
+             ("nanMember = 1" `isInfixOf` stdoutText && "zeroObjectsDiffer = 1" `isInfixOf` stdoutText)
+
+-- | Exercise sets after explicitly selecting the historical native mappings
+-- for unbounded integers and reals.
+mappedNumericSets :: Assertion
+mappedNumericSets = withSystemTempDirectory "sbv-mapped-numeric-sets" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgIntegerSize 64
+        cgSRealType CgDouble
+        cgSetDriverValues [8, 10]
+        integers <- cgInput "integers" :: SBVCodeGen (SSet Integer)
+        reals    <- cgInput "reals"    :: SBVCodeGen (SSet AlgReal)
+        cgOutput "integerMember" (8 `SS.member` integers)
+        cgOutput "realSameObject" (reals .=== reals)
+        cgReturn integers
+
+  stdoutText <- compileProgramAndRunGenerated dir "mappedNumericSets" program
+  mapM_ (\fragment -> assertBool ("Expected mapped-numeric set output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ "integerMember = 1"
+    , "realSameObject = 1"
+    , "{8LL, 9LL, 10LL}"
+    ]
+
+-- | Exercise guarded set declarations and independent owned returns from
+-- multiple generated library translation units.
+ownedSetLibrary :: Assertion
+ownedSetLibrary = withSystemTempDirectory "sbv-owned-set-library" $ \dir -> do
+  let component element seed = do
+        cgOverwriteFiles True
+        cgSetDriverValues [seed]
+        values <- cgInput "values" :: SBVCodeGen (SSet Word16)
+        cgReturn (SS.insert element values)
+
+  (_, cfg, bundle) <- compileToCLib' "ownedSetLibrary"
+    [ ("firstSet",  component 40 4)
+    , ("secondSet", component 50 6)
+    ]
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  stdoutText <- compileAndRunGenerated dir "ownedSetLibrary"
+  assertBool ("Expected both owned set results, received:\n" ++ stdoutText)
+             ("{0x0004U, 0x0005U, 0x0006U, 0x0028U}" `isInfixOf` stdoutText
+           && "{0x0006U, 0x0007U, 0x0008U, 0x0032U}" `isInfixOf` stdoutText)
+
+-- | Exercise exact-value normalization and comparison, finite/cofinite set
+-- algebra, and deep-cloned exact set results across the generated C ABI.
+exactGMPSets :: Assertion
+exactGMPSets = withSystemTempDirectory "sbv-exact-gmp-sets" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [10, 12, 11, 20, 30]
+        left      <- cgInput "left"      :: SBVCodeGen (SSet Integer)
+        right     <- cgInput "right"     :: SBVCodeGen (SSet Integer)
+        cofinite  <- cgInput "cofinite"  :: SBVCodeGen (SSet Integer)
+        reals     <- cgInput "reals"     :: SBVCodeGen (SSet AlgReal)
+        rationals <- cgInput "rationals" :: SBVCodeGen (SSet Rational)
+        let unioned        = SS.union left right
+            inserted       = SS.insert 13 left
+            intersected    = SS.intersection left right
+            mixedUnion     = SS.union left cofinite
+            realResult     = SS.insert 23 reals
+            rationalResult = SS.delete 31 rationals
+        cgOutput "sameIntegers"   (left .== SS.fromList [10, 11, 12])
+        cgOutput "member"         (13 `SS.member` unioned)
+        cgOutput "inserted"       inserted
+        cgOutput "intersected"    intersected
+        cgOutput "mixedUnion"     mixedUnion
+        cgOutput "realMember"     (21 `SS.member` reals)
+        cgOutput "rationalMember" (31 `SS.member` rationals)
+        cgOutput "realResult"     realResult
+        cgOutput "rationalResult" rationalResult
+        cgReturn unioned
+
+  stdoutText <- compileProgramAndRunGenerated dir "exactGMPSets" program
+  headerText <- readFile (dir </> "exactGMPSets.h")
+  mapM_ (\fragment -> assertBool ("Expected exact-set output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ ") ={10, 11, 12, 13, 14}"
+    , "sameIntegers = 1"
+    , "member = 1"
+    , "inserted ={10, 11, 12, 13}"
+    , "intersected ={12}"
+    , "mixedUnion =U - {13}"
+    , "realMember = 1"
+    , "rationalMember = 1"
+    , "realResult ={20, 21, 22, 23}"
+    , "rationalResult ={30, 32}"
+    ]
+  assertBool "Expected exact set ownership to clone and clear individual GMP elements"
+             ("mpz_init_set(element, value.data[i]);" `isInfixOf` headerText
+           && "mpz_clear(element); free(element);" `isInfixOf` headerText
+           && "mpq_set(element, value.data[i]);" `isInfixOf` headerText
+           && "mpq_clear(element); free(element);" `isInfixOf` headerText)
+
+-- | Exercise exact symbolic-rational construction, decomposition, arithmetic,
+-- comparison, arbitrary-width conversion, and caller-owned results.
+exactSymbolicRationals :: Assertion
+exactSymbolicRationals = withSystemTempDirectory "sbv-exact-symbolic-rationals" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [2, 5, 3, 7, 1]
+        input    <- cgInput "input"       :: SBVCodeGen SRational
+        top      <- cgInput "numerator"   :: SBVCodeGen SInteger
+        bot      <- cgInput "denominator" :: SBVCodeGen SInteger
+        wide     <- cgInput "wide"        :: SBVCodeGen (SWord 673)
+        selector <- cgInput "selector"    :: SBVCodeGen SWord8
+        let constructed = top .% bot
+            summed      = input + constructed
+            multiplied  = input * constructed
+            divided     = constructed / input
+            converted   = sFromIntegral wide :: SRational
+            paired      = tuple (constructed, summed)
+            wrapped     = sCGOne constructed :: SCodeGenADT Rational
+            rationalMap = writeArray (constArray input :: SArray Word8 Rational) 1 constructed
+            stored      = readArray rationalMap 1
+            keyed       = readArray (writeArray (constArray (9 :: SWord8) :: SArray Rational Word8) constructed 7) constructed
+            fiveThirds  = 5 / 3 :: SRational
+            selected    = select [constructed, summed] input selector
+        cgOutput "constructed" constructed
+        cgOutput "summed"      summed
+        cgOutput "multiplied"  multiplied
+        cgOutput "divided"     divided
+        cgOutput "ordered"     (constructed .< summed)
+        cgOutput "converted"   converted
+        cgOutput "paired"      paired
+        cgOutput "wrapped"     wrapped
+        cgOutput "stored"      stored
+        cgOutput "rationalMap" rationalMap
+        cgOutput "keyed"       keyed
+        cgOutput "sameValue"   (constructed .== fiveThirds)
+        cgOutput "wrappedSame" (wrapped .== wrapped)
+        cgOutput "selected"    selected
+        cgReturn summed
+
+  stdoutText <- compileProgramAndRunGenerated dir "exactSymbolicRationals" program
+  headerText <- readFile (dir </> "exactSymbolicRationals.h")
+  mapM_ (\fragment -> assertBool ("Expected exact-rational output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ ") =11/3"
+    , "constructed =5/3"
+    , "summed =11/3"
+    , "multiplied =10/3"
+    , "divided =5/6"
+    , "ordered = 1"
+    , "converted =7"
+    , "paired =(5/3, 11/3)"
+    , "wrapped =CGOne(5/3)"
+    , "stored =5/3"
+    , "rationalMap[0] =2"
+    , "keyed = 7"
+    , "sameValue = 1"
+    , "wrappedSame = 1"
+    , "selected =11/3"
+    ]
+  assertBool "Expected a public exact-rational input type"
+             ("typedef mpq_srcptr SRational;" `isInfixOf` headerText)
+  assertBool "Expected caller-owned exact-rational output and return parameters"
+             ("mpq_ptr constructed" `isInfixOf` headerText && "mpq_ptr sbv_result" `isInfixOf` headerText)
+
+-- | Exercise exact rationals when their symbolic numerator and denominator
+-- operations use an explicitly selected bounded SInteger representation.
+mappedIntegerRationals :: Assertion
+mappedIntegerRationals = withSystemTempDirectory "sbv-mapped-integer-rationals" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgIntegerSize 16
+        cgSetDriverValues [2, 5, 3]
+        input <- cgInput "input"       :: SBVCodeGen SRational
+        top   <- cgInput "numerator"   :: SBVCodeGen SInteger
+        bot   <- cgInput "denominator" :: SBVCodeGen SInteger
+        let constructed = top .% bot
+        cgOutput "constructed" constructed
+        cgOutput "converted"   (sFromIntegral top :: SRational)
+        cgOutput "asReal"      (sRationalToSReal constructed)
+        cgReturn (input + constructed)
+
+  stdoutText <- compileProgramAndRunGenerated dir "mappedIntegerRationals" program
+  mapM_ (\fragment -> assertBool ("Expected mapped-integer rational output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ ") =11/3"
+    , "constructed =5/3"
+    , "converted =5"
+    , "asReal =5/3"
+    ]
+
+-- | Exercise mapped integer divisibility for an ordinary divisor, the
+-- absolute value of the minimum signed integer, and an unrepresentable
+-- divisor whose only representable multiple is zero.
+mappedIntegerDivisibility :: Assertion
+mappedIntegerDivisibility = withSystemTempDirectory "sbv-mapped-integer-divisibility" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgIntegerSize 8
+        cgSetDriverValues [-126, -128, 0, 127]
+        multiple  <- cgInput "multiple" :: SBVCodeGen SInteger
+        minValue  <- cgInput "minimum"  :: SBVCodeGen SInteger
+        zeroValue <- cgInput "zero"     :: SBVCodeGen SInteger
+        maxValue  <- cgInput "maximum"  :: SBVCodeGen SInteger
+        cgReturn $ sDivides 3 multiple
+               .&& sDivides 128 minValue
+               .&& sDivides 129 zeroValue
+               .&& sNot (sDivides 128 multiple)
+               .&& sNot (sDivides 129 maxValue)
+
+  stdoutText <- compileProgramAndRunGenerated dir "mappedIntegerDivisibility" program
+  assertBool ("Expected mapped integer divisibility to succeed, received:\n" ++ stdoutText)
+             (") = 1" `isInfixOf` stdoutText)
+
+-- | Exercise every supported mapped-real transcendental operation across
+-- the @float@, @double@, and @long double@ C representations.
+mappedRealNonLinearOperations :: Assertion
+mappedRealNonLinearOperations = withSystemTempDirectory "sbv-mapped-real-non-linear" $ \dir -> do
+  let program realType = do
+        cgOverwriteFiles True
+        cgSRealType realType
+        cgSetDriverValues [0, 1, 2, 3, 4]
+        zeroValue  <- cgInput "zero"  :: SBVCodeGen SReal
+        oneValue   <- cgInput "one"   :: SBVCodeGen SReal
+        twoValue   <- cgInput "two"   :: SBVCodeGen SReal
+        threeValue <- cgInput "three" :: SBVCodeGen SReal
+        fourValue  <- cgInput "four"  :: SBVCodeGen SReal
+        cgReturn $ sin zeroValue  .== 0
+               .&& cos zeroValue  .== 1
+               .&& tan zeroValue  .== 0
+               .&& asin zeroValue .== 0
+               .&& acos oneValue  .== 0
+               .&& atan zeroValue .== 0
+               .&& sqrt fourValue .== 2
+               .&& sinh zeroValue .== 0
+               .&& cosh zeroValue .== 1
+               .&& tanh zeroValue .== 0
+               .&& exp zeroValue  .== 1
+               .&& log oneValue   .== 0
+               .&& twoValue ** threeValue .== 8
+
+      mappings = [("float", CgFloat), ("double", CgDouble), ("longDouble", CgLongDouble)]
+
+      runMapping (suffix, realType) = do
+        let executableName = "mappedRealNonLinear" ++ suffix
+        stdoutText <- compileProgramAndRunGenerated dir executableName (program realType)
+        assertBool ("Expected " ++ suffix ++ " non-linear operations to succeed, received:\n" ++ stdoutText)
+                   (") = 1" `isInfixOf` stdoutText)
+
+  mapM_ runMapping mappings
+
+-- | Exercise mapped integer exponentiation with modular overflow, negative
+-- exponents, signed units, and the @0 ** 0@ boundary.
+mappedIntegerExponentiation :: Assertion
+mappedIntegerExponentiation = withSystemTempDirectory "sbv-mapped-integer-exponentiation" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgIntegerSize 8
+        cgSetDriverValues [3, 5, -1, -3, 2, 0, 0]
+        base             <- cgInput "base"             :: SBVCodeGen SInteger
+        exponentValue    <- cgInput "exponent"         :: SBVCodeGen SInteger
+        negativeUnit     <- cgInput "negativeUnit"     :: SBVCodeGen SInteger
+        negativeExponent <- cgInput "negativeExponent" :: SBVCodeGen SInteger
+        positiveBase     <- cgInput "positiveBase"     :: SBVCodeGen SInteger
+        zeroBase         <- cgInput "zeroBase"         :: SBVCodeGen SInteger
+        zeroExponent     <- cgInput "zeroExponent"     :: SBVCodeGen SInteger
+        cgReturn $ base         .** exponentValue            .== -13
+               .&& negativeUnit .** negativeExponent         .== -1
+               .&& negativeUnit .** (negativeExponent + 1)   .== 1
+               .&& positiveBase .** negativeExponent         .== 0
+               .&& zeroBase     .** zeroExponent             .== 1
+
+  stdoutText <- compileProgramAndRunGenerated dir "mappedIntegerExponentiation" program
+  assertBool ("Expected mapped integer exponentiation to succeed, received:\n" ++ stdoutText)
+             (") = 1" `isInfixOf` stdoutText)
+
+-- | Check fixed-width integer arithmetic against independently reduced
+-- mathematical results. Include signed overflow, Euclidean versus truncating
+-- division, negative divisors, and the totalized public zero-divisor cases.
+mappedIntegerArithmetic :: Assertion
+mappedIntegerArithmetic = mapM_ check [8, 16, 32, 64]
+ where check bits = withSystemTempDirectory "sbv-mapped-integer-arithmetic" $ \dir -> do
+         let half = 2 ^ (bits - 1)
+             low  = negate half
+             high = half - 1
+             oversized = 2 ^ (137 :: Int) + 3
+             wrap value = (value + half) `mod` (2 * half) - half
+             operands = [(high, 1), (low, -1), (low, 3), (-7, 3), (-7, -3), (7, -3)
+                        , (low, low), (-1, low), (high, low), (low, 0), (0, 0), (high, high), (high, 2)]
+             program = do
+               cgOverwriteFiles True
+               cgIntegerSize bits
+               cgSetDriverValues (concatMap (\(a, b) -> [a, b]) operands ++ [oversized])
+               checks <- forM (zip [0 :: Int ..] operands) $ \(index, (a, b)) -> do
+                 left  <- cgInput ("left"  ++ show index) :: SBVCodeGen SInteger
+                 right <- cgInput ("right" ++ show index) :: SBVCodeGen SInteger
+                 let agrees actual expected = actual .== literal (wrap expected)
+                     (quotient, remainder) = if b == 0 then (0, a) else quotRem a b
+                     (division, modulus)   = if b == 0 then (0, a) else divMod a b
+                     euclidean
+                       | b == 0 = []  -- The internal Euclidean operators leave this case unconstrained.
+                       | True   = [ agrees (sEDiv left right) ((a `div` abs b) * signum b)
+                                  , agrees (sEMod left right) (a `mod` abs b)
+                                  ]
+                 pure $ sAnd $ euclidean ++
+                   [ agrees (left + right) (a + b)
+                   , agrees (left - right) (a - b)
+                   , agrees (left * right) (a * b)
+                   , agrees (negate left)  (negate a)
+                   , agrees (abs left)     (abs a)
+                   , agrees (left + literal oversized) (a + oversized)
+                   , agrees (sQuot left right) quotient
+                   , agrees (sRem  left right) remainder
+                   , agrees (sDiv  left right) division
+                   , agrees (sMod  left right) modulus
+                   ]
+               oversizedInput <- cgInput "oversized" :: SBVCodeGen SInteger
+               cgReturn (sAnd checks .&& oversizedInput .== literal (wrap oversized))
+         outputText <- compileProgramAndRunGenerated dir "mappedArithmetic" program
+         assertBool ("Incorrect " ++ show bits ++ "-bit arithmetic: " ++ outputText) (") = 1" `isInfixOf` outputText)
+
+-- | Check that transcendental operations over exact rational reals explain
+-- how to opt into an approximate native C representation.
+exactRealNonLinearDiagnostic :: Assertion
+exactRealNonLinearDiagnostic = do
+  result <- try (do
+    (_, _, bundle) <- compileToC' "exactRealNonLinear" $ do
+      value <- cgInput "value" :: SBVCodeGen SReal
+      cgReturn (sin value)
+    evaluate (length (show bundle))) :: IO (Either ErrorCall Int)
+  case result of
+    Left exception -> assertBool ("Expected an exact-real non-linear diagnostic, received:\n" ++ displayException exception)
+                                 ("cannot represent sin" `isInfixOf` displayException exception
+                               && "cgSRealType" `isInfixOf` displayException exception)
+    Right _        -> assertBool "Expected C generation to reject non-linear exact real arithmetic" False
+
+-- | Exercise guarded rational declarations and caller-owned rational returns
+-- across multiple generated library translation units.
+exactRationalLibrary :: Assertion
+exactRationalLibrary = withSystemTempDirectory "sbv-exact-rational-library" $ \dir -> do
+  let component increment = do
+        cgOverwriteFiles True
+        cgSetDriverValues [1]
+        value <- cgInput "value" :: SBVCodeGen SRational
+        cgReturn (value + literal increment)
+
+  (_, cfg, bundle) <- compileToCLib' "exactRationalLibrary"
+    [ ("addOneRational", component 1)
+    , ("addTwoRational", component 2)
+    ]
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  stdoutText <- compileAndRunGenerated dir "exactRationalLibrary"
+  assertBool ("Expected both exact-rational library results, received:\n" ++ stdoutText)
+             (") =2" `isInfixOf` stdoutText && ") =3" `isInfixOf` stdoutText)
+
+-- | Check that ABI kinds and scalar operations contribute the exact external
+-- runtime dependencies needed by their generated C bundles. The documented
+-- RNE precondition must not introduce hardware-mode guards or LibBF fallbacks.
+dependencyRequirements :: Assertion
+dependencyRequirements = do
+  (_, _, wideBundle) <- compileToC' "requirementsWide" $ do
+    value <- cgInput "value" :: SBVCodeGen (SWord 673)
+    cgReturn value
+
+  (_, _, fpBundle) <- compileToC' "requirementsFP" $ do
+    value <- cgInput "value" :: SBVCodeGen (SFloatingPoint 7 19)
+    cgReturn value
+
+  (_, _, integerBundle) <- compileToC' "requirementsInteger" $ do
+    value <- cgInput "value" :: SBVCodeGen SInteger
+    cgReturn value
+
+  (_, _, rationalBundle) <- compileToC' "requirementsRational" $ do
+    value <- cgInput "value" :: SBVCodeGen SRational
+    cgReturn value
+
+  (_, _, nativeFloatBundle) <- compileToC' "requirementsNativeFloat" $ do
+    value <- cgInput "value" :: SBVCodeGen SFloat
+    cgReturn (fpSqrt sRoundNearestTiesToEven value)
+
+  (_, _, roundedNativeFloatBundle) <- compileToC' "requirementsRoundedNativeFloat" $ do
+    value <- cgInput "value" :: SBVCodeGen SFloat
+    cgReturn (fpSqrt sRoundNearestTiesToAway value)
+
+  (_, _, nativeLibraryBundle) <- compileToCLib' "requirementsNativeLibrary"
+    [("addOne", do value <- cgInput "value" :: SBVCodeGen SFloat
+                   cgReturn (fpAdd sRNE value 1))]
+
+  assertEqual "wide bit-vectors should not add an external library" [[]]              (linkerFlags wideBundle)
+  assertEqual "arbitrary floats should request LibBF and libm"       [["-lbf", "-lm"]] (linkerFlags fpBundle)
+  assertEqual "exact integers should request GMP"                    [["-lgmp"]]        (linkerFlags integerBundle)
+  assertEqual "exact rationals should request GMP"                   [["-lgmp"]]        (linkerFlags rationalBundle)
+  assertEqual "native floating-point sqrt should request libm"       [["-lm"]]          (linkerFlags nativeFloatBundle)
+  assertEqual "explicit native rounding should request LibBF and libm" [["-lbf", "-lm"]] (linkerFlags roundedNativeFloatBundle)
+  assertEqual "native RNE arithmetic should not add an external library" [[]] (linkerFlags nativeLibraryBundle)
+  let checkConvention bundle = do
+        let rendered = show bundle
+        assertBool "Generated header must document the RNE calling convention"
+                   ("Enter generated code in FE_TONEAREST" `isInfixOf` rendered)
+        assertBool "The RNE precondition must not add runtime mode checks or changes"
+                   (not (any (`isInfixOf` rendered) ["fegetround(", "fesetround("]))
+  mapM_ checkConvention [nativeFloatBundle, nativeLibraryBundle]
+
+-- | Exercise symbolic constant initialization, immutable writes, reads, and
+-- an array-valued conditional without exposing arrays at the public C ABI.
+persistentArrays :: Assertion
+persistentArrays = withSystemTempDirectory "sbv-persistent-arrays" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [11, 22, 7, 99, 1]
+        firstKey     <- cgInput "firstKey"     :: SBVCodeGen SWord8
+        secondKey    <- cgInput "secondKey"    :: SBVCodeGen SWord8
+        defaultValue <- cgInput "defaultValue" :: SBVCodeGen SWord32
+        storedValue  <- cgInput "storedValue"  :: SBVCodeGen SWord32
+        chooseNewest <- cgInput "chooseNewest" :: SBVCodeGen SBool
+        let base       = constArray defaultValue
+            firstWrite = writeArray base firstKey storedValue
+            newest     = writeArray firstWrite secondKey (storedValue + 1)
+            selected   = ite chooseNewest newest firstWrite
+            literalMap = listArray [(11, 42), (11, 43)] 44 :: SArray Word8 Word32
+        cgOutput "baseStillDefault" (readArray base firstKey)
+        cgOutput "oldVersionDefault" (readArray firstWrite secondKey)
+        cgOutput "literalMapValue" (readArray literalMap firstKey)
+        cgReturn (readArray selected secondKey)
+
+  stdoutText <- compileProgramAndRunGenerated dir "persistentArrays" program
+  mapM_ (\fragment -> assertBool ("Expected generated output to contain " ++ fragment ++ ", received:\n" ++ stdoutText) (fragment `isInfixOf` stdoutText))
+    [ "0x00000064UL"
+    , "baseStillDefault = 0x00000007UL"
+    , "oldVersionDefault = 0x00000007UL"
+    , "literalMapValue = 0x0000002aUL"
+    ]
+
+-- | Exercise array-valued initialization, immutable writes, and reads without
+-- exposing a call-scoped inner array through the generated C ABI.
+nestedPersistentArrays :: Assertion
+nestedPersistentArrays = withSystemTempDirectory "sbv-nested-persistent-arrays" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [5, 17, 7, 29, 2, 2, 1]
+        firstDefault  <- cgInput "firstDefault"  :: SBVCodeGen SWord32
+        firstStored   <- cgInput "firstStored"   :: SBVCodeGen SWord32
+        secondDefault <- cgInput "secondDefault" :: SBVCodeGen SWord32
+        secondStored  <- cgInput "secondStored"  :: SBVCodeGen SWord32
+        outerStoreKey <- cgInput "outerStoreKey" :: SBVCodeGen SWord16
+        outerReadKey  <- cgInput "outerReadKey"  :: SBVCodeGen SWord16
+        innerReadKey  <- cgInput "innerReadKey"  :: SBVCodeGen SWord8
+        let firstInner  = writeArray (constArray firstDefault :: SArray Word8 Word32) 1 firstStored
+            secondInner = writeArray (constArray secondDefault :: SArray Word8 Word32) 1 secondStored
+            outerBase   = constArray firstInner :: SArray Word16 (ArrayModel Word8 Word32)
+            outer       = writeArray outerBase outerStoreKey secondInner
+            selected    = readArray outer outerReadKey
+            original    = readArray outer (outerReadKey + 1)
+        cgOutput "selected" (readArray selected innerReadKey)
+        cgReturn (readArray original innerReadKey)
+
+  stdoutText <- compileProgramAndRunGenerated dir "nestedPersistentArrays" program
+  sourceText <- readFile (dir </> "nestedPersistentArrays.c")
+  mapM_ (\fragment -> assertBool ("Expected nested-array output to contain " ++ fragment ++ ", received:\n" ++ stdoutText) (fragment `isInfixOf` stdoutText))
+    [ "0x00000011UL"
+    , "selected = 0x0000001dUL"
+    ]
+  assertBool ("Expected nested array values to use retained temporary descriptors, received:\n" ++ sourceText)
+             (    "sbv_array_stored_export_2_u8_3_u32(&sbv_local_array_ctx" `isInfixOf` sourceText
+              && "sbv_array_ctx_end(&sbv_local_array_ctx)" `isInfixOf` sourceText
+              && "sbv_local_array_descriptor_" `isInfixOf` sourceText
+             )
+
+-- | Exercise retained array descriptors in tuple construction and projection.
+tupleStoredArrays :: Assertion
+tupleStoredArrays = withSystemTempDirectory "sbv-tuple-stored-arrays" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [5, 17, 1]
+        defaultValue <- cgInput "defaultValue" :: SBVCodeGen SWord32
+        storedValue  <- cgInput "storedValue"  :: SBVCodeGen SWord32
+        key          <- cgInput "key"          :: SBVCodeGen SWord8
+        let source                  = writeArray (constArray defaultValue :: SArray Word8 Word32) 1 storedValue
+            pair                    = tuple (source, key) :: SBV (ArrayModel Word8 Word32, Word8)
+            (restored, restoredKey) = untuple pair
+        cgOutput "restoredKey" restoredKey
+        cgOutput "pair" pair
+        cgReturn (readArray restored key)
+
+  stdoutText <- compileProgramAndRunGenerated dir "tupleStoredArrays" program
+  sourceText <- readFile (dir </> "tupleStoredArrays.c")
+  mapM_ (\fragment -> assertBool ("Expected tuple-stored array output to contain " ++ fragment ++ ", received:\n" ++ stdoutText) (fragment `isInfixOf` stdoutText))
+    [ "0x00000011UL"
+    , "restoredKey = 1"
+    , "pair =([0] =0x00000005UL, 1)"
+    ]
+  assertBool ("Expected tuple construction and projection to bridge retained arrays, received:\n" ++ sourceText)
+             (    ".field1 = sbv_array_stored_export_2_u8_3_u32(&sbv_local_array_ctx" `isInfixOf` sourceText
+              && "sbv_local_array_descriptor_" `isInfixOf` sourceText
+             )
+
+-- | Exercise retained array descriptors in ADT construction and projection.
+adtStoredArrays :: Assertion
+adtStoredArrays = withSystemTempDirectory "sbv-adt-stored-arrays" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [5, 17, 1]
+        defaultValue <- cgInput "defaultValue" :: SBVCodeGen SWord32
+        storedValue  <- cgInput "storedValue"  :: SBVCodeGen SWord32
+        key          <- cgInput "key"          :: SBVCodeGen SWord8
+        let source = writeArray (constArray defaultValue :: SArray Word8 Word32) 1 storedValue
+            boxed  = sCGArrayBox source key
+        cgOutput "boxedKey" (getCGArrayBox_2 boxed)
+        cgOutput "boxed" boxed
+        cgReturn (readArray (getCGArrayBox_1 boxed) key)
+
+  stdoutText <- compileProgramAndRunGenerated dir "adtStoredArrays" program
+  sourceText <- readFile (dir </> "adtStoredArrays.c")
+  mapM_ (\fragment -> assertBool ("Expected ADT-stored array output to contain " ++ fragment ++ ", received:\n" ++ stdoutText) (fragment `isInfixOf` stdoutText))
+    [ "0x00000011UL"
+    , "boxedKey = 1"
+    , "boxed =CGArrayBox([0] =0x00000005UL, 1)"
+    ]
+  assertBool ("Expected ADT construction and projection to bridge retained arrays, received:\n" ++ sourceText)
+             (    ".field1 = sbv_array_stored_export_2_u8_3_u32(&sbv_local_array_ctx" `isInfixOf` sourceText
+              && "sbv_local_array_descriptor_" `isInfixOf` sourceText
+             )
+
+-- | Exercise retained array descriptors in list construction, indexing, and
+-- owned list outputs.
+listStoredArrays :: Assertion
+listStoredArrays = withSystemTempDirectory "sbv-list-stored-arrays" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [5, 17, 1]
+        defaultValue <- cgInput "defaultValue" :: SBVCodeGen SWord32
+        storedValue  <- cgInput "storedValue"  :: SBVCodeGen SWord32
+        key          <- cgInput "key"          :: SBVCodeGen SWord8
+        let source   = writeArray (constArray defaultValue :: SArray Word8 Word32) 1 storedValue
+            arrays   = SL.singleton source :: SList (ArrayModel Word8 Word32)
+            restored = SL.elemAt arrays 0
+        cgOutput "arrays" arrays
+        cgReturn (readArray restored key)
+
+  stdoutText <- compileProgramAndRunGenerated dir "listStoredArrays" program
+  sourceText <- readFile (dir </> "listStoredArrays.c")
+  mapM_ (\fragment -> assertBool ("Expected list-stored array output to contain " ++ fragment ++ ", received:\n" ++ stdoutText) (fragment `isInfixOf` stdoutText))
+    [ "0x00000011UL"
+    , "arrays =[[0] =0x00000005UL]"
+    ]
+  assertBool ("Expected list construction and indexing to bridge retained arrays, received:\n" ++ sourceText)
+             (    "sbv_list_array_" `isInfixOf` sourceText
+              && "sbv_array_stored_export_2_u8_3_u32(&sbv_local_array_ctx" `isInfixOf` sourceText
+              && "sbv_local_array_descriptor_" `isInfixOf` sourceText
+             )
+
+-- | Exercise generated-driver initialization and cleanup for array fields in
+-- tuple, ADT, and list inputs that share a single per-kind callback family.
+aggregateArrayInputs :: Assertion
+aggregateArrayInputs = withSystemTempDirectory "sbv-aggregate-array-inputs" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [3, 7, 11]
+        tupleInput <- cgInput "tupleInput" :: SBVCodeGen (SBV (ArrayModel Word8 (ArrayModel Word8 Word32), Word8))
+        adtInput   <- cgInput "adtInput"   :: SBVCodeGen (SBV CodeGenArrayBox)
+        listInput  <- cgInput "listInput"  :: SBVCodeGen (SList (ArrayModel Word8 Word32))
+        let (tupleOuterArray, tupleKey) = untuple tupleInput
+            tupleInnerArray             = readArray tupleOuterArray tupleKey
+            adtArray                    = getCGArrayBox_1 adtInput
+            adtKey                      = getCGArrayBox_2 adtInput
+            listHeadArray               = SL.head listInput
+            tupleValue                  = readArray tupleInnerArray 0
+            adtValue                    = readArray adtArray adtKey
+            listValue                   = readArray listHeadArray 0
+        cgOutput "tupleValue" tupleValue
+        cgOutput "adtValue" adtValue
+        cgOutput "listValue" listValue
+        cgReturn (tupleValue + adtValue + listValue)
+
+  stdoutText <- compileProgramAndRunGenerated dir "aggregateArrayInputs" program
+  driverText <- readFile (dir </> "aggregateArrayInputs_driver.c")
+  mapM_ (\fragment -> assertBool ("Expected aggregate-array driver output to contain " ++ fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ "= 0x00000015UL"
+    , "tupleValue = 0x00000003UL"
+    , "adtValue = 0x00000007UL"
+    , "listValue = 0x0000000bUL"
+    ]
+  assertBool ("Expected retained descriptors for all aggregate array inputs, received:\n" ++ driverText)
+             (length (filter (isInfixOf "sbv_array_output_retain_2_u8_3_u32") (lines driverText)) >= 5)
+
+-- | Exercise transitive ownership when tuples, lists, and ADTs hide retained
+-- arrays behind one or more concrete ADT fields.
+transitiveAggregateArrayInputs :: Assertion
+transitiveAggregateArrayInputs = withSystemTempDirectory "sbv-transitive-array-inputs" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [3, 7, 11]
+        tupleInput    <- cgInput "tupleInput"    :: SBVCodeGen (SBV (CodeGenArrayBox, Word8))
+        listInput     <- cgInput "listInput"     :: SBVCodeGen (SList (CodeGenArrayBox, Word8))
+        envelopeInput <- cgInput "envelopeInput" :: SBVCodeGen (SBV CodeGenArrayEnvelope)
+        let (tupleBox, tupleKey) = untuple tupleInput
+            (listBox, listKey)   = untuple (SL.head listInput)
+            (envelopeBox, _)     = untuple (getCGArrayEnvelope_1 envelopeInput)
+            tupleValue           = readArray (getCGArrayBox_1 tupleBox) tupleKey
+            listValue            = readArray (getCGArrayBox_1 listBox) listKey
+            envelopeValue        = readArray (getCGArrayBox_1 envelopeBox) 0
+        cgOutput "tupleValue" tupleValue
+        cgOutput "listValue" listValue
+        cgOutput "envelopeValue" envelopeValue
+        cgReturn (tupleValue + listValue + envelopeValue)
+
+  stdoutText <- compileProgramAndRunGenerated dir "transitiveAggregateArrayInputs" program
+  headerText <- readFile (dir </> "transitiveAggregateArrayInputs.h")
+  mapM_ (\fragment -> assertBool ("Expected transitive aggregate-array output to contain " ++ fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ "= 0x00000015UL"
+    , "tupleValue = 0x00000003UL"
+    , "listValue = 0x00000007UL"
+    , "envelopeValue = 0x0000000bUL"
+    ]
+  assertBool ("Expected tuple ownership to cross concrete ADT fields, received:\n" ++ headerText)
+             (    "sbv_adt_owned_clone_SBVADT_CodeGenArrayBox(source.field1)" `isInfixOf` headerText
+              && "sbv_adt_owned_release_SBVADT_CodeGenArrayBox(&value->field1)" `isInfixOf` headerText
+             )
+
+-- | Check that native floating-point array keys use SMT object equality:
+-- NaNs match, while positive and negative zero remain distinct.
+nativeFloatArrayKeys :: Assertion
+nativeFloatArrayKeys = withSystemTempDirectory "sbv-native-float-array-keys" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [0x7fc00000, 0x00000000, 0x80000000]
+        nanBits      <- cgInput "nanBits"      :: SBVCodeGen SWord32
+        positiveBits <- cgInput "positiveBits" :: SBVCodeGen SWord32
+        negativeBits <- cgInput "negativeBits" :: SBVCodeGen SWord32
+        let nanKey       = sWord32AsSFloat nanBits
+            positiveZero = sWord32AsSFloat positiveBits
+            negativeZero = sWord32AsSFloat negativeBits
+            base         = constArray 3
+            withNaN      = writeArray base nanKey 11
+            withZero     = writeArray withNaN positiveZero 12
+            flags        = [ readArray withZero nanKey .== (11 :: SWord8)
+                           , readArray withZero positiveZero .== (12 :: SWord8)
+                           , readArray withZero negativeZero .== (3 :: SWord8)
+                           ]
+        cgReturn (sum (zipWith (\flag weight -> ite flag weight 0) flags [1, 2, 4]) :: SWord8)
+
+  stdoutText <- compileProgramAndRunGenerated dir "nativeFloatArrayKeys" program
+  assertBool ("Expected all native array-key checks to pass, received:\n" ++ stdoutText) ("= 7" `isInfixOf` stdoutText)
+
+-- | Exercise array-type merging across generated library translation units,
+-- including an owned array returned through the public library ABI.
+persistentArrayLibrary :: Assertion
+persistentArrayLibrary = withSystemTempDirectory "sbv-persistent-array-library" $ \dir -> do
+  let component increment = do
+        cgOverwriteFiles True
+        cgSetDriverValues [40, 9]
+        source <- cgInput "source" :: SBVCodeGen (SArray Word16 Word32)
+        key    <- cgInput "key"    :: SBVCodeGen SWord16
+        let updated = writeArray source key (readArray source key + increment)
+        cgReturn (readArray updated key)
+
+      lambdaComponent = do
+        cgOverwriteFiles True
+        cgSetDriverValues [1]
+        key <- cgInput "key" :: SBVCodeGen SWord16
+        let source = lambdaArray (\index -> select [sFromIntegral index * 3 + 1, sFromIntegral index * 3 + 2] 0 index :: SWord32)
+                     :: SArray Word16 Word32
+        cgReturn (readArray source key)
+
+      ownedComponent = do
+        cgOverwriteFiles True
+        let source = lambdaArray (\index -> sFromIntegral index + 5) :: SArray Word16 Word32
+        cgReturn (writeArray source 0 55)
+
+  (_, cfg, bundle) <- compileToCLib' "persistentArrayLibrary"
+    [ ("increment",   component 1)
+    , ("addTwo",      component 2)
+    , ("lambdaValue", lambdaComponent)
+    , ("ownedArray",  ownedComponent)
+    ]
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  stdoutText <- compileAndRunGenerated dir "persistentArrayLibrary"
+  mapM_ (\fragment -> assertBool ("Expected generated library output to contain " ++ fragment ++ ", received:\n" ++ stdoutText) (fragment `isInfixOf` stdoutText))
+    [ "0x00000029UL"
+    , "0x0000002aUL"
+    , "0x00000005UL"
+    , "ownedArray()[0] =0x00000037UL"
+    ]
+
+-- | Exercise the borrowed callback descriptor used for a public array input,
+-- including local writes that shadow the callback only at matching keys.
+callbackArrayInput :: Assertion
+callbackArrayInput = withSystemTempDirectory "sbv-callback-array-input" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [40, 9]
+        source <- cgInput "source" :: SBVCodeGen (SArray Word8 Word32)
+        key    <- cgInput "key"    :: SBVCodeGen SWord8
+        let updated = writeArray source key 99
+        cgOutput "sourceValue" (readArray source key)
+        cgOutput "unshadowedValue" (readArray updated (key + 1))
+        cgReturn (readArray updated key)
+
+  stdoutText <- compileProgramAndRunGenerated dir "callbackArrayInput" program
+  mapM_ (\fragment -> assertBool ("Expected callback-backed output to contain " ++ fragment ++ ", received:\n" ++ stdoutText) (fragment `isInfixOf` stdoutText))
+    [ "0x00000063UL"
+    , "sourceValue = 0x00000028UL"
+    , "unshadowedValue = 0x00000028UL"
+    ]
+
+-- | Exercise a retained lambda DAG together with a persistent write that
+-- shadows exactly one value produced by the lambda.
+structuredLambdaArray :: Assertion
+structuredLambdaArray = withSystemTempDirectory "sbv-structured-lambda-array" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [9]
+        key <- cgInput "key" :: SBVCodeGen SWord16
+        let source  = lambdaArray (\index -> sFromIntegral index * 3 + 1) :: SArray Word16 Word32
+            updated = writeArray source key 99
+        cgOutput "nextValue" (readArray updated (key + 1))
+        cgReturn (readArray updated key)
+
+  stdoutText <- compileProgramAndRunGenerated dir "structuredLambdaArray" program
+  mapM_ (\fragment -> assertBool ("Expected structured-lambda output to contain " ++ fragment ++ ", received:\n" ++ stdoutText) (fragment `isInfixOf` stdoutText))
+    [ "0x00000063UL"
+    , "nextValue = 0x0000001fUL"
+    ]
+
+-- | Exercise text, list, and set allocation inside retained array callbacks,
+-- including an exact list element that shares both the GMP and list arenas.
+managedStructuredLambdaArrays :: Assertion
+managedStructuredLambdaArrays = withSystemTempDirectory "sbv-managed-structured-lambda-arrays" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [2]
+        key <- cgInput "key" :: SBVCodeGen SWord8
+        let textSource = lambdaArray (\index ->
+                           ite (index .== 2) (literal "hit") (literal "miss") SL.++ literal "!")
+                         :: SArray Word8 String
+            listSource = lambdaArray (\index ->
+                           SL.singleton (sFromIntegral index :: SInteger) SL.++ literal [100])
+                         :: SArray Word8 [Integer]
+            setSource = lambdaArray (\index ->
+                          SS.insert (sFromIntegral index :: SInteger) (SS.singleton 100))
+                        :: SArray Word8 (RCSet Integer)
+        cgOutput "textValue" (readArray textSource key)
+        cgOutput "listValue" (readArray listSource key)
+        cgReturn (readArray setSource key)
+
+  stdoutText <- compileProgramAndRunGenerated dir "managedStructuredLambdaArrays" program
+  mapM_ (\fragment -> assertBool ("Expected managed structured-lambda output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                  (fragment `isInfixOf` stdoutText))
+    [ ") ={100, 2}"
+    , "textValue =hit!"
+    , "listValue =[2, 100]"
+    ]
+
+-- | Return a retained lambda array whose callback constructs a tuple with
+-- fresh text and list storage, then read it after the generated call returns.
+escapingManagedLambdaArray :: Assertion
+escapingManagedLambdaArray = withSystemTempDirectory "sbv-escaping-managed-lambda-array" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        let source = lambdaArray (\index ->
+                       tuple ( literal "item" SL.++ literal "!"
+                             , SL.singleton (sFromIntegral index :: SWord16) SL.++ literal [99]
+                             ))
+                     :: SArray Word8 (String, [Word16])
+        cgReturn source
+
+  stdoutText <- compileProgramAndRunGenerated dir "escapingManagedLambdaArray" program
+  sourceText <- readFile (dir </> "escapingManagedLambdaArray.c")
+  assertBool ("Expected an escaping managed lambda array to retain its callback arenas, received:\n" ++ stdoutText)
+             ("[0] =(item!, [0x0000U, 0x0063U])" `isInfixOf` stdoutText)
+  assertBool ("Expected the escaping callback to clone managed results into retained storage, received:\n" ++ sourceText)
+             ("sbv_function_ctx_retain_empty" `isInfixOf` sourceText
+           && "sbv_function_result_clone_" `isInfixOf` sourceText)
+
+-- | Call scalar and managed first-order 'smtFunction' definitions from array
+-- lambdas, including a scalar signature whose body uses hidden managed arenas
+-- and a managed callback that remains callable after its array escapes.
+definedFunctionsInsideArrayLambdas :: Assertion
+definedFunctionsInsideArrayLambdas = withSystemTempDirectory "sbv-defined-functions-in-array-lambdas" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [12]
+        key <- cgInput "key" :: SBVCodeGen SWord8
+        let countDigits :: SWord8 -> SWord8
+            countDigits = smtFunction "C lambda digit count" $ \value ->
+              sFromIntegral (SL.length (SL.natToStr (sFromIntegral value :: SInteger)))
+
+            decorate :: SString -> SString
+            decorate = smtFunction "C lambda text decoration" $ \value ->
+              literal "<" SL.++ value SL.++ literal ">"
+
+            numericSource = lambdaArray countDigits :: SArray Word8 Word8
+            textSource = lambdaArray (\index ->
+                           decorate (ite (index .== 0) (literal "zero") (literal "other")))
+                         :: SArray Word8 String
+        cgOutput "digits" (readArray numericSource key)
+        cgReturn textSource
+
+  stdoutText <- compileProgramAndRunGenerated dir "definedFunctionsInsideArrayLambdas" program
+  sourceText <- readFile (dir </> "definedFunctionsInsideArrayLambdas.c")
+  mapM_ (\fragment -> assertBool ("Expected a defined-function lambda output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                  (fragment `isInfixOf` stdoutText))
+    [ "[0] =<zero>"
+    , "digits = 2"
+    ]
+  assertBool ("Expected array callbacks to forward the function ownership context, received:\n" ++ sourceText)
+             ("/* Uninterpreted function */ sbv_function_" `isInfixOf` sourceText
+           && "sbv_function_ctx sbv_local_function_ctx" `isInfixOf` sourceText)
+
+-- | Exercise retained arrays that call managed 'smtFunction' definitions in
+-- separate translation units of one generated static library.
+definedFunctionArrayLambdaLibrary :: Assertion
+definedFunctionArrayLambdaLibrary = withSystemTempDirectory "sbv-defined-function-array-lambda-library" $ \dir -> do
+  let component :: String -> SBVCodeGen ()
+      component prefix = do
+        cgOverwriteFiles True
+        let decorate :: SString -> SString
+            decorate = smtFunction ("C library lambda " ++ prefix) $ \value ->
+              literal prefix SL.++ value
+
+            source = lambdaArray (\index ->
+                       decorate (SL.natToStr (sFromIntegral index :: SInteger)))
+                     :: SArray Word8 String
+        cgReturn source
+
+  (_, cfg, bundle) <- compileToCLib' "definedFunctionArrayLambdaLibrary"
+    [ ("firstLambda", component "first-")
+    , ("secondLambda", component "second-")
+    ]
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  stdoutText <- compileAndRunGenerated dir "definedFunctionArrayLambdaLibrary"
+  mapM_ (\fragment -> assertBool ("Expected a library function-backed lambda output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                  (fragment `isInfixOf` stdoutText))
+    [ "firstLambda()[0] =first-0"
+    , "secondLambda()[0] =second-0"
+    ]
+
+-- | Return direct and tuple-contained persistent arrays from retained
+-- callbacks, read them during the generated call, and read the direct result
+-- again after its outer array escapes.
+arrayValuedLambdaResults :: Assertion
+arrayValuedLambdaResults = withSystemTempDirectory "sbv-array-valued-lambda-results" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [5]
+        key <- cgInput "key" :: SBVCodeGen SWord8
+        let inner :: SWord8 -> SArray Word8 Word32
+            inner index = writeArray
+                            (constArray (sFromIntegral index + 1 :: SWord32) :: SArray Word8 Word32)
+                            index
+                            99
+
+            makeInner :: SWord8 -> SArray Word8 Word32
+            makeInner = smtFunction "C lambda inner array" inner
+
+            directSource   = lambdaArray inner :: SArray Word8 (ArrayModel Word8 Word32)
+            functionSource = lambdaArray makeInner :: SArray Word8 (ArrayModel Word8 Word32)
+            boxedSource    = lambdaArray (\index -> tuple (inner index, sFromIntegral index + 10 :: SWord16))
+                           :: SArray Word8 (ArrayModel Word8 Word32, Word16)
+            directInner   = readArray directSource key
+            functionInner = readArray functionSource key
+            (boxedInner, marker) = untuple (readArray boxedSource key)
+        cgOutput "directStored"  (readArray directInner key)
+        cgOutput "directDefault" (readArray directInner (key + 1))
+        cgOutput "functionStored" (readArray functionInner key)
+        cgOutput "boxedStored"   (readArray boxedInner key)
+        cgOutput "marker"        marker
+        cgReturn directSource
+
+  stdoutText <- compileProgramAndRunGenerated dir "arrayValuedLambdaResults" program
+  sourceText <- readFile (dir </> "arrayValuedLambdaResults.c")
+  mapM_ (\fragment -> assertBool ("Expected an array-valued lambda output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                  (fragment `isInfixOf` stdoutText))
+    [ ")[0] =[0] =0x00000063UL"
+    , "directStored = 0x00000063UL"
+    , "directDefault = 0x00000006UL"
+    , "functionStored = 0x00000063UL"
+    , "boxedStored = 0x00000063UL"
+    , "marker = 0x000fU"
+    ]
+  assertBool ("Expected array callback results to cross through retained descriptors, received:\n" ++ sourceText)
+             ("sbv_array_stored_export_2_u8_3_u32(&sbv_local_array_ctx" `isInfixOf` sourceText
+           && "SBVArrayOutput_2_u8_3_u32 * sbv_array_lambda_" `isInfixOf` sourceText)
+
+-- | Exercise array-valued callback results in independent translation units
+-- of a generated static library.
+arrayValuedLambdaLibrary :: Assertion
+arrayValuedLambdaLibrary = withSystemTempDirectory "sbv-array-valued-lambda-library" $ \dir -> do
+  let component :: Word32 -> SBVCodeGen ()
+      component value = do
+        cgOverwriteFiles True
+        let source = lambdaArray (\index ->
+                       writeArray (constArray (literal value) :: SArray Word8 Word32) index (literal value + 1))
+                     :: SArray Word8 (ArrayModel Word8 Word32)
+        cgReturn source
+
+  (_, cfg, bundle) <- compileToCLib' "arrayValuedLambdaLibrary"
+    [ ("firstNestedArray", component 20)
+    , ("secondNestedArray", component 30)
+    ]
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  stdoutText <- compileAndRunGenerated dir "arrayValuedLambdaLibrary"
+  mapM_ (\fragment -> assertBool ("Expected a library array-valued lambda output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                  (fragment `isInfixOf` stdoutText))
+    [ "firstNestedArray()[0] =[0] =0x00000015UL"
+    , "secondNestedArray()[0] =[0] =0x0000001fUL"
+    ]
+
+-- | Lambda-lift closed array callbacks from a defined function and from an
+-- outer array callback whose result is itself a selected callback array.
+nestedStructuredArrayLambdas :: Assertion
+nestedStructuredArrayLambdas = withSystemTempDirectory "sbv-nested-structured-array-lambdas" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [1, 5, 1]
+        chooseFirst <- cgInput "chooseFirst" :: SBVCodeGen SBool
+        key         <- cgInput "key"         :: SBVCodeGen SWord8
+        outerKey    <- cgInput "outerKey"    :: SBVCodeGen SWord8
+        let choose :: SBool -> SArray Word8 Word16
+            choose = smtFunction "C nested lambda choice" $ \condition ->
+                       ite condition
+                           (lambdaArray (\index -> sFromIntegral index + 10))
+                           (lambdaArray (\index -> sFromIntegral index + 20))
+
+            recursiveChoose :: SWord8 -> SArray Word8 Word16
+            recursiveChoose = smtFunctionNoTermination "C recursive nested lambda choice" $ \count ->
+                                ite (count .== 0)
+                                    (lambdaArray (\index -> sFromIntegral index + 60))
+                                    (recursiveChoose (count - 1))
+
+            nested = lambdaArray (\outer ->
+                       ite (outer .== 0)
+                           (lambdaArray (\index -> sFromIntegral index + 30))
+                           (lambdaArray (\index -> sFromIntegral index + 40)))
+                     :: SArray Word8 (ArrayModel Word8 Word16)
+
+            deep = lambdaArray (\_ ->
+                     lambdaArray (\_ ->
+                       lambdaArray (\index -> sFromIntegral index + 50)))
+                   :: SArray Word8 (ArrayModel Word8 (ArrayModel Word8 Word16))
+
+            chosen      = choose chooseFirst
+            selected    = readArray chosen key
+            nestedInner = readArray nested outerKey
+            deepMiddle  = readArray deep outerKey
+            deepInner   = readArray deepMiddle outerKey
+            recursive   = recursiveChoose outerKey
+
+        cgOutput "selected"       selected
+        cgOutput "nestedSelected" (readArray nestedInner key)
+        cgOutput "deepSelected"   (readArray deepInner key)
+        cgOutput "recursive"      (readArray recursive key)
+        cgReturn chosen
+
+  stdoutText <- compileProgramAndRunGenerated dir "nestedStructuredArrayLambdas" program
+  sourceText <- readFile (dir </> "nestedStructuredArrayLambdas.c")
+  mapM_ (\fragment -> assertBool ("Expected nested structured-lambda output to contain " ++ fragment ++ ", received:\n" ++ stdoutText)
+                                 (fragment `isInfixOf` stdoutText))
+    [ ")[0] =0x000aU"
+    , "selected = 0x000fU"
+    , "nestedSelected = 0x002dU"
+    , "deepSelected = 0x0037U"
+    , "recursive = 0x0041U"
+    ]
+  assertBool ("Expected nested callbacks to receive lexical-scope-qualified names, received:\n" ++ sourceText)
+             ("_nested_l" `isInfixOf` sourceText)
+
+-- | Exercise lambda-lifted callbacks from private defined functions in
+-- independent translation units of a generated static library.
+nestedStructuredArrayLambdaLibrary :: Assertion
+nestedStructuredArrayLambdaLibrary = withSystemTempDirectory "sbv-nested-structured-array-lambda-library" $ \dir -> do
+  let component :: Word16 -> SBVCodeGen ()
+      component offset = do
+        cgOverwriteFiles True
+        let choose :: SBool -> SArray Word8 Word16
+            choose = smtFunction "C library nested lambda" $ \condition ->
+                       ite condition
+                           (lambdaArray (\index -> sFromIntegral index + literal offset))
+                           (lambdaArray (\index -> sFromIntegral index + literal offset + 100))
+        cgReturn (choose (literal True))
+
+  (_, cfg, bundle) <- compileToCLib' "nestedStructuredArrayLambdaLibrary"
+    [ ("firstNestedLambda", component 10)
+    , ("secondNestedLambda", component 20)
+    ]
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  stdoutText <- compileAndRunGenerated dir "nestedStructuredArrayLambdaLibrary"
+  mapM_ (\fragment -> assertBool ("Expected nested structured-lambda library output to contain " ++ fragment ++ ", received:\n" ++ stdoutText)
+                                 (fragment `isInfixOf` stdoutText))
+    [ "firstNestedLambda()[0] =0x000aU"
+    , "secondNestedLambda()[0] =0x0014U"
+    ]
+
+-- | Exercise parameter-dependent tables in two structured lambdas, ensuring
+-- their independently numbered local table declarations do not collide.
+structuredLambdaTables :: Assertion
+structuredLambdaTables = withSystemTempDirectory "sbv-structured-lambda-tables" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [1]
+        key <- cgInput "key" :: SBVCodeGen SWord8
+        let first  = lambdaArray (\index -> select [sFromIntegral index + 10, sFromIntegral index + 20] 99 index :: SWord32)
+                     :: SArray Word8 Word32
+            second = lambdaArray (\index -> select [sFromIntegral index * 2, sFromIntegral index * 3] 77 index :: SWord32)
+                     :: SArray Word8 Word32
+        cgOutput "firstValue" (readArray first key)
+        cgReturn (readArray second key)
+
+  stdoutText <- compileProgramAndRunGenerated dir "structuredLambdaTables" program
+  mapM_ (\fragment -> assertBool ("Expected structured-lambda table output to contain " ++ fragment ++ ", received:\n" ++ stdoutText) (fragment `isInfixOf` stdoutText))
+    [ "0x00000003UL"
+    , "firstValue = 0x00000015UL"
+    ]
+
+-- | Exercise structured lowering of a multi-argument 'smtFunction', including
+-- collision-free C encoding of a quoted SMT identifier.
+definedSBVFunction :: Assertion
+definedSBVFunction = withSystemTempDirectory "sbv-defined-function" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [3, 4, 5]
+        left  <- cgInput "left"  :: SBVCodeGen SWord32
+        right <- cgInput "right" :: SBVCodeGen SWord32
+        wide  <- cgInput "wide"  :: SBVCodeGen (SWord 673)
+        let combine  = smtFunction "defined function/@1" $ \x y -> ite (x .< y) (x + y) (x * y)
+            increment = smtFunction "wide defined function" (+ 1)
+        cgOutput "wideResult" (increment wide)
+        cgReturn (combine left right)
+
+  stdoutText <- compileProgramAndRunGenerated dir "definedSBVFunction" program
+  sourceText <- readFile (dir </> "definedSBVFunction.c")
+  assertBool ("Expected defined-function output to contain 0x00000007UL, received:\n" ++ stdoutText)
+             ("0x00000007UL" `isInfixOf` stdoutText)
+  assertBool ("Expected the quoted SMT function name to use a private encoded C identifier, received:\n" ++ sourceText)
+             ("static SWord32 sbv_function_" `isInfixOf` sourceText
+           && "/* Uninterpreted function */ sbv_function_" `isInfixOf` sourceText)
+  assertBool ("Expected a defined function body to contribute its wide-bit-vector runtime, received:\n" ++ sourceText)
+             ("static SWord673 sbv_function_" `isInfixOf` sourceText
+           && "sbv_bv_u673_add" `isInfixOf` sourceText)
+
+-- | Exercise an acyclic diamond of 'smtFunction' calls whose lexical name
+-- ordering requires prototypes for callees emitted after their caller.
+composedDefinedSBVFunctions :: Assertion
+composedDefinedSBVFunctions = withSystemTempDirectory "sbv-composed-defined-functions" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [4]
+        input <- cgInput "input" :: SBVCodeGen SWord32
+        let base :: SWord32 -> SWord32
+            base = smtFunction "C function base" (+ 1)
+
+            twice :: SWord32 -> SWord32
+            twice = smtFunction "C function twice" $ \value -> base value * 2
+
+            plusThree :: SWord32 -> SWord32
+            plusThree = smtFunction "C function plus three" $ \value -> base value + 3
+
+            diamond :: SWord32 -> SWord32
+            diamond = smtFunction "C function diamond" $ \value -> twice value + plusThree value
+        cgReturn (diamond input)
+
+  stdoutText <- compileProgramAndRunGenerated dir "composedDefinedSBVFunctions" program
+  sourceText <- readFile (dir </> "composedDefinedSBVFunctions.c")
+  assertBool ("Expected composed defined-function output to contain 0x00000012UL, received:\n" ++ stdoutText)
+             ("0x00000012UL" `isInfixOf` stdoutText)
+  assertBool ("Expected private prototypes before the composed defined-function bodies, received:\n" ++ sourceText)
+             (length (filter ("static SWord32 sbv_function_" `isInfixOf`) (lines sourceText)) == 8)
+
+-- | Exercise private by-value C signatures for 'smtFunction' definitions over
+-- a tuple and a scalar-only ADT, including projection and reconstruction.
+structuralDefinedSBVFunctions :: Assertion
+structuralDefinedSBVFunctions = withSystemTempDirectory "sbv-structural-defined-functions" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        let adjustTuple :: SBV (Word8, Word16) -> SBV (Word8, Word16)
+            adjustTuple = smtFunction "C structural tuple" $ \value ->
+                            let (first, second) = untuple value
+                            in tuple (first + 1, second + 2)
+
+            adjustADT :: SCodeGenADT Word8 -> SCodeGenADT Word8
+            adjustADT = smtFunction "C structural ADT" $ \value ->
+                          sCGPair (getCGPair_1 value + 1) (getCGPair_2 value + 2)
+
+        cgOutput "tupleResult" (adjustTuple (literal (4, 10)))
+        cgReturn (adjustADT (literal (CGPair 7 9)))
+
+  stdoutText <- compileProgramAndRunGenerated dir "structuralDefinedSBVFunctions" program
+  mapM_ (\fragment -> assertBool ("Expected structural defined-function output to contain " ++ fragment ++ ", received:\n" ++ stdoutText)
+                                 (fragment `isInfixOf` stdoutText))
+    [ "CGPair(8, 0x000bU)"
+    , "tupleResult =(5, 0x000cU)"
+    ]
+
+-- | Exercise transitive ownership-arena threading through composed
+-- 'smtFunction' definitions producing strings and exact GMP integers.
+managedScalarDefinedSBVFunctions :: Assertion
+managedScalarDefinedSBVFunctions = withSystemTempDirectory "sbv-managed-scalar-defined-functions" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [4, 5]
+        inputText    <- cgInput "inputText"    :: SBVCodeGen SString
+        inputInteger <- cgInput "inputInteger" :: SBVCodeGen SInteger
+        let addSuffix :: SString -> SString
+            addSuffix = smtFunction "C managed string suffix" $ \value -> value SL.++ literal "!"
+
+            decorate :: SString -> SString
+            decorate = smtFunction "C managed string decorate" $ \value -> literal "<" SL.++ addSuffix value SL.++ literal ">"
+
+            increment :: SInteger -> SInteger
+            increment = smtFunction "C managed integer increment" (+ 1)
+
+            squareIncrement :: SInteger -> SInteger
+            squareIncrement = smtFunction "C managed integer square" $ \value -> increment value * increment value
+
+        cgOutput "decorated" (decorate inputText)
+        cgReturn (squareIncrement inputInteger)
+
+  stdoutText <- compileProgramAndRunGenerated dir "managedScalarDefinedSBVFunctions" program
+  sourceText <- readFile (dir </> "managedScalarDefinedSBVFunctions.c")
+  mapM_ (\fragment -> assertBool ("Expected managed scalar defined-function output to contain " ++ fragment ++ ", received:\n" ++ stdoutText)
+                                 (fragment `isInfixOf` stdoutText))
+    [ ") =36"
+    , "decorated =<sbv4!>"
+    ]
+  assertBool "Expected private defined-function calls to thread the shared ownership context"
+             ("sbv_function_ctx *const sbv_local_parent_function_ctx" `isInfixOf` sourceText
+           && "(&sbv_local_function_ctx," `isInfixOf` sourceText)
+
+-- | Private bodies must request the shared floor helper and math linkage even
+-- when their entry point contains only a function call or array lookup.
+scopedMappedRealFloor :: Assertion
+scopedMappedRealFloor = mapM_ check [(library, useLambda, width) | library <- [False, True], useLambda <- [False, True], width <- [8, 64]]
+ where check (library, useLambda, width) = withSystemTempDirectory "sbv-scoped-real-floor" $ \dir -> do
+         let functionName = "scopedRealFloor"
+             floorHalf :: SReal -> SInteger
+             floorHalf value = sRealToSIntegerFloor (value / 2)
+             program = do
+               cgOverwriteFiles True
+               cgSRealType CgLongDouble
+               cgIntegerSize width
+               cgSetDriverValues [-5]
+               value <- cgInput "value"
+               let result = if useLambda
+                               then readArray (lambdaArray floorHalf) value
+                               else smtFunction "C long-double floor" floorHalf value
+               cgReturn (result .== -3)
+         (_, cfg, bundle) <- if library
+                               then compileToCLib' functionName [("floorComponent", program)]
+                               else compileToC' functionName ((:[]) <$> program)
+         renderCgPgmBundle (Just dir) (cfg, bundle)
+         outputText <- compileAndRunGenerated dir functionName
+         assertBool outputText (") = 1" `isInfixOf` outputText)
+
+-- | Check overflow-safe statement blocks in conditionals, private functions,
+-- and closed array lambdas. Every five-bit input is compared against equivalent
+-- unweighted predicates, including sums that exceed the entire unsigned range.
+scopedPseudoBoolean :: Assertion
+scopedPseudoBoolean = mapM_ check [(library, scope) | library <- [False, True], scope <- [0 :: Int, 1, 2]]
+ where check (library, scope) = withSystemTempDirectory "sbv-scoped-pseudo-boolean" $ \dir -> do
+         let functionName = "scopedPseudoBoolean"
+             evaluateBits :: SWord8 -> SBool
+             evaluateBits value =
+               let bits     = map (sTestBit value) [0, 1, 2]
+                   weighted = zip [maxBound, maxBound, maxBound] bits
+               in ite (sTestBit value 3)
+                      (pbLe weighted maxBound .== pbAtMost bits 1)
+                      (pbEq weighted maxBound .== pbExactly bits 1)
+                  .&& (pbGe weighted maxBound .== sOr bits)
+             evaluateScoped value = case scope of
+               0 -> evaluateBits value
+               1 -> smtFunction "C scoped pseudo-Boolean" evaluateBits value
+               _ -> readArray (lambdaArray evaluateBits) value
+             program = do
+               cgOverwriteFiles True
+               cgIntegerSize 8
+               cgSetDriverValues [0..31]
+               inputs <- cgInputArr 32 "inputs"
+               cgReturn (sAnd (map evaluateScoped inputs))
+         (_, cfg, bundle) <- if library
+                               then compileToCLib' functionName [("scopedComponent", program)]
+                               else compileToC' functionName ((:[]) <$> program)
+         renderCgPgmBundle (Just dir) (cfg, bundle)
+         outputText <- compileAndRunGenerated dir functionName
+         assertBool outputText (") = 1" `isInfixOf` outputText)
+
+-- | Exercise composed 'smtFunction' definitions over exact-element lists and
+-- sets, requiring coordinated list, set, and GMP ownership arenas.
+collectionDefinedSBVFunctions :: Assertion
+collectionDefinedSBVFunctions = withSystemTempDirectory "sbv-collection-defined-functions" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        let addPrefix :: SList Integer -> SList Integer
+            addPrefix = smtFunction "C managed list prefix" $ \values -> literal [0] SL.++ values
+
+            finishList :: SList Integer -> SList Integer
+            finishList = smtFunction "C managed list finish" $ \values -> addPrefix values SL.++ literal [3]
+
+            addThree :: SSet Integer -> SSet Integer
+            addThree = smtFunction "C managed set three" $ SS.insert 3
+
+            finishSet :: SSet Integer -> SSet Integer
+            finishSet = smtFunction "C managed set finish" $ \values -> SS.insert 4 (addThree values)
+
+            finishCollections :: SBV ([Integer], RCSet Integer) -> SBV ([Integer], RCSet Integer)
+            finishCollections = smtFunction "C managed collection tuple" $ \collections ->
+                                  let (values, members) = untuple collections
+                                  in tuple (finishList values, finishSet members)
+
+        cgOutput "listResult" (finishList (literal [1, 2]))
+        cgReturn (finishCollections (tuple (literal [1, 2], SS.fromList [1, 2])))
+
+  stdoutText <- compileProgramAndRunGenerated dir "collectionDefinedSBVFunctions" program
+  mapM_ (\fragment -> assertBool ("Expected collection defined-function output to contain " ++ fragment ++ ", received:\n" ++ stdoutText)
+                                 (fragment `isInfixOf` stdoutText))
+    [ ") =([0, 1, 2, 3], {1, 2, 3, 4})"
+    , "listResult =[0, 1, 2, 3]"
+    ]
+
+-- | Exercise persistent array roots passed through composed 'smtFunction'
+-- calls and returned inside a tuple containing its eventual lookup key.
+persistentArrayDefinedSBVFunctions :: Assertion
+persistentArrayDefinedSBVFunctions = withSystemTempDirectory "sbv-persistent-array-defined-functions" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        let storeAt :: SArray Word8 Word32 -> SWord8 -> SWord32 -> SArray Word8 Word32
+            storeAt = smtFunction "C managed array store" writeArray
+
+            storeTwice :: SArray Word8 Word32 -> SArray Word8 Word32
+            storeTwice = smtFunction "C managed array stores" $ \values ->
+                           storeAt (storeAt values 1 11) 2 22
+
+            package :: SArray Word8 Word32 -> SBV (ArrayModel Word8 Word32, Word8)
+            package = smtFunction "C managed array package" $ \values -> tuple (storeTwice values, literal 2)
+
+            base = constArray 5 :: SArray Word8 Word32
+            (updated, selectedKey) = untuple (package base)
+
+        cgOutput "atOne"    (readArray updated 1)
+        cgOutput "fallback" (readArray updated 7)
+        cgReturn (readArray updated selectedKey)
+
+  stdoutText <- compileProgramAndRunGenerated dir "persistentArrayDefinedSBVFunctions" program
+  mapM_ (\fragment -> assertBool ("Expected persistent-array defined-function output to contain " ++ fragment ++ ", received:\n" ++ stdoutText)
+                                 (fragment `isInfixOf` stdoutText))
+    [ ") = 0x00000016UL"
+    , "atOne = 0x0000000bUL"
+    , "fallback = 0x00000005UL"
+    ]
+
+-- | Exercise managed and recursive ADTs returned through composed
+-- 'smtFunction' calls, including stabilization of recursive stack literals.
+ownedADTDefinedSBVFunctions :: Assertion
+ownedADTDefinedSBVFunctions = withSystemTempDirectory "sbv-owned-adt-defined-functions" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [1, 1]
+        let extendCollections :: SCodeGenCollections -> SCodeGenCollections
+            extendCollections = smtFunction "C managed ADT collections" $ \value ->
+              let values                   = getCGCollections_1 value
+                  members                  = getCGCollections_2 value
+                  nested                   = getCGCollections_3 value
+                  (nestedValues, nestedSet) = untuple nested
+              in sCGCollections
+                   (values SL.++ literal [7])
+                   (SS.insert 8 members)
+                   (tuple (nestedValues SL.++ literal [9], SS.insert 10 nestedSet))
+
+            wrapTree :: SCodeGenTree -> SCodeGenTree
+            wrapTree = smtFunction "C managed ADT wrap" $ \tree -> sCGNode tree (sCGLeaf 99)
+
+            wrapTreeTwice :: SCodeGenTree -> SCodeGenTree
+            wrapTreeTwice = smtFunction "C managed ADT wrap twice" $ \tree -> wrapTree (wrapTree tree)
+
+        collections <- cgInput "collectionsInput" :: SBVCodeGen SCodeGenCollections
+        tree        <- cgInput "treeInput"        :: SBVCodeGen SCodeGenTree
+        cgOutput "collections" (extendCollections collections)
+        cgReturn (wrapTreeTwice tree)
+
+  stdoutText <- compileProgramAndRunGenerated dir "ownedADTDefinedSBVFunctions" program
+  sourceText <- readFile (dir </> "ownedADTDefinedSBVFunctions.c")
+  mapM_ (\fragment -> assertBool ("Expected owned-ADT defined-function output to contain " ++ fragment ++ ", received:\n" ++ stdoutText)
+                                 (fragment `isInfixOf` stdoutText))
+    [ ") =CGNode(CGNode("
+    , "CGLeaf(99)), CGLeaf(99))"
+    , "collections =CGCollections([1, 2, 3, 7], {2, 3, 4, 8}, ([3, 4, 5, 9], {4, 5, 6, 10}))"
+    ]
+  assertBool ("Expected private owned ADT results to use stable arena clones, received:\n"
+           ++ unlines (filter ("sbv_function" `isInfixOf`) (lines sourceText)))
+             ("sbv_function_result_clone_" `isInfixOf` sourceText)
+  assertBool "Expected private owned ADT result storage to be released"
+             ("sbv_function_result_ctx_end(&sbv_local_function_result_ctx);" `isInfixOf` sourceText)
+
+-- | An inactive branch must not dereference the null child returned by a
+-- mismatched recursive-ADT selector. Exercise Ite, Boolean short-circuiting,
+-- and a managed result in acyclic functions, standalone and in a library.
+guardedAcyclicDefinedFunctions :: Assertion
+guardedAcyclicDefinedFunctions = mapM_ check [(library, sample) | library <- [False, True], sample <- [1, 0]]
+ where check (library, sample) = withSystemTempDirectory "sbv-guarded-acyclic-functions" $ \dir -> do
+         let functionName = "guardedAcyclicFunctions"
+             program = do
+               cgOverwriteFiles True
+               cgSetDriverValues [sample]
+               chooseLeaf <- cgInput "chooseLeaf" :: SBVCodeGen SBool
+               let guardedLeft :: SCodeGenTree -> SWord8
+                   guardedLeft = smtFunction "C guarded acyclic left" $ \tree ->
+                     ite (isCGLeaf tree) (getCGLeaf_1 tree) (getCGLeaf_1 (getCGNode_1 tree))
+
+                   guardedAnd :: SCodeGenTree -> SBool
+                   guardedAnd = smtFunction "C guarded acyclic and" $ \tree ->
+                     isCGNode tree .&& getCGLeaf_1 (getCGNode_1 tree) .== 7
+
+                   guardedOr :: SCodeGenTree -> SBool
+                   guardedOr = smtFunction "C guarded acyclic or" $ \tree ->
+                     isCGLeaf tree .|| getCGLeaf_1 (getCGNode_1 tree) .== 7
+
+                   guardedImplies :: SCodeGenTree -> SBool
+                   guardedImplies = smtFunction "C guarded acyclic implication" $ \tree ->
+                     isCGNode tree .=> getCGLeaf_1 (getCGNode_1 tree) .== 7
+
+                   guardedTree :: SCodeGenTree -> SCodeGenTree
+                   guardedTree = smtFunction "C guarded acyclic tree" $ \tree ->
+                     ite (isCGLeaf tree) (sCGLeaf (getCGLeaf_1 tree)) (sCGLeaf (getCGLeaf_1 (getCGNode_1 tree)))
+
+                   rootTree = ite chooseLeaf (sCGLeaf 7) (sCGNode (sCGLeaf 7) (sCGLeaf 9))
+               cgOutput "selectedTree" (guardedTree rootTree)
+               cgReturn $ sAnd [guardedLeft rootTree .== 7, guardedAnd rootTree .== sNot chooseLeaf, guardedOr rootTree, guardedImplies rootTree]
+         (_, cfg, bundle) <- if library
+                               then compileToCLib' functionName [("guardedComponent", program)]
+                               else compileToC' functionName ((:[]) <$> program)
+         renderCgPgmBundle (Just dir) (cfg, bundle)
+         outputText <- compileAndRunGenerated dir functionName
+         assertBool outputText (") = 1" `isInfixOf` outputText && "selectedTree =CGLeaf(7)" `isInfixOf` outputText)
+
+-- | Demand-driven evaluation must protect partial selectors both in public
+-- entry points and in retained array callbacks, including owned branch results.
+guardedProgramEvaluation :: Bool -> Assertion
+guardedProgramEvaluation useLambda = mapM_ check [(library, sample) | library <- [False, True], sample <- [1, 0]]
+ where check (library, sample) = withSystemTempDirectory "sbv-guarded-evaluation" $ \dir -> do
+         let functionName = "guardedEvaluation"
+             evaluateTree :: SBool -> SBV (CodeGenTree, Bool)
+             evaluateTree chooseLeaf =
+               let rootTree = ite chooseLeaf (sCGLeaf 7) (sCGNode (sCGLeaf 7) (sCGLeaf 9))
+                   child    = getCGLeaf_1 (getCGNode_1 rootTree)
+                   selected = ite (isCGLeaf rootTree) (sCGLeaf (getCGLeaf_1 rootTree)) (sCGLeaf child)
+                   valid    = sAnd [ (isCGNode rootTree .&& child .== 7) .== sNot chooseLeaf
+                                   , isCGLeaf rootTree .|| child .== 7
+                                   , isCGNode rootTree .=> child .== 7
+                                   ]
+               in tuple (selected, valid)
+             program = do
+               cgOverwriteFiles True
+               cgSetDriverValues [sample]
+               chooseLeaf <- cgInput "chooseLeaf" :: SBVCodeGen SBool
+               let (selected, valid) = untuple $ if useLambda
+                                                  then readArray (lambdaArray evaluateTree) chooseLeaf
+                                                  else evaluateTree chooseLeaf
+               cgOutput "selectedTree" selected
+               cgReturn valid
+         (_, cfg, bundle) <- if library
+                               then compileToCLib' functionName [("guardedComponent", program)]
+                               else compileToC' functionName ((:[]) <$> program)
+         renderCgPgmBundle (Just dir) (cfg, bundle)
+         outputText <- compileAndRunGenerated dir functionName
+         assertBool outputText (") = 1" `isInfixOf` outputText && "selectedTree =CGLeaf(7)" `isInfixOf` outputText)
+
+-- | Preconditions must run before dependent outputs, and must not disappear
+-- when an entry point has no outputs. A rejected leaf must report the named
+-- constraint instead of crashing in the node-only output selector.
+guardedRuntimeChecks :: Assertion
+guardedRuntimeChecks = mapM_ check [(library, noResult, sample) | library <- [False, True], noResult <- [False, True], sample <- [0, 1]]
+ where check (library, noResult, sample) = withSystemTempDirectory "sbv-guarded-checks" $ \dir -> do
+         let functionName = "guardedChecks"
+             program = do
+               cgOverwriteFiles True
+               cgSetDriverValues [sample]
+               chooseLeaf <- cgInput "chooseLeaf" :: SBVCodeGen SBool
+               let rootTree = ite chooseLeaf (sCGLeaf 7) (sCGNode (sCGLeaf 7) (sCGLeaf 9))
+               namedConstraint "node required" (isCGNode rootTree)
+               unless noResult $ cgReturn (getCGLeaf_1 (getCGNode_1 rootTree))
+         (_, cfg, bundle) <- if library
+                               then compileToCLib' functionName [("guardedComponent", program)]
+                               else compileToC' functionName ((:[]) <$> program)
+         renderCgPgmBundle (Just dir) (cfg, bundle)
+         makeOptions <- generatedMakeOptions dir
+         (makeExit, _, makeError) <- readProcessWithExitCode "make" (["-C", dir] ++ makeOptions) ""
+         assertEqual makeError ExitSuccess makeExit
+         (runExit, _, runError) <- readProcessWithExitCode (dir </> functionName ++ "_driver") [] ""
+         if sample == 0
+            then assertEqual runError ExitSuccess runExit
+            else do assertBool "Expected a rejected input" (runExit /= ExitSuccess)
+                    assertBool runError ("CONSTRAINT FAILED: node required" `isInfixOf` runError)
+
+-- | A shared partial dependency must stay below its guard without being
+-- copied exponentially into subsequent conditionals. The generated DAG has
+-- only a few dozen nodes even though its expanded expression tree is large.
+guardedEvaluationSharing :: Assertion
+guardedEvaluationSharing = withSystemTempDirectory "sbv-guarded-sharing" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [0]
+        flags <- cgInput "flags" :: SBVCodeGen SWord32
+        let rootTree = ite (sTestBit flags 31) (sCGLeaf 7) (sCGNode (sCGLeaf 7) (sCGLeaf 9))
+            initial  = ite (isCGLeaf rootTree) (getCGLeaf_1 rootTree) (getCGLeaf_1 (getCGNode_1 rootTree))
+            result   = foldl (\previous bitIndex -> ite (sTestBit flags bitIndex) (previous + 1) (previous + 2)) initial [0 .. 17]
+        cgReturn result
+  (_, cfg, bundle) <- compileToC' "guardedSharing" program
+  assertBool "Guarded evaluation expanded a shared DAG exponentially" (length (show bundle) < 100000)
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  outputText <- compileAndRunGenerated dir "guardedSharing"
+  assertBool outputText (") = 43" `isInfixOf` outputText)
+
+-- | Finite selection demands only the chosen entry or the out-of-range
+-- default. Exercise dynamic owned entries and constant-table defaults at all
+-- three lowering sites, with both standalone and library entry points.
+guardedTableEvaluation :: Assertion
+guardedTableEvaluation = mapM_ check [ (library, scope, checked, sample)
+                                   | library <- [False, True]
+                                   , scope   <- [0 :: Int, 1, 2]
+                                   , checked <- [False, True]
+                                   , sample  <- if checked then [0, 1, 2] else [0, 1]
+                                   ]
+ where check (library, scope, checked, sample) = withSystemTempDirectory "sbv-guarded-tables" $ \dir -> do
+         let functionName = "guardedTables"
+             evaluateTable :: SWord8 -> SBV (CodeGenTree, Word8)
+             evaluateTable index =
+               let rootTree = ite (index .== 0) (sCGLeaf 7) (sCGNode (sCGLeaf 7) (sCGLeaf 9))
+                   child    = getCGLeaf_1 (getCGNode_1 rootTree)
+                   selected = select [sCGLeaf (getCGLeaf_1 rootTree), sCGLeaf child] (sCGLeaf (child + 1)) index
+                   constant = select [7, 9] (child + 1) index
+               in tuple (selected, constant)
+             program = do
+               cgOverwriteFiles True
+               cgPerformRTCs checked
+               cgSetDriverValues [sample]
+               index <- cgInput "index" :: SBVCodeGen SWord8
+               let result = case scope of
+                     0 -> evaluateTable index
+                     1 -> smtFunction "C guarded table function" evaluateTable index
+                     _ -> readArray (lambdaArray evaluateTable) index
+                   (selected, constant) = untuple result
+                   expected = ite (index .< 2) 7 8
+               cgOutput "selectedTree" selected
+               cgReturn (getCGLeaf_1 selected .== expected .&& constant .== ite (index .== 1) 9 expected)
+         (_, cfg, bundle) <- if library
+                               then compileToCLib' functionName [("guardedComponent", program)]
+                               else compileToC' functionName ((:[]) <$> program)
+         renderCgPgmBundle (Just dir) (cfg, bundle)
+         outputText <- compileAndRunGenerated dir functionName
+         assertBool outputText (") = 1" `isInfixOf` outputText)
+
+-- | Check the original index before machine-index narrowing. Large exact,
+-- signed-wide, and unsigned-wide indices must select the default, not alias
+-- slot zero; unselected partial entries remain protected in all three cases.
+guardedTableIndices :: Assertion
+guardedTableIndices = mapM_ check [-1, 0, 1, 2, 2 ^ (80 :: Int)]
+ where check sample = withSystemTempDirectory "sbv-guarded-table-indices" $ \dir -> do
+         let program = do
+               cgOverwriteFiles True
+               cgPerformRTCs True
+               cgSetDriverValues [sample]
+               index <- cgInput "index" :: SBVCodeGen SInteger
+               let rootTree = ite (index .== 0) (sCGLeaf 7) (sCGNode (sCGLeaf 7) (sCGLeaf 9))
+                   child    = getCGLeaf_1 (getCGNode_1 rootTree)
+                   entries  = [sCGLeaf (getCGLeaf_1 rootTree), sCGLeaf child]
+                   fallback = sCGLeaf (child + 1)
+                   exact    = select entries fallback index
+                   signed   = select entries fallback (sFromIntegral index :: SInt 673)
+                   unsigned = select entries fallback (sFromIntegral index :: SWord 673)
+                   expected = ite (index .>= 0 .&& index .< 2) 7 8
+               cgReturn $ sAnd [getCGLeaf_1 selected .== expected | selected <- [exact, signed, unsigned]]
+         outputText <- compileProgramAndRunGenerated dir "guardedTableIndices" program
+         assertBool outputText (") = 1" `isInfixOf` outputText)
+
+-- | Exercise self-recursion, mutually recursive Boolean short-circuiting, and
+-- an owned recursive list result. Each base case must avoid evaluating the
+-- recursive branch in the generated C program.
+recursiveDefinedSBVFunctions :: Assertion
+recursiveDefinedSBVFunctions = withSystemTempDirectory "sbv-recursive-defined-functions" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [5]
+        input <- cgInput "input" :: SBVCodeGen SWord8
+        let countdown :: SWord8 -> SWord8
+            countdown = smtFunctionNoTermination "C recursive countdown" $ \value ->
+                          ite (value .== 0) 0 (1 + countdown (value - 1))
+
+            isEven :: SWord8 -> SBool
+            isEven = smtFunctionNoTermination "C mutually recursive even" $ \value ->
+                       value .== 0 .|| isOdd (value - 1)
+
+            isOdd :: SWord8 -> SBool
+            isOdd = smtFunctionNoTermination "C mutually recursive odd" $ \value ->
+                      value ./= 0 .&& isEven (value - 1)
+
+            implicationChain :: SWord8 -> SBool
+            implicationChain = smtFunctionNoTermination "C recursive implication" $ \value ->
+                                 value ./= 0 .=> implicationChain (value - 1)
+
+            tableCount :: SWord8 -> SWord8
+            tableCount = smtFunctionNoTermination "C recursive local table" $ \value ->
+                           ite (value .== 0) 0
+                               (select [value, value + 1] 3 (ite (value .== 1) 1 0 :: SWord8) + tableCount (value - 1))
+
+            countdownList :: SWord8 -> SList Word8
+            countdownList = smtFunctionNoTermination "C recursive list" $ \value ->
+                              ite (value .== 0)
+                                  (literal [] :: SList Word8)
+                                  (value SL..: countdownList (value - 1))
+
+            factorial :: SInteger -> SInteger
+            factorial = smtFunctionNoTermination "C recursive exact factorial" $ \value ->
+                          ite (value .<= 1) 1 (value * factorial (value - 1))
+
+            mcCarthy91 :: SInteger -> SInteger
+            mcCarthy91 = smtFunctionNoTermination "C nested recursive McCarthy 91" $ \value ->
+                           ite (value .> 100) (value - 10) (mcCarthy91 (mcCarthy91 (value + 11)))
+        cgOutput "steps"       (countdown input)
+        cgOutput "even"        (isEven input)
+        cgOutput "odd"         (isOdd input)
+        cgOutput "implication" (implicationChain input)
+        cgOutput "tableCount"  (tableCount input)
+        cgOutput "factorial"   (factorial 5)
+        cgOutput "mcCarthy91"  (mcCarthy91 87)
+        cgReturn (countdownList input)
+
+  stdoutText <- compileProgramAndRunGenerated dir "recursiveDefinedSBVFunctions" program
+  sourceText <- readFile (dir </> "recursiveDefinedSBVFunctions.c")
+  mapM_ (\fragment -> assertBool ("Expected recursive defined-function output to contain " ++ fragment ++ ", received:\n" ++ stdoutText)
+                                 (fragment `isInfixOf` stdoutText))
+    [ ") =[5, 4, 3, 2, 1]"
+    , "steps = 5"
+    , "even = 0"
+    , "odd = 1"
+    , "implication = 1"
+    , "tableCount = 16"
+    , "factorial =120"
+    , "mcCarthy91 =91"
+    ]
+  assertBool ("Expected recursive calls to remain inside generated control flow, received:\n" ++ sourceText)
+             ("if(" `isInfixOf` sourceText
+           && length (filter ("/* Uninterpreted function */ sbv_function_" `isInfixOf`) (lines sourceText)) >= 4)
+
+-- | Exercise recursive private functions in independent translation units of
+-- a generated static library.
+recursiveDefinedSBVFunctionLibrary :: Assertion
+recursiveDefinedSBVFunctionLibrary = withSystemTempDirectory "sbv-recursive-defined-function-library" $ \dir -> do
+  let component :: Word16 -> SBVCodeGen ()
+      component offset = do
+        cgOverwriteFiles True
+        let sumTo :: SWord8 -> SWord16
+            sumTo = smtFunctionNoTermination "C library recursive sum" $ \value ->
+                      ite (value .== 0) 0 (sFromIntegral value + sumTo (value - 1))
+        cgReturn (literal offset + sumTo 4)
+
+  (_, cfg, bundle) <- compileToCLib' "recursiveDefinedSBVFunctionLibrary"
+    [ ("firstRecursive",  component 10)
+    , ("secondRecursive", component 20)
+    ]
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  stdoutText <- compileAndRunGenerated dir "recursiveDefinedSBVFunctionLibrary"
+  mapM_ (\fragment -> assertBool ("Expected recursive library output to contain " ++ fragment ++ ", received:\n" ++ stdoutText)
+                                 (fragment `isInfixOf` stdoutText))
+    [ "firstRecursive() = 0x0014U"
+    , "secondRecursive() = 0x001eU"
+    ]
+
+-- | Construct and update persistent arrays recursively, then use the returned
+-- arrays after their defining C stack frames have unwound.
+recursivePersistentArrayFunctions :: Assertion
+recursivePersistentArrayFunctions = withSystemTempDirectory "sbv-recursive-persistent-array-functions" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [3]
+        input <- cgInput "input" :: SBVCodeGen SWord8
+        let build :: SWord8 -> SArray Word8 Word8
+            build = smtFunctionNoTermination "C recursive array build" $ \value ->
+                      ite (value .== 0)
+                          (constArray 7)
+                          (writeArray (build (value - 1)) value (value + 10))
+
+            fill :: SWord8 -> SArray Word8 Word8 -> SArray Word8 Word8
+            fill = smtFunctionNoTermination "C recursive array fill" $ \value array ->
+                     ite (value .== 0)
+                         array
+                         (fill (value - 1) (writeArray array value (value + 20)))
+
+            built  = build input
+            filled = fill input built
+
+        cgOutput "builtAtOne"   (readArray built 1)
+        cgOutput "builtAtInput" (readArray built input)
+        cgOutput "filledAtOne"  (readArray filled 1)
+        cgOutput "fallback"     (readArray filled 9)
+        cgReturn filled
+
+  stdoutText <- compileProgramAndRunGenerated dir "recursivePersistentArrayFunctions" program
+  sourceText <- readFile (dir </> "recursivePersistentArrayFunctions.c")
+  mapM_ (\fragment -> assertBool ("Expected recursive persistent-array output to contain " ++ fragment ++ ", received:\n" ++ stdoutText)
+                                 (fragment `isInfixOf` stdoutText))
+    [ ")[0] =7"
+    , "builtAtOne = 11"
+    , "builtAtInput = 13"
+    , "filledAtOne = 21"
+    , "fallback = 7"
+    ]
+  assertBool ("Expected recursive array nodes to be declared outside guarded branches, received:\n" ++ sourceText)
+             ("sbv_array_node_2_u8_2_u8 sbv_local_array_s" `isInfixOf` sourceText
+           && "sbv_array_stored_export_2_u8_2_u8(&sbv_local_array_ctx" `isInfixOf` sourceText)
+
+-- | Construct, traverse, and return a recursive ADT through private recursive
+-- functions after every child-producing C stack frame has unwound.
+recursiveADTDefinedSBVFunctions :: Assertion
+recursiveADTDefinedSBVFunctions = withSystemTempDirectory "sbv-recursive-adt-defined-functions" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [3]
+        input <- cgInput "input" :: SBVCodeGen SWord8
+        let build :: SWord8 -> SCodeGenTree
+            build = smtFunctionNoTermination "C recursive ADT build" $ \value ->
+                      ite (value .== 0)
+                          (literal (CGNode (CGLeaf 4) (CGLeaf 5)))
+                          (sCGNode (build (value - 1)) (sCGLeaf value))
+
+            leftmost :: SCodeGenTree -> SWord8
+            leftmost = smtFunctionNoTermination "C recursive ADT leftmost" $ \tree ->
+                         ite (isCGLeaf tree)
+                             (getCGLeaf_1 tree)
+                             (leftmost (getCGNode_1 tree))
+
+            leafSum :: SCodeGenTree -> SWord16
+            leafSum = smtFunctionNoTermination "C recursive ADT leaf sum" $ \tree ->
+                        ite (isCGLeaf tree)
+                            (sFromIntegral (getCGLeaf_1 tree))
+                            (leafSum (getCGNode_1 tree) + leafSum (getCGNode_2 tree))
+
+            buildEven :: SWord8 -> SCodeGenEven
+            buildEven = smtFunctionNoTermination "C mutually recursive ADT even" $ \value ->
+                          ite (value .== 0)
+                              (sCGEvenEnd 0)
+                              (sCGEvenStep (buildOdd (value - 1)))
+
+            buildOdd :: SWord8 -> SCodeGenOdd
+            buildOdd = smtFunctionNoTermination "C mutually recursive ADT odd" $ sCGOddStep . buildEven
+
+            result = build input
+
+        cgOutput "leftmost" (leftmost result)
+        cgOutput "leafSum"  (leafSum result)
+        cgOutput "mutual"   (buildEven input)
+        cgReturn result
+
+  stdoutText <- compileProgramAndRunGenerated dir "recursiveADTDefinedSBVFunctions" program
+  sourceText <- readFile (dir </> "recursiveADTDefinedSBVFunctions.c")
+  mapM_ (\fragment -> assertBool ("Expected recursive-ADT function output to contain " ++ fragment ++ ", received:\n" ++ stdoutText)
+                                 (fragment `isInfixOf` stdoutText))
+    [ ") =CGNode(CGNode(CGNode(CGNode(CGLeaf(4), CGLeaf(5)), CGLeaf(1)), CGLeaf(2)), CGLeaf(3))"
+    , "leftmost = 4"
+    , "leafSum = 0x000fU"
+    , "mutual =CGEvenStep(CGOddStep(CGEvenStep(CGOddStep(CGEvenStep(CGOddStep(CGEvenEnd(0)))))))"
+    ]
+  assertBool ("Expected recursive ADT fields to use function-scoped backing values, received:\n" ++ sourceText)
+             ("SBVADT_CodeGenTree sbv_local_adt_recursive_" `isInfixOf` sourceText
+           && "sbv_function_result_clone_adt_" `isInfixOf` sourceText
+           && any (\line -> "const SBVADT_CodeGenTree l1_s" `isInfixOf` line
+                          && "= (SBVADT_CodeGenTree)" `isInfixOf` line)
+                  (lines sourceText))
+
+-- | Exercise private recursive ADT builders in independent translation units
+-- of a generated static library.
+recursiveADTDefinedSBVFunctionLibrary :: Assertion
+recursiveADTDefinedSBVFunctionLibrary = withSystemTempDirectory "sbv-recursive-adt-defined-function-library" $ \dir -> do
+  let component :: Word8 -> SBVCodeGen ()
+      component offset = do
+        cgOverwriteFiles True
+        let build :: SWord8 -> SCodeGenTree
+            build = smtFunctionNoTermination "C library recursive ADT build" $ \value ->
+                      ite (value .== 0)
+                          (sCGLeaf (literal offset))
+                          (sCGNode (build (value - 1)) (sCGLeaf (literal offset + value)))
+        cgReturn (build 2)
+
+  (_, cfg, bundle) <- compileToCLib' "recursiveADTDefinedSBVFunctionLibrary"
+    [ ("firstRecursiveADT", component 10)
+    , ("secondRecursiveADT", component 20)
+    ]
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  stdoutText <- compileAndRunGenerated dir "recursiveADTDefinedSBVFunctionLibrary"
+  mapM_ (\fragment -> assertBool ("Expected recursive-ADT library output to contain " ++ fragment ++ ", received:\n" ++ stdoutText)
+                                 (fragment `isInfixOf` stdoutText))
+    [ "firstRecursiveADT() =CGNode(CGNode(CGLeaf(10), CGLeaf(11)), CGLeaf(12))"
+    , "secondRecursiveADT() =CGNode(CGNode(CGLeaf(20), CGLeaf(21)), CGLeaf(22))"
+    ]
+
+-- | Compile SBV's firstified higher-order list operations, including an
+-- explicit symbolic closure environment, into ordinary private C functions.
+higherOrderListFunctions :: Assertion
+higherOrderListFunctions = withSystemTempDirectory "sbv-higher-order-list-functions" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [10, 5]
+        values <- cgInput "values" :: SBVCodeGen (SList Word8)
+        offset <- cgInput "offset" :: SBVCodeGen SWord8
+        let mapped   = SL.map (+ (1 :: SWord8)) values
+            filtered = SL.filter (\value -> value .> (11 :: SWord8)) mapped
+            folded   = SL.foldl ((+) @SWord8) 0 mapped
+            paired   = SL.zipWith ((+) @SWord8) values mapped
+
+            closureShift :: Closure SWord8 (SWord8 -> SWord8)
+            closureShift = Closure { closureEnv = offset
+                                   , closureFun = (+)
+                                   }
+
+            shifted = SL.map closureShift values
+
+        cgOutput "mapped"   mapped
+        cgOutput "filtered" filtered
+        cgOutput "folded"   folded
+        cgOutput "paired"   paired
+        cgReturn shifted
+
+  stdoutText <- compileProgramAndRunGenerated dir "higherOrderListFunctions" program
+  sourceText <- readFile (dir </> "higherOrderListFunctions.c")
+  mapM_ (\fragment -> assertBool ("Expected firstified higher-order output to contain " ++ fragment ++ ", received:\n" ++ stdoutText)
+                                 (fragment `isInfixOf` stdoutText))
+    [ ") =[15, 16, 17]"
+    , "mapped =[11, 12, 13]"
+    , "filtered =[12, 13]"
+    , "folded = 36"
+    , "paired =[21, 23, 25]"
+    ]
+  assertBool ("Expected higher-order instances to become private first-order C functions, received:\n" ++ sourceText)
+             ("/* Uninterpreted function */ sbv_function_" `isInfixOf` sourceText)
+
+-- | Exercise independently specialized higher-order functions in separate
+-- translation units of a generated static library.
+higherOrderListFunctionLibrary :: Assertion
+higherOrderListFunctionLibrary = withSystemTempDirectory "sbv-higher-order-list-function-library" $ \dir -> do
+  let component :: Word8 -> SBVCodeGen ()
+      component offset = do
+        cgOverwriteFiles True
+        cgSetDriverValues [10]
+        values <- cgInput "values" :: SBVCodeGen (SList Word8)
+        cgReturn (SL.map (\(value :: SWord8) -> value + literal offset) values)
+
+  (_, cfg, bundle) <- compileToCLib' "higherOrderListFunctionLibrary"
+    [ ("addTen", component 10)
+    , ("addTwenty", component 20)
+    ]
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  stdoutText <- compileAndRunGenerated dir "higherOrderListFunctionLibrary"
+  mapM_ (\fragment -> assertBool ("Expected higher-order library output to contain " ++ fragment ++ ", received:\n" ++ stdoutText)
+                                 (fragment `isInfixOf` stdoutText))
+    [ "addTen(((SBVList_u8) {(const SWord8[]) {10, 11, 12}, 3})) =[20, 21, 22]"
+    , "addTwenty(((SBVList_u8) {(const SWord8[]) {10, 11, 12}, 3})) =[30, 31, 32]"
+    ]
+
+-- | Exercise unnamed and named hard constraints as generated-C precondition
+-- checks, including a Boolean input used only by a constraint and an escaped
+-- UTF-8 diagnostic name.
+explicitHardConstraints :: Assertion
+explicitHardConstraints = withSystemTempDirectory "sbv-explicit-hard-constraints" $ \dir -> do
+  let constraintName = "value is \"seven\" (100%) \955"
+      program driverValues = do
+        cgOverwriteFiles True
+        cgSetDriverValues driverValues
+        enabled <- cgInput "enabled" :: SBVCodeGen SBool
+        value   <- cgInput "value"   :: SBVCodeGen SWord8
+        constrain enabled
+        namedConstraint constraintName (value .== 7)
+        cgReturn (value + 1)
+
+      validDir   = dir </> "valid"
+      invalidDir = dir </> "invalid"
+
+  validOutput <- compileProgramAndRunGenerated validDir "explicitHardConstraints" (program [1, 7])
+  assertBool ("Expected constrained output to contain 8, received:\n" ++ validOutput)
+             (") = 8" `isInfixOf` validOutput)
+
+  (_, invalidCfg, invalidBundle) <- compileToC' "explicitHardConstraints" (program [1, 6])
+  renderCgPgmBundle (Just invalidDir) (invalidCfg, invalidBundle)
+  makeOptions <- generatedMakeOptions invalidDir
+  (makeExit, _, makeError) <- readProcessWithExitCode "make" (["-C", invalidDir] ++ makeOptions) ""
+  assertEqual makeError ExitSuccess makeExit
+  (runExit, _, runError) <- readProcessWithExitCode (invalidDir </> "explicitHardConstraints_driver") [] ""
+  assertBool "Expected a violated hard constraint to terminate the generated driver"
+             (case runExit of ExitFailure _ -> True; ExitSuccess -> False)
+  assertBool ("Expected the named constraint diagnostic, received:\n" ++ runError)
+             (("CONSTRAINT FAILED: " ++ constraintName) `isInfixOf` runError)
+
+-- | Check that constraint forms requiring solver optimization or SMT-only
+-- attributes receive focused diagnostics instead of being silently weakened.
+unsupportedConstraintFeatures :: Assertion
+unsupportedConstraintFeatures = do
+  softResult <- try (do
+    (_, _, bundle) <- compileToC' "softConstraint" $ do
+      value <- cgInput "value" :: SBVCodeGen SBool
+      softConstrain value
+      cgReturn value
+    evaluate (length (show bundle))) :: IO (Either ErrorCall Int)
+  case softResult of
+    Left exception -> assertBool ("Expected a soft-constraint diagnostic, received:\n" ++ displayException exception)
+                                 ("Soft constraints" `isInfixOf` displayException exception)
+    Right _        -> assertBool "Expected C generation to reject a soft constraint" False
+
+  attributeResult <- try (do
+    (_, _, bundle) <- compileToC' "attributedConstraint" $ do
+      value <- cgInput "value" :: SBVCodeGen SBool
+      constrainWithAttribute [(":weight", "2")] value
+      cgReturn value
+    evaluate (length (show bundle))) :: IO (Either ErrorCall Int)
+  case attributeResult of
+    Left exception -> assertBool ("Expected a constraint-attribute diagnostic, received:\n" ++ displayException exception)
+                                 ("Constraint attributes: :weight" `isInfixOf` displayException exception)
+    Right _        -> assertBool "Expected C generation to reject an SMT-only constraint attribute" False
+
+-- | Exercise a sole 'cgReturnArr' group through the generated output-parameter
+-- ABI while preserving the return elements' declaration order.
+nonAtomicReturnGroup :: Assertion
+nonAtomicReturnGroup = withSystemTempDirectory "sbv-non-atomic-return-group" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [4]
+        input <- cgInput "input" :: SBVCodeGen SWord16
+        cgReturnArr [input + 1, input + 2, input + 3]
+
+  stdoutText <- compileProgramAndRunGenerated dir "nonAtomicReturnGroup" program
+  headerText <- readFile (dir </> "nonAtomicReturnGroup.h")
+  mapM_ (\fragment -> assertBool ("Expected non-atomic return output to contain " ++ fragment ++ ", received:\n" ++ stdoutText)
+                                 (fragment `isInfixOf` stdoutText))
+    [ "result_0[0] = 0x0005U"
+    , "result_0[1] = 0x0006U"
+    , "result_0[2] = 0x0007U"
+    ]
+  assertBool "Expected a sole array return group to use a void output-parameter ABI"
+             ("void nonAtomicReturnGroup(" `isInfixOf` headerText
+           && "SWord16 *result_0" `isInfixOf` headerText)
+
+-- | Exercise multiple ordered return groups containing a scalar, an owned
+-- symbolic list, and a fixed-size C array.
+multipleReturnGroups :: Assertion
+multipleReturnGroups = withSystemTempDirectory "sbv-multiple-return-groups" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [4]
+        input <- cgInput "input" :: SBVCodeGen SWord16
+        cgReturn (input + 1)
+        cgReturn (literal ([10, 11] :: [Word16]))
+        cgReturn (sFromIntegral input + 20 :: SInteger)
+        cgReturnArr [input + 2, input + 3]
+
+  stdoutText <- compileProgramAndRunGenerated dir "multipleReturnGroups" program
+  headerText <- readFile (dir </> "multipleReturnGroups.h")
+  mapM_ (\fragment -> assertBool ("Expected multiple-return output to contain " ++ fragment ++ ", received:\n" ++ stdoutText)
+                                 (fragment `isInfixOf` stdoutText))
+    [ "result_0 = 0x0005U"
+    , "result_1 =[0x000aU, 0x000bU]"
+    , "result_2 =24"
+    , "result_3[0] = 0x0006U"
+    , "result_3[1] = 0x0007U"
+    ]
+  assertBool "Expected multiple return groups to use ordered output parameters"
+             ("void multipleReturnGroups(" `isInfixOf` headerText
+           && "SWord16 *result_0" `isInfixOf` headerText
+           && "SWord16 *result_3" `isInfixOf` headerText)
+
+-- | Fixed-size symbolic-array inputs use public callback descriptors rather
+-- than private array nodes. Distinct seeds must initialize each callback, and
+-- managed defaults and returned arrays have independent ownership.
+groupedArrayInputs :: Bool -> Assertion
+groupedArrayInputs library = withSystemTempDirectory "sbv-grouped-array-inputs" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [3, 7, 11, 15]
+        native <- cgInputArr 2 "native" :: SBVCodeGen [SArray Word8 Word16]
+        exact  <- cgInputArr 2 "exact"  :: SBVCodeGen [SArray Word8 [Integer]]
+        cgOutputArr "nativeValues" [readArray value 0 | value <- native]
+        cgOutputArr "exactHeads" [SL.head (readArray value 0) | value <- exact]
+        cgReturnArr native
+        cgReturnArr exact
+  outputText <- runGroupedInputProgram dir "groupedArrayInputs" library program
+  headerText <- readFile (dir </> "groupedArrayInputs.h")
+  mapM_ (\fragment -> assertBool outputText (fragment `isInfixOf` outputText))
+    [ "nativeValues[0] = 0x0003U"
+    , "nativeValues[1] = 0x0007U"
+    , "exactHeads[0] = 11"
+    , "exactHeads[1] = 15"
+    , "result_0[1][0] =0x0007U"
+    , "result_1[1][0] =[15, 16, 17]"
+    ]
+  assertBool "Expected public callback descriptors for grouped array inputs"
+             ("const SBVArrayInput_2_u8_3_u16 *native" `isInfixOf` headerText)
+
+-- | A hand-written caller can pass callback groups without private runtime
+-- nodes. Returned groups retain each context independently across later calls.
+groupedArrayInputOwnership :: Assertion
+groupedArrayInputOwnership = withSystemTempDirectory "sbv-grouped-array-ownership" $ \dir -> do
+  _ <- compileToCLib (Just dir) "arrayGroupLibrary"
+    [("copyArrayGroup", do
+        cgOverwriteFiles True
+        cgGenerateDriver False
+        values <- cgInputArr 2 "values" :: SBVCodeGen [SArray Word8 Word16]
+        cgReturnArr values)]
+  compileAndRunCaller dir "arrayGroupLibrary" $ unlines
+    [ "#include \"arrayGroupLibrary.h\""
+    , "#include <assert.h>"
+    , "static unsigned live_contexts;"
+    , "static SWord16 lookup(const void *context, SWord8 key)"
+    , "{ return *(const SWord16 *) context + key; }"
+    , "static const void *retain(const void *context)"
+    , "{ SWord16 *copy = malloc(sizeof(*copy)); assert(copy != NULL); *copy = *(const SWord16 *) context; ++live_contexts; return copy; }"
+    , "static void release(const void *context)"
+    , "{ --live_contexts; free((void *) context); }"
+    , "int main(void)"
+    , "{"
+    , "  for (unsigned i = 0; i < 32; ++i) {"
+    , "    SWord16 data[] = {7, 23};"
+    , "    const SBVArrayInput_2_u8_3_u16 inputs[] = {{lookup, &data[0], retain, release}, {lookup, &data[1], retain, release}};"
+    , "    SBVArrayOutput_2_u8_3_u16 first[2], second[2];"
+    , "    copyArrayGroup(inputs, first);"
+    , "    data[0] = 99; data[1] = 101;"
+    , "    const SBVArrayInput_2_u8_3_u16 borrowed[] = {sbv_array_output_as_input_2_u8_3_u16(first[1]), sbv_array_output_as_input_2_u8_3_u16(first[0])};"
+    , "    copyArrayGroup(borrowed, second);"
+    , "    for (unsigned j = 0; j < 2; ++j) sbv_array_output_release_2_u8_3_u16(&first[j]);"
+    , "    assert(live_contexts == 2);"
+    , "    assert(sbv_array_output_read_2_u8_3_u16(second[0], 1) == 24);"
+    , "    assert(sbv_array_output_read_2_u8_3_u16(second[1], 1) == 8);"
+    , "    for (unsigned j = 0; j < 2; ++j) sbv_array_output_release_2_u8_3_u16(&second[j]);"
+    , "    assert(live_contexts == 0);"
+    , "  }"
+    , "  return 0;"
+    , "}"
+    ]
+
+-- | Managed input groups need per-element initialization, including nested
+-- exact values and retained arrays, followed by exactly one owner cleanup.
+groupedManagedInputs :: Bool -> Assertion
+groupedManagedInputs library = withSystemTempDirectory "sbv-grouped-managed-inputs" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [3, 7, 11, 15, 21, 25, 1, 5, 31, 35]
+        lists  <- cgInputArr 2 "lists"  :: SBVCodeGen [SList Integer]
+        sets   <- cgInputArr 2 "sets"   :: SBVCodeGen [SSet Rational]
+        pairs  <- cgInputArr 2 "pairs"  :: SBVCodeGen [SBV (Integer, [Integer])]
+        adts   <- cgInputArr 2 "adts"   :: SBVCodeGen [SCodeGenCollections]
+        arrays <- cgInputArr 2 "arrays" :: SBVCodeGen [SList (ArrayModel Word8 Word16)]
+        cgOutputArr "listHeads" (map SL.head lists)
+        cgOutputArr "pairIntegers" (map (fst . untuple) pairs)
+        cgOutputArr "arrayHeads" [readArray (SL.head value) 0 | value <- arrays]
+        cgReturnArr lists
+        cgReturnArr sets
+        cgReturnArr pairs
+        cgReturnArr adts
+        cgReturnArr arrays
+  outputText <- runGroupedInputProgram dir "groupedManagedInputs" library program
+  mapM_ (\fragment -> assertBool outputText (fragment `isInfixOf` outputText))
+    [ "listHeads[0] = 3"
+    , "listHeads[1] = 7"
+    , "pairIntegers[0] = 21"
+    , "pairIntegers[1] = 25"
+    , "arrayHeads[0] = 0x001fU"
+    , "arrayHeads[1] = 0x0023U"
+    , "result_0[1] = [7, 8, 9]"
+    ]
+
+-- | Exercise the same grouped-input program through standalone generation
+-- and two translation units sharing one library header and combined driver.
+runGroupedInputProgram :: FilePath -> String -> Bool -> SBVCodeGen () -> IO String
+runGroupedInputProgram dir programName library program
+  | library = do
+      (_, cfg, bundle) <- compileToCLib' programName [(programName ++ "First", program), (programName ++ "Second", program)]
+      renderCgPgmBundle (Just dir) (cfg, bundle)
+      compileAndRunGenerated dir programName
+  | True = compileProgramAndRunGenerated dir programName program
+
+-- | Exercise deep ownership and element-wise cleanup for non-atomic return
+-- groups containing lists, exact integers, and persistent arrays.
+managedReturnGroups :: Assertion
+managedReturnGroups = withSystemTempDirectory "sbv-managed-return-groups" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [4]
+        input <- cgInput "input" :: SBVCodeGen SWord16
+        let baseArray = constArray 5 :: SArray Word8 Word16
+        cgReturnArr [ literal ([1, 2] :: [Word16])
+                    , literal ([3, 4] :: [Word16])
+                    ]
+        cgReturnArr [ sFromIntegral input + 30 :: SInteger
+                    , sFromIntegral input + 31
+                    ]
+        cgReturnArr [baseArray, writeArray baseArray 0 9]
+
+  stdoutText <- compileProgramAndRunGenerated dir "managedReturnGroups" program
+  headerText <- readFile (dir </> "managedReturnGroups.h")
+  sourceText <- readFile (dir </> "managedReturnGroups.c")
+  driverText <- readFile (dir </> "managedReturnGroups_driver.c")
+  mapM_ (\fragment -> assertBool ("Expected managed return-group output to contain " ++ fragment ++ ", received:\n" ++ stdoutText)
+                                 (fragment `isInfixOf` stdoutText))
+    [ "result_0[0] = [0x0001U, 0x0002U]"
+    , "result_0[1] = [0x0003U, 0x0004U]"
+    , "result_1[0] = 34"
+    , "result_1[1] = 35"
+    , "result_2[0][0] =0x0005U"
+    , "result_2[1][0] =0x0009U"
+    ]
+  assertBool "Expected exact and persistent-array groups to expose mutable output arrays"
+             ("mpz_t *result_1" `isInfixOf` headerText
+           && "SBVArrayOutput_2_u8_3_u16 *result_2" `isInfixOf` headerText)
+  assertBool ("Expected managed group elements to be cloned and released independently, received:\n"
+           ++ unlines (filter ("sbv_" `isInfixOf`) (lines (sourceText ++ driverText))))
+             ("sbv_output_0[0] = sbv_list_clone_u16" `isInfixOf` sourceText
+           && "sbv_list_release_u16(&sbv_driver_output_0[0]);" `isInfixOf` driverText
+           && "sbv_array_output_release_2_u8_3_u16(&sbv_driver_output_2[0]);" `isInfixOf` driverText)
+
+-- | Exercise grouped return ABIs across multiple generated library
+-- translation units.
+groupedReturnLibrary :: Assertion
+groupedReturnLibrary = withSystemTempDirectory "sbv-grouped-return-library" $ \dir -> do
+  let component increment seed = do
+        cgOverwriteFiles True
+        cgSetDriverValues [seed]
+        input <- cgInput "input" :: SBVCodeGen SWord16
+        cgReturnArr [input + literal increment, input + literal increment + 1]
+        cgReturn (literal ([increment, increment + 1] :: [Word16]))
+
+  (_, cfg, bundle) <- compileToCLib' "groupedReturnLibrary"
+    [ ("firstGroups",  component 1 4)
+    , ("secondGroups", component 2 8)
+    ]
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  stdoutText <- compileAndRunGenerated dir "groupedReturnLibrary"
+  headerText <- readFile (dir </> "groupedReturnLibrary.h")
+  mapM_ (\fragment -> assertBool ("Expected grouped library output to contain " ++ fragment ++ ", received:\n" ++ stdoutText)
+                                 (fragment `isInfixOf` stdoutText))
+    [ "result_0[0] = 0x0005U"
+    , "result_0[1] = 0x0006U"
+    , "result_1 =[0x0001U, 0x0002U]"
+    , "result_0[0] = 0x000aU"
+    , "result_0[1] = 0x000bU"
+    , "result_1 =[0x0002U, 0x0003U]"
+    ]
+  assertBool "Expected both library components to publish grouped output parameters"
+             ("void firstGroups(" `isInfixOf` headerText
+           && "void secondGroups(" `isInfixOf` headerText
+           && length (filter ("SWord16 *result_0" `isInfixOf`) (lines headerText)) == 2)
+
+-- | Exercise 'freeArray' by supplying the corresponding total C function as
+-- a user declaration, preserving the existing uninterpreted-function escape hatch.
+definedFreeArray :: Assertion
+definedFreeArray = withSystemTempDirectory "sbv-defined-free-array" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [9]
+        cgAddDecl ["static SWord32 free_source(SWord16 key) { return (SWord32) key + UINT32_C(5); }"]
+        key <- cgInput "key" :: SBVCodeGen SWord16
+        let source = freeArray "free_source" :: SArray Word16 Word32
+        cgReturn (readArray source key)
+
+  stdoutText <- compileProgramAndRunGenerated dir "definedFreeArray" program
+  assertBool ("Expected defined free-array output to contain 0x0000000eUL, received:\n" ++ stdoutText) ("0x0000000eUL" `isInfixOf` stdoutText)
+
+-- | Exercise independent owned descriptors for an array output parameter and
+-- an array return, including persistent stores above a structured callback.
+ownedArrayResults :: Assertion
+ownedArrayResults = withSystemTempDirectory "sbv-owned-array-results" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        let source = lambdaArray (\index -> sFromIntegral index + 5) :: SArray Word8 Word32
+        cgOutput "owned" (writeArray source 0 99)
+        cgReturn (writeArray source 0 42)
+
+  stdoutText <- compileProgramAndRunGenerated dir "ownedArrayResults" program
+  mapM_ (\fragment -> assertBool ("Expected owned-array output to contain " ++ fragment ++ ", received:\n" ++ stdoutText) (fragment `isInfixOf` stdoutText))
+    [ "ownedArrayResults(&owned)[0] =0x0000002aUL"
+    , "owned[0] =0x00000063UL"
+    ]
+
+-- | Exercise retention of a borrowed input callback when a persistent array
+-- derived from it escapes through an owned return descriptor.
+escapingCallbackArray :: Assertion
+escapingCallbackArray = withSystemTempDirectory "sbv-escaping-callback-array" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [7]
+        source <- cgInput "source" :: SBVCodeGen (SArray Word8 Word32)
+        cgReturn (writeArray source 1 99)
+
+  stdoutText <- compileProgramAndRunGenerated dir "escapingCallbackArray" program
+  assertBool ("Expected retained callback output to contain 0x00000007UL, received:\n" ++ stdoutText) ("[0] =0x00000007UL" `isInfixOf` stdoutText)
+
+-- | Exercise structural object equality and deep ownership for array keys and
+-- values containing lists, sets, strings, tuples, and concrete ADTs.
+managedAggregateArrays :: Assertion
+managedAggregateArrays = withSystemTempDirectory "sbv-managed-aggregate-arrays" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [4, 10, 12]
+        source      <- cgInput "source"      :: SBVCodeGen (SArray [Word16] CodeGenNativeCollections)
+        key         <- cgInput "key"         :: SBVCodeGen (SList Word16)
+        exactSource <- cgInput "exactSource" :: SBVCodeGen (SArray Word8 (String, Integer))
+        let storedADT    = sCGNativeCollections
+                               (literal ([90, 91] :: [Word16]))
+                               (SS.fromList [92, 93])
+            updatedADT   = writeArray source key storedADT
+            stringKey    = literal "stored" :: SString
+            defaultTuple = tuple (literal "default" :: SString, literal ([1, 2] :: [Integer]))
+            storedTuple  = tuple (literal "stored-value" :: SString, literal ([7, 8] :: [Integer]))
+            tupleArray   = writeArray (constArray defaultTuple :: SArray String (String, [Integer])) stringKey storedTuple
+            setKey       = SS.fromList [5, 6] :: SSet Word16
+            storedList   = literal ([7, 8] :: [Word16])
+            setArray     = writeArray (constArray (literal ([1, 2] :: [Word16])) :: SArray (RCSet Word16) [Word16]) setKey storedList
+            enumArray    = writeArray (constArray 3 :: SArray CodeGenEnum Word8) sCGBlue 9
+        cgOutput "matchedADT" (readArray updatedADT key .=== storedADT)
+        cgOutput "matchedSet" (readArray setArray setKey .=== storedList)
+        cgOutput "matchedEnum" (readArray enumArray sCGBlue .== (9 :: SWord8))
+        cgOutput "storedADT" (readArray updatedADT key)
+        cgOutput "tupleArray" tupleArray
+        cgOutput "storedTuple" (readArray tupleArray stringKey)
+        cgOutput "setArray" setArray
+        cgOutput "enumArray" enumArray
+        cgOutput "exactSourceCopy" exactSource
+        cgReturn updatedADT
+
+  stdoutText <- compileProgramAndRunGenerated dir "managedAggregateArrays" program
+  headerText <- readFile (dir </> "managedAggregateArrays.h")
+  sourceText <- readFile (dir </> "managedAggregateArrays.c")
+  driverText <- readFile (dir </> "managedAggregateArrays_driver.c")
+  mapM_ (\fragment -> assertBool ("Expected managed aggregate-array output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ "matchedADT = 1"
+    , "matchedSet = 1"
+    , "matchedEnum = 1"
+    , "storedADT =CGNativeCollections([0x005aU, 0x005bU], {0x005cU, 0x005dU})"
+    , "storedTuple =(stored-value, [7, 8])"
+    , "tupleArray[0] =(default, [1, 2])"
+    , "setArray[0] =[0x0001U, 0x0002U]"
+    , "enumArray[0] =3"
+    , "exactSourceCopy[0] =(sbv12, 13)"
+    ]
+  assertBool "Expected exported arrays to own aggregate keys and values"
+             ("sbv_list_clone_u16(source->key)" `isInfixOf` sourceText
+           && "sbv_adt_owned_clone_SBVADT_CodeGenNativeCollections(source->value)" `isInfixOf` sourceText
+           && "sbv_string_clone(source->key)" `isInfixOf` sourceText
+           && "sbv_tuple_owned_clone_" `isInfixOf` sourceText
+           && "sbv_set_clone_u16(source->key)" `isInfixOf` sourceText
+           && "sbv_list_clone_u16(source->value)" `isInfixOf` sourceText
+           && "sbv_adt_owned_clone_SBVADT_CodeGenEnum(source->key)" `isInfixOf` sourceText
+           && "sbv_adt_owned_release_SBVADT_CodeGenNativeCollections" `isInfixOf` sourceText)
+  assertBool "Expected managed callback defaults to use deep retain and release helpers"
+             ("sbv_adt_owned_clone_SBVADT_CodeGenNativeCollections" `isInfixOf` headerText
+           && "sbv_local_array_retain_" `isInfixOf` driverText
+           && "sbv_local_array_release_" `isInfixOf` driverText
+           && "sbv_tuple_owned_clone_" `isInfixOf` driverText
+           && "sbv_tuple_owned_release_" `isInfixOf` driverText)
+
+-- | Exercise guarded aggregate-array declarations and owned return values
+-- shared by multiple generated library translation units.
+managedAggregateArrayLibrary :: Assertion
+managedAggregateArrayLibrary = withSystemTempDirectory "sbv-managed-aggregate-array-library" $ \dir -> do
+  let component :: Integer -> Word16 -> SBVCodeGen ()
+      component seed keyValue = do
+        cgOverwriteFiles True
+        cgSetDriverValues [seed]
+        source <- cgInput "source" :: SBVCodeGen (SArray (RCSet Word16) CodeGenNativeCollections)
+        let key   = SS.singleton (literal keyValue)
+            value = sCGNativeCollections
+                      (literal ([keyValue, keyValue + 1] :: [Word16]))
+                      (SS.fromList [keyValue + 2, keyValue + 3])
+        cgReturn (writeArray source key value)
+
+  (_, cfg, bundle) <- compileToCLib' "managedAggregateArrayLibrary"
+    [ ("firstManagedArray",  component 1 20)
+    , ("secondManagedArray", component 4 30)
+    ]
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  stdoutText <- compileAndRunGenerated dir "managedAggregateArrayLibrary"
+  headerText <- readFile (dir </> "managedAggregateArrayLibrary.h")
+  mapM_ (\fragment -> assertBool ("Expected managed aggregate-array library output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ "firstManagedArray(source)[0] =CGNativeCollections([0x0001U, 0x0002U, 0x0003U]"
+    , "secondManagedArray(source)[0] =CGNativeCollections([0x0004U, 0x0005U, 0x0006U]"
+    ]
+  assertBool "Expected one reusable guarded aggregate-array ABI"
+             ("SBVArrayOutput_9_set_3_u16_39_adt_SBVADT_x5f_CodeGenNativeCollections" `isInfixOf` headerText
+           && "sbv_array_output_release_9_set_3_u16_39_adt_SBVADT_x5f_CodeGenNativeCollections" `isInfixOf` headerText)
+
+-- | Exercise static and runtime-local finite tables containing text, lists,
+-- sets, and ADTs with managed collection fields.
+managedAggregateTables :: Assertion
+managedAggregateTables = withSystemTempDirectory "sbv-managed-aggregate-tables" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [1, 5]
+        selector <- cgInput "selector" :: SBVCodeGen SWord8
+        source   <- cgInput "source"   :: SBVCodeGen (SList Word16)
+        let staticText :: SString
+            staticText  = select [literal "zero", literal "one"] (literal "other") selector
+            staticList  = select [literal ([1, 2] :: [Word16]), literal ([3, 4] :: [Word16])]
+                                 (literal ([9] :: [Word16])) selector
+            dynamicList = select [source, source SL.++ SL.singleton 9]
+                                 (literal ([10] :: [Word16])) selector
+            staticSet :: SSet Word16
+            staticSet   = select [SS.fromList [1, 2], SS.fromList [3, 4]]
+                                 (SS.singleton 9) selector
+            firstADT    = sCGNativeCollections source (SS.singleton 20)
+            secondADT   = sCGNativeCollections (source SL.++ SL.singleton 21) (SS.fromList [22, 23])
+            selectedADT = select [firstADT, secondADT] (sCGNativeCollections SL.nil SS.empty) selector
+        cgOutput "staticText" staticText
+        cgOutput "staticList" staticList
+        cgOutput "dynamicList" dynamicList
+        cgOutput "staticSet" staticSet
+        cgOutput "selectedADT" selectedADT
+        cgReturn selectedADT
+
+  stdoutText <- compileProgramAndRunGenerated dir "managedAggregateTables" program
+  sourceText <- readFile (dir </> "managedAggregateTables.c")
+  mapM_ (\fragment -> assertBool ("Expected managed aggregate-table output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ ") =CGNativeCollections([0x0005U, 0x0006U, 0x0007U, 0x0015U], {0x0016U, 0x0017U})"
+    , "staticText =one"
+    , "staticList =[0x0003U, 0x0004U]"
+    , "dynamicList =[0x0005U, 0x0006U, 0x0007U, 0x0009U]"
+    , "staticSet ={0x0003U, 0x0004U}"
+    , "selectedADT =CGNativeCollections([0x0005U, 0x0006U, 0x0007U, 0x0015U], {0x0016U, 0x0017U})"
+    ]
+  assertBool "Expected ready aggregates to use automatic tables and dynamic entries to remain guarded"
+             (    "const SString table" `isInfixOf` sourceText
+              && "const SBVList_u16 table" `isInfixOf` sourceText
+              && "const SBVSet_u16 table" `isInfixOf` sourceText
+              && "switch((uint64_t)" `isInfixOf` sourceText
+              && not ("static const SString table" `isInfixOf` sourceText)
+              && not ("static const SBVList_u16 table" `isInfixOf` sourceText)
+              && not ("static const SBVSet_u16 table" `isInfixOf` sourceText)
+              && not ("static const SBVADT_CodeGenNativeCollections table" `isInfixOf` sourceText)
+             )
+
+-- | Exercise finite tables whose cells and default are retained arrays, both
+-- when entries are already demanded by earlier outputs and when the lookup
+-- must initialize only the selected entry.
+arrayValuedTables :: Bool -> Assertion
+arrayValuedTables readyEntries = withSystemTempDirectory "sbv-array-valued-tables" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgPerformRTCs True
+        cgSetDriverValues [1, 3]
+        selector <- cgInput "selector" :: SBVCodeGen SWord8
+        key      <- cgInput "key"      :: SBVCodeGen SWord8
+        let first     = writeArray (constArray 10) key 11 :: SArray Word8 Word32
+            second    = writeArray (constArray 20) key 21 :: SArray Word8 Word32
+            fallback  = constArray 30                  :: SArray Word8 Word32
+            selected  = select [first, second] fallback selector
+            defaulted = select [first, second] fallback (selector + 2)
+        when readyEntries $ do cgOutput "first" first
+                               cgOutput "second" second
+        cgOutput "selected" selected
+        cgOutput "defaultValue" (readArray defaulted key)
+        cgReturn (readArray selected key)
+
+  stdoutText <- compileProgramAndRunGenerated dir "arrayValuedTables" program
+  sourceText <- readFile (dir </> "arrayValuedTables.c")
+  assertBool ("Expected the selected array value, received:\n" ++ stdoutText) ("0x00000015UL" `isInfixOf` stdoutText)
+  assertBool ("Expected the out-of-range default array value, received:\n" ++ stdoutText) ("defaultValue = 0x0000001eUL" `isInfixOf` stdoutText)
+  if readyEntries
+     then assertBool ("Expected retained array-valued table storage, received:\n" ++ sourceText)
+                     (    "SBVArrayOutput_2_u8_3_u32 * const table" `isInfixOf` sourceText
+                      && "sbv_array_stored_export_2_u8_3_u32(&sbv_local_array_ctx" `isInfixOf` sourceText
+                      && "sbv_local_array_descriptor_" `isInfixOf` sourceText
+                     )
+     else assertBool "Expected guarded array initialization followed by an owned output export"
+                     (    "switch((uint64_t)" `isInfixOf` sourceText
+                      && "sbv_array_export_2_u8_3_u32(" `isInfixOf` sourceText
+                      && "sbv_local_array_s" `isInfixOf` sourceText
+                     )
+
+-- | Exercise managed finite-table results returned independently from
+-- multiple generated library translation units.
+managedAggregateTableLibrary :: Assertion
+managedAggregateTableLibrary = withSystemTempDirectory "sbv-managed-aggregate-table-library" $ \dir -> do
+  let component :: Integer -> Word16 -> SBVCodeGen ()
+      component driverSeed base = do
+        cgOverwriteFiles True
+        cgSetDriverValues [driverSeed]
+        selector <- cgInput "selector" :: SBVCodeGen SWord8
+        cgReturn (select [ literal ([base, base + 1] :: [Word16])
+                         , literal ([base + 2, base + 3] :: [Word16])
+                         ] (literal ([] :: [Word16])) selector)
+
+  (_, cfg, bundle) <- compileToCLib' "managedAggregateTableLibrary"
+    [ ("firstManagedTable",  component 0 10)
+    , ("secondManagedTable", component 1 20)
+    ]
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  stdoutText <- compileAndRunGenerated dir "managedAggregateTableLibrary"
+  mapM_ (\fragment -> assertBool ("Expected managed aggregate-table library output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ "[0x000aU, 0x000bU]"
+    , "[0x0016U, 0x0017U]"
+    ]
+
+-- | Exercise nested tuple inputs, construction, projection, conditionals,
+-- tuple constants in finite tables, public outputs, and returns.
+structuralTuples :: Assertion
+structuralTuples = withSystemTempDirectory "sbv-structural-tuples" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [3, 0]
+        source   <- cgInput "source"   :: SBVCodeGen (SBV (Word8, (Word16, Word32)))
+        selector <- cgInput "selector" :: SBVCodeGen SWord8
+        let (first, nested)   = untuple source
+            (second, third)  = untuple nested
+            rebuilt          = tuple (first + 1, tuple (second + 2, third + 3))
+            alternate        = tuple (9, tuple (10, 11))
+            selected         = select [rebuilt, alternate] alternate selector
+            conditional      = ite (selector .== 0) rebuilt alternate
+        cgOutput "selected" selected
+        cgOutput "rounding" (tuple (sRTN, first))
+        cgOutput "unit" (literal () :: SBV ())
+        cgReturn conditional
+
+  stdoutText <- compileProgramAndRunGenerated dir "structuralTuples" program
+  mapM_ (\fragment -> assertBool ("Expected tuple output to contain " ++ fragment ++ ", received:\n" ++ stdoutText) (fragment `isInfixOf` stdoutText))
+    [ "(4, (0x0006U, 0x00000008UL))"
+    , "selected =(4, (0x0006U, 0x00000008UL))"
+    , "rounding =(3, 3)"
+    , "unit =()"
+    ]
+
+-- | Exercise guarded tuple declarations shared by multiple generated library
+-- translation units and returned through the public by-value ABI.
+structuralTupleLibrary :: Assertion
+structuralTupleLibrary = withSystemTempDirectory "sbv-structural-tuple-library" $ \dir -> do
+  let component :: Integer -> SBVCodeGen ()
+      component increment = do
+        cgOverwriteFiles True
+        cgSetDriverValues [4]
+        source <- cgInput "source" :: SBVCodeGen (SBV (Word8, Word16))
+        let (first, second) = untuple source
+        cgReturn (tuple (first + fromInteger increment, second + fromInteger increment))
+
+  (_, cfg, bundle) <- compileToCLib' "structuralTupleLibrary"
+    [ ("incrementTuple", component 1)
+    , ("addTwoTuple",    component 2)
+    ]
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  stdoutText <- compileAndRunGenerated dir "structuralTupleLibrary"
+  mapM_ (\fragment -> assertBool ("Expected tuple library output to contain " ++ fragment ++ ", received:\n" ++ stdoutText) (fragment `isInfixOf` stdoutText))
+    [ "(5, 0x0006U)"
+    , "(6, 0x0007U)"
+    ]
+
+-- | Exercise borrowed nested tuple strings and independently owned tuple
+-- outputs and returns.
+ownedTextTuples :: Assertion
+ownedTextTuples = withSystemTempDirectory "sbv-owned-text-tuples" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [4]
+        source <- cgInput "source" :: SBVCodeGen (SBV (String, (String, Word8)))
+        let (first, nested)  = untuple source
+            (second, count) = untuple nested
+            result          = tuple (first SL.++ literal ":" SL.++ second, tuple (second SL.++ literal "!", count + 1))
+        cgOutput "sourceCopy" source
+        cgOutput "result" result
+        cgReturn result
+
+  stdoutText <- compileProgramAndRunGenerated dir "ownedTextTuples" program
+  headerText <- readFile (dir </> "ownedTextTuples.h")
+  mapM_ (\fragment -> assertBool ("Expected owned text-tuple output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ ") =(sbv4:sbv5, (sbv5!, 7))"
+    , "sourceCopy =(sbv4, (sbv5, 6))"
+    , "result =(sbv4:sbv5, (sbv5!, 7))"
+    ]
+  assertBool "Expected recursive string ownership in generated tuple helpers"
+             ("sbv_string_clone(source.field1)" `isInfixOf` headerText
+           && "sbv_string_release(&value->field1)" `isInfixOf` headerText)
+
+-- | Exercise guarded string-tuple ownership helpers shared by multiple
+-- generated library translation units.
+ownedTextTupleLibrary :: Assertion
+ownedTextTupleLibrary = withSystemTempDirectory "sbv-owned-text-tuple-library" $ \dir -> do
+  let component suffix resultValue seed = do
+        cgOverwriteFiles True
+        cgSetDriverValues [seed]
+        source <- cgInput "source" :: SBVCodeGen SString
+        cgReturn (tuple (source SL.++ suffix, literal resultValue :: SWord8))
+
+  (_, cfg, bundle) <- compileToCLib' "ownedTextTupleLibrary"
+    [ ("firstTextTuple",  component (literal "!") 9 4)
+    , ("secondTextTuple", component (literal "?") 8 5)
+    ]
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  stdoutText <- compileAndRunGenerated dir "ownedTextTupleLibrary"
+  mapM_ (\fragment -> assertBool ("Expected text-tuple library output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ "(sbv4!, 9)"
+    , "(sbv5?, 8)"
+    ]
+
+-- | Exercise recursively nested tuple ownership across strings, exact-element
+-- lists, and exact-element finite sets.
+ownedCollectionTuples :: Assertion
+ownedCollectionTuples = withSystemTempDirectory "sbv-owned-collection-tuples" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [10]
+        source <- cgInput "source" :: SBVCodeGen (SBV (String, ([Integer], RCSet Rational)))
+        let (prefix, nested)  = untuple source
+            (values, members) = untuple nested
+            result            = tuple (prefix SL.++ literal "!", tuple (values SL.++ literal ([14] :: [Integer]), SS.insert 15 members))
+        cgOutput "sourceCopy" source
+        cgOutput "result" result
+        cgReturn result
+
+  stdoutText <- compileProgramAndRunGenerated dir "ownedCollectionTuples" program
+  headerText <- readFile (dir </> "ownedCollectionTuples.h")
+  mapM_ (\fragment -> assertBool ("Expected owned collection-tuple output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ ") =(sbv10!, ([11, 12, 13, 14], {12, 13, 14, 15}))"
+    , "sourceCopy =(sbv10, ([11, 12, 13], {12, 13, 14}))"
+    , "result =(sbv10!, ([11, 12, 13, 14], {12, 13, 14, 15}))"
+    ]
+  assertBool "Expected recursive collection ownership in generated tuple helpers"
+             ("sbv_list_clone_integer(source.field1)" `isInfixOf` headerText
+           && "sbv_list_release_integer(&value->field1)" `isInfixOf` headerText
+           && "sbv_set_clone_rational(source.field2)" `isInfixOf` headerText
+           && "sbv_set_release_rational(&value->field2)" `isInfixOf` headerText)
+
+-- | Exercise guarded collection-tuple declarations and exact-element
+-- ownership helpers shared by multiple generated library translation units.
+ownedCollectionTupleLibrary :: Assertion
+ownedCollectionTupleLibrary = withSystemTempDirectory "sbv-owned-collection-tuple-library" $ \dir -> do
+  let component :: Integer -> Integer -> SBVCodeGen ()
+      component seed extra = do
+        cgOverwriteFiles True
+        cgSetDriverValues [seed]
+        source <- cgInput "source" :: SBVCodeGen (SBV ([Integer], RCSet Rational))
+        let (values, members) = untuple source
+        cgReturn (tuple (values SL.++ literal [extra], SS.insert (fromInteger extra) members))
+
+  (_, cfg, bundle) <- compileToCLib' "ownedCollectionTupleLibrary"
+    [ ("firstCollectionTuple",  component 3 9)
+    , ("secondCollectionTuple", component 5 10)
+    ]
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  stdoutText <- compileAndRunGenerated dir "ownedCollectionTupleLibrary"
+  mapM_ (\fragment -> assertBool ("Expected collection-tuple library output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ "([3, 4, 5, 9], {4, 5, 6, 9})"
+    , "([5, 6, 7, 10], {6, 7, 8, 10})"
+    ]
+
+-- | Exercise sequence and finite-set operations over recursively nested,
+-- by-value tuple elements and return both descriptors through an owned tuple.
+tupleValuedCollections :: Assertion
+tupleValuedCollections = withSystemTempDirectory "sbv-tuple-valued-collections" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [1, 4]
+        values  <- cgInput "values"  :: SBVCodeGen (SList (Word16, Word8))
+        members <- cgInput "members" :: SBVCodeGen (SSet (Word16, Word8))
+        let extra    = tuple (literal 9 :: SWord16, literal 10 :: SWord8)
+            joined   = values SL.++ SL.singleton extra
+            inserted = SS.insert extra members
+        cgOutput "listSameObject" (values .=== values)
+        cgOutput "containsExtra" (extra `SS.member` inserted)
+        cgOutput "joined" joined
+        cgOutput "inserted" inserted
+        cgReturn (tuple (joined, inserted))
+
+  stdoutText <- compileProgramAndRunGenerated dir "tupleValuedCollections" program
+  headerText <- readFile (dir </> "tupleValuedCollections.h")
+  mapM_ (\fragment -> assertBool ("Expected tuple-valued collection output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ "listSameObject = 1"
+    , "containsExtra = 1"
+    , "joined =[(0x0001U, 2), (0x0002U, 3), (0x0003U, 4), (0x0009U, 10)]"
+    , "inserted ={(0x0004U, 5), (0x0005U, 6), (0x0006U, 7), (0x0009U, 10)}"
+    ]
+  assertBool "Expected tuple forward declarations before collection descriptors"
+             ("typedef struct SBVTuple_" `isInfixOf` headerText
+           && "const SBVTuple_" `isInfixOf` headerText)
+
+-- | Exercise guarded tuple-element list and set descriptors shared by
+-- multiple generated library translation units.
+tupleValuedCollectionLibrary :: Assertion
+tupleValuedCollectionLibrary = withSystemTempDirectory "sbv-tuple-valued-collection-library" $ \dir -> do
+  let component :: Integer -> Word16 -> Word8 -> SBVCodeGen ()
+      component seed first second = do
+        cgOverwriteFiles True
+        cgSetDriverValues [seed, seed + 3]
+        values  <- cgInput "values"  :: SBVCodeGen (SList (Word16, Word8))
+        members <- cgInput "members" :: SBVCodeGen (SSet (Word16, Word8))
+        let extra = tuple (literal first, literal second)
+        cgReturn (tuple (values SL.++ SL.singleton extra, SS.insert extra members))
+
+  (_, cfg, bundle) <- compileToCLib' "tupleValuedCollectionLibrary"
+    [ ("firstTupleCollections",  component 1 9 10)
+    , ("secondTupleCollections", component 2 10 11)
+    ]
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  stdoutText <- compileAndRunGenerated dir "tupleValuedCollectionLibrary"
+  mapM_ (\fragment -> assertBool ("Expected tuple-valued collection library output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ "[(0x0001U, 2), (0x0002U, 3), (0x0003U, 4), (0x0009U, 10)]"
+    , "[(0x0002U, 3), (0x0003U, 4), (0x0004U, 5), (0x000aU, 11)]"
+    ]
+
+-- | Exercise deep ownership and structural equality for collection elements
+-- that are tuples containing strings, exact values, and nested collections.
+managedTupleValuedCollections :: Assertion
+managedTupleValuedCollections = withSystemTempDirectory "sbv-managed-tuple-valued-collections" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [1, 4, 7]
+        values  <- cgInput "values"  :: SBVCodeGen (SList (String, Integer))
+        members <- cgInput "members" :: SBVCodeGen (SSet (String, Integer))
+        nested  <- cgInput "nested"  :: SBVCodeGen (SList ([Integer], RCSet Rational))
+        let extra       = tuple (literal "extra" :: SString, literal 9 :: SInteger)
+            nestedExtra = tuple (literal ([9, 10] :: [Integer]), SS.singleton (literal 11 :: SRational))
+            joined      = values SL.++ SL.singleton extra
+            inserted    = SS.insert extra members
+            nestedJoin  = nested SL.++ SL.singleton nestedExtra
+        cgOutput "listSameObject" (values .=== values)
+        cgOutput "nestedSameObject" (nested .=== nested)
+        cgOutput "containsExtra" (extra `SS.member` inserted)
+        cgOutput "joined" joined
+        cgOutput "inserted" inserted
+        cgOutput "nestedJoin" nestedJoin
+        cgReturn (tuple (joined, tuple (inserted, nestedJoin)))
+
+  stdoutText <- compileProgramAndRunGenerated dir "managedTupleValuedCollections" program
+  headerText <- readFile (dir </> "managedTupleValuedCollections.h")
+  mapM_ (\fragment -> assertBool ("Expected managed tuple-valued collection output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ "listSameObject = 1"
+    , "nestedSameObject = 1"
+    , "containsExtra = 1"
+    , "joined =[(sbv1, 2), (sbv2, 3), (sbv3, 4), (extra, 9)]"
+    , "inserted ={(sbv4, 5), (sbv5, 6), (sbv6, 7), (extra, 9)}"
+    , "([9, 10], {11})"
+    ]
+  assertBool "Expected collection ownership to recurse through managed tuple elements"
+             ("sbv_tuple_owned_clone_" `isInfixOf` headerText
+           && "sbv_tuple_owned_release_" `isInfixOf` headerText
+           && "sbv_string_clone(source.field1)" `isInfixOf` headerText
+           && "sbv_list_clone_integer(source.field1)" `isInfixOf` headerText
+           && "sbv_set_clone_rational(source.field2)" `isInfixOf` headerText)
+
+-- | Exercise guarded ownership helpers for managed tuple-valued collections
+-- shared by multiple generated library translation units.
+managedTupleValuedCollectionLibrary :: Assertion
+managedTupleValuedCollectionLibrary = withSystemTempDirectory "sbv-managed-tuple-valued-collection-library" $ \dir -> do
+  let component :: Integer -> String -> Integer -> SBVCodeGen ()
+      component seed textValue extraValue = do
+        cgOverwriteFiles True
+        cgSetDriverValues [seed, seed + 3]
+        values  <- cgInput "values"  :: SBVCodeGen (SList (String, Integer))
+        members <- cgInput "members" :: SBVCodeGen (SSet (String, Integer))
+        let extra = tuple (literal textValue :: SString, literal extraValue :: SInteger)
+        cgReturn (tuple (values SL.++ SL.singleton extra, SS.insert extra members))
+
+  (_, cfg, bundle) <- compileToCLib' "managedTupleValuedCollectionLibrary"
+    [ ("firstManagedTupleCollections",  component 1 "first" 9)
+    , ("secondManagedTupleCollections", component 2 "second" 10)
+    ]
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  stdoutText <- compileAndRunGenerated dir "managedTupleValuedCollectionLibrary"
+  mapM_ (\fragment -> assertBool ("Expected managed tuple-valued collection library output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ "[(sbv1, 2), (sbv2, 3), (sbv3, 4), (first, 9)]"
+    , "[(sbv2, 3), (sbv3, 4), (sbv4, 5), (second, 10)]"
+    ]
+
+-- | Exercise string-valued symbolic collections and ADTs with direct string,
+-- list-of-string, and set-of-string fields through operations and owned ABI
+-- results.
+textAggregateCollections :: Assertion
+textAggregateCollections = withSystemTempDirectory "sbv-text-aggregate-collections" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [1, 4, 6]
+        values  <- cgInput "values"  :: SBVCodeGen (SList String)
+        members <- cgInput "members" :: SBVCodeGen (SSet String)
+        source  <- cgInput "source"  :: SBVCodeGen SCodeGenText
+        let extra         = literal "extra" :: SString
+            sourceName    = getCGText_1 source
+            sourceValues  = getCGText_2 source
+            sourceMembers = getCGText_3 source
+            joined        = values SL.++ SL.singleton extra
+            inserted      = SS.insert extra members
+            result        = sCGText
+                              (sourceName SL.++ literal "!")
+                              (sourceValues SL.++ SL.singleton extra)
+                              (SS.insert extra sourceMembers)
+        cgOutput "sameValues" (values .=== values)
+        cgOutput "sameMembers" (members .=== members)
+        cgOutput "sameSource" (source .== source)
+        cgOutput "containsExtra" (extra `SS.member` inserted)
+        cgOutput "joined" joined
+        cgOutput "inserted" inserted
+        cgOutput "result" result
+        cgReturn result
+
+  stdoutText <- compileProgramAndRunGenerated dir "textAggregateCollections" program
+  headerText <- readFile (dir </> "textAggregateCollections.h")
+  mapM_ (\fragment -> assertBool ("Expected text-aggregate output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ "sameValues = 1"
+    , "sameMembers = 1"
+    , "sameSource = 1"
+    , "containsExtra = 1"
+    , "joined =[sbv1, sbv2, sbv3, extra]"
+    , "inserted ={sbv4, sbv5, sbv6, extra}"
+    , "CGText(sbv6!, [sbv7, sbv8, sbv9, extra], {sbv8, sbv9, sbv10, extra})"
+    ]
+  assertBool "Expected ownership to recurse through direct and collection text fields"
+             (    "struct SBVList_string { const SString *data; size_t length; };" `isInfixOf` headerText
+              && "struct SBVSet_string { const SString *data; size_t length; bool is_complement; };" `isInfixOf` headerText
+              && "sbv_string_clone(source.payload.constructor1.field1)" `isInfixOf` headerText
+              && "sbv_string_release(&value->payload.constructor1.field1)" `isInfixOf` headerText
+              && "sbv_list_clone_string(source.payload.constructor1.field2)" `isInfixOf` headerText
+              && "sbv_set_clone_string(source.payload.constructor1.field3)" `isInfixOf` headerText
+             )
+
+-- | Exercise independently owned text-containing ADT results emitted by
+-- multiple generated library translation units.
+textAggregateLibrary :: Assertion
+textAggregateLibrary = withSystemTempDirectory "sbv-text-aggregate-library" $ \dir -> do
+  let component :: Integer -> SBVCodeGen ()
+      component seed = do
+        cgOverwriteFiles True
+        cgSetDriverValues [seed]
+        source <- cgInput "source" :: SBVCodeGen SCodeGenText
+        cgReturn source
+
+  (_, cfg, bundle) <- compileToCLib' "textAggregateLibrary"
+    [ ("firstTextAggregate",  component 2)
+    , ("secondTextAggregate", component 4)
+    ]
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  stdoutText <- compileAndRunGenerated dir "textAggregateLibrary"
+  mapM_ (\fragment -> assertBool ("Expected text-aggregate library output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ "CGText(sbv2, [sbv3, sbv4, sbv5], {sbv4, sbv5, sbv6})"
+    , "CGText(sbv4, [sbv5, sbv6, sbv7], {sbv6, sbv7, sbv8})"
+    ]
+
+-- | Exercise every direct list/set nesting pair admitted by SBV through
+-- symbolic operations, printing, and recursively owned tuple outputs and
+-- returns. Sets of sets are not SBV values because 'RCSet' has no 'Ord'
+-- instance.
+directlyNestedCollections :: Assertion
+directlyNestedCollections = withSystemTempDirectory "sbv-directly-nested-collections" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [1, 2, 4]
+        nestedLists <- cgInput "nestedLists" :: SBVCodeGen (SList [Word16])
+        listOfSets  <- cgInput "listOfSets"  :: SBVCodeGen (SList (RCSet Word16))
+        setOfLists  <- cgInput "setOfLists"  :: SBVCodeGen (SSet [Word16])
+        let extraList     = literal ([90, 91] :: [Word16])
+            extraSet      = SS.fromList [92, 93] :: SSet Word16
+            joinedLists   = nestedLists SL.++ SL.singleton extraList
+            joinedSets    = listOfSets SL.++ SL.singleton extraSet
+            insertedLists = SS.insert extraList setOfLists
+            result        = tuple (joinedLists, tuple (joinedSets, insertedLists))
+        cgOutput "sameNestedLists" (nestedLists .=== nestedLists)
+        cgOutput "sameListOfSets" (listOfSets .=== listOfSets)
+        cgOutput "sameSetOfLists" (setOfLists .=== setOfLists)
+        cgOutput "joinedLists" joinedLists
+        cgOutput "joinedSets" joinedSets
+        cgOutput "insertedLists" insertedLists
+        cgReturn result
+
+  stdoutText <- compileProgramAndRunGenerated dir "directlyNestedCollections" program
+  headerText <- readFile (dir </> "directlyNestedCollections.h")
+  mapM_ (\fragment -> assertBool ("Expected directly nested collection output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ "sameNestedLists = 1"
+    , "sameListOfSets = 1"
+    , "sameSetOfLists = 1"
+    , "[0x005aU, 0x005bU]"
+    , "{0x005cU, 0x005dU}"
+    ]
+  assertBool "Expected mutually forward-declared descriptors and recursive ownership helpers"
+             (    "typedef struct SBVList_u16 SBVList_u16;" `isInfixOf` headerText
+              && "typedef struct SBVSet_u16 SBVSet_u16;" `isInfixOf` headerText
+              && "struct SBVList_set_3_u16 { const SBVSet_u16 *data; size_t length; };" `isInfixOf` headerText
+              && "struct SBVSet_list_3_u16 { const SBVList_u16 *data; size_t length; bool is_complement; };" `isInfixOf` headerText
+              && "sbv_list_clone_list_3_u16" `isInfixOf` headerText
+              && "sbv_list_clone_set_3_u16" `isInfixOf` headerText
+              && "sbv_set_clone_list_3_u16" `isInfixOf` headerText
+             )
+
+-- | Exercise independently owned list-of-set results emitted by multiple
+-- generated library translation units.
+directlyNestedCollectionLibrary :: Assertion
+directlyNestedCollectionLibrary = withSystemTempDirectory "sbv-directly-nested-collection-library" $ \dir -> do
+  let component :: Integer -> Word16 -> SBVCodeGen ()
+      component seed extra = do
+        cgOverwriteFiles True
+        cgSetDriverValues [seed]
+        values <- cgInput "values" :: SBVCodeGen (SList (RCSet Word16))
+        cgReturn (values SL.++ SL.singleton (SS.fromList [extra, extra + 1]))
+
+  (_, cfg, bundle) <- compileToCLib' "directlyNestedCollectionLibrary"
+    [ ("firstNestedCollection",  component 2 90)
+    , ("secondNestedCollection", component 4 92)
+    ]
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  stdoutText <- compileAndRunGenerated dir "directlyNestedCollectionLibrary"
+  mapM_ (\fragment -> assertBool ("Expected nested-collection library output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ "{0x005aU, 0x005bU}"
+    , "{0x005cU, 0x005dU}"
+    ]
+
+-- | Exercise lists and sets whose elements are managed or recursive ADTs,
+-- including deep ownership and both symbolic equality modes.
+adtValuedCollections :: Assertion
+adtValuedCollections = withSystemTempDirectory "sbv-adt-valued-collections" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [1, 2, 4]
+        values <- cgInput "values" :: SBVCodeGen (SList CodeGenCollections)
+        trees  <- cgInput "trees"  :: SBVCodeGen (SSet CodeGenTree)
+        colors <- cgInput "colors" :: SBVCodeGen (SSet CodeGenEnum)
+        let extraValue = sCGCollections
+                           (literal ([9, 10] :: [Integer]))
+                           (SS.singleton (literal 11 :: SRational))
+                           (tuple (literal ([12] :: [Integer]), SS.singleton (literal 13 :: SRational)))
+            extraTree  = sCGLeaf 99
+            joined     = values SL.++ SL.singleton extraValue
+            inserted   = SS.insert extraTree trees
+            colored    = SS.insert sCGBlue colors
+            allColors  = SS.fromList [CGRed, CGGreen, CGBlue]
+        cgOutput "sameValues" (values .=== values)
+        cgOutput "containsExtraTree" (extraTree `SS.member` inserted)
+        cgOutput "containsBlue" (sCGBlue `SS.member` colored)
+        cgOutput "sameColorUniverse" (allColors .== (SS.full :: SSet CodeGenEnum))
+        cgOutput "joined" joined
+        cgOutput "inserted" inserted
+        cgOutput "colored" colored
+        cgReturn (tuple (joined, inserted))
+
+  stdoutText <- compileProgramAndRunGenerated dir "adtValuedCollections" program
+  headerText <- readFile (dir </> "adtValuedCollections.h")
+  sourceText <- readFile (dir </> "adtValuedCollections.c")
+  mapM_ (\fragment -> assertBool ("Expected ADT-valued collection output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ "sameValues = 1"
+    , "containsExtraTree = 1"
+    , "containsBlue = 1"
+    , "sameColorUniverse = 1"
+    , "CGCollections([9, 10], {11}, ([12], {13}))"
+    , "CGLeaf(99)"
+    , "CGBlue"
+    ]
+  assertBool "Expected ADT forward declarations before collection descriptors"
+             ("typedef struct SBVADT_CodeGenCollections SBVADT_CodeGenCollections;" `isInfixOf` headerText
+           && "const SBVADT_CodeGenCollections *data" `isInfixOf` headerText)
+  assertBool "Expected collection ownership and equality to dispatch through ADT helpers"
+             ("sbv_adt_owned_clone_SBVADT_CodeGenCollections" `isInfixOf` headerText
+           && "sbv_adt_owned_release_SBVADT_CodeGenTree" `isInfixOf` headerText
+           && "sbv_adt_object_equal_SBVADT_CodeGenCollections" `isInfixOf` sourceText
+           && "sbv_adt_equal_SBVADT_CodeGenTree" `isInfixOf` sourceText)
+
+-- | Exercise guarded recursive-ADT collection helpers shared by multiple
+-- generated library translation units.
+adtValuedCollectionLibrary :: Assertion
+adtValuedCollectionLibrary = withSystemTempDirectory "sbv-adt-valued-collection-library" $ \dir -> do
+  let component :: Integer -> Word8 -> SBVCodeGen ()
+      component seed extraValue = do
+        cgOverwriteFiles True
+        cgSetDriverValues [seed]
+        values <- cgInput "values" :: SBVCodeGen (SList CodeGenTree)
+        cgReturn (values SL.++ SL.singleton (sCGLeaf (literal extraValue)))
+
+  (_, cfg, bundle) <- compileToCLib' "adtValuedCollectionLibrary"
+    [ ("firstADTCollections",  component 1 98)
+    , ("secondADTCollections", component 2 99)
+    ]
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  stdoutText <- compileAndRunGenerated dir "adtValuedCollectionLibrary"
+  mapM_ (\fragment -> assertBool ("Expected ADT-valued collection library output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ "CGLeaf(98)"
+    , "CGLeaf(99)"
+    ]
+
+-- | Exercise parameter substitution, constructors, tests, accessors,
+-- structural equality, constants, tables, public outputs, and returns.
+nonRecursiveADTs :: Assertion
+nonRecursiveADTs = withSystemTempDirectory "sbv-non-recursive-adts" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [2, 1, 0, 1]
+        source   <- cgInput "source"   :: SBVCodeGen (SCodeGenADT Word8)
+        choose   <- cgInput "choose"   :: SBVCodeGen SBool
+        selector <- cgInput "selector" :: SBVCodeGen SWord8
+        color    <- cgInput "color"    :: SBVCodeGen SCodeGenEnum
+        let first       = getCGPair_1 source
+            second      = getCGPair_2 source
+            constructed = ite choose (sCGPair (first + 1) (second + 1)) (sCGOne first)
+            constant    = literal (CGPair 9 10)
+            selected    = select [source, constructed, constant] sCGEmpty selector
+        cgOutput "sourceCopy" source
+        cgOutput "constructed" constructed
+        cgOutput "constant" constant
+        cgOutput "isPair" (isCGPair source)
+        cgOutput "sameValue" (source .== literal (CGPair 2 3))
+        cgOutput "colorBeforeBlue" (color .< sCGBlue)
+        cgReturn selected
+
+  stdoutText <- compileProgramAndRunGenerated dir "nonRecursiveADTs" program
+  mapM_ (\fragment -> assertBool ("Expected ADT output to contain " ++ fragment ++ ", received:\n" ++ stdoutText) (fragment `isInfixOf` stdoutText))
+    [ "CGPair(2, 0x0003U)"
+    , "constructed =CGPair(3, 0x0004U)"
+    , "constant =CGPair(9, 0x000aU)"
+    , "isPair = 1"
+    , "sameValue = 1"
+    , "colorBeforeBlue = 1"
+    ]
+
+-- | Exercise an acyclic parameterized 'KApp' reference through construction,
+-- access, structural equality against a literal, and the public return ABI.
+nestedADTs :: Assertion
+nestedADTs = withSystemTempDirectory "sbv-nested-adts" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [1]
+        source <- cgInput "source" :: SBVCodeGen (SCodeGenEnvelope Word8)
+        let inner  = getCGEnvelope_1 source
+            result = sCGEnvelope (sCGOne (getCGOne_1 inner + 3))
+        cgOutput "sameValue" (source .== literal (CGEnvelope (CGOne 1)))
+        cgReturn result
+
+  stdoutText <- compileProgramAndRunGenerated dir "nestedADTs" program
+  headerText <- readFile (dir </> "nestedADTs.h")
+  mapM_ (\fragment -> assertBool ("Expected nested ADT output to contain " ++ fragment
+                               ++ ", received:\n" ++ stdoutText)
+                               (fragment `isInfixOf` stdoutText))
+    [ "CGEnvelope(CGOne(4))"
+    , "sameValue = 1"
+    ]
+  assertBool "Expected the concrete Word8 inner ADT declaration"
+             ("SBVADT_CodeGenADT_2_u8" `isInfixOf` headerText)
+  assertBool "Unexpected placeholder Integer ADT declaration"
+             (not ("SBVADT_CodeGenADT_7_integer" `isInfixOf` headerText))
+
+-- | Exercise guarded ADT declarations shared by multiple generated library
+-- translation units and returned through the public by-value ABI.
+nonRecursiveADTLibrary :: Assertion
+nonRecursiveADTLibrary = withSystemTempDirectory "sbv-non-recursive-adt-library" $ \dir -> do
+  let component :: Word8 -> SBVCodeGen ()
+      component increment = do
+        cgOverwriteFiles True
+        cgSetDriverValues [1]
+        source <- cgInput "source" :: SBVCodeGen (SCodeGenADT Word8)
+        cgReturn (ite (isCGOne source) (sCGOne (getCGOne_1 source + literal increment)) sCGEmpty)
+
+  (_, cfg, bundle) <- compileToCLib' "nonRecursiveADTLibrary"
+    [ ("incrementADT", component 1)
+    , ("addTwoADT",    component 2)
+    ]
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  stdoutText <- compileAndRunGenerated dir "nonRecursiveADTLibrary"
+  mapM_ (\fragment -> assertBool ("Expected ADT library output to contain " ++ fragment ++ ", received:\n" ++ stdoutText) (fragment `isInfixOf` stdoutText))
+    [ "CGOne(2)"
+    , "CGOne(3)"
+    ]
+
+-- | Exercise direct and tuple-nested exact-element collections through ADT
+-- construction, access, equality, outputs, and an independently owned return.
+collectionADTs :: Assertion
+collectionADTs = withSystemTempDirectory "sbv-collection-adts" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [1]
+        source <- cgInput "source" :: SBVCodeGen SCodeGenCollections
+        let values                   = getCGCollections_1 source
+            members                  = getCGCollections_2 source
+            nested                   = getCGCollections_3 source
+            (nestedValues, nestedSet) = untuple nested
+            result                   = sCGCollections
+                                         (values SL.++ literal ([4] :: [Integer]))
+                                         (SS.insert 5 members)
+                                         (tuple (nestedValues SL.++ literal ([6] :: [Integer]), SS.insert 7 nestedSet))
+        cgOutput "sourceCopy" source
+        cgOutput "sameValue" (source .== source)
+        cgOutput "result" result
+        cgReturn result
+
+  stdoutText <- compileProgramAndRunGenerated dir "collectionADTs" program
+  headerText <- readFile (dir </> "collectionADTs.h")
+  mapM_ (\fragment -> assertBool ("Expected collection ADT output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ ") =CGCollections([1, 2, 3, 4], {2, 3, 4, 5}, ([3, 4, 5, 6], {4, 5, 6, 7}))"
+    , "sourceCopy =CGCollections([1, 2, 3], {2, 3, 4}, ([3, 4, 5], {4, 5, 6}))"
+    , "sameValue = 1"
+    , "result =CGCollections([1, 2, 3, 4], {2, 3, 4, 5}, ([3, 4, 5, 6], {4, 5, 6, 7}))"
+    ]
+  assertBool "Expected direct and tuple-nested collection ownership in ADT helpers"
+             ("sbv_list_clone_integer(source.payload.constructor2.field1)" `isInfixOf` headerText
+           && "sbv_set_release_rational(&value->payload.constructor2.field2)" `isInfixOf` headerText
+           && "sbv_tuple_owned_set_" `isInfixOf` headerText)
+
+-- | Exercise recursive pointer ownership whose terminal constructor contains
+-- exact-element list and set fields, including recursive structural equality.
+recursiveCollectionADTs :: Assertion
+recursiveCollectionADTs = withSystemTempDirectory "sbv-recursive-collection-adts" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [1]
+        source <- cgInput "source" :: SBVCodeGen SCodeGenCollectionTree
+        cgOutput "sameTree" (source .== source)
+        cgOutput "treeCopy" source
+        cgReturn source
+
+  stdoutText <- compileProgramAndRunGenerated dir "recursiveCollectionADTs" program
+  sourceText <- readFile (dir </> "recursiveCollectionADTs.c")
+  mapM_ (\fragment -> assertBool ("Expected recursive collection ADT output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ "CGCollectionBranch(CGCollectionBranch("
+    , "CGCollectionLeaf([1, 2, 3], {2, 3, 4})"
+    , "sameTree = 1"
+    ]
+  assertBool "Expected private recursive equality to use collection semantics after their runtimes"
+             ("sbv_list_integer_equal" `isInfixOf` sourceText
+           && "sbv_set_rational_equal" `isInfixOf` sourceText)
+
+-- | Exercise guarded collection-owning ADT helpers shared by multiple
+-- generated library translation units.
+collectionADTLibrary :: Assertion
+collectionADTLibrary = withSystemTempDirectory "sbv-collection-adt-library" $ \dir -> do
+  let component :: Integer -> SBVCodeGen ()
+      component seed = do
+        cgOverwriteFiles True
+        cgSetDriverValues [seed]
+        source <- cgInput "source" :: SBVCodeGen SCodeGenNativeCollections
+        cgReturn source
+
+  (_, cfg, bundle) <- compileToCLib' "collectionADTLibrary"
+    [ ("firstCollectionADT",  component 1)
+    , ("secondCollectionADT", component 3)
+    ]
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  stdoutText <- compileAndRunGenerated dir "collectionADTLibrary"
+  mapM_ (\fragment -> assertBool ("Expected collection ADT library output to contain " ++ show fragment ++ ", received:\n" ++ stdoutText)
+                                (fragment `isInfixOf` stdoutText))
+    [ "CGNativeCollections([0x0001U, 0x0002U, 0x0003U], {0x0002U, 0x0003U, 0x0004U})"
+    , "CGNativeCollections([0x0003U, 0x0004U, 0x0005U], {0x0004U, 0x0005U, 0x0006U})"
+    ]
+
+-- | Exercise structural equality for ADTs instantiated with wide bit-vectors,
+-- arbitrary floating-point formats, and native floating-point values.
+adtAggregateEquality :: Assertion
+adtAggregateEquality = withSystemTempDirectory "sbv-adt-aggregate-equality" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [1, 1, 1, 1, 9, 9]
+        wideLeft     <- cgInput "wideLeft"     :: SBVCodeGen (SCodeGenADT (WordN 673))
+        wideRight    <- cgInput "wideRight"    :: SBVCodeGen (SCodeGenADT (WordN 673))
+        floatLeft    <- cgInput "floatLeft"    :: SBVCodeGen (SCodeGenADT Float)
+        floatRight   <- cgInput "floatRight"   :: SBVCodeGen (SCodeGenADT Float)
+        integerLeft  <- cgInput "integerLeft"  :: SBVCodeGen SInteger
+        integerRight <- cgInput "integerRight" :: SBVCodeGen SInteger
+        cgOutput "wideEqual" (wideLeft .== wideRight)
+        cgOutput "exactEqual" (sCGOne integerLeft .== sCGOne integerRight)
+        cgReturn (floatLeft .=== floatRight)
+
+  stdoutText <- compileProgramAndRunGenerated dir "adtAggregateEquality" program
+  mapM_ (\fragment -> assertBool ("Expected aggregate equality output to contain " ++ fragment ++ ", received:\n" ++ stdoutText) (fragment `isInfixOf` stdoutText))
+    [ "= 1"
+    , "wideEqual = 1"
+    , "exactEqual = 1"
+    ]
+
+  (_, _, arbitraryFPBundle) <- compileToC' "adtArbitraryFPEquality" $ do
+    left  <- cgInput "left"  :: SBVCodeGen (SCodeGenADT (FloatingPoint 7 19))
+    right <- cgInput "right" :: SBVCodeGen (SCodeGenADT (FloatingPoint 7 19))
+    cgReturn (left .=== right)
+  let generated = show arbitraryFPBundle
+  assertBool "Expected a concrete arbitrary-float ADT declaration" ("SBVADT_CodeGenADT_9_fp_e7_s19" `isInfixOf` generated)
+  assertBool "Expected arbitrary-float object equality in the ADT comparison" ("sbv_fp_e7_s19_obj_eq" `isInfixOf` generated)
+
+-- | Exercise a recursive input layout, including a pointer-backed accessor and
+-- a bounded generated-driver value.
+recursiveADTs :: Assertion
+recursiveADTs = withSystemTempDirectory "sbv-recursive-adts" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [1]
+        value <- cgInput "value" :: SBVCodeGen SCodeGenTree
+        let left   = getCGNode_1 value
+            result = sCGNode left (sCGLeaf 99)
+        cgOutput "isNode" (isCGNode value)
+        cgOutput "sameTree" (value .== value)
+        cgOutput "sameTreeObject" (value .=== value)
+        cgOutput "treeCopy" value
+        cgReturn result
+
+  stdoutText <- compileProgramAndRunGenerated dir "recursiveADTs" program
+  headerText <- readFile (dir </> "recursiveADTs.h")
+  sourceText <- readFile (dir </> "recursiveADTs.c")
+  assertBool ("Expected the recursive driver to select a node, received:\n" ++ stdoutText)
+             ("isNode = 1" `isInfixOf` stdoutText)
+  assertBool ("Expected recursive structural equality, received:\n" ++ stdoutText)
+             ("sameTree = 1" `isInfixOf` stdoutText)
+  assertBool ("Expected recursive strong equality, received:\n" ++ stdoutText)
+             ("sameTreeObject = 1" `isInfixOf` stdoutText)
+  assertBool ("Expected a deeply owned recursive result, received:\n" ++ stdoutText)
+             ("CGLeaf(99)" `isInfixOf` stdoutText)
+  assertBool "Expected a forward-declared recursive ADT"
+             ("typedef struct SBVADT_CodeGenTree SBVADT_CodeGenTree;" `isInfixOf` headerText)
+  assertBool "Expected recursive fields to use pointers"
+             ("SBVADT_CodeGenTree * field1;" `isInfixOf` headerText)
+  assertBool "Expected recursive equality to reject null child pointers"
+             ("== NULL) abort();" `isInfixOf` sourceText)
+
+-- | Exercise transitive ownership when an acyclic ADT embeds a recursive ADT
+-- by value.
+wrappedRecursiveADTs :: Assertion
+wrappedRecursiveADTs = withSystemTempDirectory "sbv-wrapped-recursive-adts" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [1]
+        value <- cgInput "value" :: SBVCodeGen SCodeGenForest
+        cgOutput "sameForest" (value .== value)
+        cgReturn value
+
+  stdoutText <- compileProgramAndRunGenerated dir "wrappedRecursiveADTs" program
+  headerText <- readFile (dir </> "wrappedRecursiveADTs.h")
+  assertBool ("Expected the wrapped recursive value to survive an owned return, received:\n" ++ stdoutText)
+             ("CGForest(CGNode" `isInfixOf` stdoutText)
+  assertBool ("Expected wrapped recursive structural equality, received:\n" ++ stdoutText)
+             ("sameForest = 1" `isInfixOf` stdoutText)
+  assertBool "Expected an acyclic wrapper field to remain embedded by value"
+             ("SBVADT_CodeGenTree field1;" `isInfixOf` headerText)
+
+-- | Exercise mutually recursive layouts, bounded samples, equality, printing,
+-- accessors, and deep-owned outputs and returns.
+mutuallyRecursiveADTs :: Assertion
+mutuallyRecursiveADTs = withSystemTempDirectory "sbv-mutually-recursive-adts" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [1]
+        value <- cgInput "value" :: SBVCodeGen SCodeGenOdd
+        cgOutput "sameValue" (value .== value)
+        cgOutput "valueCopy" value
+        cgReturn (getCGOddStep_1 value)
+
+  stdoutText <- compileProgramAndRunGenerated dir "mutuallyRecursiveADTs" program
+  headerText <- readFile (dir </> "mutuallyRecursiveADTs.h")
+  assertBool ("Expected mutually recursive structural equality, received:\n" ++ stdoutText)
+             ("sameValue = 1" `isInfixOf` stdoutText)
+  assertBool ("Expected mutually recursive values to print, received:\n" ++ stdoutText)
+             ("CGOddStep(CGEven" `isInfixOf` stdoutText)
+  assertBool "Expected the odd-to-even edge to use a pointer"
+             ("SBVADT_CodeGenEven * field1;" `isInfixOf` headerText)
+  assertBool "Expected the even-to-odd edge to use a pointer"
+             ("SBVADT_CodeGenOdd * field1;" `isInfixOf` headerText)
+
+-- | Exercise guarded recursive declarations and ownership helpers shared by
+-- multiple generated library components.
+recursiveADTLibrary :: Assertion
+recursiveADTLibrary = withSystemTempDirectory "sbv-recursive-adt-library" $ \dir -> do
+  let component :: Integer -> SBVCodeGen ()
+      component seed = do
+        cgOverwriteFiles True
+        cgSetDriverValues [seed]
+        value <- cgInput "value" :: SBVCodeGen SCodeGenTree
+        cgReturn value
+
+  (_, cfg, bundle) <- compileToCLib' "recursiveADTLibrary"
+    [ ("copyRecursiveLeaf", component 0)
+    , ("copyRecursiveTree", component 1)
+    ]
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  stdoutText <- compileAndRunGenerated dir "recursiveADTLibrary"
+  assertBool ("Expected recursive library results, received:\n" ++ stdoutText)
+             ("CGLeaf" `isInfixOf` stdoutText && "CGNode" `isInfixOf` stdoutText)
+
+-- | Check that bounded driver generation rejects recursive ADTs without any
+-- finite constructor path.
+uninhabitedRecursiveADT :: Assertion
+uninhabitedRecursiveADT = do
+  recursiveResult <- try (do
+    (_, _, bundle) <- compileToC' "uninhabitedRecursiveADT" $ do
+      value <- cgInput "value" :: SBVCodeGen SCodeGenLoop
+      cgReturn (isCGLoop value)
+    evaluate (length (show bundle))) :: IO (Either ErrorCall Int)
+  case recursiveResult of
+    Left exception -> assertBool ("Expected a finite-constructor diagnostic, received:\n" ++ displayException exception)
+                                 ("has no finite constructor" `isInfixOf` displayException exception)
+    Right _        -> assertBool "Expected driver generation to reject an uninhabited recursive ADT" False
+
+-- | Generate, compile, and execute one standalone C program quietly in its
+-- temporary directory.
+compileProgramAndRunGenerated :: FilePath -> String -> SBVCodeGen () -> IO String
+compileProgramAndRunGenerated dir executableName program = do
+  (_, cfg, bundle) <- compileToC' executableName (program >> cgOverwriteFiles True)
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  compileAndRunGenerated dir executableName
+
+-- | Extract linker-option lists from the Makefile entries in a generated C
+-- bundle.
+linkerFlags :: CgPgmBundle -> [[String]]
+linkerFlags (CgPgmBundle _ files) = [flags | (_, (CgMakefile flags, _)) <- files]
diff --git a/SBVTestSuite/TestSuite/CodeGeneration/ExactNumbers.hs b/SBVTestSuite/TestSuite/CodeGeneration/ExactNumbers.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CodeGeneration/ExactNumbers.hs
@@ -0,0 +1,667 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : TestSuite.CodeGeneration.ExactNumbers
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Compile-and-run tests for GMP-backed exact integer and real C lowering.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE DataKinds         #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE TypeApplications  #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module TestSuite.CodeGeneration.ExactNumbers (tests) where
+
+import Data.List                 (isInfixOf)
+import Numeric                   (showHex)
+import System.Environment        (lookupEnv)
+import System.Exit               (ExitCode(..))
+import System.FilePath           ((</>))
+import System.IO.Temp            (withSystemTempDirectory)
+import System.Process            (readProcessWithExitCode)
+import Test.Tasty.HUnit          (assertBool, assertEqual)
+
+import Data.SBV.Internals
+import Data.SBV.Tuple (tuple, untuple)
+import qualified Data.SBV.List as SL
+
+import Utils.SBVTestFramework
+import Utils.CCodeGen (generatedMakeOptions)
+
+-- | An exact-number ADT nested inside 'ExactAggregate'.
+data ExactLeaf = ExactLeaf Integer AlgReal deriving Show
+
+-- | A sum type combining nested ADT and tuple ownership.
+data ExactAggregate = ExactAbsent
+                    | ExactAggregate ExactLeaf (Integer, AlgReal)
+                    deriving Show
+
+-- | A recursive exact-number ADT used to exercise combined heap and GMP
+-- ownership.
+data ExactChain = ExactEnd Integer | ExactNext Integer ExactChain deriving Show
+
+-- | Generate symbolic interfaces for the exact-number ADTs.
+mkSymbolic [''ExactLeaf, ''ExactAggregate, ''ExactChain]
+
+-- | GMP-backed exact-number C backend tests.
+tests :: TestTree
+tests = testGroup "CodeGeneration.ExactNumbers"
+  [ testCase "compile and execute unbounded arithmetic" exactIntegerArithmetic
+  , testCase "compile and execute Euclidean division" exactIntegerDivision
+  , testCase "preserve zero-divisor semantics across integer representations" integerZeroDivision
+  , testCase "count exact decimal text without its terminator" exactDecimalText
+  , testCase "compile and execute exact divisibility" exactIntegerDivisibility
+  , testCase "compile and execute exact integer exponentiation" exactIntegerExponentiation
+  , testCase "compile and execute native conversions" exactNativeConversions
+  , testCase "reduce exact integers into native bit patterns" exactNativeBitPatterns
+  , testCase "floor exact reals into mapped integers" exactRealMappedIntegers
+  , testCase "compile and execute wide conversions" exactWideConversions
+  , testCase "compile and execute wide real conversions" exactWideRealConversions
+  , testCase "compile and execute rational arithmetic" exactRealArithmetic
+  , testCase "compile and execute exact table lookup" exactTableLookup
+  , testCase "do not alias narrowed unchecked exact table indices" uncheckedExactTableIndices
+  , testCase "compile and execute exact array keys and values" exactArray
+  , testCase "compile and execute an exact callback-backed array" exactArrayInput
+  , testCase "compile and execute fixed exact input arrays" exactFixedInputArrays
+  , testCase "compile and execute an exact structured lambda array" exactLambdaArray
+  , testCase "compile and execute an exact structured lambda table" exactLambdaTable
+  , testCase "return and output owned exact arrays" ownedExactArrays
+  , testCase "use exact fields inside tuples" exactTupleFields
+  , testCase "use owned exact tuples across the public ABI" ownedExactTuples
+  , testCase "use owned exact ADTs across the public ABI" ownedExactADTs
+  , testCase "use owned recursive exact ADTs across the public ABI" ownedRecursiveExactADTs
+  , testCase "compile and execute an exact-number library" exactNumberLibrary
+  ]
+
+-- | Exercise arithmetic well beyond any native or wide fixed-width integer.
+exactIntegerArithmetic :: Assertion
+exactIntegerArithmetic = withSystemTempDirectory "sbv-exact-integer" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [x, y]
+        a <- cgInput "a" :: SBVCodeGen SInteger
+        b <- cgInput "b" :: SBVCodeGen SInteger
+        let added     = a + b
+            result    = abs (added * (a - b))
+            bitResult = (added `xor` a) .&. complement b
+            selected  = ite (a .> b) result (negate result)
+        cgOutput "added" added
+        cgOutput "bitResult" bitResult
+        cgReturn selected
+      x           = 2 ^ (700 :: Int) + 123456789
+      y           = negate (2 ^ (511 :: Int)) + 987654321
+      expected    = abs ((x + y) * (x - y))
+      expectedBit = ((x + y) `xor` x) .&. complement y
+  compileAndRunGMP dir "exactIntegerArithmetic" program [show expected, show (x + y), show expectedBit]
+
+-- | Huge and negative integers cannot alias valid entries during conversion
+-- to a machine index, even with optional runtime checks disabled.
+uncheckedExactTableIndices :: Assertion
+uncheckedExactTableIndices = mapM_ check [-1, 2 ^ (128 :: Int) + 1]
+ where check index = withSystemTempDirectory "sbv-unchecked-exact-index" $ \dir -> do
+         let program = do
+               cgOverwriteFiles True
+               cgPerformRTCs False
+               cgSetDriverValues [index]
+               input <- cgInput "input" :: SBVCodeGen SInteger
+               cgReturn (select [10, 11, 12] 99 input :: SWord8)
+         compileAndRunGMP dir "uncheckedExactIndex" program ["= 99"]
+
+-- | Exercise SMT-Lib Euclidean quotient and nonnegative remainder semantics.
+exactIntegerDivision :: Assertion
+exactIntegerDivision = withSystemTempDirectory "sbv-exact-integer-division" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [-20, -6]
+        a <- cgInput "a" :: SBVCodeGen SInteger
+        b <- cgInput "b" :: SBVCodeGen SInteger
+        let quotient  = a `sEDiv` b
+            remainder = a `sEMod` b
+        cgOutput "quotient" quotient
+        cgOutput "remainder" remainder
+        cgReturn (quotient .== 4 .&& remainder .== 4)
+  compileAndRunGMP dir "exactIntegerDivision" program ["= 1", "quotient =4", "remainder =4"]
+
+-- | Raw Euclidean division uses SBV's concrete zero-divisor choice, whereas
+-- public truncated quotient explicitly totalizes the same input to zero.
+integerZeroDivision :: Assertion
+integerZeroDivision = mapM_ check [Nothing, Just 8, Just 16, Just 32, Just 64]
+ where check mapping = withSystemTempDirectory "sbv-integer-zero-division" $ \dir -> do
+         let program = do
+               cgOverwriteFiles True
+               maybe (pure ()) cgIntegerSize mapping
+               cgSetDriverValues [7, 0]
+               a <- cgInput "a" :: SBVCodeGen SInteger
+               b <- cgInput "b" :: SBVCodeGen SInteger
+               cgReturn $ a `sEDiv` b .== a .&& a `sEMod` b .== a .&& a `sQuot` b .== 0
+         (_, generatedConfig, bundle) <- compileToC' "integerZeroDivision" program
+         renderCgPgmBundle (Just dir) (generatedConfig, bundle)
+         makeOptions <- generatedMakeOptions dir
+         (buildExit, _, buildError) <- readProcessWithExitCode "make" (["-C", dir] ++ makeOptions) ""
+         assertEqual buildError ExitSuccess buildExit
+         (runExit, outputText, runError) <- readProcessWithExitCode (dir </> "integerZeroDivision_driver") [] ""
+         assertEqual runError ExitSuccess runExit
+         assertBool outputText ("= 1" `isInfixOf` outputText)
+
+-- | GMP's decimal allocation bound can exceed the actual digit count by one.
+exactDecimalText :: Assertion
+exactDecimalText = mapM_ check [0, 1, 7, 8, 9, 10, 99, 100, 999, 1000, 2 ^ (257 :: Int)]
+ where check value = withSystemTempDirectory "sbv-exact-decimal-text" $ \dir -> do
+         let program = do
+               cgOverwriteFiles True
+               cgSetDriverValues [value]
+               input <- cgInput "input" :: SBVCodeGen SInteger
+               let rendered = SL.natToStr input
+               cgReturn $ rendered .== literal (show value) .&& SL.length rendered .== literal (toInteger (length (show value)))
+         compileAndRunGMP dir "exactDecimalText" program ["= 1"]
+
+-- | Exercise exact divisibility with a divisor too large for any native C
+-- integer, positive and negative multiples, and a neighboring non-multiple.
+exactIntegerDivisibility :: Assertion
+exactIntegerDivisibility = withSystemTempDirectory "sbv-exact-integer-divisibility" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [divisor * 7, negate (divisor * 3), divisor * 5 + 1]
+        positive    <- cgInput "positive"    :: SBVCodeGen SInteger
+        negative    <- cgInput "negative"    :: SBVCodeGen SInteger
+        nonMultiple <- cgInput "nonMultiple" :: SBVCodeGen SInteger
+        cgReturn $ sDivides divisor positive
+               .&& sDivides divisor negative
+               .&& sNot (sDivides divisor nonMultiple)
+      divisor = 2 ^ (257 :: Int) + 93
+  compileAndRunGMP dir "exactIntegerDivisibility" program ["= 1"]
+
+-- | Exercise symbolic exact integer exponentiation, including zero and
+-- negative exponents with the SMT-LIB integer-power semantics.
+exactIntegerExponentiation :: Assertion
+exactIntegerExponentiation = withSystemTempDirectory "sbv-exact-integer-exponentiation" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [2, 200, -1, -3, 0, 0]
+        base             <- cgInput "base"             :: SBVCodeGen SInteger
+        exponentValue    <- cgInput "exponent"         :: SBVCodeGen SInteger
+        negativeUnit     <- cgInput "negativeUnit"     :: SBVCodeGen SInteger
+        negativeExponent <- cgInput "negativeExponent" :: SBVCodeGen SInteger
+        zeroBase         <- cgInput "zeroBase"         :: SBVCodeGen SInteger
+        zeroExponent     <- cgInput "zeroExponent"     :: SBVCodeGen SInteger
+        cgReturn $ base         .** exponentValue            .== 2 ^ (200 :: Int)
+               .&& negativeUnit .** negativeExponent       .== -1
+               .&& negativeUnit .** (negativeExponent + 1) .== 1
+               .&& base         .** negativeExponent       .== 0
+               .&& zeroBase     .** negativeExponent       .== 0
+               .&& zeroBase     .** zeroExponent           .== 1
+  compileAndRunGMP dir "exactIntegerExponentiation" program ["= 1"]
+
+-- | Exercise exact conversions to and from native signed and unsigned words.
+exactNativeConversions :: Assertion
+exactNativeConversions = withSystemTempDirectory "sbv-exact-native-conversions" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [maxWord, minInt]
+        unsignedValue <- cgInput "unsignedValue" :: SBVCodeGen SWord64
+        signedValue   <- cgInput "signedValue"   :: SBVCodeGen SInt64
+        let exactUnsigned = sFromIntegral unsignedValue :: SInteger
+            exactSigned   = sFromIntegral signedValue :: SInteger
+            wrapped       = sFromIntegral (exactUnsigned + 1) :: SWord64
+            asReal        = sFromIntegral signedValue :: SReal
+        cgOutput "wrapped" wrapped
+        cgOutput "asReal" asReal
+        cgReturn (exactUnsigned + exactSigned)
+      maxWord  = 2 ^ (64 :: Int) - 1
+      minInt   = negate (2 ^ (63 :: Int))
+      expected = 2 ^ (63 :: Int) - 1 :: Integer
+  compileAndRunGMP dir "exactNativeConversions" program [show expected, "wrapped = 0x0000000000000000ULL", "asReal =-9223372036854775808"]
+
+-- | Narrowing an exact integer preserves low bits, including the one-bit
+-- representation. Signed results interpret those bits as two's complement.
+exactNativeBitPatterns :: Assertion
+exactNativeBitPatterns = mapM_ check [2, 3, -2, -129, 2 ^ (180 :: Int) + 32768]
+ where check sample = withSystemTempDirectory "sbv-exact-native-bits" $ \dir -> do
+         let program = do
+               cgOverwriteFiles True
+               cgSetDriverValues [sample]
+               value <- cgInput "value" :: SBVCodeGen SInteger
+               cgReturn $ sAnd
+                 [ (sFromIntegral value :: SWord 1) .== fromInteger sample
+                 , (sFromIntegral value :: SInt8)   .== fromInteger sample
+                 , (sFromIntegral value :: SInt16)  .== fromInteger sample
+                 , (sFromIntegral value :: SInt32)  .== fromInteger sample
+                 , (sFromIntegral value :: SInt64)  .== fromInteger sample
+                 ]
+         compileAndRunGMP dir "exactNativeBits" program ["= 1"]
+
+-- | Flooring a GMP real into a mapped integer first rounds exactly, then
+-- reduces modulo the requested width, even far outside the native range.
+exactRealMappedIntegers :: Assertion
+exactRealMappedIntegers = mapM_ check [(width, sample) | width <- [8, 16, 32, 64], sample <- [-huge, huge]]
+ where huge = 2 ^ (180 :: Int) + 5
+
+       check (width, sample) = withSystemTempDirectory "sbv-exact-real-mapped-integer" $ \dir -> do
+         let program = do
+               cgOverwriteFiles True
+               cgIntegerSize width
+               cgSetDriverValues [sample]
+               value <- cgInput "value" :: SBVCodeGen SReal
+               cgReturn (sRealToSIntegerFloor (value / 3) .== fromInteger (sample `div` 3))
+         compileAndRunGMP dir "exactRealMappedInteger" program ["= 1"]
+
+-- | Exercise signed and unsigned conversions between GMP integers and
+-- limb-backed bit-vectors in both directions.
+exactWideConversions :: Assertion
+exactWideConversions = withSystemTempDirectory "sbv-exact-wide-conversions" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [unsignedSample, signedSample, exactSample]
+        unsignedValue <- cgInput "unsignedValue" :: SBVCodeGen (SWord 673)
+        signedValue   <- cgInput "signedValue"   :: SBVCodeGen (SInt 673)
+        exactValue    <- cgInput "exactValue"    :: SBVCodeGen SInteger
+        let exactUnsigned     = sFromIntegral unsignedValue :: SInteger
+            exactSigned       = sFromIntegral signedValue :: SInteger
+            unsignedRoundTrip = (sFromIntegral exactUnsigned :: SWord 673) .== unsignedValue
+            signedRoundTrip   = (sFromIntegral exactSigned :: SInt 673) .== signedValue
+            wrappedUnsigned   = sFromIntegral exactValue :: SWord 673
+            wrappedSigned     = sFromIntegral exactValue :: SInt 673
+        cgOutput "unsignedRoundTrip" unsignedRoundTrip
+        cgOutput "signedRoundTrip" signedRoundTrip
+        cgOutput "wrappedUnsigned" wrappedUnsigned
+        cgOutput "wrappedSigned" wrappedSigned
+        cgReturn (exactUnsigned + exactSigned)
+      unsignedSample = 2 ^ (672 :: Int) + 0x123456789abcdef
+      signedSample   = negate (2 ^ (671 :: Int)) + 0xfedcba987654321
+      exactSample    = negate (2 ^ (700 :: Int)) + 0x112233445566778899
+      expected       = unsignedSample + signedSample
+      wrapped        = exactSample `mod` 2 ^ (673 :: Int)
+  compileAndRunGMP dir "exactWideConversions" program
+    [ show expected
+    , "unsignedRoundTrip = 1"
+    , "signedRoundTrip = 1"
+    , "wrappedUnsigned =" ++ asHex 11 wrapped
+    , "wrappedSigned =" ++ asHex 11 wrapped
+    ]
+
+-- | Exercise exact conversion of signed and unsigned limb-backed values to
+-- rational reals, followed by explicit floor and truncation back to wide
+-- bit-vectors through 'SInteger'.
+exactWideRealConversions :: Assertion
+exactWideRealConversions = withSystemTempDirectory "sbv-exact-wide-real-conversions" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [unsignedSample, signedSample]
+        unsignedValue <- cgInput "unsignedValue" :: SBVCodeGen (SWord 673)
+        signedValue   <- cgInput "signedValue"   :: SBVCodeGen (SInt 673)
+        let unsignedReal = sFromIntegral unsignedValue :: SReal
+            signedReal   = sFromIntegral signedValue :: SReal
+            fraction     = signedReal / 3
+            floorWide    = sFromIntegral (sRealToSIntegerFloor fraction) :: SInt 673
+            truncateWide = sFromIntegral (sRealToSIntegerTruncate fraction) :: SInt 673
+        cgOutput "unsignedReal" unsignedReal
+        cgOutput "signedReal" signedReal
+        cgOutput "fraction" fraction
+        cgOutput "floorWide" floorWide
+        cgOutput "truncateWide" truncateWide
+        cgReturn (unsignedReal + signedReal)
+      unsignedSample = 2 ^ (672 :: Int) + 0x123456789abcdef
+      signedSample   = negate (2 ^ (671 :: Int)) + 0xfedcba987654321
+      floorResult    = signedSample `div` 3
+      truncateResult = signedSample `quot` 3
+      modulus        = 2 ^ (673 :: Int)
+  compileAndRunGMP dir "exactWideRealConversions" program
+    [ show (unsignedSample + signedSample)
+    , "unsignedReal =" ++ show unsignedSample
+    , "signedReal =" ++ show signedSample
+    , "fraction =" ++ show signedSample ++ "/3"
+    , "floorWide =" ++ asHex 11 (floorResult `mod` modulus)
+    , "truncateWide =" ++ asHex 11 (truncateResult `mod` modulus)
+    ]
+
+-- | Exercise exact rational arithmetic and integer-to-real conversion.
+exactRealArithmetic :: Assertion
+exactRealArithmetic = withSystemTempDirectory "sbv-exact-real" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [5, 2, 2]
+        a <- cgInput "a" :: SBVCodeGen SReal
+        b <- cgInput "b" :: SBVCodeGen SReal
+        integer <- cgInput "integer" :: SBVCodeGen SInteger
+        let converted = sFromIntegral integer :: SReal
+            base      = a / 3 + b / 7 + converted
+            result    = ite (a .> b) (abs (base * (-3))) 0
+        cgOutput "converted" converted
+        cgOutput "base" base
+        cgReturn result
+  compileAndRunGMP dir "exactRealArithmetic" program ["83/7", "converted =2", "base =83/21"]
+
+-- | Exercise finite tables with an unbounded index and GMP-backed integer and
+-- rational results, including negative and oversized default cases.
+exactTableLookup :: Assertion
+exactTableLookup = withSystemTempDirectory "sbv-exact-table" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgPerformRTCs True
+        cgSetDriverValues [1, -1, 500, 2 ^ (200 :: Int)]
+        inRangeIndex   <- cgInput "inRangeIndex"   :: SBVCodeGen SInteger
+        negativeIndex  <- cgInput "negativeIndex"  :: SBVCodeGen SInteger
+        oversizedIndex <- cgInput "oversizedIndex" :: SBVCodeGen SInteger
+        tableValue     <- cgInput "tableValue"     :: SBVCodeGen SInteger
+        let integerResult   = select [2 ^ (130 :: Int), tableValue + 7] (-11) inRangeIndex :: SInteger
+            negativeResult  = select [3 / 2, 5 / 3] (7 / 4) negativeIndex :: SReal
+            oversizedResult = select [13, 17] 19 oversizedIndex :: SInteger
+        cgOutput "negativeResult" negativeResult
+        cgOutput "oversizedResult" oversizedResult
+        cgReturn integerResult
+  compileAndRunGMP dir "exactTableLookup" program [show (2 ^ (200 :: Int) + 7 :: Integer), "negativeResult =7/4", "oversizedResult =19"]
+
+-- | Exercise a persistent array with GMP-backed integer keys and rational
+-- values, including a read from the unchanged base version.
+exactArray :: Assertion
+exactArray = withSystemTempDirectory "sbv-exact-array" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [2 ^ (300 :: Int) + 9, 20]
+        key   <- cgInput "key"   :: SBVCodeGen SInteger
+        value <- cgInput "value" :: SBVCodeGen SInteger
+        let stored  = sFromIntegral value / 3 :: SReal
+            base    = constArray (1 / 3 :: SReal)
+            updated = writeArray base key stored
+        cgOutput "baseValue" (readArray base key)
+        cgReturn (readArray updated key)
+  compileAndRunGMP dir "exactArray" program ["20/3", "baseValue =1/3"]
+
+-- | Exercise borrowed callback input and overlay semantics with GMP-backed
+-- integer keys and rational values.
+exactArrayInput :: Assertion
+exactArrayInput = withSystemTempDirectory "sbv-exact-array-input" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [7, 2 ^ (300 :: Int) + 9, 20]
+        source <- cgInput "source" :: SBVCodeGen (SArray Integer AlgReal)
+        key    <- cgInput "key"    :: SBVCodeGen SInteger
+        value  <- cgInput "value"  :: SBVCodeGen SInteger
+        let updated = writeArray source key (sFromIntegral value / 3)
+        cgOutput "sourceValue" (readArray source key)
+        cgReturn (readArray updated key)
+  compileAndRunGMP dir "exactArrayInput" program ["20/3", "sourceValue =7"]
+
+-- | Exercise borrowed fixed-size GMP input arrays for integers, reals, and
+-- rationals, including caller initialization and cleanup in the driver.
+exactFixedInputArrays :: Assertion
+exactFixedInputArrays = withSystemTempDirectory "sbv-exact-fixed-input-arrays" $ \dir -> do
+  let integerSeed = 2 ^ (300 :: Int) + 11
+      program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [integerSeed, -7, 5, 2, 9, 4]
+        [integerA, integerB]   <- cgInputArr 2 "integers"  :: SBVCodeGen [SInteger]
+        [realA, realB]         <- cgInputArr 2 "reals"     :: SBVCodeGen [SReal]
+        [rationalA, rationalB] <- cgInputArr 2 "rationals" :: SBVCodeGen [SRational]
+        cgOutput "integerResult"  (integerA + integerB)
+        cgOutput "realResult"     (realA / realB)
+        cgOutput "rationalResult" (rationalA / rationalB)
+        cgReturn (integerA .> integerB .&& realA .> realB .&& rationalA .> rationalB)
+
+  compileAndRunGMP dir "exactFixedInputArrays" program
+    [ show (integerSeed - 7)
+    , "realResult =5/2"
+    , "rationalResult =9/4"
+    , ") = 1"
+    ]
+  headerText <- readFile (dir </> "exactFixedInputArrays.h")
+  driverText <- readFile (dir </> "exactFixedInputArrays_driver.c")
+  assertBool "Expected fixed exact inputs to use borrowed GMP array parameters"
+             ("const mpz_t *integers" `isInfixOf` headerText
+           && "const mpq_t *reals" `isInfixOf` headerText
+           && "const mpq_t *rationals" `isInfixOf` headerText)
+  assertBool "Expected the generated driver to release every GMP input-array element"
+             ("mpz_clear(sbv_driver_input_0[0]);" `isInfixOf` driverText
+           && "mpz_clear(sbv_driver_input_0[1]);" `isInfixOf` driverText
+           && "mpq_clear(sbv_driver_input_1[0]);" `isInfixOf` driverText
+           && "mpq_clear(sbv_driver_input_2[1]);" `isInfixOf` driverText)
+
+-- | Exercise repeated reads from a structured array lambda whose arithmetic
+-- allocates exact rational results in the enclosing generated-call arena.
+exactLambdaArray :: Assertion
+exactLambdaArray = withSystemTempDirectory "sbv-exact-lambda-array" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [20]
+        key <- cgInput "key" :: SBVCodeGen SInteger
+        let source = lambdaArray (\index -> sFromIntegral index / 3) :: SArray Integer AlgReal
+        cgOutput "value" (readArray source key)
+        cgReturn (readArray source (key + 1))
+  compileAndRunGMP dir "exactLambdaArray" program ["7", "value =20/3"]
+
+-- | Exercise a parameter-dependent exact table whose entries allocate in the
+-- structured lambda's enclosing GMP arena.
+exactLambdaTable :: Assertion
+exactLambdaTable = withSystemTempDirectory "sbv-exact-lambda-table" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [1]
+        key <- cgInput "key" :: SBVCodeGen SInteger
+        let source = lambdaArray (\index -> select [sFromIntegral index / 3, sFromIntegral index / 5] 7 index)
+                     :: SArray Integer AlgReal
+        cgReturn (readArray source key)
+  compileAndRunGMP dir "exactLambdaTable" program ["1/5"]
+
+-- | Exercise exact store cloning and a structured callback that allocates
+-- after the generated function's original GMP arena has been released.
+ownedExactArrays :: Assertion
+ownedExactArrays = withSystemTempDirectory "sbv-owned-exact-arrays" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        let source = lambdaArray (\index -> sFromIntegral index / 3) :: SArray Integer AlgReal
+        cgOutput "stored" (writeArray source 0 (5 / 3))
+        cgReturn source
+
+  compileAndRunGMP dir "ownedExactArrays" program ["ownedExactArrays(&stored)[0] =0", "stored[0] =5/3"]
+
+-- | Exercise exact tuple construction, constants in a finite table,
+-- projection, and copying into scalar caller-owned results.
+exactTupleFields :: Assertion
+exactTupleFields = withSystemTempDirectory "sbv-exact-tuple-fields" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [0]
+        index <- cgInput "index" :: SBVCodeGen SWord8
+        let first, second             :: SBV (AlgReal, Integer)
+            first                     = tuple (1 / 3, 2 ^ (130 :: Int))
+            second                    = tuple (5 / 7, 9)
+            selected                  = select [first] second index
+            (realValue, integerValue) = untuple selected
+        cgOutput "integerValue" integerValue
+        cgReturn realValue
+
+  compileAndRunGMP dir "exactTupleFields" program ["1/3", show (2 ^ (130 :: Int) :: Integer)]
+
+-- | Exercise borrowed exact-tuple inputs and independently owned outputs and
+-- returns whose GMP fields survive the generated call's temporary arena.
+ownedExactTuples :: Assertion
+ownedExactTuples = withSystemTempDirectory "sbv-owned-exact-tuples" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [seed]
+        source <- cgInput "source" :: SBVCodeGen (SBV (Integer, (AlgReal, Integer)))
+        let (integerValue, nested)      = untuple source
+            (realValue, secondInteger) = untuple nested
+            outputTuple                = tuple (integerValue + 1, tuple (realValue / 3, secondInteger + 2))
+            result                     = tuple (integerValue * 2, tuple (realValue + 1, secondInteger * 3))
+        cgOutput "output" outputTuple
+        cgReturn result
+      seed           = 2 ^ (130 :: Int)
+      expectedOutput = "output =(" ++ show (seed + 1) ++ ", (" ++ show (seed + 1) ++ "/3, " ++ show (seed + 4) ++ "))"
+      expectedReturn = "(" ++ show (seed * 2) ++ ", (" ++ show (seed + 2) ++ ", " ++ show ((seed + 2) * 3) ++ "))"
+
+  compileAndRunGMP dir "ownedExactTuples" program [expectedReturn, expectedOutput]
+
+-- | Exercise borrowed exact-field ADT inputs and independently owned outputs
+-- and returns, including exact fields nested through another ADT and a tuple.
+ownedExactADTs :: Assertion
+ownedExactADTs = withSystemTempDirectory "sbv-owned-exact-adts" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [seed]
+        source <- cgInput "source" :: SBVCodeGen SExactAggregate
+        let leaf                      = getExactAggregate_1 source
+            values                    = getExactAggregate_2 source
+            integerValue              = getExactLeaf_1 leaf
+            realValue                 = getExactLeaf_2 leaf
+            (tupleInteger, tupleReal) = untuple values
+            outputValues              = tuple (tupleInteger + 2, tupleReal + 3)
+            outputLeaf                = sExactLeaf (integerValue + 1) (realValue / 7)
+            outputAggregate           = sExactAggregate outputLeaf outputValues
+            resultValues              = tuple (tupleInteger * 3, tupleReal / 5)
+            resultLeaf                = sExactLeaf (integerValue * 2) (realValue + 1)
+            resultAggregate           = sExactAggregate resultLeaf resultValues
+        cgOutput "output" outputAggregate
+        cgOutput "sameAsResult" (source .== resultAggregate)
+        cgReturn resultAggregate
+      seed           = 2 ^ (130 :: Int) + 1
+      expectedOutput = "output =ExactAggregate(ExactLeaf(" ++ show (seed + 1)
+                    ++ ", " ++ show (seed + 1) ++ "/7), (" ++ show (seed + 3)
+                    ++ ", " ++ show (seed + 5) ++ "))"
+      expectedReturn = "ExactAggregate(ExactLeaf(" ++ show (seed * 2)
+                    ++ ", " ++ show (seed + 2) ++ "), (" ++ show (3 * (seed + 1))
+                    ++ ", " ++ show (seed + 2) ++ "/5))"
+
+  compileAndRunGMP dir "ownedExactADTs" program [expectedReturn, expectedOutput, "sameAsResult = 0"]
+
+-- | Exercise deep cloning and release for an ADT that combines recursive
+-- pointer nodes with GMP-backed fields.
+ownedRecursiveExactADTs :: Assertion
+ownedRecursiveExactADTs = withSystemTempDirectory "sbv-owned-recursive-exact-adts" $ \dir -> do
+  let program = do
+        cgOverwriteFiles True
+        cgSetDriverValues [1]
+        source <- cgInput "source" :: SBVCodeGen SExactChain
+        cgOutput "sameChain" (source .== source)
+        cgOutput "chainCopy" source
+        cgReturn source
+
+  compileAndRunGMP dir "ownedRecursiveExactADTs" program
+    [ "sameChain = 1"
+    , "ExactNext(1, ExactEnd(2))"
+    ]
+
+-- | Exercise merged headers, archives, and drivers for exact-number libraries.
+exactNumberLibrary :: Assertion
+exactNumberLibrary = withSystemTempDirectory "sbv-exact-library" $ \dir -> do
+  let integerProgram = do
+        cgOverwriteFiles True
+        cgSetDriverValues [2 ^ (130 :: Int)]
+        value <- cgInput "value" :: SBVCodeGen SInteger
+        cgReturn (value + 7)
+      realProgram = do
+        cgOverwriteFiles True
+        cgSetDriverValues [5]
+        value <- cgInput "value" :: SBVCodeGen SReal
+        cgReturn (value / 3)
+      wideProgram = do
+        cgOverwriteFiles True
+        cgSetDriverValues [wideSample]
+        value <- cgInput "value" :: SBVCodeGen (SInt 673)
+        cgReturn (sFromIntegral value :: SInteger)
+      arrayProgram = do
+        cgOverwriteFiles True
+        cgSetDriverValues [arraySeed, 3]
+        [first, second] <- cgInputArr 2 "values" :: SBVCodeGen [SInteger]
+        cgReturn (first - second)
+      tupleProgram increment = do
+        cgOverwriteFiles True
+        cgSetDriverValues [tupleSeed]
+        source <- cgInput "source" :: SBVCodeGen (SBV (Integer, AlgReal))
+        let (integerValue, realValue) = untuple source
+        cgReturn (tuple (integerValue + fromInteger increment, realValue + fromInteger increment))
+      adtProgram increment = do
+        cgOverwriteFiles True
+        cgSetDriverValues [adtSeed]
+        source <- cgInput "source" :: SBVCodeGen SExactAggregate
+        let leaf                      = getExactAggregate_1 source
+            integerValue              = getExactLeaf_1 leaf
+            realValue                 = getExactLeaf_2 leaf
+            (tupleInteger, tupleReal) = untuple (getExactAggregate_2 source)
+            integerAmount             = fromInteger increment :: SInteger
+            realAmount                = fromInteger increment :: SReal
+            resultLeaf                = sExactLeaf (integerValue + integerAmount) (realValue + realAmount)
+            resultValues              = tuple (tupleInteger + integerAmount, tupleReal + realAmount)
+        cgReturn (sExactAggregate resultLeaf resultValues)
+      wideSample = negate (2 ^ (670 :: Int)) + 12345
+      arraySeed  = 2 ^ (180 :: Int) + 9
+      tupleSeed  = 2 ^ (140 :: Int)
+      adtSeed    = 2 ^ (150 :: Int) + 1
+
+  (_, cfg, bundle) <- compileToCLib' "exactNumberLibrary"
+    [ ("integerPart", integerProgram)
+    , ("realPart", realProgram)
+    , ("widePart", wideProgram)
+    , ("arrayPart", arrayProgram)
+    , ("incrementTuple", tupleProgram 1)
+    , ("addTwoTuple", tupleProgram 2)
+    , ("incrementADT", adtProgram 1)
+    , ("addTwoADT", adtProgram 2)
+    ]
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+
+  makeOptions <- generatedMakeOptions dir
+  (makeExit, _, makeError) <- readProcessWithExitCode "make" (["-C", dir] ++ makeOptions) ""
+  assertEqual makeError ExitSuccess makeExit
+
+  let driverExecutable = dir </> "exactNumberLibrary_driver"
+  (runExit, stdoutText, runError) <- readProcessWithExitCode driverExecutable [] ""
+  assertEqual runError ExitSuccess runExit
+  assertOutput stdoutText (show (2 ^ (130 :: Int) + 7 :: Integer))
+  assertOutput stdoutText "5/3"
+  assertOutput stdoutText (show wideSample)
+  assertOutput stdoutText (show (arraySeed - 3))
+  assertOutput stdoutText ("(" ++ show (tupleSeed + 1) ++ ", " ++ show (tupleSeed + 2) ++ ")")
+  assertOutput stdoutText ("(" ++ show (tupleSeed + 2) ++ ", " ++ show (tupleSeed + 3) ++ ")")
+  assertOutput stdoutText ("ExactAggregate(ExactLeaf(" ++ show (adtSeed + 1) ++ ", " ++ show (adtSeed + 2)
+                         ++ "), (" ++ show (adtSeed + 2) ++ ", " ++ show (adtSeed + 3) ++ "))")
+  assertOutput stdoutText ("ExactAggregate(ExactLeaf(" ++ show (adtSeed + 2) ++ ", " ++ show (adtSeed + 3)
+                         ++ "), (" ++ show (adtSeed + 3) ++ ", " ++ show (adtSeed + 4) ++ "))")
+
+-- | Generate, compile, and execute a program against the system GMP package.
+-- Exercise both a direct compiler invocation and the generated Makefile, honoring
+-- @SBV_C_TEST_FLAGS@ in both paths so rebuilding cannot hide sanitizer failures.
+compileAndRunGMP :: FilePath -> String -> SBVCodeGen () -> [String] -> Assertion
+compileAndRunGMP dir functionName program expected = do
+  (_, cfg, bundle) <- compileToC' functionName program
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+
+  (pkgExit, pkgOutput, pkgError) <- readProcessWithExitCode "pkg-config" ["--cflags", "--libs", "gmp"] ""
+  assertEqual pkgError ExitSuccess pkgExit
+
+  extraFlags <- maybe [] words <$> lookupEnv "SBV_C_TEST_FLAGS"
+  let source = dir </> functionName ++ ".c"
+      driver = dir </> functionName ++ "_driver.c"
+      exe    = dir </> functionName ++ "_driver"
+      args   = ["-std=c11", "-Wall", "-Werror", "-ffp-contract=off", source, driver, "-o", exe] ++ extraFlags ++ words pkgOutput
+      checkRun = do (runExit, stdoutText, runError) <- readProcessWithExitCode exe [] ""
+                    assertEqual runError ExitSuccess runExit
+                    mapM_ (assertOutput stdoutText) expected
+  (ccExit, _, ccError) <- readProcessWithExitCode "cc" args ""
+  assertEqual ccError ExitSuccess ccExit
+  checkRun
+
+  makeOptions <- generatedMakeOptions dir
+  (makeExit, _, makeError) <- readProcessWithExitCode "make" (["-C", dir] ++ makeOptions) ""
+  assertEqual makeError ExitSuccess makeExit
+  checkRun
+
+  makefile <- readFile (dir </> "Makefile")
+  assertBool "Generated Makefile does not request GMP compiler flags" ("pkg-config --cflags gmp" `isInfixOf` makefile)
+  assertBool "Generated Makefile does not request GMP linker flags" ("pkg-config --libs gmp" `isInfixOf` makefile)
+
+-- | Assert that generated driver output contains an expected fragment.
+assertOutput :: String -> String -> Assertion
+assertOutput stdoutText fragment =
+  assertBool ("Expected generated output to contain " ++ fragment ++ ", received:\n" ++ stdoutText) (fragment `isInfixOf` stdoutText)
+
+-- | Render the fixed-limb hexadecimal form printed by generated drivers.
+asHex :: Int -> Integer -> String
+asHex limbCount value = "0x" ++ replicate (16 * limbCount - length rendered) '0' ++ rendered
+ where rendered = showHex value ""
diff --git a/SBVTestSuite/TestSuite/CodeGeneration/LibraryBuild.hs b/SBVTestSuite/TestSuite/CodeGeneration/LibraryBuild.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CodeGeneration/LibraryBuild.hs
@@ -0,0 +1,125 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : TestSuite.CodeGeneration.LibraryBuild
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Incremental build regressions for generated C static libraries.
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module TestSuite.CodeGeneration.LibraryBuild (tests, testsWith) where
+
+import Control.Monad (void)
+import qualified Data.ByteString as BS
+import System.Directory (doesFileExist)
+import System.Environment (lookupEnv)
+import System.Exit (ExitCode(..))
+import System.FilePath ((</>), takeExtension)
+import System.IO.Temp (withSystemTempDirectory)
+import System.Process (readProcessWithExitCode)
+import Test.Tasty.HUnit (assertBool, assertEqual)
+
+import Data.SBV.Tools.CodeGen
+import qualified Data.SBV.Tools.CodeGen.Legacy as Legacy
+import Utils.SBVTestFramework
+
+-- | Generate a library named @buildLibrary@ with the supplied components.
+type LibraryGenerator = FilePath -> [(String, SBVCodeGen ())] -> IO ()
+
+-- | Exercise both the current and legacy public library generators.
+tests :: TestTree
+tests = testGroup "CodeGeneration.LibraryBuild"
+  [ testsWith "current" $ \dir components -> void $        compileToCLib (Just dir) "buildLibrary" components
+  , testsWith "legacy"  $ \dir components -> void $ Legacy.compileToCLib (Just dir) "buildLibrary" components
+  ]
+
+-- | Apply the same archive and driver checks to either public C backend.
+testsWith :: String -> LibraryGenerator -> TestTree
+testsWith groupName generate = testGroup groupName
+  [ testCase "driver archive dependency" (driverDependencies generate)
+  , testCase "remove retired components with a driver" (archiveRegeneration generate True)
+  , testCase "remove retired components without a driver" (archiveRegeneration generate False)
+  , testCase "preserve archive after a failed rebuild" (failedArchiveRebuild generate)
+  ]
+
+-- | Generate a trivial scalar component with predictable driver output.
+component :: Bool -> Word8 -> SBVCodeGen ()
+component driver value = do
+  cgOverwriteFiles True
+  cgGenerateDriver driver
+  cgSetDriverValues []
+  cgReturn (literal value)
+
+-- | Building the driver directly must first build its archive, including in
+-- parallel builds. Both archive and component changes must invalidate it.
+driverDependencies :: LibraryGenerator -> Assertion
+driverDependencies generate = withSystemTempDirectory "sbv-c-library-driver" $ \dir -> do
+  generate dir [("component", component True 7)]
+  build dir ["-j2", "buildLibrary_driver"]
+  (runExit, _, runError) <- readProcessWithExitCode (dir </> "buildLibrary_driver") [] ""
+  assertEqual runError ExitSuccess runExit
+  (freshExit, _, freshError) <- readProcessWithExitCode "make" ["-C", dir, "-q", "buildLibrary_driver"] ""
+  assertEqual freshError ExitSuccess freshExit
+  mapM_ (checkDependency dir) ["component.c", "buildLibrary.a", "buildLibrary.h"]
+ where checkDependency dir prerequisite = do
+         (staleExit, _, staleError) <- readProcessWithExitCode "make"
+           ["-C", dir, "-q", "-W", prerequisite, "buildLibrary_driver"] ""
+         assertEqual (prerequisite ++ ": " ++ staleError) (ExitFailure 1) staleExit
+
+-- | Regeneration must replace the archive's membership, not merely update
+-- members still present. Old component files outside the archive are retained.
+archiveRegeneration :: LibraryGenerator -> Bool -> Assertion
+archiveRegeneration generate driver = withSystemTempDirectory "sbv-c-library-regeneration" $ \dir -> do
+  let retained = ("retained", component driver 11)
+      retired  = ("retired",  component driver 22)
+  generate dir [retained, retired]
+  build dir ["buildLibrary.a"]
+  checkMembers dir ["retained.o", "retired.o"]
+  generate dir [retained]
+  build dir ["-B", "buildLibrary.a"]
+  checkMembers dir ["retained.o"]
+  assertBool "Unselected component objects must not be deleted" =<< doesFileExist (dir </> "retired.o")
+  generate dir [retired, retained]
+  build dir ["-B", "buildLibrary.a"]
+  checkMembers dir ["retired.o", "retained.o"]
+
+-- | An unsuccessful archiver must leave the previous valid archive intact.
+-- A subsequent successful rebuild must recover without manual cleanup.
+failedArchiveRebuild :: LibraryGenerator -> Assertion
+failedArchiveRebuild generate = withSystemTempDirectory "sbv-c-library-failed-rebuild" $ \dir -> do
+  generate dir [("component", component False 7)]
+  build dir ["buildLibrary.a"]
+  original <- BS.readFile (dir </> "buildLibrary.a")
+  makeOptions <- buildOptions
+  (failedExit, _, _) <- readProcessWithExitCode "make"
+    (["-C", dir, "-B", "buildLibrary.a", "AR=false"] ++ makeOptions) ""
+  assertBool "The failed archiver must fail the build" (failedExit /= ExitSuccess)
+  assertBool "The previous archive must still exist" =<< doesFileExist (dir </> "buildLibrary.a")
+  assertEqual "The previous archive must remain unchanged" original =<< BS.readFile (dir </> "buildLibrary.a")
+  build dir ["-B", "buildLibrary.a"]
+  checkMembers dir ["component.o"]
+
+-- | Build with strict C warnings and optional local sanitizer flags.
+build :: FilePath -> [String] -> Assertion
+build dir targets = do
+  makeOptions <- buildOptions
+  (makeExit, _, makeError) <- readProcessWithExitCode "make" (["-C", dir] ++ targets ++ makeOptions) ""
+  assertEqual makeError ExitSuccess makeExit
+
+-- | Preserve caller-selected instrumentation during compilation and linking.
+buildOptions :: IO [String]
+buildOptions = do
+  extraFlags <- maybe "" (" " ++) <$> lookupEnv "SBV_C_TEST_FLAGS"
+  pure ["CCFLAGS=-std=c11 -Wall -Wextra -Werror -O2" ++ extraFlags]
+
+-- | Compare object membership and order, ignoring platform-specific symbol
+-- index members such as the BSD archiver's @__.SYMDEF@ entry.
+checkMembers :: FilePath -> [String] -> Assertion
+checkMembers dir expected = do
+  (arExit, members, arError) <- readProcessWithExitCode "ar" ["t", dir </> "buildLibrary.a"] ""
+  assertEqual arError ExitSuccess arExit
+  assertEqual "Archive components" expected (filter ((== ".o") . takeExtension) (lines members))
diff --git a/SBVTestSuite/TestSuite/CodeGeneration/PseudoBoolean.hs b/SBVTestSuite/TestSuite/CodeGeneration/PseudoBoolean.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CodeGeneration/PseudoBoolean.hs
@@ -0,0 +1,130 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : TestSuite.CodeGeneration.PseudoBoolean
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Executed pseudo-Boolean comparisons at native overflow boundaries.
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module TestSuite.CodeGeneration.PseudoBoolean (tests, testsWith) where
+
+import Control.Monad (replicateM, void)
+import Data.List (intercalate)
+import System.Environment (lookupEnv)
+import System.Exit (ExitCode(..))
+import System.FilePath ((</>))
+import System.IO.Temp (withSystemTempDirectory)
+import System.Process (readProcessWithExitCode)
+import Test.Tasty.HUnit (assertEqual)
+
+import Data.SBV.Tools.CodeGen
+import qualified Data.SBV.Tools.CodeGen.Legacy as Legacy
+import Utils.SBVTestFramework
+
+-- | Exercise both backends through their public standalone and library APIs.
+tests :: TestTree
+tests = testGroup "CodeGeneration.PseudoBoolean"
+  [ testsWith "current" $ \dir library functionName program ->
+      if library
+         then void $ compileToCLib (Just dir) "pbLibrary" [(functionName, program)]
+         else compileToC (Just dir) functionName program
+  , testsWith "legacy" $ \dir library functionName program ->
+      if library
+         then void $ Legacy.compileToCLib (Just dir) "pbLibrary" [(functionName, program)]
+         else Legacy.compileToC (Just dir) functionName program
+  ]
+
+-- | Reuse the execution matrix for a compatibility backend without changing its
+-- import facade. Every truth assignment is checked against unbounded Haskell
+-- arithmetic, at both optimization levels and with undefined-behavior checking.
+testsWith :: String -> (FilePath -> Bool -> String -> SBVCodeGen () -> IO ()) -> TestTree
+testsWith groupName generate = testGroup groupName
+  [ testCase (form ++ " mapped" ++ show integerWidth ++ " " ++ optimization) $ withSystemTempDirectory "sbv-c-pseudo-boolean" $ \dir -> do
+      let functionName = "pbChecks"
+          artifact = if library then "pbLibrary.a" else functionName ++ ".o"
+          header   = if library then "pbLibrary.h" else functionName ++ ".h"
+      generate dir library functionName $ do
+        cgOverwriteFiles True
+        cgGenerateDriver False
+        cgIntegerSize integerWidth
+        inputs <- cgInputArr 5 "inputs"
+        cgOutputArr "checks" (comparisons inputs)
+      extraFlags <- maybe [] words <$> lookupEnv "SBV_C_TEST_FLAGS"
+      let flags = ["-std=c11", "-Wall", "-Wextra", "-Werror"] ++ words optimization ++ extraFlags
+      (makeExit, _, makeError) <- readProcessWithExitCode "make"
+        ["-C", dir, artifact, "CCFLAGS=" ++ unwords flags] ""
+      assertEqual makeError ExitSuccess makeExit
+      writeFile (dir </> "caller.c") (caller header functionName)
+      let executablePath = dir </> "caller"
+      (ccExit, _, ccError) <- readProcessWithExitCode "cc"
+        (flags ++ [dir </> "caller.c", dir </> artifact, "-o", executablePath]) ""
+      assertEqual ccError ExitSuccess ccExit
+      (runExit, _, runError) <- readProcessWithExitCode executablePath [] ""
+      assertEqual runError ExitSuccess runExit
+      mapM_ (\values -> assertEqual "Concrete SBV comparisons must agree with mathematical sums"
+                                    (map Just (expected values)) (map unliteral (comparisons (map literal values)))) assignments
+  | (form, library) <- [("standalone", False), ("library", True)]
+  , integerWidth <- [8, 64]
+  , optimization <- ["-O0", "-O2", "-O1 -fsanitize=undefined -fno-sanitize-recover=all"]
+  ]
+
+-- | Coefficients and bounds covering signed 32-bit overflow, signed and unsigned
+-- 64-bit overflow, zero weights, exact ties, and crossing a bound late in a sum.
+scenarios :: [([Int], Int)]
+scenarios = [ ([2000000000, 2000000000, 0, 0, 0], 2100000000)
+            , ([maxBound, maxBound, 0, 0, 0], maxBound)
+            , (replicate 5 maxBound, maxBound)
+            , ([maxBound, 1, maxBound, 1, 0], maxBound)
+            , ([0, 0, 0, 0, 0], 0)
+            , ([0, 1, 0, 1, 0], 0)
+            , ([1, 2, 3, 4, 5], 7)
+            , ([1, 2, 3, 4, 5], maxBound)
+            , ([maxBound, maxBound, maxBound, 0, 0], 0)
+            , ([maxBound - 1, 1, 1, maxBound - 1, 1], maxBound)
+            ]
+
+-- | All assignments to the five independent input Booleans.
+assignments :: [[Bool]]
+assignments = replicateM 5 [False, True]
+
+-- | Exercise all six pseudo-Boolean operators, plus their empty-list semantics.
+comparisons :: [SBool] -> [SBool]
+comparisons inputs = concat [let weighted = zip coefficients inputs
+                            in [pbLe weighted bound, pbGe weighted bound, pbEq weighted bound]
+                            | (coefficients, bound) <- scenarios]
+                  ++ [pbAtMost inputs 2, pbAtLeast inputs 2, pbExactly inputs 2]
+                  ++ [pbAtMost [] 0, pbAtLeast [] 1, pbExactly [] 0]
+
+-- | Compute expected answers with mathematical integers, never machine sums.
+expected :: [Bool] -> [Bool]
+expected inputs = concat [compareSum (sum [toInteger coefficient | (coefficient, True) <- zip coefficients inputs]) (toInteger bound)
+                         | (coefficients, bound) <- scenarios]
+               ++ compareSum (toInteger (length (filter id inputs))) 2
+               ++ [True, False, True]
+ where compareSum total bound = [total <= bound, total >= bound, total == bound]
+
+-- | An independent C caller supplies all input combinations and exact expected
+-- outputs. Its arrays are shared across calls to check that temporary sums reset.
+caller :: String -> String -> String
+caller header functionName = unlines
+  [ "#include <assert.h>"
+  , "#include \"" ++ header ++ "\""
+  , "int main(void)"
+  , "{"
+  , "  static const SBool inputs[][5] = {" ++ intercalate ", " (map row assignments) ++ "};"
+  , "  static const SBool expected[][" ++ show count ++ "] = {" ++ intercalate ", " (map (row . expected) assignments) ++ "};"
+  , "  SBool output[" ++ show count ++ "];"
+  , "  for (size_t i = 0; i < sizeof inputs / sizeof inputs[0]; ++i) {"
+  , "    " ++ functionName ++ "(inputs[i], output);"
+  , "    for (size_t j = 0; j < " ++ show count ++ "; ++j) assert(output[j] == expected[i][j]);"
+  , "  }"
+  , "  return 0;"
+  , "}"
+  ]
+ where count = length (expected (replicate 5 False))
+       row values = "{" ++ intercalate ", " [if value then "true" else "false" | value <- values] ++ "}"
diff --git a/SBVTestSuite/TestSuite/CodeGeneration/RegExp.hs b/SBVTestSuite/TestSuite/CodeGeneration/RegExp.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CodeGeneration/RegExp.hs
@@ -0,0 +1,351 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : TestSuite.CodeGeneration.RegExp
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Execute bounded, dependency-free C regex automata against solver results.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE OverloadedStrings #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module TestSuite.CodeGeneration.RegExp (tests) where
+
+import Control.Exception (ErrorCall, displayException, evaluate, try)
+import Control.Monad (forM, forM_, replicateM, void)
+import Data.Char (ord)
+import Data.List (intercalate, isInfixOf, nub)
+import System.Directory (listDirectory)
+import System.Environment (lookupEnv)
+import System.Exit (ExitCode(..))
+import System.FilePath ((</>))
+import System.IO.Temp (withSystemTempDirectory)
+import System.Process (readProcessWithExitCode)
+import Test.Tasty.HUnit (assertBool, assertEqual)
+
+import Data.SBV.Control
+import Data.SBV.Internals (compileToC', compileToCLib', renderCgPgmBundle)
+import Data.SBV.Tools.CodeGen
+import qualified Data.SBV.List as SL
+import qualified Data.SBV.RegExp as R
+import Utils.SBVTestFramework
+
+-- | Full-operator matching, language comparisons, scope integration, and
+-- generation budgets, including absence of overhead for non-regex code.
+tests :: TestTree
+tests = testGroup "CodeGeneration.RegExp"
+  [ testCase "regex membership agrees with Z3 and literal folding" membershipAgreement
+  , testCase "regex language equality and inequality" languageAgreement
+  , testCase "regex definitions and escaping array lambdas in a library" regexLibrary
+  , testCase "regex generation limits fail before writing" regexLimits
+  , testCase "default regex budgets accommodate ordinary bounded repetitions" calibratedRegexLimits
+  , testCase "regex limits apply to comparisons, definitions, and library components" regexLimitScopes
+  , testCase "regex character matching and dynamic tables" regexCharacterTable
+  , testCase "regex state limits do not bound input length" longRegexInput
+  , testCase "non-regex and dead-regex code require no regex support" noRegexOverhead
+  ]
+
+-- | Shared syntax and balanced-map lookup must not be charged as repeated
+-- whole-tree copies and linear scans of the entire state set.
+calibratedRegexLimits :: Assertion
+calibratedRegexLimits = do
+  mapM_ generate [R.Loop 0 30 "a", R.Power 510 "a"]
+  result <- try (generate (R.Power 1023 "a")) :: IO (Either ErrorCall ())
+  case result of
+    Left err -> assertBool (displayException err) ("state limit (1024)" `isInfixOf` displayException err)
+    Right () -> assertFailure "Expected the default state cap to reject 1025 states"
+ where generate regex = do
+         (_, _, bundle) <- compileToC' "calibratedRegex" $ do
+           cgGenerateDriver False
+           input <- cgInput "input" :: SBVCodeGen SString
+           cgReturn (input `R.match` regex)
+         void $ evaluate (length (show bundle))
+         assertBool "Default-sized automata use compact transition entries"
+           (any (\line -> "static const uint16_t sbv_regex_" `isInfixOf` line && "_step" `isInfixOf` line) (lines (show bundle)))
+
+-- | Ordinary and Boolean operators, empty languages/concatenations, and
+-- nullable repetitions; include boundaries of every supported encoding width.
+regexes :: [R.RegExp]
+regexes = nub $ atoms
+            ++ [op r | op <- [R.Comp, R.KStar, R.KPlus, R.Opt, R.Loop 0 2, R.Power 2], r <- atoms]
+            ++ [op a b | op <- [R.Inter, R.Diff, \a b -> R.Union [a, b], \a b -> R.Conc [a, b]], a <- atoms, b <- atoms]
+            ++ [ R.Conc [R.Inter "a" "ab", R.All]
+               , R.Conc [R.Diff "ab" "a", R.Opt "b"]
+               , R.Conc [R.Comp "a", "b"]
+               , R.KStar (R.Inter (R.Opt "a") (R.Comp "b"))
+               , R.KStar (R.Comp "a")
+               , R.Loop 2 3 (R.Opt "a")
+               , R.Conc [R.All, "b"]
+               , R.Range '\0' '\x2ffff'
+               , R.Range '\xd800' '\xdfff'
+               , R.Range '\x7f' '\x800'
+               , R.Literal "\0\955\xd800\x2ffff"
+               ]
+ where atoms = [R.All, R.AllChar, R.None, R.Conc [], "a", "ab", R.Range 'a' 'b', R.Range 'b' 'a']
+
+-- | Query a genuinely symbolic string for each sample, then feed the same
+-- code points to compiled C. Literal folding is checked as a third evaluator.
+membershipAgreement :: Assertion
+membershipAgreement = withSystemTempDirectory "sbv-c-regex-agreement" $ \dir -> do
+  expected <- runSMT $ do
+    input <- sString "input"
+    query $ forM samples $ \sample -> inNewAssertionStack $ do
+      constrain (input .== literal sample)
+      status <- checkSat
+      case status of
+        Sat -> getValue (SL.implode [input `R.match` r | r <- regexes])
+        _   -> error $ "Unexpected regex reference status: " ++ show status
+  forM_ (zip samples expected) $ \(sample, values) ->
+    assertEqual ("Literal regex agreement: " ++ show sample) (map Just values)
+                [unliteral (literal sample `R.match` r) | r <- regexes]
+  let program = do
+        cgOverwriteFiles True
+        cgGenerateDriver False
+        cgAddDecl (membershipHarness "regexMembership" samples (length regexes))
+        input <- cgInput "input" :: SBVCodeGen SString
+        cgOutputArr "matches" [input `R.match` r | r <- regexes]
+  (_, cfg, bundle) <- compileToC' "regexMembership" program
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  actual <- runC dir ["regexMembership"]
+  assertEqual "C automata agree with Z3 for every regex/sample" (map (map bitChar) expected) (lines actual)
+ where samples = nub $ concatMap (`replicateM` "ab") [0 .. 3]
+                    ++ ["\0", "\955", "\x7f", "\x80", "\x7ff", "\x800", "\xd800", "\xdfff", "\xffff", "\x10000", "\x2ffff"
+                       , "\0\955\xd800\x2ffff", "\955b", "a\0"]
+       bitChar True  = '1'
+       bitChar False = '0'
+
+-- | Build strings from numeric code points instead of relying on C source
+-- encoding or NUL termination. Every sample shares one generated matcher.
+membershipHarness :: String -> [String] -> Int -> [String]
+membershipHarness function samples count =
+  [ "int main(void) {"
+  , "  uint8_t bytes[" ++ show (max 1 (4 * maximum (map length samples))) ++ "];"
+  , "  SBool matches[" ++ show count ++ "];"
+  ] ++ concatMap sampleBlock samples ++ ["  return 0;", "}"]
+ where sampleBlock sample =
+         [ "  {"
+         , "    const SChar points[] = {" ++ intercalate ", " (map (show . ord) sample ++ ["0"]) ++ "};"
+         , "    size_t size = 0;"
+         , "    for (size_t i = 1; i < sizeof(points) / sizeof(points[0]); ++i) size += sbv_char_encode(points[i - 1], bytes + size);"
+         , "    " ++ function ++ "(sbv_string_borrow(bytes, size, sizeof(points) / sizeof(points[0]) - 1), matches);"
+         , "    for (size_t i = 0; i < " ++ show count ++ "; ++i) putchar(matches[i] ? '1' : '0');"
+         , "    putchar('\\n');"
+         , "  }"
+         ]
+
+-- | Decide language equality at generation time, including equality expressed
+-- by structurally different regexes and languages distinguished only by epsilon.
+languageAgreement :: Assertion
+languageAgreement = withSystemTempDirectory "sbv-c-regex-languages" $ \dir -> do
+  expected <- runSMT $ query $ do
+    status <- checkSat
+    case status of
+      Sat -> mapM (\(a, b) -> getValue (a .== b)) pairs
+      _   -> error $ "Unexpected regex reference status: " ++ show status
+  let program = do
+        cgOverwriteFiles True
+        cgGenerateDriver False
+        cgAddDecl ["int main(void) { SBool values[" ++ show (2 * length pairs) ++ "]; regexLanguages(values);"
+                  , "for (size_t i = 0; i < " ++ show (2 * length pairs) ++ "; ++i) putchar(values[i] ? '1' : '0'); return 0; }"]
+        cgOutputArr "values" (concat [[a .== b, a ./= b] | (a, b) <- pairs])
+  (_, cfg, bundle) <- compileToC' "regexLanguages" program
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  actual <- runC dir ["regexLanguages"]
+  assertEqual "Exact language comparisons" (concatMap (\equal -> if equal then "10" else "01") expected) actual
+  source <- readFile (dir </> "regexLanguages.c")
+  assertBool "Language comparisons need no runtime regex tables" (not ("sbv_regex_" `isInfixOf` source))
+ where pairs = [ (R.Conc [], "")
+               , (R.Union [], R.None)
+               , (R.Comp R.None, R.All)
+               , (R.Inter (R.Comp "a") (R.Comp "b"), R.Comp (R.Union ["a", "b"]))
+               , (R.Diff R.All "a", R.Comp "a")
+               , (R.KPlus "a", R.Conc ["a", R.KStar "a"])
+               , (R.KStar (R.Opt "a"), R.KStar "a")
+               , (R.Loop 0 0 "a", R.Conc [])
+               , (R.Range '\0' '\x2ffff', R.AllChar)
+               , (R.All, R.AllChar)
+               , (R.KStar "a", R.KPlus "a")
+               , (R.Power 3 "a", R.Loop 2 3 "a")
+               , (R.Range 'a' 'b', R.Range 'a' 'c')
+               ]
+
+-- | Library components may use independent budgets, and regex tables remain
+-- private even when definitions and escaping closed lambdas reuse node IDs.
+regexLibrary :: Assertion
+regexLibrary = withSystemTempDirectory "sbv-c-regex-library" $ \dir -> do
+  let matcher = smtFunction "regex in a defined function" (\value -> value `R.match` R.Conc [R.All, "b"])
+      component = do
+        cgOverwriteFiles True
+        cgGenerateDriver False
+        let array = lambdaArray matcher :: SArray String Bool
+        cgReturn array
+      direct = do
+        cgOverwriteFiles True
+        cgGenerateDriver False
+        input <- cgInput "input" :: SBVCodeGen SString
+        cgReturn (matcher input)
+      plain = do
+        cgOverwriteFiles True
+        cgGenerateDriver False
+        cgRegexLimits 0 0 0
+        cgAddDecl ["int main(void) {"
+                  , "  SBVArrayOutput_6_string_2_u1 array = regexClosure();"
+                  , "  const SString ab = sbv_string_borrow_utf8(\"ab\"), a = sbv_string_borrow_utf8(\"a\");"
+                  , "  const int ok = array.lookup(array.context, ab) && !array.lookup(array.context, a) && regexDirect(ab) && !regexDirect(a) && plainComponent();"
+                  , "  sbv_array_output_release_6_string_2_u1(&array);"
+                  , "  return ok ? 0 : 1;"
+                  , "}"]
+        cgReturn sTrue
+  (_, cfg, bundle) <- compileToCLib' "regexLibrary" [("regexClosure", component), ("regexDirect", direct), ("plainComponent", plain)]
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  void $ runC dir ["regexClosure", "regexDirect", "plainComponent"]
+  source <- readFile (dir </> "plainComponent.c")
+  assertBool "Non-regex library component has no regex implementation" (not ("sbv_regex_" `isInfixOf` source))
+
+-- | Exercise each independent budget and verify rejection precedes file
+-- creation. Large repetition counts must fail without expanding them first.
+regexLimits :: Assertion
+regexLimits = do
+  rejects "state" (cgRegexLimits 2 100 10000) "a"
+  rejects "expression-node" (cgRegexLimits 100 4 10000) "abcdef"
+  rejects "work" (cgRegexLimits 100 100 1) "a"
+  rejects "disabled" (cgRegexLimits 0 100 10000) "a"
+  rejects "expression-node" (pure ()) (R.Power maxBound "a")
+  rejects "expression-node" (pure ()) (R.Loop 0 maxBound "a")
+  rejects "state" (cgRegexLimits 8 4096 1000000) (R.Conc [R.All, "a", R.Power 8 R.AllChar])
+  withSystemTempDirectory "sbv-c-regex-raised-limit" $ \dir -> do
+    (_, cfg, bundle) <- compileToC' "raisedRegex" $ do
+      cgRegexLimits 3 100 10000
+      cgOverwriteFiles True
+      cgGenerateDriver False
+      cgAddDecl ["int main(void) { return raisedRegex(sbv_string_borrow_utf8(\"a\")) ? 0 : 1; }"]
+      input <- cgInput "input" :: SBVCodeGen SString
+      cgReturn (input `R.match` R.Literal "a")
+    renderCgPgmBundle (Just dir) (cfg, bundle)
+    void $ runC dir ["raisedRegex"]
+ where rejects :: String -> SBVCodeGen () -> R.RegExp -> Assertion
+       rejects diagnostic limits regex = withSystemTempDirectory "sbv-c-regex-limit" $ \dir -> do
+         result <- try (compileToC (Just dir) "limitedRegex" $ do
+                     limits
+                     input <- cgInput "input" :: SBVCodeGen SString
+                     cgReturn (input `R.match` regex)) :: IO (Either ErrorCall ())
+         case result of
+           Left err -> assertBool (displayException err) (diagnostic `isInfixOf` displayException err && "cgRegexLimits" `isInfixOf` displayException err)
+           Right () -> assertFailure "Expected regex budget rejection"
+         assertEqual "Rejected regex must not create files" [] =<< listDirectory dir
+
+-- | Successful bounded generation accepts strings far longer than any budget
+-- dimension. The runtime matcher uses neither recursion nor heap allocation.
+longRegexInput :: Assertion
+longRegexInput = withSystemTempDirectory "sbv-c-regex-long-input" $ \dir -> do
+  (_, cfg, bundle) <- compileToC' "longRegex" $ do
+    cgRegexLimits 2 16 1000
+    cgOverwriteFiles True
+    cgGenerateDriver False
+    cgAddDecl ["int main(void) { uint8_t bytes[100000]; memset(bytes, 'a', sizeof bytes);"
+              , "return longRegex(sbv_string_borrow(bytes, sizeof bytes, sizeof bytes)) ? 0 : 1; }"]
+    input <- cgInput "input" :: SBVCodeGen SString
+    cgReturn (input `R.match` R.KStar "a")
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  void $ runC dir ["longRegex"]
+
+-- | Apply budgets to every lowering scope, not just entry-point membership.
+-- Library preflight must not leave files from an earlier successful component.
+regexLimitScopes :: Assertion
+regexLimitScopes = do
+  forM_ [(-1, 100, 10000), (100, -1, 10000), (100, 100, -1)] $ \(states, nodes, work) ->
+    rejects "nonnegative" (cgRegexLimits states nodes work >> cgReturn sTrue)
+  rejects "state" $ do
+    cgRegexLimits 2 100 10000
+    cgReturn (R.Literal "a" .== R.Literal "a")
+  rejects "state" $ do
+    cgRegexLimits 2 100 10000
+    input <- cgInput "input" :: SBVCodeGen SString
+    cgReturn (smtFunction "limited regex definition" (\s -> s `R.match` R.Literal "a") input)
+  rejects "state" $ do
+    cgRegexLimits 2 100 10000
+    cgReturn (lambdaArray (\s -> s `R.match` R.Literal "a") :: SArray String Bool)
+  rejects "domain" $ do
+    input <- cgInput "input" :: SBVCodeGen SString
+    cgReturn (input `R.match` R.Literal "\x30000")
+  withSystemTempDirectory "sbv-c-regex-library-limit" $ \dir -> do
+    let plain = cgGenerateDriver False >> cgRegexLimits 0 0 0 >> cgReturn sTrue
+        limited = do cgGenerateDriver False
+                     cgRegexLimits 2 100 10000
+                     input <- cgInput "input" :: SBVCodeGen SString
+                     cgReturn (input `R.match` R.Literal "a")
+    result <- try (compileToCLib (Just dir) "limitedLibrary" [("plain", plain), ("limited", limited)]) :: IO (Either ErrorCall [()])
+    case result of
+      Left err -> assertBool (displayException err) ("state" `isInfixOf` displayException err)
+      Right _  -> assertFailure "Expected library regex budget rejection"
+    assertEqual "Library budget failure must not write any component" [] =<< listDirectory dir
+ where rejects :: String -> SBVCodeGen () -> Assertion
+       rejects diagnostic program = withSystemTempDirectory "sbv-c-regex-scoped-limit" $ \dir -> do
+         result <- try (compileToC (Just dir) "scopedLimit" program) :: IO (Either ErrorCall ())
+         case result of
+           Left err -> assertBool (displayException err) (diagnostic `isInfixOf` displayException err)
+           Right () -> assertFailure "Expected scoped regex budget rejection"
+         assertEqual "Scoped budget failure must not write files" [] =<< listDirectory dir
+
+-- | Character membership uses the existing singleton-string lowering. Regex
+-- computations in a dynamic lookup table keep their function-local tables and
+-- setup statements correctly scoped under demand-driven selection.
+regexCharacterTable :: Assertion
+regexCharacterTable = withSystemTempDirectory "sbv-c-regex-character-table" $ \dir -> do
+  (_, cfg, bundle) <- compileToC' "regexCharacterTable" $ do
+    cgOverwriteFiles True
+    cgGenerateDriver False
+    cgPerformRTCs True
+    cgAddDecl ["int main(void) {"
+              , "  return regexCharacterTable(0xd800, 0) && !regexCharacterTable('a', 0)"
+              , "      && regexCharacterTable('a', 1) && !regexCharacterTable('b', 1)"
+              , "      && regexCharacterTable('b', 2) && !regexCharacterTable('a', 2)"
+              , "      && !regexCharacterTable('a', 255) ? 0 : 1;"
+              , "}"]
+    input <- cgInput "input" :: SBVCodeGen SChar
+    index <- cgInput "index" :: SBVCodeGen SWord8
+    cgReturn $ select [input `R.match` r | r <- [R.Range '\xd800' '\xdfff', "a", R.Comp "a"]] sFalse index
+  renderCgPgmBundle (Just dir) (cfg, bundle)
+  void $ runC dir ["regexCharacterTable"]
+
+-- | Disabled regex compilation leaves non-regex generation unchanged and
+-- never examines a dead regex operation, including when regex compilation is disabled.
+noRegexOverhead :: Assertion
+noRegexOverhead = do
+  baseline <- generated (pure ()) False
+  disabled <- generated (cgRegexLimits 0 0 0) False
+  assertEqual "Regex budgets do not alter non-regex C" baseline disabled
+  dead <- generated (cgRegexLimits 0 0 0) True
+  assertBool "Dead regex has no runtime code" (not ("sbv_regex_" `isInfixOf` dead))
+ where generated :: SBVCodeGen () -> Bool -> IO String
+       generated limits useDead = do
+         (_, _, bundle) <- compileToC' "noRegex" $ do
+           limits
+           cgGenerateDriver False
+           cgSetDriverValues [1]
+           input <- cgInput "input" :: SBVCodeGen SBool
+           if useDead
+             then do string <- cgInput "string" :: SBVCodeGen SString
+                     cgReturn (ite sTrue input (string `R.match` R.Power 100 "a"))
+             else cgReturn input
+         let source = show bundle
+         void $ evaluate (length source)
+         pure source
+
+-- | Compile generated translation units with strict C warnings and optional
+-- sanitizer flags. Regex support must need no nonstandard library or header.
+runC :: FilePath -> [String] -> IO String
+runC dir components = do
+  flags <- maybe [] words <$> lookupEnv "SBV_C_TEST_FLAGS"
+  let executablePath = dir </> "regex-test"
+  (status, _, errors) <- readProcessWithExitCode "cc" (["-std=c11", "-Wall", "-Wextra", "-Werror", "-O2"] ++ flags
+                                                 ++ [dir </> component ++ ".c" | component <- components]
+                                                 ++ ["-o", executablePath]) ""
+  assertEqual errors ExitSuccess status
+  (runStatus, outputText, runError) <- readProcessWithExitCode executablePath [] ""
+  assertEqual runError ExitSuccess runStatus
+  pure outputText
diff --git a/SBVTestSuite/TestSuite/CodeGeneration/ScalarSafety.hs b/SBVTestSuite/TestSuite/CodeGeneration/ScalarSafety.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CodeGeneration/ScalarSafety.hs
@@ -0,0 +1,215 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : TestSuite.CodeGeneration.ScalarSafety
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Executed regressions for diagnostic escaping, mapped real flooring, and
+-- incremental C builds.
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module TestSuite.CodeGeneration.ScalarSafety (tests, testsWith) where
+
+import Control.Monad (void)
+import Data.List (isInfixOf)
+import System.Environment (lookupEnv)
+import System.Exit (ExitCode(..))
+import System.FilePath ((</>))
+import System.IO.Temp (withSystemTempDirectory)
+import System.Process (readProcessWithExitCode)
+import Test.Tasty.HUnit (assertBool, assertEqual)
+
+import Data.SBV.Tools.CodeGen
+import qualified Data.SBV.Tools.CodeGen.Legacy as Legacy
+import Utils.SBVTestFramework
+
+-- | Generate a standalone function or a single-component static library.
+type Generator = FilePath -> Bool -> SBVCodeGen () -> IO ()
+
+-- | Exercise both public backends with the same scalar safety matrix.
+tests :: TestTree
+tests = testGroup "CodeGeneration.ScalarSafety"
+  [ testsWith "current" $ \dir library program ->
+      if library
+         then void $ compileToCLib (Just dir) "scalarLibrary" [("scalarChecks", program)]
+         else compileToC (Just dir) "scalarChecks" program
+  , testsWith "legacy" $ \dir library program ->
+      if library
+         then void $ Legacy.compileToCLib (Just dir) "scalarLibrary" [("scalarChecks", program)]
+         else Legacy.compileToC (Just dir) "scalarChecks" program
+  ]
+
+-- | Reuse the same strict-warning, optimization, and sanitizer matrix for a
+-- compatibility backend. Independent C callers supply fractional inputs and
+-- check against mathematical integer results rather than C casts.
+testsWith :: String -> Generator -> TestTree
+testsWith groupName generate = testGroup groupName $
+  [ testGroup (form ++ "/" ++ optimization)
+      [ testGroup "floor"
+          [ testCase (show realType ++ "/" ++ show width) $ withSystemTempDirectory "sbv-c-real-floor" $ \dir -> do
+              executablePath <- compileCaller generate dir library optimization (floorCaller realType width) $ do
+                cgSRealType realType
+                cgIntegerSize width
+                value <- cgInput "value" :: SBVCodeGen SReal
+                cgReturn (sRealToSIntegerFloor value)
+              makefile <- readFile (dir </> "Makefile")
+              assertBool "Flooring must link the standard math library" ("-lm" `isInfixOf` makefile)
+              runSuccessfully executablePath
+              mapM_ (checkNonFinite executablePath) ["nan", "inf", "negative-inf"]
+          | realType <- [CgFloat, CgDouble, CgLongDouble]
+          , width <- [8, 16, 32, 64]
+          ]
+      , testGroup "labels"
+          [ testCase sampleName $ withSystemTempDirectory "sbv-c-scalar-label" $ \dir -> do
+              executablePath <- compileCaller generate dir library optimization labelCaller $ do
+                value <- cgInput "value" :: SBVCodeGen SWord8
+                cgReturn (label message value)
+              runSuccessfully executablePath
+          | (sampleName, message) <- labelSamples
+          ]
+      , testCase "assertion message" $ withSystemTempDirectory "sbv-c-assertion-text" $ \dir -> do
+          let message = "must be \"small\"; %n %s 100% */\n/* \\\n??/ \955"
+          executablePath <- compileCaller generate dir library optimization labelCaller $ do
+            value <- cgInput "value" :: SBVCodeGen SWord8
+            cgReturn (sAssert Nothing message (value .< 5) value)
+          (runExit, _, runError) <- readProcessWithExitCode executablePath [] ""
+          assertBool "The failed assertion must terminate the caller" (runExit /= ExitSuccess)
+          assertBool runError (("ASSERTION FAILED: " ++ message) `isInfixOf` runError)
+      ]
+  | (form, library) <- [("program", False), ("library", True)]
+  , optimization <- ["-O0", "-O2 -fsanitize=undefined,float-cast-overflow -fno-sanitize-recover=all"]
+  ]
+  ++ [testCase "driver header dependency" (driverHeaderDependency generate)]
+
+-- | Header changes must invalidate the separately compiled standalone driver.
+-- Make's hypothetical-newer prerequisite avoids sleeps and timestamp races.
+driverHeaderDependency :: Generator -> Assertion
+driverHeaderDependency generate = withSystemTempDirectory "sbv-c-driver-header" $ \dir -> do
+  generate dir False $ do
+    cgOverwriteFiles True
+    cgSetDriverValues [41]
+    value <- cgInput "value" :: SBVCodeGen SWord8
+    cgReturn value
+  extraFlags <- maybe "" (" " ++) <$> lookupEnv "SBV_C_TEST_FLAGS"
+  let target = "scalarChecks_driver.o"
+  (makeExit, _, makeError) <- readProcessWithExitCode "make"
+    ["-C", dir, target, "CCFLAGS=-std=c11 -Wall -Wextra -Werror -O2" ++ extraFlags] ""
+  assertEqual makeError ExitSuccess makeExit
+  (freshExit, _, freshError) <- readProcessWithExitCode "make" ["-C", dir, "-q", target] ""
+  assertEqual freshError ExitSuccess freshExit
+  (staleExit, _, staleError) <- readProcessWithExitCode "make" ["-C", dir, "-q", "-W", "scalarChecks.h", target] ""
+  assertEqual ("Changing the header must invalidate the driver object: " ++ staleError) (ExitFailure 1) staleExit
+
+-- | Text must remain a semantic no-op even when it resembles C statements or
+-- affects preprocessing. Embedded NUL/control bytes must also compile cleanly.
+labelSamples :: [(String, String)]
+labelSamples = [ ("statements", "*/; abort(); /*")
+               , ("preprocessing", "nested /* comment; \\\n??/\n*/")
+               , ("control characters", "Unicode \955, NUL \0, CR \r, tab \t and control \SOH")
+               ]
+
+-- | Generate and build the selected artifact, then link an independent caller.
+-- Additional local sanitizer flags apply to both the generated C and caller.
+compileCaller :: Generator -> FilePath -> Bool -> String -> String -> SBVCodeGen () -> IO FilePath
+compileCaller generate dir library optimization source program = do
+  generate dir library $ do
+    cgOverwriteFiles True
+    cgGenerateDriver False
+    program
+  extraFlags <- maybe [] words <$> lookupEnv "SBV_C_TEST_FLAGS"
+  let flags = ["-std=c11", "-Wall", "-Wextra", "-Werror", "-trigraphs"] ++ words optimization ++ extraFlags
+      artifact = if library then "scalarLibrary.a" else "scalarChecks.o"
+      header   = if library then "scalarLibrary.h" else "scalarChecks.h"
+      executablePath = dir </> "caller"
+  (makeExit, _, makeError) <- readProcessWithExitCode "make" ["-C", dir, artifact, "CCFLAGS=" ++ unwords flags] ""
+  assertEqual makeError ExitSuccess makeExit
+  writeFile (dir </> "caller.c") ("#include \"" ++ header ++ "\"\n" ++ source)
+  (ccExit, _, ccError) <- readProcessWithExitCode "cc" (flags ++ [dir </> "caller.c", dir </> artifact, "-lm", "-o", executablePath]) ""
+  assertEqual ccError ExitSuccess ccExit
+  pure executablePath
+
+-- | Require successful execution, reporting captured diagnostics on failure.
+runSuccessfully :: FilePath -> Assertion
+runSuccessfully executablePath = do
+  (runExit, _, runError) <- readProcessWithExitCode executablePath [] ""
+  assertEqual runError ExitSuccess runExit
+
+-- | Non-finite mapped real inputs must fail explicitly before an integer cast.
+checkNonFinite :: FilePath -> String -> Assertion
+checkNonFinite executablePath sample = do
+  (runExit, _, runError) <- readProcessWithExitCode executablePath [sample] ""
+  assertBool "Non-finite real flooring must terminate the caller" (runExit /= ExitSuccess)
+  assertBool runError ("Cannot floor a non-finite mapped SReal" `isInfixOf` runError)
+  assertBool runError (not ("runtime error:" `isInfixOf` runError))
+
+-- | A successful label is observationally identical to its scalar argument.
+labelCaller :: String
+labelCaller = unlines ["#include <assert.h>", "int main(void) { assert(scalarChecks(7) == 7); return 0; }"]
+
+-- | Supply exact binary fractions, signed boundaries, large finite values,
+-- and subnormals. Precision-dependent boundary cases run only when the actual
+-- C real representation can distinguish the adjacent integers.
+floorCaller :: CgSRealType -> Int -> String
+floorCaller realType width = unlines $
+  [ "#include <assert.h>"
+  , "#include <float.h>"
+  , "#define REAL_MANT_DIG " ++ floatMacro "MANT_DIG"
+  , "int main(int argc, char **argv)"
+  , "{"
+  , "  if (argc > 1) {"
+  , "    SReal value = argv[1][0] == 'n' ? (argv[1][1] == 'a' ? (SReal) NAN : (SReal) -INFINITY) : (SReal) INFINITY;"
+  , "    (void) scalarChecks(value); return 0;"
+  , "  }"
+  ]
+  ++ [check input (floor value) | (input, value) <- samples]
+  ++ [ "#if REAL_MANT_DIG >= 32"
+     , check "0x7fffffffp0L" (2 ^ (31 :: Int) - 1)
+     , "#endif"
+     , "#if REAL_MANT_DIG >= 64"
+     , check "0xffffffffffffffffp0L" (2 ^ (64 :: Int) - 1)
+     , check "-0x8000000000000001p0L" (negate (2 ^ (63 :: Int) + 1))
+     , "#endif"
+     , check (floatMacro "TRUE_MIN") 0
+     , check ("-" ++ floatMacro "TRUE_MIN") (-1)
+     , "#if " ++ floatMacro "MAX_EXP" ++ " - REAL_MANT_DIG >= 64"
+     , check (floatMacro "MAX") 0
+     , check ("-" ++ floatMacro "MAX") 0
+     , "#endif"
+     , "  return 0;"
+     , "}"
+     ]
+ where floatMacro suffix = case realType of
+                             CgFloat      -> "FLT_"  ++ suffix
+                             CgDouble     -> "DBL_"  ++ suffix
+                             CgLongDouble -> "LDBL_" ++ suffix
+
+       check :: String -> Integer -> String
+       check input expected = "  assert(scalarChecks((SReal) (" ++ input ++ ")) == (SInteger) " ++ signedLiteral (wrap expected) ++ ");"
+       wrap value = let modulus = 2 ^ width
+                        bits    = value `mod` modulus
+                    in if bits >= modulus `div` 2 then bits - modulus else bits
+       signedLiteral value
+         | value == negate (2 ^ (63 :: Int)) = "(-INT64_C(9223372036854775807) - INT64_C(1))"
+         | True                             = "INT64_C(" ++ show value ++ ")"
+
+-- | Values exactly representable even by binary32. Integer expectations use
+-- arbitrary-precision Haskell arithmetic, independently of the C helper.
+samples :: [(String, Rational)]
+samples = [ ("0.0L", 0), ("-0.0L", 0)
+          , ("2.5L", 5 % 2), ("-2.5L", -(5 % 2))
+          , ("0.5L", 1 % 2), ("-0.5L", -(1 % 2))
+          , ("127.75L", 511 % 4), ("-128.25L", -(513 % 4))
+          , ("255.75L", 1023 % 4), ("-256.25L", -(1025 % 4))
+          , ("65535.75L", 262143 % 4), ("-65536.25L", -(262145 % 4))
+          , ("0x1p31L", 2 ^ (31 :: Int)), ("-0x1p31L", negate (2 ^ (31 :: Int)))
+          , ("0x1p63L", 2 ^ (63 :: Int)), ("-0x1p63L", negate (2 ^ (63 :: Int)))
+          , ("0x1p64L", 2 ^ (64 :: Int)), ("-0x1p64L", negate (2 ^ (64 :: Int)))
+          , ("0x1p100L", 2 ^ (100 :: Int)), ("-0x1p100L", negate (2 ^ (100 :: Int)))
+          , ("(0x1p63L + 0x1p40L)", 2 ^ (63 :: Int) + 2 ^ (40 :: Int))
+          , ("(0x1p64L - 0x1p40L)", 2 ^ (64 :: Int) - 2 ^ (40 :: Int))
+          , ("(0x1p40L + 0x1p20L)", 2 ^ (40 :: Int) + 2 ^ (20 :: Int))
+          ]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase.hs b/SBVTestSuite/TestSuite/CompileTests/PCase.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase.hs
@@ -0,0 +1,19 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : TestSuite.CompileTests.PCase
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Testing TH messages
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module TestSuite.CompileTests.PCase(tests) where
+
+import Utils.SBVTestFramework
+
+tests :: IO TestTree
+tests = testGroup "THTests.PCase" <$> mkCompileTestGlob "SBVTestSuite/TestSuite/CompileTests/PCase/PCase*.hs"
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/Expr.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/Expr.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/Expr.hs
@@ -0,0 +1,18 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE TypeApplications  #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Expr where
+
+import Data.SBV
+
+data Expr = Zero
+          | Num Integer
+          | Var String
+          | Add Expr Expr
+          | Let String Expr Expr
+          deriving Show
+
+mkSymbolic [''Expr]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase01.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase01.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase01.hs
@@ -0,0 +1,13 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Parse error: EOF
+t :: SExpr -> Proof SBool
+t _e = [pCase| _e of|]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase01.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase01.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase01.stderr
@@ -0,0 +1,8 @@
+PCase01.hs:13:15: error: [GHC-39584]
+    " PCase01.hs:13:21: Parse error: EOF
+
+    " In the quasi-quotation: [pCase| _e of|]
+   |
+13 | t _e = [pCase| _e of|]
+   |               ^^^^^^^^
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase02.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase02.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase02.hs
@@ -0,0 +1,13 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Bad syntax
+t :: SExpr -> Proof SBool
+t e = [pCase| e + 1|]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase02.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase02.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase02.stderr
@@ -0,0 +1,8 @@
+PCase02.hs:13:14: error: [GHC-39584]
+    " PCase02.hs:13:20: Parse error: EOF
+
+    " In the quasi-quotation: [pCase| e + 1|]
+   |
+13 | t e = [pCase| e + 1|]
+   |              ^^^^^^^^
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase03.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase03.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase03.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Not usable in declaration context
+[pCase| e of
+        Zero  -> undefined
+        Num _ -> undefined
+      |]
+
+{- HLint ignore module "Unused LANGUAGE pragma" -}
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase03.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase03.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase03.stderr
@@ -0,0 +1,6 @@
+PCase03.hs:12:8: error: [GHC-39584]
+    pCase: not usable in declaration context
+   |
+12 | [pCase| e of
+   |        ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase04.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase04.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase04.hs
@@ -0,0 +1,15 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Unknown constructor
+t :: SExpr -> Proof SBool
+t e = [pCase| e of
+        FooBar _ -> undefined
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase04.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase04.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase04.stderr
@@ -0,0 +1,14 @@
+PCase04.hs:13:14: error: [GHC-39584]
+    " pCase: Unknown constructor: FooBar
+
+        Cannot find this constructor in scope.
+        Make sure the type is declared and mkSymbolic is called.
+
+    " In the quasi-quotation:
+        [pCase| e of
+        FooBar _ -> undefined
+      |]
+   |
+13 | t e = [pCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase05.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase05.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase05.hs
@@ -0,0 +1,16 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Unknown constructor
+t :: SExpr -> Proof SBool
+t e = [pCase| e of
+        Zero  -> undefined
+        Numb _ -> undefined
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase05.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase05.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase05.stderr
@@ -0,0 +1,11 @@
+PCase05.hs:13:14: error: [GHC-39584]
+    " PCase05.hs:15:9-14: sCase/pCase: Not in scope: data constructor: Numb
+    " In the quasi-quotation:
+        [pCase| e of
+        Zero  -> undefined
+        Numb _ -> undefined
+      |]
+   |
+13 | t e = [pCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase06.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase06.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase06.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Pattern guards not supported
+t :: SExpr -> Proof SBool
+t e = [pCase| e of
+        Zero        -> undefined
+        Num i | Just 1 <- Just i -> undefined
+        Var _       -> undefined
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase06.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase06.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase06.stderr
@@ -0,0 +1,14 @@
+PCase06.hs:13:14: error: [GHC-39584]
+    " sCase/pCase: Pattern guards are not supported: 
+        Just 1 <- Just i
+
+    " In the quasi-quotation:
+        [pCase| e of
+        Zero        -> undefined
+        Num i | Just 1 <- Just i -> undefined
+        Var _       -> undefined
+      |]
+   |
+13 | t e = [pCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase07.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase07.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase07.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Arity mismatch: Num takes 1 arg, given 2
+t :: SExpr -> Proof SBool
+t e = [pCase| e of
+        Zero     -> undefined
+        Num _ _  -> undefined
+        Var _    -> undefined
+        Add _ _  -> undefined
+        Let _ _ _ -> undefined
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase07.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase07.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase07.stderr
@@ -0,0 +1,19 @@
+PCase07.hs:13:14: error: [GHC-39584]
+    " PCase07.hs:15:9-15: pCase: Arity mismatch.
+        Type       : Expr
+        Constructor: Num
+        Expected   : 1
+        Given      : 2
+
+    " In the quasi-quotation:
+        [pCase| e of
+        Zero     -> undefined
+        Num _ _  -> undefined
+        Var _    -> undefined
+        Add _ _  -> undefined
+        Let _ _ _ -> undefined
+      |]
+   |
+13 | t e = [pCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase08.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase08.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase08.hs
@@ -0,0 +1,22 @@
+{-# LANGUAGE QuasiQuotes       #-}
+{-# LANGUAGE DataKinds         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions  #-}
+{-# LANGUAGE TypeApplications  #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: wildcard at the end catches remaining constructors
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero    -> e .== e =: qed
+         Num _   -> e .== e =: qed
+         _       -> e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase08.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase08.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase08.stderr
@@ -0,0 +1,12 @@
+PCase08.hs:(18,15)-(22,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero    -> e .== e =: qed\n\
+      \         Num _   -> e .== e =: qed\n\
+      \         _       -> e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)), (isNum e ==> (e .== e =: qed)),
+       (sNot ((.||) (isZero e) (isNum e)) ==> (e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase09.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase09.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase09.hs
@@ -0,0 +1,18 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Overlapping constructors: unguarded Num after guarded Num
+t :: SExpr -> Proof SBool
+t e = [pCase| e of
+        Zero         -> undefined
+        Num i        -> undefined
+        Num i | i .> 3 -> undefined
+        Var _        -> undefined
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase09.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase09.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase09.stderr
@@ -0,0 +1,17 @@
+PCase09.hs:13:14: error: [GHC-39584]
+    " PCase09.hs:16:9-13: pCase: Overlapping case constructors:
+        Constructor: Num i | i .> 3
+      Overlaps with:
+        PCase09.hs:15:9-13: Num i
+
+    " In the quasi-quotation:
+        [pCase| e of
+        Zero         -> undefined
+        Num i        -> undefined
+        Num i | i .> 3 -> undefined
+        Var _        -> undefined
+      |]
+   |
+13 | t e = [pCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase10.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase10.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase10.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Arity mismatch in nested pattern: Num takes 1, given 2
+t :: SExpr -> Proof SBool
+t e = [pCase| e of
+        Zero            -> undefined
+        Num k           -> undefined
+        Var _           -> undefined
+        Add (Num i j) b -> undefined
+        Let _ _ _       -> undefined
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase10.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase10.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase10.stderr
@@ -0,0 +1,18 @@
+PCase10.hs:13:14: error: [GHC-39584]
+    " PCase10.hs:17:9-23: sCase/pCase: Arity mismatch in nested pattern.
+        Constructor: Num
+        Expected   : 1
+        Given      : 2
+
+    " In the quasi-quotation:
+        [pCase| e of
+        Zero            -> undefined
+        Num k           -> undefined
+        Var _           -> undefined
+        Add (Num i j) b -> undefined
+        Let _ _ _       -> undefined
+      |]
+   |
+13 | t e = [pCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase11.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase11.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase11.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Unknown constructor in nested pattern
+t :: SExpr -> Proof SBool
+t e = [pCase| e of
+        Zero           -> undefined
+        Num k          -> undefined
+        Var _          -> undefined
+        Add (Numb i) b -> undefined
+        Let _ _ _      -> undefined
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase11.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase11.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase11.stderr
@@ -0,0 +1,14 @@
+PCase11.hs:13:14: error: [GHC-39584]
+    " PCase11.hs:17:9-22: sCase/pCase: Not in scope: data constructor: Numb
+    " In the quasi-quotation:
+        [pCase| e of
+        Zero           -> undefined
+        Num k          -> undefined
+        Var _          -> undefined
+        Add (Numb i) b -> undefined
+        Let _ _ _      -> undefined
+      |]
+   |
+13 | t e = [pCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase12.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase12.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase12.hs
@@ -0,0 +1,24 @@
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE DataKinds          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: all constructors covered, no guards; use matched fields in proof
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero      -> e .== e =: qed
+         Num i     -> sNum i .== sNum i =: e .== e =: qed
+         Var s     -> sVar s .== sVar s =: e .== e =: qed
+         Add a b   -> sAdd a b .== sAdd a b =: e .== e =: qed
+         Let nm a b -> sLet nm a b .== sLet nm a b =: e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase12.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase12.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase12.stderr
@@ -0,0 +1,30 @@
+PCase12.hs:(18,15)-(24,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero      -> e .== e =: qed\n\
+      \         Num i     -> sNum i .== sNum i =: e .== e =: qed\n\
+      \         Var s     -> sVar s .== sVar s =: e .== e =: qed\n\
+      \         Add a b   -> sAdd a b .== sAdd a b =: e .== e =: qed\n\
+      \         Let nm a b -> sLet nm a b .== sLet nm a b =: e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)),
+       (isNum e
+          ==> (let i = getNum_1 e in (sNum i) .== sNum i =: e .== e =: qed)),
+       (isVar e
+          ==> (let s = getVar_1 e in (sVar s) .== sVar s =: e .== e =: qed)),
+       (isAdd e
+          ==>
+            (let
+               a = getAdd_1 e
+               b = getAdd_2 e
+             in (sAdd a b) .== sAdd a b =: e .== e =: qed)),
+       (isLet e
+          ==>
+            (let
+               nm = getLet_1 e
+               a = getLet_2 e
+               b = getLet_3 e
+             in (sLet nm a b) .== sLet nm a b =: e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase13.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase13.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase13.hs
@@ -0,0 +1,21 @@
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE DataKinds          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: partial coverage is fine in pCase (no exhaustiveness check)
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero  -> e .== e =: qed
+         Num i -> sNum i .== sNum i =: e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase13.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase13.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase13.stderr
@@ -0,0 +1,12 @@
+PCase13.hs:(18,15)-(21,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero  -> e .== e =: qed\n\
+      \         Num i -> sNum i .== sNum i =: e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)),
+       (isNum e
+          ==> (let i = getNum_1 e in (sNum i) .== sNum i =: e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase14.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase14.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase14.hs
@@ -0,0 +1,24 @@
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE DataKinds          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: guard on one constructor; use matched field in proof
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero           -> e .== e =: qed
+         Num i | i .> 0 -> sNum i .== sNum i =: e .== e =: qed
+         Var s          -> sVar s .== sVar s =: e .== e =: qed
+         Add a b        -> sAdd a b .== sAdd a b =: e .== e =: qed
+         Let nm a b     -> sLet nm a b .== sLet nm a b =: e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase14.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase14.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase14.stderr
@@ -0,0 +1,30 @@
+PCase14.hs:(18,15)-(24,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero           -> e .== e =: qed\n\
+      \         Num i | i .> 0 -> sNum i .== sNum i =: e .== e =: qed\n\
+      \         Var s          -> sVar s .== sVar s =: e .== e =: qed\n\
+      \         Add a b        -> sAdd a b .== sAdd a b =: e .== e =: qed\n\
+      \         Let nm a b     -> sLet nm a b .== sLet nm a b =: e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)),
+       ((.&&) (isNum e) (let i = getNum_1 e in i .> 0)
+          ==> (let i = getNum_1 e in (sNum i) .== sNum i =: e .== e =: qed)),
+       (isVar e
+          ==> (let s = getVar_1 e in (sVar s) .== sVar s =: e .== e =: qed)),
+       (isAdd e
+          ==>
+            (let
+               a = getAdd_1 e
+               b = getAdd_2 e
+             in (sAdd a b) .== sAdd a b =: e .== e =: qed)),
+       (isLet e
+          ==>
+            (let
+               nm = getLet_1 e
+               a = getLet_2 e
+               b = getLet_3 e
+             in (sLet nm a b) .== sLet nm a b =: e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase15.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase15.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase15.hs
@@ -0,0 +1,26 @@
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE DataKinds          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: multi-arm same constructor with guards (guard accumulation)
+-- Second arm gets: isNum e .&& sNot (i .> 0)
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero             -> e .== e =: qed
+         Num i | i .> 0   -> sNum i .== sNum i =: e .== e =: qed
+               | sTrue    -> sNum i .== sNum i =: e .== e =: qed
+         Var s            -> sVar s .== sVar s =: e .== e =: qed
+         Add a b          -> sAdd a b .== sAdd a b =: e .== e =: qed
+         Let nm a b       -> sLet nm a b .== sLet nm a b =: e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase15.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase15.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase15.stderr
@@ -0,0 +1,33 @@
+PCase15.hs:(19,15)-(26,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero             -> e .== e =: qed\n\
+      \         Num i | i .> 0   -> sNum i .== sNum i =: e .== e =: qed\n\
+      \               | sTrue    -> sNum i .== sNum i =: e .== e =: qed\n\
+      \         Var s            -> sVar s .== sVar s =: e .== e =: qed\n\
+      \         Add a b          -> sAdd a b .== sAdd a b =: e .== e =: qed\n\
+      \         Let nm a b       -> sLet nm a b .== sLet nm a b =: e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)),
+       ((.&&) (isNum e) (let i = getNum_1 e in i .> 0)
+          ==> (let i = getNum_1 e in (sNum i) .== sNum i =: e .== e =: qed)),
+       ((.&&) (isNum e) (sNot (let i = getNum_1 e in i .> 0))
+          ==> (let i = getNum_1 e in (sNum i) .== sNum i =: e .== e =: qed)),
+       (isVar e
+          ==> (let s = getVar_1 e in (sVar s) .== sVar s =: e .== e =: qed)),
+       (isAdd e
+          ==>
+            (let
+               a = getAdd_1 e
+               b = getAdd_2 e
+             in (sAdd a b) .== sAdd a b =: e .== e =: qed)),
+       (isLet e
+          ==>
+            (let
+               nm = getLet_1 e
+               a = getLet_2 e
+               b = getLet_3 e
+             in (sLet nm a b) .== sLet nm a b =: e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase16.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase16.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase16.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE DataKinds          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: nested pattern; use matched fields including nested ones
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero            -> e .== e =: qed
+         Num k           -> sNum k .== sNum k =: e .== e =: qed
+         Var s           -> sVar s .== sVar s =: e .== e =: qed
+         Add (Num i) _   -> sNum i .== sNum i =: e .== e =: qed
+         Add a       b   -> sAdd a b .== sAdd a b =: e .== e =: qed
+         Let nm a b      -> sLet nm a b .== sLet nm a b =: e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase16.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase16.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase16.stderr
@@ -0,0 +1,35 @@
+PCase16.hs:(18,15)-(25,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero            -> e .== e =: qed\n\
+      \         Num k           -> sNum k .== sNum k =: e .== e =: qed\n\
+      \         Var s           -> sVar s .== sVar s =: e .== e =: qed\n\
+      \         Add (Num i) _   -> sNum i .== sNum i =: e .== e =: qed\n\
+      \         Add a       b   -> sAdd a b .== sAdd a b =: e .== e =: qed\n\
+      \         Let nm a b      -> sLet nm a b .== sLet nm a b =: e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)),
+       (isNum e
+          ==> (let k = getNum_1 e in (sNum k) .== sNum k =: e .== e =: qed)),
+       (isVar e
+          ==> (let s = getVar_1 e in (sVar s) .== sVar s =: e .== e =: qed)),
+       ((.&&) (isAdd e) (isNum (getAdd_1 e))
+          ==>
+            (let i = getNum_1 (getAdd_1 e)
+             in (sNum i) .== sNum i =: e .== e =: qed)),
+       ((.&&) (isAdd e) (sNot (isNum (getAdd_1 e)))
+          ==>
+            (let
+               a = getAdd_1 e
+               b = getAdd_2 e
+             in (sAdd a b) .== sAdd a b =: e .== e =: qed)),
+       (isLet e
+          ==>
+            (let
+               nm = getLet_1 e
+               a = getLet_2 e
+               b = getLet_3 e
+             in (sLet nm a b) .== sLet nm a b =: e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase17.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase17.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase17.hs
@@ -0,0 +1,24 @@
+{-# LANGUAGE QuasiQuotes       #-}
+{-# LANGUAGE DataKinds         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions  #-}
+{-# LANGUAGE TypeApplications  #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Negative: pCase generates cases [...] which has type TPProofRaw, not Proof SBool;
+-- so using pCase outside a TP proof context is a type error
+t :: SExpr -> Proof SBool
+t e = [pCase| e of
+       Zero      -> e .== e =: qed
+       Num _     -> e .== e =: qed
+       Var _     -> e .== e =: qed
+       Add _ _   -> e .== e =: qed
+       Let _ _ _ -> e .== e =: qed
+     |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase17.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase17.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase17.stderr
@@ -0,0 +1,32 @@
+PCase17.hs:(18,14)-(24,7): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \       Zero      -> e .== e =: qed\n\
+      \       Num _     -> e .== e =: qed\n\
+      \       Var _     -> e .== e =: qed\n\
+      \       Add _ _   -> e .== e =: qed\n\
+      \       Let _ _ _ -> e .== e =: qed\n\
+      \     "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)), (isNum e ==> (e .== e =: qed)),
+       (isVar e ==> (e .== e =: qed)), (isAdd e ==> (e .== e =: qed)),
+       (isLet e ==> (e .== e =: qed))]
+PCase17.hs:18:14: error: [GHC-83865]
+    " Couldn't match expected type: Proof SBool
+                  with actual type: sbv-14.8:Data.SBV.TP.TP.TPProofGen
+                                      (SBV Bool) [sbv-14.8:Data.SBV.TP.TP.Helper] ()
+    " In the expression:
+        cases
+          [(isZero e ==> (e .== e =: qed)), (isNum e ==> (e .== e =: qed)),
+           (isVar e ==> (e .== e =: qed)), ....]
+      In an equation for t:
+          t e
+            = (cases
+                 [(isZero e ==> (e .== e =: qed)), (isNum e ==> (e .== e =: qed)),
+                  (isVar e ==> (e .== e =: qed)), ....])
+   |
+18 | t e = [pCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase18.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase18.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase18.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Negative: wildcard with args (e.g. _ _ ->)
+t :: SExpr -> Proof SBool
+t e = [pCase| e of
+        Zero    -> undefined
+        Num _   -> undefined
+        Var _   -> undefined
+        Add _ _ -> undefined
+        _ _     -> undefined
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase18.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase18.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase18.stderr
@@ -0,0 +1,15 @@
+PCase18.hs:13:14: error: [GHC-39584]
+    " PCase18.hs:18:17: Parse error in pattern: _
+
+    " In the quasi-quotation:
+        [pCase| e of
+        Zero    -> undefined
+        Num _   -> undefined
+        Var _   -> undefined
+        Add _ _ -> undefined
+        _ _     -> undefined
+      |]
+   |
+13 | t e = [pCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase19.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase19.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase19.hs
@@ -0,0 +1,21 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Negative: overlapping — second group for same constructor after first has sTrue catch-all guard
+t :: SExpr -> Proof SBool
+t e = [pCase| e of
+        Zero             -> undefined
+        Num i | i .> 3   -> undefined
+              | sTrue    -> undefined
+        Num i | i .> 12  -> undefined
+        Var _            -> undefined
+        Add _ _          -> undefined
+        Let _ _ _        -> undefined
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase19.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase19.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase19.stderr
@@ -0,0 +1,20 @@
+PCase19.hs:13:14: error: [GHC-39584]
+    " PCase19.hs:17:9-13: pCase: Overlapping case constructors:
+        Constructor: Num i | i .> 12
+      Overlaps with:
+        PCase19.hs:15:9-13: Num i
+
+    " In the quasi-quotation:
+        [pCase| e of
+        Zero             -> undefined
+        Num i | i .> 3   -> undefined
+              | sTrue    -> undefined
+        Num i | i .> 12  -> undefined
+        Var _            -> undefined
+        Add _ _          -> undefined
+        Let _ _ _        -> undefined
+      |]
+   |
+13 | t e = [pCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase20.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase20.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase20.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE DataKinds          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: {} wildcard patterns; use matched field where available
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Num i | i .> 3  -> sNum i .== sNum i =: e .== e =: qed
+               | sTrue   -> sNum i .== sNum i =: e .== e =: qed
+         Zero{}           -> e .== e =: qed
+         Var{}            -> e .== e =: qed
+         Add{}            -> e .== e =: qed
+         Let{}            -> e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase20.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase20.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase20.stderr
@@ -0,0 +1,19 @@
+PCase20.hs:(18,15)-(25,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Num i | i .> 3  -> sNum i .== sNum i =: e .== e =: qed\n\
+      \               | sTrue   -> sNum i .== sNum i =: e .== e =: qed\n\
+      \         Zero{}           -> e .== e =: qed\n\
+      \         Var{}            -> e .== e =: qed\n\
+      \         Add{}            -> e .== e =: qed\n\
+      \         Let{}            -> e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [((.&&) (isNum e) (let i = getNum_1 e in i .> 3)
+          ==> (let i = getNum_1 e in (sNum i) .== sNum i =: e .== e =: qed)),
+       ((.&&) (isNum e) (sNot (let i = getNum_1 e in i .> 3))
+          ==> (let i = getNum_1 e in (sNum i) .== sNum i =: e .== e =: qed)),
+       (isZero e ==> (e .== e =: qed)), (isVar e ==> (e .== e =: qed)),
+       (isAdd e ==> (e .== e =: qed)), (isLet e ==> (e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase21.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase21.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase21.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE DataKinds          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: deeply nested pattern Add (Add (Num _) j) k; use matched fields
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero                  -> e .== e =: qed
+         Num k                 -> sNum k .== sNum k =: e .== e =: qed
+         Var s                 -> sVar s .== sVar s =: e .== e =: qed
+         Add (Add (Num _) j) _ -> sAdd j j .== sAdd j j =: e .== e =: qed
+         Add a b               -> sAdd a b .== sAdd a b =: e .== e =: qed
+         Let nm a b            -> sLet nm a b .== sLet nm a b =: e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase21.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase21.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase21.stderr
@@ -0,0 +1,39 @@
+PCase21.hs:(18,15)-(25,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero                  -> e .== e =: qed\n\
+      \         Num k                 -> sNum k .== sNum k =: e .== e =: qed\n\
+      \         Var s                 -> sVar s .== sVar s =: e .== e =: qed\n\
+      \         Add (Add (Num _) j) _ -> sAdd j j .== sAdd j j =: e .== e =: qed\n\
+      \         Add a b               -> sAdd a b .== sAdd a b =: e .== e =: qed\n\
+      \         Let nm a b            -> sLet nm a b .== sLet nm a b =: e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)),
+       (isNum e
+          ==> (let k = getNum_1 e in (sNum k) .== sNum k =: e .== e =: qed)),
+       (isVar e
+          ==> (let s = getVar_1 e in (sVar s) .== sVar s =: e .== e =: qed)),
+       ((.&&)
+          (isAdd e)
+          ((.&&) (isAdd (getAdd_1 e)) (isNum (getAdd_1 (getAdd_1 e))))
+          ==>
+            (let j = getAdd_2 (getAdd_1 e)
+             in (sAdd j j) .== sAdd j j =: e .== e =: qed)),
+       ((.&&)
+          (isAdd e)
+          (sNot ((.&&) (isAdd (getAdd_1 e)) (isNum (getAdd_1 (getAdd_1 e)))))
+          ==>
+            (let
+               a = getAdd_1 e
+               b = getAdd_2 e
+             in (sAdd a b) .== sAdd a b =: e .== e =: qed)),
+       (isLet e
+          ==>
+            (let
+               nm = getLet_1 e
+               a = getLet_2 e
+               b = getLet_3 e
+             in (sLet nm a b) .== sLet nm a b =: e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase22.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase22.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase22.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE DataKinds          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: nested pattern combined with a guard; use matched fields
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero                    -> e .== e =: qed
+         Num k                   -> sNum k .== sNum k =: e .== e =: qed
+         Var s                   -> sVar s .== sVar s =: e .== e =: qed
+         Add (Num i) _ | i .> 0  -> sNum i .== sNum i =: e .== e =: qed
+         Add a b                 -> sAdd a b .== sAdd a b =: e .== e =: qed
+         Let nm a b              -> sLet nm a b .== sLet nm a b =: e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase22.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase22.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase22.stderr
@@ -0,0 +1,42 @@
+PCase22.hs:(18,15)-(25,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero                    -> e .== e =: qed\n\
+      \         Num k                   -> sNum k .== sNum k =: e .== e =: qed\n\
+      \         Var s                   -> sVar s .== sVar s =: e .== e =: qed\n\
+      \         Add (Num i) _ | i .> 0  -> sNum i .== sNum i =: e .== e =: qed\n\
+      \         Add a b                 -> sAdd a b .== sAdd a b =: e .== e =: qed\n\
+      \         Let nm a b              -> sLet nm a b .== sLet nm a b =: e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)),
+       (isNum e
+          ==> (let k = getNum_1 e in (sNum k) .== sNum k =: e .== e =: qed)),
+       (isVar e
+          ==> (let s = getVar_1 e in (sVar s) .== sVar s =: e .== e =: qed)),
+       ((.&&)
+          (isAdd e)
+          ((.&&)
+             (isNum (getAdd_1 e)) (let i = getNum_1 (getAdd_1 e) in i .> 0))
+          ==>
+            (let i = getNum_1 (getAdd_1 e)
+             in (sNum i) .== sNum i =: e .== e =: qed)),
+       ((.&&)
+          (isAdd e)
+          (sNot
+             ((.&&)
+                (isNum (getAdd_1 e)) (let i = getNum_1 (getAdd_1 e) in i .> 0)))
+          ==>
+            (let
+               a = getAdd_1 e
+               b = getAdd_2 e
+             in (sAdd a b) .== sAdd a b =: e .== e =: qed)),
+       (isLet e
+          ==>
+            (let
+               nm = getLet_1 e
+               a = getLet_2 e
+               b = getLet_3 e
+             in (sLet nm a b) .== sLet nm a b =: e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase23.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase23.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase23.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE DataKinds          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: nested patterns on both sides; use matched fields
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero                -> e .== e =: qed
+         Num k               -> sNum k .== sNum k =: e .== e =: qed
+         Var s               -> sVar s .== sVar s =: e .== e =: qed
+         Add (Num i) (Num j) -> sNum (i + j) .== sNum (i + j) =: e .== e =: qed
+         Add a b             -> sAdd a b .== sAdd a b =: e .== e =: qed
+         Let nm a b          -> sLet nm a b .== sLet nm a b =: e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase23.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase23.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase23.stderr
@@ -0,0 +1,38 @@
+PCase23.hs:(18,15)-(25,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero                -> e .== e =: qed\n\
+      \         Num k               -> sNum k .== sNum k =: e .== e =: qed\n\
+      \         Var s               -> sVar s .== sVar s =: e .== e =: qed\n\
+      \         Add (Num i) (Num j) -> sNum (i + j) .== sNum (i + j) =: e .== e =: qed\n\
+      \         Add a b             -> sAdd a b .== sAdd a b =: e .== e =: qed\n\
+      \         Let nm a b          -> sLet nm a b .== sLet nm a b =: e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)),
+       (isNum e
+          ==> (let k = getNum_1 e in (sNum k) .== sNum k =: e .== e =: qed)),
+       (isVar e
+          ==> (let s = getVar_1 e in (sVar s) .== sVar s =: e .== e =: qed)),
+       ((.&&) (isAdd e) ((.&&) (isNum (getAdd_1 e)) (isNum (getAdd_2 e)))
+          ==>
+            (let
+               i = getNum_1 (getAdd_1 e)
+               j = getNum_1 (getAdd_2 e)
+             in (sNum (i + j)) .== sNum (i + j) =: e .== e =: qed)),
+       ((.&&)
+          (isAdd e) (sNot ((.&&) (isNum (getAdd_1 e)) (isNum (getAdd_2 e))))
+          ==>
+            (let
+               a = getAdd_1 e
+               b = getAdd_2 e
+             in (sAdd a b) .== sAdd a b =: e .== e =: qed)),
+       (isLet e
+          ==>
+            (let
+               nm = getLet_1 e
+               a = getLet_2 e
+               b = getLet_3 e
+             in (sLet nm a b) .== sLet nm a b =: e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase24.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase24.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase24.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE DataKinds          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: nested pattern with wildcard inside; use matched fields
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero          -> e .== e =: qed
+         Num k         -> sNum k .== sNum k =: e .== e =: qed
+         Var s         -> sVar s .== sVar s =: e .== e =: qed
+         Add (Num _) _ -> e .== e =: qed
+         Add a b       -> sAdd a b .== sAdd a b =: e .== e =: qed
+         Let nm a b    -> sLet nm a b .== sLet nm a b =: e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase24.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase24.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase24.stderr
@@ -0,0 +1,32 @@
+PCase24.hs:(18,15)-(25,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero          -> e .== e =: qed\n\
+      \         Num k         -> sNum k .== sNum k =: e .== e =: qed\n\
+      \         Var s         -> sVar s .== sVar s =: e .== e =: qed\n\
+      \         Add (Num _) _ -> e .== e =: qed\n\
+      \         Add a b       -> sAdd a b .== sAdd a b =: e .== e =: qed\n\
+      \         Let nm a b    -> sLet nm a b .== sLet nm a b =: e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)),
+       (isNum e
+          ==> (let k = getNum_1 e in (sNum k) .== sNum k =: e .== e =: qed)),
+       (isVar e
+          ==> (let s = getVar_1 e in (sVar s) .== sVar s =: e .== e =: qed)),
+       ((.&&) (isAdd e) (isNum (getAdd_1 e)) ==> (e .== e =: qed)),
+       ((.&&) (isAdd e) (sNot (isNum (getAdd_1 e)))
+          ==>
+            (let
+               a = getAdd_1 e
+               b = getAdd_2 e
+             in (sAdd a b) .== sAdd a b =: e .== e =: qed)),
+       (isLet e
+          ==>
+            (let
+               nm = getLet_1 e
+               a = getLet_2 e
+               b = getLet_3 e
+             in (sLet nm a b) .== sLet nm a b =: e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase25.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase25.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase25.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE DataKinds          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: nested pattern using parenthesized constructor; use matched fields
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero              -> e .== e =: qed
+         Num k             -> sNum k .== sNum k =: e .== e =: qed
+         Var s             -> sVar s .== sVar s =: e .== e =: qed
+         Let _ (Num i) _  -> sNum i .== sNum i =: e .== e =: qed
+         Let nm a       b  -> sLet nm a b .== sLet nm a b =: e .== e =: qed
+         Add a b           -> sAdd a b .== sAdd a b =: e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase25.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase25.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase25.stderr
@@ -0,0 +1,35 @@
+PCase25.hs:(18,15)-(25,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero              -> e .== e =: qed\n\
+      \         Num k             -> sNum k .== sNum k =: e .== e =: qed\n\
+      \         Var s             -> sVar s .== sVar s =: e .== e =: qed\n\
+      \         Let _ (Num i) _  -> sNum i .== sNum i =: e .== e =: qed\n\
+      \         Let nm a       b  -> sLet nm a b .== sLet nm a b =: e .== e =: qed\n\
+      \         Add a b           -> sAdd a b .== sAdd a b =: e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)),
+       (isNum e
+          ==> (let k = getNum_1 e in (sNum k) .== sNum k =: e .== e =: qed)),
+       (isVar e
+          ==> (let s = getVar_1 e in (sVar s) .== sVar s =: e .== e =: qed)),
+       ((.&&) (isLet e) (isNum (getLet_2 e))
+          ==>
+            (let i = getNum_1 (getLet_2 e)
+             in (sNum i) .== sNum i =: e .== e =: qed)),
+       ((.&&) (isLet e) (sNot (isNum (getLet_2 e)))
+          ==>
+            (let
+               nm = getLet_1 e
+               a = getLet_2 e
+               b = getLet_3 e
+             in (sLet nm a b) .== sLet nm a b =: e .== e =: qed)),
+       (isAdd e
+          ==>
+            (let
+               a = getAdd_1 e
+               b = getAdd_2 e
+             in (sAdd a b) .== sAdd a b =: e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase26.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase26.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase26.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE DataKinds          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: integer literal at top level (Num 1 -> ...)
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero      -> e .== e =: qed
+         Num 1     -> sNum 1 .== sNum 1 =: e .== e =: qed
+         Num k     -> sNum k .== sNum k =: e .== e =: qed
+         Var s     -> sVar s .== sVar s =: e .== e =: qed
+         Add a b   -> sAdd a b .== sAdd a b =: e .== e =: qed
+         Let nm a b -> sLet nm a b .== sLet nm a b =: e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase26.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase26.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase26.stderr
@@ -0,0 +1,33 @@
+PCase26.hs:(18,15)-(25,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero      -> e .== e =: qed\n\
+      \         Num 1     -> sNum 1 .== sNum 1 =: e .== e =: qed\n\
+      \         Num k     -> sNum k .== sNum k =: e .== e =: qed\n\
+      \         Var s     -> sVar s .== sVar s =: e .== e =: qed\n\
+      \         Add a b   -> sAdd a b .== sAdd a b =: e .== e =: qed\n\
+      \         Let nm a b -> sLet nm a b .== sLet nm a b =: e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)),
+       ((.&&) (isNum e) ((.==) (getNum_1 e) 1)
+          ==> ((sNum 1) .== sNum 1 =: e .== e =: qed)),
+       ((.&&) (isNum e) (sNot ((.==) (getNum_1 e) 1))
+          ==> (let k = getNum_1 e in (sNum k) .== sNum k =: e .== e =: qed)),
+       (isVar e
+          ==> (let s = getVar_1 e in (sVar s) .== sVar s =: e .== e =: qed)),
+       (isAdd e
+          ==>
+            (let
+               a = getAdd_1 e
+               b = getAdd_2 e
+             in (sAdd a b) .== sAdd a b =: e .== e =: qed)),
+       (isLet e
+          ==>
+            (let
+               nm = getLet_1 e
+               a = getLet_2 e
+               b = getLet_3 e
+             in (sLet nm a b) .== sLet nm a b =: e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase27.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase27.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase27.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE DataKinds          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: integer literal in nested position (Add (Num 0) j -> ...)
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero          -> e .== e =: qed
+         Num k         -> sNum k .== sNum k =: e .== e =: qed
+         Var s         -> sVar s .== sVar s =: e .== e =: qed
+         Add (Num 0) _ -> sNum 0 .== sNum 0 =: e .== e =: qed
+         Add a b       -> sAdd a b .== sAdd a b =: e .== e =: qed
+         Let nm a b    -> sLet nm a b .== sLet nm a b =: e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase27.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase27.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase27.stderr
@@ -0,0 +1,38 @@
+PCase27.hs:(18,15)-(25,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero          -> e .== e =: qed\n\
+      \         Num k         -> sNum k .== sNum k =: e .== e =: qed\n\
+      \         Var s         -> sVar s .== sVar s =: e .== e =: qed\n\
+      \         Add (Num 0) _ -> sNum 0 .== sNum 0 =: e .== e =: qed\n\
+      \         Add a b       -> sAdd a b .== sAdd a b =: e .== e =: qed\n\
+      \         Let nm a b    -> sLet nm a b .== sLet nm a b =: e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)),
+       (isNum e
+          ==> (let k = getNum_1 e in (sNum k) .== sNum k =: e .== e =: qed)),
+       (isVar e
+          ==> (let s = getVar_1 e in (sVar s) .== sVar s =: e .== e =: qed)),
+       ((.&&)
+          (isAdd e)
+          ((.&&) (isNum (getAdd_1 e)) ((.==) (getNum_1 (getAdd_1 e)) 0))
+          ==> ((sNum 0) .== sNum 0 =: e .== e =: qed)),
+       ((.&&)
+          (isAdd e)
+          (sNot
+             ((.&&) (isNum (getAdd_1 e)) ((.==) (getNum_1 (getAdd_1 e)) 0)))
+          ==>
+            (let
+               a = getAdd_1 e
+               b = getAdd_2 e
+             in (sAdd a b) .== sAdd a b =: e .== e =: qed)),
+       (isLet e
+          ==>
+            (let
+               nm = getLet_1 e
+               a = getLet_2 e
+               b = getLet_3 e
+             in (sLet nm a b) .== sLet nm a b =: e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase28.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase28.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase28.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE DataKinds          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: string literal in nested position (Var "x" -> ...)
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero      -> e .== e =: qed
+         Num k     -> sNum k .== sNum k =: e .== e =: qed
+         Var "x"   -> sVar (literal "x") .== sVar (literal "x") =: e .== e =: qed
+         Var s     -> sVar s .== sVar s =: e .== e =: qed
+         Add a b   -> sAdd a b .== sAdd a b =: e .== e =: qed
+         Let nm a b -> sLet nm a b .== sLet nm a b =: e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase28.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase28.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase28.stderr
@@ -0,0 +1,34 @@
+PCase28.hs:(18,15)-(25,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero      -> e .== e =: qed\n\
+      \         Num k     -> sNum k .== sNum k =: e .== e =: qed\n\
+      \         Var \"x\"   -> sVar (literal \"x\") .== sVar (literal \"x\") =: e .== e =: qed\n\
+      \         Var s     -> sVar s .== sVar s =: e .== e =: qed\n\
+      \         Add a b   -> sAdd a b .== sAdd a b =: e .== e =: qed\n\
+      \         Let nm a b -> sLet nm a b .== sLet nm a b =: e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)),
+       (isNum e
+          ==> (let k = getNum_1 e in (sNum k) .== sNum k =: e .== e =: qed)),
+       ((.&&) (isVar e) ((.==) (getVar_1 e) (literal "x"))
+          ==>
+            ((sVar (literal "x")) .== sVar (literal "x") =: e .== e =: qed)),
+       ((.&&) (isVar e) (sNot ((.==) (getVar_1 e) (literal "x")))
+          ==> (let s = getVar_1 e in (sVar s) .== sVar s =: e .== e =: qed)),
+       (isAdd e
+          ==>
+            (let
+               a = getAdd_1 e
+               b = getAdd_2 e
+             in (sAdd a b) .== sAdd a b =: e .== e =: qed)),
+       (isLet e
+          ==>
+            (let
+               nm = getLet_1 e
+               a = getLet_2 e
+               b = getLet_3 e
+             in (sLet nm a b) .== sLet nm a b =: e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase29.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase29.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase29.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE DataKinds          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: integer literals on both sides of nested pattern
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero                -> e .== e =: qed
+         Num k               -> sNum k .== sNum k =: e .== e =: qed
+         Var s               -> sVar s .== sVar s =: e .== e =: qed
+         Add (Num 1) (Num 2) -> sAdd (sNum 1) (sNum 2) .== sAdd (sNum 1) (sNum 2) =: e .== e =: qed
+         Add a b             -> sAdd a b .== sAdd a b =: e .== e =: qed
+         Let nm a b          -> sLet nm a b .== sLet nm a b =: e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase29.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase29.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase29.stderr
@@ -0,0 +1,48 @@
+PCase29.hs:(18,15)-(25,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero                -> e .== e =: qed\n\
+      \         Num k               -> sNum k .== sNum k =: e .== e =: qed\n\
+      \         Var s               -> sVar s .== sVar s =: e .== e =: qed\n\
+      \         Add (Num 1) (Num 2) -> sAdd (sNum 1) (sNum 2) .== sAdd (sNum 1) (sNum 2) =: e .== e =: qed\n\
+      \         Add a b             -> sAdd a b .== sAdd a b =: e .== e =: qed\n\
+      \         Let nm a b          -> sLet nm a b .== sLet nm a b =: e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)),
+       (isNum e
+          ==> (let k = getNum_1 e in (sNum k) .== sNum k =: e .== e =: qed)),
+       (isVar e
+          ==> (let s = getVar_1 e in (sVar s) .== sVar s =: e .== e =: qed)),
+       ((.&&)
+          (isAdd e)
+          ((.&&)
+             (isNum (getAdd_1 e))
+             ((.&&)
+                ((.==) (getNum_1 (getAdd_1 e)) 1)
+                ((.&&) (isNum (getAdd_2 e)) ((.==) (getNum_1 (getAdd_2 e)) 2))))
+          ==>
+            ((sAdd (sNum 1) (sNum 2)) .== sAdd (sNum 1) (sNum 2) =: e .== e
+               =: qed)),
+       ((.&&)
+          (isAdd e)
+          (sNot
+             ((.&&)
+                (isNum (getAdd_1 e))
+                ((.&&)
+                   ((.==) (getNum_1 (getAdd_1 e)) 1)
+                   ((.&&) (isNum (getAdd_2 e)) ((.==) (getNum_1 (getAdd_2 e)) 2)))))
+          ==>
+            (let
+               a = getAdd_1 e
+               b = getAdd_2 e
+             in (sAdd a b) .== sAdd a b =: e .== e =: qed)),
+       (isLet e
+          ==>
+            (let
+               nm = getLet_1 e
+               a = getLet_2 e
+               b = getLet_3 e
+             in (sLet nm a b) .== sLet nm a b =: e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase30.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase30.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase30.hs
@@ -0,0 +1,24 @@
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE DataKinds          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: Num 1 as only Num arm, no fallback — fine in pCase (no exhaustiveness check)
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero      -> e .== e =: qed
+         Num 1     -> sNum 1 .== sNum 1 =: e .== e =: qed
+         Var s     -> sVar s .== sVar s =: e .== e =: qed
+         Add _ _   -> e .== e =: qed
+         Let _ _ _ -> e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase30.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase30.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase30.stderr
@@ -0,0 +1,18 @@
+PCase30.hs:(18,15)-(24,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero      -> e .== e =: qed\n\
+      \         Num 1     -> sNum 1 .== sNum 1 =: e .== e =: qed\n\
+      \         Var s     -> sVar s .== sVar s =: e .== e =: qed\n\
+      \         Add _ _   -> e .== e =: qed\n\
+      \         Let _ _ _ -> e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)),
+       ((.&&) (isNum e) ((.==) (getNum_1 e) 1)
+          ==> ((sNum 1) .== sNum 1 =: e .== e =: qed)),
+       (isVar e
+          ==> (let s = getVar_1 e in (sVar s) .== sVar s =: e .== e =: qed)),
+       (isAdd e ==> (e .== e =: qed)), (isLet e ==> (e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase31.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase31.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase31.hs
@@ -0,0 +1,24 @@
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE DataKinds          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: Add (Num 1) j without fallback for Add — fine in pCase (no exhaustiveness check)
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero          -> e .== e =: qed
+         Num k         -> sNum k .== sNum k =: e .== e =: qed
+         Var s         -> sVar s .== sVar s =: e .== e =: qed
+         Add (Num 1) _ -> sNum 1 .== sNum 1 =: e .== e =: qed
+         Let nm a b    -> sLet nm a b .== sLet nm a b =: e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase31.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase31.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase31.stderr
@@ -0,0 +1,28 @@
+PCase31.hs:(18,15)-(24,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero          -> e .== e =: qed\n\
+      \         Num k         -> sNum k .== sNum k =: e .== e =: qed\n\
+      \         Var s         -> sVar s .== sVar s =: e .== e =: qed\n\
+      \         Add (Num 1) _ -> sNum 1 .== sNum 1 =: e .== e =: qed\n\
+      \         Let nm a b    -> sLet nm a b .== sLet nm a b =: e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)),
+       (isNum e
+          ==> (let k = getNum_1 e in (sNum k) .== sNum k =: e .== e =: qed)),
+       (isVar e
+          ==> (let s = getVar_1 e in (sVar s) .== sVar s =: e .== e =: qed)),
+       ((.&&)
+          (isAdd e)
+          ((.&&) (isNum (getAdd_1 e)) ((.==) (getNum_1 (getAdd_1 e)) 1))
+          ==> ((sNum 1) .== sNum 1 =: e .== e =: qed)),
+       (isLet e
+          ==>
+            (let
+               nm = getLet_1 e
+               a = getLet_2 e
+               b = getLet_3 e
+             in (sLet nm a b) .== sLet nm a b =: e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase32.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase32.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase32.hs
@@ -0,0 +1,23 @@
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE DataKinds          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: only 2 of 5 constructors covered, including a guarded one
+-- (sCase would reject this as non-exhaustive; pCase is fine)
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero           -> e .== e =: qed
+         Num i | i .> 0 -> sNum i .== sNum i =: e .== e =: qed
+         Var s          -> sVar s .== sVar s =: e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase32.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase32.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase32.stderr
@@ -0,0 +1,15 @@
+PCase32.hs:(19,15)-(23,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero           -> e .== e =: qed\n\
+      \         Num i | i .> 0 -> sNum i .== sNum i =: e .== e =: qed\n\
+      \         Var s          -> sVar s .== sVar s =: e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)),
+       ((.&&) (isNum e) (let i = getNum_1 e in i .> 0)
+          ==> (let i = getNum_1 e in (sNum i) .== sNum i =: e .== e =: qed)),
+       (isVar e
+          ==> (let s = getVar_1 e in (sVar s) .== sVar s =: e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase33.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase33.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase33.hs
@@ -0,0 +1,21 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Negative in pCase: wildcard mid-list (after two constructors, before more)
+-- Wildcard makes the remaining matches redundant
+t :: SExpr -> Proof SBool
+t e = [pCase| e of
+        Zero  -> undefined
+        Num _ -> undefined
+        _     -> undefined
+        Var _ -> undefined
+        Add _ _ -> undefined
+        Let _ _ _ -> undefined
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase33.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase33.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase33.stderr
@@ -0,0 +1,19 @@
+PCase33.hs:14:14: error: [GHC-39584]
+    " PCase33.hs:17:9: pCase: Wildcard makes the remaining matches redundant:
+        PCase33.hs:18:9-13: Var _
+        PCase33.hs:19:9-15: Add _ _
+        PCase33.hs:20:9-17: Let _ _ _
+
+    " In the quasi-quotation:
+        [pCase| e of
+        Zero  -> undefined
+        Num _ -> undefined
+        _     -> undefined
+        Var _ -> undefined
+        Add _ _ -> undefined
+        Let _ _ _ -> undefined
+      |]
+   |
+14 | t e = [pCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase34.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase34.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase34.hs
@@ -0,0 +1,18 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Negative in pCase: two wildcards, second is redundant
+t :: SExpr -> Proof SBool
+t e = [pCase| e of
+        Zero  -> undefined
+        Num _ -> undefined
+        _     -> undefined
+        _     -> undefined
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase34.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase34.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase34.stderr
@@ -0,0 +1,15 @@
+PCase34.hs:13:14: error: [GHC-39584]
+    " PCase34.hs:16:9: pCase: Wildcard makes the remaining matches redundant:
+        PCase34.hs:17:9: _
+
+    " In the quasi-quotation:
+        [pCase| e of
+        Zero  -> undefined
+        Num _ -> undefined
+        _     -> undefined
+        _     -> undefined
+      |]
+   |
+13 | t e = [pCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase35.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase35.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase35.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE DataKinds          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: single guarded arm with no fallback for that constructor
+-- (sCase rejects this as "guarded match might fail"; pCase is fine)
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero           -> e .== e =: qed
+         Num i | i .< 3 -> sNum i .== sNum i =: e .== e =: qed
+         Var s          -> sVar s .== sVar s =: e .== e =: qed
+         Add _ _        -> e .== e =: qed
+         Let _ _ _      -> e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase35.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase35.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase35.stderr
@@ -0,0 +1,18 @@
+PCase35.hs:(19,15)-(25,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero           -> e .== e =: qed\n\
+      \         Num i | i .< 3 -> sNum i .== sNum i =: e .== e =: qed\n\
+      \         Var s          -> sVar s .== sVar s =: e .== e =: qed\n\
+      \         Add _ _        -> e .== e =: qed\n\
+      \         Let _ _ _      -> e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)),
+       ((.&&) (isNum e) (let i = getNum_1 e in i .< 3)
+          ==> (let i = getNum_1 e in (sNum i) .== sNum i =: e .== e =: qed)),
+       (isVar e
+          ==> (let s = getVar_1 e in (sVar s) .== sVar s =: e .== e =: qed)),
+       (isAdd e ==> (e .== e =: qed)), (isLet e ==> (e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase36.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase36.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase36.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE QuasiQuotes       #-}
+{-# LANGUAGE DataKinds         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions  #-}
+{-# LANGUAGE TypeApplications  #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Negative: guarded wildcard at end with ambiguous type in guard (2 .>= 3)
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+       Zero           -> e .== e =: qed
+       Num _          -> e .== e =: qed
+       Var _          -> e .== e =: qed
+       Add _ _        -> e .== e =: qed
+       Let _ _ _      -> e .== e =: qed
+       _ | 2 .>= 3   -> e .== e =: qed
+     |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase36.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase36.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase36.stderr
@@ -0,0 +1,15 @@
+PCase36.hs:18:15: error: [GHC-39584]
+    " PCase36.hs:24:8: pCase: Wildcard match is redundant
+    " In the quasi-quotation:
+        [pCase| e of
+       Zero           -> e .== e =: qed
+       Num _          -> e .== e =: qed
+       Var _          -> e .== e =: qed
+       Add _ _        -> e .== e =: qed
+       Let _ _ _      -> e .== e =: qed
+       _ | 2 .>= 3   -> e .== e =: qed
+     |]
+   |
+18 |     |- [pCase| e of
+   |               ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase37.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase37.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase37.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE QuasiQuotes       #-}
+{-# LANGUAGE DataKinds         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions  #-}
+{-# LANGUAGE TypeApplications  #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Negative: all constructors covered + guarded wildcard with ambiguous type in guard (2 .>= 3)
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+       Zero           -> e .== e =: qed
+       Num i          -> sNum i .== sNum i =: e .== e =: qed
+       Var _          -> e .== e =: qed
+       Add _ _        -> e .== e =: qed
+       Let _ _ _      -> e .== e =: qed
+       _ | 2 .>= 3   -> e .== e =: qed
+     |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase37.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase37.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase37.stderr
@@ -0,0 +1,15 @@
+PCase37.hs:18:15: error: [GHC-39584]
+    " PCase37.hs:24:8: pCase: Wildcard match is redundant
+    " In the quasi-quotation:
+        [pCase| e of
+       Zero           -> e .== e =: qed
+       Num i          -> sNum i .== sNum i =: e .== e =: qed
+       Var _          -> e .== e =: qed
+       Add _ _        -> e .== e =: qed
+       Let _ _ _      -> e .== e =: qed
+       _ | 2 .>= 3   -> e .== e =: qed
+     |]
+   |
+18 |     |- [pCase| e of
+   |               ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase38.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase38.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase38.hs
@@ -0,0 +1,18 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+t :: SExpr -> Proof SBool
+t e = [pCase| e of
+        Zero      -> undefined
+        Num _     -> undefined
+        Var _     -> undefined
+        Add _ _   -> undefined
+        Let _ _ _ -> undefined
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase38.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase38.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase38.stderr
@@ -0,0 +1,32 @@
+PCase38.hs:(12,14)-(18,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \        Zero      -> undefined\n\
+      \        Num _     -> undefined\n\
+      \        Var _     -> undefined\n\
+      \        Add _ _   -> undefined\n\
+      \        Let _ _ _ -> undefined\n\
+      \      "
+  ======>
+    cases
+      [(isZero e ==> undefined), (isNum e ==> undefined),
+       (isVar e ==> undefined), (isAdd e ==> undefined),
+       (isLet e ==> undefined)]
+PCase38.hs:12:14: error: [GHC-83865]
+    " Couldn't match expected type: Proof SBool
+                  with actual type: sbv-14.8:Data.SBV.TP.TP.TPProofGen
+                                      a0 [sbv-14.8:Data.SBV.TP.TP.Helper] ()
+    " In the expression:
+        cases
+          [(isZero e ==> undefined), (isNum e ==> undefined),
+           (isVar e ==> undefined), ....]
+      In an equation for t:
+          t e
+            = (cases
+                 [(isZero e ==> undefined), (isNum e ==> undefined),
+                  (isVar e ==> undefined), ....])
+   |
+12 | t e = [pCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase39.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase39.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase39.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE DataKinds          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: nested pattern covers only a subset of Add, no fallback
+-- (sCase rejects as non-exhaustive; pCase is fine)
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero          -> e .== e =: qed
+         Num k         -> sNum k .== sNum k =: e .== e =: qed
+         Var s         -> sVar s .== sVar s =: e .== e =: qed
+         Add (Num i) _ -> sNum i .== sNum i =: e .== e =: qed
+         Let nm a b    -> sLet nm a b .== sLet nm a b =: e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase39.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase39.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase39.stderr
@@ -0,0 +1,28 @@
+PCase39.hs:(19,15)-(25,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero          -> e .== e =: qed\n\
+      \         Num k         -> sNum k .== sNum k =: e .== e =: qed\n\
+      \         Var s         -> sVar s .== sVar s =: e .== e =: qed\n\
+      \         Add (Num i) _ -> sNum i .== sNum i =: e .== e =: qed\n\
+      \         Let nm a b    -> sLet nm a b .== sLet nm a b =: e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)),
+       (isNum e
+          ==> (let k = getNum_1 e in (sNum k) .== sNum k =: e .== e =: qed)),
+       (isVar e
+          ==> (let s = getVar_1 e in (sVar s) .== sVar s =: e .== e =: qed)),
+       ((.&&) (isAdd e) (isNum (getAdd_1 e))
+          ==>
+            (let i = getNum_1 (getAdd_1 e)
+             in (sNum i) .== sNum i =: e .== e =: qed)),
+       (isLet e
+          ==>
+            (let
+               nm = getLet_1 e
+               a = getLet_2 e
+               b = getLet_3 e
+             in (sLet nm a b) .== sLet nm a b =: e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase40.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase40.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase40.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE DataKinds          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: deeply nested pattern, no fallback for outer Add
+-- (sCase rejects as non-exhaustive; pCase is fine)
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero                          -> e .== e =: qed
+         Num k                         -> sNum k .== sNum k =: e .== e =: qed
+         Var s                         -> sVar s .== sVar s =: e .== e =: qed
+         Add (Add (Add (Num _) b) c) _ -> sAdd b (sAdd c c) .== e =: qed
+         Let nm a b                    -> sLet nm a b .== sLet nm a b =: e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase40.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase40.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase40.stderr
@@ -0,0 +1,36 @@
+PCase40.hs:(19,15)-(25,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero                          -> e .== e =: qed\n\
+      \         Num k                         -> sNum k .== sNum k =: e .== e =: qed\n\
+      \         Var s                         -> sVar s .== sVar s =: e .== e =: qed\n\
+      \         Add (Add (Add (Num _) b) c) _ -> sAdd b (sAdd c c) .== e =: qed\n\
+      \         Let nm a b                    -> sLet nm a b .== sLet nm a b =: e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)),
+       (isNum e
+          ==> (let k = getNum_1 e in (sNum k) .== sNum k =: e .== e =: qed)),
+       (isVar e
+          ==> (let s = getVar_1 e in (sVar s) .== sVar s =: e .== e =: qed)),
+       ((.&&)
+          (isAdd e)
+          ((.&&)
+             (isAdd (getAdd_1 e))
+             ((.&&)
+                (isAdd (getAdd_1 (getAdd_1 e)))
+                (isNum (getAdd_1 (getAdd_1 (getAdd_1 e))))))
+          ==>
+            (let
+               c = getAdd_2 (getAdd_1 e)
+               b = getAdd_2 (getAdd_1 (getAdd_1 e))
+             in (sAdd b (sAdd c c)) .== e =: qed)),
+       (isLet e
+          ==>
+            (let
+               nm = getLet_1 e
+               a = getLet_2 e
+               b = getLet_3 e
+             in (sLet nm a b) .== sLet nm a b =: e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase41.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase41.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase41.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Negative: parse error (else keyword in wrong position)
+t :: SExpr -> Proof SBool
+t e = [pCase| e of
+        Zero  -> undefined
+        Var s -> ite (s .== "a") undefined else undefined
+        Num _ -> undefined
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase41.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase41.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase41.stderr
@@ -0,0 +1,13 @@
+PCase41.hs:13:14: error: [GHC-39584]
+    " PCase41.hs:15:44: Parse error: else
+
+    " In the quasi-quotation:
+        [pCase| e of
+        Zero  -> undefined
+        Var s -> ite (s .== "a") undefined else undefined
+        Num _ -> undefined
+      |]
+   |
+13 | t e = [pCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase42.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase42.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase42.hs
@@ -0,0 +1,26 @@
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE DataKinds          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: Num split across two arms — guarded first, unguarded fallback later
+-- (same constructor appearing in two separate groups is fine in pCase)
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero           -> e .== e =: qed
+         Num i | i .< 3 -> sNum i .== sNum i =: e .== e =: qed
+         Var s          -> sVar s .== sVar s =: e .== e =: qed
+         Add a b        -> sAdd a b .== sAdd a b =: e .== e =: qed
+         Num i          -> sNum i .== sNum i =: e .== e =: qed
+         Let nm a b     -> sLet nm a b .== sLet nm a b =: e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase42.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase42.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase42.stderr
@@ -0,0 +1,33 @@
+PCase42.hs:(19,15)-(26,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero           -> e .== e =: qed\n\
+      \         Num i | i .< 3 -> sNum i .== sNum i =: e .== e =: qed\n\
+      \         Var s          -> sVar s .== sVar s =: e .== e =: qed\n\
+      \         Add a b        -> sAdd a b .== sAdd a b =: e .== e =: qed\n\
+      \         Num i          -> sNum i .== sNum i =: e .== e =: qed\n\
+      \         Let nm a b     -> sLet nm a b .== sLet nm a b =: e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)),
+       ((.&&) (isNum e) (let i = getNum_1 e in i .< 3)
+          ==> (let i = getNum_1 e in (sNum i) .== sNum i =: e .== e =: qed)),
+       (isVar e
+          ==> (let s = getVar_1 e in (sVar s) .== sVar s =: e .== e =: qed)),
+       (isAdd e
+          ==>
+            (let
+               a = getAdd_1 e
+               b = getAdd_2 e
+             in (sAdd a b) .== sAdd a b =: e .== e =: qed)),
+       ((.&&) (isNum e) (sNot (let i = getNum_1 e in i .< 3))
+          ==> (let i = getNum_1 e in (sNum i) .== sNum i =: e .== e =: qed)),
+       (isLet e
+          ==>
+            (let
+               nm = getLet_1 e
+               a = getLet_2 e
+               b = getLet_3 e
+             in (sLet nm a b) .== sLet nm a b =: e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase43.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase43.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase43.hs
@@ -0,0 +1,24 @@
+{-# LANGUAGE QuasiQuotes       #-}
+{-# LANGUAGE DataKinds         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions  #-}
+{-# LANGUAGE TypeApplications  #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: guarded constructor without full coverage (exhaustiveness deferred to proof time)
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero              -> e .== e =: qed
+         Num _             -> e .== e =: qed
+         Var _             -> e .== e =: qed
+         Add a _ | isZero a -> e .== e =: qed
+         Let _ _ _         -> e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase43.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase43.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase43.stderr
@@ -0,0 +1,17 @@
+PCase43.hs:(18,15)-(24,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero              -> e .== e =: qed\n\
+      \         Num _             -> e .== e =: qed\n\
+      \         Var _             -> e .== e =: qed\n\
+      \         Add a _ | isZero a -> e .== e =: qed\n\
+      \         Let _ _ _         -> e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)), (isNum e ==> (e .== e =: qed)),
+       (isVar e ==> (e .== e =: qed)),
+       ((.&&) (isAdd e) (let a = getAdd_1 e in isZero a)
+          ==> (e .== e =: qed)),
+       (isLet e ==> (e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase44.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase44.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase44.hs
@@ -0,0 +1,26 @@
+{-# LANGUAGE QuasiQuotes       #-}
+{-# LANGUAGE DataKinds         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions  #-}
+{-# LANGUAGE TypeApplications  #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: wildcard catch-all after multi-arm guarded Var and Num
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Var s | s .== literal "a"                       -> e .== e =: qed
+               | s .== literal "b" .|| s .== literal "c" -> e .== e =: qed
+               | sTrue                                    -> e .== e =: qed
+
+         Num _ | sTrue                                    -> e .== e =: qed
+
+         _                                                -> e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase44.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase44.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase44.stderr
@@ -0,0 +1,48 @@
+PCase44.hs:(18,15)-(26,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Var s | s .== literal \"a\"                       -> e .== e =: qed\n\
+      \               | s .== literal \"b\" .|| s .== literal \"c\" -> e .== e =: qed\n\
+      \               | sTrue                                    -> e .== e =: qed\n\
+      \\n\
+      \         Num _ | sTrue                                    -> e .== e =: qed\n\
+      \\n\
+      \         _                                                -> e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [((.&&) (isVar e) (let s = getVar_1 e in s .== literal "a")
+          ==> (e .== e =: qed)),
+       ((.&&)
+          (isVar e)
+          ((.&&)
+             (sNot (let s = getVar_1 e in s .== literal "a"))
+             (let s = getVar_1 e in s .== literal "b" .|| s .== literal "c"))
+          ==> (e .== e =: qed)),
+       ((.&&)
+          (isVar e)
+          ((.&&)
+             (sNot (let s = getVar_1 e in s .== literal "a"))
+             (sNot
+                (let s = getVar_1 e in s .== literal "b" .|| s .== literal "c")))
+          ==> (e .== e =: qed)),
+       (isNum e ==> (e .== e =: qed)),
+       (sNot
+          ((.||)
+             ((.||)
+                ((.||)
+                   ((.&&) (isVar e) (let s = getVar_1 e in s .== literal "a"))
+                   ((.&&)
+                      (isVar e)
+                      ((.&&)
+                         (sNot (let s = getVar_1 e in s .== literal "a"))
+                         (let s = getVar_1 e in s .== literal "b" .|| s .== literal "c"))))
+                ((.&&)
+                   (isVar e)
+                   ((.&&)
+                      (sNot (let s = getVar_1 e in s .== literal "a"))
+                      (sNot
+                         (let s = getVar_1 e in s .== literal "b" .|| s .== literal "c")))))
+             (isNum e))
+          ==> (e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase45.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase45.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase45.hs
@@ -0,0 +1,24 @@
+{-# LANGUAGE QuasiQuotes       #-}
+{-# LANGUAGE DataKinds         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions  #-}
+{-# LANGUAGE TypeApplications  #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Negative: bound variable i from Num is not used in the RHS
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero      -> e .== e =: qed
+         Num i     -> e .== e =: qed
+         Var s     -> sVar s .== sVar s =: e .== e =: qed
+         Add a b   -> sAdd a b .== sAdd a b =: e .== e =: qed
+         Let nm a b -> sLet nm a b .== sLet nm a b =: e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase45.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase45.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase45.stderr
@@ -0,0 +1,35 @@
+PCase45.hs:(18,15)-(24,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero      -> e .== e =: qed\n\
+      \         Num i     -> e .== e =: qed\n\
+      \         Var s     -> sVar s .== sVar s =: e .== e =: qed\n\
+      \         Add a b   -> sAdd a b .== sAdd a b =: e .== e =: qed\n\
+      \         Let nm a b -> sLet nm a b .== sLet nm a b =: e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)),
+       (isNum e ==> (let i = getNum_1 e in e .== e =: qed)),
+       (isVar e
+          ==> (let s = getVar_1 e in (sVar s) .== sVar s =: e .== e =: qed)),
+       (isAdd e
+          ==>
+            (let
+               a = getAdd_1 e
+               b = getAdd_2 e
+             in (sAdd a b) .== sAdd a b =: e .== e =: qed)),
+       (isLet e
+          ==>
+            (let
+               nm = getLet_1 e
+               a = getLet_2 e
+               b = getLet_3 e
+             in (sLet nm a b) .== sLet nm a b =: e .== e =: qed))]
+PCase45.hs:18:15: error: [GHC-40910] [-Wunused-local-binds, Werror=unused-local-binds]
+    Defined but not used: i
+   |
+18 |     |- [pCase| e of
+   |               ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase46.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase46.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase46.hs
@@ -0,0 +1,24 @@
+{-# LANGUAGE QuasiQuotes       #-}
+{-# LANGUAGE DataKinds         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions  #-}
+{-# LANGUAGE TypeApplications  #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Negative: bound variables a, b from Add are not used in the RHS
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero      -> e .== e =: qed
+         Num i     -> sNum i .== sNum i =: e .== e =: qed
+         Var s     -> sVar s .== sVar s =: e .== e =: qed
+         Add a b   -> e .== e =: qed
+         Let nm a b -> sLet nm a b .== sLet nm a b =: e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase46.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase46.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase46.stderr
@@ -0,0 +1,42 @@
+PCase46.hs:(18,15)-(24,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero      -> e .== e =: qed\n\
+      \         Num i     -> sNum i .== sNum i =: e .== e =: qed\n\
+      \         Var s     -> sVar s .== sVar s =: e .== e =: qed\n\
+      \         Add a b   -> e .== e =: qed\n\
+      \         Let nm a b -> sLet nm a b .== sLet nm a b =: e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)),
+       (isNum e
+          ==> (let i = getNum_1 e in (sNum i) .== sNum i =: e .== e =: qed)),
+       (isVar e
+          ==> (let s = getVar_1 e in (sVar s) .== sVar s =: e .== e =: qed)),
+       (isAdd e
+          ==>
+            (let
+               a = getAdd_1 e
+               b = getAdd_2 e
+             in e .== e =: qed)),
+       (isLet e
+          ==>
+            (let
+               nm = getLet_1 e
+               a = getLet_2 e
+               b = getLet_3 e
+             in (sLet nm a b) .== sLet nm a b =: e .== e =: qed))]
+PCase46.hs:18:15: error: [GHC-40910] [-Wunused-local-binds, Werror=unused-local-binds]
+    Defined but not used: b
+   |
+18 |     |- [pCase| e of
+   |               ^^^^^...
+
+PCase46.hs:18:15: error: [GHC-40910] [-Wunused-local-binds, Werror=unused-local-binds]
+    Defined but not used: a
+   |
+18 |     |- [pCase| e of
+   |               ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase47.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase47.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase47.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE QuasiQuotes      #-}
+{-# LANGUAGE DataKinds          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Negative: Var s before Var "x" — Var s overlaps with Var "x"
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero      -> e .== e =: qed
+         Num k     -> sNum k .== sNum k =: e .== e =: qed
+         Var s     -> sVar s .== sVar s =: e .== e =: qed
+         Var "x"   -> sVar (literal "x") .== sVar (literal "x") =: e .== e =: qed
+         Add a b   -> sAdd a b .== sAdd a b =: e .== e =: qed
+         Let nm a b -> sLet nm a b .== sLet nm a b =: e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase47.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase47.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase47.stderr
@@ -0,0 +1,19 @@
+PCase47.hs:18:15: error: [GHC-39584]
+    " PCase47.hs:22:10-16: pCase: Overlapping case constructors:
+        Constructor: Var _ | (Data.SBV.Core.Data..==) (getVar_1 e) (Data.SBV.Core.Data.literal "x")
+      Overlaps with:
+        PCase47.hs:21:10-14: Var s
+
+    " In the quasi-quotation:
+        [pCase| e of
+         Zero      -> e .== e =: qed
+         Num k     -> sNum k .== sNum k =: e .== e =: qed
+         Var s     -> sVar s .== sVar s =: e .== e =: qed
+         Var "x"   -> sVar (literal "x") .== sVar (literal "x") =: e .== e =: qed
+         Add a b   -> sAdd a b .== sAdd a b =: e .== e =: qed
+         Let nm a b -> sLet nm a b .== sLet nm a b =: e .== e =: qed
+       |]
+   |
+18 |     |- [pCase| e of
+   |               ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase48.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase48.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase48.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE QuasiQuotes       #-}
+{-# LANGUAGE DataKinds         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions  #-}
+{-# LANGUAGE TypeApplications  #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: multi-arm guarded Var and Num, no wildcard catch-all
+-- (sCase would reject as non-exhaustive; pCase is fine)
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Var s | s .== literal "a"                       -> e .== e =: qed
+               | s .== literal "b" .|| s .== literal "c" -> e .== e =: qed
+               | sTrue                                    -> e .== e =: qed
+
+         Num _ | sTrue                                    -> e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase48.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase48.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase48.stderr
@@ -0,0 +1,28 @@
+PCase48.hs:(19,15)-(25,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Var s | s .== literal \"a\"                       -> e .== e =: qed\n\
+      \               | s .== literal \"b\" .|| s .== literal \"c\" -> e .== e =: qed\n\
+      \               | sTrue                                    -> e .== e =: qed\n\
+      \\n\
+      \         Num _ | sTrue                                    -> e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [((.&&) (isVar e) (let s = getVar_1 e in s .== literal "a")
+          ==> (e .== e =: qed)),
+       ((.&&)
+          (isVar e)
+          ((.&&)
+             (sNot (let s = getVar_1 e in s .== literal "a"))
+             (let s = getVar_1 e in s .== literal "b" .|| s .== literal "c"))
+          ==> (e .== e =: qed)),
+       ((.&&)
+          (isVar e)
+          ((.&&)
+             (sNot (let s = getVar_1 e in s .== literal "a"))
+             (sNot
+                (let s = getVar_1 e in s .== literal "b" .|| s .== literal "c")))
+          ==> (e .== e =: qed)),
+       (isNum e ==> (e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase49.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase49.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase49.hs
@@ -0,0 +1,22 @@
+{-# LANGUAGE QuasiQuotes       #-}
+{-# LANGUAGE DataKinds         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions  #-}
+{-# LANGUAGE TypeApplications  #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: guarded wildcard as last arm after explicit constructors
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero    -> e .== e =: qed
+         Num _   -> e .== e =: qed
+         _ | sTrue -> e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase49.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase49.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase49.stderr
@@ -0,0 +1,12 @@
+PCase49.hs:(18,15)-(22,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero    -> e .== e =: qed\n\
+      \         Num _   -> e .== e =: qed\n\
+      \         _ | sTrue -> e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)), (isNum e ==> (e .== e =: qed)),
+       (sNot ((.||) (isZero e) (isNum e)) ==> (e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase50.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase50.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase50.hs
@@ -0,0 +1,20 @@
+{-# LANGUAGE QuasiQuotes       #-}
+{-# LANGUAGE DataKinds         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions  #-}
+{-# LANGUAGE TypeApplications  #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: wildcard-only, no explicit constructors
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         _ -> e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase50.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase50.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase50.stderr
@@ -0,0 +1,8 @@
+PCase50.hs:(18,15)-(20,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         _ -> e .== e =: qed\n\
+      \       "
+  ======>
+    cases [(sTrue ==> (e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase51.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase51.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase51.hs
@@ -0,0 +1,21 @@
+{-# LANGUAGE QuasiQuotes       #-}
+{-# LANGUAGE DataKinds         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions  #-}
+{-# LANGUAGE TypeApplications  #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Positive: guarded wildcard only, no explicit constructors
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         _ | isZero e  -> e .== e =: qed
+           | sTrue     -> e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase51.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase51.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase51.stderr
@@ -0,0 +1,11 @@
+PCase51.hs:(18,15)-(21,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         _ | isZero e  -> e .== e =: qed\n\
+      \           | sTrue     -> e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)),
+       (sNot (isZero e) ==> (e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase52.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase52.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase52.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Negative: guarded wildcard before explicit constructor matches
+t :: SExpr -> Proof SBool
+t e = [pCase| e of
+        Zero       -> undefined
+        _ | sTrue  -> undefined
+        Num _      -> undefined
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase52.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase52.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase52.stderr
@@ -0,0 +1,14 @@
+PCase52.hs:13:14: error: [GHC-39584]
+    " PCase52.hs:15:9: pCase: Wildcard makes the remaining matches redundant:
+        PCase52.hs:16:9-13: Num _
+
+    " In the quasi-quotation:
+        [pCase| e of
+        Zero       -> undefined
+        _ | sTrue  -> undefined
+        Num _      -> undefined
+      |]
+   |
+13 | t e = [pCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase53.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase53.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase53.hs
@@ -0,0 +1,24 @@
+{-# LANGUAGE QuasiQuotes       #-}
+{-# LANGUAGE DataKinds         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions  #-}
+{-# LANGUAGE TypeApplications  #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Dump test: simple unguarded, all constructors
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero      -> e .== e =: qed
+         Num _     -> e .== e =: qed
+         Var _     -> e .== e =: qed
+         Add _ _   -> e .== e =: qed
+         Let _ _ _ -> e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase53.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase53.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase53.stderr
@@ -0,0 +1,15 @@
+PCase53.hs:(18,15)-(24,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero      -> e .== e =: qed\n\
+      \         Num _     -> e .== e =: qed\n\
+      \         Var _     -> e .== e =: qed\n\
+      \         Add _ _   -> e .== e =: qed\n\
+      \         Let _ _ _ -> e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)), (isNum e ==> (e .== e =: qed)),
+       (isVar e ==> (e .== e =: qed)), (isAdd e ==> (e .== e =: qed)),
+       (isLet e ==> (e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase54.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase54.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase54.hs
@@ -0,0 +1,26 @@
+{-# LANGUAGE QuasiQuotes       #-}
+{-# LANGUAGE DataKinds         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions  #-}
+{-# LANGUAGE TypeApplications  #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Dump test: multiple guards on same constructor (guard accumulation)
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero              -> e .== e =: qed
+         Num i | i .< 3    -> e .== e =: qed
+               | i .< 10   -> e .== e =: qed
+               | sTrue     -> e .== e =: qed
+         Var _             -> e .== e =: qed
+         Add _ _           -> e .== e =: qed
+         Let _ _ _         -> e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase54.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase54.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase54.stderr
@@ -0,0 +1,31 @@
+PCase54.hs:(18,15)-(26,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero              -> e .== e =: qed\n\
+      \         Num i | i .< 3    -> e .== e =: qed\n\
+      \               | i .< 10   -> e .== e =: qed\n\
+      \               | sTrue     -> e .== e =: qed\n\
+      \         Var _             -> e .== e =: qed\n\
+      \         Add _ _           -> e .== e =: qed\n\
+      \         Let _ _ _         -> e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)),
+       ((.&&) (isNum e) (let i = getNum_1 e in i .< 3)
+          ==> (e .== e =: qed)),
+       ((.&&)
+          (isNum e)
+          ((.&&)
+             (sNot (let i = getNum_1 e in i .< 3))
+             (let i = getNum_1 e in i .< 10))
+          ==> (e .== e =: qed)),
+       ((.&&)
+          (isNum e)
+          ((.&&)
+             (sNot (let i = getNum_1 e in i .< 3))
+             (sNot (let i = getNum_1 e in i .< 10)))
+          ==> (e .== e =: qed)),
+       (isVar e ==> (e .== e =: qed)), (isAdd e ==> (e .== e =: qed)),
+       (isLet e ==> (e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase55.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase55.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase55.hs
@@ -0,0 +1,22 @@
+{-# LANGUAGE QuasiQuotes       #-}
+{-# LANGUAGE DataKinds         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions  #-}
+{-# LANGUAGE TypeApplications  #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Dump test: wildcard after some constructors (De Morgan negation)
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Zero      -> e .== e =: qed
+         Num _     -> e .== e =: qed
+         _         -> e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase55.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase55.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase55.stderr
@@ -0,0 +1,12 @@
+PCase55.hs:(18,15)-(22,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero      -> e .== e =: qed\n\
+      \         Num _     -> e .== e =: qed\n\
+      \         _         -> e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)), (isNum e ==> (e .== e =: qed)),
+       (sNot ((.||) (isZero e) (isNum e)) ==> (e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase56.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase56.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase56.hs
@@ -0,0 +1,23 @@
+{-# LANGUAGE QuasiQuotes       #-}
+{-# LANGUAGE DataKinds         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions  #-}
+{-# LANGUAGE TypeApplications  #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Dump test: guarded wildcard + nested pattern on a constructor
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Add (Num i) _ | i .> 0  -> e .== e =: qed
+         Add _ _                  -> e .== e =: qed
+         _ | isZero e             -> e .== e =: qed
+           | sTrue                -> e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase56.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase56.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase56.stderr
@@ -0,0 +1,62 @@
+PCase56.hs:(18,15)-(23,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Add (Num i) _ | i .> 0  -> e .== e =: qed\n\
+      \         Add _ _                  -> e .== e =: qed\n\
+      \         _ | isZero e             -> e .== e =: qed\n\
+      \           | sTrue                -> e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [((.&&)
+          (isAdd e)
+          ((.&&)
+             (isNum (getAdd_1 e)) (let i = getNum_1 (getAdd_1 e) in i .> 0))
+          ==> (e .== e =: qed)),
+       ((.&&)
+          (isAdd e)
+          (sNot
+             ((.&&)
+                (isNum (getAdd_1 e)) (let i = getNum_1 (getAdd_1 e) in i .> 0)))
+          ==> (e .== e =: qed)),
+       ((.&&)
+          (sNot
+             ((.||)
+                ((.&&)
+                   (isAdd e)
+                   ((.&&)
+                      (isNum (getAdd_1 e)) (let i = getNum_1 (getAdd_1 e) in i .> 0)))
+                ((.&&)
+                   (isAdd e)
+                   (sNot
+                      ((.&&)
+                         (isNum (getAdd_1 e)) (let i = getNum_1 (getAdd_1 e) in i .> 0))))))
+          (isZero e)
+          ==> (e .== e =: qed)),
+       (sNot
+          ((.||)
+             ((.||)
+                ((.&&)
+                   (isAdd e)
+                   ((.&&)
+                      (isNum (getAdd_1 e)) (let i = getNum_1 (getAdd_1 e) in i .> 0)))
+                ((.&&)
+                   (isAdd e)
+                   (sNot
+                      ((.&&)
+                         (isNum (getAdd_1 e)) (let i = getNum_1 (getAdd_1 e) in i .> 0)))))
+             ((.&&)
+                (sNot
+                   ((.||)
+                      ((.&&)
+                         (isAdd e)
+                         ((.&&)
+                            (isNum (getAdd_1 e)) (let i = getNum_1 (getAdd_1 e) in i .> 0)))
+                      ((.&&)
+                         (isAdd e)
+                         (sNot
+                            ((.&&)
+                               (isNum (getAdd_1 e)) (let i = getNum_1 (getAdd_1 e) in i .> 0))))))
+                (isZero e)))
+          ==> (e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase57.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase57.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase57.hs
@@ -0,0 +1,22 @@
+{-# LANGUAGE QuasiQuotes       #-}
+{-# LANGUAGE DataKinds         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions  #-}
+{-# LANGUAGE TypeApplications  #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Dump test: nested pattern variable used in both guard and RHS
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Add (Num i) _ | i .> 0  -> sNum i .== sNum i =: e .== e =: qed
+         Add _ _                  -> e .== e =: qed
+         _                        -> e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase57.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase57.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase57.stderr
@@ -0,0 +1,35 @@
+PCase57.hs:(18,15)-(22,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Add (Num i) _ | i .> 0  -> sNum i .== sNum i =: e .== e =: qed\n\
+      \         Add _ _                  -> e .== e =: qed\n\
+      \         _                        -> e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [((.&&)
+          (isAdd e)
+          ((.&&)
+             (isNum (getAdd_1 e)) (let i = getNum_1 (getAdd_1 e) in i .> 0))
+          ==>
+            (let i = getNum_1 (getAdd_1 e)
+             in (sNum i) .== sNum i =: e .== e =: qed)),
+       ((.&&)
+          (isAdd e)
+          (sNot
+             ((.&&)
+                (isNum (getAdd_1 e)) (let i = getNum_1 (getAdd_1 e) in i .> 0)))
+          ==> (e .== e =: qed)),
+       (sNot
+          ((.||)
+             ((.&&)
+                (isAdd e)
+                ((.&&)
+                   (isNum (getAdd_1 e)) (let i = getNum_1 (getAdd_1 e) in i .> 0)))
+             ((.&&)
+                (isAdd e)
+                (sNot
+                   ((.&&)
+                      (isNum (getAdd_1 e)) (let i = getNum_1 (getAdd_1 e) in i .> 0)))))
+          ==> (e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase58.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase58.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase58.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE QuasiQuotes       #-}
+{-# LANGUAGE DataKinds         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions  #-}
+{-# LANGUAGE TypeApplications  #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Dump test: multiple guarded arms on nested pattern, variable in guard + RHS, wildcard
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Let s (Num i) b | i .> 0   -> sLet s (sNum i) b .== sLet s (sNum i) b =: e .== e =: qed
+                          | i .> -5  -> sLet s (sNum i) b .== sLet s (sNum i) b =: e .== e =: qed
+                          | sTrue    -> sLet s (sNum i) b .== sLet s (sNum i) b =: e .== e =: qed
+         Let s a b                   -> sLet s a b .== sLet s a b =: e .== e =: qed
+         Add (Num i) (Num j)         -> sAdd (sNum i) (sNum j) .== sAdd (sNum i) (sNum j) =: e .== e =: qed
+         _                           -> e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase58.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase58.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase58.stderr
@@ -0,0 +1,127 @@
+PCase58.hs:(18,15)-(25,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Let s (Num i) b | i .> 0   -> sLet s (sNum i) b .== sLet s (sNum i) b =: e .== e =: qed\n\
+      \                          | i .> -5  -> sLet s (sNum i) b .== sLet s (sNum i) b =: e .== e =: qed\n\
+      \                          | sTrue    -> sLet s (sNum i) b .== sLet s (sNum i) b =: e .== e =: qed\n\
+      \         Let s a b                   -> sLet s a b .== sLet s a b =: e .== e =: qed\n\
+      \         Add (Num i) (Num j)         -> sAdd (sNum i) (sNum j) .== sAdd (sNum i) (sNum j) =: e .== e =: qed\n\
+      \         _                           -> e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [((.&&)
+          (isLet e)
+          ((.&&)
+             (isNum (getLet_2 e)) (let i = getNum_1 (getLet_2 e) in i .> 0))
+          ==>
+            (let
+               s = getLet_1 e
+               b = getLet_3 e in
+             let i = getNum_1 (getLet_2 e)
+             in (sLet s (sNum i) b) .== sLet s (sNum i) b =: e .== e =: qed)),
+       ((.&&)
+          (isLet e)
+          ((.&&)
+             (sNot
+                ((.&&)
+                   (isNum (getLet_2 e)) (let i = getNum_1 (getLet_2 e) in i .> 0)))
+             ((.&&)
+                (isNum (getLet_2 e))
+                (let i = getNum_1 (getLet_2 e) in i .> negate 5)))
+          ==>
+            (let
+               s = getLet_1 e
+               b = getLet_3 e in
+             let i = getNum_1 (getLet_2 e)
+             in (sLet s (sNum i) b) .== sLet s (sNum i) b =: e .== e =: qed)),
+       ((.&&)
+          (isLet e)
+          ((.&&)
+             (sNot
+                ((.&&)
+                   (isNum (getLet_2 e)) (let i = getNum_1 (getLet_2 e) in i .> 0)))
+             ((.&&)
+                (sNot
+                   ((.&&)
+                      (isNum (getLet_2 e))
+                      (let i = getNum_1 (getLet_2 e) in i .> negate 5)))
+                (isNum (getLet_2 e))))
+          ==>
+            (let
+               s = getLet_1 e
+               b = getLet_3 e in
+             let i = getNum_1 (getLet_2 e)
+             in (sLet s (sNum i) b) .== sLet s (sNum i) b =: e .== e =: qed)),
+       ((.&&)
+          (isLet e)
+          ((.&&)
+             (sNot
+                ((.&&)
+                   (isNum (getLet_2 e)) (let i = getNum_1 (getLet_2 e) in i .> 0)))
+             ((.&&)
+                (sNot
+                   ((.&&)
+                      (isNum (getLet_2 e))
+                      (let i = getNum_1 (getLet_2 e) in i .> negate 5)))
+                (sNot (isNum (getLet_2 e)))))
+          ==>
+            (let
+               s = getLet_1 e
+               a = getLet_2 e
+               b = getLet_3 e
+             in (sLet s a b) .== sLet s a b =: e .== e =: qed)),
+       ((.&&) (isAdd e) ((.&&) (isNum (getAdd_1 e)) (isNum (getAdd_2 e)))
+          ==>
+            (let
+               i = getNum_1 (getAdd_1 e)
+               j = getNum_1 (getAdd_2 e)
+             in
+               (sAdd (sNum i) (sNum j)) .== sAdd (sNum i) (sNum j) =: e .== e
+                 =: qed)),
+       (sNot
+          ((.||)
+             ((.||)
+                ((.||)
+                   ((.||)
+                      ((.&&)
+                         (isLet e)
+                         ((.&&)
+                            (isNum (getLet_2 e)) (let i = getNum_1 (getLet_2 e) in i .> 0)))
+                      ((.&&)
+                         (isLet e)
+                         ((.&&)
+                            (sNot
+                               ((.&&)
+                                  (isNum (getLet_2 e)) (let i = getNum_1 (getLet_2 e) in i .> 0)))
+                            ((.&&)
+                               (isNum (getLet_2 e))
+                               (let i = getNum_1 (getLet_2 e) in i .> negate 5)))))
+                   ((.&&)
+                      (isLet e)
+                      ((.&&)
+                         (sNot
+                            ((.&&)
+                               (isNum (getLet_2 e)) (let i = getNum_1 (getLet_2 e) in i .> 0)))
+                         ((.&&)
+                            (sNot
+                               ((.&&)
+                                  (isNum (getLet_2 e))
+                                  (let i = getNum_1 (getLet_2 e) in i .> negate 5)))
+                            (isNum (getLet_2 e))))))
+                ((.&&)
+                   (isLet e)
+                   ((.&&)
+                      (sNot
+                         ((.&&)
+                            (isNum (getLet_2 e)) (let i = getNum_1 (getLet_2 e) in i .> 0)))
+                      ((.&&)
+                         (sNot
+                            ((.&&)
+                               (isNum (getLet_2 e))
+                               (let i = getNum_1 (getLet_2 e) in i .> negate 5)))
+                         (sNot (isNum (getLet_2 e)))))))
+             ((.&&)
+                (isAdd e) ((.&&) (isNum (getAdd_1 e)) (isNum (getAdd_2 e)))))
+          ==> (e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase59.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase59.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase59.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE QuasiQuotes       #-}
+{-# LANGUAGE DataKinds         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions  #-}
+{-# LANGUAGE TypeApplications  #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Dump test: interleaved constructors (Let/Add/Let), linear processing
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Let s a b | isZero a -> sLet s a b .== sLet s a b =: e .== e =: qed
+         Add a b              -> sAdd a b .== sAdd a b =: e .== e =: qed
+         Let s a b            -> sLet s a b .== sLet s a b =: e .== e =: qed
+         Zero                 -> e .== e =: qed
+         Num _                -> e .== e =: qed
+         Var _                -> e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase59.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase59.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase59.stderr
@@ -0,0 +1,35 @@
+PCase59.hs:(18,15)-(25,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Let s a b | isZero a -> sLet s a b .== sLet s a b =: e .== e =: qed\n\
+      \         Add a b              -> sAdd a b .== sAdd a b =: e .== e =: qed\n\
+      \         Let s a b            -> sLet s a b .== sLet s a b =: e .== e =: qed\n\
+      \         Zero                 -> e .== e =: qed\n\
+      \         Num _                -> e .== e =: qed\n\
+      \         Var _                -> e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [((.&&) (isLet e) (let a = getLet_2 e in isZero a)
+          ==>
+            (let
+               s = getLet_1 e
+               a = getLet_2 e
+               b = getLet_3 e
+             in (sLet s a b) .== sLet s a b =: e .== e =: qed)),
+       (isAdd e
+          ==>
+            (let
+               a = getAdd_1 e
+               b = getAdd_2 e
+             in (sAdd a b) .== sAdd a b =: e .== e =: qed)),
+       ((.&&) (isLet e) (sNot (let a = getLet_2 e in isZero a))
+          ==>
+            (let
+               s = getLet_1 e
+               a = getLet_2 e
+               b = getLet_3 e
+             in (sLet s a b) .== sLet s a b =: e .== e =: qed)),
+       (isZero e ==> (e .== e =: qed)), (isNum e ==> (e .== e =: qed)),
+       (isVar e ==> (e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase60.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase60.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase60.hs
@@ -0,0 +1,33 @@
+{-# LANGUAGE QuasiQuotes       #-}
+{-# LANGUAGE DataKinds         #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions  #-}
+{-# LANGUAGE TypeApplications  #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+-- Dump test: linear processing stress test
+--   - Interleaved constructors (Add / Num / Add)
+--   - Nested patterns with guards
+--   - Guard variables used in both guard and RHS
+--   - Var with guard, then unguarded Var later
+--   - Multiple guarded wildcards at the end
+t :: TP (Proof (Forall "e" Expr -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Add (Num i) b | i .> 0  -> sAdd (sNum i) b .== sAdd (sNum i) b =: e .== e =: qed
+         Num i | i .> 0           -> sNum i .== sNum i =: e .== e =: qed
+         Var s | s .== literal "hey" -> sVar s .== sVar s =: e .== e =: qed
+         Add a b                  -> sAdd a b .== sAdd a b =: e .== e =: qed
+         Num i                    -> sNum i .== sNum i =: e .== e =: qed
+         Var s                    -> sVar s .== sVar s =: e .== e =: qed
+         Zero                     -> e .== e =: qed
+         _ | isLet e              -> e .== e =: qed
+         _                        -> e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase60.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase60.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase60.stderr
@@ -0,0 +1,120 @@
+PCase60.hs:(23,15)-(33,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Add (Num i) b | i .> 0  -> sAdd (sNum i) b .== sAdd (sNum i) b =: e .== e =: qed\n\
+      \         Num i | i .> 0           -> sNum i .== sNum i =: e .== e =: qed\n\
+      \         Var s | s .== literal \"hey\" -> sVar s .== sVar s =: e .== e =: qed\n\
+      \         Add a b                  -> sAdd a b .== sAdd a b =: e .== e =: qed\n\
+      \         Num i                    -> sNum i .== sNum i =: e .== e =: qed\n\
+      \         Var s                    -> sVar s .== sVar s =: e .== e =: qed\n\
+      \         Zero                     -> e .== e =: qed\n\
+      \         _ | isLet e              -> e .== e =: qed\n\
+      \         _                        -> e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [((.&&)
+          (isAdd e)
+          ((.&&)
+             (isNum (getAdd_1 e)) (let i = getNum_1 (getAdd_1 e) in i .> 0))
+          ==>
+            (let b = getAdd_2 e in
+             let i = getNum_1 (getAdd_1 e)
+             in (sAdd (sNum i) b) .== sAdd (sNum i) b =: e .== e =: qed)),
+       ((.&&) (isNum e) (let i = getNum_1 e in i .> 0)
+          ==> (let i = getNum_1 e in (sNum i) .== sNum i =: e .== e =: qed)),
+       ((.&&) (isVar e) (let s = getVar_1 e in s .== literal "hey")
+          ==> (let s = getVar_1 e in (sVar s) .== sVar s =: e .== e =: qed)),
+       ((.&&)
+          (isAdd e)
+          (sNot
+             ((.&&)
+                (isNum (getAdd_1 e)) (let i = getNum_1 (getAdd_1 e) in i .> 0)))
+          ==>
+            (let
+               a = getAdd_1 e
+               b = getAdd_2 e
+             in (sAdd a b) .== sAdd a b =: e .== e =: qed)),
+       ((.&&) (isNum e) (sNot (let i = getNum_1 e in i .> 0))
+          ==> (let i = getNum_1 e in (sNum i) .== sNum i =: e .== e =: qed)),
+       ((.&&) (isVar e) (sNot (let s = getVar_1 e in s .== literal "hey"))
+          ==> (let s = getVar_1 e in (sVar s) .== sVar s =: e .== e =: qed)),
+       (isZero e ==> (e .== e =: qed)),
+       ((.&&)
+          (sNot
+             ((.||)
+                ((.||)
+                   ((.||)
+                      ((.||)
+                         ((.||)
+                            ((.||)
+                               ((.&&)
+                                  (isAdd e)
+                                  ((.&&)
+                                     (isNum (getAdd_1 e))
+                                     (let i = getNum_1 (getAdd_1 e) in i .> 0)))
+                               ((.&&) (isNum e) (let i = getNum_1 e in i .> 0)))
+                            ((.&&) (isVar e) (let s = getVar_1 e in s .== literal "hey")))
+                         ((.&&)
+                            (isAdd e)
+                            (sNot
+                               ((.&&)
+                                  (isNum (getAdd_1 e)) (let i = getNum_1 (getAdd_1 e) in i .> 0)))))
+                      ((.&&) (isNum e) (sNot (let i = getNum_1 e in i .> 0))))
+                   ((.&&)
+                      (isVar e) (sNot (let s = getVar_1 e in s .== literal "hey"))))
+                (isZero e)))
+          (isLet e)
+          ==> (e .== e =: qed)),
+       (sNot
+          ((.||)
+             ((.||)
+                ((.||)
+                   ((.||)
+                      ((.||)
+                         ((.||)
+                            ((.||)
+                               ((.&&)
+                                  (isAdd e)
+                                  ((.&&)
+                                     (isNum (getAdd_1 e))
+                                     (let i = getNum_1 (getAdd_1 e) in i .> 0)))
+                               ((.&&) (isNum e) (let i = getNum_1 e in i .> 0)))
+                            ((.&&) (isVar e) (let s = getVar_1 e in s .== literal "hey")))
+                         ((.&&)
+                            (isAdd e)
+                            (sNot
+                               ((.&&)
+                                  (isNum (getAdd_1 e)) (let i = getNum_1 (getAdd_1 e) in i .> 0)))))
+                      ((.&&) (isNum e) (sNot (let i = getNum_1 e in i .> 0))))
+                   ((.&&)
+                      (isVar e) (sNot (let s = getVar_1 e in s .== literal "hey"))))
+                (isZero e))
+             ((.&&)
+                (sNot
+                   ((.||)
+                      ((.||)
+                         ((.||)
+                            ((.||)
+                               ((.||)
+                                  ((.||)
+                                     ((.&&)
+                                        (isAdd e)
+                                        ((.&&)
+                                           (isNum (getAdd_1 e))
+                                           (let i = getNum_1 (getAdd_1 e) in i .> 0)))
+                                     ((.&&) (isNum e) (let i = getNum_1 e in i .> 0)))
+                                  ((.&&) (isVar e) (let s = getVar_1 e in s .== literal "hey")))
+                               ((.&&)
+                                  (isAdd e)
+                                  (sNot
+                                     ((.&&)
+                                        (isNum (getAdd_1 e))
+                                        (let i = getNum_1 (getAdd_1 e) in i .> 0)))))
+                            ((.&&) (isNum e) (sNot (let i = getNum_1 e in i .> 0))))
+                         ((.&&)
+                            (isVar e) (sNot (let s = getVar_1 e in s .== literal "hey"))))
+                      (isZero e)))
+                (isLet e)))
+          ==> (e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase61.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase61.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase61.hs
@@ -0,0 +1,20 @@
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: pCase with Maybe
+module T where
+
+import Data.SBV
+import Data.SBV.TP
+
+t :: TP (Proof (Forall "m" (Maybe Integer) -> SBool))
+t = calc "t" (\(Forall @"m" (m :: SMaybe Integer)) -> m .== m) $ \m -> []
+    |- [pCase| m of
+         Nothing -> m .== m =: qed
+         Just _  -> m .== m =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase61.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase61.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase61.stderr
@@ -0,0 +1,11 @@
+PCase61.hs:(17,15)-(20,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " m of\n\
+      \         Nothing -> m .== m =: qed\n\
+      \         Just _  -> m .== m =: qed\n\
+      \       "
+  ======>
+    cases
+      [(Data.SBV.Maybe.isNothing m ==> (m .== m =: qed)),
+       (Data.SBV.Maybe.isJust m ==> (m .== m =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase62.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase62.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase62.hs
@@ -0,0 +1,20 @@
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: pCase with Either
+module T where
+
+import Data.SBV
+import Data.SBV.TP
+
+t :: TP (Proof (Forall "e" (Either Integer Bool) -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SEither Integer Bool)) -> e .== e) $ \e -> []
+    |- [pCase| e of
+         Left _  -> e .== e =: qed
+         Right _ -> e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase62.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase62.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase62.stderr
@@ -0,0 +1,11 @@
+PCase62.hs:(17,15)-(20,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Left _  -> e .== e =: qed\n\
+      \         Right _ -> e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(Data.SBV.Either.isLeft e ==> (e .== e =: qed)),
+       (Data.SBV.Either.isRight e ==> (e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase63.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase63.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase63.hs
@@ -0,0 +1,22 @@
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE OverloadedLists     #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: pCase with List
+module T where
+
+import Prelude hiding (null, head, tail)
+import Data.SBV
+import Data.SBV.TP
+
+t :: TP (Proof (Forall "xs" [Integer] -> SBool))
+t = calc "t" (\(Forall @"xs" (xs :: SList Integer)) -> xs .== xs) $ \xs -> []
+    |- [pCase| xs of
+         []    -> xs .== xs =: qed
+         _ : _ -> xs .== xs =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase63.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase63.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase63.stderr
@@ -0,0 +1,14 @@
+PCase63.hs:(19,15)-(22,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " xs of\n\
+      \         []    -> xs .== xs =: qed\n\
+      \         _ : _ -> xs .== xs =: qed\n\
+      \       "
+  ======>
+    cases
+      [(Data.SBV.List.null xs ==> (xs .== xs =: qed)),
+       ((.&&)
+          (sNot (Data.SBV.List.null xs))
+          ((.===) xs (Data.SBV.List.head xs .: Data.SBV.List.tail xs))
+          ==> (xs .== xs =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase64.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase64.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase64.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: pCase with Tuple2
+module T where
+
+import Data.SBV
+import Data.SBV.TP
+
+t :: TP (Proof (Forall "p" (Integer, Bool) -> SBool))
+t = calc "t" (\(Forall @"p" (p :: STuple Integer Bool)) -> p .== p) $ \p -> []
+    |- [pCase| p of
+         (_, _) -> p .== p =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase64.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase64.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase64.stderr
@@ -0,0 +1,8 @@
+PCase64.hs:(17,15)-(19,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " p of\n\
+      \         (_, _) -> p .== p =: qed\n\
+      \       "
+  ======>
+    cases [(sTrue ==> (p .== p =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase65.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase65.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase65.hs
@@ -0,0 +1,21 @@
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: pCase with Maybe, guards on Just
+module T where
+
+import Data.SBV
+import Data.SBV.TP
+
+t :: TP (Proof (Forall "m" (Maybe Integer) -> SBool))
+t = calc "t" (\(Forall @"m" (m :: SMaybe Integer)) -> m .== m) $ \m -> []
+    |- [pCase| m of
+         Nothing          -> m .== m =: qed
+         Just x | x .> 0  -> m .== m =: qed
+                | sTrue    -> m .== m =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase65.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase65.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase65.stderr
@@ -0,0 +1,19 @@
+PCase65.hs:(17,15)-(21,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " m of\n\
+      \         Nothing          -> m .== m =: qed\n\
+      \         Just x | x .> 0  -> m .== m =: qed\n\
+      \                | sTrue    -> m .== m =: qed\n\
+      \       "
+  ======>
+    cases
+      [(Data.SBV.Maybe.isNothing m ==> (m .== m =: qed)),
+       ((.&&)
+          (Data.SBV.Maybe.isJust m)
+          (let x = Data.SBV.Maybe.getJust_1 m in x .> 0)
+          ==> (m .== m =: qed)),
+       ((.&&)
+          (Data.SBV.Maybe.isJust m)
+          (sNot (let x = Data.SBV.Maybe.getJust_1 m in x .> 0))
+          ==> (m .== m =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase66.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase66.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase66.hs
@@ -0,0 +1,23 @@
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE OverloadedLists     #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: pCase with List, guards and wildcard
+module T where
+
+import Prelude hiding (null, head, tail)
+import Data.SBV
+import Data.SBV.TP
+
+t :: TP (Proof (Forall "xs" [Integer] -> SBool))
+t = calc "t" (\(Forall @"xs" (xs :: SList Integer)) -> xs .== xs) $ \xs -> []
+    |- [pCase| xs of
+         []             -> xs .== xs =: qed
+         y : _ | y .> 0 -> xs .== xs =: qed
+         _              -> xs .== xs =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase66.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase66.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase66.stderr
@@ -0,0 +1,26 @@
+PCase66.hs:(19,15)-(23,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " xs of\n\
+      \         []             -> xs .== xs =: qed\n\
+      \         y : _ | y .> 0 -> xs .== xs =: qed\n\
+      \         _              -> xs .== xs =: qed\n\
+      \       "
+  ======>
+    cases
+      [(Data.SBV.List.null xs ==> (xs .== xs =: qed)),
+       ((.&&)
+          (sNot (Data.SBV.List.null xs))
+          ((.&&)
+             ((.===) xs (Data.SBV.List.head xs .: Data.SBV.List.tail xs))
+             (let y = Data.SBV.List.head xs in y .> 0))
+          ==> (xs .== xs =: qed)),
+       (sNot
+          ((.||)
+             (Data.SBV.List.null xs)
+             ((.&&)
+                (sNot (Data.SBV.List.null xs))
+                ((.&&)
+                   ((.===) xs (Data.SBV.List.head xs .: Data.SBV.List.tail xs))
+                   (let y = Data.SBV.List.head xs in y .> 0))))
+          ==> (xs .== xs =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase67.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase67.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase67.hs
@@ -0,0 +1,24 @@
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE OverloadedLists     #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: pCase with List, nested cons pattern with bindings
+module T where
+
+import Prelude hiding (null, head, tail, length)
+import Data.SBV
+import Data.SBV.List (length)
+import Data.SBV.TP
+
+t :: TP (Proof (Forall "xs" [Integer] -> SBool))
+t = calc "t" (\(Forall @"xs" (xs :: SList Integer)) -> length xs .>= 0) $ \xs -> []
+    |- [pCase| xs of
+         []              -> length xs .>= 0 =: qed
+         _ : (_ : _)     -> length xs .>= 0 =: qed
+         _ : _           -> length xs .>= 0 =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase67.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase67.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase67.stderr
@@ -0,0 +1,34 @@
+PCase67.hs:(20,15)-(24,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " xs of\n\
+      \         []              -> length xs .>= 0 =: qed\n\
+      \         _ : (_ : _)     -> length xs .>= 0 =: qed\n\
+      \         _ : _           -> length xs .>= 0 =: qed\n\
+      \       "
+  ======>
+    cases
+      [(Data.SBV.List.null xs ==> ((length xs) .>= 0 =: qed)),
+       ((.&&)
+          (sNot (Data.SBV.List.null xs))
+          ((.&&)
+             ((.===) xs (Data.SBV.List.head xs .: Data.SBV.List.tail xs))
+             ((.&&)
+                (sNot (Data.SBV.List.null (Data.SBV.List.tail xs)))
+                ((.===)
+                   (Data.SBV.List.tail xs)
+                   (Data.SBV.List.head (Data.SBV.List.tail xs)
+                      .: Data.SBV.List.tail (Data.SBV.List.tail xs)))))
+          ==> ((length xs) .>= 0 =: qed)),
+       ((.&&)
+          (sNot (Data.SBV.List.null xs))
+          ((.&&)
+             ((.===) xs (Data.SBV.List.head xs .: Data.SBV.List.tail xs))
+             (sNot
+                ((.&&)
+                   (sNot (Data.SBV.List.null (Data.SBV.List.tail xs)))
+                   ((.===)
+                      (Data.SBV.List.tail xs)
+                      (Data.SBV.List.head (Data.SBV.List.tail xs)
+                         .: Data.SBV.List.tail (Data.SBV.List.tail xs))))))
+          ==> ((length xs) .>= 0 =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase68.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase68.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase68.hs
@@ -0,0 +1,20 @@
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: pCase with Bool constructor patterns
+module T where
+
+import Data.SBV
+import Data.SBV.TP
+
+t :: TP (Proof (Forall "b" Bool -> SBool))
+t = calc "t" (\(Forall @"b" (b :: SBool)) -> b .== b) $ \b -> []
+    |- [pCase| b of
+         True  -> b .== b =: qed
+         False -> b .== b =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase68.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase68.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase68.stderr
@@ -0,0 +1,9 @@
+PCase68.hs:(17,15)-(20,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " b of\n\
+      \         True  -> b .== b =: qed\n\
+      \         False -> b .== b =: qed\n\
+      \       "
+  ======>
+    cases [(b ==> (b .== b =: qed)), (sNot b ==> (b .== b =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase69.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase69.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase69.hs
@@ -0,0 +1,21 @@
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: pCase with Bool, guard on True
+module T where
+
+import Data.SBV
+import Data.SBV.TP
+
+t :: TP (Proof (Forall "b" Bool -> Forall "x" Integer -> SBool))
+t = calc "t" (\(Forall @"b" (b :: SBool)) (Forall @"x" (x :: SInteger)) -> b .|| sNot b) $ \b x -> []
+    |- [pCase| b of
+         True  | x .> 0 -> b .|| sNot b =: qed
+               | sTrue  -> b .|| sNot b =: qed
+         False           -> b .|| sNot b =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase69.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase69.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase69.stderr
@@ -0,0 +1,19 @@
+PCase69.hs:(17,15)-(21,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " b of\n\
+      \         True  | x .> 0 -> b .|| sNot b =: qed\n\
+      \               | sTrue  -> b .|| sNot b =: qed\n\
+      \         False           -> b .|| sNot b =: qed\n\
+      \       "
+  ======>
+    cases
+      [((.&&) b (x .> 0) ==> (b .|| sNot b =: qed)),
+       ((.&&) b (sNot (x .> 0)) ==> (b .|| sNot b =: qed)),
+       (sNot b ==> (b .|| sNot b =: qed))]
+PCase69.hs:16:57: error: [GHC-40910] [-Wunused-matches, Werror=unused-matches]
+    Defined but not used: x
+   |
+16 | t = calc "t" (\(Forall @"b" (b :: SBool)) (Forall @"x" (x :: SInteger)) -> b .|| sNot b) $ \b x -> []
+   |                                                         ^
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase70.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase70.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase70.hs
@@ -0,0 +1,21 @@
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: pCase with Integer literal patterns and wildcard
+module T where
+
+import Data.SBV
+import Data.SBV.TP
+
+t :: TP (Proof (Forall "x" Integer -> SBool))
+t = calc "t" (\(Forall @"x" (x :: SInteger)) -> x .== x) $ \x -> []
+    |- [pCase| x of
+         0 -> x .== x =: qed
+         1 -> x .== x =: qed
+         _ -> x .== x =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase70.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase70.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase70.stderr
@@ -0,0 +1,14 @@
+PCase70.hs:(17,15)-(21,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " x of\n\
+      \         0 -> x .== x =: qed\n\
+      \         1 -> x .== x =: qed\n\
+      \         _ -> x .== x =: qed\n\
+      \       "
+  ======>
+    cases
+      [((.==) x 0 ==> (x .== x =: qed)),
+       ((.&&) (sNot ((.==) x 0)) ((.==) x 1) ==> (x .== x =: qed)),
+       (sNot ((.||) ((.==) x 0) ((.&&) (sNot ((.==) x 0)) ((.==) x 1)))
+          ==> (x .== x =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase71.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase71.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase71.hs
@@ -0,0 +1,21 @@
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: pCase with Char literal patterns and wildcard
+module T where
+
+import Data.SBV
+import Data.SBV.TP
+
+t :: TP (Proof (Forall "c" Char -> SBool))
+t = calc "t" (\(Forall @"c" (c :: SChar)) -> c .== c) $ \c -> []
+    |- [pCase| c of
+         'a' -> c .== c =: qed
+         'b' -> c .== c =: qed
+         _   -> c .== c =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase71.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase71.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase71.stderr
@@ -0,0 +1,18 @@
+PCase71.hs:(17,15)-(21,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " c of\n\
+      \         'a' -> c .== c =: qed\n\
+      \         'b' -> c .== c =: qed\n\
+      \         _   -> c .== c =: qed\n\
+      \       "
+  ======>
+    cases
+      [((.==) c (literal 'a') ==> (c .== c =: qed)),
+       ((.&&) (sNot ((.==) c (literal 'a'))) ((.==) c (literal 'b'))
+          ==> (c .== c =: qed)),
+       (sNot
+          ((.||)
+             ((.==) c (literal 'a'))
+             ((.&&) (sNot ((.==) c (literal 'a'))) ((.==) c (literal 'b'))))
+          ==> (c .== c =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase72.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase72.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase72.hs
@@ -0,0 +1,20 @@
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: pCase with String literal patterns and wildcard
+module T where
+
+import Data.SBV
+import Data.SBV.TP
+
+t :: TP (Proof (Forall "s" String -> SBool))
+t = calc "t" (\(Forall @"s" (s :: SString)) -> s .== s) $ \s -> []
+    |- [pCase| s of
+         "hello" -> s .== s =: qed
+         _       -> s .== s =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase72.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase72.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase72.stderr
@@ -0,0 +1,11 @@
+PCase72.hs:(17,15)-(20,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " s of\n\
+      \         \"hello\" -> s .== s =: qed\n\
+      \         _       -> s .== s =: qed\n\
+      \       "
+  ======>
+    cases
+      [((.==) s (literal "hello") ==> (s .== s =: qed)),
+       (sNot ((.==) s (literal "hello")) ==> (s .== s =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase73.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase73.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase73.hs
@@ -0,0 +1,21 @@
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: pCase with Integer variable binding and guard
+module T where
+
+import Data.SBV
+import Data.SBV.TP
+
+t :: TP (Proof (Forall "x" Integer -> SBool))
+t = calc "t" (\(Forall @"x" (x :: SInteger)) -> x .== x) $ \x -> []
+    |- [pCase| x of
+         0         -> x .== x =: qed
+         n | n .> 0 -> x .== x =: qed
+           | sTrue  -> x .== x =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase73.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase73.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase73.stderr
@@ -0,0 +1,17 @@
+PCase73.hs:(17,15)-(21,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " x of\n\
+      \         0         -> x .== x =: qed\n\
+      \         n | n .> 0 -> x .== x =: qed\n\
+      \           | sTrue  -> x .== x =: qed\n\
+      \       "
+  ======>
+    cases
+      [((.==) x 0 ==> (x .== x =: qed)),
+       ((.&&) (sNot ((.==) x 0)) (let n = x in n .> 0)
+          ==> (x .== x =: qed)),
+       (sNot
+          ((.||)
+             ((.==) x 0) ((.&&) (sNot ((.==) x 0)) (let n = x in n .> 0)))
+          ==> (x .== x =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase74.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase74.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase74.hs
@@ -0,0 +1,20 @@
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: pCase with Integer, no wildcard (only literals) — should fail with non-exhaustive
+module T where
+
+import Data.SBV
+import Data.SBV.TP
+
+t :: TP (Proof (Forall "x" Integer -> SBool))
+t = calc "t" (\(Forall @"x" (x :: SInteger)) -> x .== x) $ \x -> []
+    |- [pCase| x of
+         0 -> x .== x =: qed
+         1 -> x .== x =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase74.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase74.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase74.stderr
@@ -0,0 +1,14 @@
+PCase74.hs:17:15: error: [GHC-39584]
+    " PCase74.hs:18:10: pCase: Non-exhaustive pattern match.
+        All branches are guarded; add an unguarded wildcard or variable
+        as the last branch to ensure all cases are covered.
+
+    " In the quasi-quotation:
+        [pCase| x of
+         0 -> x .== x =: qed
+         1 -> x .== x =: qed
+       |]
+   |
+17 |     |- [pCase| x of
+   |               ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase75.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase75.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase75.hs
@@ -0,0 +1,20 @@
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: pCase with Bool non-exhaustive (only True)
+-- (sCase would reject as non-exhaustive; pCase is fine)
+module T where
+
+import Data.SBV
+import Data.SBV.TP
+
+t :: TP (Proof (Forall "b" Bool -> SBool))
+t = calc "t" (\(Forall @"b" (b :: SBool)) -> b .== b) $ \b -> []
+    |- [pCase| b of
+         True -> b .== b =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase75.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase75.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase75.stderr
@@ -0,0 +1,8 @@
+PCase75.hs:(18,15)-(20,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " b of\n\
+      \         True -> b .== b =: qed\n\
+      \       "
+  ======>
+    cases [(b ==> (b .== b =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase76.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase76.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase76.hs
@@ -0,0 +1,21 @@
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: pCase with negative integer literal
+module T where
+
+import Data.SBV
+import Data.SBV.TP
+
+t :: TP (Proof (Forall "x" Integer -> SBool))
+t = calc "t" (\(Forall @"x" (x :: SInteger)) -> x .== x) $ \x -> []
+    |- [pCase| x of
+         0    -> x .== x =: qed
+         (-1) -> x .== x =: qed
+         _    -> x .== x =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase76.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase76.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase76.stderr
@@ -0,0 +1,14 @@
+PCase76.hs:(17,15)-(21,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " x of\n\
+      \         0    -> x .== x =: qed\n\
+      \         (-1) -> x .== x =: qed\n\
+      \         _    -> x .== x =: qed\n\
+      \       "
+  ======>
+    cases
+      [((.==) x 0 ==> (x .== x =: qed)),
+       ((.&&) (sNot ((.==) x 0)) ((.==) x (-1)) ==> (x .== x =: qed)),
+       (sNot ((.||) ((.==) x 0) ((.&&) (sNot ((.==) x 0)) ((.==) x (-1))))
+          ==> (x .== x =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase77.hs b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase77.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase77.hs
@@ -0,0 +1,30 @@
+{-# LANGUAGE QuasiQuotes         #-}
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeAbstractions    #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror -Wno-name-shadowing -ddump-splices #-}
+
+-- Positive: Scoping regression test for pCase. Pattern var 'k' from 'Num k' is
+-- used in one branch of a nested case on SBool, while a sibling branch shadows
+-- 'k' with a let binding. Old scope-unaware freeVars would drop the accessor
+-- binding for 'k', causing a compilation error. See also SCase107 for the sCase
+-- counterpart.
+module T where
+
+import Expr
+import Data.SBV
+import Data.SBV.TP
+
+t :: TP (Proof (Forall "e" Expr -> Forall "b" Bool -> SBool))
+t = calc "t" (\(Forall @"e" (e :: SExpr)) (Forall @"b" (_ :: SBool)) -> e .== e) $ \e b -> []
+    |- [pCase| e of
+         Zero    -> e .== e =: qed
+         Num k   -> case b of
+                      True  -> let k = (0 :: SInteger) in k .== k =: e .== e =: qed
+                      False -> k .>= 0 .|| e .== e =: sTrue =: qed
+         Var _   -> e .== e =: qed
+         Add _ _ -> e .== e =: qed
+         Let _ _ _ -> e .== e =: qed
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/PCase/PCase77.stderr b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase77.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/PCase/PCase77.stderr
@@ -0,0 +1,24 @@
+PCase77.hs:(22,15)-(30,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      pCase
+      " e of\n\
+      \         Zero    -> e .== e =: qed\n\
+      \         Num k   -> case b of\n\
+      \                      True  -> let k = (0 :: SInteger) in k .== k =: e .== e =: qed\n\
+      \                      False -> k .>= 0 .|| e .== e =: sTrue =: qed\n\
+      \         Var _   -> e .== e =: qed\n\
+      \         Add _ _ -> e .== e =: qed\n\
+      \         Let _ _ _ -> e .== e =: qed\n\
+      \       "
+  ======>
+    cases
+      [(isZero e ==> (e .== e =: qed)),
+       (isNum e
+          ==>
+            (let k = getNum_1 e
+             in
+               cases
+                 [(b ==> (let k = (0 :: SInteger) in k .== k =: e .== e =: qed)),
+                  (sNot b ==> (k .>= 0 .|| e .== e =: sTrue =: qed))])),
+       (isVar e ==> (e .== e =: qed)), (isAdd e ==> (e .== e =: qed)),
+       (isLet e ==> (e .== e =: qed))]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase.hs b/SBVTestSuite/TestSuite/CompileTests/SCase.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase.hs
@@ -0,0 +1,19 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : TestSuite.CompileTests.SCase
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Testing TH messages
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module TestSuite.CompileTests.SCase(tests) where
+
+import Utils.SBVTestFramework
+
+tests :: IO TestTree
+tests = testGroup "THTests.SCase" <$> mkCompileTestGlob "SBVTestSuite/TestSuite/CompileTests/SCase/SCase*.hs"
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/Expr.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/Expr.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/Expr.hs
@@ -0,0 +1,18 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE TypeApplications  #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Expr where
+
+import Data.SBV
+
+data Expr = Zero
+          | Num Integer
+          | Var String
+          | Add Expr Expr
+          | Let String Expr Expr
+          deriving Show
+
+mkSymbolic [''Expr]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase01.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase01.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase01.hs
@@ -0,0 +1,11 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SInteger
+t e = [sCase| e of|]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase01.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase01.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase01.stderr
@@ -0,0 +1,8 @@
+SCase01.hs:11:14: error: [GHC-39584]
+    " SCase01.hs:11:19: Parse error: EOF
+
+    " In the quasi-quotation: [sCase| e of|]
+   |
+11 | t e = [sCase| e of|]
+   |              ^^^^^^^
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase02.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase02.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase02.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SInteger
+t e = [sCase| e of
+        Zero  -> 0
+        Num i -> i
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase02.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase02.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase02.stderr
@@ -0,0 +1,17 @@
+SCase02.hs:11:14: error: [GHC-39584]
+    " sCase: Pattern match(es) are non-exhaustive.
+        Not matched     : Var
+        Patterns of type: Expr
+        Must match each : Zero, Num, Var, Add, Let
+
+      You can use a '_' to match multiple cases.
+
+    " In the quasi-quotation:
+        [sCase| e of
+        Zero  -> 0
+        Num i -> i
+      |]
+   |
+11 | t e = [sCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase03.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase03.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase03.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SInteger
+t e = [sCase| e of
+        Zero  -> 0
+        Num _ _ -> i
+        Var _ -> 0
+        Add _ _ -> 2
+        Let _ _ _ -> 3
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase03.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase03.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase03.stderr
@@ -0,0 +1,19 @@
+SCase03.hs:11:14: error: [GHC-39584]
+    " SCase03.hs:13:9-15: sCase: Arity mismatch.
+        Type       : Expr
+        Constructor: Num
+        Expected   : 1
+        Given      : 2
+
+    " In the quasi-quotation:
+        [sCase| e of
+        Zero  -> 0
+        Num _ _ -> i
+        Var _ -> 0
+        Add _ _ -> 2
+        Let _ _ _ -> 3
+      |]
+   |
+11 | t e = [sCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase04.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase04.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase04.hs
@@ -0,0 +1,16 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+-- Rejected at the top level
+[sCase| e of
+        Zero  -> 0
+        Num i -> i
+      |]
+
+{- HLint ignore module "Unused LANGUAGE pragma" -}
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase04.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase04.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase04.stderr
@@ -0,0 +1,6 @@
+SCase04.hs:11:8: error: [GHC-39584]
+    sCase: not usable in declaration context
+   |
+11 | [sCase| e of
+   |        ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase05.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase05.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase05.hs
@@ -0,0 +1,12 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+-- bad syntax
+t :: SExpr -> SInteger
+t e = [sCase| e + 1|]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase05.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase05.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase05.stderr
@@ -0,0 +1,8 @@
+SCase05.hs:12:14: error: [GHC-39584]
+    " SCase05.hs:12:20: Parse error: EOF
+
+    " In the quasi-quotation: [sCase| e + 1|]
+   |
+12 | t e = [sCase| e + 1|]
+   |              ^^^^^^^^
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase06.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase06.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase06.hs
@@ -0,0 +1,12 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+-- Unknown constructor
+t :: SExpr -> SInteger
+t e = [sCase| e of FooBar _ -> 1|]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase06.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase06.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase06.stderr
@@ -0,0 +1,11 @@
+SCase06.hs:12:14: error: [GHC-39584]
+    " sCase: Unknown constructor: FooBar
+
+        Cannot find this constructor in scope.
+        Make sure the type is declared and mkSymbolic is called.
+
+    " In the quasi-quotation: [sCase| e of FooBar _ -> 1|]
+   |
+12 | t e = [sCase| e of FooBar _ -> 1|]
+   |              ^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase07.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase07.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase07.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero          -> 0
+               Num i | Just 1 <- Just i         -> i
+               Var s        -> ite (s .== "a") 1 2
+               Add a b       -> t e + t b
+               Let _   _a  b -> t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase07.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase07.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase07.stderr
@@ -0,0 +1,16 @@
+SCase07.hs:11:14: error: [GHC-39584]
+    " sCase/pCase: Pattern guards are not supported: 
+        Just 1 <- Just i
+
+    " In the quasi-quotation:
+        [sCase| e of
+               Zero          -> 0
+               Num i | Just 1 <- Just i         -> i
+               Var s        -> ite (s .== "a") 1 2
+               Add a b       -> t e + t b
+               Let _   _a  b -> t b
+      |]
+   |
+11 | t e = [sCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase08.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase08.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase08.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero          -> 0
+               Num i | Just 1 <- Just i         -> i
+               Var s        -> ite (s .== "a") 1 else 2
+               Add a b       -> t e + t b
+               Let _   _a  b -> t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase08.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase08.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase08.stderr
@@ -0,0 +1,15 @@
+SCase08.hs:11:14: error: [GHC-39584]
+    " SCase08.hs:14:50: Parse error: else
+
+    " In the quasi-quotation:
+        [sCase| e of
+               Zero          -> 0
+               Num i | Just 1 <- Just i         -> i
+               Var s        -> ite (s .== "a") 1 else 2
+               Add a b       -> t e + t b
+               Let _   _a  b -> t b
+      |]
+   |
+11 | t e = [sCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase09.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase09.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase09.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero          -> 0
+               Num i         -> i
+               Viar s         -> ite (s .== "a") 1 2
+               Add a b       -> t e + t b
+               Let _   _a  b -> t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase09.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase09.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase09.stderr
@@ -0,0 +1,14 @@
+SCase09.hs:11:14: error: [GHC-39584]
+    " SCase09.hs:14:16-21: sCase/pCase: Not in scope: data constructor: Viar
+    " In the quasi-quotation:
+        [sCase| e of
+               Zero          -> 0
+               Num i         -> i
+               Viar s         -> ite (s .== "a") 1 2
+               Add a b       -> t e + t b
+               Let _   _a  b -> t b
+      |]
+   |
+11 | t e = [sCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase10.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase10.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase10.hs
@@ -0,0 +1,18 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero          -> 0
+               Num k         -> k
+               Var s         -> ite (s .== literal "a") 1 2
+               Add (Num i) j -> i + t j
+               Add a b       -> t a + t b
+               Let _   _a  b -> t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase10.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase10.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase10.stderr
@@ -0,0 +1,28 @@
+SCase10.hs:(11,14)-(18,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \               Zero          -> 0\n\
+      \               Num k         -> k\n\
+      \               Var s         -> ite (s .== literal \"a\") 1 2\n\
+      \               Add (Num i) j -> i + t j\n\
+      \               Add a b       -> t a + t b\n\
+      \               Let _   _a  b -> t b\n\
+      \      "
+  ======>
+    ite
+      (isZero e) 0
+      (ite
+         (isNum e) ((\ k -> k) (getNum_1 e))
+         (ite
+            (isVar e) ((\ s -> ite (s .== literal "a") 1 2) (getVar_1 e))
+            (ite
+               ((.&&)
+                  (isAdd e)
+                  ((\ _ j -> const (isNum (getAdd_1 e)) j)
+                     (getAdd_1 e) (getAdd_2 e)))
+               ((\ _ j -> let i = getNum_1 (getAdd_1 e) in i + t j)
+                  (getAdd_1 e) (getAdd_2 e))
+               (ite
+                  (isAdd e) ((\ a b -> (t a) + t b) (getAdd_1 e) (getAdd_2 e))
+                  ((\ _ _a b -> t b) (getLet_1 e) (getLet_2 e) (getLet_3 e))))))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase100.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase100.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase100.hs
@@ -0,0 +1,16 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Positive: Top-level as-pattern on Maybe
+module T where
+
+import Data.SBV
+
+t :: SMaybe Integer -> SInteger
+t m = [sCase| m of
+               whole@(Just v) -> v + case whole of
+                                       Just w  -> w
+                                       Nothing -> 0
+               Nothing        -> 0
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase100.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase100.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase100.stderr
@@ -0,0 +1,16 @@
+SCase100.hs:(11,14)-(16,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " m of\n\
+      \               whole@(Just v) -> v + case whole of\n\
+      \                                       Just w  -> w\n\
+      \                                       Nothing -> 0\n\
+      \               Nothing        -> 0\n\
+      \      "
+  ======>
+    Data.SBV.Maybe.sCaseMaybe
+      0
+      (\ v
+         -> let whole = m
+            in v + Data.SBV.Maybe.sCaseMaybe 0 (\ w -> w) whole)
+      m
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase101.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase101.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase101.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Positive: Nested as-pattern on Either inside Maybe
+module T where
+
+import Data.SBV
+
+t :: SMaybe (Either Integer Bool) -> SInteger
+t m = [sCase| m of
+               Just inner@(Left v)  -> v + case inner of
+                                              Left w  -> w
+                                              Right _ -> 0
+               Just (Right _)       -> 1
+               Nothing              -> 0
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase101.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase101.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase101.stderr
@@ -0,0 +1,31 @@
+SCase101.hs:(11,14)-(17,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " m of\n\
+      \               Just inner@(Left v)  -> v + case inner of\n\
+      \                                              Left w  -> w\n\
+      \                                              Right _ -> 0\n\
+      \               Just (Right _)       -> 1\n\
+      \               Nothing              -> 0\n\
+      \      "
+  ======>
+    ite
+      ((.&&)
+         (Data.SBV.Maybe.isJust m)
+         ((\ _ -> Data.SBV.Either.isLeft (Data.SBV.Maybe.getJust_1 m))
+            (Data.SBV.Maybe.getJust_1 m)))
+      ((\ _
+          -> let
+               inner = Data.SBV.Maybe.getJust_1 m
+               v = Data.SBV.Either.getLeft_1 (Data.SBV.Maybe.getJust_1 m)
+             in v + Data.SBV.Either.sCaseEither (\ w -> w) (\ _ -> 0) inner)
+         (Data.SBV.Maybe.getJust_1 m))
+      (ite
+         ((.&&)
+            (Data.SBV.Maybe.isJust m)
+            ((\ _ -> Data.SBV.Either.isRight (Data.SBV.Maybe.getJust_1 m))
+               (Data.SBV.Maybe.getJust_1 m)))
+         ((\ _ -> 1) (Data.SBV.Maybe.getJust_1 m))
+         (ite
+            (Data.SBV.Maybe.isNothing m) 0
+            (symWithKind "unmatched_sCase_Maybe_6989586621679035188")))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase102.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase102.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase102.hs
@@ -0,0 +1,15 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Positive: As-pattern on wildcard
+module T where
+
+import Data.SBV
+
+t :: SMaybe Integer -> SInteger
+t m = [sCase| m of
+               x@_ -> case x of
+                         Just v  -> v
+                         Nothing -> 0
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase102.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase102.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase102.stderr
@@ -0,0 +1,10 @@
+SCase102.hs:(11,14)-(15,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " m of\n\
+      \               x@_ -> case x of\n\
+      \                         Just v  -> v\n\
+      \                         Nothing -> 0\n\
+      \      "
+  ======>
+    let x = m in Data.SBV.Maybe.sCaseMaybe 0 (\ v -> v) x
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase103.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase103.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase103.hs
@@ -0,0 +1,16 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Positive: As-pattern with Expr ADT (recursive use of as-bound name)
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               whole@(Add a _) -> t a + t whole
+               Num k           -> k
+               _               -> 0
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase103.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase103.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase103.stderr
@@ -0,0 +1,12 @@
+SCase103.hs:(12,14)-(16,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \               whole@(Add a _) -> t a + t whole\n\
+      \               Num k           -> k\n\
+      \               _               -> 0\n\
+      \      "
+  ======>
+    sCaseExpr
+      0 (\ k -> k) (\ _ -> 0) (\ a _ -> let whole = e in (t a) + t whole)
+      (\ _ _ _ -> 0) e
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase104.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase104.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase104.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Positive: As-pattern where binding is unused (should be elided)
+module T where
+
+import Data.SBV
+
+t :: SMaybe Integer -> SInteger
+t m = [sCase| m of
+               _unused@(Just v) -> v
+               Nothing          -> 0
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase104.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase104.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase104.stderr
@@ -0,0 +1,9 @@
+SCase104.hs:(11,14)-(14,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " m of\n\
+      \               _unused@(Just v) -> v\n\
+      \               Nothing          -> 0\n\
+      \      "
+  ======>
+    Data.SBV.Maybe.sCaseMaybe 0 (\ v -> v) m
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase105.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase105.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase105.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Positive: As-pattern on list cons pattern
+module T where
+
+import Data.SBV
+
+t :: SList Integer -> SInteger
+t xs = [sCase| xs of
+                a : tl@(_ : _) -> a + case tl of
+                                         b : _ -> b
+                                         []    -> 0
+                _ : _           -> 0
+                []              -> 0
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase105.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase105.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase105.stderr
@@ -0,0 +1,34 @@
+SCase105.hs:(11,15)-(17,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " xs of\n\
+      \                a : tl@(_ : _) -> a + case tl of\n\
+      \                                         b : _ -> b\n\
+      \                                         []    -> 0\n\
+      \                _ : _           -> 0\n\
+      \                []              -> 0\n\
+      \       "
+  ======>
+    ite
+      ((.&&)
+         (sNot (Data.SBV.List.null xs))
+         ((\ a _
+             -> const
+                  ((.&&)
+                     (sNot (Data.SBV.List.null (Data.SBV.List.tail xs)))
+                     ((.===)
+                        (Data.SBV.List.tail xs)
+                        (Data.SBV.List.head (Data.SBV.List.tail xs)
+                           .: Data.SBV.List.tail (Data.SBV.List.tail xs))))
+                  a)
+            (Data.SBV.List.head xs) (Data.SBV.List.tail xs)))
+      ((\ a _
+          -> let tl = Data.SBV.List.tail xs
+             in
+               a + ite
+                     (sNot (Data.SBV.List.null tl))
+                     ((\ b _ -> b) (Data.SBV.List.head tl) (Data.SBV.List.tail tl)) 0)
+         (Data.SBV.List.head xs) (Data.SBV.List.tail xs))
+      (ite
+         (sNot (Data.SBV.List.null xs))
+         ((\ _ _ -> 0) (Data.SBV.List.head xs) (Data.SBV.List.tail xs)) 0)
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase106.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase106.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase106.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Positive: As-pattern on tuple
+module T where
+
+import Data.SBV
+
+t :: STuple Integer Bool -> SInteger
+t p = [sCase| p of
+               whole@(v, b) -> ite b v (case whole of
+                                           (w, _) -> negate w)
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase106.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase106.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase106.stderr
@@ -0,0 +1,16 @@
+SCase106.hs:(11,14)-(14,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " p of\n\
+      \               whole@(v, b) -> ite b v (case whole of\n\
+      \                                           (w, _) -> negate w)\n\
+      \      "
+  ======>
+    (\ v b
+       -> let whole = p
+          in
+            ite
+              b v
+              ((\ w _ -> negate w)
+                 (Data.SBV.Tuple._1 whole) (Data.SBV.Tuple._2 whole)))
+      (Data.SBV.Tuple._1 p) (Data.SBV.Tuple._2 p)
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase107.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase107.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase107.hs
@@ -0,0 +1,24 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -Wno-name-shadowing -ddump-splices #-}
+
+-- Positive: Scoping regression test. Nested pattern var 'k' from 'Add (Num k) _'
+-- is used in one branch of a nested case on SMaybe, while a sibling branch shadows
+-- 'k' with a let binding. Old scope-unaware freeVars would drop the accessor binding
+-- for 'k', causing a compilation error. See also PCase77 for the pCase counterpart.
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SMaybe Integer -> SInteger
+t e m = [sCase| e of
+                Zero          -> 0
+                Num _         -> 0
+                Var _         -> 0
+                Add (Num k) _ -> case m of
+                                   Nothing -> let k = 42 in k
+                                   Just v  -> k + v
+                Add _ _       -> 0
+                Let _ _ _     -> 0
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase107.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase107.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase107.stderr
@@ -0,0 +1,31 @@
+SCase107.hs:(15,16)-(24,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \                Zero          -> 0\n\
+      \                Num _         -> 0\n\
+      \                Var _         -> 0\n\
+      \                Add (Num k) _ -> case m of\n\
+      \                                   Nothing -> let k = 42 in k\n\
+      \                                   Just v  -> k + v\n\
+      \                Add _ _       -> 0\n\
+      \                Let _ _ _     -> 0\n\
+      \       "
+  ======>
+    ite
+      (isZero e) 0
+      (ite
+         (isNum e) ((\ _ -> 0) (getNum_1 e))
+         (ite
+            (isVar e) ((\ _ -> 0) (getVar_1 e))
+            (ite
+               ((.&&)
+                  (isAdd e)
+                  ((\ _ _ -> isNum (getAdd_1 e)) (getAdd_1 e) (getAdd_2 e)))
+               ((\ _ _
+                   -> let k = getNum_1 (getAdd_1 e)
+                      in Data.SBV.Maybe.sCaseMaybe (let k = 42 in k) (\ v -> k + v) m)
+                  (getAdd_1 e) (getAdd_2 e))
+               (ite
+                  (isAdd e) ((\ _ _ -> 0) (getAdd_1 e) (getAdd_2 e))
+                  ((\ _ _ _ -> 0) (getLet_1 e) (getLet_2 e) (getLet_3 e))))))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase11.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase11.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase11.hs
@@ -0,0 +1,18 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero          -> 0
+               Num i         -> i
+               _ -> 3
+               Var s         -> ite (s .== "a") 1 2
+               Add a b       -> t e + t b
+               Let _   _a  b -> t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase11.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase11.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase11.stderr
@@ -0,0 +1,19 @@
+SCase11.hs:11:14: error: [GHC-39584]
+    " SCase11.hs:14:16: sCase: Wildcard makes the remaining matches redundant:
+        SCase11.hs:15:16-20: Var s
+        SCase11.hs:16:16-22: Add a b
+        SCase11.hs:17:16-28: Let _ _a b
+
+    " In the quasi-quotation:
+        [sCase| e of
+               Zero          -> 0
+               Num i         -> i
+               _ -> 3
+               Var s         -> ite (s .== "a") 1 2
+               Add a b       -> t e + t b
+               Let _   _a  b -> t b
+      |]
+   |
+11 | t e = [sCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase12.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase12.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase12.hs
@@ -0,0 +1,16 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero          -> 0
+               Num i         -> i
+               _ -> 3
+               _ -> 5
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase12.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase12.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase12.stderr
@@ -0,0 +1,15 @@
+SCase12.hs:11:14: error: [GHC-39584]
+    " SCase12.hs:14:16: sCase: Wildcard makes the remaining matches redundant:
+        SCase12.hs:15:16: _
+
+    " In the quasi-quotation:
+        [sCase| e of
+               Zero          -> 0
+               Num i         -> i
+               _ -> 3
+               _ -> 5
+      |]
+   |
+11 | t e = [sCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase13.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase13.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase13.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero          -> 0
+               Num i         -> i
+               Var {} _      -> ite (s .== "a") 1 2
+               Add a b       -> t e + t b
+               Let _   _a  b -> t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase13.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase13.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase13.stderr
@@ -0,0 +1,15 @@
+SCase13.hs:11:14: error: [GHC-39584]
+    " SCase13.hs:14:30: Parse error in pattern: Var{}
+
+    " In the quasi-quotation:
+        [sCase| e of
+               Zero          -> 0
+               Num i         -> i
+               Var {} _      -> ite (s .== "a") 1 2
+               Add a b       -> t e + t b
+               Let _   _a  b -> t b
+      |]
+   |
+11 | t e = [sCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase14.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase14.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase14.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero          -> 0
+               Num i         -> i
+               Var s _       -> ite (s .== "a") 1 2
+               Add a b       -> t e + t b
+               Let _   _a  b -> t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase14.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase14.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase14.stderr
@@ -0,0 +1,19 @@
+SCase14.hs:11:14: error: [GHC-39584]
+    " SCase14.hs:14:16-22: sCase: Arity mismatch.
+        Type       : Expr
+        Constructor: Var
+        Expected   : 1
+        Given      : 2
+
+    " In the quasi-quotation:
+        [sCase| e of
+               Zero          -> 0
+               Num i         -> i
+               Var s _       -> ite (s .== "a") 1 2
+               Add a b       -> t e + t b
+               Let _   _a  b -> t b
+      |]
+   |
+11 | t e = [sCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase15.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase15.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase15.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero          -> 0
+               Num i         -> i
+               Var s         -> ite (s .== "a") 1 2
+               Add a b       -> t e + t b
+               _ _ -> 3
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase15.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase15.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase15.stderr
@@ -0,0 +1,15 @@
+SCase15.hs:11:14: error: [GHC-39584]
+    " SCase15.hs:16:20: Parse error in pattern: _
+
+    " In the quasi-quotation:
+        [sCase| e of
+               Zero          -> 0
+               Num i         -> i
+               Var s         -> ite (s .== "a") 1 2
+               Add a b       -> t e + t b
+               _ _ -> 3
+      |]
+   |
+11 | t e = [sCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase16.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase16.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase16.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero           -> 0
+               Num i | i .< 3 -> i
+               Var s          -> ite (s .== "a") 1 2
+               Add a b        -> t e + t b
+               Let _   _a  b  -> t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase16.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase16.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase16.stderr
@@ -0,0 +1,18 @@
+SCase16.hs:11:14: error: [GHC-39584]
+    " SCase16.hs:13:16-20: sCase: Non-exhaustive match:
+        Type       : Expr
+        Constructor: Num i | i .< 3
+      NB. Guarded match might fail.
+
+    " In the quasi-quotation:
+        [sCase| e of
+               Zero           -> 0
+               Num i | i .< 3 -> i
+               Var s          -> ite (s .== "a") 1 2
+               Add a b        -> t e + t b
+               Let _   _a  b  -> t b
+      |]
+   |
+11 | t e = [sCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase17.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase17.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase17.hs
@@ -0,0 +1,18 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero           -> 0
+               Num i | i .< 3 -> i
+               Var s          -> ite (s .== literal "a") 1 2
+               Add a b        -> t a + t b
+               Num i          -> i+1
+               Let _   _a  b  -> t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase17.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase17.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase17.stderr
@@ -0,0 +1,24 @@
+SCase17.hs:(11,14)-(18,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \               Zero           -> 0\n\
+      \               Num i | i .< 3 -> i\n\
+      \               Var s          -> ite (s .== literal \"a\") 1 2\n\
+      \               Add a b        -> t a + t b\n\
+      \               Num i          -> i+1\n\
+      \               Let _   _a  b  -> t b\n\
+      \      "
+  ======>
+    ite
+      (isZero e) 0
+      (ite
+         ((.&&) (isNum e) ((\ i -> i .< 3) (getNum_1 e)))
+         ((\ i -> i) (getNum_1 e))
+         (ite
+            (isVar e) ((\ s -> ite (s .== literal "a") 1 2) (getVar_1 e))
+            (ite
+               (isAdd e) ((\ a b -> (t a) + t b) (getAdd_1 e) (getAdd_2 e))
+               (ite
+                  (isNum e) ((\ i -> i + 1) (getNum_1 e))
+                  ((\ _ _a b -> t b) (getLet_1 e) (getLet_2 e) (getLet_3 e))))))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase18.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase18.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase18.hs
@@ -0,0 +1,18 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero           -> 0
+               Num i -> 4
+               Num i | i .< 3 -> i
+               Var s          -> ite (s .== literal "a") 1 2
+               Add a b        -> t e + t b
+               Let _   _a  b  -> t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase18.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase18.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase18.stderr
@@ -0,0 +1,20 @@
+SCase18.hs:11:14: error: [GHC-39584]
+    " SCase18.hs:14:16-20: sCase: Overlapping case constructors:
+        Type       : Expr
+        Constructor: Num i | i .< 3
+      Overlaps with:
+        SCase18.hs:13:16-20: Num i
+
+    " In the quasi-quotation:
+        [sCase| e of
+               Zero           -> 0
+               Num i -> 4
+               Num i | i .< 3 -> i
+               Var s          -> ite (s .== literal "a") 1 2
+               Add a b        -> t e + t b
+               Let _   _a  b  -> t b
+      |]
+   |
+11 | t e = [sCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase19.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase19.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase19.hs
@@ -0,0 +1,18 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero           -> 0
+               Num i -> 4
+               Var s          -> ite (s .== literal "a") 1 2
+               Add a b        -> t e + t b
+               Let _   _a  b  -> t b
+               _ | 2 .>= 3 -> 4
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase19.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase19.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase19.stderr
@@ -0,0 +1,19 @@
+SCase19.hs:11:14: error: [GHC-39584]
+    " SCase19.hs:17:16: sCase: Non-exhaustive match:
+        Type       : Expr
+        Constructor: _ | 2 .>= 3
+      NB. Guarded match might fail.
+
+    " In the quasi-quotation:
+        [sCase| e of
+               Zero           -> 0
+               Num i -> 4
+               Var s          -> ite (s .== literal "a") 1 2
+               Add a b        -> t e + t b
+               Let _   _a  b  -> t b
+               _ | 2 .>= 3 -> 4
+      |]
+   |
+11 | t e = [sCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase20.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase20.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase20.hs
@@ -0,0 +1,18 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero           -> 0
+               Num i          -> 4
+               Var s          -> ite (s .== literal "a") 1 2
+               Add a b        -> t e + t b
+               Let _   _a  b  -> t b
+               _ -> 4
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase20.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase20.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase20.stderr
@@ -0,0 +1,15 @@
+SCase20.hs:11:14: error: [GHC-39584]
+    " SCase20.hs:17:16: sCase: Wildcard match is redundant
+    " In the quasi-quotation:
+        [sCase| e of
+               Zero           -> 0
+               Num i          -> 4
+               Var s          -> ite (s .== literal "a") 1 2
+               Add a b        -> t e + t b
+               Let _   _a  b  -> t b
+               _ -> 4
+      |]
+   |
+11 | t e = [sCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase21.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase21.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase21.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero           -> 0
+               Num i | i .> 4 -> 4
+               Var s          -> ite (s .== literal "a") 1 2
+               Add a b        -> t e + t b
+               Let _   _a  b  -> t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase21.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase21.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase21.stderr
@@ -0,0 +1,18 @@
+SCase21.hs:11:14: error: [GHC-39584]
+    " SCase21.hs:13:16-20: sCase: Non-exhaustive match:
+        Type       : Expr
+        Constructor: Num i | i .> 4
+      NB. Guarded match might fail.
+
+    " In the quasi-quotation:
+        [sCase| e of
+               Zero           -> 0
+               Num i | i .> 4 -> 4
+               Var s          -> ite (s .== literal "a") 1 2
+               Add a b        -> t e + t b
+               Let _   _a  b  -> t b
+      |]
+   |
+11 | t e = [sCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase22.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase22.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase22.hs
@@ -0,0 +1,18 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero           -> 0
+               Num i | i .> 4 -> 4
+               Var s          -> ite (s .== literal "a") 1 2
+               Add a b        -> t e + t b
+               Let _   _a  b  -> t b
+               _ | 2 .>= 3    -> 5
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase22.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase22.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase22.stderr
@@ -0,0 +1,19 @@
+SCase22.hs:11:14: error: [GHC-39584]
+    " SCase22.hs:13:16-20: sCase: Non-exhaustive match:
+        Type       : Expr
+        Constructor: Num i | i .> 4
+      NB. Guarded match might fail.
+
+    " In the quasi-quotation:
+        [sCase| e of
+               Zero           -> 0
+               Num i | i .> 4 -> 4
+               Var s          -> ite (s .== literal "a") 1 2
+               Add a b        -> t e + t b
+               Let _   _a  b  -> t b
+               _ | 2 .>= 3    -> 5
+      |]
+   |
+11 | t e = [sCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase23.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase23.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase23.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero           -> 0
+               Num i          -> 4
+               Var s          -> ite (s .== literal "a") 1 2
+               Add a b        -> t a + t b
+               Let _   _a  b  -> t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase23.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase23.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase23.stderr
@@ -0,0 +1,20 @@
+SCase23.hs:(11,14)-(17,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \               Zero           -> 0\n\
+      \               Num i          -> 4\n\
+      \               Var s          -> ite (s .== literal \"a\") 1 2\n\
+      \               Add a b        -> t a + t b\n\
+      \               Let _   _a  b  -> t b\n\
+      \      "
+  ======>
+    sCaseExpr
+      0 (\ i -> 4) (\ s -> ite (s .== literal "a") 1 2)
+      (\ a b -> (t a) + t b) (\ _ _a b -> t b) e
+SCase23.hs:11:14: error: [GHC-40910] [-Wunused-matches, Werror=unused-matches]
+    Defined but not used: i
+   |
+11 | t e = [sCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase24.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase24.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase24.hs
@@ -0,0 +1,18 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero           -> 0
+               Num _          -> 4
+               Var s          -> ite (s .== literal "a") 1 2
+               Add a b | t a .== 4 -> t b
+               Let _   _a  b  -> t b
+               _ -> 2
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase24.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase24.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase24.stderr
@@ -0,0 +1,26 @@
+SCase24.hs:(11,14)-(18,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \               Zero           -> 0\n\
+      \               Num _          -> 4\n\
+      \               Var s          -> ite (s .== literal \"a\") 1 2\n\
+      \               Add a b | t a .== 4 -> t b\n\
+      \               Let _   _a  b  -> t b\n\
+      \               _ -> 2\n\
+      \      "
+  ======>
+    ite
+      (isZero e) 0
+      (ite
+         (isNum e) ((\ _ -> 4) (getNum_1 e))
+         (ite
+            (isVar e) ((\ s -> ite (s .== literal "a") 1 2) (getVar_1 e))
+            (ite
+               ((.&&)
+                  (isAdd e)
+                  ((\ a b -> const ((t a) .== 4) b) (getAdd_1 e) (getAdd_2 e)))
+               ((\ a b -> const (t b) a) (getAdd_1 e) (getAdd_2 e))
+               (ite
+                  (isLet e)
+                  ((\ _ _a b -> t b) (getLet_1 e) (getLet_2 e) (getLet_3 e)) 2))))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase25.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase25.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase25.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+f :: SExpr -> SInteger
+f e = [sCase| e of
+         Var s     | s .== literal "a"                       -> 0
+                   | s .== literal "b" .|| s .== literal "c" -> 1
+                   | sTrue                                   -> 2
+
+         Num i     | sTrue                                   -> 3
+
+         _                                                   -> 6
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase25.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase25.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase25.stderr
@@ -0,0 +1,30 @@
+SCase25.hs:(11,14)-(19,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \         Var s     | s .== literal \"a\"                       -> 0\n\
+      \                   | s .== literal \"b\" .|| s .== literal \"c\" -> 1\n\
+      \                   | sTrue                                   -> 2\n\
+      \\n\
+      \         Num i     | sTrue                                   -> 3\n\
+      \\n\
+      \         _                                                   -> 6\n\
+      \      "
+  ======>
+    ite
+      ((.&&) (isVar e) ((\ s -> s .== literal "a") (getVar_1 e)))
+      ((\ s -> const 0 s) (getVar_1 e))
+      (ite
+         ((.&&)
+            (isVar e)
+            ((\ s -> s .== literal "b" .|| s .== literal "c") (getVar_1 e)))
+         ((\ s -> const 1 s) (getVar_1 e))
+         (ite
+            (isVar e) ((\ s -> const 2 s) (getVar_1 e))
+            (ite (isNum e) ((\ i -> 3) (getNum_1 e)) 6)))
+SCase25.hs:11:14: error: [GHC-40910] [-Wunused-matches, Werror=unused-matches]
+    Defined but not used: i
+   |
+11 | f e = [sCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase26.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase26.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase26.hs
@@ -0,0 +1,15 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE TypeApplications  #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Data.SBV
+
+data A = A1 { u :: Integer }
+       | B1 { s :: String, k :: Float }
+       | C1
+
+mkSymbolic [''A]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase26.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase26.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase26.stderr
@@ -0,0 +1,1 @@
+There was no failure during compilation.
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase27.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase27.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase27.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE TemplateHaskell #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Data.SBV
+
+-- don't allow multiple accessors
+data A = A1 { u :: Integer }
+       | B1 { u :: Integer, s :: String}
+       | C1
+
+mkSymbolic [''A]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase27.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase27.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase27.stderr
@@ -0,0 +1,11 @@
+SCase27.hs:14:1: error: [GHC-39584]
+    mkSymbolic: Unsupported field accessor definition.
+      Multiply used: u
+      
+      SBV does not support cases where accessor fields are replicated.
+      Please use each accessor only once.
+
+   |
+14 | mkSymbolic [''A]
+   | ^^^^^^^^^^^^^^^^
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase28.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase28.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase28.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Num i | i .> 3 -> 5
+                     | sTrue  -> 12
+
+               Zero{} -> 0
+               Var{}  -> 0
+               Add{}  -> 0
+               Let{}  -> 0
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase28.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase28.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase28.stderr
@@ -0,0 +1,25 @@
+SCase28.hs:(11,14)-(19,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \               Num i | i .> 3 -> 5\n\
+      \                     | sTrue  -> 12\n\
+      \\n\
+      \               Zero{} -> 0\n\
+      \               Var{}  -> 0\n\
+      \               Add{}  -> 0\n\
+      \               Let{}  -> 0\n\
+      \      "
+  ======>
+    ite
+      ((.&&) (isNum e) ((\ i -> i .> 3) (getNum_1 e)))
+      ((\ i -> const 5 i) (getNum_1 e))
+      (ite
+         (isNum e) ((\ i -> const 12 i) (getNum_1 e))
+         (ite
+            (isZero e) 0
+            (ite
+               (isVar e) ((\ _ -> 0) (getVar_1 e))
+               (ite
+                  (isAdd e) ((\ _ _ -> 0) (getAdd_1 e) (getAdd_2 e))
+                  ((\ _ _ _ -> 0) (getLet_1 e) (getLet_2 e) (getLet_3 e))))))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase29.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase29.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase29.hs
@@ -0,0 +1,20 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Num i | i > 3  -> 5
+                     | sTrue  -> 12
+               Num i | i > 12 -> 7
+
+               Zero{} -> 0
+               Var{}  -> 0
+               Add{}  -> 0
+               Let{}  -> 0
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase29.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase29.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase29.stderr
@@ -0,0 +1,22 @@
+SCase29.hs:11:14: error: [GHC-39584]
+    " SCase29.hs:14:16-20: sCase: Overlapping case constructors:
+        Type       : Expr
+        Constructor: Num i | i > 12
+      Overlaps with:
+        SCase29.hs:12:16-20: Num i
+
+    " In the quasi-quotation:
+        [sCase| e of
+               Num i | i > 3  -> 5
+                     | sTrue  -> 12
+               Num i | i > 12 -> 7
+
+               Zero{} -> 0
+               Var{}  -> 0
+               Add{}  -> 0
+               Let{}  -> 0
+      |]
+   |
+11 | t e = [sCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase30.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase30.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase30.hs
@@ -0,0 +1,24 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE QuasiQuotes       #-}
+{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE TypeApplications  #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Data.SBV
+
+-- Testing constructor/type name conflct
+data A = A Integer
+       | B Float
+       | C A A
+
+mkSymbolic [''A]
+
+t :: SA -> SA
+t a = [sCase| a of
+         A u     -> sA (u+1)
+         B f     -> sB (f+2)
+         C a1 a2 -> sC (t a1) (t a2)
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase30.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase30.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase30.stderr
@@ -0,0 +1,12 @@
+SCase30.hs:(20,14)-(24,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " a of\n\
+      \         A u     -> sA (u+1)\n\
+      \         B f     -> sB (f+2)\n\
+      \         C a1 a2 -> sC (t a1) (t a2)\n\
+      \      "
+  ======>
+    sCaseA
+      (\ u -> sA (u + 1)) (\ f -> sB (f + 2))
+      (\ a1 a2 -> sC (t a1) (t a2)) a
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase31.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase31.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase31.hs
@@ -0,0 +1,13 @@
+{-# LANGUAGE TemplateHaskell   #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Data.SBV
+
+-- Testing bad fields
+data A = F (Integer -> Bool)
+       | I Integer
+
+mkSymbolic [''A]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase31.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase31.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase31.stderr
@@ -0,0 +1,12 @@
+SCase31.hs:13:1: error: [GHC-39584]
+    mkSymbolic: Unsupported constructor kind
+      Datatype   : A
+      Constructor: F
+      Kind       : GHC.Internal.Bignum.Integer.Integer -> GHC.Internal.Types.Bool
+      
+      Higher order fields (i.e., function values) are not supported.
+
+   |
+13 | mkSymbolic [''A]
+   | ^^^^^^^^^^^^^^^^
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase32.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase32.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase32.hs
@@ -0,0 +1,13 @@
+{-# LANGUAGE TemplateHaskell   #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Data.SBV
+
+-- Testing bad fields
+data A = F (A -> Bool)
+       | I Integer
+
+mkSymbolic [''A]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase32.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase32.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase32.stderr
@@ -0,0 +1,12 @@
+SCase32.hs:13:1: error: [GHC-39584]
+    mkSymbolic: Unsupported constructor kind
+      Datatype   : A
+      Constructor: F
+      Kind       : T.A -> GHC.Internal.Types.Bool
+      
+      Higher order fields (i.e., function values) are not supported.
+
+   |
+13 | mkSymbolic [''A]
+   | ^^^^^^^^^^^^^^^^
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase33.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase33.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase33.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+-- Positive: deeply nested pattern Add (Add (Num i) j) k
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero                  -> 0
+               Num k                 -> k
+               Var s                 -> ite (s .== literal "a") 1 2
+               Add (Add (Num i) j) k -> i + t j + t k
+               Add a b               -> t a + t b
+               Let _   _a  b         -> t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase33.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase33.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase33.stderr
@@ -0,0 +1,34 @@
+SCase33.hs:(12,14)-(19,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \               Zero                  -> 0\n\
+      \               Num k                 -> k\n\
+      \               Var s                 -> ite (s .== literal \"a\") 1 2\n\
+      \               Add (Add (Num i) j) k -> i + t j + t k\n\
+      \               Add a b               -> t a + t b\n\
+      \               Let _   _a  b         -> t b\n\
+      \      "
+  ======>
+    ite
+      (isZero e) 0
+      (ite
+         (isNum e) ((\ k -> k) (getNum_1 e))
+         (ite
+            (isVar e) ((\ s -> ite (s .== literal "a") 1 2) (getVar_1 e))
+            (ite
+               ((.&&)
+                  (isAdd e)
+                  ((\ _ k
+                      -> const
+                           ((.&&) (isAdd (getAdd_1 e)) (isNum (getAdd_1 (getAdd_1 e)))) k)
+                     (getAdd_1 e) (getAdd_2 e)))
+               ((\ _ k
+                   -> let
+                        j = getAdd_2 (getAdd_1 e)
+                        i = getNum_1 (getAdd_1 (getAdd_1 e))
+                      in i + t j + t k)
+                  (getAdd_1 e) (getAdd_2 e))
+               (ite
+                  (isAdd e) ((\ a b -> (t a) + t b) (getAdd_1 e) (getAdd_2 e))
+                  ((\ _ _a b -> t b) (getLet_1 e) (getLet_2 e) (getLet_3 e))))))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase34.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase34.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase34.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+-- Positive: nested pattern combined with a guard
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero                -> 0
+               Num k               -> k
+               Var s               -> ite (s .== literal "a") 1 2
+               Add (Num i) j | i .> 0 -> i + t j
+               Add a b             -> t a + t b
+               Let _   _a  b       -> t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase34.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase34.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase34.stderr
@@ -0,0 +1,32 @@
+SCase34.hs:(12,14)-(19,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \               Zero                -> 0\n\
+      \               Num k               -> k\n\
+      \               Var s               -> ite (s .== literal \"a\") 1 2\n\
+      \               Add (Num i) j | i .> 0 -> i + t j\n\
+      \               Add a b             -> t a + t b\n\
+      \               Let _   _a  b       -> t b\n\
+      \      "
+  ======>
+    ite
+      (isZero e) 0
+      (ite
+         (isNum e) ((\ k -> k) (getNum_1 e))
+         (ite
+            (isVar e) ((\ s -> ite (s .== literal "a") 1 2) (getVar_1 e))
+            (ite
+               ((.&&)
+                  (isAdd e)
+                  ((\ _ j
+                      -> const
+                           ((.&&)
+                              (isNum (getAdd_1 e)) (let i = getNum_1 (getAdd_1 e) in i .> 0))
+                           j)
+                     (getAdd_1 e) (getAdd_2 e)))
+               ((\ _ j -> let i = getNum_1 (getAdd_1 e) in i + t j)
+                  (getAdd_1 e) (getAdd_2 e))
+               (ite
+                  (isAdd e) ((\ a b -> (t a) + t b) (getAdd_1 e) (getAdd_2 e))
+                  ((\ _ _a b -> t b) (getLet_1 e) (getLet_2 e) (getLet_3 e))))))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase35.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase35.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase35.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+-- Positive: nested patterns on both sides of Add
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero              -> 0
+               Num k             -> k
+               Var s             -> ite (s .== literal "a") 1 2
+               Add (Num i) (Num j) -> i + j
+               Add a b           -> t a + t b
+               Let _   _a  b     -> t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase35.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase35.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase35.stderr
@@ -0,0 +1,32 @@
+SCase35.hs:(12,14)-(19,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \               Zero              -> 0\n\
+      \               Num k             -> k\n\
+      \               Var s             -> ite (s .== literal \"a\") 1 2\n\
+      \               Add (Num i) (Num j) -> i + j\n\
+      \               Add a b           -> t a + t b\n\
+      \               Let _   _a  b     -> t b\n\
+      \      "
+  ======>
+    ite
+      (isZero e) 0
+      (ite
+         (isNum e) ((\ k -> k) (getNum_1 e))
+         (ite
+            (isVar e) ((\ s -> ite (s .== literal "a") 1 2) (getVar_1 e))
+            (ite
+               ((.&&)
+                  (isAdd e)
+                  ((\ _ _ -> (.&&) (isNum (getAdd_1 e)) (isNum (getAdd_2 e)))
+                     (getAdd_1 e) (getAdd_2 e)))
+               ((\ _ _
+                   -> let
+                        i = getNum_1 (getAdd_1 e)
+                        j = getNum_1 (getAdd_2 e)
+                      in i + j)
+                  (getAdd_1 e) (getAdd_2 e))
+               (ite
+                  (isAdd e) ((\ a b -> (t a) + t b) (getAdd_1 e) (getAdd_2 e))
+                  ((\ _ _a b -> t b) (getLet_1 e) (getLet_2 e) (getLet_3 e))))))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase36.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase36.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase36.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+-- Positive: nested pattern with wildcard inside the nested constructor
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero          -> 0
+               Num k         -> k
+               Var s         -> ite (s .== literal "a") 1 2
+               Add (Num _) j -> 1 + t j
+               Add a b       -> t a + t b
+               Let _   _a  b -> t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase36.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase36.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase36.stderr
@@ -0,0 +1,27 @@
+SCase36.hs:(12,14)-(19,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \               Zero          -> 0\n\
+      \               Num k         -> k\n\
+      \               Var s         -> ite (s .== literal \"a\") 1 2\n\
+      \               Add (Num _) j -> 1 + t j\n\
+      \               Add a b       -> t a + t b\n\
+      \               Let _   _a  b -> t b\n\
+      \      "
+  ======>
+    ite
+      (isZero e) 0
+      (ite
+         (isNum e) ((\ k -> k) (getNum_1 e))
+         (ite
+            (isVar e) ((\ s -> ite (s .== literal "a") 1 2) (getVar_1 e))
+            (ite
+               ((.&&)
+                  (isAdd e)
+                  ((\ _ j -> const (isNum (getAdd_1 e)) j)
+                     (getAdd_1 e) (getAdd_2 e)))
+               ((\ _ j -> 1 + t j) (getAdd_1 e) (getAdd_2 e))
+               (ite
+                  (isAdd e) ((\ a b -> (t a) + t b) (getAdd_1 e) (getAdd_2 e))
+                  ((\ _ _a b -> t b) (getLet_1 e) (getLet_2 e) (getLet_3 e))))))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase37.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase37.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase37.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+-- Negative: literal pattern inside nested position is not supported
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero          -> 0
+               Num k         -> k
+               Var s         -> ite (s .== literal "a") 1 2
+               Add (Num 0) j -> t j
+               Add a b       -> t a + t b
+               Let _   _a  b -> t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase37.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase37.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase37.stderr
@@ -0,0 +1,29 @@
+SCase37.hs:(12,14)-(19,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \               Zero          -> 0\n\
+      \               Num k         -> k\n\
+      \               Var s         -> ite (s .== literal \"a\") 1 2\n\
+      \               Add (Num 0) j -> t j\n\
+      \               Add a b       -> t a + t b\n\
+      \               Let _   _a  b -> t b\n\
+      \      "
+  ======>
+    ite
+      (isZero e) 0
+      (ite
+         (isNum e) ((\ k -> k) (getNum_1 e))
+         (ite
+            (isVar e) ((\ s -> ite (s .== literal "a") 1 2) (getVar_1 e))
+            (ite
+               ((.&&)
+                  (isAdd e)
+                  ((\ _ j
+                      -> const
+                           ((.&&) (isNum (getAdd_1 e)) ((.==) (getNum_1 (getAdd_1 e)) 0)) j)
+                     (getAdd_1 e) (getAdd_2 e)))
+               ((\ _ j -> t j) (getAdd_1 e) (getAdd_2 e))
+               (ite
+                  (isAdd e) ((\ a b -> (t a) + t b) (getAdd_1 e) (getAdd_2 e))
+                  ((\ _ _a b -> t b) (getLet_1 e) (getLet_2 e) (getLet_3 e))))))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase38.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase38.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase38.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+-- Negative: nested constructor with wrong arity (Num takes 1 arg, given 2)
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero              -> 0
+               Num k             -> k
+               Var s             -> ite (s .== literal "a") 1 2
+               Add (Num i j) b   -> i + t b
+               Add a b           -> t a + t b
+               Let _   _a  b     -> t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase38.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase38.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase38.stderr
@@ -0,0 +1,19 @@
+SCase38.hs:12:14: error: [GHC-39584]
+    " SCase38.hs:16:16-30: sCase/pCase: Arity mismatch in nested pattern.
+        Constructor: Num
+        Expected   : 1
+        Given      : 2
+
+    " In the quasi-quotation:
+        [sCase| e of
+               Zero              -> 0
+               Num k             -> k
+               Var s             -> ite (s .== literal "a") 1 2
+               Add (Num i j) b   -> i + t b
+               Add a b           -> t a + t b
+               Let _   _a  b     -> t b
+      |]
+   |
+12 | t e = [sCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase39.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase39.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase39.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+-- Negative: nested constructor that is not in scope
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero              -> 0
+               Num k             -> k
+               Var s             -> ite (s .== literal "a") 1 2
+               Add (Numb i) b    -> i + t b
+               Add a b           -> t a + t b
+               Let _   _a  b     -> t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase39.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase39.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase39.stderr
@@ -0,0 +1,15 @@
+SCase39.hs:12:14: error: [GHC-39584]
+    " SCase39.hs:16:16-29: sCase/pCase: Not in scope: data constructor: Numb
+    " In the quasi-quotation:
+        [sCase| e of
+               Zero              -> 0
+               Num k             -> k
+               Var s             -> ite (s .== literal "a") 1 2
+               Add (Numb i) b    -> i + t b
+               Add a b           -> t a + t b
+               Let _   _a  b     -> t b
+      |]
+   |
+12 | t e = [sCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase40.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase40.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase40.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+-- Positive: nested pattern using parenthesized constructor (ParensP)
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero                    -> 0
+               Num k                   -> k
+               Var s                   -> ite (s .== literal "a") 1 2
+               Let _ (Num i) b         -> i + t b
+               Let _ a       b         -> t a + t b
+               Add a b                 -> t a + t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase40.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase40.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase40.stderr
@@ -0,0 +1,29 @@
+SCase40.hs:(12,14)-(19,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \               Zero                    -> 0\n\
+      \               Num k                   -> k\n\
+      \               Var s                   -> ite (s .== literal \"a\") 1 2\n\
+      \               Let _ (Num i) b         -> i + t b\n\
+      \               Let _ a       b         -> t a + t b\n\
+      \               Add a b                 -> t a + t b\n\
+      \      "
+  ======>
+    ite
+      (isZero e) 0
+      (ite
+         (isNum e) ((\ k -> k) (getNum_1 e))
+         (ite
+            (isVar e) ((\ s -> ite (s .== literal "a") 1 2) (getVar_1 e))
+            (ite
+               ((.&&)
+                  (isLet e)
+                  ((\ _ _ b -> const (isNum (getLet_2 e)) b)
+                     (getLet_1 e) (getLet_2 e) (getLet_3 e)))
+               ((\ _ _ b -> let i = getNum_1 (getLet_2 e) in i + t b)
+                  (getLet_1 e) (getLet_2 e) (getLet_3 e))
+               (ite
+                  (isLet e)
+                  ((\ _ a b -> (t a) + t b) (getLet_1 e) (getLet_2 e) (getLet_3 e))
+                  ((\ a b -> (t a) + t b) (getAdd_1 e) (getAdd_2 e))))))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase41.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase41.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase41.hs
@@ -0,0 +1,18 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+-- Negative: nested pattern covers only a subset of Add; missing fallback for Add _ _
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero          -> 0
+               Num k         -> k
+               Var s         -> ite (s .== literal "a") 1 2
+               Add (Num i) j -> i + t j
+               Let _   _a  b -> t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase41.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase41.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase41.stderr
@@ -0,0 +1,18 @@
+SCase41.hs:12:14: error: [GHC-39584]
+    " SCase41.hs:16:16-28: sCase: Non-exhaustive match:
+        Type       : Expr
+        Constructor: Add _ j | isNum (getAdd_1 e)
+      NB. Guarded match might fail.
+
+    " In the quasi-quotation:
+        [sCase| e of
+               Zero          -> 0
+               Num k         -> k
+               Var s         -> ite (s .== literal "a") 1 2
+               Add (Num i) j -> i + t j
+               Let _   _a  b -> t b
+      |]
+   |
+12 | t e = [sCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase42.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase42.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase42.hs
@@ -0,0 +1,18 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+-- Negative: deeply nested pattern covers only a subset of the outermost Add; missing fallback
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero                          -> 0
+               Num k                         -> k
+               Var s                         -> ite (s .== literal "a") 1 2
+               Add (Add (Add (Num _) b) c) d -> t b + t c + t d
+               Let _   _a  b                 -> t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase42.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase42.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase42.stderr
@@ -0,0 +1,18 @@
+SCase42.hs:12:14: error: [GHC-39584]
+    " SCase42.hs:16:16-44: sCase: Non-exhaustive match:
+        Type       : Expr
+        Constructor: Add _ d | (Data.SBV.Core.Data..&&) (isAdd (getAdd_1 e)) ((Data.SBV.Core.Data..&&) (isAdd (getAdd_1 (getAdd_1 e))) (isNum (getAdd_1 (getAdd_1 (getAdd_1 e)))))
+      NB. Guarded match might fail.
+
+    " In the quasi-quotation:
+        [sCase| e of
+               Zero                          -> 0
+               Num k                         -> k
+               Var s                         -> ite (s .== literal "a") 1 2
+               Add (Add (Add (Num _) b) c) d -> t b + t c + t d
+               Let _   _a  b                 -> t b
+      |]
+   |
+12 | t e = [sCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase43.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase43.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase43.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+-- Positive: integer literal at top level (Num 1 -> ...)
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero  -> 0
+               Num 1 -> 100
+               Num k -> k
+               Var _ -> -1
+               Add a b -> t a + t b
+               Let _ _ b -> t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase43.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase43.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase43.stderr
@@ -0,0 +1,24 @@
+SCase43.hs:(12,14)-(19,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \               Zero  -> 0\n\
+      \               Num 1 -> 100\n\
+      \               Num k -> k\n\
+      \               Var _ -> -1\n\
+      \               Add a b -> t a + t b\n\
+      \               Let _ _ b -> t b\n\
+      \      "
+  ======>
+    ite
+      (isZero e) 0
+      (ite
+         ((.&&) (isNum e) ((\ _ -> (.==) (getNum_1 e) 1) (getNum_1 e)))
+         ((\ _ -> 100) (getNum_1 e))
+         (ite
+            (isNum e) ((\ k -> k) (getNum_1 e))
+            (ite
+               (isVar e) ((\ _ -> negate 1) (getVar_1 e))
+               (ite
+                  (isAdd e) ((\ a b -> (t a) + t b) (getAdd_1 e) (getAdd_2 e))
+                  ((\ _ _ b -> t b) (getLet_1 e) (getLet_2 e) (getLet_3 e))))))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase44.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase44.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase44.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+-- Positive: integer literal in nested position (Add (Num 0) j -> ...)
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero          -> 0
+               Num k         -> k
+               Var _         -> -1
+               Add (Num 0) j -> t j
+               Add a       b -> t a + t b
+               Let _ _     b -> t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase44.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase44.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase44.stderr
@@ -0,0 +1,29 @@
+SCase44.hs:(12,14)-(19,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \               Zero          -> 0\n\
+      \               Num k         -> k\n\
+      \               Var _         -> -1\n\
+      \               Add (Num 0) j -> t j\n\
+      \               Add a       b -> t a + t b\n\
+      \               Let _ _     b -> t b\n\
+      \      "
+  ======>
+    ite
+      (isZero e) 0
+      (ite
+         (isNum e) ((\ k -> k) (getNum_1 e))
+         (ite
+            (isVar e) ((\ _ -> negate 1) (getVar_1 e))
+            (ite
+               ((.&&)
+                  (isAdd e)
+                  ((\ _ j
+                      -> const
+                           ((.&&) (isNum (getAdd_1 e)) ((.==) (getNum_1 (getAdd_1 e)) 0)) j)
+                     (getAdd_1 e) (getAdd_2 e)))
+               ((\ _ j -> t j) (getAdd_1 e) (getAdd_2 e))
+               (ite
+                  (isAdd e) ((\ a b -> (t a) + t b) (getAdd_1 e) (getAdd_2 e))
+                  ((\ _ _ b -> t b) (getLet_1 e) (getLet_2 e) (getLet_3 e))))))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase45.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase45.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase45.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+-- Positive: string literal in nested position (Var "x" -> ...)
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero      -> 0
+               Num k     -> k
+               Var "x"   -> 42
+               Var _     -> -1
+               Add a b   -> t a + t b
+               Let _ _ b -> t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase45.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase45.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase45.stderr
@@ -0,0 +1,25 @@
+SCase45.hs:(12,14)-(19,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \               Zero      -> 0\n\
+      \               Num k     -> k\n\
+      \               Var \"x\"   -> 42\n\
+      \               Var _     -> -1\n\
+      \               Add a b   -> t a + t b\n\
+      \               Let _ _ b -> t b\n\
+      \      "
+  ======>
+    ite
+      (isZero e) 0
+      (ite
+         (isNum e) ((\ k -> k) (getNum_1 e))
+         (ite
+            ((.&&)
+               (isVar e) ((\ _ -> (.==) (getVar_1 e) (literal "x")) (getVar_1 e)))
+            ((\ _ -> 42) (getVar_1 e))
+            (ite
+               (isVar e) ((\ _ -> negate 1) (getVar_1 e))
+               (ite
+                  (isAdd e) ((\ a b -> (t a) + t b) (getAdd_1 e) (getAdd_2 e))
+                  ((\ _ _ b -> t b) (getLet_1 e) (getLet_2 e) (getLet_3 e))))))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase46.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase46.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase46.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+-- Positive: integer literals on both sides of nested pattern (Add (Num 1) (Num 2) -> ...)
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero              -> 0
+               Num k             -> k
+               Var _             -> -1
+               Add (Num 1) (Num 2) -> 99
+               Add a           b -> t a + t b
+               Let _       _   b -> t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase46.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase46.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase46.stderr
@@ -0,0 +1,32 @@
+SCase46.hs:(12,14)-(19,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \               Zero              -> 0\n\
+      \               Num k             -> k\n\
+      \               Var _             -> -1\n\
+      \               Add (Num 1) (Num 2) -> 99\n\
+      \               Add a           b -> t a + t b\n\
+      \               Let _       _   b -> t b\n\
+      \      "
+  ======>
+    ite
+      (isZero e) 0
+      (ite
+         (isNum e) ((\ k -> k) (getNum_1 e))
+         (ite
+            (isVar e) ((\ _ -> negate 1) (getVar_1 e))
+            (ite
+               ((.&&)
+                  (isAdd e)
+                  ((\ _ _
+                      -> (.&&)
+                           (isNum (getAdd_1 e))
+                           ((.&&)
+                              ((.==) (getNum_1 (getAdd_1 e)) 1)
+                              ((.&&) (isNum (getAdd_2 e)) ((.==) (getNum_1 (getAdd_2 e)) 2))))
+                     (getAdd_1 e) (getAdd_2 e)))
+               ((\ _ _ -> 99) (getAdd_1 e) (getAdd_2 e))
+               (ite
+                  (isAdd e) ((\ a b -> (t a) + t b) (getAdd_1 e) (getAdd_2 e))
+                  ((\ _ _ b -> t b) (getLet_1 e) (getLet_2 e) (getLet_3 e))))))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase47.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase47.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase47.hs
@@ -0,0 +1,18 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+-- Negative: Num 1 without a fallback for the Num constructor
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero      -> 0
+               Num 1     -> 100
+               Var _     -> -1
+               Add a b   -> t a + t b
+               Let _ _ b -> t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase47.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase47.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase47.stderr
@@ -0,0 +1,18 @@
+SCase47.hs:12:14: error: [GHC-39584]
+    " SCase47.hs:14:16-20: sCase: Non-exhaustive match:
+        Type       : Expr
+        Constructor: Num _ | (Data.SBV.Core.Data..==) (getNum_1 e) 1
+      NB. Guarded match might fail.
+
+    " In the quasi-quotation:
+        [sCase| e of
+               Zero      -> 0
+               Num 1     -> 100
+               Var _     -> -1
+               Add a b   -> t a + t b
+               Let _ _ b -> t b
+      |]
+   |
+12 | t e = [sCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase48.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase48.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase48.hs
@@ -0,0 +1,18 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+-- Negative: Add (Num 1) j without a fallback for the Add constructor
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero          -> 0
+               Num k         -> k
+               Var _         -> -1
+               Add (Num 1) j -> 100 + t j
+               Let _ _     b -> t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase48.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase48.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase48.stderr
@@ -0,0 +1,18 @@
+SCase48.hs:12:14: error: [GHC-39584]
+    " SCase48.hs:16:16-28: sCase: Non-exhaustive match:
+        Type       : Expr
+        Constructor: Add _ j | (Data.SBV.Core.Data..&&) (isNum (getAdd_1 e)) ((Data.SBV.Core.Data..==) (getNum_1 (getAdd_1 e)) 1)
+      NB. Guarded match might fail.
+
+    " In the quasi-quotation:
+        [sCase| e of
+               Zero          -> 0
+               Num k         -> k
+               Var _         -> -1
+               Add (Num 1) j -> 100 + t j
+               Let _ _     b -> t b
+      |]
+   |
+12 | t e = [sCase| e of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase49.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase49.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase49.hs
@@ -0,0 +1,18 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+-- Dump test: simple unguarded, all constructors, no guards/wildcards/nesting
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero          -> 0
+               Num i         -> i
+               Var _         -> 1
+               Add _ _       -> 2
+               Let _ _ _     -> 3
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase49.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase49.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase49.stderr
@@ -0,0 +1,12 @@
+SCase49.hs:(12,14)-(18,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \               Zero          -> 0\n\
+      \               Num i         -> i\n\
+      \               Var _         -> 1\n\
+      \               Add _ _       -> 2\n\
+      \               Let _ _ _     -> 3\n\
+      \      "
+  ======>
+    sCaseExpr 0 (\ i -> i) (\ _ -> 1) (\ _ _ -> 2) (\ _ _ _ -> 3) e
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase50.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase50.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase50.hs
@@ -0,0 +1,20 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+-- Dump test: multiple guards on same constructor (guard accumulation, ite chain)
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero              -> 0
+               Num i | i .< 3    -> i
+                     | i .< 10   -> i + 1
+               Num i             -> i + 2
+               Var _             -> 1
+               Add _ _           -> 2
+               Let _ _ _         -> 3
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase50.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase50.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase50.stderr
@@ -0,0 +1,28 @@
+SCase50.hs:(12,14)-(20,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \               Zero              -> 0\n\
+      \               Num i | i .< 3    -> i\n\
+      \                     | i .< 10   -> i + 1\n\
+      \               Num i             -> i + 2\n\
+      \               Var _             -> 1\n\
+      \               Add _ _           -> 2\n\
+      \               Let _ _ _         -> 3\n\
+      \      "
+  ======>
+    ite
+      (isZero e) 0
+      (ite
+         ((.&&) (isNum e) ((\ i -> i .< 3) (getNum_1 e)))
+         ((\ i -> i) (getNum_1 e))
+         (ite
+            ((.&&) (isNum e) ((\ i -> i .< 10) (getNum_1 e)))
+            ((\ i -> i + 1) (getNum_1 e))
+            (ite
+               (isNum e) ((\ i -> i + 2) (getNum_1 e))
+               (ite
+                  (isVar e) ((\ _ -> 1) (getVar_1 e))
+                  (ite
+                     (isAdd e) ((\ _ _ -> 2) (getAdd_1 e) (getAdd_2 e))
+                     ((\ _ _ _ -> 3) (getLet_1 e) (getLet_2 e) (getLet_3 e)))))))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase51.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase51.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase51.hs
@@ -0,0 +1,16 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+-- Dump test: wildcard catch-all after some constructors (ite chain with default)
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero          -> 0
+               Num i         -> i
+               _             -> 99
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase51.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase51.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase51.stderr
@@ -0,0 +1,10 @@
+SCase51.hs:(12,14)-(16,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \               Zero          -> 0\n\
+      \               Num i         -> i\n\
+      \               _             -> 99\n\
+      \      "
+  ======>
+    sCaseExpr 0 (\ i -> i) (\ _ -> 99) (\ _ _ -> 99) (\ _ _ _ -> 99) e
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase52.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase52.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase52.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+-- Dump test: nested pattern with literal (synthetic guards, accessors, let-bindings)
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Add (Num 0) j -> t j
+               Add a b       -> t a + t b
+               Zero          -> 0
+               Num i         -> i
+               Var _         -> 1
+               Let _ _ _     -> 3
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase52.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase52.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase52.stderr
@@ -0,0 +1,29 @@
+SCase52.hs:(12,14)-(19,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \               Add (Num 0) j -> t j\n\
+      \               Add a b       -> t a + t b\n\
+      \               Zero          -> 0\n\
+      \               Num i         -> i\n\
+      \               Var _         -> 1\n\
+      \               Let _ _ _     -> 3\n\
+      \      "
+  ======>
+    ite
+      ((.&&)
+         (isAdd e)
+         ((\ _ j
+             -> const
+                  ((.&&) (isNum (getAdd_1 e)) ((.==) (getNum_1 (getAdd_1 e)) 0)) j)
+            (getAdd_1 e) (getAdd_2 e)))
+      ((\ _ j -> t j) (getAdd_1 e) (getAdd_2 e))
+      (ite
+         (isAdd e) ((\ a b -> (t a) + t b) (getAdd_1 e) (getAdd_2 e))
+         (ite
+            (isZero e) 0
+            (ite
+               (isNum e) ((\ i -> i) (getNum_1 e))
+               (ite
+                  (isVar e) ((\ _ -> 1) (getVar_1 e))
+                  ((\ _ _ _ -> 3) (getLet_1 e) (getLet_2 e) (getLet_3 e))))))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase53.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase53.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase53.hs
@@ -0,0 +1,20 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+-- Dump test: nested pattern with user guard (combines nesting + guard accumulation)
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Add (Num i) b | i .> 0   -> i + t b
+                              | i .> -5  -> t b
+               Add a b                   -> t a + t b
+               Zero                      -> 0
+               Num i                     -> i
+               Var _                     -> 1
+               Let _ _ _                 -> 3
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase53.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase53.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase53.stderr
@@ -0,0 +1,44 @@
+SCase53.hs:(12,14)-(20,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \               Add (Num i) b | i .> 0   -> i + t b\n\
+      \                              | i .> -5  -> t b\n\
+      \               Add a b                   -> t a + t b\n\
+      \               Zero                      -> 0\n\
+      \               Num i                     -> i\n\
+      \               Var _                     -> 1\n\
+      \               Let _ _ _                 -> 3\n\
+      \      "
+  ======>
+    ite
+      ((.&&)
+         (isAdd e)
+         ((\ _ b
+             -> const
+                  ((.&&)
+                     (isNum (getAdd_1 e)) (let i = getNum_1 (getAdd_1 e) in i .> 0))
+                  b)
+            (getAdd_1 e) (getAdd_2 e)))
+      ((\ _ b -> let i = getNum_1 (getAdd_1 e) in i + t b)
+         (getAdd_1 e) (getAdd_2 e))
+      (ite
+         ((.&&)
+            (isAdd e)
+            ((\ _ b
+                -> const
+                     ((.&&)
+                        (isNum (getAdd_1 e))
+                        (let i = getNum_1 (getAdd_1 e) in i .> negate 5))
+                     b)
+               (getAdd_1 e) (getAdd_2 e)))
+         ((\ _ b -> t b) (getAdd_1 e) (getAdd_2 e))
+         (ite
+            (isAdd e) ((\ a b -> (t a) + t b) (getAdd_1 e) (getAdd_2 e))
+            (ite
+               (isZero e) 0
+               (ite
+                  (isNum e) ((\ i -> i) (getNum_1 e))
+                  (ite
+                     (isVar e) ((\ _ -> 1) (getVar_1 e))
+                     ((\ _ _ _ -> 3) (getLet_1 e) (getLet_2 e) (getLet_3 e)))))))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase54.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase54.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase54.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with Maybe (no guards)
+module T where
+
+import Data.SBV
+
+t :: SMaybe Integer -> SInteger
+t m = [sCase| m of
+               Nothing -> 0
+               Just x  -> x + 1
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase54.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase54.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase54.stderr
@@ -0,0 +1,9 @@
+SCase54.hs:(11,14)-(14,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " m of\n\
+      \               Nothing -> 0\n\
+      \               Just x  -> x + 1\n\
+      \      "
+  ======>
+    Data.SBV.Maybe.sCaseMaybe 0 (\ x -> x + 1) m
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase55.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase55.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase55.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with Either (no guards)
+module T where
+
+import Data.SBV
+
+t :: SEither Integer Bool -> SInteger
+t e = [sCase| e of
+               Left a  -> a
+               Right _ -> 0
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase55.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase55.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase55.stderr
@@ -0,0 +1,9 @@
+SCase55.hs:(11,14)-(14,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \               Left a  -> a\n\
+      \               Right _ -> 0\n\
+      \      "
+  ======>
+    Data.SBV.Either.sCaseEither (\ a -> a) (\ _ -> 0) e
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase56.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase56.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase56.hs
@@ -0,0 +1,16 @@
+{-# LANGUAGE QuasiQuotes     #-}
+{-# LANGUAGE OverloadedLists #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with List (no guards)
+module T where
+
+import Prelude hiding (null, head, tail)
+import Data.SBV
+
+t :: SList Integer -> SInteger
+t xs = [sCase| xs of
+                []     -> 0
+                y : ys -> y + t ys
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase56.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase56.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase56.stderr
@@ -0,0 +1,12 @@
+SCase56.hs:(13,15)-(16,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " xs of\n\
+      \                []     -> 0\n\
+      \                y : ys -> y + t ys\n\
+      \       "
+  ======>
+    ite
+      (Data.SBV.List.null xs) 0
+      ((\ y ys -> y + t ys)
+         (Data.SBV.List.head xs) (Data.SBV.List.tail xs))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase57.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase57.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase57.hs
@@ -0,0 +1,13 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with Tuple2
+module T where
+
+import Data.SBV
+
+t :: STuple Integer Bool -> SInteger
+t p = [sCase| p of
+               (a, _) -> a + 1
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase57.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase57.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase57.stderr
@@ -0,0 +1,8 @@
+SCase57.hs:(11,14)-(13,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " p of\n\
+      \               (a, _) -> a + 1\n\
+      \      "
+  ======>
+    (\ a _ -> a + 1) (Data.SBV.Tuple._1 p) (Data.SBV.Tuple._2 p)
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase58.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase58.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase58.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE QuasiQuotes     #-}
+{-# LANGUAGE OverloadedLists #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with List, nested cons pattern
+module T where
+
+import Prelude hiding (null, head, tail)
+import Data.SBV
+
+t :: SList Integer -> SInteger
+t xs = [sCase| xs of
+                []          -> 0
+                a : (b : _) -> a + b
+                _ : _       -> 1
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase58.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase58.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase58.stderr
@@ -0,0 +1,28 @@
+SCase58.hs:(13,15)-(17,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " xs of\n\
+      \                []          -> 0\n\
+      \                a : (b : _) -> a + b\n\
+      \                _ : _       -> 1\n\
+      \       "
+  ======>
+    ite
+      (Data.SBV.List.null xs) 0
+      (ite
+         ((.&&)
+            (sNot (Data.SBV.List.null xs))
+            ((\ a _
+                -> const
+                     ((.&&)
+                        (sNot (Data.SBV.List.null (Data.SBV.List.tail xs)))
+                        ((.===)
+                           (Data.SBV.List.tail xs)
+                           (Data.SBV.List.head (Data.SBV.List.tail xs)
+                              .: Data.SBV.List.tail (Data.SBV.List.tail xs))))
+                     a)
+               (Data.SBV.List.head xs) (Data.SBV.List.tail xs)))
+         ((\ a _
+             -> let b = Data.SBV.List.head (Data.SBV.List.tail xs) in a + b)
+            (Data.SBV.List.head xs) (Data.SBV.List.tail xs))
+         ((\ _ _ -> 1) (Data.SBV.List.head xs) (Data.SBV.List.tail xs)))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase59.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase59.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase59.hs
@@ -0,0 +1,15 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with Maybe, nested Either pattern
+module T where
+
+import Data.SBV
+
+t :: SMaybe (Either Integer Bool) -> SInteger
+t m = [sCase| m of
+               Nothing          -> 0
+               Just (Left x)    -> x
+               Just (Right _)   -> 1
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase59.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase59.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase59.stderr
@@ -0,0 +1,27 @@
+SCase59.hs:(11,14)-(15,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " m of\n\
+      \               Nothing          -> 0\n\
+      \               Just (Left x)    -> x\n\
+      \               Just (Right _)   -> 1\n\
+      \      "
+  ======>
+    ite
+      (Data.SBV.Maybe.isNothing m) 0
+      (ite
+         ((.&&)
+            (Data.SBV.Maybe.isJust m)
+            ((\ _ -> Data.SBV.Either.isLeft (Data.SBV.Maybe.getJust_1 m))
+               (Data.SBV.Maybe.getJust_1 m)))
+         ((\ _
+             -> let x = Data.SBV.Either.getLeft_1 (Data.SBV.Maybe.getJust_1 m)
+                in x)
+            (Data.SBV.Maybe.getJust_1 m))
+         (ite
+            ((.&&)
+               (Data.SBV.Maybe.isJust m)
+               ((\ _ -> Data.SBV.Either.isRight (Data.SBV.Maybe.getJust_1 m))
+                  (Data.SBV.Maybe.getJust_1 m)))
+            ((\ _ -> 1) (Data.SBV.Maybe.getJust_1 m))
+            (symWithKind "unmatched_sCase_Maybe_6989586621679035188")))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase60.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase60.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase60.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE QuasiQuotes     #-}
+{-# LANGUAGE OverloadedLists #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with List and guards
+module T where
+
+import Prelude hiding (null, head, tail)
+import Data.SBV
+
+t :: SList Integer -> SInteger
+t xs = [sCase| xs of
+                []         -> 0
+                y : _ | y .== 5 -> 100
+                _ : ys     -> t ys
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase60.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase60.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase60.stderr
@@ -0,0 +1,19 @@
+SCase60.hs:(13,15)-(17,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " xs of\n\
+      \                []         -> 0\n\
+      \                y : _ | y .== 5 -> 100\n\
+      \                _ : ys     -> t ys\n\
+      \       "
+  ======>
+    ite
+      (Data.SBV.List.null xs) 0
+      (ite
+         ((.&&)
+            (sNot (Data.SBV.List.null xs))
+            ((\ y _ -> y .== 5)
+               (Data.SBV.List.head xs) (Data.SBV.List.tail xs)))
+         ((\ y _ -> const 100 y)
+            (Data.SBV.List.head xs) (Data.SBV.List.tail xs))
+         ((\ _ ys -> t ys) (Data.SBV.List.head xs) (Data.SBV.List.tail xs)))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase61.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase61.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase61.hs
@@ -0,0 +1,15 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with Maybe, guards on Just
+module T where
+
+import Data.SBV
+
+t :: SMaybe Integer -> SInteger
+t m = [sCase| m of
+               Nothing        -> 0
+               Just x | x .> 5 -> x * 2
+               Just x         -> x
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase61.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase61.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase61.stderr
@@ -0,0 +1,17 @@
+SCase61.hs:(11,14)-(15,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " m of\n\
+      \               Nothing        -> 0\n\
+      \               Just x | x .> 5 -> x * 2\n\
+      \               Just x         -> x\n\
+      \      "
+  ======>
+    ite
+      (Data.SBV.Maybe.isNothing m) 0
+      (ite
+         ((.&&)
+            (Data.SBV.Maybe.isJust m)
+            ((\ x -> x .> 5) (Data.SBV.Maybe.getJust_1 m)))
+         ((\ x -> x * 2) (Data.SBV.Maybe.getJust_1 m))
+         ((\ x -> x) (Data.SBV.Maybe.getJust_1 m)))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase62.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase62.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase62.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with Either, guards and wildcard
+module T where
+
+import Data.SBV
+
+t :: SEither Integer Integer -> SInteger
+t e = [sCase| e of
+               Left x | x .> 0 -> x
+               _               -> 0
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase62.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase62.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase62.stderr
@@ -0,0 +1,13 @@
+SCase62.hs:(11,14)-(14,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \               Left x | x .> 0 -> x\n\
+      \               _               -> 0\n\
+      \      "
+  ======>
+    ite
+      ((.&&)
+         (Data.SBV.Either.isLeft e)
+         ((\ x -> x .> 0) (Data.SBV.Either.getLeft_1 e)))
+      ((\ x -> x) (Data.SBV.Either.getLeft_1 e)) 0
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase63.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase63.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase63.hs
@@ -0,0 +1,13 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with Tuple3
+module T where
+
+import Data.SBV
+
+t :: STuple3 Integer Integer Bool -> SInteger
+t p = [sCase| p of
+               (a, b, _) -> a + b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase63.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase63.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase63.stderr
@@ -0,0 +1,9 @@
+SCase63.hs:(11,14)-(13,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " p of\n\
+      \               (a, b, _) -> a + b\n\
+      \      "
+  ======>
+    (\ a b _ -> a + b)
+      (Data.SBV.Tuple._1 p) (Data.SBV.Tuple._2 p) (Data.SBV.Tuple._3 p)
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase64.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase64.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase64.hs
@@ -0,0 +1,16 @@
+{-# LANGUAGE QuasiQuotes     #-}
+{-# LANGUAGE OverloadedLists #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with List, wildcard only for cons
+module T where
+
+import Prelude hiding (null, head, tail)
+import Data.SBV
+
+t :: SList Integer -> SBool
+t xs = [sCase| xs of
+                []     -> sTrue
+                _ : _  -> sFalse
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase64.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase64.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase64.stderr
@@ -0,0 +1,11 @@
+SCase64.hs:(13,15)-(16,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " xs of\n\
+      \                []     -> sTrue\n\
+      \                _ : _  -> sFalse\n\
+      \       "
+  ======>
+    ite
+      (Data.SBV.List.null xs) sTrue
+      ((\ _ _ -> sFalse) (Data.SBV.List.head xs) (Data.SBV.List.tail xs))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase65.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase65.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase65.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with nested tuple inside Maybe
+module T where
+
+import Data.SBV
+
+t :: SMaybe (Integer, Bool) -> SInteger
+t m = [sCase| m of
+               Nothing     -> 0
+               Just (a, _) -> a
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase65.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase65.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase65.stderr
@@ -0,0 +1,13 @@
+SCase65.hs:(11,14)-(14,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " m of\n\
+      \               Nothing     -> 0\n\
+      \               Just (a, _) -> a\n\
+      \      "
+  ======>
+    Data.SBV.Maybe.sCaseMaybe
+      0
+      (\ _
+         -> let a = Data.SBV.Tuple._1 (Data.SBV.Maybe.getJust_1 m) in a)
+      m
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase66.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase66.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase66.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE QuasiQuotes     #-}
+{-# LANGUAGE OverloadedLists #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with nested list inside Either
+module T where
+
+import Prelude hiding (null, head, tail)
+import Data.SBV
+
+t :: SEither ([] Integer) Bool -> SInteger
+t e = [sCase| e of
+               Left (x : _) -> x
+               Left []      -> 0
+               Right _      -> 1
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase66.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase66.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase66.stderr
@@ -0,0 +1,33 @@
+SCase66.hs:(13,14)-(17,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \               Left (x : _) -> x\n\
+      \               Left []      -> 0\n\
+      \               Right _      -> 1\n\
+      \      "
+  ======>
+    ite
+      ((.&&)
+         (Data.SBV.Either.isLeft e)
+         ((\ _
+             -> (.&&)
+                  (sNot (Data.SBV.List.null (Data.SBV.Either.getLeft_1 e)))
+                  ((.===)
+                     (Data.SBV.Either.getLeft_1 e)
+                     (Data.SBV.List.head (Data.SBV.Either.getLeft_1 e)
+                        .: Data.SBV.List.tail (Data.SBV.Either.getLeft_1 e))))
+            (Data.SBV.Either.getLeft_1 e)))
+      ((\ _
+          -> let x = Data.SBV.List.head (Data.SBV.Either.getLeft_1 e) in x)
+         (Data.SBV.Either.getLeft_1 e))
+      (ite
+         ((.&&)
+            (Data.SBV.Either.isLeft e)
+            ((\ _ -> Data.SBV.List.null (Data.SBV.Either.getLeft_1 e))
+               (Data.SBV.Either.getLeft_1 e)))
+         ((\ _ -> 0) (Data.SBV.Either.getLeft_1 e))
+         (ite
+            (Data.SBV.Either.isRight e)
+            ((\ _ -> 1) (Data.SBV.Either.getRight_1 e))
+            (symWithKind "unmatched_sCase_Either_6989586621679035150")))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase67.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase67.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase67.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with Tuple2 with guard
+module T where
+
+import Data.SBV
+
+t :: STuple Integer Integer -> SInteger
+t p = [sCase| p of
+               (a, b) | a .> b -> a
+               (_, b)          -> b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase67.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase67.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase67.stderr
@@ -0,0 +1,12 @@
+SCase67.hs:(11,14)-(14,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " p of\n\
+      \               (a, b) | a .> b -> a\n\
+      \               (_, b)          -> b\n\
+      \      "
+  ======>
+    ite
+      ((\ a b -> a .> b) (Data.SBV.Tuple._1 p) (Data.SBV.Tuple._2 p))
+      ((\ a b -> const a b) (Data.SBV.Tuple._1 p) (Data.SBV.Tuple._2 p))
+      ((\ _ b -> b) (Data.SBV.Tuple._1 p) (Data.SBV.Tuple._2 p))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase68.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase68.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase68.hs
@@ -0,0 +1,13 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with wildcard-only, no guards
+module T where
+
+import Data.SBV
+
+t :: SInteger -> SInteger
+t x = [sCase| x of
+               _ -> x + 1
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase68.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase68.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase68.stderr
@@ -0,0 +1,8 @@
+SCase68.hs:(11,14)-(13,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " x of\n\
+      \               _ -> x + 1\n\
+      \      "
+  ======>
+    x + 1
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase69.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase69.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase69.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with guarded wildcards only
+module T where
+
+import Data.SBV
+
+t :: SInteger -> SInteger
+t x = [sCase| x of
+               _ | x .> 0 -> x
+                 | sTrue   -> -x
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase69.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase69.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase69.stderr
@@ -0,0 +1,9 @@
+SCase69.hs:(11,14)-(14,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " x of\n\
+      \               _ | x .> 0 -> x\n\
+      \                 | sTrue   -> -x\n\
+      \      "
+  ======>
+    ite (x .> 0) x (negate x)
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase70.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase70.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase70.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with integer literal pattern and wildcard
+module T where
+
+import Data.SBV
+
+t :: SInteger -> SBool
+t x = [sCase| x of
+               0 -> sTrue
+               _ -> sFalse
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase70.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase70.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase70.stderr
@@ -0,0 +1,9 @@
+SCase70.hs:(11,14)-(14,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " x of\n\
+      \               0 -> sTrue\n\
+      \               _ -> sFalse\n\
+      \      "
+  ======>
+    ite ((.==) x 0) sTrue sFalse
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase71.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase71.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase71.hs
@@ -0,0 +1,16 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with multiple integer literals and wildcard
+module T where
+
+import Data.SBV
+
+t :: SInteger -> SInteger
+t x = [sCase| x of
+               0 -> 10
+               1 -> 20
+               2 -> 30
+               _ -> x
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase71.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase71.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase71.stderr
@@ -0,0 +1,11 @@
+SCase71.hs:(11,14)-(16,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " x of\n\
+      \               0 -> 10\n\
+      \               1 -> 20\n\
+      \               2 -> 30\n\
+      \               _ -> x\n\
+      \      "
+  ======>
+    ite ((.==) x 0) 10 (ite ((.==) x 1) 20 (ite ((.==) x 2) 30 x))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase72.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase72.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase72.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with integer literal and variable binding
+module T where
+
+import Data.SBV
+
+t :: SInteger -> SInteger
+t x = [sCase| x of
+               0 -> 0
+               n -> n + 1
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase72.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase72.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase72.stderr
@@ -0,0 +1,9 @@
+SCase72.hs:(11,14)-(14,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " x of\n\
+      \               0 -> 0\n\
+      \               n -> n + 1\n\
+      \      "
+  ======>
+    ite ((.==) x 0) 0 (let n = x in n + 1)
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase73.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase73.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase73.hs
@@ -0,0 +1,15 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with char literal patterns
+module T where
+
+import Data.SBV
+
+t :: SChar -> SBool
+t c = [sCase| c of
+               'a' -> sTrue
+               'b' -> sTrue
+               _   -> sFalse
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase73.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase73.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase73.stderr
@@ -0,0 +1,12 @@
+SCase73.hs:(11,14)-(15,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " c of\n\
+      \               'a' -> sTrue\n\
+      \               'b' -> sTrue\n\
+      \               _   -> sFalse\n\
+      \      "
+  ======>
+    ite
+      ((.==) c (literal 'a')) sTrue
+      (ite ((.==) c (literal 'b')) sTrue sFalse)
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase74.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase74.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase74.hs
@@ -0,0 +1,15 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with integer literal and guard
+module T where
+
+import Data.SBV
+
+t :: SInteger -> SInteger -> SInteger
+t x y = [sCase| x of
+                 0         -> y
+                 _ | x .> y -> x
+                   | sTrue  -> y
+        |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase74.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase74.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase74.stderr
@@ -0,0 +1,10 @@
+SCase74.hs:(11,16)-(15,10): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " x of\n\
+      \                 0         -> y\n\
+      \                 _ | x .> y -> x\n\
+      \                   | sTrue  -> y\n\
+      \        "
+  ======>
+    ite ((.==) x 0) y (ite (x .> y) x y)
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase75.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase75.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase75.hs
@@ -0,0 +1,15 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with string literal patterns
+module T where
+
+import Data.SBV
+
+t :: SString -> SInteger
+t s = [sCase| s of
+               "hello" -> 1
+               "world" -> 2
+               _       -> 0
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase75.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase75.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase75.stderr
@@ -0,0 +1,11 @@
+SCase75.hs:(11,14)-(15,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " s of\n\
+      \               \"hello\" -> 1\n\
+      \               \"world\" -> 2\n\
+      \               _       -> 0\n\
+      \      "
+  ======>
+    ite
+      ((.==) s (literal "hello")) 1 (ite ((.==) s (literal "world")) 2 0)
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase76.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase76.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase76.hs
@@ -0,0 +1,15 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with negative integer literal (uses LitP with negative value)
+module T where
+
+import Data.SBV
+
+t :: SInteger -> SBool
+t x = [sCase| x of
+               0    -> sTrue
+               (-1) -> sTrue
+               _    -> sFalse
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase76.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase76.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase76.stderr
@@ -0,0 +1,10 @@
+SCase76.hs:(11,14)-(15,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " x of\n\
+      \               0    -> sTrue\n\
+      \               (-1) -> sTrue\n\
+      \               _    -> sFalse\n\
+      \      "
+  ======>
+    ite ((.==) x 0) sTrue (ite ((.==) x (-1)) sTrue sFalse)
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase77.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase77.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase77.hs
@@ -0,0 +1,16 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with integer literal patterns (no dump, just compilation check)
+-- Tests that the generated code actually type-checks with SBV types
+module T where
+
+import Data.SBV
+
+clamp :: SInteger -> SInteger
+clamp x = [sCase| x of
+                   0 -> 0
+                   1 -> 1
+                   n -> ite (n .> 0) 100 (-100)
+           |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase77.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase77.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase77.stderr
@@ -0,0 +1,12 @@
+SCase77.hs:(12,18)-(16,13): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " x of\n\
+      \                   0 -> 0\n\
+      \                   1 -> 1\n\
+      \                   n -> ite (n .> 0) 100 (-100)\n\
+      \           "
+  ======>
+    ite
+      ((.==) x 0) 0
+      (ite ((.==) x 1) 1 (let n = x in ite (n .> 0) 100 (negate 100)))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase78.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase78.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase78.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with Bool constructor patterns
+module T where
+
+import Data.SBV
+
+t :: SBool -> SBool
+t x = [sCase| x of
+               True  -> sTrue
+               False -> sFalse
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase78.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase78.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase78.stderr
@@ -0,0 +1,9 @@
+SCase78.hs:(11,14)-(14,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " x of\n\
+      \               True  -> sTrue\n\
+      \               False -> sFalse\n\
+      \      "
+  ======>
+    ite x sTrue sFalse
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase79.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase79.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase79.hs
@@ -0,0 +1,15 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with Bool patterns and guard
+module T where
+
+import Data.SBV
+
+t :: SBool -> SInteger -> SInteger
+t b x = [sCase| b of
+                 True  | x .> 0 -> x
+                 True           -> 0
+                 False          -> -x
+        |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase79.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase79.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase79.stderr
@@ -0,0 +1,10 @@
+SCase79.hs:(11,16)-(15,10): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " b of\n\
+      \                 True  | x .> 0 -> x\n\
+      \                 True           -> 0\n\
+      \                 False          -> -x\n\
+      \        "
+  ======>
+    ite ((.&&) b (x .> 0)) x (ite b 0 (negate x))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase80.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase80.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase80.hs
@@ -0,0 +1,13 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase Bool non-exhaustive (only True, no wildcard) — should fail
+module T where
+
+import Data.SBV
+
+t :: SBool -> SInteger
+t x = [sCase| x of
+               True -> 1
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase80.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase80.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase80.stderr
@@ -0,0 +1,16 @@
+SCase80.hs:11:14: error: [GHC-39584]
+    " sCase: Pattern match(es) are non-exhaustive.
+        Not matched     : False
+        Patterns of type: Bool
+        Must match each : True, False
+
+      You can use a '_' to match multiple cases.
+
+    " In the quasi-quotation:
+        [sCase| x of
+               True -> 1
+      |]
+   |
+11 | t x = [sCase| x of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase81.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase81.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase81.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase Bool with wildcard catch-all
+module T where
+
+import Data.SBV
+
+t :: SBool -> SInteger
+t x = [sCase| x of
+               True -> 1
+               _    -> 0
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase81.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase81.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase81.stderr
@@ -0,0 +1,9 @@
+SCase81.hs:(11,14)-(14,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " x of\n\
+      \               True -> 1\n\
+      \               _    -> 0\n\
+      \      "
+  ======>
+    ite x 1 0
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase82.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase82.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase82.hs
@@ -0,0 +1,16 @@
+{-# LANGUAGE QuasiQuotes #-}
+{-# LANGUAGE DataKinds   #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with Word8 integer literal patterns
+module T where
+
+import Data.SBV
+
+t :: SWord8 -> SWord8
+t x = [sCase| x of
+               0 -> 10
+               1 -> 20
+               _ -> x
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase82.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase82.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase82.stderr
@@ -0,0 +1,10 @@
+SCase82.hs:(12,14)-(16,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " x of\n\
+      \               0 -> 10\n\
+      \               1 -> 20\n\
+      \               _ -> x\n\
+      \      "
+  ======>
+    ite ((.==) x 0) 10 (ite ((.==) x 1) 20 x)
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase83.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase83.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase83.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE QuasiQuotes #-}
+{-# LANGUAGE DataKinds   #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with Int16 integer literals, variable binding, and guard
+module T where
+
+import Data.SBV
+
+t :: SInt16 -> SInt16
+t x = [sCase| x of
+               0          -> 0
+               1          -> 100
+               n | n .> 0 -> n
+                 | sTrue   -> -n
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase83.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase83.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase83.stderr
@@ -0,0 +1,16 @@
+SCase83.hs:(12,14)-(17,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " x of\n\
+      \               0          -> 0\n\
+      \               1          -> 100\n\
+      \               n | n .> 0 -> n\n\
+      \                 | sTrue   -> -n\n\
+      \      "
+  ======>
+    ite
+      ((.==) x 0) 0
+      (ite
+         ((.==) x 1) 100
+         (ite
+            (let n = x in n .> 0) (let n = x in n) (let n = x in negate n)))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase84.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase84.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase84.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase Integer non-exhaustive (all guarded, no catch-all) — should fail
+module T where
+
+import Data.SBV
+
+t :: SInteger -> SBool
+t x = [sCase| x of
+               0 -> sTrue
+               1 -> sFalse
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase84.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase84.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase84.stderr
@@ -0,0 +1,14 @@
+SCase84.hs:11:14: error: [GHC-39584]
+    " SCase84.hs:12:16: sCase: Non-exhaustive pattern match.
+        All branches are guarded; add an unguarded wildcard or variable
+        as the last branch to ensure all cases are covered.
+
+    " In the quasi-quotation:
+        [sCase| x of
+               0 -> sTrue
+               1 -> sFalse
+      |]
+   |
+11 | t x = [sCase| x of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase85.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase85.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase85.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase Bool reversed order (False first, then True)
+module T where
+
+import Data.SBV
+
+t :: SBool -> SInteger
+t x = [sCase| x of
+               False -> 0
+               True  -> 1
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase85.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase85.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase85.stderr
@@ -0,0 +1,9 @@
+SCase85.hs:(11,14)-(14,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " x of\n\
+      \               False -> 0\n\
+      \               True  -> 1\n\
+      \      "
+  ======>
+    ite (sNot x) 0 1
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase86.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase86.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase86.hs
@@ -0,0 +1,16 @@
+{-# LANGUAGE QuasiQuotes #-}
+{-# LANGUAGE DataKinds   #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase with Word8 and mixed literal/variable/wildcard
+module T where
+
+import Data.SBV
+
+t :: SWord8 -> SWord8 -> SWord8
+t x y = [sCase| x of
+                 0         -> y
+                 n | n .> y -> n
+                   | sTrue  -> y
+        |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase86.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase86.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase86.stderr
@@ -0,0 +1,10 @@
+SCase86.hs:(12,16)-(16,10): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " x of\n\
+      \                 0         -> y\n\
+      \                 n | n .> y -> n\n\
+      \                   | sTrue  -> y\n\
+      \        "
+  ======>
+    ite ((.==) x 0) y (ite (let n = x in n .> y) (let n = x in n) y)
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase87.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase87.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase87.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase String non-exhaustive (only literals, no catch-all) — should fail
+module T where
+
+import Data.SBV
+
+t :: SString -> SInteger
+t s = [sCase| s of
+               "hello" -> 1
+               "world" -> 2
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase87.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase87.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase87.stderr
@@ -0,0 +1,14 @@
+SCase87.hs:11:14: error: [GHC-39584]
+    " SCase87.hs:12:16-22: sCase: Non-exhaustive pattern match.
+        All branches are guarded; add an unguarded wildcard or variable
+        as the last branch to ensure all cases are covered.
+
+    " In the quasi-quotation:
+        [sCase| s of
+               "hello" -> 1
+               "world" -> 2
+      |]
+   |
+11 | t s = [sCase| s of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase88.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase88.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase88.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Test: sCase Char non-exhaustive (only literals, no catch-all) — should fail
+module T where
+
+import Data.SBV
+
+t :: SChar -> SBool
+t c = [sCase| c of
+               'x' -> sTrue
+               'y' -> sFalse
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase88.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase88.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase88.stderr
@@ -0,0 +1,14 @@
+SCase88.hs:11:14: error: [GHC-39584]
+    " SCase88.hs:12:16-18: sCase: Non-exhaustive pattern match.
+        All branches are guarded; add an unguarded wildcard or variable
+        as the last branch to ensure all cases are covered.
+
+    " In the quasi-quotation:
+        [sCase| c of
+               'x' -> sTrue
+               'y' -> sFalse
+      |]
+   |
+11 | t c = [sCase| c of
+   |              ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase89.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase89.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase89.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+module T where
+
+import Expr
+import Data.SBV
+
+-- Dump test: nested pattern with user guard (combines nesting + guard accumulation)
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Add (Num i) b | i .> 0   -> i + t b
+                              | i .> -5  -> t b
+               Zero                      -> 0
+               Num i                     -> i
+               Var _                     -> 1
+               Let _ _ _                 -> 3
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase89.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase89.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase89.stderr
@@ -0,0 +1,43 @@
+SCase89.hs:(12,14)-(19,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \               Add (Num i) b | i .> 0   -> i + t b\n\
+      \                              | i .> -5  -> t b\n\
+      \               Zero                      -> 0\n\
+      \               Num i                     -> i\n\
+      \               Var _                     -> 1\n\
+      \               Let _ _ _                 -> 3\n\
+      \      "
+  ======>
+    ite
+      ((.&&)
+         (isAdd e)
+         ((\ _ b
+             -> const
+                  ((.&&)
+                     (isNum (getAdd_1 e)) (let i = getNum_1 (getAdd_1 e) in i .> 0))
+                  b)
+            (getAdd_1 e) (getAdd_2 e)))
+      ((\ _ b -> let i = getNum_1 (getAdd_1 e) in i + t b)
+         (getAdd_1 e) (getAdd_2 e))
+      (ite
+         ((.&&)
+            (isAdd e)
+            ((\ _ b
+                -> const
+                     ((.&&)
+                        (isNum (getAdd_1 e))
+                        (let i = getNum_1 (getAdd_1 e) in i .> negate 5))
+                     b)
+               (getAdd_1 e) (getAdd_2 e)))
+         ((\ _ b -> t b) (getAdd_1 e) (getAdd_2 e))
+         (ite
+            (isZero e) 0
+            (ite
+               (isNum e) ((\ i -> i) (getNum_1 e))
+               (ite
+                  (isVar e) ((\ _ -> 1) (getVar_1 e))
+                  (ite
+                     (isLet e) ((\ _ _ _ -> 3) (getLet_1 e) (getLet_2 e) (getLet_3 e))
+                     (symWithKind "unmatched_sCase_Expr_6989586621679080842"))))))
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase90.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase90.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase90.hs
@@ -0,0 +1,20 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Positive: Nested case expressions. Inner case on Maybe inside outer case on Expr.
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SMaybe Integer -> SInteger
+t e m = [sCase| e of
+                Zero      -> case m of
+                               Nothing -> 0
+                               Just v  -> v
+                Num k     -> k
+                Var _     -> -1
+                Add a b   -> t a m + t b m
+                Let _ _ b -> t b m
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase90.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase90.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase90.stderr
@@ -0,0 +1,16 @@
+SCase90.hs:(12,16)-(20,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \                Zero      -> case m of\n\
+      \                               Nothing -> 0\n\
+      \                               Just v  -> v\n\
+      \                Num k     -> k\n\
+      \                Var _     -> -1\n\
+      \                Add a b   -> t a m + t b m\n\
+      \                Let _ _ b -> t b m\n\
+      \       "
+  ======>
+    sCaseExpr
+      (Data.SBV.Maybe.sCaseMaybe 0 (\ v -> v) m) (\ k -> k)
+      (\ _ -> negate 1) (\ a b -> (t a m) + t b m) (\ _ _ b -> t b m) e
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase91.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase91.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase91.hs
@@ -0,0 +1,23 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Positive: Same-type nesting. Inner case on Expr inside outer case on Expr.
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SInteger
+t e = [sCase| e of
+               Zero      -> 0
+               Num k     -> k
+               Var _     -> -1
+               Add a b   -> case a of
+                              Zero    -> t b
+                              Num k   -> k + t b
+                              Var _   -> t b
+                              Add _ _ -> t a + t b
+                              Let _ _ c -> t c + t b
+               Let _ _ b -> t b
+      |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase91.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase91.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase91.stderr
@@ -0,0 +1,23 @@
+SCase91.hs:(12,14)-(23,8): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \               Zero      -> 0\n\
+      \               Num k     -> k\n\
+      \               Var _     -> -1\n\
+      \               Add a b   -> case a of\n\
+      \                              Zero    -> t b\n\
+      \                              Num k   -> k + t b\n\
+      \                              Var _   -> t b\n\
+      \                              Add _ _ -> t a + t b\n\
+      \                              Let _ _ c -> t c + t b\n\
+      \               Let _ _ b -> t b\n\
+      \      "
+  ======>
+    sCaseExpr
+      0 (\ k -> k) (\ _ -> negate 1)
+      (\ a b
+         -> sCaseExpr
+              (t b) (\ k -> k + t b) (\ _ -> t b) (\ _ _ -> (t a) + t b)
+              (\ _ _ c -> (t c) + t b) a)
+      (\ _ _ b -> t b) e
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase92.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase92.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase92.hs
@@ -0,0 +1,22 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Positive: Deep nesting (3 levels). Outer Expr, inner Maybe, innermost Either.
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SMaybe (Either Integer Bool) -> SInteger
+t e m = [sCase| e of
+                Zero  -> case m of
+                           Nothing -> 0
+                           Just v  -> case v of
+                                        Left  x -> x
+                                        Right _ -> 1
+                Num k     -> k
+                Var _     -> -1
+                Add a b   -> t a m + t b m
+                Let _ _ b -> t b m
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase92.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase92.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase92.stderr
@@ -0,0 +1,20 @@
+SCase92.hs:(12,16)-(22,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \                Zero  -> case m of\n\
+      \                           Nothing -> 0\n\
+      \                           Just v  -> case v of\n\
+      \                                        Left  x -> x\n\
+      \                                        Right _ -> 1\n\
+      \                Num k     -> k\n\
+      \                Var _     -> -1\n\
+      \                Add a b   -> t a m + t b m\n\
+      \                Let _ _ b -> t b m\n\
+      \       "
+  ======>
+    sCaseExpr
+      (Data.SBV.Maybe.sCaseMaybe
+         0 (\ v -> Data.SBV.Either.sCaseEither (\ x -> x) (\ _ -> 1) v) m)
+      (\ k -> k) (\ _ -> negate 1) (\ a b -> (t a m) + t b m)
+      (\ _ _ b -> t b m) e
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase93.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase93.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase93.hs
@@ -0,0 +1,22 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Positive: Nested case in multiple branches of outer case.
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SBool -> SInteger
+t e b = [sCase| e of
+                Zero      -> case b of
+                               True  -> 1
+                               False -> 0
+                Num k     -> case b of
+                               True  -> k
+                               False -> -k
+                Var _     -> -1
+                Add a _   -> t a b
+                Let _ _ c -> t c b
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase93.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase93.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase93.stderr
@@ -0,0 +1,18 @@
+SCase93.hs:(12,16)-(22,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \                Zero      -> case b of\n\
+      \                               True  -> 1\n\
+      \                               False -> 0\n\
+      \                Num k     -> case b of\n\
+      \                               True  -> k\n\
+      \                               False -> -k\n\
+      \                Var _     -> -1\n\
+      \                Add a _   -> t a b\n\
+      \                Let _ _ c -> t c b\n\
+      \       "
+  ======>
+    sCaseExpr
+      (ite b 1 0) (\ k -> ite b k (negate k)) (\ _ -> negate 1)
+      (\ a _ -> t a b) (\ _ _ c -> t c b) e
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase94.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase94.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase94.hs
@@ -0,0 +1,20 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Positive: Nested case with wildcard in inner case.
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SMaybe Integer -> SInteger
+t e m = [sCase| e of
+                Zero  -> case m of
+                           Just v -> v
+                           _      -> 0
+                Num k     -> k
+                _         -> case m of
+                               Nothing -> -1
+                               _       -> 42
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase94.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase94.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase94.stderr
@@ -0,0 +1,18 @@
+SCase94.hs:(12,16)-(20,9): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \                Zero  -> case m of\n\
+      \                           Just v -> v\n\
+      \                           _      -> 0\n\
+      \                Num k     -> k\n\
+      \                _         -> case m of\n\
+      \                               Nothing -> -1\n\
+      \                               _       -> 42\n\
+      \       "
+  ======>
+    sCaseExpr
+      (Data.SBV.Maybe.sCaseMaybe 0 (\ v -> v) m) (\ k -> k)
+      (\ _ -> Data.SBV.Maybe.sCaseMaybe (negate 1) (\ _ -> 42) m)
+      (\ _ _ -> Data.SBV.Maybe.sCaseMaybe (negate 1) (\ _ -> 42) m)
+      (\ _ _ _ -> Data.SBV.Maybe.sCaseMaybe (negate 1) (\ _ -> 42) m) e
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase95.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase95.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase95.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Negative: Non-exhaustive inner case (missing Nothing).
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SMaybe Integer -> SInteger
+t e m = [sCase| e of
+                Zero      -> case m of
+                               Just v -> v
+                Num k     -> k
+                Var _     -> -1
+                Add a b   -> t a m + t b m
+                Let _ _ b -> t b m
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase95.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase95.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase95.stderr
@@ -0,0 +1,21 @@
+SCase95.hs:12:16: error: [GHC-39584]
+    " sCase: Pattern match(es) are non-exhaustive.
+        Not matched     : Nothing
+        Patterns of type: Maybe
+        Must match each : Nothing, Just
+
+      You can use a '_' to match multiple cases.
+
+    " In the quasi-quotation:
+        [sCase| e of
+                Zero      -> case m of
+                               Just v -> v
+                Num k     -> k
+                Var _     -> -1
+                Add a b   -> t a m + t b m
+                Let _ _ b -> t b m
+       |]
+   |
+12 | t e m = [sCase| e of
+   |                ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase96.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase96.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase96.hs
@@ -0,0 +1,21 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Negative: Overlapping patterns in inner case (duplicate Just).
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SMaybe Integer -> SInteger
+t e m = [sCase| e of
+                Zero      -> case m of
+                               Nothing -> 0
+                               Just v  -> v
+                               Just _  -> 42
+                Num k     -> k
+                Var _     -> -1
+                Add a b   -> t a m + t b m
+                Let _ _ b -> t b m
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase96.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase96.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase96.stderr
@@ -0,0 +1,22 @@
+SCase96.hs:12:16: error: [GHC-39584]
+    " sCase: Overlapping case constructors:
+        Type       : Maybe
+        Constructor: Just _
+      Overlaps with:
+        SCase96.hs:(12,16)-(21,10): Just v
+
+    " In the quasi-quotation:
+        [sCase| e of
+                Zero      -> case m of
+                               Nothing -> 0
+                               Just v  -> v
+                               Just _  -> 42
+                Num k     -> k
+                Var _     -> -1
+                Add a b   -> t a m + t b m
+                Let _ _ b -> t b m
+       |]
+   |
+12 | t e m = [sCase| e of
+   |                ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase97.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase97.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase97.hs
@@ -0,0 +1,23 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Negative: Inner case on ADT without mkSymbolic.
+module T where
+
+import Expr
+import Data.SBV
+
+data Color = Red | Green | Blue
+
+t :: SExpr -> Color -> SInteger
+t e c = [sCase| e of
+                Zero      -> case c of
+                               Red   -> 0
+                               Green -> 1
+                               Blue  -> 2
+                Num k     -> k
+                Var _     -> -1
+                Add a b   -> t a c + t b c
+                Let _ _ b -> t b c
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase97.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase97.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase97.stderr
@@ -0,0 +1,17 @@
+SCase97.hs:14:16: error: [GHC-79890]
+    " Red is not in the type environment at a reify
+    " In the quasi-quotation:
+        [sCase| e of
+                Zero      -> case c of
+                               Red   -> 0
+                               Green -> 1
+                               Blue  -> 2
+                Num k     -> k
+                Var _     -> -1
+                Add a b   -> t a c + t b c
+                Let _ _ b -> t b c
+       |]
+   |
+14 | t e c = [sCase| e of
+   |                ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase98.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase98.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase98.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Negative: Non-exhaustive guarded inner case (missing Nothing, guard might fail).
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SMaybe Integer -> SInteger
+t e m = [sCase| e of
+                Zero      -> case m of
+                               Just v | v .> 0 -> v
+                Num k     -> k
+                Var _     -> -1
+                Add a b   -> t a m + t b m
+                Let _ _ b -> t b m
+       |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase98.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase98.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase98.stderr
@@ -0,0 +1,19 @@
+SCase98.hs:12:16: error: [GHC-39584]
+    " sCase: Non-exhaustive match:
+        Type       : Maybe
+        Constructor: Just v | v .> 0
+      NB. Guarded match might fail.
+
+    " In the quasi-quotation:
+        [sCase| e of
+                Zero      -> case m of
+                               Just v | v .> 0 -> v
+                Num k     -> k
+                Var _     -> -1
+                Add a b   -> t a m + t b m
+                Let _ _ b -> t b m
+       |]
+   |
+12 | t e m = [sCase| e of
+   |                ^^^^^...
+
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase99.hs b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase99.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase99.hs
@@ -0,0 +1,24 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+{-# OPTIONS_GHC -Wall -Werror -ddump-splices #-}
+
+-- Positive: Deep nesting (4 levels). Outer Expr, inner Maybe, inner Either, innermost Bool.
+module T where
+
+import Expr
+import Data.SBV
+
+t :: SExpr -> SMaybe (Either Integer Bool) -> SBool -> SInteger
+t e m b = [sCase| e of
+                  Zero      -> case m of
+                                 Nothing -> 0
+                                 Just v  -> case v of
+                                              Left x  -> case b of
+                                                           True  -> x
+                                                           False -> -x
+                                              Right _ -> 1
+                  Num k     -> k
+                  Var _     -> -1
+                  Add a _   -> t a m b
+                  Let _ _ c -> t c m b
+         |]
diff --git a/SBVTestSuite/TestSuite/CompileTests/SCase/SCase99.stderr b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase99.stderr
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/CompileTests/SCase/SCase99.stderr
@@ -0,0 +1,26 @@
+SCase99.hs:(12,18)-(24,11): Splicing expression
+    ghc-internal:GHC.Internal.TH.Quote.quoteExp
+      sCase
+      " e of\n\
+      \                  Zero      -> case m of\n\
+      \                                 Nothing -> 0\n\
+      \                                 Just v  -> case v of\n\
+      \                                              Left x  -> case b of\n\
+      \                                                           True  -> x\n\
+      \                                                           False -> -x\n\
+      \                                              Right _ -> 1\n\
+      \                  Num k     -> k\n\
+      \                  Var _     -> -1\n\
+      \                  Add a _   -> t a m b\n\
+      \                  Let _ _ c -> t c m b\n\
+      \         "
+  ======>
+    sCaseExpr
+      (Data.SBV.Maybe.sCaseMaybe
+         0
+         (\ v
+            -> Data.SBV.Either.sCaseEither
+                 (\ x -> ite b x (negate x)) (\ _ -> 1) v)
+         m)
+      (\ k -> k) (\ _ -> negate 1) (\ a _ -> t a m b)
+      (\ _ _ c -> t c m b) e
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
@@ -11,11 +11,22 @@
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
+{-# LANGUAGE DataKinds #-}
+
 module TestSuite.Crypto.AES(tests) where
 
+import Data.List (intercalate)
+import System.Exit (ExitCode(..))
+import System.FilePath ((</>))
+import System.IO.Temp (withSystemTempDirectory)
+import System.Process (readProcessWithExitCode)
+import Test.Tasty.HUnit (assertEqual)
+
 import Data.SBV.Internals
+import Data.SBV.Tools.CodeGen (compileToC, compileToCLib)
 import Documentation.SBV.Examples.Crypto.AES
 
+import Utils.CCodeGen (generatedMakeOptions)
 import Utils.SBVTestFramework
 
 -- Test suite
@@ -24,6 +35,10 @@
    goldenVsStringShow "aes128Enc" $ thd <$> compileToC'    "aes128Enc" (aes128EncDec True)
  , goldenVsStringShow "aes128Dec" $ thd <$> compileToC'    "aes128Dec" (aes128EncDec False)
  , goldenVsStringShow "aes128Lib" $ thd <$> compileToCLib' "aes128Lib" aes128Comps
+ , testCase "generated standalone encryption" standaloneEncryption
+ , testCase "generated AES128 library" $ libraryVector 128 aes128Key aes128CT
+ , testCase "generated AES192 library" $ libraryVector 192 aes192Key aes192CT
+ , testCase "generated AES256 library" $ libraryVector 256 aes256Key aes256CT
  ]
  where aes128EncDec d = do pt  <- cgInputArr 4 "pt"
                            key <- cgInputArr 4 "key"
@@ -35,3 +50,73 @@
        aes128Comps = [(f, setVals c) | (f, _, c) <- aesLibComponents 128]
        setVals c = cgSetDriverValues (repeat 0) >> c
        thd (_, _, r) = r
+
+-- | Exercise the exact code-generation action shown in the documentation.
+standaloneEncryption :: Assertion
+standaloneEncryption = withSystemTempDirectory "sbv-aes-block" $ \dir -> do
+  compileToC (Just dir) "aes128BlockEncrypt" (aes128BlockEncrypt >> cgOverwriteFiles True)
+  runCaller dir "aes128BlockEncrypt" "aes128BlockEncrypt.o"
+    [ cArray "pt" commonPT
+    , cArray "key" aes128Key
+    , cArray "expected" aes128CT
+    , "SWord32 ct[4];"
+    , "aes128BlockEncrypt(pt, key, ct);"
+    , "assert(memcmp(ct, expected, sizeof expected) == 0);"
+    ]
+
+-- | Compose the generated key-schedule and block functions in C, checking
+-- encryption and both decryption paths against the standard's test vectors.
+-- Using an independent caller ensures that the key schedules are computed
+-- by generated C, rather than supplied as precomputed Haskell driver values.
+libraryVector :: Int -> Key -> [SWord 32] -> Assertion
+libraryVector size key ciphertext = withSystemTempDirectory "sbv-aes-library" $ \dir -> do
+  _ <- compileToCLib (Just dir) libraryName
+         [(functionName, cgSetDriverValues values >> program >> cgOverwriteFiles True)
+         | (functionName, values, program) <- aesLibComponents size]
+  runCaller dir libraryName (libraryName ++ ".a")
+    [ cArray "pt" commonPT
+    , cArray "key" key
+    , cArray "expected" ciphertext
+    -- The public inverse-schedule wrapper reverses each group of key words.
+    , cArray "invKey" (concatMap reverse (chop4 (extractFinalKey key)))
+    , "SWord32 encKS[" ++ show expandedWords ++ "], decKS[" ++ show expandedWords ++ "], invKS[" ++ show expandedWords ++ "];"
+    , "SWord32 ct[4], recovered[4];"
+    , prefix ++ "KeySchedule(key, encKS, decKS);"
+    , prefix ++ "BlockEncrypt(pt, encKS, ct);"
+    , "assert(memcmp(ct, expected, sizeof expected) == 0);"
+    , prefix ++ "BlockDecrypt(expected, decKS, recovered);"
+    , "assert(memcmp(recovered, pt, sizeof pt) == 0);"
+    , prefix ++ "InvKeySchedule(invKey, invKS);"
+    , prefix ++ "OTFDecrypt(expected, invKS, recovered);"
+    , "assert(memcmp(recovered, pt, sizeof pt) == 0);"
+    ]
+ where prefix = "aes" ++ show size
+       libraryName = prefix ++ "Lib"
+       expandedWords = 4 * (size `div` 32 + 7)
+
+-- | Render the existing concrete test vectors as C arrays.
+cArray :: String -> [SWord 32] -> String
+cArray arrayName values = "const SWord32 " ++ arrayName ++ "[] = {"
+                       ++ intercalate ", " ["0x" ++ hex8 value ++ "UL" | value <- values] ++ "};"
+
+-- | Build and run a caller using the generated Makefile's compiler and flags.
+-- Keep assertions enabled, and preserve optional sanitizer instrumentation.
+runCaller :: FilePath -> String -> FilePath -> [String] -> Assertion
+runCaller dir header dependency body = do
+  writeFile (dir </> "caller.c") $ unlines $
+    [ "#undef NDEBUG"
+    , "#include <assert.h>"
+    , "#include <string.h>"
+    , "#include \"" ++ header ++ ".h\""
+    , "int main(void) {"
+    ] ++ map ("  " ++) body ++ ["  return 0;", "}"]
+  writeFile (dir </> "caller.mk") $ unlines
+    [ "caller: caller.c " ++ header ++ ".h " ++ dependency
+    , "\t${CC} ${CCFLAGS} caller.c " ++ dependency ++ " ${LDFLAGS} ${SBV_LIBS} -o $@"
+    ]
+  makeOptions <- generatedMakeOptions dir
+  (buildExit, buildOutput, buildError) <- readProcessWithExitCode "make"
+    (["-C", dir, "caller"] ++ makeOptions) ""
+  assertEqual (buildOutput ++ buildError) ExitSuccess buildExit
+  (runExit, runOutput, runError) <- readProcessWithExitCode (dir </> "caller") [] ""
+  assertEqual (runOutput ++ runError) ExitSuccess runExit
diff --git a/SBVTestSuite/TestSuite/Crypto/SHA.hs b/SBVTestSuite/TestSuite/Crypto/SHA.hs
--- a/SBVTestSuite/TestSuite/Crypto/SHA.hs
+++ b/SBVTestSuite/TestSuite/Crypto/SHA.hs
@@ -20,7 +20,7 @@
 
 -- Test suite
 tests :: TestTree
-tests = testGroup "Crypto.AES" [
+tests = testGroup "Crypto.SHA" [
    goldenVsStringShow "sha256HashBlock" $ (\(_, _, r) -> r) <$> compileToC' "sha256HashBlock" c
  ]
  where c = do let algorithm = sha256P
diff --git a/SBVTestSuite/TestSuite/Optimization/Basics.hs b/SBVTestSuite/TestSuite/Optimization/Basics.hs
--- a/SBVTestSuite/TestSuite/Optimization/Basics.hs
+++ b/SBVTestSuite/TestSuite/Optimization/Basics.hs
@@ -9,18 +9,26 @@
 -- Test suite for optimization routines
 -----------------------------------------------------------------------------
 
+{-# LANGUAGE ScopedTypeVariables #-}
 {-# OPTIONS_GHC -Wall -Werror #-}
 
 module TestSuite.Optimization.Basics(tests) where
 
 import Utils.SBVTestFramework
+import Data.SBV.Control
 
+import Control.Monad
+
+import qualified Control.Exception as C
+
 -- Test suite
 tests :: TestTree
 tests =
   testGroup "Optimization.Basics" $
        [ goldenVsStringShow "optBasics1" (optimize Lexicographic optBasics1)
        , goldenVsStringShow "optBasics2" (optimize Lexicographic optBasics2)
+       , goldenCapturedIO   "qOpt_1"     (qOpt False)
+       , goldenCapturedIO   "qOpt_2"     (qOpt True)
        ]
     ++ [ goldenVsStringShow ("optBasicsRange_" ++ n) (optimize Lexicographic f)
        | (n, f) <- [ ("08_unsigned_max", sWord8  "x" >>= maximize "m")
@@ -60,3 +68,18 @@
                 constrain $ y .> 1
 
                 minimize "x_plus_y" $ x+y
+
+qOpt :: Bool -> FilePath -> IO ()
+qOpt mb rf = testQuery $ do
+                vs <- forM [1 .. 5] $ \i -> do x <- sInteger ("x" <> show (i::Int))
+                                               constrain $ 1 .<= x
+                                               when mb $ constrain $ x .< 10
+                                               maximize ("goal" <> show i) x
+                                               pure x
+                query $ do cs <- checkSat
+                           case cs of
+                             Sat -> forM vs getValue
+                             _   -> pure []
+ where testQuery fv = do r <- runSMTWith defaultSMTCfg{verbose=True, redirectVerbose=Just rf} fv
+                         appendFile rf ("\n FINAL:" ++ show r ++ "\nDONE!\n")
+                      `C.catch` (\(e :: C.SomeException) -> appendFile rf ("\nEXCEPTION CAUGHT:\n" ++ show e ++ "\n"))
diff --git a/SBVTestSuite/TestSuite/Optimization/NoOpt.hs b/SBVTestSuite/TestSuite/Optimization/NoOpt.hs
--- a/SBVTestSuite/TestSuite/Optimization/NoOpt.hs
+++ b/SBVTestSuite/TestSuite/Optimization/NoOpt.hs
@@ -9,9 +9,9 @@
 -- Check that if optimization is done, there must be goals and vice versa
 -----------------------------------------------------------------------------
 
-{-# OPTIONS_GHC -Wall -Werror #-}
-
 {-# LANGUAGE ScopedTypeVariables #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
 
 module TestSuite.Optimization.NoOpt(tests) where
 
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
@@ -11,7 +11,7 @@
 
 {-# LANGUAGE DataKinds           #-}
 {-# LANGUAGE FlexibleContexts    #-}
-{-# LANGUAGE Rank2Types          #-}
+{-# LANGUAGE RankNTypes          #-}
 {-# LANGUAGE TypeApplications    #-}
 {-# LANGUAGE TypeOperators       #-}
 {-# LANGUAGE ScopedTypeVariables #-}
diff --git a/SBVTestSuite/TestSuite/Overflows/Casts.hs b/SBVTestSuite/TestSuite/Overflows/Casts.hs
--- a/SBVTestSuite/TestSuite/Overflows/Casts.hs
+++ b/SBVTestSuite/TestSuite/Overflows/Casts.hs
@@ -9,7 +9,7 @@
 -- Test suite for overflow checking
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE Rank2Types          #-}
+{-# LANGUAGE RankNTypes          #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
diff --git a/SBVTestSuite/TestSuite/Puzzles/Sudoku.hs b/SBVTestSuite/TestSuite/Puzzles/Sudoku.hs
--- a/SBVTestSuite/TestSuite/Puzzles/Sudoku.hs
+++ b/SBVTestSuite/TestSuite/Puzzles/Sudoku.hs
@@ -15,7 +15,6 @@
 
 import Documentation.SBV.Examples.Puzzles.Sudoku
 
-import Data.Maybe (fromMaybe)
 import Utils.SBVTestFramework
 
 tests :: TestTree
@@ -27,4 +26,4 @@
 checkPuzzle :: Puzzle -> IO Bool
 checkPuzzle p = do final <- fillBoard p
                    let vld = valid (map (map literal) final)
-                   pure $ fromMaybe False (unliteral vld)
+                   pure $ Just True == unliteral vld
diff --git a/SBVTestSuite/TestSuite/Queries/Enums.hs b/SBVTestSuite/TestSuite/Queries/Enums.hs
--- a/SBVTestSuite/TestSuite/Queries/Enums.hs
+++ b/SBVTestSuite/TestSuite/Queries/Enums.hs
@@ -9,12 +9,10 @@
 -- Test suite for Documentation.SBV.Examples.Uninterpreted.AUF
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DeriveAnyClass      #-}
-{-# LANGUAGE DeriveDataTypeable  #-}
 {-# LANGUAGE FlexibleInstances   #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE StandaloneDeriving  #-}
 {-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE TypeApplications    #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -24,8 +22,8 @@
 
 import Utils.SBVTestFramework
 
-data BinOp  = Plus | Minus | Times deriving (Enum, Bounded, Ord, Eq)
-mkSymbolicEnumeration ''BinOp
+data BinOp  = Plus | Minus | Times
+mkSymbolic [''BinOp]
 
 -- Test suite
 tests :: TestTree
diff --git a/SBVTestSuite/TestSuite/Queries/FreshVars.hs b/SBVTestSuite/TestSuite/Queries/FreshVars.hs
--- a/SBVTestSuite/TestSuite/Queries/FreshVars.hs
+++ b/SBVTestSuite/TestSuite/Queries/FreshVars.hs
@@ -9,14 +9,12 @@
 -- Testing fresh-vars in query mode
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DeriveAnyClass      #-}
-{-# LANGUAGE DeriveDataTypeable  #-}
 {-# LANGUAGE FlexibleInstances   #-}
 {-# LANGUAGE OverloadedLists     #-}
 {-# LANGUAGE OverloadedStrings   #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE StandaloneDeriving  #-}
 {-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE TypeApplications    #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -26,11 +24,8 @@
 
 import Utils.SBVTestFramework
 
-data BinOp  = Plus | Minus | Times deriving (Enum, Bounded)
-mkSymbolicEnumeration ''BinOp
-
-_unused :: a
-_unused = error "stop GHC from complaining unused names" sPlus sMinus sTimes
+data BinOp  = Plus | Minus | Times
+mkSymbolic [''BinOp]
 
 -- Test suite
 tests :: TestTree
@@ -93,7 +88,7 @@
                    constrain $ readArray vSArray vi1 .== 2
 
                    let viSArray  :: SArray Integer Integer
-                       viSArray = lambdaArray (const 42)
+                       viSArray = constArray 42
                    mustBe42                              <- freshVar "mustBe42"
 
                    constrain $ readArray viSArray 96     .== mustBe42
diff --git a/SBVTestSuite/TestSuite/Queries/Lists.hs b/SBVTestSuite/TestSuite/Queries/Lists.hs
--- a/SBVTestSuite/TestSuite/Queries/Lists.hs
+++ b/SBVTestSuite/TestSuite/Queries/Lists.hs
@@ -12,6 +12,7 @@
 {-# LANGUAGE OverloadedLists     #-}
 {-# LANGUAGE QuasiQuotes         #-}
 {-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications    #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -19,20 +20,45 @@
 
 import Data.SBV
 import Data.SBV.Control
+import qualified Data.SBV.List as L
+import qualified Data.SBV.Tuple as T
 
+import Data.List (isInfixOf)
+
+import qualified Control.Exception as C
+
 import Utils.SBVTestFramework
 
--- Test suite
+-- | Test suite.
 tests :: TestTree
 tests =
   testGroup "Basics.QueryLists"
     [ goldenCapturedIO "query_Lists1" $ testQuery queryLists1
+    , testCase "query_Lists2"              $ do result <- runSMT queryLists2
+                                                result == 3 @? "Expected the filtered value 3, received: " ++ show result
+    , testCase "query_function_dependency" $ do result <- runSMT queryFunctionDependency
+                                                result == 11 @? "Expected the dependent function value 11, received: " ++ show result
+    , testCase "query_function_reuse"      $ do result <- runSMT queryFunctionReuse
+                                                result == (6, 7) @? "Expected the reused function values (6, 7), received: " ++ show result
+    , testCase "query_function_body_kind"  $ do result <- runSMT queryFunctionBodyKind
+                                                result == 11 @? "Expected the tuple-backed function value 11, received: " ++ show result
+    , testCase "query_function_ui"         $ do result <- runSMT queryFunctionUI
+                                                result == 11 @? "Expected the helper-backed function value 11, received: " ++ show result
+    , testCase "query_mutual_functions"    $ do result <- runSMT queryMutualFunctions
+                                                result @? "Expected the mutually recursive function to return true"
+    , testCase "query_bad_termination"     $ do result <- C.try (runSMT queryBadTermination)
+                                                case result of
+                                                  Left (e :: C.SomeException) -> "does not strictly decrease" `isInfixOf` show e
+                                                                                 @? "Expected a termination-check failure, received: " ++ show e
+                                                  Right value                 -> assertFailure $ "Expected a termination-check failure, received: " ++ show value
     ]
 
+-- | Run a query with its verbose transcript redirected to the given file.
 testQuery :: Show a => Symbolic a -> FilePath -> IO ()
 testQuery t rf = do r <- runSMTWith defaultSMTCfg{verbose=True, redirectVerbose=Just rf} t
                     appendFile rf ("\nFINAL OUTPUT:\n" ++ show r ++ "\n")
 
+-- | Retrieve a concrete list from a solver query.
 queryLists1 :: Symbolic [Integer]
 queryLists1 = do a :: SList Integer <- sList "a"
 
@@ -45,3 +71,85 @@
                             if av == [1..5]
                                then return av
                                else error $ "Didn't expect this: " ++ show av
+
+-- | Exercise an SMT function first encountered after entering query mode.
+queryLists2 :: Symbolic Integer
+queryLists2 = query $ do x <- freshVar @Integer "x"
+                         y <- freshVar @[Integer] "y"
+                         constrain $ y .== literal [1 .. 20]
+                         constrain $ x .== L.head (L.filter (.== literal 3) y)
+                         getValue x
+
+-- | Exercise dependency ordering between SMT functions first encountered in query mode.
+queryFunctionDependency :: Symbolic Integer
+queryFunctionDependency = query $ do n <- freshVar @Integer "n"
+                                     x <- freshVar @Integer "x"
+                                     constrain $ n .== 5
+                                     constrain $ x .== outer n
+                                     getValue x
+  where inner :: SInteger -> SInteger
+        inner = smtFunction "query.inner" (* 2)
+
+        outer :: SInteger -> SInteger
+        outer = smtFunction "query.outer" ((+ 1) . inner)
+
+-- | Exercise repeated use of an SMT function after its query-mode definition has been sent.
+queryFunctionReuse :: Symbolic (Integer, Integer)
+queryFunctionReuse = query $ do n <- freshVar @Integer "n"
+                                x <- freshVar @Integer "x"
+                                y <- freshVar @Integer "y"
+                                constrain $ n .== 5
+                                constrain $ x .== increment n
+                                constrain $ y .== increment x
+                                (,) <$> getValue x <*> getValue y
+  where increment :: SInteger -> SInteger
+        increment = smtFunction "query.increment" (+ 1)
+
+-- | Exercise a datatype used only inside an SMT function first encountered in query mode.
+queryFunctionBodyKind :: Symbolic Integer
+queryFunctionBodyKind = query $ do n <- freshVar @Integer "n"
+                                   x <- freshVar @Integer "x"
+                                   constrain $ n .== 5
+                                   constrain $ x .== pairSum n
+                                   getValue x
+  where pairSum :: SInteger -> SInteger
+        pairSum = smtFunction "query.pairSum" $ \n -> let p :: STuple Integer Integer
+                                                          p = T.tuple (n, n + 1)
+                                                      in T.fst p + T.snd p
+
+-- | Exercise an uninterpreted helper used by an SMT function first encountered in query mode.
+queryFunctionUI :: Symbolic Integer
+queryFunctionUI = query $ do n <- freshVar @Integer "n"
+                             x <- freshVar @Integer "x"
+                             constrain $ n .== 5
+                             constrain $ x .== applyHelper n
+                             constrain $ helper n .== 10
+                             getValue x
+  where helper :: SInteger -> SInteger
+        helper = uninterpret "query.helper"
+
+        applyHelper :: SInteger -> SInteger
+        applyHelper = smtFunction "query.applyHelper" ((+ 1) . helper)
+
+-- | Exercise mutually recursive SMT functions first encountered in query mode.
+queryMutualFunctions :: Symbolic Bool
+queryMutualFunctions = query $ do n <- freshVar @Bool "n"
+                                  x <- freshVar @Bool "x"
+                                  constrain n
+                                  constrain $ x .== isEven n
+                                  getValue x
+  where isEven :: SBool -> SBool
+        isEven = smtFunctionNoTermination "query.even" $ \b -> ite b (isOdd sFalse) sFalse
+
+        isOdd :: SBool -> SBool
+        isOdd  = smtFunctionNoTermination "query.odd" $ \b -> ite b (isEven sFalse) sTrue
+
+-- | Ensure query-mode definitions still undergo termination checking before reaching the solver.
+queryBadTermination :: Symbolic Integer
+queryBadTermination = query $ do n <- freshVar @Integer "n"
+                                 x <- freshVar @Integer "x"
+                                 constrain $ n .== 5
+                                 constrain $ x .== diverges n
+                                 getValue x
+  where diverges :: SInteger -> SInteger
+        diverges = smtFunctionWithMeasure "query.diverges" (abs, []) $ \n -> ite (n .<= 0) 0 (diverges (n + 1))
diff --git a/SBVTestSuite/TestSuite/Queries/Registration.hs b/SBVTestSuite/TestSuite/Queries/Registration.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/Queries/Registration.hs
@@ -0,0 +1,291 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : TestSuite.Queries.Registration
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Registration and function discovery during incremental solver interaction.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE FlexibleInstances   #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE TypeApplications    #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module TestSuite.Queries.Registration (tests) where
+
+import Control.Monad (when)
+import Control.Monad.Reader (ReaderT(..), runReaderT)
+import qualified Control.Exception as C
+import Data.List (isInfixOf, isPrefixOf)
+import Data.Maybe (fromMaybe)
+import Data.Proxy
+import System.FilePath ((</>))
+import System.IO.Temp (withSystemTempDirectory)
+
+import Data.SBV.Control
+import Data.SBV.Internals (QueryT(..), SMTModel(..), SExpr(..), parseSExpr, formatFunctionResponse)
+import Utils.SBVTestFramework
+
+-- | A rational field must be declared before the containing datatype.
+newtype RationalBox = RationalBox Rational deriving (Eq, Show)
+
+-- | An empty datatype represents an uninterpreted solver sort.
+data RegistrationSort
+
+mkSymbolic [''RationalBox, ''RegistrationSort]
+
+tests :: TestTree
+tests = testGroup "Queries.Registration"
+  [ testGroup "rationals"
+      [ rationalTest "automatic"                 False False
+      , rationalTest "registered before query"   True  False
+      , rationalTest "registered inside query"   False True
+      , rationalTest "registered in both phases" True  True
+      ]
+  , testCase "rational function first used in query" $ do
+      let half :: SInteger -> SRational
+          half = smtFunction "registration.half" $ \n -> ite (n .== 1) (1/2) (2/3)
+      result <- runSMT $ query $ do
+        n <- freshVar @Integer "n"
+        constrain $ n .== 1
+        getValue (half n)
+      result == 1 % 2 @? "Expected a rational result from a query-mode definition"
+  , testCase "nested rational types first used in query" $ do
+      result <- runSMT $ query $ do
+        x <- freshVar @(RationalBox, [Rational]) "x"
+        let expected = (RationalBox (1 % 2), [2 % 3])
+        constrain $ x .== literal expected
+        getValue x
+      result == (RationalBox (1 % 2), [2 % 3]) @? "Expected nested rational values"
+  , testCase "explicit nested type registration inside query" $ do
+      result <- runSMT $ query $ do
+        registerType (Proxy @(RationalBox, [Rational]))
+        registerType (Proxy @(RationalBox, [Rational]))
+        ensureSat
+        x <- freshVar @(RationalBox, [Rational]) "x"
+        constrain $ x .== literal (RationalBox (1 % 2), [2 % 3])
+        getValue x
+      result == (RationalBox (1 % 2), [2 % 3]) @? "Explicit registration must reach the solver"
+  , testCase "explicit uninterpreted sort registration inside query" $ do
+      result <- runSMT $ query $ do
+        registerType (Proxy @RegistrationSort)
+        registerType (Proxy @RegistrationSort)
+        ensureSat
+        x <- freshVar @RegistrationSort "x"
+        y <- freshVar_ @RegistrationSort
+        constrain $ x ./= y
+        checkSat
+      result == Sat @? "Explicit registration must declare an uninterpreted sort exactly once"
+  , testCase "quantified function first used in query" $ do
+      result <- runSMT $ query $ do
+        let f = uninterpret "registration.quantified" :: SInteger -> SInteger
+        constrain $ \(Forall (x :: SInteger)) -> f x .== f x
+        checkSat
+      result == Sat @? "Quantified uses must register their functions automatically"
+  , testGroup "function discovery" $ map discoveryTests [("z3", z3), ("cvc5", cvc5)]
+  , fallbackTests
+  ]
+
+-- | Discovery must support sorts without concrete defaults and preserve the
+-- model produced by checkSatAssuming, including when discovery fails.
+discoveryTests :: (String, SMTConfig) -> TestTree
+discoveryTests (solverName, cfg) = testGroup solverName
+  [ testCase "quoted function expression formatting" $ do
+      let f = uninterpret "|quotedPretty|" :: SInteger -> SInteger
+      result <- runSMTWith cfg $ do
+        setupFunctionModels solverName
+        constrain $ \(Forall x) -> f x .== 3 * x
+        query $ ensureSat >> getFunction f
+      case result of
+        Left (rendered, _) -> do
+          "quotedPretty " `isPrefixOf` rendered @? "Expected the function name in the formatted interpretation"
+          not ("fromSMTLib" `isInfixOf` rendered) @? "Expected the lambda to be formatted despite optional name quoting"
+        Right{} -> assertFailure "Expected an expression for the nonconstant integer function"
+  , testGroup "registered calling convention"
+      [ testCase (if registeredCurried then "curried" else "uncurried") $ do
+          let curried   = uninterpret "registeredShape" :: SInteger -> SInteger -> SInteger
+              uncurried = uninterpret "registeredShape" :: (SInteger, SInteger) -> SInteger
+              f x y | registeredCurried = curried x y
+                    | True             = uncurried (x, y)
+          result <- runSMTWith cfg $ do
+            setupFunctionModels solverName
+            constrain $ \(Forall x) (Forall y) -> f x y .== 3 * x + y
+            query $ do
+              ensureSat
+              if registeredCurried then getFunction uncurried else getFunction curried
+          case result of
+            Left (_, (isCurried, _, _)) -> isCurried == registeredCurried @? "Reading through an alias must preserve the registered display convention"
+            Right{} -> assertFailure "Expected an expression for the nonconstant integer function"
+      | registeredCurried <- [True, False]
+      ]
+  , testCase "uninterpreted argument sort" $ do
+      let f = uninterpret "discovery.sort" :: SBV RegistrationSort -> SInteger
+      result <- runSMTWith cfg $ do
+        registerFunction f
+        query $ ensureSat >> getFunction f
+      case result of
+        Right{} -> pure ()
+        Left{}  -> assertFailure "Expected an interpretation of the unused function"
+  , testCase "uncurried function with an uninterpreted argument sort" $ do
+      let f = uninterpret "discovery.uncurried" :: (SBV RegistrationSort, SBool) -> SInteger
+      result <- runSMTWith cfg $ do
+        registerFunction f
+        query $ ensureSat >> getFunction f
+      case result of
+        Right{} -> pure ()
+        Left{}  -> assertFailure "Expected an interpretation of the unused uncurried function"
+  , testCase "function first used in a query" $ do
+      let f = uninterpret "discovery.used" :: SInteger -> SInteger
+      result <- runSMTWith cfg $ query $ do
+        constrain $ f 5 .== 17
+        ensureSat
+        getFunction f
+      case result of
+        Right (table, def) -> fromMaybe def (lookup 5 table) == 17 @? "The interpretation must satisfy the constraint"
+        Left{}            -> assertFailure "Expected a value association for the constrained function"
+  , testGroup "quoted names"
+      [ testCase nm $ withSystemTempDirectory "sbv-quoted-function" $ \dir -> do
+          let logFile = dir </> "solver.smt2"
+              f = uninterpret nm :: SInteger -> SInteger
+          result <- runSMTWith cfg{transcript = Just logFile} $ do
+            constrain $ f 5 .== 17
+            query $ ensureSat >> getFunction f
+          case result of
+            Right (table, def) -> fromMaybe def (lookup 5 table) == 17 @? "The quoted function must satisfy its constraint"
+            Left{}            -> assertFailure "Expected a value association for the quoted function"
+          logText <- readFile logFile
+          ("(get-value (" ++ nm ++ "))") `isInfixOf` logText @? "Expected an explicitly quoted function lookup"
+      | nm <- ["|quotedFunction|", "|function with spaces|"]
+      ]
+  , testGroup "quoted names in models"
+      [ testCase (nm ++ if constrained then " constrained" else " unused") $ do
+          let f = uninterpret nm :: SInteger -> SInteger
+          model <- runSMTWith cfg $ do
+            if constrained then constrain $ f 5 .== 17 else registerFunction f
+            query $ ensureSat >> getModel
+          case modelUIFuns model of
+            [(modelName, (_, _, Right (table, def)))] -> do
+              modelName == filter (/= '|') nm @? "Expected the quoted function in the model"
+              when constrained $ do
+                let values = [(map (fromCV @Integer) args, fromCV @Integer value) | (args, value) <- table]
+                fromMaybe (fromCV @Integer def) (lookup [5] values) == 17 @? "The model interpretation must satisfy the constraint"
+            other -> assertFailure $ "Expected a function interpretation in the model, received: " ++ show other
+      | nm <- ["|quotedFunction|", "|function with spaces|"], constrained <- [False, True]
+      ]
+  , testCase "discovery preserves the current model" $
+      withSystemTempDirectory "sbv-discovery" $ \dir -> do
+        let logFile = dir </> "solver.smt2"
+            f = uninterpret "discovery.binary" :: SBool -> SBool -> SBool
+        runSMTWith cfg{transcript = Just logFile} $ do
+          x <- sBool "x"
+          registerFunction f
+          query $ do
+            cs <- checkSatAssuming [x]
+            io $ cs == Sat @? "Expected satisfiable assumptions"
+            before <- getValue x
+            _ <- getFunction f
+            _ <- getFunction f
+            after <- getValue x
+            io $ before && after @? "Function discovery must preserve the assumed model"
+        logText <- readFile logFile
+        let commands = filter ("(" `isPrefixOf`) $ lines logText
+            afterCheck = drop 1 $ dropWhile (not . ("(check-sat" `isPrefixOf`)) commands
+        length (filter ("(check-sat-assuming" `isPrefixOf`) commands) == 1
+          @? "Expected exactly one check with assumptions in the transcript"
+        all (\cmd -> not $ any (`isPrefixOf` cmd) ["(declare-", "(define-", "(assert", "(check-sat"]) afterCheck
+          @? "Model inspection must not emit declarations, assertions, or another satisfiability check"
+  , testCase "failed discovery leaves the query usable" $ do
+      let f = uninterpret "discovery.missing" :: SInteger -> SInteger
+          wrongType = uninterpret "discovery.existing" :: SBool -> SBool
+          existing  = uninterpret "discovery.existing" :: SInteger -> SInteger
+      runSMTWith cfg $ do
+        x <- sBool "x"
+        registerFunction existing
+        query $ do
+          cs <- checkSatAssuming [x]
+          io $ cs == Sat @? "Expected satisfiable assumptions"
+          expectQueryError "is not registered in this context" $ getFunction f
+          expectQueryError "used at incompatible SMT signatures" $ getFunction wrongType
+          expectQueryError "Must be called on an uninterpreted function" $ getFunction ((+1) :: SInteger -> SInteger)
+          value <- getValue x
+          io $ value @? "Failed discovery must preserve the assumed model"
+          -- A failed lookup must not poison the registry and prevent a later
+          -- ordinary use from declaring the function to the solver.
+          constrain $ f 0 .== 42
+          ensureSat
+          result <- getValue (f 0)
+          io $ result == 42 @? "The function must remain usable after failed discovery"
+  ]
+
+-- | CVC5 needs first-order ALL (rather than SBV's default HO_ALL) and macro
+-- expansion to produce models of these quantified function definitions.
+setupFunctionModels :: String -> Symbolic ()
+setupFunctionModels solverName = when (solverName == "cvc5") $ do
+  setLogic $ CustomLogic "ALL"
+  setOption $ OptionKeyword ":macros-quant" ["true"]
+  setOption $ OptionKeyword ":macros-quant-mode" ["all"]
+
+-- | Assert the positive raw fallback exactly, including whitespace and literal
+-- spelling. Let-wrapped lambdas and as-array values bypass lambda formatting.
+fallbackTests :: TestTree
+fallbackTests = testGroup "raw function rendering"
+  [ testGroup quotingCase
+      [ testCase bodyName $ do
+          let response = " \n ( ( " ++ actual ++ " ; before value )\n " ++ body ++ " ) ; after value\n ) \n"
+          case parseSExpr response of
+            Right (EApp [EApp [ECon _, value]]) -> do
+              let rendered = formatFunctionResponse value response wanted True Nothing
+              rendered == wanted ++ " = fromSMTLib " ++ body @? "Raw fallback changed the function value: " ++ show rendered
+            other -> assertFailure $ "Expected a function response, received: " ++ show other
+      | (bodyName, body) <-
+          [ ("as-array", "(_ as-array helper)")
+          , ("let-wrapped lambda", "(let ((offset 3))\n  (lambda ((x!1 Int)) (+ offset (* 2 x!1))))")
+          , ("comments and spacing", "(let  ((offset 3)) ; keep this ) comment\n\t(lambda ((x!1 Int))  (+ offset x!1)))")
+          , ("quoted literals", "(let ((|text )| \"he said \"\"hi\"\"; )))\")) (lambda ((x String)) |text )|))")
+          , ("bit-vector spelling", "(let ((mask #x0f) (wide (_ bv7 16))) (lambda ((x (_ BitVec 8))) (bvand x mask)))")
+          ]
+      ]
+  | (quotingCase, wanted, actual) <-
+      [ ("unquoted",        "f",                  "f")
+      , ("solver unquotes", "|f|",                "f")
+      , ("solver quotes",   "f",                  "|f|")
+      , ("quoted",          "|f|",                "|f|")
+      , ("spaces in name",  "|name with spaces|", "|name with spaces|")
+      ]
+  ]
+
+-- | Catch an error inside the same query so subsequent solver interactions
+-- verify that discovery has not corrupted either side of the connection.
+expectQueryError :: String -> Query a -> Query ()
+expectQueryError expected (QueryT action) = QueryT $ ReaderT $ \st -> do
+  result <- C.try $ runReaderT action st
+  case result of
+    Left (err :: C.ErrorCall) -> expected `isInfixOf` C.displayException err @? "Unexpected diagnostic: " ++ C.displayException err
+    Right _                  -> assertFailure $ "Expected diagnostic containing: " ++ expected
+
+-- | Exercise both rational equality helpers, repeated declarations, named and
+-- unnamed fresh variables, and declarations surviving assertion-stack changes.
+rationalTest :: String -> Bool -> Bool -> TestTree
+rationalTest testName before inside = testCase testName $ do
+  result <- runSMT $ do
+    when before $ registerType (Proxy @Rational)
+    query $ do
+      when inside $ do registerType (Proxy @Rational)
+                       registerType (Proxy @Rational)
+      push 1
+      x <- freshVar @Rational "x"
+      constrain $ x .== 1/2
+      first <- getValue x
+      pop 1
+      y <- freshVar_ @Rational
+      constrain $ y .== 1/3
+      constrain $ y ./= 0
+      later <- getValue y
+      pure (first, later)
+  result == (1 % 2, 1 % 3) @? "Expected rational values across incremental contexts, received: " ++ show result
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
@@ -60,24 +60,23 @@
        then return av
        else error $ "Didn't expect this: " ++ show av
 
-queryListOfSum :: Symbolic [Either Integer Char]
+-- This one has decidability problems if I force
+-- the list to have two elements. The current model
+-- returned has only one element; which is fine.
+-- (Adding a constraint to set the length to be anything causes unknown)
+queryListOfSum :: Symbolic [Either Integer Integer]
 queryListOfSum = do
-  lst <- sList @(Either Integer Char) "lst"
-  constrain $ L.length lst .== 2
+  lst <- sList @(Either Integer Integer) "lst"
   constrain $ isLeft $ L.head lst
   constrain $ isRight $ L.head $ L.tail lst
 
   query $ do
-    _  <- checkSat
-    av <- getValue lst
-
-    case av of
-      [Left _, Right _] -> return av
-      _                 -> error $ "Didn't expect this: " ++ show av
+    ensureSat
+    getValue lst
 
 queryMaybe :: Symbolic (Maybe Integer)
 queryMaybe = do
-  a <- sMaybe @Integer "a"
+  a :: M.SMaybe Integer <- free "a"
 
   constrain $ M.maybe sFalse (.== 1) a
 
@@ -90,20 +89,19 @@
        then return av
        else error $ "Didn't expect this: " ++ show av
 
+-- This one has decidability problems if I force
+-- the list to have two elements. The current model
+-- returned has only one element; which is fine.
+-- (Adding a constraint to set the length to be anything causes unknown)
 queryListOfMaybe :: Symbolic [Maybe Char]
 queryListOfMaybe = do
   lst <- sList @(Maybe Char) "lst"
-  constrain $ L.length lst .== 2
-  constrain $ isJust $ L.head lst
-  constrain $ isNothing $ L.head $ L.tail lst
+  constrain $ isJust (L.head lst)
+  constrain $ isNothing (L.head (L.tail lst))
 
   query $ do
-    _  <- checkSat
-    av <- getValue lst
-
-    case av of
-      [Just _, Nothing] -> return av
-      _                 -> error $ "Didn't expect this: " ++ show av
+    ensureSat
+    getValue lst
 
 querySumMaybeBoth :: Symbolic (Either Integer Integer, Maybe Integer)
 querySumMaybeBoth = query $ do
diff --git a/SBVTestSuite/TestSuite/Queries/Tables.hs b/SBVTestSuite/TestSuite/Queries/Tables.hs
--- a/SBVTestSuite/TestSuite/Queries/Tables.hs
+++ b/SBVTestSuite/TestSuite/Queries/Tables.hs
@@ -9,11 +9,11 @@
 -- Test case for https://github.com/LeventErkok/sbv/issues/539
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DeriveAnyClass                #-}
-{-# LANGUAGE DeriveGeneric                 #-}
-{-# LANGUAGE FlexibleContexts              #-}
-{-# LANGUAGE Rank2Types                    #-}
-{-# LANGUAGE QuantifiedConstraints         #-}
+{-# LANGUAGE DeriveAnyClass        #-}
+{-# LANGUAGE DeriveGeneric         #-}
+{-# LANGUAGE FlexibleContexts      #-}
+{-# LANGUAGE RankNTypes            #-}
+{-# LANGUAGE QuantifiedConstraints #-}
 
 {-# OPTIONS_GHC -Wall -Werror -Wno-orphans #-}
 
@@ -124,7 +124,7 @@
     return $ map (.== 1) locs `pbExactly` 1
 
 perform :: SInput -> Engine ()
-perform (verb, noun) = sCase verb (return ())
+perform (verb, noun) = goCase verb (return ())
     [ (1, builtin_go)
     , (10, builtin_get)
     ]
@@ -153,8 +153,8 @@
 replaceAt :: (Mergeable a) => SInt16 -> a -> [a] -> [a]
 replaceAt i x' = zipWith (\j x -> ite (i .== literal j) x' x) [0..]
 
-sCase :: (Mergeable a) => SInt16 -> a -> [(Int16, a)] -> a
-sCase x def = go
+goCase :: (Mergeable a) => SInt16 -> a -> [(Int16, a)] -> a
+goCase x def = go
   where
     go [] = def
     go ((k,v):kvs) = ite (x .== literal k) v (go kvs)
@@ -165,7 +165,7 @@
 sWhen :: (Monad m, Mergeable (m ())) => SBool -> m () -> m ()
 sWhen b act = ite b act (return ())
 
-sFindIndex :: (a -> SBool) -> [a] -> SMaybe Int16
+sFindIndex :: (a -> SBool) -> [a] -> SBV.SMaybe Int16
 sFindIndex p = go 0
   where
     go _ [] = SBV.sNothing
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
@@ -14,11 +14,8 @@
 {-# LANGUAGE OverloadedLists     #-}
 {-# LANGUAGE OverloadedStrings   #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeApplications    #-}
-
-#if MIN_VERSION_base(4,19,0)
 {-# LANGUAGE TypeAbstractions    #-}
-#endif
+{-# LANGUAGE TypeApplications    #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -79,7 +76,6 @@
           constrain $ q1 (-3) .== 9
           constrain $ q1 x    .== x+1
 
-          registerFunction q2 -- Not really necessary, but testing it doesn't break anything
           constrain $ q2 sTrue 3   .== 5
           constrain $ q2 sFalse 7  .== 6
           constrain $ q2 sFalse 12 .== 3
diff --git a/SBVTestSuite/TestSuite/Queries/Uninterpreted.hs b/SBVTestSuite/TestSuite/Queries/Uninterpreted.hs
--- a/SBVTestSuite/TestSuite/Queries/Uninterpreted.hs
+++ b/SBVTestSuite/TestSuite/Queries/Uninterpreted.hs
@@ -9,12 +9,10 @@
 -- Testing uninterpreted value extraction
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DeriveAnyClass      #-}
-{-# LANGUAGE DeriveDataTypeable  #-}
 {-# LANGUAGE FlexibleInstances   #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE StandaloneDeriving  #-}
 {-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE TypeApplications    #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -23,8 +21,8 @@
 import Data.SBV.Control
 import Utils.SBVTestFramework
 
-data L = A | B deriving (Enum, Bounded)
-mkSymbolicEnumeration ''L
+data L = A | B deriving Show
+mkSymbolic [''L]
 
 -- Test suite
 tests :: TestTree
diff --git a/SBVTestSuite/TestSuite/QuickCheck/QC.hs b/SBVTestSuite/TestSuite/QuickCheck/QC.hs
--- a/SBVTestSuite/TestSuite/QuickCheck/QC.hs
+++ b/SBVTestSuite/TestSuite/QuickCheck/QC.hs
@@ -9,7 +9,7 @@
 -- Quick-check based test suite for SBV
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE Rank2Types #-}
+{-# LANGUAGE RankNTypes #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
diff --git a/SBVTestSuite/TestSuite/Uninterpreted/Axioms.hs b/SBVTestSuite/TestSuite/Uninterpreted/Axioms.hs
--- a/SBVTestSuite/TestSuite/Uninterpreted/Axioms.hs
+++ b/SBVTestSuite/TestSuite/Uninterpreted/Axioms.hs
@@ -9,10 +9,7 @@
 -- Test suite for basic axioms and uninterpreted functions
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DeriveAnyClass     #-}
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE StandaloneDeriving #-}
-{-# LANGUAGE TemplateHaskell    #-}
+{-# LANGUAGE TemplateHaskell #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -26,9 +23,9 @@
 data B
 data Thing
 
-mkUninterpretedSort ''Bitstring
-mkUninterpretedSort ''B
-mkUninterpretedSort ''Thing
+mkSymbolic [''Bitstring]
+mkSymbolic [''B]
+mkSymbolic [''Thing]
 
 tests :: TestTree
 tests =
@@ -62,7 +59,6 @@
 p1 :: Symbolic SBool
 p1 = do constrain $ \(Forall x) -> thingCompare x x
         constrain $ \(Forall k1) (Forall k2) -> k1 ./= thingMerge k1 k2
-        registerFunction thingMerge
         k1 <- free_
         k2 <- free_
         return $ k1 .== k2 .=> thingCompare k1 k2
diff --git a/SBVTestSuite/TestSuite/Uninterpreted/EUFLogic.hs b/SBVTestSuite/TestSuite/Uninterpreted/EUFLogic.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/TestSuite/Uninterpreted/EUFLogic.hs
@@ -0,0 +1,48 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Documentation.SBV.Examples.Uninterpreted.EUFLogic
+-- License   : BSD3
+-- Stability : experimental
+--
+-- Test suite for the EUFLogic example
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE DataKinds #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module TestSuite.Uninterpreted.EUFLogic where
+
+import Documentation.SBV.Examples.Uninterpreted.EUFLogic
+
+import Utils.SBVTestFramework
+
+-- Test suite
+tests :: TestTree
+tests =
+  testGroup "Uninterpreted.LargeArgs"
+    [ testCase "euflogic-1" $ assertIsSat (interpEUF fourteen)
+    , testCase "unint17arg" $ assertIsSat f17Args
+    ]
+
+fourteen :: EUFExpr Tp_Bool
+fourteen = applyOp (Op_BVEq knownBVWidth)
+                   (applyOp f14 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
+                   (applyOp (Op_Plus knownBVWidth) a b)
+  where
+    f14 :: Op '[Tp_BV 8, Tp_BV 8, Tp_BV 8, Tp_BV 8, Tp_BV 8, Tp_BV 8, Tp_BV 8,
+                Tp_BV 8, Tp_BV 8, Tp_BV 8, Tp_BV 8, Tp_BV 8, Tp_BV 8, Tp_BV 8]
+           (Tp_BV 8)
+
+    f14 = mkUnintOp "f"
+    a, b :: EUFExpr (Tp_BV 8)
+    a = mkUnintExpr "a"
+    b = mkUnintExpr "b"
+
+f17Args :: SWord  1 -> SWord  2 -> SWord  3 -> SWord  4 -> SWord  5 -> SWord  6 -> SWord  7 -> SWord 8
+        -> SWord  9 -> SWord 10 -> SWord 11 -> SWord 12 -> SWord 13 -> SWord 14 -> SWord 15 -> SWord 16
+        -> SWord 17
+        -> SBool
+f17Args = uninterpret "f17Args"
+
+{- HLint ignore "Use camelCase" -}
diff --git a/SBVTestSuite/TestSuite/Uninterpreted/Function.hs b/SBVTestSuite/TestSuite/Uninterpreted/Function.hs
--- a/SBVTestSuite/TestSuite/Uninterpreted/Function.hs
+++ b/SBVTestSuite/TestSuite/Uninterpreted/Function.hs
@@ -9,11 +9,7 @@
 -- Testsuite for Documentation.SBV.Examples.Uninterpreted.Function
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DeriveAnyClass      #-}
-{-# LANGUAGE DeriveDataTypeable  #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE StandaloneDeriving  #-}
-{-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE TemplateHaskell #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -24,40 +20,40 @@
 import Utils.SBVTestFramework
 
 data A1
-mkUninterpretedSort ''A1
+mkSymbolic [''A1]
 
 data A2
-mkUninterpretedSort ''A2
+mkSymbolic [''A2]
 
 data A3
-mkUninterpretedSort ''A3
+mkSymbolic [''A3]
 
 data A4
-mkUninterpretedSort ''A4
+mkSymbolic [''A4]
 
 data A5
-mkUninterpretedSort ''A5
+mkSymbolic [''A5]
 
 data A6
-mkUninterpretedSort ''A6
+mkSymbolic [''A6]
 
 data A7
-mkUninterpretedSort ''A7
+mkSymbolic [''A7]
 
 data A8
-mkUninterpretedSort ''A8
+mkSymbolic [''A8]
 
 data A9
-mkUninterpretedSort ''A9
+mkSymbolic [''A9]
 
 data A10
-mkUninterpretedSort ''A10
+mkSymbolic [''A10]
 
 data A11
-mkUninterpretedSort ''A11
+mkSymbolic [''A11]
 
 data A12
-mkUninterpretedSort ''A12
+mkSymbolic [''A12]
 
 
 f1 :: SA1 -> SBool
diff --git a/SBVTestSuite/TestSuite/Uninterpreted/Sort.hs b/SBVTestSuite/TestSuite/Uninterpreted/Sort.hs
--- a/SBVTestSuite/TestSuite/Uninterpreted/Sort.hs
+++ b/SBVTestSuite/TestSuite/Uninterpreted/Sort.hs
@@ -9,10 +9,7 @@
 -- Test suite for uninterpreted sorts
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DeriveAnyClass      #-}
-{-# LANGUAGE DeriveDataTypeable  #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE StandaloneDeriving  #-}
 {-# LANGUAGE TemplateHaskell     #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
@@ -22,13 +19,12 @@
 import Utils.SBVTestFramework
 
 data L
-mkUninterpretedSort ''L
+mkSymbolic [''L]
 
 tests :: TestTree
 tests =
   testGroup "Uninterpreted.Sort"
-    [ testCase "unint-sort"
-        (assert . (==4) . length . (extractModels :: AllSatResult -> [L]) =<< allSat p0)
+    [ goldenVsStringShow "unint-sort01" $ allSat p0
     ]
 
 len :: SL -> SInteger
diff --git a/SBVTestSuite/TestSuite/Uninterpreted/Uninterpreted.hs b/SBVTestSuite/TestSuite/Uninterpreted/Uninterpreted.hs
--- a/SBVTestSuite/TestSuite/Uninterpreted/Uninterpreted.hs
+++ b/SBVTestSuite/TestSuite/Uninterpreted/Uninterpreted.hs
@@ -8,18 +8,16 @@
 --
 -----------------------------------------------------------------------------
 
-{-# LANGUAGE DeriveAnyClass     #-}
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE StandaloneDeriving #-}
-{-# LANGUAGE TemplateHaskell    #-}
-{-# OPTIONS_GHC -Wall -Werror   #-}
+{-# LANGUAGE TemplateHaskell #-}
 
+{-# OPTIONS_GHC -Wall -Werror #-}
+
 module TestSuite.Uninterpreted.Uninterpreted(tests) where
 
 import Utils.SBVTestFramework
 
 data Q
-mkUninterpretedSort ''Q
+mkSymbolic [''Q]
 
 -- Test suite
 tests :: TestTree
@@ -27,6 +25,7 @@
   testGroup "Uninterpreted.Uninterpreted"
     [ testCase         "uninterpreted-0"  $ assertIsThm   p0
     , testCase         "uninterpreted-1"  $ assertIsThm   p1
+    , goldenCapturedIO "uninterpreted-1a" $ t p1_unc satWith
     , testCase         "uninterpreted-2"  $ assertIsntThm p2
     , goldenCapturedIO "uninterpreted-3"  $ t p3 satWith
     , goldenCapturedIO "uninterpreted-3a" $ t p3 allSatWith
@@ -51,7 +50,15 @@
 p2 :: SInt8 -> SWord16 -> SWord16 -> SBool
 p2 x y z = y .== z .=> g x y .== f x    -- Not true
 
+-- | Uncurried version of 'g'
+g_unc :: (SInt8, SWord16) -> SWord32
+g_unc = uninterpret "g"
 
+-- | Same as 'p1' but using the uncurried version 'g_unc' of 'g'
+p1_unc :: SInt8 -> SWord16 -> SWord16 -> SBool
+p1_unc x y z = y .== z .=> g_unc (x, y) .== g_unc (x, z)  -- OK
+
+
 a, b :: SBool
 a = sym "p"
 b = sym "q"
@@ -65,3 +72,5 @@
 
 p4 :: SBool
 p4 = c ./= d
+
+{- HLint ignore type g_unc "Use camelCase" -}
diff --git a/SBVTestSuite/Utils/CCodeGen.hs b/SBVTestSuite/Utils/CCodeGen.hs
new file mode 100644
--- /dev/null
+++ b/SBVTestSuite/Utils/CCodeGen.hs
@@ -0,0 +1,114 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Utils.CCodeGen
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Shared dependency discovery for generated-C integration tests.
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE ScopedTypeVariables #-}
+
+{-# OPTIONS_GHC -Wall -Werror #-}
+
+module Utils.CCodeGen (locateLibBF, generatedMakeOptions) where
+
+import Control.Exception (IOException, catch)
+import Control.Concurrent.MVar (MVar, modifyMVar, newMVar)
+import Data.List (isInfixOf, isPrefixOf, isSuffixOf, sort)
+import System.Directory (doesDirectoryExist, doesFileExist, listDirectory)
+import System.Environment (lookupEnv)
+import System.FilePath ((</>), takeDirectory)
+import System.Process (readProcessWithExitCode)
+import System.Exit (ExitCode(..))
+import System.IO.Unsafe (unsafePerformIO)
+
+-- | Locate the header and static archive installed for the Haskell @libBF@
+-- dependency so integration tests exercise the same C implementation.
+locateLibBF :: IO (FilePath, FilePath)
+locateLibBF = modifyMVar libBFLocation $ \cached -> do
+  result <- maybe discoverLibBF pure cached
+  pure (Just result, result)
+
+-- | Share immutable dependency discovery across parallel integration tests.
+{-# NOINLINE libBFLocation #-}
+libBFLocation :: MVar (Maybe (FilePath, FilePath))
+libBFLocation = unsafePerformIO (newMVar Nothing)
+
+-- | Allow explicit installations; otherwise find a matching header/archive
+-- pair from one Cabal package, never from different package versions.
+discoverLibBF :: IO (FilePath, FilePath)
+discoverLibBF = do
+  includeOverride <- lookupEnv "SBV_C_LIBBF_INCLUDE"
+  libraryOverride <- lookupEnv "SBV_C_LIBBF_LIBRARY"
+  case (includeOverride, libraryOverride) of
+    (Just includeDir, Just archive) -> do
+      headerExists <- doesFileExist (includeDir </> "libbf.h")
+      archiveExists <- doesFileExist archive
+      if headerExists && archiveExists then pure (includeDir, archive)
+        else fail "SBV_C_LIBBF_INCLUDE/SBV_C_LIBBF_LIBRARY must name an installed libbf.h and library."
+    (Nothing, Nothing) -> discoverStoredLibBF
+    _ -> fail "Set both SBV_C_LIBBF_INCLUDE and SBV_C_LIBBF_LIBRARY, or neither."
+
+-- | Discover the installed Haskell dependency's bundled C library.
+discoverStoredLibBF :: IO (FilePath, FilePath)
+discoverStoredLibBF = do
+  (pathExit, pathOutput, pathError) <- readProcessWithExitCode "cabal" ["path"] ""
+  case pathExit of
+    ExitSuccess -> pure ()
+    _ -> fail $ "Unable to query Cabal store: " ++ pathError
+  let storePrefix = "compiler-store-path: "
+      stores      = [drop (length storePrefix) line | line <- lines pathOutput, storePrefix `isInfixOf` line]
+  store <- case stores of
+             path:_ -> pure path
+             []     -> fail $ "Unable to find Cabal store: " ++ pathError
+  packages <- listDirectory store
+  let libBFDirs = [store </> entry | entry <- sort packages, "lbBF-" `isPrefixOf` entry]
+  firstSuccessful [do header <- findInstalledFile path "libbf.h"
+                      archive <- findInstalledFile path "libHSlbBF"
+                      pure (takeDirectory header, archive)
+                  | path <- libBFDirs]
+
+-- | Recursively find an installed file by exact name or filename prefix.
+findInstalledFile :: FilePath -> String -> IO FilePath
+findInstalledFile root sought = do
+  entries <- listDirectory root
+  search entries
+ where search []           = fail $ "Unable to find " ++ sought ++ " below " ++ root
+       search (entry:rest) = do
+         let path = root </> entry
+         isDir  <- doesDirectoryExist path
+         isFile <- doesFileExist path
+         if isFile && matches entry
+           then pure path
+           else if isDir
+                  then findInstalledFile path sought `catchIO` search rest
+                  else search rest
+
+       matches entry
+         | sought == "libHSlbBF" = sought `isPrefixOf` entry && ".a" `isSuffixOf` entry
+         | True                  = entry == sought
+
+-- | Return the first successful filesystem search result.
+firstSuccessful :: [IO a] -> IO a
+firstSuccessful = foldr catchIO (fail "Unable to locate the installed libBF package")
+
+-- | Recover from an expected filesystem-search failure with another search.
+catchIO :: IO a -> IO a -> IO a
+catchIO action fallback = action `catch` \(_ :: IOException) -> fallback
+
+-- | Build generated Makefiles with strict warnings, resolving LibBF from the
+-- Cabal store when needed. Keep compiler overrides and GMP discovery intact.
+-- Append @SBV_C_TEST_FLAGS@ to both compilation and linking commands, allowing
+-- optimization and sanitizer runs to cover generated programs and library callers.
+generatedMakeOptions :: FilePath -> IO [String]
+generatedMakeOptions dir = do
+  makefile <- readFile (dir </> "Makefile")
+  extraFlags <- maybe "" (" " ++) <$> lookupEnv "SBV_C_TEST_FLAGS"
+  let flags = "CCFLAGS=-std=c11 -Wall -Werror -O2" ++ extraFlags
+  if "-lbf" `isInfixOf` makefile
+    then do (includeDir, archive) <- locateLibBF
+            pure [flags ++ " -I\"" ++ includeDir ++ "\"", "SBV_LIBS=\"" ++ archive ++ "\" -lm ${GMP_LIBS}"]
+    else pure [flags]
diff --git a/SBVTestSuite/Utils/SBVTestFramework.hs b/SBVTestSuite/Utils/SBVTestFramework.hs
--- a/SBVTestSuite/Utils/SBVTestFramework.hs
+++ b/SBVTestSuite/Utils/SBVTestFramework.hs
@@ -26,6 +26,8 @@
         , goldenCapturedIO
         , qc1, qc2
         , shouldNotTypeCheck
+        , mkCompileTest
+        , mkCompileTestGlob
         -- module exports to simplify life
         , module Test.Tasty
         , module Test.Tasty.HUnit
@@ -39,12 +41,12 @@
 import Control.Monad.Trans (liftIO)
 
 import qualified Data.ByteString.Lazy.Char8 as LBC
-import System.Directory   (removeFile)
+import System.Directory   (getCurrentDirectory, removeFile)
 
 import Test.Tasty            (testGroup, TestTree, TestName)
 import Test.Tasty.HUnit      ((@?), Assertion, testCase, AssertionPredicable, assertFailure)
 
-import Test.Tasty.Golden     (goldenVsString, goldenVsFileDiff)
+import Test.Tasty.Golden     (goldenVsString, goldenVsFileDiff, goldenVsStringDiff)
 
 import qualified Test.Tasty.QuickCheck   as QC
 import qualified Test.QuickCheck.Monadic as QC
@@ -54,10 +56,17 @@
 import Data.SBV
 import Data.SBV.Control
 
-import System.FilePath ((</>), (<.>))
+import System.FilePath      ((</>), (<.>), takeDirectory, takeBaseName)
+import System.FilePath.Glob (glob)
+
 import Data.List       (isInfixOf, isSuffixOf)
 
+import System.Exit
+import System.Process
+import System.IO hiding (stderr)
 
+import System.IO.Temp (withSystemTempDirectory)
+
 import Data.SBV.Internals (runSymbolic, Result, SBVRunMode(..), IStage(..), SBV(..), SVal(..), showModel, SMTModel(..), QueryContext(..), Outputtable)
 
 -- | Generic assertion. This is less safe than usual, but will do.
@@ -231,5 +240,103 @@
               -> pure ()
       | True
       -> throwIO e
+
+-- | Like readProcessWithExitCode, but in a given directory
+readProcessInDir :: FilePath -> String -> [String] -> String -> IO (ExitCode, String, String)
+readProcessInDir dir cmd args input = do
+    let cp = (proc cmd args)
+                { cwd     = Just dir
+                , std_in  = CreatePipe
+                , std_out = CreatePipe
+                , std_err = CreatePipe
+                }
+    withCreateProcess cp $ \mIn mOut mErr ph -> do
+        -- feed input if needed
+        case mIn of
+            Just hin -> hPutStr hin input >> hClose hin
+            Nothing  -> return ()
+
+        out <- case mOut of
+            Just hout -> do
+                s <- hGetContents hout
+                _ <- evaluate (length s)  -- force full read
+                return s
+            Nothing -> return ""
+
+        err <- case mErr of
+            Just herr -> do
+                s <- hGetContents herr
+                _ <- evaluate (length s)  -- force full read
+                return s
+            Nothing -> return ""
+
+        exitCode <- waitForProcess ph
+        return (exitCode, out, err)
+
+-- | Make a compilation test from all the files matching glob
+mkCompileTestGlob :: String -> IO [TestTree]
+mkCompileTestGlob g = do fs <- glob g
+                         pure $ map mkCompileTest fs
+
+-- | Make a compilation test
+mkCompileTest :: FilePath -> TestTree
+mkCompileTest file = goldenVsStringDiff nm diffCmd (testDir </> nm <.> "stderr") (compile (nm <.> "hs"))
+  where testDir = takeDirectory file
+        nm      = takeBaseName  file
+
+        diffCmd ref new = ["diff", "-u", ref, new]
+
+        packages = [ "QuickCheck"
+                   , "array"
+                   , "containers"
+                   , "deepseq"
+                   , "libBF"
+                   , "mtl"
+                   , "random"
+                   , "syb"
+                   , "template-haskell"
+                   , "text"
+                   , "time"
+                   , "transformers"
+                   , "uniplate"
+                   ]
+
+        args td  =  "-XHaskell2010 -fforce-recomp -tmpdir " ++ td ++ " -outputdir " ++ td
+                 ++ concat [" -package " ++ pkg | pkg <- packages]
+
+        compile path = withSystemTempDirectory "SBVTempDir" $ \tmpDir -> do
+           -- Use the inplace package DB from dist-newstyle so we pick up
+           -- the locally-built sbv (built by cabal test) without needing
+           -- a separate 'cabal install --lib' step.
+           projRoot <- getCurrentDirectory
+           let cabalFile = projRoot </> "sbv.cabal"
+           ver <- extractVersion <$> readFile cabalFile
+           sbvDBs <- glob (projRoot </> "dist-newstyle/build/*/ghc-*/sbv-" ++ ver ++ "/package.conf.inplace")
+           let pkgDbArgs = case sbvDBs of
+                             (db:_) -> ["-package-db", db]
+                             []     -> []
+           (exitCode, sOut, sErr) <- readProcessInDir testDir "ghc" (pkgDbArgs ++ words (args tmpDir) ++ [path]) ""
+           -- If the source uses -ddump-splices, include stdout (where GHC dumps splices)
+           -- Filter to only keep "Splicing expression" blocks, stripping temp paths and preamble
+           src <- readFile (testDir </> path)
+           let hasDump  = "-ddump-splices" `isInfixOf` src
+               splices  = unlines $ filter (not . skipLine) $ dropWhile (not . isSpliceLine) $ lines sOut
+               out      = if hasDump then splices ++ sErr else sErr
+           case exitCode of
+             ExitSuccess   -> return $ LBC.pack $ if hasDump && not (null splices)
+                                                   then splices
+                                                   else "There was no failure during compilation."
+             ExitFailure _ -> return $ LBC.pack out
+
+        isSpliceLine l = "Splicing expression" `isInfixOf` l
+        skipLine     l = "Loaded package environment" `isInfixOf` l
+                      || "Compiling" `isInfixOf` l
+
+        -- Extract the version string from sbv.cabal
+        extractVersion = go . lines
+          where go []     = error "mkCompileTest: Cannot find Version in sbv.cabal"
+                go (l:ls) = case words l of
+                              ["Version", ":", v] -> v
+                              _                   -> go ls
 
 {- HLint ignore module "Reduce duplication" -}
diff --git a/sbv.cabal b/sbv.cabal
--- a/sbv.cabal
+++ b/sbv.cabal
@@ -1,13 +1,13 @@
 Cabal-Version: 2.2
 
 Name        : sbv
-Version     : 12.2
+Version     : 14.8
 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
                (Satisfiability Modulo Theories) solvers.
 
-Copyright          : Levent Erkok, 2010-2025
+Copyright          : Levent Erkok, 2010-2026
 License            : BSD-3-Clause
 License-file       : LICENSE
 Stability          : Experimental
@@ -17,15 +17,22 @@
 Maintainer         : Levent Erkok (erkokl@gmail.com)
 Build-Type         : Simple
 Data-Files         : SBVTestSuite/GoldFiles/*.gold
+                     SBVTestSuite/TestSuite/CompileTests/SCase/*.hs
+                     SBVTestSuite/TestSuite/CompileTests/SCase/*.stderr
+                     SBVTestSuite/TestSuite/CompileTests/PCase/*.hs
+                     SBVTestSuite/TestSuite/CompileTests/PCase/*.stderr
 Extra-Doc-Files    : INSTALL, README.md, COPYRIGHT, CHANGES.md
 
-Tested-With        : GHC==9.10.1
-
 flag doctest_is_running
   description: Define this flag during doctest run
   default    : False
   manual     : True
 
+flag compile_examples
+  description: Compile examples for documentation.
+  default    : True
+  manual     : True
+
 source-repository head
   type    : git
   location: https://github.com/LeventErkok/sbv.git
@@ -34,7 +41,8 @@
    default-language: Haskell2010
    ghc-options     : -Wall
    build-depends   : base >= 4.19.2 && < 5
-   other-extensions: BangPatterns
+   other-extensions: AllowAmbiguousTypes
+                     BangPatterns
                      CPP
                      ConstraintKinds
                      DataKinds
@@ -46,6 +54,7 @@
                      DeriveLift
                      DeriveTraversable
                      DerivingStrategies
+                     EmptyDataDecls
                      ExistentialQuantification
                      FlexibleContexts
                      FlexibleInstances
@@ -59,15 +68,15 @@
                      MultiParamTypeClasses
                      NamedFieldPuns
                      NegativeLiterals
+                     NumericUnderscores
                      OverloadedLists
                      OverloadedRecordDot
                      OverloadedStrings
                      PackageImports
                      ParallelListComp
-                     PatternGuards
+                     PatternSynonyms
                      QuantifiedConstraints
                      QuasiQuotes
-                     Rank2Types
                      RankNTypes
                      RecordWildCards
                      ScopedTypeVariables
@@ -81,12 +90,9 @@
                      TypeOperators
                      UndecidableInstances
                      ViewPatterns
-
-   if impl(ghc >= 9.8.1)
-      other-extensions: TypeAbstractions
+                     TypeAbstractions
 
-   if impl(ghc >= 8.10.1)
-      ghc-options  : -Wunused-packages
+   ghc-options  : -Wunused-packages
 
 Library
   import          : common-settings
@@ -114,6 +120,7 @@
                   , random
                   , syb
                   , template-haskell
+                  , th-expand-syns
                   , text
                   , time
                   , transformers
@@ -133,11 +140,11 @@
                   , Data.SBV.Tuple
                   , Data.SBV.RegExp
                   , Data.SBV.TP
-                  , Data.SBV.TP.List
                   , Data.SBV.Tools.BMC
                   , Data.SBV.Tools.BVOptimize
                   , Data.SBV.Tools.Induction
                   , Data.SBV.Tools.CodeGen
+                  , Data.SBV.Tools.CodeGen.Legacy
                   , Data.SBV.Tools.GenTest
                   , Data.SBV.Tools.Overflow
                   , Data.SBV.Tools.Polynomial
@@ -146,124 +153,153 @@
                   , Data.SBV.Tools.WeakestPreconditions
                   , Data.SBV.Trans
                   , Data.SBV.Trans.Control
-                  , Documentation.SBV.Examples.BitPrecise.BitTricks
-                  , Documentation.SBV.Examples.BitPrecise.BrokenSearch
-                  , Documentation.SBV.Examples.BitPrecise.Legato
-                  , Documentation.SBV.Examples.BitPrecise.MergeSort
-                  , Documentation.SBV.Examples.BitPrecise.PEXT_PDEP
-                  , Documentation.SBV.Examples.BitPrecise.PrefixSum
-                  , Documentation.SBV.Examples.CodeGeneration.AddSub
-                  , Documentation.SBV.Examples.CodeGeneration.CRC_USB5
-                  , Documentation.SBV.Examples.CodeGeneration.Fibonacci
-                  , Documentation.SBV.Examples.CodeGeneration.GCD
-                  , Documentation.SBV.Examples.CodeGeneration.PopulationCount
-                  , 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.Diophantine
-                  , Documentation.SBV.Examples.Lists.Fibonacci
-                  , Documentation.SBV.Examples.Lists.BoundedMutex
-                  , Documentation.SBV.Examples.Lists.CountOutAndTransfer
-                  , Documentation.SBV.Examples.Misc.Definitions
-                  , Documentation.SBV.Examples.Misc.Enumerate
-                  , Documentation.SBV.Examples.Misc.FirstOrderLogic
-                  , Documentation.SBV.Examples.Misc.Floating
-                  , Documentation.SBV.Examples.Misc.LambdaArray
-                  , Documentation.SBV.Examples.Misc.ModelExtract
-                  , Documentation.SBV.Examples.Misc.NestedArray
-                  , Documentation.SBV.Examples.Misc.Auxiliary
-                  , Documentation.SBV.Examples.Misc.NoDiv0
-                  , Documentation.SBV.Examples.Misc.Newtypes
-                  , Documentation.SBV.Examples.Misc.Polynomials
-                  , Documentation.SBV.Examples.Misc.ProgramPaths
-                  , Documentation.SBV.Examples.Misc.SetAlgebra
-                  , Documentation.SBV.Examples.Misc.SoftConstrain
-                  , Documentation.SBV.Examples.Misc.Tuple
-                  , Documentation.SBV.Examples.Optimization.Enumerate
-                  , Documentation.SBV.Examples.Optimization.ExtField
-                  , Documentation.SBV.Examples.Optimization.LinearOpt
-                  , Documentation.SBV.Examples.Optimization.Production
-                  , Documentation.SBV.Examples.Optimization.VM
-                  , Documentation.SBV.Examples.ProofTools.AddHorn
-                  , Documentation.SBV.Examples.ProofTools.BMC
-                  , Documentation.SBV.Examples.ProofTools.Fibonacci
-                  , Documentation.SBV.Examples.ProofTools.Strengthen
-                  , Documentation.SBV.Examples.ProofTools.Sum
-                  , Documentation.SBV.Examples.WeakestPreconditions.Append
-                  , Documentation.SBV.Examples.WeakestPreconditions.Basics
-                  , Documentation.SBV.Examples.WeakestPreconditions.Fib
-                  , Documentation.SBV.Examples.WeakestPreconditions.GCD
-                  , Documentation.SBV.Examples.WeakestPreconditions.IntDiv
-                  , Documentation.SBV.Examples.WeakestPreconditions.IntSqrt
-                  , Documentation.SBV.Examples.WeakestPreconditions.Length
-                  , Documentation.SBV.Examples.WeakestPreconditions.Sum
-                  , Documentation.SBV.Examples.Puzzles.AOC_2021_24
-                  , Documentation.SBV.Examples.Puzzles.Birthday
-                  , Documentation.SBV.Examples.Puzzles.Coins
-                  , Documentation.SBV.Examples.Puzzles.Counts
-                  , Documentation.SBV.Examples.Puzzles.DieHard
-                  , Documentation.SBV.Examples.Puzzles.DogCatMouse
-                  , Documentation.SBV.Examples.Puzzles.Drinker
-                  , Documentation.SBV.Examples.Puzzles.Euler185
-                  , Documentation.SBV.Examples.Puzzles.Fish
-                  , Documentation.SBV.Examples.Puzzles.Garden
-                  , Documentation.SBV.Examples.Puzzles.HexPuzzle
-                  , Documentation.SBV.Examples.Puzzles.Jugs
-                  , Documentation.SBV.Examples.Puzzles.KnightsAndKnaves
-                  , Documentation.SBV.Examples.Puzzles.LadyAndTigers
-                  , Documentation.SBV.Examples.Puzzles.MagicSquare
-                  , Documentation.SBV.Examples.Puzzles.Murder
-                  , Documentation.SBV.Examples.Puzzles.Newspaper
-                  , Documentation.SBV.Examples.Puzzles.NQueens
-                  , Documentation.SBV.Examples.Puzzles.Orangutans
-                  , Documentation.SBV.Examples.Puzzles.Rabbits
-                  , Documentation.SBV.Examples.Puzzles.SendMoreMoney
-                  , Documentation.SBV.Examples.Puzzles.Sudoku
-                  , Documentation.SBV.Examples.Puzzles.Tower
-                  , Documentation.SBV.Examples.Puzzles.U2Bridge
-                  , Documentation.SBV.Examples.Queries.Abducts
-                  , Documentation.SBV.Examples.Queries.AllSat
-                  , Documentation.SBV.Examples.Queries.UnsatCore
-                  , Documentation.SBV.Examples.Queries.FourFours
-                  , Documentation.SBV.Examples.Queries.GuessNumber
-                  , Documentation.SBV.Examples.Queries.CaseSplit
-                  , Documentation.SBV.Examples.Queries.Enums
-                  , Documentation.SBV.Examples.Queries.Interpolants
-                  , Documentation.SBV.Examples.Queries.Concurrency
-                  , Documentation.SBV.Examples.Strings.RegexCrossword
-                  , Documentation.SBV.Examples.Strings.SQLInjection
-                  , Documentation.SBV.Examples.TP.Basics
-                  , Documentation.SBV.Examples.TP.BinarySearch
-                  , Documentation.SBV.Examples.TP.CaseSplit
-                  , Documentation.SBV.Examples.TP.Fibonacci
-                  , Documentation.SBV.Examples.TP.GCD
-                  , Documentation.SBV.Examples.TP.InsertionSort
-                  , Documentation.SBV.Examples.TP.Kleene
-                  , Documentation.SBV.Examples.TP.McCarthy91
-                  , Documentation.SBV.Examples.TP.Majority
-                  , Documentation.SBV.Examples.TP.MergeSort
-                  , Documentation.SBV.Examples.TP.Numeric
-                  , Documentation.SBV.Examples.TP.PowerMod
-                  , Documentation.SBV.Examples.TP.QuickSort
-                  , Documentation.SBV.Examples.TP.RevAcc
-                  , Documentation.SBV.Examples.TP.Reverse
-                  , Documentation.SBV.Examples.TP.ShefferStroke
-                  , Documentation.SBV.Examples.TP.SortHelpers
-                  , Documentation.SBV.Examples.TP.Sqrt2IsIrrational
-                  , Documentation.SBV.Examples.TP.StrongInduction
-                  , Documentation.SBV.Examples.TP.SumReverse
-                  , Documentation.SBV.Examples.TP.Tao
-                  , Documentation.SBV.Examples.Transformers.SymbolicEval
-                  , Documentation.SBV.Examples.Uninterpreted.AUF
-                  , Documentation.SBV.Examples.Uninterpreted.Deduce
-                  , Documentation.SBV.Examples.Uninterpreted.Function
-                  , Documentation.SBV.Examples.Uninterpreted.Multiply
-                  , Documentation.SBV.Examples.Uninterpreted.Shannon
-                  , Documentation.SBV.Examples.Uninterpreted.Sort
-                  , Documentation.SBV.Examples.Uninterpreted.UISortAllSat
+
+  if flag(compile_examples)
+    Exposed-modules : Documentation.SBV.Examples.ADT.Expr
+                    , Documentation.SBV.Examples.ADT.Param
+                    , Documentation.SBV.Examples.ADT.Shapes
+                    , Documentation.SBV.Examples.ADT.Types
+                    , Documentation.SBV.Examples.BitPrecise.Adders
+                    , Documentation.SBV.Examples.BitPrecise.BitTricks
+                    , Documentation.SBV.Examples.BitPrecise.BrokenSearch
+                    , Documentation.SBV.Examples.BitPrecise.Legato
+                    , Documentation.SBV.Examples.BitPrecise.MergeSort
+                    , Documentation.SBV.Examples.BitPrecise.PEXT_PDEP
+                    , Documentation.SBV.Examples.BitPrecise.PrefixSum
+                    , Documentation.SBV.Examples.CodeGeneration.AddSub
+                    , Documentation.SBV.Examples.CodeGeneration.CRC_USB5
+                    , Documentation.SBV.Examples.CodeGeneration.Fibonacci
+                    , Documentation.SBV.Examples.CodeGeneration.GCD
+                    , Documentation.SBV.Examples.CodeGeneration.PopulationCount
+                    , 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.Diophantine
+                    , Documentation.SBV.Examples.Lists.Fibonacci
+                    , Documentation.SBV.Examples.Lists.BoundedMutex
+                    , Documentation.SBV.Examples.Lists.CountOutAndTransfer
+                    , Documentation.SBV.Examples.Misc.Definitions
+                    , Documentation.SBV.Examples.Misc.Enumerate
+                    , Documentation.SBV.Examples.Misc.FirstOrderLogic
+                    , Documentation.SBV.Examples.Misc.Floating
+                    , Documentation.SBV.Examples.Misc.LambdaArray
+                    , Documentation.SBV.Examples.Misc.ModelExtract
+                    , Documentation.SBV.Examples.Misc.NestedArray
+                    , Documentation.SBV.Examples.Misc.Auxiliary
+                    , Documentation.SBV.Examples.Misc.NoDiv0
+                    , Documentation.SBV.Examples.Misc.Newtypes
+                    , Documentation.SBV.Examples.Misc.Polynomials
+                    , Documentation.SBV.Examples.Misc.ProgramPaths
+                    , Documentation.SBV.Examples.Misc.SetAlgebra
+                    , Documentation.SBV.Examples.Misc.SoftConstrain
+                    , Documentation.SBV.Examples.Misc.Tuple
+                    , Documentation.SBV.Examples.Optimization.Enumerate
+                    , Documentation.SBV.Examples.Optimization.ExtField
+                    , Documentation.SBV.Examples.Optimization.LinearOpt
+                    , Documentation.SBV.Examples.Optimization.Production
+                    , Documentation.SBV.Examples.Optimization.VM
+                    , Documentation.SBV.Examples.ProofTools.AddHorn
+                    , Documentation.SBV.Examples.ProofTools.BMC
+                    , Documentation.SBV.Examples.ProofTools.Fibonacci
+                    , Documentation.SBV.Examples.ProofTools.Strengthen
+                    , Documentation.SBV.Examples.ProofTools.Sum
+                    , Documentation.SBV.Examples.WeakestPreconditions.Append
+                    , Documentation.SBV.Examples.WeakestPreconditions.Basics
+                    , Documentation.SBV.Examples.WeakestPreconditions.Fib
+                    , Documentation.SBV.Examples.WeakestPreconditions.GCD
+                    , Documentation.SBV.Examples.WeakestPreconditions.IntDiv
+                    , Documentation.SBV.Examples.WeakestPreconditions.IntSqrt
+                    , Documentation.SBV.Examples.WeakestPreconditions.Length
+                    , Documentation.SBV.Examples.WeakestPreconditions.Sum
+                    , Documentation.SBV.Examples.Puzzles.AOC_2021_24
+                    , Documentation.SBV.Examples.Puzzles.Birthday
+                    , Documentation.SBV.Examples.Puzzles.Coins
+                    , Documentation.SBV.Examples.Puzzles.Counts
+                    , Documentation.SBV.Examples.Puzzles.DieHard
+                    , Documentation.SBV.Examples.Puzzles.DogCatMouse
+                    , Documentation.SBV.Examples.Puzzles.Drinker
+                    , Documentation.SBV.Examples.Puzzles.Euler185
+                    , Documentation.SBV.Examples.Puzzles.Fish
+                    , Documentation.SBV.Examples.Puzzles.Garden
+                    , Documentation.SBV.Examples.Puzzles.HexPuzzle
+                    , Documentation.SBV.Examples.Puzzles.Jugs
+                    , Documentation.SBV.Examples.Puzzles.KnightsAndKnaves
+                    , Documentation.SBV.Examples.Puzzles.LadyAndTigers
+                    , Documentation.SBV.Examples.Puzzles.MagicSquare
+                    , Documentation.SBV.Examples.Puzzles.Murder
+                    , Documentation.SBV.Examples.Puzzles.Newspaper
+                    , Documentation.SBV.Examples.Puzzles.NQueens
+                    , Documentation.SBV.Examples.Puzzles.Orangutans
+                    , Documentation.SBV.Examples.Puzzles.Rabbits
+                    , Documentation.SBV.Examples.Puzzles.SendMoreMoney
+                    , Documentation.SBV.Examples.Puzzles.SquareBirthday
+                    , Documentation.SBV.Examples.Puzzles.Sudoku
+                    , Documentation.SBV.Examples.Puzzles.Tower
+                    , Documentation.SBV.Examples.Puzzles.U2Bridge
+                    , Documentation.SBV.Examples.Queries.Abducts
+                    , Documentation.SBV.Examples.Queries.AllSat
+                    , Documentation.SBV.Examples.Queries.UnsatCore
+                    , Documentation.SBV.Examples.Queries.FourFours
+                    , Documentation.SBV.Examples.Queries.GuessNumber
+                    , Documentation.SBV.Examples.Queries.CaseSplit
+                    , Documentation.SBV.Examples.Queries.Enums
+                    , Documentation.SBV.Examples.Queries.Interpolants
+                    , Documentation.SBV.Examples.Queries.Concurrency
+                    , Documentation.SBV.Examples.Strings.RegexCrossword
+                    , Documentation.SBV.Examples.Strings.SQLInjection
+                    , Documentation.SBV.Examples.TP.Ackermann
+                    , Documentation.SBV.Examples.TP.Adder
+                    , Documentation.SBV.Examples.TP.Basics
+                    , Documentation.SBV.Examples.TP.BinarySearch
+                    , Documentation.SBV.Examples.TP.CaseSplit
+                    , Documentation.SBV.Examples.TP.Coins
+                    , Documentation.SBV.Examples.TP.Collatz
+                    , Documentation.SBV.Examples.TP.ConstFold
+                    , Documentation.SBV.Examples.TP.Countdown
+                    , Documentation.SBV.Examples.TP.Fibonacci
+                    , Documentation.SBV.Examples.TP.GCD
+                    , Documentation.SBV.Examples.TP.InsertionSort
+                    , Documentation.SBV.Examples.TP.Kadane
+                    , Documentation.SBV.Examples.TP.Kleene
+                    , Documentation.SBV.Examples.TP.Lists
+                    , Documentation.SBV.Examples.TP.McCarthy91
+                    , Documentation.SBV.Examples.TP.Majority
+                    , Documentation.SBV.Examples.TP.MergeSort
+                    , Documentation.SBV.Examples.TP.MutualCorecursion
+                    , Documentation.SBV.Examples.TP.NatStream
+                    , Documentation.SBV.Examples.TP.Numeric
+                    , Documentation.SBV.Examples.TP.Peano
+                    , Documentation.SBV.Examples.TP.PigeonHole
+                    , Documentation.SBV.Examples.TP.PowerMod
+                    , Documentation.SBV.Examples.TP.Primes
+                    , Documentation.SBV.Examples.TP.Queue
+                    , Documentation.SBV.Examples.TP.QuickSort
+                    , Documentation.SBV.Examples.TP.RevAcc
+                    , Documentation.SBV.Examples.TP.Reverse
+                    , Documentation.SBV.Examples.TP.RunLength
+                    , Documentation.SBV.Examples.TP.ShefferStroke
+                    , Documentation.SBV.Examples.TP.SortHelpers
+                    , Documentation.SBV.Examples.TP.Sqrt2IsIrrational
+                    , Documentation.SBV.Examples.TP.StrongInduction
+                    , Documentation.SBV.Examples.TP.SumReverse
+                    , Documentation.SBV.Examples.TP.Tao
+                    , Documentation.SBV.Examples.TP.TautologyChecker
+                    , Documentation.SBV.Examples.TP.Tree
+                    , Documentation.SBV.Examples.TP.UpDown
+                    , Documentation.SBV.Examples.TP.VM
+                    , Documentation.SBV.Examples.Transformers.SymbolicEval
+                    , Documentation.SBV.Examples.Uninterpreted.AUF
+                    , Documentation.SBV.Examples.Uninterpreted.Deduce
+                    , Documentation.SBV.Examples.Uninterpreted.EUFLogic
+                    , Documentation.SBV.Examples.Uninterpreted.Function
+                    , Documentation.SBV.Examples.Uninterpreted.Multiply
+                    , Documentation.SBV.Examples.Uninterpreted.Shannon
+                    , Documentation.SBV.Examples.Uninterpreted.Sort
+                    , Documentation.SBV.Examples.Uninterpreted.UISortAllSat
+
   other-modules   : Data.SBV.Client
                   , Data.SBV.Client.BaseIO
                   , Data.SBV.Core.AlgReals
@@ -276,13 +312,38 @@
                   , Data.SBV.Core.Sized
                   , Data.SBV.Core.SizedFloats
                   , Data.SBV.Core.Symbolic
+                  , Data.SBV.Core.TH
                   , Data.SBV.Control.BaseIO
                   , Data.SBV.Control.Query
                   , Data.SBV.Control.Types
                   , Data.SBV.Control.Utils
                   , Data.SBV.Compilers.C
+                  , Data.SBV.Compilers.C.ADT
+                  , Data.SBV.Compilers.C.Arena
+                  , Data.SBV.Compilers.C.Array
+                  , Data.SBV.Compilers.C.BV
+                  , Data.SBV.Compilers.C.FP
+                  , Data.SBV.Compilers.C.Finite
+                  , Data.SBV.Compilers.C.GMP
+                  , Data.SBV.Compilers.C.Legacy
+                  , Data.SBV.Compilers.C.Legacy.Internal
+                  , Data.SBV.Compilers.C.List
+                  , Data.SBV.Compilers.C.Lowering
+                  , Data.SBV.Compilers.C.NonLinear
+                  , Data.SBV.Compilers.C.Backend
+                  , Data.SBV.Compilers.C.PseudoBoolean
+                  , Data.SBV.Compilers.C.Real
+                  , Data.SBV.Compilers.C.RegExp
+                  , Data.SBV.Compilers.C.Set
+                  , Data.SBV.Compilers.C.Syntax
+                  , Data.SBV.Compilers.C.Table
+                  , Data.SBV.Compilers.C.Text
+                  , Data.SBV.Compilers.C.Types
+                  , Data.SBV.Compilers.C.Tuple
+                  , Data.SBV.Compilers.C.Value
                   , Data.SBV.Compilers.CodeGen
                   , Data.SBV.Lambda
+                  , Data.SBV.SCase
                   , Data.SBV.SEnum
                   , Data.SBV.SMT.SMT
                   , Data.SBV.SMT.SMTLib
@@ -316,22 +377,31 @@
   default-language : Haskell2010
   type             : exitcode-stdio-1.0
   ghc-options      : -with-rtsopts=-K64m
-  build-depends   : QuickCheck
+  build-depends   : Glob
+                  , QuickCheck
                   , bytestring
                   , containers
                   , deepseq
                   , directory
                   , filepath
                   , mtl
+                  , process
                   , random
                   , sbv
                   , tasty
                   , tasty-golden
                   , tasty-hunit
                   , tasty-quickcheck
+                  , temporary
   hs-source-dirs  : SBVTestSuite
   main-is         : SBVTest.hs
   other-modules   : Utils.SBVTestFramework
+                  , Utils.CCodeGen
+                  , TestSuite.ADT.ADT
+                  , TestSuite.ADT.Expr
+                  , TestSuite.ADT.MutRec
+                  , TestSuite.ADT.PExpr
+                  , TestSuite.ADT.Registration
                   , TestSuite.Arrays.InitVals
                   , TestSuite.Arrays.Memory
                   , TestSuite.Arrays.Query
@@ -360,7 +430,9 @@
                   , TestSuite.Basics.QRem
                   , TestSuite.Basics.Quantifiers
                   , TestSuite.Basics.Recursive
+                  , TestSuite.Basics.TPCaching
                   , TestSuite.Basics.Set
+                  , TestSuite.Basics.SmtFunctionUnique
                   , TestSuite.Basics.SmallShifts
                   , TestSuite.Basics.SquashReals
                   , TestSuite.Basics.String
@@ -368,24 +440,35 @@
                   , TestSuite.Basics.TOut
                   , TestSuite.Basics.Tuple
                   , TestSuite.Basics.UISat
+                  , TestSuite.CRC.CCITT
+                  , TestSuite.CRC.CCITT_Unidir
+                  , TestSuite.CRC.GenPoly
+                  , TestSuite.CRC.Parity
+                  , TestSuite.CRC.USB5
                   , TestSuite.Char.Char
                   , TestSuite.BitPrecise.BitTricks
                   , TestSuite.BitPrecise.Legato
                   , TestSuite.BitPrecise.MergeSort
                   , TestSuite.BitPrecise.PrefixSum
                   , TestSuite.CodeGeneration.AddSub
+                  , TestSuite.CodeGeneration.ArbitraryBits
+                  , TestSuite.CodeGeneration.ArbitraryFloats
+                  , TestSuite.CodeGeneration.ArrayCaptures
+                  , TestSuite.CodeGeneration.Boundaries
                   , TestSuite.CodeGeneration.CgTests
                   , TestSuite.CodeGeneration.CRC_USB5
+                  , TestSuite.CodeGeneration.ExactNumbers
                   , TestSuite.CodeGeneration.Fibonacci
                   , TestSuite.CodeGeneration.Floats
                   , TestSuite.CodeGeneration.GCD
                   , TestSuite.CodeGeneration.PopulationCount
+                  , TestSuite.CodeGeneration.LibraryBuild
+                  , TestSuite.CodeGeneration.PseudoBoolean
+                  , TestSuite.CodeGeneration.RegExp
+                  , TestSuite.CodeGeneration.ScalarSafety
                   , TestSuite.CodeGeneration.Uninterpreted
-                  , TestSuite.CRC.CCITT
-                  , TestSuite.CRC.CCITT_Unidir
-                  , TestSuite.CRC.GenPoly
-                  , TestSuite.CRC.Parity
-                  , TestSuite.CRC.USB5
+                  , TestSuite.CompileTests.SCase
+                  , TestSuite.CompileTests.PCase
                   , TestSuite.Crypto.AES
                   , TestSuite.Crypto.RC4
                   , TestSuite.Crypto.SHA
@@ -426,6 +509,7 @@
                   , TestSuite.Queries.Int_Z3
                   , TestSuite.Queries.Interpolants
                   , TestSuite.Queries.Lists
+                  , TestSuite.Queries.Registration
                   , TestSuite.Queries.Strings
                   , TestSuite.Queries.Sums
                   , TestSuite.Queries.Tables
@@ -440,6 +524,7 @@
                   , TestSuite.Uninterpreted.Function
                   , TestSuite.Uninterpreted.Sort
                   , TestSuite.Uninterpreted.Uninterpreted
+                  , TestSuite.Uninterpreted.EUFLogic
                   , TestSuite.CantTypeCheck.Misc
 
 Test-Suite SBVConnections
